Purge syn cookies from thread

This commit is contained in:
Piotr Wójcik 2024-03-13 20:34:53 +01:00 committed by Piotr Wójcik
commit 05fbd416e4
5 changed files with 37 additions and 41 deletions

View file

@ -72,6 +72,7 @@ enum class type
election_scheduler, election_scheduler,
vote_generator, vote_generator,
rep_tiers, rep_tiers,
syn_cookies,
// bootstrap // bootstrap
bulk_pull_client, bulk_pull_client,

View file

@ -53,6 +53,7 @@ enum class type : uint8_t
rep_crawler, rep_crawler,
local_block_broadcaster, local_block_broadcaster,
rep_tiers, rep_tiers,
syn_cookies,
bootstrap_ascending, bootstrap_ascending,
bootstrap_ascending_accounts, bootstrap_ascending_accounts,

View file

@ -15,17 +15,17 @@ using namespace std::chrono_literals;
* network * network
*/ */
nano::network::network (nano::node & node_a, uint16_t port_a) : nano::network::network (nano::node & node, uint16_t port) :
node (node_a), node{ node },
id (nano::network_constants::active_network), id{ nano::network_constants::active_network },
syn_cookies (node_a.network_params.network.max_peers_per_ip), syn_cookies{ node.network_params.network.max_peers_per_ip, node.logger },
resolver (node_a.io_ctx), resolver{ node.io_ctx },
tcp_message_manager (node_a.config.tcp_incoming_connections_max), tcp_message_manager{ node.config.tcp_incoming_connections_max },
publish_filter (256 * 1024), publish_filter{ 256 * 1024 },
tcp_channels (node_a, [this] (nano::message const & message, std::shared_ptr<nano::transport::channel> const & channel) { tcp_channels{ node, [this] (nano::message const & message, std::shared_ptr<nano::transport::channel> const & channel) {
inbound (message, channel); inbound (message, channel);
}), } },
port (port_a) port{ port }
{ {
} }
@ -38,15 +38,11 @@ nano::network::~network ()
void nano::network::start () void nano::network::start ()
{ {
if (!node.flags.disable_connection_cleanup) cleanup_thread = std::thread ([this] () {
{ nano::thread_role::set (nano::thread_role::name::network_cleanup);
cleanup_thread = std::thread ([this] () { run_cleanup ();
nano::thread_role::set (nano::thread_role::name::network_cleanup); });
run_cleanup ();
});
}
ongoing_syn_cookie_cleanup ();
ongoing_keepalive (); ongoing_keepalive ();
if (!node.flags.disable_tcp_realtime) if (!node.flags.disable_tcp_realtime)
@ -133,8 +129,14 @@ void nano::network::run_cleanup ()
node.stats.inc (nano::stat::type::network, nano::stat::detail::loop_cleanup); node.stats.inc (nano::stat::type::network, nano::stat::detail::loop_cleanup);
auto const cutoff = std::chrono::steady_clock::now () - node.network_params.network.cleanup_cutoff (); if (!node.flags.disable_connection_cleanup)
cleanup (cutoff); {
auto const cutoff = std::chrono::steady_clock::now () - node.network_params.network.cleanup_cutoff ();
cleanup (cutoff);
}
auto const syn_cookie_cutoff = std::chrono::steady_clock::now () - node.network_params.network.syn_cookie_cutoff;
syn_cookies.purge (syn_cookie_cutoff);
lock.lock (); lock.lock ();
} }
@ -542,18 +544,6 @@ void nano::network::cleanup (std::chrono::steady_clock::time_point const & cutof
} }
} }
void nano::network::ongoing_syn_cookie_cleanup ()
{
syn_cookies.purge (std::chrono::steady_clock::now () - nano::transport::syn_cookie_cutoff);
std::weak_ptr<nano::node> node_w (node.shared ());
node.workers.add_timed_task (std::chrono::steady_clock::now () + (nano::transport::syn_cookie_cutoff * 2), [node_w] () {
if (auto node_l = node_w.lock ())
{
node_l->network.ongoing_syn_cookie_cleanup ();
}
});
}
void nano::network::ongoing_keepalive () void nano::network::ongoing_keepalive ()
{ {
flood_keepalive (0.75f); flood_keepalive (0.75f);
@ -717,18 +707,19 @@ void nano::tcp_message_manager::stop ()
* syn_cookies * syn_cookies
*/ */
nano::syn_cookies::syn_cookies (std::size_t max_cookies_per_ip_a) : nano::syn_cookies::syn_cookies (std::size_t max_cookies_per_ip_a, nano::logger & logger_a) :
max_cookies_per_ip (max_cookies_per_ip_a) max_cookies_per_ip (max_cookies_per_ip_a),
logger (logger_a)
{ {
} }
boost::optional<nano::uint256_union> nano::syn_cookies::assign (nano::endpoint const & endpoint_a) std::optional<nano::uint256_union> nano::syn_cookies::assign (nano::endpoint const & endpoint_a)
{ {
auto ip_addr (endpoint_a.address ()); auto ip_addr (endpoint_a.address ());
debug_assert (ip_addr.is_v6 ()); debug_assert (ip_addr.is_v6 ());
nano::lock_guard<nano::mutex> lock{ syn_cookie_mutex }; nano::lock_guard<nano::mutex> lock{ syn_cookie_mutex };
unsigned & ip_cookies = cookies_per_ip[ip_addr]; unsigned & ip_cookies = cookies_per_ip[ip_addr];
boost::optional<nano::uint256_union> result; std::optional<nano::uint256_union> result;
if (ip_cookies < max_cookies_per_ip) if (ip_cookies < max_cookies_per_ip)
{ {
if (cookies.find (endpoint_a) == cookies.end ()) if (cookies.find (endpoint_a) == cookies.end ())
@ -770,6 +761,8 @@ bool nano::syn_cookies::validate (nano::endpoint const & endpoint_a, nano::accou
void nano::syn_cookies::purge (std::chrono::steady_clock::time_point const & cutoff_a) void nano::syn_cookies::purge (std::chrono::steady_clock::time_point const & cutoff_a)
{ {
logger.debug (nano::log::type::syn_cookies, "Purging syn cookies, cutoff: {}s", nano::log::seconds_delta (cutoff_a));
nano::lock_guard<nano::mutex> lock{ syn_cookie_mutex }; nano::lock_guard<nano::mutex> lock{ syn_cookie_mutex };
auto it (cookies.begin ()); auto it (cookies.begin ());
while (it != cookies.end ()) while (it != cookies.end ())

View file

@ -43,12 +43,12 @@ private:
class syn_cookies final class syn_cookies final
{ {
public: public:
explicit syn_cookies (std::size_t); syn_cookies (std::size_t max_peers_per_ip, nano::logger &);
void purge (std::chrono::steady_clock::time_point const &); void purge (std::chrono::steady_clock::time_point const &);
// Returns boost::none if the IP is rate capped on syn cookie requests, // Returns boost::none if the IP is rate capped on syn cookie requests,
// or if the endpoint already has a syn cookie query // or if the endpoint already has a syn cookie query
boost::optional<nano::uint256_union> assign (nano::endpoint const &); std::optional<nano::uint256_union> assign (nano::endpoint const &);
// Returns false if valid, true if invalid (true on error convention) // Returns false if valid, true if invalid (true on error convention)
// Also removes the syn cookie from the store if valid // Also removes the syn cookie from the store if valid
bool validate (nano::endpoint const &, nano::account const &, nano::signature const &); bool validate (nano::endpoint const &, nano::account const &, nano::signature const &);
@ -58,6 +58,9 @@ public:
std::unique_ptr<container_info_component> collect_container_info (std::string const &); std::unique_ptr<container_info_component> collect_container_info (std::string const &);
std::size_t cookies_size (); std::size_t cookies_size ();
private: // Dependencies
nano::logger & logger;
private: private:
class syn_cookie_info final class syn_cookie_info final
{ {
@ -112,7 +115,6 @@ public:
nano::tcp_endpoint bootstrap_peer (); nano::tcp_endpoint bootstrap_peer ();
nano::endpoint endpoint () const; nano::endpoint endpoint () const;
void cleanup (std::chrono::steady_clock::time_point const & cutoff); void cleanup (std::chrono::steady_clock::time_point const & cutoff);
void ongoing_syn_cookie_cleanup ();
void ongoing_keepalive (); void ongoing_keepalive ();
std::size_t size () const; std::size_t size () const;
float size_sqrt () const; float size_sqrt () const;

View file

@ -22,5 +22,4 @@ bool is_ipv4_or_v4_mapped_address (boost::asio::ip::address const &);
// Unassigned, reserved, self // Unassigned, reserved, self
bool reserved_address (nano::endpoint const &, bool = false); bool reserved_address (nano::endpoint const &, bool = false);
static std::chrono::seconds constexpr syn_cookie_cutoff = std::chrono::seconds (5);
} }