use span<> for peer_connection::send_buffer

This commit is contained in:
arvidn 2017-04-23 00:37:29 -04:00 committed by Arvid Norberg
parent 761436dc97
commit 4eb5155263
13 changed files with 90 additions and 87 deletions

View File

@ -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<char> 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).

View File

@ -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<char const> buf);
// tries to allocate memory from the end
// of the last buffer. If there isn't

View File

@ -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<char const> buf, std::uint32_t flags = 0);
void setup_send();
template <typename Holder>

View File

@ -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<char, dh_key_len> 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<char, dh_key_len> 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<char> vec(ptr, aux::numeric_cast<std::size_t>(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<char> vec(msg, aux::numeric_cast<std::size_t>(buf_size));
span<char> 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<char> 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<char>((0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff);
}
else
{
@ -2131,7 +2129,7 @@ namespace libtorrent {
#endif
m_sent_bitfield = true;
send_buffer(reinterpret_cast<char const*>(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<int>(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())

View File

@ -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<char const> buf)
{
TORRENT_ASSERT(is_single_thread());
TORRENT_ASSERT(!m_destructed);
char* const insert = allocate_appendix(s);
char* const insert = allocate_appendix(static_cast<int>(buf.size()));
if (insert == nullptr) return nullptr;
std::memcpy(insert, buf, std::size_t(s));
std::memcpy(insert, buf.data(), buf.size());
return insert;
}

View File

@ -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);
}
// --------------------------

View File

@ -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<char const> 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<std::size_t>(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();
}

View File

@ -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<peer_connection> 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

View File

@ -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<std::size_t>(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<char*>(metadata)), metadata_piece_size);
if (metadata_piece_size)
{
m_pc.append_const_send_buffer(
aux::non_owning_handle(const_cast<char*>(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);

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}