Upgrading to libtorrent 2.1
| Author: | Arvid Norberg, arvid@libtorrent.org |
|---|
Table of contents
In libtorrent 2.1, some parts of the API has changed and some deprecated parts have been removed. This document summarizes the changes affecting library clients.
C++14 no longer supported
libtorrent 2.1 requires at least C++-17. To build with boost build, specify the C++ version using the cxxstd=17 build feature (17 is the default).
WebTorrent support
The major new feature in libtorrent 2.1 is WebTorrent support. WebTorrent requires a stun server, it can be configured via the webtorrent_stun_server configuration option. It defaults to "stun.l.google.com:19302".
WebTorrent support is enabled by default. To disable it, build with webtorrent=off (or -Dwebtorrent=OFF with CMake).
loading and saving torrents
The loading and saving of .torrent files and resume data has been simplified and responsibilities of classes have become clearer.
- torrent_info
- Represents the immutable info section of a torrent file. It includes:
- the file list
- piece hashes (v1 torrents)
- merkle root hashes (v2 torrents)
- add_torrent_params
- Represents the full torrent file, including:
- the torrent_info, which is the immutable part
- trackers
- web seed URLs
- piece layers (v2 torrents)
To load a torrent file from disk, use one of load_torrent_file(), load_torrent_buffer() or load_torrent_parsed(). Those functions return an add_torrent_params object containing all the information about the torrent.
To save a torrent file from an active torrent session, first ask for the add_torrent_params object by calling save_resume_data() and pass in the save_info_dict flag. The resulting save_resume_data_alert will contain an add_torrent_params object which can be saved to disk using write_torrent_file().
The torrent_info class can be thought of as representing the info-section of a torrent file (the aspects defining the info-hash of the torrent). These are immutable features of the torrent.
The add_torrent_params can be thought of as representing the whole torrent file, including the info-dictionary. This includes fields that do not define the content of the torrent. Things like trackers.
torrent_info::into()
The torrent_info class has a member function torrent_info::info(), that looks up arbitrary keys from the info-section of the torrent file. It can be used for extensions. This function is problematic because it is not thread safe. It relies on lazily parsing the info section, mutating the torrent_info object, even if it's const. This function has been deprecated and is discouraged from being used. Instead, fetch the info section via the torrent_info::info_section() function, and parse it yourself.
Creating torrents
There is a new API to create torrents. Previously the file structure and layout would first be defined in a file_storage object then passed to a create_torrent object's constructor. The new API instead builds the file list as a std::vector<lt::create_file_entry>.
The new API can be summarized by this example:
// recursively create a list of all files in the directory auto files = list_files("./my_torrent"); create_torrent t(std::move(files)); t.add_tracker("http://my.tracker.com/announce"); t.set_creator("libtorrent example"); // reads the files and calculates the hashes set_piece_hashes(t, "."); ofstream out("my_torrent.torrent", std::ios_base::binary); bencode(std::ostream_iterator<char>(out), t.generate());
The main motivations are:
- To simplify the torrent creation logic by not conflating loading and parsing
- existing torrents with the act of creating them. The file_storage object is primarily used for the former and has an API that's largely internal. e.g. it never makes sense to specify the file root when adding files to a torrent about to be created. The file root is computed by the hashes added later.
- To allow further optimizations of file_storage. By being used solely for
- representing an existing torrents file layout, it can be made more space efficient.
For more details, see create_torrent and create_file_entry.
resume data format
The resume data format has been optimized to use less space, especially for v2 torrents. The file-version has been bumped from 1 to 2 with some fields being serialized in a more space efficient manner.
The version-1 pieces field uses 8 bits per piece. 1 bit to indicate whether the piece had been downloaded and 1 bit to indicate whether the piece had been verified, in seed-mode. 6 of those bits were unused. In version-2, This field is now split into pieces and a verified, both of which are actual bitfields, one bit per piece.
Likewise, for merkle trees (for v2 torrents) the version-1 verified and mask fields are encoded as text. In version-2, these have been changed to actual bitfields.
A user-facing consequence is that the add_torrent_params class has changed slightly. The merkle_tree_mask and verified_leaf_hashes fields are now a sequences of bitfield objects.
load_resume_data() can still load the previous resume data format.
standard string_view
libtorrent now uses std::string_view instead of boost::string_view or boost::string_ref`. This affects libtorrent's API to some extent.
bump API version
By default, functions deprecated in libtorrent 1.1 and earlier are not included in the build now. To enable them, build with deprecated-functions=1.
entry as a variant
The entry class (representing a node in a bencoded tree) has always had variant-like properties. It can hold a string, integer, list of dictionary. This type now derives from std::variant to provide a standard variant interface.
session construction
Previously, session_flags_t could be passed directly to the session constructor. These constructors are now deprecated in favor of the unified constructor taking a session_params object. Flags can now be passed through the session_params object.
set_piece_hashes()
The signature of set_piece_hashes() has changed slightly, from taking a settings_interface to a settings_pack. The impact of this change is expected to be minimal, since settings_pack implements the settings_interface and is the only public type doing so.
disk_interface
The disk_interface class is a pure virtual interface implemented by disk I/O subsystems. Part of its interface is the status_t type. This type used to be an enum class, but has been turned into a flags type in 2.1. This is primarily to allow reporting the oversized_file condition (which was introduced in 2.0.6).
The flags can be found in the lt::disk_status namespace.
This change affects custom storage implementations.
storage_params
The storage_params type has two new fields indicating whether the torrent has v1 and/or v2 hashes. this allows disk I/O subsystems to know in advance whether block-hashes (v2 torrents) or flat piece hashes (v1 torrents) will be required.
As a consequence of torrent_info representing the immutable parts of the torrent, the file_storage class is moving towards being immutable as well. One step in this transition is to separate it from the torrent creation functionality (see Creating torrents above). The storage_params object is affected by no longer receiving two file_storage objects (the original and the ones with renamed files).
Renamed files are now recorded as a separate object, renamed_files. This is an overlay over the file_storage of the original torrent_info.
Asking a torrent_handle for the underlying torrent file (torrent_info) will not return a torrent whose file list represents renamed files. It will have the original file names in it. The resume data will contain renamed files.
