Log tcp connection rejection reason (#4912)

This commit is contained in:
Piotr Wójcik 2025-05-25 23:40:25 +02:00 committed by GitHub
commit 7a01c80bd6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 62 additions and 26 deletions

View file

@ -3,6 +3,8 @@
#include <nano/lib/common.hpp> #include <nano/lib/common.hpp>
#include <nano/lib/numbers.hpp> #include <nano/lib/numbers.hpp>
#include <boost/system/error_code.hpp>
#include <fmt/ostream.h> #include <fmt/ostream.h>
template <> template <>
@ -59,3 +61,18 @@ template <>
struct fmt::formatter<nano::root> : fmt::formatter<nano::hash_or_account> struct fmt::formatter<nano::root> : fmt::formatter<nano::hash_or_account>
{ {
}; };
template <>
struct fmt::formatter<boost::system::error_code>
{
constexpr auto parse (format_parse_context & ctx)
{
return ctx.begin (); // No format specifiers supported
}
template <typename FormatContext>
auto format (const boost::system::error_code & ec, FormatContext & ctx)
{
return fmt::format_to (ctx.out (), "{} {}:{}", ec.message (), ec.value (), ec.category ().name ());
}
};

View file

@ -61,7 +61,7 @@ void nano::transport::tcp_listener::start ()
} }
catch (boost::system::system_error const & ex) catch (boost::system::system_error const & ex)
{ {
logger.critical (nano::log::type::tcp_listener, "Error while binding for incoming TCP: {} (port: {})", ex.what (), port); logger.critical (nano::log::type::tcp_listener, "Error while binding for incoming TCP: {} (port: {})", ex.code ().message (), port);
throw; throw;
} }
@ -108,7 +108,7 @@ void nano::transport::tcp_listener::stop ()
{ {
debug_assert (!stopped); debug_assert (!stopped);
logger.debug (nano::log::type::tcp_listener, "Stopping listening for incoming connections and closing all sockets..."); logger.debug (nano::log::type::tcp_listener, "Stopping...");
{ {
nano::lock_guard<nano::mutex> lock{ mutex }; nano::lock_guard<nano::mutex> lock{ mutex };
@ -134,6 +134,8 @@ void nano::transport::tcp_listener::stop ()
logger.error (nano::log::type::tcp_listener, "Error while closing acceptor: {}", ec.message ()); logger.error (nano::log::type::tcp_listener, "Error while closing acceptor: {}", ec.message ());
} }
logger.debug (nano::log::type::tcp_listener, "Closing all sockets...");
decltype (connections) connections_l; decltype (connections) connections_l;
decltype (attempts) attempts_l; decltype (attempts) attempts_l;
{ {
@ -160,6 +162,8 @@ void nano::transport::tcp_listener::stop ()
server->stop (); server->stop ();
} }
} }
logger.debug (nano::log::type::tcp_listener, "Stopped");
} }
void nano::transport::tcp_listener::run_cleanup () void nano::transport::tcp_listener::run_cleanup ()
@ -299,7 +303,7 @@ auto nano::transport::tcp_listener::connect_impl (asio::ip::tcp::endpoint endpoi
catch (boost::system::system_error const & ex) catch (boost::system::system_error const & ex)
{ {
stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::connect_error, nano::stat::dir::out); stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::connect_error, nano::stat::dir::out);
logger.log (nano::log::level::debug, nano::log::type::tcp_listener, "Error connecting to: {} ({})", endpoint, ex.code ().message ()); logger.log (nano::log::level::debug, nano::log::type::tcp_listener, "Error connecting to: {} ({})", endpoint, ex.code ());
} }
} }
@ -326,7 +330,7 @@ asio::awaitable<void> nano::transport::tcp_listener::run ()
catch (boost::system::system_error const & ex) catch (boost::system::system_error const & ex)
{ {
stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::accept_error, nano::stat::dir::in); stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::accept_error, nano::stat::dir::in);
logger.log (nano::log::level::debug, nano::log::type::tcp_listener, "Error accepting incoming connection: {}", ex.code ().message ()); logger.log (nano::log::level::debug, nano::log::type::tcp_listener, "Error accepting incoming connection: {}", ex.code ());
} }
// Sleep for a while to prevent busy loop // Sleep for a while to prevent busy loop
@ -386,8 +390,11 @@ auto nano::transport::tcp_listener::accept_one (asio::ip::tcp::socket raw_socket
if (auto result = check_limits (remote_endpoint.address (), type); result != accept_result::accepted) if (auto result = check_limits (remote_endpoint.address (), type); result != accept_result::accepted)
{ {
stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::accept_rejected, to_stat_dir (type)); stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::accept_rejected, to_stat_dir (type));
logger.debug (nano::log::type::tcp_listener, "Rejected connection from: {} ({})", remote_endpoint, to_string (type)); logger.debug (nano::log::type::tcp_listener, "Rejected connection from: {} reason: {} ({})",
// Rejection reason should be logged earlier remote_endpoint,
to_string (result),
to_string (type));
// Rejection details should be logged earlier
try try
{ {
@ -399,7 +406,7 @@ auto nano::transport::tcp_listener::accept_one (asio::ip::tcp::socket raw_socket
{ {
stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::close_error, to_stat_dir (type)); stats.inc (nano::stat::type::tcp_listener, nano::stat::detail::close_error, to_stat_dir (type));
logger.debug (nano::log::type::tcp_listener, "Error while closing socket after refusing connection: {} ({})", logger.debug (nano::log::type::tcp_listener, "Error while closing socket after refusing connection: {} ({})",
ex.code ().message (), to_string (type)); ex.code (), to_string (type));
} }
return { result }; return { result };
@ -440,7 +447,7 @@ auto nano::transport::tcp_listener::check_limits (asio::ip::address const & ip,
stats.inc (nano::stat::type::tcp_listener_rejected, nano::stat::detail::excluded, to_stat_dir (type)); stats.inc (nano::stat::type::tcp_listener_rejected, nano::stat::detail::excluded, to_stat_dir (type));
logger.debug (nano::log::type::tcp_listener, "Rejected connection from excluded peer: {} ({})", ip, to_string (type)); logger.debug (nano::log::type::tcp_listener, "Rejected connection from excluded peer: {} ({})", ip, to_string (type));
return accept_result::rejected; return accept_result::rejected_excluded;
} }
if (!node.flags.disable_max_peers_per_ip) if (!node.flags.disable_max_peers_per_ip)
@ -451,7 +458,7 @@ auto nano::transport::tcp_listener::check_limits (asio::ip::address const & ip,
logger.debug (nano::log::type::tcp_listener, "Max connections: {} per IP: {} reached, unable to open a new connection ({})", logger.debug (nano::log::type::tcp_listener, "Max connections: {} per IP: {} reached, unable to open a new connection ({})",
count, ip, to_string (type)); count, ip, to_string (type));
return accept_result::rejected; return accept_result::rejected_max_per_ip;
} }
} }
@ -464,7 +471,7 @@ auto nano::transport::tcp_listener::check_limits (asio::ip::address const & ip,
logger.debug (nano::log::type::tcp_listener, "Max connections: {} per subnetwork of IP: {} reached, unable to open a new connection ({})", logger.debug (nano::log::type::tcp_listener, "Max connections: {} per subnetwork of IP: {} reached, unable to open a new connection ({})",
count, ip, to_string (type)); count, ip, to_string (type));
return accept_result::rejected; return accept_result::rejected_max_per_subnetwork;
} }
} }
@ -478,7 +485,7 @@ auto nano::transport::tcp_listener::check_limits (asio::ip::address const & ip,
logger.debug (nano::log::type::tcp_listener, "Max inbound connections reached: {}, unable to accept new connection: {}", logger.debug (nano::log::type::tcp_listener, "Max inbound connections reached: {}, unable to accept new connection: {}",
count, ip); count, ip);
return accept_result::rejected; return accept_result::rejected_max_inbound;
} }
} }
if (type == connection_type::outbound) if (type == connection_type::outbound)
@ -489,7 +496,7 @@ auto nano::transport::tcp_listener::check_limits (asio::ip::address const & ip,
logger.debug (nano::log::type::tcp_listener, "Max outbound connections reached: {}, unable to initiate new connection: {}", logger.debug (nano::log::type::tcp_listener, "Max outbound connections reached: {}, unable to initiate new connection: {}",
count, ip); count, ip);
return accept_result::rejected; return accept_result::rejected_max_outbound;
} }
} }
@ -623,11 +630,6 @@ nano::stat::dir nano::transport::tcp_listener::to_stat_dir (connection_type type
return {}; return {};
} }
std::string_view nano::transport::tcp_listener::to_string (connection_type type)
{
return nano::enum_util::name (type);
}
nano::transport::socket_endpoint nano::transport::tcp_listener::to_socket_endpoint (connection_type type) nano::transport::socket_endpoint nano::transport::tcp_listener::to_socket_endpoint (connection_type type)
{ {
switch (type) switch (type)
@ -640,3 +642,13 @@ nano::transport::socket_endpoint nano::transport::tcp_listener::to_socket_endpoi
debug_assert (false); debug_assert (false);
return {}; return {};
} }
std::string_view nano::transport::to_string (nano::transport::tcp_listener::connection_type type)
{
return nano::enum_util::name (type);
}
std::string_view nano::transport::to_string (nano::transport::tcp_listener::accept_result result)
{
return nano::enum_util::name (result);
}

View file

@ -37,6 +37,19 @@ public:
outbound, outbound,
}; };
enum class accept_result
{
invalid,
accepted,
rejected,
rejected_excluded,
rejected_max_per_ip,
rejected_max_per_subnetwork,
rejected_max_inbound,
rejected_max_outbound,
error,
};
public: public:
tcp_listener (uint16_t port, tcp_config const &, nano::node &); tcp_listener (uint16_t port, tcp_config const &, nano::node &);
~tcp_listener (); ~tcp_listener ();
@ -82,14 +95,6 @@ private:
void cleanup (); void cleanup ();
void timeout (); void timeout ();
enum class accept_result
{
invalid,
accepted,
rejected,
error,
};
asio::awaitable<void> connect_impl (asio::ip::tcp::endpoint); asio::awaitable<void> connect_impl (asio::ip::tcp::endpoint);
asio::awaitable<asio::ip::tcp::socket> connect_socket (asio::ip::tcp::endpoint); asio::awaitable<asio::ip::tcp::socket> connect_socket (asio::ip::tcp::endpoint);
@ -155,7 +160,9 @@ private:
private: private:
static nano::stat::dir to_stat_dir (connection_type); static nano::stat::dir to_stat_dir (connection_type);
static std::string_view to_string (connection_type);
static nano::transport::socket_endpoint to_socket_endpoint (connection_type); static nano::transport::socket_endpoint to_socket_endpoint (connection_type);
}; };
std::string_view to_string (tcp_listener::connection_type);
std::string_view to_string (tcp_listener::accept_result);
} }