diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index d4167ef99..66ff276d1 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -364,7 +364,8 @@ namespace libtorrent void check_invariant(const char *place = 0); #endif #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) - boost::shared_ptr create_log(std::string const& name, int instance, bool append = true); + boost::shared_ptr create_log(std::string const& name + , int instance, bool append = true); // this list of tracker loggers serves as tracker_callbacks when // shutting down. This list is just here to keep them alive during diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 1358e2bdf..f1581d07c 100755 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -85,7 +85,6 @@ namespace libtorrent void peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid); // called when an incoming connection is accepted - // return false if the connection closed void new_connection(peer_connection& c); // this is called if a peer timed-out or diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index b826ff5e6..4f8a3bdf2 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -137,6 +137,8 @@ namespace libtorrent session_settings const& settings() const; + aux::session_impl& session() { return m_ses; } + void set_sequenced_download_threshold(int threshold); // is called every second by session. This will diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index ba2a8562a..33eb19827 100755 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1066,6 +1066,27 @@ namespace libtorrent setup_send(); } + namespace + { + struct match_peer_id + { + match_peer_id(peer_id const& id, peer_connection const* pc) + : m_id(id), m_pc(pc) + { assert(pc); } + + bool operator()(policy::peer const& p) const + { + return p.connection != m_pc + && p.connection + && p.connection->pid() == m_id + && !p.connection->pid().is_all_zeros(); + } + + peer_id m_id; + peer_connection const* m_pc; + }; + } + // -------------------------- // RECEIVE DATA // -------------------------- @@ -1150,7 +1171,6 @@ namespace libtorrent m_statistics.received_bytes(0, bytes_transferred); if (!packet_finished()) break; -// MassaRoddel #ifdef TORRENT_VERBOSE_LOGGING for (int i=0; i < 8; ++i) { @@ -1164,9 +1184,9 @@ namespace libtorrent if (recv_buffer[7] & 0x01) (*m_logger) << "supports DHT port message\n"; if (recv_buffer[7] & 0x02) - (*m_logger) << "supports XBT peer exchange message\n"; + (*m_logger) << "supports FAST extensions\n"; if (recv_buffer[5] & 0x10) - (*m_logger) << "supports LT/uT extensions\n"; + (*m_logger) << "supports extensions protocol\n"; #endif #ifndef DISABLE_EXTENSIONS @@ -1190,8 +1210,6 @@ namespace libtorrent t = associated_torrent().lock(); assert(t); - assert(t->get_policy().has_connection(this)); - // yes, we found the torrent // reply with our handshake write_handshake(); @@ -1211,12 +1229,7 @@ namespace libtorrent } } - - -#ifndef TORRENT_DISABLE_DHT - if (m_supports_dht_port && m_ses.m_dht) - write_dht_port(m_ses.kad_settings().service_port); -#endif + assert(t->get_policy().has_connection(this)); m_state = read_peer_id; reset_recv_buffer(20); @@ -1252,7 +1265,40 @@ namespace libtorrent peer_id pid; std::copy(recv_buffer.begin, recv_buffer.begin + 20, (char*)pid.begin()); set_pid(pid); - + + if (t->settings().allow_multiple_connections_per_ip) + { + // now, let's see if this connection should be closed + policy& p = t->get_policy(); + policy::iterator i = std::find_if(p.begin_peer(), p.end_peer() + , match_peer_id(pid, this)); + if (i != p.end_peer()) + { + assert(i->connection->pid() == pid); + // we found another connection with the same peer-id + // which connection should be closed in order to be + // sure that the other end closes the same connection? + // the peer with greatest peer-id is the one allowed to + // initiate connections. So, if our peer-id is greater than + // the others, we should close the incoming connection, + // if not, we should close the outgoing one. + if (pid < m_ses.get_peer_id() && is_local()) + { + i->connection->disconnect(); + } + else + { + throw protocol_error("duplicate peer-id, connection closed"); + } + } + + } + +#ifndef TORRENT_DISABLE_DHT + if (m_supports_dht_port && m_ses.m_dht) + write_dht_port(m_ses.kad_settings().service_port); +#endif + m_client_version = identify_client(pid); boost::optional f = client_fingerprint(pid); if (f && std::equal(f->name, f->name + 2, "BC")) diff --git a/src/policy.cpp b/src/policy.cpp index a00abddf2..2b7a5713c 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -335,18 +335,6 @@ namespace tcp::endpoint m_ip; }; - struct match_peer_id - { - match_peer_id(peer_id const& id) - : m_id(id) - {} - - bool operator()(policy::peer const& p) const - { return p.connection && p.connection->pid() == m_id; } - - peer_id m_id; - }; - struct match_peer_connection { match_peer_connection(peer_connection const& c) @@ -912,17 +900,7 @@ namespace libtorrent if (m_torrent->settings().allow_multiple_connections_per_ip) { - if (c.pid().is_all_zeros()) - { - i = m_peers.end(); - } - else - { - i = std::find_if( - m_peers.begin() - , m_peers.end() - , match_peer_id(c.pid())); - } + i = m_peers.end(); } else { @@ -939,6 +917,7 @@ namespace libtorrent if (i->connection != 0) { + assert(i->connection != &c); // the new connection is a local (outgoing) connection // or the current one is already connected if (!i->connection->is_connecting() || c.is_local()) @@ -953,7 +932,7 @@ namespace libtorrent "connection in favour of this one"); #endif i->connection->disconnect(); - i->connection = 0; + i->connection = &c; } } } @@ -996,17 +975,7 @@ namespace libtorrent if (m_torrent->settings().allow_multiple_connections_per_ip) { - if (pid.is_all_zeros()) - { - i = m_peers.end(); - } - else - { - i = std::find_if( - m_peers.begin() - , m_peers.end() - , match_peer_id(pid)); - } + i = m_peers.end(); } else { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 2026e4b37..8c4cfa478 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -464,7 +464,10 @@ namespace libtorrent { namespace detail struct seed_random_generator { seed_random_generator() - { std::srand((unsigned int)std::time(0)); } + { + std::srand((unsigned int)boost::posix_time::microsec_clock:: + universal_time().time_of_day().total_microseconds()); + } }; session_impl::session_impl( diff --git a/src/torrent.cpp b/src/torrent.cpp index 3577b6c91..6e1324075 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1921,8 +1921,8 @@ namespace libtorrent int dl_to_distribute = std::max(int((m_dl_bandwidth_quota.given - m_excess_dl * 0.7f) * 1.6f), 0); - m_soft_ul_limit = m_soft_ul_limit + (ul_to_distribute - m_soft_ul_limit) * 0.1f; - m_soft_dl_limit = m_soft_dl_limit + (dl_to_distribute - m_soft_dl_limit) * 0.1f; + m_soft_ul_limit = int(m_soft_ul_limit + (ul_to_distribute - m_soft_ul_limit) * 0.1f); + m_soft_dl_limit = int(m_soft_dl_limit + (dl_to_distribute - m_soft_dl_limit) * 0.1f); ul_to_distribute = m_soft_ul_limit; dl_to_distribute = m_soft_dl_limit;