[tor-commits] [tor/master] hs-v3: Add consensus parameters for DoS defenses

nickm at torproject.org nickm at torproject.org
Wed Aug 7 13:52:13 UTC 2019


commit c5b00c5a514a6b40e5245bc1fd78fe5490922739
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue Jun 11 08:28:13 2019 -0400

    hs-v3: Add consensus parameters for DoS defenses
    
    Part of #15516
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 scripts/maint/practracker/exceptions.txt | 24 +++++++++
 src/app/main/main.c                      |  5 ++
 src/feature/hs/hs_common.c               |  2 +
 src/feature/hs/hs_dos.c                  | 85 ++++++++++++++++++++++++++++++++
 src/feature/hs/hs_dos.h                  | 25 ++++------
 src/feature/nodelist/networkstatus.c     |  2 +
 src/test/test_hs_dos.c                   |  2 +
 src/test/test_hs_intropoint.c            | 19 +++++++
 8 files changed, 148 insertions(+), 16 deletions(-)

diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index d437726fe..af3ab3304 100644
--- a/scripts/maint/practracker/exceptions.txt
+++ b/scripts/maint/practracker/exceptions.txt
@@ -39,6 +39,7 @@ problem function-size /src/app/config/config.c:options_init_from_torrc() 207
 problem function-size /src/app/config/config.c:options_init_from_string() 171
 problem function-size /src/app/config/config.c:options_init_logs() 145
 problem function-size /src/app/config/config.c:parse_bridge_line() 104
+<<<<<<< HEAD
 problem function-size /src/app/config/config.c:parse_transport_line() 189
 problem function-size /src/app/config/config.c:parse_dir_authority_line() 150
 problem function-size /src/app/config/config.c:parse_dir_fallback_line() 101
@@ -48,6 +49,19 @@ problem function-size /src/app/config/config.c:getinfo_helper_config() 113
 problem include-count /src/app/main/main.c 67
 problem function-size /src/app/main/main.c:dumpstats() 102
 problem function-size /src/app/main/main.c:tor_init() 133
+=======
+problem function-size /src/app/config/config.c:parse_transport_line() 191
+problem function-size /src/app/config/config.c:parse_dir_authority_line() 151
+problem function-size /src/app/config/config.c:parse_dir_fallback_line() 102
+problem function-size /src/app/config/config.c:parse_port_config() 452
+problem function-size /src/app/config/config.c:parse_ports() 170
+problem function-size /src/app/config/config.c:getinfo_helper_config() 116
+problem function-size /src/app/config/confparse.c:config_assign_value() 205
+problem function-size /src/app/config/confparse.c:config_get_assigned_option() 129
+problem include-count /src/app/main/main.c 68
+problem function-size /src/app/main/main.c:dumpstats() 102
+problem function-size /src/app/main/main.c:tor_init() 141
+>>>>>>> hs-v3: Add consensus parameters for DoS defenses
 problem function-size /src/app/main/main.c:sandbox_init_filter() 291
 problem function-size /src/app/main/main.c:run_tor_main_loop() 105
 problem function-size /src/app/main/ntmain.c:nt_service_install() 126
@@ -206,6 +220,7 @@ problem function-size /src/feature/nodelist/authcert.c:trusted_dirs_load_certs_f
 problem function-size /src/feature/nodelist/authcert.c:authority_certs_fetch_missing() 295
 problem function-size /src/feature/nodelist/fmt_routerstatus.c:routerstatus_format_entry() 162
 problem function-size /src/feature/nodelist/microdesc.c:microdesc_cache_rebuild() 134
+<<<<<<< HEAD
 problem include-count /src/feature/nodelist/networkstatus.c 62
 problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_check_consensus_signature() 175
 problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_set_current_consensus() 289
@@ -213,6 +228,15 @@ problem function-size /src/feature/nodelist/node_select.c:router_pick_directory_
 problem function-size /src/feature/nodelist/node_select.c:compute_weighted_bandwidths() 203
 problem function-size /src/feature/nodelist/node_select.c:router_pick_trusteddirserver_impl() 112
 problem function-size /src/feature/nodelist/nodelist.c:compute_frac_paths_available() 190
+=======
+problem include-count /src/feature/nodelist/networkstatus.c 63
+problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_check_consensus_signature() 176
+problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_set_current_consensus() 293
+problem function-size /src/feature/nodelist/node_select.c:router_pick_directory_server_impl() 123
+problem function-size /src/feature/nodelist/node_select.c:compute_weighted_bandwidths() 206
+problem function-size /src/feature/nodelist/node_select.c:router_pick_trusteddirserver_impl() 114
+problem function-size /src/feature/nodelist/nodelist.c:compute_frac_paths_available() 193
+>>>>>>> hs-v3: Add consensus parameters for DoS defenses
 problem file-size /src/feature/nodelist/routerlist.c 3239
 problem function-size /src/feature/nodelist/routerlist.c:router_rebuild_store() 148
 problem function-size /src/feature/nodelist/routerlist.c:router_add_to_routerlist() 168
diff --git a/src/app/main/main.c b/src/app/main/main.c
index 31cee3763..3bdf8f146 100644
--- a/src/app/main/main.c
+++ b/src/app/main/main.c
@@ -41,6 +41,7 @@
 #include "feature/dircache/consdiffmgr.h"
 #include "feature/dirparse/routerparse.h"
 #include "feature/hibernate/hibernate.h"
+#include "feature/hs/hs_dos.h"
 #include "feature/nodelist/authcert.h"
 #include "feature/nodelist/networkstatus.h"
 #include "feature/nodelist/routerlist.h"
@@ -637,6 +638,10 @@ tor_init(int argc, char *argv[])
   /* Initialize circuit padding to defaults+torrc until we get a consensus */
   circpad_machines_init();
 
+  /* Initialize hidden service DoS subsystem. We need to do this once the
+   * configuration object has been set because it can be accessed. */
+  hs_dos_init();
+
   /* Initialize predicted ports list after loading options */
   predicted_ports_init();
 
diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c
index a5747fe17..8661ce046 100644
--- a/src/feature/hs/hs_common.c
+++ b/src/feature/hs/hs_common.c
@@ -21,6 +21,7 @@
 #include "feature/hs/hs_circuitmap.h"
 #include "feature/hs/hs_client.h"
 #include "feature/hs/hs_common.h"
+#include "feature/hs/hs_dos.h"
 #include "feature/hs/hs_ident.h"
 #include "feature/hs/hs_service.h"
 #include "feature/hs_common/shared_random_client.h"
@@ -30,6 +31,7 @@
 #include "feature/nodelist/routerset.h"
 #include "feature/rend/rendcommon.h"
 #include "feature/rend/rendservice.h"
+#include "feature/relay/routermode.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
 
diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c
index ad9d044f4..25d282adb 100644
--- a/src/feature/hs/hs_dos.c
+++ b/src/feature/hs/hs_dos.c
@@ -18,14 +18,92 @@
 
 #define HS_DOS_PRIVATE
 
+#include "core/or/or.h"
+#include "app/config/config.h"
+
 #include "core/or/circuitlist.h"
 
+#include "feature/nodelist/networkstatus.h"
+#include "feature/relay/routermode.h"
+
+#include "lib/evloop/token_bucket.h"
+
 #include "hs_dos.h"
 
