[tor-commits] [tor/master] test: Add DoS connection rate unit test

ahf at torproject.org ahf at torproject.org
Mon Feb 22 21:03:05 UTC 2021


commit 45113b648b413989ca82d2c3be6afae1699cae43
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue Jan 26 12:11:10 2021 -0500

    test: Add DoS connection rate unit test
    
    Related to #40253
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/core/or/dos.c   |  2 +-
 src/core/or/dos.h   |  1 +
 src/test/test_dos.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/src/core/or/dos.c b/src/core/or/dos.c
index 0169a631c2..ba4e5442d6 100644
--- a/src/core/or/dos.c
+++ b/src/core/or/dos.c
@@ -210,7 +210,7 @@ get_param_conn_connect_rate(const networkstatus_t *ns)
 
 /* Return the connection connect burst parameters either from the
  * configuration file or, if not found, consensus parameter. */
-static uint32_t
+STATIC uint32_t
 get_param_conn_connect_burst(const networkstatus_t *ns)
 {
   if (dos_get_options()->DoSConnectionConnectBurst) {
diff --git a/src/core/or/dos.h b/src/core/or/dos.h
index cadabdb2c9..3153a1fc5f 100644
--- a/src/core/or/dos.h
+++ b/src/core/or/dos.h
@@ -155,6 +155,7 @@ STATIC uint32_t get_param_conn_max_concurrent_count(
 STATIC uint32_t get_param_cc_circuit_burst(const networkstatus_t *ns);
 STATIC uint32_t get_param_cc_min_concurrent_connection(
                                             const networkstatus_t *ns);
+STATIC uint32_t get_param_conn_connect_burst(const networkstatus_t *ns);
 
 STATIC uint64_t get_circuit_rate_per_second(void);
 STATIC void cc_stats_refill_bucket(cc_client_stats_t *stats,
diff --git a/src/test/test_dos.c b/src/test/test_dos.c
index cbebecb030..d9ddaec108 100644
--- a/src/test/test_dos.c
+++ b/src/test/test_dos.c
@@ -79,6 +79,9 @@ test_dos_conn_creation(void *arg)
   { /* Register many conns from this client but not enough to get it blocked */
     unsigned int i;
     for (i = 0; i < max_concurrent_conns; i++) {
+      /* Don't trigger the connect() rate limitation so advance the clock 1
+       * second for each connection. */
+      update_approx_time(++now);
       dos_new_client_conn(&or_conn, NULL);
     }
   }
@@ -496,11 +499,69 @@ test_known_relay(void *arg)
   UNMOCK(get_param_cc_enabled);
 }
 
+/** Test that the connection tracker of the DoS subsystem will block clients
+ *  who try to establish too many connections */
+static void
+test_dos_conn_rate(void *arg)
+{
+  (void) arg;
+
+  MOCK(get_param_cc_enabled, mock_enable_dos_protection);
+  MOCK(get_param_conn_enabled, mock_enable_dos_protection);
+
+  /* Initialize test data */
+  or_connection_t or_conn;
+  time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
+  tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr,
+                                          "18.0.0.1"));
+  tor_addr_t *addr = &TO_CONN(&or_conn)->addr;
+  update_approx_time(now);
+
+  /* Get DoS subsystem limits */
+  dos_init();
+  uint32_t burst_conn = get_param_conn_connect_burst(NULL);
+
+  /* Introduce new client */
+  geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
+  { /* Register many conns from this client but not enough to get it blocked */
+    unsigned int i;
+    for (i = 0; i < burst_conn - 1; i++) {
+      dos_new_client_conn(&or_conn, NULL);
+    }
+  }
+
+  /* Check that new conns are still permitted */
+  tt_int_op(DOS_CONN_DEFENSE_NONE, OP_EQ,
+            dos_conn_addr_get_defense_type(addr));
+
+  /* Register another conn and check that new conns are not allowed anymore.
+   * We should have reached our burst. */
+  dos_new_client_conn(&or_conn, NULL);
+  tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
+            dos_conn_addr_get_defense_type(addr));
+
+  /* Advance the time 12 hours. It should still be blocked. */
+  update_approx_time(now + (12 * 60 * 60));
+  tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
+            dos_conn_addr_get_defense_type(addr));
+
+  /* Advance the time 24 hours plus 13 hours. It should be unblocked.
+   * Remember, we had a random value between 24 hours and rand(24/2) thus
+   * adding 13 hours is safe. */
+  update_approx_time(now + (37 * 60 * 60));
+  tt_int_op(DOS_CONN_DEFENSE_NONE, OP_EQ,
+            dos_conn_addr_get_defense_type(addr));
+
+ done:
+  dos_free_all();
+}
+
 struct testcase_t dos_tests[] = {
   { "conn_creation", test_dos_conn_creation, TT_FORK, NULL, NULL },
   { "circuit_creation", test_dos_circuit_creation, TT_FORK, NULL, NULL },
   { "bucket_refill", test_dos_bucket_refill, TT_FORK, NULL, NULL },
   { "known_relay" , test_known_relay, TT_FORK,
     NULL, NULL },
+  { "conn_rate", test_dos_conn_rate, TT_FORK, NULL, NULL },
   END_OF_TESTCASES
 };





More information about the tor-commits mailing list