| libtorrent

# Session

Author: | Arvid Norberg, arvid@libtorrent.org
Version: | 1.0.7

Table of contents

- add_torrent_params
- cache_status
- session_proxy
- session
- dht_lookup
- dht_routing_bucket
- utp_status
- session_status

# add_torrent_params

Declared in "libtorrent/add_torrent_params.hpp"

The add_torrent_params is a parameter pack for adding torrents to a session. The key fields when adding a torrent are:

- ti - when you have a .torrent file
- url - when you have a magnet link or http URL to the .torrent file
- info_hash - when all you have is an info-hash (this is similar to a magnet link)

one of those fields need to be set. Another mandatory field is `save_path`. The add_torrent_params object is passed into one of the `session::add_torrent()` overloads or `session::async_add_torrent()`.

If you only specify the info-hash, the torrent file will be downloaded from peers, which requires them to support the metadata extension. For the metadata extension to work, libtorrent must be built with extensions enabled (`TORRENT_DISABLE_EXTENSIONS` must not be defined). It also takes an optional `name` argument. This may be left empty in case no name should be assigned to the torrent. In case it's not, the name is used for the torrent as long as it doesn't have metadata. See `torrent_handle::name`.

    struct add_torrent_params
    {
       add_torrent_params (storage_constructor_type sc = default_storage_constructor);

       enum flags_t
       {
          flag_seed_mode,
          flag_override_resume_data,
          flag_upload_mode,
          flag_share_mode,
          flag_apply_ip_filter,
          flag_paused,
          flag_auto_managed,
          flag_duplicate_is_error,
          flag_merge_resume_trackers,
          flag_update_subscribe,
          flag_super_seeding,
          flag_sequential_download,
          flag_use_resume_save_path,
          flag_merge_resume_http_seeds,
       };

       int version;
       boost::intrusive_ptr<torrent_info> ti;
       std::vector<std::string> trackers;
       std::vector<std::string> url_seeds;
       std::vector<std::pair<std::string, int> > dht_nodes;
       std::string name;
       std::string save_path;
       std::vector<char> resume_data;
       storage_mode_t storage_mode;
       storage_constructor_type storage;
       void* userdata;
       std::vector<boost::uint8_t> file_priorities;
       std::string trackerid;
       std::string url;
       std::string uuid;
       std::string source_feed_url;
       boost::uint64_t flags;
       sha1_hash info_hash;
       int max_uploads;
       int max_connections;
       int upload_limit;
       int download_limit;
    };

## add_torrent_params()

    add_torrent_params (storage_constructor_type sc = default_storage_constructor);

The constructor can be used to initialize the storage constructor, which determines the storage mechanism for the downloaded or seeding data for the torrent. For more information, see the `storage` field.

## enum flags_t

Declared in "libtorrent/add_torrent_params.hpp"

name | value | description
--- | --- | ---

flag_seed_mode

1

If `flag_seed_mode` is set, libtorrent will assume that all files are present for this torrent and that they all match the hashes in the torrent file. Each time a peer requests to download a block, the piece is verified against the hash, unless it has been verified already. If a hash fails, the torrent will automatically leave the seed mode and recheck all the files. The use case for this mode is if a torrent is created and seeded, or if the user already know that the files are complete, this is a way to avoid the initial file checks, and significantly reduce the startup time.

Setting `flag_seed_mode` on a torrent without metadata (a .torrent file) is a no-op and will be ignored.

If resume data is passed in with this torrent, the seed mode saved in there will override the seed mode you set here.

flag_override_resume_data

2

If `flag_override_resume_data` is set, flags set for this torrent in this `add_torrent_params` object will take precedence over whatever states are saved in the resume data. For instance, the `paused`, `auto_managed`, `sequential_download`, `seed_mode`, `super_seeding`, `max_uploads`, `max_connections`, `upload_limit` and `download_limit` are all affected by this flag. The intention of this flag is to have any field in add_torrent_params configuring the torrent override the corresponding configuration from the resume file, with the one exception of save resume data, which has its own flag (for historic reasons).

flag_upload_mode

4

If `flag_upload_mode` is set, the torrent will be initialized in upload-mode, which means it will not make any piece requests. This state is typically entered on disk I/O errors, and if the torrent is also auto managed, it will be taken out of this state periodically. This mode can be used to avoid race conditions when adjusting priorities of pieces before allowing the torrent to start downloading.

If the torrent is auto-managed (`flag_auto_managed`), the torrent will eventually be taken out of upload-mode, regardless of how it got there. If it's important to manually control when the torrent leaves upload mode, don't make it auto managed.

flag_share_mode

8

determines if the torrent should be added in share mode or not. Share mode indicates that we are not interested in downloading the torrent, but merley want to improve our share ratio (i.e. increase it). A torrent started in share mode will do its best to never download more than it uploads to the swarm. If the swarm does not have enough demand for upload capacity, the torrent will not download anything. This mode is intended to be safe to add any number of torrents to, without manual screening, without the risk of downloading more than is uploaded.

A torrent in share mode sets the priority to all pieces to 0, except for the pieces that are downloaded, when pieces are decided to be downloaded. This affects the progress bar, which might be set to "100% finished" most of the time. Do not change file or piece priorities for torrents in share mode, it will make it not work.

The share mode has one setting, the share ratio target, see `session_settings::share_mode_target` for more info.

flag_apply_ip_filter | 16 | determines if the IP filter should apply to this torrent or not. By default all torrents are subject to filtering by the IP filter (i.e. this flag is set by default). This is useful if certain torrents needs to be excempt for some reason, being an auto-update torrent for instance.
flag_paused | 32 | specifies whether or not the torrent is to be started in a paused state. I.e. it won't connect to the tracker or any of the peers until it's resumed. This is typically a good way of avoiding race conditions when setting configuration options on torrents before starting them.

flag_auto_managed

64

If the torrent is auto-managed (`flag_auto_managed`), the torrent may be resumed at any point, regardless of how it paused. If it's important to manually control when the torrent is paused and resumed, don't make it auto managed.

