Handshake timeout

# Conflicts:
#	nano/node/transport/tcp_listener.cpp
This commit is contained in:
Piotr Wójcik 2024-12-27 15:27:38 +01:00
commit 5ff3237fc1
4 changed files with 31 additions and 5 deletions

View file

@ -383,6 +383,7 @@ enum class detail
connect_rejected,
connect_success,
attempt_timeout,
handshake_timeout,
not_a_peer,
// tcp_channel

View file

@ -207,18 +207,35 @@ void nano::transport::tcp_listener::timeout ()
{
debug_assert (!mutex.try_lock ());
auto const cutoff = std::chrono::steady_clock::now () - config.connect_timeout;
auto const now = std::chrono::steady_clock::now ();
auto const connect_cutoff = now - config.connect_timeout;
auto const handshake_cutoff = now - config.handshake_timeout;
// Cancel timed out attempts
for (auto & attempt : attempts)
{
if (!attempt.task.ready () && attempt.start < cutoff)
if (!attempt.task.ready () && attempt.start < connect_cutoff)
{
attempt.task.cancel (); // Cancel is non-blocking and will return immediately, safe to call under lock
stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::attempt_timeout);
logger.debug (nano::log::type::tcp_listener, "Connection attempt timed out: {} (started {}s ago)",
attempt.endpoint, nano::log::seconds_delta (attempt.start));
attempt.endpoint,
nano::log::seconds_delta (attempt.start));
attempt.task.cancel (); // Cancel is non-blocking and will return immediately, safe to call under lock
}
}
// Cancel too long handshakes
for (auto & connection : connections)
{
if (connection.socket->type () == nano::transport::socket_type::undefined && connection.socket->get_time_connected () < handshake_cutoff)
{
stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::handshake_timeout);
logger.debug (nano::log::type::tcp_listener, "Handshake timed out: {} (connected {}s ago)",
connection.endpoint,
nano::log::seconds_delta (connection.socket->get_time_connected ()));
connection.socket->close (); // Schedule socket close, this is non-blocking, safe to call under lock
}
}
}

View file

@ -36,6 +36,7 @@ nano::transport::tcp_socket::tcp_socket (nano::node & node_a, boost::asio::ip::t
default_timeout{ node_a.config.tcp_io_timeout },
silent_connection_tolerance_time{ node_a.network_params.network.silent_connection_tolerance_time }
{
time_connected = std::chrono::steady_clock::now ();
}
nano::transport::tcp_socket::~tcp_socket ()
@ -77,6 +78,7 @@ void nano::transport::tcp_socket::async_connect (nano::tcp_endpoint const & endp
}
else
{
this_l->time_connected = std::chrono::steady_clock::now ();
this_l->set_last_completion ();
{
// Best effort attempt to get endpoint address

View file

@ -140,6 +140,10 @@ public:
{
return !is_closed ();
}
std::chrono::steady_clock::time_point get_time_connected () const
{
return time_connected.load ();
}
private:
size_t const queue_size;
@ -188,6 +192,8 @@ protected:
/** Updated only from strand, but stored as atomic so it can be read from outside */
std::atomic<bool> write_in_progress{ false };
std::atomic<std::chrono::steady_clock::time_point> time_connected;
void close_internal ();
void write_queued_messages ();
void set_default_timeout ();