+/* Default value of the allowed INTRODUCE2 cell rate per second. Above that
+ * value per second, the introduction is denied. */
+#define HS_DOS_INTRODUCE_CELL_RATE_PER_SEC 25
+
+/* Default value of the allowed INTRODUCE2 cell burst per second. This is the
+ * maximum value a token bucket has per second. We thus allow up to this value
+ * of INTRODUCE2 cell per second but the bucket is refilled by the rate value
+ * but never goes above that burst value. */
+#define HS_DOS_INTRODUCE_CELL_BURST_PER_SEC 200
+
+/* Consensus parameters. */
+static uint32_t hs_dos_introduce_rate_per_sec =
+  HS_DOS_INTRODUCE_CELL_RATE_PER_SEC;
+static uint32_t hs_dos_introduce_burst_per_sec =
+  HS_DOS_INTRODUCE_CELL_BURST_PER_SEC;
+
+/* Return the parameter for the introduction rate per sec. */
+static uint32_t
+get_param_rate_per_sec(const networkstatus_t *ns)
+{
+  return networkstatus_get_param(ns, "HiddenServiceEnableIntroDoSRatePerSec",
+                                 HS_DOS_INTRODUCE_CELL_RATE_PER_SEC,
+                                 0, INT32_MAX);
+}
+
+/* Return the parameter for the introduction burst per sec. */
+static uint32_t
+get_param_burst_per_sec(const networkstatus_t *ns)
+{
+  return networkstatus_get_param(ns, "HiddenServiceEnableIntroDoSBurstPerSec",
+                                 HS_DOS_INTRODUCE_CELL_BURST_PER_SEC,
+                                 0, INT32_MAX);
+}
+
+/* Set consensus parameters. */
+static void
+set_consensus_parameters(const networkstatus_t *ns)
+{
+  hs_dos_introduce_rate_per_sec = get_param_rate_per_sec(ns);
+  hs_dos_introduce_burst_per_sec = get_param_burst_per_sec(ns);
+}
+
 /*
  * Public API.
  */
 
+/* Return the INTRODUCE2 cell rate per second. */
+uint32_t
+hs_dos_get_intro2_rate(void)
+{
+  return hs_dos_introduce_rate_per_sec;
+}
+
+/* Return the INTRODUCE2 cell burst per second. */
+uint32_t
+hs_dos_get_intro2_burst(void)
+{
+  return hs_dos_introduce_burst_per_sec;
+}
+
+/* Called when the consensus has changed. We might have new consensus
+ * parameters to look at. */
+void
+hs_dos_consensus_has_changed(const networkstatus_t *ns)
+{
+  /* No point on updating these values if we are not a public relay that can
+   * be picked to be an introduction point. */
+  if (!public_server_mode(get_options())) {
+    return;
+  }
+
+  set_consensus_parameters(ns);
+}
+
 /* Return true iff an INTRODUCE2 cell can be sent on the given service
  * introduction circuit. */
 bool
@@ -58,3 +136,10 @@ hs_dos_can_send_intro2(or_circuit_t *s_intro_circ)
   /* Finally, we can send a new INTRODUCE2 if there are still tokens. */
   return token_bucket_ctr_get(&s_intro_circ->introduce2_bucket) > 0;
 }
+
+/* Initialize the onion service Denial of Service subsystem. */
+void
+hs_dos_init(void)
+{
+  set_consensus_parameters(NULL);
+}
diff --git a/src/feature/hs/hs_dos.h b/src/feature/hs/hs_dos.h
index e3a83a103..9fba00b52 100644
--- a/src/feature/hs/hs_dos.h
+++ b/src/feature/hs/hs_dos.h
@@ -12,26 +12,19 @@
 
 #include "core/or/or_circuit_st.h"
 
-#include "lib/evloop/token_bucket.h"
+#include "feature/nodelist/networkstatus_st.h"
 
-#define HS_DOS_INTRODUCE_CELL_RATE_PER_SEC 25
-#define HS_DOS_INTRODUCE_CELL_BURST_PER_SEC 200
+/* Init */
+void hs_dos_init(void);
+
+/* Consensus. */
+void hs_dos_consensus_has_changed(const networkstatus_t *ns);
 
 bool hs_dos_can_send_intro2(or_circuit_t *s_intro_circ);
 
