added documentation of udp-tracker protocol and finalized support for it.
This commit is contained in:
parent
b897315abb
commit
a3b47ec826
|
@ -59,8 +59,8 @@ example client.</p>
|
|||
</div>
|
||||
<div class="section" id="aknowledgements">
|
||||
<h1><a name="aknowledgements">Aknowledgements</a></h1>
|
||||
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
||||
<p>Contributions by Magnus Jonsson</p>
|
||||
<p>Written by Arvid Norberg. Copyright (c) 2003</p>
|
||||
<p>Contributions by Magnus Jonsson and Daniel Wallin</p>
|
||||
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
||||
<p>Project is hosted by sourceforge.</p>
|
||||
<p><a class="reference" href="http://sourceforge.net"><img alt="sf_logo" src="http://sourceforge.net/sflogo.php?group_id=7994" /></a></p>
|
||||
|
|
|
@ -60,9 +60,9 @@ You can usually find me as hydri in ``#btports @ irc.freenode.net``.
|
|||
Aknowledgements
|
||||
===============
|
||||
|
||||
Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003
|
||||
Written by Arvid Norberg. Copyright (c) 2003
|
||||
|
||||
Contributions by Magnus Jonsson
|
||||
Contributions by Magnus Jonsson and Daniel Wallin
|
||||
|
||||
Thanks to Reimond Retz for bugfixes, suggestions and testing
|
||||
|
||||
|
|
|
@ -13,57 +13,57 @@
|
|||
<div class="contents topic" id="contents">
|
||||
<p class="topic-title"><a name="contents">Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#introduction" id="id8" name="id8">introduction</a></li>
|
||||
<li><a class="reference" href="#building" id="id9" name="id9">building</a></li>
|
||||
<li><a class="reference" href="#using" id="id10" name="id10">using</a></li>
|
||||
<li><a class="reference" href="#session" id="id11" name="id11">session</a></li>
|
||||
<li><a class="reference" href="#parsing-torrent-files" id="id12" name="id12">parsing torrent files</a></li>
|
||||
<li><a class="reference" href="#entry" id="id13" name="id13">entry</a></li>
|
||||
<li><a class="reference" href="#torrent-info" id="id14" name="id14">torrent_info</a></li>
|
||||
<li><a class="reference" href="#torrent-handle" id="id15" name="id15">torrent_handle</a><ul>
|
||||
<li><a class="reference" href="#status" id="id16" name="id16">status()</a></li>
|
||||
<li><a class="reference" href="#get-download-queue" id="id17" name="id17">get_download_queue()</a></li>
|
||||
<li><a class="reference" href="#get-peer-info" id="id18" name="id18">get_peer_info()</a></li>
|
||||
<li><a class="reference" href="#get-torrent-info" id="id19" name="id19">get_torrent_info()</a></li>
|
||||
<li><a class="reference" href="#is-valid" id="id20" name="id20">is_valid()</a></li>
|
||||
<li><a class="reference" href="#introduction" id="id9" name="id9">introduction</a></li>
|
||||
<li><a class="reference" href="#building" id="id10" name="id10">building</a></li>
|
||||
<li><a class="reference" href="#using" id="id11" name="id11">using</a></li>
|
||||
<li><a class="reference" href="#session" id="id12" name="id12">session</a></li>
|
||||
<li><a class="reference" href="#parsing-torrent-files" id="id13" name="id13">parsing torrent files</a></li>
|
||||
<li><a class="reference" href="#entry" id="id14" name="id14">entry</a></li>
|
||||
<li><a class="reference" href="#torrent-info" id="id15" name="id15">torrent_info</a></li>
|
||||
<li><a class="reference" href="#torrent-handle" id="id16" name="id16">torrent_handle</a><ul>
|
||||
<li><a class="reference" href="#status" id="id17" name="id17">status()</a></li>
|
||||
<li><a class="reference" href="#get-download-queue" id="id18" name="id18">get_download_queue()</a></li>
|
||||
<li><a class="reference" href="#get-peer-info" id="id19" name="id19">get_peer_info()</a></li>
|
||||
<li><a class="reference" href="#get-torrent-info" id="id20" name="id20">get_torrent_info()</a></li>
|
||||
<li><a class="reference" href="#is-valid" id="id21" name="id21">is_valid()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#address" id="id21" name="id21">address</a></li>
|
||||
<li><a class="reference" href="#http-settings" id="id22" name="id22">http_settings</a></li>
|
||||
<li><a class="reference" href="#big-number" id="id23" name="id23">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id24" name="id24">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id25" name="id25">fingerprint</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id26" name="id26">identify_client</a></li>
|
||||
<li><a class="reference" href="#address" id="id22" name="id22">address</a></li>
|
||||
<li><a class="reference" href="#http-settings" id="id23" name="id23">http_settings</a></li>
|
||||
<li><a class="reference" href="#big-number" id="id24" name="id24">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id25" name="id25">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id26" name="id26">fingerprint</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id27" name="id27">identify_client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#alerts" id="id27" name="id27">alerts</a><ul>
|
||||
<li><a class="reference" href="#tracker-alert" id="id28" name="id28">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id29" name="id29">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id30" name="id30">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id31" name="id31">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id32" name="id32">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id33" name="id33">dispatcher</a></li>
|
||||
<li><a class="reference" href="#alerts" id="id28" name="id28">alerts</a><ul>
|
||||
<li><a class="reference" href="#tracker-alert" id="id29" name="id29">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id30" name="id30">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id31" name="id31">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id32" name="id32">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id33" name="id33">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id34" name="id34">dispatcher</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#exceptions" id="id34" name="id34">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id35" name="id35">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id36" name="id36">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id37" name="id37">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id38" name="id38">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id39" name="id39">invalid_torrent_file</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id35" name="id35">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id36" name="id36">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id37" name="id37">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id38" name="id38">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id39" name="id39">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id40" name="id40">invalid_torrent_file</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#examples" id="id40" name="id40">examples</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id41" name="id41">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id42" name="id42">simple client</a></li>
|
||||
<li><a class="reference" href="#examples" id="id41" name="id41">examples</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id42" name="id42">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id43" name="id43">simple client</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#fast-resume" id="id43" name="id43">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id44" name="id44">file format</a></li>
|
||||
<li><a class="reference" href="#fast-resume" id="id44" name="id44">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id45" name="id45">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#extensions" id="id45" name="id45">extensions</a></li>
|
||||
<li><a class="reference" href="#aknowledgements" id="id46" name="id46">Aknowledgements</a></li>
|
||||
<li><a class="reference" href="#extensions" id="id46" name="id46">extensions</a></li>
|
||||
<li><a class="reference" href="#aknowledgements" id="id47" name="id47">Aknowledgements</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
|
@ -103,6 +103,7 @@ peers in a separate fast-resume file.</li>
|
|||
<li>Supports the extension protocol <a class="reference" href="http://nolar.com/azureus/extended.htm">described by Nolar</a>. See <a class="reference" href="#extensions">extensions</a>.</li>
|
||||
<li>Supports files > 2 gigabytes (currently only on windows).</li>
|
||||
<li>Supports the <tt class="literal"><span class="pre">no_peer_id=1</span></tt> extension that will ease the load off trackers.</li>
|
||||
<li>Supports the <a class="reference" href="udp_tracker_protocol.html">udp-tracker protocol</a>.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>Functions that are yet to be implemented:</p>
|
||||
|
@ -223,7 +224,7 @@ The main thread will be idle as long it doesn't have any torrents to participate
|
|||
You add torrents through the <tt class="literal"><span class="pre">add_torrent()</span></tt>-function where you give an
|
||||
object representing the information found in the torrent file and the path where you
|
||||
want to save the files. The <tt class="literal"><span class="pre">save_path</span></tt> will be prepended to the directory-
|
||||
structure in the torrent-file. <tt class="literal"><span class="pre">add_torrent</span></tt> will throw <tt class="literal"><span class="pre">duplicate_torrent</span></tt> exception
|
||||
structure in the torrent-file. <tt class="literal"><span class="pre">add_torrent</span></tt> will throw <a class="reference" href="#duplicate-torrent">duplicate_torrent</a> exception
|
||||
if the torrent already exists in the session.</p>
|
||||
<p>The optional last parameter, <tt class="literal"><span class="pre">resume_data</span></tt> can be given if up to date fast-resume data
|
||||
is available. The fast-resume data can be acquired from a running torrent by calling
|
||||
|
@ -232,7 +233,7 @@ is available. The fast-resume data can be acquired from a running torrent by cal
|
|||
the tracker that we've stopped participating in the swarm.</p>
|
||||
<p>If the torrent you are trying to add already exists in the session (is either queued
|
||||
for checking, being checked or downloading) <tt class="literal"><span class="pre">add_torrent()</span></tt> will throw
|
||||
<tt class="literal"><span class="pre">duplicate_torrent</span></tt> which derives from <tt class="literal"><span class="pre">std::exception</span></tt>.</p>
|
||||
<a class="reference" href="#duplicate-torrent">duplicate_torrent</a> which derives from <tt class="literal"><span class="pre">std::exception</span></tt>.</p>
|
||||
<p>The difference between the two constructors is that one of them takes a fingerprint
|
||||
as argument. If this is ommited, the client will get a default fingerprint stating
|
||||
the version of libtorrent. The fingerprint is a short string that will be used in
|
||||
|
@ -246,7 +247,6 @@ If some trackers are down, they will timout. All this before the destructor of s
|
|||
returns. So, it's adviced that any kind of interface (such as windows) are closed before
|
||||
destructing the sessoin object. Because it can take a few second for it to finish. The
|
||||
timeout can be set with <tt class="literal"><span class="pre">set_http_settings()</span></tt>.</p>
|
||||
<p>How to parse a torrent file and create a <tt class="literal"><span class="pre">torrent_info</span></tt> object is described below.</p>
|
||||
<p>The <a class="reference" href="#torrent-handle">torrent_handle</a> returned by <tt class="literal"><span class="pre">add_torrent</span></tt> can be used to retrieve information
|
||||
about the torrent's progress, its peers etc. It is also used to abort a torrent.</p>
|
||||
<p>The constructor takes a listen port as argument, if the given port is busy it will
|
||||
|
@ -486,6 +486,7 @@ struct torrent_handle
|
|||
boost::filsystem::path save_path() const;
|
||||
|
||||
void set_max_uploads(int max_uploads);
|
||||
void set_max_connections(int max_connections);
|
||||
|
||||
sha1_hash info_hash() const;
|
||||
|
||||
|
@ -517,6 +518,10 @@ as a standard client.</p>
|
|||
<p><tt class="literal"><span class="pre">info_hash()</span></tt> returns the info hash for the torrent.</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">set_max_connections()</span></tt> sets the maximum number of connection this torrent will open. If all
|
||||
connections are used up, incoming connections may be refused or poor connections may be closed.
|
||||
This must be at least 2. The default is unlimited number of connections. If -1 is given to the
|
||||
function, it means unlimited.</p>
|
||||
<p><tt class="literal"><span class="pre">write_resume_data()</span></tt> generates fast-resume data and returns it as an entry. This entry
|
||||
is suitable for being bencoded. For more information about how fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>.
|
||||
It may throw <a class="reference" href="#invalid-handle">invalid_handle</a> if the torrent handle is invalid.</p>
|
||||
|
@ -752,7 +757,7 @@ the total number of bytes in this block.</p>
|
|||
</div>
|
||||
<div class="section" id="get-torrent-info">
|
||||
<h2><a name="get-torrent-info">get_torrent_info()</a></h2>
|
||||
<p>Returns a const reference to the <tt class="literal"><span class="pre">torrent_info</span></tt> object associated with this torrent.
|
||||
<p>Returns a const reference to the <a class="reference" href="#torrent-info">torrent_info</a> object associated with this torrent.
|
||||
This reference is valid as long as the <a class="reference" href="#torrent-handle">torrent_handle</a> is valid, no longer. If the
|
||||
<a class="reference" href="#torrent-handle">torrent_handle</a> is invalid, <a class="reference" href="#invalid-handle">invalid_handle</a> exception will be thrown.</p>
|
||||
</div>
|
||||
|
@ -1440,8 +1445,8 @@ with future versions of bittorrent.</p>
|
|||
</div>
|
||||
<div class="section" id="aknowledgements">
|
||||
<h1><a name="aknowledgements">Aknowledgements</a></h1>
|
||||
<p>Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003</p>
|
||||
<p>Contributions by Magnus Jonsson</p>
|
||||
<p>Written by Arvid Norberg. Copyright (c) 2003</p>
|
||||
<p>Contributions by Magnus Jonsson and Daniel Wallin</p>
|
||||
<p>Thanks to Reimond Retz for bugfixes, suggestions and testing</p>
|
||||
<p>Project is hosted by sourceforge.</p>
|
||||
<p><a class="reference" href="http://sourceforge.net"><img alt="sf_logo" src="http://sourceforge.net/sflogo.php?group_id=7994" /></a></p>
|
||||
|
|
|
@ -40,10 +40,13 @@ The current state includes the following features:
|
|||
* Supports the extension protocol `described by Nolar`__. See extensions_.
|
||||
* Supports files > 2 gigabytes (currently only on windows).
|
||||
* Supports the ``no_peer_id=1`` extension that will ease the load off trackers.
|
||||
* Supports the `udp-tracker protocol`__.
|
||||
|
||||
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
||||
.. _Azureus: http://azureus.sourceforge.net
|
||||
__ http://nolar.com/azureus/extended.htm
|
||||
__ udp_tracker_protocol.html
|
||||
|
||||
|
||||
Functions that are yet to be implemented:
|
||||
|
||||
|
@ -171,7 +174,7 @@ The main thread will be idle as long it doesn't have any torrents to participate
|
|||
You add torrents through the ``add_torrent()``-function where you give an
|
||||
object representing the information found in the torrent file and the path where you
|
||||
want to save the files. The ``save_path`` will be prepended to the directory-
|
||||
structure in the torrent-file. ``add_torrent`` will throw ``duplicate_torrent`` exception
|
||||
structure in the torrent-file. ``add_torrent`` will throw duplicate_torrent_ exception
|
||||
if the torrent already exists in the session.
|
||||
|
||||
The optional last parameter, ``resume_data`` can be given if up to date fast-resume data
|
||||
|
@ -183,7 +186,7 @@ the tracker that we've stopped participating in the swarm.
|
|||
|
||||
If the torrent you are trying to add already exists in the session (is either queued
|
||||
for checking, being checked or downloading) ``add_torrent()`` will throw
|
||||
``duplicate_torrent`` which derives from ``std::exception``.
|
||||
duplicate_torrent_ which derives from ``std::exception``.
|
||||
|
||||
The difference between the two constructors is that one of them takes a fingerprint
|
||||
as argument. If this is ommited, the client will get a default fingerprint stating
|
||||
|
@ -201,8 +204,6 @@ returns. So, it's adviced that any kind of interface (such as windows) are close
|
|||
destructing the sessoin object. Because it can take a few second for it to finish. The
|
||||
timeout can be set with ``set_http_settings()``.
|
||||
|
||||
How to parse a torrent file and create a ``torrent_info`` object is described below.
|
||||
|
||||
The torrent_handle_ returned by ``add_torrent`` can be used to retrieve information
|
||||
about the torrent's progress, its peers etc. It is also used to abort a torrent.
|
||||
|
||||
|
@ -487,6 +488,7 @@ Its declaration looks like this::
|
|||
boost::filsystem::path save_path() const;
|
||||
|
||||
void set_max_uploads(int max_uploads);
|
||||
void set_max_connections(int max_connections);
|
||||
|
||||
sha1_hash info_hash() const;
|
||||
|
||||
|
@ -526,6 +528,11 @@ as a standard client.
|
|||
``set_max_uploads()`` 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.
|
||||
|
||||
``set_max_connections()`` sets the maximum number of connection this torrent will open. If all
|
||||
connections are used up, incoming connections may be refused or poor connections may be closed.
|
||||
This must be at least 2. The default is unlimited number of connections. If -1 is given to the
|
||||
function, it means unlimited.
|
||||
|
||||
``write_resume_data()`` generates fast-resume data and returns it as an entry. This entry
|
||||
is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_.
|
||||
It may throw invalid_handle_ if the torrent handle is invalid.
|
||||
|
@ -772,7 +779,7 @@ the total number of bytes in this block.
|
|||
get_torrent_info()
|
||||
------------------
|
||||
|
||||
Returns a const reference to the ``torrent_info`` object associated with this torrent.
|
||||
Returns a const reference to the torrent_info_ object associated with this torrent.
|
||||
This reference is valid as long as the torrent_handle_ is valid, no longer. If the
|
||||
torrent_handle_ is invalid, invalid_handle_ exception will be thrown.
|
||||
|
||||
|
@ -1514,9 +1521,9 @@ with future versions of bittorrent.
|
|||
Aknowledgements
|
||||
===============
|
||||
|
||||
Written by Arvid Norberg and Daniel Wallin. Copyright (c) 2003
|
||||
Written by Arvid Norberg. Copyright (c) 2003
|
||||
|
||||
Contributions by Magnus Jonsson
|
||||
Contributions by Magnus Jonsson and Daniel Wallin
|
||||
|
||||
Thanks to Reimond Retz for bugfixes, suggestions and testing
|
||||
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
<?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.1: http://docutils.sourceforge.net/" />
|
||||
<title>Bittorrent udp-tracker protocol extension</title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="bittorrent-udp-tracker-protocol-extension">
|
||||
<h1 class="title">Bittorrent udp-tracker protocol extension</h1>
|
||||
<p>A tracker with the protocol "udp://" in its URI
|
||||
is supposed to be contacted using this protocol.</p>
|
||||
<p>This protocol is supported by
|
||||
<a class="reference" href="http://xbtt.sourceforge.net">xbt-tracker</a>.</p>
|
||||
<p>For additional information and descritptions of
|
||||
the terminology used in this document, see
|
||||
the <a class="reference" href="http://wiki.theory.org/index.php/BitTorrentSpecification">protocol specification</a></p>
|
||||
<p>All values are sent in network byte order (big endian). The sizes
|
||||
are specified with ANSI-C standard types.</p>
|
||||
<p>If no response to a request is received within 15 seconds, resend
|
||||
the request. If no reply has been received after 60 seconds, stop
|
||||
retrying.</p>
|
||||
<div class="section" id="connecting">
|
||||
<h1><a name="connecting">connecting</a></h1>
|
||||
<p>Client sends packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int64_t</td>
|
||||
<td>connection_id</td>
|
||||
<td>Not used, ignored by tracker.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>0 for a connection request</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Randomized by client.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Server replies with packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>Describes the type of packet, in this
|
||||
case it should be 0, for connect.
|
||||
If 3 (for error) see <a class="reference" href="#errors">errors</a>.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Must match the transaction_id sent
|
||||
from the client.</td>
|
||||
</tr>
|
||||
<tr><td>int64_t</td>
|
||||
<td>connection_id</td>
|
||||
<td>A connection id, this is used when
|
||||
further information is exchanged with
|
||||
the tracker, to identify you.
|
||||
This connection id can be reused for
|
||||
multiple requests, but if it's cached
|
||||
for too long, it will not be valid
|
||||
anymore.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="announcing">
|
||||
<h1><a name="announcing">announcing</a></h1>
|
||||
<p>Client sends packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int64_t</td>
|
||||
<td>connection_id</td>
|
||||
<td>The connection id acquired from
|
||||
establishing the connection.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>Action. in this case, 1 for announce.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Randomized by client.</td>
|
||||
</tr>
|
||||
<tr><td>int8_t[20]</td>
|
||||
<td>info_hash</td>
|
||||
<td>The info-hash of the torrent you want
|
||||
announce yourself in.</td>
|
||||
</tr>
|
||||
<tr><td>int8_t[20]</td>
|
||||
<td>peer_id</td>
|
||||
<td>Your peer id.</td>
|
||||
</tr>
|
||||
<tr><td>int64_t</td>
|
||||
<td>downloaded</td>
|
||||
<td>The number of byte you've downloaded
|
||||
in this session.</td>
|
||||
</tr>
|
||||
<tr><td>int64_t</td>
|
||||
<td>left</td>
|
||||
<td>The number of bytes you have left to
|
||||
download until you're finished.</td>
|
||||
</tr>
|
||||
<tr><td>int64_t</td>
|
||||
<td>uploaded</td>
|
||||
<td>The number of bytes you have uploaded
|
||||
in this session.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>event</td>
|
||||
<td><p class="first">The event, one of</p>
|
||||
<blockquote class="last">
|
||||
<ul class="simple">
|
||||
<li>none = 0</li>
|
||||
<li>completed = 1</li>
|
||||
<li>started = 2</li>
|
||||
<li>stopped = 3</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td>uint32_t</td>
|
||||
<td>ip</td>
|
||||
<td>Your ip address. Set to 0 if you want
|
||||
the tracker to use the <tt class="literal"><span class="pre">sender</span></tt> of
|
||||
this udp packet.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>num_want</td>
|
||||
<td>The maximum number of peers you want
|
||||
in the reply. Use -1 for default.</td>
|
||||
</tr>
|
||||
<tr><td>uint16_t</td>
|
||||
<td>port</td>
|
||||
<td>The port you're listening on.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Server replies with packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>The action this is a reply to. Should
|
||||
in this case be 1 for announce.
|
||||
If 3 (for error) see <a class="reference" href="#errors">errors</a>.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Must match the transaction_id sent
|
||||
in the announce request.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>interval</td>
|
||||
<td>the number of seconds you should wait
|
||||
until reannouncing yourself.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The rest of the server reply is a variable number of the following structure:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int32_t</td>
|
||||
<td>ip</td>
|
||||
<td>The ip of a peer in the swarm.</td>
|
||||
</tr>
|
||||
<tr><td>uint16_t</td>
|
||||
<td>port</td>
|
||||
<td>The peers listen port.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="scraping">
|
||||
<h1><a name="scraping">scraping</a></h1>
|
||||
<p>Client sends packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int64_t</td>
|
||||
<td>connection_id</td>
|
||||
<td>The connection id retreived from the
|
||||
establishing of the connection.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>The action, in this case, 2 for
|
||||
scrape.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Randomized by client.</td>
|
||||
</tr>
|
||||
<tr><td>int8[20]</td>
|
||||
<td>info_hash</td>
|
||||
<td>The info hash that is to be scraped.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Server replies with packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>The action, should in this case be
|
||||
2 for scrape.
|
||||
If 3 (for error) see <a class="reference" href="#errors">errors</a>.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Must match the sent transaction id.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The rest of the packet contains a variable number of the following structures:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int8_t[20]</td>
|
||||
<td>info_hash</td>
|
||||
<td>The info hash of this info.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>complete</td>
|
||||
<td>The total number of completed
|
||||
downloads.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>downloaded</td>
|
||||
<td>The current number of connected seeds.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>incomplete</td>
|
||||
<td>The current number of connected
|
||||
leechers.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="errors">
|
||||
<h1><a name="errors">errors</a></h1>
|
||||
<p>In case of a tracker error, the server replies with this packet:</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="18%" />
|
||||
<col width="28%" />
|
||||
<col width="54%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>size</th>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td>int32_t</td>
|
||||
<td>action</td>
|
||||
<td>The action, in this case 3, for error.</td>
|
||||
</tr>
|
||||
<tr><td>int32_t</td>
|
||||
<td>transaction_id</td>
|
||||
<td>Must match the transaction_id sent
|
||||
from the client.</td>
|
||||
</tr>
|
||||
<tr><td>int8[]</td>
|
||||
<td>error_string</td>
|
||||
<td>The rest of the packet is a string
|
||||
describing the error.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="actions">
|
||||
<h1><a name="actions">actions</a></h1>
|
||||
<p>The action fields has the followinf encoding:</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>connect = 0</li>
|
||||
<li>announce = 1</li>
|
||||
<li>scrape = 2</li>
|
||||
<li>error = 3 (only in server replies)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h1><a name="credits">credits</a></h1>
|
||||
<p>Protocol designed by Olaf van der Spek</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,218 @@
|
|||
=========================================
|
||||
Bittorrent udp-tracker protocol extension
|
||||
=========================================
|
||||
|
||||
A tracker with the protocol "udp://" in its URI
|
||||
is supposed to be contacted using this protocol.
|
||||
|
||||
This protocol is supported by
|
||||
xbt-tracker_.
|
||||
|
||||
|
||||
.. _xbt-tracker: http://xbtt.sourceforge.net
|
||||
|
||||
For additional information and descritptions of
|
||||
the terminology used in this document, see
|
||||
the `protocol specification`__
|
||||
|
||||
__ http://wiki.theory.org/index.php/BitTorrentSpecification
|
||||
|
||||
All values are sent in network byte order (big endian). The sizes
|
||||
are specified with ANSI-C standard types.
|
||||
|
||||
If no response to a request is received within 15 seconds, resend
|
||||
the request. If no reply has been received after 60 seconds, stop
|
||||
retrying.
|
||||
|
||||
|
||||
connecting
|
||||
----------
|
||||
|
||||
Client sends packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int64_t | connection_id | Not used, ignored by tracker. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | action | 0 for a connection request |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Randomized by client. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
Server replies with packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int32_t | action | Describes the type of packet, in this |
|
||||
| | | case it should be 0, for connect. |
|
||||
| | | If 3 (for error) see errors_. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Must match the transaction_id sent |
|
||||
| | | from the client. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int64_t | connection_id | A connection id, this is used when |
|
||||
| | | further information is exchanged with |
|
||||
| | | the tracker, to identify you. |
|
||||
| | | This connection id can be reused for |
|
||||
| | | multiple requests, but if it's cached |
|
||||
| | | for too long, it will not be valid |
|
||||
| | | anymore. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
|
||||
announcing
|
||||
----------
|
||||
|
||||
Client sends packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int64_t | connection_id | The connection id acquired from |
|
||||
| | | establishing the connection. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | action | Action. in this case, 1 for announce. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Randomized by client. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int8_t[20] | info_hash | The info-hash of the torrent you want |
|
||||
| | | announce yourself in. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int8_t[20] | peer_id | Your peer id. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int64_t | downloaded | The number of byte you've downloaded |
|
||||
| | | in this session. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int64_t | left | The number of bytes you have left to |
|
||||
| | | download until you're finished. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int64_t | uploaded | The number of bytes you have uploaded |
|
||||
| | | in this session. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | event | The event, one of |
|
||||
| | | |
|
||||
| | | * none = 0 |
|
||||
| | | * completed = 1 |
|
||||
| | | * started = 2 |
|
||||
| | | * stopped = 3 |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| uint32_t | ip | Your ip address. Set to 0 if you want |
|
||||
| | | the tracker to use the ``sender`` of |
|
||||
| | | this udp packet. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | num_want | The maximum number of peers you want |
|
||||
| | | in the reply. Use -1 for default. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| uint16_t | port | The port you're listening on. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
Server replies with packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int32_t | action | The action this is a reply to. Should |
|
||||
| | | in this case be 1 for announce. |
|
||||
| | | If 3 (for error) see errors_. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Must match the transaction_id sent |
|
||||
| | | in the announce request. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | interval | the number of seconds you should wait |
|
||||
| | | until reannouncing yourself. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
The rest of the server reply is a variable number of the following structure:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int32_t | ip | The ip of a peer in the swarm. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| uint16_t | port | The peers listen port. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
|
||||
scraping
|
||||
--------
|
||||
|
||||
Client sends packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int64_t | connection_id | The connection id retreived from the |
|
||||
| | | establishing of the connection. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | action | The action, in this case, 2 for |
|
||||
| | | scrape. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Randomized by client. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int8[20] | info_hash | The info hash that is to be scraped. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
Server replies with packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int32_t | action | The action, should in this case be |
|
||||
| | | 2 for scrape. |
|
||||
| | | If 3 (for error) see errors_. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Must match the sent transaction id. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
The rest of the packet contains a variable number of the following structures:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int8_t[20] | info_hash | The info hash of this info. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | complete | The total number of completed |
|
||||
| | | downloads. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | downloaded | The current number of connected seeds. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | incomplete | The current number of connected |
|
||||
| | | leechers. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
errors
|
||||
------
|
||||
|
||||
In case of a tracker error, the server replies with this packet:
|
||||
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| size | name | description |
|
||||
+=============+=====================+========================================+
|
||||
| int32_t | action | The action, in this case 3, for error. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int32_t | transaction_id | Must match the transaction_id sent |
|
||||
| | | from the client. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
| int8[] | error_string | The rest of the packet is a string |
|
||||
| | | describing the error. |
|
||||
+-------------+---------------------+----------------------------------------+
|
||||
|
||||
|
||||
actions
|
||||
-------
|
||||
|
||||
The action fields has the followinf encoding:
|
||||
|
||||
* connect = 0
|
||||
* announce = 1
|
||||
* scrape = 2
|
||||
* error = 3 (only in server replies)
|
||||
|
||||
|
||||
credits
|
||||
-------
|
||||
|
||||
Protocol designed by Olaf van der Spek
|
||||
|
|
@ -68,96 +68,101 @@ namespace libtorrent
|
|||
{
|
||||
struct session_impl;
|
||||
|
||||
template <class T> struct type {};
|
||||
|
||||
// reads an integer from a byte stream
|
||||
// in big endian byte order and converts
|
||||
// it to native endianess
|
||||
template <class InIt>
|
||||
unsigned int read_uint(InIt& start)
|
||||
template <class T, class InIt>
|
||||
inline T read_impl(InIt& start, type<T>)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
val |= static_cast<unsigned char>(*start) << 24; ++start;
|
||||
val |= static_cast<unsigned char>(*start) << 16; ++start;
|
||||
val |= static_cast<unsigned char>(*start) << 8; ++start;
|
||||
val |= static_cast<unsigned char>(*start); ++start;
|
||||
return val;
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
inline int read_int(InIt& start)
|
||||
{
|
||||
return static_cast<int>(read_uint(start));
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
inline unsigned char read_uchar(InIt& start)
|
||||
{
|
||||
unsigned char ret = static_cast<unsigned char>(*start);
|
||||
++start;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
inline unsigned short read_ushort(InIt& start)
|
||||
{
|
||||
unsigned short val = 0;
|
||||
val |= static_cast<unsigned char>(*start) << 8; ++start;
|
||||
val |= static_cast<unsigned char>(*start); ++start;
|
||||
return val;
|
||||
}
|
||||
|
||||
// reads an integer to a byte stream
|
||||
// and converts it from native endianess
|
||||
template <class OutIt>
|
||||
void write_uint(unsigned int val, OutIt& start)
|
||||
{
|
||||
*start = static_cast<unsigned char>((val >> 24) & 0xff); ++start;
|
||||
*start = static_cast<unsigned char>((val >> 16) & 0xff); ++start;
|
||||
*start = static_cast<unsigned char>((val >> 8) & 0xff); ++start;
|
||||
*start = static_cast<unsigned char>((val) & 0xff); ++start;
|
||||
}
|
||||
|
||||
template <class OutIt>
|
||||
inline void write_int(int val, OutIt& start)
|
||||
{
|
||||
write_uint(static_cast<unsigned int>(val), start);
|
||||
}
|
||||
|
||||
template <class OutIt>
|
||||
void write_ushort(unsigned short val, OutIt& start)
|
||||
{
|
||||
*start = static_cast<unsigned char>((val >> 8) & 0xff); ++start;
|
||||
*start = static_cast<unsigned char>((val) & 0xff); ++start;
|
||||
}
|
||||
|
||||
template <class OutIt>
|
||||
inline void write_uchar(unsigned char val, OutIt& start)
|
||||
{
|
||||
*start = static_cast<char>(val);
|
||||
++start;
|
||||
}
|
||||
|
||||
template <class OutIt>
|
||||
inline void write_int64(boost::int64_t val, OutIt& start)
|
||||
{
|
||||
for (int i = 7; i <= 0; --i)
|
||||
T ret = 0;
|
||||
for (int i = 0; i < sizeof(T); ++i)
|
||||
{
|
||||
*start = static_cast<unsigned char>((val >> (i*8)) & 0xff);
|
||||
++start;
|
||||
}
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
inline boost::int64_t read_int64(InIt& start)
|
||||
{
|
||||
boost::int64_t ret = 0;
|
||||
for (int i = 7; i <= 0; --i)
|
||||
{
|
||||
ret |= static_cast<unsigned char>(*start) << (i*8);
|
||||
ret <<= 8;
|
||||
ret |= static_cast<unsigned char>(*start);
|
||||
++start;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T, class OutIt>
|
||||
inline void write_impl(T val, OutIt& start)
|
||||
{
|
||||
for (int i = sizeof(T)-1; i >= 0; --i)
|
||||
{
|
||||
*start = static_cast<unsigned char>((val >> (i * 8)) & 0xff);
|
||||
++start;
|
||||
}
|
||||
}
|
||||
|
||||
// -- adaptors
|
||||
|
||||
template <class InIt>
|
||||
boost::int64_t read_int64(InIt& start)
|
||||
{ return read_impl(start, type<boost::int64_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::uint64_t read_uint64(InIt& start)
|
||||
{ return read_impl(start, type<boost::uint64_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::uint32_t read_uint32(InIt& start)
|
||||
{ return read_impl(start, type<boost::uint32_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::int32_t read_int32(InIt& start)
|
||||
{ return read_impl(start, type<boost::int32_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::int16_t read_int16(InIt& start)
|
||||
{ return read_impl(start, type<boost::int16_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::uint16_t read_uint16(InIt& start)
|
||||
{ return read_impl(start, type<boost::uint16_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::int8_t read_int8(InIt& start)
|
||||
{ return read_impl(start, type<boost::int8_t>()); }
|
||||
|
||||
template <class InIt>
|
||||
boost::uint8_t read_uint8(InIt& start)
|
||||
{ return read_impl(start, type<boost::uint8_t>()); }
|
||||
|
||||
|
||||
template <class OutIt>
|
||||
void write_uint64(boost::uint64_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_int64(boost::int64_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_uint32(boost::uint32_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_int32(boost::int32_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_uint16(boost::uint16_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_int16(boost::int16_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_uint8(boost::uint8_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
template <class OutIt>
|
||||
void write_int8(boost::int8_t val, OutIt& start)
|
||||
{ write_impl(val, start); }
|
||||
|
||||
}
|
||||
|
||||
struct protocol_error: std::runtime_error
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace libtorrent
|
|||
// when this torrent got a response from its tracker request
|
||||
virtual void tracker_response(std::vector<peer_entry>& e, int interval);
|
||||
virtual void tracker_request_timed_out();
|
||||
virtual void tracker_request_error(int response_code, const char* str);
|
||||
virtual void tracker_request_error(int response_code, const std::string& str);
|
||||
|
||||
// generates a request string for sending
|
||||
// to the tracker
|
||||
|
|
|
@ -49,11 +49,17 @@ namespace libtorrent {
|
|||
|
||||
void alert_manager::post_alert(const alert& alert_)
|
||||
{
|
||||
// TODO: have an internal buffer limit
|
||||
boost::mutex::scoped_lock lock(m_mutex);
|
||||
if (m_severity > alert_.severity()) return;
|
||||
|
||||
if (m_severity <= alert_.severity())
|
||||
m_alerts.push(alert_.clone().release());
|
||||
// the internal limit is 100 alerts
|
||||
if (m_alerts.size() == 100)
|
||||
{
|
||||
alert* result = m_alerts.front();
|
||||
m_alerts.pop();
|
||||
delete result;
|
||||
}
|
||||
m_alerts.push(alert_.clone().release());
|
||||
}
|
||||
|
||||
std::auto_ptr<alert> alert_manager::get()
|
||||
|
|
|
@ -285,8 +285,8 @@ namespace libtorrent
|
|||
|
||||
const char* ptr = &m_recv_buffer[1];
|
||||
peer_request r;
|
||||
r.piece = detail::read_int(ptr);
|
||||
r.start = detail::read_int(ptr);
|
||||
r.piece = detail::read_int32(ptr);
|
||||
r.start = detail::read_int32(ptr);
|
||||
r.length = m_packet_size - 9;
|
||||
|
||||
// is any of the piece message header data invalid?
|
||||
|
@ -406,7 +406,7 @@ namespace libtorrent
|
|||
if (m_recv_pos < m_packet_size) return;
|
||||
|
||||
const char* ptr = &m_recv_buffer[1];
|
||||
int index = detail::read_int(ptr);
|
||||
int index = detail::read_int32(ptr);
|
||||
// if we got an invalid message, abort
|
||||
if (index >= m_have_piece.size() || index < 0)
|
||||
throw protocol_error("have message with higher index than the number of pieces");
|
||||
|
@ -514,9 +514,9 @@ namespace libtorrent
|
|||
|
||||
peer_request r;
|
||||
const char* ptr = &m_recv_buffer[1];
|
||||
r.piece = detail::read_int(ptr);
|
||||
r.start = detail::read_int(ptr);
|
||||
r.length = detail::read_int(ptr);
|
||||
r.piece = detail::read_int32(ptr);
|
||||
r.start = detail::read_int32(ptr);
|
||||
r.length = detail::read_int32(ptr);
|
||||
|
||||
// make sure this request
|
||||
// is legal and taht the peer
|
||||
|
@ -602,8 +602,8 @@ namespace libtorrent
|
|||
|
||||
const char* ptr = &m_recv_buffer[1];
|
||||
peer_request p;
|
||||
p.piece = detail::read_int(ptr);
|
||||
p.start = detail::read_int(ptr);
|
||||
p.piece = detail::read_int32(ptr);
|
||||
p.start = detail::read_int32(ptr);
|
||||
p.length = m_packet_size - 9;
|
||||
|
||||
if (!verify_piece(p))
|
||||
|
@ -724,9 +724,9 @@ namespace libtorrent
|
|||
|
||||
peer_request r;
|
||||
const char* ptr = &m_recv_buffer[1];
|
||||
r.piece = detail::read_int(ptr);
|
||||
r.start = detail::read_int(ptr);
|
||||
r.length = detail::read_int(ptr);
|
||||
r.piece = detail::read_int32(ptr);
|
||||
r.start = detail::read_int32(ptr);
|
||||
r.length = detail::read_int32(ptr);
|
||||
|
||||
std::deque<peer_request>::iterator i
|
||||
= std::find(m_requests.begin(), m_requests.end(), r);
|
||||
|
@ -812,7 +812,7 @@ namespace libtorrent
|
|||
|
||||
const char* ptr = &m_recv_buffer[1];
|
||||
|
||||
int extended_id = detail::read_int(ptr);
|
||||
int extended_id = detail::read_int32(ptr);
|
||||
|
||||
switch (extended_id)
|
||||
{
|
||||
|
@ -929,11 +929,11 @@ namespace libtorrent
|
|||
char* ptr = &m_send_buffer[start_offset];
|
||||
|
||||
// index
|
||||
detail::write_int(block.piece_index, ptr);
|
||||
detail::write_int32(block.piece_index, ptr);
|
||||
// begin
|
||||
detail::write_int(block_offset, ptr);
|
||||
detail::write_int32(block_offset, ptr);
|
||||
// length
|
||||
detail::write_int(block_size, ptr);
|
||||
detail::write_int32(block_size, ptr);
|
||||
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << " ==> CANCEL [ piece: " << block.piece_index << " | s: " << block_offset << " | l: " << block_size << " | " << block.block_index << " ]\n";
|
||||
|
@ -968,13 +968,13 @@ namespace libtorrent
|
|||
|
||||
char* ptr = &m_send_buffer[start_offset+5];
|
||||
// index
|
||||
detail::write_int(block.piece_index, ptr);
|
||||
detail::write_int32(block.piece_index, ptr);
|
||||
|
||||
// begin
|
||||
detail::write_int(block_offset, ptr);
|
||||
detail::write_int32(block_offset, ptr);
|
||||
|
||||
// length
|
||||
detail::write_int(block_size, ptr);
|
||||
detail::write_int32(block_size, ptr);
|
||||
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << " ==> REQUEST [ "
|
||||
|
@ -1005,9 +1005,9 @@ namespace libtorrent
|
|||
bencode(std::back_inserter(message), e);
|
||||
std::back_insert_iterator<std::vector<char> > ptr(m_send_buffer);
|
||||
|
||||
detail::write_uint(1 + 4 + message.size(), ptr);
|
||||
detail::write_uchar(msg_extended, ptr);
|
||||
detail::write_int(m_extension_messages[extended_chat_message], ptr);
|
||||
detail::write_uint32(1 + 4 + message.size(), ptr);
|
||||
detail::write_uint8(msg_extended, ptr);
|
||||
detail::write_int32(m_extension_messages[extended_chat_message], ptr);
|
||||
std::copy(message.begin(), message.end(), ptr);
|
||||
send_buffer_updated();
|
||||
}
|
||||
|
@ -1021,7 +1021,7 @@ namespace libtorrent
|
|||
const int old_size = m_send_buffer.size();
|
||||
m_send_buffer.resize(old_size + packet_size);
|
||||
char* ptr = &m_send_buffer[old_size];
|
||||
detail::write_int(packet_size - 4, ptr);
|
||||
detail::write_int32(packet_size - 4, ptr);
|
||||
m_send_buffer[old_size+4] = msg_bitfield;
|
||||
std::fill(m_send_buffer.begin()+old_size+5, m_send_buffer.end(), 0);
|
||||
for (std::size_t i = 0; i < m_have_piece.size(); ++i)
|
||||
|
@ -1056,7 +1056,7 @@ namespace libtorrent
|
|||
|
||||
// write the length of the message
|
||||
char* ptr = &m_send_buffer[msg_size_pos];
|
||||
detail::write_int(m_send_buffer.size() - msg_size_pos - 4, ptr);
|
||||
detail::write_int32(m_send_buffer.size() - msg_size_pos - 4, ptr);
|
||||
|
||||
send_buffer_updated();
|
||||
}
|
||||
|
@ -1120,7 +1120,7 @@ namespace libtorrent
|
|||
const int packet_size = 9;
|
||||
char msg[packet_size] = {0,0,0,5,msg_have};
|
||||
char* ptr = msg+5;
|
||||
detail::write_int(index, ptr);
|
||||
detail::write_int32(index, ptr);
|
||||
m_send_buffer.insert(m_send_buffer.end(), msg, msg + packet_size);
|
||||
#ifndef NDEBUG
|
||||
(*m_logger) << " ==> HAVE [ piece: " << index << " ]\n";
|
||||
|
@ -1406,7 +1406,7 @@ namespace libtorrent
|
|||
|
||||
// convert from big endian to native byte order
|
||||
const char* ptr = &m_recv_buffer[0];
|
||||
m_packet_size = detail::read_int(ptr);
|
||||
m_packet_size = detail::read_int32(ptr);
|
||||
// don't accept packets larger than 1 MB
|
||||
if (m_packet_size > 1024*1024 || m_packet_size < 0)
|
||||
{
|
||||
|
@ -1492,10 +1492,10 @@ namespace libtorrent
|
|||
const int packet_size = 4 + 5 + 4 + r.length;
|
||||
m_send_buffer.resize(send_buffer_offset + packet_size);
|
||||
char* ptr = &m_send_buffer[send_buffer_offset];
|
||||
detail::write_int(packet_size-4, ptr);
|
||||
detail::write_int32(packet_size-4, ptr);
|
||||
*ptr = msg_piece; ++ptr;
|
||||
detail::write_int(r.piece, ptr);
|
||||
detail::write_int(r.start, ptr);
|
||||
detail::write_int32(r.piece, ptr);
|
||||
detail::write_int32(r.start, ptr);
|
||||
|
||||
m_torrent->filesystem().read(
|
||||
&m_send_buffer[send_buffer_offset+13]
|
||||
|
|
|
@ -253,15 +253,17 @@ namespace libtorrent
|
|||
|
||||
#ifndef NDEBUG
|
||||
std::stringstream s;
|
||||
s << "interval: " << m_duration << "\n";
|
||||
s << "peers:\n";
|
||||
s << "TRACKER RESPONSE:\n"
|
||||
"interval: " << m_duration << "\n"
|
||||
"peers:\n";
|
||||
for (std::vector<peer_entry>::const_iterator i = peer_list.begin();
|
||||
i != peer_list.end();
|
||||
++i)
|
||||
{
|
||||
s << " " << std::setfill(' ') << std::setw(16) << i->ip
|
||||
<< " " << std::setw(5) << std::dec << i->port << " "
|
||||
<< i->id << " " << identify_client(i->id) << "\n";
|
||||
<< " " << std::setw(5) << std::dec << i->port << " ";
|
||||
if (!i->id.is_all_zeros()) s << " " << i->id << " " << identify_client(i->id);
|
||||
s << "\n";
|
||||
}
|
||||
debug_log(s.str());
|
||||
#endif
|
||||
|
@ -746,7 +748,7 @@ namespace libtorrent
|
|||
// with some codes, we should just consider
|
||||
// the tracker as a failure and not retry
|
||||
// it anymore
|
||||
void torrent::tracker_request_error(int response_code, const char* str)
|
||||
void torrent::tracker_request_error(int response_code, const std::string& str)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_log(std::string("*** tracker error: ") + str);
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace libtorrent
|
|||
|
||||
void torrent_handle::set_max_connections(int max_connections)
|
||||
{
|
||||
assert(max_connections >= 2);
|
||||
if (m_ses == 0) throw invalid_handle();
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue