Set response limits on http server connections

This commit is contained in:
Lee *!* Clagett
2025-02-13 23:55:17 -05:00
parent 915c5dc1d9
commit ec74ff4a3d
13 changed files with 423 additions and 27 deletions
+4
View File
@@ -127,6 +127,10 @@
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT 1000
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT 20000
#define DEFAULT_RPC_MAX_CONNECTIONS_PER_PUBLIC_IP 3
#define DEFAULT_RPC_MAX_CONNECTIONS_PER_PRIVATE_IP 25
#define DEFAULT_RPC_MAX_CONNECTIONS 100
#define DEFAULT_RPC_SOFT_LIMIT_SIZE 25 * 1024 * 1024 // 25 MiB
#define MAX_RPC_CONTENT_LENGTH 1048576 // 1 MB
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT 1000
+1 -1
View File
@@ -169,7 +169,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 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 p2p connections allowed from the same IP address", 1};
boost::optional<std::vector<proxy>> get_proxies(boost::program_options::variables_map const& vm)
{
+46 -1
View File
@@ -163,6 +163,10 @@ namespace cryptonote
command_line::add_arg(desc, arg_rpc_payment_difficulty);
command_line::add_arg(desc, arg_rpc_payment_credits);
command_line::add_arg(desc, arg_rpc_payment_allow_free_loopback);
command_line::add_arg(desc, arg_rpc_max_connections_per_public_ip);
command_line::add_arg(desc, arg_rpc_max_connections_per_private_ip);
command_line::add_arg(desc, arg_rpc_max_connections);
command_line::add_arg(desc, arg_rpc_response_soft_limit);
}
//------------------------------------------------------------------------------------------------------------------------------
core_rpc_server::core_rpc_server(
@@ -396,11 +400,28 @@ namespace cryptonote
}
} // if (store_ssl_key)
const auto max_connections_public = command_line::get_arg(vm, arg_rpc_max_connections_per_public_ip);
const auto max_connections_private = command_line::get_arg(vm, arg_rpc_max_connections_per_private_ip);
const auto max_connections = command_line::get_arg(vm, arg_rpc_max_connections);
if (max_connections < max_connections_public)
{
MFATAL(arg_rpc_max_connections_per_public_ip.name << " is bigger than " << arg_rpc_max_connections.name);
return false;
}
if (max_connections < max_connections_private)
{
MFATAL(arg_rpc_max_connections_per_private_ip.name << " is bigger than " << arg_rpc_max_connections.name);
return false;
}
auto rng = [](size_t len, uint8_t *ptr){ return crypto::rand(len, ptr); };
const bool inited = epee::http_server_impl_base<core_rpc_server, connection_context>::init(
rng, std::move(port), std::move(bind_ip_str),
std::move(bind_ipv6_str), std::move(rpc_config->use_ipv6), std::move(rpc_config->require_ipv4),
std::move(rpc_config->access_control_origins), std::move(http_login), std::move(rpc_config->ssl_options)
std::move(rpc_config->access_control_origins), std::move(http_login), std::move(rpc_config->ssl_options),
max_connections_public, max_connections_private, max_connections,
command_line::get_arg(vm, arg_rpc_response_soft_limit)
);
m_net_server.get_config_object().m_max_content_length = MAX_RPC_CONTENT_LENGTH;
@@ -3885,4 +3906,28 @@ namespace cryptonote
, "Allow free access from the loopback address (ie, the local host)"
, false
};
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"
, DEFAULT_RPC_MAX_CONNECTIONS_PER_PUBLIC_IP
};
const command_line::arg_descriptor<std::size_t> core_rpc_server::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> core_rpc_server::arg_rpc_max_connections = {
"rpc-max-connections"
, "Max RPC connections permitted"
, DEFAULT_RPC_MAX_CONNECTIONS
};
const command_line::arg_descriptor<std::size_t> core_rpc_server::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
};
} // namespace cryptonote
+4 -1
View File
@@ -56,7 +56,6 @@ namespace cryptonote
{
public:
static const command_line::arg_descriptor<bool> arg_public_node;
static const command_line::arg_descriptor<std::string, false, true, 2> arg_rpc_bind_port;
static const command_line::arg_descriptor<std::string> arg_rpc_restricted_bind_port;
static const command_line::arg_descriptor<bool> arg_restricted_rpc;
@@ -73,6 +72,10 @@ namespace cryptonote
static const command_line::arg_descriptor<uint64_t> arg_rpc_payment_difficulty;
static const command_line::arg_descriptor<uint64_t> arg_rpc_payment_credits;
static const command_line::arg_descriptor<bool> arg_rpc_payment_allow_free_loopback;
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_public_ip;
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_private_ip;
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections;
static const command_line::arg_descriptor<std::size_t> arg_rpc_response_soft_limit;
typedef epee::net_utils::connection_context_base connection_context;
+26 -1
View File
@@ -129,6 +129,10 @@ 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_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};
constexpr const char default_rpc_username[] = "monero";
@@ -325,13 +329,30 @@ namespace tools
check_background_mining();
const auto max_connections_public = command_line::get_arg(vm, arg_rpc_max_connections_per_public_ip);
const auto max_connections_private = command_line::get_arg(vm, arg_rpc_max_connections_per_private_ip);
const auto max_connections = command_line::get_arg(vm, arg_rpc_max_connections);
if (max_connections < max_connections_public)
{
MFATAL(arg_rpc_max_connections_per_public_ip.name << " is bigger than " << arg_rpc_max_connections.name);
return false;
}
if (max_connections < max_connections_private)
{
MFATAL(arg_rpc_max_connections_per_private_ip.name << " is bigger than " << arg_rpc_max_connections.name);
return false;
}
m_net_server.set_threads_prefix("RPC");
auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); };
return epee::http_server_impl_base<wallet_rpc_server, connection_context>::init(
rng, std::move(bind_port), std::move(rpc_config->bind_ip),
std::move(rpc_config->bind_ipv6_address), std::move(rpc_config->use_ipv6), std::move(rpc_config->require_ipv4),
std::move(rpc_config->access_control_origins), std::move(http_login),
std::move(rpc_config->ssl_options)
std::move(rpc_config->ssl_options),
max_connections_public, max_connections_private, max_connections,
command_line::get_arg(vm, arg_rpc_response_soft_limit)
);
}
//------------------------------------------------------------------------------------------------------------------------------
@@ -4974,6 +4995,10 @@ int main(int argc, char** argv) {
command_line::add_arg(desc_params, arg_wallet_dir);
command_line::add_arg(desc_params, arg_prompt_for_password);
command_line::add_arg(desc_params, arg_no_initial_sync);
command_line::add_arg(desc_params, arg_rpc_max_connections_per_public_ip);
command_line::add_arg(desc_params, arg_rpc_max_connections_per_private_ip);
command_line::add_arg(desc_params, arg_rpc_max_connections);
command_line::add_arg(desc_params, arg_rpc_response_soft_limit);
command_line::add_arg(hidden_options, daemonizer::arg_non_interactive);
daemonizer::init_options(hidden_options, desc_params);