introduce mechanism for plugins to prevent libtorrent to disconnect peers for time-out reasons

This commit is contained in:
Arvid Norberg 2013-08-09 07:55:12 +00:00
parent d42e43f61d
commit 6a1e861a1d
3 changed files with 33 additions and 6 deletions

View File

@ -194,6 +194,10 @@ namespace libtorrent
virtual bool on_reject(peer_request const&) { return false; }
virtual bool on_suggest(int /*index*/) { return false; }
// called when libtorrent think this peer should be disconnected.
// if the plugin returns false, the peer will not be disconnected.
virtual bool can_disconnect(error_code const& ec) { return true; }
// called when an extended message is received. If returning true,
// the message is not processed by any other plugin and if false
// is returned the next plugin in the chain will receive it to

View File

@ -486,6 +486,7 @@ namespace libtorrent
void start_receive_piece(peer_request const& r);
void incoming_cancel(peer_request const& r);
bool can_disconnect(error_code const& ec);
void incoming_dht_port(int listen_port);
void incoming_reject_request(peer_request const& r);

View File

@ -1858,7 +1858,9 @@ namespace libtorrent
m_num_pieces = num_pieces;
if (interesting) t->get_policy().peer_is_interesting(*this);
else if (upload_only()) disconnect(errors::upload_upload_connection);
else if (upload_only()
&& can_disconnect(error_code(errors::upload_upload_connection, get_libtorrent_category())))
disconnect(errors::upload_upload_connection);
}
void peer_connection::disconnect_if_redundant()
@ -1881,6 +1883,7 @@ namespace libtorrent
if (m_upload_only && t->is_upload_only())
{
if (!can_disconnect(error_code(errors::upload_upload_connection, get_libtorrent_category()))) return;
disconnect(errors::upload_upload_connection);
return;
}
@ -1890,11 +1893,24 @@ namespace libtorrent
&& m_bitfield_received
&& t->are_files_checked())
{
if (!can_disconnect(error_code(errors::uninteresting_upload_peer, get_libtorrent_category()))) return;
disconnect(errors::uninteresting_upload_peer);
return;
}
}
bool peer_connection::can_disconnect(error_code const& ec)
{
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
{
if (!(*i)->can_disconnect(ec)) return false;
}
#endif
return true;
}
// -----------------------------
// ---------- REQUEST ----------
// -----------------------------
@ -2017,7 +2033,9 @@ namespace libtorrent
// disconnect peers that downloads more than foo times an allowed
// fast piece
if (m_choked && fast_idx != -1 && m_accept_fast_piece_cnt[fast_idx] >= 3 * blocks_per_piece)
if (m_choked && fast_idx != -1
&& m_accept_fast_piece_cnt[fast_idx] >= 3 * blocks_per_piece
&& can_disconnect(error_code(errors::too_many_requests_when_choked, get_libtorrent_category())))
{
disconnect(errors::too_many_requests_when_choked);
return;
@ -2039,7 +2057,8 @@ namespace libtorrent
// allow peers to send request up to 2 seconds after getting choked,
// the disconnect them
if (total_milliseconds(since_choked) > 2000)
if (total_milliseconds(since_choked) > 2000
&& can_disconnect(error_code(errors::too_many_requests_when_choked, get_libtorrent_category())))
{
disconnect(errors::too_many_requests_when_choked, 2);
return;
@ -4145,7 +4164,8 @@ namespace libtorrent
// the peer and disconnect it
bool may_timeout = (m_channel_state[download_channel] & peer_info::bw_network);
if (may_timeout && d > seconds(m_timeout) && !m_connecting)
if (may_timeout && d > seconds(m_timeout) && !m_connecting
&& can_disconnect(error_code(errors::timed_out_inactivity, get_libtorrent_category())))
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
peer_log("*** LAST ACTIVITY [ %d seconds ago ] ***", int(total_seconds(d)));
@ -4178,7 +4198,8 @@ namespace libtorrent
&& !m_choked
&& m_peer_interested
&& t && t->is_upload_only()
&& d > seconds(20))
&& d > seconds(20)
&& can_disconnect(error_code(errors::timed_out_no_request, get_libtorrent_category())))
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
peer_log("*** NO REQUEST [ waited %d seconds ] ***", int(total_seconds(d)));
@ -4206,7 +4227,8 @@ namespace libtorrent
&& d1 > time_limit
&& d2 > time_limit
&& (m_ses.num_connections() >= m_ses.settings().connections_limit
|| (t && t->num_peers() >= t->max_connections())))
|| (t && t->num_peers() >= t->max_connections()))
&& can_disconnect(error_code(errors::timed_out_no_interest, get_libtorrent_category())))
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
peer_log("*** MUTUAL NO INTEREST [ t1: %d t2: %d ]"