forked from premiere/premiere-libtorrent
merged peerlist fix from RC_0_16
This commit is contained in:
parent
b69014f3cd
commit
8ebe11067f
|
@ -5,6 +5,7 @@
|
||||||
* fix uTP edge case where udp socket buffer fills up
|
* fix uTP edge case where udp socket buffer fills up
|
||||||
* fix nagle implementation in uTP
|
* fix nagle implementation in uTP
|
||||||
|
|
||||||
|
* fix possible dangling pointer use in peer list
|
||||||
* fix support for storing arbitrary data in the DHT
|
* fix support for storing arbitrary data in the DHT
|
||||||
* fixed bug in uTP packet circle buffer
|
* fixed bug in uTP packet circle buffer
|
||||||
* fix potential crash when using torrent_handle::add_piece
|
* fix potential crash when using torrent_handle::add_piece
|
||||||
|
|
|
@ -446,6 +446,14 @@ namespace libtorrent
|
||||||
|
|
||||||
torrent* m_torrent;
|
torrent* m_torrent;
|
||||||
|
|
||||||
|
// this shouldbe NULL for the most part. It's set
|
||||||
|
// to point to a valid torrent_peer object if that
|
||||||
|
// object needs to be kept alive. If we ever feel
|
||||||
|
// like removing a torrent_peer from m_peers, we
|
||||||
|
// first check if the peer matches this one, and
|
||||||
|
// if so, don't delete it.
|
||||||
|
peer* m_locked_peer;
|
||||||
|
|
||||||
// since the peer list can grow too large
|
// since the peer list can grow too large
|
||||||
// to scan all of it, start at this iterator
|
// to scan all of it, start at this iterator
|
||||||
int m_round_robin;
|
int m_round_robin;
|
||||||
|
|
|
@ -345,6 +345,7 @@ namespace libtorrent
|
||||||
|
|
||||||
policy::policy(torrent* t)
|
policy::policy(torrent* t)
|
||||||
: m_torrent(t)
|
: m_torrent(t)
|
||||||
|
, m_locked_peer(NULL)
|
||||||
, m_round_robin(0)
|
, m_round_robin(0)
|
||||||
, m_num_connect_candidates(0)
|
, m_num_connect_candidates(0)
|
||||||
, m_num_seeds(0)
|
, m_num_seeds(0)
|
||||||
|
@ -366,6 +367,12 @@ namespace libtorrent
|
||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*i == m_locked_peer)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ses.m_alerts.should_post<peer_blocked_alert>())
|
if (ses.m_alerts.should_post<peer_blocked_alert>())
|
||||||
ses.m_alerts.post_alert(peer_blocked_alert(m_torrent->get_handle(), (*i)->address()));
|
ses.m_alerts.post_alert(peer_blocked_alert(m_torrent->get_handle(), (*i)->address()));
|
||||||
|
@ -418,6 +425,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(i != m_peers.end());
|
TORRENT_ASSERT(i != m_peers.end());
|
||||||
|
TORRENT_ASSERT(m_locked_peer != *i);
|
||||||
|
|
||||||
if (m_torrent->has_picker())
|
if (m_torrent->has_picker())
|
||||||
m_torrent->picker().clear_peer(*i);
|
m_torrent->picker().clear_peer(*i);
|
||||||
|
@ -468,12 +476,14 @@ namespace libtorrent
|
||||||
bool policy::should_erase_immediately(peer const& p) const
|
bool policy::should_erase_immediately(peer const& p) const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(p.in_use);
|
TORRENT_ASSERT(p.in_use);
|
||||||
|
if (&p == m_locked_peer) return false;
|
||||||
return p.source == peer_info::resume_data;
|
return p.source == peer_info::resume_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool policy::is_erase_candidate(peer const& pe, bool finished) const
|
bool policy::is_erase_candidate(peer const& pe, bool finished) const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(pe.in_use);
|
TORRENT_ASSERT(pe.in_use);
|
||||||
|
if (&pe == m_locked_peer) return false;
|
||||||
if (pe.connection) return false;
|
if (pe.connection) return false;
|
||||||
if (is_connect_candidate(pe, finished)) return false;
|
if (is_connect_candidate(pe, finished)) return false;
|
||||||
|
|
||||||
|
@ -484,6 +494,7 @@ namespace libtorrent
|
||||||
bool policy::is_force_erase_candidate(peer const& pe) const
|
bool policy::is_force_erase_candidate(peer const& pe) const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(pe.in_use);
|
TORRENT_ASSERT(pe.in_use);
|
||||||
|
if (&pe == m_locked_peer) return false;
|
||||||
return pe.connection == 0;
|
return pe.connection == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,7 +816,11 @@ namespace libtorrent
|
||||||
std::pair<iterator, iterator> range = find_peers(remote.address());
|
std::pair<iterator, iterator> range = find_peers(remote.address());
|
||||||
iter = std::find_if(range.first, range.second, match_peer_endpoint(remote));
|
iter = std::find_if(range.first, range.second, match_peer_endpoint(remote));
|
||||||
|
|
||||||
if (iter != range.second) found = true;
|
if (iter != range.second)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT((*iter)->in_use);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -814,7 +829,11 @@ namespace libtorrent
|
||||||
, c.remote().address(), peer_address_compare()
|
, c.remote().address(), peer_address_compare()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (iter != m_peers.end() && (*iter)->address() == c.remote().address()) found = true;
|
if (iter != m_peers.end() && (*iter)->address() == c.remote().address())
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT((*iter)->in_use);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the iterator we got is properly sorted relative
|
// make sure the iterator we got is properly sorted relative
|
||||||
|
@ -827,9 +846,9 @@ namespace libtorrent
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
i = *iter;
|
i = *iter;
|
||||||
|
TORRENT_ASSERT(i->in_use);
|
||||||
TORRENT_ASSERT(i->connection != &c);
|
TORRENT_ASSERT(i->connection != &c);
|
||||||
|
|
||||||
TORRENT_ASSERT(i->in_use);
|
|
||||||
if (i->banned)
|
if (i->banned)
|
||||||
{
|
{
|
||||||
c.disconnect(errors::peer_banned);
|
c.disconnect(errors::peer_banned);
|
||||||
|
@ -868,8 +887,11 @@ namespace libtorrent
|
||||||
// or the current one is already connected
|
// or the current one is already connected
|
||||||
if (ec2)
|
if (ec2)
|
||||||
{
|
{
|
||||||
|
TORRENT_ASSERT(m_locked_peer == NULL);
|
||||||
|
m_locked_peer = i;
|
||||||
i->connection->disconnect(ec2);
|
i->connection->disconnect(ec2);
|
||||||
TORRENT_ASSERT(i->connection == 0);
|
TORRENT_ASSERT(i->connection == 0);
|
||||||
|
m_locked_peer = NULL;
|
||||||
}
|
}
|
||||||
else if (i->connection->is_outgoing() == c.is_outgoing())
|
else if (i->connection->is_outgoing() == c.is_outgoing())
|
||||||
{
|
{
|
||||||
|
@ -913,7 +935,10 @@ namespace libtorrent
|
||||||
c.disconnect(errors::duplicate_peer_id);
|
c.disconnect(errors::duplicate_peer_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
TORRENT_ASSERT(m_locked_peer == NULL);
|
||||||
|
m_locked_peer = i;
|
||||||
i->connection->disconnect(errors::duplicate_peer_id);
|
i->connection->disconnect(errors::duplicate_peer_id);
|
||||||
|
m_locked_peer = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -929,7 +954,10 @@ namespace libtorrent
|
||||||
c.disconnect(errors::duplicate_peer_id);
|
c.disconnect(errors::duplicate_peer_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
TORRENT_ASSERT(m_locked_peer == NULL);
|
||||||
|
m_locked_peer = i;
|
||||||
i->connection->disconnect(errors::duplicate_peer_id);
|
i->connection->disconnect(errors::duplicate_peer_id);
|
||||||
|
m_locked_peer = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1110,10 @@ namespace libtorrent
|
||||||
// we need to make sure we don't let it do that, by unlinking
|
// we need to make sure we don't let it do that, by unlinking
|
||||||
// the peer_connection from the policy::peer first.
|
// the peer_connection from the policy::peer first.
|
||||||
p->connection->set_peer_info(0);
|
p->connection->set_peer_info(0);
|
||||||
|
TORRENT_ASSERT(m_locked_peer == NULL);
|
||||||
|
m_locked_peer = p;
|
||||||
p->connection->disconnect(errors::duplicate_peer_id);
|
p->connection->disconnect(errors::duplicate_peer_id);
|
||||||
|
m_locked_peer = NULL;
|
||||||
erase_peer(p);
|
erase_peer(p);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1550,7 +1581,8 @@ namespace libtorrent
|
||||||
// to avoid adding one entry for every single connection
|
// to avoid adding one entry for every single connection
|
||||||
// the peer makes to us, don't save this entry
|
// the peer makes to us, don't save this entry
|
||||||
if (m_torrent->settings().allow_multiple_connections_per_ip
|
if (m_torrent->settings().allow_multiple_connections_per_ip
|
||||||
&& !p->connectable)
|
&& !p->connectable
|
||||||
|
&& p != m_locked_peer)
|
||||||
{
|
{
|
||||||
erase_peer(p);
|
erase_peer(p);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue