From ddb274751f1d7b53dbb7dc91aea47873ea212919 Mon Sep 17 00:00:00 2001 From: Alden Torres Date: Sat, 23 Jul 2016 18:54:39 -0400 Subject: [PATCH] using span in crypto_plugin encrypt/decrypt (#934) --- include/libtorrent/bt_peer_connection.hpp | 4 +- include/libtorrent/buffer.hpp | 8 +++- include/libtorrent/chained_buffer.hpp | 4 +- include/libtorrent/extensions.hpp | 13 ++---- include/libtorrent/pe_crypto.hpp | 15 +++---- include/libtorrent/peer_connection.hpp | 6 +-- include/libtorrent/receive_buffer.hpp | 7 ++- src/bt_peer_connection.cpp | 13 +++--- src/chained_buffer.cpp | 3 +- src/pe_crypto.cpp | 52 +++++++++++------------ src/peer_connection.cpp | 9 ++-- src/receive_buffer.cpp | 8 ++-- test/test_pe_crypto.cpp | 4 +- test/test_receive_buffer.cpp | 5 +-- 14 files changed, 69 insertions(+), 82 deletions(-) diff --git a/include/libtorrent/bt_peer_connection.hpp b/include/libtorrent/bt_peer_connection.hpp index 22ad338d4..e6d4a95ca 100644 --- a/include/libtorrent/bt_peer_connection.hpp +++ b/include/libtorrent/bt_peer_connection.hpp @@ -161,8 +161,8 @@ namespace libtorrent #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) // next_barrier, buffers-to-prepend virtual - std::tuple> - hit_send_barrier(span iovec) override; + std::tuple> + hit_send_barrier(span iovec) override; #endif virtual void get_specific_peer_info(peer_info& p) const override; diff --git a/include/libtorrent/buffer.hpp b/include/libtorrent/buffer.hpp index f4aadcd97..214fbb428 100644 --- a/include/libtorrent/buffer.hpp +++ b/include/libtorrent/buffer.hpp @@ -59,6 +59,13 @@ namespace libtorrent { } } + // TODO: eventually move this file to aux_ or create a new one + namespace aux + { + using mutable_buffer = span; + using const_buffer = span; + } + // the buffer is allocated once and cannot be resized. The size() may be // larger than requested, in case the underlying allocator over allocated. In // order to "grow" an allocation, create a new buffer and initialize it by @@ -241,4 +248,3 @@ private: } #endif // BTORRENT_BUFFER_HPP_INCLUDED - diff --git a/include/libtorrent/chained_buffer.hpp b/include/libtorrent/chained_buffer.hpp index 421aa0491..d5fc6f900 100644 --- a/include/libtorrent/chained_buffer.hpp +++ b/include/libtorrent/chained_buffer.hpp @@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/disk_io_job.hpp" // for block_cache_reference #include "libtorrent/debug.hpp" +#include "libtorrent/buffer.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp" @@ -110,7 +111,7 @@ namespace libtorrent void clear(); - void build_mutable_iovec(int bytes, std::vector& vec); + void build_mutable_iovec(int bytes, std::vector& vec); ~chained_buffer(); @@ -142,4 +143,3 @@ namespace libtorrent } #endif - diff --git a/include/libtorrent/extensions.hpp b/include/libtorrent/extensions.hpp index 4d41131af..db34b5c5a 100644 --- a/include/libtorrent/extensions.hpp +++ b/include/libtorrent/extensions.hpp @@ -160,12 +160,6 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_DISABLE_EXTENSIONS -#include "libtorrent/aux_/disable_warnings_push.hpp" - -#include - -#include "libtorrent/aux_/disable_warnings_pop.hpp" - #include #include "libtorrent/config.hpp" #include "libtorrent/buffer.hpp" @@ -509,8 +503,8 @@ namespace libtorrent // send buffer, must be owned by the crypto plugin and guaranteed to stay // alive until the crypto_plugin is destructed or this function is called // again. - virtual std::tuple> - encrypt(span /*send_vec*/) = 0; + virtual std::tuple>> + encrypt(span> /*send_vec*/) = 0; // decrypt the provided buffers. // consume is set to the number of bytes which should be trimmed from the @@ -521,7 +515,7 @@ namespace libtorrent // // packet_size is set to the minimum number of bytes which must be read to // advance the next step of decryption. default is 0 - virtual void decrypt(span /*receive_vec*/ + virtual void decrypt(span> /*receive_vec*/ , int& /* consume */, int& /*produce*/, int& /*packet_size*/) = 0; }; } @@ -529,4 +523,3 @@ namespace libtorrent #endif #endif // TORRENT_EXTENSIONS_HPP_INCLUDED - diff --git a/include/libtorrent/pe_crypto.hpp b/include/libtorrent/pe_crypto.hpp index 7e655b9b4..4ef02c66c 100644 --- a/include/libtorrent/pe_crypto.hpp +++ b/include/libtorrent/pe_crypto.hpp @@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp" -#include #include #include "libtorrent/aux_/disable_warnings_pop.hpp" @@ -47,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/extensions.hpp" #include "libtorrent/assert.hpp" #include "libtorrent/span.hpp" +#include "libtorrent/buffer.hpp" #include #include @@ -56,7 +56,7 @@ namespace libtorrent { namespace mp = boost::multiprecision; - using key_t = mp::number >; + using key_t = mp::number>; // RC4 state from libtomcrypt struct rc4 { @@ -99,8 +99,8 @@ namespace libtorrent struct encryption_handler { - std::tuple> - encrypt(span iovec); + std::tuple> + encrypt(span iovec); int decrypt(crypto_receive_buffer& recv_buffer , std::size_t& bytes_transferred); @@ -144,10 +144,10 @@ namespace libtorrent void set_incoming_key(unsigned char const* key, int len) override; void set_outgoing_key(unsigned char const* key, int len) override; - std::tuple> - encrypt(span buf) override; + std::tuple> + encrypt(span buf) override; - void decrypt(span buf + void decrypt(span buf , int& consume , int& produce , int& packet_size) override; @@ -165,4 +165,3 @@ namespace libtorrent #endif // TORRENT_PE_CRYPTO_HPP_INCLUDED #endif // TORRENT_DISABLE_ENCRYPTION - diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 61acc258b..6c5620777 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -749,11 +749,11 @@ namespace libtorrent void send_piece_suggestions(int num); virtual - std::tuple> - hit_send_barrier(span /* iovec */) + std::tuple> + hit_send_barrier(span /* iovec */) { return std::make_tuple(INT_MAX - , span()); + , span()); } void attach_to_torrent(sha1_hash const& ih); diff --git a/include/libtorrent/receive_buffer.hpp b/include/libtorrent/receive_buffer.hpp index b73ff84ce..e618a709a 100644 --- a/include/libtorrent/receive_buffer.hpp +++ b/include/libtorrent/receive_buffer.hpp @@ -92,7 +92,7 @@ struct TORRENT_EXTRA_EXPORT receive_buffer buffer::interval mutable_buffer(); // returns the last 'bytes' from the receive buffer - boost::asio::mutable_buffer mutable_buffer(int bytes); + aux::mutable_buffer mutable_buffer(int bytes); #endif // the purpose of this function is to free up and cut off all messages @@ -158,7 +158,7 @@ private: // Wraps a receive_buffer to provide the ability to inject // possibly authenticated crypto beneath the bittorrent protocol. // When authenticated crypto is in use the wrapped receive_buffer -// holds the receive state of the crpyto layer while this class +// holds the receive state of the crypto layer while this class // tracks the state of the bittorrent protocol. struct crypto_receive_buffer { @@ -200,7 +200,7 @@ struct crypto_receive_buffer buffer::const_interval get() const; - boost::asio::mutable_buffer mutable_buffer(std::size_t bytes); + aux::mutable_buffer mutable_buffer(std::size_t bytes); private: // explicitly disallow assignment, to silence msvc warning @@ -215,4 +215,3 @@ private: } // namespace libtorrent #endif // #ifndef TORRENT_RECEIVE_BUFFER_HPP_INCLUDED - diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 235a19c9f..97dd327fa 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -603,7 +603,7 @@ namespace libtorrent #endif write_pe_vc_cryptofield(ptr, encrypt_size, crypto_provide, pad_size); - boost::asio::mutable_buffer vec(ptr, encrypt_size); + aux::mutable_buffer vec(ptr, encrypt_size); m_rc4->encrypt(vec); send_buffer(msg, sizeof(msg) - 512 + pad_size); } @@ -624,7 +624,7 @@ namespace libtorrent char msg[512 + 8 + 4 + 2]; write_pe_vc_cryptofield(msg, sizeof(msg), crypto_select, pad_size); - boost::asio::mutable_buffer vec(msg, buf_size); + aux::mutable_buffer vec(msg, buf_size); m_rc4->encrypt(vec); send_buffer(msg, buf_size); @@ -702,7 +702,7 @@ namespace libtorrent int consume = 0; int produce = len; int packet_size = 0; - boost::asio::mutable_buffer vec(pos, len); + aux::mutable_buffer vec(pos, len); m_rc4->decrypt(vec, consume, produce, packet_size); } @@ -3471,12 +3471,12 @@ namespace libtorrent } #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) - std::tuple> + std::tuple> bt_peer_connection::hit_send_barrier( - span iovec) + span iovec) { int next_barrier; - span out_iovec; + span out_iovec; std::tie(next_barrier, out_iovec) = m_enc_handler.encrypt(iovec); #ifndef TORRENT_DISABLE_LOGGING if (next_barrier != 0) @@ -3576,4 +3576,3 @@ namespace libtorrent #endif } - diff --git a/src/chained_buffer.cpp b/src/chained_buffer.cpp index 39157ae5c..e4d9c60d9 100644 --- a/src/chained_buffer.cpp +++ b/src/chained_buffer.cpp @@ -151,7 +151,7 @@ namespace libtorrent return m_tmp_vec; } - void chained_buffer::build_mutable_iovec(int bytes, std::vector &vec) + void chained_buffer::build_mutable_iovec(int bytes, std::vector &vec) { build_vec(bytes, vec); } @@ -199,4 +199,3 @@ namespace libtorrent } } - diff --git a/src/pe_crypto.cpp b/src/pe_crypto.cpp index db88a96f7..f4a201380 100644 --- a/src/pe_crypto.cpp +++ b/src/pe_crypto.cpp @@ -103,38 +103,36 @@ namespace libtorrent m_xor_mask = h.final(); } - std::tuple> + std::tuple> encryption_handler::encrypt( - span iovec) + span iovec) { - using namespace boost::asio; - TORRENT_ASSERT(!m_send_barriers.empty()); TORRENT_ASSERT(m_send_barriers.front().enc_handler); int to_process = m_send_barriers.front().next; - boost::asio::mutable_buffer* bufs; + aux::mutable_buffer* bufs; size_t num_bufs; bool need_destruct = false; if (to_process != INT_MAX) { - bufs = TORRENT_ALLOCA(mutable_buffer, iovec.size()); + bufs = TORRENT_ALLOCA(aux::mutable_buffer, iovec.size()); need_destruct = true; num_bufs = 0; for (int i = 0; to_process > 0 && i < iovec.size(); ++i) { ++num_bufs; - int const size = buffer_size(iovec[i]); + int const size = int(iovec[i].size()); if (to_process < size) { - new (&bufs[i]) mutable_buffer( - buffer_cast(iovec[i]), to_process); + new (&bufs[i]) aux::mutable_buffer( + iovec[i].data(), to_process); to_process = 0; } else { - new (&bufs[i]) mutable_buffer(iovec[i]); + new (&bufs[i]) aux::mutable_buffer(iovec[i]); to_process -= size; } } @@ -146,7 +144,7 @@ namespace libtorrent } int next_barrier = 0; - span out_iovec; + span out_iovec; if (num_bufs != 0) { std::tie(next_barrier, out_iovec) @@ -179,18 +177,18 @@ namespace libtorrent { int payload = 0; for (int i = 0; i < num_bufs; ++i) - payload += int(buffer_size(bufs[i])); + payload += int(bufs[i].size()); int overhead = 0; for (auto buf : out_iovec) - overhead += int(buffer_size(buf)); + overhead += int(buf.size()); TORRENT_ASSERT(overhead + payload == next_barrier); } #endif if (need_destruct) { for (int i = 0; i < num_bufs; ++i) - bufs[i].~mutable_buffer(); + bufs[i].~span(); } return std::make_tuple(next_barrier, out_iovec); } @@ -202,7 +200,7 @@ namespace libtorrent int consume = 0; if (recv_buffer.crypto_packet_finished()) { - boost::asio::mutable_buffer wr_buf = recv_buffer.mutable_buffer(bytes_transferred); + aux::mutable_buffer wr_buf = recv_buffer.mutable_buffer(bytes_transferred); int packet_size = 0; int produce = int(bytes_transferred); m_dec_handler->decrypt(wr_buf, consume, produce, packet_size); @@ -248,7 +246,7 @@ namespace libtorrent { int consume = 0; int produce = 0; - std::vector wr_buf; + std::vector wr_buf; crypto->decrypt(wr_buf, consume, produce, packet_size); TORRENT_ASSERT(wr_buf.empty()); TORRENT_ASSERT(consume == 0); @@ -276,7 +274,7 @@ namespace libtorrent int produce = 0; int packet_size = 0; char buf[1024]; - boost::asio::mutable_buffer vec(buf, sizeof(buf)); + aux::mutable_buffer vec(buf, sizeof(buf)); decrypt(vec, consume, produce, packet_size); } @@ -286,23 +284,22 @@ namespace libtorrent rc4_init(key, len, &m_rc4_outgoing); // Discard first 1024 bytes char buf[1024]; - boost::asio::mutable_buffer vec(buf, sizeof(buf)); + aux::mutable_buffer vec(buf, sizeof(buf)); encrypt(vec); } - std::tuple> - rc4_handler::encrypt(span bufs) + std::tuple> + rc4_handler::encrypt(span bufs) { - using namespace boost::asio; - span empty; + span empty; if (!m_encrypt) return std::make_tuple(0, empty); if (bufs.size() == 0) return std::make_tuple(0, empty); int bytes_processed = 0; for (auto& buf : bufs) { - unsigned char* const pos = buffer_cast(buf); - int const len = int(buffer_size(buf)); + unsigned char* const pos = reinterpret_cast(buf.data()); + int const len = int(buf.size()); TORRENT_ASSERT(len >= 0); TORRENT_ASSERT(pos); @@ -313,7 +310,7 @@ namespace libtorrent return std::make_tuple(bytes_processed, empty); } - void rc4_handler::decrypt(span bufs + void rc4_handler::decrypt(span bufs , int& consume , int& produce , int& packet_size) @@ -327,8 +324,8 @@ namespace libtorrent int bytes_processed = 0; for (auto& buf : bufs) { - unsigned char* const pos = boost::asio::buffer_cast(buf); - int const len = int(boost::asio::buffer_size(buf)); + unsigned char* const pos = reinterpret_cast(buf.data()); + int const len = int(buf.size()); TORRENT_ASSERT(len >= 0); TORRENT_ASSERT(pos); @@ -406,4 +403,3 @@ unsigned long rc4_encrypt(unsigned char *out, unsigned long outlen, rc4 *state) } // namespace libtorrent #endif // #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) - diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 8d3fef162..d3d4fcc8d 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -5468,20 +5468,19 @@ namespace libtorrent if (m_send_barrier == 0) { - std::vector vec; + std::vector vec; // limit outgoing crypto messages to 1MB int const send_bytes = (std::min)(m_send_buffer.size(), 1024*1024); m_send_buffer.build_mutable_iovec(send_bytes, vec); int next_barrier; - span inject_vec; + span inject_vec; std::tie(next_barrier, inject_vec) = hit_send_barrier(vec); for (auto i = inject_vec.rbegin(); i != inject_vec.rend(); ++i) { - int const size = boost::asio::buffer_size(*i); + int const size = int(i->size()); // this const_cast is a here because chained_buffer need to be // fixed. - char* ptr = const_cast( - boost::asio::buffer_cast(*i)); + char* ptr = const_cast(i->data()); m_send_buffer.prepend_buffer(ptr , size, size, &nop, nullptr); } diff --git a/src/receive_buffer.cpp b/src/receive_buffer.cpp index 21f93979b..aded7f2b1 100644 --- a/src/receive_buffer.cpp +++ b/src/receive_buffer.cpp @@ -157,17 +157,15 @@ buffer::interval receive_buffer::mutable_buffer() , &m_recv_buffer[0] + m_recv_start + rcv_pos); } -boost::asio::mutable_buffer receive_buffer::mutable_buffer(int const bytes) +aux::mutable_buffer receive_buffer::mutable_buffer(int const bytes) { - namespace asio = boost::asio; - // bytes is the number of bytes we just received, and m_recv_pos has // already been adjusted for these bytes. The receive pos immediately // before we received these bytes was (m_recv_pos - bytes) int const last_recv_pos = m_recv_pos - bytes; TORRENT_ASSERT(bytes <= m_recv_pos); - return asio::mutable_buffer(&m_recv_buffer[0] + m_recv_start + return aux::mutable_buffer(&m_recv_buffer[0] + m_recv_start + last_recv_pos, bytes); } #endif @@ -329,7 +327,7 @@ buffer::const_interval crypto_receive_buffer::get() const return recv_buffer; } -boost::asio::mutable_buffer crypto_receive_buffer::mutable_buffer( +aux::mutable_buffer crypto_receive_buffer::mutable_buffer( std::size_t const bytes) { int const pending_decryption = (m_recv_pos != INT_MAX) diff --git a/test/test_pe_crypto.cpp b/test/test_pe_crypto.cpp index b94b0d17b..8edbf17a7 100644 --- a/test/test_pe_crypto.cpp +++ b/test/test_pe_crypto.cpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/session.hpp" #include "libtorrent/random.hpp" #include "libtorrent/span.hpp" +#include "libtorrent/buffer.hpp" #include "setup_transfer.hpp" #include "test.hpp" @@ -58,7 +59,7 @@ void test_enc_handler(libtorrent::crypto_plugin& a, libtorrent::crypto_plugin& b std::generate(buf.begin(), buf.end(), &std::rand); std::copy(buf.begin(), buf.end(), cmp_buf.begin()); - using namespace boost::asio; + using namespace libtorrent::aux; { mutable_buffer iovec(&buf[0], buf_len); @@ -158,4 +159,3 @@ TORRENT_TEST(disabled) std::fprintf(stderr, "PE test not run because it's disabled\n"); } #endif - diff --git a/test/test_receive_buffer.cpp b/test/test_receive_buffer.cpp index 781f1898c..8290c6a76 100644 --- a/test/test_receive_buffer.cpp +++ b/test/test_receive_buffer.cpp @@ -229,7 +229,7 @@ TORRENT_TEST(recv_buffer_mutable_buffers) b.cut(100, 1000); // packet size = 1000 packet_transferred = b.advance_pos(999); TEST_EQUAL(packet_transferred, 999); - boost::asio::mutable_buffer vec = b.mutable_buffer(999); + aux::mutable_buffer vec = b.mutable_buffer(999); // previous packet // | @@ -242,8 +242,7 @@ TORRENT_TEST(recv_buffer_mutable_buffers) // |----------------------| 1000 packet size // |---------------------| 999 buffer - TEST_EQUAL(boost::asio::buffer_size(vec), 999); + TEST_EQUAL(vec.size(), 999); } #endif -