If `flag_auto_managed` is set, the torrent will be queued, started and seeded automatically by libtorrent. When this is set, the torrent should also be started as paused. The default queue order is the order the torrents were added. They are all downloaded in that order. For more details, see queuing.

If you pass in resume data, the auto_managed state of the torrent when the resume data was saved will override the auto_managed state you pass in here. You can override this by setting `override_resume_data`.

flag_duplicate_is_error | 128 |

flag_merge_resume_trackers

256

defaults to off and specifies whether tracker URLs loaded from resume data should be added to the trackers in the torrent or replace the trackers. When replacing trackers (i.e. this flag is not set), any trackers passed in via add_torrent_params are also replaced by any trackers in the resume data. The default behavior is to have the resume data override the .torrent file _and_ the trackers added in add_torrent_params.

flag_update_subscribe | 512 | on by default and means that this torrent will be part of state updates when calling post_torrent_updates().
flag_super_seeding | 1024 | sets the torrent into super seeding mode. If the torrent is not a seed, this flag has no effect. It has the same effect as calling `torrent_handle::super_seeding(true)` on the torrent handle immediately after adding it.
flag_sequential_download | 2048 | sets the sequential download state for the torrent. It has the same effect as calling `torrent_handle::sequential_download(true)` on the torrent handle immediately after adding it.
flag_use_resume_save_path | 4096 | if this flag is set, the save path from the resume data file, if present, is honored. This defaults to not being set, in which case the save_path specified in add_torrent_params is always used.

flag_merge_resume_http_seeds

8192

defaults to off and specifies whether web seed URLs loaded from resume data should be added to the ones in the torrent file or replace them. No distinction is made between the two different kinds of web seeds (BEP 17 and BEP 19). When replacing web seeds (i.e. when this flag is not set), any web seeds passed in via add_torrent_params are also replaced. The default behavior is to have any web seeds in the resume data take presedence over whatever is passed in here as well as the .torrent file.

version
  filled in by the constructor and should be left untouched. It is used for forward binary compatibility.

ti
  torrent_info object with the torrent to add. Unless the url or info_hash is set, this is required to be initiazlied.

trackers
  If the torrent doesn't have a tracker, but relies on the DHT to find peers, the `trackers` can specify tracker URLs for the torrent.

url_seeds
  url seeds to be added to the torrent (BEP 17).

dht_nodes name
  a list of hostname and port pairs, representing DHT nodes to be added to the session (if DHT is enabled). The hostname may be an IP address.

save_path

  the path where the torrent is or will be stored. Note that this may alos be stored in resume data. If you want the save path saved in the resume data to be used, you need to set the flag_use_resume_save_path flag.

  Note

  On windows this path (and other paths) are interpreted as UNC paths. This means they must use backslashes as directory separators and may not contain the special directories "." or "..".

resume_data
  The optional parameter, `resume_data` can be given if up to date fast-resume data is available. The fast-resume data can be acquired from a running torrent by calling save_resume_data() on torrent_handle. See fast resume. The `vector` that is passed in will be swapped into the running torrent instance with `std::vector::swap()`.

storage_mode
  One of the values from storage_mode_t. For more information, see storage allocation.

storage
  can be used to customize how the data is stored. The default storage will simply write the data to the files it belongs to, but it could be overridden to save everything to a single file at a specific location or encrypt the content on disk for instance. For more information about the storage_interface that needs to be implemented for a custom storage, see storage_interface.

userdata
  The `userdata` parameter is optional and will be passed on to the extension constructor functions, if any (see add_extension()).

file_priorities
  can be set to control the initial file priorities when adding a torrent. The semantics are the same as for `torrent_handle::prioritize_files()`.

trackerid
  the default tracker id to be used when announcing to trackers. By default this is empty, and no tracker ID is used, since this is an optional argument. If a tracker returns a tracker ID, that ID is used instead of this.

url

  If you specify a `url`, the torrent will be set in `downloading_metadata` state until the .torrent file has been downloaded. If there's any error while downloading, the torrent will be stopped and the torrent error state (`torrent_status::error`) will indicate what went wrong. The `url` may refer to a magnet link or a regular http URL.

  If it refers to an HTTP URL, the info-hash for the added torrent will not be the true info-hash of the .torrent. Instead a placeholder, unique, info-hash is used which is later updated once the .torrent file has been downloaded.

  Once the info-hash change happens, a torrent_update_alert is posted.

uuid
  if `uuid` is specified, it is used to find duplicates. If another torrent is already running with the same UUID as the one being added, it will be considered a duplicate. This is mainly useful for RSS feed items which has UUIDs specified.

source_feed_url
  should point to the URL of the RSS feed this torrent comes from, if it comes from an RSS feed.

flags
  flags controlling aspects of this torrent and how it's added. See flags_t for details.

info_hash
  set this to the info hash of the torrent to add in case the info-hash is the only known property of the torrent. i.e. you don't have a .torrent file nor a magnet link.

max_uploads max_connections upload_limit download_limit

  `max_uploads`, `max_connections`, `upload_limit`, `download_limit` correspond to the `set_max_uploads()`, `set_max_connections()`, `set_upload_limit()` and `set_download_limit()` functions on torrent_handle. These values let you initialize these settings when the torrent is added, instead of calling these functions immediately following adding it.

  -1 means unlimited on these settings just like their counterpart functions on torrent_handle

# cache_status

Declared in "libtorrent/disk_io_thread.hpp"

this struct holds a number of statistics counters relevant for the disk io thread and disk cache.

    struct cache_status
    {
       cache_status ();

       size_type blocks_written;
       size_type writes;
       size_type blocks_read;
       size_type blocks_read_hit;
       size_type reads;
       mutable size_type queued_bytes;
       int cache_size;
       int read_cache_size;
       mutable int total_used_buffers;
       int average_queue_time;
       int average_read_time;
       int average_write_time;
       int average_hash_time;
       int average_job_time;
       int average_sort_time;
       int job_queue_length;
       boost::uint32_t cumulative_job_time;
       boost::uint32_t cumulative_read_time;
       boost::uint32_t cumulative_write_time;
       boost::uint32_t cumulative_hash_time;
       boost::uint32_t cumulative_sort_time;
       int total_read_back;
       int read_queue_size;
    };

## cache_status()

    cache_status ();

initializes all counters to 0

blocks_written
  the total number of 16 KiB blocks written to disk since this session was started.

writes

  the total number of write operations performed since this session was started.

  The ratio (`blocks_written` - `writes`) / `blocks_written` represents the number of saved write operations per total write operations. i.e. a kind of cache hit ratio for the write cahe.

blocks_read
  the number of blocks that were requested from the bittorrent engine (from peers), that were served from disk or cache.

blocks_read_hit

  the number of blocks that was just copied from the read cache

  The ratio `blocks_read_hit` / `blocks_read` is the cache hit ratio for the read cache.

reads
  the number of read operations used

queued_bytes
  the number of bytes waiting, in the disk job queue, to be written or inserted into the disk cache

cache_size
  the number of 16 KiB blocks currently in the disk cache (both read and write). This includes both read and write cache.

read_cache_size
  the number of 16KiB blocks in the read cache.

total_used_buffers
  the total number of buffers currently in use. This includes the read/write disk cache as well as send and receive buffers used in peer connections.

average_queue_time
  the number of microseconds an average disk I/O job has to wait in the job queue before it get processed.

average_read_time
  the time read jobs takes on average to complete (not including the time in the queue), in microseconds. This only measures read cache misses.

average_write_time
  the time write jobs takes to complete, on average, in microseconds. This does not include the time the job sits in the disk job queue or in the write cache, only blocks that are flushed to disk.

average_hash_time average_job_time average_sort_time
  the time hash jobs takes to complete on average, in microseconds. Hash jobs include running SHA-1 on the data (which for the most part is done incrementally) and sometimes reading back parts of the piece. It also includes checking files without valid resume data.

job_queue_length
  the number of jobs in the job queue.

cumulative_job_time cumulative_read_time cumulative_write_time cumulative_hash_time cumulative_sort_time
  the number of milliseconds spent in all disk jobs, and specific ones since the start of the session. Times are specified in milliseconds

total_read_back
  the number of blocks that had to be read back from disk because they were flushed before the SHA-1 hash got to hash them. If this is large, a larger cache could significantly improve performance

read_queue_size
  number of read jobs in the disk job queue

# 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()

    session_proxy ();

default constructor, does not refer to any session implementation object.

# 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.

    class session: public boost::noncopyable
    {
       session (fingerprint const& print = fingerprint("LT"
          , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0)
          , int flags = start_default_features | add_default_plugins
          , boost::uint32_t alert_mask = alert::error_notification
          TORRENT_LOGPATH_ARG_DEFAULT);
       session (fingerprint const& print
          , std::pair<int, int> listen_port_range
          , char const* listen_interface = "0.0.0.0"
          , int flags = start_default_features | add_default_plugins
          , int alert_mask = alert::error_notification
          TORRENT_LOGPATH_ARG_DEFAULT);
       ~session ();
       void load_state (lazy_entry const& e);
       void save_state (entry& e, boost::uint32_t flags = 0xffffffff) const;
       void refresh_torrent_status (std::vector<torrent_status>* ret
          , boost::uint32_t flags = 0) const;
       void get_torrent_status (std::vector<torrent_status>* ret
          , boost::function<bool(torrent_status const&)> const& pred
          , boost::uint32_t flags = 0) const;
       void post_torrent_updates ();
       torrent_handle find_torrent (sha1_hash const& info_hash) const;
       std::vector<torrent_handle> get_torrents () const;
       void async_add_torrent (add_torrent_params const& params);
       torrent_handle add_torrent (add_torrent_params const& params, error_code& ec);
       torrent_handle add_torrent (add_torrent_params const& params);
       session_proxy abort ();
       void resume ();
       void pause ();
       bool is_paused () const;
       session_status status () const;
       cache_status get_cache_status () const;
       void get_cache_info (sha1_hash const& ih
          , std::vector<cached_piece_info>& ret) const;
       feed_handle add_feed (feed_settings const& feed);
       void remove_feed (feed_handle h);
       void get_feeds (std::vector<feed_handle>& f) const;
       bool is_dht_running () const;
       dht_settings get_dht_settings () const;
       void start_dht ();
       void stop_dht ();
       void set_dht_settings (dht_settings const& settings);
       void add_dht_router (std::pair<std::string, int> const& node);
       void add_dht_node (std::pair<std::string, int> const& node);
       void dht_get_item (sha1_hash const& target);
       void dht_get_item (boost::array<char, 32> key
          , std::string salt = std::string());
       sha1_hash dht_put_item (entry data);
       void dht_put_item (boost::array<char, 32> key
          , boost::function<void(entry&, boost::array<char,64>&
          , boost::uint64_t&, std::string const&)> cb
          , std::string salt = std::string());
       void add_extension (boost::function<boost::shared_ptr<torrent_plugin>(
          torrent*, void*)> ext);
       void add_extension (boost::shared_ptr<plugin> ext);
       void load_country_db (char const* file);
       void load_asnum_db (char const* file);
       int as_for_ip (address const& addr);
       ip_filter get_ip_filter () const;
       void set_ip_filter (ip_filter const& f);
       void set_port_filter (port_filter const& f);
       peer_id id () const;
       void set_peer_id (peer_id const& pid);
       void set_key (int key);
       void listen_on (
          std::pair<int, int> const& port_range
          , error_code& ec
          , const char* net_interface = 0
          , int flags = 0);
       bool is_listening () const;
       unsigned short listen_port () const;
       unsigned short ssl_listen_port () const;
       void remove_torrent (const torrent_handle& h, int options = 0);
       session_settings settings () const;
       void set_settings (session_settings const& s);
       pe_settings get_pe_settings () const;
       void set_pe_settings (pe_settings const& settings);
       void set_proxy (proxy_settings const& s);
       proxy_settings proxy () const;
       proxy_settings i2p_proxy () const;
       void set_i2p_proxy (proxy_settings const& s);
       void pop_alerts (std::deque<alert*>* alerts);
       std::auto_ptr<alert> pop_alert ();
       alert const* wait_for_alert (time_duration max_wait);
       void set_alert_mask (boost::uint32_t m);
       void set_alert_dispatch (boost::function<void(std::auto_ptr<alert>)> const& fun);
       void stop_lsd ();
       void start_lsd ();
       void stop_upnp ();
       void start_upnp ();
       void delete_port_mapping (int handle);
       int add_port_mapping (protocol_type t, int external_port, int local_port);
       void stop_natpmp ();
       void start_natpmp ();

       enum save_state_flags_t
       {
          save_settings,
          save_dht_settings,
          save_dht_state,
          save_proxy,
          save_i2p_proxy,
          save_encryption_settings,
          save_feeds,
       };

       enum listen_on_flags_t
       {
          listen_no_system_port,
       };

       enum options_t
       {
          delete_files,
       };

       enum session_flags_t
       {
          add_default_plugins,
          start_default_features,
       };

       enum protocol_type
       {
          udp,
          tcp,
       };
    };

## session()

    session (fingerprint const& print = fingerprint("LT"
          , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0)
          , int flags = start_default_features | add_default_plugins
          , boost::uint32_t alert_mask = alert::error_notification
          TORRENT_LOGPATH_ARG_DEFAULT);
    session (fingerprint const& print
          , std::pair<int, int> listen_port_range
          , char const* listen_interface = "0.0.0.0"
          , int flags = start_default_features | add_default_plugins
          , int alert_mask = alert::error_notification
          TORRENT_LOGPATH_ARG_DEFAULT);

If the fingerprint in the first overload is omited, the client will get a default fingerprint stating the version of libtorrent. The fingerprint is a short string that will be used in the peer-id to identify the client and the client's version. For more details see the fingerprint class. The first overload (that takes a fingerprint, flags and alert_mask) will listen on INADDR_ANY and let the OS pick a listen port. To listen on a specific interface or specific port, you'll have to call `session::listen_on()`.

The second overload, that takes a port range and an interface as well as the fingerprint will automatically try to listen on a port on the given interface. For more information about the parameters, see `listen_on()` function.

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 things. If you do not want them to start, pass 0 as the flags parameter.

The `alert_mask` is the same mask that you would send to set_alert_mask().

## ~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 `set_settings()`.

## load_state() save_state()

    void load_state (lazy_entry const& e);
    void save_state (entry& e, boost::uint32_t flags = 0xffffffff) const;

loads and saves all session settings, including dht_settings, encryption settings and proxy settings. `save_state` writes all keys to the `entry` that's passed in, which needs to either not be initialized, or initialized as a dictionary.

`load_state` expects a lazy_entry which can be built from a bencoded buffer with lazy_bdecode().

The `flags` arguments passed in to `save_state` can be used to filter which parts of the session state to save. By default, all state is saved (except for the individual torrents). see save_state_flags_t

## get_torrent_status() refresh_torrent_status()

    void refresh_torrent_status (std::vector<torrent_status>* ret
          , boost::uint32_t flags = 0) const;
    void get_torrent_status (std::vector<torrent_status>* ret
          , boost::function<bool(torrent_status const&)> const& pred
          , boost::uint32_t flags = 0) const;

Note

these calls are potentially expensive and won't scale well with lots of torrents. If you're concerned about performance, consider using `post_torrent_updates()` instead.

`get_torrent_status` returns a vector of the torrent_status for every torrent which satisfies `pred`, which is a predicate function which determines if a torrent should be included in the returned set or not. Returning true means it should be included and false means excluded. The `flags` argument is the same as to `torrent_handle::status()`. Since `pred` is guaranteed to be called for every torrent, it may be used to count the number of torrents of different categories as well.

`refresh_torrent_status` takes a vector of torrent_status structs (for instance the same vector that was returned by get_torrent_status() ) and refreshes the status based on the `handle` member. It is possible to use this function by first setting up a vector of default constructed `torrent_status` objects, only initializing the `handle` member, in order to request the torrent status for multiple torrents in a single call. This can save a significant amount of time if you have a lot of torrents.

Any torrent_status object whose `handle` member is not referring to a valid torrent are ignored.

## post_torrent_updates()

    void post_torrent_updates ();

This functions instructs the session to post the state_update_alert, containing the status of all torrents whose state changed since the last time this function was called.

Only torrents who has the state subscription flag set will be included. This flag is on by default. See add_torrent_params.

## find_torrent() get_torrents()

    torrent_handle find_torrent (sha1_hash const& info_hash) const;
    std::vector<torrent_handle> get_torrents () const;

`find_torrent()` looks for a torrent with the given info-hash. In case there is such a torrent in the session, a torrent_handle to that torrent is returned. In case the torrent cannot be found, an invalid torrent_handle is returned.

See `torrent_handle::is_valid()` to know if the torrent was found or not.

`get_torrents()` returns a vector of torrent_handles to all the torrents currently in the session.

## add_torrent() async_add_torrent()

    void async_add_torrent (add_torrent_params const& params);
    torrent_handle add_torrent (add_torrent_params const& params, error_code& ec);
    torrent_handle add_torrent (add_torrent_params const& params);

You add torrents through the add_torrent() function where you give an object with all the parameters. The add_torrent() overloads will block until the torrent has been added (or failed to be added) and returns an error code and a torrent_handle. In order to add torrents more efficiently, consider using async_add_torrent() which returns immediately, without waiting for the torrent to add. Notification of the torrent being added is sent as add_torrent_alert.

The overload that does not take an error_code throws an exception on error and is not available when building without exception support. The torrent_handle returned by add_torrent() can be used to retrieve information about the torrent's progress, its peers etc. It is also used to abort a torrent.

If the torrent you are trying to add already exists in the session (is either queued for checking, being checked or downloading) `add_torrent()` will throw libtorrent_exception which derives from `std::exception` unless duplicate_is_error is set to false. In that case, add_torrent() will return the handle to the existing torrent.

all torrent_handles must be destructed before the session is destructed!

## abort()

    session_proxy abort ();

In case you want to destruct the session asynchrounously, 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()
    };

## pause() resume() is_paused()

    void resume ();
    void pause ();
    bool is_paused () const;

Pausing the session has the same effect as pausing every torrent in it, except that torrents will not be resumed by the auto-manage mechanism. Resuming will restore the torrents to their previous paused state. i.e. the session pause state is separate from the torrent pause state. A torrent is inactive if it is paused or if the session is paused.

## status()

    session_status status () const;

returns session wide-statistics and status. For more information, see the `session_status` struct.

## get_cache_status()

    cache_status get_cache_status () const;

Returns status of the disk cache for this session. For more information, see the cache_status type.

## get_cache_info()

    void get_cache_info (sha1_hash const& ih
          , std::vector<cached_piece_info>& ret) const;

fills out the supplied vector with information for each piece that is currently in the disk cache for the torrent with the specified info-hash (`ih`).

## add_feed()

    feed_handle add_feed (feed_settings const& feed);

This adds an RSS feed to the session. The feed will be refreshed regularly and optionally add all torrents from the feed, as they appear.

Before adding the feed, you must set the `url` field to the feed's url. It may point to an RSS or an atom feed. The returned feed_handle is a handle which is used to interact with the feed, things like forcing a refresh or querying for information about the items in the feed. For more information, see feed_handle.

## remove_feed()

    void remove_feed (feed_handle h);

Removes a feed from being watched by the session. When this call returns, the feed handle is invalid and won't refer to any feed.

## get_feeds()

    void get_feeds (std::vector<feed_handle>& f) const;

Returns a list of all RSS feeds that are being watched by the session.

## get_dht_settings() is_dht_running() start_dht() set_dht_settings() stop_dht()

    bool is_dht_running () const;
    dht_settings get_dht_settings () const;
    void start_dht ();
    void stop_dht ();
    void set_dht_settings (dht_settings const& settings);

starts/stops UPnP, NATPMP or LSD port mappers they are stopped by default These functions are not available in case `TORRENT_DISABLE_DHT` is defined. `start_dht` starts the dht node and makes the trackerless service available to torrents. The startup state is optional and can contain nodes and the node id from the previous session. The dht node state is a bencoded dictionary with the following entries:

nodes
  A list of strings, where each string is a node endpoint encoded in binary. If the string is 6 bytes long, it is an IPv4 address of 4 bytes, encoded in network byte order (big endian), followed by a 2 byte port number (also network byte order). If the string is 18 bytes long, it is 16 bytes of IPv6 address followed by a 2 bytes port number (also network byte order).
node-id
  The node id written as a readable string as a hexadecimal number.

`dht_state` will return the current state of the dht node, this can be used to start up the node again, passing this entry to `start_dht`. It is a good idea to save this to disk when the session is closed, and read it up again when starting.

If the port the DHT is supposed to listen on is already in use, and exception is thrown, `asio::error`.

`stop_dht` stops the dht node.

`add_dht_node` adds a node to the routing table. This can be used if your client has its own source of bootstrapping nodes.

`set_dht_settings` sets some parameters availavle to the dht node. See dht_settings for more information.

`is_dht_running()` returns true if the DHT support has been started and false otherwise.

`get_dht_settings()` returns the current settings

