fixed bug related to ignoring upload slots and made the piece rejection code more robust to handle similar bugs better
This commit is contained in:
@@ -3303,6 +3303,8 @@ that will be sent to the tracker. The user-agent is a good way to identify your
|
|||||||
int max_sparse_regions;
|
int max_sparse_regions;
|
||||||
|
|
||||||
bool lock_disk_cache;
|
bool lock_disk_cache;
|
||||||
|
|
||||||
|
int max_rejects;
|
||||||
};
|
};
|
||||||
|
|
||||||
``user_agent`` this is the client identification to the tracker.
|
``user_agent`` this is the client identification to the tracker.
|
||||||
@@ -3638,6 +3640,11 @@ to 0 on all platforms except windows.
|
|||||||
that's in use, will be locked in physical memory, preventing it from
|
that's in use, will be locked in physical memory, preventing it from
|
||||||
being swapped out.
|
being swapped out.
|
||||||
|
|
||||||
|
``max_rejects`` is the number of piece requests we will reject in a row
|
||||||
|
while a peer is choked before the peer is considered abusive and is
|
||||||
|
disconnected.
|
||||||
|
|
||||||
|
|
||||||
pe_settings
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
@@ -820,6 +820,14 @@ namespace libtorrent
|
|||||||
// at the remote end.
|
// at the remote end.
|
||||||
boost::uint8_t m_desired_queue_size;
|
boost::uint8_t m_desired_queue_size;
|
||||||
|
|
||||||
|
// the number of piece requests we have rejected
|
||||||
|
// in a row because the peer is choked. This is
|
||||||
|
// used to re-send the choked message in case the
|
||||||
|
// other end keeps requesting pieces while being
|
||||||
|
// choked, and eventuelly disconnect if it keeps
|
||||||
|
// requesting too many pieces while being choked
|
||||||
|
boost::uint8_t m_choke_rejects;
|
||||||
|
|
||||||
// if this is true, the disconnection
|
// if this is true, the disconnection
|
||||||
// timestamp is not updated when the connection
|
// timestamp is not updated when the connection
|
||||||
// is closed. This means the time until we can
|
// is closed. This means the time until we can
|
||||||
|
@@ -159,6 +159,7 @@ namespace libtorrent
|
|||||||
#ifndef TORRENT_DISABLE_MLOCK
|
#ifndef TORRENT_DISABLE_MLOCK
|
||||||
, lock_disk_cache(true)
|
, lock_disk_cache(true)
|
||||||
#endif
|
#endif
|
||||||
|
, max_rejects(50)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// this is the user agent that will be sent to the tracker
|
// this is the user agent that will be sent to the tracker
|
||||||
@@ -523,6 +524,10 @@ namespace libtorrent
|
|||||||
// be swapped out
|
// be swapped out
|
||||||
bool lock_disk_cache;
|
bool lock_disk_cache;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// the number of times to reject requests while being
|
||||||
|
// choked before disconnecting a peer for being malicious
|
||||||
|
int max_rejects;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
@@ -117,6 +117,7 @@ namespace libtorrent
|
|||||||
, m_rtt(0)
|
, m_rtt(0)
|
||||||
, m_prefer_whole_pieces(0)
|
, m_prefer_whole_pieces(0)
|
||||||
, m_desired_queue_size(2)
|
, m_desired_queue_size(2)
|
||||||
|
, m_choke_rejects(0)
|
||||||
, m_fast_reconnect(false)
|
, m_fast_reconnect(false)
|
||||||
, m_active(true)
|
, m_active(true)
|
||||||
, m_peer_interested(false)
|
, m_peer_interested(false)
|
||||||
@@ -228,6 +229,7 @@ namespace libtorrent
|
|||||||
, m_rtt(0)
|
, m_rtt(0)
|
||||||
, m_prefer_whole_pieces(0)
|
, m_prefer_whole_pieces(0)
|
||||||
, m_desired_queue_size(2)
|
, m_desired_queue_size(2)
|
||||||
|
, m_choke_rejects(0)
|
||||||
, m_fast_reconnect(false)
|
, m_fast_reconnect(false)
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_peer_interested(false)
|
, m_peer_interested(false)
|
||||||
@@ -1166,7 +1168,7 @@ namespace libtorrent
|
|||||||
#endif
|
#endif
|
||||||
m_peer_interested = true;
|
m_peer_interested = true;
|
||||||
if (is_disconnecting()) return;
|
if (is_disconnecting()) return;
|
||||||
if (ignore_unchoke_slots()) write_unchoke();
|
if (ignore_unchoke_slots()) send_unchoke();
|
||||||
t->get_policy().interested(*this);
|
t->get_policy().interested(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1209,7 +1211,7 @@ namespace libtorrent
|
|||||||
m_ses.m_unchoke_time_scaler = 0;
|
m_ses.m_unchoke_time_scaler = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore_unchoke_slots()) write_choke();
|
if (ignore_unchoke_slots()) send_unchoke();
|
||||||
t->get_policy().not_interested(*this);
|
t->get_policy().not_interested(*this);
|
||||||
|
|
||||||
if (t->super_seeding() && m_superseed_piece != -1)
|
if (t->super_seeding() && m_superseed_piece != -1)
|
||||||
@@ -1611,6 +1613,7 @@ namespace libtorrent
|
|||||||
if (m_choked && m_accept_fast.find(r.piece) == m_accept_fast.end())
|
if (m_choked && m_accept_fast.find(r.piece) == m_accept_fast.end())
|
||||||
{
|
{
|
||||||
write_reject_request(r);
|
write_reject_request(r);
|
||||||
|
++m_choke_rejects;
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
(*m_logger) << time_now_string()
|
(*m_logger) << time_now_string()
|
||||||
<< " *** REJECTING REQUEST [ peer choked and piece not in allowed fast set ]\n";
|
<< " *** REJECTING REQUEST [ peer choked and piece not in allowed fast set ]\n";
|
||||||
@@ -1620,9 +1623,22 @@ namespace libtorrent
|
|||||||
"s: " << r.start << " | "
|
"s: " << r.start << " | "
|
||||||
"l: " << r.length << " ]\n";
|
"l: " << r.length << " ]\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (m_choke_rejects > m_ses.settings().max_rejects)
|
||||||
|
{
|
||||||
|
disconnect("too many piece requests while choked");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ((m_choke_rejects & 0xf) == 0)
|
||||||
|
{
|
||||||
|
// tell the peer it's choked again
|
||||||
|
// every 16 requests in a row
|
||||||
|
write_choke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_choke_rejects = 0;
|
||||||
m_requests.push_back(r);
|
m_requests.push_back(r);
|
||||||
m_last_incoming_request = time_now();
|
m_last_incoming_request = time_now();
|
||||||
fill_send_buffer();
|
fill_send_buffer();
|
||||||
@@ -2437,6 +2453,7 @@ namespace libtorrent
|
|||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
|
|
||||||
|
if (has_peer_choked()) return;
|
||||||
if ((int)m_download_queue.size() >= m_desired_queue_size) return;
|
if ((int)m_download_queue.size() >= m_desired_queue_size) return;
|
||||||
|
|
||||||
bool empty_download_queue = m_download_queue.empty();
|
bool empty_download_queue = m_download_queue.empty();
|
||||||
|
@@ -884,7 +884,7 @@ namespace libtorrent
|
|||||||
&& ses.num_uploads() < ses.max_uploads()
|
&& ses.num_uploads() < ses.max_uploads()
|
||||||
&& !c.ignore_unchoke_slots()
|
&& !c.ignore_unchoke_slots()
|
||||||
&& (m_torrent->ratio() == 0
|
&& (m_torrent->ratio() == 0
|
||||||
|| c.share_diff() >= -free_upload_amount
|
|| c.share_diff() >= size_type(-free_upload_amount)
|
||||||
|| m_torrent->is_finished()))
|
|| m_torrent->is_finished()))
|
||||||
{
|
{
|
||||||
ses.unchoke_peer(c);
|
ses.unchoke_peer(c);
|
||||||
|
Reference in New Issue
Block a user