Skip to content

Commit 61ab0eb

Browse files
committed
merged RC_2_0 into master
2 parents 2485348 + 07a5305 commit 61ab0eb

File tree

6 files changed

+91
-82
lines changed

6 files changed

+91
-82
lines changed

CMakeLists.txt

+5-2
Original file line numberDiff line numberDiff line change
@@ -660,18 +660,21 @@ if (NOT Windows)
660660
return 0;
661661
}
662662
]=])
663+
string(REPLACE "std::atomic<int>" "std::atomic<std::int8_t>" ATOMICS8_TEST_SOURCE "${ATOMICS_TEST_SOURCE}")
663664
string(REPLACE "std::atomic<int>" "std::atomic<std::int64_t>" ATOMICS64_TEST_SOURCE "${ATOMICS_TEST_SOURCE}")
664665

665666
if(APPLE)
666667
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
667668
endif()
668669
check_cxx_source_compiles("${ATOMICS_TEST_SOURCE}" HAVE_CXX_ATOMICS_WITHOUT_LIB)
670+
check_cxx_source_compiles("${ATOMICS8_TEST_SOURCE}" HAVE_CXX_ATOMICS8_WITHOUT_LIB)
669671
check_cxx_source_compiles("${ATOMICS64_TEST_SOURCE}" HAVE_CXX_ATOMICS64_WITHOUT_LIB)
670-
if((NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) OR (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB))
672+
if((NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) OR (NOT HAVE_CXX_ATOMICS8_WITHOUT_LIB) OR (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB))
671673
set(CMAKE_REQUIRED_LIBRARIES "atomic")
672674
check_cxx_source_compiles("${ATOMICS_TEST_SOURCE}" HAVE_CXX_ATOMICS_WITH_LIB)
675+
check_cxx_source_compiles("${ATOMICS8_TEST_SOURCE}" HAVE_CXX_ATOMICS8_WITH_LIB)
673676
check_cxx_source_compiles("${ATOMICS64_TEST_SOURCE}" HAVE_CXX_ATOMICS64_WITH_LIB)
674-
if ((NOT HAVE_CXX_ATOMICS_WITH_LIB) OR (NOT HAVE_CXX_ATOMICS64_WITH_LIB))
677+
if ((NOT HAVE_CXX_ATOMICS_WITH_LIB) OR (NOT HAVE_CXX_ATOMICS8_WITH_LIB) OR (NOT HAVE_CXX_ATOMICS64_WITH_LIB))
675678
message(STATUS, "No native support for std::atomic, or libatomic not found! Build link step may fail")
676679
else()
677680
message(STATUS "Linking with libatomic for atomics support")

Jamfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,7 @@ rule linking ( properties * )
156156
result += <framework>CoreFoundation <framework>SystemConfiguration ;
157157
}
158158

