#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"
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;
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:
}
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,
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) {
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
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 */
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(
/* 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 */
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 */
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;
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));
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);
#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"
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);
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);