~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to include/libtorrent/aux_/session_impl.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2010-08-10 12:59:37 UTC
  • mfrom: (1.3.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810125937-jbcmmf17y8yo9hgz
Tags: 0.15.0-0ubuntu1
* New upstream version.
* debian/patches/100_fix_html_docs.patch: refreshed.
* debian/control: bump up standards-version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#ifndef TORRENT_SESSION_IMPL_HPP_INCLUDED
34
34
#define TORRENT_SESSION_IMPL_HPP_INCLUDED
35
35
 
36
 
#include <ctime>
37
36
#include <algorithm>
38
37
#include <vector>
39
38
#include <set>
40
39
#include <list>
41
 
#include <deque>
42
40
 
43
41
#ifndef TORRENT_DISABLE_GEO_IP
44
42
#ifdef WITH_SHIPPED_GEOIP_H
52
50
#pragma warning(push, 1)
53
51
#endif
54
52
 
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>
61
57
 
62
58
#ifdef _MSC_VER
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
87
84
 
88
85
#if TORRENT_COMPLETE_TYPES_REQUIRED
89
86
#include "libtorrent/peer_connection.hpp"
97
94
        class upnp;
98
95
        class natpmp;
99
96
        class lsd;
100
 
        class fingerprint;
 
97
        struct fingerprint;
 
98
        class torrent;
 
99
        class alert;
101
100
 
102
101
        namespace dht
103
102
        {
104
 
                class dht_tracker;
 
103
                struct dht_tracker;
105
104
        }
106
105
 
107
106
        namespace aux
112
111
                struct tracker_logger;
113
112
#endif
114
113
 
 
114
                // used to initialize the g_current_time before
 
115
                // anything else
 
116
                struct initialize_timer
 
117
                {
 
118
                        initialize_timer();
 
119
                };
 
120
 
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
118
124
                {
119
125
 
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 };
122
128
 
123
129
#ifdef TORRENT_DEBUG
124
130
                        friend class ::libtorrent::peer_connection;
161
167
                        tcp::endpoint get_ipv4_interface() const;
162
168
 
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);
 
174
 
 
175
                        void incoming_connection(boost::shared_ptr<socket_type> const& s);
166
176
                
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;
171
181
 
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; }
174
184
 
175
 
                        void close_connection(peer_connection const* p
176
 
                                , char const* message);
 
185
                        void close_connection(peer_connection const* p, error_code const& ec);
177
186
 
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; }
 
196
                        void start_dht();
 
197
                        void stop_dht();
187
198
                        void start_dht(entry const& startup_state);
188
 
                        void stop_dht();
189
199
 
190
 
                        entry dht_state() const;
 
200
#ifndef TORRENT_NO_DEPRECATE
 
201
                        entry dht_state(session_impl::mutex_t::scoped_lock& l) const;
 
202
#endif
 
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);
193
206
#endif
197
210
                        pe_settings const& get_pe_settings() const { return m_pe_settings; }
198
211
#endif
199
212
 
 
213
                        void on_port_map_log(char const* msg, int map_transport);
 
214
 
 
215
                        void on_lsd_announce(error_code const& e);
 
216
 
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);
204
221
 
205
222
                        bool is_aborted() const { return m_abort; }
218
235
                                , const char* net_interface = 0);
219
236
                        bool is_listening() const;
220
237
 
221
 
                        torrent_handle add_torrent(add_torrent_params const&);
 
238
                        torrent_handle add_torrent(add_torrent_params const&, error_code& ec);
222
239
 
223
240
                        void remove_torrent(torrent_handle const& h, int options);
224
241
 
225
242
                        std::vector<torrent_handle> get_torrents();
226
243
                        
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);
229
246
 
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&);
233
251
 
234
252
                        alert const* wait_for_alert(time_duration max_wait);
235
253
 
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;
 
258
 
 
259
                        void set_local_download_rate_limit(int bytes_per_second);
 
260
                        void set_local_upload_rate_limit(int bytes_per_second);
238
261
 
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(); }
252
275
 
253
276
                        void unchoke_peer(peer_connection& c);
 
277
                        void choke_peer(peer_connection& c);
254
278
 
255
279
                        session_status status() const;
256
280
                        void set_peer_id(peer_id const& id);
263
287
 
264
288
                        void announce_lsd(sha1_hash const& ih);
265
289
 
 
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);
 
292
 
266
293
                        void set_peer_proxy(proxy_settings const& s)
267
 
                        { m_peer_proxy = s; }
 
294
                        {
 
295
                                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();
 
299
                        }
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);
 
332
 
 
333
#ifndef BOOST_FILESYSTEM_NARROW_ONLY
 
334
                        bool load_asnum_db(wchar_t const* file);
 
335
                        bool load_country_db(wchar_t const* file);
 
336
#endif
300
337
#endif
301
338
 
302
339
                        void load_state(entry const& ses_state);
303
340
                        entry state() const;
304
341
 
305
342
                        void start_lsd();
306
 
                        natpmp* start_natpmp();
307
 
                        upnp* start_upnp();
 
343
                        void start_natpmp(natpmp* n);
 
344
                        void start_upnp(upnp* u);
308
345
 
309
346
                        void stop_lsd();
310
347
                        void stop_natpmp();
324
361
                                m_total_failed_bytes += b;
325
362
                        }
326
363
 
327
 
                        // handles delayed alerts
328
 
                        alert_manager m_alerts;
329
 
 
330
364
                        std::pair<char*, int> allocate_buffer(int size);
331
365
                        void free_buffer(char* buf, int size);
332
366
 
333
 
                        char* allocate_disk_buffer();
 
367
                        char* allocate_disk_buffer(char const* category);
334
368
                        void free_disk_buffer(char* buf);
335
369
 
336
370
                        void set_external_address(address const& ip);
338
372
 
339
373
//              private:
340
374
 
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);
 
380
 
 
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
 
385
#ifdef TORRENT_STATS
 
386
                        struct logging_allocator
 
387
                        {
 
388
                                typedef std::size_t size_type;
 
389
                                typedef std::ptrdiff_t difference_type;
 
390
 
 
391
                                static char* malloc(const size_type bytes)
 
392
                                {
 
393
                                        allocated_bytes += bytes;
 
394
                                        ++allocations;
 
395
                                        return (char*)::malloc(bytes);
 
396
                                }
 
397
 
 
398
                                static void free(char* const block)
 
399
                                {
 
400
                                        --allocations;
 
401
                                        return ::free(block);
 
402
                                }
 
403
                        
 
404
                                static int allocations;
 
405
                                static int allocated_bytes;
 
406
                        };
 
407
                        boost::object_pool<
 
408
                                policy::ipv4_peer, logging_allocator> m_ipv4_peer_pool;
 
409
# if TORRENT_USE_IPV6
 
410
                        boost::object_pool<
 
411
                                policy::ipv6_peer, logging_allocator> m_ipv6_peer_pool;
 
412
# endif
 
413
#else
 
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;
 
417
# endif
 
418
#endif
 
419
 
 
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;
344
424
 
345
425
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
346
426
                        // this pool is used to allocate and recycle send
364
444
 
365
445
                        tcp::resolver m_host_resolver;
366
446
 
 
447
                        // handles delayed alerts
 
448
                        alert_manager m_alerts;
 
449
 
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
386
469
                        // rate.
387
 
                        bandwidth_manager<peer_connection, torrent> m_download_channel;
388
 
                        bandwidth_manager<peer_connection, torrent> m_upload_channel;
389
 
 
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;
 
472
 
 
473
                        // the global rate limiter bandwidth channels
 
474
                        bandwidth_channel m_download_channel;
 
475
                        bandwidth_channel m_upload_channel;
 
476
 
 
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
 
481
                        // default
 
482
                        bandwidth_channel m_local_download_channel;
 
483
                        bandwidth_channel m_local_upload_channel;
 
484
 
 
485
                        bandwidth_channel* m_bandwidth_channel[2];
391
486
 
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;
 
490
 
 
491
                        // this has all torrents that wants to be checked in it
395
492
                        check_queue_t m_queued_for_checking;
396
493
 
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;
452
549
 
 
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;
 
553
 
 
554
                        void open_new_incoming_socks_connection();
 
555
 
453
556
                        listen_socket_t setup_listener(tcp::endpoint ep, int retries, bool v6_only = false);
454
557
 
455
558
                        // the settings for the client
463
566
                        proxy_settings m_dht_proxy;
464
567
#endif
465
568
 
 
569
#ifndef TORRENT_DISABLE_DHT     
 
570
                        entry m_dht_state;
 
571
#endif
466
572
                        // set to true when the session object
467
573
                        // is being destructed and the thread
468
574
                        // should exit
521
627
                        // NAT or not.
522
628
                        bool m_incoming_connection;
523
629
                        
524
 
                        void second_tick(error_code const& e);
 
630
                        void on_disk_queue();
 
631
                        void on_tick(error_code const& e);
 
632
 
 
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();
 
639
 
 
640
                        ptime m_created;
 
641
                        int session_time() const { return total_seconds(time_now() - m_created); }
528
642
 
529
643
                        ptime m_last_tick;
 
644
                        ptime m_last_second_tick;
 
645
 
 
646
                        // the last time we went through the peers
 
647
                        // to decide which ones to choke/unchoke
 
648
                        ptime m_last_choke;
530
649
 
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;
547
666
 
548
 
                        udp_socket m_dht_socket;
 
667
                        rate_limited_udp_socket m_dht_socket;
549
668
 
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];
569
688
 
570
 
                        // the timer used to fire the second_tick
 
689
                        // the timer used to fire the tick
571
690
                        deadline_timer m_timer;
572
691
 
 
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
 
695
                        // 5 minutes)
 
696
                        torrent_map::iterator m_next_lsd_torrent;
 
697
 
 
698
                        // this announce timer is used
 
699
                        // by Local service discovery
 
700
                        deadline_timer m_lsd_announce_timer;
 
701
 
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;
579
708
#endif
580
709
 
581
 
#ifdef TORRENT_STATS
 
710
#if defined TORRENT_STATS && defined TORRENT_DISK_STATS
582
711
                        void log_buffer_usage();
 
712
#endif
583
713
 
 
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;
604
735
                private:
605
736
 
606
737
#endif
 
738
#ifdef TORRENT_UPNP_LOGGING
 
739
                        std::ofstream m_upnp_log;
 
740
#endif
607
741
                        address m_external_address;
608
742
 
609
743
#ifndef TORRENT_DISABLE_EXTENSIONS
643
777
                        }
644
778
 
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
647
783
                                , int interval
 
784
                                , int min_interval
648
785
                                , int complete
649
786
                                , int incomplete
650
787
                                , address const& external_ip)
651
788
                        {
652
 
                                std::stringstream s;
653
 
                                s << "TRACKER RESPONSE:\n"
654
 
                                        "interval: " << interval << "\n"
655
 
                                        "peers:\n";
 
789
                                std::string s;
 
790
                                s = "TRACKER RESPONSE:\n";
 
791
                                char tmp[200];
 
792
                                snprintf(tmp, 200, "interval: %d\nmin_interval: %d\npeers:\n", interval, min_interval);
 
793
                                s += tmp;
656
794
                                for (std::vector<peer_entry>::const_iterator i = peers.begin();
657
795
                                        i != peers.end(); ++i)
658
796
                                {
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;
662
 
                                        s << "\n";
 
797
                                        char pid[41];
 
798
                                        to_hex((const char*)&i->pid[0], 20, pid);
 
799
                                        if (i->pid.is_all_zeros()) pid[0] = 0;
 
800
 
 
801
                                        snprintf(tmp, 200, " %-16s %-5d %s\n", i->ip.c_str(), i->port, pid);
 
802
                                        s += tmp;
663
803
                                }
664
 
                                s << "external ip: " << external_ip << "\n";
665
 
                                debug_log(s.str());
 
804
                                snprintf(tmp, 200, "external ip: %s\n", print_address(external_ip).c_str());
 
805
                                s += tmp;
 
806
                                debug_log(s);
666
807
                        }
667
808
 
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)
678
820
                        {
679
 
                                debug_log(std::string("*** tracker error: ")
680
 
                                        + boost::lexical_cast<std::string>(response_code) + ": "
681
 
                                        + str);
 
821
                                char msg[256];
 
822
                                snprintf(msg, sizeof(msg), "*** tracker error: %d: %s", response_code, str.c_str());
 
823
                                debug_log(msg);
682
824
                        }
683
825
                        
684
826
                        void debug_log(const std::string& line)