diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index 1378c897f..96d8e3cde 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -289,7 +289,7 @@ namespace libtorrent { int tmp[] = {0, (detail::write_int32(args, ptr), 0)...}; TORRENT_UNUSED(tmp); - send_buffer(msg, sizeof(msg), flags); + send_buffer(msg, flags); stats_counters().inc_stats_counter(counter); } @@ -318,8 +318,8 @@ namespace libtorrent { void write_pe3_sync(); void write_pe4_sync(int crypto_select); - void write_pe_vc_cryptofield(char* write_buf, int len - , int crypto_field, int pad_size); + void write_pe_vc_cryptofield(span write_buf + , int crypto_field, std::size_t pad_size); // Returns offset at which bytestream (src, src + src_size) // matches bytestream(target, target + target_size). diff --git a/include/libtorrent/chained_buffer.hpp b/include/libtorrent/chained_buffer.hpp index 950a4e580..ec053d627 100644 --- a/include/libtorrent/chained_buffer.hpp +++ b/include/libtorrent/chained_buffer.hpp @@ -153,7 +153,7 @@ namespace libtorrent { // tries to copy the given buffer to the end of the // last chained buffer. If there's not enough room // it returns nullptr - char* append(char const* buf, int s); + char* append(span buf); // tries to allocate memory from the end // of the last buffer. If there isn't diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 469322fbc..c0d7a09b3 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -620,7 +620,7 @@ namespace aux { virtual piece_block_progress downloading_piece_progress() const; enum message_type_flags { message_type_request = 1 }; - void send_buffer(char const* begin, int size, std::uint32_t flags = 0); + void send_buffer(span buf, std::uint32_t flags = 0); void setup_send(); template diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 9c58507e5..c3b00f576 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -78,13 +78,10 @@ namespace libtorrent { namespace mp = boost::multiprecision; #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) - namespace { +namespace { - enum - { - handshake_len = 68, - dh_key_len = 96 - }; + std::size_t const handshake_len = 68; + std::size_t const dh_key_len = 96; // stream key (info hash of attached torrent) // secret is the DH shared secret @@ -126,7 +123,7 @@ namespace libtorrent { return ret; } - } // anonymous namespace +} // anonymous namespace #endif #ifndef TORRENT_DISABLE_EXTENSIONS @@ -353,7 +350,7 @@ namespace libtorrent { char msg[] = {0,0,0,3, msg_dht_port, 0, 0}; char* ptr = msg + 5; detail::write_uint16(listen_port, ptr); - send_buffer(msg, sizeof(msg)); + send_buffer(msg); stats_counters().inc_stats_counter(counters::num_outgoing_dht_port); } @@ -502,22 +499,22 @@ namespace libtorrent { return; } - int const pad_size = int(random(512)); + std::size_t const pad_size = random(512); #ifndef TORRENT_DISABLE_LOGGING - peer_log(peer_log_alert::info, "ENCRYPTION", "pad size: %d", pad_size); + peer_log(peer_log_alert::info, "ENCRYPTION", "pad size: %zu", pad_size); #endif char msg[dh_key_len + 512]; char* ptr = msg; - int const buf_size = dh_key_len + pad_size; + std::size_t const buf_size = dh_key_len + pad_size; std::array const local_key = export_key(m_dh_key_exchange->get_local_key()); std::memcpy(ptr, local_key.data(), dh_key_len); ptr += dh_key_len; std::generate(ptr, ptr + pad_size, random_byte); - send_buffer(msg, buf_size); + send_buffer({msg, buf_size}); #ifndef TORRENT_DISABLE_LOGGING peer_log(peer_log_alert::info, "ENCRYPTION", "sent DH key"); @@ -541,7 +538,7 @@ namespace libtorrent { key_t const secret_key = m_dh_key_exchange->get_secret(); std::array const secret = export_key(secret_key); - int const pad_size = int(random(512)); + std::size_t const pad_size = random(512); // synchash,skeyhash,vc,crypto_provide,len(pad),pad,len(ia) char msg[20 + 20 + 8 + 4 + 2 + 512 + 2]; @@ -590,7 +587,7 @@ namespace libtorrent { m_dh_key_exchange.reset(); // secret should be invalid at this point // write the verification constant and crypto field - int const encrypt_size = int(sizeof(msg)) - 512 + pad_size - 40; + std::size_t const encrypt_size = sizeof(msg) - 512 + pad_size - 40; // this is an invalid setting, but let's just make the best of the situation int const enc_level = m_settings.get_int(settings_pack::allowed_enc_level); @@ -604,10 +601,10 @@ namespace libtorrent { , "%s", level[crypto_provide - 1]); #endif - write_pe_vc_cryptofield(ptr, encrypt_size, crypto_provide, pad_size); + write_pe_vc_cryptofield({ptr, encrypt_size}, crypto_provide, pad_size); span vec(ptr, aux::numeric_cast(encrypt_size)); m_rc4->encrypt(vec); - send_buffer(msg, int(sizeof(msg)) - 512 + pad_size); + send_buffer({msg, sizeof(msg) - 512 + pad_size}); } void bt_peer_connection::write_pe4_sync(int crypto_select) @@ -620,15 +617,15 @@ namespace libtorrent { TORRENT_ASSERT(crypto_select == 0x02 || crypto_select == 0x01); TORRENT_ASSERT(!m_sent_handshake); - int const pad_size = int(random(512)); + std::size_t const pad_size = random(512); - int const buf_size = 8 + 4 + 2 + pad_size; + std::size_t const buf_size = 8 + 4 + 2 + pad_size; char msg[512 + 8 + 4 + 2]; - write_pe_vc_cryptofield(msg, sizeof(msg), crypto_select, pad_size); + write_pe_vc_cryptofield(msg, crypto_select, pad_size); - span vec(msg, aux::numeric_cast(buf_size)); + span vec(msg, buf_size); m_rc4->encrypt(vec); - send_buffer(msg, buf_size); + send_buffer(vec); // encryption method has been negotiated if (crypto_select == 0x02) @@ -642,10 +639,10 @@ namespace libtorrent { #endif } - void bt_peer_connection::write_pe_vc_cryptofield(char* write_buf - , int const len + void bt_peer_connection::write_pe_vc_cryptofield( + span write_buf , int const crypto_field - , int const pad_size) + , std::size_t const pad_size) { INVARIANT_CHECK; #if !TORRENT_USE_ASSERTS @@ -654,26 +651,27 @@ namespace libtorrent { TORRENT_ASSERT(crypto_field <= 0x03 && crypto_field > 0); // vc,crypto_field,len(pad),pad, (len(ia)) - TORRENT_ASSERT((len >= 8+4+2+pad_size+2 && is_outgoing()) - || (len >= 8+4+2+pad_size && !is_outgoing())); + TORRENT_ASSERT((write_buf.size() >= 8+4+2+pad_size+2 + && is_outgoing()) + || (write_buf.size() >= 8+4+2+pad_size && !is_outgoing())); TORRENT_ASSERT(!m_sent_handshake); // encrypt(vc, crypto_provide/select, len(Pad), len(IA)) // len(pad) is zero for now, len(IA) only for outgoing connections // vc - std::memset(write_buf, 0, 8); - write_buf += 8; + std::memset(write_buf.data(), 0, 8); + write_buf = write_buf.subspan(8); - detail::write_uint32(crypto_field, write_buf); - detail::write_uint16(pad_size, write_buf); // len (pad) + aux::write_uint32(crypto_field, write_buf); + aux::write_uint16(pad_size, write_buf); // len (pad) - std::generate(write_buf, write_buf + pad_size, random_byte); - write_buf += pad_size; + std::generate(write_buf.data(), write_buf.data() + pad_size, random_byte); + write_buf = write_buf.subspan(pad_size); // append len(ia) if we are initiating if (is_outgoing()) - detail::write_uint16(handshake_len, write_buf); // len(IA) + aux::write_uint16(handshake_len, write_buf); // len(IA) } // TODO: 3 use span instead of (pointer,len) pairs @@ -796,7 +794,7 @@ namespace libtorrent { , "ih: %s", aux::to_hex(ih).c_str()); } #endif - send_buffer(handshake, sizeof(handshake)); + send_buffer(handshake); } piece_block_progress bt_peer_connection::downloading_piece_progress() const @@ -1592,7 +1590,7 @@ namespace libtorrent { TORRENT_ASSERT(ptr <= buf + sizeof(buf)); - send_buffer(buf, int(ptr - buf)); + send_buffer({buf, std::size_t(ptr - buf)}); stats_counters().inc_stats_counter(counters::num_outgoing_extended); } @@ -1966,7 +1964,7 @@ namespace libtorrent { // they have downloaded a single piece, although we'll // make another piece available detail::write_uint8(t->is_upload_only() && !t->super_seeding(), ptr); - send_buffer(msg, sizeof(msg)); + send_buffer(msg); stats_counters().inc_stats_counter(counters::num_outgoing_extended); } @@ -1982,7 +1980,7 @@ namespace libtorrent { char* ptr = msg + 5; detail::write_uint8(m_share_mode_id, ptr); detail::write_uint8(t->share_mode(), ptr); - send_buffer(msg, sizeof(msg)); + send_buffer(msg); stats_counters().inc_stats_counter(counters::num_outgoing_extended); } @@ -2001,7 +1999,7 @@ namespace libtorrent { TORRENT_ASSERT(m_sent_handshake); static const char msg[] = {0,0,0,0}; - send_buffer(msg, sizeof(msg)); + send_buffer(msg); } void bt_peer_connection::write_cancel(peer_request const& r) @@ -2078,7 +2076,7 @@ namespace libtorrent { const int packet_size = (num_pieces + 7) / 8 + 5; - TORRENT_ALLOCA(msg, std::uint8_t, packet_size); + TORRENT_ALLOCA(msg, char, packet_size); if (msg.data() == nullptr) return; // out of memory auto ptr = msg.begin(); @@ -2090,7 +2088,7 @@ namespace libtorrent { std::fill_n(ptr, packet_size - 5, std::uint8_t{0xff}); // Clear trailing bits - msg.back() = (0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff; + msg.back() = static_cast((0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff); } else { @@ -2131,7 +2129,7 @@ namespace libtorrent { #endif m_sent_bitfield = true; - send_buffer(reinterpret_cast(msg.data()), int(msg.size())); + send_buffer(msg); stats_counters().inc_stats_counter(counters::num_outgoing_bitfield); } @@ -2235,8 +2233,8 @@ namespace libtorrent { detail::write_uint8(msg_extended, ptr); // signal handshake message detail::write_uint8(0, ptr); - send_buffer(msg, sizeof(msg)); - send_buffer(&dict_msg[0], int(dict_msg.size())); + send_buffer(msg); + send_buffer(dict_msg); stats_counters().inc_stats_counter(counters::num_outgoing_ext_handshake); @@ -2319,7 +2317,7 @@ namespace libtorrent { char msg[] = {0,0,0,6,msg_extended,char(m_dont_have_id),0,0,0,0}; char* ptr = msg + 6; detail::write_int32(static_cast(index), ptr); - send_buffer(msg, sizeof(msg)); + send_buffer(msg); stats_counters().inc_stats_counter(counters::num_outgoing_extended); #else @@ -2379,12 +2377,12 @@ namespace libtorrent { detail::write_int32(r.length + 1 + 4 + 4 + 4 + int(piece_list_buf.size()) , ptr2); - send_buffer(msg, 17); - send_buffer(&piece_list_buf[0], int(piece_list_buf.size())); + send_buffer({msg, 17}); + send_buffer(piece_list_buf); } else { - send_buffer(msg, 13); + send_buffer({msg, 13}); } if (buffer.is_mutable()) diff --git a/src/chained_buffer.cpp b/src/chained_buffer.cpp index aa32e0eab..e96ea756d 100644 --- a/src/chained_buffer.cpp +++ b/src/chained_buffer.cpp @@ -83,14 +83,14 @@ namespace libtorrent { // tries to copy the given buffer to the end of the // last chained buffer. If there's not enough room - // it returns false - char* chained_buffer::append(char const* buf, int const s) + // it returns nullptr + char* chained_buffer::append(span buf) { TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(!m_destructed); - char* const insert = allocate_appendix(s); + char* const insert = allocate_appendix(static_cast(buf.size())); if (insert == nullptr) return nullptr; - std::memcpy(insert, buf, std::size_t(s)); + std::memcpy(insert, buf.data(), buf.size()); return insert; } diff --git a/src/http_seed_connection.cpp b/src/http_seed_connection.cpp index f5dc731aa..e7f7fc2e1 100644 --- a/src/http_seed_connection.cpp +++ b/src/http_seed_connection.cpp @@ -192,7 +192,7 @@ namespace libtorrent { peer_log(peer_log_alert::outgoing_message, "REQUEST", "%s", request.c_str()); #endif - send_buffer(request.c_str(), int(request.size()), message_type_request); + send_buffer(request, message_type_request); } // -------------------------- diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 8e7f17e73..6e530df33 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -5655,36 +5655,35 @@ namespace libtorrent { return piece_block_progress(); } - void peer_connection::send_buffer(char const* buf, int size, std::uint32_t flags) + void peer_connection::send_buffer(span buf, std::uint32_t const flags) { TORRENT_ASSERT(is_single_thread()); TORRENT_UNUSED(flags); - int free_space = m_send_buffer.space_in_last_buffer(); - if (free_space > size) free_space = size; + std::size_t const free_space = std::min( + std::size_t(m_send_buffer.space_in_last_buffer()), buf.size()); if (free_space > 0) { - char* dst = m_send_buffer.append(buf, free_space); + char* dst = m_send_buffer.append(buf.subspan(0, free_space)); // this should always succeed, because we checked how much space // there was up-front TORRENT_UNUSED(dst); TORRENT_ASSERT(dst != nullptr); - size -= free_space; - buf += free_space; + buf = buf.subspan(free_space); } - if (size <= 0) return; + if (buf.size() <= 0) return; - while (size > 0) + while (buf.size() > 0) { aux::ses_buffer_holder session_buf = m_ses.allocate_buffer(); int const alloc_buf_size = m_ses.send_buffer_size(); - int const buf_size = std::min(alloc_buf_size, size); - std::memcpy(session_buf.get(), buf, aux::numeric_cast(buf_size)); - buf += buf_size; - size -= buf_size; - m_send_buffer.append_buffer(std::move(session_buf), alloc_buf_size, buf_size); + int const buf_size = std::min(alloc_buf_size, int(buf.size())); + std::copy(buf.data(), buf.data() + buf_size, session_buf.get()); + buf = buf.subspan(std::size_t(buf_size)); + m_send_buffer.append_buffer(std::move(session_buf) + , alloc_buf_size, buf_size); } setup_send(); } diff --git a/src/peer_connection_handle.cpp b/src/peer_connection_handle.cpp index 74eb7ad61..e5df53de1 100644 --- a/src/peer_connection_handle.cpp +++ b/src/peer_connection_handle.cpp @@ -265,11 +265,12 @@ bool peer_connection_handle::in_handshake() const return pc->in_handshake(); } -void peer_connection_handle::send_buffer(char const* begin, int size, std::uint32_t flags) +void peer_connection_handle::send_buffer(char const* begin, int size + , std::uint32_t const flags) { std::shared_ptr pc = native_handle(); TORRENT_ASSERT(pc); - pc->send_buffer(begin, size, flags); + pc->send_buffer({begin, std::size_t(size)}, flags); } time_t peer_connection_handle::last_seen_complete() const diff --git a/src/ut_metadata.cpp b/src/ut_metadata.cpp index d312ddab7..1894bf999 100644 --- a/src/ut_metadata.cpp +++ b/src/ut_metadata.cpp @@ -267,21 +267,26 @@ namespace libtorrent {namespace { TORRENT_ASSERT(offset + metadata_piece_size <= int(m_tp.get_metadata_size())); } + // TODO: 3 use the aux::write_* functions and the span here instead, it + // will fit better with send_buffer() char msg[200]; char* header = msg; char* p = &msg[6]; - int len = bencode(p, e); - int total_size = 2 + len + metadata_piece_size; + int const len = bencode(p, e); + int const total_size = 2 + len + metadata_piece_size; namespace io = detail; io::write_uint32(total_size, header); io::write_uint8(bt_peer_connection::msg_extended, header); io::write_uint8(m_message_index, header); - m_pc.send_buffer(msg, len + 6); + m_pc.send_buffer({msg, static_cast(len + 6)}); // TODO: we really need to increment the refcounter on the torrent // while this buffer is still in the peer's send buffer - if (metadata_piece_size) m_pc.append_const_send_buffer( - aux::non_owning_handle(const_cast(metadata)), metadata_piece_size); + if (metadata_piece_size) + { + m_pc.append_const_send_buffer( + aux::non_owning_handle(const_cast(metadata)), metadata_piece_size); + } m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_extended); m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_metadata); diff --git a/src/ut_pex.cpp b/src/ut_pex.cpp index ecf512f84..245daf592 100644 --- a/src/ut_pex.cpp +++ b/src/ut_pex.cpp @@ -481,8 +481,8 @@ namespace libtorrent {namespace { detail::write_uint32(1 + 1 + int(pex_msg.size()), ptr); detail::write_uint8(bt_peer_connection::msg_extended, ptr); detail::write_uint8(m_message_index, ptr); - m_pc.send_buffer(msg, sizeof(msg)); - m_pc.send_buffer(&pex_msg[0], int(pex_msg.size())); + m_pc.send_buffer(msg); + m_pc.send_buffer(pex_msg); m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_extended); m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_pex); @@ -596,8 +596,8 @@ namespace libtorrent {namespace { detail::write_uint32(1 + 1 + int(pex_msg.size()), ptr); detail::write_uint8(bt_peer_connection::msg_extended, ptr); detail::write_uint8(m_message_index, ptr); - m_pc.send_buffer(msg, sizeof(msg)); - m_pc.send_buffer(&pex_msg[0], int(pex_msg.size())); + m_pc.send_buffer(msg); + m_pc.send_buffer(pex_msg); m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_extended); m_pc.stats_counters().inc_stats_counter(counters::num_outgoing_pex); diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 0769a120f..13a376db9 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -464,7 +464,7 @@ void web_peer_connection::write_request(peer_request const& r) peer_log(peer_log_alert::outgoing_message, "REQUEST", "%s", request.c_str()); #endif - send_buffer(request.c_str(), int(request.size()), message_type_request); + send_buffer(request, message_type_request); } namespace { diff --git a/test/test_buffer.cpp b/test/test_buffer.cpp index f6c8e9fa6..74e67083c 100644 --- a/test/test_buffer.cpp +++ b/test/test_buffer.cpp @@ -232,7 +232,7 @@ TORRENT_TEST(chained_buffer) TEST_CHECK(!b.empty()); TEST_EQUAL(b.space_in_last_buffer(), 512 - 6); - bool ret = b.append(data, 6) != nullptr; + bool ret = b.append({data, 6}) != nullptr; TEST_CHECK(ret == true); TEST_EQUAL(b.capacity(), 512 - 3); @@ -241,7 +241,7 @@ TORRENT_TEST(chained_buffer) TEST_EQUAL(b.space_in_last_buffer(), 512 - 12); char data2[1024]; - ret = b.append(data2, 1024) != nullptr; + ret = b.append(data2) != nullptr; TEST_CHECK(ret == false); @@ -290,11 +290,11 @@ TORRENT_TEST(chained_buffer) b.append_buffer(holder(b4), 20, 12); TEST_CHECK(b.space_in_last_buffer() == 8); - ret = b.append(data, 6) != nullptr; + ret = b.append({data, 6}) != nullptr; TEST_CHECK(ret == true); TEST_CHECK(b.space_in_last_buffer() == 2); std::cout << b.space_in_last_buffer() << std::endl; - ret = b.append(data, 2) != nullptr; + ret = b.append({data, 2}) != nullptr; TEST_CHECK(ret == true); TEST_CHECK(b.space_in_last_buffer() == 0); std::cout << b.space_in_last_buffer() << std::endl; diff --git a/test/test_fast_extension.cpp b/test/test_fast_extension.cpp index 4e4f62a7f..7012783f1 100644 --- a/test/test_fast_extension.cpp +++ b/test/test_fast_extension.cpp @@ -88,7 +88,7 @@ int read_message(tcp::socket& s, char* buffer, int max_size) if (length > max_size) { log("message size: %d", length); - TEST_ERROR("message size exceeds max limt"); + TEST_ERROR("message size exceeds max limit"); return -1; }