-/* Return the INTRODUCE2 cell rate per second. */
-static inline
-uint32_t hs_dos_get_intro2_rate(void)
-{
-  return HS_DOS_INTRODUCE_CELL_RATE_PER_SEC;
-}
-
-/* Return the INTRODUCE2 cell burst per second. */
-static inline
-uint32_t hs_dos_get_intro2_burst(void)
-{
-  return HS_DOS_INTRODUCE_CELL_BURST_PER_SEC;
-}
+/* Getters. */
+uint32_t hs_dos_get_intro2_rate(void);
+uint32_t hs_dos_get_intro2_burst(void);
 
 #ifdef HS_DOS_PRIVATE
 
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index 2db293a8a..496bafb86 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -68,6 +68,7 @@
 #include "feature/dircommon/voting_schedule.h"
 #include "feature/dirparse/ns_parse.h"
 #include "feature/hibernate/hibernate.h"
+#include "feature/hs/hs_dos.h"
 #include "feature/nodelist/authcert.h"
 #include "feature/nodelist/dirlist.h"
 #include "feature/nodelist/fmt_routerstatus.h"
@@ -1674,6 +1675,7 @@ notify_before_networkstatus_changes(const networkstatus_t *old_c,
   notify_control_networkstatus_changed(old_c, new_c);
   dos_consensus_has_changed(new_c);
   relay_consensus_has_changed(new_c);
+  hs_dos_consensus_has_changed(new_c);
 }
 
 /* Called after a new consensus has been put in the global state. It is safe
diff --git a/src/test/test_hs_dos.c b/src/test/test_hs_dos.c
index 6ade897b7..6b8261053 100644
--- a/src/test/test_hs_dos.c
+++ b/src/test/test_hs_dos.c
@@ -26,6 +26,8 @@ test_can_send_intro2(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   or_circ =  or_circuit_new(1, NULL);
 
   /* Make that circuit a service intro point. */
diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c
index 87338b448..1d472397c 100644
--- a/src/test/test_hs_intropoint.c
+++ b/src/test/test_hs_intropoint.c
@@ -26,6 +26,7 @@
 #include "feature/hs/hs_cell.h"
 #include "feature/hs/hs_circuitmap.h"
 #include "feature/hs/hs_common.h"
+#include "feature/hs/hs_dos.h"
 #include "feature/hs/hs_intropoint.h"
 #include "feature/hs/hs_service.h"
 
@@ -185,6 +186,8 @@ test_establish_intro_wrong_purpose(void *arg)
 
   (void)arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   memcpy(intro_circ->rend_circ_nonce, circ_nonce, DIGEST_LEN);
@@ -227,6 +230,8 @@ test_establish_intro_wrong_keytype(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -254,6 +259,8 @@ test_establish_intro_wrong_keytype2(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -290,6 +297,8 @@ test_establish_intro_wrong_mac(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -362,6 +371,8 @@ test_establish_intro_wrong_auth_key_len(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -407,6 +418,8 @@ test_establish_intro_wrong_sig_len(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -450,6 +463,8 @@ test_establish_intro_wrong_sig(void *arg)
 
   (void) arg;
 
+  hs_dos_init();
+
   /* Get the auth key of the intro point */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -487,6 +502,8 @@ helper_establish_intro_v3(or_circuit_t *intro_circ)
 
   tt_assert(intro_circ);
 
+  hs_dos_init();
+
   /* Prepare the circuit for the incoming ESTABLISH_INTRO */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
@@ -522,6 +539,8 @@ helper_establish_intro_v2(or_circuit_t *intro_circ)
 
   tt_assert(intro_circ);
 
+  hs_dos_init();
+
   /* Prepare the circuit for the incoming ESTABLISH_INTRO */
   crypto_rand(circ_nonce, sizeof(circ_nonce));
   helper_prepare_circ_for_intro(intro_circ, circ_nonce);





More information about the tor-commits mailing list