fixed bug in connect candidate counter

This commit is contained in:
Arvid Norberg 2009-06-18 16:16:41 +00:00
parent b8f17f34e3
commit 6b048dc85e
7 changed files with 63 additions and 11 deletions

View File

@ -62,6 +62,7 @@ release 0.14.5
* fixed bug when setting unlimited upload or download rates for torrents * fixed bug when setting unlimited upload or download rates for torrents
* fix to make torrent_status::list_peers more accurate. * fix to make torrent_status::list_peers more accurate.
* fixed memory leak in disk io thread when not using the cache * fixed memory leak in disk io thread when not using the cache
* fixed bug in connect candidate counter
release 0.14.4 release 0.14.4

View File

@ -88,6 +88,8 @@ namespace libtorrent
// the given connection was just closed // the given connection was just closed
void connection_closed(const peer_connection& c, int session_time); void connection_closed(const peer_connection& c, int session_time);
void ban_peer(policy::peer* p);
// the peer has got at least one interesting piece // the peer has got at least one interesting piece
void peer_is_interesting(peer_connection& c); void peer_is_interesting(peer_connection& c);

View File

@ -4247,7 +4247,8 @@ namespace libtorrent
{ {
// if the remote endpoint is the same as the local endpoint, we're connected // if the remote endpoint is the same as the local endpoint, we're connected
// to ourselves // to ourselves
if (m_peer_info) m_peer_info->banned = true; boost::shared_ptr<torrent> t = m_torrent.lock();
if (m_peer_info && t) t->get_policy().ban_peer(m_peer_info);
disconnect(error_code(errors::self_connection, libtorrent_category), 1); disconnect(error_code(errors::self_connection, libtorrent_category), 1);
return; return;
} }

View File

