fix issues introduced with connection ordering
This commit is contained in:
@@ -118,7 +118,9 @@ namespace libtorrent
|
|||||||
|
|
||||||
address external_ip::external_address(address const& ip) const
|
address external_ip::external_address(address const& ip) const
|
||||||
{
|
{
|
||||||
return m_vote_group[ip.is_v6()].external_address();
|
address ext = m_vote_group[ip.is_v6()].external_address();
|
||||||
|
if (ip.is_v6() && ext == address_v4()) return address_v6();
|
||||||
|
return ext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4830,11 +4830,27 @@ retry:
|
|||||||
return boost::weak_ptr<torrent>();
|
return boost::weak_ptr<torrent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if lhs is a better disconnect candidate than rhs
|
||||||
|
bool compare_disconnect_torrent(session_impl::torrent_map::value_type const& lhs
|
||||||
|
, session_impl::torrent_map::value_type const& rhs)
|
||||||
|
{
|
||||||
|
// a torrent with 0 peers is never a good disconnect candidate
|
||||||
|
// since there's nothing to disconnect
|
||||||
|
if ((lhs.second->num_peers() == 0) != (lhs.second->num_peers() == 0))
|
||||||
|
return lhs.second->num_peers() != 0;
|
||||||
|
|
||||||
|
// other than that, always prefer to disconnect peers from seeding torrents
|
||||||
|
// in order to not harm downloading ones
|
||||||
|
if (lhs.second->is_seed() != rhs.second->is_seed())
|
||||||
|
return lhs.second->is_seed();
|
||||||
|
|
||||||
|
return lhs.second->num_peers() > rhs.second->num_peers();
|
||||||
|
}
|
||||||
|
|
||||||
boost::weak_ptr<torrent> session_impl::find_disconnect_candidate_torrent()
|
boost::weak_ptr<torrent> session_impl::find_disconnect_candidate_torrent()
|
||||||
{
|
{
|
||||||
aux::session_impl::torrent_map::iterator i = std::max_element(m_torrents.begin(), m_torrents.end()
|
aux::session_impl::torrent_map::iterator i = std::min_element(m_torrents.begin(), m_torrents.end()
|
||||||
, boost::bind(&torrent::num_peers, boost::bind(&session_impl::torrent_map::value_type::second, _1))
|
, boost::bind(&compare_disconnect_torrent, _1, _2));
|
||||||
< boost::bind(&torrent::num_peers, boost::bind(&session_impl::torrent_map::value_type::second, _2)));
|
|
||||||
|
|
||||||
TORRENT_ASSERT(i != m_torrents.end());
|
TORRENT_ASSERT(i != m_torrents.end());
|
||||||
if (i == m_torrents.end()) return boost::shared_ptr<torrent>();
|
if (i == m_torrents.end()) return boost::shared_ptr<torrent>();
|
||||||
|
@@ -4328,7 +4328,8 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (ready_for_connections())
|
if (ready_for_connections())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
|
TORRENT_ASSERT(p->associated_torrent().lock().get() == NULL
|
||||||
|
|| p->associated_torrent().lock().get() == this);
|
||||||
|
|
||||||
if (p->is_seed())
|
if (p->is_seed())
|
||||||
{
|
{
|
||||||
@@ -5890,6 +5891,8 @@ namespace libtorrent
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool maybe_replace_peer = false;
|
||||||
|
|
||||||
if (m_connections.size() >= m_max_connections)
|
if (m_connections.size() >= m_max_connections)
|
||||||
{
|
{
|
||||||
// if more than 10% of the connections are outgoing
|
// if more than 10% of the connections are outgoing
|
||||||
@@ -5923,21 +5926,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// now, find the lowest rank peer and disconnect that
|
maybe_replace_peer = true;
|
||||||
// if it's lower rank than the incoming connection
|
|
||||||
peer_connection* peer = find_lowest_ranking_peer();
|
|
||||||
|
|
||||||
// TODO: if peer is a really good peer, maybe we shouldn't disconnect it
|
|
||||||
if (peer && peer->peer_rank() < p->peer_rank())
|
|
||||||
{
|
|
||||||
peer->disconnect(errors::too_many_connections);
|
|
||||||
p->peer_disconnected_other();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p->disconnect(errors::too_many_connections);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5979,6 +5968,34 @@ namespace libtorrent
|
|||||||
TORRENT_ASSERT(p->remote() == p->get_socket()->remote_endpoint(ec) || ec);
|
TORRENT_ASSERT(p->remote() == p->get_socket()->remote_endpoint(ec) || ec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TORRENT_ASSERT(p->peer_info_struct() != NULL);
|
||||||
|
|
||||||
|
// we need to do this after we've added the peer to the policy
|
||||||
|
// since that's when the peer is assigned its peer_info object,
|
||||||
|
// which holds the rank
|
||||||
|
if (maybe_replace_peer)
|
||||||
|
{
|
||||||
|
// now, find the lowest rank peer and disconnect that
|
||||||
|
// if it's lower rank than the incoming connection
|
||||||
|
peer_connection* peer = find_lowest_ranking_peer();
|
||||||
|
|
||||||
|
// TODO: if peer is a really good peer, maybe we shouldn't disconnect it
|
||||||
|
if (peer && peer->peer_rank() < p->peer_rank())
|
||||||
|
{
|
||||||
|
peer->disconnect(errors::too_many_connections);
|
||||||
|
p->peer_disconnected_other();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->disconnect(errors::too_many_connections);
|
||||||
|
// we have to do this here because from the peer's point of
|
||||||
|
// it wasn't really attached to the torrent, but we do need
|
||||||
|
// to let policy know we're removing it
|
||||||
|
remove_peer(p);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
||||||
m_policy.check_invariant();
|
m_policy.check_invariant();
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user