merged back the asio development branch

This commit is contained in:
Arvid Norberg
2006-04-25 21:04:48 +00:00
parent 410af930a7
commit 41810b1166
71 changed files with 8271 additions and 4661 deletions

View File

@@ -0,0 +1,247 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.9: http://docutils.sourceforge.net/" />
<title></title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com Ludvig Strigeus, ludde&#64;utorrent.com" />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="document">
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="reference" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a>
Ludvig Strigeus, <a class="last reference" href="mailto:ludde&#64;utorrent.com">ludde&#64;utorrent.com</a></td></tr>
</tbody>
</table>
<div class="section" id="extension-protocol-for-bittorrent">
<h1><a name="extension-protocol-for-bittorrent">extension protocol for bittorrent</a></h1>
<p>The intention of this protocol is to provide a simple and thin transport
for extensions to the bittorrent protocol. Supporting this protocol makes
it easy to add new extensions without interfering with the standard
bittorrent protocol or clients that don't support this extension or the
one you want to add.</p>
<p>To advertise to other clients that you support, one bit from the reserved
bytes is used.</p>
<dl class="docutils">
<dt>Right now, two bits have known usages.</dt>
<dd><ul class="first last simple">
<li>[7] &amp; 1 is used by Mainline for DHT support</li>
<li>[7] &amp; 2 is used by XBT client for peer-exchange support</li>
</ul>
</dd>
</dl>
<p>The bit selected for the extension protocol is bit 20 from the right (counting
starts at 0). So (reserved_byte[5] &amp; 0x10) is the expression to use for checking
if the client supports extended messaging.</p>
<p>Once support for the protocol is established, the client is supposed to
support 1 new message:</p>
<table border="1" class="docutils">
<colgroup>
<col width="86%" />
<col width="14%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">id</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">extended</span></tt></td>
<td>20</td>
</tr>
</tbody>
</table>
<p>This message is sent as any other bittorrent message, with a 4 byte length
prefix and a single byte identifying the message (the single byte being 20
in this case). At the start of the payload of the message, is a single byte
message identifier. This identifier can refer to different extension messages
and only one ID is specified, 0. If the ID is 0, the message is a handshake
message which is described below. The layout of a general <tt class="docutils literal"><span class="pre">extended</span></tt> message
follows (including the message headers used by the bittorrent protocol):</p>
<table border="1" class="docutils">
<colgroup>
<col width="15%" />
<col width="85%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">size</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>uint32_t</td>
<td>length prefix. Specifies the number of bytes for the
entire message. (Big endian)</td>
</tr>
<tr><td>uint8_t</td>
<td>bittorrent message ID, = 20</td>
</tr>
<tr><td>uint8_t</td>
<td>extended message ID. 0 = handshake, &gt;0 = extended
message as specified by the handshake.</td>
</tr>
</tbody>
</table>
<div class="section" id="handshake-message">
<h2><a name="handshake-message">handshake message</a></h2>
<p>The payload of the handshake message is a bencoded dictionary. All items
in the dictionary are optional. Any unknown names should be ignored
by the client. All parts of the dictionary are case sensitive.
This is the defined item in the dictionary:</p>
<table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>m</td>
<td>Dictionary of supported extension messages which maps
names of extensions to identification numbers of each
extension. The only requirement on the identification
numbers is that no extensions share the same. Setting
an extension number to zero means that the extension is
not supported/disabled. The client should ignore any
extension names it doesn't recognize.</td>
</tr>
</tbody>
</table>
<p>Here are two other items that an implementation may choose to support:</p>
<table border="1" class="docutils">
<colgroup>
<col width="11%" />
<col width="89%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">name</th>
<th class="head">description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>p</td>
<td>Local TCP listen port. Allows each side to learn about
the TCP port number of the other side. Note that there is
no need for the receiving side of the connection to send
this extension message, since its port number is already
known.</td>
</tr>
<tr><td>v</td>
<td>Client name and version (as an utf-8 string).
This is a much more reliable way of identifying the
client than relying on the peer id encoding.</td>
</tr>
</tbody>
</table>
<p>The handshake dictionary could also include extended handshake
information, such as support for encrypted headers or anything
imaginable.</p>
<p>An example of what the payload of a handshake message could look like:</p>
<table border="1" class="docutils">
<colgroup>
<col width="36%" />
<col width="64%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head" colspan="2">Dictionary</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">m</span></tt></td>
<td><table border="1" class="first last docutils">
<colgroup>
<col width="88%" />
<col width="12%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head" colspan="2">Dictionary</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">LT_metadata</span></tt></td>
<td>1</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">µT_PEX</span></tt></td>
<td>2</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">p</span></tt></td>
<td>6881</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">v</span></tt></td>
<td>&quot;µTorrent 1.2&quot;</td>
</tr>
</tbody>
</table>
<p>and in the encoded form:</p>
<p><tt class="docutils literal"><span class="pre">d1:md11:LT_metadatai1e6:µT_PEXi2ee1:pi6881e1:v13:\xc2\xb5Torrent</span> <span class="pre">1.2e</span></tt></p>
<p>To make sure the extension names do not collide by mistake, they should be
prefixed with the two (or one) character code that is used to identify the
client that introduced the extension. This applies for both the names of
extension messages, and for any additional information put inside the
top-level dictionary. All one and two byte identifiers are invalid to use
unless defined by this specification.</p>
<p>This message should be sent immediately after the standard bittorrent handshake
to any peer that supports this extension protocol. It is valid to send the
handshake message more than once during the lifetime of a connection,
the sending client should not be disconnected. An implementation may choose
to ignore the subsequent handshake messages (or parts of them).</p>
<p>Subsequent handshake messages can be used to enable/disable extensions
without restarting the connection. If a peer supports changing extensions
at run time, it should note that the <tt class="docutils literal"><span class="pre">m</span></tt> dictionary is additive.
It's enough that it contains the actual <em>CHANGES</em> to the extension list.
To disable the support for <tt class="docutils literal"><span class="pre">LT_metadata</span></tt> at run-time, without affecting
any other extensions, this message should be sent:
<tt class="docutils literal"><span class="pre">d11:LT_metadatai0ee</span></tt>.
As specified above, the value 0 is used to turn off an extension.</p>
<p>The extension IDs must be stored for every peer, becuase every peer may have
different IDs for the same extension.</p>
<p>This specification, deliberately, does not specify any extensions such as
peer-exchange or metadata exchange. This protocol is merely a transport
for the actual extensions to the bittorrent protocol and the extensions
named in the example above (such as <tt class="docutils literal"><span class="pre">p</span></tt>) are just examples of possible
extensions.</p>
</div>
<div class="section" id="rationale">
<h2><a name="rationale">rationale</a></h2>
<p>The reason why the extension messages' IDs would be defined in the handshake
is to avoid having a global registry somewhere, where ID's are assigned
global identifiers. Now the extensions have unique names.</p>
<p>If the client supporting the extensions can decide which numbers the messages
it receives will have, it means they are constants within that client. i.e.
they can be used in <tt class="docutils literal"><span class="pre">switch</span></tt> statements. It's easy for the other end to
store an array with the ID's we expect for each message and use that for
lookups each time it sends an extension message.</p>
<p>The reason for having a dictionary instead of having an array (using
implicitly assigned index numbers to the extensions) is that if a client
want to disable some extensions, the ID numbers would change, and it wouldn't
be able to use constants (and hence, not use them in a <tt class="docutils literal"><span class="pre">switch</span></tt>). If the
messages IDs would map directly to bittorrent message IDs, It would also make
it possible to map extensions in the handshake to existing extensions with
fixed message IDs.</p>
<p>The reasoning behind having a single byte as extended message identifier is
to follow the the bittorrent spec. with its single byte message identifiers.
It is also considered to be enough. It won't limit the total number of
extensions, only the number of extensions used simultaneously.</p>
<p>The reason for using single byte identifiers for the standardized handshake
identifiers is 1) The mainline DHT uses single byte identifiers. 2) Saves
bandwidth. The only advantage of longer messages is that it makes the
protocol more readable for a human, but the BT protocol wasn't designed to
be a human readable protocol, so why bother.</p>
</div>
</div>
</div>
</body>
</html>