@ -408,7 +408,10 @@ namespace libtorrent
m_torrent->picker().clear_peer(*i); m_torrent->picker().clear_peer(*i);
if ((*i)->seed) --m_num_seeds; if ((*i)->seed) --m_num_seeds;
if (is_connect_candidate(**i, m_finished)) if (is_connect_candidate(**i, m_finished))
{
TORRENT_ASSERT(m_num_connect_candidates > 0);
--m_num_connect_candidates; --m_num_connect_candidates;
}
if (m_round_robin > i - m_peers.begin()) --m_round_robin; if (m_round_robin > i - m_peers.begin()) --m_round_robin;
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
@ -488,6 +491,16 @@ namespace libtorrent
erase_peer(m_peers.begin() + erase_candidate); erase_peer(m_peers.begin() + erase_candidate);
} }
void policy::ban_peer(policy::peer* p)
{
INVARIANT_CHECK;
if (is_connect_candidate(*p, m_finished))
--m_num_connect_candidates;
p->banned = true;
}
bool policy::is_connect_candidate(peer const& p, bool finished) const bool policy::is_connect_candidate(peer const& p, bool finished) const
{ {
if (p.connection if (p.connection
@ -714,6 +727,8 @@ namespace libtorrent
if (iter != m_peers.end() && (*iter)->address() == c.remote().address()) found = true; if (iter != m_peers.end() && (*iter)->address() == c.remote().address()) found = true;
} }
bool was_conn_cand = false;
if (found) if (found)
{ {
i = *iter; i = *iter;
@ -724,6 +739,8 @@ namespace libtorrent
return false; return false;
} }
was_conn_cand = is_connect_candidate(*i, m_finished);
if (i->connection != 0) if (i->connection != 0)
{ {
boost::shared_ptr<socket_type> other_socket boost::shared_ptr<socket_type> other_socket
@ -772,9 +789,6 @@ namespace libtorrent
i->connection->disconnect(error_code(errors::duplicate_peer_id, libtorrent_category)); i->connection->disconnect(error_code(errors::duplicate_peer_id, libtorrent_category));
} }
} }
if (m_num_connect_candidates > 0)
--m_num_connect_candidates;
} }
else else
{ {
@ -836,6 +850,13 @@ namespace libtorrent
TORRENT_ASSERT(i->connection); TORRENT_ASSERT(i->connection);
if (!c.fast_reconnect()) if (!c.fast_reconnect())
i->last_connected = session_time; i->last_connected = session_time;
if (was_conn_cand != is_connect_candidate(*i, m_finished))
{
m_num_connect_candidates += was_conn_cand ? -1 : 1;
TORRENT_ASSERT(m_num_connect_candidates >= 0);
if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
}
return true; return true;
} }
@ -844,6 +865,8 @@ namespace libtorrent
TORRENT_ASSERT(p != 0); TORRENT_ASSERT(p != 0);
TORRENT_ASSERT(p->connection); TORRENT_ASSERT(p->connection);
INVARIANT_CHECK;
if (p->port == port) return true; if (p->port == port) return true;
if (m_torrent->settings().allow_multiple_connections_per_ip) if (m_torrent->settings().allow_multiple_connections_per_ip)
@ -857,7 +880,15 @@ namespace libtorrent
policy::peer& pp = **i; policy::peer& pp = **i;
if (pp.connection) if (pp.connection)
{ {
bool was_conn_cand = is_connect_candidate(pp, m_finished);
// if we already have an entry with this
// new endpoint, disconnect this one
pp.connectable = true;
pp.source |= src;
if (!was_conn_cand && is_connect_candidate(pp, m_finished))
++m_num_connect_candidates;
p->connection->disconnect(error_code(errors::duplicate_peer_id, libtorrent_category)); p->connection->disconnect(error_code(errors::duplicate_peer_id, libtorrent_category));
erase_peer(p);
return false; return false;
} }
erase_peer(i); erase_peer(i);
@ -879,6 +910,7 @@ namespace libtorrent
if (was_conn_cand != is_connect_candidate(*p, m_finished)) if (was_conn_cand != is_connect_candidate(*p, m_finished))
{ {
m_num_connect_candidates += was_conn_cand ? -1 : 1; m_num_connect_candidates += was_conn_cand ? -1 : 1;
TORRENT_ASSERT(m_num_connect_candidates >= 0);
if (m_num_connect_candidates < 0) m_num_connect_candidates = 0; if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
} }
return true; return true;
@ -899,7 +931,14 @@ namespace libtorrent
{ {
if (p == 0) return; if (p == 0) return;
if (p->seed == s) return; if (p->seed == s) return;
bool was_conn_cand = is_connect_candidate(*p, m_finished);
p->seed = s; p->seed = s;
if (was_conn_cand && !is_connect_candidate(*p, m_finished))
{
--m_num_connect_candidates;
if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
}
if (s) ++m_num_seeds; if (s) ++m_num_seeds;
else --m_num_seeds; else --m_num_seeds;
} }
@ -1220,6 +1259,8 @@ namespace libtorrent
{ {
// failcount is a 5 bit value // failcount is a 5 bit value
if (p.failcount < 31) ++p.failcount; if (p.failcount < 31) ++p.failcount;
if (!is_connect_candidate(p, m_finished))
--m_num_connect_candidates;
return false; return false;
} }
TORRENT_ASSERT(p.connection); TORRENT_ASSERT(p.connection);
@ -1308,10 +1349,12 @@ namespace libtorrent
void policy::recalculate_connect_candidates() void policy::recalculate_connect_candidates()
{ {
m_num_connect_candidates = 0; INVARIANT_CHECK;
const bool is_finished = m_torrent->is_finished(); const bool is_finished = m_torrent->is_finished();
if (is_finished == m_finished) return; if (is_finished == m_finished) return;
m_num_connect_candidates = 0;
m_finished = is_finished; m_finished = is_finished;
for (const_iterator i = m_peers.begin(); for (const_iterator i = m_peers.begin();
i != m_peers.end(); ++i) i != m_peers.end(); ++i)
@ -1346,6 +1389,7 @@ namespace libtorrent
int total_connections = 0; int total_connections = 0;
int nonempty_connections = 0; int nonempty_connections = 0;
int connect_candidates = 0;
std::set<tcp::endpoint> unique_test; std::set<tcp::endpoint> unique_test;
const_iterator prev = m_peers.end(); const_iterator prev = m_peers.end();
@ -1362,6 +1406,7 @@ namespace libtorrent
TORRENT_ASSERT((*prev)->address() < (*i)->address()); TORRENT_ASSERT((*prev)->address() < (*i)->address());
} }
peer const& p = **i; peer const& p = **i;
if (is_connect_candidate(p, m_finished)) ++connect_candidates;
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
TORRENT_ASSERT(p.inet_as == 0 || p.inet_as->first == p.inet_as_num); TORRENT_ASSERT(p.inet_as == 0 || p.inet_as->first == p.inet_as_num);
#endif #endif
@ -1395,6 +1440,8 @@ namespace libtorrent
++connected_peers; ++connected_peers;
} }
TORRENT_ASSERT(m_num_connect_candidates == connect_candidates);
int num_torrent_peers = 0; int num_torrent_peers = 0;
for (torrent::const_peer_iterator i = m_torrent->begin(); for (torrent::const_peer_iterator i = m_torrent->begin();
i != m_torrent->end(); ++i) i != m_torrent->end(); ++i)

