1 /*
2 
3 Copyright (c) 2003-2018, Arvid Norberg
4 Copyright (c) 2007-2018, Arvid Norberg, Un Shyam
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10 
11     * Redistributions of source code must retain the above copyright
12       notice, this list of conditions and the following disclaimer.
13     * Redistributions in binary form must reproduce the above copyright
14       notice, this list of conditions and the following disclaimer in
15       the documentation and/or other materials provided with the distribution.
16     * Neither the name of the author nor the names of its
17       contributors may be used to endorse or promote products derived
18       from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31 
32 */
33 
34 #include "libtorrent/config.hpp"
35 
36 #include <memory> // unique_ptr
37 #include <vector>
38 #include <functional>
39 
40 #ifndef TORRENT_DISABLE_LOGGING
41 #include "libtorrent/hex.hpp" // to_hex
42 #endif
43 
44 #include "libtorrent/bt_peer_connection.hpp"
45 #include "libtorrent/session.hpp"
46 #include "libtorrent/identify_client.hpp"
47 #include "libtorrent/entry.hpp"
48 #include "libtorrent/bencode.hpp"
49 #include "libtorrent/alert_types.hpp"
50 #include "libtorrent/invariant_check.hpp"
51 #include "libtorrent/io.hpp"
52 #include "libtorrent/aux_/io.hpp"
53 #include "libtorrent/socket_io.hpp"
54 #include "libtorrent/extensions.hpp"
55 #include "libtorrent/aux_/session_interface.hpp"
56 #include "libtorrent/alert_types.hpp"
57 #include "libtorrent/broadcast_socket.hpp"
58 #include "libtorrent/peer_info.hpp"
59 #include "libtorrent/random.hpp"
60 #include "libtorrent/aux_/alloca.hpp"
61 #include "libtorrent/aux_/socket_type.hpp"
62 #include "libtorrent/performance_counters.hpp" // for counters
63 #include "libtorrent/alert_manager.hpp" // for alert_manager
64 #include "libtorrent/string_util.hpp" // for search
65 #include "libtorrent/aux_/generate_peer_id.hpp"
66 
67 #if !defined TORRENT_DISABLE_ENCRYPTION
68 #include "libtorrent/pe_crypto.hpp"
69 #include "libtorrent/hasher.hpp"
70 #endif
71 
72 namespace libtorrent {
73 
74 #if !defined TORRENT_DISABLE_ENCRYPTION
75 namespace {
76 
77 	constexpr std::size_t handshake_len = 68;
78 	constexpr std::size_t dh_key_len = 96;
79 
80 	// stream key (info hash of attached torrent)
81 	// secret is the DH shared secret
82 	// initializes m_enc_handler
init_pe_rc4_handler(key_t const & secret,sha1_hash const & stream_key,bool const outgoing)83 	std::shared_ptr<rc4_handler> init_pe_rc4_handler(key_t const& secret
84 		, sha1_hash const& stream_key, bool const outgoing)
85 	{
86 		hasher h;
87 		static const char keyA[] = {'k', 'e', 'y', 'A'};
88 		static const char keyB[] = {'k', 'e', 'y', 'B'};
89 
90 		// encryption rc4 longkeys
91 		// outgoing connection : hash ('keyA',S,SKEY)
92 		// incoming connection : hash ('keyB',S,SKEY)
93 
94 		std::array<char, dh_key_len> const secret_buf = export_key(secret);
95 
96 		if (outgoing) h.update(keyA); else h.update(keyB);
97 		h.update(secret_buf);
98 		h.update(stream_key);
99 		sha1_hash const local_key = h.final();
100 
101 		h.reset();
102 
103 		// decryption rc4 longkeys
104 		// outgoing connection : hash ('keyB',S,SKEY)
105 		// incoming connection : hash ('keyA',S,SKEY)
106 
107 		if (outgoing) h.update(keyB); else h.update(keyA);
108 		h.update(secret_buf);
109 		h.update(stream_key);
110 		sha1_hash const remote_key = h.final();
111 
112 		auto ret = std::make_shared<rc4_handler>();
113 
114 		ret->set_incoming_key(remote_key);
115 		ret->set_outgoing_key(local_key);
116 
117 		return ret;
118 	}
119 
120 } // anonymous namespace
121 #endif
122 
123 #ifndef TORRENT_DISABLE_EXTENSIONS
was_introduced_by(tcp::endpoint const & ep)124 	bool ut_pex_peer_store::was_introduced_by(tcp::endpoint const &ep)
125 	{
126 		if (is_v4(ep))
127 		{
128 			peers4_t::value_type const v(ep.address().to_v4().to_bytes(), ep.port());
129 			auto const i = std::lower_bound(m_peers.begin(), m_peers.end(), v);
130 			return i != m_peers.end() && *i == v;
131 		}
132 		else
133 		{
134 			peers6_t::value_type const v(ep.address().to_v6().to_bytes(), ep.port());
135 			auto const i = std::lower_bound(m_peers6.begin(), m_peers6.end(), v);
136 			return i != m_peers6.end() && *i == v;
137 		}
138 	}
139 #endif // TORRENT_DISABLE_EXTENSIONS
140 
bt_peer_connection(peer_connection_args const & pack)141 	bt_peer_connection::bt_peer_connection(peer_connection_args const& pack)
142 		: peer_connection(pack)
143 		, m_supports_extensions(false)
144 		, m_supports_dht_port(false)
145 		, m_supports_fast(false)
146 		, m_sent_bitfield(false)
147 		, m_sent_handshake(false)
148 		, m_sent_allowed_fast(false)
149 #if !defined TORRENT_DISABLE_ENCRYPTION
150 		, m_encrypted(false)
151 		, m_rc4_encrypted(false)
152 		, m_recv_buffer(peer_connection::m_recv_buffer)
153 #endif
154 		, m_our_peer_id(pack.our_peer_id)
155 	{
156 #ifndef TORRENT_DISABLE_LOGGING
157 		peer_log(peer_log_alert::info, "CONSTRUCT", "bt_peer_connection");
158 #endif
159 
160 		m_reserved_bits.fill(0);
161 	}
162 
start()163 	void bt_peer_connection::start()
164 	{
165 		peer_connection::start();
166 
167 		// start in the state where we are trying to read the
168 		// handshake from the other side
169 		m_recv_buffer.reset(20);
170 		setup_receive();
171 	}
172 
173 	bt_peer_connection::~bt_peer_connection() = default;
174 
175 #if !defined TORRENT_DISABLE_ENCRYPTION
switch_send_crypto(std::shared_ptr<crypto_plugin> crypto)176 	void bt_peer_connection::switch_send_crypto(std::shared_ptr<crypto_plugin> crypto)
177 	{
178 		if (m_enc_handler.switch_send_crypto(std::move(crypto), send_buffer_size() - get_send_barrier()))
179 			set_send_barrier(send_buffer_size());
180 	}
181 
switch_recv_crypto(std::shared_ptr<crypto_plugin> crypto)182 	void bt_peer_connection::switch_recv_crypto(std::shared_ptr<crypto_plugin> crypto)
183 	{
184 		m_enc_handler.switch_recv_crypto(std::move(crypto), m_recv_buffer);
185 	}
186 #endif
187 
on_connected()188 	void bt_peer_connection::on_connected()
189 	{
190 		if (is_disconnecting()) return;
191 
192 		std::shared_ptr<torrent> t = associated_torrent().lock();
193 		TORRENT_ASSERT(t);
194 
195 		if (t->graceful_pause())
196 		{
197 #ifndef TORRENT_DISABLE_LOGGING
198 			peer_log(peer_log_alert::info, "ON_CONNECTED", "graceful-paused");
199 #endif
200 			disconnect(errors::torrent_paused, operation_t::bittorrent);
201 			return;
202 		}
203 
204 		// make sure are much as possible of the response ends up in the same
205 		// packet, or at least back-to-back packets
206 		cork c_(*this);
207 
208 #if !defined TORRENT_DISABLE_ENCRYPTION
209 
210 		std::uint8_t out_policy = std::uint8_t(m_settings.get_int(settings_pack::out_enc_policy));
211 
212 #ifdef TORRENT_USE_OPENSSL
213 		// never try an encrypted connection when already using SSL
214 		if (is_ssl(*get_socket()))
215 			out_policy = settings_pack::pe_disabled;
216 #endif
217 #ifndef TORRENT_DISABLE_LOGGING
218 		static char const* policy_name[] = {"forced", "enabled", "disabled"};
219 		TORRENT_ASSERT(out_policy < sizeof(policy_name)/sizeof(policy_name[0]));
220 		peer_log(peer_log_alert::info, "ENCRYPTION"
221 			, "outgoing encryption policy: %s", policy_name[out_policy]);
222 #endif
223 
224 		if (out_policy == settings_pack::pe_forced)
225 		{
226 			write_pe1_2_dhkey();
227 			if (is_disconnecting()) return;
228 
229 			m_state = state_t::read_pe_dhkey;
230 			m_recv_buffer.reset(dh_key_len);
231 			setup_receive();
232 		}
233 		else if (out_policy == settings_pack::pe_enabled)
234 		{
235 			TORRENT_ASSERT(peer_info_struct());
236 
237 			torrent_peer* pi = peer_info_struct();
238 			if (pi->pe_support == true)
239 			{
240 				// toggle encryption support flag, toggled back to
241 				// true if encrypted portion of the handshake
242 				// completes correctly
243 				pi->pe_support = false;
244 
245 				// if this fails, we need to reconnect
246 				// fast.
247 				fast_reconnect(true);
248 
249 				write_pe1_2_dhkey();
250 				if (is_disconnecting()) return;
251 				m_state = state_t::read_pe_dhkey;
252 				m_recv_buffer.reset(dh_key_len);
253 				setup_receive();
254 			}
255 			else // pi->pe_support == false
256 			{
257 				// toggled back to false if standard handshake
258 				// completes correctly (without encryption)
259 				pi->pe_support = true;
260 
261 				write_handshake();
262 				m_recv_buffer.reset(20);
263 				setup_receive();
264 			}
265 		}
266 		else if (out_policy == settings_pack::pe_disabled)
267 #endif
268 		{
269 			write_handshake();
270 
271 			// start in the state where we are trying to read the
272 			// handshake from the other side
273 			m_recv_buffer.reset(20);
274 			setup_receive();
275 		}
276 	}
277 
on_metadata()278 	void bt_peer_connection::on_metadata()
279 	{
280 #ifndef TORRENT_DISABLE_LOGGING
281 		peer_log(peer_log_alert::info, "ON_METADATA");
282 #endif
283 
284 		disconnect_if_redundant();
285 		if (m_disconnecting) return;
286 
287 		if (!m_sent_handshake) return;
288 		// we're still waiting to fully handshake with this peer. At the end of
289 		// the handshake we'll send the bitfield and dht port anyway. It's too
290 		// early to do now
291 		if (static_cast<int>(m_state)
292 			< static_cast<int>(state_t::read_packet_size))
293 		{
294 			return;
295 		}
296 
297 		// connections that are still in the handshake
298 		// will send their bitfield when the handshake
299 		// is done
300 		std::shared_ptr<torrent> t = associated_torrent().lock();
301 #ifndef TORRENT_DISABLE_SHARE_MODE
302 		if (!t->share_mode())
303 #endif
304 		{
305 			bool const upload_only_enabled = t->is_upload_only()
306 #ifndef TORRENT_DISABLE_SUPERSEEDING
307 				&& !t->super_seeding()
308 #endif
309 				;
310 			send_upload_only(upload_only_enabled);
311 		}
312 
313 		if (m_sent_bitfield) return;
314 
315 		TORRENT_ASSERT(t);
316 		write_bitfield();
317 		TORRENT_ASSERT(m_sent_bitfield);
318 		write_dht_port();
319 	}
320 
write_dht_port()321 	void bt_peer_connection::write_dht_port()
322 	{
323 #ifndef TORRENT_DISABLE_DHT
324 		if (m_supports_dht_port && m_ses.has_dht())
325 		{
326 			int const port = m_ses.external_udp_port(local_endpoint().address());
327 			if (port >= 0) write_dht_port(port);
328 		}
329 #endif
330 	}
331 
write_dht_port(int const listen_port)332 	void bt_peer_connection::write_dht_port(int const listen_port)
333 	{
334 		INVARIANT_CHECK;
335 
336 		TORRENT_ASSERT(m_sent_handshake);
337 		TORRENT_ASSERT(m_sent_bitfield);
338 
339 #ifndef TORRENT_DISABLE_LOGGING
340 		peer_log(peer_log_alert::outgoing_message, "DHT_PORT", "%d", listen_port);
341 #endif
342 		char msg[] = {0,0,0,3, msg_dht_port, 0, 0};
343 		char* ptr = msg + 5;
344 		detail::write_uint16(listen_port, ptr);
345 		send_buffer(msg);
346 
347 		stats_counters().inc_stats_counter(counters::num_outgoing_dht_port);
348 	}
349 
write_have_all()350 	void bt_peer_connection::write_have_all()
351 	{
352 		INVARIANT_CHECK;
353 
354 		m_sent_bitfield = true;
355 #ifndef TORRENT_DISABLE_LOGGING
356 		peer_log(peer_log_alert::outgoing_message, "HAVE_ALL");
357 #endif
358 		send_message(msg_have_all, counters::num_outgoing_have_all);
359 	}
360 
write_have_none()361 	void bt_peer_connection::write_have_none()
362 	{
363 		INVARIANT_CHECK;
364 		m_sent_bitfield = true;
365 #ifndef TORRENT_DISABLE_LOGGING
366 		peer_log(peer_log_alert::outgoing_message, "HAVE_NONE");
367 #endif
368 		send_message(msg_have_none, counters::num_outgoing_have_none);
369 	}
370 
write_reject_request(peer_request const & r)371 	void bt_peer_connection::write_reject_request(peer_request const& r)
372 	{
373 		INVARIANT_CHECK;
374 
375 		stats_counters().inc_stats_counter(counters::piece_rejects);
376 
377 		if (!m_supports_fast) return;
378 
379 #ifndef TORRENT_DISABLE_LOGGING
380 		peer_log(peer_log_alert::outgoing_message, "REJECT_PIECE"
381 			, "piece: %d | s: %d | l: %d", static_cast<int>(r.piece)
382 			, r.start, r.length);
383 #endif
384 
385 		send_message(msg_reject_request, counters::num_outgoing_reject
386 			, static_cast<int>(r.piece), r.start, r.length);
387 	}
388 
write_allow_fast(piece_index_t const piece)389 	void bt_peer_connection::write_allow_fast(piece_index_t const piece)
390 	{
391 		INVARIANT_CHECK;
392 
393 		if (!m_supports_fast) return;
394 
395 #ifndef TORRENT_DISABLE_LOGGING
396 		peer_log(peer_log_alert::outgoing_message, "ALLOWED_FAST", "%d"
397 			, static_cast<int>(piece));
398 #endif
399 
400 		TORRENT_ASSERT(associated_torrent().lock()->valid_metadata());
401 
402 		send_message(msg_allowed_fast, counters::num_outgoing_allowed_fast
403 			, static_cast<int>(piece));
404 	}
405 
write_suggest(piece_index_t const piece)406 	void bt_peer_connection::write_suggest(piece_index_t const piece)
407 	{
408 		INVARIANT_CHECK;
409 
410 		if (!m_supports_fast) return;
411 
412 #if TORRENT_USE_ASSERTS
413 		std::shared_ptr<torrent> t = associated_torrent().lock();
414 		TORRENT_ASSERT(t);
415 		TORRENT_ASSERT(t->valid_metadata());
416 #endif
417 
418 #ifndef TORRENT_DISABLE_LOGGING
419 		if (should_log(peer_log_alert::outgoing_message))
420 		{
421 #if !TORRENT_USE_ASSERTS
422 			std::shared_ptr<torrent> t = associated_torrent().lock();
423 #endif
424 			peer_log(peer_log_alert::outgoing_message, "SUGGEST"
425 				, "piece: %d num_peers: %d", static_cast<int>(piece)
426 				, t->has_picker() ? t->picker().get_availability(piece) : -1);
427 		}
428 #endif
429 
430 		send_message(msg_suggest_piece, counters::num_outgoing_suggest
431 			, static_cast<int>(piece));
432 	}
433 
get_specific_peer_info(peer_info & p) const434 	void bt_peer_connection::get_specific_peer_info(peer_info& p) const
435 	{
436 		TORRENT_ASSERT(!associated_torrent().expired());
437 
438 		if (is_interesting()) p.flags |= peer_info::interesting;
439 		if (is_choked()) p.flags |= peer_info::choked;
440 		if (is_peer_interested()) p.flags |= peer_info::remote_interested;
441 		if (has_peer_choked()) p.flags |= peer_info::remote_choked;
442 		if (support_extensions()) p.flags |= peer_info::supports_extensions;
443 		if (is_outgoing()) p.flags |= peer_info::local_connection;
444 #if TORRENT_USE_I2P
445 		if (is_i2p(*get_socket())) p.flags |= peer_info::i2p_socket;
446 #endif
447 		if (is_utp(*get_socket())) p.flags |= peer_info::utp_socket;
448 		if (is_ssl(*get_socket())) p.flags |= peer_info::ssl_socket;
449 
450 #if !defined TORRENT_DISABLE_ENCRYPTION
451 		if (m_encrypted)
452 		{
453 			p.flags |= m_rc4_encrypted
454 				? peer_info::rc4_encrypted
455 				: peer_info::plaintext_encrypted;
456 		}
457 #endif
458 
459 		if (!is_connecting() && in_handshake())
460 			p.flags |= peer_info::handshake;
461 		if (is_connecting()) p.flags |= peer_info::connecting;
462 
463 		p.client = m_client_version;
464 		p.connection_type = peer_info::standard_bittorrent;
465 	}
466 
in_handshake() const467 	bool bt_peer_connection::in_handshake() const
468 	{
469 		// this returns true until we have received a handshake
470 		// and until we have send our handshake
471 		return !m_sent_handshake || m_state < state_t::read_packet_size;
472 	}
473 
474 #if !defined TORRENT_DISABLE_ENCRYPTION
475 
write_pe1_2_dhkey()476 	void bt_peer_connection::write_pe1_2_dhkey()
477 	{
478 		INVARIANT_CHECK;
479 
480 		TORRENT_ASSERT(!m_encrypted);
481 		TORRENT_ASSERT(!m_rc4_encrypted);
482 		TORRENT_ASSERT(!m_dh_key_exchange.get());
483 		TORRENT_ASSERT(!m_sent_handshake);
484 
485 #ifndef TORRENT_DISABLE_LOGGING
486 		if (is_outgoing())
487 			peer_log(peer_log_alert::info, "ENCRYPTION", "initiating encrypted handshake");
488 #endif
489 
490 		m_dh_key_exchange.reset(new (std::nothrow) dh_key_exchange);
491 		if (!m_dh_key_exchange || !m_dh_key_exchange->good())
492 		{
493 			disconnect(errors::no_memory, operation_t::encryption);
494 			return;
495 		}
496 
497 		int const pad_size = int(random(512));
498 
499 #ifndef TORRENT_DISABLE_LOGGING
500 		peer_log(peer_log_alert::info, "ENCRYPTION", "pad size: %d", pad_size);
501 #endif
502 
503 		char msg[dh_key_len + 512];
504 		char* ptr = msg;
505 		int const buf_size = int(dh_key_len) + pad_size;
506 
507 		std::array<char, dh_key_len> const local_key = export_key(m_dh_key_exchange->get_local_key());
508 		std::memcpy(ptr, local_key.data(), dh_key_len);
509 		ptr += dh_key_len;
510 
511 		aux::random_bytes({ptr, pad_size});
512 		send_buffer({msg, buf_size});
513 
514 #ifndef TORRENT_DISABLE_LOGGING
515 		peer_log(peer_log_alert::info, "ENCRYPTION", "sent DH key");
516 #endif
517 	}
518 
write_pe3_sync()519 	void bt_peer_connection::write_pe3_sync()
520 	{
521 		INVARIANT_CHECK;
522 
523 		TORRENT_ASSERT(!m_encrypted);
524 		TORRENT_ASSERT(!m_rc4_encrypted);
525 		TORRENT_ASSERT(is_outgoing());
526 		TORRENT_ASSERT(!m_sent_handshake);
527 
528 		std::shared_ptr<torrent> t = associated_torrent().lock();
529 		TORRENT_ASSERT(t);
530 
531 		hasher h;
532 		sha1_hash const& info_hash = t->torrent_file().info_hash();
533 		key_t const secret_key = m_dh_key_exchange->get_secret();
534 		std::array<char, dh_key_len> const secret = export_key(secret_key);
535 
536 		int const pad_size = int(random(512));
537 
538 		// synchash,skeyhash,vc,crypto_provide,len(pad),pad,len(ia)
539 		char msg[20 + 20 + 8 + 4 + 2 + 512 + 2];
540 		char* ptr = msg;
541 
542 		static char const req1[4] = {'r', 'e', 'q', '1'};
543 		// sync hash (hash('req1',S))
544 		h.reset();
545 		h.update(req1);
546 		h.update(secret);
547 		sha1_hash const sync_hash = h.final();
548 
549 		std::memcpy(ptr, sync_hash.data(), 20);
550 		ptr += 20;
551 #ifndef TORRENT_DISABLE_LOGGING
552 		if (should_log(peer_log_alert::info))
553 		{
554 			peer_log(peer_log_alert::info, "ENCRYPTION"
555 				, "writing synchash");
556 		}
557 #endif
558 
559 		static char const req2[4] = {'r', 'e', 'q', '2'};
560 		// stream key obfuscated hash [ hash('req2',SKEY) xor hash('req3',S) ]
561 		h.reset();
562 		h.update(req2);
563 		h.update(info_hash);
564 		sha1_hash const streamkey_hash = h.final();
565 
566 		static char const req3[4] = {'r', 'e', 'q', '3'};
567 		h.reset();
568 		h.update(req3);
569 		h.update(secret);
570 		sha1_hash const obfsc_hash = h.final() ^ streamkey_hash;
571 
572 		std::memcpy(ptr, obfsc_hash.data(), 20);
573 		ptr += 20;
574 
575 		// Discard DH key exchange data, setup RC4 keys
576 		m_rc4 = init_pe_rc4_handler(secret_key, info_hash, is_outgoing());
577 #ifndef TORRENT_DISABLE_LOGGING
578 		peer_log(peer_log_alert::info, "ENCRYPTION", "computed RC4 keys");
579 #endif
580 		m_dh_key_exchange.reset(); // secret should be invalid at this point
581 
582 		// write the verification constant and crypto field
583 		int const encrypt_size = int(sizeof(msg)) - 512 + pad_size - 40;
584 
585 		// this is an invalid setting, but let's just make the best of the situation
586 		int const enc_level = m_settings.get_int(settings_pack::allowed_enc_level);
587 		std::uint8_t const crypto_provide = ((enc_level & settings_pack::pe_both) == 0)
588 			? std::uint8_t(settings_pack::pe_both)
589 			: std::uint8_t(enc_level);
590 
591 #ifndef TORRENT_DISABLE_LOGGING
592 		static char const* level[] = {"plaintext", "rc4", "plaintext rc4"};
593 		peer_log(peer_log_alert::info, "ENCRYPTION"
594 			, "%s", level[crypto_provide - 1]);
595 #endif
596 
597 		write_pe_vc_cryptofield({ptr, encrypt_size}, crypto_provide, pad_size);
598 		span<char> vec(ptr, encrypt_size);
599 		m_rc4->encrypt(vec);
600 		send_buffer({msg, int(sizeof(msg)) - 512 + pad_size});
601 	}
602 
write_pe4_sync(int const crypto_select)603 	void bt_peer_connection::write_pe4_sync(int const crypto_select)
604 	{
605 		INVARIANT_CHECK;
606 
607 		TORRENT_ASSERT(!is_outgoing());
608 		TORRENT_ASSERT(!m_encrypted);
609 		TORRENT_ASSERT(!m_rc4_encrypted);
610 		TORRENT_ASSERT(crypto_select == 0x02 || crypto_select == 0x01);
611 		TORRENT_ASSERT(!m_sent_handshake);
612 
613 		int const pad_size = int(random(512));
614 
615 		int const buf_size = 8 + 4 + 2 + pad_size;
616 		char msg[512 + 8 + 4 + 2];
617 		write_pe_vc_cryptofield(msg, crypto_select, pad_size);
618 
619 		span<char> vec(msg, buf_size);
620 		m_rc4->encrypt(vec);
621 		send_buffer(vec);
622 
623 		// encryption method has been negotiated
624 		if (crypto_select == 0x02)
625 			m_rc4_encrypted = true;
626 		else // 0x01
627 			m_rc4_encrypted = false;
628 
629 #ifndef TORRENT_DISABLE_LOGGING
630 		peer_log(peer_log_alert::info, "ENCRYPTION", " crypto select: %s"
631 			, (crypto_select == 0x01) ? "plaintext" : "rc4");
632 #endif
633 	}
634 
write_pe_vc_cryptofield(span<char> write_buf,int const crypto_field,int const pad_size)635 	void bt_peer_connection::write_pe_vc_cryptofield(
636 		span<char> write_buf
637 		, int const crypto_field
638 		, int const pad_size)
639 	{
640 		INVARIANT_CHECK;
641 
642 		TORRENT_ASSERT(crypto_field <= 0x03 && crypto_field > 0);
643 		// vc,crypto_field,len(pad),pad, (len(ia))
644 		TORRENT_ASSERT((write_buf.size() >= 8+4+2+pad_size+2
645 				&& is_outgoing())
646 			|| (write_buf.size() >= 8+4+2+pad_size && !is_outgoing()));
647 		TORRENT_ASSERT(!m_sent_handshake);
648 
649 		// encrypt(vc, crypto_provide/select, len(Pad), len(IA))
650 		// len(pad) is zero for now, len(IA) only for outgoing connections
651 
652 		// vc
653 		std::memset(write_buf.data(), 0, 8);
654 		write_buf = write_buf.subspan(8);
655 
656 		aux::write_uint32(crypto_field, write_buf);
657 		aux::write_uint16(pad_size, write_buf); // len (pad)
658 
659 		aux::random_bytes(write_buf.first(pad_size));
660 		write_buf = write_buf.subspan(pad_size);
661 
662 		// append len(ia) if we are initiating
663 		if (is_outgoing())
664 			aux::write_uint16(handshake_len, write_buf); // len(IA)
665 	}
666 
rc4_decrypt(span<char> buf)667 	void bt_peer_connection::rc4_decrypt(span<char> buf)
668 	{
669 		m_rc4->decrypt(buf);
670 	}
671 
672 #endif // #if !defined TORRENT_DISABLE_ENCRYPTION
673 
write_handshake()674 	void bt_peer_connection::write_handshake()
675 	{
676 		INVARIANT_CHECK;
677 
678 		TORRENT_ASSERT(!m_sent_handshake);
679 		m_sent_handshake = true;
680 
681 		std::shared_ptr<torrent> t = associated_torrent().lock();
682 		TORRENT_ASSERT(t);
683 
684 		// add handshake to the send buffer
685 		static const char version_string[] = "BitTorrent protocol";
686 		const int string_len = sizeof(version_string) - 1;
687 
688 		char handshake[1 + string_len + 8 + 20 + 20];
689 		char* ptr = handshake;
690 		// length of version string
691 		detail::write_uint8(string_len, ptr);
692 		// protocol identifier
693 		std::memcpy(ptr, version_string, string_len);
694 		ptr += string_len;
695 		// 8 zeroes
696 		std::memset(ptr, 0, 8);
697 
698 #ifndef TORRENT_DISABLE_DHT
699 		// indicate that we support the DHT messages
700 		*(ptr + 7) |= 0x01;
701 #endif
702 
703 		// we support extensions
704 		*(ptr + 5) |= 0x10;
705 
706 		if (m_settings.get_bool(settings_pack::support_merkle_torrents))
707 		{
708 			// we support merkle torrents
709 			*(ptr + 5) |= 0x08;
710 		}
711 
712 		// we support FAST extension
713 		*(ptr + 7) |= 0x04;
714 
715 #ifndef TORRENT_DISABLE_LOGGING
716 		if (should_log(peer_log_alert::outgoing_message))
717 		{
718 			std::string bitmask;
719 			for (int k = 0; k < 8; ++k)
720 			{
721 				for (int j = 0; j < 8; ++j)
722 				{
723 					if (ptr[k] & (0x80 >> j)) bitmask += '1';
724 					else bitmask += '0';
725 				}
726 			}
727 			peer_log(peer_log_alert::outgoing_message, "EXTENSIONS"
728 				, "%s", bitmask.c_str());
729 		}
730 #endif
731 		ptr += 8;
732 
733 		// info hash
734 		sha1_hash const& ih = t->torrent_file().info_hash();
735 		std::memcpy(ptr, ih.data(), ih.size());
736 		ptr += 20;
737 
738 		std::memcpy(ptr, m_our_peer_id.data(), 20);
739 
740 #ifndef TORRENT_DISABLE_LOGGING
741 		if (should_log(peer_log_alert::outgoing))
742 		{
743 			peer_log(peer_log_alert::outgoing, "HANDSHAKE"
744 				, "sent peer_id: %s client: %s"
745 				, aux::to_hex(m_our_peer_id).c_str(), identify_client(m_our_peer_id).c_str());
746 		}
747 		if (should_log(peer_log_alert::outgoing_message))
748 		{
749 			peer_log(peer_log_alert::outgoing_message, "HANDSHAKE"
750 				, "ih: %s", aux::to_hex(ih).c_str());
751 		}
752 #endif
753 		send_buffer(handshake);
754 	}
755 
downloading_piece_progress() const756 	piece_block_progress bt_peer_connection::downloading_piece_progress() const
757 	{
758 		std::shared_ptr<torrent> t = associated_torrent().lock();
759 		TORRENT_ASSERT(t);
760 
761 		span<char const> recv_buffer = m_recv_buffer.get();
762 		// are we currently receiving a 'piece' message?
763 		if (m_state != state_t::read_packet
764 			|| int(recv_buffer.size()) <= 9
765 			|| recv_buffer[0] != msg_piece)
766 			return piece_block_progress();
767 
768 		const char* ptr = recv_buffer.data() + 1;
769 		peer_request r;
770 		r.piece = piece_index_t(detail::read_int32(ptr));
771 		r.start = detail::read_int32(ptr);
772 		r.length = m_recv_buffer.packet_size() - 9;
773 
774 		// is any of the piece message header data invalid?
775 		if (!verify_piece(r))
776 			return piece_block_progress();
777 
778 		piece_block_progress p;
779 
780 		p.piece_index = r.piece;
781 		p.block_index = r.start / t->block_size();
782 		p.bytes_downloaded = int(recv_buffer.size()) - 9;
783 		p.full_block_bytes = r.length;
784 
785 		return p;
786 	}
787 
788 
789 	// message handlers
790 
791 	// -----------------------------
792 	// ----------- CHOKE -----------
793 	// -----------------------------
794 
on_choke(int received)795 	void bt_peer_connection::on_choke(int received)
796 	{
797 		INVARIANT_CHECK;
798 
799 		TORRENT_ASSERT(received >= 0);
800 		received_bytes(0, received);
801 		if (m_recv_buffer.packet_size() != 1)
802 		{
803 			disconnect(errors::invalid_choke, operation_t::bittorrent, peer_error);
804 			return;
805 		}
806 		if (!m_recv_buffer.packet_finished()) return;
807 
808 		incoming_choke();
809 		if (is_disconnecting()) return;
810 		if (!m_supports_fast)
811 		{
812 			// we just got choked, and the peer that choked use
813 			// doesn't support fast extensions, so we have to
814 			// assume that the choke message implies that all
815 			// of our requests are rejected. Go through them and
816 			// pretend that we received reject request messages
817 			std::shared_ptr<torrent> t = associated_torrent().lock();
818 			TORRENT_ASSERT(t);
819 			auto const dlq = download_queue();
820 			for (pending_block const& pb : dlq)
821 			{
822 				peer_request r;
823 				r.piece = pb.block.piece_index;
824 				r.start = pb.block.block_index * t->block_size();
825 				r.length = t->block_size();
826 				// if it's the last piece, make sure to
827 				// set the length of the request to not
828 				// exceed the end of the torrent. This is
829 				// necessary in order to maintain a correct
830 				// m_outstanding_bytes
831 				if (r.piece == t->torrent_file().last_piece())
832 				{
833 					r.length = std::min(t->torrent_file().piece_size(
834 						r.piece) - r.start, r.length);
835 				}
836 				incoming_reject_request(r);
837 			}
838 		}
839 	}
840 
841 	// -----------------------------
842 	// ---------- UNCHOKE ----------
843 	// -----------------------------
844 
on_unchoke(int received)845 	void bt_peer_connection::on_unchoke(int received)
846 	{
847 		INVARIANT_CHECK;
848 
849 		TORRENT_ASSERT(received >= 0);
850 		received_bytes(0, received);
851 		if (m_recv_buffer.packet_size() != 1)
852 		{
853 			disconnect(errors::invalid_unchoke, operation_t::bittorrent, peer_error);
854 			return;
855 		}
856 		if (!m_recv_buffer.packet_finished()) return;
857 
858 		incoming_unchoke();
859 	}
860 
861 	// -----------------------------
862 	// -------- INTERESTED ---------
863 	// -----------------------------
864 
on_interested(int received)865 	void bt_peer_connection::on_interested(int received)
866 	{
867 		INVARIANT_CHECK;
868 
869 		TORRENT_ASSERT(received >= 0);
870 		received_bytes(0, received);
871 		if (m_recv_buffer.packet_size() != 1)
872 		{
873 			disconnect(errors::invalid_interested, operation_t::bittorrent, peer_error);
874 			return;
875 		}
876 		if (!m_recv_buffer.packet_finished()) return;
877 
878 		// we defer sending the allowed set until the peer says it's interested in
879 		// us. This saves some bandwidth and allows us to omit messages for pieces
880 		// that the peer already has
881 		if (!m_sent_allowed_fast && m_supports_fast)
882 		{
883 			m_sent_allowed_fast = true;
884 			send_allowed_set();
885 		}
886 
887 		incoming_interested();
888 	}
889 
890 	// -----------------------------
891 	// ------ NOT INTERESTED -------
892 	// -----------------------------
893 
on_not_interested(int received)894 	void bt_peer_connection::on_not_interested(int received)
895 	{
896 		INVARIANT_CHECK;
897 
898 		TORRENT_ASSERT(received >= 0);
899 		received_bytes(0, received);
900 		if (m_recv_buffer.packet_size() != 1)
901 		{
902 			disconnect(errors::invalid_not_interested, operation_t::bittorrent, peer_error);
903 			return;
904 		}
905 		if (!m_recv_buffer.packet_finished()) return;
906 
907 		incoming_not_interested();
908 	}
909 
910 	// -----------------------------
911 	// ----------- HAVE ------------
912 	// -----------------------------
913 
on_have(int received)914 	void bt_peer_connection::on_have(int received)
915 	{
916 		INVARIANT_CHECK;
917 
918 		TORRENT_ASSERT(received >= 0);
919 		received_bytes(0, received);
920 		if (m_recv_buffer.packet_size() != 5)
921 		{
922 			disconnect(errors::invalid_have, operation_t::bittorrent, peer_error);
923 			return;
924 		}
925 		if (!m_recv_buffer.packet_finished()) return;
926 
927 		span<char const> recv_buffer = m_recv_buffer.get();
928 
929 		const char* ptr = recv_buffer.data() + 1;
930 		piece_index_t const index(detail::read_int32(ptr));
931 
932 		incoming_have(index);
933 	}
934 
935 	// -----------------------------
936 	// --------- BITFIELD ----------
937 	// -----------------------------
938 
on_bitfield(int received)939 	void bt_peer_connection::on_bitfield(int received)
940 	{
941 		INVARIANT_CHECK;
942 
943 		TORRENT_ASSERT(received >= 0);
944 
945 		std::shared_ptr<torrent> t = associated_torrent().lock();
946 		TORRENT_ASSERT(t);
947 
948 		received_bytes(0, received);
949 		// if we don't have the metadata, we cannot
950 		// verify the bitfield size
951 		if (t->valid_metadata()
952 			&& m_recv_buffer.packet_size() - 1 != (t->torrent_file().num_pieces() + CHAR_BIT - 1) / CHAR_BIT)
953 		{
954 			disconnect(errors::invalid_bitfield_size, operation_t::bittorrent, peer_error);
955 			return;
956 		}
957 
958 		if (!m_recv_buffer.packet_finished()) return;
959 
960 		span<char const> recv_buffer = m_recv_buffer.get();
961 
962 		typed_bitfield<piece_index_t> bits;
963 		bits.assign(recv_buffer.data() + 1
964 			, t->valid_metadata()?get_bitfield().size():(m_recv_buffer.packet_size()-1)*CHAR_BIT);
965 
966 		incoming_bitfield(bits);
967 	}
968 
969 	// -----------------------------
970 	// ---------- REQUEST ----------
971 	// -----------------------------
972 
on_request(int received)973 	void bt_peer_connection::on_request(int received)
974 	{
975 		INVARIANT_CHECK;
976 
977 		TORRENT_ASSERT(received >= 0);
978 		received_bytes(0, received);
979 		if (m_recv_buffer.packet_size() != 13)
980 		{
981 			disconnect(errors::invalid_request, operation_t::bittorrent, peer_error);
982 			return;
983 		}
984 		if (!m_recv_buffer.packet_finished()) return;
985 
986 		span<char const> recv_buffer = m_recv_buffer.get();
987 
988 		peer_request r;
989 		const char* ptr = recv_buffer.data() + 1;
990 		r.piece = piece_index_t(detail::read_int32(ptr));
991 		r.start = detail::read_int32(ptr);
992 		r.length = detail::read_int32(ptr);
993 
994 		incoming_request(r);
995 	}
996 
997 	// -----------------------------
998 	// ----------- PIECE -----------
999 	// -----------------------------
1000 
on_piece(int const received)1001 	void bt_peer_connection::on_piece(int const received)
1002 	{
1003 		INVARIANT_CHECK;
1004 
1005 		TORRENT_ASSERT(received >= 0);
1006 
1007 		span<char const> recv_buffer = m_recv_buffer.get();
1008 		int const recv_pos = m_recv_buffer.pos();
1009 
1010 		std::shared_ptr<torrent> t = associated_torrent().lock();
1011 		TORRENT_ASSERT(t);
1012 		bool const merkle = static_cast<std::uint8_t>(recv_buffer.front()) == 250;
1013 		if (merkle)
1014 		{
1015 			if (recv_pos == 1)
1016 			{
1017 				received_bytes(0, received);
1018 				return;
1019 			}
1020 			if (recv_pos < 13)
1021 			{
1022 				received_bytes(0, received);
1023 				return;
1024 			}
1025 			char const* ptr = recv_buffer.data() + 9;
1026 			int const list_size = detail::read_int32(ptr);
1027 
1028 			if (list_size > m_recv_buffer.packet_size() - 13 || list_size < 0)
1029 			{
1030 				received_bytes(0, received);
1031 				disconnect(errors::invalid_hash_list, operation_t::bittorrent, peer_error);
1032 				return;
1033 			}
1034 
1035 			if (m_recv_buffer.packet_size() - 13 - list_size > t->block_size())
1036 			{
1037 				received_bytes(0, received);
1038 				disconnect(errors::packet_too_large, operation_t::bittorrent, peer_error);
1039 				return;
1040 			}
1041 		}
1042 		else
1043 		{
1044 			if (recv_pos == 1)
1045 			{
1046 				if (m_recv_buffer.packet_size() - 9 > t->block_size())
1047 				{
1048 					received_bytes(0, received);
1049 					disconnect(errors::packet_too_large, operation_t::bittorrent, peer_error);
1050 					return;
1051 				}
1052 			}
1053 		}
1054 		// classify the received data as protocol chatter
1055 		// or data payload for the statistics
1056 		int piece_bytes = 0;
1057 
1058 		int header_size = merkle?13:9;
1059 
1060 		peer_request p;
1061 		int list_size = 0;
1062 
1063 		if (recv_pos >= header_size)
1064 		{
1065 			const char* ptr = recv_buffer.data() + 1;
1066 			p.piece = piece_index_t(detail::read_int32(ptr));
1067 			p.start = detail::read_int32(ptr);
1068 
1069 			if (merkle)
1070 			{
1071 				list_size = detail::read_int32(ptr);
1072 				if (list_size < 0)
1073 				{
1074 					received_bytes(0, received);
1075 					disconnect(errors::invalid_hash_list, operation_t::bittorrent, peer_error);
1076 					return;
1077 				}
1078 				p.length = m_recv_buffer.packet_size() - list_size - header_size;
1079 				header_size += list_size;
1080 			}
1081 			else
1082 			{
1083 				p.length = m_recv_buffer.packet_size() - header_size;
1084 			}
1085 		}
1086 		else
1087 		{
1088 			p.piece = piece_index_t(0);
1089 			p.start = 0;
1090 			p.length = 0;
1091 		}
1092 
1093 		if (recv_pos <= header_size)
1094 		{
1095 			// only received protocol data
1096 			received_bytes(0, received);
1097 		}
1098 		else if (recv_pos - received >= header_size)
1099 		{
1100 			// only received payload data
1101 			received_bytes(received, 0);
1102 			piece_bytes = received;
1103 		}
1104 		else
1105 		{
1106 			// received a bit of both
1107 			TORRENT_ASSERT(recv_pos - received < header_size);
1108 			TORRENT_ASSERT(recv_pos > header_size);
1109 			TORRENT_ASSERT(header_size - (recv_pos - received) <= header_size);
1110 			received_bytes(
1111 				recv_pos - header_size
1112 				, header_size - (recv_pos - received));
1113 			piece_bytes = recv_pos - header_size;
1114 		}
1115 
1116 		if (recv_pos < header_size) return;
1117 
1118 #ifndef TORRENT_DISABLE_LOGGING
1119 //			peer_log(peer_log_alert::incoming_message, "PIECE_FRAGMENT", "p: %d start: %d length: %d"
1120 //				, p.piece, p.start, p.length);
1121 #endif
1122 
1123 		if (recv_pos - received < header_size)
1124 		{
1125 			// call this once, the first time the entire header
1126 			// has been received
1127 			start_receive_piece(p);
1128 			if (is_disconnecting()) return;
1129 		}
1130 
1131 		incoming_piece_fragment(piece_bytes);
1132 		if (!m_recv_buffer.packet_finished()) return;
1133 
1134 		if (merkle && list_size > 0)
1135 		{
1136 #ifndef TORRENT_DISABLE_LOGGING
1137 			peer_log(peer_log_alert::incoming_message, "HASHPIECE"
1138 				, "piece: %d list: %d", static_cast<int>(p.piece), list_size);
1139 #endif
1140 			error_code ec;
1141 			bdecode_node const hash_list = bdecode(recv_buffer.subspan(13).first(list_size)
1142 				, ec);
1143 			if (ec)
1144 			{
1145 				disconnect(errors::invalid_hash_piece, operation_t::bittorrent, peer_error);
1146 				return;
1147 			}
1148 
1149 			// the list has this format:
1150 			// [ [node-index, hash], [node-index, hash], ... ]
1151 			if (hash_list.type() != bdecode_node::list_t)
1152 			{
1153 				disconnect(errors::invalid_hash_list, operation_t::bittorrent, peer_error);
1154 				return;
1155 			}
1156 
1157 			std::map<int, sha1_hash> nodes;
1158 			for (int i = 0; i < hash_list.list_size(); ++i)
1159 			{
1160 				bdecode_node const e = hash_list.list_at(i);
1161 				if (e.type() != bdecode_node::list_t
1162 					|| e.list_size() != 2
1163 					|| e.list_at(0).type() != bdecode_node::int_t
1164 					|| e.list_at(1).type() != bdecode_node::string_t
1165 					|| e.list_at(1).string_length() != 20) continue;
1166 
1167 				nodes.emplace(int(e.list_int_value_at(0))
1168 					, sha1_hash(e.list_at(1).string_ptr()));
1169 			}
1170 			if (!nodes.empty() && !t->add_merkle_nodes(nodes, p.piece))
1171 			{
1172 				disconnect(errors::invalid_hash_piece, operation_t::bittorrent, peer_error);
1173 				return;
1174 			}
1175 		}
1176 
1177 		incoming_piece(p, recv_buffer.data() + header_size);
1178 	}
1179 
1180 	// -----------------------------
1181 	// ---------- CANCEL -----------
1182 	// -----------------------------
1183 
on_cancel(int received)1184 	void bt_peer_connection::on_cancel(int received)
1185 	{
1186 		INVARIANT_CHECK;
1187 
1188 		TORRENT_ASSERT(received >= 0);
1189 		received_bytes(0, received);
1190 		if (m_recv_buffer.packet_size() != 13)
1191 		{
1192 			disconnect(errors::invalid_cancel, operation_t::bittorrent, peer_error);
1193 			return;
1194 		}
1195 		if (!m_recv_buffer.packet_finished()) return;
1196 
1197 		span<char const> recv_buffer = m_recv_buffer.get();
1198 
1199 		peer_request r;
1200 		const char* ptr = recv_buffer.data() + 1;
1201 		r.piece = piece_index_t(detail::read_int32(ptr));
1202 		r.start = detail::read_int32(ptr);
1203 		r.length = detail::read_int32(ptr);
1204 
1205 		incoming_cancel(r);
1206 	}
1207 
1208 	// -----------------------------
1209 	// --------- DHT PORT ----------
1210 	// -----------------------------
1211 
on_dht_port(int received)1212 	void bt_peer_connection::on_dht_port(int received)
1213 	{
1214 		INVARIANT_CHECK;
1215 
1216 		TORRENT_ASSERT(received >= 0);
1217 		received_bytes(0, received);
1218 		if (m_recv_buffer.packet_size() != 3)
1219 		{
1220 			disconnect(errors::invalid_dht_port, operation_t::bittorrent, peer_error);
1221 			return;
1222 		}
1223 		if (!m_recv_buffer.packet_finished()) return;
1224 
1225 		span<char const> recv_buffer = m_recv_buffer.get();
1226 
1227 		const char* ptr = recv_buffer.data() + 1;
1228 		int const listen_port = detail::read_uint16(ptr);
1229 
1230 		incoming_dht_port(listen_port);
1231 
1232 		if (!m_supports_dht_port)
1233 		{
1234 			m_supports_dht_port = true;
1235 			// if we're done with the handshake, respond right away, otherwise
1236 			// we'll send the DHT port later
1237 			if (m_sent_bitfield)
1238 				write_dht_port();
1239 		}
1240 	}
1241 
on_suggest_piece(int received)1242 	void bt_peer_connection::on_suggest_piece(int received)
1243 	{
1244 		INVARIANT_CHECK;
1245 
1246 		received_bytes(0, received);
1247 		if (!m_supports_fast || m_recv_buffer.packet_size() != 5)
1248 		{
1249 			disconnect(errors::invalid_suggest, operation_t::bittorrent, peer_error);
1250 			return;
1251 		}
1252 
1253 		if (!m_recv_buffer.packet_finished()) return;
1254 
1255 		span<char const> recv_buffer = m_recv_buffer.get();
1256 
1257 		const char* ptr = recv_buffer.data() + 1;
1258 		piece_index_t const piece(detail::read_int32(ptr));
1259 		incoming_suggest(piece);
1260 	}
1261 
on_have_all(int received)1262 	void bt_peer_connection::on_have_all(int received)
1263 	{
1264 		INVARIANT_CHECK;
1265 
1266 		received_bytes(0, received);
1267 		if (!m_supports_fast || m_recv_buffer.packet_size() != 1)
1268 		{
1269 			disconnect(errors::invalid_have_all, operation_t::bittorrent, peer_error);
1270 			return;
1271 		}
1272 		incoming_have_all();
1273 	}
1274 
on_have_none(int received)1275 	void bt_peer_connection::on_have_none(int received)
1276 	{
1277 		INVARIANT_CHECK;
1278 
1279 		received_bytes(0, received);
1280 		if (!m_supports_fast || m_recv_buffer.packet_size() != 1)
1281 		{
1282 			disconnect(errors::invalid_have_none, operation_t::bittorrent, peer_error);
1283 			return;
1284 		}
1285 		incoming_have_none();
1286 	}
1287 
on_reject_request(int received)1288 	void bt_peer_connection::on_reject_request(int received)
1289 	{
1290 		INVARIANT_CHECK;
1291 
1292 		received_bytes(0, received);
1293 		if (!m_supports_fast || m_recv_buffer.packet_size() != 13)
1294 		{
1295 			disconnect(errors::invalid_reject, operation_t::bittorrent, peer_error);
1296 			return;
1297 		}
1298 
1299 		if (!m_recv_buffer.packet_finished()) return;
1300 
1301 		span<char const> recv_buffer = m_recv_buffer.get();
1302 
1303 		peer_request r;
1304 		const char* ptr = recv_buffer.data() + 1;
1305 		r.piece = piece_index_t(detail::read_int32(ptr));
1306 		r.start = detail::read_int32(ptr);
1307 		r.length = detail::read_int32(ptr);
1308 
1309 		incoming_reject_request(r);
1310 	}
1311 
on_allowed_fast(int received)1312 	void bt_peer_connection::on_allowed_fast(int received)
1313 	{
1314 		INVARIANT_CHECK;
1315 
1316 		received_bytes(0, received);
1317 		if (!m_supports_fast || m_recv_buffer.packet_size() != 5)
1318 		{
1319 			disconnect(errors::invalid_allow_fast, operation_t::bittorrent, peer_error);
1320 			return;
1321 		}
1322 
1323 		if (!m_recv_buffer.packet_finished()) return;
1324 		span<char const> recv_buffer = m_recv_buffer.get();
1325 		const char* ptr = recv_buffer.data() + 1;
1326 		piece_index_t const index(detail::read_int32(ptr));
1327 
1328 		incoming_allowed_fast(index);
1329 	}
1330 
1331 	// -----------------------------
1332 	// -------- RENDEZVOUS ---------
1333 	// -----------------------------
1334 
on_holepunch()1335 	void bt_peer_connection::on_holepunch()
1336 	{
1337 		INVARIANT_CHECK;
1338 
1339 		if (!m_recv_buffer.packet_finished()) return;
1340 
1341 		// we can't accept holepunch messages from peers
1342 		// that don't support the holepunch extension
1343 		// because we wouldn't be able to respond
1344 		if (m_holepunch_id == 0) return;
1345 
1346 		span<char const> recv_buffer = m_recv_buffer.get();
1347 		TORRENT_ASSERT(recv_buffer.front() == msg_extended);
1348 		recv_buffer = recv_buffer.subspan(1);
1349 		TORRENT_ASSERT(recv_buffer.front() == holepunch_msg);
1350 		recv_buffer = recv_buffer.subspan(1);
1351 
1352 		char const* ptr = recv_buffer.data();
1353 		char const* const end = recv_buffer.data() + recv_buffer.size();
1354 
1355 		// ignore invalid messages
1356 		if (int(recv_buffer.size()) < 2) return;
1357 
1358 		auto const msg_type = static_cast<hp_message>(detail::read_uint8(ptr));
1359 		int const addr_type = detail::read_uint8(ptr);
1360 
1361 		tcp::endpoint ep;
1362 
1363 		if (addr_type == 0)
1364 		{
1365 			if (int(recv_buffer.size()) < 2 + 4 + 2) return;
1366 			// IPv4 address
1367 			ep = detail::read_v4_endpoint<tcp::endpoint>(ptr);
1368 		}
1369 		else if (addr_type == 1)
1370 		{
1371 			// IPv6 address
1372 			if (int(recv_buffer.size()) < 2 + 16 + 2) return;
1373 			ep = detail::read_v6_endpoint<tcp::endpoint>(ptr);
1374 		}
1375 		else
1376 		{
1377 #ifndef TORRENT_DISABLE_LOGGING
1378 			if (should_log(peer_log_alert::incoming_message))
1379 			{
1380 				static const char* hp_msg_name[] = {"rendezvous", "connect", "failed"};
1381 				peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1382 					, "msg: %s from %s to: unknown address type"
1383 					, (static_cast<int>(msg_type) < 3
1384 						? hp_msg_name[static_cast<int>(msg_type)]
1385 						: "unknown message type")
1386 					, print_address(remote().address()).c_str());
1387 			}
1388 #endif
1389 
1390 			return; // unknown address type
1391 		}
1392 
1393 #ifndef TORRENT_DISABLE_LOGGING
1394 		if (msg_type > hp_message::failed)
1395 		{
1396 			if (should_log(peer_log_alert::incoming_message))
1397 			{
1398 				peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1399 					, "msg: unknown message type (%d) to: %s"
1400 					, static_cast<int>(msg_type)
1401 					, print_address(ep.address()).c_str());
1402 			}
1403 			return;
1404 		}
1405 #endif
1406 
1407 		std::shared_ptr<torrent> t = associated_torrent().lock();
1408 		if (!t) return;
1409 
1410 		switch (msg_type)
1411 		{
1412 			case hp_message::rendezvous: // rendezvous
1413 			{
1414 #ifndef TORRENT_DISABLE_LOGGING
1415 				if (should_log(peer_log_alert::incoming_message))
1416 				{
1417 					peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1418 						, "msg: rendezvous to: %s", print_address(ep.address()).c_str());
1419 				}
1420 #endif
1421 				// this peer is asking us to introduce it to
1422 				// the peer at 'ep'. We need to find which of
1423 				// our connections points to that endpoint
1424 				bt_peer_connection* p = t->find_peer(ep);
1425 				if (p == nullptr)
1426 				{
1427 					// we're not connected to this peer
1428 					write_holepunch_msg(hp_message::failed, ep, hp_error::not_connected);
1429 					break;
1430 				}
1431 				if (!p->supports_holepunch())
1432 				{
1433 					write_holepunch_msg(hp_message::failed, ep, hp_error::no_support);
1434 					break;
1435 				}
1436 				if (p == this)
1437 				{
1438 					write_holepunch_msg(hp_message::failed, ep, hp_error::no_self);
1439 					break;
1440 				}
1441 
1442 				write_holepunch_msg(hp_message::connect, ep);
1443 				p->write_holepunch_msg(hp_message::connect, remote());
1444 			} break;
1445 			case hp_message::connect:
1446 			{
1447 				// add or find the peer with this endpoint
1448 				torrent_peer* p = t->add_peer(ep, peer_info::pex);
1449 				if (p == nullptr || p->connection)
1450 				{
1451 #ifndef TORRENT_DISABLE_LOGGING
1452 					if (should_log(peer_log_alert::incoming_message))
1453 					{
1454 						peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1455 							, "msg:connect to: %s ERROR: failed to add peer"
1456 							, print_address(ep.address()).c_str());
1457 					}
1458 #endif
1459 					// we either couldn't add this peer, or it's
1460 					// already connected. Just ignore the connect message
1461 					break;
1462 				}
1463 				if (p->banned)
1464 				{
1465 #ifndef TORRENT_DISABLE_LOGGING
1466 					if (should_log(peer_log_alert::incoming_message))
1467 					{
1468 						peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1469 							, "msg:connect to: %s ERROR: peer banned", print_address(ep.address()).c_str());
1470 					}
1471 #endif
1472 					// this peer is banned, don't connect to it
1473 					break;
1474 				}
1475 				// to make sure we use the uTP protocol
1476 				p->supports_utp = true;
1477 				// #error make sure we make this a connection candidate
1478 				// in case it has too many failures for instance
1479 				t->connect_to_peer(p, true);
1480 				// mark this connection to be in holepunch mode
1481 				// so that it will retry faster and stick to uTP while it's
1482 				// retrying
1483 				t->update_want_peers();
1484 				if (p->connection)
1485 					p->connection->set_holepunch_mode();
1486 #ifndef TORRENT_DISABLE_LOGGING
1487 				if (should_log(peer_log_alert::incoming_message))
1488 				{
1489 					peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1490 						, "msg:connect to: %s"
1491 						, print_address(ep.address()).c_str());
1492 				}
1493 #endif
1494 			} break;
1495 			case hp_message::failed:
1496 			{
1497 				if (end - ptr < 4) return;
1498 				std::uint32_t const error = detail::read_uint32(ptr);
1499 #ifndef TORRENT_DISABLE_LOGGING
1500 				if (should_log(peer_log_alert::incoming_message))
1501 				{
1502 					static char const* err_msg[] = {"no such peer", "not connected", "no support", "no self"};
1503 					peer_log(peer_log_alert::incoming_message, "HOLEPUNCH"
1504 						, "msg:failed ERROR: %d msg: %s", error
1505 						, ((error > 0 && error < 5)?err_msg[error-1]:"unknown message id"));
1506 				}
1507 #endif
1508 				// #error deal with holepunch errors
1509 				(void)error;
1510 			} break;
1511 		}
1512 	}
1513 
write_holepunch_msg(hp_message const type,tcp::endpoint const & ep,hp_error const error)1514 	void bt_peer_connection::write_holepunch_msg(hp_message const type
1515 		, tcp::endpoint const& ep, hp_error const error)
1516 	{
1517 		char buf[35];
1518 		char* ptr = buf + 6;
1519 		detail::write_uint8(type, ptr);
1520 		if (is_v4(ep)) detail::write_uint8(0, ptr);
1521 		else detail::write_uint8(1, ptr);
1522 		detail::write_endpoint(ep, ptr);
1523 
1524 #ifndef TORRENT_DISABLE_LOGGING
1525 		if (should_log(peer_log_alert::outgoing_message))
1526 		{
1527 			static const char* hp_msg_name[] = {"rendezvous", "connect", "failed"};
1528 			static const char* hp_error_string[] = {"", "no such peer", "not connected", "no support", "no self"};
1529 			peer_log(peer_log_alert::outgoing_message, "HOLEPUNCH"
1530 				, "msg: %s to: %s ERROR: %s"
1531 				, (static_cast<std::uint8_t>(type) < 3
1532 					? hp_msg_name[static_cast<std::uint8_t>(type)]
1533 					: "unknown message type")
1534 				, print_address(ep.address()).c_str()
1535 				, hp_error_string[static_cast<int>(error)]);
1536 		}
1537 #endif
1538 		if (type == hp_message::failed)
1539 		{
1540 			detail::write_uint32(static_cast<int>(error), ptr);
1541 		}
1542 
1543 		// write the packet length and type
1544 		char* hdr = buf;
1545 		detail::write_uint32(ptr - buf - 4, hdr);
1546 		detail::write_uint8(msg_extended, hdr);
1547 		detail::write_uint8(m_holepunch_id, hdr);
1548 
1549 		TORRENT_ASSERT(ptr <= buf + sizeof(buf));
1550 
1551 		send_buffer({buf, ptr - buf});
1552 
1553 		stats_counters().inc_stats_counter(counters::num_outgoing_extended);
1554 	}
1555 
1556 	// -----------------------------
1557 	// --------- EXTENDED ----------
1558 	// -----------------------------
1559 
on_extended(int received)1560 	void bt_peer_connection::on_extended(int received)
1561 	{
1562 		INVARIANT_CHECK;
1563 
1564 		TORRENT_ASSERT(received >= 0);
1565 		received_bytes(0, received);
1566 		if (m_recv_buffer.packet_size() < 2)
1567 		{
1568 			disconnect(errors::invalid_extended, operation_t::bittorrent, peer_error);
1569 			return;
1570 		}
1571 
1572 		if (associated_torrent().expired())
1573 		{
1574 			disconnect(errors::invalid_extended, operation_t::bittorrent, peer_error);
1575 			return;
1576 		}
1577 
1578 		span<char const> recv_buffer = m_recv_buffer.get();
1579 		if (int(recv_buffer.size()) < 2) return;
1580 
1581 		TORRENT_ASSERT(recv_buffer.front() == msg_extended);
1582 		recv_buffer = recv_buffer.subspan(1);
1583 
1584 		int const extended_id = aux::read_uint8(recv_buffer);
1585 
1586 		if (extended_id == 0)
1587 		{
1588 			on_extended_handshake();
1589 			disconnect_if_redundant();
1590 			return;
1591 		}
1592 
1593 		if (extended_id == upload_only_msg)
1594 		{
1595 			if (!m_recv_buffer.packet_finished()) return;
1596 			if (m_recv_buffer.packet_size() != 3)
1597 			{
1598 #ifndef TORRENT_DISABLE_LOGGING
1599 				peer_log(peer_log_alert::incoming_message, "UPLOAD_ONLY"
1600 					, "ERROR: unexpected packet size: %d", m_recv_buffer.packet_size());
1601 #endif
1602 				return;
1603 			}
1604 			bool const ul = aux::read_uint8(recv_buffer) != 0;
1605 #ifndef TORRENT_DISABLE_LOGGING
1606 			peer_log(peer_log_alert::incoming_message, "UPLOAD_ONLY"
1607 				, "%s", (ul?"true":"false"));
1608 #endif
1609 			set_upload_only(ul);
1610 			return;
1611 		}
1612 
1613 #ifndef TORRENT_DISABLE_SHARE_MODE
1614 		if (extended_id == share_mode_msg)
1615 		{
1616 			if (!m_recv_buffer.packet_finished()) return;
1617 			if (m_recv_buffer.packet_size() != 3)
1618 			{
1619 #ifndef TORRENT_DISABLE_LOGGING
1620 				peer_log(peer_log_alert::incoming_message, "SHARE_MODE"
1621 					, "ERROR: unexpected packet size: %d", m_recv_buffer.packet_size());
1622 #endif
1623 				return;
1624 			}
1625 			bool sm = aux::read_uint8(recv_buffer) != 0;
1626 #ifndef TORRENT_DISABLE_LOGGING
1627 			peer_log(peer_log_alert::incoming_message, "SHARE_MODE"
1628 				, "%s", (sm?"true":"false"));
1629 #endif
1630 			set_share_mode(sm);
1631 			return;
1632 		}
1633 #endif // TORRENT_DISABLE_SHARE_MODE
1634 
1635 		if (extended_id == holepunch_msg)
1636 		{
1637 			if (!m_recv_buffer.packet_finished()) return;
1638 #ifndef TORRENT_DISABLE_LOGGING
1639 			peer_log(peer_log_alert::incoming_message, "HOLEPUNCH");
1640 #endif
1641 			on_holepunch();
1642 			return;
1643 		}
1644 
1645 		if (extended_id == dont_have_msg)
1646 		{
1647 			if (!m_recv_buffer.packet_finished()) return;
1648 			if (m_recv_buffer.packet_size() != 6)
1649 			{
1650 #ifndef TORRENT_DISABLE_LOGGING
1651 				peer_log(peer_log_alert::incoming_message, "DONT_HAVE"
1652 					, "ERROR: unexpected packet size: %d", m_recv_buffer.packet_size());
1653 #endif
1654 				return;
1655 			}
1656 			piece_index_t const piece(aux::read_int32(recv_buffer));
1657 			incoming_dont_have(piece);
1658 			return;
1659 		}
1660 
1661 #ifndef TORRENT_DISABLE_LOGGING
1662 		if (m_recv_buffer.packet_finished())
1663 			peer_log(peer_log_alert::incoming_message, "EXTENSION_MESSAGE"
1664 				, "msg: %d size: %d", extended_id, m_recv_buffer.packet_size());
1665 #endif
1666 
1667 #ifndef TORRENT_DISABLE_EXTENSIONS
1668 		for (auto const& e : m_extensions)
1669 		{
1670 			if (e->on_extended(m_recv_buffer.packet_size() - 2, extended_id
1671 				, recv_buffer))
1672 				return;
1673 		}
1674 #endif
1675 
1676 		disconnect(errors::invalid_message, operation_t::bittorrent, peer_error);
1677 	}
1678 
on_extended_handshake()1679 	void bt_peer_connection::on_extended_handshake()
1680 	{
1681 		if (!m_recv_buffer.packet_finished()) return;
1682 
1683 		std::shared_ptr<torrent> t = associated_torrent().lock();
1684 		TORRENT_ASSERT(t);
1685 
1686 		span<char const> recv_buffer = m_recv_buffer.get();
1687 
1688 		error_code ec;
1689 		int pos;
1690 		bdecode_node root = bdecode(recv_buffer.subspan(2), ec, &pos);
1691 		if (ec || root.type() != bdecode_node::dict_t)
1692 		{
1693 #ifndef TORRENT_DISABLE_LOGGING
1694 			if (should_log(peer_log_alert::info))
1695 			{
1696 				peer_log(peer_log_alert::info, "EXTENSION_MESSAGE"
1697 					, "invalid extended handshake. pos: %d %s"
1698 					, pos, print_error(ec).c_str());
1699 			}
1700 #endif
1701 			return;
1702 		}
1703 
1704 #ifndef TORRENT_DISABLE_LOGGING
1705 		if (should_log(peer_log_alert::incoming_message))
1706 		{
1707 			peer_log(peer_log_alert::incoming_message, "EXTENDED_HANDSHAKE"
1708 				, "%s", print_entry(root, true).c_str());
1709 		}
1710 #endif
1711 
1712 #ifndef TORRENT_DISABLE_EXTENSIONS
1713 		for (auto i = m_extensions.begin();
1714 			!m_extensions.empty() && i != m_extensions.end();)
1715 		{
1716 			// a false return value means that the extension
1717 			// isn't supported by the other end. So, it is removed.
1718 			if (!(*i)->on_extension_handshake(root))
1719 				i = m_extensions.erase(i);
1720 			else
1721 				++i;
1722 		}
1723 		if (is_disconnecting()) return;
1724 #endif
1725 
1726 		// upload_only
1727 		if (bdecode_node const m = root.dict_find_dict("m"))
1728 		{
1729 			m_upload_only_id = std::uint8_t(m.dict_find_int_value("upload_only", 0));
1730 			m_holepunch_id = std::uint8_t(m.dict_find_int_value("ut_holepunch", 0));
1731 			m_dont_have_id = std::uint8_t(m.dict_find_int_value("lt_donthave", 0));
1732 		}
1733 
1734 		// there is supposed to be a remote listen port
1735 		int const listen_port = int(root.dict_find_int_value("p"));
1736 		if (listen_port > 0 && peer_info_struct() != nullptr)
1737 		{
1738 			t->update_peer_port(listen_port, peer_info_struct(), peer_info::incoming);
1739 			received_listen_port();
1740 			if (is_disconnecting()) return;
1741 		}
1742 
1743 		// there should be a version too
1744 		// but where do we put that info?
1745 
1746 		int const last_seen_complete = int(root.dict_find_int_value("complete_ago", -1));
1747 		if (last_seen_complete >= 0) set_last_seen_complete(last_seen_complete);
1748 
1749 		auto const client_info = root.dict_find_string_value("v");
1750 		if (!client_info.empty())
1751 		{
1752 			m_client_version = client_info.to_string();
1753 			// the client name is supposed to be UTF-8
1754 			verify_encoding(m_client_version);
1755 		}
1756 
1757 		int const reqq = int(root.dict_find_int_value("reqq"));
1758 		if (reqq > 0) max_out_request_queue(reqq);
1759 
1760 		if (root.dict_find_int_value("upload_only", 0))
1761 			set_upload_only(true);
1762 
1763 #ifndef TORRENT_DISABLE_SHARE_MODE
1764 		if (m_settings.get_bool(settings_pack::support_share_mode)
1765 			&& root.dict_find_int_value("share_mode", 0))
1766 			set_share_mode(true);
1767 #endif
1768 
1769 		auto const myip = root.dict_find_string_value("yourip");
1770 		if (!myip.empty())
1771 		{
1772 			if (myip.size() == std::tuple_size<address_v4::bytes_type>::value)
1773 			{
1774 				address_v4::bytes_type bytes;
1775 				std::copy(myip.begin(), myip.end(), bytes.begin());
1776 				m_ses.set_external_address(local_endpoint()
1777 					, address_v4(bytes)
1778 					, aux::session_interface::source_peer, remote().address());
1779 			}
1780 			else if (myip.size() == std::tuple_size<address_v6::bytes_type>::value)
1781 			{
1782 				address_v6::bytes_type bytes;
1783 				std::copy(myip.begin(), myip.end(), bytes.begin());
1784 				address_v6 ipv6_address(bytes);
1785 				if (ipv6_address.is_v4_mapped())
1786 					m_ses.set_external_address(local_endpoint()
1787 						, ipv6_address.to_v4()
1788 						, aux::session_interface::source_peer, remote().address());
1789 				else
1790 					m_ses.set_external_address(local_endpoint()
1791 						, ipv6_address
1792 						, aux::session_interface::source_peer, remote().address());
1793 			}
1794 		}
1795 
1796 		// if we're finished and this peer is uploading only
1797 		// disconnect it
1798 		if (t->is_finished() && upload_only()
1799 			&& m_settings.get_bool(settings_pack::close_redundant_connections)
1800 #ifndef TORRENT_DISABLE_SHARE_MODE
1801 			&& !t->share_mode()
1802 #endif
1803 			)
1804 			disconnect(errors::upload_upload_connection, operation_t::bittorrent);
1805 
1806 		stats_counters().inc_stats_counter(counters::num_incoming_ext_handshake);
1807 	}
1808 
dispatch_message(int const received)1809 	bool bt_peer_connection::dispatch_message(int const received)
1810 	{
1811 		INVARIANT_CHECK;
1812 
1813 		TORRENT_ASSERT(received >= 0);
1814 
1815 		// this means the connection has been closed already
1816 		if (associated_torrent().expired())
1817 		{
1818 			received_bytes(0, received);
1819 			return false;
1820 		}
1821 
1822 		span<char const> recv_buffer = m_recv_buffer.get();
1823 
1824 		TORRENT_ASSERT(int(recv_buffer.size()) >= 1);
1825 		int packet_type = static_cast<std::uint8_t>(recv_buffer[0]);
1826 
1827 		if (m_settings.get_bool(settings_pack::support_merkle_torrents)
1828 			&& packet_type == 250) packet_type = msg_piece;
1829 
1830 #if TORRENT_USE_ASSERTS
1831 		std::int64_t const cur_payload_dl = statistics().last_payload_downloaded();
1832 		std::int64_t const cur_protocol_dl = statistics().last_protocol_downloaded();
1833 #endif
1834 
1835 		// call the handler for this packet type
1836 		switch (packet_type)
1837 		{
1838 			// original BitTorrent message
1839 			case msg_choke: on_choke(received); break;
1840 			case msg_unchoke: on_unchoke(received); break;
1841 			case msg_interested: on_interested(received); break;
1842 			case msg_not_interested: on_not_interested(received); break;
1843 			case msg_have: on_have(received); break;
1844 			case msg_bitfield: on_bitfield(received); break;
1845 			case msg_request: on_request(received); break;
1846 			case msg_piece: on_piece(received); break;
1847 			case msg_cancel: on_cancel(received); break;
1848 
1849 			// DHT extension
1850 			case msg_dht_port: on_dht_port(received); break;
1851 
1852 			// FAST extension messages
1853 			case msg_suggest_piece: on_suggest_piece(received); break;
1854 			case msg_have_all: on_have_all(received); break;
1855 			case msg_have_none: on_have_none(received); break;
1856 			case msg_reject_request: on_reject_request(received); break;
1857 			case msg_allowed_fast: on_allowed_fast(received); break;
1858 			case msg_extended: on_extended(received); break;
1859 			default:
1860 			{
1861 #ifndef TORRENT_DISABLE_EXTENSIONS
1862 				for (auto const& e : m_extensions)
1863 				{
1864 					if (e->on_unknown_message(m_recv_buffer.packet_size(), packet_type
1865 						, recv_buffer.subspan(1)))
1866 						return m_recv_buffer.packet_finished();
1867 				}
1868 #endif
1869 				received_bytes(0, received);
1870 				disconnect(errors::invalid_message, operation_t::bittorrent);
1871 				return m_recv_buffer.packet_finished();
1872 			}
1873 		}
1874 
1875 #if TORRENT_USE_ASSERTS
1876 		TORRENT_ASSERT(statistics().last_payload_downloaded() - cur_payload_dl >= 0);
1877 		TORRENT_ASSERT(statistics().last_protocol_downloaded() - cur_protocol_dl >= 0);
1878 		std::int64_t const stats_diff = statistics().last_payload_downloaded()
1879 			- cur_payload_dl + statistics().last_protocol_downloaded()
1880 			- cur_protocol_dl;
1881 		TORRENT_ASSERT(stats_diff == received);
1882 #endif
1883 
1884 		bool const finished = m_recv_buffer.packet_finished();
1885 
1886 		if (finished)
1887 		{
1888 			// count this packet in the session stats counters
1889 			int const counter = (packet_type <= msg_dht_port)
1890 				? counters::num_incoming_choke + packet_type
1891 				: (packet_type <= msg_allowed_fast)
1892 				? counters::num_incoming_suggest + packet_type
1893 				: counters::num_incoming_extended;
1894 
1895 			stats_counters().inc_stats_counter(counter);
1896 		}
1897 
1898 		return finished;
1899 	}
1900 
write_upload_only(bool const enabled)1901 	void bt_peer_connection::write_upload_only(bool const enabled)
1902 	{
1903 		INVARIANT_CHECK;
1904 
1905 #if TORRENT_USE_ASSERTS && !defined TORRENT_DISABLE_SHARE_MODE
1906 		std::shared_ptr<torrent> t = associated_torrent().lock();
1907 		TORRENT_ASSERT(!t->share_mode());
1908 #endif
1909 
1910 		if (m_upload_only_id == 0) return;
1911 
1912 		// if we send upload-only, the other end is very likely to disconnect
1913 		// us, at least if it's a seed. If we don't want to close redundant
1914 		// connections, don't sent upload-only
1915 		if (!m_settings.get_bool(settings_pack::close_redundant_connections)) return;
1916 
1917 		char msg[7] = {0, 0, 0, 3, msg_extended};
1918 		char* ptr = msg + 5;
1919 		detail::write_uint8(m_upload_only_id, ptr);
1920 		detail::write_uint8(enabled, ptr);
1921 		send_buffer(msg);
1922 
1923 		stats_counters().inc_stats_counter(counters::num_outgoing_extended);
1924 	}
1925 
1926 #ifndef TORRENT_DISABLE_SHARE_MODE
write_share_mode()1927 	void bt_peer_connection::write_share_mode()
1928 	{
1929 		INVARIANT_CHECK;
1930 
1931 		std::shared_ptr<torrent> t = associated_torrent().lock();
1932 		if (m_share_mode_id == 0) return;
1933 
1934 		char msg[7] = {0, 0, 0, 3, msg_extended};
1935 		char* ptr = msg + 5;
1936 		detail::write_uint8(m_share_mode_id, ptr);
1937 		detail::write_uint8(t->share_mode(), ptr);
1938 		send_buffer(msg);
1939 
1940 		stats_counters().inc_stats_counter(counters::num_outgoing_extended);
1941 	}
1942 #endif
1943 
write_keepalive()1944 	void bt_peer_connection::write_keepalive()
1945 	{
1946 		INVARIANT_CHECK;
1947 
1948 		// Don't require the bitfield to have been sent at this point
1949 		// the case where m_sent_bitfield may not be true is if the
1950 		// torrent doesn't have any metadata, and a peer is timing out.
1951 		// then the keep-alive message will be sent before the bitfield
1952 		// this is a violation to the original protocol, but necessary
1953 		// for the metadata extension.
1954 		TORRENT_ASSERT(m_sent_handshake);
1955 
1956 		static const char msg[] = {0,0,0,0};
1957 		send_buffer(msg);
1958 	}
1959 
write_cancel(peer_request const & r)1960 	void bt_peer_connection::write_cancel(peer_request const& r)
1961 	{
1962 		INVARIANT_CHECK;
1963 
1964 		send_message(msg_cancel, counters::num_outgoing_cancel
1965 			, static_cast<int>(r.piece), r.start, r.length);
1966 
1967 		if (!m_supports_fast) incoming_reject_request(r);
1968 	}
1969 
write_request(peer_request const & r)1970 	void bt_peer_connection::write_request(peer_request const& r)
1971 	{
1972 		INVARIANT_CHECK;
1973 
1974 		send_message(msg_request, counters::num_outgoing_request
1975 			, static_cast<int>(r.piece), r.start, r.length);
1976 	}
1977 
write_bitfield()1978 	void bt_peer_connection::write_bitfield()
1979 	{
1980 		INVARIANT_CHECK;
1981 
1982 		// if we have not received the other peer's extension bits yet, how do we
1983 		// know whether to send a have-all or have-none?
1984 		TORRENT_ASSERT(m_state >= state_t::read_peer_id);
1985 
1986 		std::shared_ptr<torrent> t = associated_torrent().lock();
1987 		TORRENT_ASSERT(t);
1988 		TORRENT_ASSERT(m_sent_handshake);
1989 		TORRENT_ASSERT(t->valid_metadata());
1990 
1991 #ifndef TORRENT_DISABLE_SUPERSEEDING
1992 		if (t->super_seeding())
1993 		{
1994 #ifndef TORRENT_DISABLE_LOGGING
1995 			peer_log(peer_log_alert::info, "BITFIELD", "not sending bitfield, super seeding");
1996 #endif
1997 			if (m_supports_fast) write_have_none();
1998 
1999 			// if we are super seeding, pretend to not have any piece
2000 			// and don't send a bitfield
2001 			m_sent_bitfield = true;
2002 
2003 			// bootstrap super-seeding by sending two have message
2004 			piece_index_t piece = t->get_piece_to_super_seed(get_bitfield());
2005 			if (piece >= piece_index_t(0)) superseed_piece(piece_index_t(-1), piece);
2006 			piece = t->get_piece_to_super_seed(get_bitfield());
2007 			if (piece >= piece_index_t(0)) superseed_piece(piece_index_t(-1), piece);
2008 			return;
2009 		}
2010 		else
2011 #endif
2012 			if (m_supports_fast && t->is_seed())
2013 		{
2014 			write_have_all();
2015 			return;
2016 		}
2017 		else if (m_supports_fast && t->num_have() == 0)
2018 		{
2019 			write_have_none();
2020 			return;
2021 		}
2022 		else if (t->num_have() == 0)
2023 		{
2024 			// don't send a bitfield if we don't have any pieces
2025 #ifndef TORRENT_DISABLE_LOGGING
2026 			peer_log(peer_log_alert::info, "BITFIELD", "not sending bitfield, have none");
2027 #endif
2028 			m_sent_bitfield = true;
2029 			return;
2030 		}
2031 
2032 		const int num_pieces = t->torrent_file().num_pieces();
2033 		TORRENT_ASSERT(num_pieces > 0);
2034 
2035 		constexpr std::uint8_t char_bit_mask = CHAR_BIT - 1;
2036 		constexpr std::uint8_t char_top_bit = 1 << (CHAR_BIT - 1);
2037 
2038 		const int packet_size = (num_pieces + char_bit_mask) / CHAR_BIT + 5;
2039 
2040 		TORRENT_ALLOCA(msg, char, packet_size);
2041 		if (msg.data() == nullptr) return; // out of memory
2042 		auto ptr = msg.begin();
2043 
2044 		detail::write_int32(packet_size - 4, ptr);
2045 		detail::write_uint8(msg_bitfield, ptr);
2046 
2047 		if (t->is_seed())
2048 		{
2049 			std::fill_n(ptr, packet_size - 5, std::uint8_t{0xff});
2050 
2051 			// Clear trailing bits
2052 			msg.back() = static_cast<char>((0xff << ((CHAR_BIT - (num_pieces & char_bit_mask)) & char_bit_mask)) & 0xff);
2053 		}
2054 		else
2055 		{
2056 			std::memset(ptr, 0, aux::numeric_cast<std::size_t>(packet_size - 5));
2057 			piece_picker const& p = t->picker();
2058 			int mask = char_top_bit;
2059 			for (piece_index_t i(0); i < piece_index_t(num_pieces); ++i)
2060 			{
2061 				if (p.have_piece(i)) *ptr |= mask;
2062 				mask >>= 1;
2063 				if (mask == 0)
2064 				{
2065 					mask = char_top_bit;
2066 					++ptr;
2067 				}
2068 			}
2069 		}
2070 
2071 #ifndef TORRENT_DISABLE_PREDICTIVE_PIECES
2072 		// add predictive pieces to the bitfield as well, since we won't
2073 		// announce them again
2074 		for (piece_index_t const p : t->predictive_pieces())
2075 			msg[5 + static_cast<int>(p) / CHAR_BIT] |= (char_top_bit >> (static_cast<int>(p) & char_bit_mask));
2076 #endif
2077 
2078 #ifndef TORRENT_DISABLE_LOGGING
2079 		if (should_log(peer_log_alert::outgoing_message))
2080 		{
2081 			std::string bitfield_string;
2082 			std::size_t const n_pieces = aux::numeric_cast<std::size_t>(num_pieces);
2083 			bitfield_string.resize(n_pieces);
2084 			for (std::size_t k = 0; k < n_pieces; ++k)
2085 			{
2086 				if (msg[5 + int(k) / CHAR_BIT] & (char_top_bit >> (k % CHAR_BIT))) bitfield_string[k] = '1';
2087 				else bitfield_string[k] = '0';
2088 			}
2089 			peer_log(peer_log_alert::outgoing_message, "BITFIELD"
2090 				, "%s", bitfield_string.c_str());
2091 		}
2092 #endif
2093 		m_sent_bitfield = true;
2094 
2095 		send_buffer(msg);
2096 
2097 		stats_counters().inc_stats_counter(counters::num_outgoing_bitfield);
2098 	}
2099 
write_extensions()2100 	void bt_peer_connection::write_extensions()
2101 	{
2102 		INVARIANT_CHECK;
2103 
2104 		TORRENT_ASSERT(m_supports_extensions);
2105 		TORRENT_ASSERT(m_sent_handshake);
2106 
2107 		entry handshake;
2108 		entry::dictionary_type& m = handshake["m"].dict();
2109 
2110 		std::shared_ptr<torrent> t = associated_torrent().lock();
2111 		TORRENT_ASSERT(t);
2112 
2113 		// if we're using a proxy, our listen port won't be useful
2114 		// anyway.
2115 		if (is_outgoing())
2116 		{
2117 			auto const port = m_ses.listen_port(
2118 				t->is_ssl_torrent() ? aux::transport::ssl : aux::transport::plaintext
2119 				, local_endpoint().address());
2120 			if (port != 0) handshake["p"] = port;
2121 		}
2122 
2123 		// only send the port in case we bade the connection
2124 		// on incoming connections the other end already knows
2125 		// our listen port
2126 		if (!m_settings.get_bool(settings_pack::anonymous_mode))
2127 		{
2128 			handshake["v"] = m_settings.get_str(settings_pack::handshake_client_version).empty()
2129 				? m_settings.get_str(settings_pack::user_agent)
2130 				: m_settings.get_str(settings_pack::handshake_client_version);
2131 		}
2132 
2133 		std::string remote_address;
2134 		std::back_insert_iterator<std::string> out(remote_address);
2135 		detail::write_address(remote().address(), out);
2136 #if TORRENT_USE_I2P
2137 		if (!is_i2p(*get_socket()))
2138 #endif
2139 			handshake["yourip"] = remote_address;
2140 		handshake["reqq"] = m_settings.get_int(settings_pack::max_allowed_in_request_queue);
2141 
2142 		m["upload_only"] = upload_only_msg;
2143 		m["ut_holepunch"] = holepunch_msg;
2144 #ifndef TORRENT_DISABLE_SHARE_MODE
2145 		if (m_settings.get_bool(settings_pack::support_share_mode))
2146 			m["share_mode"] = share_mode_msg;
2147 #endif
2148 		m["lt_donthave"] = dont_have_msg;
2149 
2150 		int complete_ago = -1;
2151 		if (t->last_seen_complete() > 0) complete_ago = t->time_since_complete();
2152 		handshake["complete_ago"] = complete_ago;
2153 
2154 		// if we're super seeding, don't say we're upload only, since it might
2155 		// make peers disconnect. don't tell anyone we're upload only when in
2156 		// share mode, we want to stay connected to seeds. if we're super seeding,
2157 		// we don't want to make peers think that we only have a single piece and
2158 		// is upload only, since they might disconnect immediately when they have
2159 		// downloaded a single piece, although we'll make another piece available.
2160 		// If we don't have metadata, we also need to suppress saying we're
2161 		// upload-only. If we do, we may be disconnected before we receive the
2162 		// metadata.
2163 		if (t->is_upload_only()
2164 #ifndef TORRENT_DISABLE_SHARE_MODE
2165 			&& !t->share_mode()
2166 #endif
2167 			&& t->valid_metadata()
2168 #ifndef TORRENT_DISABLE_SUPERSEEDING
2169 			&& !t->super_seeding()
2170 #endif
2171 			)
2172 		{
2173 			handshake["upload_only"] = 1;
2174 		}
2175 
2176 #ifndef TORRENT_DISABLE_SHARE_MODE
2177 		if (m_settings.get_bool(settings_pack::support_share_mode)
2178 			&& t->share_mode())
2179 			handshake["share_mode"] = 1;
2180 #endif
2181 
2182 #ifndef TORRENT_DISABLE_EXTENSIONS
2183 		// loop backwards, to make the first extension be the last
2184 		// to fill in the handshake (i.e. give the first extensions priority)
2185 		for (auto const& e : m_extensions)
2186 		{
2187 			e->add_handshake(handshake);
2188 		}
2189 #endif
2190 
2191 #ifndef NDEBUG
2192 		// make sure there are not conflicting extensions
2193 		std::set<int> ext;
2194 		for (entry::dictionary_type::const_iterator i = m.begin()
2195 			, end(m.end()); i != end; ++i)
2196 		{
2197 			if (i->second.type() != entry::int_t) continue;
2198 			int val = int(i->second.integer());
2199 			TORRENT_ASSERT(ext.find(val) == ext.end());
2200 			ext.insert(val);
2201 		}
2202 #endif
2203 
2204 		std::vector<char> dict_msg;
2205 		bencode(std::back_inserter(dict_msg), handshake);
2206 
2207 		char msg[6];
2208 		char* ptr = msg;
2209 
2210 		// write the length of the message
2211 		detail::write_int32(int(dict_msg.size()) + 2, ptr);
2212 		detail::write_uint8(msg_extended, ptr);
2213 		// signal handshake message
2214 		detail::write_uint8(0, ptr);
2215 		send_buffer(msg);
2216 		send_buffer(dict_msg);
2217 
2218 		stats_counters().inc_stats_counter(counters::num_outgoing_ext_handshake);
2219 
2220 #ifndef TORRENT_DISABLE_LOGGING
2221 		if (should_log(peer_log_alert::outgoing_message))
2222 		{
2223 			peer_log(peer_log_alert::outgoing_message, "EXTENDED_HANDSHAKE"
2224 				, "%s", handshake.to_string(true).c_str());
2225 		}
2226 #endif
2227 	}
2228 
write_choke()2229 	void bt_peer_connection::write_choke()
2230 	{
2231 		INVARIANT_CHECK;
2232 
2233 		if (is_choked()) return;
2234 		send_message(msg_choke, counters::num_outgoing_choke);
2235 	}
2236 
write_unchoke()2237 	void bt_peer_connection::write_unchoke()
2238 	{
2239 		INVARIANT_CHECK;
2240 
2241 		send_message(msg_unchoke, counters::num_outgoing_unchoke);
2242 
2243 #ifndef TORRENT_DISABLE_EXTENSIONS
2244 		for (auto const& e : m_extensions)
2245 		{
2246 			e->sent_unchoke();
2247 		}
2248 #endif
2249 	}
2250 
write_interested()2251 	void bt_peer_connection::write_interested()
2252 	{
2253 		INVARIANT_CHECK;
2254 
2255 		send_message(msg_interested, counters::num_outgoing_interested);
2256 	}
2257 
write_not_interested()2258 	void bt_peer_connection::write_not_interested()
2259 	{
2260 		INVARIANT_CHECK;
2261 
2262 		send_message(msg_not_interested, counters::num_outgoing_not_interested);
2263 	}
2264 
write_have(piece_index_t const index)2265 	void bt_peer_connection::write_have(piece_index_t const index)
2266 	{
2267 		INVARIANT_CHECK;
2268 		TORRENT_ASSERT(associated_torrent().lock()->valid_metadata());
2269 		TORRENT_ASSERT(index >= piece_index_t(0));
2270 		TORRENT_ASSERT(index < associated_torrent().lock()->torrent_file().end_piece());
2271 
2272 		// if we haven't sent the bitfield yet, this piece should be included in
2273 		// there instead
2274 		if (!m_sent_bitfield) return;
2275 
2276 		send_message(msg_have, counters::num_outgoing_have
2277 			, static_cast<int>(index));
2278 	}
2279 
write_dont_have(piece_index_t const index)2280 	void bt_peer_connection::write_dont_have(piece_index_t const index)
2281 	{
2282 		INVARIANT_CHECK;
2283 		TORRENT_ASSERT(associated_torrent().lock()->valid_metadata());
2284 		TORRENT_ASSERT(index >= piece_index_t(0));
2285 		TORRENT_ASSERT(index < associated_torrent().lock()->torrent_file().end_piece());
2286 
2287 		if (in_handshake()) return;
2288 
2289 		TORRENT_ASSERT(m_sent_handshake);
2290 		TORRENT_ASSERT(m_sent_bitfield);
2291 
2292 		if (!m_supports_extensions || m_dont_have_id == 0) return;
2293 
2294 		char msg[] = {0,0,0,6,msg_extended,char(m_dont_have_id),0,0,0,0};
2295 		char* ptr = msg + 6;
2296 		detail::write_int32(static_cast<int>(index), ptr);
2297 		send_buffer(msg);
2298 
2299 		stats_counters().inc_stats_counter(counters::num_outgoing_extended);
2300 	}
2301 
write_piece(peer_request const & r,disk_buffer_holder buffer)2302 	void bt_peer_connection::write_piece(peer_request const& r, disk_buffer_holder buffer)
2303 	{
2304 		INVARIANT_CHECK;
2305 
2306 		TORRENT_ASSERT(m_sent_handshake);
2307 		TORRENT_ASSERT(m_sent_bitfield);
2308 
2309 		std::shared_ptr<torrent> t = associated_torrent().lock();
2310 		TORRENT_ASSERT(t);
2311 
2312 		bool merkle = t->torrent_file().is_merkle_torrent() && r.start == 0;
2313 	// the hash piece looks like this:
2314 	// uint8_t  msg
2315 	// uint32_t piece index
2316 	// uint32_t start
2317 	// uint32_t list len
2318 	// var      bencoded list
2319 	// var      piece data
2320 		char msg[4 + 1 + 4 + 4 + 4];
2321 		char* ptr = msg;
2322 		TORRENT_ASSERT(r.length <= 16 * 1024);
2323 		detail::write_int32(r.length + 1 + 4 + 4, ptr);
2324 		if (m_settings.get_bool(settings_pack::support_merkle_torrents) && merkle)
2325 			detail::write_uint8(250, ptr);
2326 		else
2327 			detail::write_uint8(msg_piece, ptr);
2328 		detail::write_int32(static_cast<int>(r.piece), ptr);
2329 		detail::write_int32(r.start, ptr);
2330 
2331 		// if this is a merkle torrent and the start offset
2332 		// is 0, we need to include the merkle node hashes
2333 		if (merkle)
2334 		{
2335 			std::vector<char> piece_list_buf;
2336 			entry piece_list;
2337 			entry::list_type& l = piece_list.list();
2338 			std::map<int, sha1_hash> merkle_node_list = t->torrent_file().build_merkle_list(r.piece);
2339 			l.reserve(merkle_node_list.size());
2340 			for (auto const& i : merkle_node_list)
2341 			{
2342 				l.emplace_back(entry::list_t);
2343 				l.back().list().emplace_back(i.first);
2344 				l.back().list().emplace_back(i.second.to_string());
2345 			}
2346 			bencode(std::back_inserter(piece_list_buf), piece_list);
2347 			detail::write_int32(int(piece_list_buf.size()), ptr);
2348 
2349 			// back-patch the length field
2350 			char* ptr2 = msg;
2351 			detail::write_int32(r.length + 1 + 4 + 4 + 4 + int(piece_list_buf.size())
2352 				, ptr2);
2353 
2354 			send_buffer({msg, 17});
2355 			send_buffer(piece_list_buf);
2356 		}
2357 		else
2358 		{
2359 			send_buffer({msg, 13});
2360 		}
2361 
2362 		if (buffer.is_mutable())
2363 		{
2364 			append_send_buffer(std::move(buffer), r.length);
2365 		}
2366 		else
2367 		{
2368 			append_const_send_buffer(std::move(buffer), r.length);
2369 		}
2370 
2371 		m_payloads.emplace_back(send_buffer_size() - r.length, r.length);
2372 		setup_send();
2373 
2374 		stats_counters().inc_stats_counter(counters::num_outgoing_piece);
2375 
2376 		if (t->alerts().should_post<block_uploaded_alert>())
2377 		{
2378 			t->alerts().emplace_alert<block_uploaded_alert>(t->get_handle(),
2379 				remote(), pid(), r.start / t->block_size() , r.piece);
2380 		}
2381 	}
2382 
2383 	// --------------------------
2384 	// RECEIVE DATA
2385 	// --------------------------
2386 
on_receive(error_code const & error,std::size_t bytes_transferred)2387 	void bt_peer_connection::on_receive(error_code const& error
2388 		, std::size_t bytes_transferred)
2389 	{
2390 		INVARIANT_CHECK;
2391 
2392 		if (error)
2393 		{
2394 			received_bytes(0, int(bytes_transferred));
2395 			return;
2396 		}
2397 
2398 		// make sure are much as possible of the response ends up in the same
2399 		// packet, or at least back-to-back packets
2400 		cork c_(*this);
2401 
2402 #if !defined TORRENT_DISABLE_ENCRYPTION
2403 		if (!m_enc_handler.is_recv_plaintext())
2404 		{
2405 			int const consumed = m_enc_handler.decrypt(m_recv_buffer, bytes_transferred);
2406 #ifndef TORRENT_DISABLE_LOGGING
2407 			if (consumed + int(bytes_transferred) > 0)
2408 				peer_log(peer_log_alert::incoming_message, "ENCRYPTION"
2409 					, "decrypted block s = %d", consumed + int(bytes_transferred));
2410 #endif
2411 			if (bytes_transferred == SIZE_MAX)
2412 			{
2413 				disconnect(errors::parse_failed, operation_t::encryption);
2414 				return;
2415 			}
2416 			received_bytes(0, consumed);
2417 
2418 			// don't accept packets larger than 1 MB with a 1KB allowance for headers
2419 			if (!m_recv_buffer.crypto_packet_finished()
2420 				&& m_recv_buffer.crypto_packet_size() > 1025 * 1024)
2421 			{
2422 				disconnect(errors::packet_too_large, operation_t::encryption, peer_error);
2423 				return;
2424 			}
2425 
2426 			int sub_transferred = 0;
2427 			while (bytes_transferred > 0 &&
2428 				((sub_transferred = m_recv_buffer.advance_pos(int(bytes_transferred))) > 0))
2429 			{
2430 #if TORRENT_USE_ASSERTS
2431 				std::int64_t const cur_payload_dl = m_statistics.last_payload_downloaded();
2432 				std::int64_t const cur_protocol_dl = m_statistics.last_protocol_downloaded();
2433 #endif
2434 				TORRENT_ASSERT(sub_transferred > 0);
2435 				on_receive_impl(std::size_t(sub_transferred));
2436 				bytes_transferred -= std::size_t(sub_transferred);
2437 
2438 #if TORRENT_USE_ASSERTS
2439 				TORRENT_ASSERT(m_statistics.last_payload_downloaded() - cur_payload_dl >= 0);
2440 				TORRENT_ASSERT(m_statistics.last_protocol_downloaded() - cur_protocol_dl >= 0);
2441 				std::int64_t const stats_diff = m_statistics.last_payload_downloaded() - cur_payload_dl +
2442 					m_statistics.last_protocol_downloaded() - cur_protocol_dl;
2443 				TORRENT_ASSERT(stats_diff == sub_transferred);
2444 #endif
2445 
2446 				if (m_disconnecting) return;
2447 			}
2448 		}
2449 		else
2450 #endif
2451 			on_receive_impl(bytes_transferred);
2452 	}
2453 
on_receive_impl(std::size_t bytes_transferred)2454 	void bt_peer_connection::on_receive_impl(std::size_t bytes_transferred)
2455 	{
2456 		std::shared_ptr<torrent> t = associated_torrent().lock();
2457 
2458 		span<char const> recv_buffer = m_recv_buffer.get();
2459 
2460 #if !defined TORRENT_DISABLE_ENCRYPTION
2461 		// m_state is set to read_pe_dhkey in initial state
2462 		// (read_protocol_identifier) for incoming, or in constructor
2463 		// for outgoing
2464 		if (m_state == state_t::read_pe_dhkey)
2465 		{
2466 			received_bytes(0, int(bytes_transferred));
2467 
2468 			TORRENT_ASSERT(!m_encrypted);
2469 			TORRENT_ASSERT(!m_rc4_encrypted);
2470 			TORRENT_ASSERT(m_recv_buffer.packet_size() == dh_key_len);
2471 			TORRENT_ASSERT(recv_buffer.data() == m_recv_buffer.get().data());
2472 			TORRENT_ASSERT(recv_buffer.size() == m_recv_buffer.get().size());
2473 
2474 			if (!m_recv_buffer.packet_finished()) return;
2475 
2476 			// write our dh public key. m_dh_key_exchange is
2477 			// initialized in write_pe1_2_dhkey()
2478 			if (!is_outgoing()) write_pe1_2_dhkey();
2479 			if (is_disconnecting()) return;
2480 
2481 			// read dh key, generate shared secret
2482 			m_dh_key_exchange->compute_secret(
2483 				reinterpret_cast<std::uint8_t const*>(recv_buffer.data()));
2484 
2485 #ifndef TORRENT_DISABLE_LOGGING
2486 			peer_log(peer_log_alert::info, "ENCRYPTION", "received DH key");
2487 #endif
2488 
2489 			// PadA/B can be a max of 512 bytes, and 20 bytes more for
2490 			// the sync hash (if incoming), or 8 bytes more for the
2491 			// encrypted verification constant (if outgoing). Instead
2492 			// of requesting the maximum possible, request the maximum
2493 			// possible to ensure we do not overshoot the standard
2494 			// handshake.
2495 
2496 			if (is_outgoing())
2497 			{
2498 				m_state = state_t::read_pe_syncvc;
2499 				write_pe3_sync();
2500 
2501 				// initial payload is the standard handshake, this is
2502 				// always rc4 if sent here. m_rc4_encrypted is flagged
2503 				// again according to peer selection.
2504 				switch_send_crypto(m_rc4);
2505 				write_handshake();
2506 				switch_send_crypto(std::shared_ptr<crypto_plugin>());
2507 
2508 				// vc,crypto_select,len(pad),pad, encrypt(handshake)
2509 				// 8+4+2+0+handshake_len
2510 				m_recv_buffer.reset(8+4+2+0+handshake_len);
2511 			}
2512 			else
2513 			{
2514 				// already written dh key
2515 				m_state = state_t::read_pe_synchash;
2516 				// synchash,skeyhash,vc,crypto_provide,len(pad),pad,encrypt(handshake)
2517 				m_recv_buffer.reset(20+20+8+4+2+0+handshake_len);
2518 			}
2519 			TORRENT_ASSERT(!m_recv_buffer.packet_finished());
2520 			return;
2521 		}
2522 
2523 		// cannot fall through into
2524 		if (m_state == state_t::read_pe_synchash)
2525 		{
2526 			TORRENT_ASSERT(!m_encrypted);
2527 			TORRENT_ASSERT(!m_rc4_encrypted);
2528 			TORRENT_ASSERT(!is_outgoing());
2529 			TORRENT_ASSERT(recv_buffer.data() == m_recv_buffer.get().data());
2530 			TORRENT_ASSERT(recv_buffer.size() == m_recv_buffer.get().size());
2531 
2532 			if (int(recv_buffer.size()) < 20)
2533 			{
2534 				received_bytes(0, int(bytes_transferred));
2535 
2536 				if (m_recv_buffer.packet_finished())
2537 					disconnect(errors::sync_hash_not_found, operation_t::bittorrent, failure);
2538 				return;
2539 			}
2540 
2541 			if (!m_sync_hash)
2542 			{
2543 				TORRENT_ASSERT(m_sync_bytes_read == 0);
2544 
2545 				static char const req1[4] = {'r', 'e', 'q', '1'};
2546 				// compute synchash (hash('req1',S))
2547 				std::array<char, dh_key_len> const buffer = export_key(m_dh_key_exchange->get_secret());
2548 				hasher h(req1);
2549 				h.update(buffer);
2550 				m_sync_hash.reset(new sha1_hash(h.final()));
2551 
2552 #ifndef TORRENT_DISABLE_LOGGING
2553 				if (should_log(peer_log_alert::info))
2554 				{
2555 					peer_log(peer_log_alert::info, "ENCRYPTION"
2556 						, "looking for synchash %s secret: %s"
2557 						, aux::to_hex(*m_sync_hash).c_str()
2558 						, aux::to_hex(buffer).c_str());
2559 				}
2560 #endif
2561 			}
2562 
2563 			int const syncoffset = search(*m_sync_hash, recv_buffer);
2564 
2565 			// No sync
2566 			if (syncoffset == -1)
2567 			{
2568 				received_bytes(0, int(bytes_transferred));
2569 
2570 				int const bytes_processed = int(recv_buffer.size()) - 20;
2571 				m_sync_bytes_read += bytes_processed;
2572 				if (m_sync_bytes_read >= 512)
2573 				{
2574 					disconnect(errors::sync_hash_not_found, operation_t::encryption, failure);
2575 					return;
2576 				}
2577 
2578 				m_recv_buffer.cut(bytes_processed, std::min(m_recv_buffer.packet_size()
2579 					, (512 + 20) - m_sync_bytes_read));
2580 
2581 				TORRENT_ASSERT(!m_recv_buffer.packet_finished());
2582 				return;
2583 			}
2584 			// found complete sync
2585 			else
2586 			{
2587 				int const bytes_processed = syncoffset + 20;
2588 #ifndef TORRENT_DISABLE_LOGGING
2589 				peer_log(peer_log_alert::info, "ENCRYPTION"
2590 					, "sync point (hash) found at offset %d"
2591 					, m_sync_bytes_read + bytes_processed - 20);
2592 #endif
2593 				m_state = state_t::read_pe_skey_vc;
2594 				// skey,vc - 28 bytes
2595 				m_sync_hash.reset();
2596 				int const transferred_used = bytes_processed
2597 					- aux::numeric_cast<int>(recv_buffer.size())
2598 					+ aux::numeric_cast<int>(bytes_transferred);
2599 				TORRENT_ASSERT(transferred_used >= 0);
2600 				TORRENT_ASSERT(transferred_used <= int(bytes_transferred));
2601 				received_bytes(0, transferred_used);
2602 				bytes_transferred -= std::size_t(transferred_used);
2603 				m_recv_buffer.cut(bytes_processed, 28);
2604 			}
2605 		}
2606 
2607 		if (m_state == state_t::read_pe_skey_vc)
2608 		{
2609 			received_bytes(0, int(bytes_transferred));
2610 			bytes_transferred = 0;
2611 
2612 			TORRENT_ASSERT(!m_encrypted);
2613 			TORRENT_ASSERT(!m_rc4_encrypted);
2614 			TORRENT_ASSERT(!is_outgoing());
2615 			TORRENT_ASSERT(m_recv_buffer.packet_size() == 28);
2616 
2617 			if (!m_recv_buffer.packet_finished()) return;
2618 			if (is_disconnecting()) return;
2619 			TORRENT_ASSERT(!is_disconnecting());
2620 
2621 			recv_buffer = m_recv_buffer.get();
2622 
2623 			TORRENT_ASSERT(!is_disconnecting());
2624 
2625 			sha1_hash ih(recv_buffer.data());
2626 			torrent const* ti = m_ses.find_encrypted_torrent(ih, m_dh_key_exchange->get_hash_xor_mask());
2627 
2628 			if (ti)
2629 			{
2630 				if (!t)
2631 				{
2632 					attach_to_torrent(ti->info_hash());
2633 					if (is_disconnecting()) return;
2634 					TORRENT_ASSERT(!is_disconnecting());
2635 
2636 					t = associated_torrent().lock();
2637 					TORRENT_ASSERT(t);
2638 				}
2639 
2640 				m_rc4 = init_pe_rc4_handler(m_dh_key_exchange->get_secret()
2641 					, ti->info_hash(), is_outgoing());
2642 #ifndef TORRENT_DISABLE_LOGGING
2643 				peer_log(peer_log_alert::info, "ENCRYPTION", "computed RC4 keys");
2644 				peer_log(peer_log_alert::info, "ENCRYPTION", "stream key found, torrent located");
2645 #endif
2646 			}
2647 
2648 			if (!m_rc4)
2649 			{
2650 				disconnect(errors::invalid_info_hash, operation_t::bittorrent, failure);
2651 				return;
2652 			}
2653 
2654 			// verify constant
2655 			rc4_decrypt(m_recv_buffer.mutable_buffer().subspan(20, 8));
2656 
2657 			static const char sh_vc[] = {0,0,0,0, 0,0,0,0};
2658 			if (!std::equal(sh_vc, sh_vc + 8, recv_buffer.begin() + 20))
2659 			{
2660 				disconnect(errors::invalid_encryption_constant, operation_t::encryption, peer_error);
2661 				return;
2662 			}
2663 
2664 #ifndef TORRENT_DISABLE_LOGGING
2665 			peer_log(peer_log_alert::info, "ENCRYPTION", "verification constant found");
2666 #endif
2667 			m_state = state_t::read_pe_cryptofield;
2668 			m_recv_buffer.reset(4 + 2);
2669 		}
2670 
2671 		// cannot fall through into
2672 		if (m_state == state_t::read_pe_syncvc)
2673 		{
2674 			TORRENT_ASSERT(is_outgoing());
2675 			TORRENT_ASSERT(!m_encrypted);
2676 			TORRENT_ASSERT(!m_rc4_encrypted);
2677 			TORRENT_ASSERT(recv_buffer.data() == m_recv_buffer.get().data());
2678 			TORRENT_ASSERT(recv_buffer.size() == m_recv_buffer.get().size());
2679 
2680 			if (int(recv_buffer.size()) < 8)
2681 			{
2682 				received_bytes(0, int(bytes_transferred));
2683 				if (m_recv_buffer.packet_finished())
2684 					disconnect(errors::invalid_encryption_constant, operation_t::encryption, peer_error);
2685 				return;
2686 			}
2687 
2688 			// generate the verification constant
2689 			if (!m_sync_vc)
2690 			{
2691 				TORRENT_ASSERT(m_sync_bytes_read == 0);
2692 
2693 				m_sync_vc.reset(new (std::nothrow) char[8]);
2694 				if (!m_sync_vc)
2695 				{
2696 					disconnect(errors::no_memory, operation_t::encryption);
2697 					return;
2698 				}
2699 				std::fill(m_sync_vc.get(), m_sync_vc.get() + 8, char{0});
2700 				rc4_decrypt({m_sync_vc.get(), 8});
2701 			}
2702 
2703 			TORRENT_ASSERT(m_sync_vc);
2704 			int const syncoffset = search({m_sync_vc.get(), 8}, recv_buffer);
2705 
2706 			// No sync
2707 			if (syncoffset == -1)
2708 			{
2709 				int const bytes_processed = int(recv_buffer.size()) - 8;
2710 				m_sync_bytes_read += bytes_processed;
2711 				received_bytes(0, int(bytes_transferred));
2712 
2713 				if (m_sync_bytes_read >= 512)
2714 				{
2715 					disconnect(errors::invalid_encryption_constant, operation_t::encryption, peer_error);
2716 					return;
2717 				}
2718 
2719 				m_recv_buffer.cut(bytes_processed, std::min(m_recv_buffer.packet_size()
2720 					, (512 + 8) - m_sync_bytes_read));
2721 
2722 				TORRENT_ASSERT(!m_recv_buffer.packet_finished());
2723 			}
2724 			// found complete sync
2725 			else
2726 			{
2727 				int const bytes_processed = syncoffset + 8;
2728 #ifndef TORRENT_DISABLE_LOGGING
2729 				peer_log(peer_log_alert::info, "ENCRYPTION"
2730 					, "sync point (verification constant) found at offset %d"
2731 					, m_sync_bytes_read + bytes_processed - 8);
2732 #endif
2733 				int const transferred_used = bytes_processed
2734 					- aux::numeric_cast<int>(recv_buffer.size())
2735 					+ aux::numeric_cast<int>(bytes_transferred);
2736 				TORRENT_ASSERT(transferred_used >= 0);
2737 				TORRENT_ASSERT(transferred_used <= int(bytes_transferred));
2738 				received_bytes(0, transferred_used);
2739 				bytes_transferred -= std::size_t(transferred_used);
2740 
2741 				m_recv_buffer.cut(bytes_processed, 4 + 2);
2742 
2743 				// delete verification constant
2744 				m_sync_vc.reset();
2745 				m_state = state_t::read_pe_cryptofield;
2746 				// fall through
2747 			}
2748 		}
2749 
2750 		if (m_state == state_t::read_pe_cryptofield) // local/remote
2751 		{
2752 			TORRENT_ASSERT(!m_encrypted);
2753 			TORRENT_ASSERT(!m_rc4_encrypted);
2754 			TORRENT_ASSERT(m_recv_buffer.packet_size() == 4+2);
2755 			received_bytes(0, int(bytes_transferred));
2756 			bytes_transferred = 0;
2757 
2758 			if (!m_recv_buffer.packet_finished()) return;
2759 
2760 			rc4_decrypt(m_recv_buffer.mutable_buffer().first(
2761 				m_recv_buffer.packet_size()));
2762 
2763 			recv_buffer = m_recv_buffer.get();
2764 
2765 			std::uint32_t crypto_field = aux::read_uint32(recv_buffer);
2766 
2767 #ifndef TORRENT_DISABLE_LOGGING
2768 			peer_log(peer_log_alert::info, "ENCRYPTION", "crypto %s : [%s%s ]"
2769 				, is_outgoing() ? "select" : "provide"
2770 				, (crypto_field & 1) ? " plaintext" : ""
2771 				, (crypto_field & 2) ? " rc4" : "");
2772 #endif
2773 
2774 			if (!is_outgoing())
2775 			{
2776 				// select a crypto method
2777 				int allowed_encryption = m_settings.get_int(settings_pack::allowed_enc_level);
2778 				std::uint32_t crypto_select = crypto_field & std::uint32_t(allowed_encryption);
2779 
2780 				// when prefer_rc4 is set, keep the most significant bit
2781 				// otherwise keep the least significant one
2782 				if (m_settings.get_bool(settings_pack::prefer_rc4))
2783 				{
2784 					std::uint32_t mask = std::numeric_limits<std::uint32_t>::max();
2785 					while (crypto_select & (mask << 1))
2786 					{
2787 						mask <<= 1;
2788 						crypto_select = crypto_select & mask;
2789 					}
2790 				}
2791 				else
2792 				{
2793 					std::uint32_t mask = std::numeric_limits<std::uint32_t>::max();
2794 					while (crypto_select & (mask >> 1))
2795 					{
2796 						mask >>= 1;
2797 						crypto_select = crypto_select & mask;
2798 					}
2799 				}
2800 
2801 				if (crypto_select == 0)
2802 				{
2803 					disconnect(errors::unsupported_encryption_mode, operation_t::encryption, failure);
2804 					return;
2805 				}
2806 
2807 				// write the pe4 step
2808 				write_pe4_sync(aux::numeric_cast<int>(crypto_select));
2809 			}
2810 			else // is_outgoing()
2811 			{
2812 				// check if crypto select is valid
2813 				int allowed_encryption = m_settings.get_int(settings_pack::allowed_enc_level);
2814 
2815 				crypto_field &= std::uint32_t(allowed_encryption);
2816 				if (crypto_field == 0)
2817 				{
2818 					// we don't allow any of the offered encryption levels
2819 					disconnect(errors::unsupported_encryption_mode_selected, operation_t::encryption, peer_error);
2820 					return;
2821 				}
2822 
2823 				if (crypto_field == settings_pack::pe_plaintext)
2824 					m_rc4_encrypted = false;
2825 				else if (crypto_field == settings_pack::pe_rc4)
2826 					m_rc4_encrypted = true;
2827 			}
2828 
2829 			int const len_pad = aux::read_int16(recv_buffer);
2830 			if (len_pad < 0 || len_pad > 512)
2831 			{
2832 				disconnect(errors::invalid_pad_size, operation_t::encryption, peer_error);
2833 				return;
2834 			}
2835 
2836 			m_state = state_t::read_pe_pad;
2837 			if (!is_outgoing())
2838 				m_recv_buffer.reset(len_pad + 2); // len(IA) at the end of pad
2839 			else
2840 			{
2841 				if (len_pad == 0)
2842 				{
2843 					m_encrypted = true;
2844 					if (m_rc4_encrypted)
2845 					{
2846 						switch_send_crypto(m_rc4);
2847 						switch_recv_crypto(m_rc4);
2848 					}
2849 					m_state = state_t::init_bt_handshake;
2850 				}
2851 				else
2852 					m_recv_buffer.reset(len_pad);
2853 			}
2854 		}
2855 
2856 		if (m_state == state_t::read_pe_pad)
2857 		{
2858 			TORRENT_ASSERT(!m_encrypted);
2859 			received_bytes(0, int(bytes_transferred));
2860 			bytes_transferred = 0;
2861 			if (!m_recv_buffer.packet_finished()) return;
2862 
2863 			int const pad_size = is_outgoing() ? m_recv_buffer.packet_size() : m_recv_buffer.packet_size() - 2;
2864 
2865 			rc4_decrypt(m_recv_buffer.mutable_buffer().first(m_recv_buffer.packet_size()));
2866 
2867 			recv_buffer = m_recv_buffer.get();
2868 
2869 			if (!is_outgoing())
2870 			{
2871 				recv_buffer = recv_buffer.subspan(pad_size);
2872 				int const len_ia = aux::read_int16(recv_buffer);
2873 
2874 				if (len_ia < 0)
2875 				{
2876 					disconnect(errors::invalid_encrypt_handshake, operation_t::encryption, peer_error);
2877 					return;
2878 				}
2879 
2880 #ifndef TORRENT_DISABLE_LOGGING
2881 				peer_log(peer_log_alert::info, "ENCRYPTION", "len(IA) : %d", len_ia);
2882 #endif
2883 				if (len_ia == 0)
2884 				{
2885 					// everything after this is Encrypt2
2886 					m_encrypted = true;
2887 					if (m_rc4_encrypted)
2888 					{
2889 						switch_send_crypto(m_rc4);
2890 						switch_recv_crypto(m_rc4);
2891 					}
2892 					m_state = state_t::init_bt_handshake;
2893 				}
2894 				else
2895 				{
2896 					m_state = state_t::read_pe_ia;
2897 					m_recv_buffer.reset(len_ia);
2898 				}
2899 			}
2900 			else // is_outgoing()
2901 			{
2902 				// everything that arrives after this is Encrypt2
2903 				m_encrypted = true;
2904 				if (m_rc4_encrypted)
2905 				{
2906 					switch_send_crypto(m_rc4);
2907 					switch_recv_crypto(m_rc4);
2908 				}
2909 				m_state = state_t::init_bt_handshake;
2910 			}
2911 		}
2912 
2913 		if (m_state == state_t::read_pe_ia)
2914 		{
2915 			received_bytes(0, int(bytes_transferred));
2916 			bytes_transferred = 0;
2917 			TORRENT_ASSERT(!is_outgoing());
2918 			TORRENT_ASSERT(!m_encrypted);
2919 
2920 			if (!m_recv_buffer.packet_finished()) return;
2921 
2922 			// ia is always rc4, so decrypt it
2923 			rc4_decrypt(m_recv_buffer.mutable_buffer().first(m_recv_buffer.packet_size()));
2924 
2925 #ifndef TORRENT_DISABLE_LOGGING
2926 			peer_log(peer_log_alert::info, "ENCRYPTION"
2927 				, "decrypted ia : %d bytes", m_recv_buffer.packet_size());
2928 #endif
2929 
2930 			// everything that arrives after this is encrypted
2931 			m_encrypted = true;
2932 			if (m_rc4_encrypted)
2933 			{
2934 				switch_send_crypto(m_rc4);
2935 				switch_recv_crypto(m_rc4);
2936 			}
2937 			m_rc4.reset();
2938 
2939 			m_state = state_t::read_protocol_identifier;
2940 			m_recv_buffer.cut(0, 20);
2941 		}
2942 
2943 		if (m_state == state_t::init_bt_handshake)
2944 		{
2945 			received_bytes(0, int(bytes_transferred));
2946 			bytes_transferred = 0;
2947 			TORRENT_ASSERT(m_encrypted);
2948 
2949 			// decrypt remaining received bytes
2950 			if (m_rc4_encrypted)
2951 			{
2952 				span<char> const remaining = m_recv_buffer.mutable_buffer()
2953 					.subspan(m_recv_buffer.packet_size());
2954 				rc4_decrypt(remaining);
2955 
2956 #ifndef TORRENT_DISABLE_LOGGING
2957 				peer_log(peer_log_alert::info, "ENCRYPTION"
2958 					, "decrypted remaining %d bytes", int(remaining.size()));
2959 #endif
2960 			}
2961 			m_rc4.reset();
2962 
2963 			// payload stream, start with 20 handshake bytes
2964 			m_state = state_t::read_protocol_identifier;
2965 			m_recv_buffer.reset(20);
2966 
2967 			// encrypted portion of handshake completed, toggle
2968 			// peer_info pe_support flag back to true
2969 			if (is_outgoing() &&
2970 				m_settings.get_int(settings_pack::out_enc_policy)
2971 					== settings_pack::pe_enabled)
2972 			{
2973 				torrent_peer* pi = peer_info_struct();
2974 				TORRENT_ASSERT(pi);
2975 
2976 				pi->pe_support = true;
2977 			}
2978 		}
2979 
2980 #endif // #if !defined TORRENT_DISABLE_ENCRYPTION
2981 
2982 		if (m_state == state_t::read_protocol_identifier)
2983 		{
2984 			received_bytes(0, int(bytes_transferred));
2985 			bytes_transferred = 0;
2986 			TORRENT_ASSERT(m_recv_buffer.packet_size() == 20);
2987 
2988 			if (!m_recv_buffer.packet_finished()) return;
2989 			recv_buffer = m_recv_buffer.get();
2990 
2991 			int const packet_size = recv_buffer[0];
2992 			static const char protocol_string[] = "\x13" "BitTorrent protocol";
2993 
2994 			if (packet_size != 19 ||
2995 				recv_buffer.first(20) != span<char const>{protocol_string, 20})
2996 			{
2997 #if !defined TORRENT_DISABLE_ENCRYPTION
2998 #ifndef TORRENT_DISABLE_LOGGING
2999 				peer_log(peer_log_alert::info, "ENCRYPTION"
3000 					, "unrecognized protocol header");
3001 #endif
3002 
3003 #ifdef TORRENT_USE_OPENSSL
3004 				if (is_ssl(*get_socket()))
3005 				{
3006 #ifndef TORRENT_DISABLE_LOGGING
3007 					peer_log(peer_log_alert::info, "ENCRYPTION"
3008 						, "SSL peers are not allowed to use any other encryption");
3009 #endif
3010 					disconnect(errors::invalid_info_hash, operation_t::bittorrent, failure);
3011 					return;
3012 				}
3013 #endif // TORRENT_USE_OPENSSL
3014 
3015 				if (!is_outgoing()
3016 					&& m_settings.get_int(settings_pack::in_enc_policy)
3017 						== settings_pack::pe_disabled)
3018 				{
3019 					disconnect(errors::no_incoming_encrypted, operation_t::bittorrent);
3020 					return;
3021 				}
3022 
3023 				// Don't attempt to perform an encrypted handshake
3024 				// within an encrypted connection. For local connections,
3025 				// we're expected to already have passed the encrypted
3026 				// handshake by this point
3027 				if (m_encrypted || is_outgoing())
3028 				{
3029 					disconnect(errors::invalid_info_hash, operation_t::bittorrent, failure);
3030 					return;
3031 				}
3032 
3033 #ifndef TORRENT_DISABLE_LOGGING
3034 				peer_log(peer_log_alert::info, "ENCRYPTION", "attempting encrypted connection");
3035 #endif
3036 				m_state = state_t::read_pe_dhkey;
3037 				m_recv_buffer.cut(0, dh_key_len);
3038 				TORRENT_ASSERT(!m_recv_buffer.packet_finished());
3039 				return;
3040 #else
3041 				disconnect(errors::invalid_info_hash, operation_t::bittorrent, failure);
3042 				return;
3043 #endif // TORRENT_DISABLE_ENCRYPTION
3044 			}
3045 			else
3046 			{
3047 #if !defined TORRENT_DISABLE_ENCRYPTION
3048 				TORRENT_ASSERT(m_state != state_t::read_pe_dhkey);
3049 
3050 				if (!is_outgoing()
3051 					&& m_settings.get_int(settings_pack::in_enc_policy)
3052 						== settings_pack::pe_forced
3053 					&& !m_encrypted
3054 					&& !is_ssl(*get_socket()))
3055 				{
3056 					disconnect(errors::no_incoming_regular, operation_t::bittorrent);
3057 					return;
3058 				}
3059 #endif
3060 
3061 #ifndef TORRENT_DISABLE_LOGGING
3062 				peer_log(peer_log_alert::incoming_message, "HANDSHAKE", "BitTorrent protocol");
3063 #endif
3064 			}
3065 
3066 			m_state = state_t::read_info_hash;
3067 			m_recv_buffer.reset(28);
3068 		}
3069 
3070 		// fall through
3071 		if (m_state == state_t::read_info_hash)
3072 		{
3073 			received_bytes(0, int(bytes_transferred));
3074 			bytes_transferred = 0;
3075 			TORRENT_ASSERT(m_recv_buffer.packet_size() == 28);
3076 
3077 			if (!m_recv_buffer.packet_finished()) return;
3078 			recv_buffer = m_recv_buffer.get();
3079 
3080 #ifndef TORRENT_DISABLE_LOGGING
3081 			std::string extensions;
3082 			extensions.reserve(8 * 8);
3083 			for (int i = 0; i < 8; ++i)
3084 				for (int j = 0; j < 8; ++j)
3085 					extensions += (recv_buffer[i] & (0x80 >> j)) ? '1' : '0';
3086 
3087 			if (should_log(peer_log_alert::incoming_message))
3088 			{
3089 				peer_log(peer_log_alert::incoming_message, "EXTENSIONS", "%s ext: %s%s%s"
3090 					, extensions.c_str()
3091 					, (recv_buffer[7] & 0x01) ? "DHT " : ""
3092 					, (recv_buffer[7] & 0x04) ? "FAST " : ""
3093 					, (recv_buffer[5] & 0x10) ? "extension " : "");
3094 			}
3095 #endif
3096 
3097 			std::memcpy(m_reserved_bits.data(), recv_buffer.data(), 8);
3098 			if (recv_buffer[5] & 0x10)
3099 				m_supports_extensions = true;
3100 
3101 			if (recv_buffer[7] & 0x01)
3102 				m_supports_dht_port = true;
3103 
3104 			if (recv_buffer[7] & 0x04)
3105 				m_supports_fast = true;
3106 
3107 			t = associated_torrent().lock();
3108 
3109 			// ok, now we have got enough of the handshake. Is this connection
3110 			// attached to a torrent?
3111 			if (!t)
3112 			{
3113 				// now, we have to see if there's a torrent with the
3114 				// info_hash we got from the peer
3115 				sha1_hash info_hash;
3116 				std::copy(recv_buffer.begin() + 8, recv_buffer.begin() + 28
3117 					, info_hash.data());
3118 
3119 				attach_to_torrent(info_hash);
3120 				if (is_disconnecting()) return;
3121 			}
3122 			else
3123 			{
3124 				// verify info hash
3125 				if (!std::equal(recv_buffer.begin() + 8, recv_buffer.begin() + 28
3126 					, t->torrent_file().info_hash().data()))
3127 				{
3128 #ifndef TORRENT_DISABLE_LOGGING
3129 					peer_log(peer_log_alert::info, "ERROR", "received invalid info_hash");
3130 #endif
3131 					disconnect(errors::invalid_info_hash, operation_t::bittorrent, failure);
3132 					return;
3133 				}
3134 
3135 #ifndef TORRENT_DISABLE_LOGGING
3136 				peer_log(peer_log_alert::incoming, "HANDSHAKE", "info_hash received");
3137 #endif
3138 			}
3139 
3140 			t = associated_torrent().lock();
3141 			TORRENT_ASSERT(t);
3142 
3143 			// if this is a local connection, we have already
3144 			// sent the handshake
3145 			if (!is_outgoing()) write_handshake();
3146 			TORRENT_ASSERT(m_sent_handshake);
3147 
3148 			if (is_disconnecting()) return;
3149 
3150 			m_state = state_t::read_peer_id;
3151 			m_recv_buffer.reset(20);
3152 		}
3153 
3154 		// fall through
3155 		if (m_state == state_t::read_peer_id)
3156 		{
3157 			TORRENT_ASSERT(m_sent_handshake);
3158 			received_bytes(0, int(bytes_transferred));
3159 
3160 			t = associated_torrent().lock();
3161 			if (!t)
3162 			{
3163 				TORRENT_ASSERT(!m_recv_buffer.packet_finished()); // TODO
3164 				return;
3165 			}
3166 			TORRENT_ASSERT(m_recv_buffer.packet_size() == 20);
3167 
3168 			if (!m_recv_buffer.packet_finished()) return;
3169 			recv_buffer = m_recv_buffer.get();
3170 
3171 #ifndef TORRENT_DISABLE_LOGGING
3172 			if (should_log(peer_log_alert::incoming))
3173 			{
3174 				char hex_pid[41];
3175 				aux::to_hex({recv_buffer.data(), 20}, hex_pid);
3176 				hex_pid[40] = 0;
3177 				char ascii_pid[21];
3178 				ascii_pid[20] = 0;
3179 				for (int i = 0; i != 20; ++i)
3180 					ascii_pid[i] = (is_print(recv_buffer[i])) ? recv_buffer[i] : '.';
3181 
3182 				peer_log(peer_log_alert::incoming, "HANDSHAKE", "received peer_id: %s client: %s ascii: \"%s\""
3183 					, hex_pid, identify_client(peer_id(recv_buffer.data())).c_str(), ascii_pid);
3184 			}
3185 #endif
3186 			peer_id pid;
3187 			std::copy(recv_buffer.begin(), recv_buffer.begin() + 20, pid.data());
3188 
3189 			// now, let's see if this connection should be closed
3190 			peer_connection* p = t->find_peer(pid);
3191 			if (p)
3192 			{
3193 				TORRENT_ASSERT(p->pid() == pid);
3194 				// we found another connection with the same peer-id
3195 				// which connection should be closed in order to be
3196 				// sure that the other end closes the same connection?
3197 				// the peer with greatest peer-id is the one allowed to
3198 				// initiate connections. So, if our peer-id is greater than
3199 				// the others, we should close the incoming connection,
3200 				// if not, we should close the outgoing one.
3201 				if ((pid < m_our_peer_id) == is_outgoing())
3202 				{
3203 					p->disconnect(errors::duplicate_peer_id, operation_t::bittorrent);
3204 				}
3205 				else
3206 				{
3207 					disconnect(errors::duplicate_peer_id, operation_t::bittorrent);
3208 					return;
3209 				}
3210 			}
3211 
3212 			set_pid(pid);
3213 			m_client_version = identify_client(pid);
3214 			if (pid[0] == '-' && pid[1] == 'B' && pid[2] == 'C' && pid[7] == '-')
3215 			{
3216 				// if this is a bitcomet client, lower the request queue size limit
3217 				if (max_out_request_queue() > 50) max_out_request_queue(50);
3218 			}
3219 
3220 			if (t->is_self_connection(pid))
3221 			{
3222 				disconnect(errors::self_connection, operation_t::bittorrent);
3223 				return;
3224 			}
3225 
3226 #ifndef TORRENT_DISABLE_EXTENSIONS
3227 			for (auto i = m_extensions.begin()
3228 				, end(m_extensions.end()); i != end;)
3229 			{
3230 				if (!(*i)->on_handshake(m_reserved_bits))
3231 				{
3232 					i = m_extensions.erase(i);
3233 				}
3234 				else
3235 				{
3236 					++i;
3237 				}
3238 			}
3239 			if (is_disconnecting()) return;
3240 #endif
3241 
3242 			if (m_supports_extensions) write_extensions();
3243 
3244 #ifndef TORRENT_DISABLE_LOGGING
3245 			peer_log(peer_log_alert::incoming_message, "HANDSHAKE", "connection ready");
3246 #endif
3247 			// consider this a successful connection, reset the failcount
3248 			if (peer_info_struct())
3249 				t->clear_failcount(peer_info_struct());
3250 
3251 #if !defined TORRENT_DISABLE_ENCRYPTION
3252 			// Toggle pe_support back to false if this is a
3253 			// standard successful connection
3254 			if (is_outgoing() && !m_encrypted &&
3255 				m_settings.get_int(settings_pack::out_enc_policy)
3256 					== settings_pack::pe_enabled)
3257 			{
3258 				torrent_peer* pi = peer_info_struct();
3259 				TORRENT_ASSERT(pi);
3260 
3261 				pi->pe_support = false;
3262 			}
3263 #endif
3264 
3265 			// complete the handshake
3266 			// we don't know how many pieces there are until we
3267 			// have the metadata
3268 			if (t->ready_for_connections())
3269 			{
3270 				write_bitfield();
3271 				write_dht_port();
3272 
3273 				// if we don't have any pieces, don't do any preemptive
3274 				// unchoking at all.
3275 				if (t->num_have() > 0)
3276 				{
3277 					// if the peer is ignoring unchoke slots, or if we have enough
3278 					// unused slots, unchoke this peer right away, to save a round-trip
3279 					// in case it's interested.
3280 					maybe_unchoke_this_peer();
3281 				}
3282 			}
3283 
3284 			m_state = state_t::read_packet_size;
3285 			m_recv_buffer.reset(5);
3286 
3287 			TORRENT_ASSERT(!m_recv_buffer.packet_finished());
3288 			return;
3289 		}
3290 
3291 		// cannot fall through into
3292 		if (m_state == state_t::read_packet_size)
3293 		{
3294 			// Make sure this is not fallen though into
3295 			TORRENT_ASSERT(recv_buffer.data() == m_recv_buffer.get().data());
3296 			TORRENT_ASSERT(recv_buffer.size() == m_recv_buffer.get().size());
3297 			TORRENT_ASSERT(m_recv_buffer.packet_size() == 5);
3298 
3299 			if (!t) return;
3300 
3301 			// the 5th byte (if one) should not count as protocol
3302 			// byte here, instead it's counted in the message
3303 			// handler itself, for the specific message
3304 			TORRENT_ASSERT(bytes_transferred <= 5);
3305 			int used_bytes = int(recv_buffer.size()) > 4 ? int(bytes_transferred) - 1: int(bytes_transferred);
3306 			received_bytes(0, used_bytes);
3307 			bytes_transferred -= aux::numeric_cast<std::size_t>(used_bytes);
3308 			if (int(recv_buffer.size()) < 4) return;
3309 
3310 			TORRENT_ASSERT(bytes_transferred <= 1);
3311 
3312 			const char* ptr = recv_buffer.data();
3313 			int const packet_size = detail::read_int32(ptr);
3314 
3315 			// don't accept packets larger than 1 MB
3316 			if (packet_size > 1024 * 1024 || packet_size < 0)
3317 			{
3318 				// packet too large
3319 				received_bytes(0, int(bytes_transferred));
3320 				disconnect(errors::packet_too_large, operation_t::bittorrent, peer_error);
3321 				return;
3322 			}
3323 
3324 			if (packet_size == 0)
3325 			{
3326 				TORRENT_ASSERT(bytes_transferred <= 1);
3327 				received_bytes(0, int(bytes_transferred));
3328 				incoming_keepalive();
3329 				if (is_disconnecting()) return;
3330 				// keepalive message
3331 				m_state = state_t::read_packet_size;
3332 				m_recv_buffer.cut(4, 5);
3333 				return;
3334 			}
3335 			if (int(recv_buffer.size()) < 5) return;
3336 
3337 			m_state = state_t::read_packet;
3338 			m_recv_buffer.cut(4, packet_size);
3339 			recv_buffer = m_recv_buffer.get();
3340 			TORRENT_ASSERT(int(recv_buffer.size()) == 1);
3341 			TORRENT_ASSERT(bytes_transferred == 1);
3342 		}
3343 
3344 		if (m_state == state_t::read_packet)
3345 		{
3346 			TORRENT_ASSERT(recv_buffer.data() == m_recv_buffer.get().data());
3347 			TORRENT_ASSERT(recv_buffer.size() == m_recv_buffer.get().size());
3348 			if (!t)
3349 			{
3350 				received_bytes(0, int(bytes_transferred));
3351 				disconnect(errors::torrent_removed, operation_t::bittorrent, failure);
3352 				return;
3353 			}
3354 #if TORRENT_USE_ASSERTS
3355 			std::int64_t const cur_payload_dl = statistics().last_payload_downloaded();
3356 			std::int64_t const cur_protocol_dl = statistics().last_protocol_downloaded();
3357 #endif
3358 			if (dispatch_message(int(bytes_transferred)))
3359 			{
3360 				m_state = state_t::read_packet_size;
3361 				m_recv_buffer.reset(5);
3362 			}
3363 
3364 #if TORRENT_USE_ASSERTS
3365 			TORRENT_ASSERT(statistics().last_payload_downloaded() - cur_payload_dl >= 0);
3366 			TORRENT_ASSERT(statistics().last_protocol_downloaded() - cur_protocol_dl >= 0);
3367 			std::int64_t const stats_diff = statistics().last_payload_downloaded() - cur_payload_dl +
3368 				statistics().last_protocol_downloaded() - cur_protocol_dl;
3369 			TORRENT_ASSERT(stats_diff == std::int64_t(bytes_transferred));
3370 			TORRENT_ASSERT(!m_recv_buffer.packet_finished());
3371 #endif
3372 			return;
3373 		}
3374 
3375 		TORRENT_ASSERT(!m_recv_buffer.packet_finished());
3376 	}
3377 
3378 #if !defined TORRENT_DISABLE_ENCRYPTION
3379 	std::tuple<int, span<span<char const>>>
hit_send_barrier(span<span<char>> iovec)3380 	bt_peer_connection::hit_send_barrier(
3381 		span<span<char>> iovec)
3382 	{
3383 		int next_barrier;
3384 		span<span<char const>> out_iovec;
3385 		std::tie(next_barrier, out_iovec) = m_enc_handler.encrypt(iovec);
3386 #ifndef TORRENT_DISABLE_LOGGING
3387 		if (next_barrier != 0)
3388 			peer_log(peer_log_alert::outgoing, "SEND_BARRIER"
3389 				, "encrypted block s = %d", next_barrier);
3390 #endif
3391 		return std::make_tuple(next_barrier, out_iovec);
3392 	}
3393 #endif
3394 
3395 	// --------------------------
3396 	// SEND DATA
3397 	// --------------------------
3398 
on_sent(error_code const & error,std::size_t const bytes_transferred)3399 	void bt_peer_connection::on_sent(error_code const& error
3400 		, std::size_t const bytes_transferred)
3401 	{
3402 		INVARIANT_CHECK;
3403 
3404 		if (error)
3405 		{
3406 			sent_bytes(0, int(bytes_transferred));
3407 			return;
3408 		}
3409 
3410 		// manage the payload markers
3411 		int amount_payload = 0;
3412 		if (!m_payloads.empty())
3413 		{
3414 			// this points to the first entry to not erase. i.e.
3415 			// [begin, first_to_keep) will be erased because
3416 			// the payload ranges they represent have been sent
3417 			auto first_to_keep = m_payloads.begin();
3418 
3419 			for (auto i = m_payloads.begin(); i != m_payloads.end(); ++i)
3420 			{
3421 				i->start -= int(bytes_transferred);
3422 				if (i->start < 0)
3423 				{
3424 					if (i->start + i->length <= 0)
3425 					{
3426 						amount_payload += i->length;
3427 						TORRENT_ASSERT(first_to_keep == i);
3428 						++first_to_keep;
3429 					}
3430 					else
3431 					{
3432 						amount_payload += -i->start;
3433 						i->length -= -i->start;
3434 						i->start = 0;
3435 					}
3436 				}
3437 			}
3438 
3439 			// remove all payload ranges that have been sent
3440 			m_payloads.erase(m_payloads.begin(), first_to_keep);
3441 		}
3442 
3443 		TORRENT_ASSERT(amount_payload <= int(bytes_transferred));
3444 		sent_bytes(amount_payload, int(bytes_transferred) - amount_payload);
3445 
3446 		if (amount_payload > 0)
3447 		{
3448 			std::shared_ptr<torrent> t = associated_torrent().lock();
3449 			TORRENT_ASSERT(t);
3450 			if (t) t->update_last_upload();
3451 		}
3452 	}
3453 
3454 #if TORRENT_USE_INVARIANT_CHECKS
check_invariant() const3455 	void bt_peer_connection::check_invariant() const
3456 	{
3457 		std::shared_ptr<torrent> t = associated_torrent().lock();
3458 
3459 #if !defined TORRENT_DISABLE_ENCRYPTION
3460 		TORRENT_ASSERT( (bool(m_state != state_t::read_pe_dhkey) || m_dh_key_exchange.get())
3461 				|| !is_outgoing());
3462 
3463 		TORRENT_ASSERT(!m_rc4_encrypted || (!m_encrypted && m_rc4)
3464 			|| (m_encrypted && !m_enc_handler.is_send_plaintext()));
3465 #endif
3466 		if (!in_handshake())
3467 		{
3468 			TORRENT_ASSERT(m_sent_handshake);
3469 		}
3470 
3471 		if (!m_payloads.empty())
3472 		{
3473 			for (std::vector<range>::const_iterator i = m_payloads.begin();
3474 				i != m_payloads.end() - 1; ++i)
3475 			{
3476 				TORRENT_ASSERT(i->start + i->length <= (i+1)->start);
3477 			}
3478 		}
3479 	}
3480 #endif
3481 
3482 }
3483