71
70
#include "libtorrent/hasher.hpp"
72
71
#include "libtorrent/assert.hpp"
73
72
#include "libtorrent/bitfield.hpp"
73
#include "libtorrent/aux_/session_impl.hpp"
75
75
#if TORRENT_COMPLETE_TYPES_REQUIRED
76
76
#include "libtorrent/peer_connection.hpp"
85
85
class piece_manager;
86
86
struct torrent_plugin;
88
struct announce_entry;
89
struct tracker_request;
90
struct add_torrent_params;
92
94
struct piece_checker_data;
100
// http seeds are different from url seeds in the
101
// protocol they use. http seeds follows the original
102
// http seed spec. by John Hoffman
103
enum type_t { url_seed, http_seed} type;
105
web_seed_entry(std::string const& url_, type_t type_)
106
: url(url_), type(type_) {}
108
bool operator==(web_seed_entry const& e) const
109
{ return url == e.url && type == e.type; }
111
bool operator<(web_seed_entry const& e) const
113
if (url < e.url) return true;
114
if (url > e.url) return false;
115
return type < e.type;
95
119
namespace fs = boost::filesystem;
97
121
// a torrent is a class that holds information
106
aux::session_impl& ses
107
, boost::intrusive_ptr<torrent_info> tf
108
, fs::path const& save_path
109
, tcp::endpoint const& net_interface
110
, storage_mode_t m_storage_mode
112
, storage_constructor_type sc
114
, std::vector<char>* resume_data
116
, bool auto_managed);
118
// used with metadata-less torrents
119
// (the metadata is downloaded from the peers)
121
aux::session_impl& ses
122
, char const* tracker_url
123
, sha1_hash const& info_hash
125
, fs::path const& save_path
126
, tcp::endpoint const& net_interface
127
, storage_mode_t m_storage_mode
129
, storage_constructor_type sc
131
, std::vector<char>* resume_data
133
, bool auto_managed);
129
torrent(aux::session_impl& ses, tcp::endpoint const& net_interface
130
, int block_size, int seq, add_torrent_params const& p);
137
133
#ifndef TORRENT_DISABLE_ENCRYPTION
163
159
void on_resume_data_checked(int ret, disk_io_job const& j);
164
160
void on_force_recheck(int ret, disk_io_job const& j);
165
161
void on_piece_checked(int ret, disk_io_job const& j);
166
void files_checked();
162
void files_checked_lock();
163
void files_checked(aux::session_impl::mutex_t::scoped_lock const&);
167
164
void start_checking();
169
166
void start_announcing();
170
167
void stop_announcing();
169
void send_upload_only();
171
void set_upload_mode(bool b);
172
bool upload_mode() const { return m_upload_mode; }
173
bool is_upload_only() const
174
{ return (is_finished() || upload_mode()) && !super_seeding(); }
172
176
int seed_rank(session_settings const& s) const;
178
enum flags_t { overwrite_existing = 1 };
179
void add_piece(int piece, char const* data, int flags = 0);
180
void on_disk_write_complete(int ret, disk_io_job const& j
183
struct read_piece_struct
185
boost::shared_array<char> piece_data;
189
void read_piece(int piece);
190
void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp);
174
192
storage_mode_t storage_mode() const { return m_storage_mode; }
175
193
storage_interface* get_storage()
201
217
void set_queue_position(int p);
202
218
int queue_position() const { return m_sequence_number; }
204
void second_tick(stat& accumulator, float tick_interval);
206
// debug purpose only
207
void print(std::ostream& os) const;
220
void second_tick(stat& accumulator, int tick_interval_ms);
209
222
std::string name() const;
211
224
stat statistics() const { return m_stat; }
212
void add_stats(stat const& s) { m_stat += s; }
225
void add_stats(stat const& s);
213
226
size_type bytes_left() const;
214
boost::tuples::tuple<size_type, size_type> bytes_done() const;
227
int block_bytes_wanted(piece_block const& p) const;
228
void bytes_done(torrent_status& st) const;
215
229
size_type quantized_bytes_done() const;
217
231
void ip_filter_updated() { m_policy.ip_filter_updated(); }
219
void set_error(std::string const& msg);
220
bool has_error() const { return !m_error.empty(); }
233
void handle_disk_error(disk_io_job const& j, peer_connection* c = 0);
235
void set_error(error_code const& ec, std::string const& file);
236
bool has_error() const { return m_error; }
243
261
bool is_piece_filtered(int index) const;
244
262
void filtered_pieces(std::vector<bool>& bitmask) const;
245
263
void filter_files(std::vector<bool> const& files);
246
265
void file_progress(std::vector<float>& fp) const;
247
267
// ============ end deprecation =============
249
269
void piece_availability(std::vector<int>& avail) const;
260
280
void prioritize_files(std::vector<int> const& files);
261
281
void file_priorities(std::vector<int>&) const;
283
void set_piece_deadline(int piece, int t, int flags);
263
284
void update_piece_priorities();
265
286
torrent_status status() const;
267
void file_progress(std::vector<size_type>& fp) const;
288
void file_progress(std::vector<size_type>& fp, int flags = 0) const;
269
290
void use_interface(const char* net_interface);
270
291
tcp::endpoint const& get_interface() const { return m_net_interface; }
272
void connect_to_url_seed(std::string const& url);
293
void connect_to_url_seed(web_seed_entry const& url);
273
294
bool connect_to_peer(policy::peer* peerinfo);
275
void set_ratio(float ratio)
276
{ TORRENT_ASSERT(ratio >= 0.0f); m_ratio = ratio; }
296
void set_ratio(float r)
297
{ TORRENT_ASSERT(r >= 0.0f); m_ratio = r; }
278
299
float ratio() const
279
300
{ return m_ratio; }
302
int priority() const { return m_priority; }
303
void set_priority(int prio)
305
TORRENT_ASSERT(prio <= 255 && prio >= 0);
306
if (prio > 255) prio = 255;
307
else if (prio < 0) prio = 0;
281
311
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
282
312
void resolve_countries(bool r)
283
313
{ m_resolve_countries = r; }
288
318
// --------------------------------------------
289
319
// BANDWIDTH MANAGEMENT
291
bandwidth_limit m_bandwidth_limit[2];
293
void request_bandwidth(int channel
294
, boost::intrusive_ptr<peer_connection> const& p
295
, int max_block_size, int priority);
297
void perform_bandwidth_request(int channel
298
, boost::intrusive_ptr<peer_connection> const& p
299
, int block_size, int priority);
301
void expire_bandwidth(int channel, int amount);
302
void assign_bandwidth(int channel, int amount, int blk);
321
bandwidth_channel m_bandwidth_channel[2];
304
323
int bandwidth_throttle(int channel) const;
306
int max_assignable_bandwidth(int channel) const
307
{ return m_bandwidth_limit[channel].max_assignable(); }
309
int bandwidth_queue_size(int channel) const;
311
325
// --------------------------------------------
312
326
// PEER MANAGEMENT
314
328
// add or remove a url that will be attempted for
315
329
// finding the file(s) in this torrent.
316
void add_url_seed(std::string const& url)
317
{ m_web_seeds.insert(url); }
330
void add_web_seed(std::string const& url, web_seed_entry::type_t type)
331
{ m_web_seeds.insert(web_seed_entry(url, type)); }
319
void remove_url_seed(std::string const& url)
320
{ m_web_seeds.erase(url); }
322
void retry_url_seed(std::string const& url);
324
std::set<std::string> url_seeds() const
333
void remove_web_seed(std::string const& url, web_seed_entry::type_t type)
334
{ m_web_seeds.erase(web_seed_entry(url, type)); }
336
void retry_web_seed(std::string const& url, web_seed_entry::type_t type, int retry = 0);
338
std::set<web_seed_entry> web_seeds() const
325
339
{ return m_web_seeds; }
341
std::set<std::string> web_seeds(web_seed_entry::type_t type) const;
327
343
bool free_upload_slots() const
328
344
{ return m_num_uploads < m_max_uploads; }
330
void choke_peer(peer_connection& c);
346
bool choke_peer(peer_connection& c);
331
347
bool unchoke_peer(peer_connection& c);
333
349
// used by peer_connection to attach itself to a torrent
375
391
// or when a failure occured
376
392
virtual void tracker_response(
377
393
tracker_request const& r
378
, std::vector<peer_entry>& e, int interval
394
, address const& tracker_ip
395
, std::list<address> const& ip_list
396
, std::vector<peer_entry>& e, int interval, int min_interval
379
397
, int complete, int incomplete, address const& external_ip);
380
398
virtual void tracker_request_timed_out(
381
399
tracker_request const& r);
382
400
virtual void tracker_request_error(tracker_request const& r
383
, int response_code, const std::string& str);
401
, int response_code, const std::string& str, int retry_interval);
384
402
virtual void tracker_warning(tracker_request const& req
385
403
, std::string const& msg);
386
404
virtual void tracker_scrape_response(tracker_request const& req
402
420
void force_tracker_request(ptime);
403
421
void scrape_tracker();
404
422
void announce_with_tracker(tracker_request::event_t e
405
= tracker_request::none);
423
= tracker_request::none
424
, address const& bind_interface = address_v4::any());
406
425
ptime const& last_scrape() const { return m_last_scrape; }
408
427
#ifndef TORRENT_DISABLE_DHT
417
436
// announce ourself at the last time we tried to announce
418
437
const tcp::endpoint& current_tracker() const;
439
announce_entry* find_tracker(tracker_request const& r);
420
441
// --------------------------------------------
421
442
// PIECE MANAGEMENT
444
void update_sparse_piece_prio(int piece, int cursor, int reverse_cursor);
446
bool super_seeding() const
447
{ return m_super_seeding; }
449
void super_seeding(bool on);
450
int get_piece_to_super_seed(bitfield const&);
423
452
// returns true if we have downloaded the given piece
424
453
bool have_piece(int index) const
426
455
return has_picker()?m_picker->have_piece(index):true;
458
// called when we learn that we have a piece
459
// only once per piece
460
void we_have(int index);
429
462
int num_have() const
431
464
return has_picker()
514
547
// this is the asio callback that is called when a name
515
548
// lookup for a WEB SEED is completed.
516
549
void on_name_lookup(error_code const& e, tcp::resolver::iterator i
517
, std::string url, tcp::endpoint proxy);
550
, web_seed_entry url, tcp::endpoint proxy);
519
552
// this is the asio callback that is called when a name
520
553
// lookup for a proxy for a web seed is completed.
521
554
void on_proxy_name_lookup(error_code const& e, tcp::resolver::iterator i
555
, web_seed_entry url);
524
557
// this is called when the torrent has finished. i.e.
525
558
// all the pieces we have not filtered have been downloaded.
647
683
// to the checker thread for initial checking
648
684
// of the storage.
649
685
// a return value of false indicates an error
650
bool set_metadata(lazy_entry const& metadata, std::string& error);
686
bool set_metadata(char const* metadata_buf, int metadata_size);
652
688
int sequence_number() const { return m_sequence_number; }
690
bool seed_mode() const { return m_seed_mode; }
691
void leave_seed_mode(bool seed)
693
if (!m_seed_mode) return;
695
// seed is false if we turned out not
696
// to be a seed after all
697
if (!seed) force_recheck();
701
bool all_verified() const
702
{ return m_num_verified == m_torrent_file->num_pieces(); }
703
bool verified_piece(int piece) const
705
TORRENT_ASSERT(piece < int(m_verified.size()));
706
TORRENT_ASSERT(piece >= 0);
707
return m_verified.get_bit(piece);
709
void verified(int piece)
711
TORRENT_ASSERT(piece < int(m_verified.size()));
712
TORRENT_ASSERT(piece >= 0);
713
TORRENT_ASSERT(m_verified.get_bit(piece) == false);
715
m_verified.set_bit(piece);
718
bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int piece);
720
// this is called once periodically for torrents
721
// that are not private
656
726
void on_files_deleted(int ret, disk_io_job const& j);
660
730
void on_storage_moved(int ret, disk_io_job const& j);
661
731
void on_save_resume_data(int ret, disk_io_job const& j);
662
732
void on_file_renamed(int ret, disk_io_job const& j);
733
void on_cache_flushed(int ret, disk_io_job const& j);
664
735
void on_piece_verified(int ret, disk_io_job const& j
665
736
, boost::function<void(int)> f);
667
void try_next_tracker(tracker_request const& req);
668
738
int prioritize_tracker(int tracker_index);
739
int deprioritize_tracker(int tracker_index);
669
741
void on_country_lookup(error_code const& error, tcp::resolver::iterator i
670
742
, boost::intrusive_ptr<peer_connection> p) const;
671
743
bool request_bandwidth_from_session(int channel) const;
673
745
void update_peer_interest(bool was_finished);
746
void prioritize_udp_trackers();
675
748
void queue_torrent_check();
676
749
void dequeue_torrent_check();
681
754
// does not count when the torrent is stopped or paused
682
755
time_duration m_active_time;
757
// total time we've been finished with this torrent
758
// does not count when the torrent is stopped or paused
759
time_duration m_finished_time;
684
761
// total time we've been available as a seed on this torrent
685
762
// does not count when the torrent is stopped or paused
686
763
time_duration m_seeding_time;
700
777
// one of the trackers in this torrent
701
778
ptime m_last_scrape;
780
// the time when we switched to upload mode
781
ptime m_upload_mode_time;
703
783
boost::intrusive_ptr<torrent_info> m_torrent_file;
705
785
void parse_response(const entry& e, std::vector<peer_entry>& peer_list);
743
820
// The list of web seeds in this torrent. Seeds
744
821
// with fatal errors are removed from the set
745
std::set<std::string> m_web_seeds;
822
std::set<web_seed_entry> m_web_seeds;
747
824
// a list of web seeds that have failed and are
748
825
// waiting to be retried
749
std::map<std::string, ptime> m_web_seeds_next_retry;
826
std::map<web_seed_entry, ptime> m_web_seeds_next_retry;
751
828
// urls of the web seeds that we are currently
752
829
// resolving the address for
753
std::set<std::string> m_resolving_web_seeds;
830
std::set<web_seed_entry> m_resolving_web_seeds;
755
832
#ifndef TORRENT_DISABLE_EXTENSIONS
756
833
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;
760
837
// used to resolve the names of web seeds
761
838
mutable tcp::resolver m_host_resolver;
840
#ifndef TORRENT_DISABLE_DHT
763
841
// this announce timer is used both
764
842
// by Local service discovery and
766
deadline_timer m_lsd_announce_timer;
844
deadline_timer m_dht_announce_timer;
768
847
// used for tracker announces
769
848
deadline_timer m_tracker_timer;
771
void restart_tracker_timer(ptime announce_at);
850
void update_tracker_timer();
773
852
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
774
853
, error_code const& e);
776
855
void on_tracker_announce();
778
static void on_lsd_announce_disp(boost::weak_ptr<torrent> p
779
, error_code const& e);
781
// this is called once every 5 minutes for torrents
782
// that are not private
783
void on_lsd_announce();
785
859
#ifndef TORRENT_DISABLE_DHT
786
860
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
787
861
, std::vector<tcp::endpoint> const& peers);
788
862
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
789
863
bool should_announce_dht() const;
864
void on_dht_announce(error_code const& e);
791
866
// the time when the DHT was last announced of our
792
867
// presence on this torrent
806
881
std::vector<boost::uint8_t> m_file_priority;
883
// this vector contains the number of bytes completely
884
// downloaded (as in passed-hash-check) in each file.
885
// this lets us trigger on individual files completing
886
std::vector<size_type> m_file_progress;
808
888
boost::scoped_ptr<piece_picker> m_picker;
810
// the queue of peer_connections that want more bandwidth
811
typedef std::deque<bw_queue_entry<peer_connection, torrent> > queue_t;
812
queue_t m_bandwidth_queue[2];
814
890
std::vector<announce_entry> m_trackers;
815
891
// this is an index into m_trackers
893
struct time_critical_piece
895
// when this piece was first requested
896
ptime first_requested;
897
// when this piece was last requested
898
ptime last_requested;
899
// by what time we want this piece
901
// 1 = send alert with piece data when available
903
// how many peers it's been requested from
907
bool operator<(time_critical_piece const& rhs) const
908
{ return deadline < rhs.deadline; }
911
void remove_time_critical_piece(int piece, bool finished = false);
912
void remove_time_critical_pieces(std::vector<int> const& priority);
913
void request_time_critical_pieces();
915
// this list is sorted by time_critical_piece::deadline
916
std::list<time_critical_piece> m_time_critical_pieces;
918
// the average time it takes to download one time critical piece
919
time_duration m_average_piece_time;
920
// the average piece download time deviation
921
time_duration m_piece_time_deviation;
817
923
// the number of bytes that has been
818
924
// downloaded that failed the hash-test
819
925
size_type m_total_failed_bytes;
820
926
size_type m_total_redundant_bytes;
928
// the number of bytes of padding files
822
931
std::string m_username;
823
932
std::string m_password;
829
938
fs::path m_save_path;
940
// each bit represents a piece. a set bit means
941
// the piece has had its hash verified. This
942
// is only used in seed mode (when m_seed_mode
945
// m_num_verified = m_verified.count()
948
// free download we have got that hasn't
949
// been distributed yet.
950
size_type m_available_free_upload;
831
952
// determines the storage state for this torrent.
832
953
storage_mode_t m_storage_mode;
834
// the state of this torrent (queued, checking, downloading)
955
// the state of this torrent (queued, checking, downloading, etc.)
835
956
torrent_status::state_t m_state;
837
// if there's an error on this torrent, this is the
958
// set if there's an error on this torrent
960
// if the error ocurred on a file, this is the file
961
std::string m_error_file;
841
963
// used if there is any resume data
842
964
std::vector<char> m_resume_data;
906
1028
// torrent object, these points are called connect_points.
907
1029
int m_deficit_counter;
909
// the number number of seconds between requests
911
boost::int16_t m_duration;
913
1031
// the sequence number for this torrent, this is a
914
1032
// monotonically increasing number for each added torrent
915
1033
boost::int16_t m_sequence_number;
917
1035
// the index to the last tracker that worked
918
1036
boost::int8_t m_last_working_tracker;
920
// the tracker that is currently (or was last)
922
boost::int8_t m_currently_trying_tracker;
924
1038
// the number of connection attempts that has
925
1039
// failed in a row, this is currently used to
926
1040
// determine the timeout until next try.
931
1045
// is called and the time scaler is reset to 10.
932
1046
boost::int8_t m_time_scaler;
1048
// this is the priority of the torrent. The higher
1049
// the value is, the more bandwidth is assigned to
1050
// the torrent's peers
1051
boost::uint8_t m_priority;
934
1053
// is set to true when the torrent has
935
1054
// been aborted.
938
1057
// is true if this torrent has been paused
939
1058
bool m_paused:1;
1060
// set to true when this torrent may not download anything
1061
bool m_upload_mode:1;
941
1063
// if this is true, libtorrent may pause and resume
942
1064
// this torrent depending on queuing rules. Torrents
943
1065
// started with auto_managed flag set may be added in
995
1121
// is is disabled while paused and checking files
996
1122
bool m_announcing:1;
998
// this is true if event start has been sent to the tracker
1001
// this is true if event completed has been sent to the tracker
1002
bool m_complete_sent:1;
1124
// this is true while the tracker deadline timer
1125
// is in use. i.e. one or more trackers are waiting
1127
bool m_waiting_tracker:1;
1129
// this means we haven't verified the file content
1130
// of the files we're seeding. the m_verified bitfield
1131
// indicates which pieces have been verified and which
1135
// this is set when we don't want to load seed_mode,
1136
// paused or auto_managed from the resume data
1137
bool m_override_resume_data:1;
1005
inline ptime torrent::next_announce() const
1007
return m_next_tracker_announce;
1010
inline void torrent::force_tracker_request()
1012
if (!is_paused()) announce_with_tracker();
1015
inline void torrent::force_tracker_request(ptime t)
1017
if (!is_paused()) restart_tracker_timer(t);
1020
inline void torrent::set_tracker_login(
1021
std::string const& name
1022
, std::string const& pw)
1030
1141
#endif // TORRENT_TORRENT_HPP_INCLUDED