p2p, rpc: group public IPv6 connection limits by /64

(cherry picked from commit f277d328cf1f7e64423b5eb7dc0e21649f71e47a)
This commit is contained in:
selsta
2026-10-04 18:50:22 -04:00
committed by such-gitea
parent 881dcfbd43
commit f26ac02df9
13 changed files with 275 additions and 8 deletions
+1 -1
View File
@@ -176,7 +176,7 @@ namespace nodetool
const command_line::arg_descriptor<bool> arg_pad_transactions = {
"pad-transactions", "Pad relayed transactions to help defend against traffic volume analysis", false
};
const command_line::arg_descriptor<uint32_t> arg_max_connections_per_ip = {"max-connections-per-ip", "Maximum number of p2p connections allowed from the same IP address", 1};
const command_line::arg_descriptor<uint32_t> arg_max_connections_per_ip = {"max-connections-per-ip", "Maximum number of inbound p2p connections allowed from the same IPv4 address or shared across a public IPv6 /64 subnet", 1};
boost::optional<std::vector<proxy>> get_proxies(boost::program_options::variables_map const& vm)
{
+17 -1
View File
@@ -81,6 +81,22 @@ static inline boost::asio::ip::address_v4 make_address_v4_from_v6(const boost::a
namespace nodetool
{
inline bool is_same_p2p_connection_limit_host(const epee::net_utils::network_address& left, const epee::net_utils::network_address& right)
{
if (left.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id() &&
right.get_type_id() == epee::net_utils::ipv6_network_address::get_type_id())
{
const boost::asio::ip::address_v6 left_ip = left.as<const epee::net_utils::ipv6_network_address>().ip();
const boost::asio::ip::address_v6 right_ip = right.as<const epee::net_utils::ipv6_network_address>().ip();
if (epee::net_utils::should_group_ipv6_by_prefix(left_ip) &&
epee::net_utils::should_group_ipv6_by_prefix(right_ip))
return epee::net_utils::get_ipv6_subnet_address(left_ip, 64) ==
epee::net_utils::get_ipv6_subnet_address(right_ip, 64);
}
return left.is_same_host(right);
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
node_server<t_payload_net_handler>::~node_server()
{
@@ -2935,7 +2951,7 @@ namespace nodetool
m_network_zones.at(epee::net_utils::zone::public_).m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
{
if (cntxt.m_is_income && cntxt.m_remote_address.is_same_host(address)) {
if (cntxt.m_is_income && is_same_p2p_connection_limit_host(cntxt.m_remote_address, address)) {
count++;
// the only call location happens BEFORE foreach_connection list is updated
+1 -1
View File
@@ -3791,7 +3791,7 @@ namespace cryptonote
const command_line::arg_descriptor<std::size_t> core_rpc_server::arg_rpc_max_connections_per_public_ip = {
"rpc-max-connections-per-public-ip"
, "Max RPC connections per public IP permitted"
, "Max RPC connections permitted per public IPv4 address or shared across a public IPv6 /64 subnet"
, DEFAULT_RPC_MAX_CONNECTIONS_PER_PUBLIC_IP
};
+1 -1
View File
@@ -142,7 +142,7 @@ namespace
const command_line::arg_descriptor<std::string> arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"};
const command_line::arg_descriptor<bool> arg_prompt_for_password = {"prompt-for-password", "Prompts for password when not provided", false};
const command_line::arg_descriptor<bool> arg_no_initial_sync = {"no-initial-sync", "Skips the initial sync before listening for connections", false};
const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_public_ip = {"rpc-max-connections-per-public-ip", "Max RPC connections per public IP permitted", DEFAULT_RPC_MAX_CONNECTIONS_PER_PUBLIC_IP};
const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_public_ip = {"rpc-max-connections-per-public-ip", "Max RPC connections permitted per public IPv4 address or shared across a public IPv6 /64 subnet", DEFAULT_RPC_MAX_CONNECTIONS_PER_PUBLIC_IP};
const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_private_ip = {"rpc-max-connections-per-private-ip", "Max RPC connections per private and localhost IP permitted", DEFAULT_RPC_MAX_CONNECTIONS_PER_PRIVATE_IP};
const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections = {"rpc-max-connections", "Max RPC connections permitted", DEFAULT_RPC_MAX_CONNECTIONS};
const command_line::arg_descriptor<std::size_t> arg_rpc_response_soft_limit = {"rpc-response-soft-limit", "Max response bytes that can be queued, enforced at next response attempt", DEFAULT_RPC_SOFT_LIMIT_SIZE};