diff --git a/Jamfile b/Jamfile index 39af8a6..b9cf9b9 100644 --- a/Jamfile +++ b/Jamfile @@ -78,6 +78,12 @@ lib simulator # make sure asio uses std::chrono BOOST_ASIO_HAS_STD_CHRONO + # io_executor only implements the legacy (Networking TS v1) executor + # concept: this falls any_io_executor back to boost::asio::executor, + # which it can wrap, so boost::asio::ssl::stream's bookkeeping timers + # work for consumers that include simulator/ssl.hpp. + BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT + # disable auto-link BOOST_ALL_NO_LIB @@ -96,6 +102,7 @@ lib simulator BOOST_ASIO_DISABLE_BOOST_DATE_TIME BOOST_ASIO_HAS_MOVE BOOST_ASIO_ENABLE_CANCELIO + BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT multi include shared:SIMULATOR_LINKING_SHARED diff --git a/include/simulator/ssl.hpp b/include/simulator/ssl.hpp new file mode 100644 index 0000000..9e47936 --- /dev/null +++ b/include/simulator/ssl.hpp @@ -0,0 +1,44 @@ +/* + +Copyright (c) 2026, Arvid Norberg +All rights reserved. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifndef SIMULATOR_SSL_HPP_INCLUDED +#define SIMULATOR_SSL_HPP_INCLUDED + +#include "simulator/simulator.hpp" + +#include "simulator/push_warnings.hpp" +#include +#include "simulator/pop_warnings.hpp" + +namespace sim { +namespace asio { + +namespace ssl +{ + using boost::asio::ssl::context; + using boost::asio::ssl::stream_base; + using boost::asio::ssl::verify_context; + + template + using stream = boost::asio::ssl::stream; +} // ssl + +} // asio +} // sim + +#endif diff --git a/src/tcp_socket.cpp b/src/tcp_socket.cpp index 987129c..918efc8 100644 --- a/src/tcp_socket.cpp +++ b/src/tcp_socket.cpp @@ -537,6 +537,15 @@ namespace ip { std::vector const& bufs , boost::system::error_code& ec) { + // a zero-sized read always completes immediately with 0 bytes; + // boost.asio's SSL implementation relies on this to post a + // completion handler without transferring any data. + if (boost::asio::buffer_size(bufs) == 0) + { + ec.clear(); + return 0; + } + assert(!bufs.empty()); if (!m_open) { @@ -635,8 +644,18 @@ namespace ip { void tcp::socket::async_read_some_impl(std::vector const& bufs , aux::function handler) { + // a zero-sized read always completes immediately with 0 bytes + // transferred, regardless of connection or queue state. boost.asio's + // SSL implementation relies on this to bounce a completion handler + // through the executor without actually transferring any data. + if (boost::asio::buffer_size(bufs) == 0) + { + post(m_io_service, aux::make_malloc(std::bind(std::move(handler) + , boost::system::error_code(), std::size_t(0)))); + return; + } + assert(!bufs.empty()); - assert(bufs[0].size()); boost::system::error_code ec; std::size_t bytes_transferred = read_some_impl(bufs, ec);