159-
if ( <toolset>gcc in $(properties)
160-
|| <toolset>clang in $(properties) )
159+
if <toolset>gcc in $(properties)
161160
&& <target-os>linux in $(properties)
162161
&& ( <asserts>on in $(properties)
163162
|| <asserts>production in $(properties)

include/libtorrent/aux_/bt_peer_connection.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ namespace libtorrent::aux {
341341

342342
private:
343343

344+
#if !defined TORRENT_DISABLE_ENCRYPTION
345+
void init_bt_handshake();
346+
#endif
347+
344348
enum class state_t : std::uint8_t
345349
{
346350
#if !defined TORRENT_DISABLE_ENCRYPTION
@@ -351,7 +355,6 @@ namespace libtorrent::aux {
351355
read_pe_cryptofield,
352356
read_pe_pad,
353357
read_pe_ia,
354-
init_bt_handshake,
355358
#endif
356359
read_protocol_identifier,
357360
read_info_hash,

include/libtorrent/aux_/pe_crypto.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ namespace libtorrent::aux {
5151
{
5252
public:
5353
dh_key_exchange();
54-
bool good() const { return true; }
5554

5655
// Get local public key
5756
key_t const& get_local_key() const { return m_dh_local_key; }

include/libtorrent/aux_/torrent_list.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ struct torrent_list
211211
#endif
212212

213213
TORRENT_ASSERT(all_torrents == all_indexed_torrents);
214+
#if !defined TORRENT_DISABLE_ENCRYPTION
214215
TORRENT_ASSERT(all_torrents == all_obf_indexed_torrents);
216+
#endif
215217
}
216218
#endif
217219

src/bt_peer_connection.cpp

+79-76
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ namespace {
512512
#endif
513513

514514
m_dh_key_exchange.reset(new (std::nothrow) dh_key_exchange);
515-
if (!m_dh_key_exchange || !m_dh_key_exchange->good())
515+
if (!m_dh_key_exchange)
516516
{
517517
disconnect(errors::no_memory, operation_t::encryption);
518518
return;
@@ -2714,6 +2714,44 @@ namespace {
27142714
on_receive_impl(bytes_transferred);
27152715
}
27162716

2717+
#if !defined TORRENT_DISABLE_ENCRYPTION
2718+
void bt_peer_connection::init_bt_handshake()
2719+
{
2720+
m_encrypted = true;
2721+
if (m_rc4_encrypted)
2722+
{
2723+
switch_send_crypto(m_rc4);
2724+
switch_recv_crypto(m_rc4);
2725+
}
2726+
2727+
// decrypt remaining received bytes
2728+
if (m_rc4_encrypted)
2729+
{
2730+
span<char> const remaining = m_recv_buffer.mutable_buffer()
2731+
.subspan(m_recv_buffer.packet_size());
2732+
rc4_decrypt(remaining);
2733+
2734+
#ifndef TORRENT_DISABLE_LOGGING
2735+
peer_log(peer_log_alert::info, "ENCRYPTION"
2736+
, "decrypted remaining %d bytes", int(remaining.size()));
2737+
#endif
2738+
}
2739+
m_rc4.reset();
2740+
2741+
// encrypted portion of handshake completed, toggle
2742+
// peer_info pe_support flag back to true
2743+
if (is_outgoing() &&
2744+
m_settings.get_int(settings_pack::out_enc_policy)
2745+
== settings_pack::pe_enabled)
2746+
{
2747+
torrent_peer* pi = peer_info_struct();
2748+
TORRENT_ASSERT(pi);
2749+
2750+
pi->pe_support = true;
2751+
}
2752+
}
2753+
#endif
2754+
27172755
void bt_peer_connection::on_receive_impl(std::size_t bytes_transferred)
27182756
{
27192757
auto t = associated_torrent().lock();
@@ -3104,30 +3142,28 @@ namespace {
31043142
m_rc4_encrypted = true;
31053143
}
31063144

3107-
int const len_pad = aux::read_int16(recv_buffer);
3145+
int len_pad = aux::read_int16(recv_buffer);
31083146
if (len_pad < 0 || len_pad > 512)
31093147
{
31103148
disconnect(errors::invalid_pad_size, operation_t::encryption, peer_error);
31113149
return;
31123150
}
31133151

3114-
m_state = state_t::read_pe_pad;
3152+
// len(IA) at the end of pad
31153153
if (!is_outgoing())
3116-
m_recv_buffer.reset(len_pad + 2); // len(IA) at the end of pad
3154+
len_pad += 2;
3155+
3156+
if (len_pad > 0)
3157+
{
3158+
m_state = state_t::read_pe_pad;
3159+
m_recv_buffer.reset(len_pad);
3160+
}
31173161
else
31183162
{
3119-
if (len_pad == 0)
3120-
{
3121-
m_encrypted = true;
3122-
if (m_rc4_encrypted)
3123-
{
3124-
switch_send_crypto(m_rc4);
3125-
switch_recv_crypto(m_rc4);
3126-
}
3127-
m_state = state_t::init_bt_handshake;
3128-
}
3129-
else
3130-
m_recv_buffer.reset(len_pad);
3163+
TORRENT_ASSERT(len_pad == 0);
3164+
init_bt_handshake();
3165+
m_state = state_t::read_protocol_identifier;
3166+
m_recv_buffer.reset(20);
31313167
}
31323168
}
31333169

@@ -3149,55 +3185,51 @@ namespace {
31493185
recv_buffer = recv_buffer.subspan(pad_size);
31503186
int const len_ia = aux::read_int16(recv_buffer);
31513187

3152-
if (len_ia < 0)
3188+
#ifndef TORRENT_DISABLE_LOGGING
3189+
peer_log(peer_log_alert::info, "ENCRYPTION", "len(IA) : %d", len_ia);
3190+
#endif
3191+
if (len_ia < 0 || len_ia > 68)
31533192
{
31543193
disconnect(errors::invalid_encrypt_handshake, operation_t::encryption, peer_error);
31553194
return;
31563195
}
31573196

3158-
#ifndef TORRENT_DISABLE_LOGGING
3159-
peer_log(peer_log_alert::info, "ENCRYPTION", "len(IA) : %d", len_ia);
3160-
#endif
31613197
if (len_ia == 0)
31623198
{
3163-
// everything after this is Encrypt2
3164-
m_encrypted = true;
3165-
if (m_rc4_encrypted)
3166-
{
3167-
switch_send_crypto(m_rc4);
3168-
switch_recv_crypto(m_rc4);
3169-
}
3170-
m_state = state_t::init_bt_handshake;
3199+
// everything after this is encrypted
3200+
init_bt_handshake();
3201+
m_state = state_t::read_protocol_identifier;
3202+
m_recv_buffer.reset(20);
31713203
}
31723204
else
31733205
{
3206+
// The other peer indicated that a non-zero bytes will be
3207+
// encrypted at the start of the underlying bittorrent
3208+
// protocol. This number of bytes, len_ia, is not
3209+
// necessarily aligned to message boundaries. We first read
3210+
// that many bytes, decrypt it, and then pass it back into
3211+
// the regular protocol parser
31743212
m_state = state_t::read_pe_ia;
31753213
m_recv_buffer.reset(len_ia);
31763214
}
31773215
}
31783216
else // is_outgoing()
31793217
{
3180-
// everything that arrives after this is Encrypt2
3181-
m_encrypted = true;
3182-
if (m_rc4_encrypted)
3183-
{
3184-
switch_send_crypto(m_rc4);
3185-
switch_recv_crypto(m_rc4);
3186-
}
3187-
m_state = state_t::init_bt_handshake;
3218+
// everything that arrives after this is encrypted
3219+
init_bt_handshake();
3220+
m_state = state_t::read_protocol_identifier;
3221+
m_recv_buffer.reset(20);
31883222
}
31893223
}
31903224

31913225
if (m_state == state_t::read_pe_ia)
31923226
{
3193-
received_bytes(0, int(bytes_transferred));
3194-
bytes_transferred = 0;
31953227
TORRENT_ASSERT(!is_outgoing());
31963228
TORRENT_ASSERT(!m_encrypted);
31973229

31983230
if (!m_recv_buffer.packet_finished()) return;
31993231

3200-
// ia is always rc4, so decrypt it
3232+
// the IA bytes are always rc4, so decrypt it
32013233
rc4_decrypt(m_recv_buffer.mutable_buffer().first(m_recv_buffer.packet_size()));
32023234

32033235
#ifndef TORRENT_DISABLE_LOGGING
@@ -3214,47 +3246,14 @@ namespace {
32143246
}
32153247
m_rc4.reset();
32163248

3249+
// now that we have decrypted IA length of bytes, we
3250+
// reinterpret the receive buffer as the very start of a normal
3251+
// connection. First we expect to find the protocol identifier
3252+
// (i.e. "BitTorrent Protocol")
32173253
m_state = state_t::read_protocol_identifier;
32183254
m_recv_buffer.cut(0, 20);
32193255
}
32203256

3221-
if (m_state == state_t::init_bt_handshake)
3222-
{
3223-
received_bytes(0, int(bytes_transferred));
3224-
bytes_transferred = 0;
3225-
TORRENT_ASSERT(m_encrypted);
3226-
3227-
// decrypt remaining received bytes
3228-
if (m_rc4_encrypted)
3229-
{
3230-
span<char> const remaining = m_recv_buffer.mutable_buffer()
3231-
.subspan(m_recv_buffer.packet_size());
3232-
rc4_decrypt(remaining);
3233-
3234-
#ifndef TORRENT_DISABLE_LOGGING
3235-
peer_log(peer_log_alert::info, "ENCRYPTION"
3236-
, "decrypted remaining %d bytes", int(remaining.size()));
3237-
#endif
3238-
}
3239-
m_rc4.reset();
3240-
3241-
// payload stream, start with 20 handshake bytes
3242-
m_state = state_t::read_protocol_identifier;
3243-
m_recv_buffer.reset(20);
3244-
3245-
// encrypted portion of handshake completed, toggle
3246-
// peer_info pe_support flag back to true
3247-
if (is_outgoing() &&
3248-
m_settings.get_int(settings_pack::out_enc_policy)
3249-
== settings_pack::pe_enabled)
3250-
{
3251-
torrent_peer* pi = peer_info_struct();
3252-
TORRENT_ASSERT(pi);
3253-
3254-
pi->pe_support = true;
3255-
}
3256-
}
3257-
32583257
#endif // #if !defined TORRENT_DISABLE_ENCRYPTION
32593258

32603259
if (m_state == state_t::read_protocol_identifier)
@@ -3312,6 +3311,10 @@ namespace {
33123311
peer_log(peer_log_alert::info, "ENCRYPTION", "attempting encrypted connection");
33133312
#endif
33143313
m_state = state_t::read_pe_dhkey;
3314+
// we're "cutting" off 0 bytes from the receive buffer here
3315+
// because we want to interpret it as something else. It didn't
3316+
// contain the expected bittorrent handshake string, so let's
3317+
// try again to interpret it as an encrypted handshake
33153318
m_recv_buffer.cut(0, dh_key_len);
33163319
TORRENT_ASSERT(!m_recv_buffer.packet_finished());
33173320
return;

0 commit comments

Comments
 (0)