diff --git a/CMakeLists.txt b/CMakeLists.txt index cc624e8d3..e91ed5507 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ set(sources rss session session_call + session_handle session_impl session_settings session_stats diff --git a/Jamfile b/Jamfile old mode 100755 new mode 100644 index a24cbdfe9..f4dffebea --- a/Jamfile +++ b/Jamfile @@ -640,6 +640,7 @@ SOURCES = resolve_links rss session + session_handle session_impl session_call settings_pack diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index 071d884ef..acb1fbb18 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -107,6 +107,7 @@ nobase_include_HEADERS = \ request_blocks.hpp \ rss.hpp \ session.hpp \ + session_handle.hpp \ session_settings.hpp \ session_stats.hpp \ session_status.hpp \ diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 53238061b..d5c37829f 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -43,22 +43,15 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/config.hpp" -#include "libtorrent/torrent_handle.hpp" -#include "libtorrent/entry.hpp" #include "libtorrent/version.hpp" #include "libtorrent/fingerprint.hpp" -#include "libtorrent/disk_io_thread.hpp" // for cached_piece_info -#include "libtorrent/peer_id.hpp" -#include "libtorrent/alert.hpp" // alert::error_notification -#include "libtorrent/add_torrent_params.hpp" -#include "libtorrent/peer_class.hpp" -#include "libtorrent/peer_class_type_filter.hpp" #include "libtorrent/build_config.hpp" #include "libtorrent/settings_pack.hpp" #include "libtorrent/io_service.hpp" #include "libtorrent/storage.hpp" #include "libtorrent/session_settings.hpp" +#include "libtorrent/session_handle.hpp" #include "libtorrent/thread.hpp" #ifndef TORRENT_NO_DEPRECATE @@ -74,21 +67,6 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { - struct plugin; - struct torrent_plugin; - class torrent; - struct ip_filter; - class port_filter; - class connection_queue; - class alert; - -#ifndef TORRENT_NO_DEPRECATE - struct session_status; -#endif - - typedef boost::function& - , error_code&)> user_load_function_t; - // The default values of the session settings are set for a regular // bittorrent client running on a desktop system. There are functions that // can set the session settings to pre set settings for other environments. @@ -173,7 +151,7 @@ namespace libtorrent // the settings to be set and pass it in to ``session::apply_settings()``. // // see apply_settings(). - class TORRENT_EXPORT session: public boost::noncopyable + class TORRENT_EXPORT session: public boost::noncopyable, public session_handle { public: @@ -190,6 +168,7 @@ namespace libtorrent // pass 0 as the flags parameter. session(settings_pack const& pack = settings_pack() , int flags = start_default_features | add_default_plugins) + : session_handle(NULL) { TORRENT_CFG(); start(flags, pack, NULL); @@ -211,6 +190,7 @@ namespace libtorrent session(settings_pack const& pack , io_service& ios , int flags = start_default_features | add_default_plugins) + : session_handle(NULL) { TORRENT_CFG(); start(flags, pack, &ios); @@ -221,6 +201,7 @@ namespace libtorrent session(fingerprint const& print , int flags = start_default_features | add_default_plugins , boost::uint32_t alert_mask = alert::error_notification) + : session_handle(NULL) { TORRENT_CFG(); settings_pack pack; @@ -243,6 +224,7 @@ namespace libtorrent , char const* listen_interface = "0.0.0.0" , int flags = start_default_features | add_default_plugins , int alert_mask = alert::error_notification) + : session_handle(NULL) { TORRENT_CFG(); TORRENT_ASSERT(listen_port_range.first > 0); @@ -275,177 +257,6 @@ namespace libtorrent // it to finish. The timeout can be set with apply_settings(). ~session(); - // TODO: 2 the ip filter should probably be saved here too - - // flags that determines which aspects of the session should be - // saved when calling save_state(). - enum save_state_flags_t - { - // saves settings (i.e. the session_settings) - save_settings = 0x001, - - // saves dht_settings - save_dht_settings = 0x002, - - // saves dht state such as nodes and node-id, possibly accelerating - // joining the DHT if provided at next session startup. - save_dht_state = 0x004, - - // save pe_settings - save_encryption_settings = 0x020, - - // internal - save_as_map = 0x040 - -#ifndef TORRENT_NO_DEPRECATE - , - // saves RSS feeds - save_feeds = 0x080, - save_proxy = 0x008, - save_i2p_proxy = 0x010, - save_dht_proxy = save_proxy, - save_peer_proxy = save_proxy, - save_web_proxy = save_proxy, - save_tracker_proxy = save_proxy -#endif - }; - - // 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 bdecode_node which can be built from a bencoded - // buffer with 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 - void save_state(entry& e, boost::uint32_t flags = 0xffffffff) const; - void load_state(bdecode_node const& e); - - // .. 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. - void get_torrent_status(std::vector* ret - , boost::function const& pred - , boost::uint32_t flags = 0) const; - void refresh_torrent_status(std::vector* ret - , boost::uint32_t flags = 0) const; - - // 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. - // the ``flags`` argument is the same as for torrent_handle::status(). - // see torrent_handle::status_flags_t. - void post_torrent_updates(boost::uint32_t flags = 0xffffffff); - - // This function will post a session_stats_alert object, containing a - // snapshot of the performance counters from the internals of libtorrent. - // To interpret these counters, query the session via - // session_stats_metrics(). - // - // For more information, see the session-statistics_ section. - void post_session_stats(); - - // This will cause a dht_stats_alert to be posted. - void post_dht_stats(); - - // internal - io_service& get_io_service(); - - // ``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. - torrent_handle find_torrent(sha1_hash const& info_hash) const; - std::vector get_torrents() const; - - // 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! -#ifndef BOOST_NO_EXCEPTIONS - torrent_handle add_torrent(add_torrent_params const& params); -#endif - torrent_handle add_torrent(add_torrent_params const& params, error_code& ec); - void async_add_torrent(add_torrent_params const& params); - -#ifndef BOOST_NO_EXCEPTIONS -#ifndef TORRENT_NO_DEPRECATE - // deprecated in 0.14 - TORRENT_DEPRECATED - torrent_handle add_torrent( - torrent_info const& ti - , std::string const& save_path - , entry const& resume_data = entry() - , storage_mode_t storage_mode = storage_mode_sparse - , bool paused = false - , storage_constructor_type sc = default_storage_constructor); - - // deprecated in 0.14 - TORRENT_DEPRECATED - torrent_handle add_torrent( - char const* tracker_url - , sha1_hash const& info_hash - , char const* name - , std::string const& save_path - , entry const& resume_data = entry() - , storage_mode_t storage_mode = storage_mode_sparse - , bool paused = false - , storage_constructor_type sc = default_storage_constructor - , void* userdata = 0); -#endif -#endif - // 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 @@ -466,788 +277,6 @@ namespace libtorrent // }; session_proxy abort() { return session_proxy(m_io_service, m_thread, m_impl); } - // 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. - void pause(); - void resume(); - bool is_paused() const; - - // This function enables dynamic-loading-of-torrent-files_. When a - // torrent is unloaded but needs to be availabe in memory, this function - // is called **from within the libtorrent network thread**. From within - // this thread, you can **not** use any of the public APIs of libtorrent - // itself. The the info-hash of the torrent is passed in to the function - // and it is expected to fill in the passed in ``vector`` with the - // .torrent file corresponding to it. - // - // If there is an error loading the torrent file, the ``error_code`` - // (``ec``) should be set to reflect the error. In such case, the torrent - // itself is stopped and set to an error state with the corresponding - // error code. - // - // Given that the function is called from the internal network thread of - // libtorrent, it's important to not stall. libtorrent will not be able - // to send nor receive any data until the function call returns. - // - // The signature of the function to pass in is:: - // - // void fun(sha1_hash const& info_hash, std::vector& buf, error_code& ec); - void set_load_function(user_load_function_t fun); - -#ifndef TORRENT_NO_DEPRECATE - // deprecated in libtorrent 1.1, use performance_counters instead - // returns session wide-statistics and status. For more information, see - // the ``session_status`` struct. - TORRENT_DEPRECATED - session_status status() const; - - // deprecated in libtorrent 1.1 - // 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``). - TORRENT_DEPRECATED - void get_cache_info(sha1_hash const& ih - , std::vector& ret) const; - - // Returns status of the disk cache for this session. - // For more information, see the cache_status type. - TORRENT_DEPRECATED - cache_status get_cache_status() const; -#endif - - enum { disk_cache_no_pieces = 1 }; - - // Fills in the cache_status struct with information about the given torrent. - // If ``flags`` is ``session::disk_cache_no_pieces`` the ``cache_status::pieces`` field - // will not be set. This may significantly reduce the cost of this call. - void get_cache_info(cache_status* ret, torrent_handle h = torrent_handle(), int flags = 0) const; - -#ifndef TORRENT_NO_DEPRECATE - // 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. - TORRENT_DEPRECATED - feed_handle add_feed(feed_settings const& feed); - - // 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. - TORRENT_DEPRECATED - void remove_feed(feed_handle h); - - // Returns a list of all RSS feeds that are being watched by the session. - TORRENT_DEPRECATED - void get_feeds(std::vector& f) const; - - // ``start_dht`` starts the dht node and makes the trackerless service - // available to torrents. - // - // ``stop_dht`` stops the dht node. - // deprecated. use settings_pack::enable_dht instead - TORRENT_DEPRECATED - void start_dht(); - TORRENT_DEPRECATED - void stop_dht(); -#endif - - // ``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 - void set_dht_settings(dht_settings const& settings); - bool is_dht_running() const; - dht_settings get_dht_settings() const; - - // ``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``. - void add_dht_node(std::pair const& node); - void add_dht_router(std::pair const& node); - - // query the DHT for an immutable item at the ``target`` hash. - // the result is posted as a dht_immutable_item_alert. - void dht_get_item(sha1_hash const& target); - - // 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. - void dht_get_item(boost::array key - , std::string salt = std::string()); - - // 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. - sha1_hash dht_put_item(entry data); - - // 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& 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. - void dht_put_item(boost::array key - , boost::function& - , boost::uint64_t&, std::string const&)> cb - , std::string salt = std::string()); - -#ifndef TORRENT_NO_DEPRECATE - // deprecated in 0.15 - // use save_state and load_state instead - TORRENT_DEPRECATED - entry dht_state() const; - TORRENT_DEPRECATED - void start_dht(entry const& startup_state); -#endif - - // 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``. 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 - // ses.add_extension(&libtorrent::create_metadata_plugin); - // - // uTorrent metadata - // Same as ``metadata extension`` but compatible with uTorrent. - // - // :: - // - // #include - // ses.add_extension(&libtorrent::create_ut_metadata_plugin); - // - // uTorrent peer exchange - // Exchanges peers between clients. - // - // :: - // - // #include - // 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 - // ses.add_extension(&libtorrent::create_smart_ban_plugin); - // - // - // .. _`libtorrent plugins`: libtorrent_plugins.html - void add_extension(boost::function( - torrent*, void*)> ext); - void add_extension(boost::shared_ptr ext); - -#ifndef TORRENT_NO_DEPRECATE - // GeoIP support has been removed from libtorrent internals. If you - // still need to resolve peers, please do so on the client side, using - // libgeoip directly. This was removed in libtorrent 1.1 - - // These functions 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. - // - // .. _`MaxMind ASN database`: http://www.maxmind.com/app/asnum - // .. _`MaxMind GeoIP database`: http://www.maxmind.com/app/geolitecountry - TORRENT_DEPRECATED - void load_asnum_db(char const* file); - TORRENT_DEPRECATED - void load_country_db(char const* file); - TORRENT_DEPRECATED - int as_for_ip(address const& addr); -#if TORRENT_USE_WSTRING - // all wstring APIs are deprecated since 0.16.11 - // instead, use the wchar -> utf8 conversion functions - // and pass in utf8 strings - TORRENT_DEPRECATED - void load_country_db(wchar_t const* file); - TORRENT_DEPRECATED - void load_asnum_db(wchar_t const* file); -#endif // TORRENT_USE_WSTRING - - // deprecated in 0.15 - // use load_state and save_state instead - TORRENT_DEPRECATED - void load_state(entry const& ses_state); - TORRENT_DEPRECATED - entry state() const; - // deprecated in 1.1 - TORRENT_DEPRECATED - void load_state(lazy_entry const& ses_state); -#endif // TORRENT_NO_DEPRECATE - - // 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. - void set_ip_filter(ip_filter const& f); - ip_filter get_ip_filter() const; - - // 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. - void set_port_filter(port_filter const& f); - -#ifndef TORRENT_NO_DEPRECATE - // deprecated in 1.1, use settings_pack::peer_fingerprint instead - TORRENT_DEPRECATED - void set_peer_id(peer_id const& pid); -#endif - // returns the raw peer ID used by libtorrent. When anonymous mode is set - // the peer ID is randomized per peer. - peer_id id() const; - - // 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. - void set_key(int key); - - // built-in peer classes - enum { - global_peer_class_id, - tcp_peer_class_id, - local_peer_class_id - }; - - // ``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. If the - // port specified in settings_pack::listen_interfaces failed, libtorrent - // will try to bind to the next port, and so on. If it fails - // settings_pack::max_retry_port_bind times, it will bind to port 0 - // (meaning the OS picks the port). The only way to know which port it - // ended up binding to is to ask for it by calling ``listen_port()``. - // - // 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. - unsigned short listen_port() const; - unsigned short ssl_listen_port() const; - bool is_listening() const; - - // 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 200.1.1.0 - 200.1.255.255 - // belong to their own peer class, apply the following filter:: - // - // ip_filter f; - // int my_class = ses.create_peer_class("200.1.x.x IP range"); - // f.add_rule(address_v4::from_string("200.1.1.0") - // , address_v4::from_string("200.1.255.255") - // , 1 << 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. - // - // For more information, see peer-classes_. - void set_peer_class_filter(ip_filter const& f); - - // 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: - // - // 1. peer-class IP filter - // 2. peer-class type filter, removing classes - // 3. peer-class type filter, adding classes - // - // For more information, see peer-classes_. - // TODO: add get_peer_class_type_filter() as well - void set_peer_class_type_filter(peer_class_type_filter const& f); - - // 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_. - int create_peer_class(char const* name); - - // 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_. - void delete_peer_class(int cid); - - // 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 balonging 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_. - peer_class_info get_peer_class(int cid); - void set_peer_class(int cid, peer_class_info const& pci); - -#ifndef TORRENT_NO_DEPRECATE - // if the listen port failed in some way you can retry to listen on - // another port- range with this function. If the listener succeeded and - // is currently listening, a call to this function will shut down the - // listen port and reopen it using these new properties (the given - // interface and port range). As usual, if the interface is left as 0 - // this function will return false on failure. If it fails, it will also - // generate alerts describing the error. It will return true on success. - enum listen_on_flags_t - { - // this is always on starting with 0.16.2 - listen_reuse_address = 0x01, - listen_no_system_port = 0x02 - }; - - // deprecated in 0.16 - - // specify which interfaces to bind outgoing connections to - // This has been moved to a session setting - TORRENT_DEPRECATED - void use_interfaces(char const* interfaces); - - // instead of using this, specify listen interface and port in - // the settings_pack::listen_interfaces setting - TORRENT_DEPRECATED - void listen_on( - std::pair const& port_range - , error_code& ec - , const char* net_interface = 0 - , int flags = 0); - -#endif - - // flags to be passed in to remove_torrent(). - enum options_t - { - // delete the files belonging to the torrent from disk. - delete_files = 1 - }; - - // flags to be passed in to the session constructor - enum session_flags_t - { - // this will add common extensions like ut_pex, ut_metadata, lt_tex - // smart_ban and possibly others. - add_default_plugins = 1, - - // this will start features like DHT, local service discovery, UPnP - // and NAT-PMP. - start_default_features = 2 - }; - - // ``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. - void remove_torrent(const torrent_handle& h, int options = 0); - -#ifndef TORRENT_NO_DEPRECATE - // deprecated in aio-branch - // Sets the session settings and the packet encryption settings - // respectively. See session_settings and pe_settings for more - // information on available options. - TORRENT_DEPRECATED - void set_settings(session_settings const& s); - TORRENT_DEPRECATED - session_settings settings() const; - - // deprecated in libtorrent 1.1. use settings_pack instead - TORRENT_DEPRECATED - void set_pe_settings(pe_settings const& settings); - TORRENT_DEPRECATED - pe_settings get_pe_settings() const; -#endif - - // 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. - void apply_settings(settings_pack const& s); - settings_pack get_settings() const; - -#ifndef TORRENT_NO_DEPRECATE - // ``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. - // - // .. _i2p: http://www.i2p2.de - - TORRENT_DEPRECATED - void set_i2p_proxy(proxy_settings const& s); - TORRENT_DEPRECATED - proxy_settings i2p_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. - TORRENT_DEPRECATED - void set_proxy(proxy_settings const& s); - TORRENT_DEPRECATED - proxy_settings proxy() const; - - // deprecated in 0.16 - // Get the number of uploads. - TORRENT_DEPRECATED - int num_uploads() const; - - // Get the number of connections. This number also contains the - // number of half open connections. - TORRENT_DEPRECATED - int num_connections() const; - - // deprecated in 0.15. - TORRENT_DEPRECATED - void set_peer_proxy(proxy_settings const& s); - TORRENT_DEPRECATED - void set_web_seed_proxy(proxy_settings const& s); - TORRENT_DEPRECATED - void set_tracker_proxy(proxy_settings const& s); - - TORRENT_DEPRECATED - proxy_settings peer_proxy() const; - TORRENT_DEPRECATED - proxy_settings web_seed_proxy() const; - TORRENT_DEPRECATED - proxy_settings tracker_proxy() const; - - TORRENT_DEPRECATED - void set_dht_proxy(proxy_settings const& s); - TORRENT_DEPRECATED - proxy_settings dht_proxy() const; - - // deprecated in 0.16 - TORRENT_DEPRECATED - int upload_rate_limit() const; - TORRENT_DEPRECATED - int download_rate_limit() const; - TORRENT_DEPRECATED - int local_upload_rate_limit() const; - TORRENT_DEPRECATED - int local_download_rate_limit() const; - TORRENT_DEPRECATED - int max_half_open_connections() const; - - TORRENT_DEPRECATED - void set_local_upload_rate_limit(int bytes_per_second); - TORRENT_DEPRECATED - void set_local_download_rate_limit(int bytes_per_second); - TORRENT_DEPRECATED - void set_upload_rate_limit(int bytes_per_second); - TORRENT_DEPRECATED - void set_download_rate_limit(int bytes_per_second); - TORRENT_DEPRECATED - void set_max_uploads(int limit); - TORRENT_DEPRECATED - void set_max_connections(int limit); - TORRENT_DEPRECATED - void set_max_half_open_connections(int limit); - - TORRENT_DEPRECATED - int max_connections() const; - TORRENT_DEPRECATED - int max_uploads() const; - - TORRENT_DEPRECATED - std::auto_ptr pop_alert(); - TORRENT_DEPRECATED - void pop_alerts(std::deque* alerts); - -#endif - - // 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. The session still owns these alerts and they will stay - // valid until the next time ``pop_alerts`` is called. 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 NULL. - // - // 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 - // ``session_settings::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, regardelss of the alert mask. - // - // To control which alerts are posted, set the alert_mask - // (settings_pack::alert_mask). - // - // 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. - void pop_alerts(std::vector* alerts); - alert* wait_for_alert(time_duration max_wait); - void set_alert_notify(boost::function const& fun); - -#ifndef TORRENT_NO_DEPRECATE - TORRENT_DEPRECATED - void set_severity_level(alert::severity_t s); - - // use the setting instead - TORRENT_DEPRECATED - size_t set_alert_queue_size_limit(size_t queue_size_limit_); - - // 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. - // - // ``get_alert_mask()`` returns the current mask; - // - // See category_t enum for options. - TORRENT_DEPRECATED - void set_alert_mask(boost::uint32_t m); - TORRENT_DEPRECATED - boost::uint32_t get_alert_mask() const; - - // 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 block. - // - // 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. - TORRENT_DEPRECATED - void set_alert_dispatch( - boost::function)> const& fun); - - // 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. - // - // deprecated. use settings_pack::enable_lsd instead - TORRENT_DEPRECATED - void start_lsd(); - TORRENT_DEPRECATED - void stop_lsd(); - - // 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_. - // - // deprecated. use settings_pack::enable_upnp instead - TORRENT_DEPRECATED - void start_upnp(); - TORRENT_DEPRECATED - void stop_upnp(); - - // 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_. - // - // deprecated. use settings_pack::enable_natpmp instead - TORRENT_DEPRECATED - void start_natpmp(); - TORRENT_DEPRECATED - void stop_natpmp(); -#endif - - // protocols used by add_port_mapping() - enum protocol_type { udp = 1, tcp = 2 }; - - // 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. - int add_port_mapping(protocol_type t, int external_port, int local_port); - void delete_port_mapping(int handle); - private: void start(int flags, settings_pack const& pack, io_service* ios); diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp new file mode 100644 index 000000000..555abfb0c --- /dev/null +++ b/include/libtorrent/session_handle.hpp @@ -0,0 +1,1037 @@ +/* + +Copyright (c) 2003-2015, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef TORRENT_SESSION_HANDLE_HPP_INCLUDED +#define TORRENT_SESSION_HANDLE_HPP_INCLUDED + +#include "libtorrent/config.hpp" +#include "libtorrent/entry.hpp" +#include "libtorrent/torrent_handle.hpp" +#include "libtorrent/add_torrent_params.hpp" +#include "libtorrent/disk_io_thread.hpp" // for cached_piece_info +#include "libtorrent/alert.hpp" // alert::error_notification +#include "libtorrent/peer_class.hpp" +#include "libtorrent/peer_class_type_filter.hpp" +#include "libtorrent/session_settings.hpp" + +#ifndef TORRENT_NO_DEPRECATE +#include "libtorrent/rss.hpp" +#endif + +namespace libtorrent +{ + struct plugin; + struct torrent_plugin; + class torrent; + struct ip_filter; + class port_filter; + class connection_queue; + class alert; + +#ifndef TORRENT_NO_DEPRECATE + struct session_status; +#endif + + typedef boost::function& + , error_code&)> user_load_function_t; + + struct TORRENT_EXPORT session_handle + { + session_handle(aux::session_impl* impl) + : m_impl(impl) + {} + + // TODO: 2 the ip filter should probably be saved here too + + // flags that determines which aspects of the session should be + // saved when calling save_state(). + enum save_state_flags_t + { + // saves settings (i.e. the session_settings) + save_settings = 0x001, + + // saves dht_settings + save_dht_settings = 0x002, + + // saves dht state such as nodes and node-id, possibly accelerating + // joining the DHT if provided at next session startup. + save_dht_state = 0x004, + + // save pe_settings + save_encryption_settings = 0x020, + + // internal + save_as_map = 0x040 + +#ifndef TORRENT_NO_DEPRECATE + , + // saves RSS feeds + save_feeds = 0x080, + save_proxy = 0x008, + save_i2p_proxy = 0x010, + save_dht_proxy = save_proxy, + save_peer_proxy = save_proxy, + save_web_proxy = save_proxy, + save_tracker_proxy = save_proxy +#endif + }; + + // 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 bdecode_node which can be built from a bencoded + // buffer with 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 + void save_state(entry& e, boost::uint32_t flags = 0xffffffff) const; + void load_state(bdecode_node const& e); + + // .. 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. + void get_torrent_status(std::vector* ret + , boost::function const& pred + , boost::uint32_t flags = 0) const; + void refresh_torrent_status(std::vector* ret + , boost::uint32_t flags = 0) const; + + // 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. + // the ``flags`` argument is the same as for torrent_handle::status(). + // see torrent_handle::status_flags_t. + void post_torrent_updates(boost::uint32_t flags = 0xffffffff); + + // This function will post a session_stats_alert object, containing a + // snapshot of the performance counters from the internals of libtorrent. + // To interpret these counters, query the session via + // session_stats_metrics(). + // + // For more information, see the session-statistics_ section. + void post_session_stats(); + + // This will cause a dht_stats_alert to be posted. + void post_dht_stats(); + + // internal + io_service& get_io_service(); + + // ``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. + torrent_handle find_torrent(sha1_hash const& info_hash) const; + std::vector get_torrents() const; + + // 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! +#ifndef BOOST_NO_EXCEPTIONS + torrent_handle add_torrent(add_torrent_params const& params); +#endif + torrent_handle add_torrent(add_torrent_params const& params, error_code& ec); + void async_add_torrent(add_torrent_params const& params); + +#ifndef BOOST_NO_EXCEPTIONS +#ifndef TORRENT_NO_DEPRECATE + // deprecated in 0.14 + TORRENT_DEPRECATED + torrent_handle add_torrent( + torrent_info const& ti + , std::string const& save_path + , entry const& resume_data = entry() + , storage_mode_t storage_mode = storage_mode_sparse + , bool paused = false + , storage_constructor_type sc = default_storage_constructor); + + // deprecated in 0.14 + TORRENT_DEPRECATED + torrent_handle add_torrent( + char const* tracker_url + , sha1_hash const& info_hash + , char const* name + , std::string const& save_path + , entry const& resume_data = entry() + , storage_mode_t storage_mode = storage_mode_sparse + , bool paused = false + , storage_constructor_type sc = default_storage_constructor + , void* userdata = 0); +#endif +#endif + + // 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. + void pause(); + void resume(); + bool is_paused() const; + + // This function enables dynamic-loading-of-torrent-files_. When a + // torrent is unloaded but needs to be availabe in memory, this function + // is called **from within the libtorrent network thread**. From within + // this thread, you can **not** use any of the public APIs of libtorrent + // itself. The the info-hash of the torrent is passed in to the function + // and it is expected to fill in the passed in ``vector`` with the + // .torrent file corresponding to it. + // + // If there is an error loading the torrent file, the ``error_code`` + // (``ec``) should be set to reflect the error. In such case, the torrent + // itself is stopped and set to an error state with the corresponding + // error code. + // + // Given that the function is called from the internal network thread of + // libtorrent, it's important to not stall. libtorrent will not be able + // to send nor receive any data until the function call returns. + // + // The signature of the function to pass in is:: + // + // void fun(sha1_hash const& info_hash, std::vector& buf, error_code& ec); + void set_load_function(user_load_function_t fun); + +#ifndef TORRENT_NO_DEPRECATE + // deprecated in libtorrent 1.1, use performance_counters instead + // returns session wide-statistics and status. For more information, see + // the ``session_status`` struct. + TORRENT_DEPRECATED + session_status status() const; + + // deprecated in libtorrent 1.1 + // 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``). + TORRENT_DEPRECATED + void get_cache_info(sha1_hash const& ih + , std::vector& ret) const; + + // Returns status of the disk cache for this session. + // For more information, see the cache_status type. + TORRENT_DEPRECATED + cache_status get_cache_status() const; +#endif + + enum { disk_cache_no_pieces = 1 }; + + // Fills in the cache_status struct with information about the given torrent. + // If ``flags`` is ``session::disk_cache_no_pieces`` the ``cache_status::pieces`` field + // will not be set. This may significantly reduce the cost of this call. + void get_cache_info(cache_status* ret, torrent_handle h = torrent_handle(), int flags = 0) const; + +#ifndef TORRENT_NO_DEPRECATE + // 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. + TORRENT_DEPRECATED + feed_handle add_feed(feed_settings const& feed); + + // 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. + TORRENT_DEPRECATED + void remove_feed(feed_handle h); + + // Returns a list of all RSS feeds that are being watched by the session. + TORRENT_DEPRECATED + void get_feeds(std::vector& f) const; + + // ``start_dht`` starts the dht node and makes the trackerless service + // available to torrents. + // + // ``stop_dht`` stops the dht node. + // deprecated. use settings_pack::enable_dht instead + TORRENT_DEPRECATED + void start_dht(); + TORRENT_DEPRECATED + void stop_dht(); +#endif + + // ``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 + void set_dht_settings(dht_settings const& settings); + bool is_dht_running() const; + dht_settings get_dht_settings() const; + + // ``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``. + void add_dht_node(std::pair const& node); + void add_dht_router(std::pair const& node); + + // query the DHT for an immutable item at the ``target`` hash. + // the result is posted as a dht_immutable_item_alert. + void dht_get_item(sha1_hash const& target); + + // 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. + void dht_get_item(boost::array key + , std::string salt = std::string()); + + // 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. + sha1_hash dht_put_item(entry data); + + // 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& 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. + void dht_put_item(boost::array key + , boost::function& + , boost::uint64_t&, std::string const&)> cb + , std::string salt = std::string()); + +#ifndef TORRENT_NO_DEPRECATE + // deprecated in 0.15 + // use save_state and load_state instead + TORRENT_DEPRECATED + entry dht_state() const; + TORRENT_DEPRECATED + void start_dht(entry const& startup_state); +#endif + + // 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``. 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 + // ses.add_extension(&libtorrent::create_metadata_plugin); + // + // uTorrent metadata + // Same as ``metadata extension`` but compatible with uTorrent. + // + // :: + // + // #include + // ses.add_extension(&libtorrent::create_ut_metadata_plugin); + // + // uTorrent peer exchange + // Exchanges peers between clients. + // + // :: + // + // #include + // 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 + // ses.add_extension(&libtorrent::create_smart_ban_plugin); + // + // + // .. _`libtorrent plugins`: libtorrent_plugins.html + void add_extension(boost::function( + torrent*, void*)> ext); + void add_extension(boost::shared_ptr ext); + +#ifndef TORRENT_NO_DEPRECATE + // GeoIP support has been removed from libtorrent internals. If you + // still need to resolve peers, please do so on the client side, using + // libgeoip directly. This was removed in libtorrent 1.1 + + // These functions 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. + // + // .. _`MaxMind ASN database`: http://www.maxmind.com/app/asnum + // .. _`MaxMind GeoIP database`: http://www.maxmind.com/app/geolitecountry + TORRENT_DEPRECATED + void load_asnum_db(char const* file); + TORRENT_DEPRECATED + void load_country_db(char const* file); + TORRENT_DEPRECATED + int as_for_ip(address const& addr); +#if TORRENT_USE_WSTRING + // all wstring APIs are deprecated since 0.16.11 + // instead, use the wchar -> utf8 conversion functions + // and pass in utf8 strings + TORRENT_DEPRECATED + void load_country_db(wchar_t const* file); + TORRENT_DEPRECATED + void load_asnum_db(wchar_t const* file); +#endif // TORRENT_USE_WSTRING + + // deprecated in 0.15 + // use load_state and save_state instead + TORRENT_DEPRECATED + void load_state(entry const& ses_state); + TORRENT_DEPRECATED + entry state() const; + // deprecated in 1.1 + TORRENT_DEPRECATED + void load_state(lazy_entry const& ses_state); +#endif // TORRENT_NO_DEPRECATE + + // 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. + void set_ip_filter(ip_filter const& f); + ip_filter get_ip_filter() const; + + // 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. + void set_port_filter(port_filter const& f); + +#ifndef TORRENT_NO_DEPRECATE + // deprecated in 1.1, use settings_pack::peer_fingerprint instead + TORRENT_DEPRECATED + void set_peer_id(peer_id const& pid); +#endif + + // returns the raw peer ID used by libtorrent. When anonymous mode is set + // the peer ID is randomized per peer. + peer_id id() const; + + // 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. + void set_key(int key); + + // built-in peer classes + enum { + global_peer_class_id, + tcp_peer_class_id, + local_peer_class_id + }; + + // ``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. If the + // port specified in settings_pack::listen_interfaces failed, libtorrent + // will try to bind to the next port, and so on. If it fails + // settings_pack::max_retry_port_bind times, it will bind to port 0 + // (meaning the OS picks the port). The only way to know which port it + // ended up binding to is to ask for it by calling ``listen_port()``. + // + // 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. + unsigned short listen_port() const; + unsigned short ssl_listen_port() const; + bool is_listening() const; + + // 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 200.1.1.0 - 200.1.255.255 + // belong to their own peer class, apply the following filter:: + // + // ip_filter f; + // int my_class = ses.create_peer_class("200.1.x.x IP range"); + // f.add_rule(address_v4::from_string("200.1.1.0") + // , address_v4::from_string("200.1.255.255") + // , 1 << 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. + // + // For more information, see peer-classes_. + void set_peer_class_filter(ip_filter const& f); + + // 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: + // + // 1. peer-class IP filter + // 2. peer-class type filter, removing classes + // 3. peer-class type filter, adding classes + // + // For more information, see peer-classes_. + // TODO: add get_peer_class_type_filter() as well + void set_peer_class_type_filter(peer_class_type_filter const& f); + + // 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_. + int create_peer_class(char const* name); + + // 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_. + void delete_peer_class(int cid); + + // 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 balonging 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_. + peer_class_info get_peer_class(int cid); + void set_peer_class(int cid, peer_class_info const& pci); + +#ifndef TORRENT_NO_DEPRECATE + // if the listen port failed in some way you can retry to listen on + // another port- range with this function. If the listener succeeded and + // is currently listening, a call to this function will shut down the + // listen port and reopen it using these new properties (the given + // interface and port range). As usual, if the interface is left as 0 + // this function will return false on failure. If it fails, it will also + // generate alerts describing the error. It will return true on success. + enum listen_on_flags_t + { + // this is always on starting with 0.16.2 + listen_reuse_address = 0x01, + listen_no_system_port = 0x02 + }; + + // deprecated in 0.16 + + // specify which interfaces to bind outgoing connections to + // This has been moved to a session setting + TORRENT_DEPRECATED + void use_interfaces(char const* interfaces); + + // instead of using this, specify listen interface and port in + // the settings_pack::listen_interfaces setting + TORRENT_DEPRECATED + void listen_on( + std::pair const& port_range + , error_code& ec + , const char* net_interface = 0 + , int flags = 0); +#endif + + // flags to be passed in to remove_torrent(). + enum options_t + { + // delete the files belonging to the torrent from disk. + delete_files = 1 + }; + + // flags to be passed in to the session constructor + enum session_flags_t + { + // this will add common extensions like ut_pex, ut_metadata, lt_tex + // smart_ban and possibly others. + add_default_plugins = 1, + + // this will start features like DHT, local service discovery, UPnP + // and NAT-PMP. + start_default_features = 2 + }; + + // ``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. + void remove_torrent(const torrent_handle& h, int options = 0); + +#ifndef TORRENT_NO_DEPRECATE + // deprecated in aio-branch + // Sets the session settings and the packet encryption settings + // respectively. See session_settings and pe_settings for more + // information on available options. + TORRENT_DEPRECATED + void set_settings(session_settings const& s); + TORRENT_DEPRECATED + session_settings settings() const; + + // deprecated in libtorrent 1.1. use settings_pack instead + TORRENT_DEPRECATED + void set_pe_settings(pe_settings const& settings); + TORRENT_DEPRECATED + pe_settings get_pe_settings() const; +#endif + + // 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. + void apply_settings(settings_pack const& s); + settings_pack get_settings() const; + +#ifndef TORRENT_NO_DEPRECATE + // ``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. + // + // .. _i2p: http://www.i2p2.de + + TORRENT_DEPRECATED + void set_i2p_proxy(proxy_settings const& s); + TORRENT_DEPRECATED + proxy_settings i2p_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. + TORRENT_DEPRECATED + void set_proxy(proxy_settings const& s); + TORRENT_DEPRECATED + proxy_settings proxy() const; + + // deprecated in 0.16 + // Get the number of uploads. + TORRENT_DEPRECATED + int num_uploads() const; + + // Get the number of connections. This number also contains the + // number of half open connections. + TORRENT_DEPRECATED + int num_connections() const; + + // deprecated in 0.15. + TORRENT_DEPRECATED + void set_peer_proxy(proxy_settings const& s); + TORRENT_DEPRECATED + void set_web_seed_proxy(proxy_settings const& s); + TORRENT_DEPRECATED + void set_tracker_proxy(proxy_settings const& s); + + TORRENT_DEPRECATED + proxy_settings peer_proxy() const; + TORRENT_DEPRECATED + proxy_settings web_seed_proxy() const; + TORRENT_DEPRECATED + proxy_settings tracker_proxy() const; + + TORRENT_DEPRECATED + void set_dht_proxy(proxy_settings const& s); + TORRENT_DEPRECATED + proxy_settings dht_proxy() const; + + // deprecated in 0.16 + TORRENT_DEPRECATED + int upload_rate_limit() const; + TORRENT_DEPRECATED + int download_rate_limit() const; + TORRENT_DEPRECATED + int local_upload_rate_limit() const; + TORRENT_DEPRECATED + int local_download_rate_limit() const; + TORRENT_DEPRECATED + int max_half_open_connections() const; + + TORRENT_DEPRECATED + void set_local_upload_rate_limit(int bytes_per_second); + TORRENT_DEPRECATED + void set_local_download_rate_limit(int bytes_per_second); + TORRENT_DEPRECATED + void set_upload_rate_limit(int bytes_per_second); + TORRENT_DEPRECATED + void set_download_rate_limit(int bytes_per_second); + TORRENT_DEPRECATED + void set_max_uploads(int limit); + TORRENT_DEPRECATED + void set_max_connections(int limit); + TORRENT_DEPRECATED + void set_max_half_open_connections(int limit); + + TORRENT_DEPRECATED + int max_connections() const; + TORRENT_DEPRECATED + int max_uploads() const; + + TORRENT_DEPRECATED + std::auto_ptr pop_alert(); + TORRENT_DEPRECATED + void pop_alerts(std::deque* alerts); + +#endif + + // 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. The session still owns these alerts and they will stay + // valid until the next time ``pop_alerts`` is called. 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 NULL. + // + // 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 + // ``session_settings::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, regardelss of the alert mask. + // + // To control which alerts are posted, set the alert_mask + // (settings_pack::alert_mask). + // + // 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. + void pop_alerts(std::vector* alerts); + alert* wait_for_alert(time_duration max_wait); + void set_alert_notify(boost::function const& fun); + +#ifndef TORRENT_NO_DEPRECATE + TORRENT_DEPRECATED + void set_severity_level(alert::severity_t s); + + // use the setting instead + TORRENT_DEPRECATED + size_t set_alert_queue_size_limit(size_t queue_size_limit_); + + // 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. + // + // ``get_alert_mask()`` returns the current mask; + // + // See category_t enum for options. + TORRENT_DEPRECATED + void set_alert_mask(boost::uint32_t m); + TORRENT_DEPRECATED + boost::uint32_t get_alert_mask() const; + + // 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 block. + // + // 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. + TORRENT_DEPRECATED + void set_alert_dispatch( + boost::function)> const& fun); + + // 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. + // + // deprecated. use settings_pack::enable_lsd instead + TORRENT_DEPRECATED + void start_lsd(); + TORRENT_DEPRECATED + void stop_lsd(); + + // 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_. + // + // deprecated. use settings_pack::enable_upnp instead + TORRENT_DEPRECATED + void start_upnp(); + TORRENT_DEPRECATED + void stop_upnp(); + + // 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_. + // + // deprecated. use settings_pack::enable_natpmp instead + TORRENT_DEPRECATED + void start_natpmp(); + TORRENT_DEPRECATED + void stop_natpmp(); +#endif + + // protocols used by add_port_mapping() + enum protocol_type { udp = 1, tcp = 2 }; + + // 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. + int add_port_mapping(protocol_type t, int external_port, int local_port); + void delete_port_mapping(int handle); + + // 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. + aux::session_impl* native_handle() const + { return m_impl; } + + private: + aux::session_impl* m_impl; + }; + +} // namespace libtorrent + +#endif // TORRENT_SESSION_HANDLE_HPP_INCLUDED diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 3d63bddf3..351e56c9e 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -240,6 +240,7 @@ namespace libtorrent friend class invariant_access; friend struct aux::session_impl; friend class session; + friend struct session_handle; friend struct feed; friend class torrent; friend std::size_t hash_value(torrent_handle const& th); diff --git a/src/Makefile.am b/src/Makefile.am index b1d8fe78c..f1568076c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,6 +109,7 @@ libtorrent_rasterbar_la_SOURCES = \ rss.cpp \ session.cpp \ session_call.cpp \ + session_handle.cpp \ session_impl.cpp \ session_settings.cpp \ settings_pack.cpp \ diff --git a/src/session.cpp b/src/session.cpp index 328beba4b..a4ebd2fa0 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -58,6 +58,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/hasher.hpp" #include "libtorrent/entry.hpp" #include "libtorrent/session.hpp" +#include "libtorrent/session_handle.hpp" #include "libtorrent/fingerprint.hpp" #include "libtorrent/entry.hpp" #include "libtorrent/alert_types.hpp" @@ -338,42 +339,6 @@ namespace libtorrent #define TORRENT_ASYNC_CALL(x) \ m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl.get())) -#define TORRENT_ASYNC_CALL1(x, a1) \ - m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl.get(), a1)) - -#define TORRENT_ASYNC_CALL2(x, a1, a2) \ - m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl.get(), a1, a2)) - -#define TORRENT_ASYNC_CALL3(x, a1, a2, a3) \ - m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl.get(), a1, a2, a3)) - -#define TORRENT_SYNC_CALL(x) \ - aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get()))) - -#define TORRENT_SYNC_CALL1(x, a1) \ - aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1))) - -#define TORRENT_SYNC_CALL2(x, a1, a2) \ - aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1, a2))) - -#define TORRENT_SYNC_CALL3(x, a1, a2, a3) \ - aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1, a2, a3))) - -#define TORRENT_SYNC_CALL4(x, a1, a2, a3, a4) \ - aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1, a2, a3, a4))) - -#define TORRENT_SYNC_CALL_RET(type, x) \ - aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get()))) - -#define TORRENT_SYNC_CALL_RET1(type, x, a1) \ - aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1))) - -#define TORRENT_SYNC_CALL_RET2(type, x, a1, a2) \ - aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1, a2))) - -#define TORRENT_SYNC_CALL_RET3(type, x, a1, a2, a3) \ - aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl.get(), a1, a2, a3))) - #ifndef TORRENT_CFG #error TORRENT_CFG is not defined! #endif @@ -408,6 +373,7 @@ namespace libtorrent } m_impl = boost::make_shared(boost::ref(*ios)); + *static_cast(this) = session_handle(m_impl.get()); #ifndef TORRENT_DISABLE_EXTENSIONS if (flags & add_default_plugins) @@ -439,847 +405,6 @@ namespace libtorrent m_thread->join(); } - void session::save_state(entry& e, boost::uint32_t flags) const - { - TORRENT_SYNC_CALL2(save_state, &e, flags); - } - - void session::load_state(bdecode_node const& e) - { - // this needs to be synchronized since the lifespan - // of e is tied to the caller - TORRENT_SYNC_CALL1(load_state, &e); - } - -#ifndef TORRENT_NO_DEPRECATE - feed_handle session::add_feed(feed_settings const& feed) - { - // if you have auto-download enabled, you must specify a download directory! - TORRENT_ASSERT_PRECOND(!feed.auto_download || !feed.add_args.save_path.empty()); - return TORRENT_SYNC_CALL_RET1(feed_handle, add_feed, feed); - } - - void session::remove_feed(feed_handle h) - { - TORRENT_ASYNC_CALL1(remove_feed, h); - } - - void session::get_feeds(std::vector& f) const - { - f.clear(); - TORRENT_SYNC_CALL1(get_feeds, &f); - } -#endif - - void session::set_load_function(user_load_function_t fun) - { - TORRENT_ASYNC_CALL1(set_load_function, fun); - } - - void session::add_extension(boost::function(torrent*, void*)> ext) - { -#ifndef TORRENT_DISABLE_EXTENSIONS - TORRENT_ASYNC_CALL1(add_extension, ext); -#endif - } - - void session::add_extension(boost::shared_ptr ext) - { -#ifndef TORRENT_DISABLE_EXTENSIONS - TORRENT_ASYNC_CALL1(add_ses_extension, ext); -#endif - } - -#ifndef TORRENT_NO_DEPRECATE - void session::load_asnum_db(char const*) {} - void session::load_country_db(char const*) {} - - int session::as_for_ip(address const&) - { return 0; } - -#if TORRENT_USE_WSTRING - void session::load_asnum_db(wchar_t const*) {} - void session::load_country_db(wchar_t const*) {} -#endif // TORRENT_USE_WSTRING - - void session::load_state(entry const& ses_state) - { - if (ses_state.type() == entry::undefined_t) return; - std::vector buf; - bencode(std::back_inserter(buf), ses_state); - bdecode_node e; - error_code ec; -#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || !defined BOOST_NO_EXCEPTIONS - int ret = -#endif - bdecode(&buf[0], &buf[0] + buf.size(), e, ec); - - TORRENT_ASSERT(ret == 0); -#ifndef BOOST_NO_EXCEPTIONS - if (ret != 0) throw libtorrent_exception(ec); -#endif - TORRENT_SYNC_CALL1(load_state, &e); - } - - void session::load_state(lazy_entry const& ses_state) - { - if (ses_state.type() == lazy_entry::none_t) return; - std::pair buf = ses_state.data_section(); - bdecode_node e; - error_code ec; -#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || !defined BOOST_NO_EXCEPTIONS - int ret = -#endif - bdecode(buf.first, buf.first + buf.second, e, ec); - - TORRENT_ASSERT(ret == 0); -#ifndef BOOST_NO_EXCEPTIONS - if (ret != 0) throw libtorrent_exception(ec); -#endif - TORRENT_SYNC_CALL1(load_state, &e); - } - - entry session::state() const - { - entry ret; - TORRENT_SYNC_CALL2(save_state, &ret, 0xffffffff); - return ret; - } -#endif // TORRENT_NO_DEPRECATE - - void session::set_ip_filter(ip_filter const& f) - { - boost::shared_ptr copy = boost::make_shared(f); - TORRENT_ASYNC_CALL1(set_ip_filter, copy); - } - - ip_filter session::get_ip_filter() const - { - return TORRENT_SYNC_CALL_RET(ip_filter, get_ip_filter); - } - - void session::set_port_filter(port_filter const& f) - { - TORRENT_ASYNC_CALL1(set_port_filter, f); - } - -#ifndef TORRENT_NO_DEPRECATE - void session::set_peer_id(peer_id const& id) - { - settings_pack p; - p.set_str(settings_pack::peer_fingerprint, id.to_string()); - apply_settings(p); - } -#endif - - peer_id session::id() const - { - return TORRENT_SYNC_CALL_RET(peer_id, get_peer_id); - } - - io_service& session::get_io_service() - { - return m_impl->get_io_service(); - } - - void session::set_key(int key) - { - TORRENT_ASYNC_CALL1(set_key, key); - } - - void session::get_torrent_status(std::vector* ret - , boost::function const& pred - , boost::uint32_t flags) const - { - TORRENT_SYNC_CALL3(get_torrent_status, ret, boost::ref(pred), flags); - } - - void session::refresh_torrent_status(std::vector* ret - , boost::uint32_t flags) const - { - TORRENT_SYNC_CALL2(refresh_torrent_status, ret, flags); - } - - void session::post_torrent_updates(boost::uint32_t flags) - { - TORRENT_ASYNC_CALL1(post_torrent_updates, flags); - } - - void session::post_session_stats() - { - TORRENT_ASYNC_CALL(post_session_stats); - } - - void session::post_dht_stats() - { - TORRENT_ASYNC_CALL(post_dht_stats); - } - - std::vector session::get_torrents() const - { - return TORRENT_SYNC_CALL_RET(std::vector, get_torrents); - } - - torrent_handle session::find_torrent(sha1_hash const& info_hash) const - { - return TORRENT_SYNC_CALL_RET1(torrent_handle, find_torrent_handle, info_hash); - } - -#ifndef BOOST_NO_EXCEPTIONS - torrent_handle session::add_torrent(add_torrent_params const& params) - { - error_code ec; - torrent_handle r = TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, boost::ref(ec)); - if (ec) throw libtorrent_exception(ec); - return r; - } -#endif - - torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec) - { - ec.clear(); - return TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, boost::ref(ec)); - } - - void session::async_add_torrent(add_torrent_params const& params) - { - add_torrent_params* p = new add_torrent_params(params); -#ifndef TORRENT_NO_DEPRECATE - if (params.tracker_url) - { - p->trackers.push_back(params.tracker_url); - p->tracker_url = NULL; - } -#endif - TORRENT_ASYNC_CALL1(async_add_torrent, p); - } - -#ifndef BOOST_NO_EXCEPTIONS -#ifndef TORRENT_NO_DEPRECATE - // if the torrent already exists, this will throw duplicate_torrent - torrent_handle session::add_torrent( - torrent_info const& ti - , std::string const& save_path - , entry const& resume_data - , storage_mode_t storage_mode - , bool paused - , storage_constructor_type sc) - { - boost::shared_ptr tip(boost::make_shared(ti)); - add_torrent_params p(sc); - p.ti = tip; - p.save_path = save_path; - if (resume_data.type() != entry::undefined_t) - { - bencode(std::back_inserter(p.resume_data), resume_data); - } - p.storage_mode = storage_mode; - p.paused = paused; - return add_torrent(p); - } - - torrent_handle session::add_torrent( - char const* tracker_url - , sha1_hash const& info_hash - , char const* name - , std::string const& save_path - , entry const& resume_data - , storage_mode_t storage_mode - , bool paused - , storage_constructor_type sc - , void* userdata) - { - add_torrent_params p(sc); - p.tracker_url = tracker_url; - p.info_hash = info_hash; - p.save_path = save_path; - p.storage_mode = storage_mode; - p.paused = paused; - p.userdata = userdata; - p.name = name; - if (resume_data.type() != entry::undefined_t) - { - bencode(std::back_inserter(p.resume_data), resume_data); - } - return add_torrent(p); - } -#endif // TORRENT_NO_DEPRECATE -#endif // BOOST_NO_EXCEPTIONS - - void session::remove_torrent(const torrent_handle& h, int options) - { - if (!h.is_valid()) -#ifdef BOOST_NO_EXCEPTIONS - return; -#else - throw_invalid_handle(); -#endif - TORRENT_ASYNC_CALL2(remove_torrent, h, options); - } - -#ifndef TORRENT_NO_DEPRECATE - void session::listen_on( - std::pair const& port_range - , error_code& ec - , const char* net_interface, int flags) - { - settings_pack p; - std::string interfaces_str; - if (net_interface == NULL || strlen(net_interface) == 0) - net_interface = "0.0.0.0"; - - interfaces_str = print_endpoint(tcp::endpoint(address::from_string(net_interface, ec), port_range.first)); - if (ec) return; - - p.set_str(settings_pack::listen_interfaces, interfaces_str); - p.set_int(settings_pack::max_retry_port_bind, port_range.second - port_range.first); - p.set_bool(settings_pack::listen_system_port_fallback, (flags & session::listen_no_system_port) == 0); - apply_settings(p); - } - - void session::use_interfaces(char const* interfaces) - { - settings_pack pack; - pack.set_str(settings_pack::outgoing_interfaces, interfaces); - apply_settings(pack); - } -#endif - - unsigned short session::listen_port() const - { - return TORRENT_SYNC_CALL_RET(unsigned short, listen_port); - } - - unsigned short session::ssl_listen_port() const - { - return TORRENT_SYNC_CALL_RET(unsigned short, ssl_listen_port); - } - - void session::pause() - { - TORRENT_ASYNC_CALL(pause); - } - - void session::resume() - { - TORRENT_ASYNC_CALL(resume); - } - - bool session::is_paused() const - { - return TORRENT_SYNC_CALL_RET(bool, is_paused); - } - -#ifndef TORRENT_NO_DEPRECATE - session_status session::status() const - { - return TORRENT_SYNC_CALL_RET(session_status, status); - } - - void session::get_cache_info(sha1_hash const& ih - , std::vector& ret) const - { - cache_status st; - get_cache_info(&st, find_torrent(ih)); - ret.swap(st.pieces); - } - - cache_status session::get_cache_status() const - { - cache_status st; - get_cache_info(&st); - return st; - } -#endif - - void session::get_cache_info(cache_status* ret - , torrent_handle h, int flags) const - { - piece_manager* st = 0; - boost::shared_ptr t = h.m_torrent.lock(); - if (t) - { - if (t->has_storage()) - st = &t->storage(); - else - flags = session::disk_cache_no_pieces; - } - m_impl->disk_thread().get_cache_info(ret, flags & session::disk_cache_no_pieces, st); - } - -#ifndef TORRENT_NO_DEPRECATE - void session::start_dht() - { - settings_pack p; - p.set_bool(settings_pack::enable_dht, true); - apply_settings(p); - } - - void session::stop_dht() - { - settings_pack p; - p.set_bool(settings_pack::enable_dht, false); - apply_settings(p); - } -#endif - - void session::set_dht_settings(dht_settings const& settings) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL1(set_dht_settings, settings); -#endif - } - - dht_settings session::get_dht_settings() const - { -#ifndef TORRENT_DISABLE_DHT - return TORRENT_SYNC_CALL_RET(dht_settings, get_dht_settings); -#else - return dht_settings(); -#endif - } - - -#ifndef TORRENT_NO_DEPRECATE - void session::start_dht(entry const& startup_state) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL1(start_dht, startup_state); -#endif - } - - entry session::dht_state() const - { -#ifndef TORRENT_DISABLE_DHT - return TORRENT_SYNC_CALL_RET(entry, dht_state); -#else - return entry(); -#endif - } -#endif // TORRENT_NO_DEPRECATE - - void session::add_dht_node(std::pair const& node) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL1(add_dht_node_name, node); -#endif - } - - void session::add_dht_router(std::pair const& node) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL1(add_dht_router, node); -#endif - } - - bool session::is_dht_running() const - { -#ifndef TORRENT_DISABLE_DHT - return TORRENT_SYNC_CALL_RET(bool, is_dht_running); -#else - return false; -#endif - } - - void session::dht_get_item(sha1_hash const& target) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL1(dht_get_immutable_item, target); -#endif - } - - void session::dht_get_item(boost::array key - , std::string salt) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL2(dht_get_mutable_item, key, salt); -#endif - } - - sha1_hash session::dht_put_item(entry data) - { - std::vector buf; - bencode(std::back_inserter(buf), data); - sha1_hash ret = hasher(&buf[0], buf.size()).final(); - -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL2(dht_put_item, data, ret); -#endif - return ret; - } - - void session::dht_put_item(boost::array key - , boost::function& - , boost::uint64_t&, std::string const&)> cb - , std::string salt) - { -#ifndef TORRENT_DISABLE_DHT - TORRENT_ASYNC_CALL3(dht_put_mutable_item, key, cb, salt); -#endif - } - -#ifndef TORRENT_NO_DEPRECATE - void session::set_pe_settings(pe_settings const& r) - { - settings_pack pack; - pack.set_bool(settings_pack::prefer_rc4, r.prefer_rc4); - pack.set_int(settings_pack::out_enc_policy, r.out_enc_policy); - pack.set_int(settings_pack::in_enc_policy, r.in_enc_policy); - pack.set_int(settings_pack::allowed_enc_level, r.allowed_enc_level); - - apply_settings(pack); - } - - pe_settings session::get_pe_settings() const - { - settings_pack sett = get_settings(); - - pe_settings r; - r.prefer_rc4 = sett.get_bool(settings_pack::prefer_rc4); - r.out_enc_policy = sett.get_int(settings_pack::out_enc_policy); - r.in_enc_policy = sett.get_int(settings_pack::in_enc_policy); - r.allowed_enc_level = sett.get_int(settings_pack::allowed_enc_level); - return r; - } -#endif // TORRENT_NO_DEPRECATE - - void session::set_peer_class_filter(ip_filter const& f) - { - TORRENT_ASYNC_CALL1(set_peer_class_filter, f); - } - - void session::set_peer_class_type_filter(peer_class_type_filter const& f) - { - TORRENT_ASYNC_CALL1(set_peer_class_type_filter, f); - } - - int session::create_peer_class(char const* name) - { - return TORRENT_SYNC_CALL_RET1(int, create_peer_class, name); - } - - void session::delete_peer_class(int cid) - { - TORRENT_ASYNC_CALL1(delete_peer_class, cid); - } - - peer_class_info session::get_peer_class(int cid) - { - return TORRENT_SYNC_CALL_RET1(peer_class_info, get_peer_class, cid); - } - - void session::set_peer_class(int cid, peer_class_info const& pci) - { - TORRENT_ASYNC_CALL2(set_peer_class, cid, pci); - } - - bool session::is_listening() const - { - return TORRENT_SYNC_CALL_RET(bool, is_listening); - } - -#ifndef TORRENT_NO_DEPRECATE - void session::set_settings(session_settings const& s) - { - TORRENT_ASYNC_CALL1(set_settings, s); - } - - session_settings session::settings() const - { - return TORRENT_SYNC_CALL_RET(session_settings, deprecated_settings); - } -#endif - - void session::apply_settings(settings_pack const& s) - { - boost::shared_ptr copy = boost::make_shared(s); - TORRENT_ASYNC_CALL1(apply_settings_pack, copy); - } - - settings_pack session::get_settings() const - { - return TORRENT_SYNC_CALL_RET(settings_pack, get_settings); - } - -#ifndef TORRENT_NO_DEPRECATE - - void session::set_proxy(proxy_settings const& s) - { - settings_pack pack; - pack.set_str(settings_pack::proxy_hostname, s.hostname); - pack.set_str(settings_pack::proxy_username, s.username); - pack.set_str(settings_pack::proxy_password, s.password); - pack.set_int(settings_pack::proxy_type, s.type); - pack.set_int(settings_pack::proxy_port, s.port); - pack.set_bool(settings_pack::proxy_hostnames,s.proxy_hostnames); - pack.set_bool(settings_pack::proxy_peer_connections, s.proxy_peer_connections); - - apply_settings(pack); - } - - proxy_settings session::proxy() const - { - settings_pack sett = get_settings(); - return proxy_settings(sett); - } - - void session::set_peer_proxy(proxy_settings const& s) - { - set_proxy(s); - } - - void session::set_web_seed_proxy(proxy_settings const& s) - { - set_proxy(s); - } - - void session::set_tracker_proxy(proxy_settings const& s) - { - set_proxy(s); - } - - proxy_settings session::peer_proxy() const - { - return proxy(); - } - - proxy_settings session::web_seed_proxy() const - { - return proxy(); - } - - proxy_settings session::tracker_proxy() const - { - return proxy(); - } - - void session::set_dht_proxy(proxy_settings const& s) - { - set_proxy(s); - } - - proxy_settings session::dht_proxy() const - { - return proxy(); - } - - void session::set_i2p_proxy(proxy_settings const& s) - { - settings_pack pack; - pack.set_str(settings_pack::i2p_hostname, s.hostname); - pack.set_int(settings_pack::i2p_port, s.port); - - apply_settings(pack); - } - - proxy_settings session::i2p_proxy() const - { - proxy_settings ret; - settings_pack sett = get_settings(); - ret.hostname = sett.get_str(settings_pack::i2p_hostname); - ret.port = sett.get_int(settings_pack::i2p_port); - return ret; - } - - void session::set_max_half_open_connections(int) {} - int session::max_half_open_connections() const { return 8; } - - int session::max_uploads() const - { - return TORRENT_SYNC_CALL_RET(int, max_uploads); - } - - void session::set_max_uploads(int limit) - { - TORRENT_ASYNC_CALL1(set_max_uploads, limit); - } - - int session::max_connections() const - { - return TORRENT_SYNC_CALL_RET(int, max_connections); - } - - void session::set_max_connections(int limit) - { - TORRENT_ASYNC_CALL1(set_max_connections, limit); - } - - int session::local_upload_rate_limit() const - { - return TORRENT_SYNC_CALL_RET(int, local_upload_rate_limit); - } - - int session::local_download_rate_limit() const - { - return TORRENT_SYNC_CALL_RET(int, local_download_rate_limit); - } - - int session::upload_rate_limit() const - { - return TORRENT_SYNC_CALL_RET(int, upload_rate_limit); - } - - int session::download_rate_limit() const - { - return TORRENT_SYNC_CALL_RET(int, download_rate_limit); - } - - void session::set_local_upload_rate_limit(int bytes_per_second) - { - TORRENT_ASYNC_CALL1(set_local_upload_rate_limit, bytes_per_second); - } - - void session::set_local_download_rate_limit(int bytes_per_second) - { - TORRENT_ASYNC_CALL1(set_local_download_rate_limit, bytes_per_second); - } - - void session::set_upload_rate_limit(int bytes_per_second) - { - TORRENT_ASYNC_CALL1(set_upload_rate_limit, bytes_per_second); - } - - void session::set_download_rate_limit(int bytes_per_second) - { - TORRENT_ASYNC_CALL1(set_download_rate_limit, bytes_per_second); - } - - int session::num_uploads() const - { - return TORRENT_SYNC_CALL_RET(int, num_uploads); - } - - int session::num_connections() const - { - return TORRENT_SYNC_CALL_RET(int, num_connections); - } - - void session::set_alert_dispatch(boost::function)> const& fun) - { - m_impl->alerts().set_dispatch_function(fun); - } -#endif // TORRENT_NO_DEPRECATE - - alert* session::wait_for_alert(time_duration max_wait) - { - return m_impl->wait_for_alert(max_wait); - } - - // the alerts are const, they may not be deleted by the client - void session::pop_alerts(std::vector* alerts) - { - m_impl->pop_alerts(alerts); - } - - void session::set_alert_notify(boost::function const& fun) - { - m_impl->alerts().set_notify_function(fun); - } - -#ifndef TORRENT_NO_DEPRECATE - void session::pop_alerts(std::deque* alerts) - { - m_impl->pop_alerts(alerts); - } - - std::auto_ptr session::pop_alert() - { - alert const* a = m_impl->pop_alert(); - if (a == NULL) return std::auto_ptr(); - return a->clone(); - } - - void session::set_alert_mask(boost::uint32_t m) - { - settings_pack p; - p.set_int(settings_pack::alert_mask, m); - apply_settings(p); - } - - boost::uint32_t session::get_alert_mask() const - { - return get_settings().get_int(settings_pack::alert_mask); - } - - size_t session::set_alert_queue_size_limit(size_t queue_size_limit_) - { - return TORRENT_SYNC_CALL_RET1(size_t, set_alert_queue_size_limit, queue_size_limit_); - } - - void session::set_severity_level(alert::severity_t s) - { - int m = 0; - switch (s) - { - case alert::debug: m = alert::all_categories; break; - case alert::info: m = alert::all_categories & ~(alert::debug_notification - | alert::progress_notification | alert::dht_notification); break; - case alert::warning: m = alert::all_categories & ~(alert::debug_notification - | alert::status_notification | alert::progress_notification - | alert::dht_notification); break; - case alert::critical: m = alert::error_notification | alert::storage_notification; break; - case alert::fatal: m = alert::error_notification; break; - default: break; - } - - settings_pack p; - p.set_int(settings_pack::alert_mask, m); - apply_settings(p); - } - - void session::start_lsd() - { - settings_pack p; - p.set_bool(settings_pack::enable_lsd, true); - apply_settings(p); - } - - void session::start_natpmp() - { - settings_pack p; - p.set_bool(settings_pack::enable_natpmp, true); - apply_settings(p); - } - - void session::start_upnp() - { - settings_pack p; - p.set_bool(settings_pack::enable_upnp, true); - apply_settings(p); - } - - void session::stop_lsd() - { - settings_pack p; - p.set_bool(settings_pack::enable_lsd, false); - apply_settings(p); - } - - void session::stop_natpmp() - { - settings_pack p; - p.set_bool(settings_pack::enable_natpmp, false); - apply_settings(p); - } - - void session::stop_upnp() - { - settings_pack p; - p.set_bool(settings_pack::enable_upnp, false); - apply_settings(p); - } -#endif // TORRENT_NO_DEPRECATED - - int session::add_port_mapping(protocol_type t, int external_port, int local_port) - { - return TORRENT_SYNC_CALL_RET3(int, add_port_mapping, int(t), external_port, local_port); - } - - void session::delete_port_mapping(int handle) - { - TORRENT_ASYNC_CALL1(delete_port_mapping, handle); - } - #ifndef TORRENT_NO_DEPRECATE session_settings::session_settings(std::string const& user_agent_) { diff --git a/src/session_handle.cpp b/src/session_handle.cpp new file mode 100644 index 000000000..37de60bb3 --- /dev/null +++ b/src/session_handle.cpp @@ -0,0 +1,918 @@ +/* + +Copyright (c) 2003-2015, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "libtorrent/session_handle.hpp" +#include "libtorrent/aux_/session_impl.hpp" +#include "libtorrent/aux_/session_call.hpp" +#include "libtorrent/torrent.hpp" +#include "libtorrent/lazy_entry.hpp" + +#define TORRENT_ASYNC_CALL(x) \ + m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl)) + +#define TORRENT_ASYNC_CALL1(x, a1) \ + m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl, a1)) + +#define TORRENT_ASYNC_CALL2(x, a1, a2) \ + m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl, a1, a2)) + +#define TORRENT_ASYNC_CALL3(x, a1, a2, a3) \ + m_impl->get_io_service().dispatch(boost::bind(&session_impl:: x, m_impl, a1, a2, a3)) + +#define TORRENT_SYNC_CALL(x) \ + aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl))) + +#define TORRENT_SYNC_CALL1(x, a1) \ + aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1))) + +#define TORRENT_SYNC_CALL2(x, a1, a2) \ + aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1, a2))) + +#define TORRENT_SYNC_CALL3(x, a1, a2, a3) \ + aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1, a2, a3))) + +#define TORRENT_SYNC_CALL4(x, a1, a2, a3, a4) \ + aux::sync_call(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1, a2, a3, a4))) + +#define TORRENT_SYNC_CALL_RET(type, x) \ + aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl))) + +#define TORRENT_SYNC_CALL_RET1(type, x, a1) \ + aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1))) + +#define TORRENT_SYNC_CALL_RET2(type, x, a1, a2) \ + aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1, a2))) + +#define TORRENT_SYNC_CALL_RET3(type, x, a1, a2, a3) \ + aux::sync_call_ret(*m_impl, boost::function(boost::bind(&session_impl:: x, m_impl, a1, a2, a3))) + +using libtorrent::aux::session_impl; + +namespace libtorrent +{ + void session_handle::save_state(entry& e, boost::uint32_t flags) const + { + TORRENT_SYNC_CALL2(save_state, &e, flags); + } + + void session_handle::load_state(bdecode_node const& e) + { + // this needs to be synchronized since the lifespan + // of e is tied to the caller + TORRENT_SYNC_CALL1(load_state, &e); + } + + void session_handle::get_torrent_status(std::vector* ret + , boost::function const& pred + , boost::uint32_t flags) const + { + TORRENT_SYNC_CALL3(get_torrent_status, ret, boost::ref(pred), flags); + } + + void session_handle::refresh_torrent_status(std::vector* ret + , boost::uint32_t flags) const + { + TORRENT_SYNC_CALL2(refresh_torrent_status, ret, flags); + } + + void session_handle::post_torrent_updates(boost::uint32_t flags) + { + TORRENT_ASYNC_CALL1(post_torrent_updates, flags); + } + + void session_handle::post_session_stats() + { + TORRENT_ASYNC_CALL(post_session_stats); + } + + void session_handle::post_dht_stats() + { + TORRENT_ASYNC_CALL(post_dht_stats); + } + + io_service& session_handle::get_io_service() + { + return m_impl->get_io_service(); + } + + torrent_handle session_handle::find_torrent(sha1_hash const& info_hash) const + { + return TORRENT_SYNC_CALL_RET1(torrent_handle, find_torrent_handle, info_hash); + } + + std::vector session_handle::get_torrents() const + { + return TORRENT_SYNC_CALL_RET(std::vector, get_torrents); + } + + #ifndef BOOST_NO_EXCEPTIONS + torrent_handle session_handle::add_torrent(add_torrent_params const& params) + { + error_code ec; + torrent_handle r = TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, boost::ref(ec)); + if (ec) throw libtorrent_exception(ec); + return r; + } +#endif + + torrent_handle session_handle::add_torrent(add_torrent_params const& params, error_code& ec) + { + ec.clear(); + return TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, boost::ref(ec)); + } + + void session_handle::async_add_torrent(add_torrent_params const& params) + { + add_torrent_params* p = new add_torrent_params(params); +#ifndef TORRENT_NO_DEPRECATE + if (params.tracker_url) + { + p->trackers.push_back(params.tracker_url); + p->tracker_url = NULL; + } +#endif + TORRENT_ASYNC_CALL1(async_add_torrent, p); + } + +#ifndef BOOST_NO_EXCEPTIONS +#ifndef TORRENT_NO_DEPRECATE + // if the torrent already exists, this will throw duplicate_torrent + torrent_handle session_handle::add_torrent( + torrent_info const& ti + , std::string const& save_path + , entry const& resume_data + , storage_mode_t storage_mode + , bool paused + , storage_constructor_type sc) + { + boost::shared_ptr tip(boost::make_shared(ti)); + add_torrent_params p(sc); + p.ti = tip; + p.save_path = save_path; + if (resume_data.type() != entry::undefined_t) + { + bencode(std::back_inserter(p.resume_data), resume_data); + } + p.storage_mode = storage_mode; + p.paused = paused; + return add_torrent(p); + } + + torrent_handle session_handle::add_torrent( + char const* tracker_url + , sha1_hash const& info_hash + , char const* name + , std::string const& save_path + , entry const& resume_data + , storage_mode_t storage_mode + , bool paused + , storage_constructor_type sc + , void* userdata) + { + add_torrent_params p(sc); + p.tracker_url = tracker_url; + p.info_hash = info_hash; + p.save_path = save_path; + p.storage_mode = storage_mode; + p.paused = paused; + p.userdata = userdata; + p.name = name; + if (resume_data.type() != entry::undefined_t) + { + bencode(std::back_inserter(p.resume_data), resume_data); + } + return add_torrent(p); + } +#endif // TORRENT_NO_DEPRECATE +#endif // BOOST_NO_EXCEPTIONS + + void session_handle::pause() + { + TORRENT_ASYNC_CALL(pause); + } + + void session_handle::resume() + { + TORRENT_ASYNC_CALL(resume); + } + + bool session_handle::is_paused() const + { + return TORRENT_SYNC_CALL_RET(bool, is_paused); + } + + void session_handle::set_load_function(user_load_function_t fun) + { + TORRENT_ASYNC_CALL1(set_load_function, fun); + } + +#ifndef TORRENT_NO_DEPRECATE + session_status session_handle::status() const + { + return TORRENT_SYNC_CALL_RET(session_status, status); + } + + void session_handle::get_cache_info(sha1_hash const& ih + , std::vector& ret) const + { + cache_status st; + get_cache_info(&st, find_torrent(ih)); + ret.swap(st.pieces); + } + + cache_status session_handle::get_cache_status() const + { + cache_status st; + get_cache_info(&st); + return st; + } +#endif + + void session_handle::get_cache_info(cache_status* ret + , torrent_handle h, int flags) const + { + piece_manager* st = 0; + boost::shared_ptr t = h.m_torrent.lock(); + if (t) + { + if (t->has_storage()) + st = &t->storage(); + else + flags = session::disk_cache_no_pieces; + } + m_impl->disk_thread().get_cache_info(ret, flags & session::disk_cache_no_pieces, st); + } + +#ifndef TORRENT_NO_DEPRECATE + feed_handle session_handle::add_feed(feed_settings const& feed) + { + // if you have auto-download enabled, you must specify a download directory! + TORRENT_ASSERT_PRECOND(!feed.auto_download || !feed.add_args.save_path.empty()); + return TORRENT_SYNC_CALL_RET1(feed_handle, add_feed, feed); + } + + void session_handle::remove_feed(feed_handle h) + { + TORRENT_ASYNC_CALL1(remove_feed, h); + } + + void session_handle::get_feeds(std::vector& f) const + { + f.clear(); + TORRENT_SYNC_CALL1(get_feeds, &f); + } + + void session_handle::start_dht() + { + settings_pack p; + p.set_bool(settings_pack::enable_dht, true); + apply_settings(p); + } + + void session_handle::stop_dht() + { + settings_pack p; + p.set_bool(settings_pack::enable_dht, false); + apply_settings(p); + } +#endif + + void session_handle::set_dht_settings(dht_settings const& settings) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL1(set_dht_settings, settings); +#endif + } + + dht_settings session_handle::get_dht_settings() const + { +#ifndef TORRENT_DISABLE_DHT + return TORRENT_SYNC_CALL_RET(dht_settings, get_dht_settings); +#else + return dht_settings(); +#endif + } + + bool session_handle::is_dht_running() const + { +#ifndef TORRENT_DISABLE_DHT + return TORRENT_SYNC_CALL_RET(bool, is_dht_running); +#else + return false; +#endif + } + + void session_handle::add_dht_node(std::pair const& node) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL1(add_dht_node_name, node); +#endif + } + + void session_handle::add_dht_router(std::pair const& node) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL1(add_dht_router, node); +#endif + } + + void session_handle::dht_get_item(sha1_hash const& target) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL1(dht_get_immutable_item, target); +#endif + } + + void session_handle::dht_get_item(boost::array key + , std::string salt) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL2(dht_get_mutable_item, key, salt); +#endif + } + + sha1_hash session_handle::dht_put_item(entry data) + { + std::vector buf; + bencode(std::back_inserter(buf), data); + sha1_hash ret = hasher(&buf[0], buf.size()).final(); + +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL2(dht_put_item, data, ret); +#endif + return ret; + } + + void session_handle::dht_put_item(boost::array key + , boost::function& + , boost::uint64_t&, std::string const&)> cb + , std::string salt) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL3(dht_put_mutable_item, key, cb, salt); +#endif + } + +#ifndef TORRENT_NO_DEPRECATE + entry session_handle::dht_state() const + { +#ifndef TORRENT_DISABLE_DHT + return TORRENT_SYNC_CALL_RET(entry, dht_state); +#else + return entry(); +#endif + } + + void session_handle::start_dht(entry const& startup_state) + { +#ifndef TORRENT_DISABLE_DHT + TORRENT_ASYNC_CALL1(start_dht, startup_state); +#endif + } +#endif // TORRENT_NO_DEPRECATE + + void session_handle::add_extension(boost::function(torrent*, void*)> ext) + { +#ifndef TORRENT_DISABLE_EXTENSIONS + TORRENT_ASYNC_CALL1(add_extension, ext); +#endif + } + + void session_handle::add_extension(boost::shared_ptr ext) + { +#ifndef TORRENT_DISABLE_EXTENSIONS + TORRENT_ASYNC_CALL1(add_ses_extension, ext); +#endif + } + +#ifndef TORRENT_NO_DEPRECATE + void session_handle::load_asnum_db(char const*) {} + void session_handle::load_country_db(char const*) {} + + int session_handle::as_for_ip(address const&) + { return 0; } + +#if TORRENT_USE_WSTRING + void session_handle::load_asnum_db(wchar_t const*) {} + void session_handle::load_country_db(wchar_t const*) {} +#endif // TORRENT_USE_WSTRING + + void session_handle::load_state(entry const& ses_state) + { + if (ses_state.type() == entry::undefined_t) return; + std::vector buf; + bencode(std::back_inserter(buf), ses_state); + bdecode_node e; + error_code ec; +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || !defined BOOST_NO_EXCEPTIONS + int ret = +#endif + bdecode(&buf[0], &buf[0] + buf.size(), e, ec); + + TORRENT_ASSERT(ret == 0); +#ifndef BOOST_NO_EXCEPTIONS + if (ret != 0) throw libtorrent_exception(ec); +#endif + TORRENT_SYNC_CALL1(load_state, &e); + } + + entry session_handle::state() const + { + entry ret; + TORRENT_SYNC_CALL2(save_state, &ret, 0xffffffff); + return ret; + } + + void session_handle::load_state(lazy_entry const& ses_state) + { + if (ses_state.type() == lazy_entry::none_t) return; + std::pair buf = ses_state.data_section(); + bdecode_node e; + error_code ec; +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS || !defined BOOST_NO_EXCEPTIONS + int ret = +#endif + bdecode(buf.first, buf.first + buf.second, e, ec); + + TORRENT_ASSERT(ret == 0); +#ifndef BOOST_NO_EXCEPTIONS + if (ret != 0) throw libtorrent_exception(ec); +#endif + TORRENT_SYNC_CALL1(load_state, &e); + } +#endif // TORRENT_NO_DEPRECATE + + void session_handle::set_ip_filter(ip_filter const& f) + { + boost::shared_ptr copy = boost::make_shared(f); + TORRENT_ASYNC_CALL1(set_ip_filter, copy); + } + + ip_filter session_handle::get_ip_filter() const + { + return TORRENT_SYNC_CALL_RET(ip_filter, get_ip_filter); + } + + void session_handle::set_port_filter(port_filter const& f) + { + TORRENT_ASYNC_CALL1(set_port_filter, f); + } + +#ifndef TORRENT_NO_DEPRECATE + void session_handle::set_peer_id(peer_id const& id) + { + settings_pack p; + p.set_str(settings_pack::peer_fingerprint, id.to_string()); + apply_settings(p); + } +#endif + + peer_id session_handle::id() const + { + return TORRENT_SYNC_CALL_RET(peer_id, get_peer_id); + } + + void session_handle::set_key(int key) + { + TORRENT_ASYNC_CALL1(set_key, key); + } + + unsigned short session_handle::listen_port() const + { + return TORRENT_SYNC_CALL_RET(unsigned short, listen_port); + } + + unsigned short session_handle::ssl_listen_port() const + { + return TORRENT_SYNC_CALL_RET(unsigned short, ssl_listen_port); + } + + bool session_handle::is_listening() const + { + return TORRENT_SYNC_CALL_RET(bool, is_listening); + } + + void session_handle::set_peer_class_filter(ip_filter const& f) + { + TORRENT_ASYNC_CALL1(set_peer_class_filter, f); + } + + void session_handle::set_peer_class_type_filter(peer_class_type_filter const& f) + { + TORRENT_ASYNC_CALL1(set_peer_class_type_filter, f); + } + + int session_handle::create_peer_class(char const* name) + { + return TORRENT_SYNC_CALL_RET1(int, create_peer_class, name); + } + + void session_handle::delete_peer_class(int cid) + { + TORRENT_ASYNC_CALL1(delete_peer_class, cid); + } + + peer_class_info session_handle::get_peer_class(int cid) + { + return TORRENT_SYNC_CALL_RET1(peer_class_info, get_peer_class, cid); + } + + void session_handle::set_peer_class(int cid, peer_class_info const& pci) + { + TORRENT_ASYNC_CALL2(set_peer_class, cid, pci); + } + +#ifndef TORRENT_NO_DEPRECATE + void session_handle::use_interfaces(char const* interfaces) + { + settings_pack pack; + pack.set_str(settings_pack::outgoing_interfaces, interfaces); + apply_settings(pack); + } + + void session_handle::listen_on( + std::pair const& port_range + , error_code& ec + , const char* net_interface, int flags) + { + settings_pack p; + std::string interfaces_str; + if (net_interface == NULL || strlen(net_interface) == 0) + net_interface = "0.0.0.0"; + + interfaces_str = print_endpoint(tcp::endpoint(address::from_string(net_interface, ec), port_range.first)); + if (ec) return; + + p.set_str(settings_pack::listen_interfaces, interfaces_str); + p.set_int(settings_pack::max_retry_port_bind, port_range.second - port_range.first); + p.set_bool(settings_pack::listen_system_port_fallback, (flags & session::listen_no_system_port) == 0); + apply_settings(p); + } +#endif + + void session_handle::remove_torrent(const torrent_handle& h, int options) + { + if (!h.is_valid()) +#ifdef BOOST_NO_EXCEPTIONS + return; +#else + throw_invalid_handle(); +#endif + TORRENT_ASYNC_CALL2(remove_torrent, h, options); + } + +#ifndef TORRENT_NO_DEPRECATE + void session_handle::set_settings(session_settings const& s) + { + TORRENT_ASYNC_CALL1(set_settings, s); + } + + session_settings session_handle::settings() const + { + return TORRENT_SYNC_CALL_RET(session_settings, deprecated_settings); + } + + void session_handle::set_pe_settings(pe_settings const& r) + { + settings_pack pack; + pack.set_bool(settings_pack::prefer_rc4, r.prefer_rc4); + pack.set_int(settings_pack::out_enc_policy, r.out_enc_policy); + pack.set_int(settings_pack::in_enc_policy, r.in_enc_policy); + pack.set_int(settings_pack::allowed_enc_level, r.allowed_enc_level); + + apply_settings(pack); + } + + pe_settings session_handle::get_pe_settings() const + { + settings_pack sett = get_settings(); + + pe_settings r; + r.prefer_rc4 = sett.get_bool(settings_pack::prefer_rc4); + r.out_enc_policy = sett.get_int(settings_pack::out_enc_policy); + r.in_enc_policy = sett.get_int(settings_pack::in_enc_policy); + r.allowed_enc_level = sett.get_int(settings_pack::allowed_enc_level); + return r; + } +#endif + + void session_handle::apply_settings(settings_pack const& s) + { + boost::shared_ptr copy = boost::make_shared(s); + TORRENT_ASYNC_CALL1(apply_settings_pack, copy); + } + + settings_pack session_handle::get_settings() const + { + return TORRENT_SYNC_CALL_RET(settings_pack, get_settings); + } + +#ifndef TORRENT_NO_DEPRECATE + void session_handle::set_i2p_proxy(proxy_settings const& s) + { + settings_pack pack; + pack.set_str(settings_pack::i2p_hostname, s.hostname); + pack.set_int(settings_pack::i2p_port, s.port); + + apply_settings(pack); + } + + proxy_settings session_handle::i2p_proxy() const + { + proxy_settings ret; + settings_pack sett = get_settings(); + ret.hostname = sett.get_str(settings_pack::i2p_hostname); + ret.port = sett.get_int(settings_pack::i2p_port); + return ret; + } + + void session_handle::set_proxy(proxy_settings const& s) + { + settings_pack pack; + pack.set_str(settings_pack::proxy_hostname, s.hostname); + pack.set_str(settings_pack::proxy_username, s.username); + pack.set_str(settings_pack::proxy_password, s.password); + pack.set_int(settings_pack::proxy_type, s.type); + pack.set_int(settings_pack::proxy_port, s.port); + pack.set_bool(settings_pack::proxy_hostnames,s.proxy_hostnames); + pack.set_bool(settings_pack::proxy_peer_connections, s.proxy_peer_connections); + + apply_settings(pack); + } + + proxy_settings session_handle::proxy() const + { + settings_pack sett = get_settings(); + return proxy_settings(sett); + } + + int session_handle::num_uploads() const + { + return TORRENT_SYNC_CALL_RET(int, num_uploads); + } + + int session_handle::num_connections() const + { + return TORRENT_SYNC_CALL_RET(int, num_connections); + } + + void session_handle::set_peer_proxy(proxy_settings const& s) + { + set_proxy(s); + } + + void session_handle::set_web_seed_proxy(proxy_settings const& s) + { + set_proxy(s); + } + + void session_handle::set_tracker_proxy(proxy_settings const& s) + { + set_proxy(s); + } + + proxy_settings session_handle::peer_proxy() const + { + return proxy(); + } + + proxy_settings session_handle::web_seed_proxy() const + { + return proxy(); + } + + proxy_settings session_handle::tracker_proxy() const + { + return proxy(); + } + + void session_handle::set_dht_proxy(proxy_settings const& s) + { + set_proxy(s); + } + + proxy_settings session_handle::dht_proxy() const + { + return proxy(); + } + + int session_handle::upload_rate_limit() const + { + return TORRENT_SYNC_CALL_RET(int, upload_rate_limit); + } + + int session_handle::download_rate_limit() const + { + return TORRENT_SYNC_CALL_RET(int, download_rate_limit); + } + + int session_handle::local_upload_rate_limit() const + { + return TORRENT_SYNC_CALL_RET(int, local_upload_rate_limit); + } + + int session_handle::local_download_rate_limit() const + { + return TORRENT_SYNC_CALL_RET(int, local_download_rate_limit); + } + + int session_handle::max_half_open_connections() const { return 8; } + + void session_handle::set_local_upload_rate_limit(int bytes_per_second) + { + TORRENT_ASYNC_CALL1(set_local_upload_rate_limit, bytes_per_second); + } + + void session_handle::set_local_download_rate_limit(int bytes_per_second) + { + TORRENT_ASYNC_CALL1(set_local_download_rate_limit, bytes_per_second); + } + + void session_handle::set_upload_rate_limit(int bytes_per_second) + { + TORRENT_ASYNC_CALL1(set_upload_rate_limit, bytes_per_second); + } + + void session_handle::set_download_rate_limit(int bytes_per_second) + { + TORRENT_ASYNC_CALL1(set_download_rate_limit, bytes_per_second); + } + + void session_handle::set_max_connections(int limit) + { + TORRENT_ASYNC_CALL1(set_max_connections, limit); + } + + void session_handle::set_max_uploads(int limit) + { + TORRENT_ASYNC_CALL1(set_max_uploads, limit); + } + + void session_handle::set_max_half_open_connections(int) {} + + int session_handle::max_uploads() const + { + return TORRENT_SYNC_CALL_RET(int, max_uploads); + } + + int session_handle::max_connections() const + { + return TORRENT_SYNC_CALL_RET(int, max_connections); + } + + std::auto_ptr session_handle::pop_alert() + { + alert const* a = m_impl->pop_alert(); + if (a == NULL) return std::auto_ptr(); + return a->clone(); + } + + void session_handle::pop_alerts(std::deque* alerts) + { + m_impl->pop_alerts(alerts); + } +#endif // TORRENT_NO_DEPRECATE + + // the alerts are const, they may not be deleted by the client + void session_handle::pop_alerts(std::vector* alerts) + { + m_impl->pop_alerts(alerts); + } + + alert* session_handle::wait_for_alert(time_duration max_wait) + { + return m_impl->wait_for_alert(max_wait); + } + + void session_handle::set_alert_notify(boost::function const& fun) + { + m_impl->alerts().set_notify_function(fun); + } + +#ifndef TORRENT_NO_DEPRECATE + void session_handle::set_severity_level(alert::severity_t s) + { + int m = 0; + switch (s) + { + case alert::debug: m = alert::all_categories; break; + case alert::info: m = alert::all_categories & ~(alert::debug_notification + | alert::progress_notification | alert::dht_notification); break; + case alert::warning: m = alert::all_categories & ~(alert::debug_notification + | alert::status_notification | alert::progress_notification + | alert::dht_notification); break; + case alert::critical: m = alert::error_notification | alert::storage_notification; break; + case alert::fatal: m = alert::error_notification; break; + default: break; + } + + settings_pack p; + p.set_int(settings_pack::alert_mask, m); + apply_settings(p); + } + + size_t session_handle::set_alert_queue_size_limit(size_t queue_size_limit_) + { + return TORRENT_SYNC_CALL_RET1(size_t, set_alert_queue_size_limit, queue_size_limit_); + } + + void session_handle::set_alert_mask(boost::uint32_t m) + { + settings_pack p; + p.set_int(settings_pack::alert_mask, m); + apply_settings(p); + } + + boost::uint32_t session_handle::get_alert_mask() const + { + return get_settings().get_int(settings_pack::alert_mask); + } + + void session_handle::set_alert_dispatch(boost::function)> const& fun) + { + m_impl->alerts().set_dispatch_function(fun); + } + + void session_handle::start_lsd() + { + settings_pack p; + p.set_bool(settings_pack::enable_lsd, true); + apply_settings(p); + } + + void session_handle::stop_lsd() + { + settings_pack p; + p.set_bool(settings_pack::enable_lsd, false); + apply_settings(p); + } + + void session_handle::start_upnp() + { + settings_pack p; + p.set_bool(settings_pack::enable_upnp, true); + apply_settings(p); + } + + void session_handle::stop_upnp() + { + settings_pack p; + p.set_bool(settings_pack::enable_upnp, false); + apply_settings(p); + } + + void session_handle::start_natpmp() + { + settings_pack p; + p.set_bool(settings_pack::enable_natpmp, true); + apply_settings(p); + } + + void session_handle::stop_natpmp() + { + settings_pack p; + p.set_bool(settings_pack::enable_natpmp, false); + apply_settings(p); + } +#endif // TORRENT_NO_DEPRECATED + + int session_handle::add_port_mapping(session::protocol_type t, int external_port, int local_port) + { + return TORRENT_SYNC_CALL_RET3(int, add_port_mapping, int(t), external_port, local_port); + } + + void session_handle::delete_port_mapping(int handle) + { + TORRENT_ASYNC_CALL1(delete_port_mapping, handle); + } + +} // namespace libtorrent