support for dont-have extension message

This commit is contained in:
Arvid Norberg 2011-08-07 00:41:13 +00:00
parent 4f7c9e2be2
commit d4958c9286
8 changed files with 104 additions and 3 deletions

View File

@ -88,6 +88,7 @@
incoming connection
* added more detailed instrumentation of the disk I/O thread
* add support for dont-have extension message
* fix for set_piece_deadline
* add reset_piece_deadline function
* fix merkle tree torrent assert

View File

@ -106,7 +106,8 @@ namespace libtorrent
{
upload_only_msg = 2,
holepunch_msg = 3,
share_mode_msg = 4
share_mode_msg = 4,
dont_have_msg = 5,
};
~bt_peer_connection();
@ -383,6 +384,9 @@ private:
// the message ID for holepunch messages
boost::uint8_t m_holepunch_id;
// the message ID for don't-have message
boost::uint8_t m_dont_have_id;
// the message ID for share mode message
// 0 if not supported
boost::uint8_t m_share_mode_id;

View File

@ -167,7 +167,7 @@ namespace libtorrent
invalid_lt_tracker_message,
too_frequent_pex,
no_metadata,
reserved110,
invalid_dont_have,
reserved111,
reserved112,
reserved113,

View File

@ -184,6 +184,9 @@ namespace libtorrent
virtual bool on_have(int index)
{ return false; }
virtual bool on_dont_have(int index)
{ return false; }
virtual bool on_bitfield(bitfield const& bitfield)
{ return false; }

View File

@ -458,6 +458,7 @@ namespace libtorrent
void incoming_interested();
void incoming_not_interested();
void incoming_have(int piece_index);
void incoming_dont_have(int piece_index);
void incoming_bitfield(bitfield const& bits);
void incoming_request(peer_request const& r);
void incoming_piece(peer_request const& p, disk_buffer_holder& data);

View File

@ -102,6 +102,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
, m_upload_only_id(0)
, m_holepunch_id(0)
, m_dont_have_id(0)
, m_share_mode_id(0)
, m_supports_extensions(false)
#endif
@ -138,6 +139,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
, m_upload_only_id(0)
, m_holepunch_id(0)
, m_dont_have_id(0)
, m_share_mode_id(0)
, m_supports_extensions(false)
#endif
@ -1605,6 +1607,13 @@ namespace libtorrent
if (extended_id == upload_only_msg)
{
if (!packet_finished()) return;
if (packet_size() != 1)
{
#ifdef TORRENT_VERBOSE_LOGGING
peer_log("<== UPLOAD_ONLY [ ERROR: unexpected packet size: %d ]", packet_size());
#endif
return;
}
bool ul = detail::read_uint8(recv_buffer.begin) != 0;
#ifdef TORRENT_VERBOSE_LOGGING
peer_log("<== UPLOAD_ONLY [ %s ]", (ul?"true":"false"));
@ -1616,6 +1625,13 @@ namespace libtorrent
if (extended_id == share_mode_msg)
{
if (!packet_finished()) return;
if (packet_size() != 1)
{
#ifdef TORRENT_VERBOSE_LOGGING
peer_log("<== SHARE_MODE [ ERROR: unexpected packet size: %d ]", packet_size());
#endif
return;
}
bool sm = detail::read_uint8(recv_buffer.begin) != 0;
#ifdef TORRENT_VERBOSE_LOGGING
peer_log("<== SHARE_MODE [ %s ]", (sm?"true":"false"));
@ -1634,6 +1650,21 @@ namespace libtorrent
return;
}
if (extended_id == dont_have_msg)
{
if (!packet_finished()) return;
if (packet_size() != 4)
{
#ifdef TORRENT_VERBOSE_LOGGING
peer_log("<== DONT_HAVE [ ERROR: unexpected packet size: %d ]", packet_size());
#endif
return;
}
int piece = detail::read_uint32(recv_buffer.begin) != 0;
incoming_dont_have(piece);
return;
}
#ifdef TORRENT_VERBOSE_LOGGING
if (packet_finished())
peer_log("<== EXTENSION MESSAGE [ msg: %d size: %d ]"
@ -1698,6 +1729,7 @@ namespace libtorrent
{
m_upload_only_id = boost::uint8_t(m->dict_find_int_value("upload_only", 0));
m_holepunch_id = boost::uint8_t(m->dict_find_int_value("ut_holepunch", 0));
m_dont_have_id = boost::uint8_t(m->dict_find_int_value("lt_donthave", 0));
}
#endif
@ -2082,6 +2114,7 @@ namespace libtorrent
m["upload_only"] = upload_only_msg;
m["ut_holepunch"] = holepunch_msg;
m["share_mode"] = share_mode_msg;
m["lt_donthave"] = dont_have_msg;
int complete_ago = -1;
if (t->last_seen_complete() > 0) complete_ago = t->time_since_complete();

View File

@ -159,7 +159,7 @@ namespace libtorrent
"invalid lt_tracker message",
"pex messages sent too frequent (possible attack)",
"torrent has no metadata",
"",
"invalid dont-have message",
"",
"",
"",

View File

@ -1746,6 +1746,65 @@ namespace libtorrent
}
}
// -----------------------------
// -------- DONT HAVE ----------
// -----------------------------
void peer_connection::incoming_dont_have(int index)
{
INVARIANT_CHECK;
boost::shared_ptr<torrent> t = m_torrent.lock();
TORRENT_ASSERT(t);
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
{
if ((*i)->on_dont_have(index)) return;
}
#endif
if (is_disconnecting()) return;
#ifdef TORRENT_VERBOSE_LOGGING
peer_log("<== DONT_HAVE [ piece: %d ]", index);
#endif
if (is_disconnecting()) return;
// if we got an invalid message, abort
if (index >= int(m_have_piece.size()) || index < 0)
{
disconnect(errors::invalid_dont_have, 2);
return;
}
if (!m_have_piece[index])
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
peer_log(" got redundant DONT_HAVE message for index: %d", index);
#endif
return;
}
bool was_seed = is_seed();
m_have_piece.clear_bit(index);
TORRENT_ASSERT(m_num_pieces > 0);
--m_num_pieces;
// only update the piece_picker if
// we have the metadata and if
// we're not a seed (in which case
// we won't have a piece picker)
if (!t->valid_metadata()) return;
t->peer_lost(index);
if (was_seed)
t->get_policy().set_seed(m_peer_info, false);
}
// -----------------------------
// --------- BITFIELD ----------
// -----------------------------