From b8bc4d77b7533ff7b02c4b362ef3891da04137ba Mon Sep 17 00:00:00 2001 From: anon Date: Sun, 27 Dec 2020 01:55:12 +0000 Subject: [PATCH] ssl: buffered handshake detection --- .../epee/include/net/abstract_tcp_server2.inl | 17 ++++++++--------- contrib/epee/include/net/connection_basic.hpp | 4 ++-- contrib/epee/include/net/net_helper.h | 2 +- contrib/epee/include/net/net_ssl.h | 1 + contrib/epee/src/net_ssl.cpp | 3 ++- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 44a7899f9..cb1388f3b 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -207,7 +207,6 @@ PRAGMA_WARNING_DISABLE_VS(4355) buffer_ssl_init_fill = 0; if (is_income && m_ssl_support != epee::net_utils::ssl_support_t::e_ssl_support_disabled) socket().async_receive(boost::asio::buffer(buffer_), - boost::asio::socket_base::message_peek, strand_.wrap( std::bind(&connection::handle_receive, self, std::placeholders::_1, @@ -447,16 +446,11 @@ PRAGMA_WARNING_DISABLE_VS(4355) return; } - buffer_ssl_init_fill = bytes_transferred; + buffer_ssl_init_fill += bytes_transferred; MTRACE("we now have " << buffer_ssl_init_fill << "/" << get_ssl_magic_size() << " bytes needed to detect SSL"); if (buffer_ssl_init_fill < get_ssl_magic_size()) { - // don't busy loop on this, ideally we'd want to queue a "async_receive_if_new_data" but there doesn't - // seem to be something like that in boost if we want to just peek at the data, so we'd need to copy and - // have a bit more code just for this. Though I'm just seeing async_read_until which might just work. - epee::misc_utils::sleep_no_w(100); - socket().async_receive(boost::asio::buffer(buffer_.data(), buffer_.size()), - boost::asio::socket_base::message_peek, + socket().async_receive(boost::asio::buffer(buffer_.data() + buffer_ssl_init_fill, buffer_.size() - buffer_ssl_init_fill), strand_.wrap( boost::bind(&connection::handle_receive, connection::shared_from_this(), boost::asio::placeholders::error, @@ -482,7 +476,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) if (m_ssl_support == epee::net_utils::ssl_support_t::e_ssl_support_enabled) { // Handshake - if (!handshake(boost::asio::ssl::stream_base::server)) + if (!handshake(boost::asio::ssl::stream_base::server, boost::asio::const_buffer(buffer_.data(), buffer_ssl_init_fill))) { MERROR("SSL handshake failed"); boost::interprocess::ipcdetail::atomic_write32(&m_want_close_connection, 1); @@ -497,6 +491,11 @@ PRAGMA_WARNING_DISABLE_VS(4355) return; } } + else + { + handle_read(e, buffer_ssl_init_fill); + return; + } async_read_some(boost::asio::buffer(buffer_), strand_.wrap( diff --git a/contrib/epee/include/net/connection_basic.hpp b/contrib/epee/include/net/connection_basic.hpp index 90303a785..23873f65b 100644 --- a/contrib/epee/include/net/connection_basic.hpp +++ b/contrib/epee/include/net/connection_basic.hpp @@ -132,10 +132,10 @@ class connection_basic { // not-templated base class for rapid developmet of som ssl_support_t get_ssl_support() const { return m_ssl_support; } void disable_ssl() { m_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_disabled; } - bool handshake(boost::asio::ssl::stream_base::handshake_type type) + bool handshake(boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer = {}) { //m_state != nullptr verified in constructor - return m_state->ssl_options().handshake(socket_, type); + return m_state->ssl_options().handshake(socket_, type, buffer); } template diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 9446e3588..486cd51e2 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -178,7 +178,7 @@ namespace net_utils // SSL Options if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_enabled || m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) { - if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, addr, timeout)) + if (!m_ssl_options.handshake(*m_ssl_socket, boost::asio::ssl::stream_base::client, {}, addr, timeout)) { if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect) { diff --git a/contrib/epee/include/net/net_ssl.h b/contrib/epee/include/net/net_ssl.h index 643b2c486..1b1577e77 100644 --- a/contrib/epee/include/net/net_ssl.h +++ b/contrib/epee/include/net/net_ssl.h @@ -132,6 +132,7 @@ namespace net_utils bool handshake( boost::asio::ssl::stream &socket, boost::asio::ssl::stream_base::handshake_type type, + boost::asio::const_buffer buffer = {}, const std::string& host = {}, std::chrono::milliseconds timeout = std::chrono::seconds(15)) const; }; diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp index a09e82771..6ed27efa9 100644 --- a/contrib/epee/src/net_ssl.cpp +++ b/contrib/epee/src/net_ssl.cpp @@ -473,6 +473,7 @@ bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const bool ssl_options_t::handshake( boost::asio::ssl::stream &socket, boost::asio::ssl::stream_base::handshake_type type, + boost::asio::const_buffer buffer, const std::string& host, std::chrono::milliseconds timeout) const { @@ -530,7 +531,7 @@ bool ssl_options_t::handshake( }); boost::system::error_code ec = boost::asio::error::would_block; - socket.async_handshake(type, boost::lambda::var(ec) = boost::lambda::_1); + socket.async_handshake(type, boost::asio::buffer(buffer), boost::lambda::var(ec) = boost::lambda::_1); if (io_service.stopped()) { io_service.reset();