forked from premiere/premiere-libtorrent
added timeout for interested peers that don't request once they're unchoked. Added support for suggest_piece
This commit is contained in:
parent
cd5275f8e6
commit
61c269efee
|
@ -219,6 +219,7 @@ namespace libtorrent
|
|||
|
||||
std::vector<bool> const& get_bitfield() const;
|
||||
std::vector<int> const& allowed_fast();
|
||||
std::vector<int> const& suggested_pieces() const { return m_suggested_pieces; }
|
||||
|
||||
void timed_out();
|
||||
// this will cause this peer_connection to be disconnected.
|
||||
|
@ -303,6 +304,7 @@ namespace libtorrent
|
|||
void incoming_have_all();
|
||||
void incoming_have_none();
|
||||
void incoming_allowed_fast(int index);
|
||||
void incoming_suggest(int index);
|
||||
|
||||
// the following functions appends messages
|
||||
// to the send buffer
|
||||
|
@ -493,6 +495,11 @@ namespace libtorrent
|
|||
// the time we sent a request to
|
||||
// this peer the last time
|
||||
ptime m_last_request;
|
||||
// the time we received the last
|
||||
// piece request from the peer
|
||||
ptime m_last_incoming_request;
|
||||
// the time when we unchoked this peer
|
||||
ptime m_last_unchoke;
|
||||
|
||||
int m_packet_size;
|
||||
int m_recv_pos;
|
||||
|
@ -590,7 +597,7 @@ namespace libtorrent
|
|||
std::deque<peer_request> m_requests;
|
||||
|
||||
// the blocks we have reserved in the piece
|
||||
// picker and will send to this peer.
|
||||
// picker and will request from this peer.
|
||||
std::deque<piece_block> m_request_queue;
|
||||
|
||||
// the queue of blocks we have requested
|
||||
|
@ -718,6 +725,10 @@ namespace libtorrent
|
|||
// requested (regardless of choke state)
|
||||
std::vector<int> m_allowed_fast;
|
||||
|
||||
// pieces that has been suggested to be
|
||||
// downloaded from this peer
|
||||
std::vector<int> m_suggested_pieces;
|
||||
|
||||
// the number of bytes send to the disk-io
|
||||
// thread that hasn't yet been completely written.
|
||||
int m_outstanding_writing_bytes;
|
||||
|
|
|
@ -1062,8 +1062,14 @@ namespace libtorrent
|
|||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'suggest_piece' without FAST extension support");
|
||||
|
||||
// just ignore for now
|
||||
return;
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
buffer::const_interval recv_buffer = receive_buffer();
|
||||
|
||||
const char* ptr = recv_buffer.begin + 1;
|
||||
int piece = detail::read_uint32(ptr);
|
||||
incoming_suggest(piece);
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_have_all(int received)
|
||||
|
|
|
@ -77,6 +77,8 @@ namespace libtorrent
|
|||
, m_timeout(m_ses.settings().peer_timeout)
|
||||
, m_last_piece(time_now())
|
||||
, m_last_request(time_now())
|
||||
, m_last_incoming_request(min_time())
|
||||
, m_last_unchoke(min_time())
|
||||
, m_packet_size(0)
|
||||
, m_recv_pos(0)
|
||||
, m_current_send_buffer(0)
|
||||
|
@ -155,6 +157,8 @@ namespace libtorrent
|
|||
, m_timeout(m_ses.settings().peer_timeout)
|
||||
, m_last_piece(time_now())
|
||||
, m_last_request(time_now())
|
||||
, m_last_incoming_request(min_time())
|
||||
, m_last_unchoke(min_time())
|
||||
, m_packet_size(0)
|
||||
, m_recv_pos(0)
|
||||
, m_current_send_buffer(0)
|
||||
|
@ -397,6 +401,11 @@ namespace libtorrent
|
|||
// dont announce during handshake
|
||||
if (in_handshake()) return;
|
||||
|
||||
// remove suggested pieces that we have
|
||||
std::vector<int>::iterator i = std::find(
|
||||
m_suggested_pieces.begin(), m_suggested_pieces.end(), index);
|
||||
if (i != m_suggested_pieces.end()) m_suggested_pieces.erase(i);
|
||||
|
||||
// optimization, don't send have messages
|
||||
// to peers that already have the piece
|
||||
if (!m_ses.settings().send_redundant_have
|
||||
|
@ -724,6 +733,33 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// -------- REJECT PIECE -------
|
||||
// -----------------------------
|
||||
|
||||
void peer_connection::incoming_suggest(int index)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string()
|
||||
<< " <== SUGGEST_PIECE [ piece: " << index << " ]\n";
|
||||
#endif
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
if (!t) return;
|
||||
|
||||
if (t->have_piece(index)) return;
|
||||
|
||||
if (m_suggested_pieces.size() > 9)
|
||||
m_suggested_pieces.erase(m_suggested_pieces.begin());
|
||||
m_suggested_pieces.push_back(index);
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string()
|
||||
<< " ** SUGGEST_PIECE [ piece: " << index << " added to set: " << m_suggested_pieces.size() << " ]\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// ---------- UNCHOKE ----------
|
||||
// -----------------------------
|
||||
|
@ -1097,6 +1133,7 @@ namespace libtorrent
|
|||
else
|
||||
{
|
||||
m_requests.push_back(r);
|
||||
m_last_incoming_request = time_now();
|
||||
fill_send_buffer();
|
||||
}
|
||||
}
|
||||
|
@ -1702,6 +1739,7 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_choked) return;
|
||||
m_last_unchoke = time_now();
|
||||
write_unchoke();
|
||||
m_choked = false;
|
||||
|
||||
|
@ -2863,9 +2901,20 @@ namespace libtorrent
|
|||
// if the peer hasn't said a thing for a certain
|
||||
// time, it is considered to have timed out
|
||||
time_duration d;
|
||||
d = time_now() - m_last_receive;
|
||||
d = now - m_last_receive;
|
||||
if (d > seconds(m_timeout)) return true;
|
||||
|
||||
// disconnect peers that we unchoked, but
|
||||
// they didn't send a request within 20 seconds.
|
||||
// but only if we're a seed
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
d = now - (std::max)(m_last_unchoke, m_last_incoming_request);
|
||||
if (m_requests.empty()
|
||||
&& !m_choked
|
||||
&& m_peer_interested
|
||||
&& t && t->is_seed()
|
||||
&& d > seconds(20)) return true;
|
||||
|
||||
// TODO: as long as we have less than 95% of the
|
||||
// global (or local) connection limit, connections should
|
||||
// never time out for another reason
|
||||
|
|
|
@ -258,6 +258,21 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!c.suggested_pieces().empty())
|
||||
{
|
||||
// if the peer has suggested us to download certain pieces
|
||||
// try to pick among those primarily
|
||||
std::vector<int> const& suggested = c.suggested_pieces();
|
||||
|
||||
p.add_interesting_blocks(suggested, c.get_bitfield()
|
||||
, interesting_pieces, busy_pieces, num_requests
|
||||
, prefer_whole_pieces, c.peer_info_struct(), state
|
||||
, false);
|
||||
interesting_pieces.insert(interesting_pieces.end()
|
||||
, busy_pieces.begin(), busy_pieces.end());
|
||||
busy_pieces.clear();
|
||||
}
|
||||
|
||||
// picks the interesting pieces from this peer
|
||||
// the integer is the number of pieces that
|
||||
// should be guaranteed to be available for download
|
||||
|
@ -266,9 +281,11 @@ namespace libtorrent
|
|||
// the last argument is if we should prefer whole pieces
|
||||
// for this peer. If we're downloading one piece in 20 seconds
|
||||
// then use this mode.
|
||||
p.pick_pieces(c.get_bitfield(), interesting_pieces
|
||||
, num_requests, prefer_whole_pieces, c.peer_info_struct()
|
||||
, state, rarest_first);
|
||||
if (int(interesting_pieces.size()) < num_requests)
|
||||
p.pick_pieces(c.get_bitfield(), interesting_pieces
|
||||
, num_requests, prefer_whole_pieces, c.peer_info_struct()
|
||||
, state, rarest_first);
|
||||
|
||||
busy_pieces.reserve(10);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue