]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Support creating ephemeral services with PoW defenses
authorLd Qr <ldqr@pm.me>
Sat, 12 Oct 2024 05:09:03 +0000 (05:09 +0000)
committerLd Qr <ldqr@pm.me>
Sat, 12 Oct 2024 05:09:03 +0000 (05:09 +0000)
Add 3 more keywords to the ADD_ONION control command:
PoWDefensesEnabled, PoWQueueRate and PoWQueueBurst which correspond to
HiddenServicePoWDefensesEnabled, HiddenServicePoWQueueRate and HiddenServicePoWQueueBurst
from torrc.

src/feature/control/control_cmd.c
src/feature/control/control_cmd.h
src/feature/hs/hs_config.h
src/feature/hs/hs_service.c
src/feature/hs/hs_service.h
src/test/test_hs_control.c

index dd0cde4f7d992504fb21377164d88228d7b2e32e..2b44561acbab081dd15221694e8fe16336918f41 100644 (file)
@@ -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 */
index 8cbe70a2ed2ec03d2f3c2090e1b1a44b8cdd2971..fd48e4330b23378836c612ddc83c02dde0c5ba46 100644 (file)
@@ -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(
index bde6da9612f8572bde880a4e18db62a8fe02b76b..8e4596fb8536b13060df7696f38f8004739275f1 100644 (file)
@@ -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 */
 
index 3fb0220cc0bda270d6c1452275b7144c7dd135b3..6a0bbe6a686e5d04950040674659c35b1e9b94aa 100644 (file)
@@ -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));
index b3a41174611901aad588239b25e4597b9c9a44b1..a94f903324f9e33acedad746662c73a75277f05e 100644 (file)
@@ -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);
 
index eaeba47b0cfb910f7819fea73a91ce64a6e5742c..d7d0af1210bf4b84d5df957ef41b0714cb3d9544 100644 (file)
@@ -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);