improved support for multiple connections per ip

This commit is contained in:
Arvid Norberg 2006-11-30 11:56:19 +00:00
parent 982b69a8a7
commit 947df91b20
7 changed files with 72 additions and 52 deletions

View File

@ -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<logger> create_log(std::string const& name, int instance, bool append = true);
boost::shared_ptr<logger> 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

View File

@ -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

View File

@ -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

View File

@ -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<fingerprint> f = client_fingerprint(pid);
if (f && std::equal(f->name, f->name + 2, "BC"))

View File

@ -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
{

View File

@ -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(

View File

@ -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;