52
50
#pragma warning(push, 1)
55
#include <boost/limits.hpp>
56
#include <boost/tuple/tuple.hpp>
57
53
#include <boost/filesystem/path.hpp>
58
54
#include <boost/thread.hpp>
59
#include <boost/thread/recursive_mutex.hpp>
60
55
#include <boost/thread/condition.hpp>
56
#include <boost/pool/object_pool.hpp>
63
59
#pragma warning(pop)
68
64
#include "libtorrent/socket.hpp"
69
65
#include "libtorrent/peer_id.hpp"
70
66
#include "libtorrent/tracker_manager.hpp"
71
#include "libtorrent/alert.hpp"
72
67
#include "libtorrent/debug.hpp"
73
68
#include "libtorrent/piece_block_progress.hpp"
74
69
#include "libtorrent/ip_filter.hpp"
82
77
#include "libtorrent/socket_type.hpp"
83
78
#include "libtorrent/connection_queue.hpp"
84
79
#include "libtorrent/disk_io_thread.hpp"
80
#include "libtorrent/udp_socket.hpp"
85
81
#include "libtorrent/assert.hpp"
86
#include "libtorrent/udp_socket.hpp"
82
#include "libtorrent/policy.hpp" // for policy::peer
83
#include "libtorrent/alert.hpp" // for alert_manager
88
85
#if TORRENT_COMPLETE_TYPES_REQUIRED
89
86
#include "libtorrent/peer_connection.hpp"
112
111
struct tracker_logger;
114
// used to initialize the g_current_time before
116
struct initialize_timer
115
121
// this is the link between the main thread and the
116
122
// thread started to run the main downloader loop
117
struct session_impl: boost::noncopyable
123
struct session_impl: boost::noncopyable, initialize_timer
120
126
// the size of each allocation that is chained in the send buffer
121
enum { send_buffer_size = 200 };
127
enum { send_buffer_size = 128 };
123
129
#ifdef TORRENT_DEBUG
124
130
friend class ::libtorrent::peer_connection;
161
167
tcp::endpoint get_ipv4_interface() const;
163
169
void async_accept(boost::shared_ptr<socket_acceptor> const& listener);
164
void on_incoming_connection(boost::shared_ptr<socket_type> const& s
170
void on_accept_connection(boost::shared_ptr<socket_type> const& s
165
171
, boost::weak_ptr<socket_acceptor> listener, error_code const& e);
172
void on_socks_accept(boost::shared_ptr<socket_type> const& s
173
, error_code const& e);
175
void incoming_connection(boost::shared_ptr<socket_type> const& s);
167
177
// must be locked to access the data
168
178
// in this struct
169
typedef boost::recursive_mutex mutex_t;
179
typedef boost::mutex mutex_t;
170
180
mutable mutex_t m_mutex;
172
182
boost::weak_ptr<torrent> find_torrent(const sha1_hash& info_hash);
173
183
peer_id const& get_peer_id() const { return m_peer_id; }
175
void close_connection(peer_connection const* p
176
, char const* message);
185
void close_connection(peer_connection const* p, error_code const& ec);
178
187
void set_settings(session_settings const& s);
179
188
session_settings const& settings() const { return m_settings; }
184
193
void add_dht_router(std::pair<std::string, int> const& node);
185
194
void set_dht_settings(dht_settings const& s);
186
195
dht_settings const& get_dht_settings() const { return m_dht_settings; }
187
198
void start_dht(entry const& startup_state);
190
entry dht_state() const;
200
#ifndef TORRENT_NO_DEPRECATE
201
entry dht_state(session_impl::mutex_t::scoped_lock& l) const;
203
void maybe_update_udp_mapping(int nat, int local_port, int external_port);
191
204
void on_dht_router_name_lookup(error_code const& e
192
205
, tcp::resolver::iterator host);
197
210
pe_settings const& get_pe_settings() const { return m_pe_settings; }
213
void on_port_map_log(char const* msg, int map_transport);
215
void on_lsd_announce(error_code const& e);
200
217
// called when a port mapping is successful, or a router returns
201
218
// a failure to map a port
202
void on_port_mapping(int mapping, int port, std::string const& errmsg
219
void on_port_mapping(int mapping, int port, error_code const& ec
203
220
, int nat_transport);
205
222
bool is_aborted() const { return m_abort; }
218
235
, const char* net_interface = 0);
219
236
bool is_listening() const;
221
torrent_handle add_torrent(add_torrent_params const&);
238
torrent_handle add_torrent(add_torrent_params const&, error_code& ec);
223
240
void remove_torrent(torrent_handle const& h, int options);
225
242
std::vector<torrent_handle> get_torrents();
227
void check_torrent(boost::shared_ptr<torrent> const& t);
228
void done_checking(boost::shared_ptr<torrent> const& t);
244
void queue_check_torrent(boost::shared_ptr<torrent> const& t);
245
void dequeue_check_torrent(boost::shared_ptr<torrent> const& t);
230
247
void set_alert_mask(int m);
231
248
size_t set_alert_queue_size_limit(size_t queue_size_limit_);
232
249
std::auto_ptr<alert> pop_alert();
250
void set_alert_dispatch(boost::function<void(alert const&)> const&);
234
252
alert const* wait_for_alert(time_duration max_wait);
236
254
int upload_rate_limit() const;
237
255
int download_rate_limit() const;
256
int local_upload_rate_limit() const;
257
int local_download_rate_limit() const;
259
void set_local_download_rate_limit(int bytes_per_second);
260
void set_local_upload_rate_limit(int bytes_per_second);
239
262
void set_download_rate_limit(int bytes_per_second);
240
263
void set_upload_rate_limit(int bytes_per_second);
251
274
{ return m_connections.size(); }
253
276
void unchoke_peer(peer_connection& c);
277
void choke_peer(peer_connection& c);
255
279
session_status status() const;
256
280
void set_peer_id(peer_id const& id);
264
288
void announce_lsd(sha1_hash const& ih);
290
void save_state(entry& e, boost::uint32_t flags, session_impl::mutex_t::scoped_lock& l) const;
291
void load_state(lazy_entry const& e);
266
293
void set_peer_proxy(proxy_settings const& s)
267
{ m_peer_proxy = s; }
296
// in case we just set a socks proxy, we might have to
297
// open the socks incoming connection
298
if (!m_socks_listen_socket) open_new_incoming_socks_connection();
268
300
void set_web_seed_proxy(proxy_settings const& s)
269
301
{ m_web_seed_proxy = s; }
270
302
void set_tracker_proxy(proxy_settings const& s)
297
329
bool load_country_db(char const* file);
298
330
bool has_country_db() const { return m_country_db; }
299
331
char const* country_for_ip(address const& a);
333
#ifndef BOOST_FILESYSTEM_NARROW_ONLY
334
bool load_asnum_db(wchar_t const* file);
335
bool load_country_db(wchar_t const* file);
302
339
void load_state(entry const& ses_state);
303
340
entry state() const;
305
342
void start_lsd();
306
natpmp* start_natpmp();
343
void start_natpmp(natpmp* n);
344
void start_upnp(upnp* u);
310
347
void stop_natpmp();
324
361
m_total_failed_bytes += b;
327
// handles delayed alerts
328
alert_manager m_alerts;
330
364
std::pair<char*, int> allocate_buffer(int size);
331
365
void free_buffer(char* buf, int size);
333
char* allocate_disk_buffer();
367
char* allocate_disk_buffer(char const* category);
334
368
void free_disk_buffer(char* buf);
336
370
void set_external_address(address const& ip);
341
void dht_state_callback(boost::condition& c
375
void update_disk_thread_settings();
376
void on_dht_state_callback(boost::condition& c
342
377
, entry& e, bool& done) const;
343
378
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
379
void setup_socket_buffers(socket_type& s);
381
// this is a shared pool where policy_peer objects
382
// are allocated. It's a pool since we're likely
383
// to have tens of thousands of peers, and a pool
384
// saves significant overhead
386
struct logging_allocator
388
typedef std::size_t size_type;
389
typedef std::ptrdiff_t difference_type;
391
static char* malloc(const size_type bytes)
393
allocated_bytes += bytes;
395
return (char*)::malloc(bytes);
398
static void free(char* const block)
401
return ::free(block);
404
static int allocations;
405
static int allocated_bytes;
408
policy::ipv4_peer, logging_allocator> m_ipv4_peer_pool;
409
# if TORRENT_USE_IPV6
411
policy::ipv6_peer, logging_allocator> m_ipv6_peer_pool;
414
boost::object_pool<policy::ipv4_peer> m_ipv4_peer_pool;
415
# if TORRENT_USE_IPV6
416
boost::object_pool<policy::ipv6_peer> m_ipv6_peer_pool;
420
// this vector is used to store the block_info
421
// objects pointed to by partial_piece_info returned
422
// by torrent::get_download_queue.
423
std::vector<block_info> m_block_info_storage;
345
425
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
346
426
// this pool is used to allocate and recycle send
365
445
tcp::resolver m_host_resolver;
447
// handles delayed alerts
448
alert_manager m_alerts;
367
450
// handles disk io requests asynchronously
368
451
// peers have pointers into the disk buffer
369
452
// pool, and must be destructed before this
384
467
// handing out bandwidth to connections that
385
468
// asks for it, it can also throttle the
387
bandwidth_manager<peer_connection, torrent> m_download_channel;
388
bandwidth_manager<peer_connection, torrent> m_upload_channel;
390
bandwidth_manager<peer_connection, torrent>* m_bandwidth_manager[2];
470
bandwidth_manager<peer_connection> m_download_rate;
471
bandwidth_manager<peer_connection> m_upload_rate;
473
// the global rate limiter bandwidth channels
474
bandwidth_channel m_download_channel;
475
bandwidth_channel m_upload_channel;
477
// bandwidth channels for local peers when
478
// rate limits are ignored. They are only
479
// throttled by these global rate limiters
480
// and they don't have a rate limit set by
482
bandwidth_channel m_local_download_channel;
483
bandwidth_channel m_local_upload_channel;
485
bandwidth_channel* m_bandwidth_channel[2];
392
487
tracker_manager m_tracker_manager;
393
488
torrent_map m_torrents;
394
489
typedef std::list<boost::shared_ptr<torrent> > check_queue_t;
491
// this has all torrents that wants to be checked in it
395
492
check_queue_t m_queued_for_checking;
397
494
// this maps sockets to their peer_connection
450
547
// we might need more than one listen socket
451
548
std::list<listen_socket_t> m_listen_sockets;
550
// when as a socks proxy is used for peers, also
551
// listen for incoming connections on a socks connection
552
boost::shared_ptr<socket_type> m_socks_listen_socket;
554
void open_new_incoming_socks_connection();
453
556
listen_socket_t setup_listener(tcp::endpoint ep, int retries, bool v6_only = false);
455
558
// the settings for the client
522
628
bool m_incoming_connection;
524
void second_tick(error_code const& e);
630
void on_disk_queue();
631
void on_tick(error_code const& e);
633
int auto_manage_torrents(std::vector<torrent*>& list
634
, int hard_limit, int type_limit);
525
635
void recalculate_auto_managed_torrents();
526
636
void recalculate_unchoke_slots(int congested_torrents
527
637
, int uncongested_torrents);
638
void recalculate_optimistic_unchoke_slot();
641
int session_time() const { return total_seconds(time_now() - m_created); }
529
643
ptime m_last_tick;
644
ptime m_last_second_tick;
646
// the last time we went through the peers
647
// to decide which ones to choke/unchoke
531
650
// when outgoing_ports is configured, this is the
532
651
// port we'll bind the next outgoing socket to
545
664
// but for the udp port used by the DHT.
546
665
int m_external_udp_port;
548
udp_socket m_dht_socket;
667
rate_limited_udp_socket m_dht_socket;
550
669
// these are used when starting the DHT
551
670
// (and bootstrapping it), and then erased
567
686
int m_tcp_mapping[2];
568
687
int m_udp_mapping[2];
570
// the timer used to fire the second_tick
689
// the timer used to fire the tick
571
690
deadline_timer m_timer;
692
// torrents are announced on the local network in a
693
// round-robin fashion. All torrents are cycled through
694
// within the LSD announce interval (which defaults to
696
torrent_map::iterator m_next_lsd_torrent;
698
// this announce timer is used
699
// by Local service discovery
700
deadline_timer m_lsd_announce_timer;
573
702
// the index of the torrent that will be offered to
574
// connect to a peer next time second_tick is called.
703
// connect to a peer next time on_tick is called.
575
704
// This implements a round robin.
576
int m_next_connect_torrent;
705
torrent_map::iterator m_next_connect_torrent;
577
706
#ifdef TORRENT_DEBUG
578
707
void check_invariant() const;
710
#if defined TORRENT_STATS && defined TORRENT_DISK_STATS
582
711
void log_buffer_usage();
714
#if defined TORRENT_STATS
584
715
// logger used to write bandwidth usage statistics
585
716
std::ofstream m_stats_logger;
586
717
int m_second_counter;
645
779
void tracker_response(tracker_request const&
780
, libtorrent::address const& tracker_ip
781
, std::list<address> const& ip_list
646
782
, std::vector<peer_entry>& peers
650
787
, address const& external_ip)
653
s << "TRACKER RESPONSE:\n"
654
"interval: " << interval << "\n"
790
s = "TRACKER RESPONSE:\n";
792
snprintf(tmp, 200, "interval: %d\nmin_interval: %d\npeers:\n", interval, min_interval);
656
794
for (std::vector<peer_entry>::const_iterator i = peers.begin();
657
795
i != peers.end(); ++i)
659
s << " " << std::setfill(' ') << std::setw(16) << i->ip
660
<< " " << std::setw(5) << std::dec << i->port << " ";
661
if (!i->pid.is_all_zeros()) s << " " << i->pid;
798
to_hex((const char*)&i->pid[0], 20, pid);
799
if (i->pid.is_all_zeros()) pid[0] = 0;
801
snprintf(tmp, 200, " %-16s %-5d %s\n", i->ip.c_str(), i->port, pid);
664
s << "external ip: " << external_ip << "\n";
804
snprintf(tmp, 200, "external ip: %s\n", print_address(external_ip).c_str());
668
809
void tracker_request_timed_out(
674
815
void tracker_request_error(
675
816
tracker_request const&
676
817
, int response_code
677
, const std::string& str)
818
, const std::string& str
819
, int retry_interval)
679
debug_log(std::string("*** tracker error: ")
680
+ boost::lexical_cast<std::string>(response_code) + ": "
822
snprintf(msg, sizeof(msg), "*** tracker error: %d: %s", response_code, str.c_str());
684
826
void debug_log(const std::string& line)