diff --git a/ChangeLog b/ChangeLog index e851fc7c0..a5ff930bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,7 @@ incoming connection * added more detailed instrumentation of the disk I/O thread + * fixed bug in metadata extensions combined with encryption * refactored socket reading code to not use async. operations unnecessarily * some timer optimizations * removed the reuse-address flag on the listen socket diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index bea368fef..3240d8706 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -265,6 +265,7 @@ public: // these functions encrypt the send buffer if m_rc4_encrypted // is true, otherwise it passes the call to the // peer_connection functions of the same names + virtual void append_const_send_buffer(char const* buffer, int size); void send_buffer(char const* buf, int size, int flags = 0); buffer::interval allocate_send_buffer(int size); template diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 9481e3068..b4bb2e517 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -518,6 +518,8 @@ namespace libtorrent m_send_buffer.append_buffer(buffer, size, size, destructor); } + virtual void append_const_send_buffer(char const* buffer, int size); + #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES void set_country(char const* c) { diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 9c43e989f..2249f92ba 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -657,14 +657,30 @@ namespace libtorrent #endif } + void bt_peer_connection::append_const_send_buffer(char const* buffer, int size) + { + // if we're encrypting this buffer, we need to make a copy + // since we'll mutate it +#ifndef TORRENT_DISABLE_ENCRYPTION + if (m_encrypted && m_rc4_encrypted) + { + send_buffer(buffer, size); + } + else +#endif + { + append_const_send_buffer(buffer, size); + } + } + void bt_peer_connection::send_buffer(char const* buf, int size, int flags) { TORRENT_ASSERT(buf); TORRENT_ASSERT(size > 0); +#ifndef TORRENT_DISABLE_ENCRYPTION encrypt_pending_buffer(); -#ifndef TORRENT_DISABLE_ENCRYPTION if (m_encrypted && m_rc4_encrypted) { TORRENT_ASSERT(send_buffer_size() == m_encrypted_bytes); diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index b1e70c6c7..7b331991d 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -4535,6 +4535,17 @@ namespace libtorrent m_packet_size = packet_size; } + void nop(char*) {} + + void peer_connection::append_const_send_buffer(char const* buffer, int size) + { + m_send_buffer.append_buffer((char*)buffer, size, size, &nop); +#ifdef TORRENT_STATS + m_ses.m_buffer_usage_logger << log_time() << " append_const_send_buffer: " << size << std::endl; + m_ses.log_buffer_usage(); +#endif + } + void peer_connection::send_buffer(char const* buf, int size, int flags) { if (flags == message_type_request) diff --git a/src/ut_metadata.cpp b/src/ut_metadata.cpp index 25dc3011c..dc2a3057f 100644 --- a/src/ut_metadata.cpp +++ b/src/ut_metadata.cpp @@ -66,8 +66,6 @@ namespace libtorrent { namespace return (numerator + denominator - 1) / denominator; } - void nop(char*) {} - struct ut_metadata_plugin : torrent_plugin { ut_metadata_plugin(torrent& t) @@ -283,8 +281,8 @@ namespace libtorrent { namespace io::write_uint8(m_message_index, header); m_pc.send_buffer(msg, len + 6); - if (metadata_piece_size) m_pc.append_send_buffer( - (char*)metadata, metadata_piece_size, &nop); + if (metadata_piece_size) m_pc.append_const_send_buffer( + metadata, metadata_piece_size); } virtual bool on_extended(int length