From 8c98c45ff8b80b27996dad9fe0872bc9e130db1b Mon Sep 17 00:00:00 2001 From: Lee *!* Clagett Date: Tue, 17 Dec 2024 16:40:15 -0500 Subject: [PATCH] Fix build with boost ASIO 1.87. Support boost 1.66+ --- .../epee/include/net/abstract_tcp_server2.h | 44 +-- .../epee/include/net/abstract_tcp_server2.inl | 331 +++++++----------- contrib/epee/include/net/connection_basic.hpp | 9 +- .../epee/include/net/http_server_impl_base.h | 2 +- .../net/levin_protocol_handler_async.h | 2 +- contrib/epee/include/net/net_helper.h | 24 +- contrib/epee/include/net/net_ssl.h | 2 + contrib/epee/include/net/net_utils_base.h | 10 +- contrib/epee/src/connection_basic.cpp | 22 +- contrib/epee/src/net_helper.cpp | 43 +-- contrib/epee/src/net_ssl.cpp | 15 +- src/common/util.cpp | 2 +- src/cryptonote_core/blockchain.cpp | 7 +- src/cryptonote_core/blockchain.h | 6 +- src/cryptonote_protocol/levin_notify.cpp | 60 ++-- src/cryptonote_protocol/levin_notify.h | 4 +- src/net/parse.cpp | 2 +- src/net/socks.cpp | 18 +- src/net/socks.h | 4 +- src/net/socks_connect.cpp | 2 +- src/p2p/net_node.cpp | 2 +- src/p2p/net_node.h | 6 +- src/p2p/net_node.inl | 26 +- src/rpc/rpc_args.cpp | 8 +- tests/fuzz/levin.cpp | 10 +- tests/net_load_tests/net_load_tests.h | 2 +- tests/net_load_tests/srv.cpp | 2 +- tests/unit_tests/epee_boosted_tcp_server.cpp | 54 +-- .../epee_levin_protocol_handler_async.cpp | 8 +- tests/unit_tests/levin.cpp | 114 +++--- tests/unit_tests/net.cpp | 20 +- tests/unit_tests/node_server.cpp | 122 ++++--- 32 files changed, 440 insertions(+), 543 deletions(-) diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/net/abstract_tcp_server2.h index bc0da66e299..d7e7fa455e9 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.h +++ b/contrib/epee/include/net/abstract_tcp_server2.h @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -100,8 +101,8 @@ namespace net_utils using ec_t = boost::system::error_code; using handshake_t = boost::asio::ssl::stream_base::handshake_type; - using io_context_t = boost::asio::io_service; - using strand_t = boost::asio::io_service::strand; + using io_context_t = boost::asio::io_context; + using strand_t = boost::asio::io_context::strand; using socket_t = boost::asio::ip::tcp::socket; using network_throttle_t = epee::net_utils::network_throttle; @@ -267,13 +268,14 @@ namespace net_utils bool stop_signal_sent; }; - /// Construct a connection with the given io_service. - explicit connection( boost::asio::io_service& io_service, + /// Construct a connection with the given io_context. + explicit connection( boost::asio::io_context& io_context, std::shared_ptr state, t_connection_type connection_type, epee::net_utils::ssl_support_t ssl_support); - explicit connection( boost::asio::ip::tcp::socket&& sock, + explicit connection( boost::asio::io_context& io_context, + boost::asio::ip::tcp::socket&& sock, std::shared_ptr state, t_connection_type connection_type, epee::net_utils::ssl_support_t ssl_support); @@ -306,7 +308,7 @@ namespace net_utils virtual bool close(); virtual bool call_run_once_service_io(); virtual bool request_callback(); - virtual boost::asio::io_service& get_io_service(); + virtual boost::asio::io_context& get_io_context(); virtual bool add_ref(); virtual bool release(); //------------------------------------------------------ @@ -336,7 +338,7 @@ namespace net_utils /// serve up files from the given directory. boosted_tcp_server(t_connection_type connection_type); - explicit boosted_tcp_server(boost::asio::io_service& external_io_service, t_connection_type connection_type); + explicit boosted_tcp_server(boost::asio::io_context& external_io_context, t_connection_type connection_type); ~boosted_tcp_server(); std::map server_type_map; @@ -349,7 +351,7 @@ namespace net_utils const std::string port_ipv6 = "", const std::string address_ipv6 = "::", bool use_ipv6 = false, bool require_ipv4 = true, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect); - /// Run the server's io_service loop. + /// Run the server's io_context loop. bool run_server(size_t threads_count, bool wait = true, const boost::thread::attributes& attrs = boost::thread::attributes()); /// wait for service workers stop @@ -409,7 +411,7 @@ namespace net_utils return connections_count; } - boost::asio::io_service& get_io_service(){return io_service_;} + boost::asio::io_context& get_io_context(){return io_context_;} struct idle_callback_conext_base { @@ -417,7 +419,7 @@ namespace net_utils virtual bool call_handler(){return true;} - idle_callback_conext_base(boost::asio::io_service& io_serice): + idle_callback_conext_base(boost::asio::io_context& io_serice): m_timer(io_serice) {} boost::asio::deadline_timer m_timer; @@ -426,7 +428,7 @@ namespace net_utils template struct idle_callback_conext: public idle_callback_conext_base { - idle_callback_conext(boost::asio::io_service& io_serice, t_handler& h, uint64_t period): + idle_callback_conext(boost::asio::io_context& io_serice, t_handler& h, uint64_t period): idle_callback_conext_base(io_serice), m_handler(h) {this->m_period = period;} @@ -442,7 +444,7 @@ namespace net_utils template bool add_idle_handler(t_handler t_callback, uint64_t timeout_ms) { - boost::shared_ptr> ptr(new idle_callback_conext(io_service_, t_callback, timeout_ms)); + boost::shared_ptr> ptr(new idle_callback_conext(io_context_, t_callback, timeout_ms)); //needed call handler here ?... ptr->m_timer.expires_from_now(boost::posix_time::milliseconds(ptr->m_period)); ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server::global_timer_handler, this, ptr)); @@ -461,14 +463,14 @@ namespace net_utils } template - bool async_call(t_handler t_callback) + bool async_call(t_handler&& t_callback) { - io_service_.post(t_callback); + boost::asio::post(io_context_, std::forward(t_callback)); return true; } private: - /// Run the server's io_service loop. + /// Run the server's io_context loop. bool worker_thread(); /// Handle completion of an asynchronous accept operation. void handle_accept_ipv4(const boost::system::error_code& e); @@ -479,18 +481,18 @@ namespace net_utils const std::shared_ptr::shared_state> m_state; - /// The io_service used to perform asynchronous operations. + /// The io_context used to perform asynchronous operations. struct worker { worker() - : io_service(), work(io_service) + : io_context(), work(io_context.get_executor()) {} - boost::asio::io_service io_service; - boost::asio::io_service::work work; + boost::asio::io_context io_context; + boost::asio::executor_work_guard work; }; - std::unique_ptr m_io_service_local_instance; - boost::asio::io_service& io_service_; + std::unique_ptr m_io_context_local_instance; + boost::asio::io_context& io_context_; /// Acceptor used to listen for incoming connections. boost::asio::ip::tcp::acceptor acceptor_; diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index d88f1819421..9bb552508ff 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -31,11 +31,12 @@ // - +#include #include #include #include #include +#include #include #include // TODO #include // TODO @@ -145,23 +146,19 @@ namespace net_utils if (m_state.timers.general.wait_expire) { m_state.timers.general.cancel_expire = true; m_state.timers.general.reset_expire = true; - ec_t ec; - m_timers.general.expires_from_now( + m_timers.general.expires_after( std::min( - duration + (add ? m_timers.general.expires_from_now() : duration_t{}), + duration + (add ? (m_timers.general.expiry() - std::chrono::steady_clock::now()) : duration_t{}), get_default_timeout() - ), - ec + ) ); } else { - ec_t ec; - m_timers.general.expires_from_now( + m_timers.general.expires_after( std::min( - duration + (add ? m_timers.general.expires_from_now() : duration_t{}), + duration + (add ? (m_timers.general.expiry() - std::chrono::steady_clock::now()) : duration_t{}), get_default_timeout() - ), - ec + ) ); async_wait_timer(); } @@ -202,8 +199,7 @@ namespace net_utils return; m_state.timers.general.cancel_expire = true; m_state.timers.general.reset_expire = false; - ec_t ec; - m_timers.general.cancel(ec); + m_timers.general.cancel(); } template @@ -225,7 +221,8 @@ namespace net_utils m_state.data.read.buffer.size() ), boost::asio::transfer_exactly(epee::net_utils::get_ssl_magic_size()), - m_strand.wrap( + boost::asio::bind_executor( + m_strand, [this, self](const ec_t &ec, size_t bytes_transferred){ std::lock_guard guard(m_state.lock); m_state.socket.wait_read = false; @@ -246,7 +243,8 @@ namespace net_utils ) { m_state.ssl.enabled = false; m_state.socket.handle_read = true; - connection_basic::strand_.post( + boost::asio::post( + connection_basic::strand_, [this, self, bytes_transferred]{ bool success = m_handler.handle_recv( reinterpret_cast(m_state.data.read.buffer.data()), @@ -304,7 +302,8 @@ namespace net_utils static_cast( connection_basic::get_state() ).ssl_options().configure(connection_basic::socket_, handshake); - m_strand.post( + boost::asio::post( + m_strand, [this, self, on_handshake]{ connection_basic::socket_.async_handshake( handshake, @@ -313,7 +312,7 @@ namespace net_utils m_state.ssl.forced ? 0 : epee::net_utils::get_ssl_magic_size() ), - m_strand.wrap(on_handshake) + boost::asio::bind_executor(m_strand, on_handshake) ); } ); @@ -345,8 +344,7 @@ namespace net_utils }; const auto duration = calc_duration(); if (duration > duration_t{}) { - ec_t ec; - m_timers.throttle.in.expires_from_now(duration, ec); + m_timers.throttle.in.expires_after(duration); m_state.timers.throttle.in.wait_expire = true; m_timers.throttle.in.async_wait([this, self](const ec_t &ec){ std::lock_guard guard(m_state.lock); @@ -401,7 +399,8 @@ namespace net_utils // writes until the connection terminates without deadlocking waiting // for handle_recv. m_state.socket.handle_read = true; - connection_basic::strand_.post( + boost::asio::post( + connection_basic::strand_, [this, self, bytes_transferred]{ bool success = m_handler.handle_recv( reinterpret_cast(m_state.data.read.buffer.data()), @@ -428,17 +427,18 @@ namespace net_utils m_state.data.read.buffer.data(), m_state.data.read.buffer.size() ), - m_strand.wrap(on_read) + boost::asio::bind_executor(m_strand, on_read) ); else - m_strand.post( + boost::asio::post( + m_strand, [this, self, on_read]{ connection_basic::socket_.async_read_some( boost::asio::buffer( m_state.data.read.buffer.data(), m_state.data.read.buffer.size() ), - m_strand.wrap(on_read) + boost::asio::bind_executor(m_strand, on_read) ); } ); @@ -473,8 +473,7 @@ namespace net_utils }; const auto duration = calc_duration(); if (duration > duration_t{}) { - ec_t ec; - m_timers.throttle.out.expires_from_now(duration, ec); + m_timers.throttle.out.expires_after(duration); m_state.timers.throttle.out.wait_expire = true; m_timers.throttle.out.async_wait([this, self](const ec_t &ec){ std::lock_guard guard(m_state.lock); @@ -539,10 +538,11 @@ namespace net_utils m_state.data.write.queue.back().data(), m_state.data.write.queue.back().size() ), - m_strand.wrap(on_write) + boost::asio::bind_executor(m_strand, on_write) ); else - m_strand.post( + boost::asio::post( + m_strand, [this, self, on_write]{ boost::asio::async_write( connection_basic::socket_, @@ -550,7 +550,7 @@ namespace net_utils m_state.data.write.queue.back().data(), m_state.data.write.queue.back().size() ), - m_strand.wrap(on_write) + boost::asio::bind_executor(m_strand, on_write) ); } ); @@ -587,10 +587,11 @@ namespace net_utils terminate(); } }; - m_strand.post( + boost::asio::post( + m_strand, [this, self, on_shutdown]{ connection_basic::socket_.async_shutdown( - m_strand.wrap(on_shutdown) + boost::asio::bind_executor(m_strand, on_shutdown) ); } ); @@ -605,15 +606,13 @@ namespace net_utils wait_socket = m_state.socket.cancel_handshake = true; if (m_state.timers.throttle.in.wait_expire) { m_state.timers.throttle.in.cancel_expire = true; - ec_t ec; - m_timers.throttle.in.cancel(ec); + m_timers.throttle.in.cancel(); } if (m_state.socket.wait_read) wait_socket = m_state.socket.cancel_read = true; if (m_state.timers.throttle.out.wait_expire) { m_state.timers.throttle.out.cancel_expire = true; - ec_t ec; - m_timers.throttle.out.cancel(ec); + m_timers.throttle.out.cancel(); } if (m_state.socket.wait_write) wait_socket = m_state.socket.cancel_write = true; @@ -860,7 +859,7 @@ namespace net_utils ipv4_network_address{ uint32_t{ boost::asio::detail::socket_ops::host_to_network_long( - endpoint.address().to_v4().to_ulong() + endpoint.address().to_v4().to_uint() ) }, endpoint.port() @@ -938,7 +937,8 @@ namespace net_utils ssl_support_t ssl_support ): connection( - std::move(socket_t{io_context}), + io_context, + socket_t{io_context}, std::move(shared_state), connection_type, ssl_support @@ -948,15 +948,16 @@ namespace net_utils template connection::connection( + io_context_t &io_context, socket_t &&socket, std::shared_ptr shared_state, t_connection_type connection_type, ssl_support_t ssl_support ): - connection_basic(std::move(socket), shared_state, ssl_support), + connection_basic(io_context, std::move(socket), shared_state, ssl_support), m_handler(this, *shared_state, m_conn_context), m_connection_type(connection_type), - m_io_context{GET_IO_SERVICE(connection_basic::socket_)}, + m_io_context{io_context}, m_strand{m_io_context}, m_timers{m_io_context} { @@ -1075,20 +1076,23 @@ namespace net_utils return false; auto self = connection::shared_from_this(); ++m_state.protocol.wait_callback; - connection_basic::strand_.post([this, self]{ - m_handler.handle_qued_callback(); - std::lock_guard guard(m_state.lock); - --m_state.protocol.wait_callback; - if (m_state.status == status_t::INTERRUPTED) - on_interrupted(); - else if (m_state.status == status_t::TERMINATING) - on_terminating(); - }); + boost::asio::post( + connection_basic::strand_, + [this, self]{ + m_handler.handle_qued_callback(); + std::lock_guard guard(m_state.lock); + --m_state.protocol.wait_callback; + if (m_state.status == status_t::INTERRUPTED) + on_interrupted(); + else if (m_state.status == status_t::TERMINATING) + on_terminating(); + } + ); return true; } template - typename connection::io_context_t &connection::get_io_service() + typename connection::io_context_t &connection::get_io_context() { return m_io_context; } @@ -1128,10 +1132,10 @@ namespace net_utils template boosted_tcp_server::boosted_tcp_server( t_connection_type connection_type ) : m_state(std::make_shared::shared_state>()), - m_io_service_local_instance(new worker()), - io_service_(m_io_service_local_instance->io_service), - acceptor_(io_service_), - acceptor_ipv6(io_service_), + m_io_context_local_instance(new worker()), + io_context_(m_io_context_local_instance->io_context), + acceptor_(io_context_), + acceptor_ipv6(io_context_), default_remote(), m_stop_signal_sent(false), m_port(0), m_threads_count(0), @@ -1145,11 +1149,11 @@ namespace net_utils } template - boosted_tcp_server::boosted_tcp_server(boost::asio::io_service& extarnal_io_service, t_connection_type connection_type) : + boosted_tcp_server::boosted_tcp_server(boost::asio::io_context& extarnal_io_context, t_connection_type connection_type) : m_state(std::make_shared::shared_state>()), - io_service_(extarnal_io_service), - acceptor_(io_service_), - acceptor_ipv6(io_service_), + io_context_(extarnal_io_context), + acceptor_(io_context_), + acceptor_ipv6(io_context_), default_remote(), m_stop_signal_sent(false), m_port(0), m_threads_count(0), @@ -1194,79 +1198,71 @@ namespace net_utils if (ssl_options) m_state->configure_ssl(std::move(ssl_options)); - std::string ipv4_failed = ""; - std::string ipv6_failed = ""; - try + boost::system::error_code error{}; + boost::asio::ip::tcp::resolver resolver(io_context_); + auto results = resolver.resolve(address, boost::lexical_cast(port), error); + if (error || (results.empty() && require_ipv4)) + throw boost::system::system_error{error, "Unable to find IPv4 or IPv6 address"}; + + if (!results.empty()) { - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(address, boost::lexical_cast(port), boost::asio::ip::tcp::resolver::query::canonical_name); - boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); - acceptor_.open(endpoint.protocol()); + try + { + acceptor_.open(results.begin()->endpoint().protocol()); #if !defined(_WIN32) - acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); #endif - acceptor_.bind(endpoint); - acceptor_.listen(); - boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_.local_endpoint(); - m_port = binded_endpoint.port(); - MDEBUG("start accept (IPv4)"); - new_connection_.reset(new connection(io_service_, m_state, m_connection_type, m_state->ssl_options().support)); - acceptor_.async_accept(new_connection_->socket(), - boost::bind(&boosted_tcp_server::handle_accept_ipv4, this, - boost::asio::placeholders::error)); - } - catch (const std::exception &e) - { - ipv4_failed = e.what(); - } - - if (ipv4_failed != "") - { - MERROR("Failed to bind IPv4: " << ipv4_failed); - if (require_ipv4) + acceptor_.bind(*results.begin()); + acceptor_.listen(); + boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_.local_endpoint(); + m_port = binded_endpoint.port(); + MDEBUG("start accept (IPv4)"); + new_connection_.reset(new connection(io_context_, m_state, m_connection_type, m_state->ssl_options().support)); + acceptor_.async_accept(new_connection_->socket(), + boost::bind(&boosted_tcp_server::handle_accept_ipv4, this, + boost::asio::placeholders::error)); + } + catch (const std::exception &e) { - throw std::runtime_error("Failed to bind IPv4 (set to required)"); + MERROR("Failed to bind IPv4: " << e.what()); + if (require_ipv4) + throw; } } if (use_ipv6) { + if (port_ipv6 == 0) port_ipv6 = port; // default arg means bind to same port as ipv4 + + boost::system::error_code error{}; + boost::asio::ip::tcp::resolver resolver(io_context_); + results = resolver.resolve(address_ipv6, boost::lexical_cast(port_ipv6), error); + if (error || results.empty()) + throw boost::system::system_error{error, "Unable to find IPv6 address"}; + try { - if (port_ipv6 == 0) port_ipv6 = port; // default arg means bind to same port as ipv4 - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(address_ipv6, boost::lexical_cast(port_ipv6), boost::asio::ip::tcp::resolver::query::canonical_name); - boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); - acceptor_ipv6.open(endpoint.protocol()); + acceptor_ipv6.open(results.begin()->endpoint().protocol()); #if !defined(_WIN32) acceptor_ipv6.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); #endif acceptor_ipv6.set_option(boost::asio::ip::v6_only(true)); - acceptor_ipv6.bind(endpoint); + acceptor_ipv6.bind(*results.begin()); acceptor_ipv6.listen(); boost::asio::ip::tcp::endpoint binded_endpoint = acceptor_ipv6.local_endpoint(); m_port_ipv6 = binded_endpoint.port(); MDEBUG("start accept (IPv6)"); - new_connection_ipv6.reset(new connection(io_service_, m_state, m_connection_type, m_state->ssl_options().support)); + new_connection_ipv6.reset(new connection(io_context_, m_state, m_connection_type, m_state->ssl_options().support)); acceptor_ipv6.async_accept(new_connection_ipv6->socket(), boost::bind(&boosted_tcp_server::handle_accept_ipv6, this, boost::asio::placeholders::error)); } catch (const std::exception &e) { - ipv6_failed = e.what(); + MERROR("Failed to bind IPv6: " << e.what()); + throw; } } - - if (use_ipv6 && ipv6_failed != "") - { - MERROR("Failed to bind IPv6: " << ipv6_failed); - if (ipv4_failed != "") - { - throw std::runtime_error("Failed to bind IPv4 and IPv6"); - } - } - return true; } catch (const std::exception &e) @@ -1314,7 +1310,7 @@ namespace net_utils { try { - io_service_.run(); + io_context_.run(); return true; } catch(const std::exception& ex) @@ -1358,7 +1354,7 @@ namespace net_utils while(!m_stop_signal_sent) { - // Create a pool of threads to run all of the io_services. + // Create a pool of threads to run all of the io_contexts. CRITICAL_REGION_BEGIN(m_threads_lock); for (std::size_t i = 0; i < threads_count; ++i) { @@ -1450,7 +1446,7 @@ namespace net_utils } connections_.clear(); connections_mutex.unlock(); - io_service_.stop(); + io_context_.stop(); CATCH_ENTRY_L0("boosted_tcp_server::send_stop_signal()", void()); } //--------------------------------------------------------------------------------- @@ -1497,7 +1493,7 @@ namespace net_utils (*current_new_connection)->setRpcStation(); // hopefully this is not needed actually } connection_ptr conn(std::move((*current_new_connection))); - (*current_new_connection).reset(new connection(io_service_, m_state, m_connection_type, conn->get_ssl_support())); + (*current_new_connection).reset(new connection(io_context_, m_state, m_connection_type, conn->get_ssl_support())); current_acceptor->async_accept((*current_new_connection)->socket(), boost::bind(accept_function_pointer, this, boost::asio::placeholders::error)); @@ -1532,7 +1528,7 @@ namespace net_utils assert(m_state != nullptr); // always set in constructor _erro("Some problems at accept: " << e.message() << ", connections_count = " << m_state->sock_count); misc_utils::sleep_no_w(100); - (*current_new_connection).reset(new connection(io_service_, m_state, m_connection_type, (*current_new_connection)->get_ssl_support())); + (*current_new_connection).reset(new connection(io_context_, m_state, m_connection_type, (*current_new_connection)->get_ssl_support())); current_acceptor->async_accept((*current_new_connection)->socket(), boost::bind(accept_function_pointer, this, boost::asio::placeholders::error)); @@ -1541,9 +1537,9 @@ namespace net_utils template bool boosted_tcp_server::add_connection(t_connection_context& out, boost::asio::ip::tcp::socket&& sock, network_address real_remote, epee::net_utils::ssl_support_t ssl_support) { - if(std::addressof(get_io_service()) == std::addressof(GET_IO_SERVICE(sock))) + if(std::addressof(get_io_context()) == std::addressof(sock.get_executor().context())) { - connection_ptr conn(new connection(std::move(sock), m_state, m_connection_type, ssl_support)); + connection_ptr conn(new connection(io_context_, std::move(sock), m_state, m_connection_type, ssl_support)); if(conn->start(false, 1 < m_threads_count, std::move(real_remote))) { conn->get_context(out); @@ -1553,7 +1549,7 @@ namespace net_utils } else { - MWARNING(out << " was not added, socket/io_service mismatch"); + MWARNING(out << " was not added, socket/io_context mismatch"); } return false; } @@ -1566,7 +1562,7 @@ namespace net_utils sock_.open(remote_endpoint.protocol()); if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) { - boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(bind_ip.c_str()), 0); + boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::make_address(bind_ip), 0); boost::system::error_code ec; sock_.bind(local_endpoint, ec); if (ec) @@ -1661,7 +1657,7 @@ namespace net_utils { TRY_ENTRY(); - connection_ptr new_connection_l(new connection(io_service_, m_state, m_connection_type, ssl_support) ); + connection_ptr new_connection_l(new connection(io_context_, m_state, m_connection_type, ssl_support) ); connections_mutex.lock(); connections_.insert(new_connection_l); MDEBUG("connections_ size now " << connections_.size()); @@ -1669,25 +1665,17 @@ namespace net_utils epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ CRITICAL_REGION_LOCAL(connections_mutex); connections_.erase(new_connection_l); }); boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket(); - bool try_ipv6 = false; - - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - boost::system::error_code resolve_error; - boost::asio::ip::tcp::resolver::iterator iterator; + boost::asio::ip::tcp::resolver resolver(io_context_); + boost::asio::ip::tcp::resolver::results_type::iterator iterator; try { //resolving ipv4 address as ipv6 throws, catch here and move on - iterator = resolver.resolve(query, resolve_error); + const auto results = resolver.resolve(adr, port); + iterator = results.begin(); } catch (const boost::system::system_error& e) { - if (!m_use_ipv6 || (resolve_error != boost::asio::error::host_not_found && - resolve_error != boost::asio::error::host_not_found_try_again)) - { - throw; - } - try_ipv6 = true; + return false; } catch (...) { @@ -1696,51 +1684,17 @@ namespace net_utils std::string bind_ip_to_use; - boost::asio::ip::tcp::resolver::iterator end; + const boost::asio::ip::tcp::resolver::results_type::iterator end; if(iterator == end) { - if (!m_use_ipv6) - { - _erro("Failed to resolve " << adr); - return false; - } - else - { - try_ipv6 = true; - MINFO("Resolving address as IPv4 failed, trying IPv6"); - } + _erro("Failed to resolve " << adr); + return false; } else { bind_ip_to_use = bind_ip; } - if (try_ipv6) - { - boost::asio::ip::tcp::resolver::query query6(boost::asio::ip::tcp::v6(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - - iterator = resolver.resolve(query6, resolve_error); - - if(iterator == end) - { - _erro("Failed to resolve " << adr); - return false; - } - else - { - if (bind_ip == "0.0.0.0") - { - bind_ip_to_use = "::"; - } - else - { - bind_ip_to_use = ""; - } - - } - - } - MDEBUG("Trying to connect to " << adr << ":" << port << ", bind_ip = " << bind_ip_to_use); //boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port); @@ -1767,7 +1721,7 @@ namespace net_utils if (r) { new_connection_l->get_context(conn_context); - //new_connection_l.reset(new connection(io_service_, m_config, m_sock_count, m_pfilter)); + //new_connection_l.reset(new connection(io_context_, m_config, m_sock_count, m_pfilter)); } else { @@ -1786,7 +1740,7 @@ namespace net_utils bool boosted_tcp_server::connect_async(const std::string& adr, const std::string& port, uint32_t conn_timeout, const t_callback &cb, const std::string& bind_ip, epee::net_utils::ssl_support_t ssl_support) { TRY_ENTRY(); - connection_ptr new_connection_l(new connection(io_service_, m_state, m_connection_type, ssl_support) ); + connection_ptr new_connection_l(new connection(io_context_, m_state, m_connection_type, ssl_support) ); connections_mutex.lock(); connections_.insert(new_connection_l); MDEBUG("connections_ size now " << connections_.size()); @@ -1794,65 +1748,36 @@ namespace net_utils epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ CRITICAL_REGION_LOCAL(connections_mutex); connections_.erase(new_connection_l); }); boost::asio::ip::tcp::socket& sock_ = new_connection_l->socket(); - bool try_ipv6 = false; - - boost::asio::ip::tcp::resolver resolver(io_service_); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - boost::system::error_code resolve_error; - boost::asio::ip::tcp::resolver::iterator iterator; + boost::asio::ip::tcp::resolver resolver(io_context_); + boost::asio::ip::tcp::resolver::results_type::iterator iterator; try { //resolving ipv4 address as ipv6 throws, catch here and move on - iterator = resolver.resolve(query, resolve_error); + const auto results = resolver.resolve(adr, port); + iterator = results.begin(); } catch (const boost::system::system_error& e) { - if (!m_use_ipv6 || (resolve_error != boost::asio::error::host_not_found && - resolve_error != boost::asio::error::host_not_found_try_again)) - { - throw; - } - try_ipv6 = true; + return false; } catch (...) { throw; } - boost::asio::ip::tcp::resolver::iterator end; + const boost::asio::ip::tcp::resolver::results_type::iterator end; if(iterator == end) { - if (!try_ipv6) - { - _erro("Failed to resolve " << adr); - return false; - } - else - { - MINFO("Resolving address as IPv4 failed, trying IPv6"); - } - } - - if (try_ipv6) - { - boost::asio::ip::tcp::resolver::query query6(boost::asio::ip::tcp::v6(), adr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - - iterator = resolver.resolve(query6, resolve_error); - - if(iterator == end) - { - _erro("Failed to resolve " << adr); - return false; - } + _erro("Failed to resolve " << adr); + return false; } - boost::asio::ip::tcp::endpoint remote_endpoint(*iterator); sock_.open(remote_endpoint.protocol()); if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) { - boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(bind_ip.c_str()), 0); + boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::make_address(bind_ip.c_str()), 0); boost::system::error_code ec; sock_.bind(local_endpoint, ec); if (ec) @@ -1864,7 +1789,7 @@ namespace net_utils } } - boost::shared_ptr sh_deadline(new boost::asio::deadline_timer(io_service_)); + boost::shared_ptr sh_deadline(new boost::asio::deadline_timer(io_context_)); //start deadline sh_deadline->expires_from_now(boost::posix_time::milliseconds(conn_timeout)); sh_deadline->async_wait([=](const boost::system::error_code& error) diff --git a/contrib/epee/include/net/connection_basic.hpp b/contrib/epee/include/net/connection_basic.hpp index f2fbf09b3a5..93bfd7570ba 100644 --- a/contrib/epee/include/net/connection_basic.hpp +++ b/contrib/epee/include/net/connection_basic.hpp @@ -112,21 +112,20 @@ class connection_basic { // not-templated base class for rapid developmet of som std::deque m_send_que; volatile bool m_is_multithreaded; /// Strand to ensure the connection's handlers are not called concurrently. - boost::asio::io_service::strand strand_; + boost::asio::io_context::strand strand_; /// Socket for the connection. boost::asio::ssl::stream socket_; ssl_support_t m_ssl_support; public: // first counter is the ++/-- count of current sockets, the other socket_number is only-increasing ++ number generator - connection_basic(boost::asio::ip::tcp::socket&& socket, std::shared_ptr state, ssl_support_t ssl_support); - connection_basic(boost::asio::io_service &io_service, std::shared_ptr state, ssl_support_t ssl_support); + connection_basic(boost::asio::io_context &context, boost::asio::ip::tcp::socket&& sock, std::shared_ptr state, ssl_support_t ssl_support); + connection_basic(boost::asio::io_context &context, std::shared_ptr state, ssl_support_t ssl_support); virtual ~connection_basic() noexcept(false); //! \return `shared_state` object passed in construction (ptr never changes). connection_basic_shared_state& get_state() noexcept { return *m_state; /* verified in constructor */ } - connection_basic(boost::asio::io_service& io_service, std::atomic &ref_sock_count, std::atomic &sock_number, ssl_support_t ssl); boost::asio::ip::tcp::socket& socket() { return socket_.next_layer(); } ssl_support_t get_ssl_support() const { return m_ssl_support; } @@ -135,7 +134,7 @@ class connection_basic { // not-templated base class for rapid developmet of som 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, buffer); + return m_state->ssl_options().handshake(strand_.context(), socket_, type, buffer); } template diff --git a/contrib/epee/include/net/http_server_impl_base.h b/contrib/epee/include/net/http_server_impl_base.h index d88b53c9427..024f141b4ca 100644 --- a/contrib/epee/include/net/http_server_impl_base.h +++ b/contrib/epee/include/net/http_server_impl_base.h @@ -52,7 +52,7 @@ namespace epee : m_net_server(epee::net_utils::e_connection_type_RPC) {} - explicit http_server_impl_base(boost::asio::io_service& external_io_service) + explicit http_server_impl_base(boost::asio::io_context& external_io_service) : m_net_server(external_io_service) {} diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 5122f167777..892c3853965 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -191,7 +191,7 @@ class async_protocol_handler struct anvoke_handler: invoke_response_handler_base { anvoke_handler(const callback_t& cb, uint64_t timeout, async_protocol_handler& con, int command) - :m_cb(cb), m_timeout(timeout), m_con(con), m_timer(con.m_pservice_endpoint->get_io_service()), m_timer_started(false), + :m_cb(cb), m_timeout(timeout), m_con(con), m_timer(con.m_pservice_endpoint->get_io_context()), m_timer_started(false), m_cancel_timer_called(false), m_timer_cancelled(false), m_command(command) { if(m_con.start_outer_call()) diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 3cb3d8c669b..0c0e7f97539 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -144,11 +144,11 @@ namespace net_utils inline try_connect_result_t try_connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout) { - m_deadline.expires_from_now(timeout); + m_deadline.expires_after(timeout); boost::unique_future connection = m_connector(addr, port, m_deadline); for (;;) { - m_io_service.reset(); + m_io_service.restart(); m_io_service.run_one(); if (connection.is_ready()) @@ -164,7 +164,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_io_service, *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) { @@ -271,7 +271,7 @@ namespace net_utils try { - m_deadline.expires_from_now(timeout); + m_deadline.expires_after(timeout); // Set up the variable that receives the result of the asynchronous // operation. The error code is set to would_block to signal that the @@ -289,7 +289,7 @@ namespace net_utils // Block until the asynchronous operation has completed. while (ec == boost::asio::error::would_block) { - m_io_service.reset(); + m_io_service.restart(); m_io_service.run_one(); } @@ -337,7 +337,7 @@ namespace net_utils // Set a deadline for the asynchronous operation. Since this function uses // a composed operation (async_read_until), the deadline applies to the // entire operation, rather than individual reads from the socket. - m_deadline.expires_from_now(timeout); + m_deadline.expires_after(timeout); // Set up the variable that receives the result of the asynchronous // operation. The error code is set to would_block to signal that the @@ -364,7 +364,7 @@ namespace net_utils // Block until the asynchronous operation has completed. while (ec == boost::asio::error::would_block && !m_shutdowned) { - m_io_service.reset(); + m_io_service.restart(); m_io_service.run_one(); } @@ -452,7 +452,7 @@ namespace net_utils // Check whether the deadline has passed. We compare the deadline against // the current time since a new asynchronous operation may have moved the // deadline before this actor had a chance to run. - if (m_deadline.expires_at() <= std::chrono::steady_clock::now()) + if (m_deadline.expiry() <= std::chrono::steady_clock::now()) { // The deadline has passed. The socket is closed so that any outstanding // asynchronous operations are cancelled. This allows the blocked @@ -473,11 +473,11 @@ namespace net_utils void shutdown_ssl() { // ssl socket shutdown blocks if server doesn't respond. We close after 2 secs boost::system::error_code ec = boost::asio::error::would_block; - m_deadline.expires_from_now(std::chrono::milliseconds(2000)); + m_deadline.expires_after(std::chrono::milliseconds(2000)); m_ssl_socket->async_shutdown(boost::lambda::var(ec) = boost::lambda::_1); while (ec == boost::asio::error::would_block) { - m_io_service.reset(); + m_io_service.restart(); m_io_service.run_one(); } // Ignore "short read" error @@ -511,7 +511,7 @@ namespace net_utils } protected: - boost::asio::io_service m_io_service; + boost::asio::io_context m_io_service; boost::asio::ssl::context m_ctx; std::shared_ptr> m_ssl_socket; std::function m_connector; diff --git a/contrib/epee/include/net/net_ssl.h b/contrib/epee/include/net/net_ssl.h index c6ef925baa7..854429e3a9c 100644 --- a/contrib/epee/include/net/net_ssl.h +++ b/contrib/epee/include/net/net_ssl.h @@ -125,6 +125,7 @@ namespace net_utils \note It is strongly encouraged that clients using `system_ca` verification provide a non-empty `host` for rfc2818 verification. + \param io_context associated with `socket`. \param socket Used in SSL handshake and verification \param type Client or server \param host This parameter is only used when @@ -136,6 +137,7 @@ namespace net_utils \return True if the SSL handshake completes with peer verification settings. */ bool handshake( + boost::asio::io_context& io_context, boost::asio::ssl::stream &socket, boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer = {}, diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h index 722206ee135..05cb3a6a1d7 100644 --- a/contrib/epee/include/net/net_utils_base.h +++ b/contrib/epee/include/net/net_utils_base.h @@ -30,7 +30,7 @@ #define _NET_UTILS_BASE_H_ #include -#include +#include #include #include #include @@ -47,12 +47,6 @@ #define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(((uint32_t)a4)<<24)) #endif -#if BOOST_VERSION >= 107000 -#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) -#else -#define GET_IO_SERVICE(s) ((s).get_io_service()) -#endif - namespace net { class tor_address; @@ -443,7 +437,7 @@ namespace net_utils virtual bool send_done()=0; virtual bool call_run_once_service_io()=0; virtual bool request_callback()=0; - virtual boost::asio::io_service& get_io_service()=0; + virtual boost::asio::io_context& get_io_context()=0; //protect from deletion connection object(with protocol instance) during external call "invoke" virtual bool add_ref()=0; virtual bool release()=0; diff --git a/contrib/epee/src/connection_basic.cpp b/contrib/epee/src/connection_basic.cpp index 49d28ce1ad5..9eb0b9027f7 100644 --- a/contrib/epee/src/connection_basic.cpp +++ b/contrib/epee/src/connection_basic.cpp @@ -46,12 +46,6 @@ // TODO: #include "net/network_throttle-detail.hpp" -#if BOOST_VERSION >= 107000 -#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) -#else -#define GET_IO_SERVICE(s) ((s).get_io_service()) -#endif - #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.conn" @@ -127,21 +121,21 @@ connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_thro int connection_basic_pimpl::m_default_tos; // methods: -connection_basic::connection_basic(boost::asio::ip::tcp::socket&& sock, std::shared_ptr state, ssl_support_t ssl_support) +connection_basic::connection_basic(boost::asio::io_context &io_context, boost::asio::ip::tcp::socket&& sock, std::shared_ptr state, ssl_support_t ssl_support) : m_state(std::move(state)), mI( new connection_basic_pimpl("peer") ), - strand_(GET_IO_SERVICE(sock)), - socket_(GET_IO_SERVICE(sock), get_context(m_state.get())), + strand_(io_context), + socket_(io_context, get_context(m_state.get())), m_want_close_connection(false), m_was_shutdown(false), m_is_multithreaded(false), m_ssl_support(ssl_support) { // add nullptr checks if removed - assert(m_state != nullptr); // release runtime check in get_context + assert(m_state != nullptr); // release runtime check in get_contextp - socket_.next_layer() = std::move(sock); + socket_.next_layer() = std::move(sock); ++(m_state->sock_count); // increase the global counter mI->m_peer_number = m_state->sock_number.fetch_add(1); // use, and increase the generated number @@ -152,12 +146,12 @@ connection_basic::connection_basic(boost::asio::ip::tcp::socket&& sock, std::sha _note("Spawned connection #"<m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_state->sock_count); } -connection_basic::connection_basic(boost::asio::io_service &io_service, std::shared_ptr state, ssl_support_t ssl_support) +connection_basic::connection_basic(boost::asio::io_context &io_context, std::shared_ptr state, ssl_support_t ssl_support) : m_state(std::move(state)), mI( new connection_basic_pimpl("peer") ), - strand_(io_service), - socket_(io_service, get_context(m_state.get())), + strand_(io_context), + socket_(io_context, get_context(m_state.get())), m_want_close_connection(false), m_was_shutdown(false), m_is_multithreaded(false), diff --git a/contrib/epee/src/net_helper.cpp b/contrib/epee/src/net_helper.cpp index 719f1c8e045..64947f69910 100644 --- a/contrib/epee/src/net_helper.cpp +++ b/contrib/epee/src/net_helper.cpp @@ -9,41 +9,12 @@ namespace net_utils { // Get a list of endpoints corresponding to the server name. ////////////////////////////////////////////////////////////////////////// - boost::asio::ip::tcp::resolver resolver(GET_IO_SERVICE(timeout)); - boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port, boost::asio::ip::tcp::resolver::query::canonical_name); + boost::asio::ip::tcp::resolver resolver(timeout.get_executor()); - bool try_ipv6 = false; - boost::asio::ip::tcp::resolver::iterator iterator; - boost::asio::ip::tcp::resolver::iterator end; boost::system::error_code resolve_error; - try - { - iterator = resolver.resolve(query, resolve_error); - if(iterator == end) // Documentation states that successful call is guaranteed to be non-empty - { - // if IPv4 resolution fails, try IPv6. Unintentional outgoing IPv6 connections should only - // be possible if for some reason a hostname was given and that hostname fails IPv4 resolution, - // so at least for now there should not be a need for a flag "using ipv6 is ok" - try_ipv6 = true; - } - - } - catch (const boost::system::system_error& e) - { - if (resolve_error != boost::asio::error::host_not_found && - resolve_error != boost::asio::error::host_not_found_try_again) - { - throw; - } - try_ipv6 = true; - } - if (try_ipv6) - { - boost::asio::ip::tcp::resolver::query query6(boost::asio::ip::tcp::v6(), addr, port, boost::asio::ip::tcp::resolver::query::canonical_name); - iterator = resolver.resolve(query6); - if (iterator == end) - throw boost::system::system_error{boost::asio::error::fault, "Failed to resolve " + addr}; - } + auto result = resolver.resolve(addr, port, resolve_error); + if(resolve_error || result.empty()) // Documentation states that successful call is guaranteed to be non-empty + throw boost::system::system_error{boost::asio::error::fault, "Failed to resolve " + addr}; ////////////////////////////////////////////////////////////////////////// @@ -52,12 +23,12 @@ namespace net_utils boost::promise result_; boost::asio::ip::tcp::socket socket_; - explicit new_connection(boost::asio::io_service& io_service) + explicit new_connection(const boost::asio::steady_timer::executor_type& io_service) : result_(), socket_(io_service) {} }; - const auto shared = std::make_shared(GET_IO_SERVICE(timeout)); + const auto shared = std::make_shared(timeout.get_executor()); timeout.async_wait([shared] (boost::system::error_code error) { if (error != boost::system::errc::operation_canceled && shared && shared->socket_.is_open()) @@ -66,7 +37,7 @@ namespace net_utils shared->socket_.close(); } }); - shared->socket_.async_connect(*iterator, [shared] (boost::system::error_code error) + shared->socket_.async_connect(*result.begin(), [shared] (boost::system::error_code error) { if (shared) { diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp index d8a3728edb9..d9f14e7644f 100644 --- a/contrib/epee/src/net_ssl.cpp +++ b/contrib/epee/src/net_ssl.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -527,7 +528,7 @@ void ssl_options_t::configure( // preverified means it passed system or user CA check. System CA is never loaded // when fingerprints are whitelisted. const bool verified = preverified && - (verification != ssl_verification_t::system_ca || host.empty() || boost::asio::ssl::rfc2818_verification(host)(preverified, ctx)); + (verification != ssl_verification_t::system_ca || host.empty() || boost::asio::ssl::host_name_verification(host)(preverified, ctx)); if (!verified && !has_fingerprint(ctx)) { @@ -545,6 +546,7 @@ void ssl_options_t::configure( } bool ssl_options_t::handshake( + boost::asio::io_context& io_context, boost::asio::ssl::stream &socket, boost::asio::ssl::stream_base::handshake_type type, boost::asio::const_buffer buffer, @@ -556,12 +558,11 @@ bool ssl_options_t::handshake( auto start_handshake = [&]{ using ec_t = boost::system::error_code; using timer_t = boost::asio::steady_timer; - using strand_t = boost::asio::io_service::strand; + using strand_t = boost::asio::io_context::strand; using socket_t = boost::asio::ip::tcp::socket; - auto &io_context = GET_IO_SERVICE(socket); if (io_context.stopped()) - io_context.reset(); + io_context.restart(); strand_t strand(io_context); timer_t deadline(io_context, timeout); @@ -596,13 +597,13 @@ bool ssl_options_t::handshake( state.result = ec; if (!state.cancel_handshake) { state.cancel_timer = true; - ec_t ec; - deadline.cancel(ec); + deadline.cancel(); } }; deadline.async_wait(on_timer); - strand.post( + boost::asio::post( + strand, [&]{ socket.async_handshake( type, diff --git a/src/common/util.cpp b/src/common/util.cpp index 47d671057d0..2aaa1a98df7 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -664,7 +664,7 @@ namespace tools } boost::system::error_code ec; - const auto parsed_ip = boost::asio::ip::address::from_string(u_c.host, ec); + const auto parsed_ip = boost::asio::ip::make_address(u_c.host, ec); if (ec) { MDEBUG("Failed to parse '" << address << "' as IP address: " << ec.message() << ". Considering it not local"); return false; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 13c470172a4..91a7b18e9e0 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -374,9 +375,9 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline // create general purpose async service queue - m_async_work_idle = std::unique_ptr < boost::asio::io_service::work > (new boost::asio::io_service::work(m_async_service)); + m_async_work_idle = std::make_unique>(m_async_service.get_executor()); // we only need 1 - m_async_pool.create_thread(boost::bind(&boost::asio::io_service::run, &m_async_service)); + m_async_pool.create_thread(boost::bind(&boost::asio::io_context::run, &m_async_service)); #if defined(PER_BLOCK_CHECKPOINT) if (m_nettype != FAKECHAIN) @@ -4756,7 +4757,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync) { m_sync_counter = 0; m_bytes_to_sync = 0; - m_async_service.dispatch(boost::bind(&Blockchain::store_blockchain, this)); + boost::asio::dispatch(m_async_service, boost::bind(&Blockchain::store_blockchain, this)); } else if(m_db_sync_mode == db_sync) { diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 2caad16a577..3b79a751f0b 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -29,7 +29,7 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #pragma once -#include +#include #include #if BOOST_VERSION >= 107400 #include @@ -1175,9 +1175,9 @@ namespace cryptonote crypto::hash m_difficulty_for_next_block_top_hash; difficulty_type m_difficulty_for_next_block; - boost::asio::io_service m_async_service; + boost::asio::io_context m_async_service; boost::thread_group m_async_pool; - std::unique_ptr m_async_work_idle; + std::unique_ptr> m_async_work_idle; // some invalid blocks blocks_ext_by_hash m_invalid_blocks; // crypto::hash -> block_extended_info diff --git a/src/cryptonote_protocol/levin_notify.cpp b/src/cryptonote_protocol/levin_notify.cpp index 631a6c305ee..2483a84e94c 100644 --- a/src/cryptonote_protocol/levin_notify.cpp +++ b/src/cryptonote_protocol/levin_notify.cpp @@ -28,6 +28,8 @@ #include "levin_notify.h" +#include +#include #include #include #include @@ -221,7 +223,7 @@ namespace levin `dispatch` is used heavily, which means "execute immediately in _this_ thread if the strand is not in use, otherwise queue the callback to be executed immediately after the strand completes its current task". - `post` is used where deferred execution to an `asio::io_service::run` + `post` is used where deferred execution to an `asio::io_context::run` thread is preferred. The strand per "zone" is useful because the levin @@ -238,7 +240,7 @@ namespace levin //! A queue of levin messages for a noise i2p/tor link struct noise_channel { - explicit noise_channel(boost::asio::io_service& io_service) + explicit noise_channel(boost::asio::io_context& io_service) : active(nullptr), queue(), strand(io_service), @@ -246,7 +248,7 @@ namespace levin connection(boost::uuids::nil_uuid()) {} - // `asio::io_service::strand` cannot be copied or moved + // `asio::io_context::strand` cannot be copied or moved noise_channel(const noise_channel&) = delete; noise_channel& operator=(const noise_channel&) = delete; @@ -254,7 +256,7 @@ namespace levin epee::byte_slice active; std::deque queue; - boost::asio::io_service::strand strand; + boost::asio::io_context::strand strand; boost::asio::steady_timer next_noise; boost::uuids::uuid connection; }; @@ -264,7 +266,7 @@ namespace levin { struct zone { - explicit zone(boost::asio::io_service& io_service, std::shared_ptr p2p, epee::byte_slice noise_in, epee::net_utils::zone zone, bool pad_txs) + explicit zone(boost::asio::io_context& io_service, std::shared_ptr p2p, epee::byte_slice noise_in, epee::net_utils::zone zone, bool pad_txs) : p2p(std::move(p2p)), noise(std::move(noise_in)), next_epoch(io_service), @@ -286,7 +288,7 @@ namespace levin const epee::byte_slice noise; //!< `!empty()` means zone is using noise channels boost::asio::steady_timer next_epoch; boost::asio::steady_timer flush_txs; - boost::asio::io_service::strand strand; + boost::asio::io_context::strand strand; struct context_t { std::vector fluff_txs; std::chrono::steady_clock::time_point flush_time; @@ -454,7 +456,7 @@ namespace levin if (next_flush == std::chrono::steady_clock::time_point::max()) MWARNING("Unable to send transaction(s), no available connections"); - else if (!zone->flush_callbacks || next_flush < zone->flush_txs.expires_at()) + else if (!zone->flush_callbacks || next_flush < zone->flush_txs.expiry()) fluff_flush::queue(std::move(zone), next_flush); } }; @@ -515,7 +517,7 @@ namespace levin for (auto id = zone->map.begin(); id != zone->map.end(); ++id) { const std::size_t i = id - zone->map.begin(); - zone->channels[i].strand.post(update_channel{zone, i, *id}); + boost::asio::post(zone->channels[i].strand, update_channel{zone, i, *id}); } } @@ -674,7 +676,7 @@ namespace levin MWARNING("Unable to send transaction(s) to " << epee::net_utils::zone_to_string(zone_->nzone) << " - no suitable outbound connections at height " << height); - zone_->strand.post(update_channels{zone_, std::move(connections)}); + boost::asio::post(zone_->strand, update_channels{zone_, std::move(connections)}); } } @@ -704,7 +706,8 @@ namespace levin const bool fluffing = crypto::rand_idx(unsigned(100)) < CRYPTONOTE_DANDELIONPP_FLUFF_PROBABILITY; const auto start = std::chrono::steady_clock::now(); auto connections = get_out_connections(*(zone_->p2p), core_); - zone_->strand.dispatch( + boost::asio::dispatch( + zone_->strand, change_channels{zone_, net::dandelionpp::connection_map{std::move(connections), count_}, fluffing} ); @@ -715,7 +718,7 @@ namespace levin }; } // anonymous - notify::notify(boost::asio::io_service& service, std::shared_ptr p2p, epee::byte_slice noise, epee::net_utils::zone zone, const bool pad_txs, i_core_events& core) + notify::notify(boost::asio::io_context& service, std::shared_ptr p2p, epee::byte_slice noise, epee::net_utils::zone zone, const bool pad_txs, i_core_events& core) : zone_(std::make_shared(service, std::move(p2p), std::move(noise), zone, pad_txs)) , core_(std::addressof(core)) { @@ -758,7 +761,8 @@ namespace levin if (!zone_ || zone_->noise.empty() || CRYPTONOTE_NOISE_CHANNELS <= zone_->connection_count) return; - zone_->strand.dispatch( + boost::asio::dispatch( + zone_->strand, update_channels{zone_, get_out_connections(*(zone_->p2p), core_)} ); } @@ -769,13 +773,16 @@ namespace levin return; auto& zone = zone_; - zone_->strand.dispatch([zone, id, is_income]{ - zone->contexts[id] = { - .fluff_txs = {}, - .flush_time = std::chrono::steady_clock::time_point::max(), - .m_is_income = is_income, - }; - }); + boost::asio::dispatch( + zone_->strand, + [zone, id, is_income] { + zone->contexts[id] = { + .fluff_txs = {}, + .flush_time = std::chrono::steady_clock::time_point::max(), + .m_is_income = is_income, + }; + } + ); } void notify::on_connection_close(const boost::uuids::uuid &id) @@ -784,9 +791,10 @@ namespace levin return; auto& zone = zone_; - zone_->strand.dispatch([zone, id]{ - zone->contexts.erase(id); - }); + boost::asio::dispatch( + zone_->strand, + [zone, id]{ zone->contexts.erase(id); } + ); } void notify::run_epoch() @@ -859,7 +867,8 @@ namespace levin for (std::size_t channel = 0; channel < zone_->channels.size(); ++channel) { - zone_->channels[channel].strand.dispatch( + boost::asio::dispatch( + zone_->channels[channel].strand, queue_covert_notify{zone_, message.clone(), channel} ); } @@ -878,7 +887,8 @@ namespace levin if (zone_->nzone == epee::net_utils::zone::public_) { // this will change a local/forward tx to stem or fluff ... - zone_->strand.dispatch( + boost::asio::dispatch( + zone_->strand, dandelionpp_notify{zone_, core_, std::move(txs), source, tx_relay} ); break; @@ -891,7 +901,7 @@ namespace levin ipv4/6. Marking it as "fluff" here will make the tx immediately visible externally from this node, which is not desired. */ core_->on_transactions_relayed(epee::to_span(txs), tx_relay); - zone_->strand.dispatch(fluff_notify{zone_, std::move(txs), source}); + boost::asio::dispatch(zone_->strand, fluff_notify{zone_, std::move(txs), source}); break; } } diff --git a/src/cryptonote_protocol/levin_notify.h b/src/cryptonote_protocol/levin_notify.h index 20a9556899c..4b07924a69f 100644 --- a/src/cryptonote_protocol/levin_notify.h +++ b/src/cryptonote_protocol/levin_notify.h @@ -28,7 +28,7 @@ #pragma once -#include +#include #include #include #include @@ -86,7 +86,7 @@ namespace levin {} //! Construct an instance with available notification `zones`. - explicit notify(boost::asio::io_service& service, std::shared_ptr p2p, epee::byte_slice noise, epee::net_utils::zone zone, bool pad_txs, i_core_events& core); + explicit notify(boost::asio::io_context& service, std::shared_ptr p2p, epee::byte_slice noise, epee::net_utils::zone zone, bool pad_txs, i_core_events& core); notify(const notify&) = delete; notify(notify&&) = default; diff --git a/src/net/parse.cpp b/src/net/parse.cpp index 6d580f6889c..b761da335b8 100644 --- a/src/net/parse.cpp +++ b/src/net/parse.cpp @@ -84,7 +84,7 @@ namespace net return i2p_address::make(address); boost::system::error_code ec; - boost::asio::ip::address_v6 v6 = boost::asio::ip::address_v6::from_string(host_str, ec); + boost::asio::ip::address_v6 v6 = boost::asio::ip::make_address_v6(host_str, ec); ipv6 = !ec; std::uint16_t port = default_port; diff --git a/src/net/socks.cpp b/src/net/socks.cpp index 734537b446b..5de4fa95e36 100644 --- a/src/net/socks.cpp +++ b/src/net/socks.cpp @@ -29,7 +29,9 @@ #include "socks.h" #include +#include #include +#include #include #include #include @@ -176,7 +178,7 @@ namespace socks { std::shared_ptr self_; - static boost::asio::mutable_buffers_1 get_buffer(client& self) noexcept + static boost::asio::mutable_buffer get_buffer(client& self) noexcept { static_assert(sizeof(v4_header) <= sizeof(self.buffer_), "buffer too small for v4 response"); return boost::asio::buffer(self.buffer_, sizeof(v4_header)); @@ -192,7 +194,7 @@ namespace socks else if (bytes < self.buffer().size()) self.done(socks::error::bad_write, std::move(self_)); else - boost::asio::async_read(self.proxy_, get_buffer(self), self.strand_.wrap(completed{std::move(self_)})); + boost::asio::async_read(self.proxy_, get_buffer(self), boost::asio::bind_executor(self.strand_, completed{std::move(self_)})); } } }; @@ -201,7 +203,7 @@ namespace socks { std::shared_ptr self_; - static boost::asio::const_buffers_1 get_buffer(client const& self) noexcept + static boost::asio::const_buffer get_buffer(client const& self) noexcept { return boost::asio::buffer(self.buffer_, self.buffer_size_); } @@ -214,13 +216,13 @@ namespace socks if (error) self.done(error, std::move(self_)); else - boost::asio::async_write(self.proxy_, get_buffer(self), self.strand_.wrap(read{std::move(self_)})); + boost::asio::async_write(self.proxy_, get_buffer(self), boost::asio::bind_executor(self.strand_, read{std::move(self_)})); } } }; client::client(stream_type::socket&& proxy, socks::version ver) - : proxy_(std::move(proxy)), strand_(GET_IO_SERVICE(proxy_)), buffer_size_(0), buffer_(), ver_(ver) + : proxy_(std::move(proxy)), strand_(proxy_.get_executor()), buffer_size_(0), buffer_(), ver_(ver) {} client::~client() {} @@ -295,7 +297,7 @@ namespace socks if (self && !self->buffer().empty()) { client& alias = *self; - alias.proxy_.async_connect(proxy_address, alias.strand_.wrap(write{std::move(self)})); + alias.proxy_.async_connect(proxy_address, boost::asio::bind_executor(alias.strand_, write{std::move(self)})); return true; } return false; @@ -306,7 +308,7 @@ namespace socks if (self && !self->buffer().empty()) { client& alias = *self; - boost::asio::async_write(alias.proxy_, write::get_buffer(alias), alias.strand_.wrap(read{std::move(self)})); + boost::asio::async_write(alias.proxy_, write::get_buffer(alias), boost::asio::bind_executor(alias.strand_, read{std::move(self)})); return true; } return false; @@ -317,7 +319,7 @@ namespace socks if (self_ && error != boost::system::errc::operation_canceled) { const std::shared_ptr self = std::move(self_); - self->strand_.dispatch([self] () + boost::asio::dispatch(self->strand_, [self] () { if (self && self->proxy_.is_open()) { diff --git a/src/net/socks.h b/src/net/socks.h index 35273057658..812a6c3e88b 100644 --- a/src/net/socks.h +++ b/src/net/socks.h @@ -29,8 +29,8 @@ #pragma once #include +#include #include -#include #include #include #include @@ -93,7 +93,7 @@ namespace socks class client { boost::asio::ip::tcp::socket proxy_; - boost::asio::io_service::strand strand_; + boost::asio::strand strand_; std::uint16_t buffer_size_; std::uint8_t buffer_[1024]; socks::version ver_; diff --git a/src/net/socks_connect.cpp b/src/net/socks_connect.cpp index febcd218bbc..74b4632f475 100644 --- a/src/net/socks_connect.cpp +++ b/src/net/socks_connect.cpp @@ -71,7 +71,7 @@ namespace socks boost::promise result{}; out = result.get_future(); const auto proxy = net::socks::make_connect_client( - boost::asio::ip::tcp::socket{GET_IO_SERVICE(timeout)}, net::socks::version::v4a, future_socket{std::move(result)} + boost::asio::ip::tcp::socket{timeout.get_executor()}, net::socks::version::v4a, future_socket{std::move(result)} ); if (epee::string_tools::get_ip_int32_from_string(ip_address, remote_host)) diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp index d6681238ffd..5cba55b4b1e 100644 --- a/src/p2p/net_node.cpp +++ b/src/p2p/net_node.cpp @@ -327,7 +327,7 @@ namespace nodetool } boost::optional - socks_connect_internal(const std::atomic& stop_signal, boost::asio::io_service& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote) + socks_connect_internal(const std::atomic& stop_signal, boost::asio::io_context& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote) { using socket_type = net::socks::client::stream_type::socket; using client_result = std::pair; diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 7b3477e1f7d..6b6caee5dbe 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -31,7 +31,7 @@ #pragma once #include #include -#include +#include #include #include #include @@ -103,7 +103,7 @@ namespace nodetool // hides boost::future and chrono stuff from mondo template file boost::optional - socks_connect_internal(const std::atomic& stop_signal, boost::asio::io_service& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote); + socks_connect_internal(const std::atomic& stop_signal, boost::asio::io_context& service, const boost::asio::ip::tcp::endpoint& proxy, const epee::net_utils::network_address& remote); template @@ -179,7 +179,7 @@ namespace nodetool set_config_defaults(); } - network_zone(boost::asio::io_service& public_service) + network_zone(boost::asio::io_context& public_service) : m_connect(nullptr), m_net_server(public_service, epee::net_utils::e_connection_type_P2P), m_seed_nodes(), diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 662e598e8a1..d8ceaf9f9ce 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -83,7 +83,7 @@ namespace nodetool template node_server::~node_server() { - // tcp server uses io_service in destructor, and every zone uses + // tcp server uses io_context in destructor, and every zone uses // io_service from public zone. for (auto current = m_network_zones.begin(); current != m_network_zones.end(); /* below */) { @@ -452,7 +452,7 @@ namespace nodetool m_use_ipv6 = command_line::get_arg(vm, arg_p2p_use_ipv6); m_require_ipv4 = !command_line::get_arg(vm, arg_p2p_ignore_ipv4); public_zone.m_notifier = cryptonote::levin::notify{ - public_zone.m_net_server.get_io_service(), public_zone.m_net_server.get_config_shared(), nullptr, epee::net_utils::zone::public_, pad_txs, m_payload_handler.get_core() + public_zone.m_net_server.get_io_context(), public_zone.m_net_server.get_config_shared(), nullptr, epee::net_utils::zone::public_, pad_txs, m_payload_handler.get_core() }; if (command_line::has_arg(vm, arg_p2p_add_peer)) @@ -605,7 +605,7 @@ namespace nodetool } zone.m_notifier = cryptonote::levin::notify{ - zone.m_net_server.get_io_service(), zone.m_net_server.get_config_shared(), std::move(this_noise), proxy.zone, pad_txs, m_payload_handler.get_core() + zone.m_net_server.get_io_context(), zone.m_net_server.get_config_shared(), std::move(this_noise), proxy.zone, pad_txs, m_payload_handler.get_core() }; } @@ -667,20 +667,18 @@ namespace nodetool net::get_network_address_host_and_port(addr, host, port); MINFO("Resolving node address: host=" << host << ", port=" << port); - io_service io_srv; - ip::tcp::resolver resolver(io_srv); - ip::tcp::resolver::query query(host, port, boost::asio::ip::tcp::resolver::query::canonical_name); boost::system::error_code ec; - ip::tcp::resolver::iterator i = resolver.resolve(query, ec); - CHECK_AND_ASSERT_MES(!ec, false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value()); + io_context io_srv; + ip::tcp::resolver resolver(io_srv); + const auto results = resolver.resolve(host, port, boost::asio::ip::tcp::resolver::canonical_name, ec); + CHECK_AND_ASSERT_MES(!ec && !results.empty(), false, "Failed to resolve host name '" << host << "': " << ec.message() << ':' << ec.value()); - ip::tcp::resolver::iterator iend; - for (; i != iend; ++i) + for (const auto& result : results) { - ip::tcp::endpoint endpoint = *i; + const auto& endpoint = result.endpoint(); if (endpoint.address().is_v4()) { - epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_ulong()), endpoint.port()}}; + epee::net_utils::network_address na{epee::net_utils::ipv4_network_address{boost::asio::detail::socket_ops::host_to_network_long(endpoint.address().to_v4().to_uint()), endpoint.port()}}; seed_nodes.push_back(na); MINFO("Added node: " << na.str()); } @@ -890,7 +888,7 @@ namespace nodetool return zone_->second; network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_]; - return m_network_zones.emplace_hint(zone_, std::piecewise_construct, std::make_tuple(zone), std::tie(public_zone.m_net_server.get_io_service()))->second; + return m_network_zones.emplace_hint(zone_, std::piecewise_construct, std::make_tuple(zone), std::tie(public_zone.m_net_server.get_io_context()))->second; } //----------------------------------------------------------------------------------- template @@ -3104,7 +3102,7 @@ namespace nodetool boost::optional> node_server::socks_connect(network_zone& zone, const epee::net_utils::network_address& remote, epee::net_utils::ssl_support_t ssl_support) { - auto result = socks_connect_internal(zone.m_net_server.get_stop_signal(), zone.m_net_server.get_io_service(), zone.m_proxy_address, remote); + auto result = socks_connect_internal(zone.m_net_server.get_stop_signal(), zone.m_net_server.get_io_context(), zone.m_proxy_address, remote); if (result) // if no error { p2p_connection_context context{}; diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp index 18a3fb90c4e..793a1edf768 100644 --- a/src/rpc/rpc_args.cpp +++ b/src/rpc/rpc_args.cpp @@ -149,7 +149,7 @@ namespace cryptonote { // always parse IP here for error consistency boost::system::error_code ec{}; - const auto parsed_ip = boost::asio::ip::address::from_string(config.bind_ip, ec); + const auto parsed_ip = boost::asio::ip::make_address(config.bind_ip, ec); if (ec) { LOG_ERROR(tr("Invalid IP address given for --") << arg.rpc_bind_ip.name); @@ -177,7 +177,7 @@ namespace cryptonote // always parse IP here for error consistency boost::system::error_code ec{}; - const auto parsed_ip = boost::asio::ip::address::from_string(config.bind_ipv6_address, ec); + const auto parsed_ip = boost::asio::ip::make_address(config.bind_ipv6_address, ec); if (ec) { LOG_ERROR(tr("Invalid IP address given for --") << arg.rpc_bind_ipv6_address.name); @@ -198,7 +198,7 @@ namespace cryptonote { // always parse IP here for error consistency boost::system::error_code ec{}; - boost::asio::ip::address::from_string(config.restricted_bind_ip, ec); + boost::asio::ip::make_address(config.restricted_bind_ip, ec); if (ec) { LOG_ERROR(tr("Invalid IP address given for --") << arg.rpc_restricted_bind_ip.name); @@ -215,7 +215,7 @@ namespace cryptonote // always parse IP here for error consistency boost::system::error_code ec{}; - boost::asio::ip::address::from_string(config.restricted_bind_ipv6_address, ec); + boost::asio::ip::make_address(config.restricted_bind_ipv6_address, ec); if (ec) { LOG_ERROR(tr("Invalid IP address given for --") << arg.rpc_restricted_bind_ipv6_address.name); diff --git a/tests/fuzz/levin.cpp b/tests/fuzz/levin.cpp index 7ebb1bb1891..6391abf21f9 100644 --- a/tests/fuzz/levin.cpp +++ b/tests/fuzz/levin.cpp @@ -138,7 +138,7 @@ namespace class test_connection : public epee::net_utils::i_service_endpoint { public: - test_connection(boost::asio::io_service& io_service, test_levin_protocol_handler_config& protocol_config) + test_connection(boost::asio::io_context& io_service, test_levin_protocol_handler_config& protocol_config) : m_io_service(io_service) , m_protocol_handler(this, protocol_config, m_context) , m_send_return(true) @@ -163,7 +163,7 @@ namespace virtual bool send_done() { return true; } virtual bool call_run_once_service_io() { return true; } virtual bool request_callback() { return true; } - virtual boost::asio::io_service& get_io_service() { return m_io_service; } + virtual boost::asio::io_context& get_io_context() { return m_io_service; } virtual bool add_ref() { return true; } virtual bool release() { return true; } @@ -180,7 +180,7 @@ namespace test_levin_protocol_handler m_protocol_handler; private: - boost::asio::io_service& m_io_service; + boost::asio::io_context& m_io_service; call_counter m_send_counter; boost::mutex m_mutex; @@ -224,7 +224,7 @@ namespace } protected: - boost::asio::io_service m_io_service; + boost::asio::io_context m_io_service; test_levin_protocol_handler_config m_handler_config; test_levin_commands_handler *m_pcommands_handler, &m_commands_handler; }; @@ -300,7 +300,7 @@ BEGIN_SIMPLE_FUZZER() fclose(f); #endif //std::unique_ptr conn = new test(); - boost::asio::io_service io_service; + boost::asio::io_context io_service; test_levin_protocol_handler_config m_handler_config; test_levin_commands_handler *m_pcommands_handler = new test_levin_commands_handler(); m_handler_config.set_handler(m_pcommands_handler, [](epee::levin::levin_commands_handler *handler) { delete handler; }); diff --git a/tests/net_load_tests/net_load_tests.h b/tests/net_load_tests/net_load_tests.h index f938ce083cd..f17aa8c7166 100644 --- a/tests/net_load_tests/net_load_tests.h +++ b/tests/net_load_tests/net_load_tests.h @@ -32,7 +32,7 @@ #include -#include +#include #include #include "include_base_utils.h" diff --git a/tests/net_load_tests/srv.cpp b/tests/net_load_tests/srv.cpp index 6abc39166da..dd22b1b61f5 100644 --- a/tests/net_load_tests/srv.cpp +++ b/tests/net_load_tests/srv.cpp @@ -189,7 +189,7 @@ namespace if (0 < count) { // Perhaps not all connections were closed, try to close it after 7 seconds - boost::shared_ptr sh_deadline(new boost::asio::deadline_timer(m_tcp_server.get_io_service(), boost::posix_time::seconds(7))); + boost::shared_ptr sh_deadline(new boost::asio::deadline_timer(m_tcp_server.get_io_context(), boost::posix_time::seconds(7))); sh_deadline->async_wait([=](const boost::system::error_code& ec) { boost::shared_ptr t = sh_deadline; // Capture sh_deadline diff --git a/tests/unit_tests/epee_boosted_tcp_server.cpp b/tests/unit_tests/epee_boosted_tcp_server.cpp index 3fff9af040b..61e1b0cee80 100644 --- a/tests/unit_tests/epee_boosted_tcp_server.cpp +++ b/tests/unit_tests/epee_boosted_tcp_server.cpp @@ -28,6 +28,7 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include #include #include #include @@ -173,9 +174,9 @@ TEST(test_epee_connection, test_lifetime) using shared_states_t = std::vector; using tag_t = boost::uuids::uuid; using tags_t = std::vector; - using io_context_t = boost::asio::io_service; + using io_context_t = boost::asio::io_context; using endpoint_t = boost::asio::ip::tcp::endpoint; - using work_t = boost::asio::io_service::work; + using work_t = boost::asio::executor_work_guard; using work_ptr = std::shared_ptr; using workers_t = std::vector; using server_t = epee::net_utils::boosted_tcp_server; @@ -189,7 +190,7 @@ TEST(test_epee_connection, test_lifetime) using shared_conn_ptr = std::shared_ptr; io_context_t io_context; - work_ptr work(std::make_shared(io_context)); + work_ptr work(std::make_shared(io_context.get_executor())); workers_t workers; while (workers.size() < 4) { @@ -198,7 +199,7 @@ TEST(test_epee_connection, test_lifetime) }); } - endpoint_t endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 5262); + endpoint_t endpoint(boost::asio::ip::make_address("127.0.0.1"), 5262); server_t server(epee::net_utils::e_connection_type_P2P); server.init_server(endpoint.port(), endpoint.address().to_string(), @@ -211,13 +212,16 @@ TEST(test_epee_connection, test_lifetime) server.run_server(2, false); server.get_config_shared()->set_handler(new command_handler_t, &command_handler_t::destroy); - io_context.post([&io_context, &work, &endpoint, &server]{ - shared_state_ptr shared_state; - auto scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&work, &shared_state]{ - work.reset(); - if (shared_state) - shared_state->set_handler(nullptr, nullptr); - }); + boost::asio::post( + io_context, + [&io_context, &work, &endpoint, &server]{ + shared_state_ptr shared_state; + auto scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&work, &shared_state]{ + work.reset(); + if (shared_state) + shared_state->set_handler(nullptr, nullptr); + } + ); shared_state = std::make_shared(); shared_state->set_handler(new command_handler_t, &command_handler_t::destroy); @@ -380,9 +384,7 @@ TEST(test_epee_connection, test_lifetime) connection_ptr conn(new connection_t(io_context, s, {}, {})); conn->socket().connect(endpoint); conn->start({}, {}); - io_context.post([conn]{ - conn->cancel(); - }); + boost::asio::post(io_context, [conn] { conn->cancel(); }); conn.reset(); s->del_out_connections(1); while (s->sock_count); @@ -452,9 +454,7 @@ TEST(test_epee_connection, test_lifetime) context_t context; conn->get_context(context); auto tag = context.m_connection_id; - io_context.post([conn]{ - conn->cancel(); - }); + boost::asio::post(io_context, [conn] { conn->cancel(); }); conn.reset(); s->close(tag); while (s->sock_count); @@ -497,7 +497,7 @@ TEST(test_epee_connection, ssl_shutdown) }; using handler_t = epee::levin::async_protocol_handler; - using io_context_t = boost::asio::io_service; + using io_context_t = boost::asio::io_context; using endpoint_t = boost::asio::ip::tcp::endpoint; using server_t = epee::net_utils::boosted_tcp_server; using socket_t = boost::asio::ip::tcp::socket; @@ -505,7 +505,7 @@ TEST(test_epee_connection, ssl_shutdown) using ssl_context_t = boost::asio::ssl::context; using ec_t = boost::system::error_code; - endpoint_t endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 5263); + endpoint_t endpoint(boost::asio::ip::make_address("127.0.0.1"), 5263); server_t server(epee::net_utils::e_connection_type_P2P); server.init_server(endpoint.port(), endpoint.address().to_string(), @@ -540,8 +540,8 @@ TEST(test_epee_connection, ssl_shutdown) TEST(test_epee_connection, ssl_handshake) { - using io_context_t = boost::asio::io_service; - using work_t = boost::asio::io_service::work; + using io_context_t = boost::asio::io_context; + using work_t = boost::asio::executor_work_guard; using work_ptr = std::shared_ptr; using workers_t = std::vector; using socket_t = boost::asio::ip::tcp::socket; @@ -549,7 +549,7 @@ TEST(test_epee_connection, ssl_handshake) using ssl_socket_ptr = std::unique_ptr; using ssl_options_t = epee::net_utils::ssl_options_t; io_context_t io_context; - work_ptr work(std::make_shared(io_context)); + work_ptr work(std::make_shared(io_context.get_executor())); workers_t workers; auto constexpr N = 2; while (workers.size() < N) { @@ -563,12 +563,14 @@ TEST(test_epee_connection, ssl_handshake) ssl_socket_ptr ssl_socket(new ssl_socket_t(io_context, ssl_context)); ssl_socket->next_layer().open(boost::asio::ip::tcp::v4()); for (size_t i = 0; i < N; ++i) { - io_context.post([]{ - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - }); + boost::asio::post( + io_context, + [] { std::this_thread::sleep_for(std::chrono::milliseconds(50)); } + ); } EXPECT_EQ( ssl_options.handshake( + io_context, *ssl_socket, ssl_socket_t::server, {}, @@ -673,7 +675,7 @@ TEST(boosted_tcp_server, strand_deadlock) using server_t = epee::net_utils::boosted_tcp_server; using endpoint_t = boost::asio::ip::tcp::endpoint; - endpoint_t endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 5262); + endpoint_t endpoint(boost::asio::ip::make_address("127.0.0.1"), 5262); server_t server(epee::net_utils::e_connection_type_P2P); server.init_server( endpoint.port(), diff --git a/tests/unit_tests/epee_levin_protocol_handler_async.cpp b/tests/unit_tests/epee_levin_protocol_handler_async.cpp index e445466c0aa..9677081114e 100644 --- a/tests/unit_tests/epee_levin_protocol_handler_async.cpp +++ b/tests/unit_tests/epee_levin_protocol_handler_async.cpp @@ -129,7 +129,7 @@ namespace class test_connection : public epee::net_utils::i_service_endpoint { public: - test_connection(boost::asio::io_service& io_service, test_levin_protocol_handler_config& protocol_config) + test_connection(boost::asio::io_context& io_service, test_levin_protocol_handler_config& protocol_config) : m_io_service(io_service) , m_protocol_handler(this, protocol_config, m_context) , m_send_return(true) @@ -155,7 +155,7 @@ namespace virtual bool send_done() { /*std::cout << "test_connection::send_done()" << std::endl; */return true; } virtual bool call_run_once_service_io() { std::cout << "test_connection::call_run_once_service_io()" << std::endl; return true; } virtual bool request_callback() { std::cout << "test_connection::request_callback()" << std::endl; return true; } - virtual boost::asio::io_service& get_io_service() { std::cout << "test_connection::get_io_service()" << std::endl; return m_io_service; } + virtual boost::asio::io_context& get_io_context() { std::cout << "test_connection::get_io_context()" << std::endl; return m_io_service; } virtual bool add_ref() { std::cout << "test_connection::add_ref()" << std::endl; return true; } virtual bool release() { std::cout << "test_connection::release()" << std::endl; return true; } @@ -171,7 +171,7 @@ namespace test_levin_protocol_handler m_protocol_handler; private: - boost::asio::io_service& m_io_service; + boost::asio::io_context& m_io_service; test_levin_connection_context m_context; unit_test::call_counter m_send_counter; @@ -216,7 +216,7 @@ namespace } protected: - boost::asio::io_service m_io_service; + boost::asio::io_context m_io_service; test_levin_protocol_handler_config m_handler_config; test_levin_commands_handler *m_pcommands_handler, &m_commands_handler; }; diff --git a/tests/unit_tests/levin.cpp b/tests/unit_tests/levin.cpp index 6ebed8494d8..32a9acbd7e8 100644 --- a/tests/unit_tests/levin.cpp +++ b/tests/unit_tests/levin.cpp @@ -54,7 +54,7 @@ namespace { class test_endpoint final : public epee::net_utils::i_service_endpoint { - boost::asio::io_service& io_service_; + boost::asio::io_context& io_service_; std::size_t ref_count_; virtual bool do_send(epee::byte_slice message) override final @@ -83,7 +83,7 @@ namespace throw std::logic_error{"request_callback not implemented"}; } - virtual boost::asio::io_service& get_io_service() override final + virtual boost::asio::io_context& get_io_context() override final { return io_service_; } @@ -101,7 +101,7 @@ namespace } public: - test_endpoint(boost::asio::io_service& io_service) + test_endpoint(boost::asio::io_context& io_service) : epee::net_utils::i_service_endpoint(), io_service_(io_service), ref_count_(0), @@ -171,7 +171,7 @@ namespace epee::levin::async_protocol_handler handler_; public: - test_connection(boost::asio::io_service& io_service, cryptonote::levin::connections& connections, boost::uuids::random_generator& random_generator, const bool is_incoming) + test_connection(boost::asio::io_context& io_service, cryptonote::levin::connections& connections, boost::uuids::random_generator& random_generator, const bool is_incoming) : endpoint_(io_service), context_(), handler_(std::addressof(endpoint_), connections, context_) @@ -364,7 +364,7 @@ namespace } boost::uuids::random_generator random_generator_; - boost::asio::io_service io_service_; + boost::asio::io_context io_service_; test_receiver receiver_; std::deque contexts_; test_core_events events_; @@ -626,7 +626,7 @@ TEST_F(levin_notify, fluff_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::fluff)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); ASSERT_LT(0u, io_service_.poll()); @@ -680,7 +680,7 @@ TEST_F(levin_notify, stem_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); const bool is_stem = events_.has_stem_txes(); EXPECT_EQ(txs, events_.take_relayed(is_stem ? cryptonote::relay_method::stem : cryptonote::relay_method::fluff)); @@ -751,7 +751,7 @@ TEST_F(levin_notify, stem_no_outs_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); if (events_.has_stem_txes()) @@ -820,7 +820,7 @@ TEST_F(levin_notify, local_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(their_txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); const bool is_stem = events_.has_stem_txes(); EXPECT_EQ(their_txs, events_.take_relayed(is_stem ? cryptonote::relay_method::stem : cryptonote::relay_method::fluff)); @@ -860,7 +860,7 @@ TEST_F(levin_notify, local_without_padding) context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(my_txs, context->get_id(), cryptonote::relay_method::local)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_TRUE(events_.has_stem_txes()); EXPECT_EQ(my_txs, events_.take_relayed(cryptonote::relay_method::stem)); @@ -922,7 +922,7 @@ TEST_F(levin_notify, forward_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::forward)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); const bool is_stem = events_.has_stem_txes(); EXPECT_EQ(txs, events_.take_relayed(is_stem ? cryptonote::relay_method::stem : cryptonote::relay_method::fluff)); @@ -990,7 +990,7 @@ TEST_F(levin_notify, block_without_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::block)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1021,7 +1021,7 @@ TEST_F(levin_notify, none_without_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::none)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1052,7 +1052,7 @@ TEST_F(levin_notify, fluff_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::fluff)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); ASSERT_LT(0u, io_service_.poll()); @@ -1103,7 +1103,7 @@ TEST_F(levin_notify, stem_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); const bool is_stem = events_.has_stem_txes(); EXPECT_EQ(txs, events_.take_relayed(is_stem ? cryptonote::relay_method::stem : cryptonote::relay_method::fluff)); @@ -1172,7 +1172,7 @@ TEST_F(levin_notify, stem_no_outs_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); if (events_.has_stem_txes()) @@ -1235,7 +1235,7 @@ TEST_F(levin_notify, local_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(their_txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); const bool is_stem = events_.has_stem_txes(); EXPECT_EQ(their_txs, events_.take_relayed(is_stem ? cryptonote::relay_method::stem : cryptonote::relay_method::fluff)); @@ -1273,7 +1273,7 @@ TEST_F(levin_notify, local_with_padding) context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(my_txs, context->get_id(), cryptonote::relay_method::local)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_TRUE(events_.has_stem_txes()); EXPECT_EQ(my_txs, events_.take_relayed(cryptonote::relay_method::stem)); @@ -1332,7 +1332,7 @@ TEST_F(levin_notify, forward_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::forward)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); const bool is_stem = events_.has_stem_txes(); EXPECT_EQ(txs, events_.take_relayed(is_stem ? cryptonote::relay_method::stem : cryptonote::relay_method::fluff)); @@ -1398,7 +1398,7 @@ TEST_F(levin_notify, block_with_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::block)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1429,7 +1429,7 @@ TEST_F(levin_notify, none_with_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::none)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1460,10 +1460,10 @@ TEST_F(levin_notify, private_fluff_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::fluff)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); @@ -1513,10 +1513,10 @@ TEST_F(levin_notify, private_stem_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::stem)); @@ -1566,10 +1566,10 @@ TEST_F(levin_notify, private_local_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::local)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::local)); @@ -1619,10 +1619,10 @@ TEST_F(levin_notify, private_forward_without_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::forward)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::forward)); @@ -1672,7 +1672,7 @@ TEST_F(levin_notify, private_block_without_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::block)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1704,7 +1704,7 @@ TEST_F(levin_notify, private_none_without_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::none)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1735,10 +1735,10 @@ TEST_F(levin_notify, private_fluff_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::fluff)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); @@ -1787,10 +1787,10 @@ TEST_F(levin_notify, private_stem_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::stem)); @@ -1839,10 +1839,10 @@ TEST_F(levin_notify, private_local_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::local)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::local)); @@ -1891,10 +1891,10 @@ TEST_F(levin_notify, private_forward_with_padding) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::forward)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::forward)); @@ -1943,7 +1943,7 @@ TEST_F(levin_notify, private_block_with_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::block)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -1974,7 +1974,7 @@ TEST_F(levin_notify, private_none_with_padding) auto context = contexts_.begin(); EXPECT_FALSE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::none)); - io_service_.reset(); + io_service_.restart(); ASSERT_EQ(0u, io_service_.poll()); } } @@ -2008,14 +2008,14 @@ TEST_F(levin_notify, stem_mappings) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); if (events_.has_stem_txes()) break; EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(0u, context->process_send_queue()); @@ -2032,7 +2032,7 @@ TEST_F(levin_notify, stem_mappings) } notifier.run_epoch(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); } EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::stem)); @@ -2070,7 +2070,7 @@ TEST_F(levin_notify, stem_mappings) auto& incoming = contexts_[i % contexts_.size()]; EXPECT_TRUE(notifier.send_txs(txs, incoming.get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::stem)); @@ -2133,7 +2133,7 @@ TEST_F(levin_notify, fluff_multiple) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); if (!events_.has_stem_txes()) break; @@ -2164,12 +2164,12 @@ TEST_F(levin_notify, fluff_multiple) } notifier.run_epoch(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); } EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); { auto context = contexts_.begin(); @@ -2192,10 +2192,10 @@ TEST_F(levin_notify, fluff_multiple) auto& incoming = contexts_[i % contexts_.size()]; EXPECT_TRUE(notifier.send_txs(txs, incoming.get_id(), cryptonote::relay_method::stem)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); @@ -2252,7 +2252,7 @@ TEST_F(levin_notify, fluff_with_duplicate) auto context = contexts_.begin(); EXPECT_TRUE(notifier.send_txs(txs, context->get_id(), cryptonote::relay_method::fluff)); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); notifier.run_fluff(); ASSERT_LT(0u, io_service_.poll()); @@ -2303,7 +2303,7 @@ TEST_F(levin_notify, noise) } notifier.run_stems(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); { std::size_t sent = 0; @@ -2316,7 +2316,7 @@ TEST_F(levin_notify, noise) EXPECT_TRUE(notifier.send_txs(txs, incoming_id, cryptonote::relay_method::local)); notifier.run_stems(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::local)); @@ -2338,7 +2338,7 @@ TEST_F(levin_notify, noise) txs[0].resize(3000, 'r'); EXPECT_TRUE(notifier.send_txs(txs, incoming_id, cryptonote::relay_method::fluff)); notifier.run_stems(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); EXPECT_EQ(txs, events_.take_relayed(cryptonote::relay_method::fluff)); @@ -2352,7 +2352,7 @@ TEST_F(levin_notify, noise) } notifier.run_stems(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); { std::size_t sent = 0; @@ -2397,7 +2397,7 @@ TEST_F(levin_notify, noise_stem) } notifier.run_stems(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); { std::size_t sent = 0; @@ -2410,7 +2410,7 @@ TEST_F(levin_notify, noise_stem) EXPECT_TRUE(notifier.send_txs(txs, incoming_id, cryptonote::relay_method::stem)); notifier.run_stems(); - io_service_.reset(); + io_service_.restart(); ASSERT_LT(0u, io_service_.poll()); // downgraded to local when being notified diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp index abdd2558d7f..8c680301f35 100644 --- a/tests/unit_tests/net.cpp +++ b/tests/unit_tests/net.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -889,8 +889,8 @@ namespace struct io_thread { - boost::asio::io_service io_service; - boost::asio::io_service::work work; + boost::asio::io_context io_service; + boost::asio::executor_work_guard work; stream_type::socket server; stream_type::acceptor acceptor; boost::thread io; @@ -898,7 +898,7 @@ namespace io_thread() : io_service(), - work(io_service), + work(io_service.get_executor()), server(io_service), acceptor(io_service), io([this] () { try { this->io_service.run(); } catch (const std::exception& e) { MERROR(e.what()); }}), @@ -938,7 +938,7 @@ namespace TEST(socks_client, unsupported_command) { - boost::asio::io_service io_service{}; + boost::asio::io_context io_service{}; stream_type::socket client{io_service}; auto test_client = net::socks::make_connect_client( @@ -956,7 +956,7 @@ TEST(socks_client, unsupported_command) TEST(socks_client, no_command) { - boost::asio::io_service io_service{}; + boost::asio::io_context io_service{}; stream_type::socket client{io_service}; auto test_client = net::socks::make_connect_client( @@ -1110,7 +1110,7 @@ TEST(socks_connector, host) { io_thread io{}; boost::asio::steady_timer timeout{io.io_service}; - timeout.expires_from_now(std::chrono::seconds{5}); + timeout.expires_after(std::chrono::seconds{5}); boost::unique_future sock = net::socks::connector{io.acceptor.local_endpoint()}("example.com", "8080", timeout); @@ -1137,7 +1137,7 @@ TEST(socks_connector, ipv4) { io_thread io{}; boost::asio::steady_timer timeout{io.io_service}; - timeout.expires_from_now(std::chrono::seconds{5}); + timeout.expires_after(std::chrono::seconds{5}); boost::unique_future sock = net::socks::connector{io.acceptor.local_endpoint()}("250.88.125.99", "8080", timeout); @@ -1163,7 +1163,7 @@ TEST(socks_connector, error) { io_thread io{}; boost::asio::steady_timer timeout{io.io_service}; - timeout.expires_from_now(std::chrono::seconds{5}); + timeout.expires_after(std::chrono::seconds{5}); boost::unique_future sock = net::socks::connector{io.acceptor.local_endpoint()}("250.88.125.99", "8080", timeout); @@ -1189,7 +1189,7 @@ TEST(socks_connector, timeout) { io_thread io{}; boost::asio::steady_timer timeout{io.io_service}; - timeout.expires_from_now(std::chrono::milliseconds{10}); + timeout.expires_after(std::chrono::milliseconds{10}); boost::unique_future sock = net::socks::connector{io.acceptor.local_endpoint()}("250.88.125.99", "8080", timeout); diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp index 39178884c87..e5f1c910fae 100644 --- a/tests/unit_tests/node_server.cpp +++ b/tests/unit_tests/node_server.cpp @@ -341,14 +341,14 @@ TEST(cryptonote_protocol_handler, race_condition) using connections_t = std::vector; using shared_state_t = typename connection_t::shared_state; using shared_state_ptr = std::shared_ptr; - using io_context_t = boost::asio::io_service; + using io_context_t = boost::asio::io_context; using event_t = epee::simple_event; using ec_t = boost::system::error_code; auto create_conn_pair = [](connection_ptr in, connection_ptr out) { using endpoint_t = boost::asio::ip::tcp::endpoint; using acceptor_t = boost::asio::ip::tcp::acceptor; io_context_t io_context; - endpoint_t endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 5262); + endpoint_t endpoint(boost::asio::ip::make_address("127.0.0.1"), 5262); acceptor_t acceptor(io_context); ec_t ec; acceptor.open(endpoint.protocol(), ec); @@ -356,7 +356,7 @@ TEST(cryptonote_protocol_handler, race_condition) acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); acceptor.bind(endpoint, ec); EXPECT_EQ(ec.value(), 0); - acceptor.listen(boost::asio::socket_base::max_connections, ec); + acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); EXPECT_EQ(ec.value(), 0); out->socket().open(endpoint.protocol(), ec); EXPECT_EQ(ec.value(), 0); @@ -374,7 +374,7 @@ TEST(cryptonote_protocol_handler, race_condition) conn.get_context(context); return context.m_connection_id; }; - using work_t = boost::asio::io_service::work; + using work_t = boost::asio::executor_work_guard; using work_ptr = std::shared_ptr; using workers_t = std::vector; using commands_handler_t = epee::levin::levin_commands_handler; @@ -688,7 +688,7 @@ TEST(cryptonote_protocol_handler, race_condition) }; io_context_t io_context; - work_ptr work = std::make_shared(io_context); + work_ptr work = std::make_shared(io_context.get_executor()); workers_t workers; while (workers.size() < 4) { workers.emplace_back([&io_context]{ @@ -725,26 +725,28 @@ TEST(cryptonote_protocol_handler, race_condition) auto conn = connections.first; auto shared_state = daemon.main.shared_state; const auto tag = get_conn_tag(*conn); - conn->strand_.post([tag, conn, shared_state, &events]{ - shared_state->for_connection(tag, [](context_t &context){ - context.m_expect_height = -1; - context.m_expect_response = -1; - context.m_last_request_time = boost::date_time::min_date_time; - context.m_score = 0; - context.m_state = contexts::cryptonote::state_synchronizing; - return true; - }); - events.prepare.raise(); - events.check.wait(); - shared_state->for_connection(tag, [](context_t &context){ - EXPECT_TRUE(context.m_expect_height == -1); - EXPECT_TRUE(context.m_expect_response == -1); - EXPECT_TRUE(context.m_last_request_time == boost::date_time::min_date_time); - EXPECT_TRUE(context.m_score == 0); - EXPECT_TRUE(context.m_state == contexts::cryptonote::state_synchronizing); - return true; - }); - events.finish.raise(); + boost::asio::post( + conn->strand_, + [tag, conn, shared_state, &events]{ + shared_state->for_connection(tag, [](context_t &context){ + context.m_expect_height = -1; + context.m_expect_response = -1; + context.m_last_request_time = boost::date_time::min_date_time; + context.m_score = 0; + context.m_state = contexts::cryptonote::state_synchronizing; + return true; + }); + events.prepare.raise(); + events.check.wait(); + shared_state->for_connection(tag, [](context_t &context){ + EXPECT_TRUE(context.m_expect_height == -1); + EXPECT_TRUE(context.m_expect_response == -1); + EXPECT_TRUE(context.m_last_request_time == boost::date_time::min_date_time); + EXPECT_TRUE(context.m_score == 0); + EXPECT_TRUE(context.m_state == contexts::cryptonote::state_synchronizing); + return true; + }); + events.finish.raise(); }); } events.prepare.wait(); @@ -752,12 +754,14 @@ TEST(cryptonote_protocol_handler, race_condition) events.check.raise(); events.finish.wait(); - connections.first->strand_.post([connections]{ - connections.first->cancel(); - }); - connections.second->strand_.post([connections]{ - connections.second->cancel(); - }); + boost::asio::post( + connections.first->strand_, + [connections] { connections.first->cancel(); } + ); + boost::asio::post( + connections.second->strand_, + [connections] { connections.second->cancel(); } + ); connections.first.reset(); connections.second.reset(); while (daemon.main.shared_state->sock_count); @@ -799,7 +803,7 @@ TEST(cryptonote_protocol_handler, race_condition) work_ptr work; workers_t workers; } check; - check.work = std::make_shared(check.io_context); + check.work = std::make_shared(check.io_context.get_executor()); while (check.workers.size() < 2) { check.workers.emplace_back([&check]{ check.io_context.run(); @@ -820,18 +824,20 @@ TEST(cryptonote_protocol_handler, race_condition) auto conn = daemon.main.conn.back(); auto shared_state = daemon.main.shared_state; const auto tag = get_conn_tag(*conn); - conn->strand_.post([tag, conn, shared_state, &events]{ - shared_state->for_connection(tag, [](context_t &context){ - EXPECT_TRUE(context.m_state == contexts::cryptonote::state_normal); - return true; - }); - events.prepare.raise(); - events.sync.wait(); - shared_state->for_connection(tag, [](context_t &context){ - EXPECT_TRUE(context.m_state == contexts::cryptonote::state_normal); - return true; - }); - events.finish.raise(); + boost::asio::post( + conn->strand_, + [tag, conn, shared_state, &events]{ + shared_state->for_connection(tag, [](context_t &context){ + EXPECT_TRUE(context.m_state == contexts::cryptonote::state_normal); + return true; + }); + events.prepare.raise(); + events.sync.wait(); + shared_state->for_connection(tag, [](context_t &context){ + EXPECT_TRUE(context.m_state == contexts::cryptonote::state_normal); + return true; + }); + events.finish.raise(); }); } events.prepare.wait(); @@ -872,15 +878,11 @@ TEST(cryptonote_protocol_handler, race_condition) for (;daemon.main.conn.size(); daemon.main.conn.pop_back()) { auto conn = daemon.main.conn.back(); - conn->strand_.post([conn]{ - conn->cancel(); - }); + boost::asio::post(conn->strand_, [conn] { conn->cancel(); }); } for (;daemon.alt.conn.size(); daemon.alt.conn.pop_back()) { auto conn = daemon.alt.conn.back(); - conn->strand_.post([conn]{ - conn->cancel(); - }); + boost::asio::post(conn->strand_, [conn] { conn->cancel(); }); } while (daemon.main.shared_state->sock_count); while (daemon.alt.shared_state->sock_count); @@ -1048,8 +1050,8 @@ TEST(node_server, race_condition) using connection_ptr = boost::shared_ptr; using shared_state_t = typename connection_t::shared_state; using shared_state_ptr = std::shared_ptr; - using io_context_t = boost::asio::io_service; - using work_t = boost::asio::io_service::work; + using io_context_t = boost::asio::io_context; + using work_t = boost::asio::executor_work_guard; using work_ptr = std::shared_ptr; using workers_t = std::vector; using endpoint_t = boost::asio::ip::tcp::endpoint; @@ -1066,23 +1068,19 @@ TEST(node_server, race_condition) static void destroy(epee::levin::levin_commands_handler* ptr) { delete ptr; } }; io_context_t io_context; - work_ptr work = std::make_shared(io_context); + work_ptr work = std::make_shared(io_context.get_executor()); workers_t workers; while (workers.size() < 4) { workers.emplace_back([&io_context]{ io_context.run(); }); } - io_context.post([&]{ - protocol.on_idle(); - }); - io_context.post([&]{ - protocol.on_idle(); - }); + boost::asio::post(io_context, [&] { protocol.on_idle(); }); + boost::asio::post(io_context, [&] { protocol.on_idle(); }); shared_state_ptr shared_state = std::make_shared(); shared_state->set_handler(new command_handler_t, &command_handler_t::destroy); connection_ptr conn{new connection_t(io_context, shared_state, {}, {})}; - endpoint_t endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 48080); + endpoint_t endpoint(boost::asio::ip::make_address("127.0.0.1"), 48080); conn->socket().connect(endpoint); conn->socket().set_option(boost::asio::ip::tcp::socket::reuse_address(true)); conn->start({}, {}); @@ -1105,9 +1103,7 @@ TEST(node_server, race_condition) P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT ); handshaked.wait(); - conn->strand_.post([conn]{ - conn->cancel(); - }); + boost::asio::post(conn->strand_, [conn] { conn->cancel(); }); conn.reset(); work.reset(); for (auto& w: workers) {