*** empty log message ***
This commit is contained in:
parent
97b387b196
commit
8a3d994416
|
@ -345,6 +345,8 @@ const char* buf;
|
|||
entry e = bdecode(buf, buf + data_size);
|
||||
</pre>
|
||||
<p>Now we just need to know how to retrieve information from the <tt class="literal"><span class="pre">entry</span></tt>.</p>
|
||||
<p>If <tt class="literal"><span class="pre">bdecode()</span></tt> encounters invalid encoded data in the range given to it
|
||||
it will throw <a class="reference" href="#invalid-encoding">invalid_encoding</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="entry">
|
||||
<h2><a class="toc-backref" href="#id12" name="entry">entry</a></h2>
|
||||
|
@ -392,7 +394,7 @@ public:
|
|||
</pre>
|
||||
<p>The <tt class="literal"><span class="pre">integer()</span></tt>, <tt class="literal"><span class="pre">string()</span></tt>, <tt class="literal"><span class="pre">list()</span></tt> and <tt class="literal"><span class="pre">dict()</span></tt> functions
|
||||
are accessorts that return the respecive type. If the <tt class="literal"><span class="pre">entry</span></tt> object isn't of the
|
||||
type you request, the accessor will throw <tt class="literal"><span class="pre">type_error</span></tt> (which derives from
|
||||
type you request, the accessor will throw <a class="reference" href="#type-error">type_error</a> (which derives from
|
||||
<tt class="literal"><span class="pre">std::runtime_error</span></tt>). You can ask an <tt class="literal"><span class="pre">entry</span></tt> for its type through the
|
||||
<tt class="literal"><span class="pre">type()</span></tt> function.</p>
|
||||
<p>The <tt class="literal"><span class="pre">print()</span></tt> function is there for debug purposes only.</p>
|
||||
|
@ -541,7 +543,7 @@ was started.</p>
|
|||
<p><tt class="literal"><span class="pre">set_max_uploads()</span></tt> sets the maximum number of peers that's unchoked at the same time on this
|
||||
torrent. If you set this to -1, there will be no limit.</p>
|
||||
<p><tt class="literal"><span class="pre">write_resume_data()</span></tt> takes a non-const reference to a char-vector, that vector will be filled
|
||||
with the fast-resume data. For more information about hpw fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>.</p>
|
||||
with the fast-resume data. For more information about how fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>.</p>
|
||||
<div class="section" id="status">
|
||||
<h3><a class="toc-backref" href="#id15" name="status">status()</a></h3>
|
||||
<p><tt class="literal"><span class="pre">status()</span></tt> will return a structure with information about the status of this
|
||||
|
@ -1140,7 +1142,7 @@ for each slot
|
|||
4 bytes, the number of unfinished pieces
|
||||
for each unfinished piece
|
||||
4 bytes, index of the unfinished piece
|
||||
blocks_per_piece / 32 bytes, the bitmask describing which
|
||||
blocks_per_piece / 8 bytes, the bitmask describing which
|
||||
blocks are finished in this piece.
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
@ -325,6 +325,8 @@ Or, if you have a raw char buffer::
|
|||
|
||||
Now we just need to know how to retrieve information from the ``entry``.
|
||||
|
||||
If ``bdecode()`` encounters invalid encoded data in the range given to it
|
||||
it will throw invalid_encoding_.
|
||||
|
||||
|
||||
|
||||
|
@ -375,7 +377,7 @@ or a string. This is its synopsis::
|
|||
|
||||
The ``integer()``, ``string()``, ``list()`` and ``dict()`` functions
|
||||
are accessorts that return the respecive type. If the ``entry`` object isn't of the
|
||||
type you request, the accessor will throw ``type_error`` (which derives from
|
||||
type you request, the accessor will throw type_error_ (which derives from
|
||||
``std::runtime_error``). You can ask an ``entry`` for its type through the
|
||||
``type()`` function.
|
||||
|
||||
|
@ -551,7 +553,7 @@ was started.
|
|||
torrent. If you set this to -1, there will be no limit.
|
||||
|
||||
``write_resume_data()`` takes a non-const reference to a char-vector, that vector will be filled
|
||||
with the fast-resume data. For more information about hpw fast-resume works, see `fast resume`_.
|
||||
with the fast-resume data. For more information about how fast-resume works, see `fast resume`_.
|
||||
|
||||
status()
|
||||
~~~~~~~~
|
||||
|
@ -1211,7 +1213,7 @@ The format of the fast-resume data is as follows, given that all
|
|||
4 bytes, the number of unfinished pieces
|
||||
for each unfinished piece
|
||||
4 bytes, index of the unfinished piece
|
||||
blocks_per_piece / 32 bytes, the bitmask describing which
|
||||
blocks_per_piece / 8 bytes, the bitmask describing which
|
||||
blocks are finished in this piece.
|
||||
|
||||
Feedback
|
||||
|
|
|
@ -319,7 +319,9 @@ int main(int argc, char* argv[])
|
|||
<< static_cast<const char*>((i->flags & peer_info::interesting)?"I":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::choked)?"C":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::remote_interested)?"i":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::remote_choked)?"c":"_") << "\n";
|
||||
<< static_cast<const char*>((i->flags & peer_info::remote_choked)?"c":"_")
|
||||
<< static_cast<const char*>((i->flags & peer_info::supports_extensions)?"e":"_")
|
||||
<< "\n";
|
||||
|
||||
if (i->downloading_piece_index >= 0)
|
||||
{
|
||||
|
|
|
@ -298,6 +298,9 @@ namespace libtorrent
|
|||
- m_statistics.total_payload_upload();
|
||||
}
|
||||
|
||||
bool support_extensions() const
|
||||
{ return m_supports_extensions; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
boost::shared_ptr<logger> m_logger;
|
||||
#endif
|
||||
|
@ -310,6 +313,7 @@ namespace libtorrent
|
|||
void send_bitfield();
|
||||
void send_have(int index);
|
||||
void send_handshake();
|
||||
void send_extensions();
|
||||
|
||||
// is used during handshake
|
||||
enum state
|
||||
|
@ -330,6 +334,7 @@ namespace libtorrent
|
|||
|
||||
enum message_type
|
||||
{
|
||||
// standard messages
|
||||
msg_choke = 0,
|
||||
msg_unchoke,
|
||||
msg_interested,
|
||||
|
@ -338,7 +343,11 @@ namespace libtorrent
|
|||
msg_bitfield,
|
||||
msg_request,
|
||||
msg_piece,
|
||||
msg_cancel
|
||||
msg_cancel,
|
||||
// extension protocol message
|
||||
msg_extensions = 20,
|
||||
// extended messages
|
||||
msg_gzip_piece
|
||||
};
|
||||
|
||||
std::size_t m_packet_size;
|
||||
|
@ -420,6 +429,11 @@ namespace libtorrent
|
|||
// we have choked the upload to the peer
|
||||
bool m_choked;
|
||||
|
||||
// this is set to true if the handshake from
|
||||
// the peer indicated that it supports the
|
||||
// extension protocol
|
||||
bool m_supports_extensions;
|
||||
|
||||
// the pieces the other end have
|
||||
std::vector<bool> m_have_piece;
|
||||
|
||||
|
@ -477,6 +491,14 @@ namespace libtorrent
|
|||
// this value. If it sinks below a threshold, its
|
||||
// considered a bad peer and will be banned.
|
||||
int m_trust_points;
|
||||
|
||||
enum extension_index
|
||||
{
|
||||
gzip_piece,
|
||||
num_supported_extensions
|
||||
};
|
||||
static const char* extension_names[num_supported_extensions];
|
||||
unsigned char m_extension_messages[num_supported_extensions];
|
||||
};
|
||||
|
||||
// this is called each time this peer generates some
|
||||
|
|
|
@ -46,7 +46,8 @@ namespace libtorrent
|
|||
interesting = 0x1,
|
||||
choked = 0x2,
|
||||
remote_interested = 0x4,
|
||||
remote_choked = 0x8
|
||||
remote_choked = 0x8,
|
||||
supports_extensions = 0x10
|
||||
};
|
||||
unsigned int flags;
|
||||
address ip;
|
||||
|
|
|
@ -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,6 +78,7 @@ 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)
|
||||
|
@ -83,6 +92,11 @@ libtorrent::peer_connection::peer_connection(
|
|||
m_logger = m_ses.create_log(s->sender().as_string().c_str());
|
||||
#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();
|
||||
|
||||
// start in the state where we are trying to read the
|
||||
|
@ -96,7 +110,7 @@ libtorrent::peer_connection::peer_connection(
|
|||
send_bitfield();
|
||||
}
|
||||
|
||||
libtorrent::peer_connection::peer_connection(
|
||||
peer_connection::peer_connection(
|
||||
detail::session_impl& ses
|
||||
, selector& sel
|
||||
, boost::shared_ptr<libtorrent::socket> s)
|
||||
|
@ -118,6 +132,7 @@ 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)
|
||||
|
@ -130,6 +145,11 @@ libtorrent::peer_connection::peer_connection(
|
|||
m_logger = m_ses.create_log(s->sender().as_string().c_str());
|
||||
#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
|
||||
// which torrent the connector want's to connect to
|
||||
|
@ -139,7 +159,7 @@ libtorrent::peer_connection::peer_connection(
|
|||
m_recv_buffer.resize(1);
|
||||
}
|
||||
|
||||
libtorrent::peer_connection::~peer_connection()
|
||||
peer_connection::~peer_connection()
|
||||
{
|
||||
m_selector.remove(m_socket);
|
||||
if (m_attached_to_torrent)
|
||||
|
@ -149,7 +169,7 @@ libtorrent::peer_connection::~peer_connection()
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -159,7 +179,7 @@ void libtorrent::peer_connection::set_send_quota(int num_bytes)
|
|||
send_buffer_updated();
|
||||
}
|
||||
|
||||
void libtorrent::peer_connection::send_handshake()
|
||||
void peer_connection::send_handshake()
|
||||
{
|
||||
assert(m_send_buffer.size() == 0);
|
||||
|
||||
|
@ -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
|
||||
|
@ -207,7 +229,7 @@ void libtorrent::peer_connection::send_handshake()
|
|||
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
|
||||
|
@ -240,7 +262,7 @@ boost::optional<piece_block_progress> libtorrent::peer_connection::downloading_p
|
|||
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);
|
||||
|
@ -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:
|
||||
{
|
||||
|
@ -635,7 +696,7 @@ bool libtorrent::peer_connection::dispatch_message(int received)
|
|||
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());
|
||||
|
@ -681,7 +742,7 @@ void libtorrent::peer_connection::cancel_block(piece_block block)
|
|||
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());
|
||||
|
@ -722,7 +783,7 @@ void libtorrent::peer_connection::request_block(piece_block block)
|
|||
send_buffer_updated();
|
||||
}
|
||||
|
||||
void libtorrent::peer_connection::send_bitfield()
|
||||
void peer_connection::send_bitfield()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << m_socket->sender().as_string() << " ==> BITFIELD\n";
|
||||
|
@ -742,7 +803,41 @@ void libtorrent::peer_connection::send_bitfield()
|
|||
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};
|
||||
|
@ -755,7 +850,7 @@ void libtorrent::peer_connection::choke()
|
|||
send_buffer_updated();
|
||||
}
|
||||
|
||||
void libtorrent::peer_connection::unchoke()
|
||||
void peer_connection::unchoke()
|
||||
{
|
||||
if (!m_choked) return;
|
||||
char msg[] = {0,0,0,1,msg_unchoke};
|
||||
|
@ -767,7 +862,7 @@ void libtorrent::peer_connection::unchoke()
|
|||
send_buffer_updated();
|
||||
}
|
||||
|
||||
void libtorrent::peer_connection::interested()
|
||||
void peer_connection::interested()
|
||||
{
|
||||
if (m_interesting) return;
|
||||
char msg[] = {0,0,0,1,msg_interested};
|
||||
|
@ -779,7 +874,7 @@ void libtorrent::peer_connection::interested()
|
|||
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};
|
||||
|
@ -791,7 +886,7 @@ void libtorrent::peer_connection::not_interested()
|
|||
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};
|
||||
|
@ -804,7 +899,7 @@ void libtorrent::peer_connection::send_have(int index)
|
|||
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;
|
||||
|
@ -852,7 +947,7 @@ void libtorrent::peer_connection::second_tick()
|
|||
// --------------------------
|
||||
|
||||
// throws exception when the client should be disconnected
|
||||
void libtorrent::peer_connection::receive_data()
|
||||
void peer_connection::receive_data()
|
||||
{
|
||||
assert(!m_socket->is_blocking());
|
||||
assert(m_packet_size > 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
|
||||
|
@ -988,6 +1088,8 @@ void libtorrent::peer_connection::receive_data()
|
|||
}
|
||||
}
|
||||
|
||||
if (m_supports_extensions) send_extensions();
|
||||
|
||||
m_state = read_peer_id;
|
||||
m_packet_size = 20;
|
||||
m_recv_pos = 0;
|
||||
|
@ -1108,7 +1210,7 @@ void libtorrent::peer_connection::receive_data()
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -1123,7 +1225,7 @@ bool libtorrent::peer_connection::has_data() const throw()
|
|||
// --------------------------
|
||||
|
||||
// throws exception when the client should be disconnected
|
||||
void libtorrent::peer_connection::send_data()
|
||||
void peer_connection::send_data()
|
||||
{
|
||||
assert(m_socket->is_writable());
|
||||
assert(has_data());
|
||||
|
@ -1299,7 +1401,7 @@ void libtorrent::peer_connection::send_data()
|
|||
}
|
||||
|
||||
|
||||
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;
|
||||
|
@ -1314,3 +1416,4 @@ void libtorrent::peer_connection::keep_alive()
|
|||
send_buffer_updated();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -880,6 +880,7 @@ namespace libtorrent
|
|||
m_impl.m_alerts.set_severity(s);
|
||||
}
|
||||
|
||||
// TODO: store resume data as an entry instead
|
||||
void detail::piece_checker_data::parse_resume_data(
|
||||
const std::vector<char>* rd
|
||||
, const torrent_info& info)
|
||||
|
@ -920,7 +921,7 @@ namespace libtorrent
|
|||
|
||||
int num_unfinished = read_int(ptr);
|
||||
if (num_unfinished < 0) return;
|
||||
if (data.size() != 20 + (1 + num_slots + 2 + num_unfinished * (num_blocks_per_piece / 32 + 1)) * 4)
|
||||
if (data.size() != 20 + (1 + num_slots + 2 + num_unfinished) * 4 + num_unfinished * (num_blocks_per_piece / 8))
|
||||
return;
|
||||
|
||||
tmp_unfinished.reserve(num_unfinished);
|
||||
|
@ -935,12 +936,13 @@ namespace libtorrent
|
|||
|| p.index >= info.num_pieces())
|
||||
return;
|
||||
|
||||
for (int j = 0; j < num_blocks_per_piece / 32; ++j)
|
||||
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
||||
for (int j = 0; j < num_bitmask_bytes; ++j)
|
||||
{
|
||||
unsigned int bits = read_int(ptr);
|
||||
for (int k = 0; k < 32; ++k)
|
||||
unsigned char bits = read_uchar(ptr);
|
||||
for (int k = 0; k < 8; ++k)
|
||||
{
|
||||
const int bit = j * 32 + k;
|
||||
const int bit = j * 8 + k;
|
||||
if (bits & (1 << bit))
|
||||
p.finished_blocks[bit] = true;
|
||||
}
|
||||
|
|
|
@ -231,12 +231,15 @@ namespace libtorrent
|
|||
// the unsinished piece's index
|
||||
detail::write_int(i->index, out);
|
||||
|
||||
// write
|
||||
for (int j = 0; j < num_blocks_per_piece / 32; ++j)
|
||||
// TODO: write the bitmask in correct byteorder
|
||||
// TODO: make sure to read it in the correct order too
|
||||
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
||||
for (int j = 0; j < num_bitmask_bytes; ++j)
|
||||
{
|
||||
unsigned int v = 0;
|
||||
for (int k = 0; k < 32; ++k) v |= i->finished_blocks[j*32+k]?(1 << k):0;
|
||||
detail::write_int(v, out);
|
||||
unsigned char v = 0;
|
||||
for (int k = 0; k < 8; ++k)
|
||||
v |= i->finished_blocks[j*8+k]?(1 << k):0;
|
||||
detail::write_uchar(v, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -337,6 +340,7 @@ namespace libtorrent
|
|||
if (peer->is_choked()) p.flags |= peer_info::choked;
|
||||
if (peer->is_peer_interested()) p.flags |= peer_info::remote_interested;
|
||||
if (peer->has_peer_choked()) p.flags |= peer_info::remote_choked;
|
||||
if (peer->support_extensions()) p.flags |= peer_info::supports_extensions;
|
||||
|
||||
p.pieces = peer->get_bitfield();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue