commit d89d497ab6b6ddb1622e3da997e23058751a5b89
parent b9907f787cc4c7c2d5174536fee3cb7c05bdd5f6
Author: David Goulet <dgoulet@torproject.org>
Date: Thu, 27 Mar 2025 11:20:07 -0400
Merge branch 'tor-gitlab/mr/835'
Diffstat:
6 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c
@@ -32,6 +32,7 @@
#include "feature/control/control_events.h"
#include "feature/control/control_getinfo.h"
#include "feature/control/control_proto.h"
+#include "feature/hs/hs_config.h"
#include "feature/hs/hs_control.h"
#include "feature/hs/hs_service.h"
#include "feature/nodelist/nodelist.h"
@@ -1578,6 +1579,9 @@ add_onion_helper_add_service(int hs_version,
add_onion_secret_key_t *pk,
smartlist_t *port_cfgs, int max_streams,
int max_streams_close_circuit,
+ int pow_defenses_enabled,
+ uint32_t pow_queue_rate,
+ uint32_t pow_queue_burst,
smartlist_t *auth_clients_v3, char **address_out)
{
hs_service_add_ephemeral_status_t ret;
@@ -1590,6 +1594,9 @@ add_onion_helper_add_service(int hs_version,
case HS_VERSION_THREE:
ret = hs_service_add_ephemeral(pk->v3, port_cfgs, max_streams,
max_streams_close_circuit,
+ pow_defenses_enabled,
+ pow_queue_rate,
+ pow_queue_burst,
auth_clients_v3, address_out);
break;
default:
@@ -1614,7 +1621,15 @@ get_detached_onion_services(void)
}
static const char *add_onion_keywords[] = {
- "Port", "Flags", "MaxStreams", "ClientAuth", "ClientAuthV3", NULL
+ "Port",
+ "Flags",
+ "MaxStreams",
+ "PoWDefensesEnabled",
+ "PoWQueueRate",
+ "PoWQueueBurst",
+ "ClientAuth",
+ "ClientAuthV3",
+ NULL
};
static const control_cmd_syntax_t add_onion_syntax = {
.min_args = 1, .max_args = 1,
@@ -1641,6 +1656,9 @@ handle_control_add_onion(control_connection_t *conn,
int max_streams = 0;
int max_streams_close_circuit = 0;
int non_anonymous = 0;
+ int pow_defenses_enabled = HS_CONFIG_V3_POW_DEFENSES_DEFAULT;
+ uint32_t pow_queue_rate = HS_CONFIG_V3_POW_QUEUE_RATE;
+ uint32_t pow_queue_burst = HS_CONFIG_V3_POW_QUEUE_BURST;
const config_line_t *arg;
for (arg = args->kwargs; arg; arg = arg->next) {
@@ -1660,6 +1678,30 @@ handle_control_add_onion(control_connection_t *conn,
control_write_endreply(conn, 512, "Invalid MaxStreams");
goto out;
}
+ } else if (!strcasecmp(arg->key, "PoWDefensesEnabled")) {
+ int ok = 0;
+ pow_defenses_enabled = (int)tor_parse_long(arg->value, 10,
+ 0, 1, &ok, NULL);
+ if (!ok) {
+ control_write_endreply(conn, 512, "Invalid PoWDefensesEnabled");
+ goto out;
+ }
+ } else if (!strcasecmp(arg->key, "PoWQueueRate")) {
+ int ok = 0;
+ pow_queue_rate = (uint32_t)tor_parse_ulong(arg->value, 10,
+ 0, UINT32_MAX, &ok, NULL);
+ if (!ok) {
+ control_write_endreply(conn, 512, "Invalid PoWQueueRate");
+ goto out;
+ }
+ } else if (!strcasecmp(arg->key, "PoWQueueBurst")) {
+ int ok = 0;
+ pow_queue_burst = (uint32_t)tor_parse_ulong(arg->value, 10,
+ 0, UINT32_MAX, &ok, NULL);
+ if (!ok) {
+ control_write_endreply(conn, 512, "Invalid PoWQueueBurst");
+ goto out;
+ }
} else if (!strcasecmp(arg->key, "Flags")) {
/* "Flags=Flag[,Flag]", where Flag can be:
* * 'DiscardPK' - If tor generates the keypair, do not include it in
@@ -1775,6 +1817,9 @@ handle_control_add_onion(control_connection_t *conn,
int ret = add_onion_helper_add_service(hs_version, &pk, port_cfgs,
max_streams,
max_streams_close_circuit,
+ pow_defenses_enabled,
+ pow_queue_rate,
+ pow_queue_burst,
auth_clients_v3, &service_id);
port_cfgs = NULL; /* port_cfgs is now owned by the hs_service code. */
auth_clients_v3 = NULL; /* so is auth_clients_v3 */
diff --git a/src/feature/control/control_cmd.h b/src/feature/control/control_cmd.h
@@ -98,6 +98,9 @@ STATIC hs_service_add_ephemeral_status_t add_onion_helper_add_service(
add_onion_secret_key_t *pk,
smartlist_t *port_cfgs, int max_streams,
int max_streams_close_circuit,
+ int pow_defenses_enabled,
+ uint32_t pow_queue_rate,
+ uint32_t pow_queue_burst,
smartlist_t *auth_clients_v3, char **address_out);
STATIC control_cmd_args_t *control_cmd_parse_args(
diff --git a/src/feature/hs/hs_config.h b/src/feature/hs/hs_config.h
@@ -27,6 +27,8 @@
/* Default values for the HS anti-DoS PoW defenses. */
#define HS_CONFIG_V3_POW_DEFENSES_DEFAULT 0
+#define HS_CONFIG_V3_POW_QUEUE_RATE 250
+#define HS_CONFIG_V3_POW_QUEUE_BURST 2500
/* API */
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
@@ -264,7 +264,9 @@ set_service_default_config(hs_service_config_t *c,
c->intro_dos_rate_per_sec = HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT;
c->intro_dos_burst_per_sec = HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT;
/* PoW default options. */
- c->has_dos_defense_enabled = HS_CONFIG_V3_POW_DEFENSES_DEFAULT;
+ c->has_pow_defenses_enabled = HS_CONFIG_V3_POW_DEFENSES_DEFAULT;
+ c->pow_queue_rate = HS_CONFIG_V3_POW_QUEUE_RATE;
+ c->pow_queue_burst = HS_CONFIG_V3_POW_QUEUE_BURST;
}
/** Initialize PoW defenses */
@@ -4063,6 +4065,9 @@ hs_service_add_ephemeral_status_t
hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports,
int max_streams_per_rdv_circuit,
int max_streams_close_circuit,
+ int pow_defenses_enabled,
+ uint32_t pow_queue_rate,
+ uint32_t pow_queue_burst,
smartlist_t *auth_clients_v3, char **address_out)
{
hs_service_add_ephemeral_status_t ret;
@@ -4082,6 +4087,9 @@ hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports,
service->config.is_ephemeral = 1;
smartlist_free(service->config.ports);
service->config.ports = ports;
+ service->config.has_pow_defenses_enabled = pow_defenses_enabled;
+ service->config.pow_queue_rate = pow_queue_rate;
+ service->config.pow_queue_burst = pow_queue_burst;
/* Handle the keys. */
memcpy(&service->keys.identity_sk, sk, sizeof(service->keys.identity_sk));
diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h
@@ -389,6 +389,9 @@ hs_service_add_ephemeral_status_t
hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports,
int max_streams_per_rdv_circuit,
int max_streams_close_circuit,
+ int pow_defenses_enabled,
+ uint32_t pow_queue_rate,
+ uint32_t pow_queue_burst,
smartlist_t *auth_clients_v3, char **address_out);
int hs_service_del_ephemeral(const char *address);
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
@@ -23,6 +23,7 @@
#include "app/config/config.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_client.h"
+#include "feature/hs/hs_config.h"
#include "feature/hs/hs_control.h"
#include "feature/nodelist/nodelist.h"
@@ -829,8 +830,12 @@ test_hs_control_add_onion_helper_add_service(void *arg)
list_good = smartlist_new();
smartlist_add(list_good, client_good);
- add_onion_helper_add_service(HS_VERSION_THREE, &sk_good, portcfgs, 1, 1,
- list_good, &address_out_good);
+ add_onion_helper_add_service(
+ HS_VERSION_THREE, &sk_good, portcfgs, 1, 1,
+ /*pow_defenses_enabled=*/1,
+ /*pow_queue_rate=*/HS_CONFIG_V3_POW_QUEUE_RATE,
+ /*pow_queue_burst=*/HS_CONFIG_V3_POW_QUEUE_BURST,
+ list_good, &address_out_good);
service_good = find_service(global_map, &pk_good);
tt_int_op(smartlist_len(service_good->config.clients), OP_EQ, 1);
@@ -845,8 +850,12 @@ test_hs_control_add_onion_helper_add_service(void *arg)
portcfgs = smartlist_new();
smartlist_add(portcfgs, portcfg);
- add_onion_helper_add_service(HS_VERSION_THREE, &sk_bad, portcfgs, 1, 1,
- list_bad, &address_out_bad);
+ add_onion_helper_add_service(
+ HS_VERSION_THREE, &sk_bad, portcfgs, 1, 1,
+ /*pow_defenses_enabled=*/1,
+ /*pow_queue_rate=*/HS_CONFIG_V3_POW_QUEUE_RATE,
+ /*pow_queue_burst=*/HS_CONFIG_V3_POW_QUEUE_BURST,
+ list_bad, &address_out_bad);
service_bad = find_service(global_map, &pk_bad);