If you want to make sure the dht is initially created with your custom storage, create a session with the setting settings_pack::enable_dht to false, set your constructor function and call apply_settings with settings_pack::enable_dht to true.
[report issue]add_dht_node()
void add_dht_node (std::pair<std::string, int> const& node);
add_dht_node takes a host name and port pair. That endpoint will be pinged, and if a valid DHT reply is received, the node will be added to the routing table.
[report issue]dht_get_item()
void dht_get_item (sha1_hash const& target);
query the DHT for an immutable item at the target hash. the result is posted as a dht_immutable_item_alert.
[report issue]dht_get_item()
void dht_get_item (std::array<char, 32> key , std::string salt = std::string());
query the DHT for a mutable item under the public key key. this is an ed25519 key. salt is optional and may be left as an empty string if no salt is to be used. if the item is found in the DHT, a dht_mutable_item_alert is posted.
[report issue]dht_put_item()
sha1_hash dht_put_item (entry data);
store the given bencoded data as an immutable item in the DHT. the returned hash is the key that is to be used to look the item up again. It's just the SHA-1 hash of the bencoded form of the structure.
[report issue]dht_put_item()
void dht_put_item (std::array<char, 32> key , std::function<void(entry&, std::array<char, 64>& , std::int64_t&, std::string const&)> cb , std::string salt = std::string());
store a mutable item. The key is the public key the blob is to be stored under. The optional salt argument is a string that is to be mixed in with the key when determining where in the DHT the value is to be stored. The callback function is called from within the libtorrent network thread once we've found where to store the blob, possibly with the current value stored under the key. The values passed to the callback functions are:
- entry& value
- the current value stored under the key (may be empty). Also expected to be set to the value to be stored by the function.
- std::array<char,64>& signature
- the signature authenticating the current value. This may be zeros if there is currently no value stored. The function is expected to fill in this buffer with the signature of the new value to store. To generate the signature, you may want to use the sign_mutable_item function.
- std::int64_t& seq
- current sequence number. May be zero if there is no current value. The function is expected to set this to the new sequence number of the value that is to be stored. Sequence numbers must be monotonically increasing. Attempting to overwrite a value with a lower or equal sequence number will fail, even if the signature is correct.
- std::string const& salt
- this is the salt that was used for this put call.
Since the callback function cb is called from within libtorrent, it is critical to not perform any blocking operations. Ideally not even locking a mutex. Pass any data required for this function along with the function object's context and make the function entirely self-contained. The only reason data blob's value is computed via a function instead of just passing in the new value is to avoid race conditions. If you want to update the value in the DHT, you must first retrieve it, then modify it, then write it back. The way the DHT works, it is natural to always do a lookup before storing and calling the callback in between is convenient.
[report issue]dht_get_peers() dht_announce()
void dht_get_peers (sha1_hash const& info_hash); void dht_announce (sha1_hash const& info_hash, int port = 0, dht::announce_flags_t flags = {});
dht_get_peers() will issue a DHT get_peer request to the DHT for the specified info-hash. The response (the peers) will be posted back in a dht_get_peers_reply_alert.
dht_announce() will issue a DHT announce request to the DHT to the specified info-hash, advertising the specified port. If the port is left at its default, 0, the port will be implied by the DHT message's source port (which may improve connectivity through a NAT).
Both these functions are exposed for advanced custom use of the DHT. All torrents eligible to be announce to the DHT will be automatically, by libtorrent.
For possible flags, see announce_flags_t.
[report issue]dht_live_nodes()
void dht_live_nodes (sha1_hash const& nid);
Retrieve all the live DHT (identified by nid) nodes. All the nodes id and endpoint will be returned in the list of nodes in the alert dht_live_nodes_alert. Since this alert is a response to an explicit call, it will always be posted, regardless of the alert mask.
[report issue]dht_sample_infohashes()
void dht_sample_infohashes (udp::endpoint const& ep, sha1_hash const& target);
Query the DHT node specified by ep to retrieve a sample of the info-hashes that the node currently have in their storage. The target is included for iterative lookups so that indexing nodes can perform a key space traversal with a single RPC per node by adjusting the target value for each RPC. It has no effect on the returned sample value. The result is posted as a dht_sample_infohashes_alert.
[report issue]dht_direct_request()
void dht_direct_request (udp::endpoint const& ep, entry const& e, void* userdata = nullptr);
Send an arbitrary DHT request directly to the specified endpoint. This function is intended for use by plugins. When a response is received or the request times out, a dht_direct_response_alert will be posted with the response (if any) and the userdata pointer passed in here. Since this alert is a response to an explicit call, it will always be posted, regardless of the alert mask.
[report issue]add_extension()
void add_extension (std::function<std::shared_ptr<torrent_plugin>( torrent_handle const&, void*)> ext); void add_extension (std::shared_ptr<plugin> ext);
This function adds an extension to this session. The argument is a function object that is called with a torrent_handle and which should return a std::shared_ptr<torrent_plugin>. To write custom plugins, see libtorrent plugins. For the typical bittorrent client all of these extensions should be added. The main plugins implemented in libtorrent are:
- uTorrent metadata
- Allows peers to download the metadata (.torrent files) from the swarm directly. Makes it possible to join a swarm with just a tracker and info-hash.
#include <libtorrent/extensions/ut_metadata.hpp> ses.add_extension(<::create_ut_metadata_plugin);
- uTorrent peer exchange
- Exchanges peers between clients.
#include <libtorrent/extensions/ut_pex.hpp> ses.add_extension(<::create_ut_pex_plugin);
- smart ban plugin
- A plugin that, with a small overhead, can ban peers that sends bad data with very high accuracy. Should eliminate most problems on poisoned torrents.
#include <libtorrent/extensions/smart_ban.hpp> ses.add_extension(<::create_smart_ban_plugin);[report issue]
get_ip_filter() set_ip_filter()
ip_filter get_ip_filter () const; void set_ip_filter (ip_filter const& f);
Sets a filter that will be used to reject and accept incoming as well as outgoing connections based on their originating ip address. The default filter will allow connections to any ip address. To build a set of rules for which addresses are accepted and not, see ip_filter.
Each time a peer is blocked because of the IP filter, a peer_blocked_alert is generated. get_ip_filter() Returns the ip_filter currently in the session. See ip_filter.
[report issue]set_port_filter()
void set_port_filter (port_filter const& f);
apply port_filter f to incoming and outgoing peers. a port filter will reject making outgoing peer connections to certain remote ports. The main intention is to be able to avoid triggering certain anti-virus software by connecting to SMTP, FTP ports.
[report issue]listen_port() ssl_listen_port() is_listening()
bool is_listening () const; unsigned short listen_port () const; unsigned short ssl_listen_port () const;
is_listening() will tell you whether or not the session has successfully opened a listening port. If it hasn't, this function will return false, and then you can set a new settings_pack::listen_interfaces to try another interface and port to bind to.
listen_port() returns the port we ended up listening on.
[report issue]get_peer_class_filter() set_peer_class_filter()
ip_filter get_peer_class_filter () const; void set_peer_class_filter (ip_filter const& f);
Sets the peer class filter for this session. All new peer connections will take this into account and be added to the peer classes specified by this filter, based on the peer's IP address.
The ip-filter essentially maps an IP -> uint32. Each bit in that 32 bit integer represents a peer class. The least significant bit represents class 0, the next bit class 1 and so on.
For more info, see ip_filter.
For example, to make all peers in the range <IP_ADDRESS> - <IP_ADDRESS> belong to their own peer class, apply the following filter:
ip_filter f = ses.get_peer_class_filter(); peer_class_t my_class = ses.create_peer_class("200.1.x.x IP range"); f.add_rule(make_address("<IP_ADDRESS>"), make_address("<IP_ADDRESS>") , 1 << static_cast<std::uint32_t>(my_class)); ses.set_peer_class_filter(f);
This setting only applies to new connections, it won't affect existing peer connections.
This function is limited to only peer class 0-31, since there are only 32 bits in the IP range mapping. Only the set bits matter; no peer class will be removed from a peer as a result of this call, peer classes are only added.
The peer_class argument cannot be greater than 31. The bitmasks representing peer classes in the peer_class_filter are 32 bits.
The get_peer_class_filter() function returns the current filter.
For more information, see peer classes.
[report issue]set_peer_class_type_filter() get_peer_class_type_filter()
void set_peer_class_type_filter (peer_class_type_filter const& f); peer_class_type_filter get_peer_class_type_filter () const;
Sets and gets the peer class type filter. This is controls automatic peer class assignments to peers based on what kind of socket it is.
It does not only support assigning peer classes, it also supports removing peer classes based on socket type.
The order of these rules being applied are:
- peer-class IP filter
- peer-class type filter, removing classes
- peer-class type filter, adding classes
For more information, see peer classes.
[report issue]create_peer_class()
peer_class_t create_peer_class (char const* name);
Creates a new peer class (see peer classes) with the given name. The returned integer is the new peer class identifier. Peer classes may have the same name, so each invocation of this function creates a new class and returns a unique identifier.
Identifiers are assigned from low numbers to higher. So if you plan on using certain peer classes in a call to set_peer_class_filter(), make sure to create those early on, to get low identifiers.
For more information on peer classes, see peer classes.
[report issue]delete_peer_class()
void delete_peer_class (peer_class_t cid);
This call dereferences the reference count of the specified peer class. When creating a peer class it's automatically referenced by 1. If you want to recycle a peer class, you may call this function. You may only call this function once per peer class you create. Calling it more than once for the same class will lead to memory corruption.
Since peer classes are reference counted, this function will not remove the peer class if it's still assigned to torrents or peers. It will however remove it once the last peer and torrent drops their references to it.
There is no need to call this function for custom peer classes. All peer classes will be properly destructed when the session object destructs.
For more information on peer classes, see peer classes.
[report issue]get_peer_class() set_peer_class()
peer_class_info get_peer_class (peer_class_t cid) const; void set_peer_class (peer_class_t cid, peer_class_info const& pci);
These functions queries information from a peer class and updates the configuration of a peer class, respectively.
cid must refer to an existing peer class. If it does not, the return value of get_peer_class() is undefined.
set_peer_class() sets all the information in the peer_class_info object in the specified peer class. There is no option to only update a single property.
A peer or torrent belonging to more than one class, the highest priority among any of its classes is the one that is taken into account.
For more information, see peer classes.
[report issue]remove_torrent()
void remove_torrent (const torrent_handle& h, remove_flags_t options = {});
remove_torrent() will close all peer connections associated with the torrent and tell the tracker that we've stopped participating in the swarm. This operation cannot fail. When it completes, you will receive a torrent_removed_alert.
The optional second argument options can be used to delete all the files downloaded by this torrent. To do so, pass in the value session_handle::delete_files. The removal of the torrent is asynchronous, there is no guarantee that adding the same torrent immediately after it was removed will not throw a system_error exception. Once the torrent is deleted, a torrent_deleted_alert is posted.
Note that when a queued or downloading torrent is removed, its position in the download queue is vacated and every subsequent torrent in the queue has their queue positions updated. This can potentially cause a large state_update to be posted. When removing all torrents, it is advised to remove them from the back of the queue, to minimize the shifting.
[report issue]get_settings() apply_settings()
void apply_settings (settings_pack&& s); settings_pack get_settings () const; void apply_settings (settings_pack const& s);
Applies the settings specified by the settings_pack s. This is an asynchronous operation that will return immediately and actually apply the settings to the main thread of libtorrent some time later.
[report issue]pop_alerts() wait_for_alert() set_alert_notify()
void pop_alerts (std::vector<alert*>* alerts); void set_alert_notify (std::function<void()> const& fun); alert* wait_for_alert (time_duration max_wait);
Alerts is the main mechanism for libtorrent to report errors and events. pop_alerts fills in the vector passed to it with pointers to new alerts.  You may not delete the alert objects.
It is safe to call pop_alerts from multiple different threads, as long as the alerts themselves are not accessed once another thread calls pop_alerts. Doing this requires manual synchronization between the popping threads.
wait_for_alert will block the current thread for max_wait time duration, or until another alert is posted. If an alert is available at the time of the call, it returns immediately. The returned alert pointer is the head of the alert queue. wait_for_alert does not pop alerts from the queue, it merely peeks at it. The returned alert will stay valid until pop_alerts is called twice. The first time will pop it and the second will free it.
If there is no alert in the queue and no alert arrives within the specified timeout, wait_for_alert returns nullptr.
In the python binding, wait_for_alert takes the number of milliseconds to wait as an integer.
The alert queue in the session will not grow indefinitely. Make sure to pop periodically to not miss notifications. To control the max number of alerts that's queued by the session, see settings_pack::alert_queue_size.
Some alerts are considered so important that they are posted even when the alert queue is full. Some alerts are considered mandatory and cannot be disabled by the alert_mask. For instance, save_resume_data_alert and save_resume_data_failed_alert are always posted, regardless of the alert mask.
To control which alerts are posted, set the alert_mask (settings_pack::alert_mask).
If the alert queue fills up to the point where alerts are dropped, this will be indicated by a alerts_dropped_alert, which contains a bitmask of which types of alerts were dropped. Generally it is a good idea to make sure the alert queue is large enough, the alert_mask doesn't have unnecessary categories enabled and to call pop_alert() frequently, to avoid alerts being dropped.
the set_alert_notify function lets the client set a function object to be invoked every time the alert queue goes from having 0 alerts to 1 alert. This function is called from within libtorrent, it may be the main thread, or it may be from within a user call. The intention of of the function is that the client wakes up its main thread, to poll for more alerts using pop_alerts(). If the notify function fails to do so, it won't be called again, until pop_alerts is called for some other reason. For instance, it could signal an eventfd, post a message to an HWND or some other main message pump. The actual retrieval of alerts should not be done in the callback. In fact, the callback should not block. It should not perform any expensive work. It really should just notify the main application thread.
The type of an alert is returned by the polymorphic function alert::type() but can also be queries from a concrete type via T::alert_type, as a static constant.
[report issue]add_port_mapping() delete_port_mapping()
void delete_port_mapping (port_mapping_t handle); std::vector<port_mapping_t> add_port_mapping (portmap_protocol t, int external_port, int local_port);
add_port_mapping adds one or more port forwards on UPnP and/or NAT-PMP, whichever is enabled. A mapping is created for each listen socket in the session. The return values are all handles referring to the port mappings that were just created. Pass them to delete_port_mapping() to remove them.
[report issue]reopen_network_sockets()
void reopen_network_sockets (reopen_network_flags_t options = reopen_map_ports);
Instructs the session to reopen all listen and outgoing sockets.
It's useful in the case your platform doesn't support the built in IP notifier mechanism, or if you have a better more reliable way to detect changes in the IP routing table.
[report issue]native_handle()
std::shared_ptr<aux::session_impl> native_handle () const;
This function is intended only for use by plugins. This type does not have a stable API and should be relied on as little as possible.
[report issue]- save_settings
- saves settings (i.e. the settings_pack)
- save_dht_settings
- saves dht_settings
- save_dht_state
- saves dht state such as nodes and node-id, possibly accelerating joining the DHT if provided at next session startup.
- global_peer_class_id tcp_peer_class_id local_peer_class_id
- built-in peer classes
- delete_files
- delete the files belonging to the torrent from disk. including the part-file, if there is one
- delete_partfile
- delete just the part-file associated with this torrent
- add_default_plugins
- this will add common extensions like ut_pex, ut_metadata, lt_tex smart_ban and possibly others.
- udp tcp
- protocols used by add_port_mapping()
- reopen_map_ports
- This option indicates if the ports are mapped using natpmp and upnp. If mapping was already made, they are deleted and added again. This only works if natpmp and/or upnp are configured to be enable.
session_proxy
Declared in "libtorrent/session.hpp"
this is a holder for the internal session implementation object. Once the session destruction is explicitly initiated, this holder is used to synchronize the completion of the shutdown. The lifetime of this object may outlive session, causing the session destructor to not block. The session_proxy destructor will block however, until the underlying session is done shutting down.
class session_proxy { session_proxy (session_proxy&&) noexcept; session_proxy& operator= (session_proxy const&); ~session_proxy (); session_proxy& operator= (session_proxy&&) noexcept; session_proxy (); session_proxy (session_proxy const&); };[report issue]
session_proxy() ~session_proxy() operator=()
session_proxy (session_proxy&&) noexcept; session_proxy& operator= (session_proxy const&); ~session_proxy (); session_proxy& operator= (session_proxy&&) noexcept; session_proxy (); session_proxy (session_proxy const&);
default constructor, does not refer to any session implementation object.
[report issue]session_params
Declared in "libtorrent/session.hpp"
The session_params is a parameters pack for configuring the session before it's started.
struct session_params { explicit session_params (settings_pack&& sp); explicit session_params (settings_pack const& sp); session_params (); session_params (settings_pack&& sp , std::vector<std::shared_ptr<plugin>> exts); session_params (settings_pack const& sp , std::vector<std::shared_ptr<plugin>> exts); settings_pack settings; std::vector<std::shared_ptr<plugin>> extensions; dht::dht_settings dht_settings; dht::dht_state dht_state; dht::dht_storage_constructor_type dht_storage_constructor; };[report issue]
session_params()
explicit session_params (settings_pack&& sp); explicit session_params (settings_pack const& sp); session_params ();
This constructor can be used to start with the default plugins (ut_metadata, ut_pex and smart_ban). The default values in the settings is to start the default features like upnp, NAT-PMP, and dht for example.
[report issue]session_params()
session_params (settings_pack&& sp , std::vector<std::shared_ptr<plugin>> exts); session_params (settings_pack const& sp , std::vector<std::shared_ptr<plugin>> exts);
This constructor helps to configure the set of initial plugins to be added to the session before it's started.
[report issue]session
Declared in "libtorrent/session.hpp"
The session holds all state that spans multiple torrents. Among other things it runs the network loop and manages all torrents. Once it's created, the session object will spawn the main thread that will do all the work. The main thread will be idle as long it doesn't have any torrents to participate in.
You have some control over session configuration through the session_handle::apply_settings() member function. To change one or more configuration options, create a settings_pack. object and fill it with the settings to be set and pass it in to session::apply_settings().
see apply_settings().
class session : public session_handle { explicit session (session_params&& params); session (); explicit session (session_params const& params); session (session_params&& params, io_service& ios); session (session_params const& params, io_service& ios); session (settings_pack const& pack , session_flags_t const flags = add_default_plugins); session (settings_pack&& pack , session_flags_t const flags = add_default_plugins); session (session&&) = default; session& operator= (session&&) = default; session& operator= (session const&) = delete; session (session const&) = delete; session (settings_pack&& pack , io_service& ios , session_flags_t const flags = add_default_plugins); session (settings_pack const& pack , io_service& ios , session_flags_t const flags = add_default_plugins); ~session (); session_proxy abort (); };[report issue]
session()
explicit session (session_params&& params); session (); explicit session (session_params const& params);
Constructs the session objects which acts as the container of torrents. In order to avoid a race condition between starting the session and configuring it, you can pass in a session_params object. Its settings will take effect before the session starts up.
[report issue]session()
session (session_params&& params, io_service& ios); session (session_params const& params, io_service& ios);
Overload of the constructor that takes an external io_service to run the session object on. This is primarily useful for tests that may want to run multiple sessions on a single io_service, or low resource systems where additional threads are expensive and sharing an io_service with other events is fine.
Warning
The session object does not cleanly terminate with an external io_service. The io_service::run() call _must_ have returned before it's safe to destruct the session. Which means you MUST call session::abort() and save the session_proxy first, then destruct the session object, then sync with the io_service, then destruct the session_proxy object.
session()
session (settings_pack const& pack , session_flags_t const flags = add_default_plugins); session (settings_pack&& pack , session_flags_t const flags = add_default_plugins);
Constructs the session objects which acts as the container of torrents. It provides configuration options across torrents (such as rate limits, disk cache, ip filter etc.). In order to avoid a race condition between starting the session and configuring it, you can pass in a settings_pack object. Its settings will take effect before the session starts up.
The flags parameter can be used to start default features (UPnP & NAT-PMP) and default plugins (ut_metadata, ut_pex and smart_ban). The default is to start those features. If you do not want them to start, pass 0 as the flags parameter.
[report issue]session() operator=()
session (session&&) = default; session& operator= (session&&) = default;
movable
[report issue]session() operator=()
session& operator= (session const&) = delete; session (session const&) = delete;
non-copyable
[report issue]session()
session (settings_pack&& pack , io_service& ios , session_flags_t const flags = add_default_plugins); session (settings_pack const& pack , io_service& ios , session_flags_t const flags = add_default_plugins);
overload of the constructor that takes an external io_service to run the session object on. This is primarily useful for tests that may want to run multiple sessions on a single io_service, or low resource systems where additional threads are expensive and sharing an io_service with other events is fine.
Warning
The session object does not cleanly terminate with an external io_service. The io_service::run() call _must_ have returned before it's safe to destruct the session. Which means you MUST call session::abort() and save the session_proxy first, then destruct the session object, then sync with the io_service, then destruct the session_proxy object.
~session()
~session ();
The destructor of session will notify all trackers that our torrents have been shut down. If some trackers are down, they will time out. All this before the destructor of session returns. So, it's advised that any kind of interface (such as windows) are closed before destructing the session object. Because it can take a few second for it to finish. The timeout can be set with apply_settings().
[report issue]abort()
session_proxy abort ();
In case you want to destruct the session asynchronously, you can request a session destruction proxy. If you don't do this, the destructor of the session object will block while the trackers are contacted. If you keep one session_proxy to the session when destructing it, the destructor will not block, but start to close down the session, the destructor of the proxy will then synchronize the threads. So, the destruction of the session is performed from the session destructor call until the session_proxy destructor call. The session_proxy does not have any operations on it (since the session is being closed down, no operations are allowed on it). The only valid operation is calling the destructor:
class session_proxy { public: session_proxy(); ~session_proxy() };[report issue]
session_stats_metrics()
Declared in "libtorrent/session_stats.hpp"
std::vector<stats_metric> session_stats_metrics ();
This free function returns the list of available metrics exposed by libtorrent's statistics API. Each metric has a name and a value index. The value index is the index into the array in session_stats_alert where this metric's value can be found when the session stats is sampled (by calling post_session_stats()).
[report issue]find_metric_idx()
Declared in "libtorrent/session_stats.hpp"
int find_metric_idx (string_view name);
given a name of a metric, this function returns the counter index of it, or -1 if it could not be found. The counter index is the index into the values array returned by session_stats_alert.
[report issue]read_session_params()
Declared in "libtorrent/session.hpp"
session_params read_session_params (bdecode_node const& e , save_state_flags_t flags = save_state_flags_t::all());
This function helps to construct a session_params from a bencoded data generated by session_handle::save_state
[report issue]enum metric_type_t
Declared in "libtorrent/session_stats.hpp"
| name | value | description |
|---|---|---|
| counter | 0 | |
| gauge | 1 |
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Plugins
libtorrent has a plugin interface for implementing extensions to the protocol. These can be general extensions for transferring metadata or peer exchange extensions, or it could be used to provide a way to customize the protocol to fit a particular (closed) network.
In short, the plugin interface makes it possible to:
- register extension messages (sent in the extension handshake), see extensions.
- add data and parse data from the extension handshake.
- send extension messages and standard bittorrent messages.
- override or block the handling of standard bittorrent messages.
- save and restore state via the session state
- see all alerts that are posted
a word of caution
Writing your own plugin is a very easy way to introduce serious bugs such as dead locks and race conditions. Since a plugin has access to internal structures it is also quite easy to sabotage libtorrent's operation.
All the callbacks are always called from the libtorrent network thread. In case portions of your plugin are called from other threads, typically the main thread, you cannot use any of the member functions on the internal structures in libtorrent, since those require being called from the libtorrent network thread . Furthermore, you also need to synchronize your own shared data within the plugin, to make sure it is not accessed at the same time from the libtorrent thread (through a callback). If you need to send out a message from another thread, it is advised to use an internal queue, and do the actual sending in tick().
Since the plugin interface gives you easy access to internal structures, it is not supported as a stable API. Plugins should be considered specific to a specific version of libtorrent. Although, in practice the internals mostly don't change that dramatically.
plugin-interface
The plugin interface consists of three base classes that the plugin may implement. These are called plugin, torrent_plugin and peer_plugin. They are found in the <libtorrent/extensions.hpp> header.
These plugins are instantiated for each session, torrent and possibly each peer, respectively.
For plugins that only need per torrent state, it is enough to only implement torrent_plugin and pass a constructor function or function object to session::add_extension() or torrent_handle::add_extension() (if the torrent has already been started and you want to hook in the extension at run-time).
The signature of the function is:
std::shared_ptr<torrent_plugin> (*)(torrent_handle const&, void*);
The second argument is the userdata passed to session::add_torrent() or torrent_handle::add_extension().
The function should return a std::shared_ptr<torrent_plugin> which may or may not be 0. If it is a nullptr, the extension is simply ignored for this torrent. If it is a valid pointer (to a class inheriting torrent_plugin), it will be associated with this torrent and callbacks will be made on torrent events.
For more elaborate plugins which require session wide state, you would implement plugin, construct an object (in a std::shared_ptr) and pass it in to session::add_extension().
custom alerts
Since plugins are running within internal libtorrent threads, one convenient way to communicate with the client is to post custom alerts.
The expected interface of any alert, apart from deriving from the alert base class, looks like this:
static const int alert_type = <unique alert ID>; virtual int type() const { return alert_type; } virtual std::string message() const; static const alert_category_t static_category = <bitmask of alert::category_t flags>; virtual alert_category_t category() const { return static_category; } virtual char const* what() const { return <string literal of the name of this alert>; }
The alert_type is used for the type-checking in alert_cast. It must not collide with any other alert. The built-in alerts in libtorrent will not use alert type IDs greater than user_alert_id. When defining your own alert, make sure it's greater than this constant.
type() is the run-time equivalence of the alert_type.
The message() virtual function is expected to construct a useful string representation of the alert and the event or data it represents. Something convenient to put in a log file for instance.
clone() is used internally to copy alerts. The suggested implementation of simply allocating a new instance as a copy of *this is all that's expected.
The static category is required for checking whether or not the category for a specific alert is enabled or not, without instantiating the alert. The category virtual function is the run-time equivalence.
The what() virtual function may simply be a string literal of the class name of your alert.
For more information, see the alert section.
[report issue]plugin
Declared in "libtorrent/extensions.hpp"
this is the base class for a session plugin. One primary feature is that it is notified of all torrents that are added to the session, and can add its own torrent_plugins.
struct plugin { virtual feature_flags_t implemented_features (); virtual std::shared_ptr<torrent_plugin> new_torrent (torrent_handle const&, void*); virtual void added (session_handle const&); virtual bool on_dht_request (string_view /* query */ , udp::endpoint const& /* source */, bdecode_node const& /* message */ , entry& /* response */); virtual void on_alert (alert const*); virtual bool on_unknown_torrent (sha1_hash const& /* info_hash */ , peer_connection_handle const& /* pc */, add_torrent_params& /* p */); virtual void on_tick (); virtual uint64_t get_unchoke_priority (peer_connection_handle const& /* peer */); virtual void save_state (entry&); virtual void load_state (bdecode_node const&); static constexpr feature_flags_t optimistic_unchoke_feature = 1_bit; static constexpr feature_flags_t tick_feature = 2_bit; static constexpr feature_flags_t dht_request_feature = 3_bit; static constexpr feature_flags_t alert_feature = 4_bit; };[report issue]
implemented_features()
virtual feature_flags_t implemented_features ();
This function is expected to return a bitmask indicating which features this plugin implements. Some callbacks on this object may not be called unless the corresponding feature flag is returned here. Note that callbacks may still be called even if the corresponding feature is not specified in the return value here. See feature_flags_t for possible flags to return.
[report issue]new_torrent()
virtual std::shared_ptr<torrent_plugin> new_torrent (torrent_handle const&, void*);
this is called by the session every time a new torrent is added. The torrent* points to the internal torrent object created for the new torrent. The void* is the userdata pointer as passed in via add_torrent_params.
If the plugin returns a torrent_plugin instance, it will be added to the new torrent. Otherwise, return an empty shared_ptr to a torrent_plugin (the default).
[report issue]added()
virtual void added (session_handle const&);
called when plugin is added to a session
[report issue]on_dht_request()
virtual bool on_dht_request (string_view /* query */ , udp::endpoint const& /* source */, bdecode_node const& /* message */ , entry& /* response */);
called when a dht request is received. If your plugin expects this to be called, make sure to include the flag dht_request_feature in the return value from implemented_features().
[report issue]on_alert()
virtual void on_alert (alert const*);
called when an alert is posted alerts that are filtered are not posted. If your plugin expects this to be called, make sure to include the flag alert_feature in the return value from implemented_features().
[report issue]on_unknown_torrent()
virtual bool on_unknown_torrent (sha1_hash const& /* info_hash */ , peer_connection_handle const& /* pc */, add_torrent_params& /* p */);
return true if the add_torrent_params should be added
[report issue]on_tick()
virtual void on_tick ();
called once per second. If your plugin expects this to be called, make sure to include the flag tick_feature in the return value from implemented_features().
[report issue]get_unchoke_priority()
virtual uint64_t get_unchoke_priority (peer_connection_handle const& /* peer */);
called when choosing peers to optimistically unchoke. The return value indicates the peer's priority for unchoking. Lower return values correspond to higher priority. Priorities above 2^63-1 are reserved. If your plugin has no priority to assign a peer it should return 2^64-1. If your plugin expects this to be called, make sure to include the flag optimistic_unchoke_feature in the return value from implemented_features(). If multiple plugins implement this function the lowest return value (i.e. the highest priority) is used.
[report issue]load_state()
virtual void load_state (bdecode_node const&);
called when loading settings state
[report issue]- optimistic_unchoke_feature
- include this bit if your plugin needs to alter the order of the optimistic unchoke of peers. i.e. have the on_optimistic_unchoke() callback be called.
- dht_request_feature
- include this bit if your plugin needs to have on_dht_request() called
- alert_feature
- include this bit if your plugin needs to have on_alert() called
torrent_plugin
Declared in "libtorrent/extensions.hpp"
Torrent plugins are associated with a single torrent and have a number of functions called at certain events. Many of its functions have the ability to change or override the default libtorrent behavior.
struct torrent_plugin { virtual std::shared_ptr<peer_plugin> new_connection (peer_connection_handle const&); virtual void on_piece_failed (piece_index_t); virtual void on_piece_pass (piece_index_t); virtual void tick (); virtual bool on_resume (); virtual bool on_pause (); virtual void on_files_checked (); virtual void on_state (torrent_status::state_t); virtual void on_add_peer (tcp::endpoint const&, peer_source_flags_t, add_peer_flags_t); static constexpr add_peer_flags_t first_time = 1_bit; static constexpr add_peer_flags_t filtered = 2_bit; };[report issue]
new_connection()
virtual std::shared_ptr<peer_plugin> new_connection (peer_connection_handle const&);
This function is called each time a new peer is connected to the torrent. You may choose to ignore this by just returning a default constructed shared_ptr (in which case you don't need to override this member function).
If you need an extension to the peer connection (which most plugins do) you are supposed to return an instance of your peer_plugin class. Which in turn will have its hook functions called on event specific to that peer.
The peer_connection_handle will be valid as long as the shared_ptr is being held by the torrent object. So, it is generally a good idea to not keep a shared_ptr to your own peer_plugin. If you want to keep references to it, use weak_ptr.
If this function throws an exception, the connection will be closed.
[report issue]on_piece_failed() on_piece_pass()
virtual void on_piece_failed (piece_index_t); virtual void on_piece_pass (piece_index_t);
These hooks are called when a piece passes the hash check or fails the hash check, respectively. The index is the piece index that was downloaded. It is possible to access the list of peers that participated in sending the piece through the torrent and the piece_picker.
[report issue]tick()
virtual void tick ();
This hook is called approximately once per second. It is a way of making it easy for plugins to do timed events, for sending messages or whatever.
[report issue]on_resume() on_pause()
virtual bool on_resume (); virtual bool on_pause ();
These hooks are called when the torrent is paused and resumed respectively. The return value indicates if the event was handled. A return value of true indicates that it was handled, and no other plugin after this one will have this hook function called, and the standard handler will also not be invoked. So, returning true effectively overrides the standard behavior of pause or resume.
Note that if you call pause() or resume() on the torrent from your handler it will recurse back into your handler, so in order to invoke the standard handler, you have to keep your own state on whether you want standard behavior or overridden behavior.
[report issue]on_files_checked()
virtual void on_files_checked ();
This function is called when the initial files of the torrent have been checked. If there are no files to check, this function is called immediately.
i.e. This function is always called when the torrent is in a state where it can start downloading.
[report issue]on_state()
virtual void on_state (torrent_status::state_t);
called when the torrent changes state the state is one of torrent_status::state_t enum members
[report issue]on_add_peer()
virtual void on_add_peer (tcp::endpoint const&, peer_source_flags_t, add_peer_flags_t);
called every time a new peer is added to the peer list. This is before the peer is connected to. For flags, see torrent_plugin::flags_t. The source argument refers to the source where we learned about this peer from. It's a bitmask, because many sources may have told us about the same peer. For peer source flags, see peer_info::peer_source_flags.
[report issue]- first_time
- this is the first time we see this peer
- filtered
- this peer was not added because it was filtered by the IP filter
peer_plugin
Declared in "libtorrent/extensions.hpp"
peer plugins are associated with a specific peer. A peer could be both a regular bittorrent peer (bt_peer_connection) or one of the web seed connections (web_peer_connection or http_seed_connection). In order to only attach to certain peers, make your torrent_plugin::new_connection only return a plugin for certain peer connection types
struct peer_plugin { virtual string_view type () const; virtual void add_handshake (entry&); virtual void on_disconnect (error_code const&); virtual void on_connected (); virtual bool on_handshake (span<char const>); virtual bool on_extension_handshake (bdecode_node const&); virtual bool on_bitfield (bitfield const& /*bitfield*/); virtual bool on_dont_have (piece_index_t); virtual bool on_request (peer_request const&); virtual bool on_unchoke (); virtual bool on_interested (); virtual bool on_have_all (); virtual bool on_allowed_fast (piece_index_t); virtual bool on_have_none (); virtual bool on_choke (); virtual bool on_not_interested (); virtual bool on_have (piece_index_t); virtual bool on_piece (peer_request const& /*piece*/ , span<char const> /*buf*/); virtual bool on_suggest (piece_index_t); virtual bool on_reject (peer_request const&); virtual bool on_cancel (peer_request const&); virtual void sent_unchoke (); virtual void sent_payload (int /* bytes */); virtual bool can_disconnect (error_code const& /*ec*/); virtual bool on_extended (int /*length*/, int /*msg*/, span<char const> /*body*/); virtual bool on_unknown_message (int /*length*/, int /*msg*/, span<char const> /*body*/); virtual void on_piece_failed (piece_index_t); virtual void on_piece_pass (piece_index_t); virtual void tick (); virtual bool write_request (peer_request const&); };[report issue]
type()
virtual string_view type () const;
This function is expected to return the name of the plugin.
[report issue]add_handshake()
virtual void add_handshake (entry&);
can add entries to the extension handshake this is not called for web seeds
[report issue]on_disconnect()
virtual void on_disconnect (error_code const&);
called when the peer is being disconnected.
[report issue]on_connected()
virtual void on_connected ();
called when the peer is successfully connected. Note that incoming connections will have been connected by the time the peer plugin is attached to it, and won't have this hook called.
[report issue]on_handshake()
virtual bool on_handshake (span<char const>);
this is called when the initial bittorrent handshake is received. Returning false means that the other end doesn't support this extension and will remove it from the list of plugins. this is not called for web seeds
[report issue]on_extension_handshake()
virtual bool on_extension_handshake (bdecode_node const&);
called when the extension handshake from the other end is received if this returns false, it means that this extension isn't supported by this peer. It will result in this peer_plugin being removed from the peer_connection and destructed. this is not called for web seeds
[report issue]on_bitfield() on_have_none() on_unchoke() on_have() on_choke() on_request() on_not_interested() on_interested() on_allowed_fast() on_have_all() on_dont_have()
virtual bool on_bitfield (bitfield const& /*bitfield*/); virtual bool on_dont_have (piece_index_t); virtual bool on_request (peer_request const&); virtual bool on_unchoke (); virtual bool on_interested (); virtual bool on_have_all (); virtual bool on_allowed_fast (piece_index_t); virtual bool on_have_none (); virtual bool on_choke (); virtual bool on_not_interested (); virtual bool on_have (piece_index_t);
returning true from any of the message handlers indicates that the plugin has handled the message. it will break the plugin chain traversing and not let anyone else handle the message, including the default handler.
[report issue]on_piece()
virtual bool on_piece (peer_request const& /*piece*/ , span<char const> /*buf*/);
This function is called when the peer connection is receiving a piece. buf points (non-owning pointer) to the data in an internal immutable disk buffer. The length of the data is specified in the length member of the piece parameter. returns true to indicate that the piece is handled and the rest of the logic should be ignored.
[report issue]sent_unchoke()
virtual void sent_unchoke ();
called after a choke message has been sent to the peer
[report issue]sent_payload()
virtual void sent_payload (int /* bytes */);
called after piece data has been sent to the peer this can be used for stats book keeping
[report issue]can_disconnect()
virtual bool can_disconnect (error_code const& /*ec*/);
called when libtorrent think this peer should be disconnected. if the plugin returns false, the peer will not be disconnected.
[report issue]on_extended()
virtual bool on_extended (int /*length*/, int /*msg*/, span<char const> /*body*/);
called when an extended message is received. If returning true, the message is not processed by any other plugin and if false is returned the next plugin in the chain will receive it to be able to handle it. This is not called for web seeds. thus function may be called more than once per incoming message, but only the last of the calls will the body size equal the length. i.e. Every time another fragment of the message is received, this function will be called, until finally the whole message has been received. The purpose of this is to allow early disconnects for invalid messages and for reporting progress of receiving large messages.
[report issue]on_unknown_message()
virtual bool on_unknown_message (int /*length*/, int /*msg*/, span<char const> /*body*/);
this is not called for web seeds
[report issue]on_piece_failed() on_piece_pass()
virtual void on_piece_failed (piece_index_t); virtual void on_piece_pass (piece_index_t);
called when a piece that this peer participated in either fails or passes the hash_check
[report issue]write_request()
virtual bool write_request (peer_request const&);
called each time a request message is to be sent. If true is returned, the original request message won't be sent and no other plugin will have this function called.
[report issue]crypto_plugin
Declared in "libtorrent/extensions.hpp"
struct crypto_plugin { virtual void set_outgoing_key (span<char const> key) = 0; virtual void set_incoming_key (span<char const> key) = 0; encrypt (span<span<char>> /*send_vec*/) = 0; virtual std::tuple<int, int, int> decrypt (span<span<char>> /*receive_vec*/) = 0; };[report issue]
decrypt()
virtual std::tuple<int, int, int> decrypt (span<span<char>> /*receive_vec*/) = 0;
decrypt the provided buffers. returns is a tuple representing the values (consume, produce, packet_size)
consume is set to the number of bytes which should be trimmed from the head of the buffers, default is 0
produce is set to the number of bytes of payload which are now ready to be sent to the upper layer. default is the number of bytes passed in receive_vec
packet_size is set to the minimum number of bytes which must be read to advance the next step of decryption. default is 0
[report issue]create_ut_metadata_plugin()
Declared in "libtorrent/extensions/ut_metadata.hpp"
std::shared_ptr<torrent_plugin> create_ut_metadata_plugin (torrent_handle const&, void*);
constructor function for the ut_metadata extension. The ut_metadata extension allows peers to request the .torrent file (or more specifically the info-dictionary of the .torrent file) from each other. This is the main building block in making magnet links work. This extension is enabled by default unless explicitly disabled in the session constructor.
This can either be passed in the add_torrent_params::extensions field, or via torrent_handle::add_extension().
[report issue]create_smart_ban_plugin()
Declared in "libtorrent/extensions/smart_ban.hpp"
std::shared_ptr<torrent_plugin> create_smart_ban_plugin (torrent_handle const&, void*);
constructor function for the smart ban extension. The extension keeps track of the data peers have sent us for failing pieces and once the piece completes and passes the hash check bans the peers that turned out to have sent corrupt data. This function can either be passed in the add_torrent_params::extensions field, or via torrent_handle::add_extension().
[report issue]create_ut_pex_plugin()
Declared in "libtorrent/extensions/ut_pex.hpp"
std::shared_ptr<torrent_plugin> create_ut_pex_plugin (torrent_handle const&, void*);
constructor function for the ut_pex extension. The ut_pex extension allows peers to gossip about their connections, allowing the swarm stay well connected and peers aware of more peers in the swarm. This extension is enabled by default unless explicitly disabled in the session constructor.
This can either be passed in the add_torrent_params::extensions field, or via torrent_handle::add_extension().
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Create Torrents
This section describes the functions and classes that are used to create torrent files. It is a layered API with low level classes and higher level convenience functions. A torrent is created in 4 steps:
- first the files that will be part of the torrent are determined.
- the torrent properties are set, such as tracker url, web seeds, DHT nodes etc.
- Read through all the files in the torrent, SHA-1 all the data and set the piece hashes.
- The torrent is bencoded into a file or buffer.
If there are a lot of files and or deep directory hierarchies to traverse, step one can be time consuming.
Typically step 3 is by far the most time consuming step, since it requires to read all the bytes from all the files in the torrent.
All of these classes and functions are declared by including libtorrent/create_torrent.hpp.
example:
file_storage fs; // recursively adds files in directories add_files(fs, "./my_torrent"); create_torrent t(fs); 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());[report issue]
create_torrent
Declared in "libtorrent/create_torrent.hpp"
This class holds state for creating a torrent. After having added all information to it, call create_torrent::generate() to generate the torrent. The entry that's returned can then be bencoded into a .torrent file using bencode().
struct create_torrent { explicit create_torrent (file_storage& fs, int piece_size = 0 , int pad_file_limit = -1, create_flags_t flags = optimize_alignment , int alignment = -1); explicit create_torrent (torrent_info const& ti); entry generate () const; file_storage const& files () const; void set_comment (char const* str); void set_creator (char const* str); void set_hash (piece_index_t index, sha1_hash const& h); void set_file_hash (file_index_t index, sha1_hash const& h); void add_url_seed (string_view url); void add_http_seed (string_view url); void add_node (std::pair<std::string, int> node); void add_tracker (string_view url, int tier = 0); void set_root_cert (string_view pem); bool priv () const; void set_priv (bool p); int num_pieces () const; int piece_size (piece_index_t i) const; int piece_length () const; std::vector<sha1_hash> const& merkle_tree () const; void add_similar_torrent (sha1_hash ih); void add_collection (string_view c); static constexpr create_flags_t optimize_alignment = 0_bit; static constexpr create_flags_t merkle = 1_bit; static constexpr create_flags_t modification_time = 2_bit; static constexpr create_flags_t symlinks = 3_bit; static constexpr create_flags_t mutable_torrent_support = 4_bit; };[report issue]
create_torrent()
explicit create_torrent (file_storage& fs, int piece_size = 0 , int pad_file_limit = -1, create_flags_t flags = optimize_alignment , int alignment = -1); explicit create_torrent (torrent_info const& ti);
The piece_size is the size of each piece in bytes. It must be a multiple of 16 kiB. If a piece size of 0 is specified, a piece_size will be calculated such that the torrent file is roughly 40 kB.
If a pad_file_limit is specified (other than -1), any file larger than the specified number of bytes will be preceded by a pad file to align it with the start of a piece. The pad_file_limit is ignored unless the optimize_alignment flag is passed. Typically it doesn't make sense to set this any lower than 4 kiB.
The overload that takes a torrent_info object will make a verbatim copy of its info dictionary (to preserve the info-hash). The copy of the info dictionary will be used by create_torrent::generate(). This means that none of the member functions of create_torrent that affects the content of the info dictionary (such as set_hash()), will have any affect.
The flags arguments specifies options for the torrent creation. It can be any combination of the flags defined by create_flags_t.
alignment is used when pad files are enabled. This is the size eligible files are aligned to. The default is -1, which means the piece size of the torrent.
[report issue]generate()
entry generate () const;
This function will generate the .torrent file as a bencode tree. In order to generate the flat file, use the bencode() function.
It may be useful to add custom entries to the torrent file before bencoding it and saving it to disk.
If anything goes wrong during torrent generation, this function will return an empty entry structure. You can test for this condition by querying the type of the entry:
file_storage fs; // add file ... create_torrent t(fs); // add trackers and piece hashes ... e = t.generate(); if (e.type() == entry::undefined_t) { // something went wrong }
For instance, you cannot generate a torrent with 0 files in it. If you don't add any files to the file_storage, torrent generation will fail.
[report issue]files()
file_storage const& files () const;
returns an immutable reference to the file_storage used to create the torrent from.
[report issue]set_comment()
void set_comment (char const* str);
Sets the comment for the torrent. The string str should be utf-8 encoded. The comment in a torrent file is optional.
[report issue]set_creator()
void set_creator (char const* str);
Sets the creator of the torrent. The string str should be utf-8 encoded. This is optional.
[report issue]set_hash()
void set_hash (piece_index_t index, sha1_hash const& h);
This sets the SHA-1 hash for the specified piece (index). You are required to set the hash for every piece in the torrent before generating it. If you have the files on disk, you can use the high level convenience function to do this. See set_piece_hashes().
[report issue]set_file_hash()
void set_file_hash (file_index_t index, sha1_hash const& h);
This sets the sha1 hash for this file. This hash will end up under the key sha1 associated with this file (for multi-file torrents) or in the root info dictionary for single-file torrents.
[report issue]add_url_seed() add_http_seed()
void add_url_seed (string_view url); void add_http_seed (string_view url);
This adds a url seed to the torrent. You can have any number of url seeds. For a single file torrent, this should be an HTTP url, pointing to a file with identical content as the file of the torrent. For a multi-file torrent, it should point to a directory containing a directory with the same name as this torrent, and all the files of the torrent in it.
The second function, add_http_seed() adds an HTTP seed instead.
[report issue]add_node()
void add_node (std::pair<std::string, int> node);
This adds a DHT node to the torrent. This especially useful if you're creating a tracker less torrent. It can be used by clients to bootstrap their DHT node from. The node is a hostname and a port number where there is a DHT node running. You can have any number of DHT nodes in a torrent.
[report issue]add_tracker()
void add_tracker (string_view url, int tier = 0);
Adds a tracker to the torrent. This is not strictly required, but most torrents use a tracker as their main source of peers. The url should be an http:// or udp:// url to a machine running a bittorrent tracker that accepts announces for this torrent's info-hash. The tier is the fallback priority of the tracker. All trackers with tier 0 are tried first (in any order). If all fail, trackers with tier 1 are tried. If all of those fail, trackers with tier 2 are tried, and so on.
[report issue]set_root_cert()
void set_root_cert (string_view pem);
This function sets an X.509 certificate in PEM format to the torrent. This makes the torrent an SSL torrent. An SSL torrent requires that each peer has a valid certificate signed by this root certificate. For SSL torrents, all peers are connecting over SSL connections. For more information, see the section on ssl torrents.
The string is not the path to the cert, it's the actual content of the certificate.
[report issue]priv() set_priv()
bool priv () const; void set_priv (bool p);
Sets and queries the private flag of the torrent. Torrents with the private flag set ask the client to not use any other sources than the tracker for peers, and to not use DHT to advertise itself publicly, only the tracker.
[report issue]num_pieces()
int num_pieces () const;
returns the number of pieces in the associated file_storage object.
[report issue]piece_length() piece_size()
int piece_size (piece_index_t i) const; int piece_length () const;
piece_length() returns the piece size of all pieces but the last one. piece_size() returns the size of the specified piece. these functions are just forwarding to the associated file_storage.
[report issue]merkle_tree()
std::vector<sha1_hash> const& merkle_tree () const;
This function returns the merkle hash tree, if the torrent was created as a merkle torrent. The tree is created by generate() and won't be valid until that function has been called. When creating a merkle tree torrent, the actual tree itself has to be saved off separately and fed into libtorrent the first time you start seeding it, through the torrent_info::set_merkle_tree() function. From that point onwards, the tree will be saved in the resume data.
[report issue]add_collection() add_similar_torrent()
void add_similar_torrent (sha1_hash ih); void add_collection (string_view c);
Add similar torrents (by info-hash) or collections of similar torrents. Similar torrents are expected to share some files with this torrent. Torrents sharing a collection name with this torrent are also expected to share files with this torrent. A torrent may have more than one collection and more than one similar torrents. For more information, see BEP 38.
[report issue]- optimize_alignment
- This will insert pad files to align the files to piece boundaries, for optimized disk-I/O. This will minimize the number of bytes of pad- files, to keep the impact down for clients that don't support them.
- merkle
- This will create a merkle hash tree torrent. A merkle torrent cannot be opened in clients that don't specifically support merkle torrents. The benefit is that the resulting torrent file will be much smaller and not grow with more pieces. When this option is specified, it is recommended to have a fairly small piece size, say 64 kiB. When creating merkle torrents, the full hash tree is also generated and should be saved off separately. It is accessed through the create_torrent::merkle_tree() function.
- modification_time
- This will include the file modification time as part of the torrent. This is not enabled by default, as it might cause problems when you create a torrent from separate files with the same content, hoping to yield the same info-hash. If the files have different modification times, with this option enabled, you would get different info-hashes for the files.
- symlinks
- If this flag is set, files that are symlinks get a symlink attribute set on them and their data will not be included in the torrent. This is useful if you need to reconstruct a file hierarchy which contains symlinks.
- mutable_torrent_support
- to create a torrent that can be updated via a mutable torrent (see BEP 38). This also needs to be enabled for torrents that update another torrent.
add_files()
Declared in "libtorrent/create_torrent.hpp"
void add_files (file_storage& fs, std::string const& file , std::function<bool(std::string)> p, create_flags_t flags = {}); void add_files (file_storage& fs, std::string const& file , create_flags_t flags = {});
Adds the file specified by path to the file_storage object. In case path refers to a directory, files will be added recursively from the directory.
If specified, the predicate p is called once for every file and directory that is encountered. Files for which p returns true are added, and directories for which p returns true are traversed. p must have the following signature:
bool Pred(std::string const& p);
The path that is passed in to the predicate is the full path of the file or directory. If no predicate is specified, all files are added, and all directories are traversed.
The ".." directory is never traversed.
The flags argument should be the same as the flags passed to the create_torrent constructor.
[report issue]set_piece_hashes()
Declared in "libtorrent/create_torrent.hpp"
inline void set_piece_hashes (create_torrent& t, std::string const& p); void set_piece_hashes (create_torrent& t, std::string const& p , std::function<void(piece_index_t)> const& f, error_code& ec); inline void set_piece_hashes (create_torrent& t, std::string const& p , std::function<void(piece_index_t)> const& f); inline void set_piece_hashes (create_torrent& t, std::string const& p, error_code& ec);
This function will assume that the files added to the torrent file exists at path p, read those files and hash the content and set the hashes in the create_torrent object. The optional function f is called in between every hash that is set. f must have the following signature:
void Fun(piece_index_t);
The overloads that don't take an error_code& may throw an exception in case of a file error, the other overloads sets the error code to reflect the error, if any.
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Error Codes
[report issue]storage_error
Declared in "libtorrent/error_code.hpp"
used by storage to return errors also includes which underlying file the error happened on
struct storage_error { explicit operator bool () const; file_index_t file () const; void file (file_index_t f); error_code ec; operation_t operation; };[report issue]
bool()
explicit operator bool () const;
explicitly converts to true if this object represents an error, and false if it does not.
[report issue]file()
file_index_t file () const; void file (file_index_t f);
set and query the index (in the torrent) of the file this error occurred on. This may also have special values defined in torrent_status.
[report issue]- ec
- the error that occurred
- operation
- A code from operation_t enum, indicating what kind of operation failed.
libtorrent_category()
Declared in "libtorrent/error_code.hpp"
boost::system::error_category& libtorrent_category ();
return the instance of the libtorrent_error_category which maps libtorrent error codes to human readable error messages.
[report issue]http_category()
Declared in "libtorrent/error_code.hpp"
boost::system::error_category& http_category ();
returns the error_category for HTTP errors
[report issue]pcp_category()
Declared in "libtorrent/natpmp.hpp"
boost::system::error_category& pcp_category ();[report issue]
upnp_category()
Declared in "libtorrent/upnp.hpp"
boost::system::error_category& upnp_category ();
the boost.system error category for UPnP errors
[report issue]utf8_category()
Declared in "libtorrent/utf8.hpp"
boost::system::error_category const& utf8_category ();[report issue]
gzip_category()
Declared in "libtorrent/gzip.hpp"
boost::system::error_category& gzip_category ();
get the error_category for zip errors
[report issue]bdecode_category()
Declared in "libtorrent/bdecode.hpp"
boost::system::error_category& bdecode_category ();[report issue]
socks_category()
Declared in "libtorrent/socks5_stream.hpp"
boost::system::error_category& socks_category ();
returns the error_category for SOCKS5 errors
[report issue]i2p_category()
Declared in "libtorrent/i2p_stream.hpp"
boost::system::error_category& i2p_category ();
returns the error category for I2P errors
[report issue]enum error_code_enum
Declared in "libtorrent/error_code.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | Not an error |
| file_collision | 1 | Two torrents has files which end up overwriting each other |
| failed_hash_check | 2 | A piece did not match its piece hash |
| torrent_is_no_dict | 3 | The .torrent file does not contain a bencoded dictionary at its top level |
| torrent_missing_info | 4 | The .torrent file does not have an info dictionary |
| torrent_info_no_dict | 5 | The .torrent file's info entry is not a dictionary |
| torrent_missing_piece_length | 6 | The .torrent file does not have a piece length entry |
| torrent_missing_name | 7 | The .torrent file does not have a name entry |
| torrent_invalid_name | 8 | The .torrent file's name entry is invalid |
| torrent_invalid_length | 9 | The length of a file, or of the whole .torrent file is invalid. Either negative or not an integer |
| torrent_file_parse_failed | 10 | Failed to parse a file entry in the .torrent |
| torrent_missing_pieces | 11 | The pieces field is missing or invalid in the .torrent file |
| torrent_invalid_hashes | 12 | The pieces string has incorrect length |
| too_many_pieces_in_torrent | 13 | The .torrent file has more pieces than is supported by libtorrent |
| invalid_swarm_metadata | 14 | The metadata (.torrent file) that was received from the swarm matched the info-hash, but failed to be parsed |
| invalid_bencoding | 15 | The file or buffer is not correctly bencoded |
| no_files_in_torrent | 16 | The .torrent file does not contain any files |
| invalid_escaped_string | 17 | The string was not properly url-encoded as expected |
| session_is_closing | 18 | Operation is not permitted since the session is shutting down |
| duplicate_torrent | 19 | There's already a torrent with that info-hash added to the session |
| invalid_torrent_handle | 20 | The supplied torrent_handle is not referring to a valid torrent |
| invalid_entry_type | 21 | The type requested from the entry did not match its type |
| missing_info_hash_in_uri | 22 | The specified URI does not contain a valid info-hash |
| file_too_short | 23 | One of the files in the torrent was unexpectedly small. This might be caused by files being changed by an external process |
| unsupported_url_protocol | 24 | The URL used an unknown protocol. Currently http and https (if built with openssl support) are recognized. For trackers udp is recognized as well. |
| url_parse_error | 25 | The URL did not conform to URL syntax and failed to be parsed |
| peer_sent_empty_piece | 26 | The peer sent a piece message of length 0 |
| parse_failed | 27 | A bencoded structure was corrupt and failed to be parsed |
| invalid_file_tag | 28 | The fast resume file was missing or had an invalid file version tag |
| missing_info_hash | 29 | The fast resume file was missing or had an invalid info-hash |
| mismatching_info_hash | 30 | The info-hash did not match the torrent |
| invalid_hostname | 31 | The URL contained an invalid hostname |
| invalid_port | 32 | The URL had an invalid port |
| port_blocked | 33 | The port is blocked by the port-filter, and prevented the connection |
| expected_close_bracket_in_address | 34 | The IPv6 address was expected to end with "]" |
| destructing_torrent | 35 | The torrent is being destructed, preventing the operation to succeed |
| timed_out | 36 | The connection timed out |
| upload_upload_connection | 37 | The peer is upload only, and we are upload only. There's no point in keeping the connection |
| uninteresting_upload_peer | 38 | The peer is upload only, and we're not interested in it. There's no point in keeping the connection |
| invalid_info_hash | 39 | The peer sent an unknown info-hash |
| torrent_paused | 40 | The torrent is paused, preventing the operation from succeeding |
| invalid_have | 41 | The peer sent an invalid have message, either wrong size or referring to a piece that doesn't exist in the torrent |
| invalid_bitfield_size | 42 | The bitfield message had the incorrect size |
| too_many_requests_when_choked | 43 | The peer kept requesting pieces after it was choked, possible abuse attempt. |
| invalid_piece | 44 | The peer sent a piece message that does not correspond to a piece request sent by the client |
| no_memory | 45 | memory allocation failed |
| torrent_aborted | 46 | The torrent is aborted, preventing the operation to succeed |
| self_connection | 47 | The peer is a connection to ourself, no point in keeping it |
| invalid_piece_size | 48 | The peer sent a piece message with invalid size, either negative or greater than one block |
| timed_out_no_interest | 49 | The peer has not been interesting or interested in us for too long, no point in keeping it around |
| timed_out_inactivity | 50 | The peer has not said anything in a long time, possibly dead |
| timed_out_no_handshake | 51 | The peer did not send a handshake within a reasonable amount of time, it might not be a bittorrent peer |
| timed_out_no_request | 52 | The peer has been unchoked for too long without requesting any data. It might be lying about its interest in us |
| invalid_choke | 53 | The peer sent an invalid choke message |
| invalid_unchoke | 54 | The peer send an invalid unchoke message |
| invalid_interested | 55 | The peer sent an invalid interested message |
| invalid_not_interested | 56 | The peer sent an invalid not-interested message |
| invalid_request | 57 | The peer sent an invalid piece request message |
| invalid_hash_list | 58 | The peer sent an invalid hash-list message (this is part of the merkle-torrent extension) |
| invalid_hash_piece | 59 | The peer sent an invalid hash-piece message (this is part of the merkle-torrent extension) |
| invalid_cancel | 60 | The peer sent an invalid cancel message |
| invalid_dht_port | 61 | The peer sent an invalid DHT port-message |
| invalid_suggest | 62 | The peer sent an invalid suggest piece-message |
| invalid_have_all | 63 | The peer sent an invalid have all-message |
| invalid_have_none | 64 | The peer sent an invalid have none-message |
| invalid_reject | 65 | The peer sent an invalid reject message |
| invalid_allow_fast | 66 | The peer sent an invalid allow fast-message |
| invalid_extended | 67 | The peer sent an invalid extension message ID |
| invalid_message | 68 | The peer sent an invalid message ID |
| sync_hash_not_found | 69 | The synchronization hash was not found in the encrypted handshake |
| invalid_encryption_constant | 70 | The encryption constant in the handshake is invalid |
| no_plaintext_mode | 71 | The peer does not support plain text, which is the selected mode |
| no_rc4_mode | 72 | The peer does not support RC4, which is the selected mode |
| unsupported_encryption_mode | 73 | The peer does not support any of the encryption modes that the client supports |
| unsupported_encryption_mode_selected | 74 | The peer selected an encryption mode that the client did not advertise and does not support |
| invalid_pad_size | 75 | The pad size used in the encryption handshake is of invalid size |
| invalid_encrypt_handshake | 76 | The encryption handshake is invalid |
| no_incoming_encrypted | 77 | The client is set to not support incoming encrypted connections and this is an encrypted connection |
| no_incoming_regular | 78 | The client is set to not support incoming regular bittorrent connections, and this is a regular connection |
| duplicate_peer_id | 79 | The client is already connected to this peer-ID |
| torrent_removed | 80 | Torrent was removed |
| packet_too_large | 81 | The packet size exceeded the upper sanity check-limit |
| reserved | 82 | |
| http_error | 83 | The web server responded with an error |
| missing_location | 84 | The web server response is missing a location header |
| invalid_redirection | 85 | The web seed redirected to a path that no longer matches the .torrent directory structure |
| redirecting | 86 | The connection was closed because it redirected to a different URL |
| invalid_range | 87 | The HTTP range header is invalid |
| no_content_length | 88 | The HTTP response did not have a content length |
| banned_by_ip_filter | 89 | The IP is blocked by the IP filter |
| too_many_connections | 90 | At the connection limit |
| peer_banned | 91 | The peer is marked as banned |
| stopping_torrent | 92 | The torrent is stopping, causing the operation to fail |
| too_many_corrupt_pieces | 93 | The peer has sent too many corrupt pieces and is banned |
| torrent_not_ready | 94 | The torrent is not ready to receive peers |
| peer_not_constructed | 95 | The peer is not completely constructed yet |
| session_closing | 96 | The session is closing, causing the operation to fail |
| optimistic_disconnect | 97 | The peer was disconnected in order to leave room for a potentially better peer |
| torrent_finished | 98 | The torrent is finished |
| no_router | 99 | No UPnP router found |
| metadata_too_large | 100 | The metadata message says the metadata exceeds the limit |
| invalid_metadata_request | 101 | The peer sent an invalid metadata request message |
| invalid_metadata_size | 102 | The peer advertised an invalid metadata size |
| invalid_metadata_offset | 103 | The peer sent a message with an invalid metadata offset |
| invalid_metadata_message | 104 | The peer sent an invalid metadata message |
| pex_message_too_large | 105 | The peer sent a peer exchange message that was too large |
| invalid_pex_message | 106 | The peer sent an invalid peer exchange message |
| invalid_lt_tracker_message | 107 | The peer sent an invalid tracker exchange message |
| too_frequent_pex | 108 | The peer sent an pex messages too often. This is a possible attempt of and attack |
| no_metadata | 109 | The operation failed because it requires the torrent to have the metadata (.torrent file) and it doesn't have it yet. This happens for magnet links before they have downloaded the metadata, and also torrents added by URL. |
| invalid_dont_have | 110 | The peer sent an invalid dont_have message. The don't have message is an extension to allow peers to advertise that the no longer has a piece they previously had. |
| requires_ssl_connection | 111 | The peer tried to connect to an SSL torrent without connecting over SSL. |
| invalid_ssl_cert | 112 | The peer tried to connect to a torrent with a certificate for a different torrent. |
| not_an_ssl_torrent | 113 | the torrent is not an SSL torrent, and the operation requires an SSL torrent |
| banned_by_port_filter | 114 | peer was banned because its listen port is within a banned port range, as specified by the port_filter. |
| invalid_session_handle | 115 | The session_handle is not referring to a valid session_impl |
| invalid_listen_socket | 116 | the listen socket associated with this request was closed |
| deprecated_120 | 120 | |
| deprecated_121 | 121 | |
| deprecated_122 | 122 | |
| deprecated_123 | 123 | |
| deprecated_124 | 124 | |
| missing_file_sizes | 130 | The resume data file is missing the file sizes entry |
| no_files_in_resume_data | 131 | The resume data file file sizes entry is empty |
| missing_pieces | 132 | The resume data file is missing the pieces and slots entry |
| mismatching_number_of_files | 133 | The number of files in the resume data does not match the number of files in the torrent |
| mismatching_file_size | 134 | One of the files on disk has a different size than in the fast resume file |
| mismatching_file_timestamp | 135 | One of the files on disk has a different timestamp than in the fast resume file |
| not_a_dictionary | 136 | The resume data file is not a dictionary |
| invalid_blocks_per_piece | 137 | The blocks per piece entry is invalid in the resume data file |
| missing_slots | 138 | The resume file is missing the slots entry, which is required for torrents with compact allocation. DEPRECATED |
| too_many_slots | 139 | The resume file contains more slots than the torrent |
| invalid_slot_list | 140 | The slot entry is invalid in the resume data |
| invalid_piece_index | 141 | One index in the slot list is invalid |
| pieces_need_reorder | 142 | The pieces on disk needs to be re-ordered for the specified allocation mode. This happens if you specify sparse allocation and the files on disk are using compact storage. The pieces needs to be moved to their right position. DEPRECATED |
| resume_data_not_modified | 143 | this error is returned when asking to save resume data and specifying the flag to only save when there's anything new to save (torrent_handle::only_if_modified) and there wasn't anything changed. |
| http_parse_error | 150 | The HTTP header was not correctly formatted |
| http_missing_location | 151 | The HTTP response was in the 300-399 range but lacked a location header |
| http_failed_decompress | 152 | The HTTP response was encoded with gzip or deflate but decompressing it failed |
| no_i2p_router | 160 | The URL specified an i2p address, but no i2p router is configured |
| no_i2p_endpoint | 161 | i2p acceptor is not available yet, can't announce without endpoint |
| scrape_not_available | 170 | The tracker URL doesn't support transforming it into a scrape URL. i.e. it doesn't contain "announce. |
| invalid_tracker_response | 171 | invalid tracker response |
| invalid_peer_dict | 172 | invalid peer dictionary entry. Not a dictionary |
| tracker_failure | 173 | tracker sent a failure message |
| invalid_files_entry | 174 | missing or invalid files entry |
| invalid_hash_entry | 175 | missing or invalid hash entry |
| invalid_peers_entry | 176 | missing or invalid peers and peers6 entry |
| invalid_tracker_response_length | 177 | UDP tracker response packet has invalid size |
| invalid_tracker_transaction_id | 178 | invalid transaction id in UDP tracker response |
| invalid_tracker_action | 179 | invalid action field in UDP tracker response |
| no_entropy | 200 | random number generation failed |
| error_code_max | 201 | the number of error codes |
enum http_errors
Declared in "libtorrent/error_code.hpp"
| name | value | description |
|---|---|---|
| cont | 100 | |
| ok | 200 | |
| created | 201 | |
| accepted | 202 | |
| no_content | 204 | |
| multiple_choices | 300 | |
| moved_permanently | 301 | |
| moved_temporarily | 302 | |
| not_modified | 304 | |
| bad_request | 400 | |
| unauthorized | 401 | |
| forbidden | 403 | |
| not_found | 404 | |
| internal_server_error | 500 | |
| not_implemented | 501 | |
| bad_gateway | 502 | |
| service_unavailable | 503 |
enum pcp_errors
Declared in "libtorrent/natpmp.hpp"
| name | value | description |
|---|---|---|
| pcp_success | 0 | |
| pcp_unsupp_version | 1 | |
| pcp_not_authorized | 2 | |
| pcp_malformed_request | 3 | |
| pcp_unsupp_opcode | 4 | |
| pcp_unsupp_option | 5 | |
| pcp_malformed_option | 6 | |
| pcp_network_failure | 7 | |
| pcp_no_resources | 8 | |
| pcp_unsupp_protocol | 9 | |
| pcp_user_ex_quota | 10 | |
| pcp_cannot_provide_external | 11 | |
| pcp_address_mismatch | 12 | |
| pcp_excessive_remote_peers | 13 |
enum error_code_enum
Declared in "libtorrent/upnp.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | No error |
| invalid_argument | 402 | One of the arguments in the request is invalid |
| action_failed | 501 | The request failed |
| value_not_in_array | 714 | The specified value does not exist in the array |
| source_ip_cannot_be_wildcarded | 715 | The source IP address cannot be wild-carded, but must be fully specified |
| external_port_cannot_be_wildcarded | 716 | The external port cannot be a wildcard, but must be specified |
| port_mapping_conflict | 718 | The port mapping entry specified conflicts with a mapping assigned previously to another client |
| internal_port_must_match_external | 724 | Internal and external port value must be the same |
| only_permanent_leases_supported | 725 | The NAT implementation only supports permanent lease times on port mappings |
| remote_host_must_be_wildcard | 726 | RemoteHost must be a wildcard and cannot be a specific IP address or DNS name |
| external_port_must_be_wildcard | 727 | ExternalPort must be a wildcard and cannot be a specific port |
enum error_code_enum
Declared in "libtorrent/gzip.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | Not an error |
| invalid_gzip_header | 1 | the supplied gzip buffer has invalid header |
| inflated_data_too_large | 2 | the gzip buffer would inflate to more bytes than the specified maximum size, and was rejected. |
| data_did_not_terminate | 3 | available inflate data did not terminate |
| space_exhausted | 4 | output space exhausted before completing inflate |
| invalid_block_type | 5 | invalid block type (type == 3) |
| invalid_stored_block_length | 6 | stored block length did not match one's complement |
| too_many_length_or_distance_codes | 7 | dynamic block code description: too many length or distance codes |
| code_lengths_codes_incomplete | 8 | dynamic block code description: code lengths codes incomplete |
| repeat_lengths_with_no_first_length | 9 | dynamic block code description: repeat lengths with no first length |
| repeat_more_than_specified_lengths | 10 | dynamic block code description: repeat more than specified lengths |
| invalid_literal_length_code_lengths | 11 | dynamic block code description: invalid literal/length code lengths |
| invalid_distance_code_lengths | 12 | dynamic block code description: invalid distance code lengths |
| invalid_literal_code_in_block | 13 | invalid literal/length or distance code in fixed or dynamic block |
| distance_too_far_back_in_block | 14 | distance is too far back in fixed or dynamic block |
| unknown_gzip_error | 15 | an unknown error occurred during gzip inflation |
| error_code_max | 16 | the number of error codes |
enum error_code_enum
Declared in "libtorrent/bdecode.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | Not an error |
| expected_digit | 1 | expected digit in bencoded string |
| expected_colon | 2 | expected colon in bencoded string |
| unexpected_eof | 3 | unexpected end of file in bencoded string |
| expected_value | 4 | expected value (list, dict, int or string) in bencoded string |
| depth_exceeded | 5 | bencoded recursion depth limit exceeded |
| limit_exceeded | 6 | bencoded item count limit exceeded |
| overflow | 7 | integer overflow |
| error_code_max | 8 | the number of error codes |
enum socks_error_code
Declared in "libtorrent/socks5_stream.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | |
| unsupported_version | 1 | |
| unsupported_authentication_method | 2 | |
| unsupported_authentication_version | 3 | |
| authentication_error | 4 | |
| username_required | 5 | |
| general_failure | 6 | |
| command_not_supported | 7 | |
| no_identd | 8 | |
| identd_error | 9 | |
| num_errors | 10 |
enum i2p_error_code
Declared in "libtorrent/i2p_stream.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | |
| parse_failed | 1 | |
| cant_reach_peer | 2 | |
| i2p_error | 3 | |
| invalid_key | 4 | |
| invalid_id | 5 | |
| timeout | 6 | |
| key_not_found | 7 | |
| duplicated_id | 8 | |
| num_errors | 9 |
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Storage
[report issue]storage_params
Declared in "libtorrent/storage_defs.hpp"
struct storage_params { storage_params (file_storage const& f, file_storage const* mf , std::string const& sp, storage_mode_t const sm , aux::vector<download_priority_t, file_index_t> const& prio , sha1_hash const& ih); file_storage const& files; file_storage const* mapped_files = nullptr; std::string const& path; storage_mode_t mode {storage_mode_sparse}; aux::vector<download_priority_t, file_index_t> const& priorities; sha1_hash const& info_hash; };[report issue]
file_slice
Declared in "libtorrent/file_storage.hpp"
represents a window of a file in a torrent.
The file_index refers to the index of the file (in the torrent_info). To get the path and filename, use file_path() and give the file_index as argument. The offset is the byte offset in the file where the range starts, and size is the number of bytes this range is. The size + offset will never be greater than the file size.
struct file_slice { file_index_t file_index; std::int64_t offset; std::int64_t size; };[report issue]
- file_index
- the index of the file
- offset
- the offset from the start of the file, in bytes
- size
- the size of the window, in bytes
file_storage
Declared in "libtorrent/file_storage.hpp"
The file_storage class represents a file list and the piece size. Everything necessary to interpret a regular bittorrent storage file structure.
class file_storage { bool is_valid () const; void reserve (int num_files); void add_file (std::string const& path, std::int64_t file_size , file_flags_t file_flags = {} , std::time_t mtime = 0, string_view symlink_path = string_view()); void add_file_borrow (string_view filename , std::string const& path, std::int64_t file_size , file_flags_t file_flags = {}, char const* filehash = nullptr , std::int64_t mtime = 0, string_view symlink_path = string_view()); void rename_file (file_index_t index, std::string const& new_filename); std::vector<file_slice> map_block (piece_index_t piece, std::int64_t offset , int size) const; peer_request map_file (file_index_t file, std::int64_t offset, int size) const; int num_files () const noexcept; file_index_t end_file () const noexcept; index_range<file_index_t> file_range () const noexcept; std::int64_t total_size () const; void set_num_pieces (int n); int num_pieces () const; piece_index_t end_piece () const; piece_index_t last_piece () const; index_range<piece_index_t> piece_range () const noexcept; void set_piece_length (int l); int piece_length () const; int piece_size (piece_index_t index) const; std::string const& name () const; void set_name (std::string const& n); void swap (file_storage& ti) noexcept; void optimize (int pad_file_limit = -1, int alignment = -1 , bool tail_padding = false); std::time_t mtime (file_index_t index) const; std::int64_t file_offset (file_index_t index) const; string_view file_name (file_index_t index) const; bool pad_file_at (file_index_t index) const; std::string const& symlink (file_index_t index) const; std::int64_t file_size (file_index_t index) const; std::string file_path (file_index_t index, std::string const& save_path = "") const; sha1_hash hash (file_index_t index) const; std::uint32_t file_path_hash (file_index_t index, std::string const& save_path) const; void all_path_hashes (std::unordered_set<std::uint32_t>& table) const; std::vector<std::string> const& paths () const; file_flags_t file_flags (file_index_t index) const; bool file_absolute_path (file_index_t index) const; file_index_t file_index_at_offset (std::int64_t offset) const; int file_name_len (file_index_t index) const; char const* file_name_ptr (file_index_t index) const; void apply_pointer_offset (std::ptrdiff_t off); void sanitize_symlinks (); static constexpr file_flags_t flag_pad_file = 0_bit; static constexpr file_flags_t flag_hidden = 1_bit; static constexpr file_flags_t flag_executable = 2_bit; static constexpr file_flags_t flag_symlink = 3_bit; };[report issue]
is_valid()
bool is_valid () const;
returns true if the piece length has been initialized on the file_storage. This is typically taken as a proxy of whether the file_storage as a whole is initialized or not.
[report issue]reserve()
void reserve (int num_files);
allocates space for num_files in the internal file list. This can be used to avoid reallocating the internal file list when the number of files to be added is known up-front.
[report issue]add_file() add_file_borrow()
void add_file (std::string const& path, std::int64_t file_size , file_flags_t file_flags = {} , std::time_t mtime = 0, string_view symlink_path = string_view()); void add_file_borrow (string_view filename , std::string const& path, std::int64_t file_size , file_flags_t file_flags = {}, char const* filehash = nullptr , std::int64_t mtime = 0, string_view symlink_path = string_view());
Adds a file to the file storage. The add_file_borrow version expects that filename is the file name (without a path) of the file that's being added. This memory is borrowed, i.e. it is the caller's responsibility to make sure it stays valid throughout the lifetime of this file_storage object or any copy of it. The same thing applies to filehash, which is an optional pointer to a 20 byte binary SHA-1 hash of the file.
if filename is empty, the filename from path is used and not borrowed.
The path argument is the full path (in the torrent file) to the file to add. Note that this is not supposed to be an absolute path, but it is expected to include the name of the torrent as the first path element.
file_size is the size of the file in bytes.
The file_flags argument sets attributes on the file. The file attributes is an extension and may not work in all bittorrent clients.
For possible file attributes, see file_storage::flags_t.
The mtime argument is optional and can be set to 0. If non-zero, it is the posix time of the last modification time of this file.
symlink_path is the path the file is a symlink to. To make this a symlink you also need to set the file_storage::flag_symlink file flag.
If more files than one are added, certain restrictions to their paths apply. In a multi-file file storage (torrent), all files must share the same root directory.
That is, the first path element of all files must be the same. This shared path element is also set to the name of the torrent. It can be changed by calling set_name.
[report issue]rename_file()
void rename_file (file_index_t index, std::string const& new_filename);
renames the file at index to new_filename. Keep in mind that filenames are expected to be UTF-8 encoded.
[report issue]map_block()
std::vector<file_slice> map_block (piece_index_t piece, std::int64_t offset , int size) const;
returns a list of file_slice objects representing the portions of files the specified piece index, byte offset and size range overlaps. this is the inverse mapping of map_file().
Preconditions of this function is that the input range is within the torrents address space. piece may not be negative and
piece * piece_size + offset + size
may not exceed the total size of the torrent.
[report issue]map_file()
peer_request map_file (file_index_t file, std::int64_t offset, int size) const;
returns a peer_request representing the piece index, byte offset and size the specified file range overlaps. This is the inverse mapping over map_block(). Note that the peer_request return type is meant to hold bittorrent block requests, which may not be larger than 16 kiB. Mapping a range larger than that may return an overflown integer.
[report issue]num_files()
int num_files () const noexcept;
returns the number of files in the file_storage
[report issue]end_file()
file_index_t end_file () const noexcept;
returns the index of the one-past-end file in the file storage
[report issue]file_range()
index_range<file_index_t> file_range () const noexcept;
returns an implementation-defined type that can be used as the container in a range-for loop. Where the values are the indices of all files in the file_storage.
[report issue]total_size()
std::int64_t total_size () const;
returns the total number of bytes all the files in this torrent spans
[report issue]num_pieces() set_num_pieces()
void set_num_pieces (int n); int num_pieces () const;
set and get the number of pieces in the torrent
[report issue]end_piece()
piece_index_t end_piece () const;
returns the index of the one-past-end piece in the file storage
[report issue]last_piece()
piece_index_t last_piece () const;
returns the index of the last piece in the torrent. The last piece is special in that it may be smaller than the other pieces (and the other pieces are all the same size).
[report issue]piece_range()
index_range<piece_index_t> piece_range () const noexcept;
returns an implementation-defined type that can be used as the container in a range-for loop. Where the values are the indices of all pieces in the file_storage.
[report issue]piece_length() set_piece_length()
void set_piece_length (int l); int piece_length () const;
set and get the size of each piece in this torrent. This size is typically an even power of 2. It doesn't have to be though. It should be divisible by 16 kiB however.
[report issue]piece_size()
int piece_size (piece_index_t index) const;
returns the piece size of index. This will be the same as piece_length(), except for the last piece, which may be shorter.
[report issue]set_name() name()
std::string const& name () const; void set_name (std::string const& n);
set and get the name of this torrent. For multi-file torrents, this is also the name of the root directory all the files are stored in.
[report issue]optimize()
void optimize (int pad_file_limit = -1, int alignment = -1 , bool tail_padding = false);
if pad_file_limit >= 0, files larger than that limit will be padded, default is to not add any padding (-1). The alignment specifies the alignment files should be padded to. This defaults to the piece size (-1) but it may also make sense to set it to 16 kiB, or something divisible by 16 kiB. If pad_file_limit is 0, every file will be padded (except empty ones). tail_padding indicates whether aligned files also are padded at the end to make them end aligned. This is required for mutable torrents, since piece hashes are compared
[report issue]mtime() hash() symlink() file_name() pad_file_at() file_size() file_path() file_offset()
std::time_t mtime (file_index_t index) const; std::int64_t file_offset (file_index_t index) const; string_view file_name (file_index_t index) const; bool pad_file_at (file_index_t index) const; std::string const& symlink (file_index_t index) const; std::int64_t file_size (file_index_t index) const; std::string file_path (file_index_t index, std::string const& save_path = "") const; sha1_hash hash (file_index_t index) const;
These functions are used to query attributes of files at a given index.
The hash() is a SHA-1 hash of the file, or 0 if none was provided in the torrent file. This can potentially be used to join a bittorrent network with other file sharing networks.
The mtime() is the modification time is the posix time when a file was last modified when the torrent was created, or 0 if it was not included in the torrent file.
file_path() returns the full path to a file.
file_size() returns the size of a file.
pad_file_at() returns true if the file at the given index is a pad-file.
file_name() returns just the name of the file, whereas file_path() returns the path (inside the torrent file) with the filename appended.
file_offset() returns the byte offset within the torrent file where this file starts. It can be used to map the file to a piece index (given the piece size).
[report issue]file_path_hash()
std::uint32_t file_path_hash (file_index_t index, std::string const& save_path) const;
returns the crc32 hash of file_path(index)
[report issue]all_path_hashes()
void all_path_hashes (std::unordered_set<std::uint32_t>& table) const;
this will add the CRC32 hash of all directory entries to the table. No filename will be included, just directories. Every depth of directories are added separately to allow test for collisions with files at all levels. i.e. if one path in the torrent is foo/bar/baz, the CRC32 hashes for foo, foo/bar and foo/bar/baz will be added to the set.
[report issue]paths()
std::vector<std::string> const& paths () const;
returns all directories used in the torrent. Files in the torrent are located in one of these directories. This is not a tree, it's a flat list of all leaf directories. i.e. the union of the parent paths of all files.
[report issue]file_flags()
file_flags_t file_flags (file_index_t index) const;
returns a bitmask of flags from file_flags_t that apply to file at index.
[report issue]file_absolute_path()
bool file_absolute_path (file_index_t index) const;
returns true if the file at the specified index has been renamed to have an absolute path, i.e. is not anchored in the save path of the torrent.
[report issue]file_index_at_offset()
file_index_t file_index_at_offset (std::int64_t offset) const;
returns the index of the file at the given offset in the torrent
[report issue]file_name_len() file_name_ptr()
int file_name_len (file_index_t index) const; char const* file_name_ptr (file_index_t index) const;
low-level function. returns a pointer to the internal storage for the filename. This string may not be 0-terminated! the file_name_len() function returns the length of the filename. prefer to use file_name() instead, which returns a string_view.
[report issue]apply_pointer_offset()
void apply_pointer_offset (std::ptrdiff_t off);
if the backing buffer changed for this storage, this is the pointer offset to add to any pointers to make them point into the new buffer
[report issue]sanitize_symlinks()
void sanitize_symlinks ();
validate any symlinks, to ensure they all point to other files or directories inside this storage. Any invalid symlinks are updated to point to themselves.
[report issue]- flag_pad_file
- the file is a pad file. It's required to contain zeros at it will not be saved to disk. Its purpose is to make the following file start on a piece boundary.
- flag_hidden
- this file has the hidden attribute set. This is primarily a windows attribute
- flag_executable
- this file has the executable attribute set.
- flag_symlink
- this file is a symbolic link. It should have a link target string associated with it.
default_storage_constructor()
Declared in "libtorrent/storage_defs.hpp"
storage_interface* default_storage_constructor (storage_params const& , file_pool& p);
the constructor function for the regular file storage. This is the default value for add_torrent_params::storage.
[report issue]disabled_storage_constructor()
Declared in "libtorrent/storage_defs.hpp"
storage_interface* disabled_storage_constructor (storage_params const&, file_pool&);
the constructor function for the disabled storage. This can be used for testing and benchmarking. It will throw away any data written to it and return garbage for anything read from it.
[report issue]zero_storage_constructor()
Declared in "libtorrent/storage_defs.hpp"
storage_interface* zero_storage_constructor (storage_params const&, file_pool&);
the constructor function for the "zero" storage. This will always read zeros and ignore all writes.
[report issue]enum storage_mode_t
Declared in "libtorrent/storage_defs.hpp"
| name | value | description |
|---|---|---|
| storage_mode_allocate | 0 | All pieces will be written to their final position, all files will be allocated in full when the torrent is first started. This is done with fallocate() and similar calls. This mode minimizes fragmentation. |
| storage_mode_sparse | 1 | All pieces will be written to the place where they belong and sparse files will be used. This is the recommended, and default mode. |
enum status_t
Declared in "libtorrent/storage_defs.hpp"
| name | value | description |
|---|---|---|
| no_error | 0 | |
| fatal_disk_error | 1 | |
| need_full_check | 2 | |
| file_exist | 3 |
enum move_flags_t
Declared in "libtorrent/storage_defs.hpp"
| name | value | description |
|---|---|---|
| always_replace_files | 0 | replace any files in the destination when copying or moving the storage |
| fail_if_exist | 1 | if any files that we want to copy exist in the destination exist, fail the whole operation and don't perform any copy or move. There is an inherent race condition in this mode. The files are checked for existence before the operation starts. In between the check and performing the copy, the destination files may be created, in which case they are replaced. |
| dont_replace | 2 | if any file exist in the target, take those files instead of the ones we may have in the source. |
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Custom Storage
libtorrent provides a customization point for storage of data. By default, (default_storage) downloaded files are saved to disk according with the general conventions of bittorrent clients, mimicking the original file layout when the torrent was created. The libtorrent user may define a custom storage to store piece data in a different way.
A custom storage implementation must derive from and implement the storage_interface. You must also provide a function that constructs the custom storage object and provide this function to the add_torrent() call via add_torrent_params. Either passed in to the constructor or by setting the add_torrent_params::storage field.
This is an example storage implementation that stores all pieces in a std::map, i.e. in RAM. It's not necessarily very useful in practice, but illustrates the basics of implementing a custom storage.
struct temp_storage : lt::storage_interface { explicit temp_storage(lt::file_storage const& fs) : lt::storage_interface(fs) {} void initialize(lt::storage_error&) override {} bool has_any_file(lt::storage_error&) override { return false; } void set_file_priority(lt::aux::vector<lt::download_priority_t, lt::file_index_t>& , lt::storage_error&) override {} int readv(lt::span<lt::iovec_t const> bufs, lt::piece_index_t piece , int offset, lt::open_mode_t, lt::storage_error&) override { auto const i = m_file_data.find(piece); if (i == m_file_data.end()) return 0; if (int(i->second.size()) <= offset) return 0; lt::iovec_t data{ i->second.data() + offset, int(i->second.size() - offset) }; int ret = 0; for (lt::iovec_t const& b : bufs) { int const to_copy = std::min(int(b.size()), int(data.size())); memcpy(b.data(), data.data(), to_copy); data = data.subspan(to_copy); ret += to_copy; if (data.empty()) break; } return ret; } int writev(lt::span<lt::iovec_t const> bufs , lt::piece_index_t const piece, int offset, lt::open_mode_t, lt::storage_error&) override { auto& data = m_file_data[piece]; int ret = 0; for (auto& b : bufs) { if (int(data.size()) < offset + b.size()) data.resize(offset + b.size()); std::memcpy(data.data() + offset, b.data(), b.size()); offset += int(b.size()); ret += int(b.size()); } return ret; } void rename_file(lt::file_index_t, std::string const&, lt::storage_error&) override { assert(false); } lt::status_t move_storage(std::string const& , lt::move_flags_t, lt::storage_error&) override { return lt::status_t::no_error; } bool verify_resume_data(lt::add_torrent_params const& , lt::aux::vector<std::string, lt::file_index_t> const& , lt::storage_error&) override { return false; } void release_files(lt::storage_error&) override {} void delete_files(lt::remove_flags_t, lt::storage_error&) override {} std::map<lt::piece_index_t, std::vector<char>> m_file_data; }; lt::storage_interface* temp_storage_constructor(lt::storage_params const& params, lt::file_pool&) { return new temp_storage(params.files); }[report issue]
storage_interface
Declared in "libtorrent/storage.hpp"
The storage interface is a pure virtual class that can be implemented to customize how and where data for a torrent is stored. The default storage implementation uses regular files in the filesystem, mapping the files in the torrent in the way one would assume a torrent is saved to disk. Implementing your own storage interface makes it possible to store all data in RAM, or in some optimized order on disk (the order the pieces are received for instance), or saving multi file torrents in a single file in order to be able to take advantage of optimized disk-I/O.
It is also possible to write a thin class that uses the default storage but modifies some particular behavior, for instance encrypting the data before it's written to disk, and decrypting it when it's read again.
The storage interface is based on pieces. Every read and write operation happens in the piece-space. Each piece fits piece_size number of bytes. All access is done by writing and reading whole or partial pieces.
libtorrent comes with two built-in storage implementations; default_storage and disabled_storage. Their constructor functions are called default_storage_constructor() and disabled_storage_constructor respectively. The disabled storage does just what it sounds like. It throws away data that's written, and it reads garbage. It's useful mostly for benchmarking and profiling purpose.
struct storage_interface: std::enable_shared_from_this<storage_interface>, aux::disk_job_fence, aux::storage_piece_set { explicit storage_interface (file_storage const& fs); storage_interface& operator= (storage_interface const&) = delete; storage_interface (storage_interface const&) = delete; virtual void initialize (storage_error& ec) = 0; virtual int writev (span<iovec_t const> bufs , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0; virtual int readv (span<iovec_t const> bufs , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0; virtual bool has_any_file (storage_error& ec) = 0; virtual void set_file_priority (aux::vector<download_priority_t, file_index_t>& prio , storage_error& ec) = 0; virtual status_t move_storage (std::string const& save_path , move_flags_t flags, storage_error& ec) = 0; virtual bool verify_resume_data (add_torrent_params const& rd , aux::vector<std::string, file_index_t> const& links , storage_error& ec) = 0; virtual void release_files (storage_error& ec) = 0; virtual void rename_file (file_index_t index, std::string const& new_filename , storage_error& ec) = 0; virtual void delete_files (remove_flags_t options, storage_error& ec) = 0; virtual bool tick (); file_storage const& files () const; bool set_need_tick (); void do_tick (); void set_owner (std::shared_ptr<void> const& tor); aux::session_settings const& settings () const; storage_index_t storage_index () const; void set_storage_index (storage_index_t st); int dec_refcount (); void inc_refcount (); aux::session_settings const* m_settings = nullptr; };[report issue]
initialize()
virtual void initialize (storage_error& ec) = 0;
This function is called when the storage on disk is to be initialized. The default storage will create directories and empty files at this point. If allocate_files is true, it will also ftruncate all files to their target size.
This function may be called multiple time on a single instance. When a torrent is force-rechecked, the storage is re-initialized to trigger the re-check from scratch.
The function is not necessarily called before other member functions. For instance has_any_files() and verify_resume_data() are called early to determine whether we may have to check all files or not. If we're doing a full check of the files every piece will be hashed, causing readv() to be called as well.
Any required internals that need initialization should be done in the constructor. This function is called before the torrent starts to download.
If an error occurs, storage_error should be set to reflect it.
[report issue]writev() readv()
virtual int writev (span<iovec_t const> bufs , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0; virtual int readv (span<iovec_t const> bufs , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0;
These functions should read and write the data in or to the given piece at the given offset. It should read or write num_bufs buffers sequentially, where the size of each buffer is specified in the buffer array bufs. The iovec_t type has the following members:
struct iovec_t { void* iov_base; size_t iov_len; };
These functions may be called simultaneously from multiple threads. Make sure they are thread safe. The file in libtorrent is thread safe when it can fall back to pread, preadv or the windows equivalents. On targets where read operations cannot be thread safe (i.e one has to seek first and then read), only one disk thread is used.
The offset is aligned to 16 kiB boundaries most of the time, but there are rare exceptions when it's not. Specifically if the read cache is disabled/or full and a peer requests unaligned data. Most clients request aligned data.
The number of bytes read or written should be returned, or -1 on error. If there's an error, the storage_error must be filled out to represent the error that occurred.
For possible values of flags, see open_mode_t.
[report issue]has_any_file()
virtual bool has_any_file (storage_error& ec) = 0;
This function is called when first checking (or re-checking) the storage for a torrent. It should return true if any of the files that is used in this storage exists on disk. If so, the storage will be checked for existing pieces before starting the download.
If an error occurs, storage_error should be set to reflect it.
[report issue]set_file_priority()
virtual void set_file_priority (aux::vector<download_priority_t, file_index_t>& prio , storage_error& ec) = 0;
change the priorities of files. This is a fenced job and is guaranteed to be the only running function on this storage when called
[report issue]move_storage()
virtual status_t move_storage (std::string const& save_path , move_flags_t flags, storage_error& ec) = 0;
This function should move all the files belonging to the storage to the new save_path. The default storage moves the single file or the directory of the torrent.
Before moving the files, any open file handles may have to be closed, like release_files().
If an error occurs, storage_error should be set to reflect it.
[report issue]verify_resume_data()
virtual bool verify_resume_data (add_torrent_params const& rd , aux::vector<std::string, file_index_t> const& links , storage_error& ec) = 0;
This function should verify the resume data rd with the files on disk. If the resume data seems to be up-to-date, return true. If not, set error to a description of what mismatched and return false.
The default storage may compare file sizes and time stamps of the files.
If an error occurs, storage_error should be set to reflect it.
This function should verify the resume data rd with the files on disk. If the resume data seems to be up-to-date, return true. If not, set error to a description of what mismatched and return false.
If the links pointer is non-empty, it has the same number of elements as there are files. Each element is either empty or contains the absolute path to a file identical to the corresponding file in this torrent. The storage must create hard links (or copy) those files. If any file does not exist or is inaccessible, the disk job must fail.
[report issue]release_files()
virtual void release_files (storage_error& ec) = 0;
This function should release all the file handles that it keeps open to files belonging to this storage. The default implementation just calls file_pool::release_files().
If an error occurs, storage_error should be set to reflect it.
[report issue]rename_file()
virtual void rename_file (file_index_t index, std::string const& new_filename , storage_error& ec) = 0;
Rename the file with index file to name new_name.
If an error occurs, storage_error should be set to reflect it.
[report issue]delete_files()
virtual void delete_files (remove_flags_t options, storage_error& ec) = 0;
This function should delete some or all of the storage for this torrent. The options parameter specifies whether to delete all files or just the partfile. options are set to the same value as the options passed to session::remove_torrent().
If an error occurs, storage_error should be set to reflect it.
The disk_buffer_pool is used to allocate and free disk buffers. It has the following members:
struct disk_buffer_pool { char* allocate_buffer(char const* category); void free_buffer(char* buf); char* allocate_buffers(int blocks, char const* category); void free_buffers(char* buf, int blocks); int block_size() const { return m_block_size; } };[report issue]
tick()
virtual bool tick ();
called periodically (useful for deferred flushing). When returning false, it means no more ticks are necessary. Any disk job submitted will re-enable ticking. The default will always turn ticking back off again.
[report issue]settings()
aux::session_settings const& settings () const;
access global session_settings
[report issue]- m_settings
- initialized in disk_io_thread::perform_async_job
default_storage
Declared in "libtorrent/storage.hpp"
The default implementation of storage_interface. Behaves as a normal bittorrent client. It is possible to derive from this class in order to override some of its behavior, when implementing a custom storage.
class default_storage : public storage_interface { explicit default_storage (storage_params const& params, file_pool&); bool tick () override; void release_files (storage_error& ec) override; void rename_file (file_index_t index, std::string const& new_filename , storage_error& ec) override; void initialize (storage_error& ec) override; void set_file_priority (aux::vector<download_priority_t, file_index_t>& prio , storage_error& ec) override; status_t move_storage (std::string const& save_path , move_flags_t flags, storage_error& ec) override; void delete_files (remove_flags_t options, storage_error& ec) override; bool has_any_file (storage_error& ec) override; bool verify_resume_data (add_torrent_params const& rd , aux::vector<std::string, file_index_t> const& links , storage_error& error) override; int readv (span<iovec_t const> bufs , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override; int writev (span<iovec_t const> bufs , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override; file_storage const& files () const; };[report issue]
default_storage()
explicit default_storage (storage_params const& params, file_pool&);
constructs the default_storage based on the give file_storage (fs). mapped is an optional argument (it may be nullptr). If non-nullptr it represents the file mapping that have been made to the torrent before adding it. That's where files are supposed to be saved and looked for on disk. save_path is the root save folder for this torrent. file_pool is the cache of file handles that the storage will use. All files it opens will ask the file_pool to open them. file_prio is a vector indicating the priority of files on startup. It may be an empty vector. Any file whose index is not represented by the vector (because the vector is too short) are assumed to have priority 1. this is used to treat files with priority 0 slightly differently.
[report issue]files()
file_storage const& files () const;
if the files in this storage are mapped, returns the mapped file_storage, otherwise returns the original file_storage object.
[report issue]file_pool
Declared in "libtorrent/file_pool.hpp"
this is an internal cache of open file handles. It's primarily used by storage_interface implementations. It provides semi weak guarantees of not opening more file handles than specified. Given multiple threads, each with the ability to lock a file handle (via smart pointer), there may be windows where more file handles are open.
struct file_pool : boost::noncopyable { explicit file_pool (int size = 40); ~file_pool (); file_handle open_file (storage_index_t st, std::string const& p , file_index_t file_index, file_storage const& fs, open_mode_t m , error_code& ec); void release (); void release (storage_index_t st); void release (storage_index_t st, file_index_t file_index); void resize (int size); int size_limit () const; void close_oldest (); };[report issue]
~file_pool() file_pool()
explicit file_pool (int size = 40); ~file_pool ();
size specifies the number of allowed files handles to hold open at any given time.
[report issue]open_file()
file_handle open_file (storage_index_t st, std::string const& p , file_index_t file_index, file_storage const& fs, open_mode_t m , error_code& ec);
return an open file handle to file at file_index in the file_storage fs opened at save path p. m is the file open mode (see file::open_mode_t).
[report issue]release()
void release (); void release (storage_index_t st); void release (storage_index_t st, file_index_t file_index);
release all files belonging to the specified storage_interface (st) the overload that takes file_index releases only the file with that index in storage st.
[report issue]resize()
void resize (int size);
update the allowed number of open file handles to size.
[report issue]size_limit()
int size_limit () const;
returns the current limit of number of allowed open file handles held by the file_pool.
[report issue]close_oldest()
void close_oldest ();
close the file that was opened least recently (i.e. not accessed least recently). The purpose is to make the OS (really just windows) clear and flush its disk cache associated with this file. We don't want any file to stay open for too long, allowing the disk cache to accrue.
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Utility
[report issue]bitfield
Declared in "libtorrent/bitfield.hpp"
The bitfield type stores any number of bits as a bitfield in a heap allocated array.
struct bitfield { bitfield (int bits, bool val); bitfield () noexcept = default; bitfield (bitfield const& rhs); explicit bitfield (int bits); bitfield (bitfield&& rhs) noexcept = default; bitfield (char const* b, int bits); void assign (char const* b, int const bits); bool get_bit (int index) const noexcept; bool operator[] (int index) const noexcept; void clear_bit (int index) noexcept; void set_bit (int index) noexcept; bool all_set () const noexcept; bool none_set () const noexcept; int size () const noexcept; int num_words () const noexcept; bool empty () const noexcept; char* data () noexcept; char const* data () const noexcept; void swap (bitfield& rhs) noexcept; int count () const noexcept; int find_first_set () const noexcept; int find_last_clear () const noexcept; };[report issue]
bitfield()
bitfield (int bits, bool val); bitfield () noexcept = default; bitfield (bitfield const& rhs); explicit bitfield (int bits); bitfield (bitfield&& rhs) noexcept = default; bitfield (char const* b, int bits);
constructs a new bitfield. The default constructor creates an empty bitfield. bits is the size of the bitfield (specified in bits). val is the value to initialize the bits to. If not specified all bits are initialized to 0.
The constructor taking a pointer b and bits copies a bitfield from the specified buffer, and bits number of bits (rounded up to the nearest byte boundary).
[report issue]assign()
void assign (char const* b, int const bits);
copy bitfield from buffer b of bits number of bits, rounded up to the nearest byte boundary.
[report issue]operator[]() get_bit()
bool get_bit (int index) const noexcept; bool operator[] (int index) const noexcept;
query bit at index. Returns true if bit is 1, otherwise false.
[report issue]set_bit() clear_bit()
void clear_bit (int index) noexcept; void set_bit (int index) noexcept;
set bit at index to 0 (clear_bit) or 1 (set_bit).
[report issue]all_set()
bool all_set () const noexcept;
returns true if all bits in the bitfield are set
[report issue]none_set()
bool none_set () const noexcept;
returns true if no bit in the bitfield is set
[report issue]num_words()
int num_words () const noexcept;
returns the number of 32 bit words are needed to represent all bits in this bitfield.
[report issue]data()
char* data () noexcept; char const* data () const noexcept;
returns a pointer to the internal buffer of the bitfield, or nullptr if it's empty.
[report issue]swap()
void swap (bitfield& rhs) noexcept;
swaps the bit-fields two variables refer to
[report issue]count()
int count () const noexcept;
count the number of bits in the bitfield that are set to 1.
[report issue]find_first_set()
int find_first_set () const noexcept;
returns the index of the first set bit in the bitfield, i.e. 1 bit.
[report issue]find_last_clear()
int find_last_clear () const noexcept;
returns the index to the last cleared bit in the bitfield, i.e. 0 bit.
[report issue]hasher
Declared in "libtorrent/hasher.hpp"
this is a SHA-1 hash class.
You use it by first instantiating it, then call update() to feed it with data. i.e. you don't have to keep the entire buffer of which you want to create the hash in memory. You can feed the hasher parts of it at a time. When You have fed the hasher with all the data, you call final() and it will return the sha1-hash of the data.
The constructor that takes a char const* and an integer will construct the sha1 context and feed it the data passed in.
If you want to reuse the hasher object once you have created a hash, you have to call reset() to reinitialize it.
The built-in software version of sha1-algorithm was implemented by Steve Reid and released as public domain. For more info, see src/sha1.cpp.
class hasher { hasher (); explicit hasher (span<char const> data); hasher (char const* data, int len); hasher (hasher const&); hasher& operator= (hasher const&) &; hasher& update (span<char const> data); hasher& update (char const* data, int len); sha1_hash final (); void reset (); };[report issue]
hasher() operator=()
explicit hasher (span<char const> data); hasher (char const* data, int len); hasher (hasher const&); hasher& operator= (hasher const&) &;
this is the same as default constructing followed by a call to update(data, len).
[report issue]update()
hasher& update (span<char const> data); hasher& update (char const* data, int len);
append the following bytes to what is being hashed
[report issue]final()
sha1_hash final ();
returns the SHA-1 digest of the buffers previously passed to update() and the hasher constructor.
[report issue]reset()
void reset ();
restore the hasher state to be as if the hasher has just been default constructed.
[report issue]operator<<()
Declared in "libtorrent/sha1_hash.hpp"
std::ostream& operator<< (std::ostream& os, sha1_hash const& peer);
print a sha1_hash object to an ostream as 40 hexadecimal digits
[report issue]operator>>()
Declared in "libtorrent/sha1_hash.hpp"
std::istream& operator>> (std::istream& is, sha1_hash& peer);
read 40 hexadecimal digits from an istream into a sha1_hash
| Author: | Arvid Norberg<EMAIL_ADDRESS>|
|---|---|
| Version: | 1.2.6 |
Bencoding
Bencoding is a common representation in bittorrent used for dictionary, list, int and string hierarchies. It's used to encode .torrent files and some messages in the network protocol. libtorrent also uses it to store settings, resume data and other session state.
Strings in bencoded structures do not necessarily represent text. Strings are raw byte buffers of a certain length. If a string is meant to be interpreted as text, it is required to be UTF-8 encoded. See BEP 3.
The function for decoding bencoded data bdecode(), returning a bdecode_node. This function builds a tree that points back into the original buffer. The returned bdecode_node will not be valid once the buffer it was parsed out of is discarded.
It's possible to construct an entry from a bdecode_node, if a structure needs to be altered and re-encoded.
[report issue]entry
Declared in "libtorrent/entry.hpp"
The entry class represents one node in a bencoded hierarchy. It works as a variant type, it can be either a list, a dictionary (std::map), an integer or a string.
class entry { data_type type () const; entry (dictionary_type); // NOLINT; entry& operator= (list_type) &; entry (list_type); // NOLINT; entry& operator= (preformatted_type) &; entry& operator= (integer_type) &; preformatted_type& preformatted (); const integer_type& integer () const; const string_type& string () const; const preformatted_type& preformatted () const; const dictionary_type& dict () const; string_type& string (); list_type& list (); dictionary_type& dict (); integer_type& integer (); const list_type& list () const; void swap (entry& e); entry& operator[] (string_view key); const entry& operator[] (string_view key) const; entry* find_key (string_view key); entry const* find_key (string_view key) const; std::string to_string (bool single_line = false) const; enum data_type { int_t, string_t, list_t, dictionary_t, undefined_t, preformatted_t, }; mutable std::uint8_t m_type_queried:1; };[report issue]
entry() operator=()
entry (dictionary_type); // NOLINT; entry& operator= (list_type) &; entry (list_type); // NOLINT; entry& operator= (preformatted_type) &; entry& operator= (integer_type) &;
constructors directly from a specific type. The content of the argument is copied into the newly constructed entry
[report issue]string() integer() dict() preformatted() list()
preformatted_type& preformatted (); const integer_type& integer () const; const string_type& string () const; const preformatted_type& preformatted () const; const dictionary_type& dict () const; string_type& string (); list_type& list (); dictionary_type& dict (); integer_type& integer (); const list_type& list () const;
The integer(), string(), list() and dict() functions are accessors that return the respective type. If the entry object isn't of the type you request, the accessor will throw system_error. You can ask an entry for its type through the type() function.
If you want to create an entry you give it the type you want it to have in its constructor, and then use one of the non-const accessors to get a reference which you then can assign the value you want it to have.
The typical code to get info from a torrent file will then look like this:
entry torrent_file; // ... // throws if this is not a dictionary entry::dictionary_type const& dict = torrent_file.dict(); entry::dictionary_type::const_iterator i; i = dict.find("announce"); if (i != dict.end()) { std::string tracker_url = i->second.string(); std::cout << tracker_url << "\n"; }
The following code is equivalent, but a little bit shorter: