1 /* 2 3 Copyright (c) 2003-2018, Arvid Norberg 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 10 * Redistributions of source code must retain the above copyright 11 notice, this list of conditions and the following disclaimer. 12 * Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in 14 the documentation and/or other materials provided with the distribution. 15 * Neither the name of the author nor the names of its 16 contributors may be used to endorse or promote products derived 17 from this software without specific prior written permission. 18 19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 POSSIBILITY OF SUCH DAMAGE. 30 31 */ 32 33 #ifndef TORRENT_TORRENT_HPP_INCLUDE 34 #define TORRENT_TORRENT_HPP_INCLUDE 35 36 #include <algorithm> 37 #include <vector> 38 #include <set> 39 #include <list> 40 #include <deque> 41 #include <limits> // for numeric_limits 42 #include <memory> // for unique_ptr 43 44 #include "libtorrent/fwd.hpp" 45 #include "libtorrent/optional.hpp" 46 #include "libtorrent/torrent_handle.hpp" 47 #include "libtorrent/entry.hpp" 48 #include "libtorrent/torrent_info.hpp" 49 #include "libtorrent/socket.hpp" 50 #include "libtorrent/address.hpp" 51 #include "libtorrent/peer_list.hpp" 52 #include "libtorrent/tracker_manager.hpp" 53 #include "libtorrent/stat.hpp" 54 #include "libtorrent/alert.hpp" 55 #include "libtorrent/piece_picker.hpp" 56 #include "libtorrent/config.hpp" 57 #include "libtorrent/bandwidth_limit.hpp" 58 #include "libtorrent/bandwidth_queue_entry.hpp" 59 #include "libtorrent/storage_defs.hpp" 60 #include "libtorrent/assert.hpp" 61 #include "libtorrent/aux_/session_interface.hpp" 62 #include "libtorrent/aux_/time.hpp" 63 #include "libtorrent/deadline_timer.hpp" 64 #include "libtorrent/peer_class_set.hpp" 65 #include "libtorrent/link.hpp" 66 #include "libtorrent/vector_utils.hpp" 67 #include "libtorrent/linked_list.hpp" 68 #include "libtorrent/debug.hpp" 69 #include "libtorrent/piece_block.hpp" 70 #include "libtorrent/disk_interface.hpp" 71 #include "libtorrent/aux_/file_progress.hpp" 72 #include "libtorrent/aux_/suggest_piece.hpp" 73 #include "libtorrent/units.hpp" 74 #include "libtorrent/aux_/vector.hpp" 75 #include "libtorrent/aux_/deferred_handler.hpp" 76 #include "libtorrent/aux_/allocating_handler.hpp" 77 #include "libtorrent/extensions.hpp" // for add_peer_flags_t 78 79 #ifdef TORRENT_USE_OPENSSL 80 // there is no forward declaration header for asio 81 namespace boost { 82 namespace asio { 83 namespace ssl { 84 class context; 85 class verify_context; 86 } 87 } 88 } 89 #endif 90 91 #if TORRENT_COMPLETE_TYPES_REQUIRED 92 #include "libtorrent/peer_connection.hpp" 93 #endif 94 95 // define as 0 to disable. 1 enables debug output of the pieces and requested 96 // blocks. 2 also enables trace output of the time critical piece picking 97 // logic 98 #define TORRENT_DEBUG_STREAMING 0 99 100 namespace libtorrent { 101 102 class http_parser; 103 struct tracker_request; 104 class bt_peer_connection; 105 106 using web_seed_flag_t = flags::bitfield_flag<std::uint8_t, struct web_seed_flag_tag>; 107 108 // internal 109 enum class waste_reason 110 { 111 piece_timed_out, piece_cancelled, piece_unknown, piece_seed 112 , piece_end_game, piece_closing 113 , max 114 }; 115 116 TORRENT_EXTRA_EXPORT std::int64_t calc_bytes(file_storage const& fs, piece_count const& pc); 117 118 #ifndef TORRENT_DISABLE_STREAMING 119 struct time_critical_piece 120 { 121 // when this piece was first requested 122 time_point first_requested; 123 // when this piece was last requested 124 time_point last_requested; 125 // by what time we want this piece 126 time_point deadline; 127 // 1 = send alert with piece data when available 128 deadline_flags_t flags; 129 // how many peers it's been requested from 130 int peers; 131 // the piece index 132 piece_index_t piece; 133 #if TORRENT_DEBUG_STREAMING > 0 134 // the number of multiple requests are allowed 135 // to blocks still not downloaded (debugging only) 136 int timed_out; 137 #endif operator <libtorrent::time_critical_piece138 bool operator<(time_critical_piece const& rhs) const 139 { return deadline < rhs.deadline; } 140 }; 141 #endif // TORRENT_DISABLE_STREAMING 142 143 // this is the internal representation of web seeds 144 struct web_seed_t : web_seed_entry 145 { 146 explicit web_seed_t(web_seed_entry const& wse); 147 web_seed_t(std::string const& url_, web_seed_entry::type_t type_ 148 , std::string const& auth_ = std::string() 149 , web_seed_entry::headers_t const& extra_headers_ = web_seed_entry::headers_t()); 150 151 // if this is > now, we can't reconnect yet 152 time_point32 retry = aux::time_now32(); 153 154 // if the hostname of the web seed has been resolved, 155 // these are its IP addresses 156 std::vector<tcp::endpoint> endpoints; 157 158 // this is the peer_info field used for the 159 // connection, just to count hash failures 160 // it's also used to hold the peer_connection 161 // pointer, when the web seed is connected 162 ipv4_peer peer_info{tcp::endpoint(), true, {}}; 163 164 // this is initialized to true, but if we discover the 165 // server not to support it, it's set to false, and we 166 // make larger requests. 167 bool supports_keepalive = true; 168 169 // this indicates whether or not we're resolving the 170 // hostname of this URL 171 bool resolving = false; 172 173 // if the user wanted to remove this while 174 // we were resolving it. In this case, we set 175 // the removed flag to true, to make the resolver 176 // callback remove it 177 bool removed = false; 178 179 // this indicates whether this web seed has any files. A server that only 180 // redirects to other servers for instance, may not have any files and 181 // once we've seen all redirects, there's no point in connecting to it 182 // again. 183 bool interesting = true; 184 185 // if this is true, this URL was created by a redirect and should not be 186 // saved in the resume data 187 bool ephemeral = false; 188 189 // if the web server doesn't support keepalive or a block request was 190 // interrupted, the block received so far is kept here for the next 191 // connection to pick up 192 peer_request restart_request = { piece_index_t(-1), -1, -1}; 193 std::vector<char> restart_piece; 194 195 // this maps file index to a URL it has been redirected to. If an entry is 196 // missing, it means it has not been redirected and the full path should 197 // be constructed normally based on the filename. All redirections are 198 // relative to the web seed hostname root. 199 std::map<file_index_t, std::string> redirects; 200 201 // if this bitfield is non-empty, it represents the files this web server 202 // has. 203 typed_bitfield<file_index_t> have_files; 204 #if defined __GNUC__ && defined _GLIBCXX_DEBUG 205 // this works around a bug in libstdc++'s checked iterators 206 // http://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle operator =libtorrent::web_seed_t207 web_seed_t& operator=(web_seed_t&& rhs) noexcept 208 { 209 if (&rhs == this) return *this; 210 211 web_seed_entry::operator=(std::move(rhs)); 212 retry = std::move(rhs.retry); 213 endpoints = std::move(rhs.endpoints); 214 peer_info = std::move(rhs.peer_info); 215 supports_keepalive = std::move(rhs.supports_keepalive); 216 resolving = std::move(rhs.resolving); 217 removed = std::move(rhs.removed); 218 ephemeral = std::move(rhs.ephemeral); 219 restart_request = std::move(rhs.restart_request); 220 restart_piece = std::move(rhs.restart_piece); 221 redirects = std::move(rhs.redirects); 222 have_files = std::move(rhs.have_files); 223 return *this; 224 } 225 226 web_seed_t& operator=(web_seed_t const&) = default; 227 web_seed_t(web_seed_t const&) = default; 228 #endif 229 }; 230 231 struct TORRENT_EXTRA_EXPORT torrent_hot_members 232 { 233 torrent_hot_members(aux::session_interface& ses 234 , add_torrent_params const& p, bool session_paused); 235 236 protected: 237 // the piece picker. This is allocated lazily. When we don't 238 // have anything in the torrent (for instance, if it hasn't 239 // been started yet) or if we have everything, there is no 240 // picker. It's allocated on-demand the first time we need 241 // it in torrent::need_picker(). In order to tell the 242 // difference between having everything and nothing in 243 // the case there is no piece picker, see m_have_all. 244 std::unique_ptr<piece_picker> m_picker; 245 246 // TODO: make this a raw pointer. perhaps keep the shared_ptr 247 // around further down the object to maintain an owner 248 std::shared_ptr<torrent_info> m_torrent_file; 249 250 // a back reference to the session 251 // this torrent belongs to. 252 aux::session_interface& m_ses; 253 254 // this vector is sorted at all times, by the pointer value. 255 // use sorted_insert() and sorted_find() on it. The GNU STL 256 // implementation on Darwin uses significantly less memory to 257 // represent a vector than a set, and this set is typically 258 // relatively small, and it's cheap to copy pointers. 259 aux::vector<peer_connection*> m_connections; 260 261 // the scrape data from the tracker response, this 262 // is optional and may be 0xffffff 263 std::uint32_t m_complete:24; 264 265 // set to true when this torrent may not download anything 266 bool m_upload_mode:1; 267 268 // this is set to false as long as the connections 269 // of this torrent haven't been initialized. If we 270 // have metadata from the start, connections are 271 // initialized immediately, if we didn't have metadata, 272 // they are initialized right after files_checked(). 273 // valid_resume_data() will return false as long as 274 // the connections aren't initialized, to avoid 275 // them from altering the piece-picker before it 276 // has been initialized with files_checked(). 277 bool m_connections_initialized:1; 278 279 // is set to true when the torrent has 280 // been aborted. 281 bool m_abort:1; 282 283 // is true if this torrent has allows having peers 284 bool m_paused:1; 285 286 // is true if the session is paused, in which case the torrent is 287 // effectively paused as well. 288 bool m_session_paused:1; 289 290 #ifndef TORRENT_DISABLE_SHARE_MODE 291 // this is set when the torrent is in share-mode 292 bool m_share_mode:1; 293 #endif 294 295 // this is true if we have all pieces. If it's false, 296 // it means we either don't have any pieces, or, if 297 // there is a piece_picker object present, it contains 298 // the state of how many pieces we have 299 bool m_have_all:1; 300 301 // set to true when this torrent has been paused but 302 // is waiting to finish all current download requests 303 // before actually closing all connections, when in graceful pause mode, 304 // m_paused is also true. 305 bool m_graceful_pause_mode:1; 306 307 // state subscription. If set, a pointer to this torrent will be added 308 // to the session_impl::m_torrent_lists[torrent_state_updates] 309 // whenever this torrent's state changes (any state). 310 bool m_state_subscription:1; 311 312 // the maximum number of connections for this torrent 313 std::uint32_t m_max_connections:24; 314 315 // the state of this torrent (queued, checking, downloading, etc.) 316 std::uint32_t m_state:3; 317 318 std::unique_ptr<peer_list> m_peer_list; 319 }; 320 321 // a torrent is a class that holds information 322 // for a specific download. It updates itself against 323 // the tracker 324 class TORRENT_EXTRA_EXPORT torrent 325 : private single_threaded 326 , private torrent_hot_members 327 , public request_callback 328 , public peer_class_set 329 , public aux::error_handler_interface 330 , public std::enable_shared_from_this<torrent> 331 { 332 public: 333 334 torrent(aux::session_interface& ses 335 , bool session_paused, add_torrent_params const& p); 336 ~torrent() override; 337 338 // This may be called from multiple threads info_hash() const339 sha1_hash const& info_hash() const { return m_info_hash; } 340 is_deleted() const341 bool is_deleted() const { return m_deleted; } 342 343 // starts the announce timer 344 void start(); 345 added()346 void added() 347 { 348 TORRENT_ASSERT(m_added == false); 349 m_added = true; 350 update_gauge(); 351 } 352 removed()353 void removed() 354 { 355 TORRENT_ASSERT(m_added == true); 356 m_added = false; 357 set_queue_position(no_pos); 358 // make sure we decrement the gauge counter for this torrent 359 update_gauge(); 360 } 361 362 #if TORRENT_ABI_VERSION == 1 363 // deprecated in 1.2 364 void start_download_url(); 365 #endif 366 367 // returns which stats gauge this torrent currently 368 // has incremented. 369 int current_stats_state() const; 370 371 #ifndef TORRENT_DISABLE_EXTENSIONS 372 void add_extension(std::shared_ptr<torrent_plugin>); 373 void remove_extension(std::shared_ptr<torrent_plugin>); 374 void add_extension_fun(std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)> const& ext 375 , void* userdata); 376 void notify_extension_add_peer(tcp::endpoint const& ip 377 , peer_source_flags_t src, add_peer_flags_t flags); 378 #endif 379 380 peer_connection* find_lowest_ranking_peer() const; 381 382 #if TORRENT_USE_ASSERTS has_peer(peer_connection const * p) const383 bool has_peer(peer_connection const* p) const 384 { return sorted_find(m_connections, p) != m_connections.end(); } is_single_thread() const385 bool is_single_thread() const { return single_threaded::is_single_thread(); } 386 #endif 387 388 // this is called when the torrent has metadata. 389 // it will initialize the storage and the piece-picker 390 void init(); 391 392 // find the peer that introduced us to the given endpoint. This is 393 // used when trying to holepunch. We need the introducer so that we 394 // can send a rendezvous connect message 395 bt_peer_connection* find_introducer(tcp::endpoint const& ep) const; 396 397 // if we're connected to a peer at ep, return its peer connection 398 // only count BitTorrent peers 399 bt_peer_connection* find_peer(tcp::endpoint const& ep) const; 400 peer_connection* find_peer(peer_id const& pid); 401 402 // checks to see if this peer id is used in one of our own outgoing 403 // connections. 404 bool is_self_connection(peer_id const& pid) const; 405 406 void on_resume_data_checked(status_t status, storage_error const& error); 407 void on_force_recheck(status_t status, storage_error const& error); 408 void on_piece_hashed(piece_index_t piece, sha1_hash const& piece_hash 409 , storage_error const& error); 410 void files_checked(); 411 void start_checking(); 412 413 void start_announcing(); 414 void stop_announcing(); 415 416 void send_upload_only(); 417 418 #ifndef TORRENT_DISABLE_SHARE_MODE 419 void send_share_mode(); 420 void set_share_mode(bool s); share_mode() const421 bool share_mode() const { return m_share_mode; } 422 #endif 423 424 // TODO: make graceful pause also finish all sending blocks 425 // before disconnecting graceful_pause() const426 bool graceful_pause() const { return m_graceful_pause_mode; } 427 428 torrent_flags_t flags() const; 429 void set_flags(torrent_flags_t flags, torrent_flags_t mask); 430 431 void set_upload_mode(bool b); upload_mode() const432 bool upload_mode() const { return m_upload_mode || m_graceful_pause_mode; } is_upload_only() const433 bool is_upload_only() const { return is_finished() || upload_mode(); } 434 435 int seed_rank(aux::session_settings const& s) const; 436 437 void add_piece(piece_index_t piece, char const* data, add_piece_flags_t flags); 438 void on_disk_write_complete(storage_error const& error 439 , peer_request const& p); 440 set_progress_ppm(int p)441 void set_progress_ppm(int p) { m_progress_ppm = std::uint32_t(p); } 442 struct read_piece_struct 443 { 444 boost::shared_array<char> piece_data; 445 int blocks_left; 446 bool fail; 447 error_code error; 448 }; 449 void read_piece(piece_index_t piece); 450 void on_disk_read_complete(disk_buffer_holder block, disk_job_flags_t, storage_error const& se 451 , peer_request const& r, std::shared_ptr<read_piece_struct> rp); 452 453 storage_mode_t storage_mode() const; 454 455 // this will flag the torrent as aborted. The main 456 // loop in session_impl will check for this state 457 // on all torrents once every second, and take 458 // the necessary actions then. 459 void abort(); is_aborted() const460 bool is_aborted() const { return m_abort; } 461 void panic(); 462 463 void new_external_ip(); 464 state() const465 torrent_status::state_t state() const 466 { return torrent_status::state_t(m_state); } 467 void set_state(torrent_status::state_t s); 468 469 aux::session_settings const& settings() const; session()470 aux::session_interface& session() { return m_ses; } 471 472 void set_sequential_download(bool sd); is_sequential_download() const473 bool is_sequential_download() const 474 { return m_sequential_download || m_auto_sequential; } 475 476 void queue_up(); 477 void queue_down(); 478 void set_queue_position(queue_position_t p); queue_position() const479 queue_position_t queue_position() const { return m_sequence_number; } 480 // used internally set_queue_position_impl(queue_position_t const p)481 void set_queue_position_impl(queue_position_t const p) 482 { 483 if (m_sequence_number == p) return; 484 m_sequence_number = p; 485 state_updated(); 486 } 487 488 void second_tick(int tick_interval_ms); 489 490 // see if we need to connect to web seeds, and if so, 491 // connect to them 492 void maybe_connect_web_seeds(); 493 494 std::string name() const; 495 statistics() const496 stat statistics() const { return m_stat; } 497 boost::optional<std::int64_t> bytes_left() const; 498 499 void bytes_done(torrent_status& st, status_flags_t) const; 500 501 void sent_bytes(int bytes_payload, int bytes_protocol); 502 void received_bytes(int bytes_payload, int bytes_protocol); 503 void trancieve_ip_packet(int bytes, bool ipv6); 504 void sent_syn(bool ipv6); 505 void received_synack(bool ipv6); 506 507 void set_ip_filter(std::shared_ptr<const ip_filter> ipf); 508 void port_filter_updated(); get_ip_filter()509 ip_filter const* get_ip_filter() { return m_ip_filter.get(); } 510 511 std::string resolve_filename(file_index_t file) const; 512 void handle_exception(); 513 514 enum class disk_class { none, write }; 515 void handle_disk_error(string_view job_name 516 , storage_error const& error, peer_connection* c = nullptr 517 , disk_class rw = disk_class::none); 518 void clear_error(); 519 520 void set_error(error_code const& ec, file_index_t file); has_error() const521 bool has_error() const { return !!m_error; } error() const522 error_code error() const { return m_error; } 523 524 void flush_cache(); 525 void pause(pause_flags_t flags = {}); 526 void resume(); 527 528 void set_session_paused(bool b); 529 void set_paused(bool b, pause_flags_t flags = torrent_handle::clear_disk_cache); set_announce_to_dht(bool b)530 void set_announce_to_dht(bool b) { m_announce_to_dht = b; } set_announce_to_trackers(bool b)531 void set_announce_to_trackers(bool b) { m_announce_to_trackers = b; } set_announce_to_lsd(bool b)532 void set_announce_to_lsd(bool b) { m_announce_to_lsd = b; } 533 534 void stop_when_ready(bool b); 535 started() const536 time_point32 started() const { return m_started; } 537 void step_session_time(int seconds); 538 void do_pause(pause_flags_t flags = torrent_handle::clear_disk_cache, bool was_paused = false); 539 void do_resume(); 540 541 seconds32 finished_time() const; 542 seconds32 active_time() const; 543 seconds32 seeding_time() const; 544 seconds32 upload_mode_time() const; 545 546 bool is_paused() const; is_torrent_paused() const547 bool is_torrent_paused() const { return m_paused; } 548 void force_recheck(); 549 void save_resume_data(resume_data_flags_t flags); 550 need_save_resume_data() const551 bool need_save_resume_data() const { return m_need_save_resume_data; } 552 set_need_save_resume()553 void set_need_save_resume() 554 { 555 m_need_save_resume_data = true; 556 } 557 is_auto_managed() const558 bool is_auto_managed() const { return m_auto_managed; } 559 void auto_managed(bool a); 560 561 bool should_check_files() const; 562 563 bool delete_files(remove_flags_t options); 564 void peers_erased(std::vector<torrent_peer*> const& peers); 565 566 #if TORRENT_ABI_VERSION == 1 567 #if !TORRENT_NO_FPU 568 void file_progress_float(aux::vector<float, file_index_t>& fp); 569 #endif 570 #endif // TORRENT_ABI_VERSION 571 572 void piece_availability(aux::vector<int, piece_index_t>& avail) const; 573 574 void set_piece_priority(piece_index_t index, download_priority_t priority); 575 download_priority_t piece_priority(piece_index_t index) const; 576 577 void prioritize_pieces(aux::vector<download_priority_t, piece_index_t> const& pieces); 578 void prioritize_piece_list(std::vector<std::pair<piece_index_t, download_priority_t>> const& pieces); 579 void piece_priorities(aux::vector<download_priority_t, piece_index_t>*) const; 580 581 void set_file_priority(file_index_t index, download_priority_t priority); 582 download_priority_t file_priority(file_index_t index) const; 583 584 void on_file_priority(storage_error const& err, aux::vector<download_priority_t, file_index_t> prios); 585 void prioritize_files(aux::vector<download_priority_t, file_index_t> files); 586 void file_priorities(aux::vector<download_priority_t, file_index_t>*) const; 587 588 #ifndef TORRENT_DISABLE_STREAMING 589 void cancel_non_critical(); 590 void set_piece_deadline(piece_index_t piece, int t, deadline_flags_t flags); 591 void reset_piece_deadline(piece_index_t piece); 592 void clear_time_critical(); 593 #endif // TORRENT_DISABLE_STREAMING 594 595 void update_piece_priorities( 596 aux::vector<download_priority_t, file_index_t> const& file_prios); 597 598 void status(torrent_status* st, status_flags_t flags); 599 600 // this torrent changed state, if the user is subscribing to 601 // it, add it to the m_state_updates list in session_impl 602 void state_updated(); 603 604 void file_progress(aux::vector<std::int64_t, file_index_t>& fp, int flags = 0); 605 606 #if TORRENT_ABI_VERSION == 1 607 void use_interface(std::string net_interface); 608 #endif 609 610 void connect_to_url_seed(std::list<web_seed_t>::iterator url); 611 bool connect_to_peer(torrent_peer* peerinfo, bool ignore_limit = false); 612 613 int priority() const; 614 #if TORRENT_ABI_VERSION == 1 615 void set_priority(int prio); 616 #endif // TORRENT_ABI_VERSION 617 618 // -------------------------------------------- 619 // BANDWIDTH MANAGEMENT 620 621 void set_upload_limit(int limit); 622 int upload_limit() const; 623 void set_download_limit(int limit); 624 int download_limit() const; 625 peer_class() const626 peer_class_t peer_class() const { return m_peer_class; } 627 628 void set_max_uploads(int limit, bool state_update = true); max_uploads() const629 int max_uploads() const { return int(m_max_uploads); } 630 void set_max_connections(int limit, bool state_update = true); max_connections() const631 int max_connections() const { return int(m_max_connections); } 632 633 // -------------------------------------------- 634 // PEER MANAGEMENT 635 636 static constexpr web_seed_flag_t ephemeral = 0_bit; 637 638 // add_web_seed won't add duplicates. If we have already added an entry 639 // with this URL, we'll get back the existing entry 640 web_seed_t* add_web_seed(std::string const& url 641 , web_seed_t::type_t type 642 , std::string const& auth = std::string() 643 , web_seed_t::headers_t const& extra_headers = web_seed_entry::headers_t() 644 , web_seed_flag_t flags = {}); 645 646 void remove_web_seed(std::string const& url, web_seed_t::type_t type); 647 void disconnect_web_seed(peer_connection* p); 648 649 void retry_web_seed(peer_connection* p, boost::optional<seconds32> retry = boost::none); 650 651 void remove_web_seed_conn(peer_connection* p, error_code const& ec 652 , operation_t op, disconnect_severity_t error = peer_connection_interface::normal); 653 654 std::set<std::string> web_seeds(web_seed_entry::type_t type) const; 655 free_upload_slots() const656 bool free_upload_slots() const 657 { return m_num_uploads < m_max_uploads; } 658 659 bool choke_peer(peer_connection& c); 660 bool unchoke_peer(peer_connection& c, bool optimistic = false); 661 662 void trigger_unchoke() noexcept; 663 void trigger_optimistic_unchoke() noexcept; 664 665 // used by peer_connection to attach itself to a torrent 666 // since incoming connections don't know what torrent 667 // they're a part of until they have received an info_hash. 668 // false means attach failed 669 bool attach_peer(peer_connection* p); 670 671 // this will remove the peer and make sure all 672 // the pieces it had have their reference counter 673 // decreased in the piece_picker 674 void remove_peer(std::shared_ptr<peer_connection> p) noexcept; 675 676 // cancel requests to this block from any peer we're 677 // connected to on this torrent 678 void cancel_block(piece_block block); 679 680 bool want_tick() const; 681 void update_want_tick(); 682 void update_state_list(); 683 684 bool want_peers() const; 685 bool want_peers_download() const; 686 bool want_peers_finished() const; 687 688 void update_want_peers(); 689 void update_want_scrape(); 690 void update_gauge(); 691 692 bool try_connect_peer(); 693 torrent_peer* add_peer(tcp::endpoint const& adr 694 , peer_source_flags_t source, pex_flags_t flags = {}); 695 bool ban_peer(torrent_peer* tp); 696 void update_peer_port(int port, torrent_peer* p, peer_source_flags_t src); 697 void set_seed(torrent_peer* p, bool s); 698 void clear_failcount(torrent_peer* p); 699 std::pair<peer_list::iterator, peer_list::iterator> find_peers(address const& a); 700 701 // the number of peers that belong to this torrent num_peers() const702 int num_peers() const { return int(m_connections.size() - m_peers_to_disconnect.size()); } 703 int num_seeds() const; 704 int num_downloaders() const; 705 706 using peer_iterator = std::vector<peer_connection*>::iterator; 707 using const_peer_iterator = std::vector<peer_connection*>::const_iterator; 708 begin() const709 const_peer_iterator begin() const { return m_connections.begin(); } end() const710 const_peer_iterator end() const { return m_connections.end(); } 711 begin()712 peer_iterator begin() { return m_connections.begin(); } end()713 peer_iterator end() { return m_connections.end(); } 714 715 #if TORRENT_ABI_VERSION == 1 716 void get_full_peer_list(std::vector<peer_list_entry>* v) const; 717 #endif 718 void get_peer_info(std::vector<peer_info>* v); 719 void get_download_queue(std::vector<partial_piece_info>* queue) const; 720 721 void update_auto_sequential(); 722 private: 723 void remove_connection(peer_connection const* p); 724 public: 725 // -------------------------------------------- 726 // TRACKER MANAGEMENT 727 728 // these are callbacks called by the tracker_connection instance 729 // (either http_tracker_connection or udp_tracker_connection) 730 // when this torrent got a response from its tracker request 731 // or when a failure occurred 732 void tracker_response( 733 tracker_request const& r 734 , address const& tracker_ip 735 , std::list<address> const& ip_list 736 , struct tracker_response const& resp) override; 737 void tracker_request_error(tracker_request const& r 738 , error_code const& ec, const std::string& msg 739 , seconds32 retry_interval) override; 740 void tracker_warning(tracker_request const& req 741 , std::string const& msg) override; 742 void tracker_scrape_response(tracker_request const& req 743 , int complete, int incomplete, int downloaded, int downloaders) override; 744 745 void update_scrape_state(); 746 747 #if TORRENT_ABI_VERSION == 1 748 // if no password and username is set 749 // this will return an empty string, otherwise 750 // it will concatenate the login and password 751 // ready to be sent over http (but without 752 // base64 encoding). 753 std::string tracker_login() const; 754 #endif 755 756 // generate the tracker key for this torrent. 757 // The key is passed to http trackers as ``&key=``. 758 std::uint32_t tracker_key() const; 759 760 // if we need a connect boost, connect some peers 761 // immediately 762 void do_connect_boost(); 763 764 // forcefully sets next_announce to the current time 765 void force_tracker_request(time_point, int tracker_idx, reannounce_flags_t flags); 766 void scrape_tracker(int idx, bool user_triggered); 767 void announce_with_tracker(std::uint8_t e 768 = tracker_request::none); 769 770 #ifndef TORRENT_DISABLE_DHT 771 void dht_announce(); 772 #endif 773 774 #if TORRENT_ABI_VERSION == 1 775 // sets the username and password that will be sent to 776 // the tracker 777 void set_tracker_login(std::string const& name, std::string const& pw); 778 #endif 779 780 announce_entry* find_tracker(std::string const& url); 781 // -------------------------------------------- 782 // PIECE MANAGEMENT 783 784 #ifndef TORRENT_DISABLE_SHARE_MODE 785 void recalc_share_mode(); 786 #endif 787 788 #ifndef TORRENT_DISABLE_SUPERSEEDING super_seeding() const789 bool super_seeding() const 790 { 791 // we're not super seeding if we're not a seed 792 return m_super_seeding; 793 } 794 795 void set_super_seeding(bool on); 796 piece_index_t get_piece_to_super_seed(typed_bitfield<piece_index_t> const&); 797 #endif 798 799 // returns true if we have downloaded the given piece have_piece(piece_index_t index) const800 bool have_piece(piece_index_t index) const 801 { 802 if (!valid_metadata()) return false; 803 if (!has_picker()) return m_have_all; 804 return m_picker->have_piece(index); 805 } 806 807 // returns true if we have downloaded the given piece user_have_piece(piece_index_t index) const808 bool user_have_piece(piece_index_t index) const 809 { 810 if (!valid_metadata()) return false; 811 if (index < piece_index_t{0} || index >= m_torrent_file->end_piece()) return false; 812 if (!has_picker()) return m_have_all; 813 return m_picker->have_piece(index); 814 } 815 816 // returns true if we have downloaded the given piece has_piece_passed(piece_index_t index) const817 bool has_piece_passed(piece_index_t index) const 818 { 819 if (!valid_metadata()) return false; 820 if (index < piece_index_t(0) || index >= torrent_file().end_piece()) return false; 821 if (!has_picker()) return m_have_all; 822 return m_picker->has_piece_passed(index); 823 } 824 825 #ifndef TORRENT_DISABLE_PREDICTIVE_PIECES 826 // a predictive piece is a piece that we might 827 // not have yet, but still announced to peers, anticipating that 828 // we'll have it very soon is_predictive_piece(piece_index_t index) const829 bool is_predictive_piece(piece_index_t index) const 830 { 831 return std::binary_search(m_predictive_pieces.begin(), m_predictive_pieces.end(), index); 832 } 833 #endif // TORRENT_DISABLE_PREDICTIVE_PIECES 834 835 private: 836 837 // called when we learn that we have a piece 838 // only once per piece 839 void we_have(piece_index_t index); 840 841 public: 842 num_have() const843 int num_have() const 844 { 845 // pretend we have every piece when in seed mode 846 if (m_seed_mode) return m_torrent_file->num_pieces(); 847 if (has_picker()) return m_picker->have().num_pieces; 848 if (m_have_all) return m_torrent_file->num_pieces(); 849 return 0; 850 } 851 852 // the number of pieces that have passed 853 // hash check, but aren't necessarily 854 // flushed to disk yet num_passed() const855 int num_passed() const 856 { 857 if (has_picker()) return m_picker->num_passed(); 858 if (m_have_all) return m_torrent_file->num_pieces(); 859 return 0; 860 } 861 862 // when we get a have message, this is called for that piece 863 void peer_has(piece_index_t index, peer_connection const* peer); 864 865 // when we get a bitfield message, this is called for that piece 866 void peer_has(typed_bitfield<piece_index_t> const& bits, peer_connection const* peer); 867 868 void peer_has_all(peer_connection const* peer); 869 870 void peer_lost(piece_index_t index, peer_connection const* peer); 871 void peer_lost(typed_bitfield<piece_index_t> const& bits 872 , peer_connection const* peer); 873 block_size() const874 int block_size() const 875 { 876 return valid_metadata() 877 ? (std::min)(m_torrent_file->piece_length(), default_block_size) 878 : default_block_size; 879 } 880 peer_request to_req(piece_block const& p) const; 881 882 void disconnect_all(error_code const& ec, operation_t op); 883 int disconnect_peers(int num, error_code const& ec); 884 885 // called every time a block is marked as finished in the 886 // piece picker. We might have completed the torrent and 887 // we can delete the piece picker 888 void maybe_done_flushing(); 889 890 // this is called when the torrent has completed 891 // the download. It will post an event, disconnect 892 // all seeds and let the tracker know we're finished. 893 void completed(); 894 895 #if TORRENT_USE_I2P 896 void on_i2p_resolve(error_code const& ec, char const* dest); is_i2p() const897 bool is_i2p() const { return m_torrent_file && m_torrent_file->is_i2p(); } 898 #endif 899 900 // this is the asio callback that is called when a name 901 // lookup for a PEER is completed. 902 void on_peer_name_lookup(error_code const& e 903 , std::vector<address> const& addrs 904 , int port); 905 906 // this is the asio callback that is called when a name 907 // lookup for a WEB SEED is completed. 908 void on_name_lookup(error_code const& e 909 , std::vector<address> const& addrs 910 , int port 911 , std::list<web_seed_t>::iterator web); 912 913 void connect_web_seed(std::list<web_seed_t>::iterator web, tcp::endpoint a); 914 915 // this is the asio callback that is called when a name 916 // lookup for a proxy for a web seed is completed. 917 void on_proxy_name_lookup(error_code const& e 918 , std::vector<address> const& addrs 919 , std::list<web_seed_t>::iterator web, int port); 920 921 // re-evaluates whether this torrent should be considered inactive or not 922 void on_inactivity_tick(error_code const& ec); 923 924 925 // calculate the instantaneous inactive state (the externally facing 926 // inactive state is not instantaneous, but low-pass filtered) 927 bool is_inactive_internal() const; 928 929 // remove a web seed, or schedule it for removal in case there 930 // are outstanding operations on it 931 void remove_web_seed_iter(std::list<web_seed_t>::iterator web); 932 933 // this is called when the torrent has finished. i.e. 934 // all the pieces we have not filtered have been downloaded. 935 // If no pieces are filtered, this is called first and then 936 // completed() is called immediately after it. 937 void finished(); 938 939 // This is the opposite of finished. It is called if we used 940 // to be finished but enabled some files for download so that 941 // we wasn't finished anymore. 942 void resume_download(); 943 944 void verify_piece(piece_index_t piece); 945 void on_piece_verified(piece_index_t piece 946 , sha1_hash const& piece_hash, storage_error const& error); 947 948 // this is called whenever a peer in this swarm becomes interesting 949 // it is responsible for issuing a block request, if appropriate 950 void peer_is_interesting(peer_connection& c); 951 952 // piece_passed is called when a piece passes the hash check 953 // this will tell all peers that we just got his piece 954 // and also let the piece picker know that we have this piece 955 // so it wont pick it for download 956 void piece_passed(piece_index_t index); 957 958 // piece_failed is called when a piece fails the hash check 959 void piece_failed(piece_index_t index); 960 961 // this is the handler for hash failure piece synchronization 962 // i.e. resetting the piece 963 void on_piece_sync(piece_index_t piece); 964 965 // this is the handler for write failure piece synchronization 966 void on_piece_fail_sync(piece_index_t piece, piece_block b); 967 968 void add_redundant_bytes(int b, waste_reason reason); 969 void add_failed_bytes(int b); 970 971 // this is true if we have all the pieces, but not necessarily flushed them to disk 972 bool is_seed() const; 973 974 // this is true if we have all the pieces that we want 975 // the pieces don't necessarily need to be flushed to disk 976 bool is_finished() const; 977 978 bool is_inactive() const; 979 980 std::string save_path() const; 981 alert_manager& alerts() const; picker()982 piece_picker& picker() 983 { 984 TORRENT_ASSERT(m_picker.get()); 985 return *m_picker; 986 } picker() const987 piece_picker const& picker() const 988 { 989 TORRENT_ASSERT(m_picker.get()); 990 return *m_picker; 991 } 992 void need_picker(); has_picker() const993 bool has_picker() const 994 { 995 return m_picker.get() != nullptr; 996 } 997 update_max_failcount()998 void update_max_failcount() 999 { 1000 if (!m_peer_list) return; 1001 torrent_state st = get_peer_list_state(); 1002 m_peer_list->set_max_failcount(&st); 1003 } num_known_peers() const1004 int num_known_peers() const { return m_peer_list ? m_peer_list->num_peers() : 0; } num_connect_candidates() const1005 int num_connect_candidates() const { return m_peer_list ? m_peer_list->num_connect_candidates() : 0; } 1006 1007 void clear_peers(); 1008 has_storage() const1009 bool has_storage() const { return bool(m_storage); } storage() const1010 storage_index_t storage() const { return m_storage; } 1011 storage_interface* get_storage_impl() const; 1012 torrent_file() const1013 torrent_info const& torrent_file() const 1014 { return *m_torrent_file; } 1015 1016 std::shared_ptr<const torrent_info> get_torrent_copy(); 1017 1018 #if TORRENT_ABI_VERSION == 1 1019 // deprecated in 1.2 uuid() const1020 std::string const& uuid() const { return m_uuid; } set_uuid(std::string const & s)1021 void set_uuid(std::string const& s) { m_uuid = s; } url() const1022 std::string const& url() const { return m_url; } set_url(std::string const & s)1023 void set_url(std::string const& s) { m_url = s; } source_feed_url() const1024 std::string const& source_feed_url() const { return m_source_feed_url; } set_source_feed_url(std::string const & s)1025 void set_source_feed_url(std::string const& s) { m_source_feed_url = s; } 1026 #endif 1027 trackers() const1028 std::vector<announce_entry> const& trackers() const 1029 { return m_trackers; } 1030 1031 // this sets all the "enabled" states on all trackers, giving them 1032 // all one more chance of being tried 1033 void enable_all_trackers(); 1034 1035 void replace_trackers(std::vector<announce_entry> const& urls); 1036 1037 // returns true if the tracker was added, and false if it was already 1038 // in the tracker list (in which case the source was added to the 1039 // entry in the list) 1040 bool add_tracker(announce_entry const& url); 1041 1042 torrent_handle get_handle(); 1043 1044 void write_resume_data(resume_data_flags_t const flags, add_torrent_params& ret) const; 1045 seen_complete()1046 void seen_complete() { m_last_seen_complete = ::time(nullptr); } time_since_complete() const1047 int time_since_complete() const { return int(::time(nullptr) - m_last_seen_complete); } last_seen_complete() const1048 time_t last_seen_complete() const { return m_last_seen_complete; } 1049 1050 template <typename Fun, typename... Args> 1051 void wrap(Fun f, Args&&... a); 1052 1053 // LOGGING 1054 #ifndef TORRENT_DISABLE_LOGGING 1055 bool should_log() const override; 1056 void debug_log(const char* fmt, ...) const noexcept override TORRENT_FORMAT(2,3); 1057 1058 void log_to_all_peers(char const* message); 1059 time_point m_dht_start_time; 1060 #endif 1061 1062 // DEBUG 1063 #if TORRENT_USE_INVARIANT_CHECKS 1064 void check_invariant() const; 1065 #endif 1066 1067 // -------------------------------------------- 1068 // RESOURCE MANAGEMENT 1069 1070 // flags are defined in storage.hpp 1071 void move_storage(std::string const& save_path, move_flags_t flags); 1072 1073 // renames the file with the given index to the new name 1074 // the name may include a directory path 1075 // posts alert to indicate success or failure 1076 void rename_file(file_index_t index, std::string name); 1077 1078 // unless this returns true, new connections must wait 1079 // with their initialization. ready_for_connections() const1080 bool ready_for_connections() const 1081 { return m_connections_initialized; } valid_metadata() const1082 bool valid_metadata() const 1083 { return m_torrent_file->is_valid(); } are_files_checked() const1084 bool are_files_checked() const 1085 { return m_files_checked; } 1086 1087 // parses the info section from the given 1088 // bencoded tree and moves the torrent 1089 // to the checker thread for initial checking 1090 // of the storage. 1091 // a return value of false indicates an error 1092 bool set_metadata(span<char const> metadata); 1093 1094 #if TORRENT_ABI_VERSION == 1 1095 void on_torrent_download(error_code const& ec, http_parser const& parser 1096 , span<char const> data); 1097 #endif 1098 sequence_number() const1099 queue_position_t sequence_number() const { return m_sequence_number; } 1100 seed_mode() const1101 bool seed_mode() const { return m_seed_mode; } 1102 1103 enum class seed_mode_t { check_files, skip_checking }; 1104 1105 void leave_seed_mode(seed_mode_t checking); 1106 all_verified() const1107 bool all_verified() const 1108 { return int(m_num_verified) == m_torrent_file->num_pieces(); } verifying_piece(piece_index_t const piece) const1109 bool verifying_piece(piece_index_t const piece) const 1110 { return m_verifying.get_bit(piece); } verifying(piece_index_t const piece)1111 void verifying(piece_index_t const piece) 1112 { 1113 TORRENT_ASSERT(m_verifying.get_bit(piece) == false); 1114 m_verifying.set_bit(piece); 1115 } verified_piece(piece_index_t piece) const1116 bool verified_piece(piece_index_t piece) const 1117 { return m_verified.get_bit(piece); } 1118 void verified(piece_index_t piece); 1119 1120 bool add_merkle_nodes(std::map<int, sha1_hash> const& n, piece_index_t piece); 1121 1122 // this is called once periodically for torrents 1123 // that are not private 1124 void lsd_announce(); 1125 update_last_upload()1126 void update_last_upload() { m_last_upload = aux::time_now32(); } 1127 1128 void set_apply_ip_filter(bool b); apply_ip_filter() const1129 bool apply_ip_filter() const { return m_apply_ip_filter; } 1130 1131 #ifndef TORRENT_DISABLE_PREDICTIVE_PIECES predictive_pieces() const1132 std::vector<piece_index_t> const& predictive_pieces() const 1133 { return m_predictive_pieces; } 1134 1135 // this is called whenever we predict to have this piece 1136 // within one second 1137 void predicted_have_piece(piece_index_t index, int milliseconds); 1138 #endif 1139 clear_in_state_update()1140 void clear_in_state_update() 1141 { 1142 TORRENT_ASSERT(m_links[aux::session_interface::torrent_state_updates].in_list()); 1143 m_links[aux::session_interface::torrent_state_updates].clear(); 1144 } 1145 inc_num_connecting(torrent_peer * pp)1146 void inc_num_connecting(torrent_peer* pp) 1147 { 1148 ++m_num_connecting; 1149 if (pp->seed) ++m_num_connecting_seeds; 1150 } dec_num_connecting(torrent_peer * pp)1151 void dec_num_connecting(torrent_peer* pp) 1152 { 1153 TORRENT_ASSERT(m_num_connecting > 0); 1154 --m_num_connecting; 1155 if (pp->seed) 1156 { 1157 TORRENT_ASSERT(m_num_connecting_seeds > 0); 1158 --m_num_connecting_seeds; 1159 } 1160 TORRENT_ASSERT(m_num_connecting <= int(m_connections.size())); 1161 } 1162 is_ssl_torrent() const1163 bool is_ssl_torrent() const { return m_ssl_torrent; } 1164 #ifdef TORRENT_USE_OPENSSL 1165 void set_ssl_cert(std::string const& certificate 1166 , std::string const& private_key 1167 , std::string const& dh_params 1168 , std::string const& passphrase); 1169 void set_ssl_cert_buffer(std::string const& certificate 1170 , std::string const& private_key 1171 , std::string const& dh_params); ssl_ctx() const1172 boost::asio::ssl::context* ssl_ctx() const { return m_ssl_ctx.get(); } 1173 #endif 1174 num_time_critical_pieces() const1175 int num_time_critical_pieces() const 1176 { 1177 #ifndef TORRENT_DISABLE_STREAMING 1178 return int(m_time_critical_pieces.size()); 1179 #else 1180 return 0; 1181 #endif 1182 } 1183 get_suggest_pieces(std::vector<piece_index_t> & p,typed_bitfield<piece_index_t> const & bits,int const n)1184 int get_suggest_pieces(std::vector<piece_index_t>& p 1185 , typed_bitfield<piece_index_t> const& bits 1186 , int const n) 1187 { 1188 return m_suggest_pieces.get_pieces(p, bits, n); 1189 } 1190 void add_suggest_piece(piece_index_t index); 1191 1192 static constexpr int no_gauge_state = 0xf; 1193 1194 private: 1195 1196 void on_exception(std::exception const& e) override; 1197 void on_error(error_code const& ec) override; 1198 1199 // trigger deferred disconnection of peers 1200 void on_remove_peers() noexcept; 1201 1202 void ip_filter_updated(); 1203 1204 void inc_stats_counter(int c, int value = 1); 1205 1206 // initialize the torrent_state structure passed to peer_list 1207 // member functions. Don't forget to also call peers_erased() 1208 // on the erased member after the peer_list call 1209 torrent_state get_peer_list_state(); 1210 1211 void construct_storage(); 1212 void update_list(torrent_list_index_t list, bool in); 1213 1214 void on_files_deleted(storage_error const& error); 1215 void on_torrent_paused(); 1216 void on_storage_moved(status_t status, std::string const& path 1217 , storage_error const& error); 1218 void on_file_renamed(std::string const& filename 1219 , file_index_t file_idx 1220 , storage_error const& error); 1221 void on_cache_flushed(bool manually_triggered); 1222 1223 // this is used when a torrent is being removed.It synchronizes with the 1224 // disk thread 1225 void on_torrent_aborted(); 1226 1227 // upload and download rate limits for the torrent 1228 void set_limit_impl(int limit, int channel, bool state_update = true); 1229 int limit_impl(int channel) const; 1230 1231 int deprioritize_tracker(int tracker_index); 1232 1233 void update_peer_interest(bool was_finished); 1234 void prioritize_udp_trackers(); 1235 1236 void update_tracker_timer(time_point32 now); 1237 1238 void on_tracker_announce(error_code const& ec); 1239 1240 #ifndef TORRENT_DISABLE_DHT 1241 static void on_dht_announce_response_disp(std::weak_ptr<torrent> t 1242 , std::vector<tcp::endpoint> const& peers); 1243 void on_dht_announce_response(std::vector<tcp::endpoint> const& peers); 1244 bool should_announce_dht() const; 1245 #endif 1246 1247 #ifndef TORRENT_DISABLE_STREAMING 1248 void remove_time_critical_piece(piece_index_t piece, bool finished = false); 1249 void remove_time_critical_pieces(aux::vector<download_priority_t, piece_index_t> const& priority); 1250 void request_time_critical_pieces(); 1251 #endif // TORRENT_DISABLE_STREAMING 1252 1253 void need_peer_list(); 1254 1255 std::shared_ptr<const ip_filter> m_ip_filter; 1256 1257 // all time totals of uploaded and downloaded payload 1258 // stored in resume data 1259 std::int64_t m_total_uploaded = 0; 1260 std::int64_t m_total_downloaded = 0; 1261 1262 // this is a handle that keeps the storage object in the disk io subsystem 1263 // alive, as well as the index referencing the storage/torrent in the disk 1264 // I/O. When this destructs, the torrent will be removed from the disk 1265 // subsystem. 1266 storage_holder m_storage; 1267 1268 #ifdef TORRENT_USE_OPENSSL 1269 std::unique_ptr<boost::asio::ssl::context> m_ssl_ctx; 1270 1271 bool verify_peer_cert(bool preverified, boost::asio::ssl::verify_context& ctx); 1272 1273 void init_ssl(string_view cert); 1274 #endif 1275 1276 void setup_peer_class(); 1277 1278 // The list of web seeds in this torrent. Seeds with fatal errors are 1279 // removed from the set. It's important that iterators are not 1280 // invalidated as entries are added and removed from this list, hence the 1281 // std::list 1282 std::list<web_seed_t> m_web_seeds; 1283 1284 #ifndef TORRENT_DISABLE_EXTENSIONS 1285 std::list<std::shared_ptr<torrent_plugin>> m_extensions; 1286 #endif 1287 1288 // used for tracker announces 1289 deadline_timer m_tracker_timer; 1290 1291 // used to detect when we are active or inactive for long enough 1292 // to trigger the auto-manage logic 1293 deadline_timer m_inactivity_timer; 1294 1295 // this is the upload and download statistics for the whole torrent. 1296 // it's updated from all its peers once every second. 1297 libtorrent::stat m_stat; 1298 1299 // ----------------------------- 1300 1301 // this vector is allocated lazily. If no file priorities are 1302 // ever changed, this remains empty. Any unallocated slot 1303 // implicitly means the file has priority 4. 1304 // TODO: this wastes 5 bits per file 1305 aux::vector<download_priority_t, file_index_t> m_file_priority; 1306 1307 // any file priority updates attempted while another file priority update 1308 // is in-progress/outstanding with the disk I/O thread, are queued up in 1309 // this dictionary. Once the outstanding update comes back, all of these 1310 // are applied in one batch 1311 std::map<file_index_t, download_priority_t> m_deferred_file_priorities; 1312 1313 // this object is used to track download progress of individual files 1314 aux::file_progress m_file_progress; 1315 1316 // a queue of the most recent low-availability pieces we accessed on disk. 1317 // These are good candidates for suggesting other peers to request from 1318 // us. 1319 aux::suggest_piece m_suggest_pieces; 1320 1321 aux::vector<announce_entry> m_trackers; 1322 1323 #ifndef TORRENT_DISABLE_STREAMING 1324 // this list is sorted by time_critical_piece::deadline 1325 std::vector<time_critical_piece> m_time_critical_pieces; 1326 #endif 1327 1328 std::string m_trackerid; 1329 #if TORRENT_ABI_VERSION == 1 1330 // deprecated in 1.1 1331 std::string m_username; 1332 std::string m_password; 1333 #endif 1334 1335 std::string m_save_path; 1336 1337 #if TORRENT_ABI_VERSION == 1 1338 // deprecated in 1.2 1339 1340 // if we don't have the metadata, this is a url to 1341 // the torrent file 1342 std::string m_url; 1343 1344 // if this was added from an RSS feed, this is the unique 1345 // identifier in the feed. 1346 std::string m_uuid; 1347 1348 // if this torrent was added by an RSS feed, this is the 1349 // URL to that feed 1350 std::string m_source_feed_url; 1351 #endif 1352 1353 #ifndef TORRENT_DISABLE_PREDICTIVE_PIECES 1354 // this is a list of all pieces that we have announced 1355 // as having, without actually having yet. If we receive 1356 // a request for a piece in this list, we need to hold off 1357 // on responding until we have completed the piece and 1358 // verified its hash. If the hash fails, send reject to 1359 // peers with outstanding requests, and dont_have to other 1360 // peers. This vector is ordered, to make lookups fast. 1361 1362 // TODO: 3 factor out predictive pieces and all operations on it into a 1363 // separate class (to use as memeber here instead) 1364 std::vector<piece_index_t> m_predictive_pieces; 1365 #endif 1366 1367 // the performance counters of this session 1368 counters& m_stats_counters; 1369 1370 // each bit represents a piece. a set bit means 1371 // the piece has had its hash verified. This 1372 // is only used in seed mode (when m_seed_mode 1373 // is true) 1374 typed_bitfield<piece_index_t> m_verified; 1375 1376 // this means there is an outstanding, async, operation 1377 // to verify each piece that has a 1 1378 typed_bitfield<piece_index_t> m_verifying; 1379 1380 // set if there's an error on this torrent 1381 error_code m_error; 1382 1383 // used if there is any resume data. Some of the information from the 1384 // add_torrent_params struct are needed later in the torrent object's life 1385 // cycle, and not in the constructor. So we need to save if away here 1386 std::unique_ptr<add_torrent_params> m_add_torrent_params; 1387 1388 // if the torrent is started without metadata, it may 1389 // still be given a name until the metadata is received 1390 // once the metadata is received this field will no 1391 // longer be used and will be reset 1392 std::unique_ptr<std::string> m_name; 1393 1394 storage_constructor_type m_storage_constructor; 1395 1396 // the posix time this torrent was added and when 1397 // it was completed. If the torrent isn't yet 1398 // completed, m_completed_time is 0 1399 std::time_t m_added_time; 1400 std::time_t m_completed_time; 1401 1402 // this was the last time _we_ saw a seed in this swarm 1403 std::time_t m_last_seen_complete = 0; 1404 1405 // this is the time last any of our peers saw a seed 1406 // in this swarm 1407 std::time_t m_swarm_last_seen_complete = 0; 1408 1409 // keep a copy if the info-hash here, so it can be accessed from multiple 1410 // threads, and be cheap to access from the client 1411 sha1_hash m_info_hash; 1412 1413 public: 1414 // these are the lists this torrent belongs to. For more 1415 // details about each list, see session_impl.hpp. Each list 1416 // represents a group this torrent belongs to and makes it 1417 // efficient to enumerate only torrents belonging to a specific 1418 // group. Such as torrents that want peer connections or want 1419 // to be ticked etc. 1420 1421 // TODO: 3 factor out the links (as well as update_list() to a separate 1422 // class that torrent can inherit) 1423 aux::array<link, aux::session_interface::num_torrent_lists, torrent_list_index_t> 1424 m_links; 1425 1426 private: 1427 1428 // m_num_verified = m_verified.count() 1429 std::uint32_t m_num_verified = 0; 1430 1431 // if this torrent is running, this was the time 1432 // when it was started. This is used to have a 1433 // bias towards keeping seeding torrents that 1434 // recently was started, to avoid oscillation 1435 // this is specified at a second granularity 1436 time_point32 m_started = aux::time_now32(); 1437 1438 // if we're a seed, this is the timestamp of when we became one 1439 time_point32 m_became_seed = aux::time_now32(); 1440 1441 // if we're finished, this is the timestamp of when we finished 1442 time_point32 m_became_finished = aux::time_now32(); 1443 1444 // when checking, this is the first piece we have not 1445 // issued a hash job for 1446 piece_index_t m_checking_piece{0}; 1447 1448 // the number of pieces we completed the check of 1449 piece_index_t m_num_checked_pieces{0}; 1450 1451 // if the error occurred on a file, this is the index of that file 1452 // there are a few special cases, when this is negative. See 1453 // set_error() 1454 file_index_t m_error_file; 1455 1456 // the average time it takes to download one time critical piece 1457 std::int32_t m_average_piece_time = 0; 1458 1459 // the average piece download time deviation 1460 std::int32_t m_piece_time_deviation = 0; 1461 1462 // the number of bytes that has been 1463 // downloaded that failed the hash-test 1464 std::int64_t m_total_failed_bytes = 0; 1465 std::int64_t m_total_redundant_bytes = 0; 1466 1467 // the sequence number for this torrent, this is a 1468 // monotonically increasing number for each added torrent 1469 queue_position_t m_sequence_number; 1470 1471 // used to post a message to defer disconnecting peers 1472 std::vector<std::shared_ptr<peer_connection>> m_peers_to_disconnect; 1473 aux::deferred_handler m_deferred_disconnect; 1474 aux::handler_storage<104> m_deferred_handler_storage; 1475 1476 // these are the peer IDs we've used for our outgoing peer connections for 1477 // this torrent. If we get an incoming peer claiming to have one of these, 1478 // it's a connection to ourself, and we should reject it. 1479 std::set<peer_id> m_outgoing_pids; 1480 1481 // for torrents who have a bandwidth limit, this is != 0 1482 // and refers to a peer_class in the session. 1483 peer_class_t m_peer_class{0}; 1484 1485 // of all peers in m_connections, this is the number 1486 // of peers that are outgoing and still waiting to 1487 // complete the connection. This is used to possibly 1488 // kick out these connections when we get incoming 1489 // connections (if we've reached the connection limit) 1490 std::uint16_t m_num_connecting = 0; 1491 1492 // this is the peer id we generate when we add the torrent. Peers won't 1493 // use this (they generate their own peer ids) but this is used in case 1494 // the tracker returns peer IDs, to identify ourself in the peer list to 1495 // avoid connecting back to it. 1496 peer_id m_peer_id; 1497 1498 // ============================== 1499 // The following members are specifically 1500 // ordered to make the 24 bit members 1501 // properly 32 bit aligned by inserting 1502 // 8 bits after each one 1503 // ============================== 1504 1505 // if we're currently in upload-mode this is the time timestamp of when 1506 // we entered it 1507 time_point32 m_upload_mode_time = aux::time_now32(); 1508 1509 // true when this torrent should announce to 1510 // trackers 1511 bool m_announce_to_trackers:1; 1512 1513 // true when this torrent should announce to 1514 // the local network 1515 bool m_announce_to_lsd:1; 1516 1517 // is set to true every time there is an incoming 1518 // connection to this torrent 1519 bool m_has_incoming:1; 1520 1521 // this is set to true when the files are checked 1522 // before the files are checked, we don't try to 1523 // connect to peers 1524 bool m_files_checked:1; 1525 1526 // determines the storage state for this torrent. 1527 unsigned int m_storage_mode:2; 1528 1529 // this is true while tracker announcing is enabled 1530 // is is disabled while paused and checking files 1531 bool m_announcing:1; 1532 1533 // this is true when the torrent has been added to the session. Before 1534 // then, it isn't included in the counters (session_stats) 1535 bool m_added:1; 1536 1537 // this is > 0 while the tracker deadline timer 1538 // is in use. i.e. one or more trackers are waiting 1539 // for a reannounce 1540 std::int8_t m_waiting_tracker = 0; 1541 1542 // ---- 1543 1544 // total time we've been active on this torrent. i.e. either (trying to) 1545 // download or seed. does not count time when the torrent is stopped or 1546 // paused. specified in seconds. This only track time _before_ we started 1547 // the torrent this last time. When the torrent is paused, this counter is 1548 // incremented to include this current session. 1549 seconds32 m_active_time{0}; 1550 1551 // the index to the last tracker that worked 1552 std::int8_t m_last_working_tracker = -1; 1553 1554 // ---- 1555 1556 // total time we've been finished with this torrent. 1557 // does not count when the torrent is stopped or paused. 1558 seconds32 m_finished_time{0}; 1559 1560 // in case the piece picker hasn't been constructed 1561 // when this settings is set, this variable will keep 1562 // its value until the piece picker is created 1563 bool m_sequential_download:1; 1564 1565 // this is set if the auto_sequential setting is true and this swarm 1566 // satisfies the criteria to be considered high-availability. i.e. if 1567 // there's mostly seeds in the swarm, download the files sequentially 1568 // for improved disk I/O performance. 1569 bool m_auto_sequential:1; 1570 1571 // this means we haven't verified the file content 1572 // of the files we're seeding. the m_verified bitfield 1573 // indicates which pieces have been verified and which 1574 // haven't 1575 bool m_seed_mode:1; 1576 1577 #ifndef TORRENT_DISABLE_SUPERSEEDING 1578 // if this is true, we're currently super seeding this 1579 // torrent. 1580 bool m_super_seeding:1; 1581 #endif 1582 1583 // if this is set, whenever transitioning into a downloading/seeding state 1584 // from a non-downloading/seeding state, the torrent is paused. 1585 bool m_stop_when_ready:1; 1586 1587 // set to false when saving resume data. Set to true 1588 // whenever something is downloaded 1589 bool m_need_save_resume_data:1; 1590 1591 // when this is true, this torrent participates in the DHT 1592 bool m_enable_dht:1; 1593 1594 // when this is true, this torrent participates in local service discovery 1595 bool m_enable_lsd:1; 1596 1597 // ---- 1598 1599 // total time we've been available as a seed on this torrent. 1600 // does not count when the torrent is stopped or paused. This value only 1601 // accounts for the time prior to the current start of the torrent. When 1602 // the torrent is paused, this counter is incremented to account for the 1603 // additional seeding time. 1604 seconds32 m_seeding_time{0}; 1605 1606 // ---- 1607 1608 // the maximum number of uploads for this torrent 1609 std::uint32_t m_max_uploads:24; 1610 1611 // 8 bits free 1612 1613 // ---- 1614 1615 // the number of unchoked peers in this torrent 1616 unsigned int m_num_uploads:24; 1617 1618 // 4 unused bits 1619 1620 // when this is true, this torrent supports peer exchange 1621 bool m_enable_pex:1; 1622 1623 // set to true if the session IP filter applies to this 1624 // torrent or not. Defaults to true. 1625 bool m_apply_ip_filter:1; 1626 1627 // this is true when our effective inactive state is different from our 1628 // actual inactive state. Whenever this state changes, there is a 1629 // quarantine period until we change the effective state. This is to avoid 1630 // flapping. If the state changes back during this period, we cancel the 1631 // quarantine 1632 bool m_pending_active_change:1; 1633 1634 // ---- 1635 1636 // the number of (16kiB) blocks that fall entirely in pad files 1637 // i.e. blocks that we consider we have on start-up 1638 std::uint16_t m_padding_blocks = 0; 1639 1640 // this is set to the connect boost quota for this torrent. 1641 // After having received this many priority peer connection attempts, it 1642 // falls back onto the steady state peer connection logic, driven by the 1643 // session tick. Each tracker response, as long as this is non-zero, will 1644 // attempt to connect to peers immediately and decrement the counter. 1645 // We give torrents a connect boost when they are first added and then 1646 // every time they resume from being paused. 1647 std::uint8_t m_connect_boost_counter; 1648 1649 // ---- 1650 1651 // the scrape data from the tracker response, this 1652 // is optional and may be 0xffffff 1653 std::uint32_t m_incomplete:24; 1654 1655 // true when the torrent should announce to 1656 // the DHT 1657 bool m_announce_to_dht:1; 1658 1659 // even if we're not built to support SSL torrents, 1660 // remember that this is an SSL torrent, so that we don't 1661 // accidentally start seeding it without any authentication. 1662 bool m_ssl_torrent:1; 1663 1664 // this is set to true if we're trying to delete the 1665 // files belonging to it. When set, don't write any 1666 // more blocks to disk! 1667 bool m_deleted:1; 1668 1669 // ---- 1670 1671 // the timestamp of the last piece passed for this torrent specified in 1672 // seconds since epoch. 1673 time_point32 m_last_download{seconds32(0)}; 1674 1675 // the number of peer connections to seeds. This should be the same as 1676 // counting the peer connections that say true for is_seed() 1677 std::uint16_t m_num_seeds = 0; 1678 1679 // this is the number of peers that are seeds, and count against 1680 // m_num_seeds, but have not yet been connected 1681 std::uint16_t m_num_connecting_seeds = 0; 1682 1683 // the timestamp of the last byte uploaded from this torrent specified in 1684 // seconds since epoch. 1685 time_point32 m_last_upload{seconds32(0)}; 1686 1687 // ---- 1688 1689 // if this is true, libtorrent may pause and resume 1690 // this torrent depending on queuing rules. Torrents 1691 // started with auto_managed flag set may be added in 1692 // a paused state in case there are no available 1693 // slots. 1694 bool m_auto_managed:1; 1695 1696 // the current stats gauge this torrent counts against 1697 std::uint32_t m_current_gauge_state:4; 1698 1699 // set to true while moving the storage 1700 bool m_moving_storage:1; 1701 1702 // this is true if this torrent is considered inactive from the 1703 // queuing mechanism's point of view. If a torrent doesn't transfer 1704 // at high enough rates, it's inactive. 1705 bool m_inactive:1; 1706 1707 // ---- 1708 1709 // the scrape data from the tracker response, this 1710 // is optional and may be 0xffffff 1711 std::uint32_t m_downloaded:24; 1712 1713 #if TORRENT_ABI_VERSION == 1 1714 // the timestamp of the last scrape request to one of the trackers in 1715 // this torrent specified in session_time. This is signed because it must 1716 // be able to represent time before the session started 1717 time_point32 m_last_scrape{seconds32(0)}; 1718 #endif 1719 1720 // ---- 1721 1722 // progress parts per million (the number of 1723 // millionths of completeness) 1724 std::uint32_t m_progress_ppm:20; 1725 1726 // set to true once init() completes successfully. This is important to 1727 // track in case it fails and need to be retried if the client clears 1728 // the torrent error 1729 bool m_torrent_initialized:1; 1730 1731 // this is set to true while waiting for an async_set_file_priority 1732 bool m_outstanding_file_priority:1; 1733 1734 // set to true if we've sent an event=completed to any tracker. This will 1735 // prevent us from sending it again to anyone 1736 bool m_complete_sent:1; 1737 1738 #if TORRENT_USE_ASSERTS 1739 // set to true when torrent is start()ed. It may only be started once 1740 bool m_was_started = false; 1741 bool m_outstanding_check_files = false; 1742 1743 // this is set to true while we're looping over m_connections. We may not 1744 // mutate the list while doing this 1745 mutable int m_iterating_connections = 0; 1746 #endif 1747 }; 1748 } 1749 1750 #endif // TORRENT_TORRENT_HPP_INCLUDED 1751