diff --git a/nano/node/network.cpp b/nano/node/network.cpp index f67ed7f5..e5b17780 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -810,6 +810,10 @@ void nano::tcp_message_manager::stop () producer_condition.notify_all (); } +/* + * syn_cookies + */ + nano::syn_cookies::syn_cookies (std::size_t max_cookies_per_ip_a) : max_cookies_per_ip (max_cookies_per_ip_a) { @@ -888,6 +892,30 @@ void nano::syn_cookies::purge (std::chrono::steady_clock::time_point const & cut } } +std::optional nano::syn_cookies::cookie (const nano::endpoint & endpoint_a) +{ + auto ip_addr (endpoint_a.address ()); + debug_assert (ip_addr.is_v6 ()); + nano::lock_guard lock{ syn_cookie_mutex }; + auto cookie_it (cookies.find (endpoint_a)); + if (cookie_it != cookies.end ()) + { + auto cookie = cookie_it->second.cookie; + cookies.erase (cookie_it); + unsigned & ip_cookies = cookies_per_ip[ip_addr]; + if (ip_cookies > 0) + { + --ip_cookies; + } + else + { + debug_assert (false && "More SYN cookies deleted than created for IP"); + } + return cookie; + } + return std::nullopt; +} + std::size_t nano::syn_cookies::cookies_size () { nano::lock_guard lock{ syn_cookie_mutex }; diff --git a/nano/node/network.hpp b/nano/node/network.hpp index cb103593..363ef7c2 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -14,6 +14,7 @@ namespace nano { class node; + class tcp_message_manager final { public: @@ -34,13 +35,15 @@ private: friend class network_tcp_message_manager_Test; }; + /** * Node ID cookies for node ID handshakes */ class syn_cookies final { public: - syn_cookies (std::size_t); + explicit syn_cookies (std::size_t); + void purge (std::chrono::steady_clock::time_point const &); // Returns boost::none if the IP is rate capped on syn cookie requests, // or if the endpoint already has a syn cookie query @@ -48,6 +51,9 @@ public: // Returns false if valid, true if invalid (true on error convention) // Also removes the syn cookie from the store if valid bool validate (nano::endpoint const &, nano::account const &, nano::signature const &); + /** Get cookie associated with endpoint and erases that cookie from this container */ + std::optional cookie (nano::endpoint const &); + std::unique_ptr collect_container_info (std::string const &); std::size_t cookies_size ();