1 /*
2 
3 Copyright (c) 2006, 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_SESSION_IMPL_HPP_INCLUDED
34 #define TORRENT_SESSION_IMPL_HPP_INCLUDED
35 
36 #include "libtorrent/config.hpp"
37 #include "libtorrent/aux_/session_settings.hpp"
38 #include "libtorrent/aux_/session_interface.hpp"
39 #include "libtorrent/aux_/session_udp_sockets.hpp"
40 #include "libtorrent/aux_/socket_type.hpp"
41 #include "libtorrent/torrent_peer.hpp"
42 #include "libtorrent/torrent_peer_allocator.hpp"
43 #include "libtorrent/performance_counters.hpp" // for counters
44 #include "libtorrent/aux_/allocating_handler.hpp"
45 
46 #ifdef TORRENT_USE_OPENSSL
47 #include "libtorrent/ssl_stream.hpp"
48 #endif
49 
50 #include "libtorrent/session.hpp" // for user_load_function_t
51 #include "libtorrent/ip_voter.hpp"
52 #include "libtorrent/entry.hpp"
53 #include "libtorrent/socket.hpp"
54 #include "libtorrent/peer_id.hpp"
55 #include "libtorrent/tracker_manager.hpp"
56 #include "libtorrent/debug.hpp"
57 #include "libtorrent/piece_block_progress.hpp"
58 #include "libtorrent/ip_filter.hpp"
59 #include "libtorrent/aux_/ip_notifier.hpp"
60 #include "libtorrent/session_status.hpp"
61 #include "libtorrent/add_torrent_params.hpp"
62 #include "libtorrent/stat.hpp"
63 #include "libtorrent/file_pool.hpp"
64 #include "libtorrent/bandwidth_manager.hpp"
65 #include "libtorrent/disk_io_thread.hpp"
66 #include "libtorrent/udp_socket.hpp"
67 #include "libtorrent/assert.hpp"
68 #include "libtorrent/alert_manager.hpp" // for alert_manager
69 #include "libtorrent/deadline_timer.hpp"
70 #include "libtorrent/socket_io.hpp" // for print_address
71 #include "libtorrent/address.hpp"
72 #include "libtorrent/utp_socket_manager.hpp"
73 #include "libtorrent/bloom_filter.hpp"
74 #include "libtorrent/peer_class.hpp"
75 #include "libtorrent/disk_io_job.hpp" // block_cache_reference
76 #include "libtorrent/peer_class_type_filter.hpp"
77 #include "libtorrent/kademlia/dht_observer.hpp"
78 #include "libtorrent/kademlia/dht_state.hpp"
79 #include "libtorrent/kademlia/announce_flags.hpp"
80 #include "libtorrent/resolver.hpp"
81 #include "libtorrent/invariant_check.hpp"
82 #include "libtorrent/extensions.hpp"
83 #include "libtorrent/aux_/portmap.hpp"
84 #include "libtorrent/aux_/lsd.hpp"
85 #include "libtorrent/flags.hpp"
86 #include "libtorrent/span.hpp"
87 
88 #if TORRENT_ABI_VERSION == 1
89 #include "libtorrent/session_settings.hpp"
90 #endif
91 
92 #if TORRENT_COMPLETE_TYPES_REQUIRED
93 #include "libtorrent/peer_connection.hpp"
94 #endif
95 
96 #include <algorithm>
97 #include <vector>
98 #include <set>
99 #include <list>
100 #include <deque>
101 #include <condition_variable>
102 #include <mutex>
103 #include <cstdarg> // for va_start, va_end
104 #include <unordered_map>
105 
106 namespace libtorrent {
107 
108 	struct plugin;
109 	struct upnp;
110 	struct natpmp;
111 	struct lsd;
112 	class torrent;
113 	class alert;
114 	struct torrent_handle;
115 
116 namespace dht {
117 
118 	struct dht_tracker;
119 	class item;
120 
121 }
122 
123 namespace aux {
124 
125 	struct session_impl;
126 	struct session_settings;
127 
128 #ifndef TORRENT_DISABLE_LOGGING
129 	struct tracker_logger;
130 #endif
131 
132 	using listen_socket_flags_t = flags::bitfield_flag<std::uint8_t, struct listen_socket_flags_tag>;
133 
134 	struct listen_port_mapping
135 	{
136 		port_mapping_t mapping = port_mapping_t{-1};
137 		int port = 0;
138 	};
139 
140 	struct TORRENT_EXTRA_EXPORT listen_socket_t : utp_socket_interface
141 	{
142 		// we accept incoming connections on this interface
143 		static constexpr listen_socket_flags_t accept_incoming = 0_bit;
144 
145 		// this interface was specified to be just the local network. If this flag
146 		// is not set, this interface is assumed to have a path to the internet
147 		// (i.e. have a gateway configured)
148 		static constexpr listen_socket_flags_t local_network = 1_bit;
149 
150 		// this interface was expanded from the user requesting to
151 		// listen on an unspecified address (either IPv4 or IPv6)
152 		static constexpr listen_socket_flags_t was_expanded = 2_bit;
153 
154 		// there's a proxy configured, and this is the only one interface
155 		// representing that one proxy
156 		static constexpr listen_socket_flags_t proxy = 3_bit;
157 
158 		listen_socket_t() = default;
159 
160 		// listen_socket_t should not be copied or moved because
161 		// references to it are held by the DHT and tracker announce
162 		// code. That code expects a listen_socket_t to always refer
163 		// to the same socket. It would be easy to accidentally
164 		// invalidate that assumption if copying or moving were allowed.
165 		listen_socket_t(listen_socket_t const&) = delete;
166 		listen_socket_t(listen_socket_t&&) = delete;
167 		listen_socket_t& operator=(listen_socket_t const&) = delete;
168 		listen_socket_t& operator=(listen_socket_t&&) = delete;
169 
get_local_endpointlibtorrent::aux::listen_socket_t170 		udp::endpoint get_local_endpoint() override
171 		{
172 			error_code ec;
173 			if (udp_sock) return udp_sock->sock.local_endpoint(ec);
174 			return {local_endpoint.address(), local_endpoint.port()};
175 		}
176 
177 		// returns true if this listen socket/interface can reach and be reached
178 		// by the given address. This is useful to know whether it should be
179 		// annoucned to a tracker (given the tracker's IP) or whether it should
180 		// have a SOCKS5 UDP tunnel set up (given the IP of the socks proxy)
181 		bool can_route(address const&) const;
182 
183 		// this may be empty but can be set
184 		// to the WAN IP address of a NAT router
185 		ip_voter external_address;
186 
187 		// this is a cached local endpoint for the listen TCP socket
188 		tcp::endpoint local_endpoint;
189 
190 		address netmask;
191 
192 		// the name of the device the socket is bound to, may be empty
193 		// if the socket is not bound to a device
194 		std::string device;
195 
196 		// this is the port that was originally specified to listen on it may be
197 		// different from local_endpoint.port() if we had to retry binding with a
198 		// higher port
199 		int original_port = 0;
200 
201 		// tcp_external_port and udp_external_port return the port which
202 		// should be published to peers/trackers for this socket
203 		// If there are active NAT mappings the return value will be
204 		// the external port returned by the NAT router, otherwise the
205 		// local listen port is returned
tcp_external_portlibtorrent::aux::listen_socket_t206 		int tcp_external_port()
207 		{
208 			for (auto const& m : tcp_port_mapping)
209 			{
210 				if (m.port != 0) return m.port;
211 			}
212 			return local_endpoint.port();
213 		}
214 
udp_external_portlibtorrent::aux::listen_socket_t215 		int udp_external_port()
216 		{
217 			for (auto const& m : udp_port_mapping)
218 			{
219 				if (m.port != 0) return m.port;
220 			}
221 			if (udp_sock) return udp_sock->sock.local_port();
222 			return 0;
223 		}
224 
225 		// 0 is natpmp 1 is upnp
226 		// the order of these arrays determines the priorty in
227 		// which their ports will be announced to peers
228 		aux::array<listen_port_mapping, 2, portmap_transport> tcp_port_mapping;
229 		aux::array<listen_port_mapping, 2, portmap_transport> udp_port_mapping;
230 
231 		// indicates whether this is an SSL listen socket or not
232 		transport ssl = transport::plaintext;
233 
234 		listen_socket_flags_t flags = accept_incoming;
235 
236 		// the actual sockets (TCP listen socket and UDP socket)
237 		// An entry does not necessarily have a UDP or TCP socket. One of these
238 		// pointers may be nullptr!
239 		// These must be shared_ptr to avoid a dangling reference if an
240 		// incoming packet is in the event queue when the socket is erased
241 		// TODO: make these direct members and generate shared_ptrs to them
242 		// which alias the listen_socket_t shared_ptr
243 		std::shared_ptr<tcp::acceptor> sock;
244 		std::shared_ptr<aux::session_udp_socket> udp_sock;
245 
246 		// since udp packets are expected to be dispatched frequently, this saves
247 		// time on handler allocation every time we read again.
248 		aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> udp_handler_storage;
249 
250 		std::shared_ptr<natpmp> natpmp_mapper;
251 		std::shared_ptr<upnp> upnp_mapper;
252 
253 		std::shared_ptr<struct lsd> lsd;
254 
255 		// set to true when we receive an incoming connection from this listen
256 		// socket
257 		bool incoming_connection = false;
258 	};
259 
260 		struct TORRENT_EXTRA_EXPORT listen_endpoint_t
261 		{
listen_endpoint_tlibtorrent::aux::listen_endpoint_t262 			listen_endpoint_t(address const& adr, int p, std::string dev, transport s
263 				, listen_socket_flags_t f, address const& nmask = address{})
264 				: addr(adr), netmask(nmask), port(p), device(std::move(dev)), ssl(s), flags(f) {}
265 
operator ==libtorrent::aux::listen_endpoint_t266 			bool operator==(listen_endpoint_t const& o) const
267 			{
268 				return addr == o.addr
269 					&& port == o.port
270 					&& device == o.device
271 					&& ssl == o.ssl
272 					&& flags == o.flags;
273 			}
274 
275 			address addr;
276 			// if this listen endpoint/interface doesn't have a gateway, we cannot
277 			// route outside of our network, this netmask defines the range of our
278 			// local network
279 			address netmask;
280 			int port;
281 			std::string device;
282 			transport ssl;
283 			listen_socket_flags_t flags;
284 		};
285 
286 		// partitions sockets based on whether they match one of the given endpoints
287 		// all matched sockets are ordered before unmatched sockets
288 		// matched endpoints are removed from the vector
289 		// returns an iterator to the first unmatched socket
290 		TORRENT_EXTRA_EXPORT std::vector<std::shared_ptr<aux::listen_socket_t>>::iterator
291 		partition_listen_sockets(
292 			std::vector<listen_endpoint_t>& eps
293 			, std::vector<std::shared_ptr<aux::listen_socket_t>>& sockets);
294 
295 		TORRENT_EXTRA_EXPORT void interface_to_endpoints(
296 			listen_interface_t const& iface
297 			, listen_socket_flags_t flags
298 			, span<ip_interface const> const ifs
299 			, std::vector<listen_endpoint_t>& eps);
300 
301 		// expand [::] to all IPv6 interfaces for BEP 45 compliance
302 		TORRENT_EXTRA_EXPORT void expand_unspecified_address(
303 			span<ip_interface const> ifs
304 			, span<ip_route const> routes
305 			, std::vector<listen_endpoint_t>& eps);
306 
307 		TORRENT_EXTRA_EXPORT void expand_devices(span<ip_interface const>
308 			, std::vector<listen_endpoint_t>& eps);
309 
310 		// this is the link between the main thread and the
311 		// thread started to run the main downloader loop
312 		struct TORRENT_EXTRA_EXPORT session_impl final
313 			: session_interface
314 			, dht::dht_observer
315 			, aux::portmap_callback
316 			, aux::lsd_callback
317 			, boost::noncopyable
318 			, single_threaded
319 			, aux::error_handler_interface
320 			, std::enable_shared_from_this<session_impl>
321 		{
322 			// plugin feature-index key map
323 			enum
324 			{
325 				plugins_all_idx = 0, // to store all plugins
326 				plugins_optimistic_unchoke_idx = 1, // optimistic_unchoke_feature
327 				plugins_tick_idx = 2, // tick_feature
328 				plugins_dht_request_idx = 3 // dht_request_feature
329 			};
330 
331 			template <typename Fun, typename... Args>
332 			void wrap(Fun f, Args&&... a);
333 
334 #if TORRENT_USE_INVARIANT_CHECKS
335 			friend class libtorrent::invariant_access;
336 #endif
337 			using connection_map = std::set<std::shared_ptr<peer_connection>>;
338 			using torrent_map = std::unordered_map<sha1_hash, std::shared_ptr<torrent>>;
339 
340 			session_impl(io_service& ios, settings_pack const& pack, session_flags_t);
341 			~session_impl() override;
342 
343 			void start_session();
344 
345 			void init_peer_class_filter(bool unlimited_local);
346 
call_abortlibtorrent::aux::session_impl347 			void call_abort()
348 			{
349 				auto self = shared_from_this();
350 				m_io_service.dispatch(make_handler([self] { self->abort(); }
351 					, m_abort_handler_storage, *this));
352 			}
353 
354 #ifndef TORRENT_DISABLE_EXTENSIONS
355 			using ext_function_t
356 				= std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>;
357 
358 			struct session_plugin_wrapper : plugin
359 			{
session_plugin_wrapperlibtorrent::aux::session_impl::session_plugin_wrapper360 				explicit session_plugin_wrapper(ext_function_t f) : m_f(std::move(f)) {}
361 
new_torrentlibtorrent::aux::session_impl::session_plugin_wrapper362 				std::shared_ptr<torrent_plugin> new_torrent(torrent_handle const& t, void* user) override
363 				{ return m_f(t, user); }
364 				ext_function_t m_f;
365 			};
366 
367 			void add_extension(std::function<std::shared_ptr<torrent_plugin>(
368 				torrent_handle const&, void*)> ext);
369 			void add_ses_extension(std::shared_ptr<plugin> ext);
370 #endif
371 #if TORRENT_USE_ASSERTS
372 			bool has_peer(peer_connection const* p) const override;
373 			bool any_torrent_has_peer(peer_connection const* p) const override;
is_single_threadlibtorrent::aux::session_impl374 			bool is_single_thread() const override { return single_threaded::is_single_thread(); }
is_posting_torrent_updateslibtorrent::aux::session_impl375 			bool is_posting_torrent_updates() const override { return m_posting_torrent_updates; }
376 			// this is set while the session is building the
377 			// torrent status update message
378 			bool m_posting_torrent_updates = false;
379 			bool verify_queue_position(torrent const* t, queue_position_t pos) override;
380 #endif
381 
382 			void on_exception(std::exception const& e) override;
383 			void on_error(error_code const& ec) override;
384 
385 			void on_ip_change(error_code const& ec);
386 			void reopen_listen_sockets(bool map_ports = true);
387 			void reopen_outgoing_sockets();
388 			void reopen_network_sockets(reopen_network_flags_t options);
389 
get_peer_allocatorlibtorrent::aux::session_impl390 			torrent_peer_allocator_interface& get_peer_allocator() override
391 			{ return m_peer_allocator; }
392 
get_io_servicelibtorrent::aux::session_impl393 			io_service& get_io_service() override { return m_io_service; }
get_resolverlibtorrent::aux::session_impl394 			resolver_interface& get_resolver() override { return m_host_resolver; }
395 
torrent_listlibtorrent::aux::session_impl396 			aux::vector<torrent*>& torrent_list(torrent_list_index_t i) override
397 			{
398 				TORRENT_ASSERT(i >= torrent_list_index_t{});
399 				TORRENT_ASSERT(i < m_torrent_lists.end_index());
400 				return m_torrent_lists[i];
401 			}
402 
403 			// prioritize this torrent to be allocated some connection
404 			// attempts, because this torrent needs more peers.
405 			// this is typically done when a torrent starts out and
406 			// need the initial push to connect peers
407 			void prioritize_connections(std::weak_ptr<torrent> t) override;
408 
409 			void async_accept(std::shared_ptr<tcp::acceptor> const& listener, transport ssl);
410 			void on_accept_connection(std::shared_ptr<socket_type> const& s
411 				, std::weak_ptr<tcp::acceptor> listener, error_code const& e, transport ssl);
412 
413 			void incoming_connection(std::shared_ptr<socket_type> const& s);
414 
415 			std::weak_ptr<torrent> find_torrent(sha1_hash const& info_hash) const override;
416 #if TORRENT_ABI_VERSION == 1
417 			//deprecated in 1.2
418 
419 			TORRENT_DEPRECATED
set_load_functionlibtorrent::aux::session_impl420 			void set_load_function(user_load_function_t fun)
421 			{ m_user_load_torrent = fun; }
422 
423 			TORRENT_DEPRECATED
424 			std::weak_ptr<torrent> find_torrent(std::string const& uuid) const;
425 
426 			TORRENT_DEPRECATED
insert_uuid_torrentlibtorrent::aux::session_impl427 			void insert_uuid_torrent(std::string uuid, std::shared_ptr<torrent> const& t) override
428 			{ m_uuids.insert(std::make_pair(uuid, t)); }
429 #endif
430 #ifndef TORRENT_DISABLE_MUTABLE_TORRENTS
431 			std::vector<std::shared_ptr<torrent>> find_collection(
432 				std::string const& collection) const override;
433 #endif
434 			std::weak_ptr<torrent> find_disconnect_candidate_torrent() const override;
num_torrentslibtorrent::aux::session_impl435 			int num_torrents() const override { return int(m_torrents.size()); }
436 
437 			void insert_torrent(sha1_hash const& ih, std::shared_ptr<torrent> const& t
438 #if TORRENT_ABI_VERSION == 1
439 				, std::string uuid
440 #endif
441 			) override;
442 
443 			std::shared_ptr<torrent> delay_load_torrent(sha1_hash const& info_hash
444 				, peer_connection* pc) override;
445 			void set_queue_position(torrent* t, queue_position_t p) override;
446 
447 			void close_connection(peer_connection* p) noexcept override;
448 
449 			void apply_settings_pack(std::shared_ptr<settings_pack> pack) override;
450 			void apply_settings_pack_impl(settings_pack const& pack);
settingslibtorrent::aux::session_impl451 			session_settings const& settings() const override { return m_settings; }
452 			settings_pack get_settings() const;
453 
454 #ifndef TORRENT_DISABLE_DHT
dhtlibtorrent::aux::session_impl455 			dht::dht_tracker* dht() override { return m_dht.get(); }
announce_dhtlibtorrent::aux::session_impl456 			bool announce_dht() const override { return !m_listen_sockets.empty(); }
457 
458 			void add_dht_node_name(std::pair<std::string, int> const& node);
459 			void add_dht_node(udp::endpoint const& n) override;
460 			void add_dht_router(std::pair<std::string, int> const& node);
461 			void set_dht_settings(dht::dht_settings const& s);
get_dht_settingslibtorrent::aux::session_impl462 			dht::dht_settings const& get_dht_settings() const { return m_dht_settings; }
463 
464 			// you must give up ownership of the dht state
465 			void set_dht_state(dht::dht_state&& state);
466 			void set_dht_state(dht::dht_state const& state) = delete;
467 
468 			void set_dht_storage(dht::dht_storage_constructor_type sc);
469 			void start_dht();
470 			void stop_dht();
471 			bool has_dht() const override;
472 
473 			// this is called for torrents when they are started
474 			// it will prioritize them for announcing to
475 			// the DHT, to get the initial peers quickly
476 			void prioritize_dht(std::weak_ptr<torrent> t) override;
477 
478 			void get_immutable_callback(sha1_hash target
479 				, dht::item const& i);
480 			void get_mutable_callback(dht::item const& i, bool);
481 
482 			void dht_get_immutable_item(sha1_hash const& target);
483 
484 			void dht_get_mutable_item(std::array<char, 32> key
485 				, std::string salt = std::string());
486 
487 			void dht_put_immutable_item(entry const& data, sha1_hash target);
488 
489 			void dht_put_mutable_item(std::array<char, 32> key
490 				, std::function<void(entry&, std::array<char,64>&
491 					, std::int64_t&, std::string const&)> cb
492 				, std::string salt = std::string());
493 
494 			void dht_get_peers(sha1_hash const& info_hash);
495 			void dht_announce(sha1_hash const& info_hash, int port = 0, dht::announce_flags_t flags = {});
496 
497 			void dht_live_nodes(sha1_hash const& nid);
498 			void dht_sample_infohashes(udp::endpoint const& ep, sha1_hash const& target);
499 
500 			void dht_direct_request(udp::endpoint const& ep, entry& e
501 				, void* userdata = nullptr);
502 
503 #if TORRENT_ABI_VERSION == 1
504 			TORRENT_DEPRECATED
505 			entry dht_state() const;
506 			TORRENT_DEPRECATED
507 			void start_dht_deprecated(entry const& startup_state);
508 #endif
509 			void on_dht_announce(error_code const& e);
510 			void on_dht_name_lookup(error_code const& e
511 				, std::vector<address> const& addresses, int port);
512 			void on_dht_router_name_lookup(error_code const& e
513 				, std::vector<address> const& addresses, int port);
514 #endif
515 
516 #if !defined TORRENT_DISABLE_ENCRYPTION
517 			torrent const* find_encrypted_torrent(
518 				sha1_hash const& info_hash, sha1_hash const& xor_mask) override;
519 
520 			void add_obfuscated_hash(sha1_hash const& obfuscated, std::weak_ptr<torrent> const& t) override;
521 #endif
522 
523 			void on_lsd_announce(error_code const& e);
524 
525 			// called when a port mapping is successful, or a router returns
526 			// a failure to map a port
527 			void on_port_mapping(port_mapping_t mapping, address const& ip, int port
528 				, portmap_protocol proto, error_code const& ec
529 				, portmap_transport transport) override;
530 
is_abortedlibtorrent::aux::session_impl531 			bool is_aborted() const override { return m_abort; }
is_pausedlibtorrent::aux::session_impl532 			bool is_paused() const { return m_paused; }
533 
534 			void pause();
535 			void resume();
536 
537 			void set_ip_filter(std::shared_ptr<ip_filter> const& f);
538 			ip_filter const& get_ip_filter();
539 
540 			void set_port_filter(port_filter const& f);
541 			port_filter const& get_port_filter() const override;
542 			void ban_ip(address addr) override;
543 
544 			void queue_tracker_request(tracker_request&& req
545 				, std::weak_ptr<request_callback> c) override;
546 
547 			// ==== peer class operations ====
548 
549 			// implements session_interface
550 			void set_peer_classes(peer_class_set* s, address const& a, int st) override;
peer_classeslibtorrent::aux::session_impl551 			peer_class_pool const& peer_classes() const override { return m_classes; }
peer_classeslibtorrent::aux::session_impl552 			peer_class_pool& peer_classes() override { return m_classes; }
553 			bool ignore_unchoke_slots_set(peer_class_set const& set) const override;
554 			int copy_pertinent_channels(peer_class_set const& set
555 				, int channel, bandwidth_channel** dst, int m) override;
556 			int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) override;
557 			bool use_quota_overhead(bandwidth_channel* ch, int amount);
558 
559 			peer_class_t create_peer_class(char const* name);
560 			void delete_peer_class(peer_class_t cid);
561 			void set_peer_class_filter(ip_filter const& f);
562 			ip_filter const& get_peer_class_filter() const;
563 
564 			void set_peer_class_type_filter(peer_class_type_filter f);
565 			peer_class_type_filter get_peer_class_type_filter();
566 
567 			peer_class_info get_peer_class(peer_class_t cid) const;
568 			void set_peer_class(peer_class_t cid, peer_class_info const& pci);
569 
570 			bool is_listening() const;
571 
572 #ifndef TORRENT_DISABLE_EXTENSIONS
573 			void add_extensions_to_torrent(
574 				std::shared_ptr<torrent> const& torrent_ptr, void* userdata);
575 #endif
576 
577 			// the add_torrent_params object must be moved in
578 			torrent_handle add_torrent(add_torrent_params&&, error_code& ec);
579 
580 			// second return value is true if the torrent was added and false if an
581 			// existing one was found.
582 			std::pair<std::shared_ptr<torrent>, bool>
583 			add_torrent_impl(add_torrent_params& p, error_code& ec);
584 			void async_add_torrent(add_torrent_params* params);
585 
586 #if TORRENT_ABI_VERSION == 1
587 			void on_async_load_torrent(add_torrent_params* params, error_code ec);
588 #endif
589 
590 			void remove_torrent(torrent_handle const& h, remove_flags_t options) override;
591 			void remove_torrent_impl(std::shared_ptr<torrent> tptr, remove_flags_t options) override;
592 
593 			void get_torrent_status(std::vector<torrent_status>* ret
594 				, std::function<bool(torrent_status const&)> const& pred
595 				, status_flags_t flags) const;
596 			void refresh_torrent_status(std::vector<torrent_status>* ret
597 				, status_flags_t flags) const;
598 			void post_torrent_updates(status_flags_t flags);
599 			void post_session_stats();
600 			void post_dht_stats();
601 
602 			std::vector<torrent_handle> get_torrents() const;
603 
604 			void pop_alerts(std::vector<alert*>* alerts);
605 			alert* wait_for_alert(time_duration max_wait);
606 
607 #if TORRENT_ABI_VERSION == 1
608 			TORRENT_DEPRECATED void pop_alerts();
609 			TORRENT_DEPRECATED alert const* pop_alert();
610 			TORRENT_DEPRECATED std::size_t set_alert_queue_size_limit(std::size_t queue_size_limit_);
611 			TORRENT_DEPRECATED int upload_rate_limit_depr() const;
612 			TORRENT_DEPRECATED int download_rate_limit_depr() const;
613 			TORRENT_DEPRECATED int local_upload_rate_limit() const;
614 			TORRENT_DEPRECATED int local_download_rate_limit() const;
615 
616 			TORRENT_DEPRECATED void set_local_download_rate_limit(int bytes_per_second);
617 			TORRENT_DEPRECATED void set_local_upload_rate_limit(int bytes_per_second);
618 			TORRENT_DEPRECATED void set_download_rate_limit_depr(int bytes_per_second);
619 			TORRENT_DEPRECATED void set_upload_rate_limit_depr(int bytes_per_second);
620 			TORRENT_DEPRECATED void set_max_connections(int limit);
621 			TORRENT_DEPRECATED void set_max_uploads(int limit);
622 
623 			TORRENT_DEPRECATED int max_connections() const;
624 			TORRENT_DEPRECATED int max_uploads() const;
625 #endif
626 
627 			bandwidth_manager* get_bandwidth_manager(int channel) override;
628 
629 			int upload_rate_limit(peer_class_t c) const;
630 			int download_rate_limit(peer_class_t c) const;
631 			void set_upload_rate_limit(peer_class_t c, int limit);
632 			void set_download_rate_limit(peer_class_t c, int limit);
633 
634 			void set_rate_limit(peer_class_t c, int channel, int limit);
635 			int rate_limit(peer_class_t c, int channel) const;
636 
637 			bool preemptive_unchoke() const override;
638 
639 			// deprecated, use stats counters ``num_peers_up_unchoked`` instead
num_uploadslibtorrent::aux::session_impl640 			int num_uploads() const override
641 			{ return int(m_stats_counters[counters::num_peers_up_unchoked]); }
642 
643 			// deprecated, use stats counters ``num_peers_connected`` +
644 			// ``num_peers_half_open`` instead.
num_connectionslibtorrent::aux::session_impl645 			int num_connections() const override { return int(m_connections.size()); }
646 
trigger_unchokelibtorrent::aux::session_impl647 			void trigger_unchoke() noexcept override
648 			{
649 				TORRENT_ASSERT(is_single_thread());
650 				m_unchoke_time_scaler = 0;
651 			}
trigger_optimistic_unchokelibtorrent::aux::session_impl652 			void trigger_optimistic_unchoke() noexcept override
653 			{
654 				TORRENT_ASSERT(is_single_thread());
655 				m_optimistic_unchoke_time_scaler = 0;
656 			}
657 
658 #if TORRENT_ABI_VERSION == 1
659 #include "libtorrent/aux_/disable_warnings_push.hpp"
660 			session_status status() const;
661 			peer_id deprecated_get_peer_id() const;
662 #include "libtorrent/aux_/disable_warnings_pop.hpp"
663 #endif
664 
665 			void get_cache_info(torrent_handle h, cache_status* ret, int flags) const;
666 
667 			std::uint16_t listen_port() const override;
668 			std::uint16_t listen_port(listen_socket_t* sock) const;
669 			std::uint16_t ssl_listen_port() const override;
670 			std::uint16_t ssl_listen_port(listen_socket_t* sock) const;
671 
672 			// used by the DHT tracker, returns a UDP listen port
673 			int get_listen_port(transport ssl, aux::listen_socket_handle const& s) override;
674 			// used by peer connections, returns a TCP listen port
675 			// or zero if no matching listen socket is found
676 			int listen_port(transport ssl, address const& local_addr) override;
677 
for_each_listen_socketlibtorrent::aux::session_impl678 			void for_each_listen_socket(std::function<void(aux::listen_socket_handle const&)> f) override
679 			{
680 				for (auto& s : m_listen_sockets)
681 				{
682 					f(listen_socket_handle(s));
683 				}
684 			}
685 
alertslibtorrent::aux::session_impl686 			alert_manager& alerts() override { return m_alerts; }
disk_threadlibtorrent::aux::session_impl687 			disk_interface& disk_thread() override { return m_disk_thread; }
688 
689 			void abort() noexcept;
690 			void abort_stage2() noexcept;
691 
692 			torrent_handle find_torrent_handle(sha1_hash const& info_hash);
693 
694 			void announce_lsd(sha1_hash const& ih, int port) override;
695 
696 			void save_state(entry* e, save_state_flags_t flags) const;
697 			void load_state(bdecode_node const* e, save_state_flags_t flags);
698 
699 			bool has_connection(peer_connection* p) const override;
700 			void insert_peer(std::shared_ptr<peer_connection> const& c) override;
701 
702 			proxy_settings proxy() const override;
703 
704 #ifndef TORRENT_DISABLE_DHT
is_dht_runninglibtorrent::aux::session_impl705 			bool is_dht_running() const { return (m_dht.get() != nullptr); }
706 			int external_udp_port(address const& local_address) const override;
707 #endif
708 
709 #if TORRENT_USE_I2P
i2p_sessionlibtorrent::aux::session_impl710 			char const* i2p_session() const override { return m_i2p_conn.session_id(); }
711 			proxy_settings i2p_proxy() const override;
712 
713 			void on_i2p_open(error_code const& ec);
714 			void open_new_incoming_i2p_connection();
715 			void on_i2p_accept(std::shared_ptr<socket_type> const& s
716 				, error_code const& e);
717 #endif
718 
719 			void start_ip_notifier();
720 			void start_lsd();
721 			void start_natpmp();
722 			void start_upnp();
723 
724 			void stop_ip_notifier();
725 			void stop_lsd();
726 			void stop_natpmp();
727 			void stop_upnp();
728 
729 			std::vector<port_mapping_t> add_port_mapping(portmap_protocol t, int external_port
730 				, int local_port);
731 			void delete_port_mapping(port_mapping_t handle);
732 
733 			int next_port() const;
734 
735 			void deferred_submit_jobs() override;
736 
737 			// implements dht_observer
738 			void set_external_address(aux::listen_socket_handle const& iface
739 				, address const& ip, address const& source) override;
740 			void get_peers(sha1_hash const& ih) override;
741 			void announce(sha1_hash const& ih, address const& addr, int port) override;
742 			void outgoing_get_peers(sha1_hash const& target
743 				, sha1_hash const& sent_target, udp::endpoint const& ep) override;
744 
745 #ifndef TORRENT_DISABLE_LOGGING
746 			bool should_log(module_t m) const override;
747 			void log(module_t m, char const* fmt, ...)
748 				override TORRENT_FORMAT(3,4);
749 			void log_packet(message_direction_t dir, span<char const> pkt
750 				, udp::endpoint const& node) override;
751 
752 			bool should_log_portmap(portmap_transport transport) const override;
753 			void log_portmap(portmap_transport transport, char const* msg) const override;
754 
755 			bool should_log_lsd() const override;
756 			void log_lsd(char const* msg) const override;
757 #endif
758 
759 			bool on_dht_request(string_view query
760 				, dht::msg const& request, entry& response) override;
761 
762 			void set_external_address(tcp::endpoint const& local_endpoint
763 				, address const& ip
764 				, ip_source_t source_type, address const& source) override;
765 			external_ip external_address() const override;
766 
767 			// used when posting synchronous function
768 			// calls to session_impl and torrent objects
769 			mutable std::mutex mut;
770 			mutable std::condition_variable cond;
771 
772 			// implements session_interface
773 			tcp::endpoint bind_outgoing_socket(socket_type& s
774 				, address const& remote_address, error_code& ec) const override;
775 			bool verify_incoming_interface(address const& addr);
776 			bool verify_bound_address(address const& addr, bool utp
777 				, error_code& ec) override;
778 
779 			bool has_lsd() const override;
780 
block_info_storagelibtorrent::aux::session_impl781 			std::vector<block_info>& block_info_storage() override { return m_block_info_storage; }
782 
utp_socket_managerlibtorrent::aux::session_impl783 			libtorrent::utp_socket_manager* utp_socket_manager() override
784 			{ return &m_utp_socket_manager; }
785 #ifdef TORRENT_USE_OPENSSL
ssl_utp_socket_managerlibtorrent::aux::session_impl786 			libtorrent::utp_socket_manager* ssl_utp_socket_manager() override
787 			{ return &m_ssl_utp_socket_manager; }
788 #endif
789 
inc_boost_connectionslibtorrent::aux::session_impl790 			void inc_boost_connections() override
791 			{
792 				++m_boost_connections;
793 				m_stats_counters.inc_stats_counter(counters::boost_connection_attempts);
794 			}
795 
796 			// the settings for the client
797 			aux::session_settings m_settings;
798 
799 #if TORRENT_ABI_VERSION == 1
800 			void update_ssl_listen();
801 			void update_local_download_rate();
802 			void update_local_upload_rate();
803 			void update_rate_limit_utp();
804 			void update_ignore_rate_limits_on_local_network();
805 #endif
806 
807 			void update_dht_upload_rate_limit();
808 			void update_proxy();
809 			void update_i2p_bridge();
810 			void update_peer_tos();
811 			void update_user_agent();
812 			void update_unchoke_limit();
813 			void update_connection_speed();
814 			void update_queued_disk_bytes();
815 			void update_alert_queue_size();
816 			void update_disk_threads();
817 			void update_report_web_seed_downloads();
818 			void update_outgoing_interfaces();
819 			void update_listen_interfaces();
820 			void update_privileged_ports();
821 			void update_auto_sequential();
822 			void update_max_failcount();
823 			void update_resolver_cache_timeout();
824 
825 			void update_ip_notifier();
826 			void update_upnp();
827 			void update_natpmp();
828 			void update_lsd();
829 			void update_dht();
830 			void update_count_slow();
831 			void update_dht_bootstrap_nodes();
832 			void update_dht_settings();
833 
834 			void update_socket_buffer_size();
835 			void update_dht_announce_interval();
836 			void update_download_rate();
837 			void update_upload_rate();
838 			void update_connections_limit();
839 			void update_alert_mask();
840 			void update_validate_https();
841 
842 			void trigger_auto_manage() override;
843 
844 		private:
845 
846 			// return the settings value for int setting "n", if the value is
847 			// negative, return INT_MAX
848 			int get_int_setting(int n) const;
849 
850 			aux::array<aux::vector<torrent*>, num_torrent_lists, torrent_list_index_t>
851 				m_torrent_lists;
852 
853 			peer_class_pool m_classes;
854 
855 			void init();
856 
857 			void submit_disk_jobs();
858 
859 			void on_trigger_auto_manage();
860 
861 			void on_lsd_peer(tcp::endpoint const& peer, sha1_hash const& ih) override;
862 
863 			void start_natpmp(aux::listen_socket_t& s);
864 			void start_upnp(aux::listen_socket_t& s);
865 
866 			void set_external_address(std::shared_ptr<listen_socket_t> const& sock, address const& ip
867 				, ip_source_t source_type, address const& source);
868 
869 			counters m_stats_counters;
870 
871 			// this is a pool allocator for torrent_peer objects
872 			// torrents and the disk cache (implicitly by holding references to the
873 			// torrents) depend on this outliving them.
874 			torrent_peer_allocator m_peer_allocator;
875 
876 			// this vector is used to store the block_info
877 			// objects pointed to by partial_piece_info returned
878 			// by torrent::get_download_queue.
879 			std::vector<block_info> m_block_info_storage;
880 
881 			io_service& m_io_service;
882 
883 #ifdef TORRENT_USE_OPENSSL
884 			// this is a generic SSL context used when talking to HTTPS servers
885 			ssl::context m_ssl_ctx;
886 
887 			// this is the SSL context used for SSL listen sockets. It doesn't
888 			// verify peers, but it has the servername callback set on it. Once it
889 			// knows which torrent a peer is connecting to, it will switch the
890 			// socket over to the torrent specific context, which does verify peers
891 			ssl::context m_peer_ssl_ctx;
892 #endif
893 
894 			// handles delayed alerts
895 			mutable alert_manager m_alerts;
896 
897 #if TORRENT_ABI_VERSION == 1
898 			// the alert pointers stored in m_alerts
899 			mutable aux::vector<alert*> m_alert_pointers;
900 
901 			// if not all the alerts in m_alert_pointers have been delivered to
902 			// the client. This is the offset into m_alert_pointers where the next
903 			// alert is. If this is greater than or equal to m_alert_pointers.size()
904 			// it means we need to request new alerts from the main thread.
905 			mutable int m_alert_pointer_pos = 0;
906 #endif
907 
908 			// handles disk io requests asynchronously
909 			// peers have pointers into the disk buffer
910 			// pool, and must be destructed before this
911 			// object. The disk thread relies on the file
912 			// pool object, and must be destructed before
913 			// m_files. The disk io thread posts completion
914 			// events to the io service, and needs to be
915 			// constructed after it.
916 			disk_io_thread m_disk_thread;
917 
918 			// the bandwidth manager is responsible for
919 			// handing out bandwidth to connections that
920 			// asks for it, it can also throttle the
921 			// rate.
922 			bandwidth_manager m_download_rate;
923 			bandwidth_manager m_upload_rate;
924 
925 			// the peer class that all peers belong to by default
926 			peer_class_t m_global_class{0};
927 
928 			// the peer class all TCP peers belong to by default
929 			// all tcp peer connections are subject to these
930 			// bandwidth limits. Local peers are exempted
931 			// from this limit. The purpose is to be able to
932 			// throttle TCP that passes over the internet
933 			// bottleneck (i.e. modem) to avoid starving out
934 			// uTP connections.
935 			peer_class_t m_tcp_peer_class{0};
936 
937 			// peer class for local peers
938 			peer_class_t m_local_peer_class{0};
939 
940 			resolver m_host_resolver;
941 
942 			tracker_manager m_tracker_manager;
943 
944 			// the torrents must be destructed after the torrent_peer_allocator,
945 			// since the torrents hold the peer lists that own the torrent_peers
946 			// (which are allocated in the torrent_peer_allocator)
947 			torrent_map m_torrents;
948 
949 			// all torrents that are downloading or queued,
950 			// ordered by their queue position
951 			aux::vector<torrent*, queue_position_t> m_download_queue;
952 
953 #if !defined TORRENT_DISABLE_ENCRYPTION
954 			// this maps obfuscated hashes to torrents. It's only
955 			// used when encryption is enabled
956 			torrent_map m_obfuscated_torrents;
957 #endif
958 
959 #if TORRENT_ABI_VERSION == 1
960 			//deprecated in 1.2
961 			std::map<std::string, std::shared_ptr<torrent>> m_uuids;
962 #endif
963 
964 			// peer connections are put here when disconnected to avoid
965 			// race conditions with the disk thread. It's important that
966 			// peer connections are destructed from the network thread,
967 			// once a peer is disconnected, it's put in this list and
968 			// every second their refcount is checked, and if it's 1,
969 			// they are deleted (from the network thread)
970 			std::vector<std::shared_ptr<peer_connection>> m_undead_peers;
971 
972 			// keep the io_service alive until we have posted the job
973 			// to clear the undead peers
974 			std::unique_ptr<io_service::work> m_work;
975 
976 			// this maps sockets to their peer_connection
977 			// object. It is the complete list of all connected
978 			// peers.
979 			connection_map m_connections;
980 
981 			// this list holds incoming connections while they
982 			// are performing SSL handshake. When we shut down
983 			// the session, all of these are disconnected, otherwise
984 			// they would linger and stall or hang session shutdown
985 			std::set<std::shared_ptr<socket_type>> m_incoming_sockets;
986 
987 			// maps IP ranges to bitfields representing peer class IDs
988 			// to assign peers matching a specific IP range based on its
989 			// remote endpoint
990 			ip_filter m_peer_class_filter;
991 
992 			// maps socket types to peer classes
993 			peer_class_type_filter m_peer_class_type_filter;
994 
995 			// filters incoming connections
996 			std::shared_ptr<ip_filter> m_ip_filter;
997 
998 			// filters outgoing connections
999 			port_filter m_port_filter;
1000 
1001 			// posts a notification when the set of local IPs changes
1002 			std::unique_ptr<ip_change_notifier> m_ip_notifier;
1003 
1004 			// the addresses or device names of the interfaces we are supposed to
1005 			// listen on. if empty, it means that we should let the os decide
1006 			// which interface to listen on
1007 			std::vector<listen_interface_t> m_listen_interfaces;
1008 
1009 			// the network interfaces outgoing connections are opened through. If
1010 			// there is more then one, they are used in a round-robin fashion
1011 			// each element is a device name or IP address (in string form) and
1012 			// a port number. The port determines which port to bind the listen
1013 			// socket to, and the device or IP determines which network adapter
1014 			// to be used. If no adapter with the specified name exists, the listen
1015 			// socket fails.
1016 			std::vector<std::string> m_outgoing_interfaces;
1017 
1018 			// since we might be listening on multiple interfaces
1019 			// we might need more than one listen socket
1020 			std::vector<std::shared_ptr<listen_socket_t>> m_listen_sockets;
1021 
1022 #if TORRENT_USE_I2P
1023 			i2p_connection m_i2p_conn;
1024 			std::shared_ptr<socket_type> m_i2p_listen_socket;
1025 #endif
1026 
1027 #ifdef TORRENT_USE_OPENSSL
ssl_ctxlibtorrent::aux::session_impl1028 			ssl::context* ssl_ctx() override { return &m_ssl_ctx; }
1029 			void on_incoming_utp_ssl(std::shared_ptr<socket_type> const& s);
1030 			void ssl_handshake(error_code const& ec, std::shared_ptr<socket_type> s);
1031 #endif
1032 
1033 			// round-robin index into m_outgoing_interfaces
1034 			mutable std::uint8_t m_interface_index = 0;
1035 
1036 			std::shared_ptr<listen_socket_t> setup_listener(
1037 				listen_endpoint_t const& lep, error_code& ec);
1038 
1039 #ifndef TORRENT_DISABLE_DHT
1040 			dht::dht_state m_dht_state;
1041 #endif
1042 
1043 			// this is initialized to the unchoke_interval
1044 			// session_setting and decreased every second.
1045 			// when it reaches zero, it is reset to the
1046 			// unchoke_interval and the unchoke set is
1047 			// recomputed.
1048 			// TODO: replace this by a proper asio timer
1049 			int m_unchoke_time_scaler = 0;
1050 
1051 			// this is used to decide when to recalculate which
1052 			// torrents to keep queued and which to activate
1053 			// TODO: replace this by a proper asio timer
1054 			int m_auto_manage_time_scaler = 0;
1055 
1056 			// works like unchoke_time_scaler but it
1057 			// is only decreased when the unchoke set
1058 			// is recomputed, and when it reaches zero,
1059 			// the optimistic unchoke is moved to another peer.
1060 			// TODO: replace this by a proper asio timer
1061 			int m_optimistic_unchoke_time_scaler = 0;
1062 
1063 			// works like unchoke_time_scaler. Each time
1064 			// it reaches 0, and all the connections are
1065 			// used, the worst connection will be disconnected
1066 			// from the torrent with the most peers
1067 			int m_disconnect_time_scaler = 90;
1068 
1069 			// when this scaler reaches zero, it will
1070 			// scrape one of the auto managed, paused,
1071 			// torrents.
1072 			int m_auto_scrape_time_scaler = 180;
1073 
1074 			// statistics gathered from all torrents.
1075 			stat m_stat;
1076 
1077 			// implements session_interface
1078 			void sent_bytes(int bytes_payload, int bytes_protocol) override;
1079 			void received_bytes(int bytes_payload, int bytes_protocol) override;
1080 			void trancieve_ip_packet(int bytes, bool ipv6) override;
1081 			void sent_syn(bool ipv6) override;
1082 			void received_synack(bool ipv6) override;
1083 
1084 #if TORRENT_ABI_VERSION == 1
1085 			int m_peak_up_rate = 0;
1086 #endif
1087 
1088 			void on_tick(error_code const& e);
1089 
1090 			void try_connect_more_peers();
1091 			void auto_manage_checking_torrents(std::vector<torrent*>& list
1092 				, int& limit);
1093 			void auto_manage_torrents(std::vector<torrent*>& list
1094 				, int& dht_limit, int& tracker_limit
1095 				, int& lsd_limit, int& hard_limit, int type_limit);
1096 			void recalculate_auto_managed_torrents();
1097 			void recalculate_unchoke_slots();
1098 			void recalculate_optimistic_unchoke_slots();
1099 
1100 			time_point m_created;
session_timelibtorrent::aux::session_impl1101 			std::uint16_t session_time() const override
1102 			{
1103 				// +1 is here to make it possible to distinguish uninitialized (to
1104 				// 0) timestamps and timestamps of things that happened during the
1105 				// first second after the session was constructed
1106 				std::int64_t const ret = total_seconds(aux::time_now()
1107 					- m_created) + 1;
1108 				TORRENT_ASSERT(ret >= 0);
1109 				if (ret > (std::numeric_limits<std::uint16_t>::max)())
1110 					return (std::numeric_limits<std::uint16_t>::max)();
1111 				return static_cast<std::uint16_t>(ret);
1112 			}
session_start_timelibtorrent::aux::session_impl1113 			time_point session_start_time() const override
1114 			{
1115 				return m_created;
1116 			}
1117 
1118 			time_point m_last_tick;
1119 			time_point m_last_second_tick;
1120 
1121 			// the last time we went through the peers
1122 			// to decide which ones to choke/unchoke
1123 			time_point m_last_choke;
1124 
1125 			// the last time we recalculated which torrents should be started
1126 			// and stopped (only the auto managed ones)
1127 			time_point m_last_auto_manage;
1128 
1129 			// when outgoing_ports is configured, this is the
1130 			// port we'll bind the next outgoing socket to
1131 			mutable int m_next_port = 0;
1132 
1133 #ifndef TORRENT_DISABLE_DHT
1134 			std::unique_ptr<dht::dht_storage_interface> m_dht_storage;
1135 			std::shared_ptr<dht::dht_tracker> m_dht;
1136 			dht::settings m_dht_settings;
1137 			dht::dht_storage_constructor_type m_dht_storage_constructor
1138 				= dht::dht_default_storage_constructor;
1139 
1140 			// these are used when starting the DHT
1141 			// (and bootstrapping it), and then erased
1142 			std::vector<udp::endpoint> m_dht_router_nodes;
1143 
1144 			// if a DHT node is added when there's no DHT instance, they're stored
1145 			// here until we start the DHT
1146 			std::vector<udp::endpoint> m_dht_nodes;
1147 
1148 			// this announce timer is used
1149 			// by the DHT.
1150 			deadline_timer m_dht_announce_timer;
1151 
1152 			// the number of torrents there were when the
1153 			// update_dht_announce_interval() was last called.
1154 			// if the number of torrents changes significantly
1155 			// compared to this number, the DHT announce interval
1156 			// is updated again. This especially matters for
1157 			// small numbers.
1158 			int m_dht_interval_update_torrents = 0;
1159 
1160 			// the number of DHT router lookups there are currently outstanding. As
1161 			// long as this is > 0, we'll postpone starting the DHT
1162 			int m_outstanding_router_lookups = 0;
1163 #endif
1164 
1165 			void send_udp_packet_hostname(std::weak_ptr<utp_socket_interface> sock
1166 				, char const* hostname
1167 				, int port
1168 				, span<char const> p
1169 				, error_code& ec
1170 				, udp_send_flags_t flags);
1171 
send_udp_packet_hostname_listenlibtorrent::aux::session_impl1172 			void send_udp_packet_hostname_listen(aux::listen_socket_handle const& sock
1173 				, char const* hostname
1174 				, int port
1175 				, span<char const> p
1176 				, error_code& ec
1177 				, udp_send_flags_t const flags)
1178 			{
1179 				listen_socket_t* s = sock.get();
1180 				if (!s)
1181 				{
1182 					ec = boost::asio::error::bad_descriptor;
1183 					return;
1184 				}
1185 				send_udp_packet_hostname(sock.get_ptr(), hostname, port, p, ec, flags);
1186 			}
1187 
1188 			void send_udp_packet(std::weak_ptr<utp_socket_interface> sock
1189 				, udp::endpoint const& ep
1190 				, span<char const> p
1191 				, error_code& ec
1192 				, udp_send_flags_t flags);
1193 
send_udp_packet_listenlibtorrent::aux::session_impl1194 			void send_udp_packet_listen(aux::listen_socket_handle const& sock
1195 				, udp::endpoint const& ep
1196 				, span<char const> p
1197 				, error_code& ec
1198 				, udp_send_flags_t const flags)
1199 			{
1200 				listen_socket_t* s = sock.get();
1201 				if (!s)
1202 				{
1203 					ec = boost::asio::error::bad_descriptor;
1204 					return;
1205 				}
1206 				send_udp_packet(sock.get_ptr(), ep, p, ec, flags);
1207 			}
1208 
1209 			void on_udp_writeable(std::weak_ptr<session_udp_socket> s, error_code const& ec);
1210 
1211 			void on_udp_packet(std::weak_ptr<session_udp_socket> s
1212 				, std::weak_ptr<listen_socket_t> ls
1213 				, transport ssl, error_code const& ec);
1214 
1215 			libtorrent::utp_socket_manager m_utp_socket_manager;
1216 
1217 #ifdef TORRENT_USE_OPENSSL
1218 			// used for uTP connections over SSL
1219 			libtorrent::utp_socket_manager m_ssl_utp_socket_manager;
1220 #endif
1221 
1222 			// the number of torrent connection boosts
1223 			// connections that have been made this second
1224 			// this is deducted from the connect speed
1225 			int m_boost_connections = 0;
1226 
1227 #if TORRENT_ABI_VERSION == 1
1228 			struct work_thread_t
1229 			{
work_thread_tlibtorrent::aux::session_impl::work_thread_t1230 				work_thread_t()
1231 					: work(new boost::asio::io_service::work(ios))
1232 					, thread([this] { ios.run(); })
1233 				{}
~work_thread_tlibtorrent::aux::session_impl::work_thread_t1234 				~work_thread_t()
1235 				{
1236 					work.reset();
1237 					thread.join();
1238 				}
1239 				work_thread_t(work_thread_t const&) = delete;
1240 				work_thread_t& operator=(work_thread_t const&) = delete;
1241 
1242 				boost::asio::io_service ios;
1243 				std::unique_ptr<boost::asio::io_service::work> work;
1244 				std::thread thread;
1245 			};
1246 			std::unique_ptr<work_thread_t> m_torrent_load_thread;
1247 #endif
1248 
1249 			// mask is a bitmask of which protocols to remap on:
1250 			enum remap_port_mask_t
1251 			{
1252 				remap_natpmp = 1,
1253 				remap_upnp = 2,
1254 				remap_natpmp_and_upnp = 3
1255 			};
1256 			void remap_ports(remap_port_mask_t mask, listen_socket_t& s);
1257 
1258 			// the timer used to fire the tick
1259 			deadline_timer m_timer;
1260 			aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_tick_handler_storage;
1261 
1262 			// abort may not fail and cannot allocate memory
1263 #if defined BOOST_ASIO_ENABLE_HANDLER_TRACKING
1264 			aux::handler_storage<104> m_abort_handler_storage;
1265 #else
1266 			aux::handler_storage<96> m_abort_handler_storage;
1267 #endif
1268 
1269 			// torrents are announced on the local network in a
1270 			// round-robin fashion. All torrents are cycled through
1271 			// within the LSD announce interval (which defaults to
1272 			// 5 minutes)
1273 			torrent_map::iterator m_next_lsd_torrent;
1274 
1275 #ifndef TORRENT_DISABLE_DHT
1276 			// torrents are announced on the DHT in a
1277 			// round-robin fashion. All torrents are cycled through
1278 			// within the DHT announce interval (which defaults to
1279 			// 15 minutes)
1280 			torrent_map::iterator m_next_dht_torrent;
1281 
1282 			// torrents that don't have any peers
1283 			// when added should be announced to the DHT
1284 			// as soon as possible. Such torrents are put
1285 			// in this queue and get announced the next time
1286 			// the timer fires, instead of the next one in
1287 			// the round-robin sequence.
1288 			std::deque<std::weak_ptr<torrent>> m_dht_torrents;
1289 #endif
1290 
1291 			// torrents prioritized to get connection attempts
1292 			std::deque<std::pair<std::weak_ptr<torrent>, int>> m_prio_torrents;
1293 
1294 			// this announce timer is used
1295 			// by Local service discovery
1296 			deadline_timer m_lsd_announce_timer;
1297 
1298 			// this is the timer used to call ``close_oldest`` on the ``file_pool``
1299 			// object. This closes the file that's been opened the longest every
1300 			// time it's called, to force the windows disk cache to be flushed
1301 			deadline_timer m_close_file_timer;
1302 
1303 			// the index of the torrent that will be offered to
1304 			// connect to a peer next time on_tick is called.
1305 			// This implements a round robin peer connections among
1306 			// torrents that want more peers. The index is into
1307 			// m_torrent_lists[torrent_want_peers_downloading]
1308 			// (which is a list of torrent pointers with all
1309 			// torrents that want peers and are downloading)
1310 			int m_next_downloading_connect_torrent = 0;
1311 			int m_next_finished_connect_torrent = 0;
1312 
1313 			// this is the number of attempts of connecting to
1314 			// peers we have given to downloading torrents.
1315 			// when this gets high enough, we try to connect
1316 			// a peer from a finished torrent
1317 			int m_download_connect_attempts = 0;
1318 
1319 			// index into m_torrent_lists[torrent_want_scrape] referring
1320 			// to the next torrent to auto-scrape
1321 			int m_next_scrape_torrent = 0;
1322 
1323 #if TORRENT_USE_INVARIANT_CHECKS
1324 			void check_invariant() const;
1325 #endif
1326 
stats_counterslibtorrent::aux::session_impl1327 			counters& stats_counters() override { return m_stats_counters; }
1328 
1329 			void received_buffer(int size) override;
1330 			void sent_buffer(int size) override;
1331 
1332 #ifndef TORRENT_DISABLE_LOGGING
1333 			bool should_log() const override;
1334 			void session_log(char const* fmt, ...) const noexcept override TORRENT_FORMAT(2,3);
1335 #endif
1336 
1337 #ifndef TORRENT_DISABLE_EXTENSIONS
1338 			// this is a list to allow extensions to potentially remove themselves.
1339 			std::array<std::vector<std::shared_ptr<plugin>>, 4> m_ses_extensions;
1340 #endif
1341 
1342 #if TORRENT_ABI_VERSION == 1
1343 			user_load_function_t m_user_load_torrent;
1344 #endif
1345 
1346 			// this is true whenever we have posted a deferred-disk job
1347 			// it means we don't need to post another one
1348 			bool m_deferred_submit_disk_jobs = false;
1349 
1350 			// this is set to true when a torrent auto-manage
1351 			// event is triggered, and reset whenever the message
1352 			// is delivered and the auto-manage is executed.
1353 			// there should never be more than a single pending auto-manage
1354 			// message in-flight at any given time.
1355 			bool m_pending_auto_manage = false;
1356 
1357 			// this is set to true when triggering an auto-manage
1358 			// of the torrents. However, if the normal auto-manage
1359 			// timer comes along and executes the auto-management,
1360 			// this is set to false, which means the triggered event
1361 			// no longer needs to execute the auto-management.
1362 			bool m_need_auto_manage = false;
1363 
1364 			// set to true when the session object
1365 			// is being destructed and the thread
1366 			// should exit
1367 			bool m_abort = false;
1368 
1369 			// is true if the session is paused
1370 			bool m_paused = false;
1371 
1372 			// set to true the first time post_session_stats() is
1373 			// called and we post the headers alert
1374 			bool m_posted_stats_header = false;
1375 		};
1376 
1377 #ifndef TORRENT_DISABLE_LOGGING
1378 		struct tracker_logger : request_callback
1379 		{
1380 			explicit tracker_logger(session_interface& ses);
1381 			void tracker_warning(tracker_request const& req
1382 				, std::string const& str) override;
1383 			void tracker_response(tracker_request const&
1384 				, libtorrent::address const& tracker_ip
1385 				, std::list<address> const& ip_list
1386 				, struct tracker_response const& resp) override;
1387 			void tracker_request_error(tracker_request const& r
1388 				, error_code const& ec, const std::string& str
1389 				, seconds32 retry_interval) override;
1390 			bool should_log() const override;
1391 			void debug_log(const char* fmt, ...) const noexcept override TORRENT_FORMAT(2,3);
1392 			session_interface& m_ses;
1393 		private:
1394 			// explicitly disallow assignment, to silence msvc warning
1395 			tracker_logger& operator=(tracker_logger const&);
1396 		};
1397 #endif
1398 
1399 	}
1400 }
1401 
1402 #endif
1403