added timeout for interested peers that don't request once they're unchoked. Added support for suggest_piece

This commit is contained in:
Arvid Norberg 2007-09-01 07:38:10 +00:00
parent cd5275f8e6
commit 61c269efee
4 changed files with 91 additions and 8 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);
}