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
# include <algorithm>
# include <vector>
# include <set>
# include <list>
2012-09-30 21:35:08 +02:00
# include <stdarg.h> // for va_start, va_end
2006-10-11 16:02:21 +02:00
2008-04-05 06:53:22 +02:00
# ifndef TORRENT_DISABLE_GEO_IP
2009-10-12 22:56:17 +02:00
# ifdef WITH_SHIPPED_GEOIP_H
2008-04-05 06:53:22 +02:00
# include "libtorrent/GeoIP.h"
2009-10-12 22:56:17 +02:00
# else
# include <GeoIP.h>
# endif
2008-04-05 06:53:22 +02:00
# endif
2006-10-11 16:02:21 +02:00
# ifdef _MSC_VER
# pragma warning(push, 1)
# endif
2009-05-07 00:36:24 +02:00
# include <boost/pool/object_pool.hpp>
2006-10-11 16:02:21 +02:00
# ifdef _MSC_VER
# pragma warning(pop)
# endif
# include "libtorrent/torrent_handle.hpp"
# 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"
# include "libtorrent/config.hpp"
# include "libtorrent/session_settings.hpp"
# 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-05-05 02:29:33 +02:00
# include "libtorrent/connection_queue.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"
2009-10-20 04:49:56 +02:00
# include "libtorrent/thread.hpp"
2009-05-07 00:36:24 +02:00
# include "libtorrent/policy.hpp" // for policy::peer
2009-05-07 22:30:20 +02:00
# include "libtorrent/alert.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"
2011-01-18 04:41:54 +01:00
# include "libtorrent/rss.hpp"
2012-04-30 07:39:35 +02:00
# include "libtorrent/alert_dispatcher.hpp"
2012-04-30 08:30:35 +02:00
# include "libtorrent/kademlia/dht_observer.hpp"
2006-10-11 16:02:21 +02:00
2010-03-03 08:42:51 +01:00
# if TORRENT_COMPLETE_TYPES_REQUIRED
# include "libtorrent/peer_connection.hpp"
# endif
2010-10-12 10:57:43 +02:00
# ifdef TORRENT_USE_OPENSSL
# include <boost/asio/ssl/context.hpp>
# endif
2011-10-22 19:44:40 +02:00
# if defined TORRENT_STATS && defined __MACH__
2011-06-29 00:20:34 +02:00
# include <mach/vm_statistics.h>
# include <mach/mach_init.h>
# include <mach/host_info.h>
# include <mach/mach_host.h>
# endif
2006-10-11 16:02:21 +02:00
namespace libtorrent
{
2011-01-29 11:37:21 +01:00
struct plugin ;
2008-12-26 08:00:21 +01:00
class upnp ;
class natpmp ;
class lsd ;
2009-04-30 19:30:14 +02:00
struct fingerprint ;
2009-04-04 09:55:34 +02:00
class torrent ;
2009-05-03 22:21:24 +02:00
class alert ;
2008-12-26 08:00:21 +01:00
namespace dht
{
2009-04-30 19:30:14 +02:00
struct dht_tracker ;
2009-11-11 06:22:57 +01:00
}
2007-06-10 22:46:09 +02:00
2010-12-26 09:03:02 +01:00
struct bencode_map_entry ;
2011-09-12 05:51:49 +02:00
struct listen_socket_t
{
2012-01-14 17:04:25 +01:00
listen_socket_t ( ) : external_port ( 0 ) , ssl ( false ) { }
2011-09-12 05:51:49 +02:00
// this is typically empty but can be set
// to the WAN IP address of NAT-PMP or UPnP router
address external_address ;
// 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.
int external_port ;
2012-01-14 17:04:25 +01:00
// set to true if this is an SSL listen socket
bool ssl ;
2011-09-12 05:51:49 +02:00
// the actual socket
boost : : shared_ptr < socket_acceptor > sock ;
} ;
2006-10-11 16:02:21 +02:00
namespace aux
{
struct session_impl ;
2011-06-29 00:20:34 +02:00
# if defined TORRENT_STATS && !defined __MACH__
2011-10-17 19:12:08 +02:00
struct vm_statistics_data_t
{
boost : : uint64_t active_count ;
boost : : uint64_t inactive_count ;
boost : : uint64_t wire_count ;
boost : : uint64_t free_count ;
boost : : uint64_t pageins ;
boost : : uint64_t pageouts ;
boost : : uint64_t faults ;
} ;
2011-06-29 00:20:34 +02:00
# endif
2011-10-17 19:12:08 +02:00
struct thread_cpu_usage
{
ptime user_time ;
ptime system_time ;
} ;
2008-02-17 23:51:03 +01:00
# if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
2006-11-15 22:39:58 +01:00
struct tracker_logger ;
# endif
2009-12-13 17:32:07 +01:00
// used to initialize the g_current_time before
// anything else
struct initialize_timer
{
initialize_timer ( ) ;
} ;
2012-02-25 09:02:52 +01:00
TORRENT_EXPORT std : : pair < bencode_map_entry * , int > settings_map ( ) ;
2010-12-26 09:03:02 +01:00
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
2012-04-30 07:39:35 +02:00
struct TORRENT_EXTRA_EXPORT session_impl
: alert_dispatcher
2012-04-30 08:30:35 +02:00
, dht : : dht_observer
2012-04-30 07:39:35 +02:00
, boost : : noncopyable
, initialize_timer
2012-06-22 06:21:20 +02:00
, udp_socket_observer
2011-01-29 11:37:21 +01:00
, boost : : enable_shared_from_this < session_impl >
2006-10-11 16:02:21 +02:00
{
2012-02-21 07:47:08 +01:00
# if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
// this needs to be destructed last, since other components may log
// things as they are being destructed. That's why it's declared at
// the top of session_impl
boost : : shared_ptr < logger > m_logger ;
# endif
2007-09-29 18:14:03 +02:00
// the size of each allocation that is chained in the send buffer
2008-12-27 18:00:06 +01:00
enum { send_buffer_size = 128 } ;
2007-09-29 18:14:03 +02:00
2008-11-29 22:33:21 +01:00
# ifdef TORRENT_DEBUG
2006-10-11 16:02:21 +02:00
friend class : : libtorrent : : peer_connection ;
# endif
2007-02-17 02:01:34 +01:00
friend struct checker_impl ;
2006-10-11 16:02:21 +02:00
friend class invariant_access ;
2007-10-31 10:48:20 +01:00
typedef std : : set < boost : : intrusive_ptr < peer_connection > > connection_map ;
2006-10-11 16:02:21 +02:00
typedef std : : map < sha1_hash , boost : : shared_ptr < torrent > > torrent_map ;
session_impl (
std : : pair < int , int > listen_port_range
, fingerprint const & cl_fprint
2007-11-16 22:21:28 +01:00
, char const * listen_interface
2011-10-08 11:52:36 +02:00
, boost : : uint32_t alert_mask
2008-02-17 23:51:03 +01:00
# if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
2009-10-26 02:29:39 +01:00
, std : : string const & logpath
2007-11-16 22:21:28 +01:00
# endif
) ;
2012-06-30 17:30:38 +02:00
virtual ~ session_impl ( ) ;
2012-08-03 07:13:40 +02:00
void update_dht_announce_interval ( ) ;
2010-12-04 23:20:31 +01:00
void init ( ) ;
void start_session ( ) ;
2006-10-11 16:02:21 +02:00
2006-11-14 01:08:16 +01:00
# ifndef TORRENT_DISABLE_EXTENSIONS
2007-10-31 10:48:20 +01:00
void add_extension ( boost : : function < boost : : shared_ptr < torrent_plugin > (
torrent * , void * ) > ext ) ;
2011-01-29 11:37:21 +01:00
void add_ses_extension ( boost : : shared_ptr < plugin > ext ) ;
2008-01-07 02:10:46 +01:00
# endif
2008-11-29 22:33:21 +01:00
# ifdef TORRENT_DEBUG
2008-01-07 02:10:46 +01:00
bool has_peer ( peer_connection const * p ) const
{
2010-12-04 23:20:31 +01:00
TORRENT_ASSERT ( is_network_thread ( ) ) ;
2008-01-07 02:10:46 +01:00
return std : : find_if ( m_connections . begin ( ) , m_connections . end ( )
, boost : : bind ( & boost : : intrusive_ptr < peer_connection > : : get , _1 ) = = p )
! = m_connections . end ( ) ;
}
2012-10-06 16:31:14 +02:00
// this is set while the session is building the
// torrent status update message
bool m_posting_torrent_updates ;
2006-11-14 01:08:16 +01:00
# endif
2009-10-20 04:49:56 +02:00
void main_thread ( ) ;
2006-10-11 16:02:21 +02:00
2011-02-16 07:35:53 +01:00
void open_listen_port ( int flags , error_code & ec ) ;
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
void prioritize_connections ( boost : : weak_ptr < torrent > t ) ;
2007-09-22 18:27:29 +02:00
// if we are listening on an IPv6 interface
// this will return one of the IPv6 addresses on this
// machine, otherwise just an empty endpoint
tcp : : endpoint get_ipv6_interface ( ) const ;
2009-04-12 02:37:06 +02:00
tcp : : endpoint get_ipv4_interface ( ) const ;
2007-09-22 18:27:29 +02:00
2012-01-14 17:04:25 +01:00
void async_accept ( boost : : shared_ptr < socket_acceptor > const & listener , bool ssl ) ;
2009-04-09 03:04:49 +02:00
void on_accept_connection ( boost : : shared_ptr < socket_type > const & s
2012-01-14 17:04:25 +01:00
, boost : : weak_ptr < socket_acceptor > listener , error_code const & e , bool ssl ) ;
2009-04-09 03:04:49 +02:00
void on_socks_accept ( boost : : shared_ptr < socket_type > const & s
, error_code const & e ) ;
void incoming_connection ( boost : : shared_ptr < socket_type > const & s ) ;
2006-10-11 16:02:21 +02:00
2011-05-08 11:04:59 +02:00
# if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
2010-07-14 06:16:38 +02:00
bool is_network_thread ( ) const
{
# if defined BOOST_HAS_PTHREADS
2010-12-19 09:12:31 +01:00
if ( m_network_thread = = 0 ) return true ;
2010-07-14 06:16:38 +02:00
return m_network_thread = = pthread_self ( ) ;
# endif
return true ;
}
# endif
2006-10-11 16:02:21 +02:00
2011-01-18 04:41:54 +01:00
feed_handle add_feed ( feed_settings const & feed ) ;
void remove_feed ( feed_handle h ) ;
void get_feeds ( std : : vector < feed_handle > * f ) const ;
boost : : weak_ptr < torrent > find_torrent ( sha1_hash const & info_hash ) ;
boost : : weak_ptr < torrent > find_torrent ( std : : string const & uuid ) ;
2006-10-11 16:02:21 +02:00
peer_id const & get_peer_id ( ) const { return m_peer_id ; }
2009-06-12 18:40:38 +02:00
void close_connection ( peer_connection const * p , error_code const & ec ) ;
2006-10-11 16:02:21 +02:00
void set_settings ( session_settings const & s ) ;
session_settings const & settings ( ) const { return m_settings ; }
# ifndef TORRENT_DISABLE_DHT
2010-07-14 06:16:38 +02:00
void add_dht_node_name ( std : : pair < std : : string , int > const & node ) ;
2006-10-11 16:02:21 +02:00
void add_dht_node ( udp : : endpoint n ) ;
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 ; }
2010-03-04 17:42:39 +01:00
void start_dht ( ) ;
2006-10-11 16:02:21 +02:00
void stop_dht ( ) ;
2010-03-04 17:42:39 +01:00
void start_dht ( entry const & startup_state ) ;
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
void prioritize_dht ( boost : : weak_ptr < torrent > t ) ;
2010-03-04 17:42:39 +01:00
# ifndef TORRENT_NO_DEPRECATE
2010-07-14 06:16:38 +02:00
entry dht_state ( ) const ;
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 ) ;
2010-02-14 08:46:57 +01:00
void on_dht_router_name_lookup ( error_code const & e
, tcp : : resolver : : iterator host ) ;
2006-10-11 16:02:21 +02:00
# endif
2007-03-15 23:03:56 +01:00
2010-12-29 03:17:44 +01:00
void maybe_update_udp_mapping ( int nat , int local_port , int external_port ) ;
2007-06-06 02:41:20 +02:00
# ifndef TORRENT_DISABLE_ENCRYPTION
void set_pe_settings ( pe_settings const & settings ) ;
pe_settings const & get_pe_settings ( ) const { return m_pe_settings ; }
# endif
2009-06-12 18:40:38 +02:00
void on_port_map_log ( char const * msg , int map_transport ) ;
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
, error_code const & ec , int nat_transport ) ;
2007-03-15 23:03:56 +01:00
2006-10-11 16:02:21 +02:00
bool is_aborted ( ) const { return m_abort ; }
2008-06-29 21:08:30 +02:00
bool is_paused ( ) const { return m_paused ; }
void pause ( ) ;
void resume ( ) ;
2006-10-11 16:02:21 +02:00
void set_ip_filter ( ip_filter const & f ) ;
2009-07-21 03:52:37 +02:00
ip_filter const & get_ip_filter ( ) const ;
2007-06-01 03:05:57 +02:00
void set_port_filter ( port_filter const & f ) ;
2006-10-11 16:02:21 +02:00
2011-02-16 07:35:53 +01:00
void listen_on (
2006-10-11 16:02:21 +02:00
std : : pair < int , int > const & port_range
2011-02-16 07:35:53 +01:00
, error_code & ec
2010-06-17 19:14:56 +02:00
, const char * net_interface = 0
, int flags = 0 ) ;
2006-10-11 16:02:21 +02:00
bool is_listening ( ) const ;
2009-02-23 02:21:19 +01:00
torrent_handle add_torrent ( add_torrent_params const & , error_code & ec ) ;
2012-11-08 03:07:10 +01:00
torrent_handle add_torrent_impl ( add_torrent_params const & , error_code & ec ) ;
2011-10-12 12:27:17 +02:00
void async_add_torrent ( add_torrent_params * params ) ;
2006-10-11 16:02:21 +02:00
2007-10-13 05:33:33 +02:00
void remove_torrent ( torrent_handle const & h , int options ) ;
2011-03-23 03:46:22 +01:00
void remove_torrent_impl ( boost : : shared_ptr < torrent > tptr , int options ) ;
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
, boost : : function < bool ( torrent_status const & ) > const & pred
, boost : : uint32_t flags ) const ;
void refresh_torrent_status ( std : : vector < torrent_status > * ret
, boost : : uint32_t flags ) const ;
2011-11-15 03:34:00 +01:00
void post_torrent_updates ( ) ;
2011-02-01 10:48:28 +01:00
std : : vector < torrent_handle > get_torrents ( ) const ;
2006-10-11 16:02:21 +02:00
2010-01-17 22:42:14 +01:00
void queue_check_torrent ( boost : : shared_ptr < torrent > const & t ) ;
void dequeue_check_torrent ( boost : : shared_ptr < torrent > const & t ) ;
2008-03-08 07:06:31 +01:00
2011-06-14 08:10:35 +02:00
void set_alert_mask ( boost : : uint32_t m ) ;
2008-10-07 07:46:42 +02:00
size_t set_alert_queue_size_limit ( size_t queue_size_limit_ ) ;
2006-10-11 16:02:21 +02:00
std : : auto_ptr < alert > pop_alert ( ) ;
2011-03-14 03:59:46 +01:00
void pop_alerts ( std : : deque < alert * > * alerts ) ;
2010-07-14 06:16:38 +02:00
void set_alert_dispatch ( boost : : function < void ( std : : auto_ptr < alert > ) > const & ) ;
2011-01-29 11:37:21 +01:00
void post_alert ( const alert & alert_ ) ;
2007-01-02 00:51:24 +01:00
2007-11-25 09:18:57 +01:00
alert const * wait_for_alert ( time_duration max_wait ) ;
2010-10-09 21:09:38 +02:00
# ifndef TORRENT_NO_DEPRECATE
2007-01-02 00:51:24 +01:00
int upload_rate_limit ( ) const ;
int download_rate_limit ( ) const ;
2009-05-14 19:21:19 +02:00
int local_upload_rate_limit ( ) const ;
int local_download_rate_limit ( ) const ;
void set_local_download_rate_limit ( int bytes_per_second ) ;
void set_local_upload_rate_limit ( int bytes_per_second ) ;
2006-10-11 16:02:21 +02:00
void set_download_rate_limit ( int bytes_per_second ) ;
void set_upload_rate_limit ( int bytes_per_second ) ;
void set_max_half_open_connections ( int limit ) ;
void set_max_connections ( int limit ) ;
void set_max_uploads ( int limit ) ;
2010-10-09 21:09:38 +02:00
int max_connections ( ) const ;
int max_uploads ( ) const ;
int max_half_open_connections ( ) const ;
# endif
2007-08-16 14:41:46 +02:00
int num_uploads ( ) const { return m_num_unchoked ; }
int num_connections ( ) const
{ return m_connections . size ( ) ; }
2008-12-26 08:00:21 +01:00
void unchoke_peer ( peer_connection & c ) ;
2009-07-23 06:38:52 +02:00
void choke_peer ( peer_connection & c ) ;
2006-10-11 16:02:21 +02:00
session_status status ( ) const ;
void set_peer_id ( peer_id const & id ) ;
void set_key ( int key ) ;
2010-12-05 21:40:28 +01:00
address listen_address ( ) const ;
2012-01-14 17:04:25 +01:00
boost : : uint16_t listen_port ( ) const ;
boost : : uint16_t ssl_listen_port ( ) const ;
2006-10-11 16:02:21 +02:00
void abort ( ) ;
2006-11-14 01:08:16 +01:00
torrent_handle find_torrent_handle ( sha1_hash const & info_hash ) ;
2011-09-12 05:51:49 +02:00
void announce_lsd ( sha1_hash const & ih , int port , bool broadcast = false ) ;
2007-04-25 20:26:35 +02:00
2010-07-14 06:16:38 +02:00
void save_state ( entry * e , boost : : uint32_t flags ) const ;
void load_state ( lazy_entry const * e ) ;
2009-12-03 06:11:57 +01:00
2010-08-23 08:27:18 +02:00
void set_proxy ( proxy_settings const & s ) ;
proxy_settings const & proxy ( ) const { return m_proxy ; }
2007-04-25 20:26:35 +02:00
2010-08-23 08:27:18 +02:00
# ifndef TORRENT_NO_DEPRECATE
void set_peer_proxy ( proxy_settings const & s ) { set_proxy ( s ) ; }
void set_web_seed_proxy ( proxy_settings const & s ) { set_proxy ( s ) ; }
void set_tracker_proxy ( proxy_settings const & s ) { set_proxy ( s ) ; }
proxy_settings const & peer_proxy ( ) const { return proxy ( ) ; }
proxy_settings const & web_seed_proxy ( ) const { return proxy ( ) ; }
proxy_settings const & tracker_proxy ( ) const { return proxy ( ) ; }
# ifndef TORRENT_DISABLE_DHT
void set_dht_proxy ( proxy_settings const & s ) { set_proxy ( s ) ; }
proxy_settings const & dht_proxy ( ) const { return proxy ( ) ; }
# endif
# endif // TORRENT_NO_DEPRECATE
2007-04-25 20:26:35 +02:00
# ifndef TORRENT_DISABLE_DHT
2010-07-14 06:16:38 +02:00
bool is_dht_running ( ) const { return m_dht ; }
2007-04-25 20:26:35 +02:00
# endif
2009-08-20 05:19:12 +02:00
# if TORRENT_USE_I2P
void set_i2p_proxy ( proxy_settings const & s )
{
m_i2p_conn . open ( s , boost : : bind ( & session_impl : : on_i2p_open , this , _1 ) ) ;
open_new_incoming_i2p_connection ( ) ;
}
void on_i2p_open ( error_code const & ec ) ;
proxy_settings const & i2p_proxy ( ) const
{ return m_i2p_conn . proxy ( ) ; }
void open_new_incoming_i2p_connection ( ) ;
void on_i2p_accept ( boost : : shared_ptr < socket_type > const & s
, error_code const & e ) ;
# endif
2008-04-05 06:53:22 +02:00
# ifndef TORRENT_DISABLE_GEO_IP
std : : string as_name_for_ip ( address const & a ) ;
int as_for_ip ( address const & a ) ;
std : : pair < const int , int > * lookup_as ( int as ) ;
2010-07-14 06:16:38 +02:00
void load_asnum_db ( std : : string file ) ;
2008-04-11 10:46:43 +02:00
bool has_asnum_db ( ) const { return m_asnum_db ; }
2010-07-14 06:16:38 +02:00
void load_country_db ( std : : string file ) ;
2008-04-11 10:46:43 +02:00
bool has_country_db ( ) const { return m_country_db ; }
char const * country_for_ip ( address const & a ) ;
2009-03-31 10:12:35 +02:00
2009-10-29 19:12:43 +01:00
# if TORRENT_USE_WSTRING
2010-07-14 09:38:35 +02:00
void load_asnum_dbw ( std : : wstring file ) ;
void load_country_dbw ( std : : wstring file ) ;
2009-10-29 19:12:43 +01:00
# endif // TORRENT_USE_WSTRING
# endif // TORRENT_DISABLE_GEO_IP
2008-04-05 06:53:22 +02:00
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 ( ) ;
2008-02-28 08:34:07 +01:00
int next_port ( ) ;
2011-11-16 03:29:59 +01:00
void add_redundant_bytes ( size_type b , int reason )
2008-07-11 09:30:04 +02:00
{
TORRENT_ASSERT ( b > 0 ) ;
m_total_redundant_bytes + = b ;
2011-11-16 03:29:59 +01:00
m_redundant_bytes [ reason ] + = b ;
2008-07-11 09:30:04 +02:00
}
void add_failed_bytes ( size_type b )
{
TORRENT_ASSERT ( b > 0 ) ;
m_total_failed_bytes + = b ;
}
2011-05-19 04:41:28 +02:00
char * allocate_buffer ( ) ;
void free_buffer ( char * buf ) ;
2008-04-10 12:03:23 +02:00
2009-01-23 10:13:31 +01:00
char * allocate_disk_buffer ( char const * category ) ;
2007-09-29 18:14:03 +02:00
void free_disk_buffer ( char * buf ) ;
2008-03-29 23:45:55 +01:00
2010-12-24 02:31:41 +01:00
enum
{
source_dht = 1 ,
source_peer = 2 ,
source_tracker = 4 ,
source_router = 8
} ;
2012-04-30 08:30:35 +02:00
// implements dht_observer
virtual void set_external_address ( address const & ip
2010-12-24 02:31:41 +01:00
, int source_type , address const & source ) ;
2008-03-29 23:45:55 +01:00
address const & external_address ( ) const { return m_external_address ; }
2008-02-28 04:09:34 +01:00
2011-02-13 23:27:02 +01:00
bool can_write_to_disk ( ) const
{ return m_disk_thread . can_write ( ) ; }
2010-07-14 06:16:38 +02:00
// used when posting synchronous function
// calls to session_impl and torrent objects
mutable libtorrent : : mutex mut ;
mutable libtorrent : : condition cond ;
2011-01-30 11:04:15 +01:00
void inc_disk_queue ( int channel )
{
TORRENT_ASSERT ( channel > = 0 & & channel < 2 ) ;
+ + m_disk_queues [ channel ] ;
}
void dec_disk_queue ( int channel )
{
TORRENT_ASSERT ( channel > = 0 & & channel < 2 ) ;
TORRENT_ASSERT ( m_disk_queues [ channel ] > 0 ) ;
- - m_disk_queues [ channel ] ;
}
2012-06-21 05:51:39 +02:00
void inc_active_downloading ( ) { + + m_num_active_downloading ; }
void dec_active_downloading ( )
{
TORRENT_ASSERT ( m_num_active_downloading > 0 ) ;
- - m_num_active_downloading ;
}
void inc_active_finished ( ) { + + m_num_active_finished ; }
void dec_active_finished ( )
{
TORRENT_ASSERT ( m_num_active_finished > 0 ) ;
- - m_num_active_finished ;
}
2012-01-20 07:07:19 +01:00
# if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
bool in_state_updates ( boost : : shared_ptr < torrent > t )
{
return std : : find_if ( m_state_updates . begin ( ) , m_state_updates . end ( )
, boost : : bind ( & boost : : weak_ptr < torrent > : : lock , _1 ) = = t ) ! = m_state_updates . end ( ) ;
}
# endif
2011-11-15 07:47:02 +01:00
void add_to_update_queue ( boost : : weak_ptr < torrent > t )
2012-01-20 06:40:32 +01:00
{
TORRENT_ASSERT ( std : : find_if ( m_state_updates . begin ( ) , m_state_updates . end ( )
, boost : : bind ( & boost : : weak_ptr < torrent > : : lock , _1 ) = = t . lock ( ) ) = = m_state_updates . end ( ) ) ;
m_state_updates . push_back ( t ) ;
}
2011-11-15 07:47:02 +01:00
2006-10-11 16:02:21 +02:00
// private:
2012-04-30 07:39:35 +02:00
// implements alert_dispatcher
virtual bool post_alert ( alert * a ) ;
2010-10-09 21:09:38 +02:00
void update_connections_limit ( ) ;
void update_unchoke_limit ( ) ;
2012-11-03 04:50:12 +01:00
void trigger_auto_manage ( ) ;
void on_trigger_auto_manage ( ) ;
2010-10-09 21:09:38 +02:00
void update_rate_settings ( ) ;
2010-03-10 08:14:10 +01:00
void update_disk_thread_settings ( ) ;
2007-04-04 04:06:07 +02:00
void on_lsd_peer ( tcp : : endpoint peer , sha1_hash const & ih ) ;
2009-05-01 06:59:15 +02:00
void setup_socket_buffers ( socket_type & s ) ;
2007-04-04 04:06:07 +02:00
2011-03-07 01:36:51 +01:00
// the settings for the client
session_settings m_settings ;
2009-05-07 00:36:24 +02:00
// this is a shared pool where policy_peer objects
// are allocated. It's a pool since we're likely
// to have tens of thousands of peers, and a pool
// saves significant overhead
2009-05-07 22:30:20 +02:00
# ifdef TORRENT_STATS
struct logging_allocator
{
typedef std : : size_t size_type ;
typedef std : : ptrdiff_t difference_type ;
static char * malloc ( const size_type bytes )
{
allocated_bytes + = bytes ;
+ + allocations ;
return ( char * ) : : malloc ( bytes ) ;
}
static void free ( char * const block )
{
- - allocations ;
return : : free ( block ) ;
}
static int allocations ;
static int allocated_bytes ;
} ;
2009-05-24 23:49:19 +02:00
boost : : object_pool <
policy : : ipv4_peer , logging_allocator > m_ipv4_peer_pool ;
2009-08-20 05:19:12 +02:00
# if TORRENT_USE_IPV6
2009-05-24 23:49:19 +02:00
boost : : object_pool <
policy : : ipv6_peer , logging_allocator > m_ipv6_peer_pool ;
2009-08-20 05:19:12 +02:00
# endif
# if TORRENT_USE_I2P
boost : : object_pool <
policy : : i2p_peer , logging_allocator > m_i2p_peer_pool ;
# endif
2009-05-07 22:30:20 +02:00
# else
2009-05-24 23:49:19 +02:00
boost : : object_pool < policy : : ipv4_peer > m_ipv4_peer_pool ;
2009-08-20 05:19:12 +02:00
# if TORRENT_USE_IPV6
2009-05-24 23:49:19 +02:00
boost : : object_pool < policy : : ipv6_peer > m_ipv6_peer_pool ;
2009-08-20 05:19:12 +02:00
# endif
# if TORRENT_USE_I2P
boost : : object_pool < policy : : i2p_peer > m_i2p_peer_pool ;
# endif
2009-05-07 22:30:20 +02:00
# endif
// 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.
boost : : pool < > m_send_buffers ;
2008-04-09 07:19:11 +02:00
# endif
2007-09-29 18:14:03 +02:00
2007-05-12 01:41:31 +02:00
// the file pool that all storages in this session's
// torrents uses. It sets a limit on the number of
// open files by this session.
// file pool must be destructed after the torrents
// since they will still have references to it
// when they are destructed.
file_pool m_files ;
2008-02-08 11:22:05 +01:00
// this is where all active sockets are stored.
// the selector can sleep while there's no activity on
// them
2009-01-23 17:40:00 +01:00
mutable 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
2010-10-12 10:57:43 +02:00
asio : : ssl : : context m_ssl_ctx ;
# endif
2009-05-23 23:36:09 +02:00
// handles delayed alerts
alert_manager m_alerts ;
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-05-24 20:53:55 +02:00
// this is a list of half-open tcp connections
// (only outgoing connections)
// this has to be one of the last
// members to be destructed
connection_queue m_half_open ;
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
2009-05-14 19:21:19 +02:00
// the global rate limiter bandwidth channels
2009-04-26 02:21:59 +02:00
bandwidth_channel m_download_channel ;
bandwidth_channel m_upload_channel ;
2009-05-14 19:21:19 +02:00
// bandwidth channels for local peers when
// rate limits are ignored. They are only
// throttled by these global rate limiters
// and they don't have a rate limit set by
// default
bandwidth_channel m_local_download_channel ;
bandwidth_channel m_local_upload_channel ;
2010-11-29 02:33:05 +01:00
// all tcp peer connections are subject to these
// bandwidth limits. Local peers are excempted
// 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.
bandwidth_channel m_tcp_download_channel ;
bandwidth_channel m_tcp_upload_channel ;
2009-04-26 02:21:59 +02:00
bandwidth_channel * m_bandwidth_channel [ 2 ] ;
2011-01-30 11:04:15 +01:00
// the number of peer connections that are waiting
// for the disk. one for each channel.
// upload_channel means waiting to read from disk
// and download_channel is waiting to write to disk
int m_disk_queues [ 2 ] ;
2007-01-10 16:02:25 +01:00
2006-10-11 16:02:21 +02:00
tracker_manager m_tracker_manager ;
torrent_map m_torrents ;
2011-01-18 04:41:54 +01:00
std : : map < std : : string , boost : : shared_ptr < torrent > > m_uuids ;
2012-06-21 05:51:39 +02:00
// counters of how many of the active (non-paused) torrents
// are finished and downloading. This is used to weigh the
// priority of downloading and finished torrents when connecting
// more peers.
int m_num_active_downloading ;
int m_num_active_finished ;
2008-06-12 23:22:24 +02:00
typedef std : : list < boost : : shared_ptr < torrent > > check_queue_t ;
2010-01-17 22:42:14 +01:00
// this has all torrents that wants to be checked in it
2008-06-12 23:22:24 +02:00
check_queue_t m_queued_for_checking ;
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 ;
// filters incoming connections
ip_filter m_ip_filter ;
2007-06-01 03:05:57 +02:00
// filters outgoing connections
port_filter m_port_filter ;
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
int m_key ;
2007-09-22 18:27:29 +02:00
// the number of retries we make when binding the
// listen socket. For each retry the port number
// is incremented by one
int m_listen_port_retries ;
2006-10-11 16:02:21 +02:00
// the ip-address of the interface
// we are supposed to listen on.
// if the ip is set to zero, it means
// that we should let the os decide which
// interface to listen on
tcp : : endpoint m_listen_interface ;
2007-09-22 18:27:29 +02:00
// if we're listening on an IPv6 interface
// this is one of the non local IPv6 interfaces
// on this machine
tcp : : endpoint m_ipv6_interface ;
2009-04-12 02:37:06 +02:00
tcp : : endpoint m_ipv4_interface ;
2007-03-15 23:03:56 +01: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 ;
2012-01-14 17:04:25 +01:00
# ifdef TORRENT_USE_OPENSSL
void ssl_handshake ( error_code const & ec , boost : : shared_ptr < socket_type > s ) ;
# endif
2009-04-09 03:04:49 +02:00
// when as a socks proxy is used for peers, also
// listen for incoming connections on a socks connection
boost : : shared_ptr < socket_type > m_socks_listen_socket ;
2010-04-13 06:30:34 +02:00
boost : : uint16_t m_socks_listen_port ;
2009-04-09 03:04:49 +02:00
void open_new_incoming_socks_connection ( ) ;
2009-08-20 05:19:12 +02:00
# if TORRENT_USE_I2P
i2p_connection m_i2p_conn ;
boost : : shared_ptr < socket_type > m_i2p_listen_socket ;
# endif
2012-10-08 01:34:44 +02:00
void setup_listener ( listen_socket_t * s , tcp : : endpoint ep , int & retries
2011-02-16 07:35:53 +01:00
, bool v6_only , int flags , error_code & ec ) ;
2006-10-11 16:02:21 +02:00
2010-08-23 08:27:18 +02:00
// the proxy used for bittorrent
proxy_settings m_proxy ;
2006-10-11 16:02:21 +02:00
2010-03-04 17:42:39 +01:00
# ifndef TORRENT_DISABLE_DHT
entry m_dht_state ;
# endif
2006-10-11 16:02:21 +02:00
// set to true when the session object
// is being destructed and the thread
// should exit
2010-06-24 23:43:00 +02:00
bool m_abort ;
2006-10-11 16:02:21 +02:00
2008-06-29 21:08:30 +02:00
// is true if the session is paused
bool m_paused ;
2008-01-13 12:18:18 +01:00
// the number of unchoked peers as set by the auto-unchoker
// this should always be >= m_max_uploads
int m_allowed_upload_slots ;
2007-08-16 14:41:46 +02:00
// the number of unchoked peers
int m_num_unchoked ;
// 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.
int m_unchoke_time_scaler ;
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
int m_auto_manage_time_scaler ;
2007-08-16 14:41:46 +02:00
// works like unchoke_time_scaler but it
// is only decresed when the unchoke set
// is recomputed, and when it reaches zero,
// the optimistic unchoke is moved to another peer.
int m_optimistic_unchoke_time_scaler ;
// 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
int m_disconnect_time_scaler ;
2008-05-19 06:06:25 +02:00
// when this scaler reaches zero, it will
// scrape one of the auto managed, paused,
// torrents.
int m_auto_scrape_time_scaler ;
2010-01-15 17:45:42 +01:00
// the index of the torrent that we'll
// refresh the next time
int m_next_explicit_cache_torrent ;
// this is a counter of the number of seconds until
// the next time the read cache is rotated, if we're
// using an explicit read read cache.
int m_cache_rotation_timer ;
2006-10-11 16:02:21 +02:00
// statistics gathered from all torrents.
stat m_stat ;
2010-02-09 04:04:41 +01:00
int m_peak_up_rate ;
int m_peak_down_rate ;
2006-10-11 16:02:21 +02:00
// is false by default and set to true when
// the first incoming connection is established
// this is used to know if the client is behind
// NAT or not.
bool m_incoming_connection ;
2006-11-14 16:53:38 +01:00
2009-06-10 10:30:55 +02:00
void on_disk_queue ( ) ;
2009-04-26 02:21:59 +02:00
void on_tick ( error_code const & e ) ;
2012-07-04 22:41:22 +02:00
void try_connect_more_peers ( int num_downloads , int num_downloads_peers ) ;
2010-03-29 02:34:04 +02:00
void auto_manage_torrents ( std : : vector < torrent * > & list
, int & dht_limit , int & tracker_limit , int & lsd_limit
, int & hard_limit , int type_limit ) ;
2008-04-24 05:28:48 +02:00
void recalculate_auto_managed_torrents ( ) ;
void recalculate_unchoke_slots ( int congested_torrents
, int uncongested_torrents ) ;
2010-02-02 19:39:32 +01:00
void recalculate_optimistic_unchoke_slots ( ) ;
2008-04-24 05:28:48 +02:00
2009-04-30 07:49:46 +02:00
ptime m_created ;
int session_time ( ) const { return total_seconds ( time_now ( ) - m_created ) ; }
2007-04-05 00:27:36 +02:00
ptime m_last_tick ;
2009-04-26 02:21:59 +02:00
ptime m_last_second_tick ;
2011-01-23 03:09:54 +01:00
// used to limit how often disk warnings are generated
ptime m_last_disk_performance_warning ;
2011-03-16 08:45:51 +01:00
ptime m_last_disk_queue_performance_warning ;
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
ptime m_last_choke ;
2011-01-18 04:41:54 +01:00
// the time when the next rss feed needs updating
ptime m_next_rss_update ;
// update any rss feeds that need updating and
// recalculate m_next_rss_update
void update_rss_feeds ( ) ;
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
int m_next_port ;
2006-10-11 16:02:21 +02:00
# ifndef TORRENT_DISABLE_DHT
2007-03-02 02:16:59 +01:00
boost : : intrusive_ptr < dht : : dht_tracker > m_dht ;
2006-10-11 16:02:21 +02:00
dht_settings m_dht_settings ;
2007-03-15 23:03:56 +01:00
2008-09-02 08:37:40 +02:00
// these are used when starting the DHT
// (and bootstrapping it), and then erased
2010-02-14 08:46:57 +01:00
std : : list < udp : : endpoint > m_dht_router_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.
int m_dht_interval_update_torrents ;
2010-12-29 03:17:44 +01:00
# endif
2012-06-22 06:21:20 +02:00
bool incoming_packet ( error_code const & ec
, udp : : endpoint const & , char const * buf , int size ) ;
2012-06-21 17:05:57 +02:00
2010-05-30 03:33:03 +02:00
// see m_external_listen_port. This is the same
// but for the udp port used by the DHT.
int m_external_udp_port ;
rate_limited_udp_socket m_udp_socket ;
2010-11-29 02:33:05 +01:00
utp_socket_manager m_utp_socket_manager ;
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
int m_boost_connections ;
2007-06-06 02:41:20 +02:00
# ifndef TORRENT_DISABLE_ENCRYPTION
pe_settings m_pe_settings ;
# endif
2007-09-29 23:31:51 +02:00
boost : : intrusive_ptr < natpmp > m_natpmp ;
boost : : intrusive_ptr < upnp > m_upnp ;
boost : : intrusive_ptr < lsd > m_lsd ;
2007-03-15 23:03:56 +01:00
2012-01-14 17:04:25 +01:00
// mask is a bitmask of which protocols to remap on:
// 1: NAT-PMP
// 2: UPnP
void remap_tcp_ports ( boost : : uint32_t mask , int tcp_port , int ssl_port ) ;
2008-04-06 21:17:58 +02:00
// 0 is natpmp 1 is upnp
int m_tcp_mapping [ 2 ] ;
int m_udp_mapping [ 2 ] ;
2012-01-14 17:04:25 +01:00
# ifdef TORRENT_USE_OPENSSL
int m_ssl_mapping [ 2 ] ;
# endif
2008-04-06 21:17:58 +02: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 ;
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.
std : : deque < boost : : 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
std : : deque < std : : pair < boost : : weak_ptr < torrent > , int > > m_prio_torrents ;
2010-02-05 09:23:17 +01:00
// this announce timer is used
// by Local service discovery
deadline_timer m_lsd_announce_timer ;
2010-02-14 02:39:55 +01:00
tcp : : resolver m_host_resolver ;
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.
2007-05-05 02:29:33 +02:00
// This implements a round robin.
2010-02-05 09:23:17 +01:00
torrent_map : : iterator m_next_connect_torrent ;
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
// peers we have given to the torrent pointed to
// by m_next_connect_torrent. Once this reaches
// the number of connection attempts this particular
// torrent should have, the counter is reset and
// m_next_connect_torrent takes a step forward
// to give the next torrent its connection attempts.
int m_current_connect_attempts ;
2011-03-27 22:46:20 +02:00
// this is the round-robin cursor for peers that
// get to download again after the disk has been
// blocked
connection_map : : iterator m_next_disk_peer ;
2008-11-29 22:33:21 +01:00
# ifdef TORRENT_DEBUG
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
2011-02-03 05:09:50 +01:00
# ifdef TORRENT_DISK_STATS
2008-12-26 08:00:21 +01:00
void log_buffer_usage ( ) ;
2011-02-03 05:09:50 +01:00
// used to log send buffer usage statistics
std : : ofstream m_buffer_usage_logger ;
// the number of send buffers that are allocated
int m_buffer_allocations ;
2010-01-31 21:32:12 +01:00
# endif
2008-12-26 08:00:21 +01:00
2011-12-29 13:15:29 +01:00
# ifdef TORRENT_REQUEST_LOGGING
// used to log all requests from peers
FILE * m_request_log ;
# endif
2011-04-06 08:27:42 +02:00
# ifdef TORRENT_STATS
2011-02-11 18:39:22 +01:00
void rotate_stats_log ( ) ;
2011-04-06 08:27:42 +02:00
void print_log_line ( int tick_interval_ms , ptime now ) ;
void reset_stat_counters ( ) ;
void enable_stats_logging ( bool s ) ;
bool m_stats_logging_enabled ;
2011-02-11 18:39:22 +01:00
// the last time we rotated the log file
ptime m_last_log_rotation ;
2007-05-14 00:01:21 +02:00
// logger used to write bandwidth usage statistics
2011-02-11 18:39:22 +01:00
FILE * m_stats_logger ;
// sequence number for log file. Log files are
// rotated every hour and the sequence number is
// incremented by one
int m_log_seq ;
2011-02-03 07:22:22 +01:00
// the number of peers that were disconnected this
// tick due to protocol error
int m_error_peers ;
2011-02-04 05:31:20 +01:00
int m_disconnected_peers ;
int m_eof_peers ;
int m_connreset_peers ;
2012-03-02 09:52:54 +01:00
int m_connrefused_peers ;
int m_connaborted_peers ;
int m_perm_peers ;
int m_buffer_peers ;
int m_unreachable_peers ;
int m_broken_pipe_peers ;
int m_addrinuse_peers ;
int m_no_access_peers ;
int m_invalid_arg_peers ;
int m_aborted_peers ;
2012-03-09 07:24:01 +01:00
int m_piece_requests ;
int m_max_piece_requests ;
int m_invalid_piece_requests ;
int m_choked_piece_requests ;
int m_cancelled_piece_requests ;
int m_piece_rejects ;
2012-03-02 09:52:54 +01:00
int m_error_incoming_peers ;
int m_error_outgoing_peers ;
int m_error_rc4_peers ;
int m_error_encrypted_peers ;
int m_error_tcp_peers ;
int m_error_utp_peers ;
2011-02-06 04:07:00 +01:00
// the number of times the piece picker fell through
// to the end-game mode
2011-02-07 01:51:20 +01:00
int m_end_game_piece_picker_blocks ;
2011-02-07 00:40:21 +01:00
int m_piece_picker_blocks ;
2011-02-07 01:51:20 +01:00
int m_piece_picks ;
int m_reject_piece_picks ;
int m_unchoke_piece_picks ;
int m_incoming_redundant_piece_picks ;
int m_incoming_piece_picks ;
int m_end_game_piece_picks ;
int m_snubbed_piece_picks ;
2011-02-14 05:48:02 +01:00
int m_connect_timeouts ;
int m_uninteresting_peers ;
2011-02-14 06:38:59 +01:00
int m_timeout_peers ;
2011-11-24 18:50:57 +01:00
int m_no_memory_peers ;
int m_too_many_peers ;
int m_transport_timeout_peers ;
2011-03-11 08:37:12 +01:00
cache_status m_last_cache_status ;
2011-03-13 05:34:57 +01:00
size_type m_last_failed ;
size_type m_last_redundant ;
size_type m_last_uploaded ;
size_type m_last_downloaded ;
2011-03-17 06:31:06 +01:00
int m_connection_attempts ;
int m_num_banned_peers ;
int m_banned_for_hash_failure ;
2011-06-29 00:20:34 +02:00
vm_statistics_data_t m_last_vm_stat ;
2011-10-17 19:12:08 +02:00
thread_cpu_usage m_network_thread_cpu_usage ;
2011-07-04 07:52:15 +02:00
sliding_average < 20 > m_read_ops ;
sliding_average < 20 > m_write_ops ; ;
2011-10-17 07:17:21 +02:00
enum
{
on_read_counter ,
on_write_counter ,
on_tick_counter ,
on_lsd_counter ,
on_lsd_peer_counter ,
on_udp_counter ,
on_accept_counter ,
on_disk_queue_counter ,
on_disk_read_counter ,
on_disk_write_counter ,
max_messages
} ;
int m_num_messages [ max_messages ] ;
2011-10-17 08:54:02 +02:00
// 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
// 16384, 32768, 65536, 131072, 262144, 524288, 1048576
int m_send_buffer_sizes [ 18 ] ;
int m_recv_buffer_sizes [ 18 ] ;
2007-05-14 00:01:21 +02:00
# endif
2010-02-14 02:39:55 +01:00
// each second tick the timer takes a little
// bit longer than one second to trigger. The
// extra time it took is accumulated into this
// counter. Every time it exceeds 1000, torrents
// will tick their timers 2 seconds instead of one.
// this keeps the timers more accurate over time
// as a kind of "leap second" to adjust for the
// accumulated error
boost : : uint16_t m_tick_residual ;
2011-03-04 08:00:27 +01:00
// the number of torrents that have apply_ip_filter
// set to false. This is typically 0
int m_non_filtered_torrents ;
2008-02-17 23:51:03 +01:00
# if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
2006-11-30 12:56:19 +01:00
boost : : shared_ptr < logger > create_log ( std : : string const & name
, int instance , bool append = true ) ;
2006-11-15 22:39:58 +01:00
2012-10-18 17:14:18 +02:00
void session_log ( char const * fmt , . . . ) const ;
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
std : : list < boost : : shared_ptr < tracker_logger > > m_tracker_loggers ;
2007-05-05 02:29:33 +02:00
2012-10-07 01:45:36 +02:00
std : : string get_log_path ( ) const
{ return m_logpath ; }
2009-10-26 02:29:39 +01:00
std : : string m_logpath ;
2010-07-14 06:16:38 +02:00
2006-10-11 16:02:21 +02:00
private :
2008-03-29 23:45:55 +01:00
2008-10-22 03:12:14 +02:00
# endif
# ifdef TORRENT_UPNP_LOGGING
std : : ofstream m_upnp_log ;
2006-10-11 16:02:21 +02:00
# endif
2012-12-31 07:54:54 +01:00
// TODO: factor the IP voting out to its own type, maybe templated by the address type. Have one IPv4 vote and a separate IPv6 vote. Maybe even better, have one per local interface sockets can be bound to
2010-12-24 02:31:41 +01:00
struct external_ip_t
{
external_ip_t ( ) : sources ( 0 ) , num_votes ( 0 ) { }
bool add_vote ( sha1_hash const & k , int type ) ;
bool operator < ( external_ip_t const & rhs ) const
{
if ( num_votes < rhs . num_votes ) return true ;
2012-03-19 01:31:21 +01:00
if ( num_votes > rhs . num_votes ) return false ;
2010-12-24 02:31:41 +01:00
return sources < rhs . sources ;
}
// this is a bloom filter of the IPs that have
// reported this address
bloom_filter < 16 > voters ;
// this is the actual external address
address addr ;
// a bitmask of sources the reporters have come from
boost : : uint16_t sources ;
// the total number of votes for this IP
boost : : uint16_t num_votes ;
} ;
// this is a bloom filter of all the IPs that have
// been the first to report an external address. Each
// IP only gets to add a new item once.
bloom_filter < 32 > m_external_address_voters ;
std : : vector < external_ip_t > m_external_addresses ;
2008-03-29 23:45:55 +01:00
address m_external_address ;
2006-10-11 16:02:21 +02:00
2006-11-14 01:08:16 +01:00
# ifndef TORRENT_DISABLE_EXTENSIONS
typedef std : : list < boost : : function < boost : : shared_ptr <
2007-09-14 02:11:33 +02:00
torrent_plugin > ( torrent * , void * ) > > extension_list_t ;
2006-11-14 01:08:16 +01:00
extension_list_t m_extensions ;
2011-01-29 11:37:21 +01:00
typedef std : : list < boost : : shared_ptr < plugin > > ses_extension_list_t ;
ses_extension_list_t m_ses_extensions ;
2006-11-14 01:08:16 +01:00
# endif
2008-04-05 06:53:22 +02:00
# ifndef TORRENT_DISABLE_GEO_IP
2008-04-11 10:46:43 +02:00
GeoIP * m_asnum_db ;
GeoIP * m_country_db ;
2008-04-05 06:53:22 +02:00
// maps AS number to the peak download rate
// we've seen from it. Entries are never removed
// from this map. Pointers to its elements
// are kept in the policy::peer structures.
std : : map < int , int > m_as_peak ;
# endif
2008-07-11 09:30:04 +02:00
// total redundant and failed bytes
size_type m_total_failed_bytes ;
size_type m_total_redundant_bytes ;
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.
bool m_pending_auto_manage ;
// 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.
bool m_need_auto_manage ;
2011-11-16 03:29:59 +01:00
// redundant bytes per category
size_type m_redundant_bytes [ 7 ] ;
2011-01-18 04:41:54 +01:00
std : : vector < boost : : shared_ptr < feed > > m_feeds ;
2011-11-15 03:34:00 +01:00
// this is the set of (subscribed) torrents that have changed
// their states since the last time the user requested updates.
std : : vector < boost : : weak_ptr < torrent > > m_state_updates ;
2006-10-11 16:02:21 +02:00
// the main working thread
2009-10-20 04:49:56 +02:00
boost : : scoped_ptr < thread > m_thread ;
2010-12-04 23:20:31 +01:00
2011-05-08 11:04:59 +02:00
# if (defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS) && defined BOOST_HAS_PTHREADS
2010-12-04 23:20:31 +01:00
pthread_t m_network_thread ;
# endif
2006-10-11 16:02:21 +02:00
} ;
2006-11-15 22:39:58 +01:00
2008-02-17 23:51:03 +01:00
# if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
2006-11-15 22:39:58 +01:00
struct tracker_logger : request_callback
{
tracker_logger ( session_impl & ses ) : m_ses ( ses ) { }
2008-04-24 03:35:48 +02:00
void tracker_warning ( tracker_request const & req
, std : : string const & str )
2006-11-15 22:39:58 +01:00
{
2012-09-28 01:04:51 +02:00
debug_log ( " *** tracker warning: %s " , str . c_str ( ) ) ;
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
2006-11-15 22:39:58 +01:00
, std : : vector < peer_entry > & peers
, int interval
2009-12-03 18:44:11 +01:00
, int min_interval
2006-11-15 22:39:58 +01:00
, int complete
2008-03-30 20:31:30 +02:00
, int incomplete
2010-11-26 21:44:48 +01:00
, address const & external_ip
, std : : string const & tracker_id )
2006-11-15 22:39:58 +01:00
{
2009-04-04 11:52:25 +02:00
std : : string s ;
s = " TRACKER RESPONSE: \n " ;
char tmp [ 200 ] ;
2009-12-03 18:44:11 +01:00
snprintf ( tmp , 200 , " interval: %d \n min_interval: %d \n peers: \n " , interval , min_interval ) ;
2009-04-04 11:52:25 +02:00
s + = tmp ;
2006-11-15 22:39:58 +01:00
for ( std : : vector < peer_entry > : : const_iterator i = peers . begin ( ) ;
i ! = peers . end ( ) ; + + i )
{
2009-04-04 11:52:25 +02:00
char pid [ 41 ] ;
to_hex ( ( const char * ) & i - > pid [ 0 ] , 20 , pid ) ;
if ( i - > pid . is_all_zeros ( ) ) pid [ 0 ] = 0 ;
2009-05-15 23:23:41 +02:00
snprintf ( tmp , 200 , " %-16s %-5d %s \n " , i - > ip . c_str ( ) , i - > port , pid ) ;
2009-04-04 11:52:25 +02:00
s + = tmp ;
2006-11-15 22:39:58 +01:00
}
2009-04-04 11:52:25 +02:00
snprintf ( tmp , 200 , " external ip: %s \n " , print_address ( external_ip ) . c_str ( ) ) ;
s + = tmp ;
2012-09-28 01:04:51 +02:00
debug_log ( " %s " , s . c_str ( ) ) ;
2006-11-15 22:39:58 +01:00
}
void tracker_request_timed_out (
tracker_request const & )
{
debug_log ( " *** tracker timed out " ) ;
}
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
2009-12-28 21:59:34 +01:00
, int retry_interval )
2006-11-15 22:39:58 +01:00
{
2012-09-28 01:04:51 +02:00
debug_log ( " *** tracker error: %d: %s %s "
2010-03-20 10:35:45 +01:00
, response_code , ec . message ( ) . c_str ( ) , str . c_str ( ) ) ;
2006-11-15 22:39:58 +01:00
}
2012-09-28 01:04:51 +02:00
void debug_log ( const char * fmt , . . . ) const
2006-11-15 22:39:58 +01:00
{
2012-09-28 01:04:51 +02:00
if ( ! m_ses . m_logger ) return ;
va_list v ;
va_start ( v , fmt ) ;
char usr [ 1024 ] ;
vsnprintf ( usr , sizeof ( usr ) , fmt , v ) ;
va_end ( v ) ;
char buf [ 1280 ] ;
snprintf ( buf , sizeof ( buf ) , " %s: %s \n " , time_now_string ( ) , usr ) ;
( * m_ses . m_logger ) < < buf ;
2006-11-15 22:39:58 +01:00
}
session_impl & m_ses ;
} ;
# endif
2006-10-11 16:02:21 +02:00
}
}
# endif