## add_dht_router() add_dht_node()

    void add_dht_router (std::pair<std::string, int> const& 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.

`add_dht_router` adds the given endpoint to a list of DHT router nodes. If a search is ever made while the routing table is empty, those nodes will be used as backups. Nodes in the router node list will also never be added to the regular routing table, which effectively means they are only used for bootstrapping, to keep the load off them.

An example routing node that you could typically add is `router.bittorrent.com`.

## 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.

## dht_get_item()

    void dht_get_item (boost::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.

## 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 agan. It's just the sha-1 hash of the bencoded form of the structure.

## dht_put_item()

    void dht_put_item (boost::array<char, 32> key
          , boost::function<void(entry&, boost::array<char,64>&
          , boost::uint64_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.
boost::array<char,64>& signature
  the signature authenticating the current value. This may be zeroes if there is currently no value stored. The functon 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.
boost::uint64_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 blobs' values are 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.

## add_extension()

    void add_extension (boost::function<boost::shared_ptr<torrent_plugin>(
          torrent*, void*)> ext);
    void add_extension (boost::shared_ptr<plugin> ext);

This function adds an extension to this session. The argument is a function object that is called with a `torrent*` and which should return a `boost::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:

metadata extension
  Allows peers to download the metadata (.torren files) from the swarm directly. Makes it possible to join a swarm with just a tracker and info-hash.

    #include <libtorrent/extensions/metadata_transfer.hpp>
    ses.add_extension(&libtorrent::create_metadata_plugin);

uTorrent metadata
  Same as `metadata extension` but compatible with uTorrent.

    #include <libtorrent/extensions/ut_metadata.hpp>
    ses.add_extension(&libtorrent::create_ut_metadata_plugin);

uTorrent peer exchange
  Exchanges peers between clients.

    #include <libtorrent/extensions/ut_pex.hpp>
    ses.add_extension(&libtorrent::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(&libtorrent::create_smart_ban_plugin);

## load_asnum_db() load_country_db() as_for_ip()

    void load_country_db (char const* file);
    void load_asnum_db (char const* file);
    int as_for_ip (address const& addr);

These functions are not available if `TORRENT_DISABLE_GEO_IP` is defined. They expects a path to the MaxMind ASN database and MaxMind GeoIP database respectively. This will be used to look up which AS and country peers belong to.

`as_for_ip` returns the AS number for the IP address specified. If the IP is not in the database or the ASN database is not loaded, 0 is returned.

## 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.

## 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.

## set_peer_id() id()

    peer_id id () const;
    void set_peer_id (peer_id const& pid);

sets and gets the raw peer ID used by libtorrent. When anonymous mode is set the peer ID is randomized per peer anyway.

## set_key()

    void set_key (int key);

sets the key sent to trackers. If it's not set, it is initialized by libtorrent. The key may be used by the tracker to identify the peer potentially across you changing your IP.

## listen_port() listen_on() ssl_listen_port() is_listening()

    void listen_on (
          std::pair<int, int> const& port_range
          , error_code& ec
          , const char* net_interface = 0
          , int flags = 0);
    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 use `listen_on()` to make another attempt.

`listen_port()` returns the port we ended up listening on. Since you just pass a port-range to the constructor and to `listen_on()`, to know which port it ended up using, you have to ask the session using this function.

`listen_on()` will change the listen port and/or the listen interface. If the session is already listening on a port, this socket will be closed and a new socket will be opened with these new settings. The port range is the ports it will try to listen on, if the first port fails, it will continue trying the next port within the range and so on. The interface parameter can be left as 0, in that case the os will decide which interface to listen on, otherwise it should be the ip-address of the interface you want the listener socket bound to. `listen_on()` returns the error code of the operation in `ec`. If this indicates success, the session is listening on a port within the specified range. If it fails, it will also generate an appropriate alert (listen_failed_alert).

If all ports in the specified range fails to be opened for listening, libtorrent will try to use port 0 (which tells the operating system to pick a port that's free). If that still fails you may see a listen_failed_alert with port 0 even if you didn't ask to listen on it.

It is possible to prevent libtorrent from binding to port 0 by passing in the flag `session::no_system_port` in the `flags` argument.

The interface parameter can also be a hostname that will resolve to the device you want to listen on. If you don't specify an interface, libtorrent may attempt to listen on multiple interfaces (typically 0.0.0.0 and ::). This means that if your IPv6 interface doesn't work, you may still see a listen_failed_alert, even though the IPv4 port succeeded.

The `flags` parameter can either be 0 or `session::listen_reuse_address`, which will set the reuse address socket option on the listen socket(s). By default, the listen socket does not use reuse address. If you're running a service that needs to run on a specific port no matter if it's in use, set this flag.

If you're also starting the DHT, it is a good idea to do that after you've called `listen_on()`, since the default listen port for the DHT is the same as the tcp listen socket. If you start the DHT first, it will assume the tcp port is free and open the udp socket on that port, then later, when `listen_on()` is called, it may turn out that the tcp port is in use. That results in the DHT and the bittorrent socket listening on different ports. If the DHT is active when `listen_on` is called, the udp port will be rebound to the new port, if it was configured to use the same port as the tcp socket, and if the listen_on call failed to bind to the same port that the udp uses.

If you want the OS to pick a port for you, pass in 0 as both first and second.

The reason why it's a good idea to run the DHT and the bittorrent socket on the same port is because that is an assumption that may be used to increase performance. One way to accelerate the connecting of peers on windows may be to first ping all peers with a DHT ping packet, and connect to those that responds first. On windows one can only connect to a few peers at a time because of a built in limitation (in XP Service pack 2).

## remove_torrent()

    void remove_torrent (const torrent_handle& h, int options = 0);

`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::delete_files`. The removal of the torrent is asyncronous, there is no guarantee that adding the same torrent immediately after it was removed will not throw a libtorrent_exception exception. Once the torrent is deleted, a torrent_deleted_alert is posted.

## set_pe_settings() settings() get_pe_settings() set_settings()

    session_settings settings () const;
    void set_settings (session_settings const& s);
    pe_settings get_pe_settings () const;
    void set_pe_settings (pe_settings const& settings);

Sets the session settings and the packet encryption settings respectively. See session_settings and pe_settings for more information on available options.

## set_proxy() proxy()

    void set_proxy (proxy_settings const& s);
    proxy_settings proxy () const;

These functions sets and queries the proxy settings to be used for the session.

For more information on what settings are available for proxies, see proxy_settings. If the session is not in anonymous mode, proxies that aren't working or fail, will automatically be disabled and packets will flow without using any proxy. If you want to enforce using a proxy, even when the proxy doesn't work, enable anonymous_mode in session_settings.

## i2p_proxy() set_i2p_proxy()

    proxy_settings i2p_proxy () const;
    void set_i2p_proxy (proxy_settings const& s);

`set_i2p_proxy` sets the i2p proxy, and tries to open a persistant connection to it. The only used fields in the proxy settings structs are `hostname` and `port`.

`i2p_proxy` returns the current i2p proxy in use.

## pop_alert() pop_alerts() wait_for_alert()

    void pop_alerts (std::deque<alert*>* alerts);
    std::auto_ptr<alert> pop_alert ();
    alert const* wait_for_alert (time_duration max_wait);

`pop_alert()` is used to ask the session if any errors or events has occurred. With set_alert_mask() you can filter which alerts to receive through `pop_alert()`. For information about the alert categories, see alerts.

`pop_alerts()` pops all pending alerts in a single call. In high performance environments with a very high alert churn rate, this can save significant amount of time compared to popping alerts one at a time. Each call requires one round-trip to the network thread. If alerts are produced in a higher rate than they can be popped (when popped one at a time) it's easy to get stuck in an infinite loop, trying to drain the alert queue. Popping the entire queue at once avoids this problem.

However, the `pop_alerts` function comes with significantly more responsibility. You pass in an empty `std::dequeue<alert*>` to it. If it's not empty, all elements in it will be deleted and then cleared. All currently pending alerts are returned by being swapped into the passed in container. The responsibility of deleting the alerts is transferred to the caller. This means you need to call delete for each item in the returned dequeue. It's probably a good idea to delete the alerts as you handle them, to save one extra pass over the dequeue.

Alternatively, you can pass in the same container the next time you call `pop_alerts`.

`wait_for_alert` blocks until an alert is available, or for no more than `max_wait` time. If `wait_for_alert` returns because of the time-out, and no alerts are available, it returns 0. If at least one alert was generated, a pointer to that alert is returned. The alert is not popped, any subsequent calls to `wait_for_alert` will return the same pointer until the alert is popped by calling `pop_alert`. This is useful for leaving any alert dispatching mechanism independent of this blocking call, the dispatcher can be called and it can pop the alert independently.

Note

Although these functions are all thread-safe, popping alerts from multiple separate threads may introduce race conditions in that the thread issuing an asynchronous operation may not be the one receiving the alert with the result.

In the python binding, `wait_for_alert` takes the number of milliseconds to wait as an integer.

To control the max number of alerts that's queued by the session, see `session_settings::alert_queue_size`.

save_resume_data_alert and save_resume_data_failed_alert are always posted, regardelss of the alert mask.

## set_alert_mask()

    void set_alert_mask (boost::uint32_t m);

Changes the mask of which alerts to receive. By default only errors are reported. `m` is a bitmask where each bit represents a category of alerts.

See category_t enum for options.

## set_alert_dispatch()

    void set_alert_dispatch (boost::function<void(std::auto_ptr<alert>)> const& fun);

This sets a function to be called (from within libtorrent's netowrk thread) every time an alert is posted. Since the function (`fun`) is run in libtorrent's internal thread, it may not call any of libtorrent's external API functions. Doing so results in a dead lock.

The main intention with this function is to support integration with platform-dependent message queues or signalling systems. For instance, on windows, one could post a message to an HNWD or on linux, write to a pipe or an eventfd.

## start_lsd() stop_lsd()

    void stop_lsd ();
    void start_lsd ();

Starts and stops Local Service Discovery. This service will broadcast the infohashes of all the non-private torrents on the local network to look for peers on the same swarm within multicast reach.

It is turned off by default.

## stop_upnp() start_upnp()

    void stop_upnp ();
    void start_upnp ();

Starts and stops the UPnP service. When started, the listen port and the DHT port are attempted to be forwarded on local UPnP router devices.

The upnp object returned by `start_upnp()` can be used to add and remove arbitrary port mappings. Mapping status is returned through the portmap_alert and the portmap_error_alert. The object will be valid until `stop_upnp()` is called. See upnp and nat pmp.

It is off by default.

## add_port_mapping() delete_port_mapping()

    void delete_port_mapping (int handle);
    int add_port_mapping (protocol_type t, int external_port, int local_port);

add_port_mapping adds a port forwarding on UPnP and/or NAT-PMP, whichever is enabled. The return value is a handle referring to the port mapping that was just created. Pass it to delete_port_mapping() to remove it.

## start_natpmp() stop_natpmp()

    void stop_natpmp ();
    void start_natpmp ();

Starts and stops the NAT-PMP service. When started, the listen port and the DHT port are attempted to be forwarded on the router through NAT-PMP.

The natpmp object returned by `start_natpmp()` can be used to add and remove arbitrary port mappings. Mapping status is returned through the portmap_alert and the portmap_error_alert. The object will be valid until `stop_natpmp()` is called. See upnp and nat pmp.

It is off by default.

## enum save_state_flags_t

Declared in "libtorrent/session.hpp"

name | value | description
--- | --- | ---
save_settings | 1 | saves settings (i.e. the session_settings)
save_dht_settings | 2 | saves dht_settings
save_dht_state | 4 | saves dht state such as nodes and node-id, possibly accelerating joining the DHT if provided at next session startup.
save_proxy | 8 | save proxy_settings
save_i2p_proxy | 16 | save i2p_proxy settings
save_encryption_settings | 32 | save pe_settings
save_feeds | 128 | saves RSS feeds

## enum listen_on_flags_t

Declared in "libtorrent/session.hpp"

name | value | description
--- | --- | ---
listen_no_system_port | 2 |

## enum options_t

Declared in "libtorrent/session.hpp"

name | value | description
--- | --- | ---
delete_files | 1 | delete the files belonging to the torrent from disk.

## enum session_flags_t

Declared in "libtorrent/session.hpp"

name | value | description
--- | --- | ---
add_default_plugins | 1 | this will add common extensions like ut_pex, ut_metadata, lt_tex smart_ban and possibly others.
start_default_features | 2 | this will start features like DHT, local service discovery, UPnP and NAT-PMP.

## enum protocol_type

Declared in "libtorrent/session.hpp"

name | value | description
--- | --- | ---
udp | 1 |
tcp | 2 |

# dht_lookup

Declared in "libtorrent/session_status.hpp"

holds statistics about a current dht_lookup operation. a DHT lookup is the travesal of nodes, looking up a set of target nodes in the DHT for retrieving and possibly storing information in the DHT

    struct dht_lookup
    {
       char const* type;
       int outstanding_requests;
       int timeouts;
       int responses;
       int branch_factor;
       int nodes_left;
       int last_sent;
       int first_timeout;
    };

type
  string literal indicating which kind of lookup this is

outstanding_requests
  the number of outstanding request to individual nodes this lookup has right now

timeouts
  the total number of requests that have timed out so far for this lookup

responses
  the total number of responses we have received for this lookup so far for this lookup

branch_factor
  the branch factor for this lookup. This is the number of nodes we keep outstanding requests to in parallel by default. when nodes time out we may increase this.

nodes_left
  the number of nodes left that could be queries for this lookup. Many of these are likely to be part of the trail while performing the lookup and would never end up actually being queried.

last_sent
  the number of seconds ago the last message was sent that's still outstanding

first_timeout
  the number of outstanding requests that have exceeded the short timeout and are considered timed out in the sense that they increased the branch factor

# dht_routing_bucket

Declared in "libtorrent/session_status.hpp"

holds dht routing table stats

    struct dht_routing_bucket
    {
       int num_nodes;
       int num_replacements;
    };

num_nodes num_replacements
  the total number of nodes and replacement nodes in the routing table

# utp_status

Declared in "libtorrent/session_status.hpp"

holds counters and gauges for the uTP sockets

    struct utp_status
    {
       int num_idle;
       int num_syn_sent;
       int num_connected;
       int num_fin_sent;
       int num_close_wait;
       boost::uint64_t packet_loss;
       boost::uint64_t timeout;
       boost::uint64_t packets_in;
       boost::uint64_t packets_out;
       boost::uint64_t fast_retransmit;
       boost::uint64_t packet_resend;
       boost::uint64_t samples_above_target;
       boost::uint64_t samples_below_target;
       boost::uint64_t payload_pkts_in;
       boost::uint64_t payload_pkts_out;
       boost::uint64_t invalid_pkts_in;
       boost::uint64_t redundant_pkts_in;
    };

num_idle num_syn_sent num_connected num_fin_sent num_close_wait
  gauges. These are snapshots of the number of uTP sockets in each respective state

packet_loss timeout packets_in packets_out fast_retransmit packet_resend samples_above_target samples_below_target payload_pkts_in payload_pkts_out invalid_pkts_in redundant_pkts_in
  counters. These are monotonically increasing and cumulative counters for their respective event.

# session_status

Declared in "libtorrent/session_status.hpp"

contains session wide state and counters

    struct session_status
    {
       bool has_incoming_connections;
       int upload_rate;
       int download_rate;
       size_type total_download;
       size_type total_upload;
       int payload_upload_rate;
       int payload_download_rate;
       size_type total_payload_download;
       size_type total_payload_upload;
       int ip_overhead_upload_rate;
       int ip_overhead_download_rate;
       size_type total_ip_overhead_download;
       size_type total_ip_overhead_upload;
       int dht_upload_rate;
       int dht_download_rate;
       size_type total_dht_download;
       size_type total_dht_upload;
       int tracker_upload_rate;
       int tracker_download_rate;
       size_type total_tracker_download;
       size_type total_tracker_upload;
       size_type total_redundant_bytes;
       size_type total_failed_bytes;
       int num_peers;
       int num_unchoked;
       int allowed_upload_slots;
       int up_bandwidth_queue;
       int down_bandwidth_queue;
       int up_bandwidth_bytes_queue;
       int down_bandwidth_bytes_queue;
       int optimistic_unchoke_counter;
       int unchoke_counter;
       int disk_write_queue;
       int disk_read_queue;
       int dht_nodes;
       int dht_node_cache;
       int dht_torrents;
       size_type dht_global_nodes;
       std::vector<dht_lookup> active_requests;
       std::vector<dht_routing_bucket> dht_routing_table;
       int dht_total_allocations;
       utp_status utp_stats;
       int peerlist_size;
    };

has_incoming_connections
  false as long as no incoming connections have been established on the listening socket. Every time you change the listen port, this will be reset to false.

upload_rate download_rate
  the total download and upload rates accumulated from all torrents. This includes bittorrent protocol, DHT and an estimated TCP/IP protocol overhead.

total_download total_upload
  the total number of bytes downloaded and uploaded to and from all torrents. This also includes all the protocol overhead.

payload_upload_rate payload_download_rate
  the rate of the payload down- and upload only.

total_payload_download total_payload_upload
  the total transfers of payload only. The payload does not include the bittorrent protocol overhead, but only parts of the actual files to be downloaded.

ip_overhead_upload_rate ip_overhead_download_rate total_ip_overhead_download total_ip_overhead_upload
  the estimated TCP/IP overhead in each direction.

dht_upload_rate dht_download_rate total_dht_download total_dht_upload
  the upload and download rate used by DHT traffic. Also the total number of bytes sent and received to and from the DHT.

tracker_upload_rate tracker_download_rate total_tracker_download total_tracker_upload
  the upload and download rate used by tracker traffic. Also the total number of bytes sent and received to and from trackers.

total_redundant_bytes
  the number of bytes that has been received more than once. This can happen if a request from a peer times out and is requested from a different peer, and then received again from the first one. To make this lower, increase the `request_timeout` and the `piece_timeout` in the session settings.

total_failed_bytes
  the number of bytes that was downloaded which later failed the hash-check.

num_peers
  the total number of peer connections this session has. This includes incoming connections that still hasn't sent their handshake or outgoing connections that still hasn't completed the TCP connection. This number may be slightly higher than the sum of all peers of all torrents because the incoming connections may not be assigned a torrent yet.

num_unchoked
  the current number of unchoked peers.

allowed_upload_slots
  the current allowed number of unchoked peers.

up_bandwidth_queue down_bandwidth_queue
  the number of peers that are waiting for more bandwidth quota from the torrent rate limiter.

up_bandwidth_bytes_queue down_bandwidth_bytes_queue
  count the number of bytes the connections are waiting for to be able to send and receive.

optimistic_unchoke_counter unchoke_counter
  tells the number of seconds until the next optimistic unchoke change and the start of the next unchoke interval. These numbers may be reset prematurely if a peer that is unchoked disconnects or becomes notinterested.

disk_write_queue disk_read_queue
  the number of peers currently waiting on a disk write or disk read to complete before it receives or sends any more data on the socket. It'a a metric of how disk bound you are.

dht_nodes dht_node_cache
  only available when built with DHT support. They are all set to 0 if the DHT isn't running. When the DHT is running, `dht_nodes` is set to the number of nodes in the routing table. This number only includes active nodes, not cache nodes. The `dht_node_cache` is set to the number of nodes in the node cache. These nodes are used to replace the regular nodes in the routing table in case any of them becomes unresponsive.

dht_torrents
  the number of torrents tracked by the DHT at the moment.

dht_global_nodes
  an estimation of the total number of nodes in the DHT network.

active_requests
  a vector of the currently running DHT lookups.

dht_routing_table
  contains information about every bucket in the DHT routing table.

dht_total_allocations
  the number of nodes allocated dynamically for a particular DHT lookup. This represents roughly the amount of memory used by the DHT.

utp_stats
  statistics on the uTP sockets.

peerlist_size
  the number of known peers across all torrents. These are not necessarily connected peers, just peers we know of.