choke dishonest peer in anti-leech seeding algorithm (#3833)

support peers not sending redundant HAVE messages in anti-leech seeding algorithm
This commit is contained in:
Monson Shao 2019-06-10 14:53:16 +08:00 committed by Arvid Norberg
parent f9d31cf71b
commit 186371f1a2
1 changed files with 18 additions and 17 deletions

View File

@ -136,18 +136,8 @@ namespace {
return lhs->time_of_last_unchoke() < rhs->time_of_last_unchoke();
}
// return true if 'lhs' peer should be preferred to be unchoke over 'rhs'
bool unchoke_compare_anti_leech(peer_connection const* lhs
, peer_connection const* rhs)
int anti_leech_score(peer_connection const* peer)
{
int const cmp = compare_peers(lhs, rhs);
if (cmp != 0) return cmp > 0;
std::shared_ptr<torrent> const t1 = lhs->associated_torrent().lock();
std::shared_ptr<torrent> const t2 = rhs->associated_torrent().lock();
TORRENT_ASSERT(t1);
TORRENT_ASSERT(t2);
// the anti-leech seeding algorithm is based on the paper "Improving
// BitTorrent: A Simple Approach" from Chow et. al. and ranks peers based
// on how many pieces they have, preferring to unchoke peers that just
@ -168,13 +158,24 @@ namespace {
// | V |
// +---------------------------+
// 0% num have pieces 100%
int const t1_total = t1->torrent_file().num_pieces();
int const t2_total = t2->torrent_file().num_pieces();
int const score1 = (lhs->num_have_pieces() < t1_total / 2
? t1_total - lhs->num_have_pieces() : lhs->num_have_pieces()) * 1000 / t1_total;
int const score2 = (rhs->num_have_pieces() < t2_total / 2
? t2_total - rhs->num_have_pieces() : rhs->num_have_pieces()) * 1000 / t2_total;
std::shared_ptr<torrent> const t = peer->associated_torrent().lock();
TORRENT_ASSERT(t);
std::int64_t const total_size = t->torrent_file().total_size();
std::int64_t const have_size = std::max(peer->statistics().total_payload_upload()
, std::int64_t(t->torrent_file().piece_length()) * peer->num_have_pieces());
return int(std::abs((have_size - total_size / 2) * 2000 / total_size));
}
// return true if 'lhs' peer should be preferred to be unchoke over 'rhs'
bool unchoke_compare_anti_leech(peer_connection const* lhs
, peer_connection const* rhs)
{
int const cmp = compare_peers(lhs, rhs);
if (cmp != 0) return cmp > 0;
int const score1 = anti_leech_score(lhs);
int const score2 = anti_leech_score(rhs);
if (score1 != score2) return score1 > score2;
// prioritize the one that has waited the longest to be unchoked