diff --git a/src/ripple/beast/asio/ssl_bundle.h b/src/ripple/beast/asio/ssl_bundle.h deleted file mode 100644 index 41a4f1e0a4..0000000000 --- a/src/ripple/beast/asio/ssl_bundle.h +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef BEAST_ASIO_SSL_BUNDLE_H_INCLUDED -#define BEAST_ASIO_SSL_BUNDLE_H_INCLUDED - -#include -#include -#include -#include -#include - -namespace beast { -namespace asio { - -/** Work-around for non-movable boost::ssl::stream. - This allows ssl::stream to be movable and allows the stream to - construct from an already-existing socket. -*/ -struct ssl_bundle -{ - using socket_type = boost::asio::ip::tcp::socket; - using stream_type = boost::asio::ssl::stream ; - using shared_context = std::shared_ptr; - - template - ssl_bundle (shared_context const& context_, Args&&... args); - - // DEPRECATED - template - ssl_bundle (boost::asio::ssl::context& context_, Args&&... args); - - shared_context context; - socket_type socket; - stream_type stream; -}; - -template -ssl_bundle::ssl_bundle (shared_context const& context_, Args&&... args) - : socket(std::forward(args)...) - , stream (socket, *context_) -{ -} - -template -ssl_bundle::ssl_bundle (boost::asio::ssl::context& context_, Args&&... args) - : socket(std::forward(args)...) - , stream (socket, context_) -{ -} - -} // asio -} // beast - -#endif diff --git a/src/ripple/overlay/Overlay.h b/src/ripple/overlay/Overlay.h index 2961d6c111..087e0bf564 100644 --- a/src/ripple/overlay/Overlay.h +++ b/src/ripple/overlay/Overlay.h @@ -24,8 +24,12 @@ #include #include #include -#include +#include +#include +#include #include +#include +#include #include #include #include @@ -45,6 +49,9 @@ class Overlay , public beast::PropertyStream::Source { protected: + using socket_type = boost::beast::tcp_stream; + using stream_type = boost::beast::ssl_stream ; + // VFALCO NOTE The requirement of this constructor is an // unfortunate problem with the API for // Stoppable and PropertyStream @@ -82,7 +89,7 @@ public: /** Conditionally accept an incoming HTTP request. */ virtual Handoff - onHandoff (std::unique_ptr && bundle, + onHandoff (std::unique_ptr && bundle, http_request_type&& request, boost::asio::ip::tcp::endpoint remote_address) = 0; diff --git a/src/ripple/overlay/impl/ConnectAttempt.cpp b/src/ripple/overlay/impl/ConnectAttempt.cpp index 5bea51ff9d..2c79e7ccc2 100644 --- a/src/ripple/overlay/impl/ConnectAttempt.cpp +++ b/src/ripple/overlay/impl/ConnectAttempt.cpp @@ -27,7 +27,7 @@ namespace ripple { ConnectAttempt::ConnectAttempt (Application& app, boost::asio::io_service& io_service, endpoint_type const& remote_endpoint, Resource::Consumer usage, - beast::asio::ssl_bundle::shared_context const& context, + shared_context const& context, std::uint32_t id, std::shared_ptr const& slot, beast::Journal journal, OverlayImpl& overlay) : Child (overlay) @@ -39,10 +39,10 @@ ConnectAttempt::ConnectAttempt (Application& app, boost::asio::io_service& io_se , usage_ (usage) , strand_ (io_service) , timer_ (io_service) - , ssl_bundle_ (std::make_unique( - context, io_service)) - , socket_ (ssl_bundle_->socket) - , stream_ (ssl_bundle_->stream) + , stream_ptr_ (std::make_unique( + socket_type(std::forward(io_service)), *context)) + , socket_ (stream_ptr_->next_layer().socket()) + , stream_ (*stream_ptr_) , slot_ (slot) { JLOG(journal_.debug()) << @@ -63,7 +63,7 @@ ConnectAttempt::stop() if (! strand_.running_in_this_thread()) return strand_.post(std::bind( &ConnectAttempt::stop, shared_from_this())); - if (stream_.next_layer().is_open()) + if (socket_.is_open()) { JLOG(journal_.debug()) << "Stop"; @@ -85,7 +85,7 @@ void ConnectAttempt::close() { assert(strand_.running_in_this_thread()); - if (stream_.next_layer().is_open()) + if (socket_.is_open()) { error_code ec; timer_.cancel(ec); @@ -135,7 +135,7 @@ ConnectAttempt::cancelTimer() void ConnectAttempt::onTimer (error_code ec) { - if (! stream_.next_layer().is_open()) + if (! socket_.is_open()) return; if (ec == boost::asio::error::operation_aborted) return; @@ -158,10 +158,10 @@ ConnectAttempt::onConnect (error_code ec) return; endpoint_type local_endpoint; if(! ec) - local_endpoint = stream_.next_layer().local_endpoint(ec); + local_endpoint = socket_.local_endpoint(ec); if(ec) return fail("onConnect", ec); - if(! stream_.next_layer().is_open()) + if(! socket_.is_open()) return; JLOG(journal_.trace()) << "onConnect"; @@ -177,13 +177,13 @@ void ConnectAttempt::onHandshake (error_code ec) { cancelTimer(); - if(! stream_.next_layer().is_open()) + if(! socket_.is_open()) return; if(ec == boost::asio::error::operation_aborted) return; endpoint_type local_endpoint; if (! ec) - local_endpoint = stream_.next_layer().local_endpoint(ec); + local_endpoint = socket_.local_endpoint(ec); if(ec) return fail("onHandshake", ec); JLOG(journal_.trace()) << @@ -193,7 +193,7 @@ ConnectAttempt::onHandshake (error_code ec) beast::IPAddressConversion::from_asio (local_endpoint))) return fail("Duplicate connection"); - auto const sharedValue = makeSharedValue(*ssl_bundle_, journal_); + auto const sharedValue = makeSharedValue(*stream_ptr_, journal_); if (! sharedValue) return close(); // makeSharedValue logs @@ -212,7 +212,7 @@ void ConnectAttempt::onWrite (error_code ec) { cancelTimer(); - if(! stream_.next_layer().is_open()) + if(! socket_.is_open()) return; if(ec == boost::asio::error::operation_aborted) return; @@ -228,7 +228,7 @@ ConnectAttempt::onRead (error_code ec) { cancelTimer(); - if(! stream_.next_layer().is_open()) + if(! socket_.is_open()) return; if(ec == boost::asio::error::operation_aborted) return; @@ -338,7 +338,7 @@ ConnectAttempt::processResponse() return fail("processResponse: Unable to negotiate protocol version"); } - auto const sharedValue = makeSharedValue(*ssl_bundle_, journal_); + auto const sharedValue = makeSharedValue(*stream_ptr_, journal_); if(! sharedValue) return close(); // makeSharedValue logs @@ -365,7 +365,7 @@ ConnectAttempt::processResponse() if (result != PeerFinder::Result::success) return fail("Outbound slots full"); - auto const peer = std::make_shared(app_, std::move(ssl_bundle_), + auto const peer = std::make_shared(app_, std::move(stream_ptr_), read_buf_.data(), std::move(slot_), std::move(response_), usage_, publicKey, *negotiatedProtocol, id_, overlay_); diff --git a/src/ripple/overlay/impl/ConnectAttempt.h b/src/ripple/overlay/impl/ConnectAttempt.h index c227e15c03..601207de13 100644 --- a/src/ripple/overlay/impl/ConnectAttempt.h +++ b/src/ripple/overlay/impl/ConnectAttempt.h @@ -41,6 +41,11 @@ private: using response_type = boost::beast::http::response; + using socket_type = boost::asio::ip::tcp::socket; + using middle_type = boost::beast::tcp_stream; + using stream_type = boost::beast::ssl_stream ; + using shared_context = std::shared_ptr; + Application& app_; std::uint32_t const id_; beast::WrappedSink sink_; @@ -49,9 +54,9 @@ private: Resource::Consumer usage_; boost::asio::io_service::strand strand_; boost::asio::basic_waitable_timer timer_; - std::unique_ptr ssl_bundle_; - beast::asio::ssl_bundle::socket_type& socket_; - beast::asio::ssl_bundle::stream_type& stream_; + std::unique_ptr stream_ptr_; + socket_type& socket_; + stream_type& stream_; boost::beast::multi_buffer read_buf_; response_type response_; std::shared_ptr slot_; @@ -60,7 +65,7 @@ private: public: ConnectAttempt (Application& app, boost::asio::io_service& io_service, endpoint_type const& remote_endpoint, Resource::Consumer usage, - beast::asio::ssl_bundle::shared_context const& context, + shared_context const& context, std::uint32_t id, std::shared_ptr const& slot, beast::Journal journal, OverlayImpl& overlay); diff --git a/src/ripple/overlay/impl/Handshake.cpp b/src/ripple/overlay/impl/Handshake.cpp index 15ea5df47c..bb81f8ed47 100644 --- a/src/ripple/overlay/impl/Handshake.cpp +++ b/src/ripple/overlay/impl/Handshake.cpp @@ -70,10 +70,10 @@ hashLastMessage (SSL const* ssl, } boost::optional -makeSharedValue (beast::asio::ssl_bundle& ssl, beast::Journal journal) +makeSharedValue (stream_type& ssl, beast::Journal journal) { auto const cookie1 = hashLastMessage( - ssl.stream.native_handle(), SSL_get_finished); + ssl.native_handle(), SSL_get_finished); if (!cookie1) { JLOG (journal.error()) << "Cookie generation: local setup not complete"; @@ -81,7 +81,7 @@ makeSharedValue (beast::asio::ssl_bundle& ssl, beast::Journal journal) } auto const cookie2 = hashLastMessage( - ssl.stream.native_handle(), SSL_get_peer_finished); + ssl.native_handle(), SSL_get_peer_finished); if (!cookie2) { JLOG (journal.error()) << "Cookie generation: peer setup not complete"; diff --git a/src/ripple/overlay/impl/Handshake.h b/src/ripple/overlay/impl/Handshake.h index 455780339b..40bd1b173a 100644 --- a/src/ripple/overlay/impl/Handshake.h +++ b/src/ripple/overlay/impl/Handshake.h @@ -21,7 +21,11 @@ #define RIPPLE_OVERLAY_HANDSHAKE_H_INCLUDED #include -#include +#include +#include +#include +#include +#include #include #include @@ -32,6 +36,9 @@ namespace ripple { +using socket_type = boost::beast::tcp_stream; +using stream_type = boost::beast::ssl_stream ; + /** Computes a shared value based on the SSL connection state. When there is no man in the middle, both sides will compute the same @@ -42,7 +49,7 @@ namespace ripple { @return A 256-bit value on success; an unseated optional otherwise. */ boost::optional -makeSharedValue (beast::asio::ssl_bundle& ssl, beast::Journal journal); +makeSharedValue (stream_type& ssl, beast::Journal journal); /** Insert fields headers necessary for upgrading the link to the peer protocol. */ void diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 34b0a8af34..afc7ff813d 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -177,7 +177,7 @@ OverlayImpl::~OverlayImpl () //------------------------------------------------------------------------------ Handoff -OverlayImpl::onHandoff (std::unique_ptr && ssl_bundle, +OverlayImpl::onHandoff (std::unique_ptr && stream_ptr, http_request_type&& request, endpoint_type remote_endpoint) { @@ -196,7 +196,7 @@ OverlayImpl::onHandoff (std::unique_ptr && ssl_bundle, JLOG(journal.debug()) << "Peer connection upgrade from " << remote_endpoint; error_code ec; - auto const local_endpoint (ssl_bundle->socket.local_endpoint(ec)); + auto const local_endpoint (stream_ptr->next_layer().socket().local_endpoint(ec)); if (ec) { JLOG(journal.debug()) << remote_endpoint << " failed: " << ec.message(); @@ -249,7 +249,7 @@ OverlayImpl::onHandoff (std::unique_ptr && ssl_bundle, return handoff; } - auto const sharedValue = makeSharedValue(*ssl_bundle, journal); + auto const sharedValue = makeSharedValue(*stream_ptr, journal); if(! sharedValue) { m_peerFinder->on_closed(slot); @@ -286,7 +286,7 @@ OverlayImpl::onHandoff (std::unique_ptr && ssl_bundle, auto const peer = std::make_shared(app_, id, slot, std::move(request), publicKey, *negotiatedVersion, consumer, - std::move(ssl_bundle), *this); + std::move(stream_ptr), *this); { // As we are not on the strand, run() must be called // while holding the lock, otherwise new I/O can be diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index bdc152f2be..bd04127b61 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -169,7 +169,7 @@ public: } Handoff - onHandoff (std::unique_ptr && bundle, + onHandoff (std::unique_ptr && bundle, http_request_type&& request, endpoint_type remote_endpoint) override; diff --git a/src/ripple/overlay/impl/PeerImp.cpp b/src/ripple/overlay/impl/PeerImp.cpp index d50fb082da..3c35b004a4 100644 --- a/src/ripple/overlay/impl/PeerImp.cpp +++ b/src/ripple/overlay/impl/PeerImp.cpp @@ -58,7 +58,7 @@ PeerImp::PeerImp (Application& app, id_t id, std::shared_ptr const& slot, http_request_type&& request, PublicKey const& publicKey, ProtocolVersion protocol, Resource::Consumer consumer, - std::unique_ptr&& ssl_bundle, + std::unique_ptr&& stream_ptr, OverlayImpl& overlay) : Child (overlay) , app_ (app) @@ -67,9 +67,9 @@ PeerImp::PeerImp (Application& app, id_t id, , p_sink_(app_.journal("Protocol"), makePrefix(id)) , journal_ (sink_) , p_journal_(p_sink_) - , ssl_bundle_(std::move(ssl_bundle)) - , socket_ (ssl_bundle_->socket) - , stream_ (ssl_bundle_->stream) + , stream_ptr_(std::move(stream_ptr)) + , socket_ (stream_ptr_->next_layer().socket()) + , stream_ (*stream_ptr_) , strand_ (socket_.get_executor()) , timer_ (waitable_timer{socket_.get_executor()}) , remote_address_ (slot->remote_endpoint()) @@ -697,7 +697,7 @@ void PeerImp::doAccept() JLOG(journal_.debug()) << "doAccept: " << remote_address_; - auto const sharedValue = makeSharedValue(*ssl_bundle_, journal_); + auto const sharedValue = makeSharedValue(*stream_ptr_, journal_); // This shouldn't fail since we already computed // the shared value successfully in OverlayImpl @@ -857,7 +857,7 @@ PeerImp::onReadMessage (error_code ec, std::size_t bytes_transferred) read_buffer_.data(), *this); if (ec) return fail("onReadMessage", ec); - if (! stream_.next_layer().is_open()) + if (! socket_.is_open()) return; if(gracefulClose_) return; diff --git a/src/ripple/overlay/impl/PeerImp.h b/src/ripple/overlay/impl/PeerImp.h index 249c0745be..69897f5820 100644 --- a/src/ripple/overlay/impl/PeerImp.h +++ b/src/ripple/overlay/impl/PeerImp.h @@ -94,7 +94,8 @@ private: using clock_type = std::chrono::steady_clock; using error_code = boost::system::error_code; using socket_type = boost::asio::ip::tcp::socket; - using stream_type = boost::asio::ssl::stream ; + using middle_type = boost::beast::tcp_stream; + using stream_type = boost::beast::ssl_stream ; using address_type = boost::asio::ip::address; using endpoint_type = boost::asio::ip::tcp::endpoint; using waitable_timer = boost::asio::basic_waitable_timer; @@ -105,7 +106,7 @@ private: beast::WrappedSink p_sink_; beast::Journal const journal_; beast::Journal const p_journal_; - std::unique_ptr ssl_bundle_; + std::unique_ptr stream_ptr_; socket_type& socket_; stream_type& stream_; boost::asio::strand strand_; @@ -234,13 +235,13 @@ public: std::shared_ptr const& slot, http_request_type&& request, PublicKey const& publicKey, ProtocolVersion protocol, Resource::Consumer consumer, - std::unique_ptr&& ssl_bundle, + std::unique_ptr&& stream_ptr, OverlayImpl& overlay); /** Create outgoing, handshaked peer. */ // VFALCO legacyPublicKey should be implied by the Slot template - PeerImp (Application& app, std::unique_ptr&& ssl_bundle, + PeerImp (Application& app, std::unique_ptr&& stream_ptr, Buffers const& buffers, std::shared_ptr&& slot, http_response_type&& response, Resource::Consumer usage, PublicKey const& publicKey, @@ -541,7 +542,7 @@ private: //------------------------------------------------------------------------------ template -PeerImp::PeerImp (Application& app, std::unique_ptr&& ssl_bundle, +PeerImp::PeerImp (Application& app, std::unique_ptr&& stream_ptr, Buffers const& buffers, std::shared_ptr&& slot, http_response_type&& response, Resource::Consumer usage, PublicKey const& publicKey, @@ -553,9 +554,9 @@ PeerImp::PeerImp (Application& app, std::unique_ptr&& s , p_sink_ (app_.journal("Protocol"), makePrefix(id)) , journal_ (sink_) , p_journal_ (p_sink_) - , ssl_bundle_(std::move(ssl_bundle)) - , socket_ (ssl_bundle_->socket) - , stream_ (ssl_bundle_->stream) + , stream_ptr_(std::move(stream_ptr)) + , socket_ (stream_ptr_->next_layer().socket()) + , stream_ (*stream_ptr_) , strand_ (socket_.get_executor()) , timer_ (waitable_timer{socket_.get_executor()}) , remote_address_ (slot->remote_endpoint()) diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index 88b189f7f7..ee904241c6 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -172,7 +172,7 @@ ServerHandlerImp::onAccept (Session& session, Handoff ServerHandlerImp::onHandoff( Session& session, - std::unique_ptr&& bundle, + std::unique_ptr&& bundle, http_request_type&& request, boost::asio::ip::tcp::endpoint const& remote_address) { diff --git a/src/ripple/rpc/impl/ServerHandlerImp.h b/src/ripple/rpc/impl/ServerHandlerImp.h index 3e5508a8b0..c4f3df26bb 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.h +++ b/src/ripple/rpc/impl/ServerHandlerImp.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -84,6 +86,8 @@ public: }; private: + using socket_type = boost::beast::tcp_stream; + using stream_type = boost::beast::ssl_stream ; Application& app_; Resource::Manager& m_resourceManager; @@ -135,7 +139,7 @@ public: Handoff onHandoff( Session& session, - std::unique_ptr&& bundle, + std::unique_ptr&& bundle, http_request_type&& request, boost::asio::ip::tcp::endpoint const& remote_address); diff --git a/src/ripple/server/impl/BaseHTTPPeer.h b/src/ripple/server/impl/BaseHTTPPeer.h index 5238a8d59d..862de1c299 100644 --- a/src/ripple/server/impl/BaseHTTPPeer.h +++ b/src/ripple/server/impl/BaseHTTPPeer.h @@ -25,6 +25,7 @@ #include #include #include // for is_short_read? +#include #include #include #include @@ -54,7 +55,6 @@ protected: using clock_type = std::chrono::system_clock; using error_code = boost::system::error_code; using endpoint_type = boost::asio::ip::tcp::endpoint; - using waitable_timer = boost::asio::basic_waitable_timer ; using yield_context = boost::asio::yield_context; enum @@ -86,7 +86,6 @@ protected: Handler& handler_; boost::asio::executor_work_guard work_; boost::asio::strand strand_; - waitable_timer timer_; endpoint_type remote_address_; beast::Journal const journal_; @@ -114,7 +113,6 @@ public: Port const& port, Handler& handler, boost::asio::executor const& executor, - waitable_timer timer, beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const& buffers); @@ -147,7 +145,7 @@ protected: cancel_timer(); void - on_timer(error_code ec); + on_timer(); void do_read(yield_context do_yield); @@ -219,7 +217,6 @@ BaseHTTPPeer::BaseHTTPPeer( Port const& port, Handler& handler, boost::asio::executor const& executor, - waitable_timer timer, beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const& buffers) @@ -227,7 +224,6 @@ BaseHTTPPeer::BaseHTTPPeer( , handler_(handler) , work_(executor) , strand_(executor) - , timer_(std::move(timer)) , remote_address_(remote_address) , journal_(journal) { @@ -261,8 +257,7 @@ close() std::bind( (void (BaseHTTPPeer::*)(void)) & BaseHTTPPeer::close, impl().shared_from_this())); - error_code ec; - impl().stream_.lowest_layer().close(ec); + boost::beast::get_lowest_layer(impl().stream_).close(); } //------------------------------------------------------------------------------ @@ -277,7 +272,7 @@ fail(error_code ec, char const* what) ec_ = ec; JLOG(journal_.trace()) << id_ << std::string(what) << ": " << ec.message(); - impl().stream_.lowest_layer().close(ec); + boost::beast::get_lowest_layer(impl().stream_).close(); } } @@ -286,21 +281,12 @@ void BaseHTTPPeer:: start_timer() { - error_code ec; - timer_.expires_from_now( + boost::beast::get_lowest_layer(impl().stream_).expires_after( std::chrono::seconds( remote_address_.address().is_loopback() ? timeoutSecondsLocal : - timeoutSeconds), - ec); - if(ec) - return fail(ec, "start_timer"); - timer_.async_wait(bind_executor( - strand_, - std::bind( - &BaseHTTPPeer::on_timer, - impl().shared_from_this(), - std::placeholders::_1))); + timeoutSeconds) + ); } // Convenience for discarding the error code @@ -309,20 +295,16 @@ void BaseHTTPPeer:: cancel_timer() { - error_code ec; - timer_.cancel(ec); + boost::beast::get_lowest_layer(impl().stream_).expires_never(); } // Called when session times out template void BaseHTTPPeer:: -on_timer(error_code ec) +on_timer() { - if(ec == boost::asio::error::operation_aborted) - return; - if(! ec) - ec = boost::system::errc::make_error_code( + auto ec = boost::system::errc::make_error_code( boost::system::errc::timed_out); fail(ec, "timer"); } @@ -342,6 +324,8 @@ do_read(yield_context do_yield) cancel_timer(); if(ec == boost::beast::http::error::end_of_stream) return do_close(); + if(ec == boost::beast::error::timeout) + return on_timer(); if(ec) return fail(ec, "http::read"); do_request(); @@ -356,6 +340,8 @@ on_write(error_code const& ec, std::size_t bytes_transferred) { cancel_timer(); + if(ec == boost::beast::error::timeout) + return on_timer(); if(ec) return fail(ec, "write"); bytes_out_ += bytes_transferred; @@ -549,8 +535,7 @@ close(bool graceful) return do_close(); } - error_code ec; - impl().stream_.lowest_layer().close(ec); + boost::beast::get_lowest_layer(impl().stream_).close(); } } // ripple diff --git a/src/ripple/server/impl/BasePeer.h b/src/ripple/server/impl/BasePeer.h index c860e87f2f..ceaca93a89 100644 --- a/src/ripple/server/impl/BasePeer.h +++ b/src/ripple/server/impl/BasePeer.h @@ -103,7 +103,7 @@ close() return post( strand_, std::bind(&BasePeer::close, impl().shared_from_this())); error_code ec; - ripple::get_lowest_layer(impl().ws_).close(ec); + ripple::get_lowest_layer(impl().ws_).socket().close(ec); } } // ripple diff --git a/src/ripple/server/impl/BaseWSPeer.h b/src/ripple/server/impl/BaseWSPeer.h index 729e24271f..de4649582a 100644 --- a/src/ripple/server/impl/BaseWSPeer.h +++ b/src/ripple/server/impl/BaseWSPeer.h @@ -529,7 +529,7 @@ fail(error_code ec, String const& what) ec_ = ec; JLOG(this->j_.trace()) << what << ": " << ec.message(); - ripple::get_lowest_layer(impl().ws_).close(ec); + ripple::get_lowest_layer(impl().ws_).socket().close(ec); } } diff --git a/src/ripple/server/impl/Door.h b/src/ripple/server/impl/Door.h index c7756f354c..70e5cfd77f 100644 --- a/src/ripple/server/impl/Door.h +++ b/src/ripple/server/impl/Door.h @@ -25,8 +25,9 @@ #include #include #include -#include +#include #include +#include #include #include #include @@ -55,7 +56,8 @@ private: using protocol_type = boost::asio::ip::tcp; using acceptor_type = protocol_type::acceptor; using endpoint_type = protocol_type::endpoint; - using socket_type = protocol_type::socket; + using socket_type = boost::asio::ip::tcp::socket; + using stream_type = boost::beast::tcp_stream; // Detects SSL on a socket class Detector @@ -66,8 +68,8 @@ private: Port const& port_; Handler& handler_; boost::asio::io_context& ioc_; - socket_type socket_; - timer_type timer_; + stream_type stream_; + socket_type &socket_; endpoint_type remote_address_; boost::asio::io_context::strand strand_; beast::Journal const j_; @@ -77,14 +79,13 @@ private: Port const& port, Handler& handler, boost::asio::io_context& ioc, - socket_type&& socket, + stream_type&& stream, endpoint_type remote_address, beast::Journal j); void run(); void close() override; private: - void do_timer (yield_context yield); void do_detect (yield_context yield); }; @@ -120,74 +121,24 @@ public: private: template void create (bool ssl, ConstBufferSequence const& buffers, - socket_type&& socket, endpoint_type remote_address); + stream_type&& stream, endpoint_type remote_address); void do_accept (yield_context yield); }; -/** Detect SSL client handshakes. - Analyzes the bytes in the provided buffer to detect the SSL client - handshake. If the buffer contains insufficient data, more data will be - read from the stream until there is enough to determine a result. - No bytes are discarded from buf. Any additional bytes read are retained. - buf must provide an interface compatible with boost::asio::streambuf - http://boost.org/doc/libs/1_56_0/doc/html/boost_asio/reference/streambuf.html - See - http://www.ietf.org/rfc/rfc2246.txt - Section 7.4. Handshake protocol - @param socket The stream to read from - @param buf A buffer to hold the received data - @param do_yield A do_yield context - @return The error code if an error occurs, otherwise `true` if - the data read indicates the SSL client handshake. -*/ -template -std::pair -detect_ssl (Socket& socket, StreamBuf& buf, Yield do_yield) -{ - std::pair result; - result.second = false; - for(;;) - { - std::size_t const max = 4; // the most bytes we could need - unsigned char data[max]; - auto const bytes = boost::asio::buffer_copy ( - boost::asio::buffer(data), buf.data()); - - if (bytes > 0) - { - if (data[0] != 0x16) // message type 0x16 = "SSL Handshake" - break; - } - - if (bytes >= max) - { - result.second = true; - break; - } - - buf.commit(boost::asio::async_read (socket, - buf.prepare(max - bytes), boost::asio::transfer_at_least(1), - do_yield[result.first])); - if (result.first) - break; - } - return result; -} - template Door::Detector::Detector( Port const& port, Handler& handler, boost::asio::io_context& ioc, - socket_type&& socket, + stream_type&& stream, endpoint_type remote_address, beast::Journal j) : port_(port) , handler_(handler) , ioc_(ioc) - , socket_(std::move(socket)) - , timer_(ioc_) + , stream_(std::move(stream)) + , socket_(stream_.socket()) , remote_address_(remote_address) , strand_(ioc_) , j_(j) @@ -199,13 +150,8 @@ void Door::Detector:: run() { - // do_detect must be called before do_timer or else - // the timer can be canceled before it gets set. boost::asio::spawn(strand_, std::bind (&Detector::do_detect, this->shared_from_this(), std::placeholders::_1)); - - boost::asio::spawn(strand_, std::bind (&Detector::do_timer, - this->shared_from_this(), std::placeholders::_1)); } template @@ -213,23 +159,7 @@ void Door::Detector:: close() { - error_code ec; - socket_.close(ec); - timer_.cancel(ec); -} - -template -void -Door::Detector:: -do_timer(yield_context do_yield) -{ - error_code ec; // ignored - while (socket_.is_open()) - { - timer_.async_wait (do_yield[ec]); - if (timer_.expires_from_now() <= std::chrono::seconds(0)) - socket_.close(ec); - } + stream_.close(); } template @@ -238,23 +168,23 @@ Door::Detector:: do_detect(boost::asio::yield_context do_yield) { boost::beast::multi_buffer buf(16); - timer_.expires_from_now(std::chrono::seconds(15)); - auto const [ec, ssl] = detect_ssl(socket_, buf, do_yield); - error_code unused; - timer_.cancel(unused); + stream_.expires_after(std::chrono::seconds(15)); + boost::system::error_code ec; + bool const ssl = async_detect_ssl(stream_, buf, do_yield[ec]); + stream_.expires_never(); if (! ec) { if (ssl) { if (auto sp = ios().template emplace>( port_, handler_, ioc_, j_, remote_address_, - buf.data(), std::move(socket_))) + buf.data(), std::move(stream_))) sp->run(); return; } if (auto sp = ios().template emplace>( port_, handler_, ioc_, j_, remote_address_, - buf.data(), std::move(socket_))) + buf.data(), std::move(stream_))) sp->run(); return; } @@ -357,19 +287,19 @@ template void Door:: create(bool ssl, ConstBufferSequence const& buffers, - socket_type&& socket, endpoint_type remote_address) + stream_type&& stream, endpoint_type remote_address) { if (ssl) { if (auto sp = ios().template emplace>( port_, handler_, ioc_, j_, remote_address, - buffers, std::move(socket))) + buffers, std::move(stream))) sp->run(); return; } if (auto sp = ios().template emplace>( port_, handler_, ioc_, j_, remote_address, - buffers, std::move(socket))) + buffers, std::move(stream))) sp->run(); } @@ -382,7 +312,8 @@ do_accept(boost::asio::yield_context do_yield) { error_code ec; endpoint_type remote_address; - socket_type socket (ioc_); + stream_type stream (ioc_); + socket_type &socket = stream.socket(); acceptor_.async_accept (socket, remote_address, do_yield[ec]); if (ec && ec != boost::asio::error::operation_aborted) { @@ -397,14 +328,14 @@ do_accept(boost::asio::yield_context do_yield) if (ssl_ && plain_) { if (auto sp = ios().template emplace( - port_, handler_, ioc_, std::move(socket), + port_, handler_, ioc_, std::move(stream), remote_address, j_)) sp->run(); } else if (ssl_ || plain_) { create(ssl_, boost::asio::null_buffers{}, - std::move(socket), remote_address); + std::move(stream), remote_address); } } } diff --git a/src/ripple/server/impl/PlainHTTPPeer.h b/src/ripple/server/impl/PlainHTTPPeer.h index 9f249dacfb..fa7cfae16c 100644 --- a/src/ripple/server/impl/PlainHTTPPeer.h +++ b/src/ripple/server/impl/PlainHTTPPeer.h @@ -23,6 +23,7 @@ #include #include #include +#include #include namespace ripple { @@ -34,11 +35,12 @@ class PlainHTTPPeer { private: friend class BaseHTTPPeer; - using waitable_timer = typename BaseHTTPPeer::waitable_timer; using socket_type = boost::asio::ip::tcp::socket; + using stream_type = boost::beast::tcp_stream; using endpoint_type = boost::asio::ip::tcp::endpoint; - socket_type stream_; + stream_type stream_; + socket_type& socket_; public: template @@ -49,7 +51,7 @@ public: beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const& buffers, - socket_type&& socket); + stream_type&& stream); void run(); @@ -75,23 +77,23 @@ PlainHTTPPeer::PlainHTTPPeer( beast::Journal journal, endpoint_type remote_endpoint, ConstBufferSequence const& buffers, - socket_type&& socket) + stream_type&& stream) : BaseHTTPPeer( port, handler, ioc.get_executor(), - waitable_timer{ioc}, journal, remote_endpoint, buffers) - , stream_(std::move(socket)) + , stream_(std::move(stream)) + , socket_(stream_.socket()) { // Set TCP_NODELAY on loopback interfaces, // otherwise Nagle's algorithm makes Env // tests run slower on Linux systems. // if(remote_endpoint.address().is_loopback()) - stream_.set_option(boost::asio::ip::tcp::no_delay{true}); + socket_.set_option(boost::asio::ip::tcp::no_delay{true}); } template @@ -107,7 +109,7 @@ run() return; } - if (! stream_.is_open()) + if (! socket_.is_open()) return; boost::asio::spawn(this->strand_, std::bind(&PlainHTTPPeer::do_read, @@ -141,7 +143,7 @@ do_request() { // half-close on Connection: close if (! what.keep_alive) - stream_.shutdown(socket_type::shutdown_receive, ec); + socket_.shutdown(socket_type::shutdown_receive, ec); if (ec) return this->fail(ec, "request"); return this->write(what.response, what.keep_alive); @@ -149,7 +151,7 @@ do_request() // Perform half-close when Connection: close and not SSL if (! beast::rfc2616::is_keep_alive(this->message_)) - stream_.shutdown(socket_type::shutdown_receive, ec); + socket_.shutdown(socket_type::shutdown_receive, ec); if (ec) return this->fail(ec, "request"); // legacy @@ -162,7 +164,7 @@ PlainHTTPPeer:: do_close() { boost::system::error_code ec; - stream_.shutdown(socket_type::shutdown_send, ec); + socket_.shutdown(socket_type::shutdown_send, ec); } } // ripple diff --git a/src/ripple/server/impl/PlainWSPeer.h b/src/ripple/server/impl/PlainWSPeer.h index e364909f58..51b0cef097 100644 --- a/src/ripple/server/impl/PlainWSPeer.h +++ b/src/ripple/server/impl/PlainWSPeer.h @@ -21,6 +21,7 @@ #define RIPPLE_SERVER_PLAINWSPEER_H_INCLUDED #include +#include #include namespace ripple { @@ -37,7 +38,7 @@ class PlainWSPeer using error_code = boost::system::error_code; using endpoint_type = boost::asio::ip::tcp::endpoint; using waitable_timer = boost::asio::basic_waitable_timer ; - using socket_type = boost::asio::ip::tcp::socket; + using socket_type = boost::beast::tcp_stream; boost::beast::websocket::stream ws_; diff --git a/src/ripple/server/impl/SSLHTTPPeer.h b/src/ripple/server/impl/SSLHTTPPeer.h index 8d3e656e27..dbe2ed7b23 100644 --- a/src/ripple/server/impl/SSLHTTPPeer.h +++ b/src/ripple/server/impl/SSLHTTPPeer.h @@ -22,7 +22,11 @@ #include #include -#include +#include +#include +#include +#include +#include #include namespace ripple { @@ -34,15 +38,16 @@ class SSLHTTPPeer { private: friend class BaseHTTPPeer; - using waitable_timer = typename BaseHTTPPeer::waitable_timer; using socket_type = boost::asio::ip::tcp::socket; - using stream_type = boost::asio::ssl::stream ; + using middle_type = boost::beast::tcp_stream; + using stream_type = boost::beast::ssl_stream ; using endpoint_type = boost::asio::ip::tcp::endpoint; using yield_context = boost::asio::yield_context; using error_code = boost::system::error_code; - std::unique_ptr ssl_bundle_; + std::unique_ptr stream_ptr_; stream_type& stream_; + socket_type& socket_; public: template @@ -53,7 +58,7 @@ public: beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const& buffers, - socket_type&& socket); + middle_type&& stream); void run(); @@ -86,18 +91,18 @@ SSLHTTPPeer::SSLHTTPPeer( beast::Journal journal, endpoint_type remote_address, ConstBufferSequence const& buffers, - socket_type&& socket) + middle_type&& stream) : BaseHTTPPeer( port, handler, ioc.get_executor(), - waitable_timer{ioc}, journal, remote_address, buffers) - , ssl_bundle_(std::make_unique( - port.context, std::move(socket))) - , stream_(ssl_bundle_->stream) + , stream_ptr_(std::make_unique( + middle_type(std::move(stream)), *port.context)) + , stream_(*stream_ptr_) + , socket_(stream_.next_layer().socket()) { } @@ -114,7 +119,7 @@ run() this->shared_from_this())); return; } - if (! stream_.lowest_layer().is_open()) + if (! socket_.is_open()) return; boost::asio::spawn(this->strand_, std::bind( &SSLHTTPPeer::do_handshake, this->shared_from_this(), @@ -128,7 +133,7 @@ websocketUpgrade() { auto ws = this->ios().template emplace>( this->port_, this->handler_, this->remote_address_, - std::move(this->message_), std::move(this->ssl_bundle_), + std::move(this->message_), std::move(this->stream_ptr_), this->journal_); return ws; } @@ -144,6 +149,8 @@ do_handshake(yield_context do_yield) this->read_buf_.consume(stream_.async_handshake( stream_type::server, this->read_buf_.data(), do_yield[ec])); this->cancel_timer(); + if(ec == boost::beast::error::timeout) + return this->on_timer(); if (ec) return this->fail(ec, "handshake"); bool const http = @@ -168,7 +175,7 @@ do_request() { ++this->request_count_; auto const what = this->handler_.onHandoff(this->session(), - std::move(ssl_bundle_), std::move(this->message_), + std::move(stream_ptr_), std::move(this->message_), this->remote_address_); if(what.moved) return; @@ -208,7 +215,7 @@ on_shutdown(error_code ec) } // Close socket now in case this->destructor is delayed - stream_.lowest_layer().close(ec); + stream_.next_layer().close(); } } // ripple diff --git a/src/ripple/server/impl/SSLWSPeer.h b/src/ripple/server/impl/SSLWSPeer.h index 358cba393a..aae39edfed 100644 --- a/src/ripple/server/impl/SSLWSPeer.h +++ b/src/ripple/server/impl/SSLWSPeer.h @@ -22,7 +22,11 @@ #include #include -#include +#include +#include +#include +#include +#include #include #include @@ -39,12 +43,13 @@ class SSLWSPeer using clock_type = std::chrono::system_clock; using error_code = boost::system::error_code; using endpoint_type = boost::asio::ip::tcp::endpoint; + using socket_type = boost::beast::tcp_stream; + using stream_type = boost::beast::ssl_stream ; using waitable_timer = boost::asio::basic_waitable_timer ; - std::unique_ptr ssl_bundle_; - boost::beast::websocket::stream< - beast::asio::ssl_bundle::stream_type&> ws_; + std::unique_ptr stream_ptr_; + boost::beast::websocket::stream ws_; public: template @@ -53,8 +58,7 @@ public: Handler& handler, endpoint_type remote_endpoint, boost::beast::http::request&& request, - std::unique_ptr< - beast::asio::ssl_bundle>&& ssl_bundle, + std::unique_ptr&& stream_ptr, beast::Journal journal); }; @@ -67,18 +71,18 @@ SSLWSPeer::SSLWSPeer( Handler& handler, endpoint_type remote_endpoint, boost::beast::http::request&& request, - std::unique_ptr&& ssl_bundle, + std::unique_ptr&& stream_ptr, beast::Journal journal) : BaseWSPeer( port, handler, - ssl_bundle->socket.get_executor(), - waitable_timer{ssl_bundle->socket.get_executor()}, + stream_ptr->get_executor(), + waitable_timer{stream_ptr->get_executor()}, remote_endpoint, std::move(request), journal) - , ssl_bundle_(std::move(ssl_bundle)) - , ws_(ssl_bundle_->stream) + , stream_ptr_(std::move(stream_ptr)) + , ws_(*stream_ptr_) { } diff --git a/src/test/server/Server_test.cpp b/src/test/server/Server_test.cpp index 45a7e3d1f7..43626e19e7 100644 --- a/src/test/server/Server_test.cpp +++ b/src/test/server/Server_test.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,6 +38,9 @@ namespace ripple { namespace test { +using socket_type = boost::beast::tcp_stream; +using stream_type = boost::beast::ssl_stream ; + class Server_test : public beast::unit_test::suite { public: @@ -104,7 +109,7 @@ public: Handoff onHandoff (Session& session, - std::unique_ptr && bundle, + std::unique_ptr && bundle, http_request_type&& request, boost::asio::ip::tcp::endpoint remote_address) { @@ -309,7 +314,7 @@ public: Handoff onHandoff (Session& session, - std::unique_ptr && bundle, + std::unique_ptr && bundle, http_request_type&& request, boost::asio::ip::tcp::endpoint remote_address) {