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,
vote_generator,
rep_tiers,
syn_cookies,
// bootstrap
bulk_pull_client,

View file

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

View file

@ -15,17 +15,17 @@ using namespace std::chrono_literals;
* network
*/
nano::network::network (nano::node & node_a, uint16_t port_a) :
node (node_a),
id (nano::network_constants::active_network),
syn_cookies (node_a.network_params.network.max_peers_per_ip),
resolver (node_a.io_ctx),
tcp_message_manager (node_a.config.tcp_incoming_connections_max),
publish_filter (256 * 1024),
tcp_channels (node_a, [this] (nano::message const & message, std::shared_ptr<nano::transport::channel> const & channel) {
inbound (message, channel);
}),
port (port_a)
nano::network::network (nano::node & node, uint16_t port) :
node{ node },
id{ nano::network_constants::active_network },
syn_cookies{ node.network_params.network.max_peers_per_ip, node.logger },
resolver{ node.io_ctx },
tcp_message_manager{ node.config.tcp_incoming_connections_max },
publish_filter{ 256 * 1024 },
tcp_channels{ node, [this] (nano::message const & message, std::shared_ptr<nano::transport::channel> const & channel) {
inbound (message, channel);
} },
port{ port }
{
}
@ -38,15 +38,11 @@ nano::network::~network ()
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);
run_cleanup ();
});
}
cleanup_thread = std::thread ([this] () {
nano::thread_role::set (nano::thread_role::name::network_cleanup);
run_cleanup ();
});
ongoing_syn_cookie_cleanup ();
ongoing_keepalive ();
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);
auto const cutoff = std::chrono::steady_clock::now () - node.network_params.network.cleanup_cutoff ();
cleanup (cutoff);
if (!node.flags.disable_connection_cleanup)
{
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 ();
}
@ -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 ()
{
flood_keepalive (0.75f);
@ -717,18 +707,19 @@ void nano::tcp_message_manager::stop ()
* syn_cookies
*/
nano::syn_cookies::syn_cookies (std::size_t max_cookies_per_ip_a) :
max_cookies_per_ip (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),
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 ());
debug_assert (ip_addr.is_v6 ());
nano::lock_guard<nano::mutex> lock{ syn_cookie_mutex };
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 (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)
{
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 };
auto it (cookies.begin ());
while (it != cookies.end ())

View file

@ -43,12 +43,12 @@ private:
class syn_cookies final
{
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 &);
// Returns boost::none if the IP is rate capped on syn cookie requests,
// 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)
// Also removes the syn cookie from the store if valid
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::size_t cookies_size ();
private: // Dependencies
nano::logger & logger;
private:
class syn_cookie_info final
{
@ -112,7 +115,6 @@ public:
nano::tcp_endpoint bootstrap_peer ();
nano::endpoint endpoint () const;
void cleanup (std::chrono::steady_clock::time_point const & cutoff);
void ongoing_syn_cookie_cleanup ();
void ongoing_keepalive ();
std::size_t size () 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
bool reserved_address (nano::endpoint const &, bool = false);
static std::chrono::seconds constexpr syn_cookie_cutoff = std::chrono::seconds (5);
}