View File

@ -609,6 +609,7 @@ namespace aux {
void session_impl::set_port_filter(port_filter const& f) void session_impl::set_port_filter(port_filter const& f)
{ {
m_port_filter = f; m_port_filter = f;
// TODO: recalculate all connect candidates for all torrents
} }
void session_impl::set_ip_filter(ip_filter const& f) void session_impl::set_ip_filter(ip_filter const& f)

View File

@ -213,7 +213,7 @@ namespace libtorrent { namespace
<< " | crc2: " << e.crc << " | crc2: " << e.crc
<< " | ip: " << p->ip() << " ]\n"; << " | ip: " << p->ip() << " ]\n";
#endif #endif
p->banned = true; m_torrent.get_policy().ban_peer(p);
if (p->connection) p->connection->disconnect( if (p->connection) p->connection->disconnect(
error_code(errors::peer_banned, libtorrent_category)); error_code(errors::peer_banned, libtorrent_category));
} }
@ -276,7 +276,7 @@ namespace libtorrent { namespace
<< " | bad_crc: " << b.second.crc << " | bad_crc: " << b.second.crc
<< " | ip: " << p->ip() << " ]\n"; << " | ip: " << p->ip() << " ]\n";
#endif #endif
p->banned = true; m_torrent.get_policy().ban_peer(p);
if (p->connection) p->connection->disconnect( if (p->connection) p->connection->disconnect(
error_code(errors::peer_banned, libtorrent_category)); error_code(errors::peer_banned, libtorrent_category));
} }

View File

@ -718,7 +718,7 @@ namespace libtorrent
{ {
policy::peer* p = m_policy.add_peer(read_v4_endpoint<tcp::endpoint>(ptr) policy::peer* p = m_policy.add_peer(read_v4_endpoint<tcp::endpoint>(ptr)
, id, peer_info::resume_data, 0); , id, peer_info::resume_data, 0);
if (p) p->banned = true; if (p) m_policy.ban_peer(p);
} }
} }
@ -742,7 +742,7 @@ namespace libtorrent
{ {
policy::peer* p = m_policy.add_peer(read_v6_endpoint<tcp::endpoint>(ptr) policy::peer* p = m_policy.add_peer(read_v6_endpoint<tcp::endpoint>(ptr)
, id, peer_info::resume_data, 0); , id, peer_info::resume_data, 0);
if (p) p->banned = true; if (p) m_policy.ban_peer(p);
} }
} }
#endif #endif
@ -778,7 +778,7 @@ namespace libtorrent
tcp::endpoint a(address::from_string(ip, ec), (unsigned short)port); tcp::endpoint a(address::from_string(ip, ec), (unsigned short)port);
if (ec) continue; if (ec) continue;
policy::peer* p = m_policy.add_peer(a, id, peer_info::resume_data, 0); policy::peer* p = m_policy.add_peer(a, id, peer_info::resume_data, 0);
if (p) p->banned = true; if (p) m_policy.ban_peer(p);
} }
} }
} }
@ -1916,7 +1916,7 @@ namespace libtorrent
} }
// mark the peer as banned // mark the peer as banned
p->banned = true; m_policy.ban_peer(p);
if (p->connection) if (p->connection)
{ {