|
|
|
@@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
#include "libtorrent/peer_connection.hpp"
|
|
|
|
|
#include "libtorrent/session.hpp"
|
|
|
|
|
#include "libtorrent/identify_client.hpp"
|
|
|
|
|
#include "libtorrent/entry.hpp"
|
|
|
|
|
#include "libtorrent/bencode.hpp"
|
|
|
|
|
|
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
|
#define for if (false) {} else for
|
|
|
|
@@ -44,9 +46,15 @@ POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
#define VERBOSE
|
|
|
|
|
|
|
|
|
|
using namespace libtorrent;
|
|
|
|
|
namespace libtorrent
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
libtorrent::peer_connection::peer_connection(
|
|
|
|
|
// the names of the extensions to look for in
|
|
|
|
|
// the extensions-message
|
|
|
|
|
const char* peer_connection::extension_names[] =
|
|
|
|
|
{ "gzip" };
|
|
|
|
|
|
|
|
|
|
peer_connection::peer_connection(
|
|
|
|
|
detail::session_impl& ses
|
|
|
|
|
, selector& sel
|
|
|
|
|
, torrent* t
|
|
|
|
@@ -70,18 +78,24 @@ libtorrent::peer_connection::peer_connection(
|
|
|
|
|
, m_peer_choked(true)
|
|
|
|
|
, m_interesting(false)
|
|
|
|
|
, m_choked(true)
|
|
|
|
|
, m_supports_extensions(false)
|
|
|
|
|
, m_free_upload(0)
|
|
|
|
|
, m_send_quota(100)
|
|
|
|
|
, m_send_quota_left(100)
|
|
|
|
|
, m_send_quota_limit(100)
|
|
|
|
|
, m_trust_points(0)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
assert(!m_socket->is_blocking());
|
|
|
|
|
assert(m_torrent != 0);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
m_logger = m_ses.create_log(s->sender().as_string().c_str());
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// initialize the extension list to zero, since
|
|
|
|
|
// we don't know which extensions the other
|
|
|
|
|
// end supports yet
|
|
|
|
|
std::fill(m_extension_messages, m_extension_messages + num_supported_extensions, 0);
|
|
|
|
|
|
|
|
|
|
send_handshake();
|
|
|
|
|
|
|
|
|
@@ -94,9 +108,9 @@ libtorrent::peer_connection::peer_connection(
|
|
|
|
|
std::fill(m_have_piece.begin(), m_have_piece.end(), false);
|
|
|
|
|
|
|
|
|
|
send_bitfield();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
libtorrent::peer_connection::peer_connection(
|
|
|
|
|
peer_connection::peer_connection(
|
|
|
|
|
detail::session_impl& ses
|
|
|
|
|
, selector& sel
|
|
|
|
|
, boost::shared_ptr<libtorrent::socket> s)
|
|
|
|
@@ -118,17 +132,23 @@ libtorrent::peer_connection::peer_connection(
|
|
|
|
|
, m_peer_choked(true)
|
|
|
|
|
, m_interesting(false)
|
|
|
|
|
, m_choked(true)
|
|
|
|
|
, m_supports_extensions(false)
|
|
|
|
|
, m_free_upload(0)
|
|
|
|
|
, m_send_quota(100)
|
|
|
|
|
, m_send_quota_left(100)
|
|
|
|
|
, m_send_quota_limit(100)
|
|
|
|
|
, m_trust_points(0)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
assert(!m_socket->is_blocking());
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
m_logger = m_ses.create_log(s->sender().as_string().c_str());
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// initialize the extension list to zero, since
|
|
|
|
|
// we don't know which extensions the other
|
|
|
|
|
// end supports yet
|
|
|
|
|
std::fill(m_extension_messages, m_extension_messages + num_supported_extensions, 0);
|
|
|
|
|
|
|
|
|
|
// we are not attached to any torrent yet.
|
|
|
|
|
// we have to wait for the handshake to see
|
|
|
|
@@ -137,30 +157,30 @@ libtorrent::peer_connection::peer_connection(
|
|
|
|
|
// start in the state where we are trying to read the
|
|
|
|
|
// handshake from the other side
|
|
|
|
|
m_recv_buffer.resize(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
libtorrent::peer_connection::~peer_connection()
|
|
|
|
|
{
|
|
|
|
|
peer_connection::~peer_connection()
|
|
|
|
|
{
|
|
|
|
|
m_selector.remove(m_socket);
|
|
|
|
|
if (m_attached_to_torrent)
|
|
|
|
|
{
|
|
|
|
|
assert(m_torrent != 0);
|
|
|
|
|
m_torrent->remove_peer(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::set_send_quota(int num_bytes)
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::set_send_quota(int num_bytes)
|
|
|
|
|
{
|
|
|
|
|
assert(num_bytes <= m_send_quota_limit || m_send_quota_limit == -1);
|
|
|
|
|
if (num_bytes > m_send_quota_limit && m_send_quota_limit!=-1) num_bytes = m_send_quota_limit;
|
|
|
|
|
|
|
|
|
|
m_send_quota = num_bytes;
|
|
|
|
|
m_send_quota_left = num_bytes;
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::send_handshake()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::send_handshake()
|
|
|
|
|
{
|
|
|
|
|
assert(m_send_buffer.size() == 0);
|
|
|
|
|
|
|
|
|
|
// add handshake to the send buffer
|
|
|
|
@@ -185,6 +205,8 @@ void libtorrent::peer_connection::send_handshake()
|
|
|
|
|
m_send_buffer.begin() + pos
|
|
|
|
|
, m_send_buffer.begin() + pos + 8
|
|
|
|
|
, 0);
|
|
|
|
|
// indicate that we support the extension protocol
|
|
|
|
|
m_send_buffer[pos] = 0x80;
|
|
|
|
|
pos += 8;
|
|
|
|
|
|
|
|
|
|
// info hash
|
|
|
|
@@ -200,15 +222,15 @@ void libtorrent::peer_connection::send_handshake()
|
|
|
|
|
, m_ses.get_peer_id().end()
|
|
|
|
|
, m_send_buffer.begin() + pos);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> HANDSHAKE\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boost::optional<piece_block_progress> libtorrent::peer_connection::downloading_piece() const
|
|
|
|
|
{
|
|
|
|
|
boost::optional<piece_block_progress> peer_connection::downloading_piece() const
|
|
|
|
|
{
|
|
|
|
|
// are we currently receiving a 'piece' message?
|
|
|
|
|
if (m_state != read_packet
|
|
|
|
|
|| m_recv_pos < 9
|
|
|
|
@@ -238,10 +260,10 @@ boost::optional<piece_block_progress> libtorrent::peer_connection::downloading_p
|
|
|
|
|
p.full_block_bytes = len;
|
|
|
|
|
|
|
|
|
|
return boost::optional<piece_block_progress>(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
{
|
|
|
|
|
bool peer_connection::dispatch_message(int received)
|
|
|
|
|
{
|
|
|
|
|
assert(m_recv_pos >= received);
|
|
|
|
|
assert(m_recv_pos > 0);
|
|
|
|
|
|
|
|
|
@@ -259,9 +281,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
m_statistics.received_bytes(0, received);
|
|
|
|
|
if (m_recv_pos < m_packet_size) return false;
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== CHOKE\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_peer_choked = true;
|
|
|
|
|
m_torrent->get_policy().choked(*this);
|
|
|
|
|
|
|
|
|
@@ -274,9 +296,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
m_torrent->picker().abort_download(*i);
|
|
|
|
|
}
|
|
|
|
|
m_download_queue.clear();
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
// m_torrent->picker().integrity_check(m_torrent);
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
// m_torrent->picker().integrity_check(m_torrent);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -288,9 +310,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
m_statistics.received_bytes(0, received);
|
|
|
|
|
if (m_recv_pos < m_packet_size) return false;
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== UNCHOKE\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_peer_choked = false;
|
|
|
|
|
m_torrent->get_policy().unchoked(*this);
|
|
|
|
|
break;
|
|
|
|
@@ -303,9 +325,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
m_statistics.received_bytes(0, received);
|
|
|
|
|
if (m_recv_pos < m_packet_size) return false;
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== INTERESTED\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_peer_interested = true;
|
|
|
|
|
m_torrent->get_policy().interested(*this);
|
|
|
|
|
break;
|
|
|
|
@@ -321,9 +343,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
// clear the request queue if the client isn't interested
|
|
|
|
|
m_requests.clear();
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== NOT_INTERESTED\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_peer_interested = false;
|
|
|
|
|
m_torrent->get_policy().not_interested(*this);
|
|
|
|
|
break;
|
|
|
|
@@ -344,15 +366,15 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
if (index >= m_have_piece.size() || index < 0)
|
|
|
|
|
throw protocol_error("have message with higher index than the number of pieces");
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== HAVE [ piece: " << index << "]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (m_have_piece[index])
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " oops.. we already knew that: " << index << "\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@@ -376,9 +398,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
m_statistics.received_bytes(0, received);
|
|
|
|
|
if (m_recv_pos < m_packet_size) return false;
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== BITFIELD\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
// build a vector of all pieces
|
|
|
|
|
std::vector<int> piece_list;
|
|
|
|
|
for (std::size_t i = 0; i < m_have_piece.size(); ++i)
|
|
|
|
@@ -414,9 +436,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
|
|
|
|
|
if (piece_list.empty())
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " *** THIS IS A SEED ***\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (interesting) m_torrent->get_policy().peer_is_interesting(*this);
|
|
|
|
@@ -425,6 +447,45 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// *************** EXTENSIONS ***************
|
|
|
|
|
case msg_extensions:
|
|
|
|
|
{
|
|
|
|
|
if (m_packet_size > 100 * 1024)
|
|
|
|
|
{
|
|
|
|
|
// too big extension message, abort
|
|
|
|
|
throw protocol_error("'extensions' message size > 100kB");
|
|
|
|
|
}
|
|
|
|
|
m_statistics.received_bytes(0, received);
|
|
|
|
|
if (m_recv_pos < m_packet_size) return false;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
entry e = bdecode(m_recv_buffer.begin()+1, m_recv_buffer.end());
|
|
|
|
|
entry::dictionary_type& extensions = e.dict();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num_supported_extensions; ++i)
|
|
|
|
|
{
|
|
|
|
|
entry::dictionary_type::iterator f =
|
|
|
|
|
extensions.find(extension_names[i]);
|
|
|
|
|
if (f != extensions.end())
|
|
|
|
|
{
|
|
|
|
|
m_extension_messages[i] = f->second.integer();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(invalid_encoding& e)
|
|
|
|
|
{
|
|
|
|
|
throw protocol_error("'extensions' packet contains invalid bencoding");
|
|
|
|
|
}
|
|
|
|
|
catch(type_error& e)
|
|
|
|
|
{
|
|
|
|
|
throw protocol_error("'extensions' packet contains incorrect types");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// *************** REQUEST ***************
|
|
|
|
|
case msg_request:
|
|
|
|
|
{
|
|
|
|
@@ -453,9 +514,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
{
|
|
|
|
|
m_requests.push_back(r);
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== REQUEST [ piece: " << r.piece << " | s: " << r.start << " | l: " << r.length << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@@ -496,9 +557,9 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
int index = detail::read_int(ptr);
|
|
|
|
|
if (index < 0 || index >= m_torrent->torrent_file().num_pieces())
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " piece index invalid\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw protocol_error("invalid piece index in piece message");
|
|
|
|
|
}
|
|
|
|
|
int offset = detail::read_int(ptr);
|
|
|
|
@@ -506,17 +567,17 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
|
|
|
|
|
if (offset < 0)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " offset < 0\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw protocol_error("offset < 0 in piece message");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (offset + len > m_torrent->torrent_file().piece_size(index))
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " piece packet contains more data than the piece size\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw protocol_error("piece message contains more data than the piece size");
|
|
|
|
|
}
|
|
|
|
|
// TODO: make sure that len is == block_size or less only
|
|
|
|
@@ -524,32 +585,32 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
|
|
|
|
|
if (offset % m_torrent->block_size() != 0)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " piece packet contains unaligned offset\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw protocol_error("piece message contains unaligned offset");
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
/*
|
|
|
|
|
piece_block req = m_download_queue.front();
|
|
|
|
|
if (req.piece_index != index)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " piece packet contains unrequested index\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (req.block_index != offset / m_torrent->block_size())
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " piece packet contains unrequested offset\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
*/
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== PIECE [ piece: " << index << " | s: " << offset << " | l: " << len << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
piece_picker& picker = m_torrent->picker();
|
|
|
|
|
piece_block block_finished(index, offset / m_torrent->block_size());
|
|
|
|
@@ -625,18 +686,18 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|
|
|
|
m_selector.remove_writable(m_socket);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " <== CANCEL [ piece: " << r.piece << " | s: " << r.start << " | l: " << r.length << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assert(m_recv_pos == m_packet_size);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::cancel_block(piece_block block)
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::cancel_block(piece_block block)
|
|
|
|
|
{
|
|
|
|
|
assert(block.piece_index >= 0);
|
|
|
|
|
assert(block.piece_index < m_torrent->torrent_file().num_pieces());
|
|
|
|
|
assert(m_torrent->picker().is_downloading(block));
|
|
|
|
@@ -674,15 +735,15 @@ void libtorrent::peer_connection::cancel_block(piece_block block)
|
|
|
|
|
// length
|
|
|
|
|
detail::write_int(block_size, ptr);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> CANCEL [ piece: " << block.piece_index << " | s: " << block_offset << " | l: " << block_size << " | " << block.block_index << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::request_block(piece_block block)
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::request_block(piece_block block)
|
|
|
|
|
{
|
|
|
|
|
assert(block.piece_index >= 0);
|
|
|
|
|
assert(block.piece_index < m_torrent->torrent_file().num_pieces());
|
|
|
|
|
assert(!m_torrent->picker().is_downloading(block));
|
|
|
|
@@ -715,18 +776,18 @@ void libtorrent::peer_connection::request_block(piece_block block)
|
|
|
|
|
// length
|
|
|
|
|
detail::write_int(block_size, ptr);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> REQUEST [ piece: " << block.piece_index << " | s: " << block_offset << " | l: " << block_size << " | " << block.block_index << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::send_bitfield()
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
void peer_connection::send_bitfield()
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> BITFIELD\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
const int packet_size = (m_have_piece.size() + 7) / 8 + 5;
|
|
|
|
|
const int old_size = m_send_buffer.size();
|
|
|
|
|
m_send_buffer.resize(old_size + packet_size);
|
|
|
|
@@ -740,72 +801,106 @@ void libtorrent::peer_connection::send_bitfield()
|
|
|
|
|
m_send_buffer[old_size + 5 + (i>>3)] |= 1 << (7 - (i&7));
|
|
|
|
|
}
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::choke()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::send_extensions()
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> EXTENSIONS\n";
|
|
|
|
|
#endif
|
|
|
|
|
assert(m_supports_extensions);
|
|
|
|
|
|
|
|
|
|
entry extension_list(entry::dictionary_t);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num_supported_extensions; ++i)
|
|
|
|
|
{
|
|
|
|
|
entry msg_index(entry::int_t);
|
|
|
|
|
msg_index.integer() = msg_extensions + 1 + i;
|
|
|
|
|
extension_list.dict()[extension_names[i]] = msg_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
extension_list.print(std::cout);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
m_send_buffer.push_back(msg_extensions);
|
|
|
|
|
// make room for message size
|
|
|
|
|
const int msg_size_pos = m_send_buffer.size();
|
|
|
|
|
m_send_buffer.resize(msg_size_pos + 4);
|
|
|
|
|
|
|
|
|
|
bencode(std::back_inserter(m_send_buffer), extension_list);
|
|
|
|
|
|
|
|
|
|
// write the length of the message
|
|
|
|
|
char* ptr = &m_send_buffer[msg_size_pos];
|
|
|
|
|
detail::write_int(m_send_buffer.size() - msg_size_pos + 1, ptr);
|
|
|
|
|
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void peer_connection::choke()
|
|
|
|
|
{
|
|
|
|
|
if (m_choked) return;
|
|
|
|
|
char msg[] = {0,0,0,1,msg_choke};
|
|
|
|
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
|
|
|
|
m_choked = true;
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> CHOKE\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_requests.clear();
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::unchoke()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::unchoke()
|
|
|
|
|
{
|
|
|
|
|
if (!m_choked) return;
|
|
|
|
|
char msg[] = {0,0,0,1,msg_unchoke};
|
|
|
|
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
|
|
|
|
m_choked = false;
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> UNCHOKE\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::interested()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::interested()
|
|
|
|
|
{
|
|
|
|
|
if (m_interesting) return;
|
|
|
|
|
char msg[] = {0,0,0,1,msg_interested};
|
|
|
|
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
|
|
|
|
m_interesting = true;
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> INTERESTED\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::not_interested()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::not_interested()
|
|
|
|
|
{
|
|
|
|
|
if (!m_interesting) return;
|
|
|
|
|
char msg[] = {0,0,0,1,msg_not_interested};
|
|
|
|
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
|
|
|
|
m_interesting = false;
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> NOT_INTERESTED\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::send_have(int index)
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::send_have(int index)
|
|
|
|
|
{
|
|
|
|
|
const int packet_size = 9;
|
|
|
|
|
char msg[packet_size] = {0,0,0,5,msg_have};
|
|
|
|
|
char* ptr = msg+5;
|
|
|
|
|
detail::write_int(index, ptr);
|
|
|
|
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg + packet_size);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> HAVE [ piece: " << index << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::second_tick()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::second_tick()
|
|
|
|
|
{
|
|
|
|
|
m_statistics.second_tick();
|
|
|
|
|
m_send_quota_left = m_send_quota;
|
|
|
|
|
if (m_send_quota > 0) send_buffer_updated();
|
|
|
|
@@ -845,15 +940,15 @@ void libtorrent::peer_connection::second_tick()
|
|
|
|
|
// the maximum send_quota given our download rate from this peer
|
|
|
|
|
if (m_send_quota_limit < 256) m_send_quota_limit = 256;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------
|
|
|
|
|
// RECEIVE DATA
|
|
|
|
|
// --------------------------
|
|
|
|
|
// --------------------------
|
|
|
|
|
// RECEIVE DATA
|
|
|
|
|
// --------------------------
|
|
|
|
|
|
|
|
|
|
// throws exception when the client should be disconnected
|
|
|
|
|
void libtorrent::peer_connection::receive_data()
|
|
|
|
|
{
|
|
|
|
|
// throws exception when the client should be disconnected
|
|
|
|
|
void peer_connection::receive_data()
|
|
|
|
|
{
|
|
|
|
|
assert(!m_socket->is_blocking());
|
|
|
|
|
assert(m_packet_size > 0);
|
|
|
|
|
for(;;)
|
|
|
|
@@ -894,18 +989,18 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
assert(m_recv_pos == m_packet_size);
|
|
|
|
|
|
|
|
|
|
m_packet_size = reinterpret_cast<unsigned char&>(m_recv_buffer[0]);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " protocol length: " << m_packet_size << "\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_state = read_protocol_string;
|
|
|
|
|
m_recv_buffer.resize(m_packet_size);
|
|
|
|
|
m_recv_pos = 0;
|
|
|
|
|
|
|
|
|
|
if (m_packet_size == 0)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << "incorrect protocol length\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
@@ -916,16 +1011,16 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
m_statistics.received_bytes(0, received);
|
|
|
|
|
if (m_recv_pos < m_packet_size) break;
|
|
|
|
|
assert(m_recv_pos == m_packet_size);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " protocol: '" << std::string(m_recv_buffer.begin(), m_recv_buffer.end()) << "'\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
const char protocol_string[] = "BitTorrent protocol";
|
|
|
|
|
const int protocol_len = sizeof(protocol_string) - 1;
|
|
|
|
|
if (!std::equal(m_recv_buffer.begin(), m_recv_buffer.end(), protocol_string))
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << "incorrect protocol name\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -945,11 +1040,16 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
// ok, now we have got enough of the handshake. Is this connection
|
|
|
|
|
// attached to a torrent?
|
|
|
|
|
|
|
|
|
|
if (m_torrent == 0)
|
|
|
|
|
{
|
|
|
|
|
// TODO: if the protocol is to be extended
|
|
|
|
|
// these 8 bytes would be used to describe the
|
|
|
|
|
// extensions available on the other side
|
|
|
|
|
if (m_recv_buffer[0] & 0x80)
|
|
|
|
|
{
|
|
|
|
|
m_supports_extensions = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_torrent == 0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// now, we have to see if there's a torrent with the
|
|
|
|
|
// info_hash we got from the peer
|
|
|
|
@@ -960,9 +1060,9 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
if (m_torrent == 0)
|
|
|
|
|
{
|
|
|
|
|
// we couldn't find the torrent!
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " couldn't find a torrent with the given info_hash\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -981,20 +1081,22 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
// verify info hash
|
|
|
|
|
if (!std::equal(m_recv_buffer.begin()+8, m_recv_buffer.begin() + 28, (const char*)m_torrent->torrent_file().info_hash().begin()))
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " received invalid info_hash\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_supports_extensions) send_extensions();
|
|
|
|
|
|
|
|
|
|
m_state = read_peer_id;
|
|
|
|
|
m_packet_size = 20;
|
|
|
|
|
m_recv_pos = 0;
|
|
|
|
|
m_recv_buffer.resize(20);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " info_hash received\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1005,7 +1107,7 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
if (m_recv_pos < m_packet_size) break;
|
|
|
|
|
assert(m_recv_pos == m_packet_size);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
peer_id tmp;
|
|
|
|
|
std::copy(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (char*)tmp.begin());
|
|
|
|
@@ -1013,7 +1115,7 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
s << "received peer_id: " << tmp << " client: " << identify_client(tmp) << "\n";
|
|
|
|
|
(*m_logger) << s.str();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (m_active)
|
|
|
|
|
{
|
|
|
|
@@ -1022,9 +1124,9 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
// can that be correct?
|
|
|
|
|
if (!std::equal(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (const char*)m_peer_id.begin()))
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " invalid peer_id (it doesn't equal the one from the tracker)\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -1036,9 +1138,9 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
|
|
|
|
|
if (m_torrent->has_peer(m_peer_id))
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << " duplicate connection, closing\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1068,9 +1170,9 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
// don't accept packets larger than 1 MB
|
|
|
|
|
if (m_packet_size > 1024*1024 || m_packet_size < 0)
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " packet too large (packet_size > 1 Megabyte), abort\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
// packet too large
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
@@ -1105,26 +1207,26 @@ void libtorrent::peer_connection::receive_data()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assert(m_packet_size > 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool libtorrent::peer_connection::has_data() const throw()
|
|
|
|
|
{
|
|
|
|
|
bool peer_connection::has_data() const throw()
|
|
|
|
|
{
|
|
|
|
|
// if we have requests or pending data to be sent or announcements to be made
|
|
|
|
|
// we want to send data
|
|
|
|
|
return ((!m_requests.empty() && !m_choked)
|
|
|
|
|
|| !m_send_buffer.empty()
|
|
|
|
|
|| !m_announce_queue.empty())
|
|
|
|
|
&& m_send_quota_left != 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------
|
|
|
|
|
// SEND DATA
|
|
|
|
|
// --------------------------
|
|
|
|
|
// --------------------------
|
|
|
|
|
// SEND DATA
|
|
|
|
|
// --------------------------
|
|
|
|
|
|
|
|
|
|
// throws exception when the client should be disconnected
|
|
|
|
|
void libtorrent::peer_connection::send_data()
|
|
|
|
|
{
|
|
|
|
|
// throws exception when the client should be disconnected
|
|
|
|
|
void peer_connection::send_data()
|
|
|
|
|
{
|
|
|
|
|
assert(m_socket->is_writable());
|
|
|
|
|
assert(has_data());
|
|
|
|
|
|
|
|
|
@@ -1154,9 +1256,9 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
throw network_error(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
assert(m_torrent->verify_piece(r.piece) && "internal error");
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
const int send_buffer_offset = m_send_buffer.size();
|
|
|
|
|
const int packet_size = 4 + 5 + 4 + r.length;
|
|
|
|
|
m_send_buffer.resize(send_buffer_offset + packet_size);
|
|
|
|
@@ -1171,14 +1273,14 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
, r.piece
|
|
|
|
|
, r.start
|
|
|
|
|
, r.length);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> PIECE [ piece: " << r.piece << " | s: " << r.start << " | l: " << r.length << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
m_payloads.push_back(range(send_buffer_offset+13, r.length));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string()
|
|
|
|
|
<< " *** WARNING [ illegal piece request idx: " << r.piece
|
|
|
|
|
<< " | s: " << r.start
|
|
|
|
@@ -1187,7 +1289,7 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
<< " | torrent: " << (m_torrent != 0)
|
|
|
|
|
<< " | have: " << m_torrent->have_piece(r.piece)
|
|
|
|
|
<< " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
m_requests.erase(m_requests.begin());
|
|
|
|
|
}
|
|
|
|
@@ -1198,7 +1300,7 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
i != m_announce_queue.end();
|
|
|
|
|
++i)
|
|
|
|
|
{
|
|
|
|
|
// (*m_logger) << "have piece: " << *i << " sent to: " << m_socket->sender().as_string() << "\n";
|
|
|
|
|
// (*m_logger) << "have piece: " << *i << " sent to: " << m_socket->sender().as_string() << "\n";
|
|
|
|
|
send_have(*i);
|
|
|
|
|
}
|
|
|
|
|
m_announce_queue.clear();
|
|
|
|
@@ -1220,7 +1322,7 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
, amount_to_send);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
// (*m_logger) << m_socket->sender().as_string() << " ==> SENT [ length: " << sent << " ]\n";
|
|
|
|
|
// (*m_logger) << m_socket->sender().as_string() << " ==> SENT [ length: " << sent << " ]\n";
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (sent > 0)
|
|
|
|
@@ -1287,7 +1389,7 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
|
|
|
|
|
assert(m_added_to_selector);
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
if (has_data())
|
|
|
|
|
{
|
|
|
|
|
if (m_socket->is_writable())
|
|
|
|
@@ -1295,12 +1397,12 @@ void libtorrent::peer_connection::send_data()
|
|
|
|
|
std::cout << "ERROR\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void libtorrent::peer_connection::keep_alive()
|
|
|
|
|
{
|
|
|
|
|
void peer_connection::keep_alive()
|
|
|
|
|
{
|
|
|
|
|
boost::posix_time::time_duration d;
|
|
|
|
|
d = boost::posix_time::second_clock::local_time() - m_last_sent;
|
|
|
|
|
if (d.seconds() > m_timeout / 2)
|
|
|
|
@@ -1308,9 +1410,10 @@ void libtorrent::peer_connection::keep_alive()
|
|
|
|
|
char noop[] = {0,0,0,0};
|
|
|
|
|
m_send_buffer.insert(m_send_buffer.end(), noop, noop+4);
|
|
|
|
|
m_last_sent = boost::posix_time::second_clock::local_time();
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
(*m_logger) << m_socket->sender().as_string() << " ==> NOP\n";
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
send_buffer_updated();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|