libtorrent

libtorrent
Developer(s) Arvid Norberg
Initial release 0.9 (September 2005)
Stable release 1.1.4[1] (July 3, 2017 (2017-07-03)) [±]
Written in C++
Operating system Cross-platform
Available in English
Type BitTorrent library
License BSD license (Free software)
Website www.libtorrent.org

libtorrent is an open source implementation of the BitTorrent protocol. It is written in and has its main library interface in C++. Its most notable features are support for Mainline DHT, IPv6, HTTP seeds and µTorrent's peer exchange.

libtorrent uses Boost, specifically Boost.Asio to gain its platform independence. It is known to build on Windows and most Unix-like operating systems (OS X, Linux, and many BSDs).

Its original author is Arvid Norberg.

Overview

libtorrent is kept up to date with the most useful bittorrent extensions and is constantly being optimized to work in a broader set of environments. Many of its features can be disabled at compile time to not include code that would not be used in a particular use case. It aims to be the most suitable libtorrent implementation for embedded devices as well as desktops and seed-servers. Some of its implementation details are described in the features section.

libtorrent was the first client to support the extension protocol together with µTorrent, which is now a foundation that many other extensions build upon.

Features

Implemented BEPs

BEP # Title Note
3 BitTorrent protocol
5 DHT protocol trackerless torrents, Mainline Kademlia DHT protocol
7 IPv6 Tracker Extension
9 Extension for Peers to Send Metadata Files metadata transfer protocol, enables magnet links
10 Extension Protocol
11 Peer exchange uTorrent PEX
12 Multitracker Metadata Extension also supports the µTorrent interpretation
14 Local Peer Discovery
15 UDP Tracker Protocol for BitTorrent
16 Superseeding
17 HTTP Seeding Hoffman-style
19 WebSeed - HTTP/FTP Seeding (GetRight style)
21 Partial seed upload-only
24 Tracker Returns External IP
27 Private Torrents
29 uTorrent transport protocol since 0.16.0[2]
30 Merkle hash since 0.15 [3]
33 DHT scrape since 0.16 [4]
38 mutable torrents since 1.1 [5]
40 canonical peer priority since 1.0 [6]
43 read-only DHT nodes since 1.0.3 [7]
44 DHT put/get since 1.0 [8]
47 pad files and file attributes since 0.15 [9][10]

Miscellaneous features list

Disk caching

All disk I/O in libtorrent is done asynchronously to the network thread, by the disk io thread. When a block is read, the disk io thread reads all subsequent blocks from that piece into the read cache, assuming that the peer requesting the block will also request more blocks from the same piece. This decreases the number of syscalls for reading data. It also decreases delay from seeking.

Similarly, for write requests, blocks are cached and flushed to disk once one full piece is complete or the piece is the least recently updated one when more cache space is needed. The cache dynamically allocates space between the write and read cache. The write cache is strictly prioritized over the read cache.

The cache blocks that are in use, are locked into physical memory to avoid it being paged out to disk. Allowing the disk cache to be paged out to disk means that it would become extremely inefficient to flush it, since it would have to be read back into physical memory only to be flushed back out to disk again.

In order to conserve memory, and system calls, iovec file operations are used to flush multiple cache blocks in a single call.

On low-memory systems, the disk cache can be disabled altogether or set to smaller limit, to save memory.

Network buffers

On CPUs with small L2 caches, copying memory can be expensive operations. It is important to keep copying to a minimum on such machines. This mostly applies to embedded systems.

In order to minimize the number of times received data is copied, the receive buffer for payload data is received directly into a page aligned disk buffer. If the connection is encrypted, the buffer is decrypted in-place. The buffer is then moved into the disk cache without being copied. Once all the blocks for a piece have been received, or the cache needs to be flushed, all the blocks are passed directly to writev() to flush them in a single syscall. This means a single copy into user space memory, and a single copy back into kernel memory.

When seeding and uploading in general, unnecessary copying is avoided by caching blocks in aligned buffers, that are copied once into the peer's send buffer. The peer's send buffer is not guaranteed to be aligned, even though it is most of the time. The send buffer is then encrypted with the peer specific key and chained onto the iovec for sending. This means there is one user space copy in order to allow unaligned peer requests and peer-specific encryption.

Piece picker

The piece picker is a central component in a bittorrent implementation. The piece picker in libtorrent is optimized for quickly finding the rarest pieces. It keeps a list of all available pieces sorted by rarity, and pieces with the same rarity, shuffled. The rarest first mode is the dominant piece picker mode. Other modes are supported as well, and used by peers in specific situations.

The piece picker allows to combine the availability of a piece with a priority. Together they determine the sort order of the piece list. Pieces with priority 0 will never be picked, which is used for the selective download feature.

In order to have as few partially finished pieces as possible, peers have an affinity towards picking blocks from the same pieces as other peers in the same speed category. The speed category is a coarse categorization of peers based on their download rate. This makes slow peers pick blocks from the same piece, and fast peers pick from the same piece, and hence decreasing the likelihood of slow peers blocking the completion of pieces.

The piece picker can also be set to download pieces in sequential order.

Merkle hash tree torrents

This is BEP30 of the BitTorrent protocol. Merkle hash tree torrents is an extension that lets a torrent file only contain the root hash of the hash tree forming the piece hashes.[11] The main benefit of this feature is that regardless of how many pieces there are in a torrent, the .torrent file will always be the same size. It will only grow with the number of files (since it still has to contain the file names).

With regular torrents, clients have to request multiple blocks for pieces, typically from different peers, before the data can be verified against the piece hash. The larger the pieces are, the longer it will take to download a complete piece and verify it. Before the piece is verified, it cannot be shared with the swarm, which means the larger piece sizes, the slower turnaround data has when it is downloaded by peers. Since on average the data has to sit around, waiting, in client buffers before it has been verified and can be uploaded again.

Another problem with large piece sizes is that it is harder for a client to pinpoint the malicious or buggy peer when a piece fails, and it will take longer to re-download it and take more tries before the piece succeeds the larger the pieces are.

The piece size in regular torrents is a tradeoff between the size of the .torrent file itself and the piece size. Often, for files that are 4 GB, the piece size is 2 or 4 MB, just to avoid making the .torrent file too big.

Merkle torrents solves these problems by removing the tradeoff between .torrent size and piece size. With merkle torrents, the piece size can be the minimum block size (16 KB), which lets peers verify every block of data received from peers, immediately. This gives a minimum turnaround time and completely removes the problem of identifying malicious peers.

Applications

Some applications that use libtorrent:

See also

References

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.