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:
Arvid Norberg 2009-03-12 17:06:41 +00:00
parent 59fa30400f
commit 0de21dc815
5 changed files with 40 additions and 3 deletions

View File

@ -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;
bool lock_disk_cache;
int max_rejects;
};
``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
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
===========

View File

@ -820,6 +820,14 @@ namespace libtorrent
// at the remote end.
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
// timestamp is not updated when the connection
// is closed. This means the time until we can

View File

@ -159,6 +159,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_MLOCK
, lock_disk_cache(true)
#endif
, max_rejects(50)
{}
// this is the user agent that will be sent to the tracker
@ -523,6 +524,10 @@ namespace libtorrent
// be swapped out
bool lock_disk_cache;
#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

View File

@ -117,6 +117,7 @@ namespace libtorrent
, m_rtt(0)
, m_prefer_whole_pieces(0)
, m_desired_queue_size(2)
, m_choke_rejects(0)
, m_fast_reconnect(false)
, m_active(true)
, m_peer_interested(false)
@ -228,6 +229,7 @@ namespace libtorrent
, m_rtt(0)
, m_prefer_whole_pieces(0)
, m_desired_queue_size(2)
, m_choke_rejects(0)
, m_fast_reconnect(false)
, m_active(false)
, m_peer_interested(false)
@ -1166,7 +1168,7 @@ namespace libtorrent
#endif
m_peer_interested = true;
if (is_disconnecting()) return;
if (ignore_unchoke_slots()) write_unchoke();
if (ignore_unchoke_slots()) send_unchoke();
t->get_policy().interested(*this);
}
@ -1209,7 +1211,7 @@ namespace libtorrent
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);
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())
{
write_reject_request(r);
++m_choke_rejects;
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
(*m_logger) << time_now_string()
<< " *** REJECTING REQUEST [ peer choked and piece not in allowed fast set ]\n";
@ -1620,9 +1623,22 @@ namespace libtorrent
"s: " << r.start << " | "
"l: " << r.length << " ]\n";
#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
{
m_choke_rejects = 0;
m_requests.push_back(r);
m_last_incoming_request = time_now();
fill_send_buffer();
@ -2437,6 +2453,7 @@ namespace libtorrent
boost::shared_ptr<torrent> t = m_torrent.lock();
TORRENT_ASSERT(t);
if (has_peer_choked()) return;
if ((int)m_download_queue.size() >= m_desired_queue_size) return;
bool empty_download_queue = m_download_queue.empty();

View File

@ -884,7 +884,7 @@ namespace libtorrent
&& ses.num_uploads() < ses.max_uploads()
&& !c.ignore_unchoke_slots()
&& (m_torrent->ratio() == 0
|| c.share_diff() >= -free_upload_amount
|| c.share_diff() >= size_type(-free_upload_amount)
|| m_torrent->is_finished()))
{
ses.unchoke_peer(c);