diff --git a/libtorrent/include/libtorrent/aux_/session_impl.hpp b/libtorrent/include/libtorrent/aux_/session_impl.hpp index df39fabb0..bff8e3387 100644 --- a/libtorrent/include/libtorrent/aux_/session_impl.hpp +++ b/libtorrent/include/libtorrent/aux_/session_impl.hpp @@ -178,7 +178,9 @@ namespace libtorrent #endif friend struct checker_impl; friend class invariant_access; - typedef std::set > connection_map; + typedef std::map + , boost::intrusive_ptr > + connection_map; typedef std::map > torrent_map; session_impl( @@ -188,8 +190,7 @@ namespace libtorrent ~session_impl(); #ifndef TORRENT_DISABLE_EXTENSIONS - void add_extension(boost::function( - torrent*, void*)> ext); + void add_extension(boost::function(torrent*, void*)> ext); #endif void operator()(); @@ -213,7 +214,7 @@ namespace libtorrent peer_id const& get_peer_id() const { return m_peer_id; } void close_connection(boost::intrusive_ptr const& p); - void connection_failed(boost::intrusive_ptr const& p + void connection_failed(boost::shared_ptr const& s , tcp::endpoint const& a, char const* message); void set_settings(session_settings const& s); @@ -341,8 +342,8 @@ namespace libtorrent for (connection_map::const_iterator i = m_connections.begin() , end(m_connections.end()); i != end; ++i) { - send_buffer_capacity += (*i)->send_buffer_capacity(); - used_send_buffer += (*i)->send_buffer_size(); + send_buffer_capacity += i->second->send_buffer_capacity(); + used_send_buffer += i->second->send_buffer_size(); } TORRENT_ASSERT(send_buffer_capacity >= used_send_buffer); m_buffer_usage_logger << log_time() << " send_buffer_size: " << send_buffer_capacity << std::endl; @@ -374,6 +375,12 @@ namespace libtorrent // buffers from. boost::pool<> m_send_buffers; + // this is where all active sockets are stored. + // the selector can sleep while there's no activity on + // them + io_service m_io_service; + asio::strand m_strand; + // the file pool that all storages in this session's // torrents uses. It sets a limit on the number of // open files by this session. @@ -385,17 +392,9 @@ namespace libtorrent // handles disk io requests asynchronously // peers have pointers into the disk buffer // pool, and must be destructed before this - // object. The disk thread relies on the file - // pool object, and must be destructed before - // m_files. + // object. disk_io_thread m_disk_thread; - // this is where all active sockets are stored. - // the selector can sleep while there's no activity on - // them - io_service m_io_service; - asio::strand m_strand; - // this is a list of half-open tcp connections // (only outgoing connections) // this has to be one of the last @@ -647,7 +646,7 @@ namespace libtorrent void debug_log(const std::string& line) { - (*m_ses.m_logger) << time_now_string() << " " << line << "\n"; + (*m_ses.m_logger) << line << "\n"; } session_impl& m_ses; }; diff --git a/libtorrent/include/libtorrent/bencode.hpp b/libtorrent/include/libtorrent/bencode.hpp index 1d3f1ea2b..66da191ab 100755 --- a/libtorrent/include/libtorrent/bencode.hpp +++ b/libtorrent/include/libtorrent/bencode.hpp @@ -135,38 +135,26 @@ namespace libtorrent } template - std::string read_until(InIt& in, InIt end, char end_token, bool& err) + std::string read_until(InIt& in, InIt end, char end_token) { + if (in == end) throw invalid_encoding(); std::string ret; - if (in == end) - { - err = true; - return ret; - } while (*in != end_token) { ret += *in; ++in; - if (in == end) - { - err = true; - return ret; - } + if (in == end) throw invalid_encoding(); } return ret; } template - void read_string(InIt& in, InIt end, int len, std::string& str, bool& err) + void read_string(InIt& in, InIt end, int len, std::string& str) { TORRENT_ASSERT(len >= 0); for (int i = 0; i < len; ++i) { - if (in == end) - { - err = true; - return; - } + if (in == end) throw invalid_encoding(); str += *in; ++in; } @@ -214,13 +202,9 @@ namespace libtorrent } template - void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err) + void bdecode_recursive(InIt& in, InIt end, entry& ret) { - if (in == end) - { - err = true; - return; - } + if (in == end) throw invalid_encoding(); switch (*in) { @@ -229,8 +213,7 @@ namespace libtorrent case 'i': { ++in; // 'i' - std::string val = read_until(in, end, 'e', err); - if (err) return; + std::string val = read_until(in, end, 'e'); TORRENT_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); @@ -247,13 +230,8 @@ namespace libtorrent { ret.list().push_back(entry()); entry& e = ret.list().back(); - bdecode_recursive(in, end, e, err); - if (err) return; - if (in == end) - { - err = true; - return; - } + bdecode_recursive(in, end, e); + if (in == end) throw invalid_encoding(); } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' @@ -268,16 +246,10 @@ namespace libtorrent while (*in != 'e') { entry key; - bdecode_recursive(in, end, key, err); - if (err) return; + bdecode_recursive(in, end, key); entry& e = ret[key.string()]; - bdecode_recursive(in, end, e, err); - if (err) return; - if (in == end) - { - err = true; - return; - } + bdecode_recursive(in, end, e); + if (in == end) throw invalid_encoding(); } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' @@ -288,19 +260,16 @@ namespace libtorrent default: if (isdigit((unsigned char)*in)) { - std::string len_s = read_until(in, end, ':', err); - if (err) return; + std::string len_s = read_until(in, end, ':'); TORRENT_ASSERT(*in == ':'); ++in; // ':' int len = std::atoi(len_s.c_str()); ret = entry(entry::string_t); - read_string(in, end, len, ret.string(), err); - if (err) return; + read_string(in, end, len, ret.string()); } else { - err = true; - return; + throw invalid_encoding(); } } } @@ -315,18 +284,16 @@ namespace libtorrent template entry bdecode(InIt start, InIt end) { - entry e; - bool err = false; - detail::bdecode_recursive(start, end, e, err); - if (err) + try { -#ifdef BOOST_NO_EXCEPTIONS - return entry(); -#else - throw invalid_encoding(); -#endif + entry e; + detail::bdecode_recursive(start, end, e); + return e; + } + catch(type_error&) + { + throw invalid_encoding(); } - return e; } } diff --git a/libtorrent/include/libtorrent/connection_queue.hpp b/libtorrent/include/libtorrent/connection_queue.hpp index c229ec217..b3b7cde86 100644 --- a/libtorrent/include/libtorrent/connection_queue.hpp +++ b/libtorrent/include/libtorrent/connection_queue.hpp @@ -56,7 +56,6 @@ public: void done(int ticket); void limit(int limit); int limit() const; - void close(); #ifndef NDEBUG diff --git a/libtorrent/include/libtorrent/entry.hpp b/libtorrent/include/libtorrent/entry.hpp index 1c25cc7c7..7fd6c8c53 100755 --- a/libtorrent/include/libtorrent/entry.hpp +++ b/libtorrent/include/libtorrent/entry.hpp @@ -161,10 +161,8 @@ namespace libtorrent // is a dictionary, otherwise they will throw entry& operator[](char const* key); entry& operator[](std::string const& key); -#ifndef BOOST_NO_EXCEPTIONS const entry& operator[](char const* key) const; const entry& operator[](std::string const& key) const; -#endif entry* find_key(char const* key); entry const* find_key(char const* key) const; @@ -223,80 +221,55 @@ namespace libtorrent copy(e); } - inline entry::integer_type& entry::integer() { if (m_type == undefined_t) construct(int_t); -#ifndef BOOST_NO_EXCEPTIONS if (m_type != int_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == int_t); return *reinterpret_cast(data); } inline entry::integer_type const& entry::integer() const { -#ifndef BOOST_NO_EXCEPTIONS if (m_type != int_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == int_t); return *reinterpret_cast(data); } inline entry::string_type& entry::string() { if (m_type == undefined_t) construct(string_t); -#ifndef BOOST_NO_EXCEPTIONS if (m_type != string_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == string_t); return *reinterpret_cast(data); } inline entry::string_type const& entry::string() const { -#ifndef BOOST_NO_EXCEPTIONS if (m_type != string_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == string_t); return *reinterpret_cast(data); } inline entry::list_type& entry::list() { if (m_type == undefined_t) construct(list_t); -#ifndef BOOST_NO_EXCEPTIONS if (m_type != list_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == list_t); return *reinterpret_cast(data); } inline entry::list_type const& entry::list() const { -#ifndef BOOST_NO_EXCEPTIONS if (m_type != list_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == list_t); return *reinterpret_cast(data); } inline entry::dictionary_type& entry::dict() { if (m_type == undefined_t) construct(dictionary_t); -#ifndef BOOST_NO_EXCEPTIONS if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == dictionary_t); return *reinterpret_cast(data); } inline entry::dictionary_type const& entry::dict() const { -#ifndef BOOST_NO_EXCEPTIONS if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); -#endif - TORRENT_ASSERT(m_type == dictionary_t); return *reinterpret_cast(data); } diff --git a/libtorrent/include/libtorrent/http_tracker_connection.hpp b/libtorrent/include/libtorrent/http_tracker_connection.hpp index c0057dfa1..5b618c876 100755 --- a/libtorrent/include/libtorrent/http_tracker_connection.hpp +++ b/libtorrent/include/libtorrent/http_tracker_connection.hpp @@ -130,8 +130,6 @@ namespace libtorrent , proxy_settings const& ps , std::string const& password = ""); - void close(); - private: boost::intrusive_ptr self() diff --git a/libtorrent/include/libtorrent/peer_connection.hpp b/libtorrent/include/libtorrent/peer_connection.hpp index 805b38d9d..e1581affe 100755 --- a/libtorrent/include/libtorrent/peer_connection.hpp +++ b/libtorrent/include/libtorrent/peer_connection.hpp @@ -367,12 +367,8 @@ namespace libtorrent return boost::optional(); } - // these functions are virtual to let bt_peer_connection hook into them - // and encrypt the content - virtual void send_buffer(char const* begin, int size); - virtual buffer::interval allocate_send_buffer(int size); - virtual void setup_send(); - + void send_buffer(char const* begin, int size); + buffer::interval allocate_send_buffer(int size); template void append_send_buffer(char* buffer, int size, Destructor const& destructor) { @@ -382,6 +378,7 @@ namespace libtorrent m_ses.log_buffer_usage(); #endif } + void setup_send(); #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES void set_country(char const* c) @@ -469,6 +466,9 @@ namespace libtorrent // the peer belongs to. aux::session_impl& m_ses; + boost::intrusive_ptr self() + { return boost::intrusive_ptr(this); } + // called from the main loop when this connection has any // work to do. void on_send_data(asio::error_code const& error diff --git a/libtorrent/include/libtorrent/policy.hpp b/libtorrent/include/libtorrent/policy.hpp index 95397b49e..c38bb426c 100755 --- a/libtorrent/include/libtorrent/policy.hpp +++ b/libtorrent/include/libtorrent/policy.hpp @@ -85,7 +85,6 @@ namespace libtorrent // the tracker, pex, lsd or dht. policy::peer* peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid , int source, char flags); - void update_peer_port(int port, policy::peer* p, int src); // called when an incoming connection is accepted void new_connection(peer_connection& c); @@ -220,8 +219,6 @@ namespace libtorrent typedef std::multimap::const_iterator const_iterator; iterator begin_peer() { return m_peers.begin(); } iterator end_peer() { return m_peers.end(); } - const_iterator begin_peer() const { return m_peers.begin(); } - const_iterator end_peer() const { return m_peers.end(); } bool connect_one_peer(); bool disconnect_one_peer(); diff --git a/libtorrent/include/libtorrent/storage.hpp b/libtorrent/include/libtorrent/storage.hpp index a3f97b589..8686f2afc 100755 --- a/libtorrent/include/libtorrent/storage.hpp +++ b/libtorrent/include/libtorrent/storage.hpp @@ -345,7 +345,7 @@ namespace libtorrent // used to move pieces while expanding // the storage from compact allocation // to full allocation - buffer m_scratch_buffer; + buffer m_scratch_buffer; buffer m_scratch_buffer2; // the piece that is in the scratch buffer int m_scratch_piece; diff --git a/libtorrent/include/libtorrent/torrent.hpp b/libtorrent/include/libtorrent/torrent.hpp index 99bbefb82..20779e6f5 100755 --- a/libtorrent/include/libtorrent/torrent.hpp +++ b/libtorrent/include/libtorrent/torrent.hpp @@ -171,7 +171,7 @@ namespace libtorrent boost::tuples::tuple bytes_done() const; size_type quantized_bytes_done() const; - void ip_filter_updated() { m_policy.ip_filter_updated(); } + void ip_filter_updated() { m_policy->ip_filter_updated(); } void pause(); void resume(); @@ -204,7 +204,7 @@ namespace libtorrent tcp::endpoint const& get_interface() const { return m_net_interface; } void connect_to_url_seed(std::string const& url); - bool connect_to_peer(policy::peer* peerinfo) throw(); + peer_connection* connect_to_peer(policy::peer* peerinfo); void set_ratio(float ratio) { TORRENT_ASSERT(ratio >= 0.0f); m_ratio = ratio; } @@ -276,12 +276,31 @@ namespace libtorrent bool want_more_peers() const; bool try_connect_peer(); + peer_connection* connection_for(tcp::endpoint const& a) + { + peer_iterator i = m_connections.find(a); + if (i == m_connections.end()) return 0; + return i->second; + } + +#ifndef NDEBUG + void connection_for(address const& a, std::vector& pc) + { + for (peer_iterator i = m_connections.begin() + , end(m_connections.end()); i != end; ++i) + { + if (i->first.address() == a) pc.push_back(i->second); + } + return; + } +#endif + // the number of peers that belong to this torrent int num_peers() const { return (int)m_connections.size(); } int num_seeds() const; - typedef std::set::iterator peer_iterator; - typedef std::set::const_iterator const_peer_iterator; + typedef std::map::iterator peer_iterator; + typedef std::map::const_iterator const_peer_iterator; const_peer_iterator begin() const { return m_connections.begin(); } const_peer_iterator end() const { return m_connections.end(); } @@ -476,7 +495,11 @@ namespace libtorrent { return m_picker.get() != 0; } - policy& get_policy() { return m_policy; } + policy& get_policy() + { + TORRENT_ASSERT(m_policy); + return *m_policy; + } piece_manager& filesystem(); torrent_info const& torrent_file() const { return *m_torrent_file; } @@ -527,7 +550,7 @@ namespace libtorrent // to the checker thread for initial checking // of the storage. void set_metadata(entry const&); - + private: void on_files_deleted(int ret, disk_io_job const& j); @@ -610,7 +633,7 @@ namespace libtorrent #ifndef NDEBUG public: #endif - std::set m_connections; + std::map m_connections; #ifndef NDEBUG private: #endif @@ -666,6 +689,8 @@ namespace libtorrent // ----------------------------- + boost::shared_ptr m_policy; + // a back reference to the session // this torrent belongs to. aux::session_impl& m_ses; @@ -777,8 +802,6 @@ namespace libtorrent // total_done - m_initial_done <= total_payload_download size_type m_initial_done; #endif - - policy m_policy; }; inline ptime torrent::next_announce() const diff --git a/libtorrent/include/libtorrent/tracker_manager.hpp b/libtorrent/include/libtorrent/tracker_manager.hpp index fdc3f6bbf..07c377a0f 100755 --- a/libtorrent/include/libtorrent/tracker_manager.hpp +++ b/libtorrent/include/libtorrent/tracker_manager.hpp @@ -184,7 +184,6 @@ namespace libtorrent typedef boost::mutex mutex_t; mutable mutex_t m_mutex; - bool m_abort; }; struct TORRENT_EXPORT tracker_connection @@ -203,7 +202,7 @@ namespace libtorrent void fail(int code, char const* msg); void fail_timeout(); - virtual void close(); + void close(); address const& bind_interface() const { return m_bind_interface; } protected: diff --git a/libtorrent/include/libtorrent/udp_tracker_connection.hpp b/libtorrent/include/libtorrent/udp_tracker_connection.hpp index 4fba505a4..e5eadc144 100755 --- a/libtorrent/include/libtorrent/udp_tracker_connection.hpp +++ b/libtorrent/include/libtorrent/udp_tracker_connection.hpp @@ -74,8 +74,6 @@ namespace libtorrent , boost::weak_ptr c , session_settings const& stn); - void close(); - private: enum action_t diff --git a/libtorrent/src/broadcast_socket.cpp b/libtorrent/src/broadcast_socket.cpp index a9d27eff4..01c6dd1c5 100644 --- a/libtorrent/src/broadcast_socket.cpp +++ b/libtorrent/src/broadcast_socket.cpp @@ -190,7 +190,7 @@ namespace libtorrent void broadcast_socket::close() { - m_on_receive.clear(); + m_on_receive.clear(); for (std::list::iterator i = m_sockets.begin() , end(m_sockets.end()); i != end; ++i) diff --git a/libtorrent/src/bt_peer_connection.cpp b/libtorrent/src/bt_peer_connection.cpp index d7b3226ec..0559aff95 100755 --- a/libtorrent/src/bt_peer_connection.cpp +++ b/libtorrent/src/bt_peer_connection.cpp @@ -582,8 +582,9 @@ namespace libtorrent { TORRENT_ASSERT(buf); TORRENT_ASSERT(size > 0); + TORRENT_ASSERT(!m_rc4_encrypted || m_encrypted); - if (m_encrypted && m_rc4_encrypted) + if (m_rc4_encrypted) m_RC4_handler->encrypt(buf, size); peer_connection::send_buffer(buf, size); @@ -591,7 +592,9 @@ namespace libtorrent buffer::interval bt_peer_connection::allocate_send_buffer(int size) { - if (m_encrypted && m_rc4_encrypted) + TORRENT_ASSERT(!m_rc4_encrypted || m_encrypted); + + if (m_rc4_encrypted) { TORRENT_ASSERT(m_enc_send_buffer.left() == 0); m_enc_send_buffer = peer_connection::allocate_send_buffer(size); @@ -606,7 +609,9 @@ namespace libtorrent void bt_peer_connection::setup_send() { - if (m_encrypted && m_rc4_encrypted && m_enc_send_buffer.left()) + TORRENT_ASSERT(!m_rc4_encrypted || m_encrypted); + + if (m_rc4_encrypted && m_enc_send_buffer.left()) { TORRENT_ASSERT(m_enc_send_buffer.begin); TORRENT_ASSERT(m_enc_send_buffer.end); @@ -1203,11 +1208,11 @@ namespace libtorrent // there is supposed to be a remote listen port if (entry* listen_port = root.find_key("p")) { - if (listen_port->type() == entry::int_t - && peer_info_struct() != 0) + if (listen_port->type() == entry::int_t) { - t->get_policy().update_peer_port(listen_port->integer() - , peer_info_struct(), peer_info::incoming); + tcp::endpoint adr(remote().address() + , (unsigned short)listen_port->integer()); + t->get_policy().peer_from_tracker(adr, pid(), peer_info::incoming, 0); } } // there should be a version too diff --git a/libtorrent/src/connection_queue.cpp b/libtorrent/src/connection_queue.cpp index a48456ed5..1caeb99fc 100644 --- a/libtorrent/src/connection_queue.cpp +++ b/libtorrent/src/connection_queue.cpp @@ -86,11 +86,6 @@ namespace libtorrent try_connect(); } - void connection_queue::close() - { - m_timer.cancel(); - } - void connection_queue::limit(int limit) { m_half_open_limit = limit; } @@ -116,14 +111,8 @@ namespace libtorrent { INVARIANT_CHECK; - if (!free_slots()) + if (!free_slots() || m_queue.empty()) return; - - if (m_queue.empty()) - { - m_timer.cancel(); - return; - } std::list::iterator i = std::find_if(m_queue.begin() , m_queue.end(), boost::bind(&entry::connecting, _1) == false); diff --git a/libtorrent/src/disk_io_thread.cpp b/libtorrent/src/disk_io_thread.cpp index a9446f664..ec5b8d8da 100644 --- a/libtorrent/src/disk_io_thread.cpp +++ b/libtorrent/src/disk_io_thread.cpp @@ -344,7 +344,6 @@ namespace libtorrent #ifndef NDEBUG m_current.storage = 0; - m_current.callback.clear(); #endif if (j.buffer && free_buffer) diff --git a/libtorrent/src/entry.cpp b/libtorrent/src/entry.cpp index 88800713c..50c6967cc 100755 --- a/libtorrent/src/entry.cpp +++ b/libtorrent/src/entry.cpp @@ -126,7 +126,6 @@ namespace libtorrent return &i->second; } -#ifndef BOOST_NO_EXCEPTIONS const entry& entry::operator[](char const* key) const { dictionary_type::const_iterator i = dict().find(key); @@ -139,7 +138,6 @@ namespace libtorrent { return (*this)[key.c_str()]; } -#endif entry::entry(dictionary_type const& v) { diff --git a/libtorrent/src/http_tracker_connection.cpp b/libtorrent/src/http_tracker_connection.cpp index ed9823b83..ccca58226 100755 --- a/libtorrent/src/http_tracker_connection.cpp +++ b/libtorrent/src/http_tracker_connection.cpp @@ -489,9 +489,7 @@ namespace libtorrent , boost::lexical_cast(m_port)); m_name_lookup.async_resolve(q, m_strand.wrap( boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2))); - set_timeout(req.event == tracker_request::stopped - ? m_settings.stop_tracker_timeout - : m_settings.tracker_completion_timeout + set_timeout(m_settings.tracker_completion_timeout , m_settings.tracker_receive_timeout); } @@ -505,23 +503,6 @@ namespace libtorrent fail_timeout(); } - void http_tracker_connection::close() - { - asio::error_code ec; - m_socket.close(ec); - m_name_lookup.cancel(); - if (m_connection_ticket > -1) m_cc.done(m_connection_ticket); - m_connection_ticket = -1; - m_timed_out = true; - tracker_connection::close(); -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - boost::shared_ptr cb = requester(); - std::stringstream msg; - msg << "http_tracker_connection::close() " << m_man.num_requests(); - if (cb) cb->debug_log(msg.str()); -#endif - } - void http_tracker_connection::name_lookup(asio::error_code const& error , tcp::resolver::iterator i) try { @@ -778,6 +759,7 @@ namespace libtorrent if (m_parser.status_code() != 200) { fail(m_parser.status_code(), m_parser.message().c_str()); + close(); return; } @@ -839,7 +821,6 @@ namespace libtorrent TORRENT_ASSERT(false); } #endif - close(); } peer_entry http_tracker_connection::extract_peer_info(const entry& info) diff --git a/libtorrent/src/metadata_transfer.cpp b/libtorrent/src/metadata_transfer.cpp index 50dc57ec7..e02a2d758 100644 --- a/libtorrent/src/metadata_transfer.cpp +++ b/libtorrent/src/metadata_transfer.cpp @@ -504,10 +504,11 @@ namespace libtorrent { namespace // extension and that has metadata int peers = 0; #ifndef TORRENT_DISABLE_EXTENSIONS - for (torrent::peer_iterator i = m_torrent.begin() + typedef std::map conn_map; + for (conn_map::iterator i = m_torrent.begin() , end(m_torrent.end()); i != end; ++i) { - bt_peer_connection* c = dynamic_cast(*i); + bt_peer_connection* c = dynamic_cast(i->second); if (c == 0) continue; metadata_peer_plugin* p = c->supports_extension(); diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index 9bd089234..5def3438d 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -390,6 +390,7 @@ namespace libtorrent TORRENT_ASSERT(m_peer_info->connection == 0); boost::shared_ptr t = m_torrent.lock(); + if (t) TORRENT_ASSERT(t->connection_for(remote()) != this); #endif } @@ -1393,7 +1394,7 @@ namespace libtorrent if (!t) { - m_ses.connection_failed(self(), remote(), j.str.c_str()); + m_ses.connection_failed(m_socket, remote(), j.str.c_str()); return; } @@ -1943,7 +1944,7 @@ namespace libtorrent (*m_ses.m_logger) << "CONNECTION TIMED OUT: " << m_remote.address().to_string() << "\n"; #endif - m_ses.connection_failed(self(), m_remote, "timed out"); + m_ses.connection_failed(m_socket, m_remote, "timed out"); } void peer_connection::disconnect() @@ -2289,7 +2290,7 @@ namespace libtorrent #ifdef TORRENT_VERBOSE_LOGGING (*m_logger) << "**ERROR**: " << e.what() << "\n"; #endif - m_ses.connection_failed(self(), remote(), e.what()); + m_ses.connection_failed(m_socket, remote(), e.what()); } } @@ -2339,7 +2340,7 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); if (!t) { - m_ses.connection_failed(self(), remote(), j.str.c_str()); + m_ses.connection_failed(m_socket, remote(), j.str.c_str()); return; } @@ -2675,7 +2676,7 @@ namespace libtorrent boost::shared_ptr t = m_torrent.lock(); if (!t) { - m_ses.connection_failed(self(), remote(), e.what()); + m_ses.connection_failed(m_socket, remote(), e.what()); return; } @@ -2690,14 +2691,14 @@ namespace libtorrent catch (std::exception& e) { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - m_ses.connection_failed(self(), remote(), e.what()); + m_ses.connection_failed(m_socket, remote(), e.what()); } catch (...) { // all exceptions should derive from std::exception TORRENT_ASSERT(false); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - m_ses.connection_failed(self(), remote(), "connection failed for unknown reason"); + m_ses.connection_failed(m_socket, remote(), "connection failed for unknown reason"); } bool peer_connection::can_write() const @@ -2778,7 +2779,7 @@ namespace libtorrent (*m_ses.m_logger) << "CONNECTION FAILED: " << m_remote.address().to_string() << ": " << e.message() << "\n"; #endif - m_ses.connection_failed(self(), m_remote, e.message().c_str()); + m_ses.connection_failed(m_socket, m_remote, e.message().c_str()); return; } @@ -2798,14 +2799,14 @@ namespace libtorrent catch (std::exception& ex) { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - m_ses.connection_failed(self(), remote(), ex.what()); + m_ses.connection_failed(m_socket, remote(), ex.what()); } catch (...) { // all exceptions should derive from std::exception TORRENT_ASSERT(false); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - m_ses.connection_failed(self(), remote(), "connection failed for unkown reason"); + m_ses.connection_failed(m_socket, remote(), "connection failed for unkown reason"); } // -------------------------- @@ -2855,14 +2856,14 @@ namespace libtorrent catch (std::exception& e) { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - m_ses.connection_failed(self(), remote(), e.what()); + m_ses.connection_failed(m_socket, remote(), e.what()); } catch (...) { // all exceptions should derive from std::exception TORRENT_ASSERT(false); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); - m_ses.connection_failed(self(), remote(), "connection failed for unknown reason"); + m_ses.connection_failed(m_socket, remote(), "connection failed for unknown reason"); } @@ -2879,18 +2880,26 @@ namespace libtorrent } boost::shared_ptr t = m_torrent.lock(); - if (!t) return; - - if (m_peer_info) + if (!t) { - policy::const_iterator i; - for (i = t->get_policy().begin_peer(); - i != t->get_policy().end_peer(); ++i) + typedef session_impl::torrent_map torrent_map; + torrent_map& m = m_ses.m_torrents; + for (torrent_map::iterator i = m.begin(), end(m.end()); i != end; ++i) { - if (&i->second == m_peer_info) break; + torrent& t = *i->second; + TORRENT_ASSERT(t.connection_for(m_remote) != this); } - TORRENT_ASSERT(i != t->get_policy().end_peer()); + return; } + + TORRENT_ASSERT(t->connection_for(remote()) != 0 || m_in_constructor); + + if (!m_in_constructor && t->connection_for(remote()) != this + && !m_ses.settings().allow_multiple_connections_per_ip) + { + TORRENT_ASSERT(false); + } + if (t->has_picker() && !t->is_aborted()) { // make sure that pieces that have completed the download diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index f203eaa56..4de01d055 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -82,13 +82,13 @@ namespace // want to trade it's surplus uploads for downloads itself // (and we should not consider it free). If the share diff is // negative, there's no free download to get from this peer. - size_type diff = (*i)->share_diff(); + size_type diff = i->second->share_diff(); TORRENT_ASSERT(diff < (std::numeric_limits::max)()); - if ((*i)->is_peer_interested() || diff <= 0) + if (i->second->is_peer_interested() || diff <= 0) continue; TORRENT_ASSERT(diff > 0); - (*i)->add_free_upload(-diff); + i->second->add_free_upload(-diff); accumulator += diff; TORRENT_ASSERT(accumulator > 0); } @@ -109,10 +109,10 @@ namespace size_type total_diff = 0; for (torrent::peer_iterator i = start; i != end; ++i) { - size_type d = (*i)->share_diff(); + size_type d = i->second->share_diff(); TORRENT_ASSERT(d < (std::numeric_limits::max)()); total_diff += d; - if (!(*i)->is_peer_interested() || (*i)->share_diff() >= 0) continue; + if (!i->second->is_peer_interested() || i->second->share_diff() >= 0) continue; ++num_peers; } @@ -130,7 +130,7 @@ namespace for (torrent::peer_iterator i = start; i != end; ++i) { - peer_connection* p = *i; + peer_connection* p = i->second; if (!p->is_peer_interested() || p->share_diff() >= 0) continue; p->add_free_upload(upload_share); free_upload -= upload_share; @@ -904,7 +904,7 @@ namespace libtorrent { TORRENT_ASSERT(!c.is_local()); -// INVARIANT_CHECK; + INVARIANT_CHECK; // if the connection comes from the tracker, // it's probably just a NAT-check. Ignore the @@ -932,11 +932,10 @@ namespace libtorrent if (m_torrent->settings().allow_multiple_connections_per_ip) { - tcp::endpoint remote = c.remote(); - std::pair range = m_peers.equal_range(remote.address()); - i = std::find_if(range.first, range.second, match_peer_endpoint(remote)); - - if (i == range.second) i = m_peers.end(); + i = std::find_if( + m_peers.begin() + , m_peers.end() + , match_peer_connection(c)); } else { @@ -978,6 +977,8 @@ namespace libtorrent i = m_peers.insert(std::make_pair(c.remote().address(), p)); } + TORRENT_ASSERT(m_torrent->connection_for(c.remote()) == &c); + c.set_peer_info(&i->second); TORRENT_ASSERT(i->second.connection == 0); c.add_stat(i->second.prev_amount_download, i->second.prev_amount_upload); @@ -990,38 +991,7 @@ namespace libtorrent // m_last_optimistic_disconnect = time_now(); } - void policy::update_peer_port(int port, policy::peer* p, int src) - { - TORRENT_ASSERT(p != 0); - if (p->ip.port() == port) return; - - if (m_torrent->settings().allow_multiple_connections_per_ip) - { - tcp::endpoint remote(p->ip.address(), port); - std::pair range = m_peers.equal_range(remote.address()); - iterator i = std::find_if(range.first, range.second - , match_peer_endpoint(remote)); - if (i != m_peers.end()) - { - policy::peer& pp = i->second; - if (pp.connection) - { - throw protocol_error("duplicate connection"); - } - if (m_torrent->has_picker()) - m_torrent->picker().clear_peer(&i->second); - m_peers.erase(i); - } - } - else - { - TORRENT_ASSERT(m_peers.count(p->ip.address()) == 1); - } - p->ip.port(port); - p->source |= src; - } - - policy::peer* policy::peer_from_tracker(tcp::endpoint const& remote, peer_id const& pid + policy::peer* policy::peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid , int src, char flags) { // too expensive @@ -1052,7 +1022,9 @@ namespace libtorrent { std::pair range = m_peers.equal_range(remote.address()); i = std::find_if(range.first, range.second, match_peer_endpoint(remote)); - if (i == range.second) i = m_peers.end(); + + if (i == range.second) + i = std::find_if(m_peers.begin(), m_peers.end(), match_peer_id(pid)); } else { @@ -1094,6 +1066,9 @@ namespace libtorrent { i->second.type = peer::connectable; + // in case we got the ip from a remote connection, port is + // not known, so save it. Client may also have changed port + // for some reason. i->second.ip = remote; i->second.source |= src; @@ -1306,7 +1281,10 @@ namespace libtorrent try { - if (!m_torrent->connect_to_peer(&p->second)) + p->second.connected = time_now(); + p->second.connection = m_torrent->connect_to_peer(&p->second); + TORRENT_ASSERT(p->second.connection == m_torrent->connection_for(p->second.ip)); + if (p->second.connection == 0) { ++p->second.failcount; return false; @@ -1418,7 +1396,6 @@ namespace libtorrent void policy::check_invariant() const { if (m_torrent->is_aborted()) return; - int connected_peers = 0; int total_connections = 0; @@ -1437,14 +1414,20 @@ namespace libtorrent { TORRENT_ASSERT(unique_test.count(p.ip) == 0); unique_test.insert(p.ip); - TORRENT_ASSERT(i->first == p.ip.address()); -// TORRENT_ASSERT(p.connection == 0 || p.ip == p.connection->remote()); } ++total_connections; if (!p.connection) { continue; } + if (!m_torrent->settings().allow_multiple_connections_per_ip) + { + std::vector conns; + m_torrent->connection_for(p.ip.address(), conns); + TORRENT_ASSERT(std::find_if(conns.begin(), conns.end() + , boost::bind(std::equal_to(), _1, p.connection)) + != conns.end()); + } if (p.optimistically_unchoked) { TORRENT_ASSERT(p.connection); @@ -1461,10 +1444,10 @@ namespace libtorrent for (torrent::const_peer_iterator i = m_torrent->begin(); i != m_torrent->end(); ++i) { - if ((*i)->is_disconnecting()) continue; + if (i->second->is_disconnecting()) continue; // ignore web_peer_connections since they are not managed // by the policy class - if (dynamic_cast(*i)) continue; + if (dynamic_cast(i->second)) continue; ++num_torrent_peers; } diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index 0828578f0..31403e083 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -547,8 +547,8 @@ namespace detail , fingerprint const& cl_fprint , char const* listen_interface) : m_send_buffers(send_buffer_size) - , m_files(40) , m_strand(m_io_service) + , m_files(40) , m_half_open(m_io_service) , m_download_channel(m_io_service, peer_connection::download_channel) , m_upload_channel(m_io_service, peer_connection::upload_channel) @@ -675,17 +675,6 @@ namespace detail if (m_dht) m_dht->stop(); #endif m_timer.cancel(); - - // close the listen sockets - for (std::list::iterator i = m_listen_sockets.begin() - , end(m_listen_sockets.end()); i != end; ++i) - { - i->sock->close(); - } - -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " aborting all torrents\n"; -#endif // abort all torrents for (torrent_map::iterator i = m_torrents.begin() , end(m_torrents.end()); i != end; ++i) @@ -693,65 +682,7 @@ namespace detail i->second->abort(); } -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " aborting all tracker requests\n"; -#endif - m_tracker_manager.abort_all_requests(); - -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " sending event=stopped to trackers\n"; - int counter = 0; -#endif - for (torrent_map::iterator i = m_torrents.begin(); - i != m_torrents.end(); ++i) - { - torrent& t = *i->second; - - if ((!t.is_paused() || t.should_request()) - && !t.trackers().empty()) - { -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - ++counter; -#endif - tracker_request req = t.generate_tracker_request(); - TORRENT_ASSERT(req.event == tracker_request::stopped); - req.listen_port = 0; - if (!m_listen_sockets.empty()) - req.listen_port = m_listen_sockets.front().external_port; - req.key = m_key; - std::string login = i->second->tracker_login(); -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - boost::shared_ptr tl(new tracker_logger(*this)); - m_tracker_loggers.push_back(tl); - m_tracker_manager.queue_request(m_strand, m_half_open, req, login - , m_listen_interface.address(), tl); -#else - m_tracker_manager.queue_request(m_strand, m_half_open, req, login - , m_listen_interface.address()); -#endif - } - } -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " sent " << counter << " tracker stop requests\n"; -#endif - -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " aborting all connections (" << m_connections.size() << ")\n"; -#endif - // abort all connections - while (!m_connections.empty()) - { -#ifndef NDEBUG - int conn = m_connections.size(); -#endif - (*m_connections.begin())->disconnect(); - TORRENT_ASSERT(conn == m_connections.size() + 1); - } - -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << time_now_string() << " shutting down connection queue\n"; -#endif - m_half_open.close(); + m_io_service.stop(); mutex::scoped_lock l2(m_checker_impl.m_mutex); // abort the checker thread @@ -1043,16 +974,16 @@ namespace detail m_alerts.post_alert(peer_blocked_alert(endp.address() , "incoming connection blocked by IP filter")); } - return; - } - - // don't allow more connections than the max setting - if (num_connections() > max_connections()) - { -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - (*m_logger) << "number of connections limit exceeded (conns: " - << num_connections() << ", limit: " << max_connections() - << "), connection rejected\n"; + return; + } + + // don't allow more connections than the max setting + if (m_connections.size() > max_connections()) + { +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << "number of connections limit exceeded (conns: " + << num_connections() << ", limit: " << max_connections() + << "), connection rejected\n"; #endif return; } @@ -1079,7 +1010,7 @@ namespace detail c->m_in_constructor = false; #endif - m_connections.insert(c); + m_connections.insert(std::make_pair(s, c)); } catch (std::exception& exc) { @@ -1088,7 +1019,7 @@ namespace detail #endif }; - void session_impl::connection_failed(boost::intrusive_ptr const& peer + void session_impl::connection_failed(boost::shared_ptr const& s , tcp::endpoint const& a, char const* message) #ifndef NDEBUG try @@ -1099,7 +1030,7 @@ namespace detail // too expensive // INVARIANT_CHECK; - connection_map::iterator p = m_connections.find(peer); + connection_map::iterator p = m_connections.find(s); // the connection may have been disconnected in the receive or send phase if (p == m_connections.end()) return; @@ -1108,15 +1039,15 @@ namespace detail m_alerts.post_alert( peer_error_alert( a - , (*p)->pid() + , p->second->pid() , message)); } #if defined(TORRENT_VERBOSE_LOGGING) - (*(*p)->m_logger) << "*** CONNECTION FAILED " << message << "\n"; + (*p->second->m_logger) << "*** CONNECTION FAILED " << message << "\n"; #endif - (*p)->set_failed(); - (*p)->disconnect(); + p->second->set_failed(); + p->second->disconnect(); } #ifndef NDEBUG catch (...) @@ -1133,10 +1064,10 @@ namespace detail // INVARIANT_CHECK; TORRENT_ASSERT(p->is_disconnecting()); - connection_map::iterator i = m_connections.find(p); + connection_map::iterator i = m_connections.find(p->get_socket()); if (i != m_connections.end()) { - if (!(*i)->is_choked()) --m_num_unchoked; + if (!i->second->is_choked()) --m_num_unchoked; m_connections.erase(i); } } @@ -1195,7 +1126,7 @@ namespace detail for (connection_map::iterator i = m_connections.begin() , end(m_connections.end()); i != end; ++i) { - if ((*i)->is_connecting()) + if (i->second->is_connecting()) ++num_half_open; else ++num_complete_connections; @@ -1283,7 +1214,7 @@ namespace detail ++i; // if this socket has timed out // close it. - peer_connection& c = *j->get(); + peer_connection& c = *j->second; if (c.has_timed_out()) { if (m_alerts.should_post(alert::debug)) @@ -1350,7 +1281,7 @@ namespace detail for (connection_map::iterator i = m_connections.begin() , end(m_connections.end()); i != end; ++i) { - peer_connection* p = i->get(); + peer_connection* p = i->second.get(); torrent* t = p->associated_torrent().lock().get(); if (!p->peer_info_struct() || t == 0 @@ -1360,7 +1291,7 @@ namespace detail || (p->share_diff() < -free_upload_amount && !t->is_seed())) { - if (!(*i)->is_choked() && t) + if (!i->second->is_choked() && t) { policy::peer* pi = p->peer_info_struct(); if (pi && pi->optimistically_unchoked) @@ -1369,11 +1300,11 @@ namespace detail // force a new optimistic unchoke m_optimistic_unchoke_time_scaler = 0; } - t->choke_peer(*(*i)); + t->choke_peer(*i->second); } continue; } - peers.push_back(i->get()); + peers.push_back(i->second.get()); } // sort the peers that are eligible for unchoke by download rate and secondary @@ -1445,7 +1376,7 @@ namespace detail for (connection_map::iterator i = m_connections.begin() , end(m_connections.end()); i != end; ++i) { - peer_connection* p = i->get(); + peer_connection* p = i->second.get(); TORRENT_ASSERT(p); policy::peer* pi = p->peer_info_struct(); if (!pi) continue; @@ -1476,21 +1407,21 @@ namespace detail { if (current_optimistic_unchoke != m_connections.end()) { - torrent* t = (*current_optimistic_unchoke)->associated_torrent().lock().get(); + torrent* t = current_optimistic_unchoke->second->associated_torrent().lock().get(); TORRENT_ASSERT(t); - (*current_optimistic_unchoke)->peer_info_struct()->optimistically_unchoked = false; - t->choke_peer(*current_optimistic_unchoke->get()); + current_optimistic_unchoke->second->peer_info_struct()->optimistically_unchoked = false; + t->choke_peer(*current_optimistic_unchoke->second); } else { ++m_num_unchoked; } - torrent* t = (*optimistic_unchoke_candidate)->associated_torrent().lock().get(); + torrent* t = optimistic_unchoke_candidate->second->associated_torrent().lock().get(); TORRENT_ASSERT(t); - bool ret = t->unchoke_peer(*optimistic_unchoke_candidate->get()); + bool ret = t->unchoke_peer(*optimistic_unchoke_candidate->second); TORRENT_ASSERT(ret); - (*optimistic_unchoke_candidate)->peer_info_struct()->optimistically_unchoked = true; + optimistic_unchoke_candidate->second->peer_info_struct()->optimistically_unchoked = true; } } } @@ -1553,11 +1484,96 @@ namespace detail } while (!m_abort); + deadline_timer tracker_timer(m_io_service); + // this will remove the port mappings + if (m_natpmp.get()) + m_natpmp->close(); + if (m_upnp.get()) + m_upnp->close(); + #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " locking mutex\n"; #endif session_impl::mutex_t::scoped_lock l(m_mutex); +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " aborting all tracker requests\n"; +#endif + m_tracker_manager.abort_all_requests(); +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " sending stopped to all torrent's trackers\n"; +#endif + for (std::map >::iterator i = + m_torrents.begin(); i != m_torrents.end(); ++i) + { + i->second->abort(); + // generate a tracker request in case the torrent is not paused + // (in which case it's not currently announced with the tracker) + // or if the torrent itself thinks we should request. Do not build + // a request in case the torrent doesn't have any trackers + if ((!i->second->is_paused() || i->second->should_request()) + && !i->second->trackers().empty()) + { + tracker_request req = i->second->generate_tracker_request(); + TORRENT_ASSERT(!m_listen_sockets.empty()); + req.listen_port = 0; + if (!m_listen_sockets.empty()) + req.listen_port = m_listen_sockets.front().external_port; + req.key = m_key; + std::string login = i->second->tracker_login(); +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + boost::shared_ptr tl(new tracker_logger(*this)); + m_tracker_loggers.push_back(tl); + m_tracker_manager.queue_request(m_strand, m_half_open, req, login + , m_listen_interface.address(), tl); +#else + m_tracker_manager.queue_request(m_strand, m_half_open, req, login + , m_listen_interface.address()); +#endif + } + } + + // close the listen sockets + m_listen_sockets.clear(); + + ptime start(time_now()); + l.unlock(); + +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " waiting for trackers to respond (" + << m_settings.stop_tracker_timeout << " seconds timeout)\n"; +#endif + + while (time_now() - start < seconds( + m_settings.stop_tracker_timeout) + && !m_tracker_manager.empty()) + { +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " " << m_tracker_manager.num_requests() + << " tracker requests pending\n"; +#endif + tracker_timer.expires_from_now(milliseconds(100)); + tracker_timer.async_wait(m_strand.wrap( + bind(&io_service::stop, &m_io_service))); + + m_io_service.reset(); + m_io_service.run(); + } + +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " tracker shutdown complete, locking mutex\n"; +#endif + + l.lock(); + TORRENT_ASSERT(m_abort); + m_abort = true; + +#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) + (*m_logger) << time_now_string() << " cleaning up connections\n"; +#endif + while (!m_connections.empty()) + m_connections.begin()->second->disconnect(); + #ifndef NDEBUG for (torrent_map::iterator i = m_torrents.begin(); i != m_torrents.end(); ++i) @@ -2085,8 +2101,8 @@ namespace detail entry session_impl::dht_state() const { + TORRENT_ASSERT(m_dht); mutex_t::scoped_lock l(m_mutex); - if (!m_dht) return entry(); return m_dht->state(); } @@ -2122,10 +2138,16 @@ namespace detail session_impl::~session_impl() { + abort(); + #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n"; #endif - abort(); + // lock the main thread and abort it + mutex_t::scoped_lock l(m_mutex); + m_abort = true; + m_io_service.stop(); + l.unlock(); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " waiting for main thread\n"; @@ -2366,20 +2388,19 @@ namespace detail for (connection_map::const_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - TORRENT_ASSERT(*i); - boost::shared_ptr t = (*i)->associated_torrent().lock(); + TORRENT_ASSERT(i->second); + boost::shared_ptr t = i->second->associated_torrent().lock(); - peer_connection* p = i->get(); - if (!p->is_choked()) ++unchokes; - if (p->peer_info_struct() - && p->peer_info_struct()->optimistically_unchoked) + if (!i->second->is_choked()) ++unchokes; + if (i->second->peer_info_struct() + && i->second->peer_info_struct()->optimistically_unchoked) { ++num_optimistic; - TORRENT_ASSERT(!p->is_choked()); + TORRENT_ASSERT(!i->second->is_choked()); } - if (t && p->peer_info_struct()) + if (t && i->second->peer_info_struct()) { - TORRENT_ASSERT(t->get_policy().has_connection(p)); + TORRENT_ASSERT(t->get_policy().has_connection(boost::get_pointer(i->second))); } } TORRENT_ASSERT(num_optimistic == 0 || num_optimistic == 1); diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 0468684f3..47fc6d408 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -1624,8 +1624,8 @@ namespace libtorrent if (m_current_slot == m_info->num_pieces()) { m_state = state_create_files; - buffer().swap(m_scratch_buffer); - buffer().swap(m_scratch_buffer2); + buffer().swap(m_scratch_buffer); + buffer().swap(m_scratch_buffer2); if (m_storage_mode != storage_mode_compact) { std::vector().swap(m_piece_to_slot); diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index c38111908..719f56853 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -116,11 +116,11 @@ namespace , tor(t) { TORRENT_ASSERT(t != 0); } - bool operator()(session_impl::connection_map::value_type const& c) const + bool operator()(const session_impl::connection_map::value_type& c) const { - tcp::endpoint const& sender = c->remote(); + tcp::endpoint sender = c.first->remote_endpoint(); if (sender.address() != ip.address()) return false; - if (tor != c->associated_torrent().lock().get()) return false; + if (tor != c.second->associated_torrent().lock().get()) return false; return true; } @@ -132,9 +132,9 @@ namespace { peer_by_id(const peer_id& i): pid(i) {} - bool operator()(session_impl::connection_map::value_type const& p) const + bool operator()(const std::pair& p) const { - if (p->pid() != pid) return false; + if (p.second->pid() != pid) return false; // have a special case for all zeros. We can have any number // of peers with that pid, since it's used to indicate no pid. if (std::count(pid.begin(), pid.end(), 0) == 20) return false; @@ -178,6 +178,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_DHT , m_last_dht_announce(time_now() - minutes(15)) #endif + , m_policy() , m_ses(ses) , m_checker(checker) , m_picker(0) @@ -202,8 +203,8 @@ namespace libtorrent , m_max_uploads((std::numeric_limits::max)()) , m_num_uploads(0) , m_max_connections((std::numeric_limits::max)()) - , m_policy(this) { + m_policy.reset(new policy(this)); } torrent::torrent( @@ -238,6 +239,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_DHT , m_last_dht_announce(time_now() - minutes(15)) #endif + , m_policy() , m_ses(ses) , m_checker(checker) , m_picker(0) @@ -261,7 +263,6 @@ namespace libtorrent , m_max_uploads((std::numeric_limits::max)()) , m_num_uploads(0) , m_max_connections((std::numeric_limits::max)()) - , m_policy(this) { INVARIANT_CHECK; @@ -272,6 +273,8 @@ namespace libtorrent m_trackers.push_back(announce_entry(tracker_url)); m_torrent_file->add_tracker(tracker_url); } + + m_policy.reset(new policy(this)); } void torrent::start() @@ -314,7 +317,7 @@ namespace libtorrent for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - (*(*i)->m_logger) << "*** DESTRUCTING TORRENT\n"; + (*i->second->m_logger) << "*** DESTRUCTING TORRENT\n"; } #endif @@ -563,7 +566,7 @@ namespace libtorrent continue; } - m_policy.peer_from_tracker(a, i->pid, peer_info::tracker, 0); + m_policy->peer_from_tracker(a, i->pid, peer_info::tracker, 0); } catch (std::exception&) { @@ -611,7 +614,7 @@ namespace libtorrent return; } - m_policy.peer_from_tracker(*host, pid, peer_info::tracker, 0); + m_policy->peer_from_tracker(*host, pid, peer_info::tracker, 0); } catch (std::exception&) {}; @@ -741,7 +744,7 @@ namespace libtorrent std::map downloading_piece; for (const_peer_iterator i = begin(); i != end(); ++i) { - peer_connection* pc = *i; + peer_connection* pc = i->second; boost::optional p = pc->downloading_piece_progress(); if (p) @@ -882,7 +885,7 @@ namespace libtorrent { #endif - m_policy.piece_finished(index, passed_hash_check); + m_policy->piece_finished(index, passed_hash_check); #ifndef NDEBUG } @@ -922,7 +925,7 @@ namespace libtorrent // resets the download queue. So, we cannot do the // invariant check here since it assumes: // (total_done == m_torrent_file->total_size()) => is_seed() - INVARIANT_CHECK; +// INVARIANT_CHECK; TORRENT_ASSERT(m_storage); TORRENT_ASSERT(m_storage->refcount() > 0); @@ -961,6 +964,17 @@ namespace libtorrent { policy::peer* p = static_cast(*i); if (p == 0) continue; +#ifndef NDEBUG + if (!settings().allow_multiple_connections_per_ip) + { + std::vector conns; + connection_for(p->ip.address(), conns); + TORRENT_ASSERT(p->connection == 0 + || std::find_if(conns.begin(), conns.end() + , boost::bind(std::equal_to(), _1, p->connection)) + != conns.end()); + } +#endif if (p->connection) p->connection->received_invalid_data(index); // either, we have received too many failed hashes @@ -1025,7 +1039,7 @@ namespace libtorrent for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - (*(*i)->m_logger) << "*** ABORTING TORRENT\n"; + (*i->second->m_logger) << "*** ABORTING TORRENT\n"; } #endif @@ -1094,7 +1108,7 @@ namespace libtorrent m_picker->we_have(index); for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) - try { (*i)->announce_piece(index); } catch (std::exception&) {} + try { i->second->announce_piece(index); } catch (std::exception&) {} for (std::set::iterator i = peers.begin() , end(peers.end()); i != end; ++i) @@ -1265,7 +1279,7 @@ namespace libtorrent void torrent::update_peer_interest() { for (peer_iterator i = begin(); i != end(); ++i) - (*i)->update_interest(); + i->second->update_interest(); } void torrent::filter_piece(int index, bool filter) @@ -1447,7 +1461,7 @@ namespace libtorrent for (peer_iterator i = m_connections.begin() , end(m_connections.end()); i != end; ++i) { - (*i)->cancel_request(block); + i->second->cancel_request(block); } } @@ -1457,7 +1471,7 @@ namespace libtorrent TORRENT_ASSERT(p != 0); - peer_iterator i = m_connections.find(p); + peer_iterator i = m_connections.find(p->remote()); if (i == m_connections.end()) { TORRENT_ASSERT(false); @@ -1495,9 +1509,8 @@ namespace libtorrent if (!p->is_choked()) --m_num_uploads; - m_policy.connection_closed(*p); + m_policy->connection_closed(*p); p->set_peer_info(0); - TORRENT_ASSERT(i != m_connections.end()); m_connections.erase(i); } catch (std::exception& e) @@ -1650,6 +1663,14 @@ namespace libtorrent return; } + peer_iterator conn = m_connections.find(a); + if (conn != m_connections.end()) + { + if (dynamic_cast(conn->second) == 0 + || conn->second->is_disconnecting()) conn->second->disconnect(); + else return; + } + boost::shared_ptr s(new socket_type); bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s); @@ -1681,8 +1702,10 @@ namespace libtorrent try { // add the newly connected peer to this torrent's peer list - m_connections.insert(boost::get_pointer(c)); - m_ses.m_connections.insert(c); + TORRENT_ASSERT(m_connections.find(a) == m_connections.end()); + m_connections.insert( + std::make_pair(a, boost::get_pointer(c))); + m_ses.m_connections.insert(std::make_pair(s, c)); m_ses.m_half_open.enqueue( bind(&peer_connection::connect, c, _1) @@ -1698,7 +1721,7 @@ namespace libtorrent // TODO: post an error alert! // std::map::iterator i = m_connections.find(a); // if (i != m_connections.end()) m_connections.erase(i); - m_ses.connection_failed(c, a, e.what()); + m_ses.connection_failed(s, a, e.what()); c->disconnect(); } } @@ -1843,19 +1866,19 @@ namespace libtorrent } #endif - bool torrent::connect_to_peer(policy::peer* peerinfo) throw() + peer_connection* torrent::connect_to_peer(policy::peer* peerinfo) { INVARIANT_CHECK; TORRENT_ASSERT(peerinfo); TORRENT_ASSERT(peerinfo->connection == 0); - peerinfo->connected = time_now(); #ifndef NDEBUG // this asserts that we don't have duplicates in the policy's peer list - peer_iterator i_ = std::find_if(m_connections.begin(), m_connections.end() - , bind(&peer_connection::remote, _1) == peerinfo->ip); + peer_iterator i_ = m_connections.find(peerinfo->ip); TORRENT_ASSERT(i_ == m_connections.end() - || dynamic_cast(*i_) == 0); + || i_->second->is_disconnecting() + || dynamic_cast(i_->second) == 0 + || m_ses.settings().allow_multiple_connections_per_ip); #endif TORRENT_ASSERT(want_more_peers()); @@ -1876,20 +1899,23 @@ namespace libtorrent c->m_in_constructor = false; #endif - try - { #ifndef TORRENT_DISABLE_EXTENSIONS - for (extension_list_t::iterator i = m_extensions.begin() - , end(m_extensions.end()); i != end; ++i) - { - boost::shared_ptr pp((*i)->new_connection(c.get())); - if (pp) c->add_extension(pp); - } + for (extension_list_t::iterator i = m_extensions.begin() + , end(m_extensions.end()); i != end; ++i) + { + boost::shared_ptr pp((*i)->new_connection(c.get())); + if (pp) c->add_extension(pp); + } #endif + try + { + TORRENT_ASSERT(m_connections.find(a) == m_connections.end()); + // add the newly connected peer to this torrent's peer list - m_connections.insert(boost::get_pointer(c)); - m_ses.m_connections.insert(c); + m_connections.insert( + std::make_pair(a, boost::get_pointer(c))); + m_ses.m_connections.insert(std::make_pair(s, c)); int timeout = settings().peer_connect_timeout; if (peerinfo) timeout += 3 * peerinfo->failcount; @@ -1901,15 +1927,16 @@ namespace libtorrent } catch (std::exception& e) { - std::set::iterator i - = m_connections.find(boost::get_pointer(c)); + TORRENT_ASSERT(false); + // TODO: post an error alert! + std::map::iterator i = m_connections.find(a); if (i != m_connections.end()) m_connections.erase(i); - m_ses.connection_failed(c, a, e.what()); + m_ses.connection_failed(s, a, e.what()); c->disconnect(); - return false; + throw; } - peerinfo->connection = c.get(); - return true; + if (c->is_disconnecting()) throw protocol_error("failed to connect"); + return c.get(); } void torrent::set_metadata(entry const& metadata) @@ -1953,7 +1980,25 @@ namespace libtorrent TORRENT_ASSERT(p != 0); TORRENT_ASSERT(!p->is_local()); - if (m_ses.m_connections.find(p) == m_ses.m_connections.end()) + std::map::iterator c + = m_connections.find(p->remote()); + if (c != m_connections.end()) + { + TORRENT_ASSERT(p != c->second); + // we already have a peer_connection to this ip. + // It may currently be waiting for completing a + // connection attempt that might fail. So, + // prioritize this current connection since + // it has already succeeded. + if (!c->second->is_connecting()) + { + throw protocol_error("already connected to peer"); + } + c->second->disconnect(); + } + + if (m_ses.m_connections.find(p->get_socket()) + == m_ses.m_connections.end()) { throw protocol_error("peer is not properly constructed"); } @@ -1963,8 +2008,9 @@ namespace libtorrent throw protocol_error("session is closing"); } - TORRENT_ASSERT(m_connections.find(p) == m_connections.end()); - peer_iterator ci = m_connections.insert(p).first; + TORRENT_ASSERT(m_connections.find(p->remote()) == m_connections.end()); + peer_iterator ci = m_connections.insert( + std::make_pair(p->remote(), p)).first; try { // if new_connection throws, we have to remove the @@ -1978,9 +2024,9 @@ namespace libtorrent if (pp) p->add_extension(pp); } #endif - TORRENT_ASSERT(m_connections.find(p) == ci); - TORRENT_ASSERT(*ci == p); - m_policy.new_connection(**ci); + TORRENT_ASSERT(connection_for(p->remote()) == p); + TORRENT_ASSERT(ci->second == p); + m_policy->new_connection(*ci->second); } catch (std::exception& e) { @@ -1990,7 +2036,7 @@ namespace libtorrent TORRENT_ASSERT(p->remote() == p->get_socket()->remote_endpoint()); #ifndef NDEBUG - m_policy.check_invariant(); + m_policy->check_invariant(); #endif } @@ -2009,19 +2055,19 @@ namespace libtorrent while (!m_connections.empty()) { - peer_connection* p = *m_connections.begin(); - TORRENT_ASSERT(p->associated_torrent().lock().get() == this); + peer_connection& p = *m_connections.begin()->second; + TORRENT_ASSERT(p.associated_torrent().lock().get() == this); #if defined(TORRENT_VERBOSE_LOGGING) if (m_abort) - (*p->m_logger) << "*** CLOSING CONNECTION 'aborting'\n"; + (*p.m_logger) << "*** CLOSING CONNECTION 'aborting'\n"; else - (*p->m_logger) << "*** CLOSING CONNECTION 'pausing'\n"; + (*p.m_logger) << "*** CLOSING CONNECTION 'pausing'\n"; #endif #ifndef NDEBUG std::size_t size = m_connections.size(); #endif - p->disconnect(); + p.disconnect(); TORRENT_ASSERT(m_connections.size() <= size); } } @@ -2112,14 +2158,13 @@ namespace libtorrent for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - peer_connection* p = *i; - TORRENT_ASSERT(p->associated_torrent().lock().get() == this); - if (p->is_seed()) + TORRENT_ASSERT(i->second->associated_torrent().lock().get() == this); + if (i->second->is_seed()) { #if defined(TORRENT_VERBOSE_LOGGING) - (*p->m_logger) << "*** SEED, CLOSING CONNECTION\n"; + (*i->second->m_logger) << "*** SEED, CLOSING CONNECTION\n"; #endif - seeds.push_back(p); + seeds.push_back(i->second); } } std::for_each(seeds.begin(), seeds.end() @@ -2320,21 +2365,23 @@ namespace libtorrent m_connections_initialized = true; // all peer connections have to initialize themselves now that the metadata // is available - for (torrent::peer_iterator i = m_connections.begin() + typedef std::map conn_map; + for (conn_map::iterator i = m_connections.begin() , end(m_connections.end()); i != end;) { try { - (*i)->on_metadata(); - (*i)->init(); + i->second->on_metadata(); + i->second->init(); ++i; } catch (std::exception& e) { // the connection failed, close it - torrent::peer_iterator j = i; + conn_map::iterator j = i; ++j; - m_ses.connection_failed(*i, (*i)->remote(), e.what()); + m_ses.connection_failed(i->second->get_socket() + , i->first, e.what()); i = j; } } @@ -2405,7 +2452,7 @@ namespace libtorrent std::map num_requests; for (const_peer_iterator i = begin(); i != end(); ++i) { - peer_connection const& p = *(*i); + peer_connection const& p = *i->second; for (std::deque::const_iterator i = p.request_queue().begin() , end(p.request_queue().end()); i != end; ++i) ++num_requests[*i]; @@ -2437,12 +2484,12 @@ namespace libtorrent TORRENT_ASSERT(m_abort || m_have_pieces.empty()); } - for (policy::const_iterator i = m_policy.begin_peer() - , end(m_policy.end_peer()); i != end; ++i) +/* for (policy::const_iterator i = m_policy->begin_peer() + , end(m_policy->end_peer()); i != end; ++i) { - TORRENT_ASSERT(i->second.ip.address() == i->first); + TORRENT_ASSERT(i->connection == const_cast(this)->connection_for(i->ip)); } - +*/ size_type total_done = quantized_bytes_done(); if (m_torrent_file->is_valid()) { @@ -2525,19 +2572,17 @@ namespace libtorrent void torrent::set_peer_upload_limit(tcp::endpoint ip, int limit) { TORRENT_ASSERT(limit >= -1); - peer_iterator i = std::find_if(m_connections.begin(), m_connections.end() - , bind(&peer_connection::remote, _1) == ip); - if (i == m_connections.end()) return; - (*i)->set_upload_limit(limit); + peer_connection* p = connection_for(ip); + if (p == 0) return; + p->set_upload_limit(limit); } void torrent::set_peer_download_limit(tcp::endpoint ip, int limit) { TORRENT_ASSERT(limit >= -1); - peer_iterator i = std::find_if(m_connections.begin(), m_connections.end() - , bind(&peer_connection::remote, _1) == ip); - if (i == m_connections.end()) return; - (*i)->set_download_limit(limit); + peer_connection* p = connection_for(ip); + if (p == 0) return; + p->set_download_limit(limit); } void torrent::set_upload_limit(int limit) @@ -2576,7 +2621,7 @@ namespace libtorrent for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - (*(*i)->m_logger) << "*** DELETING FILES IN TORRENT\n"; + (*i->second->m_logger) << "*** DELETING FILES IN TORRENT\n"; } #endif @@ -2611,7 +2656,7 @@ namespace libtorrent for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i) { - (*(*i)->m_logger) << "*** PAUSING TORRENT\n"; + (*i->second->m_logger) << "*** PAUSING TORRENT\n"; } #endif @@ -2685,7 +2730,7 @@ namespace libtorrent i != m_connections.end(); ++i) { web_peer_connection* p - = dynamic_cast(*i); + = dynamic_cast(i->second); if (!p) continue; web_seeds.insert(p->url()); } @@ -2708,7 +2753,7 @@ namespace libtorrent for (peer_iterator i = m_connections.begin(); i != m_connections.end();) { - peer_connection* p = *i; + peer_connection* p = i->second; ++i; m_stat += p->statistics(); // updates the peer connection's ul/dl bandwidth @@ -2733,14 +2778,14 @@ namespace libtorrent if (m_time_scaler <= 0) { m_time_scaler = 10; - m_policy.pulse(); + m_policy->pulse(); } } bool torrent::try_connect_peer() { TORRENT_ASSERT(want_more_peers()); - return m_policy.connect_one_peer(); + return m_policy->connect_one_peer(); } void torrent::async_verify_piece(int piece_index, boost::function const& f) @@ -2824,7 +2869,8 @@ namespace libtorrent torrent_status st; st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end(), - !boost::bind(&peer_connection::is_connecting, _1)); + !boost::bind(&peer_connection::is_connecting + , boost::bind(&std::map::value_type::second, _1))); st.storage_mode = m_storage_mode; @@ -2951,7 +2997,9 @@ namespace libtorrent INVARIANT_CHECK; return (int)std::count_if(m_connections.begin(), m_connections.end() - , boost::bind(&peer_connection::is_seed, _1)); + , boost::bind(&peer_connection::is_seed + , boost::bind(&std::map::value_type::second, _1))); } void torrent::tracker_request_timed_out( @@ -3007,7 +3055,7 @@ namespace libtorrent #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) void torrent::debug_log(const std::string& line) { - (*m_ses.m_logger) << time_now_string() << " " << line << "\n"; + (*m_ses.m_logger) << line << "\n"; } #endif diff --git a/libtorrent/src/torrent_handle.cpp b/libtorrent/src/torrent_handle.cpp index dd6dd3c21..9418d50e8 100755 --- a/libtorrent/src/torrent_handle.cpp +++ b/libtorrent/src/torrent_handle.cpp @@ -908,7 +908,7 @@ namespace libtorrent for (torrent::const_peer_iterator i = t->begin(); i != t->end(); ++i) { - peer_connection* peer = *i; + peer_connection* peer = i->second; // incoming peers that haven't finished the handshake should // not be included in this list diff --git a/libtorrent/src/tracker_manager.cpp b/libtorrent/src/tracker_manager.cpp index 82c5cc948..a9c0e2c2b 100755 --- a/libtorrent/src/tracker_manager.cpp +++ b/libtorrent/src/tracker_manager.cpp @@ -296,20 +296,18 @@ namespace libtorrent , m_timeout(str.io_service()) , m_completion_timeout(0) , m_read_timeout(0) - , m_abort(false) {} void timeout_handler::set_timeout(int completion_timeout, int read_timeout) { m_completion_timeout = completion_timeout; m_read_timeout = read_timeout; - m_start_time = m_read_time = time_now(); + m_start_time = time_now(); + m_read_time = time_now(); - if (m_abort) return; - - int timeout = (std::min)( - m_read_timeout, (std::min)(m_completion_timeout, m_read_timeout)); - m_timeout.expires_at(m_read_time + seconds(timeout)); + m_timeout.expires_at((std::min)( + m_read_time + seconds(m_read_timeout) + , m_start_time + seconds(m_completion_timeout))); m_timeout.async_wait(m_strand.wrap(bind( &timeout_handler::timeout_callback, self(), _1))); } @@ -321,7 +319,6 @@ namespace libtorrent void timeout_handler::cancel() { - m_abort = true; m_completion_timeout = 0; m_timeout.cancel(); } @@ -344,11 +341,9 @@ namespace libtorrent return; } - if (m_abort) return; - - int timeout = (std::min)( - m_read_timeout, (std::min)(m_completion_timeout, m_read_timeout)); - m_timeout.expires_at(m_read_time + seconds(timeout)); + m_timeout.expires_at((std::min)( + m_read_time + seconds(m_read_timeout) + , m_start_time + seconds(m_completion_timeout))); m_timeout.async_wait(m_strand.wrap( bind(&timeout_handler::timeout_callback, self(), _1))); } @@ -572,24 +567,24 @@ namespace libtorrent m_abort = true; tracker_connections_t keep_connections; - while (!m_connections.empty()) - { - boost::intrusive_ptr& c = m_connections.back(); - if (!c) - { - m_connections.pop_back(); - continue; - } + while (!m_connections.empty()) + { + boost::intrusive_ptr& c = m_connections.back(); + if (!c) + { + m_connections.pop_back(); + continue; + } tracker_request const& req = c->tracker_req(); if (req.event == tracker_request::stopped) - { - keep_connections.push_back(c); - m_connections.pop_back(); - continue; - } - // close will remove the entry from m_connections - // so no need to pop - c->close(); + { + keep_connections.push_back(c); + m_connections.pop_back(); + continue; + } + // close will remove the entry from m_connections + // so no need to pop + c->close(); } std::swap(m_connections, keep_connections); diff --git a/libtorrent/src/udp_tracker_connection.cpp b/libtorrent/src/udp_tracker_connection.cpp index 6d76988d3..dd2ff10a1 100755 --- a/libtorrent/src/udp_tracker_connection.cpp +++ b/libtorrent/src/udp_tracker_connection.cpp @@ -96,9 +96,7 @@ namespace libtorrent m_name_lookup.async_resolve(q , m_strand.wrap(boost::bind( &udp_tracker_connection::name_lookup, self(), _1, _2))); - set_timeout(req.event == tracker_request::stopped - ? m_settings.stop_tracker_timeout - : m_settings.tracker_completion_timeout + set_timeout(m_settings.tracker_completion_timeout , m_settings.tracker_receive_timeout); } @@ -158,20 +156,11 @@ namespace libtorrent void udp_tracker_connection::on_timeout() { - asio::error_code ec; - m_socket.close(ec); + m_socket.close(); m_name_lookup.cancel(); fail_timeout(); } - void udp_tracker_connection::close() - { - asio::error_code ec; - m_socket.close(ec); - m_name_lookup.cancel(); - tracker_connection::close(); - } - void udp_tracker_connection::send_udp_connect() { #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) @@ -479,7 +468,6 @@ namespace libtorrent , complete, incomplete); m_man.remove_request(this); - close(); return; } catch (std::exception& e) @@ -555,7 +543,6 @@ namespace libtorrent if (!cb) { m_man.remove_request(this); - close(); return; } @@ -564,7 +551,6 @@ namespace libtorrent , complete, incomplete); m_man.remove_request(this); - close(); } catch (std::exception& e) { diff --git a/libtorrent/src/ut_pex.cpp b/libtorrent/src/ut_pex.cpp index d1248637c..071407005 100644 --- a/libtorrent/src/ut_pex.cpp +++ b/libtorrent/src/ut_pex.cpp @@ -72,7 +72,7 @@ namespace libtorrent { namespace struct ut_pex_plugin: torrent_plugin { - ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(55) {} + ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(0) {} virtual boost::shared_ptr new_connection(peer_connection* pc); @@ -113,20 +113,18 @@ namespace libtorrent { namespace for (torrent::peer_iterator i = m_torrent.begin() , end(m_torrent.end()); i != end; ++i) { - peer_connection* peer = *i; - if (!send_peer(*peer)) continue; + if (!send_peer(*i->second)) continue; - tcp::endpoint const& remote = peer->remote(); - m_old_peers.insert(remote); + m_old_peers.insert(i->first); - std::set::iterator di = dropped.find(remote); + std::set::iterator di = dropped.find(i->first); if (di == dropped.end()) { // don't write too big of a package if (num_added >= max_peer_entries) break; // only send proper bittorrent peers - bt_peer_connection* p = dynamic_cast(peer); + bt_peer_connection* p = dynamic_cast(i->second); if (!p) continue; // no supported flags to set yet @@ -137,14 +135,14 @@ namespace libtorrent { namespace flags |= p->supports_encryption() ? 1 : 0; #endif // i->first was added since the last time - if (remote.address().is_v4()) + if (i->first.address().is_v4()) { - detail::write_endpoint(remote, pla_out); + detail::write_endpoint(i->first, pla_out); detail::write_uint8(flags, plf_out); } else { - detail::write_endpoint(remote, pla6_out); + detail::write_endpoint(i->first, pla6_out); detail::write_uint8(flags, plf6_out); } ++num_added; @@ -158,7 +156,7 @@ namespace libtorrent { namespace } for (std::set::const_iterator i = dropped.begin() - , end(dropped.end()); i != end; ++i) + , end(dropped.end());i != end; ++i) { if (i->address().is_v4()) detail::write_endpoint(*i, pld_out); @@ -185,7 +183,7 @@ namespace libtorrent { namespace : m_torrent(t) , m_pc(pc) , m_tp(tp) - , m_1_minute(55) + , m_1_minute(0) , m_message_index(0) , m_first_time(true) {} @@ -329,14 +327,13 @@ namespace libtorrent { namespace for (torrent::peer_iterator i = m_torrent.begin() , end(m_torrent.end()); i != end; ++i) { - peer_connection* peer = *i; - if (!send_peer(*peer)) continue; + if (!send_peer(*i->second)) continue; // don't write too big of a package if (num_added >= max_peer_entries) break; // only send proper bittorrent peers - bt_peer_connection* p = dynamic_cast(peer); + bt_peer_connection* p = dynamic_cast(i->second); if (!p) continue; // no supported flags to set yet @@ -346,16 +343,15 @@ namespace libtorrent { namespace #ifndef TORRENT_DISABLE_ENCRYPTION flags |= p->supports_encryption() ? 1 : 0; #endif - tcp::endpoint const& remote = peer->remote(); // i->first was added since the last time - if (remote.address().is_v4()) + if (i->first.address().is_v4()) { - detail::write_endpoint(remote, pla_out); + detail::write_endpoint(i->first, pla_out); detail::write_uint8(flags, plf_out); } else { - detail::write_endpoint(remote, pla6_out); + detail::write_endpoint(i->first, pla6_out); detail::write_uint8(flags, plf6_out); } ++num_added;