179
docs/extension_protocol.rst Normal file
View File

@@ -0,0 +1,179 @@
:Author: Arvid Norberg, arvid@rasterbar.com
Ludvig Strigeus, ludde@utorrent.com
extension protocol for bittorrent
=================================
The intention of this protocol is to provide a simple and thin transport
for extensions to the bittorrent protocol. Supporting this protocol makes
it easy to add new extensions without interfering with the standard
bittorrent protocol or clients that don't support this extension or the
one you want to add.
To advertise to other clients that you support, one bit from the reserved
bytes is used.
Right now, two bits have known usages.
* [7] & 1 is used by Mainline for DHT support
* [7] & 2 is used by XBT client for peer-exchange support
The bit selected for the extension protocol is bit 20 from the right (counting
starts at 0). So (reserved_byte[5] & 0x10) is the expression to use for checking
if the client supports extended messaging.
Once support for the protocol is established, the client is supposed to
support 1 new message:
+------------------------+----+
|name | id |
+========================+====+
|``extended`` | 20 |
+------------------------+----+
This message is sent as any other bittorrent message, with a 4 byte length
prefix and a single byte identifying the message (the single byte being 20
in this case). At the start of the payload of the message, is a single byte
message identifier. This identifier can refer to different extension messages
and only one ID is specified, 0. If the ID is 0, the message is a handshake
message which is described below. The layout of a general ``extended`` message
follows (including the message headers used by the bittorrent protocol):
+----------+---------------------------------------------------------+
| size | description |
+==========+=========================================================+
| uint32_t | length prefix. Specifies the number of bytes for the |
| | entire message. (Big endian) |
+----------+---------------------------------------------------------+
| uint8_t | bittorrent message ID, = 20 |
+----------+---------------------------------------------------------+
| uint8_t | extended message ID. 0 = handshake, >0 = extended |
| | message as specified by the handshake. |
+----------+---------------------------------------------------------+
handshake message
-----------------
The payload of the handshake message is a bencoded dictionary. All items
in the dictionary are optional. Any unknown names should be ignored
by the client. All parts of the dictionary are case sensitive.
This is the defined item in the dictionary:
+-------+-----------------------------------------------------------+
| name | description |
+=======+===========================================================+
| m | Dictionary of supported extension messages which maps |
| | names of extensions to identification numbers of each |
| | extension. The only requirement on the identification |
| | numbers is that no extensions share the same. Setting |
| | an extension number to zero means that the extension is |
| | not supported/disabled. The client should ignore any |
| | extension names it doesn't recognize. |
+-------+-----------------------------------------------------------+
Here are two other items that an implementation may choose to support:
+-------+-----------------------------------------------------------+
| name | description |
+=======+===========================================================+
| p | Local TCP listen port. Allows each side to learn about |
| | the TCP port number of the other side. Note that there is |
| | no need for the receiving side of the connection to send |
| | this extension message, since its port number is already |
| | known. |
+-------+-----------------------------------------------------------+
| v | Client name and version (as an utf-8 string). |
| | This is a much more reliable way of identifying the |
| | client than relying on the peer id encoding. |
+-------+-----------------------------------------------------------+
The handshake dictionary could also include extended handshake
information, such as support for encrypted headers or anything
imaginable.
An example of what the payload of a handshake message could look like:
+------------------------------------------------------+
| Dictionary |
+===================+==================================+
| ``m`` | +--------------------------+ |
| | | Dictionary | |
| | +======================+===+ |
| | | ``LT_metadata`` | 1 | |
| | +----------------------+---+ |
| | | ``<EFBFBD>T_PEX`` | 2 | |
| | +----------------------+---+ |
| | |
+-------------------+----------------------------------+
| ``p`` | 6881 |
+-------------------+----------------------------------+
| ``v`` | "<22>Torrent 1.2" |
+-------------------+----------------------------------+
and in the encoded form:
``d1:md11:LT_metadatai1e6:<3A>T_PEXi2ee1:pi6881e1:v13:\xc2\xb5Torrent 1.2e``
To make sure the extension names do not collide by mistake, they should be
prefixed with the two (or one) character code that is used to identify the
client that introduced the extension. This applies for both the names of
extension messages, and for any additional information put inside the
top-level dictionary. All one and two byte identifiers are invalid to use
unless defined by this specification.
This message should be sent immediately after the standard bittorrent handshake
to any peer that supports this extension protocol. It is valid to send the
handshake message more than once during the lifetime of a connection,
the sending client should not be disconnected. An implementation may choose
to ignore the subsequent handshake messages (or parts of them).
Subsequent handshake messages can be used to enable/disable extensions
without restarting the connection. If a peer supports changing extensions
at run time, it should note that the ``m`` dictionary is additive.
It's enough that it contains the actual *CHANGES* to the extension list.
To disable the support for ``LT_metadata`` at run-time, without affecting
any other extensions, this message should be sent:
``d11:LT_metadatai0ee``.
As specified above, the value 0 is used to turn off an extension.
The extension IDs must be stored for every peer, becuase every peer may have
different IDs for the same extension.
This specification, deliberately, does not specify any extensions such as
peer-exchange or metadata exchange. This protocol is merely a transport
for the actual extensions to the bittorrent protocol and the extensions
named in the example above (such as ``p``) are just examples of possible
extensions.
rationale
---------
The reason why the extension messages' IDs would be defined in the handshake
is to avoid having a global registry somewhere, where ID's are assigned
global identifiers. Now the extensions have unique names.
If the client supporting the extensions can decide which numbers the messages
it receives will have, it means they are constants within that client. i.e.
they can be used in ``switch`` statements. It's easy for the other end to
store an array with the ID's we expect for each message and use that for
lookups each time it sends an extension message.
The reason for having a dictionary instead of having an array (using
implicitly assigned index numbers to the extensions) is that if a client
want to disable some extensions, the ID numbers would change, and it wouldn't
be able to use constants (and hence, not use them in a ``switch``). If the
messages IDs would map directly to bittorrent message IDs, It would also make
it possible to map extensions in the handshake to existing extensions with
fixed message IDs.
The reasoning behind having a single byte as extended message identifier is
to follow the the bittorrent spec. with its single byte message identifiers.
It is also considered to be enough. It won't limit the total number of
extensions, only the number of extensions used simultaneously.
The reason for using single byte identifiers for the standardized handshake
identifiers is 1) The mainline DHT uses single byte identifiers. 2) Saves
bandwidth. The only advantage of longer messages is that it makes the
protocol more readable for a human, but the BT protocol wasn't designed to
be a human readable protocol, so why bother.

