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