<p>The interface of libtorrent consists of a few classes. The main class is
the <ttclass="docutils literal">session</tt>, it contains the main loop that serves all torrents.</p>
<p>The basic usage is as follows:</p>
<ul>
<li><pclass="first">construct a <aclass="reference external"href="reference-Session.html#session">session</a></p>
</li>
<li><pclass="first">load <aclass="reference external"href="reference-Session.html#session">session</a> state from settings file (see <aclass="reference external"href="reference-Session.html#load_state()">load_state()</a>)</p>
</li>
<li><pclass="first">start extensions (see <aclass="reference external"href="reference-Core.html#add_extension()">add_extension()</a>).</p>
</li>
<li><pclass="first">start DHT, LSD, UPnP, NAT-PMP etc (see <aclass="reference external"href="reference-Session.html#start_dht()">start_dht()</a>, <aclass="reference external"href="reference-Session.html#start_lsd()">start_lsd()</a>, <aclass="reference external"href="reference-Session.html#start_upnp()">start_upnp()</a> and <aclass="reference external"href="reference-Session.html#start_natpmp()">start_natpmp()</a>).</p>
</li>
<li><pclass="first">parse .torrent-files and add them to the <aclass="reference external"href="reference-Session.html#session">session</a> (see <aclass="reference external"href="reference-Core.html#torrent_info">torrent_info</a>, <aclass="reference external"href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <aclass="reference external"href="reference-Session.html#add_torrent()">add_torrent()</a>)</p>
</li>
<li><pclass="first">main loop (see <aclass="reference external"href="reference-Session.html#session">session</a>)</p>
<blockquote>
<ulclass="simple">
<li>poll for alerts (see <aclass="reference external"href="reference-Session.html#wait_for_alert()">wait_for_alert()</a>, <aclass="reference external"href="reference-Session.html#pop_alerts()">pop_alerts()</a>)</li>
<li>handle updates to torrents, (see <aclass="reference external"href="reference-Alerts.html#state_update_alert">state_update_alert</a>).</li>
<li>handle other alerts, (see <aclass="reference external"href="reference-Alerts.html#alert">alert</a>).</li>
<li>query the <aclass="reference external"href="reference-Session.html#session">session</a> for information (see <aclass="reference external"href="reference-Session.html#status()">session::status()</a>).</li>
<li>add and remove torrents from the <aclass="reference external"href="reference-Session.html#session">session</a> (remove_torrent())</li>
</ul>
</blockquote>
</li>
<li><pclass="first">save resume data for all torrent_handles (optional, see
<li><pclass="first">save <aclass="reference external"href="reference-Session.html#session">session</a> state (see <aclass="reference external"href="reference-Session.html#save_state()">save_state()</a>)</p>
<p>Each class and function is described in this manual.</p>
<p>For a description on how to create torrent files, see <aclass="reference external"href="reference-Create_Torrents.html#create_torrent">create_torrent</a>.</p>
</div>
<divclass="section"id="things-to-keep-in-mind">
<h1>things to keep in mind</h1>
<p>A common problem developers are facing is torrents stopping without explanation.
Here is a description on which conditions libtorrent will stop your torrents,
how to find out about it and what to do about it.</p>
<p>Make sure to keep track of the paused state, the error state and the upload
mode of your torrents. By default, torrents are auto-managed, which means
libtorrent will pause them, unpause them, scrape them and take them out
of upload-mode automatically.</p>
<p>Whenever a torrent encounters a fatal error, it will be stopped, and the
<ttclass="docutils literal"><spanclass="pre">torrent_status::error</span></tt> will describe the error that caused it. If a torrent
is auto managed, it is scraped periodically and paused or resumed based on
the number of downloaders per seed. This will effectively seed torrents that
are in the greatest need of seeds.</p>
<p>If a torrent hits a disk write error, it will be put into upload mode. This
means it will not download anything, but only upload. The assumption is that
the write error is caused by a full disk or write permission errors. If the
torrent is auto-managed, it will periodically be taken out of the upload
mode, trying to write things to the disk again. This means torrent will recover
from certain disk errors if the problem is resolved. If the torrent is not
auto managed, you have to call <aclass="reference external"href="reference-Core.html#set_upload_mode()">set_upload_mode()</a> to turn
downloading back on again.</p>
</div>
<divclass="section"id="network-primitives">
<h1>network primitives</h1>
<p>There are a few typedefs in the <ttclass="docutils literal">libtorrent</tt> namespace which pulls
in network types from the <ttclass="docutils literal">asio</tt> namespace. These are:</p>
<preclass="literal-block">
typedef asio::ip::address address;
typedef asio::ip::address_v4 address_v4;
typedef asio::ip::address_v6 address_v6;
using asio::ip::tcp;
using asio::ip::udp;
</pre>
<p>These are declared in the <ttclass="docutils literal"><libtorrent/socket.hpp></tt> header.</p>
<p>The <ttclass="docutils literal">using</tt> statements will give easy access to:</p>
<preclass="literal-block">
tcp::endpoint
udp::endpoint
</pre>
<p>Which are the endpoint types used in libtorrent. An endpoint is an address
with an associated port.</p>
<p>For documentation on these types, please refer to the <aclass="reference external"href="http://asio.sourceforge.net/asio-0.3.8/doc/asio/reference.html">asio documentation</a>.</p>
</div>
<divclass="section"id="exceptions">
<h1>exceptions</h1>
<p>Many functions in libtorrent have two versions, one that throws exceptions on
errors and one that takes an <ttclass="docutils literal">error_code</tt> reference which is filled with the
error code on errors.</p>
<p>There is one exception class that is used for errors in libtorrent, it is based
on boost.system's <ttclass="docutils literal">error_code</tt> class to carry the error code.</p>
<p>For more information, see <aclass="reference external"href="reference-Error_Codes.html#libtorrent_exception">libtorrent_exception</a> and <aclass="reference external"href="reference-Error_Codes.html#error_code_enum">error_code_enum</a>.</p>
<divclass="section"id="translating-error-codes">
<h2>translating error codes</h2>
<p>The error_code::message() function will typically return a localized error string,
for system errors. That is, errors that belong to the generic or system category.</p>
<p>Errors that belong to the libtorrent error category are not localized however, they
are only available in english. In order to translate libtorrent errors, compare the
error category of the <ttclass="docutils literal">error_code</tt> object against <ttclass="docutils literal"><spanclass="pre">libtorrent::get_libtorrent_category()</span></tt>,
and if matches, you know the error code refers to the list above. You can provide
your own mapping from error code to string, which is localized. In this case, you
cannot rely on <ttclass="docutils literal"><spanclass="pre">error_code::message()</span></tt> to generate your strings.</p>
<p>The numeric values of the errors are part of the API and will stay the same, although
new error codes may be appended at the end.</p>
<p>Here's a simple example of how to translate error codes:</p>
<p>libtorrent supports <em>queuing</em>. Which means it makes sure that a limited number of
torrents are being downloaded at any given time, and once a torrent is completely
downloaded, the next in line is started.</p>
<p>Torrents that are <em>auto managed</em> are subject to the queuing and the active torrents
limits. To make a torrent auto managed, set <ttclass="docutils literal">auto_managed</tt> to true when adding the
torrent (see <aclass="reference external"href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <aclass="reference external"href="reference-Session.html#add_torrent()">add_torrent()</a>).</p>
<p>The limits of the number of downloading and seeding torrents are controlled via
<ttclass="docutils literal">active_downloads</tt>, <ttclass="docutils literal">active_seeds</tt> and <ttclass="docutils literal">active_limit</tt> in <aclass="reference external"href="reference-Settings.html#session_settings">session_settings</a>.
These limits takes non auto managed torrents into account as well. If there are
more non-auto managed torrents being downloaded than the <ttclass="docutils literal">active_downloads</tt>
setting, any auto managed torrents will be queued until torrents are removed so
that the number drops below the limit.</p>
<p>The default values are 8 active downloads and 5 active seeds.</p>
<p>At a regular interval, torrents are checked if there needs to be any re-ordering of
which torrents are active and which are queued. This interval can be controlled via
<ttclass="docutils literal">auto_manage_interval</tt> in <aclass="reference external"href="reference-Settings.html#session_settings">session_settings</a>. It defaults to every 30 seconds.</p>
<p>For queuing to work, resume data needs to be saved and restored for all torrents.
See <aclass="reference external"href="reference-Core.html#save_resume_data()">save_resume_data()</a>.</p>
<divclass="section"id="downloading">
<h2>downloading</h2>
<p>Torrents that are currently being downloaded or incomplete (with bytes still to download)
are queued. The torrents in the front of the queue are started to be actively downloaded
and the rest are ordered with regards to their queue position. Any newly added torrent
is placed at the end of the queue. Once a torrent is removed or turns into a seed, its
queue position is -1 and all torrents that used to be after it in the queue, decreases their
position in order to fill the gap.</p>
<p>The queue positions are always in a sequence without any gaps.</p>
<p>Lower queue position means closer to the front of the queue, and will be started sooner than
torrents with higher queue positions.</p>
<p>To query a torrent for its position in the queue, or change its position, see:
<p>Auto managed seeding torrents are rotated, so that all of them are allocated a fair
amount of seeding. Torrents with fewer completed <em>seed cycles</em> are prioritized for
seeding. A seed cycle is completed when a torrent meets either the share ratio limit
(uploaded bytes / downloaded bytes), the share time ratio (time seeding / time
downloaing) or seed time limit (time seeded).</p>
<p>The relevant settings to control these limits are <ttclass="docutils literal">share_ratio_limit</tt>,
<ttclass="docutils literal">seed_time_ratio_limit</tt> and <ttclass="docutils literal">seed_time_limit</tt> in <aclass="reference external"href="reference-Settings.html#session_settings">session_settings</a>.</p>
</div>
</div>
<divclass="section"id="fast-resume">
<h1>fast resume</h1>
<p>The fast resume mechanism is a way to remember which pieces are downloaded
and where they are put between sessions. You can generate fast resume data by
calling <aclass="reference external"href="reference-Core.html#save_resume_data()">save_resume_data()</a> on <aclass="reference external"href="reference-Core.html#torrent_handle">torrent_handle</a>. You can
then save this data to disk and use it when resuming the torrent. libtorrent
will not check the piece hashes then, and rely on the information given in the
fast-resume data. The fast-resume data also contains information about which
blocks, in the unfinished pieces, were downloaded, so it will not have to
start from scratch on the partially downloaded pieces.</p>
<p>To use the fast-resume data you simply give it to <aclass="reference external"href="reference-Session.html#async_add_torrent()">async_add_torrent()</a> and <aclass="reference external"href="reference-Session.html#add_torrent()">add_torrent()</a>, and it
will skip the time consuming checks. It may have to do the checking anyway, if
the fast-resume data is corrupt or doesn't fit the storage for that torrent,
then it will not trust the fast-resume data and just do the checking.</p>
<divclass="section"id="file-format">
<h2>file format</h2>
<p>The file format is a bencoded dictionary containing the following fields:</p>
<td>The allocation mode for the storage. Can be either <ttclass="docutils literal">full</tt>
or <ttclass="docutils literal">compact</tt>. If this is full, the file sizes and
timestamps are disregarded. Pieces are assumed not to have
moved around even if the files have been modified after the
last resume data checkpoint.</td>
</tr>
</tbody>
</table>
</div>
</div>
<divclass="section"id="storage-allocation">
<h1>storage allocation</h1>
<p>There are two modes in which storage (files on disk) are allocated in libtorrent.</p>
<olclass="arabic simple">
<li>The traditional <em>full allocation</em> mode, where the entire files are filled up with
zeros before anything is downloaded. libtorrent will look for sparse files support
in the filesystem that is used for storage, and use sparse files or file system
zero fill support if present. This means that on NTFS, full allocation mode will
only allocate storage for the downloaded pieces.</li>
<li>The <em>sparse allocation</em>, sparse files are used, and pieces are downloaded directly
to where they belong. This is the recommended (and default) mode.</li>
</ol>
<p>In previous versions of libtorrent, a 3rd mode was supported, <em>compact allocation</em>.
Support for this is deprecated and will be removed in future versions of libtorrent.
It's still described in here for completeness.</p>
<p>The allocation mode is selected when a torrent is started. It is passed as an
argument to <aclass="reference external"href="reference-Session.html#add_torrent()">session::add_torrent()</a> or <aclass="reference external"href="reference-Session.html#async_add_torrent()">session::async_add_torrent()</a>.</p>
<p>The decision to use full allocation or compact allocation typically depends on whether
any files have priority 0 and if the filesystem supports sparse files.</p>
<divclass="section"id="sparse-allocation">
<h2>sparse allocation</h2>
<p>On filesystems that supports sparse files, this allocation mode will only use
as much space as has been downloaded.</p>
<blockquote>
<ulclass="simple">
<li>It does not require an allocation pass on startup.</li>
<li>It supports skipping files (setting prioirty to 0 to not download).</li>
<li>Fast resume data will remain valid even when file time stamps are out of date.</li>
</ul>
</blockquote>
</div>
<divclass="section"id="full-allocation">
<h2>full allocation</h2>
<p>When a torrent is started in full allocation mode, the disk-io thread
will make sure that the entire storage is allocated, and fill any gaps with zeros.
This will be skipped if the filesystem supports sparse files or automatic zero filling.
It will of course still check for existing pieces and fast resume data. The main
drawbacks of this mode are:</p>
<blockquote>
<ulclass="simple">
<li>It may take longer to start the torrent, since it will need to fill the files
with zeros on some systems. This delay is linearly dependent on the size of
the download.</li>
<li>The download may occupy unnecessary disk space between download sessions. In case
sparse files are not supported.</li>
<li>Disk caches usually perform extremely poorly with random access to large files
and may slow down a download considerably.</li>
</ul>
</blockquote>
<p>The benefits of this mode are:</p>
<blockquote>
<ulclass="simple">
<li>Downloaded pieces are written directly to their final place in the files and the
total number of disk operations will be fewer and may also play nicer to
filesystems' file allocation, and reduce fragmentation.</li>
<li>No risk of a download failing because of a full disk during download. Unless
sparse files are being used.</li>
<li>The fast resume data will be more likely to be usable, regardless of crashes or
out of date data, since pieces won't move around.</li>
<li>Can be used with prioritizing files to 0.</li>
</ul>
</blockquote>
</div>
<divclass="section"id="compact-allocation">
<h2>compact allocation</h2>
<divclass="note">
<pclass="first admonition-title">Note</p>
<pclass="last">Note that support for compact allocation is deprecated in libttorrent, and will
be removed in future versions.</p>
</div>
<p>The compact allocation will only allocate as much storage as it needs to keep the
pieces downloaded so far. This means that pieces will be moved around to be placed
at their final position in the files while downloading (to make sure the completed
download has all its pieces in the correct place). So, the main drawbacks are:</p>
<blockquote>
<ulclass="simple">
<li>More disk operations while downloading since pieces are moved around.</li>
<li>Potentially more fragmentation in the filesystem.</li>
<li>Cannot be used while having files with priority 0.</li>
</ul>
</blockquote>
<p>The benefits though, are:</p>
<blockquote>
<ulclass="simple">
<li>No startup delay, since the files don't need allocating.</li>
<li>The download will not use unnecessary disk space.</li>
<li>Disk caches perform much better than in full allocation and raises the download
speed limit imposed by the disk.</li>
<li>Works well on filesystems that don't support sparse files.</li>
</ul>
</blockquote>
<p>The algorithm that is used when allocating pieces and slots isn't very complicated.
For the interested, a description follows.</p>
<p>storing a piece:</p>
<olclass="arabic simple">
<li>let <strong>A</strong> be a newly downloaded piece, with index <strong>n</strong>.</li>
<li>let <strong>s</strong> be the number of slots allocated in the file we're
downloading to. (the number of pieces it has room for).</li>
<li>if <strong>n</strong>>= <strong>s</strong> then allocate a new slot and put the piece there.</li>
<li>if <strong>n</strong><<strong>s</strong> then allocate a new slot, move the data at
slot <strong>n</strong> to the new slot and put <strong>A</strong> in slot <strong>n</strong>.</li>
</ol>
<p>allocating a new slot:</p>
<olclass="arabic simple">
<li>if there's an unassigned slot (a slot that doesn't
contain any piece), return that slot index.</li>
<li>append the new slot at the end of the file (or find an unused slot).</li>
<li>let <strong>i</strong> be the index of newly allocated slot</li>
<li>if we have downloaded piece index <strong>i</strong> already (to slot <strong>j</strong>) then<olclass="arabic">
<li>move the data at slot <strong>j</strong> to slot <strong>i</strong>.</li>
<li>return slot index <strong>j</strong> as the newly allocated free slot.</li>
</ol>
</li>
<li>return <strong>i</strong> as the newly allocated slot.</li>
</ol>
</div>
</div>
<divclass="section"id="extensions">
<h1>extensions</h1>
<p>These extensions all operates within the <aclass="reference external"href="extension_protocol.html">extension protocol</a>. The
name of the extension is the name used in the extension-list packets,
and the payload is the data in the extended message (not counting the
length-prefix, message-id nor extension-id).</p>
<p>Note that since this protocol relies on one of the reserved bits in the
handshake, it may be incompatible with future versions of the mainline
bittorrent client.</p>
<p>These are the extensions that are currently implemented.</p>
<divclass="section"id="metadata-from-peers">
<h2>metadata from peers</h2>
<p>Extension name: "LT_metadata"</p>
<p>This extension is deprecated in favor of the more widely supported <ttclass="docutils literal">ut_metadata</tt>
extension, see <aclass="reference external"href="http://bittorrent.org/beps/bep_0009.html">BEP 9</a>.
The point with this extension is that you don't have to distribute the
metadata (.torrent-file) separately. The metadata can be distributed
through the bittorrent swarm. The only thing you need to download such
a torrent is the tracker url and the info-hash of the torrent.</p>
<p>It works by assuming that the initial seeder has the metadata and that
the metadata will propagate through the network as more peers join.</p>
<p>There are three kinds of messages in the metadata extension. These packets
are put as payload to the extension message. The three packets are:</p>
<blockquote>
<ulclass="simple">
<li>request metadata</li>
<li>metadata</li>
<li>don't have metadata</li>
</ul>
</blockquote>
<p>request metadata:</p>
<tableborder="1"class="docutils">
<colgroup>
<colwidth="17%"/>
<colwidth="23%"/>
<colwidth="61%"/>
</colgroup>
<theadvalign="bottom">
<tr><thclass="head">size</th>
<thclass="head">name</th>
<thclass="head">description</th>
</tr>
</thead>
<tbodyvalign="top">
<tr><td>uint8_t</td>
<td>msg_type</td>
<td>Determines the kind of message this is
0 means 'request metadata'</td>
</tr>
<tr><td>uint8_t</td>
<td>start</td>
<td>The start of the metadata block that
is requested. It is given in 256:ths
of the total size of the metadata,
since the requesting client don't know
the size of the metadata.</td>
</tr>
<tr><td>uint8_t</td>
<td>size</td>
<td>The size of the metadata block that is
requested. This is also given in
256:ths of the total size of the
metadata. The size is given as size-1.
That means that if this field is set
0, the request wants one 256:th of the
metadata.</td>
</tr>
</tbody>
</table>
<p>metadata:</p>
<tableborder="1"class="docutils">
<colgroup>
<colwidth="17%"/>
<colwidth="23%"/>
<colwidth="61%"/>
</colgroup>
<theadvalign="bottom">
<tr><thclass="head">size</th>
<thclass="head">name</th>
<thclass="head">description</th>
</tr>
</thead>
<tbodyvalign="top">
<tr><td>uint8_t</td>
<td>msg_type</td>
<td>1 means 'metadata'</td>
</tr>
<tr><td>int32_t</td>
<td>total_size</td>
<td>The total size of the metadata, given
in number of bytes.</td>
</tr>
<tr><td>int32_t</td>
<td>offset</td>
<td>The offset of where the metadata block
in this message belongs in the final
metadata. This is given in bytes.</td>
</tr>
<tr><td>uint8_t[]</td>
<td>metadata</td>
<td>The actual metadata block. The size of
this part is given implicit by the
length prefix in the bittorrent
protocol packet.</td>
</tr>
</tbody>
</table>
<p>Don't have metadata:</p>
<tableborder="1"class="docutils">
<colgroup>
<colwidth="17%"/>
<colwidth="23%"/>
<colwidth="61%"/>
</colgroup>
<theadvalign="bottom">
<tr><thclass="head">size</th>
<thclass="head">name</th>
<thclass="head">description</th>
</tr>
</thead>
<tbodyvalign="top">
<tr><td>uint8_t</td>
<td>msg_type</td>
<td>2 means 'I don't have metadata'.
This message is sent as a reply to a
metadata request if the the client
doesn't have any metadata.</td>
</tr>
</tbody>
</table>
</div>
<divclass="section"id="dont-have">
<h2>dont_have</h2>
<p>Extension name: "lt_dont_have"</p>
<p>The <ttclass="docutils literal">dont_have</tt> extension message is used to tell peers that the client no longer
has a specific piece. The extension message should be advertised in the <ttclass="docutils literal">m</tt> dictionary
as <ttclass="docutils literal">lt_dont_have</tt>. The message format mimics the regular <ttclass="docutils literal">HAVE</tt> bittorrent message.</p>
<p>Just like all extension messages, the first 2 bytes in the mssage itself are 20 (the
bittorrent extension message) and the message ID assigned to this extension in the <ttclass="docutils literal">m</tt>
dictionary in the handshake.</p>
<tableborder="1"class="docutils">
<colgroup>
<colwidth="17%"/>
<colwidth="23%"/>
<colwidth="61%"/>
</colgroup>
<theadvalign="bottom">
<tr><thclass="head">size</th>
<thclass="head">name</th>
<thclass="head">description</th>
</tr>
</thead>
<tbodyvalign="top">
<tr><td>uint32_t</td>
<td>piece</td>
<td>index of the piece the peer no longer
has.</td>
</tr>
</tbody>
</table>
<p>The length of this message (including the extension message prefix) is
6 bytes, i.e. one byte longer than the normal <ttclass="docutils literal">HAVE</tt> message, because
of the extension message wrapping.</p>
</div>
<divclass="section"id="http-seeding">
<h2>HTTP seeding</h2>
<p>There are two kinds of HTTP seeding. One with that assumes a smart
(and polite) client and one that assumes a smart server. These
are specified in <aclass="reference external"href="http://bittorrent.org/beps/bep_0019.html">BEP 19</a> and <aclass="reference external"href="http://bittorrent.org/beps/bep_0017.html">BEP 17</a> respectively.</p>
<p>libtorrent supports both. In the libtorrent source code and API,
BEP 19 urls are typically referred to as <em>url seeds</em> and BEP 17
urls are typically referred to as <em>HTTP seeds</em>.</p>
<p>The libtorrent implementation of <aclass="reference external"href="http://bittorrent.org/beps/bep_0019.html">BEP 19</a> 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.</p>
</div>
</div>
<divclass="section"id="piece-picker">
<h1>piece picker</h1>
<p>The piece picker in libtorrent has the following features:</p>
<ulclass="simple">
<li>rarest first</li>
<li>sequential download</li>
<li>random pick</li>
<li>reverse order picking</li>
<li>parole mode</li>
<li>prioritize partial pieces</li>
<li>prefer whole pieces</li>
<li>piece affinity by speed category</li>
<li>piece priorities</li>
</ul>
<divclass="section"id="internal-representation">
<h2>internal representation</h2>
<p>It is optimized by, at all times, keeping a list of pieces ordered
by rarity, randomly shuffled within each rarity class. This list
is organized as a single vector of contigous memory in RAM, for
optimal memory locality and to eliminate heap allocations and frees
when updating rarity of pieces.</p>
<p>Expensive events, like a peer joining or leaving, are evaluated
lazily, since it's cheaper to rebuild the whole list rather than
updating every single piece in it. This means as long as no blocks
are picked, peers joining and leaving is no more costly than a single
peer joining or leaving. Of course the special cases of peers that have
all or no pieces are optimized to not require rebuilding the list.</p>
</div>
<divclass="section"id="picker-strategy">
<h2>picker strategy</h2>
<p>The normal mode of the picker is of course <em>rarest first</em>, meaning
pieces that few peers have are preferred to be downloaded over pieces
that more peers have. This is a fundamental algorithm that is the
basis of the performance of bittorrent. However, the user may set the
piece picker into sequential download mode. This mode simply picks
<p>When a torrent starts out, picking the rarest pieces means increased
risk that pieces won't be completed early (since there are only a few
peers they can be downloaded from), leading to a delay of having any
piece to offer to other peers. This lack of pieces to trade, delays
the client from getting started into the normal tit-for-tat mode of
bittorrent, and will result in a long ramp-up time. The heuristic to
mitigate this problem is to, for the first few pieces, pick random pieces
rather than rare pieces. The threshold for when to leave this initial
picker mode is determined by <aclass="reference external"href="reference-Settings.html#initial_picker_threshold">session_settings::initial_picker_threshold</a>.</p>
</div>
<divclass="section"id="reverse-order">
<h2>reverse order</h2>
<p>An orthogonal setting is <em>reverse order</em>, which is used for <em>snubbed</em>
peers. Snubbed peers are peers that appear very slow, and might have timed
out a piece request. The idea behind this is to make all snubbed peers
more likely to be able to do download blocks from the same piece,
concentrating slow peers on as few pieces as possible. The reverse order
means that the most common pieces are picked, instead of the rarest pieces
(or in the case of sequential download, the last pieces, intead of the first).</p>
</div>
<divclass="section"id="parole-mode">
<h2>parole mode</h2>
<p>Peers that have participated in a piece that failed the hash check, may be
put in <em>parole mode</em>. This means we prefer downloading a full piece from this
peer, in order to distinguish which peer is sending corrupt data. Whether to
do this is or not is controlled by <aclass="reference external"href="reference-Settings.html#use_parole_mode">session_settings::use_parole_mode</a>.</p>
<p>In parole mode, the piece picker prefers picking one whole piece at a time for
a given peer, avoiding picking any blocks from a piece any other peer has
contributed to (since that would defeat the purpose of parole mode).</p>
<p>This setting determines if partially downloaded or requested pieces should always
be preferred over other pieces. The benefit of doing this is that the number of
partial pieces is minimized (and hence the turn-around time for downloading a block
until it can be uploaded to others is minimized). It also puts less stress on the
disk cache, since fewer partial pieces need to be kept in the cache. Whether or
not to enable this is controlled by <aclass="reference external"href="reference-Settings.html#prioritize_partial_pieces">session_settings::prioritize_partial_pieces</a>.</p>
<p>The main benefit of not prioritizing partial pieces is that the rarest first
algorithm gets to have more influence on which pieces are picked. The picker is
more likely to truly pick the rarest piece, and hence improving the performance
of the swarm.</p>
<p>This setting is turned on automatically whenever the number of partial pieces
in the piece picker exceeds the number of peers we're connected to times 1.5.
This is in order to keep the waste of partial pieces to a minimum, but still
prefer rarest pieces.</p>
</div>
<divclass="section"id="prefer-whole-pieces">
<h2>prefer whole pieces</h2>
<p>The <em>prefer whole pieces</em> setting makes the piece picker prefer picking entire
pieces at a time. This is used by web connections (both http seeding
standards), in order to be able to coalesce the small bittorrent requests
to larger HTTP requests. This significantly improves performance when
downloading over HTTP.</p>
<p>It is also used by peers that are downloading faster than a certain
threshold. The main advantage is that these peers will better utilize the
other peer's disk cache, by requesting all blocks in a single piece, from
the same peer.</p>
<p>This threshold is controlled by <aclass="reference external"href="reference-Settings.html#whole_pieces_threshold">session_settings::whole_pieces_threshold</a>.</p>
<p><em>TODO: piece affinity by speed category</em>
<em>TODO: piece priorities</em></p>
</div>
</div>
<divclass="section"id="ssl-torrents">
<h1>SSL torrents</h1>
<p>Torrents may have an SSL root (CA) certificate embedded in them. Such torrents
are called <em>SSL torrents</em>. An SSL torrent talks to all bittorrent peers over SSL.
The protocols are layered like this:</p>
<preclass="literal-block">
+-----------------------+
| BitTorrent protocol |
+-----------------------+
| SSL |
+-----------+-----------+
| TCP | uTP |
| +-----------+
| | UDP |
+-----------+-----------+
</pre>
<p>During the SSL handshake, both peers need to authenticate by providing a certificate
that is signed by the CA certificate found in the .torrent file. These peer
certificates are expected to be privided to peers through some other means than
bittorrent. Typically by a peer generating a certificate request which is sent to
the publisher of the torrent, and the publisher returning a signed certificate.</p>
<p>In libtorrent, <aclass="reference external"href="reference-Core.html#set_ssl_certificate()">set_ssl_certificate()</a> in <aclass="reference external"href="reference-Core.html#torrent_handle">torrent_handle</a> is used to tell libtorrent where
to find the peer certificate and the private key for it. When an SSL torrent is loaded,
the <aclass="reference external"href="reference-Alerts.html#torrent_need_cert_alert">torrent_need_cert_alert</a> is posted to remind the user to provide a certificate.</p>
<p>A peer connecting to an SSL torrent MUST provide the <em>SNI</em> TLS extension (server name
indication). The server name is the hex encoded info-hash of the torrent to connect to.
This is required for the client accepting the connection to know which certificate to
present.</p>
<p>SSL connections are accepted on a separate socket from normal bittorrent connections. To
pick which port the SSL socket should bind to, set <aclass="reference external"href="reference-Settings.html#ssl_listen">session_settings::ssl_listen</a> to a
different port. It defaults to port 4433. This setting is only taken into account when the
normal listen socket is opened (i.e. just changing this setting won't necessarily close
and re-open the SSL socket). To not listen on an SSL socket at all, set <ttclass="docutils literal">ssl_listen</tt> to 0.</p>
<p>This feature is only available if libtorrent is build with openssl support (<ttclass="docutils literal">TORRENT_USE_OPENSSL</tt>)
and requires at least openSSL version 1.0, since it needs SNI support.</p>
<p>Peer certificates must have at least one <em>SubjectAltName</em> field of type dNSName. At least
one of the fields must <em>exactly</em> match the name of the torrent. This is a byte-by-byte comparison,
the UTF-8 encoding must be identical (i.e. there's no unicode normalization going on). This is
the recommended way of verifying certificates for HTTPS servers according to <aclass="reference external"href="http://www.ietf.org/rfc/rfc2818.txt">RFC 2818</a>. Note
the difference that for torrents only <em>dNSName</em> fields are taken into account (not IP address fields).
The most specific (i.e. last) <em>Common Name</em> field is also taken into account if no <em>SubjectAltName</em>
did not match.</p>
<p>If any of these fields contain a single asterisk ("*"), the certificate is considered covering
any torrent, allowing it to be reused for any torrent.</p>
<p>The purpose of matching the torrent name with the fields in the peer certificate is to allow
a publisher to have a single root certificate for all torrents it distributes, and issue
separate peer certificates for each torrent. A peer receiving a certificate will not necessarily
be able to access all torrents published by this root certificate (only if it has a "star cert").</p>
<divclass="section"id="testing">
<h2>testing</h2>
<p>To test incoming SSL connections to an SSL torrent, one can use the following <em>openssl</em> command:</p>