2006-10-11 16:02:21 +02:00
|
|
|
/*
|
|
|
|
|
|
|
|
Copyright (c) 2006, 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_IMPL_HPP_INCLUDED
|
|
|
|
#define TORRENT_SESSION_IMPL_HPP_INCLUDED
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/config.hpp"
|
|
|
|
#include "libtorrent/aux_/session_settings.hpp"
|
|
|
|
#include "libtorrent/aux_/session_interface.hpp"
|
2017-04-21 06:45:43 +02:00
|
|
|
#include "libtorrent/aux_/session_udp_sockets.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/linked_list.hpp"
|
|
|
|
#include "libtorrent/torrent_peer.hpp"
|
|
|
|
#include "libtorrent/torrent_peer_allocator.hpp"
|
|
|
|
#include "libtorrent/performance_counters.hpp" // for counters
|
2016-12-05 20:49:45 +01:00
|
|
|
#include "libtorrent/aux_/allocating_handler.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2015-04-18 04:33:39 +02:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2015-08-08 22:19:44 +02:00
|
|
|
#include "libtorrent/ssl_stream.hpp"
|
2006-10-11 16:02:21 +02:00
|
|
|
#endif
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/session.hpp" // for user_load_function_t
|
2013-01-02 00:12:16 +01:00
|
|
|
#include "libtorrent/ip_voter.hpp"
|
2006-10-11 16:02:21 +02:00
|
|
|
#include "libtorrent/entry.hpp"
|
|
|
|
#include "libtorrent/socket.hpp"
|
|
|
|
#include "libtorrent/peer_id.hpp"
|
|
|
|
#include "libtorrent/tracker_manager.hpp"
|
|
|
|
#include "libtorrent/debug.hpp"
|
|
|
|
#include "libtorrent/piece_block_progress.hpp"
|
|
|
|
#include "libtorrent/ip_filter.hpp"
|
2017-04-05 23:55:29 +02:00
|
|
|
#include "libtorrent/aux_/ip_notifier.hpp"
|
2006-10-11 16:02:21 +02:00
|
|
|
#include "libtorrent/session_status.hpp"
|
2009-11-26 06:45:43 +01:00
|
|
|
#include "libtorrent/add_torrent_params.hpp"
|
2006-10-11 16:02:21 +02:00
|
|
|
#include "libtorrent/stat.hpp"
|
2006-11-14 16:53:38 +01:00
|
|
|
#include "libtorrent/file_pool.hpp"
|
2007-01-10 16:02:25 +01:00
|
|
|
#include "libtorrent/bandwidth_manager.hpp"
|
2007-04-25 20:26:35 +02:00
|
|
|
#include "libtorrent/socket_type.hpp"
|
2007-06-10 22:46:09 +02:00
|
|
|
#include "libtorrent/disk_io_thread.hpp"
|
2009-05-03 22:21:24 +02:00
|
|
|
#include "libtorrent/udp_socket.hpp"
|
2007-09-10 08:12:41 +02:00
|
|
|
#include "libtorrent/assert.hpp"
|
2013-04-09 04:38:11 +02:00
|
|
|
#include "libtorrent/alert_manager.hpp" // for alert_manager
|
2009-09-16 05:46:36 +02:00
|
|
|
#include "libtorrent/deadline_timer.hpp"
|
2009-09-20 17:21:31 +02:00
|
|
|
#include "libtorrent/socket_io.hpp" // for print_address
|
2009-11-23 09:38:50 +01:00
|
|
|
#include "libtorrent/address.hpp"
|
2010-11-29 02:33:05 +01:00
|
|
|
#include "libtorrent/utp_socket_manager.hpp"
|
2010-12-24 02:31:41 +01:00
|
|
|
#include "libtorrent/bloom_filter.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/peer_class.hpp"
|
|
|
|
#include "libtorrent/disk_io_job.hpp" // block_cache_reference
|
|
|
|
#include "libtorrent/peer_class_type_filter.hpp"
|
2012-04-30 08:30:35 +02:00
|
|
|
#include "libtorrent/kademlia/dht_observer.hpp"
|
2016-09-17 15:42:04 +02:00
|
|
|
#include "libtorrent/kademlia/dht_state.hpp"
|
2014-07-06 21:18:00 +02:00
|
|
|
#include "libtorrent/resolver.hpp"
|
2015-06-05 08:31:52 +02:00
|
|
|
#include "libtorrent/invariant_check.hpp"
|
2016-08-12 02:32:14 +02:00
|
|
|
#include "libtorrent/extensions.hpp"
|
2016-09-16 15:53:17 +02:00
|
|
|
#include "libtorrent/aux_/portmap.hpp"
|
2016-09-16 18:21:41 +02:00
|
|
|
#include "libtorrent/aux_/lsd.hpp"
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2016-09-21 08:49:23 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
#include "libtorrent/session_settings.hpp"
|
|
|
|
#endif
|
|
|
|
|
2010-03-03 08:42:51 +01:00
|
|
|
#if TORRENT_COMPLETE_TYPES_REQUIRED
|
|
|
|
#include "libtorrent/peer_connection.hpp"
|
|
|
|
#endif
|
|
|
|
|
2016-09-01 21:04:58 +02:00
|
|
|
#include <algorithm>
|
|
|
|
#include <vector>
|
|
|
|
#include <set>
|
|
|
|
#include <list>
|
|
|
|
#include <deque>
|
|
|
|
#include <condition_variable>
|
|
|
|
#include <mutex>
|
|
|
|
#include <cstdarg> // for va_start, va_end
|
|
|
|
#include <unordered_map>
|
|
|
|
|
2017-04-12 19:00:57 +02:00
|
|
|
namespace libtorrent {
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2011-01-29 11:37:21 +01:00
|
|
|
struct plugin;
|
2016-05-01 08:01:31 +02:00
|
|
|
struct upnp;
|
2016-05-01 08:21:30 +02:00
|
|
|
struct natpmp;
|
2008-12-26 08:00:21 +01:00
|
|
|
class lsd;
|
2009-04-04 09:55:34 +02:00
|
|
|
class torrent;
|
2009-05-03 22:21:24 +02:00
|
|
|
class alert;
|
2014-07-06 21:18:00 +02:00
|
|
|
struct cache_info;
|
2015-07-25 18:39:25 +02:00
|
|
|
struct torrent_handle;
|
2008-12-26 08:00:21 +01:00
|
|
|
|
2017-04-12 19:00:57 +02:00
|
|
|
namespace dht {
|
|
|
|
|
2009-04-30 19:30:14 +02:00
|
|
|
struct dht_tracker;
|
2014-02-24 01:31:13 +01:00
|
|
|
class item;
|
2009-11-11 06:22:57 +01:00
|
|
|
}
|
2007-06-10 22:46:09 +02:00
|
|
|
|
2017-04-21 06:45:43 +02:00
|
|
|
struct listen_socket_t final : aux::session_listen_socket
|
2011-09-12 05:51:49 +02:00
|
|
|
{
|
2017-04-21 06:45:43 +02:00
|
|
|
address get_external_address() override
|
|
|
|
{ return external_address.external_address(); }
|
|
|
|
|
|
|
|
tcp::endpoint get_local_endpoint() override
|
|
|
|
{ return local_endpoint; }
|
|
|
|
|
2016-02-07 08:09:19 +01:00
|
|
|
listen_socket_t()
|
|
|
|
{
|
|
|
|
tcp_port_mapping[0] = -1;
|
|
|
|
tcp_port_mapping[1] = -1;
|
2016-04-24 21:26:28 +02:00
|
|
|
udp_port_mapping[0] = -1;
|
|
|
|
udp_port_mapping[1] = -1;
|
2016-02-07 08:09:19 +01:00
|
|
|
}
|
2011-09-12 05:51:49 +02:00
|
|
|
|
2016-12-04 21:58:51 +01:00
|
|
|
// this may be empty but can be set
|
|
|
|
// to the WAN IP address of a NAT router
|
|
|
|
ip_voter external_address;
|
2011-09-12 05:51:49 +02:00
|
|
|
|
2016-04-24 21:26:28 +02:00
|
|
|
// this is a cached local endpoint for the listen TCP socket
|
2016-02-07 08:09:19 +01:00
|
|
|
tcp::endpoint local_endpoint;
|
|
|
|
|
2016-11-20 04:48:24 +01:00
|
|
|
// the name of the device the socket is bound to, may be empty
|
|
|
|
// if the socket is not bound to a device
|
|
|
|
std::string device;
|
|
|
|
|
2016-11-21 02:06:52 +01:00
|
|
|
// this is the port that was originally specified to listen on
|
|
|
|
// it may be different from local_endpoint.port() if we could
|
|
|
|
// had to retry binding with a higher port
|
2016-12-29 15:55:58 +01:00
|
|
|
int original_port = 0;
|
2016-11-21 02:06:52 +01:00
|
|
|
|
2011-09-12 05:51:49 +02:00
|
|
|
// this is typically set to the same as the local
|
|
|
|
// listen port. In case a NAT port forward was
|
|
|
|
// successfully opened, this will be set to the
|
|
|
|
// port that is open on the external (NAT) interface
|
|
|
|
// on the NAT box itself. This is the port that has
|
|
|
|
// to be published to peers, since this is the port
|
|
|
|
// the client is reachable through.
|
2016-12-29 15:55:58 +01:00
|
|
|
int tcp_external_port = 0;
|
|
|
|
int udp_external_port = 0;
|
2016-02-07 08:09:19 +01:00
|
|
|
|
|
|
|
// 0 is natpmp 1 is upnp
|
|
|
|
int tcp_port_mapping[2];
|
2016-04-24 21:26:28 +02:00
|
|
|
int udp_port_mapping[2];
|
2011-09-12 05:51:49 +02:00
|
|
|
|
2012-01-14 17:04:25 +01:00
|
|
|
// set to true if this is an SSL listen socket
|
2016-12-29 15:55:58 +01:00
|
|
|
bool ssl = false;
|
2012-01-14 17:04:25 +01:00
|
|
|
|
2016-04-24 21:26:28 +02:00
|
|
|
// the actual sockets (TCP listen socket and UDP socket)
|
|
|
|
// An entry does not necessarily have a UDP or TCP socket. One of these
|
2016-06-20 17:32:06 +02:00
|
|
|
// pointers may be nullptr!
|
2016-04-30 19:50:42 +02:00
|
|
|
// These must be shared_ptr to avoid a dangling reference if an
|
|
|
|
// incoming packet is in the event queue when the socket is erased
|
2016-08-31 18:45:45 +02:00
|
|
|
std::shared_ptr<tcp::acceptor> sock;
|
2017-04-21 06:45:43 +02:00
|
|
|
std::shared_ptr<aux::session_udp_socket> udp_sock;
|
2011-09-12 05:51:49 +02:00
|
|
|
};
|
|
|
|
|
2017-04-12 19:00:57 +02:00
|
|
|
namespace aux {
|
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
struct session_impl;
|
2014-07-06 21:18:00 +02:00
|
|
|
struct session_settings;
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2015-04-17 03:15:33 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2006-11-15 22:39:58 +01:00
|
|
|
struct tracker_logger;
|
|
|
|
#endif
|
|
|
|
|
2016-09-17 15:42:04 +02:00
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
|
|
|
TORRENT_EXTRA_EXPORT dht_settings read_dht_settings(bdecode_node const& e);
|
|
|
|
TORRENT_EXTRA_EXPORT entry save_dht_settings(dht_settings const& settings);
|
|
|
|
#endif
|
2010-12-26 09:03:02 +01:00
|
|
|
|
2016-11-21 02:06:52 +01:00
|
|
|
struct TORRENT_EXTRA_EXPORT listen_endpoint_t
|
|
|
|
{
|
|
|
|
listen_endpoint_t(address adr, int p, std::string dev, bool s)
|
|
|
|
: addr(adr), port(p), device(dev), ssl(s) {}
|
|
|
|
|
|
|
|
address addr;
|
|
|
|
int port;
|
|
|
|
std::string device;
|
|
|
|
bool ssl;
|
|
|
|
};
|
|
|
|
|
|
|
|
// partitions sockets based on whether they match one of the given endpoints
|
|
|
|
// all matched sockets are ordered before unmatched sockets
|
|
|
|
// matched endpoints are removed from the vector
|
|
|
|
// returns an iterator to the first unmatched socket
|
|
|
|
TORRENT_EXTRA_EXPORT std::list<listen_socket_t>::iterator
|
|
|
|
partition_listen_sockets(
|
|
|
|
std::vector<listen_endpoint_t>& eps
|
|
|
|
, std::list<listen_socket_t>& sockets);
|
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
// this is the link between the main thread and the
|
|
|
|
// thread started to run the main downloader loop
|
2016-04-30 17:05:54 +02:00
|
|
|
struct TORRENT_EXTRA_EXPORT session_impl final
|
2014-07-06 21:18:00 +02:00
|
|
|
: session_interface
|
2012-04-30 08:30:35 +02:00
|
|
|
, dht::dht_observer
|
2016-09-16 15:53:17 +02:00
|
|
|
, aux::portmap_callback
|
2016-09-16 18:21:41 +02:00
|
|
|
, aux::lsd_callback
|
2012-04-30 07:39:35 +02:00
|
|
|
, boost::noncopyable
|
2014-07-06 21:18:00 +02:00
|
|
|
, single_threaded
|
2016-09-25 15:50:48 +02:00
|
|
|
, aux::error_handler_interface
|
2006-10-11 16:02:21 +02:00
|
|
|
{
|
2007-09-29 18:14:03 +02:00
|
|
|
// the size of each allocation that is chained in the send buffer
|
2014-07-06 21:18:00 +02:00
|
|
|
enum { send_buffer_size_impl = 128 };
|
2016-06-18 04:02:21 +02:00
|
|
|
// plugin feature-index key map
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
plugins_all_idx = 0, // to store all plugins
|
|
|
|
plugins_optimistic_unchoke_idx = 1, // optimistic_unchoke_feature
|
|
|
|
plugins_tick_idx = 2, // tick_feature
|
|
|
|
plugins_dht_request_idx = 3 // dht_request_feature
|
|
|
|
};
|
2007-09-29 18:14:03 +02:00
|
|
|
|
2016-10-06 06:08:14 +02:00
|
|
|
template <typename Fun, typename... Args>
|
|
|
|
void wrap(Fun f, Args&&... a);
|
|
|
|
|
2015-06-05 08:31:52 +02:00
|
|
|
#if TORRENT_USE_INVARIANT_CHECKS
|
2015-06-03 06:33:20 +02:00
|
|
|
friend class libtorrent::invariant_access;
|
2015-06-05 08:31:52 +02:00
|
|
|
#endif
|
2016-09-01 03:42:18 +02:00
|
|
|
typedef std::set<std::shared_ptr<peer_connection>> connection_map;
|
2016-08-31 14:27:36 +02:00
|
|
|
typedef std::unordered_map<sha1_hash, std::shared_ptr<torrent>> torrent_map;
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2016-10-08 20:07:11 +02:00
|
|
|
explicit session_impl(io_service& ios);
|
2012-06-30 17:30:38 +02:00
|
|
|
virtual ~session_impl();
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-09-28 19:28:43 +02:00
|
|
|
void start_session(settings_pack pack);
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void init_peer_class_filter(bool unlimited_local);
|
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
2016-08-12 02:32:14 +02:00
|
|
|
using ext_function_t
|
2016-08-17 20:30:24 +02:00
|
|
|
= std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>;
|
2016-08-12 02:32:14 +02:00
|
|
|
|
|
|
|
struct session_plugin_wrapper : plugin
|
|
|
|
{
|
|
|
|
explicit session_plugin_wrapper(ext_function_t const& f) : m_f(f) {}
|
|
|
|
|
2016-08-17 20:30:24 +02:00
|
|
|
std::shared_ptr<torrent_plugin> new_torrent(torrent_handle const& t, void* user) override
|
2016-08-12 02:32:14 +02:00
|
|
|
{ return m_f(t, user); }
|
|
|
|
ext_function_t m_f;
|
|
|
|
};
|
|
|
|
|
2016-08-17 20:30:24 +02:00
|
|
|
void add_extension(std::function<std::shared_ptr<torrent_plugin>(
|
2015-07-25 18:39:25 +02:00
|
|
|
torrent_handle const&, void*)> ext);
|
2016-08-17 20:30:24 +02:00
|
|
|
void add_ses_extension(std::shared_ptr<plugin> ext);
|
2008-01-07 02:10:46 +01:00
|
|
|
#endif
|
2014-01-19 20:45:50 +01:00
|
|
|
#if TORRENT_USE_ASSERTS
|
2016-04-30 17:05:54 +02:00
|
|
|
bool has_peer(peer_connection const* p) const override;
|
|
|
|
bool any_torrent_has_peer(peer_connection const* p) const override;
|
|
|
|
bool is_single_thread() const override { return single_threaded::is_single_thread(); }
|
|
|
|
bool is_posting_torrent_updates() const override { return m_posting_torrent_updates; }
|
2012-10-06 16:31:14 +02:00
|
|
|
// this is set while the session is building the
|
|
|
|
// torrent status update message
|
2016-08-30 02:29:27 +02:00
|
|
|
bool m_posting_torrent_updates = false;
|
2017-03-25 23:00:23 +01:00
|
|
|
bool verify_queue_position(torrent const* t, int pos) override;
|
2006-11-14 01:08:16 +01:00
|
|
|
#endif
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-09-25 15:50:48 +02:00
|
|
|
void on_exception(std::exception const& e) override;
|
|
|
|
void on_error(error_code const& ec) override;
|
|
|
|
|
2016-11-07 13:40:09 +01:00
|
|
|
void on_ip_change(error_code const& ec);
|
2016-02-09 00:15:47 +01:00
|
|
|
void reopen_listen_sockets();
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
torrent_peer_allocator_interface* get_peer_allocator() override
|
2015-10-17 16:02:37 +02:00
|
|
|
{ return &m_peer_allocator; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
io_service& get_io_service() override { return m_io_service; }
|
|
|
|
resolver_interface& get_resolver() override { return m_host_resolver; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2017-01-13 07:55:29 +01:00
|
|
|
aux::vector<torrent*>& torrent_list(int i) override
|
2014-07-06 21:18:00 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT(i >= 0);
|
|
|
|
TORRENT_ASSERT(i < session_interface::num_torrent_lists);
|
|
|
|
return m_torrent_lists[i];
|
|
|
|
}
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2012-11-03 04:50:12 +01:00
|
|
|
// prioritize this torrent to be allocated some connection
|
|
|
|
// attempts, because this torrent needs more peers.
|
|
|
|
// this is typically done when a torrent starts out and
|
|
|
|
// need the initial push to connect peers
|
2016-08-31 14:27:36 +02:00
|
|
|
void prioritize_connections(std::weak_ptr<torrent> t) override;
|
2012-11-03 04:50:12 +01:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
tcp::endpoint get_ipv6_interface() const override;
|
|
|
|
tcp::endpoint get_ipv4_interface() const override;
|
2007-09-22 18:27:29 +02:00
|
|
|
|
2016-08-31 18:45:45 +02:00
|
|
|
void async_accept(std::shared_ptr<tcp::acceptor> const& listener, bool ssl);
|
|
|
|
void on_accept_connection(std::shared_ptr<socket_type> const& s
|
|
|
|
, std::weak_ptr<tcp::acceptor> listener, error_code const& e, bool ssl);
|
2009-04-09 03:04:49 +02:00
|
|
|
|
2016-08-31 18:45:45 +02:00
|
|
|
void incoming_connection(std::shared_ptr<socket_type> const& s);
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2016-08-31 14:27:36 +02:00
|
|
|
std::weak_ptr<torrent> find_torrent(sha1_hash const& info_hash) const override;
|
2016-02-20 21:49:49 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
//deprecated in 1.2
|
2016-10-25 14:02:34 +02:00
|
|
|
|
|
|
|
TORRENT_DEPRECATED
|
|
|
|
void set_load_function(user_load_function_t fun)
|
|
|
|
{ m_user_load_torrent = fun; }
|
|
|
|
|
|
|
|
TORRENT_DEPRECATED
|
2016-08-31 14:27:36 +02:00
|
|
|
std::weak_ptr<torrent> find_torrent(std::string const& uuid) const;
|
2016-02-20 21:49:49 +01:00
|
|
|
#endif
|
2015-03-21 01:12:40 +01:00
|
|
|
#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS
|
2016-08-31 14:27:36 +02:00
|
|
|
std::vector<std::shared_ptr<torrent>> find_collection(
|
2016-04-30 17:05:54 +02:00
|
|
|
std::string const& collection) const override;
|
2015-03-21 01:12:40 +01:00
|
|
|
#endif
|
2016-08-31 14:27:36 +02:00
|
|
|
std::weak_ptr<torrent> find_disconnect_candidate_torrent() const override;
|
2016-04-30 17:05:54 +02:00
|
|
|
int num_torrents() const override { return int(m_torrents.size()); }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-08-31 14:27:36 +02:00
|
|
|
void insert_torrent(sha1_hash const& ih, std::shared_ptr<torrent> const& t
|
2016-04-30 17:05:54 +02:00
|
|
|
, std::string uuid) override;
|
2016-02-20 21:49:49 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
//deprecated in 1.2
|
2016-10-25 14:02:34 +02:00
|
|
|
TORRENT_DEPRECATED
|
2016-08-31 14:27:36 +02:00
|
|
|
void insert_uuid_torrent(std::string uuid, std::shared_ptr<torrent> const& t) override
|
2014-07-06 21:18:00 +02:00
|
|
|
{ m_uuids.insert(std::make_pair(uuid, t)); }
|
2016-02-20 21:49:49 +01:00
|
|
|
#endif
|
2016-08-31 14:27:36 +02:00
|
|
|
std::shared_ptr<torrent> delay_load_torrent(sha1_hash const& info_hash
|
2016-04-30 17:05:54 +02:00
|
|
|
, peer_connection* pc) override;
|
|
|
|
void set_queue_position(torrent* t, int p) override;
|
2011-01-18 04:41:54 +01:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
peer_id const& get_peer_id() const override { return m_peer_id; }
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2017-03-07 19:50:03 +01:00
|
|
|
void close_connection(peer_connection* p) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-09-01 03:42:18 +02:00
|
|
|
void apply_settings_pack(std::shared_ptr<settings_pack> pack) override;
|
2016-06-23 23:54:31 +02:00
|
|
|
void apply_settings_pack_impl(settings_pack const& pack
|
|
|
|
, bool const init = false);
|
2016-04-30 17:05:54 +02:00
|
|
|
session_settings const& settings() const override { return m_settings; }
|
2015-06-07 06:23:30 +02:00
|
|
|
settings_pack get_settings() const;
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2015-05-19 05:13:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
2016-04-30 17:05:54 +02:00
|
|
|
dht::dht_tracker* dht() override { return m_dht.get(); }
|
|
|
|
bool announce_dht() const override { return !m_listen_sockets.empty(); }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2010-07-14 06:16:38 +02:00
|
|
|
void add_dht_node_name(std::pair<std::string, int> const& node);
|
2016-09-09 21:02:20 +02:00
|
|
|
void add_dht_node(udp::endpoint const& n) override;
|
2006-10-11 16:02:21 +02:00
|
|
|
void add_dht_router(std::pair<std::string, int> const& node);
|
|
|
|
void set_dht_settings(dht_settings const& s);
|
2007-03-15 23:03:56 +01:00
|
|
|
dht_settings const& get_dht_settings() const { return m_dht_settings; }
|
2016-09-29 14:25:51 +02:00
|
|
|
void set_dht_state(dht::dht_state state);
|
2015-09-27 01:00:36 +02:00
|
|
|
void set_dht_storage(dht::dht_storage_constructor_type sc);
|
2010-03-04 17:42:39 +01:00
|
|
|
void start_dht();
|
2006-10-11 16:02:21 +02:00
|
|
|
void stop_dht();
|
2016-04-30 17:05:54 +02:00
|
|
|
bool has_dht() const override;
|
2009-01-23 17:40:00 +01:00
|
|
|
|
2012-11-03 04:50:12 +01:00
|
|
|
// this is called for torrents when they are started
|
|
|
|
// it will prioritize them for announcing to
|
|
|
|
// the DHT, to get the initial peers quickly
|
2016-08-31 14:27:36 +02:00
|
|
|
void prioritize_dht(std::weak_ptr<torrent> t) override;
|
2012-11-03 04:50:12 +01:00
|
|
|
|
2014-02-24 01:31:13 +01:00
|
|
|
void get_immutable_callback(sha1_hash target
|
|
|
|
, dht::item const& i);
|
2015-08-08 05:37:36 +02:00
|
|
|
void get_mutable_callback(dht::item const& i, bool);
|
2014-02-24 01:31:13 +01:00
|
|
|
|
|
|
|
void dht_get_immutable_item(sha1_hash const& target);
|
|
|
|
|
2016-05-01 05:10:47 +02:00
|
|
|
void dht_get_mutable_item(std::array<char, 32> key
|
2014-02-24 01:31:13 +01:00
|
|
|
, std::string salt = std::string());
|
|
|
|
|
2015-11-22 19:00:29 +01:00
|
|
|
void dht_put_immutable_item(entry const& data, sha1_hash target);
|
2014-02-24 01:31:13 +01:00
|
|
|
|
2016-05-01 05:10:47 +02:00
|
|
|
void dht_put_mutable_item(std::array<char, 32> key
|
2016-08-13 03:31:55 +02:00
|
|
|
, std::function<void(entry&, std::array<char,64>&
|
2016-11-27 14:46:53 +01:00
|
|
|
, std::int64_t&, std::string const&)> cb
|
2014-02-24 01:31:13 +01:00
|
|
|
, std::string salt = std::string());
|
|
|
|
|
2015-06-25 17:01:36 +02:00
|
|
|
void dht_get_peers(sha1_hash const& info_hash);
|
|
|
|
void dht_announce(sha1_hash const& info_hash, int port = 0, int flags = 0);
|
|
|
|
|
2017-02-19 05:02:23 +01:00
|
|
|
void dht_live_nodes(sha1_hash const& nid);
|
|
|
|
|
2017-02-22 23:40:14 +01:00
|
|
|
void dht_direct_request(udp::endpoint const& ep, entry& e
|
2016-08-30 19:28:46 +02:00
|
|
|
, void* userdata = nullptr);
|
2014-02-17 06:56:49 +01:00
|
|
|
|
2010-03-04 17:42:39 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2016-10-25 14:02:34 +02:00
|
|
|
TORRENT_DEPRECATED
|
2010-07-14 06:16:38 +02:00
|
|
|
entry dht_state() const;
|
2016-10-25 14:02:34 +02:00
|
|
|
TORRENT_DEPRECATED
|
2016-02-27 04:16:17 +01:00
|
|
|
void start_dht_deprecated(entry const& startup_state);
|
2010-03-04 17:42:39 +01:00
|
|
|
#endif
|
2010-02-14 02:39:55 +01:00
|
|
|
void on_dht_announce(error_code const& e);
|
2015-08-18 23:35:27 +02:00
|
|
|
void on_dht_name_lookup(error_code const& e
|
|
|
|
, std::vector<address> const& addresses, int port);
|
2010-02-14 08:46:57 +01:00
|
|
|
void on_dht_router_name_lookup(error_code const& e
|
2014-07-06 21:18:00 +02:00
|
|
|
, std::vector<address> const& addresses, int port);
|
2006-10-11 16:02:21 +02:00
|
|
|
#endif
|
2007-03-15 23:03:56 +01:00
|
|
|
|
2014-11-23 07:14:47 +01:00
|
|
|
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
2014-07-06 21:18:00 +02:00
|
|
|
torrent const* find_encrypted_torrent(
|
2016-04-30 17:05:54 +02:00
|
|
|
sha1_hash const& info_hash, sha1_hash const& xor_mask) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-08-31 14:27:36 +02:00
|
|
|
void add_obfuscated_hash(sha1_hash const& obfuscated, std::weak_ptr<torrent> const& t) override;
|
2007-06-06 02:41:20 +02:00
|
|
|
#endif
|
|
|
|
|
2010-02-05 09:23:17 +01:00
|
|
|
void on_lsd_announce(error_code const& e);
|
|
|
|
|
2007-03-15 23:03:56 +01:00
|
|
|
// called when a port mapping is successful, or a router returns
|
|
|
|
// a failure to map a port
|
2010-12-05 21:40:28 +01:00
|
|
|
void on_port_mapping(int mapping, address const& ip, int port
|
2016-09-18 16:11:56 +02:00
|
|
|
, portmap_protocol proto, error_code const& ec
|
2016-09-16 15:53:17 +02:00
|
|
|
, aux::portmap_transport transport) override;
|
2007-03-15 23:03:56 +01:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
bool is_aborted() const override { return m_abort; }
|
2016-06-03 13:32:48 +02:00
|
|
|
bool is_paused() const { return m_paused; }
|
2008-06-29 21:08:30 +02:00
|
|
|
|
|
|
|
void pause();
|
|
|
|
void resume();
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2016-09-01 03:42:18 +02:00
|
|
|
void set_ip_filter(std::shared_ptr<ip_filter> const& f);
|
2015-05-16 08:33:37 +02:00
|
|
|
ip_filter const& get_ip_filter();
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2007-06-01 03:05:57 +02:00
|
|
|
void set_port_filter(port_filter const& f);
|
2016-04-30 17:05:54 +02:00
|
|
|
port_filter const& get_port_filter() const override;
|
|
|
|
void ban_ip(address addr) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void queue_tracker_request(tracker_request& req
|
2016-08-31 14:27:36 +02:00
|
|
|
, std::weak_ptr<request_callback> c) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
// ==== peer class operations ====
|
|
|
|
|
|
|
|
// implements session_interface
|
2016-04-30 17:05:54 +02:00
|
|
|
void set_peer_classes(peer_class_set* s, address const& a, int st) override;
|
|
|
|
peer_class_pool const& peer_classes() const override { return m_classes; }
|
|
|
|
peer_class_pool& peer_classes() override { return m_classes; }
|
|
|
|
bool ignore_unchoke_slots_set(peer_class_set const& set) const override;
|
2014-07-06 21:18:00 +02:00
|
|
|
int copy_pertinent_channels(peer_class_set const& set
|
2016-04-30 17:05:54 +02:00
|
|
|
, int channel, bandwidth_channel** dst, int max) override;
|
|
|
|
int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) override;
|
2015-05-19 05:13:49 +02:00
|
|
|
bool use_quota_overhead(bandwidth_channel* ch, int amount);
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2017-01-22 04:40:19 +01:00
|
|
|
peer_class_t create_peer_class(char const* name);
|
2017-01-22 18:06:52 +01:00
|
|
|
void delete_peer_class(peer_class_t cid);
|
2014-07-06 21:18:00 +02:00
|
|
|
void set_peer_class_filter(ip_filter const& f);
|
|
|
|
ip_filter const& get_peer_class_filter() const;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void set_peer_class_type_filter(peer_class_type_filter f);
|
|
|
|
peer_class_type_filter get_peer_class_type_filter();
|
|
|
|
|
2017-01-22 18:06:52 +01:00
|
|
|
peer_class_info get_peer_class(peer_class_t cid);
|
|
|
|
void set_peer_class(peer_class_t cid, peer_class_info const& pci);
|
2006-10-11 16:02:21 +02:00
|
|
|
|
|
|
|
bool is_listening() const;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
|
|
|
void add_extensions_to_torrent(
|
2016-08-31 14:27:36 +02:00
|
|
|
std::shared_ptr<torrent> const& torrent_ptr, void* userdata);
|
2014-07-06 21:18:00 +02:00
|
|
|
#endif
|
|
|
|
|
2017-03-26 20:54:16 +02:00
|
|
|
torrent_handle add_torrent(add_torrent_params, error_code& ec);
|
2016-06-23 19:19:35 +02:00
|
|
|
// second return value is true if the torrent was added and false if an
|
|
|
|
// existing one was found.
|
2016-08-31 14:27:36 +02:00
|
|
|
std::pair<std::shared_ptr<torrent>, bool>
|
2016-06-23 19:19:35 +02:00
|
|
|
add_torrent_impl(add_torrent_params& p, error_code& ec);
|
2011-10-12 12:27:17 +02:00
|
|
|
void async_add_torrent(add_torrent_params* params);
|
2017-03-26 15:16:42 +02:00
|
|
|
|
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2016-11-02 06:01:04 +01:00
|
|
|
void on_async_load_torrent(add_torrent_params* params, error_code ec);
|
2017-03-26 15:16:42 +02:00
|
|
|
#endif
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void remove_torrent(torrent_handle const& h, int options) override;
|
2016-08-31 14:27:36 +02:00
|
|
|
void remove_torrent_impl(std::shared_ptr<torrent> tptr, int options) override;
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2011-02-01 10:48:28 +01:00
|
|
|
void get_torrent_status(std::vector<torrent_status>* ret
|
2016-08-13 03:31:55 +02:00
|
|
|
, std::function<bool(torrent_status const&)> const& pred
|
2016-06-18 20:01:38 +02:00
|
|
|
, std::uint32_t flags) const;
|
2011-02-01 10:48:28 +01:00
|
|
|
void refresh_torrent_status(std::vector<torrent_status>* ret
|
2016-06-18 20:01:38 +02:00
|
|
|
, std::uint32_t flags) const;
|
|
|
|
void post_torrent_updates(std::uint32_t flags);
|
2014-07-06 21:18:00 +02:00
|
|
|
void post_session_stats();
|
2015-01-17 18:02:58 +01:00
|
|
|
void post_dht_stats();
|
2011-02-01 10:48:28 +01:00
|
|
|
|
|
|
|
std::vector<torrent_handle> get_torrents() const;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2015-04-03 22:15:48 +02:00
|
|
|
void pop_alerts(std::vector<alert*>* alerts);
|
|
|
|
alert* wait_for_alert(time_duration max_wait);
|
2007-11-25 09:18:57 +01:00
|
|
|
|
2010-10-09 21:09:38 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2016-10-25 14:02:34 +02:00
|
|
|
TORRENT_DEPRECATED void pop_alerts();
|
|
|
|
TORRENT_DEPRECATED alert const* pop_alert();
|
2017-01-13 14:44:08 +01:00
|
|
|
TORRENT_DEPRECATED std::size_t set_alert_queue_size_limit(std::size_t queue_size_limit_);
|
2016-10-25 14:02:34 +02:00
|
|
|
TORRENT_DEPRECATED int upload_rate_limit_depr() const;
|
|
|
|
TORRENT_DEPRECATED int download_rate_limit_depr() const;
|
|
|
|
TORRENT_DEPRECATED int local_upload_rate_limit() const;
|
|
|
|
TORRENT_DEPRECATED int local_download_rate_limit() const;
|
|
|
|
|
|
|
|
TORRENT_DEPRECATED void set_local_download_rate_limit(int bytes_per_second);
|
|
|
|
TORRENT_DEPRECATED void set_local_upload_rate_limit(int bytes_per_second);
|
|
|
|
TORRENT_DEPRECATED void set_download_rate_limit_depr(int bytes_per_second);
|
|
|
|
TORRENT_DEPRECATED void set_upload_rate_limit_depr(int bytes_per_second);
|
|
|
|
TORRENT_DEPRECATED void set_max_connections(int limit);
|
|
|
|
TORRENT_DEPRECATED void set_max_uploads(int limit);
|
|
|
|
|
|
|
|
TORRENT_DEPRECATED int max_connections() const;
|
|
|
|
TORRENT_DEPRECATED int max_uploads() const;
|
2010-10-09 21:09:38 +02:00
|
|
|
#endif
|
2007-08-16 14:41:46 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
bandwidth_manager* get_bandwidth_manager(int channel) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
int upload_rate_limit(peer_class_t c) const;
|
|
|
|
int download_rate_limit(peer_class_t c) const;
|
|
|
|
void set_upload_rate_limit(peer_class_t c, int limit);
|
|
|
|
void set_download_rate_limit(peer_class_t c, int limit);
|
|
|
|
|
|
|
|
void set_rate_limit(peer_class_t c, int channel, int limit);
|
|
|
|
int rate_limit(peer_class_t c, int channel) const;
|
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
bool preemptive_unchoke() const override;
|
2017-03-18 05:58:06 +01:00
|
|
|
|
|
|
|
// deprecated, use stats counters ``num_peers_up_unchoked`` instead
|
2016-04-30 17:05:54 +02:00
|
|
|
int num_uploads() const override
|
2015-01-16 21:51:39 +01:00
|
|
|
{ return int(m_stats_counters[counters::num_peers_up_unchoked]); }
|
2017-03-18 05:58:06 +01:00
|
|
|
|
|
|
|
// deprecated, use stats counters ``num_peers_connected`` +
|
|
|
|
// ``num_peers_half_open`` instead.
|
2016-04-30 17:05:54 +02:00
|
|
|
int num_connections() const override { return int(m_connections.size()); }
|
2007-08-16 14:41:46 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
int peak_up_rate() const { return m_peak_up_rate; }
|
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void trigger_unchoke() override
|
2014-09-22 05:47:43 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT(is_single_thread());
|
|
|
|
m_unchoke_time_scaler = 0;
|
|
|
|
}
|
2016-04-30 17:05:54 +02:00
|
|
|
void trigger_optimistic_unchoke() override
|
2014-09-22 05:47:43 +02:00
|
|
|
{
|
|
|
|
TORRENT_ASSERT(is_single_thread());
|
|
|
|
m_optimistic_unchoke_time_scaler = 0;
|
|
|
|
}
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2015-01-04 22:31:02 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2006-10-11 16:02:21 +02:00
|
|
|
session_status status() const;
|
2015-01-04 22:31:02 +01:00
|
|
|
#endif
|
|
|
|
|
2016-12-31 18:35:10 +01:00
|
|
|
void get_cache_info(torrent_handle h, cache_status* ret, int flags) const;
|
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
void set_peer_id(peer_id const& id);
|
2017-02-23 05:28:25 +01:00
|
|
|
void set_key(std::uint32_t key);
|
2016-06-18 20:01:38 +02:00
|
|
|
std::uint16_t listen_port() const override;
|
2017-04-21 06:45:43 +02:00
|
|
|
std::uint16_t listen_port(listen_socket_t* sock) const;
|
2016-06-18 20:01:38 +02:00
|
|
|
std::uint16_t ssl_listen_port() const override;
|
2017-04-21 06:45:43 +02:00
|
|
|
std::uint16_t ssl_listen_port(listen_socket_t* sock) const;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
alert_manager& alerts() override { return m_alerts; }
|
|
|
|
disk_interface& disk_thread() override { return m_disk_thread; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
void abort();
|
2015-06-14 22:00:04 +02:00
|
|
|
void abort_stage2();
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
torrent_handle find_torrent_handle(sha1_hash const& info_hash);
|
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void announce_lsd(sha1_hash const& ih, int port, bool broadcast = false) override;
|
2007-04-25 20:26:35 +02:00
|
|
|
|
2016-06-18 20:01:38 +02:00
|
|
|
void save_state(entry* e, std::uint32_t flags) const;
|
|
|
|
void load_state(bdecode_node const* e, std::uint32_t flags);
|
2009-12-03 06:11:57 +01:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
bool has_connection(peer_connection* p) const override;
|
2016-09-01 03:42:18 +02:00
|
|
|
void insert_peer(std::shared_ptr<peer_connection> const& c) override;
|
2010-08-23 08:27:18 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
proxy_settings proxy() const override;
|
2007-04-25 20:26:35 +02:00
|
|
|
|
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
2016-06-20 17:32:06 +02:00
|
|
|
bool is_dht_running() const { return (m_dht.get() != nullptr); }
|
2016-04-30 17:05:54 +02:00
|
|
|
int external_udp_port() const override
|
2016-04-24 21:26:28 +02:00
|
|
|
{
|
2016-12-10 20:31:09 +01:00
|
|
|
for (auto const& s : m_listen_sockets)
|
2016-04-24 21:26:28 +02:00
|
|
|
{
|
2016-12-10 20:31:09 +01:00
|
|
|
if (s.udp_sock) return s.udp_external_port;
|
2016-04-24 21:26:28 +02:00
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2007-04-25 20:26:35 +02:00
|
|
|
#endif
|
|
|
|
|
2009-08-20 05:19:12 +02:00
|
|
|
#if TORRENT_USE_I2P
|
2016-04-30 17:05:54 +02:00
|
|
|
char const* i2p_session() const override { return m_i2p_conn.session_id(); }
|
|
|
|
proxy_settings i2p_proxy() const override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2009-08-20 05:19:12 +02:00
|
|
|
void on_i2p_open(error_code const& ec);
|
|
|
|
void open_new_incoming_i2p_connection();
|
2016-08-31 18:45:45 +02:00
|
|
|
void on_i2p_accept(std::shared_ptr<socket_type> const& s
|
2009-08-20 05:19:12 +02:00
|
|
|
, error_code const& e);
|
|
|
|
#endif
|
|
|
|
|
2007-05-31 02:21:54 +02:00
|
|
|
void start_lsd();
|
2010-07-14 06:16:38 +02:00
|
|
|
natpmp* start_natpmp();
|
|
|
|
upnp* start_upnp();
|
2007-05-31 02:21:54 +02:00
|
|
|
|
|
|
|
void stop_lsd();
|
|
|
|
void stop_natpmp();
|
|
|
|
void stop_upnp();
|
|
|
|
|
2013-12-31 23:24:56 +01:00
|
|
|
int add_port_mapping(int t, int external_port
|
|
|
|
, int local_port);
|
|
|
|
void delete_port_mapping(int handle);
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
int next_port() const;
|
2008-02-28 08:34:07 +01:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void deferred_submit_jobs() override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-12-29 02:47:18 +01:00
|
|
|
ses_buffer_holder allocate_buffer() override;
|
2014-07-06 21:18:00 +02:00
|
|
|
torrent_peer* allocate_peer_entry(int type);
|
|
|
|
void free_peer_entry(torrent_peer* p);
|
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void free_buffer(char* buf) override;
|
|
|
|
int send_buffer_size() const override { return send_buffer_size_impl; }
|
2008-04-10 12:03:23 +02:00
|
|
|
|
2012-04-30 08:30:35 +02:00
|
|
|
// implements dht_observer
|
2017-04-21 06:45:43 +02:00
|
|
|
virtual void set_external_address(aux::session_listen_socket* iface
|
|
|
|
, address const& ip, address const& source) override;
|
2016-04-30 17:05:54 +02:00
|
|
|
virtual void get_peers(sha1_hash const& ih) override;
|
|
|
|
virtual void announce(sha1_hash const& ih, address const& addr, int port) override;
|
2015-04-03 22:15:48 +02:00
|
|
|
virtual void outgoing_get_peers(sha1_hash const& target
|
2016-04-30 17:05:54 +02:00
|
|
|
, sha1_hash const& sent_target, udp::endpoint const& ep) override;
|
2016-05-18 07:54:37 +02:00
|
|
|
|
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-09 01:13:47 +02:00
|
|
|
virtual bool should_log(module_t m) const override;
|
|
|
|
virtual void log(module_t m, char const* fmt, ...)
|
2016-04-30 17:05:54 +02:00
|
|
|
override TORRENT_FORMAT(3,4);
|
2016-09-28 05:21:18 +02:00
|
|
|
virtual void log_packet(message_direction_t dir, span<char const> pkt
|
2016-09-16 03:13:43 +02:00
|
|
|
, udp::endpoint const& node) override;
|
2016-09-16 15:53:17 +02:00
|
|
|
|
|
|
|
virtual bool should_log_portmap(aux::portmap_transport transport) const override;
|
|
|
|
virtual void log_portmap(aux::portmap_transport transport, char const* msg)
|
|
|
|
const override;
|
2016-09-16 18:21:41 +02:00
|
|
|
|
|
|
|
virtual bool should_log_lsd() const override;
|
|
|
|
virtual void log_lsd(char const* msg) const override;
|
2016-05-18 07:54:37 +02:00
|
|
|
#endif
|
2013-02-05 05:18:44 +01:00
|
|
|
|
2016-08-15 22:17:13 +02:00
|
|
|
virtual bool on_dht_request(string_view query
|
2016-04-30 17:05:54 +02:00
|
|
|
, dht::msg const& request, entry& response) override;
|
2014-02-17 06:56:49 +01:00
|
|
|
|
2013-02-05 05:18:44 +01:00
|
|
|
void set_external_address(address const& ip
|
2016-04-30 17:05:54 +02:00
|
|
|
, int source_type, address const& source) override;
|
2017-04-21 06:45:43 +02:00
|
|
|
void set_external_address(tcp::endpoint const& local_endpoint
|
|
|
|
, address const& ip
|
|
|
|
, int source_type, address const& source) override;
|
2016-12-04 21:58:51 +01:00
|
|
|
virtual external_ip external_address() const override;
|
2011-02-13 23:27:02 +01:00
|
|
|
|
2010-07-14 06:16:38 +02:00
|
|
|
// used when posting synchronous function
|
|
|
|
// calls to session_impl and torrent objects
|
2016-05-01 00:54:23 +02:00
|
|
|
mutable std::mutex mut;
|
|
|
|
mutable std::condition_variable cond;
|
2010-07-14 06:16:38 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// implements session_interface
|
|
|
|
virtual tcp::endpoint bind_outgoing_socket(socket_type& s, address
|
2016-04-30 17:05:54 +02:00
|
|
|
const& remote_address, error_code& ec) const override;
|
2014-07-06 21:18:00 +02:00
|
|
|
virtual bool verify_bound_address(address const& addr, bool utp
|
2016-04-30 17:05:54 +02:00
|
|
|
, error_code& ec) override;
|
2012-01-20 07:07:19 +01:00
|
|
|
|
2016-06-20 17:32:06 +02:00
|
|
|
bool has_lsd() const override { return m_lsd.get() != nullptr; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
std::vector<block_info>& block_info_storage() override { return m_block_info_storage; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
libtorrent::utp_socket_manager* utp_socket_manager() override
|
2015-12-14 01:44:42 +01:00
|
|
|
{ return &m_utp_socket_manager; }
|
2016-02-08 08:01:25 +01:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2016-04-30 17:05:54 +02:00
|
|
|
libtorrent::utp_socket_manager* ssl_utp_socket_manager() override
|
2016-02-08 08:01:25 +01:00
|
|
|
{ return &m_ssl_utp_socket_manager; }
|
|
|
|
#endif
|
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void inc_boost_connections() override { ++m_boost_connections; }
|
2011-11-15 07:47:02 +01:00
|
|
|
|
2015-06-03 06:33:20 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2016-02-08 08:01:25 +01:00
|
|
|
void update_ssl_listen();
|
|
|
|
void update_dht_upload_rate_limit();
|
|
|
|
void update_local_download_rate();
|
|
|
|
void update_local_upload_rate();
|
|
|
|
void update_rate_limit_utp();
|
|
|
|
void update_ignore_rate_limits_on_local_network();
|
2015-06-03 06:33:20 +02:00
|
|
|
#endif
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void update_proxy();
|
|
|
|
void update_i2p_bridge();
|
|
|
|
void update_peer_tos();
|
|
|
|
void update_user_agent();
|
2014-10-23 00:06:56 +02:00
|
|
|
void update_unchoke_limit();
|
2014-07-06 21:18:00 +02:00
|
|
|
void update_connection_speed();
|
|
|
|
void update_queued_disk_bytes();
|
|
|
|
void update_alert_queue_size();
|
|
|
|
void update_disk_threads();
|
|
|
|
void update_cache_buffer_chunk_size();
|
|
|
|
void update_report_web_seed_downloads();
|
|
|
|
void update_outgoing_interfaces();
|
|
|
|
void update_listen_interfaces();
|
|
|
|
void update_privileged_ports();
|
2014-09-24 02:02:00 +02:00
|
|
|
void update_auto_sequential();
|
2015-01-20 07:26:22 +01:00
|
|
|
void update_max_failcount();
|
2017-04-05 00:23:37 +02:00
|
|
|
void update_resolver_cache_timeout();
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void update_upnp();
|
|
|
|
void update_natpmp();
|
|
|
|
void update_lsd();
|
|
|
|
void update_dht();
|
2014-10-06 00:30:09 +02:00
|
|
|
void update_count_slow();
|
2014-12-31 16:51:45 +01:00
|
|
|
void update_peer_fingerprint();
|
2016-08-21 18:15:19 +02:00
|
|
|
void update_dht_bootstrap_nodes();
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
void update_socket_buffer_size();
|
|
|
|
void update_dht_announce_interval();
|
|
|
|
void update_anonymous_mode();
|
|
|
|
void update_force_proxy();
|
|
|
|
void update_download_rate();
|
|
|
|
void update_upload_rate();
|
|
|
|
void update_connections_limit();
|
|
|
|
void update_alert_mask();
|
2010-10-09 21:09:38 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void trigger_auto_manage() override;
|
2015-06-03 06:33:20 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2016-03-27 18:09:53 +02:00
|
|
|
// return the settings value for int setting "n", if the value is
|
|
|
|
// negative, return INT_MAX
|
|
|
|
int get_int_setting(int n) const;
|
|
|
|
|
2017-01-13 07:55:29 +01:00
|
|
|
aux::vector<torrent*> m_torrent_lists[num_torrent_lists];
|
2015-06-03 06:33:20 +02:00
|
|
|
|
|
|
|
peer_class_pool m_classes;
|
|
|
|
|
2016-09-01 03:42:18 +02:00
|
|
|
void init(std::shared_ptr<settings_pack> pack);
|
2017-03-23 13:32:56 +01:00
|
|
|
void init_dht();
|
2015-06-03 06:33:20 +02:00
|
|
|
|
|
|
|
void submit_disk_jobs();
|
|
|
|
|
|
|
|
void on_trigger_auto_manage();
|
|
|
|
|
2016-09-16 18:21:41 +02:00
|
|
|
void on_lsd_peer(tcp::endpoint const& peer, sha1_hash const& ih) override;
|
2016-04-30 17:05:54 +02:00
|
|
|
void setup_socket_buffers(socket_type& s) override;
|
2007-04-04 04:06:07 +02:00
|
|
|
|
2017-04-21 06:45:43 +02:00
|
|
|
void set_external_address(listen_socket_t& sock, address const& ip
|
|
|
|
, int const source_type, address const& source);
|
|
|
|
|
|
|
|
void interface_to_endpoints(std::string const& device, int const port
|
|
|
|
, bool const ssl, std::vector<listen_endpoint_t>& eps);
|
|
|
|
|
2011-03-07 01:36:51 +01:00
|
|
|
// the settings for the client
|
2014-07-06 21:18:00 +02:00
|
|
|
aux::session_settings m_settings;
|
2011-03-07 01:36:51 +01:00
|
|
|
|
2014-08-01 08:07:48 +02:00
|
|
|
counters m_stats_counters;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// this is a pool allocator for torrent_peer objects
|
|
|
|
torrent_peer_allocator m_peer_allocator;
|
2009-05-07 22:30:20 +02:00
|
|
|
|
|
|
|
// this vector is used to store the block_info
|
|
|
|
// objects pointed to by partial_piece_info returned
|
|
|
|
// by torrent::get_download_queue.
|
|
|
|
std::vector<block_info> m_block_info_storage;
|
2009-05-07 00:36:24 +02:00
|
|
|
|
2008-04-09 07:19:11 +02:00
|
|
|
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
|
2007-09-29 18:14:03 +02:00
|
|
|
// this pool is used to allocate and recycle send
|
|
|
|
// buffers from.
|
2016-08-30 02:29:27 +02:00
|
|
|
boost::pool<> m_send_buffers{send_buffer_size_impl};
|
2008-04-09 07:19:11 +02:00
|
|
|
#endif
|
2007-09-29 18:14:03 +02:00
|
|
|
|
2015-06-03 05:04:44 +02:00
|
|
|
io_service& m_io_service;
|
2008-02-08 11:22:05 +01:00
|
|
|
|
2010-10-12 10:57:43 +02:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2012-01-14 17:04:25 +01:00
|
|
|
// this is a generic SSL context used when talking to
|
|
|
|
// unauthenticated HTTPS servers
|
2015-08-08 22:19:44 +02:00
|
|
|
ssl::context m_ssl_ctx;
|
2010-10-12 10:57:43 +02:00
|
|
|
#endif
|
|
|
|
|
2009-05-23 23:36:09 +02:00
|
|
|
// handles delayed alerts
|
2014-12-09 10:08:26 +01:00
|
|
|
mutable alert_manager m_alerts;
|
2009-05-23 23:36:09 +02:00
|
|
|
|
2015-04-03 22:15:48 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
// the alert pointers stored in m_alerts
|
2017-02-08 16:54:55 +01:00
|
|
|
mutable aux::vector<alert*> m_alert_pointers;
|
2015-04-03 22:15:48 +02:00
|
|
|
|
|
|
|
// if not all the alerts in m_alert_pointers have been delivered to
|
|
|
|
// the client. This is the offset into m_alert_pointers where the next
|
|
|
|
// alert is. If this is greater than or equal to m_alert_pointers.size()
|
|
|
|
// it means we need to request new alerts from the main thread.
|
2016-08-30 02:29:27 +02:00
|
|
|
mutable int m_alert_pointer_pos = 0;
|
2015-04-03 22:15:48 +02:00
|
|
|
#endif
|
|
|
|
|
2007-10-10 00:17:16 +02:00
|
|
|
// handles disk io requests asynchronously
|
|
|
|
// peers have pointers into the disk buffer
|
|
|
|
// pool, and must be destructed before this
|
2007-10-31 10:48:20 +01:00
|
|
|
// object. The disk thread relies on the file
|
|
|
|
// pool object, and must be destructed before
|
2008-02-08 11:22:05 +01:00
|
|
|
// m_files. The disk io thread posts completion
|
|
|
|
// events to the io service, and needs to be
|
|
|
|
// constructed after it.
|
2007-10-10 00:17:16 +02:00
|
|
|
disk_io_thread m_disk_thread;
|
|
|
|
|
2007-01-10 16:02:25 +01:00
|
|
|
// the bandwidth manager is responsible for
|
|
|
|
// handing out bandwidth to connections that
|
|
|
|
// asks for it, it can also throttle the
|
|
|
|
// rate.
|
2009-09-16 06:41:35 +02:00
|
|
|
bandwidth_manager m_download_rate;
|
|
|
|
bandwidth_manager m_upload_rate;
|
2007-07-03 01:48:06 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// the peer class that all peers belong to by default
|
2017-01-22 04:40:19 +01:00
|
|
|
peer_class_t m_global_class{0};
|
2009-05-14 19:21:19 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// the peer class all TCP peers belong to by default
|
2010-11-29 02:33:05 +01:00
|
|
|
// all tcp peer connections are subject to these
|
2016-04-26 06:37:47 +02:00
|
|
|
// bandwidth limits. Local peers are exempted
|
2010-11-29 02:33:05 +01:00
|
|
|
// from this limit. The purpose is to be able to
|
|
|
|
// throttle TCP that passes over the internet
|
|
|
|
// bottleneck (i.e. modem) to avoid starving out
|
|
|
|
// uTP connections.
|
2017-01-22 04:40:19 +01:00
|
|
|
peer_class_t m_tcp_peer_class{0};
|
2011-01-30 11:04:15 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// peer class for local peers
|
2017-01-22 04:40:19 +01:00
|
|
|
peer_class_t m_local_peer_class{0};
|
2007-01-10 16:02:25 +01:00
|
|
|
|
2017-03-30 14:47:41 +02:00
|
|
|
resolver m_host_resolver;
|
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
tracker_manager m_tracker_manager;
|
|
|
|
torrent_map m_torrents;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2017-03-25 23:00:23 +01:00
|
|
|
// all torrents that are downloading or queued,
|
|
|
|
// ordered by their queue position
|
|
|
|
aux::vector<torrent*> m_download_queue;
|
|
|
|
|
2014-11-23 07:14:47 +01:00
|
|
|
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
2014-07-06 21:18:00 +02:00
|
|
|
// this maps obfuscated hashes to torrents. It's only
|
|
|
|
// used when encryption is enabled
|
|
|
|
torrent_map m_obfuscated_torrents;
|
|
|
|
#endif
|
|
|
|
|
2016-02-20 21:49:49 +01:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
//deprecated in 1.2
|
2016-08-31 14:27:36 +02:00
|
|
|
std::map<std::string, std::shared_ptr<torrent>> m_uuids;
|
2016-02-20 21:49:49 +01:00
|
|
|
#endif
|
2011-01-18 04:41:54 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// peer connections are put here when disconnected to avoid
|
|
|
|
// race conditions with the disk thread. It's important that
|
|
|
|
// peer connections are destructed from the network thread,
|
|
|
|
// once a peer is disconnected, it's put in this list and
|
|
|
|
// every second their refcount is checked, and if it's 1,
|
|
|
|
// they are deleted (from the network thread)
|
2016-09-01 03:42:18 +02:00
|
|
|
std::vector<std::shared_ptr<peer_connection>> m_undead_peers;
|
2010-01-17 22:42:14 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// keep the io_service alive until we have posted the job
|
|
|
|
// to clear the undead peers
|
2016-09-05 03:49:11 +02:00
|
|
|
std::unique_ptr<io_service::work> m_work;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
// this maps sockets to their peer_connection
|
|
|
|
// object. It is the complete list of all connected
|
|
|
|
// peers.
|
|
|
|
connection_map m_connections;
|
2013-08-21 17:55:24 +02:00
|
|
|
|
|
|
|
// this list holds incoming connections while they
|
|
|
|
// are performing SSL handshake. When we shut down
|
|
|
|
// the session, all of these are disconnected, otherwise
|
|
|
|
// they would linger and stall or hang session shutdown
|
2016-08-31 18:45:45 +02:00
|
|
|
std::set<std::shared_ptr<socket_type>> m_incoming_sockets;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// maps IP ranges to bitfields representing peer class IDs
|
|
|
|
// to assign peers matching a specific IP range based on its
|
|
|
|
// remote endpoint
|
|
|
|
ip_filter m_peer_class_filter;
|
|
|
|
|
|
|
|
// maps socket types to peer classes
|
|
|
|
peer_class_type_filter m_peer_class_type_filter;
|
2013-12-05 08:42:32 +01:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
// filters incoming connections
|
2016-09-01 03:42:18 +02:00
|
|
|
std::shared_ptr<ip_filter> m_ip_filter;
|
2007-06-01 03:05:57 +02:00
|
|
|
|
|
|
|
// filters outgoing connections
|
|
|
|
port_filter m_port_filter;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
// the peer id that is generated at the start of the session
|
|
|
|
peer_id m_peer_id;
|
|
|
|
|
|
|
|
// the key is an id that is used to identify the
|
|
|
|
// client with the tracker only. It is randomized
|
|
|
|
// at startup
|
2017-02-23 05:28:25 +01:00
|
|
|
std::uint32_t m_key = 0;
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2016-11-07 13:40:09 +01:00
|
|
|
// posts a notification when the set of local IPs changes
|
2017-04-05 16:42:40 +02:00
|
|
|
std::unique_ptr<ip_change_notifier> m_ip_notifier;
|
2016-11-07 13:40:09 +01:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// the addresses or device names of the interfaces we are supposed to
|
|
|
|
// listen on. if empty, it means that we should let the os decide
|
|
|
|
// which interface to listen on
|
2016-02-08 08:01:25 +01:00
|
|
|
std::vector<listen_interface_t> m_listen_interfaces;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
// the network interfaces outgoing connections are opened through. If
|
2016-01-26 18:21:25 +01:00
|
|
|
// there is more then one, they are used in a round-robin fashion
|
2014-07-06 21:18:00 +02:00
|
|
|
// each element is a device name or IP address (in string form) and
|
2016-01-26 18:21:25 +01:00
|
|
|
// a port number. The port determines which port to bind the listen
|
2014-07-06 21:18:00 +02:00
|
|
|
// socket to, and the device or IP determines which network adapter
|
|
|
|
// to be used. If no adapter with the specified name exists, the listen
|
|
|
|
// socket fails.
|
2016-02-09 00:15:47 +01:00
|
|
|
std::vector<std::string> m_outgoing_interfaces;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2007-09-22 18:27:29 +02:00
|
|
|
// since we might be listening on multiple interfaces
|
|
|
|
// we might need more than one listen socket
|
|
|
|
std::list<listen_socket_t> m_listen_sockets;
|
|
|
|
|
2013-11-26 03:00:02 +01:00
|
|
|
#if TORRENT_USE_I2P
|
|
|
|
i2p_connection m_i2p_conn;
|
2016-08-31 18:45:45 +02:00
|
|
|
std::shared_ptr<socket_type> m_i2p_listen_socket;
|
2013-11-26 03:00:02 +01:00
|
|
|
#endif
|
|
|
|
|
2012-01-14 17:04:25 +01:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2016-05-02 18:36:21 +02:00
|
|
|
ssl::context* ssl_ctx() override { return &m_ssl_ctx; }
|
2016-08-31 18:45:45 +02:00
|
|
|
void on_incoming_utp_ssl(std::shared_ptr<socket_type> const& s);
|
|
|
|
void ssl_handshake(error_code const& ec, std::shared_ptr<socket_type> s);
|
2012-01-14 17:04:25 +01:00
|
|
|
#endif
|
|
|
|
|
2016-02-09 00:15:47 +01:00
|
|
|
// round-robin index into m_outgoing_interfaces
|
2016-08-30 02:29:27 +02:00
|
|
|
mutable std::uint8_t m_interface_index = 0;
|
2009-04-09 03:04:49 +02:00
|
|
|
|
2014-10-22 00:08:48 +02:00
|
|
|
enum listen_on_flags_t
|
|
|
|
{
|
|
|
|
open_ssl_socket = 0x10
|
|
|
|
};
|
|
|
|
|
|
|
|
listen_socket_t setup_listener(std::string const& device
|
2016-02-07 08:09:19 +01:00
|
|
|
, tcp::endpoint bind_ep, int flags, error_code& ec);
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2015-05-19 05:13:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
2016-09-17 15:42:04 +02:00
|
|
|
dht::dht_state m_dht_state;
|
2010-03-04 17:42:39 +01:00
|
|
|
#endif
|
2008-06-29 21:08:30 +02:00
|
|
|
|
2007-08-16 14:41:46 +02:00
|
|
|
// this is initialized to the unchoke_interval
|
|
|
|
// session_setting and decreased every second.
|
|
|
|
// when it reaches zero, it is reset to the
|
|
|
|
// unchoke_interval and the unchoke set is
|
|
|
|
// recomputed.
|
2014-09-22 05:47:43 +02:00
|
|
|
// TODO: replace this by a proper asio timer
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_unchoke_time_scaler = 0;
|
2007-08-16 14:41:46 +02:00
|
|
|
|
2008-04-24 05:28:48 +02:00
|
|
|
// this is used to decide when to recalculate which
|
|
|
|
// torrents to keep queued and which to activate
|
2014-09-22 05:47:43 +02:00
|
|
|
// TODO: replace this by a proper asio timer
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_auto_manage_time_scaler = 0;
|
2008-04-24 05:28:48 +02:00
|
|
|
|
2007-08-16 14:41:46 +02:00
|
|
|
// works like unchoke_time_scaler but it
|
2016-04-26 06:37:47 +02:00
|
|
|
// is only decreased when the unchoke set
|
2007-08-16 14:41:46 +02:00
|
|
|
// is recomputed, and when it reaches zero,
|
|
|
|
// the optimistic unchoke is moved to another peer.
|
2014-09-22 05:47:43 +02:00
|
|
|
// TODO: replace this by a proper asio timer
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_optimistic_unchoke_time_scaler = 0;
|
2007-08-16 14:41:46 +02:00
|
|
|
|
|
|
|
// works like unchoke_time_scaler. Each time
|
|
|
|
// it reaches 0, and all the connections are
|
|
|
|
// used, the worst connection will be disconnected
|
|
|
|
// from the torrent with the most peers
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_disconnect_time_scaler = 90;
|
2007-08-16 14:41:46 +02:00
|
|
|
|
2008-05-19 06:06:25 +02:00
|
|
|
// when this scaler reaches zero, it will
|
|
|
|
// scrape one of the auto managed, paused,
|
|
|
|
// torrents.
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_auto_scrape_time_scaler = 180;
|
2008-05-19 06:06:25 +02:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
// statistics gathered from all torrents.
|
|
|
|
stat m_stat;
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
// implements session_interface
|
2016-04-30 17:05:54 +02:00
|
|
|
virtual void sent_bytes(int bytes_payload, int bytes_protocol) override;
|
|
|
|
virtual void received_bytes(int bytes_payload, int bytes_protocol) override;
|
|
|
|
virtual void trancieve_ip_packet(int bytes, bool ipv6) override;
|
|
|
|
virtual void sent_syn(bool ipv6) override;
|
|
|
|
virtual void received_synack(bool ipv6) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_peak_up_rate = 0;
|
|
|
|
int m_peak_down_rate = 0;
|
2010-02-09 04:04:41 +01:00
|
|
|
|
2009-04-26 02:21:59 +02:00
|
|
|
void on_tick(error_code const& e);
|
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
void try_connect_more_peers();
|
2015-05-26 20:39:49 +02:00
|
|
|
void auto_manage_checking_torrents(std::vector<torrent*>& list
|
|
|
|
, int& limit);
|
2010-03-29 02:34:04 +02:00
|
|
|
void auto_manage_torrents(std::vector<torrent*>& list
|
2015-05-26 20:39:49 +02:00
|
|
|
, int& dht_limit, int& tracker_limit
|
2014-07-06 21:18:00 +02:00
|
|
|
, int& lsd_limit, int& hard_limit, int type_limit);
|
2008-04-24 05:28:48 +02:00
|
|
|
void recalculate_auto_managed_torrents();
|
2014-07-06 21:18:00 +02:00
|
|
|
void recalculate_unchoke_slots();
|
2010-02-02 19:39:32 +01:00
|
|
|
void recalculate_optimistic_unchoke_slots();
|
2008-04-24 05:28:48 +02:00
|
|
|
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point m_created;
|
2016-06-18 20:01:38 +02:00
|
|
|
std::uint16_t session_time() const override
|
2016-01-31 03:33:47 +01:00
|
|
|
{
|
|
|
|
// +1 is here to make it possible to distinguish uninitialized (to
|
2016-04-26 06:37:47 +02:00
|
|
|
// 0) timestamps and timestamps of things that happened during the
|
2016-01-31 03:33:47 +01:00
|
|
|
// first second after the session was constructed
|
2016-06-18 20:01:38 +02:00
|
|
|
std::int64_t const ret = total_seconds(aux::time_now()
|
2016-04-24 22:43:45 +02:00
|
|
|
- m_created) + 1;
|
2016-04-15 01:22:27 +02:00
|
|
|
TORRENT_ASSERT(ret >= 0);
|
2016-06-18 20:01:38 +02:00
|
|
|
TORRENT_ASSERT(ret <= (std::numeric_limits<std::uint16_t>::max)());
|
|
|
|
return static_cast<std::uint16_t>(ret);
|
2016-01-31 03:33:47 +01:00
|
|
|
}
|
2016-11-10 23:08:32 +01:00
|
|
|
time_point session_start_time() const override
|
|
|
|
{
|
|
|
|
return m_created;
|
|
|
|
}
|
2009-04-30 07:49:46 +02:00
|
|
|
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point m_last_tick;
|
|
|
|
time_point m_last_second_tick;
|
2006-10-11 16:02:21 +02:00
|
|
|
|
2009-04-04 09:55:34 +02:00
|
|
|
// the last time we went through the peers
|
|
|
|
// to decide which ones to choke/unchoke
|
2015-03-12 05:34:54 +01:00
|
|
|
time_point m_last_choke;
|
2009-04-04 09:55:34 +02:00
|
|
|
|
2015-04-05 21:35:58 +02:00
|
|
|
// the last time we recalculated which torrents should be started
|
|
|
|
// and stopped (only the auto managed ones)
|
|
|
|
time_point m_last_auto_manage;
|
|
|
|
|
2008-02-28 08:34:07 +01:00
|
|
|
// when outgoing_ports is configured, this is the
|
|
|
|
// port we'll bind the next outgoing socket to
|
2016-08-30 02:29:27 +02:00
|
|
|
mutable int m_next_port = 0;
|
2008-02-28 08:34:07 +01:00
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
2016-06-05 20:07:24 +02:00
|
|
|
std::unique_ptr<dht::dht_storage_interface> m_dht_storage;
|
2016-08-29 14:31:23 +02:00
|
|
|
std::shared_ptr<dht::dht_tracker> m_dht;
|
2006-10-11 16:02:21 +02:00
|
|
|
dht_settings m_dht_settings;
|
2016-08-30 02:29:27 +02:00
|
|
|
dht::dht_storage_constructor_type m_dht_storage_constructor
|
|
|
|
= dht::dht_default_storage_constructor;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2008-09-02 08:37:40 +02:00
|
|
|
// these are used when starting the DHT
|
|
|
|
// (and bootstrapping it), and then erased
|
2015-08-18 23:35:27 +02:00
|
|
|
std::vector<udp::endpoint> m_dht_router_nodes;
|
|
|
|
|
|
|
|
// if a DHT node is added when there's no DHT instance, they're stored
|
|
|
|
// here until we start the DHT
|
|
|
|
std::vector<udp::endpoint> m_dht_nodes;
|
2008-09-02 08:37:40 +02:00
|
|
|
|
2010-12-29 03:17:44 +01:00
|
|
|
// this announce timer is used
|
|
|
|
// by the DHT.
|
|
|
|
deadline_timer m_dht_announce_timer;
|
2012-08-03 07:13:40 +02:00
|
|
|
|
|
|
|
// the number of torrents there were when the
|
|
|
|
// update_dht_announce_interval() was last called.
|
|
|
|
// if the number of torrents changes significantly
|
|
|
|
// compared to this number, the DHT announce interval
|
|
|
|
// is updated again. This especially matters for
|
|
|
|
// small numbers.
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_dht_interval_update_torrents = 0;
|
2015-08-18 18:56:05 +02:00
|
|
|
|
|
|
|
// the number of DHT router lookups there are currently outstanding. As
|
|
|
|
// long as this is > 0, we'll postpone starting the DHT
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_outstanding_router_lookups = 0;
|
2010-12-29 03:17:44 +01:00
|
|
|
#endif
|
|
|
|
|
2016-04-24 21:26:28 +02:00
|
|
|
void send_udp_packet_hostname(char const* hostname
|
|
|
|
, int port
|
2016-07-22 18:31:42 +02:00
|
|
|
, span<char const> p
|
2016-04-24 21:26:28 +02:00
|
|
|
, error_code& ec
|
|
|
|
, int flags);
|
|
|
|
|
2017-04-21 06:45:43 +02:00
|
|
|
void send_udp_packet_hostname_listen(aux::session_listen_socket* sock
|
|
|
|
, char const* hostname
|
|
|
|
, int port
|
|
|
|
, span<char const> p
|
|
|
|
, error_code& ec
|
|
|
|
, int flags);
|
|
|
|
|
2016-04-24 21:26:28 +02:00
|
|
|
void send_udp_packet(bool ssl
|
|
|
|
, udp::endpoint const& ep
|
2016-07-22 18:31:42 +02:00
|
|
|
, span<char const> p
|
2016-04-24 21:26:28 +02:00
|
|
|
, error_code& ec
|
|
|
|
, int flags);
|
2012-06-21 17:05:57 +02:00
|
|
|
|
2017-04-21 06:45:43 +02:00
|
|
|
void send_udp_packet_listen(aux::session_listen_socket* sock
|
|
|
|
, udp::endpoint const& ep
|
|
|
|
, span<char const> p
|
|
|
|
, error_code& ec
|
|
|
|
, int flags);
|
|
|
|
|
|
|
|
void on_udp_writeable(std::weak_ptr<session_udp_socket> s, error_code const& ec);
|
2016-04-24 21:26:28 +02:00
|
|
|
|
2017-04-21 06:45:43 +02:00
|
|
|
void on_udp_packet(std::weak_ptr<session_udp_socket> s
|
2016-04-24 21:26:28 +02:00
|
|
|
, bool ssl, error_code const& ec);
|
2010-05-30 03:33:03 +02:00
|
|
|
|
2014-07-06 21:18:00 +02:00
|
|
|
libtorrent::utp_socket_manager m_utp_socket_manager;
|
2010-11-29 02:33:05 +01:00
|
|
|
|
2014-10-06 05:03:01 +02:00
|
|
|
#ifdef TORRENT_USE_OPENSSL
|
2016-04-26 06:37:47 +02:00
|
|
|
// used for uTP connections over SSL
|
2014-10-06 05:03:01 +02:00
|
|
|
libtorrent::utp_socket_manager m_ssl_utp_socket_manager;
|
|
|
|
#endif
|
|
|
|
|
2010-12-17 04:10:56 +01:00
|
|
|
// the number of torrent connection boosts
|
|
|
|
// connections that have been made this second
|
|
|
|
// this is deducted from the connect speed
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_boost_connections = 0;
|
2010-12-17 04:10:56 +01:00
|
|
|
|
2016-08-29 14:31:23 +02:00
|
|
|
std::shared_ptr<natpmp> m_natpmp;
|
|
|
|
std::shared_ptr<upnp> m_upnp;
|
|
|
|
std::shared_ptr<lsd> m_lsd;
|
2007-03-15 23:03:56 +01:00
|
|
|
|
2017-03-26 15:16:42 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2016-11-02 06:01:04 +01:00
|
|
|
struct work_thread_t
|
|
|
|
{
|
|
|
|
work_thread_t()
|
|
|
|
: work(new boost::asio::io_service::work(ios))
|
|
|
|
, thread([&] { ios.run(); })
|
|
|
|
{}
|
|
|
|
~work_thread_t()
|
|
|
|
{
|
|
|
|
work.reset();
|
|
|
|
thread.join();
|
|
|
|
}
|
|
|
|
work_thread_t(work_thread_t const&) = delete;
|
|
|
|
work_thread_t& operator=(work_thread_t const&) = delete;
|
|
|
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
std::unique_ptr<boost::asio::io_service::work> work;
|
|
|
|
std::thread thread;
|
|
|
|
};
|
|
|
|
std::unique_ptr<work_thread_t> m_torrent_load_thread;
|
2017-03-26 15:16:42 +02:00
|
|
|
#endif
|
2016-11-02 06:01:04 +01:00
|
|
|
|
2016-02-07 08:09:19 +01:00
|
|
|
// mask is a bitmask of which protocols to remap on:
|
|
|
|
// 1: NAT-PMP
|
|
|
|
// 2: UPnP
|
2016-04-24 21:26:28 +02:00
|
|
|
// TODO: 3 perhaps this function should move into listen_socket_t
|
|
|
|
enum remap_port_mask_t
|
|
|
|
{
|
|
|
|
remap_natpmp = 1,
|
|
|
|
remap_upnp = 2,
|
|
|
|
remap_natpmp_and_upnp = 3
|
|
|
|
};
|
|
|
|
void remap_ports(remap_port_mask_t mask, listen_socket_t& s);
|
2016-02-07 08:09:19 +01:00
|
|
|
|
2009-04-26 02:21:59 +02:00
|
|
|
// the timer used to fire the tick
|
2006-10-11 16:02:21 +02:00
|
|
|
deadline_timer m_timer;
|
2015-11-25 22:36:06 +01:00
|
|
|
aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_tick_handler_storage;
|
|
|
|
|
|
|
|
template <class Handler>
|
|
|
|
aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>
|
|
|
|
make_tick_handler(Handler const& handler)
|
|
|
|
{
|
|
|
|
return aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>(
|
2016-09-25 15:50:48 +02:00
|
|
|
handler, m_tick_handler_storage, *this);
|
2015-11-25 22:36:06 +01:00
|
|
|
}
|
2007-05-05 02:29:33 +02:00
|
|
|
|
2010-02-05 09:23:17 +01:00
|
|
|
// torrents are announced on the local network in a
|
|
|
|
// round-robin fashion. All torrents are cycled through
|
|
|
|
// within the LSD announce interval (which defaults to
|
|
|
|
// 5 minutes)
|
|
|
|
torrent_map::iterator m_next_lsd_torrent;
|
|
|
|
|
2010-02-14 02:39:55 +01:00
|
|
|
#ifndef TORRENT_DISABLE_DHT
|
|
|
|
// torrents are announced on the DHT in a
|
|
|
|
// round-robin fashion. All torrents are cycled through
|
|
|
|
// within the DHT announce interval (which defaults to
|
|
|
|
// 15 minutes)
|
|
|
|
torrent_map::iterator m_next_dht_torrent;
|
2012-08-03 07:13:40 +02:00
|
|
|
|
|
|
|
// torrents that don't have any peers
|
|
|
|
// when added should be announced to the DHT
|
|
|
|
// as soon as possible. Such torrents are put
|
|
|
|
// in this queue and get announced the next time
|
|
|
|
// the timer fires, instead of the next one in
|
|
|
|
// the round-robin sequence.
|
2016-08-31 14:27:36 +02:00
|
|
|
std::deque<std::weak_ptr<torrent>> m_dht_torrents;
|
2010-02-14 02:39:55 +01:00
|
|
|
#endif
|
|
|
|
|
2012-11-03 04:50:12 +01:00
|
|
|
// torrents prioritized to get connection attempts
|
2016-08-31 14:27:36 +02:00
|
|
|
std::deque<std::pair<std::weak_ptr<torrent>, int>> m_prio_torrents;
|
2012-11-03 04:50:12 +01:00
|
|
|
|
2010-02-05 09:23:17 +01:00
|
|
|
// this announce timer is used
|
|
|
|
// by Local service discovery
|
|
|
|
deadline_timer m_lsd_announce_timer;
|
|
|
|
|
2017-03-01 00:06:02 +01:00
|
|
|
// this is the timer used to call ``close_oldest`` on the ``file_pool``
|
|
|
|
// object. This closes the file that's been opened the longest every
|
|
|
|
// time it's called, to force the windows disk cache to be flushed
|
|
|
|
deadline_timer m_close_file_timer;
|
|
|
|
|
2007-05-05 02:29:33 +02:00
|
|
|
// the index of the torrent that will be offered to
|
2009-04-26 02:21:59 +02:00
|
|
|
// connect to a peer next time on_tick is called.
|
2014-07-06 21:18:00 +02:00
|
|
|
// This implements a round robin peer connections among
|
|
|
|
// torrents that want more peers. The index is into
|
|
|
|
// m_torrent_lists[torrent_want_peers_downloading]
|
|
|
|
// (which is a list of torrent pointers with all
|
|
|
|
// torrents that want peers and are downloading)
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_next_downloading_connect_torrent = 0;
|
|
|
|
int m_next_finished_connect_torrent = 0;
|
2011-03-27 22:46:20 +02:00
|
|
|
|
2012-07-04 22:41:22 +02:00
|
|
|
// this is the number of attempts of connecting to
|
2014-07-06 21:18:00 +02:00
|
|
|
// peers we have given to downloading torrents.
|
|
|
|
// when this gets high enough, we try to connect
|
|
|
|
// a peer from a finished torrent
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_download_connect_attempts = 0;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
// index into m_torrent_lists[torrent_want_scrape] referring
|
|
|
|
// to the next torrent to auto-scrape
|
2016-08-30 02:29:27 +02:00
|
|
|
int m_next_scrape_torrent = 0;
|
2012-07-04 22:41:22 +02:00
|
|
|
|
2014-01-21 20:26:09 +01:00
|
|
|
#if TORRENT_USE_INVARIANT_CHECKS
|
2007-08-21 20:33:28 +02:00
|
|
|
void check_invariant() const;
|
2006-10-11 16:02:21 +02:00
|
|
|
#endif
|
2007-05-14 00:01:21 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
counters& stats_counters() override { return m_stats_counters; }
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2016-04-30 17:05:54 +02:00
|
|
|
void received_buffer(int size) override;
|
|
|
|
void sent_buffer(int size) override;
|
2014-07-06 21:18:00 +02:00
|
|
|
|
2015-04-17 03:15:33 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-14 04:46:07 +02:00
|
|
|
virtual bool should_log() const override;
|
2016-04-30 17:05:54 +02:00
|
|
|
virtual void session_log(char const* fmt, ...) const override TORRENT_FORMAT(2,3);
|
2012-10-18 17:14:18 +02:00
|
|
|
|
2006-11-15 22:39:58 +01:00
|
|
|
// this list of tracker loggers serves as tracker_callbacks when
|
|
|
|
// shutting down. This list is just here to keep them alive during
|
|
|
|
// whe shutting down process
|
2016-09-01 03:42:18 +02:00
|
|
|
std::list<std::shared_ptr<tracker_logger>> m_tracker_loggers;
|
2015-05-05 04:32:14 +02:00
|
|
|
#endif
|
2010-07-14 06:16:38 +02:00
|
|
|
|
2006-11-14 01:08:16 +01:00
|
|
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
2015-05-28 16:46:12 +02:00
|
|
|
// this is a list to allow extensions to potentially remove themselves.
|
2016-08-17 20:30:24 +02:00
|
|
|
std::array<std::vector<std::shared_ptr<plugin>>, 4> m_ses_extensions;
|
2006-11-14 01:08:16 +01:00
|
|
|
#endif
|
|
|
|
|
2016-10-25 14:02:34 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
2014-07-06 21:18:00 +02:00
|
|
|
user_load_function_t m_user_load_torrent;
|
2016-10-25 14:02:34 +02:00
|
|
|
#endif
|
2014-07-06 21:18:00 +02:00
|
|
|
|
|
|
|
// this is true whenever we have posted a deferred-disk job
|
|
|
|
// it means we don't need to post another one
|
2016-08-30 02:29:27 +02:00
|
|
|
bool m_deferred_submit_disk_jobs = false;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2012-11-03 04:50:12 +01:00
|
|
|
// this is set to true when a torrent auto-manage
|
|
|
|
// event is triggered, and reset whenever the message
|
|
|
|
// is delivered and the auto-manage is executed.
|
|
|
|
// there should never be more than a single pending auto-manage
|
|
|
|
// message in-flight at any given time.
|
2016-08-30 02:29:27 +02:00
|
|
|
bool m_pending_auto_manage = false;
|
2015-05-19 05:13:49 +02:00
|
|
|
|
2012-11-03 04:50:12 +01:00
|
|
|
// this is also set to true when triggering an auto-manage
|
|
|
|
// of the torrents. However, if the normal auto-manage
|
|
|
|
// timer comes along and executes the auto-management,
|
|
|
|
// this is set to false, which means the triggered event
|
|
|
|
// no longer needs to execute the auto-management.
|
2016-08-30 02:29:27 +02:00
|
|
|
bool m_need_auto_manage = false;
|
2012-11-03 04:50:12 +01:00
|
|
|
|
2013-11-26 03:00:02 +01:00
|
|
|
// set to true when the session object
|
|
|
|
// is being destructed and the thread
|
|
|
|
// should exit
|
2016-08-30 02:29:27 +02:00
|
|
|
bool m_abort = false;
|
2013-11-26 03:00:02 +01:00
|
|
|
|
|
|
|
// is true if the session is paused
|
2016-08-30 02:29:27 +02:00
|
|
|
bool m_paused = false;
|
2006-10-11 16:02:21 +02:00
|
|
|
};
|
2015-05-25 23:46:42 +02:00
|
|
|
|
2015-04-17 03:15:33 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2006-11-15 22:39:58 +01:00
|
|
|
struct tracker_logger : request_callback
|
|
|
|
{
|
2016-10-08 20:07:11 +02:00
|
|
|
explicit tracker_logger(session_interface& ses);
|
2008-04-24 03:35:48 +02:00
|
|
|
void tracker_warning(tracker_request const& req
|
2017-02-06 01:18:06 +01:00
|
|
|
, std::string const& str) override;
|
2006-11-15 22:39:58 +01:00
|
|
|
void tracker_response(tracker_request const&
|
2008-12-02 09:29:45 +01:00
|
|
|
, libtorrent::address const& tracker_ip
|
2009-05-15 23:23:41 +02:00
|
|
|
, std::list<address> const& ip_list
|
2017-02-06 01:18:06 +01:00
|
|
|
, struct tracker_response const& resp) override;
|
2010-03-20 10:35:45 +01:00
|
|
|
void tracker_request_error(tracker_request const& r
|
|
|
|
, int response_code, error_code const& ec, const std::string& str
|
2017-02-06 01:18:06 +01:00
|
|
|
, seconds32 retry_interval) override;
|
|
|
|
bool should_log() const override;
|
|
|
|
void debug_log(const char* fmt, ...) const override TORRENT_FORMAT(2,3);
|
2014-07-06 21:18:00 +02:00
|
|
|
session_interface& m_ses;
|
2015-04-27 04:21:12 +02:00
|
|
|
private:
|
|
|
|
// explicitly disallow assignment, to silence msvc warning
|
|
|
|
tracker_logger& operator=(tracker_logger const&);
|
2006-11-15 22:39:58 +01:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2006-10-11 16:02:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|