forked from premiere/premiere-libtorrent
make super-seeding a bit more robust
This commit is contained in:
parent
a7f1d7df91
commit
49f74be42f
|
@ -275,8 +275,12 @@ namespace libtorrent
|
||||||
|
|
||||||
// this will tell the peer to announce the given piece
|
// this will tell the peer to announce the given piece
|
||||||
// and only allow it to request that piece
|
// and only allow it to request that piece
|
||||||
void superseed_piece(int index);
|
void superseed_piece(int replace_piece, int new_piece);
|
||||||
int superseed_piece() const { return m_superseed_piece; }
|
bool super_seeded_piece(int index) const
|
||||||
|
{
|
||||||
|
return m_superseed_piece[0] == index
|
||||||
|
|| m_superseed_piece[1] == index;
|
||||||
|
}
|
||||||
|
|
||||||
// tells if this connection has data it want to send
|
// tells if this connection has data it want to send
|
||||||
// and has enough upload bandwidth quota left to send it.
|
// and has enough upload bandwidth quota left to send it.
|
||||||
|
@ -993,12 +997,12 @@ namespace libtorrent
|
||||||
// once the connection completes
|
// once the connection completes
|
||||||
int m_connection_ticket;
|
int m_connection_ticket;
|
||||||
|
|
||||||
// if this is -1, superseeding is not active. If it is >= 0
|
// if [0] is -1, superseeding is not active. If it is >= 0
|
||||||
// this is the piece that is available to this peer. Only
|
// this is the piece that is available to this peer. Only
|
||||||
// this piece can be downloaded from us by this peer.
|
// these two pieces can be downloaded from us by this peer.
|
||||||
// This will remain the current piece for this peer until
|
// This will remain the current piece for this peer until
|
||||||
// another peer sends us a have message for this piece
|
// another peer sends us a have message for this piece
|
||||||
int m_superseed_piece;
|
int m_superseed_piece[2];
|
||||||
|
|
||||||
// bytes downloaded since last second
|
// bytes downloaded since last second
|
||||||
// timer timeout; used for determining
|
// timer timeout; used for determining
|
||||||
|
|
|
@ -492,7 +492,10 @@ namespace libtorrent
|
||||||
void get_suggested_pieces(std::vector<int>& s) const;
|
void get_suggested_pieces(std::vector<int>& s) const;
|
||||||
|
|
||||||
bool super_seeding() const
|
bool super_seeding() const
|
||||||
{ return m_super_seeding; }
|
{
|
||||||
|
// we're not super seeding if we're not a seed
|
||||||
|
return m_super_seeding && is_seed();
|
||||||
|
}
|
||||||
|
|
||||||
void super_seeding(bool on);
|
void super_seeding(bool on);
|
||||||
int get_piece_to_super_seed(bitfield const&);
|
int get_piece_to_super_seed(bitfield const&);
|
||||||
|
|
|
@ -338,6 +338,10 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!m_supports_fast) return;
|
if (!m_supports_fast) return;
|
||||||
|
|
||||||
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
|
peer_log("==> REJECT_PIECE [ piece: %d | s: %d | l: %d ]"
|
||||||
|
, r.piece, r.start, r.length);
|
||||||
|
#endif
|
||||||
TORRENT_ASSERT(m_sent_handshake && m_sent_bitfield);
|
TORRENT_ASSERT(m_sent_handshake && m_sent_bitfield);
|
||||||
TORRENT_ASSERT(associated_torrent().lock()->valid_metadata());
|
TORRENT_ASSERT(associated_torrent().lock()->valid_metadata());
|
||||||
|
|
||||||
|
@ -1989,9 +1993,9 @@ namespace libtorrent
|
||||||
m_sent_bitfield = true;
|
m_sent_bitfield = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// bootstrap superseeding by sending one have message
|
// bootstrap superseeding by sending two have message
|
||||||
superseed_piece(t->get_piece_to_super_seed(
|
superseed_piece(-1, t->get_piece_to_super_seed(get_bitfield()));
|
||||||
get_bitfield()));
|
superseed_piece(-1, t->get_piece_to_super_seed(get_bitfield()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (m_supports_fast && t->is_seed())
|
else if (m_supports_fast && t->is_seed())
|
||||||
|
|
|
@ -158,7 +158,6 @@ namespace libtorrent
|
||||||
, m_peer_info(peerinfo)
|
, m_peer_info(peerinfo)
|
||||||
, m_speed(slow)
|
, m_speed(slow)
|
||||||
, m_connection_ticket(-1)
|
, m_connection_ticket(-1)
|
||||||
, m_superseed_piece(-1)
|
|
||||||
, m_remote_bytes_dled(0)
|
, m_remote_bytes_dled(0)
|
||||||
, m_remote_dl_rate(0)
|
, m_remote_dl_rate(0)
|
||||||
, m_outstanding_writing_bytes(0)
|
, m_outstanding_writing_bytes(0)
|
||||||
|
@ -202,6 +201,8 @@ namespace libtorrent
|
||||||
, m_received_in_piece(0)
|
, m_received_in_piece(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
m_superseed_piece[0] = -1;
|
||||||
|
m_superseed_piece[1] = -1;
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
// if t is NULL, we better not be connecting, since
|
// if t is NULL, we better not be connecting, since
|
||||||
// we can't decrement the connecting counter
|
// we can't decrement the connecting counter
|
||||||
|
@ -311,7 +312,6 @@ namespace libtorrent
|
||||||
, m_peer_info(peerinfo)
|
, m_peer_info(peerinfo)
|
||||||
, m_speed(slow)
|
, m_speed(slow)
|
||||||
, m_connection_ticket(-1)
|
, m_connection_ticket(-1)
|
||||||
, m_superseed_piece(-1)
|
|
||||||
, m_remote_bytes_dled(0)
|
, m_remote_bytes_dled(0)
|
||||||
, m_remote_dl_rate(0)
|
, m_remote_dl_rate(0)
|
||||||
, m_outstanding_writing_bytes(0)
|
, m_outstanding_writing_bytes(0)
|
||||||
|
@ -355,6 +355,8 @@ namespace libtorrent
|
||||||
, m_received_in_piece(0)
|
, m_received_in_piece(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
m_superseed_piece[0] = -1;
|
||||||
|
m_superseed_piece[1] = -1;
|
||||||
m_est_reciprocation_rate = m_ses.m_settings.default_est_reciprocation_rate;
|
m_est_reciprocation_rate = m_ses.m_settings.default_est_reciprocation_rate;
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
|
@ -1661,11 +1663,11 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->super_seeding() && m_superseed_piece != -1)
|
if (t->super_seeding())
|
||||||
{
|
{
|
||||||
// assume the peer has the piece we're superseeding to it
|
// maybe we need to try another piece, to see if the peer
|
||||||
// and give it another one
|
// is interested in us then
|
||||||
if (!m_have_piece[m_superseed_piece]) incoming_have(m_superseed_piece);
|
superseed_piece(-1, t->get_piece_to_super_seed(m_have_piece));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1733,9 +1735,9 @@ namespace libtorrent
|
||||||
// if the peer optimizes out redundant have messages
|
// if the peer optimizes out redundant have messages
|
||||||
// this will be handled when the peer sends not-interested
|
// this will be handled when the peer sends not-interested
|
||||||
// instead.
|
// instead.
|
||||||
if (m_superseed_piece == index)
|
if (super_seeded_piece(index))
|
||||||
{
|
{
|
||||||
superseed_piece(t->get_piece_to_super_seed(m_have_piece));
|
superseed_piece(index, t->get_piece_to_super_seed(m_have_piece));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1798,15 +1800,15 @@ namespace libtorrent
|
||||||
// a new piece to that peer
|
// a new piece to that peer
|
||||||
if (t->super_seeding()
|
if (t->super_seeding()
|
||||||
&& m_ses.settings().strict_super_seeding
|
&& m_ses.settings().strict_super_seeding
|
||||||
&& (index != m_superseed_piece || t->num_peers() == 1))
|
&& (!super_seeded_piece(index) || t->num_peers() == 1))
|
||||||
{
|
{
|
||||||
for (torrent::peer_iterator i = t->begin()
|
for (torrent::peer_iterator i = t->begin()
|
||||||
, end(t->end()); i != end; ++i)
|
, end(t->end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
peer_connection* p = *i;
|
peer_connection* p = *i;
|
||||||
if (p->superseed_piece() != index) continue;
|
if (!p->super_seeded_piece(index)) continue;
|
||||||
if (!p->has_piece(index)) continue;
|
if (!p->has_piece(index)) continue;
|
||||||
p->superseed_piece(t->get_piece_to_super_seed(p->get_bitfield()));
|
p->superseed_piece(index, t->get_piece_to_super_seed(p->get_bitfield()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2034,8 +2036,8 @@ namespace libtorrent
|
||||||
, r.piece, r.start, r.length);
|
, r.piece, r.start, r.length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_superseed_piece != -1
|
if (t->super_seeding()
|
||||||
&& r.piece != m_superseed_piece)
|
&& !super_seeded_piece(r.piece))
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_STATS
|
#ifdef TORRENT_STATS
|
||||||
++m_ses.m_invalid_piece_requests;
|
++m_ses.m_invalid_piece_requests;
|
||||||
|
@ -2043,14 +2045,17 @@ namespace libtorrent
|
||||||
++m_num_invalid_requests;
|
++m_num_invalid_requests;
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
peer_log("*** INVALID_REQUEST [ piece not superseeded "
|
peer_log("*** INVALID_REQUEST [ piece not superseeded "
|
||||||
"i: %d t: %d n: %d h: %d ss: %d ]"
|
"i: %d t: %d n: %d h: %d ss1: %d ss2: %d ]"
|
||||||
, m_peer_interested
|
, m_peer_interested
|
||||||
, int(t->torrent_file().piece_size(r.piece))
|
, int(t->torrent_file().piece_size(r.piece))
|
||||||
, t->torrent_file().num_pieces()
|
, t->torrent_file().num_pieces()
|
||||||
, t->have_piece(r.piece)
|
, t->have_piece(r.piece)
|
||||||
, m_superseed_piece);
|
, m_superseed_piece[0]
|
||||||
|
, m_superseed_piece[1]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
write_reject_request(r);
|
||||||
|
|
||||||
if (t->alerts().should_post<invalid_request_alert>())
|
if (t->alerts().should_post<invalid_request_alert>())
|
||||||
{
|
{
|
||||||
t->alerts().post_alert(invalid_request_alert(
|
t->alerts().post_alert(invalid_request_alert(
|
||||||
|
@ -3990,12 +3995,13 @@ namespace libtorrent
|
||||||
m_packet_size = packet_size;
|
m_packet_size = packet_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::superseed_piece(int index)
|
void peer_connection::superseed_piece(int replace_piece, int new_piece)
|
||||||
{
|
{
|
||||||
if (index == -1)
|
if (new_piece == -1)
|
||||||
{
|
{
|
||||||
if (m_superseed_piece == -1) return;
|
if (m_superseed_piece[0] == -1) return;
|
||||||
m_superseed_piece = -1;
|
m_superseed_piece[0] = -1;
|
||||||
|
m_superseed_piece[1] = -1;
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
peer_log("*** ending super seed mode");
|
peer_log("*** ending super seed mode");
|
||||||
|
@ -4003,6 +4009,7 @@ namespace libtorrent
|
||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
assert(t);
|
assert(t);
|
||||||
|
|
||||||
|
// TODO: we should probably just send a HAVE_ALL here
|
||||||
for (int i = 0; i < int(m_have_piece.size()); ++i)
|
for (int i = 0; i < int(m_have_piece.size()); ++i)
|
||||||
{
|
{
|
||||||
if (m_have_piece[i] || !t->have_piece(i)) continue;
|
if (m_have_piece[i] || !t->have_piece(i)) continue;
|
||||||
|
@ -4015,13 +4022,22 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!has_piece(index));
|
assert(!has_piece(new_piece));
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
peer_log("==> HAVE [ piece: %d ] (super seed)", index);
|
peer_log("==> HAVE [ piece: %d ] (super seed)", new_piece);
|
||||||
#endif
|
#endif
|
||||||
write_have(index);
|
write_have(new_piece);
|
||||||
m_superseed_piece = index;
|
|
||||||
|
if (replace_piece >= 0)
|
||||||
|
{
|
||||||
|
// move the piece we're replacing to the tail
|
||||||
|
if (m_superseed_piece[0] == replace_piece)
|
||||||
|
std::swap(m_superseed_piece[0], m_superseed_piece[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_superseed_piece[1] = m_superseed_piece[0];
|
||||||
|
m_superseed_piece[0] = new_piece;
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::update_desired_queue_size()
|
void peer_connection::update_desired_queue_size()
|
||||||
|
|
|
@ -923,8 +923,6 @@ namespace libtorrent
|
||||||
// been closed by the time the torrent is destructed. And they are
|
// been closed by the time the torrent is destructed. And they are
|
||||||
// supposed to be closed. So we can still do the invariant check.
|
// supposed to be closed. So we can still do the invariant check.
|
||||||
|
|
||||||
TORRENT_ASSERT(m_connections.empty());
|
|
||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING
|
||||||
|
@ -932,6 +930,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TORRENT_ASSERT(m_abort);
|
TORRENT_ASSERT(m_abort);
|
||||||
|
TORRENT_ASSERT(m_connections.empty());
|
||||||
if (!m_connections.empty())
|
if (!m_connections.empty())
|
||||||
disconnect_all(errors::torrent_aborted);
|
disconnect_all(errors::torrent_aborted);
|
||||||
}
|
}
|
||||||
|
@ -3474,7 +3473,7 @@ namespace libtorrent
|
||||||
// disable super seeding for all peers
|
// disable super seeding for all peers
|
||||||
for (peer_iterator i = begin(); i != end(); ++i)
|
for (peer_iterator i = begin(); i != end(); ++i)
|
||||||
{
|
{
|
||||||
(*i)->superseed_piece(-1);
|
(*i)->superseed_piece(-1, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3495,7 +3494,7 @@ namespace libtorrent
|
||||||
int availability = 0;
|
int availability = 0;
|
||||||
for (const_peer_iterator j = begin(); j != end(); ++j)
|
for (const_peer_iterator j = begin(); j != end(); ++j)
|
||||||
{
|
{
|
||||||
if ((*j)->superseed_piece() == i)
|
if ((*j)->super_seeded_piece(i))
|
||||||
{
|
{
|
||||||
// avoid superseeding the same piece to more than one
|
// avoid superseeding the same piece to more than one
|
||||||
// peer if we can avoid it. Do this by artificially
|
// peer if we can avoid it. Do this by artificially
|
||||||
|
|
Loading…
Reference in New Issue