From 97afc803b338d3b1cae5c478fd91cf017f270218 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Mon, 14 Sep 2020 14:38:31 +0200 Subject: [PATCH] socket_server should accept and drop connections when it hits the limit. This relieves the operating system from managing listening socket overflow. (#2929) The existing implementation didn't attempt to evict stale connections before testing if after an overflow occurred, possibly needlessly disconnecting a connection. After an overflow, the listening socket also wouldn't accept connections for 2 seconds, regardless of whether a connection goes stale during that time. --- nano/node/socket.cpp | 45 ++++++++++++++++---------------------------- nano/node/socket.hpp | 1 - 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/nano/node/socket.cpp b/nano/node/socket.cpp index e2f6c3c0..14ff5c9b 100644 --- a/nano/node/socket.cpp +++ b/nano/node/socket.cpp @@ -325,7 +325,7 @@ size_t nano::socket::get_max_write_queue_size () const } nano::server_socket::server_socket (std::shared_ptr node_a, boost::asio::ip::tcp::endpoint local_a, size_t max_connections_a, nano::socket::concurrency concurrency_a) : -socket (node_a, std::chrono::seconds::max (), concurrency_a), acceptor (node_a->io_ctx), local (local_a), deferred_accept_timer (node_a->io_ctx), max_inbound_connections (max_connections_a), concurrency_new_connections (concurrency_a) +socket (node_a, std::chrono::seconds::max (), concurrency_a), acceptor (node_a->io_ctx), local (local_a), max_inbound_connections (max_connections_a), concurrency_new_connections (concurrency_a) { } @@ -367,14 +367,15 @@ void nano::server_socket::on_connection (std::functionacceptor.is_open ()) { - if (this_l->connections.size () < this_l->max_inbound_connections) - { - // Prepare new connection - auto new_connection (std::make_shared (node_l->shared (), boost::none, this_l->concurrency_new_connections)); - this_l->acceptor.async_accept (new_connection->tcp_socket, new_connection->remote, - boost::asio::bind_executor (this_l->strand, - [this_l, new_connection, callback_a](boost::system::error_code const & ec_a) { - if (auto node_l = this_l->node.lock ()) + // Prepare new connection + auto new_connection (std::make_shared (node_l->shared (), boost::none, this_l->concurrency_new_connections)); + this_l->acceptor.async_accept (new_connection->tcp_socket, new_connection->remote, + boost::asio::bind_executor (this_l->strand, + [this_l, new_connection, callback_a](boost::system::error_code const & ec_a) { + this_l->evict_dead_connections (); + if (auto node_l = this_l->node.lock ()) + { + if (this_l->connections.size () < this_l->max_inbound_connections) { if (!ec_a) { @@ -384,7 +385,6 @@ void nano::server_socket::on_connection (std::functionstart_timer (node_l->network_params.network.is_dev_network () ? std::chrono::seconds (2) : node_l->network_params.node.idle_timeout); node_l->stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_success, nano::stat::dir::in); this_l->connections.push_back (new_connection); - this_l->evict_dead_connections (); } else { @@ -401,28 +401,15 @@ void nano::server_socket::on_connection (std::functionlogger.try_log ("Stopping to accept connections"); } } - })); - } - else - { - this_l->evict_dead_connections (); - node_l->stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in); - this_l->deferred_accept_timer.expires_after (std::chrono::seconds (2)); - this_l->deferred_accept_timer.async_wait ([this_l, callback_a](const boost::system::error_code & ec_a) { - if (!ec_a) - { - // Try accepting again - std::static_pointer_cast (this_l)->on_connection (callback_a); - } else { - if (auto node_l = this_l->node.lock ()) - { - node_l->logger.try_log ("Unable to accept connection (deferred): ", ec_a.message ()); - } + node_l->stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in); + boost::asio::post (this_l->strand, boost::asio::bind_executor (this_l->strand, [this_l, callback_a]() { + this_l->on_connection (callback_a); + })); } - }); - } + }; + })); } } })); diff --git a/nano/node/socket.hpp b/nano/node/socket.hpp index 399f9373..838d162c 100644 --- a/nano/node/socket.hpp +++ b/nano/node/socket.hpp @@ -132,7 +132,6 @@ private: std::vector> connections; boost::asio::ip::tcp::acceptor acceptor; boost::asio::ip::tcp::endpoint local; - boost::asio::steady_timer deferred_accept_timer; size_t max_inbound_connections; /** Concurrency setting for new connections */ concurrency concurrency_new_connections;