File diff suppressed because it is too large Load Diff

View File

@@ -30,6 +30,7 @@ following features:
* serves multiple torrents on a single port and a single thread
* supports http proxies and proxy authentication
* gzipped tracker-responses
* `HTTP seeding`_, as `specified by Michael Burford of GetRight`__.
* piece picking on block-level like in Azureus_ (as opposed to piece-level).
This means it can download parts of the same piece from different peers.
It will also prefer to download whole pieces from single peers if the
@@ -64,13 +65,19 @@ following features:
* ip filter
__ http://home.elp.rr.com/tur/multitracker-spec.txt
__ http://www.getright.com/seedtorrent.html
.. _Azureus: http://azureus.sourceforge.net
__ extension_protocol.html
__ udp_tracker_protocol.html
libtorrent is portable at least among Windows, MacOS X and other UNIX-systems. It uses Boost.Thread,
Boost.Filesystem, Boost.Date_time and various other boost libraries as well as zlib.
libtorrent is portable at least among Windows, MacOS X and other UNIX-systems.
It uses Boost.Thread, Boost.Filesystem, Boost.Date_time and various other
boost libraries as well as zlib_ (shipped) and asio_ (shipped). At least version
1.33.1 of boost is required.
.. _zlib: http://www.zlib.org
.. _asio: http://asio.sf.net
libtorrent has been successfully compiled and tested on:
@@ -255,6 +262,10 @@ The ``Jamfile`` has the following build variants:
* ``debug_log`` - debug version with standard logging
* ``debug_vlog`` - debug version with verbose logging
When building the example client on windows, you need to build with
``link=static`` otherwise you may get unresolved external symbols for some
boost.program-options symbols.
building with autotools
-----------------------
@@ -983,6 +994,7 @@ The ``torrent_info`` has the following synopsis::
void set_hash(int index, sha1_hash const& h);
void add_tracker(std::string const& url, int tier = 0);
void add_file(boost::filesystem::path file, size_type size);
void add_url_seed(std::string const& url);
typedef std::vector<file_entry>::const_iterator file_iterator;
typedef std::vector<file_entry>::const_reverse_iterator
@@ -996,8 +1008,15 @@ The ``torrent_info`` has the following synopsis::
int num_files() const;
file_entry const& file_at(int index) const;
std::vector<file_slice> map_block(int piece, size_type offset
, int size) const;
peer_request map_file(int file_index, size_type file_offset
, int size) const;
std::vector<announce_entry> const& trackers() const;
std::vector<std::string> const& url_seeds() const;
size_type total_size() const;
size_type piece_length() const;
int num_pieces() const;
@@ -1138,6 +1157,81 @@ If you need index-access to files you can use the ``num_files()`` and ``file_at(
to access files using indices.
map_block()
-----------
::
std::vector<file_slice> map_block(int piece, size_type offset
, int size) const;
This function will map a piece index, a byte offset within that piece and
a size (in bytes) into the corresponding files with offsets where that data
for that piece is supposed to be stored.
The file slice struct looks like this::
struct file_slice
{
int file_index;
size_type offset;
size_type size;
};
The ``file_index`` refers to the index of the file (in the torrent_info).
To get the path and filename, use ``file_at()`` and give the ``file_index``
as argument. The ``offset`` is the byte offset in the file where the range
starts, and ``size`` is the number of bytes this range is. The size + offset
will never be greater than the file size.
map_file()
----------
::
peer_request map_file(int file_index, size_type file_offset
, int size) const;
This function will map a range in a specific file into a range in the torrent.
The ``file_offset`` parameter is the offset in the file, given in bytes, where
0 is the start of the file.
The ``peer_request`` structure looks like this::
struct peer_request
{
int piece;
int start;
int length;
bool operator==(peer_request const& r) const;
};
``piece`` is the index of the piece in which the range starts.
``start`` is the offset within that piece where the range starts.
``length`` is the size of the range, in bytes.
The input range is assumed to be valid within the torrent. ``file_offset``
+ ``size`` is not allowed to be greater than the file size. ``file_index``
must refer to a valid file, i.e. it cannot be >= ``num_files()``.
url_seeds()
-----------
::
std::vector<std::string> const& url_seeds() const;
void add_url_seed(std::string const& url);
If there are any url-seeds in this torrent, ``url_seeds()`` will return a
vector of those urls. If you're creating a torrent file, ``add_url_seed()``
adds one url to the list of url-seeds. Currently, the only transport protocol
supported for the url is http.
See `HTTP seeding`_ for more information.
print()
-------
@@ -1202,6 +1296,8 @@ hash_for_piece() info_hash()
``hash_for_piece()`` takes a piece-index and returns the 20-bytes sha1-hash for that
piece and ``info_hash()`` returns the 20-bytes sha1-hash for the info-section of the
torrent file. For more information on the ``sha1_hash``, see the big_number_ class.
``info_hash()`` will only return a valid hash if the torrent_info was read from a
``.torrent`` file or if an ``entry`` was created from it (through ``create_torrent``).
name() comment() creation_date() creator()
@@ -1250,7 +1346,7 @@ Its declaration looks like this::
entry write_resume_data() const;
std::vector<char> const& metadata() const;
void force_reannounce() const;
void connect_peer(address const& adr) const;
void connect_peer(asio::ipv4::tcp::endpoint const& adr) const;
void set_tracker_login(std::string const& username
, std::string const& password) const;
@@ -1258,11 +1354,17 @@ Its declaration looks like this::
std::vector<announce_entry> const& trackers() const;
void replace_trackers(std::vector<announce_entry> const&);
void add_url_seed(std::string const& url);
void set_ratio(float ratio) const;
void set_max_uploads(int max_uploads) const;
void set_max_connections(int max_connections) const;
void set_upload_limit(int limit) const;
void set_download_limit(int limit) const;
void set_peer_upload_limit(asio::ipv4::tcp::endpoint ip, int limit) const;
void set_peer_download_limit(asio::ipv4::tcp::endpoint ip, int limit) const;
void use_interface(char const* net_interface) const;
void pause() const;
@@ -1336,7 +1438,7 @@ connect_peer()
::
void connect_peer(address const& adr) const;
void connect_peer(asio::ipv4::tcp::endpoint const& adr) const;
``connect_peer()`` is a way to manually connect to peers that one believe is a part of the
torrent. If the peer does not respond, or is not a member of this torrent, it will simply
@@ -1377,6 +1479,16 @@ Note that setting a higher limit on a torrent then the global limit (``session::
will not override the global rate limit. The torrent can never upload more than the global rate
limit.
set_peer_upload_limit() set_peer_download_limit()
-------------------------------------------------
::
void set_peer_upload_limit(asio::ipv4::tcp::endpoint ip, int limit) const;
void set_peer_download_limit(asio::ipv4::tcp::endpoint ip, int limit) const;
Works like ``set_upload_limit`` and ``set_download_limit`` respectively, but controls individual
peer instead of the whole torrent.
pause() resume() is_paused()
----------------------------
@@ -1445,6 +1557,21 @@ replace it. If you want an immediate effect, you have to call
`force_reannounce()`_.
add_url_seed()
--------------
::
void add_url_seed(std::string const& url);
``add_url_seed()`` adds another url to the torrent's list of url seeds. If the
given url already exists in that list, the call has no effect. The torrent
will connect to the server and try to download pieces from it, unless it's
paused, queued, checking or seeding.
See `HTTP seeding`_ for more information.
use_interface()
---------------
@@ -1649,6 +1776,7 @@ It contains the following fields::
size_type total_payload_upload;
size_type total_failed_bytes;
size_type total_redundant_bytes;
float download_rate;
float upload_rate;
@@ -1662,6 +1790,8 @@ It contains the following fields::
int num_incomplete;
const std::vector<bool>* pieces;
int num_pieces;
size_type total_done;
size_type total_wanted_done;
size_type total_wanted;
@@ -1727,10 +1857,24 @@ data), these counters ignore any protocol overhead.
has failed the piece hash test. In other words, this is just how much crap that
has been downloaded.
``total_redundant_bytes`` is the number of bytes that has been downloaded even
though that data already was downloaded. The reason for this is that in some
situations the same data can be downloaded by mistake. When libtorrent sends
requests to a peer, and the peer doesn't send a response within a certain
timeout, libtorrent will re-request that block. Another situation when
libtorrent will re-request blocks is when the requests it sends out are not
replyed in FIFO-order (it will re-request blocks that are skipped by an out of
order block). This is supposed to be as low as possible.
``pieces`` is the bitmask that represents which pieces we have (set to true) and
the pieces we don't have. It's a pointer and may be set to 0 if the torrent isn't
downloading or seeding.
``num_pieces`` is the number of pieces that has been downloaded. It is equivalent
to: ``std::accumulate(pieces->begin(), pieces->end())``. So you don't have to
count yourself. This can be used to see if anything has updated since last time
if you want to keep a graph of the pieces up to date.
``download_rate`` and ``upload_rate`` are the total rates for all peers for this
torrent. These will usually have better precision than summing the rates from
all peers. The rates are given as the number of bytes per second. The
@@ -1793,22 +1937,23 @@ It contains the following fields::
remote_choked = 0x8,
supports_extensions = 0x10,
local_connection = 0x20,
connecting = 0x40,
queued = 0x80
handshake = 0x40,
connecting = 0x80,
queued = 0x100
};
unsigned int flags;
address ip;
asio::ipv4::tcp::endpoint ip;
float up_speed;
float down_speed;
float payload_up_speed;
float payload_down_speed;
size_type total_download;
size_type total_upload;
peer_id id;
peer_id pid;
std::vector<bool> pieces;
bool seed;
int upload_limit;
int upload_ceiling;
int download_limit;
size_type load_balancing;
@@ -1819,6 +1964,15 @@ It contains the following fields::
int downloading_block_index;
int downloading_progress;
int downloading_total;
std::string client;
enum
{
standard_bittorrent = 0,
web_seed = 1
};
int connection_type;
};
The ``flags`` attribute tells you in which state the peer is. It is set to
@@ -1838,10 +1992,14 @@ any combination of the enums above. The following table describes each flag:
+-------------------------+-------------------------------------------------------+
| ``local_connection`` | The connection was initiated by us, the peer has a |
| | listen port open, and that port is the same as in the |
| | address_ of this peer. If this flag is not set, this |
| | address of this peer. If this flag is not set, this |
| | peer connection was opened by this peer connecting to |
| | us. |
+-------------------------+-------------------------------------------------------+
| ``handshake`` | The connection is opened, and waiting for the |
| | handshake. Until the handshake is done, the peer |
| | cannot be identified. |
+-------------------------+-------------------------------------------------------+
| ``connecting`` | The connection is in a half-open state (i.e. it is |
| | being connected). |
+-------------------------+-------------------------------------------------------+
@@ -1852,8 +2010,10 @@ any combination of the enums above. The following table describes each flag:
__ extension_protocol.html
The ``ip`` field is the IP-address to this peer. Its type is a wrapper around the
actual address and the port number. See address_ class.
The ``ip`` field is the IP-address to this peer. The type is an asio endpoint. For
more info, see the asio_ documentation.
.. _asio: http://asio.sf.net
``up_speed`` and ``down_speed`` contains the current upload and download speed
we have to and from this peer (including any protocol messages). The transfer rates
@@ -1864,7 +2024,7 @@ These figures are updated aproximately once every second.
from and uploaded to this peer. These numbers do not include the protocol chatter, but only
the payload data.
``id`` is the peer's id as used in the bit torrent protocol. This id can be used to
``pid`` is the peer's id as used in the bit torrent protocol. This id can be used to
extract 'fingerprints' from the peer. Sometimes it can tell you which client the peer
is using. See identify_client()_
@@ -1878,9 +2038,8 @@ or if the peer miss that piece (set to false).
peer every second. It may be -1 if there's no limit. The upload limits of all peers
should sum up to the upload limit set by ``session::set_upload_limit``.
``upload_ceiling`` is the current maximum allowed upload rate given the cownload
rate and share ratio. If the global upload rate is inlimited, the ``upload_limit``
for every peer will be the same as their ``upload_ceiling``.
``download_limit`` is the number of bytes per second this peer is allowed to
receive. -1 means it's unlimited.
``load_balancing`` is a measurment of the balancing of free download (that we get)
and free upload that we give. Every peer gets a certain amount of free upload, but
@@ -1903,44 +2062,14 @@ block (or sub-piece) that is being downloaded. ``downloading_progress`` is the n
of bytes of this block we have received from the peer, and ``downloading_total`` is
the total number of bytes in this block.
``client`` is a string describing the software at the other end of the connection.
In some cases this information is not available, then it will contain a string
that may give away something about which software is running in the other end.
In the case of a web seed, the server type and version will be a part of this
string.
address
=======
The ``address`` class represents a name of a network endpoint (usually referred to as
IP-address) and a port number. This is the same thing as a ``sockaddr_in`` would contain.
Its declaration looks like this::
class address
{
public:
address();
address(unsigned char a
, unsigned char b
, unsigned char c
, unsigned char d
, unsigned short port);
address(unsigned int addr, unsigned short port);
address(const std::string& addr, unsigned short port);
address(const address& a);
~address();
std::string as_string() const;
unsigned int ip() const;
unsigned short port() const;
bool operator<(const address& a) const;
bool operator!=(const address& a) const;
bool operator==(const address& a) const;
};
It is less-than comparable to make it possible to use it as a key in a map. ``as_string()`` may block
while it does the DNS lookup, it returns a string that points to the address represented by the object.
``ip()`` will return the 32-bit ip-address as an integer. ``port()`` returns the port number.
``connection_type`` can currently be one of ``standard_bittorrent`` or
``web_seed``. These are currently the only implemented protocols.
http_settings
=============
@@ -1960,7 +2089,8 @@ that will be sent to the tracker. The user-agent is a good way to identify your
std::string proxy_login;
std::string proxy_password;
std::string user_agent;
int tracker_timeout;
int tracker_completion_timeout;
int tracker_receive_timeout;
int tracker_maximum_response_length;
};
@@ -1978,10 +2108,18 @@ empty, the http proxy will be tried to be used without authentication.
``user_agent`` this is the client identification to the tracker. It will
be followed by the string "(libtorrent)" to identify that this library
is being used. This should be set to your client's name and version number.
This name will not only be used when making HTTP requests, but also when
sending extended headers to peers that support that extension.
``tracker_timeout`` is the number of seconds the tracker connection will
wait until it considers the tracker to have timed-out. Default value is 10
seconds.
``tracker_completion_timeout`` is the number of seconds the tracker
connection will wait from when it sent the request until it considers the
tracker to have timed-out. Default value is 60 seconds.
``tracker_receive_timeout`` is the number of seconds to wait to receive
any data from the tracker. If no data is received for this number of
seconds, the tracker will be considered as having timed out. If a tracker
is down, this is the kind of timeout that will occur. The default value
is 20 seconds.
``tracker_maximum_response_length`` is the maximum number of bytes in a
tracker response. If a response size passes this number it will be rejected
@@ -1998,6 +2136,8 @@ ip_filter
The ``ip_filter`` class is a set of rules that uniquely categorizes all
ip addresses as allowed or disallowed. The default constructor creates
a single rule that allowes all addresses (0.0.0.0 - 255.255.255.255).
The ``address`` type here is ``asio::ipv4::address``. It can also be
accessed as ``libtorrent::address``.
::
@@ -2112,8 +2252,9 @@ This class creates sha1-hashes. Its declaration looks like this::
{
public:
hasher();
hasher(char const* data, unsigned int len);
void update(const char* data, unsigned int len);
void update(char const* data, unsigned int len);
sha1_hash final();
void reset();
};
@@ -2125,6 +2266,9 @@ create the hash in memory. You can feed the hasher parts of it at a time. When
You have fed the hasher with all the data, you call ``final()`` and it
will return the sha1-hash of the data.
The constructor that takes a ``char const*`` and an integer will construct the
sha1 context and feed it the data passed in.
If you want to reuse the hasher object once you have created a hash, you have to
call ``reset()`` to reinitialize it.
@@ -2147,7 +2291,7 @@ This is the class declaration::
std::string to_string() const;
char id[2];
char name[2];
char major_version;
char minor_version;
char revision_version;
@@ -2458,6 +2602,25 @@ the tracker. It is generated with severity level ``warning``.
};
url_seed_alert
--------------
This alert is generated when a HTTP seed name lookup fails. This alert is
generated as severity level ``warning``.
It contains ``url`` to the HTTP seed that failed along with an error message.
::
struct url_seed_alert: alert
{
url_seed_alert(std::string const& h, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
std::string url;
};
hash_failed_alert
-----------------
@@ -2493,12 +2656,12 @@ to the torrent that this peer was a member of.
struct peer_ban_alert: alert
{
peer_ban_alert(
address const& pip
asio::ipv4::tcp::endpoint const& pip
, torrent_handle h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
address ip;
asio::ipv4::tcp::endpoint ip;
torrent_handle handle;
};
@@ -2515,12 +2678,12 @@ is generated as severity level ``debug``.
struct peer_error_alert: alert
{
peer_error_alert(
address const& pip
asio::ipv4::tcp::endpoint const& pip
, peer_id const& pid
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
address ip;
asio::ipv4::tcp::endpoint ip;
peer_id id;
};
@@ -2540,13 +2703,13 @@ is a handle to the torrent the peer is a member of. ``
invalid_request_alert(
peer_request const& r
, torrent_handle const& h
, address const& send
, asio::ipv4::tcp::endpoint const& send
, peer_id const& pid
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
torrent_handle handle;
address ip;
asio::ipv4::tcp::endpoint ip;
peer_request request;
peer_id id;
};
@@ -3292,6 +3455,20 @@ Don't have metadata:
| | | doesn't have any metadata. |
+-----------+---------------+----------------------------------------+
HTTP seeding
------------
The HTTP seed extension implements `this specification`__.
The libtorrent implementation assumes that, if the URL ends with a slash
('/'), the filename should be appended to it in order to request pieces from
that file. The way this works is that if the torrent is a single-file torrent,
only that filename is appended. If the torrent is a multi-file torrent, the
torrent's name '/' the file name is appended. This is the same directory
structure that libtorrent will download torrents into.
__ http://www.getright.com/seedtorrent.html
filename checks
===============