Skip to content

Commit

Permalink
Better handling of TCP accept overflow (#1638)
Browse files Browse the repository at this point in the history
  • Loading branch information
rkeene committed Jan 28, 2019
1 parent 72bfc97 commit b97581f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
36 changes: 30 additions & 6 deletions nano/node/bootstrap.cpp
Expand Up @@ -1884,6 +1884,7 @@ void nano::bootstrap_initiator::notify_listeners (bool in_progress_a)

nano::bootstrap_listener::bootstrap_listener (boost::asio::io_context & io_ctx_a, uint16_t port_a, nano::node & node_a) :
acceptor (io_ctx_a),
defer_acceptor (io_ctx_a),
local (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::any (), port_a)),
io_ctx (io_ctx_a),
node (node_a)
Expand Down Expand Up @@ -1928,26 +1929,49 @@ void nano::bootstrap_listener::stop ()

void nano::bootstrap_listener::accept_connection ()
{
auto socket (std::make_shared<nano::socket> (node.shared ()));
acceptor.async_accept (socket->socket_m, [this, socket](boost::system::error_code const & ec) {
accept_action (ec, socket);
});
if (acceptor.is_open ())
{
if (connections.size () < node.config.bootstrap_connections_max)
{
auto socket (std::make_shared<nano::socket> (node.shared ()));
acceptor.async_accept (socket->socket_m, [this, socket](boost::system::error_code const & ec) {
accept_action (ec, socket);
});
}
else
{
BOOST_LOG (node.log) << boost::str (boost::format ("Unable to accept new TCP network sockets (have %1% concurrent connections, limit of %2%), will try to accept again in 1s") % connections.size () % node.config.bootstrap_connections_max);
defer_acceptor.expires_after (std::chrono::seconds (1));
defer_acceptor.async_wait ([this](const boost::system::error_code & ec) {
/*
* There should be no other call points that can invoke
* accept_connect() after starting the listener, so if we
* get an error from the I/O context, something is probably
* wrong.
*/
if (!ec)
{
accept_connection ();
}
});
}
}
}

void nano::bootstrap_listener::accept_action (boost::system::error_code const & ec, std::shared_ptr<nano::socket> socket_a)
{
if (!ec)
{
accept_connection ();
auto connection (std::make_shared<nano::bootstrap_server> (socket_a, node.shared ()));
{
std::lock_guard<std::mutex> lock (mutex);
if (connections.size () < node.config.bootstrap_connections_max && acceptor.is_open ())
if (acceptor.is_open ())
{
connections[connection.get ()] = connection;
connection->receive ();
}
}
accept_connection ();
}
else
{
Expand Down
3 changes: 3 additions & 0 deletions nano/node/bootstrap.hpp
Expand Up @@ -259,6 +259,9 @@ class bootstrap_listener
boost::asio::io_context & io_ctx;
nano::node & node;
bool on;

private:
boost::asio::steady_timer defer_acceptor;
};
class message;
class bootstrap_server : public std::enable_shared_from_this<nano::bootstrap_server>
Expand Down

0 comments on commit b97581f

Please sign in to comment.