diff options
author | David Goulet <dgoulet@torproject.org> | 2021-01-26 12:11:10 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2021-02-22 15:48:52 -0500 |
commit | 45113b648b413989ca82d2c3be6afae1699cae43 (patch) | |
tree | d2223044533c9ebc0d11d41452546a536996f1b4 /src/test/test_dos.c | |
parent | 99703eaca0f575e4739523ca815cf55329d16024 (diff) | |
download | tor-45113b648b413989ca82d2c3be6afae1699cae43.tar.gz tor-45113b648b413989ca82d2c3be6afae1699cae43.zip |
test: Add DoS connection rate unit test
Related to #40253
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/test/test_dos.c')
-rw-r--r-- | src/test/test_dos.c | 61 |
1 files changed, 61 insertions, 0 deletions
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 }; |