From 9f738be8937d675929b43a149d706160641a089d Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 29 May 2019 14:05:16 -0400 Subject: [PATCH 1/8] hs: Limit the amount of relayed INTRODUCE2 This commit add the hs_dos.{c|h} file that has the purpose of having the anti-DoS code for onion services. At this commit, it only has one which is a function that decides if an INTRODUCE2 can be sent on the given introduction service circuit (S<->IP) using a simple token bucket. The rate per second is 25 and allowed burst to 200. Basic defenses on #15516. Signed-off-by: David Goulet --- src/core/include.am | 2 ++ src/core/or/or_circuit_st.h | 7 ++++ src/feature/hs/hs_dos.c | 60 ++++++++++++++++++++++++++++++++++ src/feature/hs/hs_dos.h | 44 +++++++++++++++++++++++++ src/feature/hs/hs_intropoint.c | 22 +++++++++++-- src/feature/rend/rendmid.c | 9 +++++ src/test/test_hs_intropoint.c | 2 ++ 7 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 src/feature/hs/hs_dos.c create mode 100644 src/feature/hs/hs_dos.h diff --git a/src/core/include.am b/src/core/include.am index 1a4b9fb8ab..ee275f172c 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -117,6 +117,7 @@ LIBTOR_APP_A_SOURCES = \ src/feature/hs/hs_config.c \ src/feature/hs/hs_control.c \ src/feature/hs/hs_descriptor.c \ + src/feature/hs/hs_dos.c \ src/feature/hs/hs_ident.c \ src/feature/hs/hs_intropoint.c \ src/feature/hs/hs_service.c \ @@ -374,6 +375,7 @@ noinst_HEADERS += \ src/feature/hs/hs_config.h \ src/feature/hs/hs_control.h \ src/feature/hs/hs_descriptor.h \ + src/feature/hs/hs_dos.h \ src/feature/hs/hs_ident.h \ src/feature/hs/hs_intropoint.h \ src/feature/hs/hs_service.h \ diff --git a/src/core/or/or_circuit_st.h b/src/core/or/or_circuit_st.h index 6789668224..8f319585a6 100644 --- a/src/core/or/or_circuit_st.h +++ b/src/core/or/or_circuit_st.h @@ -12,6 +12,8 @@ #include "core/or/circuit_st.h" #include "core/or/crypt_path_st.h" +#include "lib/evloop/token_bucket.h" + struct onion_queue_t; /** An or_circuit_t holds information needed to implement a circuit at an @@ -69,6 +71,11 @@ struct or_circuit_t { * exit-ward queues of this circuit; reset every time when writing * buffer stats to disk. */ uint64_t total_cell_waiting_time; + + /** INTRODUCE2 cell bucket controlling how much can go on this circuit. Only + * used if this is a service introduction circuit at the intro point + * (purpose = CIRCUIT_PURPOSE_INTRO_POINT). */ + token_bucket_ctr_t introduce2_bucket; }; #endif /* !defined(OR_CIRCUIT_ST_H) */ diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c new file mode 100644 index 0000000000..ad9d044f48 --- /dev/null +++ b/src/feature/hs/hs_dos.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file hs_dos.c + * \brief Implement denial of service mitigation for the onion service + * subsystem. + * + * This module defenses: + * + * - Introduction Rate Limiting: If enabled by the consensus, an introduction + * point will rate limit client introduction towards the service (INTRODUCE2 + * cells). It uses a token bucket model with a rate and burst per second. + * + * Proposal 305 will expand this module by allowing an operator to define + * these values into the ESTABLISH_INTRO cell. Not yet implemented. + **/ + +#define HS_DOS_PRIVATE + +#include "core/or/circuitlist.h" + +#include "hs_dos.h" + +/* + * Public API. + */ + +/* Return true iff an INTRODUCE2 cell can be sent on the given service + * introduction circuit. */ +bool +hs_dos_can_send_intro2(or_circuit_t *s_intro_circ) +{ + tor_assert(s_intro_circ); + + /* Should not happen but if so, scream loudly. */ + if (BUG(TO_CIRCUIT(s_intro_circ)->purpose != CIRCUIT_PURPOSE_INTRO_POINT)) { + return false; + } + + /* This is called just after we got a valid and parsed INTRODUCE1 cell. The + * service has been found and we have its introduction circuit. + * + * First, the INTRODUCE2 bucket will be refilled (if any). Then, decremented + * because we are about to send or not the cell we just got. Finally, + * evaluate if we can send it based on our token bucket state. */ + + /* Refill INTRODUCE2 bucket. */ + token_bucket_ctr_refill(&s_intro_circ->introduce2_bucket, + (uint32_t) approx_time()); + + /* Decrement the bucket for this valid INTRODUCE1 cell we just got. Don't + * underflow else we end up with a too big of a bucket. */ + if (token_bucket_ctr_get(&s_intro_circ->introduce2_bucket) > 0) { + token_bucket_ctr_dec(&s_intro_circ->introduce2_bucket, 1); + } + + /* Finally, we can send a new INTRODUCE2 if there are still tokens. */ + return token_bucket_ctr_get(&s_intro_circ->introduce2_bucket) > 0; +} diff --git a/src/feature/hs/hs_dos.h b/src/feature/hs/hs_dos.h new file mode 100644 index 0000000000..e3a83a1039 --- /dev/null +++ b/src/feature/hs/hs_dos.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file hs_dos.h + * \brief Header file containing denial of service defenses for the HS + * subsystem for all versions. + **/ + +#ifndef TOR_HS_DOS_H +#define TOR_HS_DOS_H + +#include "core/or/or_circuit_st.h" + +#include "lib/evloop/token_bucket.h" + +#define HS_DOS_INTRODUCE_CELL_RATE_PER_SEC 25 +#define HS_DOS_INTRODUCE_CELL_BURST_PER_SEC 200 + +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; +} + +#ifdef HS_DOS_PRIVATE + +#ifdef TOR_UNIT_TESTS + +#endif /* define(TOR_UNIT_TESTS) */ + +#endif /* defined(HS_DOS_PRIVATE) */ + +#endif /* !defined(TOR_HS_DOS_H) */ diff --git a/src/feature/hs/hs_intropoint.c b/src/feature/hs/hs_intropoint.c index 6383d3ed22..2c105f0b60 100644 --- a/src/feature/hs/hs_intropoint.c +++ b/src/feature/hs/hs_intropoint.c @@ -25,9 +25,10 @@ #include "trunnel/hs/cell_introduce1.h" #include "feature/hs/hs_circuitmap.h" -#include "feature/hs/hs_descriptor.h" -#include "feature/hs/hs_intropoint.h" #include "feature/hs/hs_common.h" +#include "feature/hs/hs_descriptor.h" +#include "feature/hs/hs_dos.h" +#include "feature/hs/hs_intropoint.h" #include "core/or/or_circuit_st.h" @@ -203,6 +204,9 @@ handle_verified_establish_intro_cell(or_circuit_t *circ, hs_circuitmap_register_intro_circ_v3_relay_side(circ, &auth_key); /* Repurpose this circuit into an intro circuit. */ circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_INTRO_POINT); + /* Initialize the INTRODUCE2 token bucket for the rate limiting. */ + token_bucket_ctr_init(&circ->introduce2_bucket, hs_dos_get_intro2_rate(), + hs_dos_get_intro2_burst(), (uint32_t) approx_time()); return 0; } @@ -481,6 +485,20 @@ handle_introduce1(or_circuit_t *client_circ, const uint8_t *request, } } + /* Before sending, lets make sure this cell can be sent on the service + * circuit asking the DoS defenses. */ + if (!hs_dos_can_send_intro2(service_circ)) { + char *msg; + static ratelim_t rlimit = RATELIM_INIT(5 * 60); + if ((msg = rate_limit_log(&rlimit, approx_time()))) { + log_info(LD_PROTOCOL, "Can't relay INTRODUCE1 v3 cell due to DoS " + "limitations. Sending NACK to client."); + tor_free(msg); + } + status = TRUNNEL_HS_INTRO_ACK_STATUS_UNKNOWN_ID; + goto send_ack; + } + /* Relay the cell to the service on its intro circuit with an INTRODUCE2 * cell which is the same exact payload. */ if (relay_send_command_from_edge(CONTROL_CELL_ID, TO_CIRCUIT(service_circ), diff --git a/src/feature/rend/rendmid.c b/src/feature/rend/rendmid.c index 849f355990..192da166ee 100644 --- a/src/feature/rend/rendmid.c +++ b/src/feature/rend/rendmid.c @@ -18,6 +18,7 @@ #include "feature/rend/rendmid.h" #include "feature/stats/rephist.h" #include "feature/hs/hs_circuitmap.h" +#include "feature/hs/hs_dos.h" #include "feature/hs/hs_intropoint.h" #include "core/or/or_circuit_st.h" @@ -180,6 +181,14 @@ rend_mid_introduce_legacy(or_circuit_t *circ, const uint8_t *request, goto err; } + /* Before sending, lets make sure this cell can be sent on the service + * circuit asking the DoS defenses. */ + if (!hs_dos_can_send_intro2(intro_circ)) { + log_info(LD_PROTOCOL, "Can't relay INTRODUCE1 v2 cell due to DoS " + "limitations. Sending NACK to client."); + goto err; + } + log_info(LD_REND, "Sending introduction request for service %s " "from circ %u to circ %u", diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index 0cdb1fef27..87338b448f 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -119,6 +119,8 @@ helper_create_intro_circuit(void) or_circuit_t *circ = or_circuit_new(0, NULL); tt_assert(circ); circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR); + token_bucket_ctr_init(&circ->introduce2_bucket, 100, 100, + (uint32_t) approx_time()); done: return circ; } From fec0a7b7cbae344bd813152c8a04b6e87b6fa9a7 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 30 May 2019 08:55:40 -0400 Subject: [PATCH 2/8] test: Add hs_dos.c unit tests Currently test the only available function which is hs_dos_can_send_intro2() within the HS anti-DoS subsystem. Closes #15516 Signed-off-by: David Goulet --- src/test/include.am | 1 + src/test/test.c | 1 + src/test/test.h | 1 + src/test/test_hs_dos.c | 104 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/test/test_hs_dos.c diff --git a/src/test/include.am b/src/test/include.am index 0ec4d96ad4..86209b2db3 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -154,6 +154,7 @@ src_test_test_SOURCES += \ src/test/test_handles.c \ src/test/test_hs_cache.c \ src/test/test_hs_descriptor.c \ + src/test/test_hs_dos.c \ src/test/test_introduce.c \ src/test/test_keypin.c \ src/test/test_link_handshake.c \ diff --git a/src/test/test.c b/src/test/test.c index 266b7454a3..b9a1da06f0 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -877,6 +877,7 @@ struct testgroup_t testgroups[] = { { "hs_config/", hs_config_tests }, { "hs_control/", hs_control_tests }, { "hs_descriptor/", hs_descriptor }, + { "hs_dos/", hs_dos_tests }, { "hs_intropoint/", hs_intropoint_tests }, { "hs_ntor/", hs_ntor_tests }, { "hs_service/", hs_service_tests }, diff --git a/src/test/test.h b/src/test/test.h index 322716a9ab..f5c21bfe88 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -227,6 +227,7 @@ extern struct testcase_t hs_common_tests[]; extern struct testcase_t hs_config_tests[]; extern struct testcase_t hs_control_tests[]; extern struct testcase_t hs_descriptor[]; +extern struct testcase_t hs_dos_tests[]; extern struct testcase_t hs_intropoint_tests[]; extern struct testcase_t hs_ntor_tests[]; extern struct testcase_t hs_service_tests[]; diff --git a/src/test/test_hs_dos.c b/src/test/test_hs_dos.c new file mode 100644 index 0000000000..6ade897b7e --- /dev/null +++ b/src/test/test_hs_dos.c @@ -0,0 +1,104 @@ +/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file test_hs_cell.c + * \brief Test hidden service cell functionality. + */ + +#define CIRCUITLIST_PRIVATE + +#include "test/test.h" +#include "test/test_helpers.h" +#include "test/log_test_helpers.h" + +#include "core/or/circuitlist.h" +#include "core/or/circuituse.h" +#include "core/or/or_circuit_st.h" + +#include "feature/hs/hs_dos.h" + +static void +test_can_send_intro2(void *arg) +{ + uint32_t now = (uint32_t) approx_time(); + or_circuit_t *or_circ = NULL; + + (void) arg; + + or_circ = or_circuit_new(1, NULL); + + /* Make that circuit a service intro point. */ + circuit_change_purpose(TO_CIRCUIT(or_circ), CIRCUIT_PURPOSE_INTRO_POINT); + /* Initialize the INTRODUCE2 token bucket for the rate limiting. */ + token_bucket_ctr_init(&or_circ->introduce2_bucket, hs_dos_get_intro2_rate(), + hs_dos_get_intro2_burst(), now); + + /* Brand new circuit, we should be able to send INTRODUCE2 cells. */ + tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ)); + + /* Simulate that 10 cells have arrived in 1 second. There should be no + * refill since the bucket is already at maximum on the first cell. */ + update_approx_time(++now); + for (int i = 0; i < 10; i++) { + tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ)); + } + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, + hs_dos_get_intro2_burst() - 10); + + /* Fully refill the bucket minus 1 cell. */ + update_approx_time(++now); + tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ)); + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, + hs_dos_get_intro2_burst() - 1); + + /* Receive an INTRODUCE2 at each second. We should have the bucket full + * since at every second it gets refilled. */ + for (int i = 0; i < 10; i++) { + update_approx_time(++now); + tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ)); + } + /* Last check if we can send the cell decrements the bucket so minus 1. */ + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, + hs_dos_get_intro2_burst() - 1); + + /* Manually reset bucket for next test. */ + token_bucket_ctr_reset(&or_circ->introduce2_bucket, now); + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, + hs_dos_get_intro2_burst()); + + /* Do a full burst in the current second which should empty the bucket and + * we shouldn't be allowed to send one more cell after that. We go minus 1 + * cell else the very last check if we can send the INTRO2 cell returns + * false because the bucket goes down to 0. */ + for (uint32_t i = 0; i < hs_dos_get_intro2_burst() - 1; i++) { + tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ)); + } + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, 1); + /* Get the last remaining cell, we shouldn't be allowed to send it. */ + tt_int_op(false, OP_EQ, hs_dos_can_send_intro2(or_circ)); + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, 0); + + /* Make sure the next 100 cells aren't allowed and bucket stays at 0. */ + for (int i = 0; i < 100; i++) { + tt_int_op(false, OP_EQ, hs_dos_can_send_intro2(or_circ)); + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, 0); + } + + /* One second has passed, we should have the rate minus 1 cell added. */ + update_approx_time(++now); + tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ)); + tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, + hs_dos_get_intro2_rate() - 1); + + done: + circuit_free_(TO_CIRCUIT(or_circ)); +} + +struct testcase_t hs_dos_tests[] = { + { "can_send_intro2", test_can_send_intro2, TT_FORK, + NULL, NULL }, + + END_OF_TESTCASES +}; + From c5b00c5a514a6b40e5245bc1fd78fe5490922739 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 11 Jun 2019 08:28:13 -0400 Subject: [PATCH 3/8] hs-v3: Add consensus parameters for DoS defenses Part of #15516 Signed-off-by: David Goulet --- 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 d437726fe8..af3ab33042 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 31cee37637..3bdf8f146b 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 a5747fe170..8661ce046a 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 ad9d044f48..25d282adbc 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 e3a83a1039..9fba00b52b 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 2db293a8af..496bafb865 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 6ade897b7e..6b82610534 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 87338b448f..1d472397ca 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); From be8bd2a46eaba4c992ec912a1bef8d950e481bd4 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 27 Jun 2019 12:58:43 -0400 Subject: [PATCH 4/8] hs-v3: Add enable/disable HS DoS introduce parameter Following prop305 values. Signed-off-by: David Goulet --- src/feature/hs/hs_dos.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c index 25d282adbc..f817b49885 100644 --- a/src/feature/hs/hs_dos.c +++ b/src/feature/hs/hs_dos.c @@ -40,11 +40,24 @@ * but never goes above that burst value. */ #define HS_DOS_INTRODUCE_CELL_BURST_PER_SEC 200 +/* Default value of the consensus parameter enabling or disabling the + * introduction DoS defense. Disabled by default. */ +#define HS_DOS_INTRODUCE_ENABLED_DEFAULT 0 + /* 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; +static uint32_t hs_dos_introduce_enabled = + HS_DOS_INTRODUCE_ENABLED_DEFAULT; + +static uint32_t +get_param_intro_dos_enabled(const networkstatus_t *ns) +{ + return networkstatus_get_param(ns, "HiddenServiceEnableIntroDoSDefense", + HS_DOS_INTRODUCE_ENABLED_DEFAULT, 0, 1); +} /* Return the parameter for the introduction rate per sec. */ static uint32_t @@ -70,6 +83,7 @@ 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); + hs_dos_introduce_enabled = get_param_intro_dos_enabled(ns); } /* @@ -111,6 +125,11 @@ hs_dos_can_send_intro2(or_circuit_t *s_intro_circ) { tor_assert(s_intro_circ); + /* Always allowed if the defense is disabled. */ + if (!hs_dos_introduce_enabled) { + return true; + } + /* Should not happen but if so, scream loudly. */ if (BUG(TO_CIRCUIT(s_intro_circ)->purpose != CIRCUIT_PURPOSE_INTRO_POINT)) { return false; From e53796854811724fdd1db5127bb67943ba5d423c Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 27 Jun 2019 13:32:58 -0400 Subject: [PATCH 5/8] dos: Update HS intro circuits if parameters change In case the consensus parameters for the rate/burst changes, we need to update all already established introduction circuits to the newest value. This commit introduces a "get all intro circ" function from the HS circuitmap (v2 and v3) so it can be used by the HS DoS module to go over all circuits and adjust the INTRODUCE2 token bucket parameters. Signed-off-by: David Goulet --- src/feature/hs/hs_circuitmap.c | 27 +++++++++++++++++++++++++++ src/feature/hs/hs_circuitmap.h | 2 ++ src/feature/hs/hs_dos.c | 24 ++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/feature/hs/hs_circuitmap.c b/src/feature/hs/hs_circuitmap.c index 5480d5eb84..e34f564fb4 100644 --- a/src/feature/hs/hs_circuitmap.c +++ b/src/feature/hs/hs_circuitmap.c @@ -272,6 +272,33 @@ hs_circuitmap_get_or_circuit(hs_token_type_t type, /**** Public relay-side getters: */ +/* Public function: Return v2 and v3 introduction circuit to this relay. + * Always return a newly allocated list for which it is the caller's + * responsability to free it. */ +smartlist_t * +hs_circuitmap_get_all_intro_circ_relay_side(void) +{ + circuit_t **iter; + smartlist_t *circuit_list = smartlist_new(); + + HT_FOREACH(iter, hs_circuitmap_ht, the_hs_circuitmap) { + circuit_t *circ = *iter; + + /* An origin circuit or purpose is wrong or the hs token is not set to be + * a v2 or v3 intro relay side type, we ignore the circuit. Else, we have + * a match so add it to our list. */ + if (CIRCUIT_IS_ORIGIN(circ) || + circ->purpose != CIRCUIT_PURPOSE_INTRO_POINT || + (circ->hs_token->type != HS_TOKEN_INTRO_V3_RELAY_SIDE && + circ->hs_token->type != HS_TOKEN_INTRO_V2_RELAY_SIDE)) { + continue; + } + smartlist_add(circuit_list, circ); + } + + return circuit_list; +} + /* Public function: Return a v3 introduction circuit to this relay with * auth_key. Return NULL if no such circuit is found in the * circuitmap. */ diff --git a/src/feature/hs/hs_circuitmap.h b/src/feature/hs/hs_circuitmap.h index c1bbb1ff1c..eac8230bbf 100644 --- a/src/feature/hs/hs_circuitmap.h +++ b/src/feature/hs/hs_circuitmap.h @@ -34,6 +34,8 @@ void hs_circuitmap_register_intro_circ_v2_relay_side(struct or_circuit_t *circ, void hs_circuitmap_register_intro_circ_v3_relay_side(struct or_circuit_t *circ, const ed25519_public_key_t *auth_key); +smartlist_t *hs_circuitmap_get_all_intro_circ_relay_side(void); + /** Public service-side API: */ struct origin_circuit_t * diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c index f817b49885..da898dc3a0 100644 --- a/src/feature/hs/hs_dos.c +++ b/src/feature/hs/hs_dos.c @@ -23,6 +23,7 @@ #include "core/or/circuitlist.h" +#include "feature/hs/hs_circuitmap.h" #include "feature/nodelist/networkstatus.h" #include "feature/relay/routermode.h" @@ -77,6 +78,25 @@ get_param_burst_per_sec(const networkstatus_t *ns) 0, INT32_MAX); } +/* Go over all introduction circuit relay side and adjust their rate/burst + * values using the global parameters. This is called right after the + * consensus parameters might have changed. */ +static void +update_intro_circuits(void) +{ + /* Returns all HS version intro circuits. */ + smartlist_t *intro_circs = hs_circuitmap_get_all_intro_circ_relay_side(); + + SMARTLIST_FOREACH_BEGIN(intro_circs, circuit_t *, circ) { + /* Adjust the rate/burst value that might have changed. */ + token_bucket_ctr_adjust(&TO_OR_CIRCUIT(circ)->introduce2_bucket, + hs_dos_get_intro2_rate(), + hs_dos_get_intro2_burst()); + } SMARTLIST_FOREACH_END(circ); + + smartlist_free(intro_circs); +} + /* Set consensus parameters. */ static void set_consensus_parameters(const networkstatus_t *ns) @@ -84,6 +104,10 @@ 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); hs_dos_introduce_enabled = get_param_intro_dos_enabled(ns); + + /* The above might have changed which means we need to go through all + * introduction circuits (relay side) and update the token buckets. */ + update_intro_circuits(); } /* From 90b5422e8ee9dd7c7d04507291668e5870f2e351 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 27 Jun 2019 14:06:42 -0400 Subject: [PATCH 6/8] test: Series of fixes for hs_dos.c unit tests Signed-off-by: David Goulet --- src/test/test_hs_dos.c | 28 ++++++++++++++++ src/test/test_hs_intropoint.c | 63 ++++++++++++++++++----------------- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/test/test_hs_dos.c b/src/test/test_hs_dos.c index 6b82610534..3dfa057a4a 100644 --- a/src/test/test_hs_dos.c +++ b/src/test/test_hs_dos.c @@ -7,16 +7,37 @@ */ #define CIRCUITLIST_PRIVATE +#define NETWORKSTATUS_PRIVATE #include "test/test.h" #include "test/test_helpers.h" #include "test/log_test_helpers.h" +#include "app/config/config.h" + #include "core/or/circuitlist.h" #include "core/or/circuituse.h" #include "core/or/or_circuit_st.h" #include "feature/hs/hs_dos.h" +#include "feature/nodelist/networkstatus.h" + +static void +setup_mock_consensus(void) +{ + current_ns_consensus = tor_malloc_zero(sizeof(networkstatus_t)); + current_ns_consensus->net_params = smartlist_new(); + smartlist_add(current_ns_consensus->net_params, + (void *) "HiddenServiceEnableIntroDoSDefense=1"); + hs_dos_consensus_has_changed(current_ns_consensus); +} + +static void +free_mock_consensus(void) +{ + smartlist_free(current_ns_consensus->net_params); + tor_free(current_ns_consensus); +} static void test_can_send_intro2(void *arg) @@ -26,8 +47,12 @@ test_can_send_intro2(void *arg) (void) arg; + hs_init(); hs_dos_init(); + get_options_mutable()->ORPort_set = 1; + setup_mock_consensus(); + or_circ = or_circuit_new(1, NULL); /* Make that circuit a service intro point. */ @@ -95,6 +120,9 @@ test_can_send_intro2(void *arg) done: circuit_free_(TO_CIRCUIT(or_circ)); + + hs_free_all(); + free_mock_consensus(); } struct testcase_t hs_dos_tests[] = { diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index 1d472397ca..7b01809f96 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -186,8 +186,6 @@ 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); @@ -230,8 +228,6 @@ 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); @@ -259,8 +255,6 @@ 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); @@ -297,8 +291,6 @@ 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); @@ -371,8 +363,6 @@ 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); @@ -418,8 +408,6 @@ 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); @@ -463,8 +451,6 @@ 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); @@ -502,8 +488,6 @@ 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); @@ -539,8 +523,6 @@ 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); @@ -921,42 +903,63 @@ test_received_introduce1_handling(void *arg) UNMOCK(relay_send_command_from_edge_); } +static void * +hs_subsystem_setup_fn(const struct testcase_t *tc) +{ + (void) tc; + + return NULL; +} + +static int +hs_subsystem_cleanup_fn(const struct testcase_t *tc, void *arg) +{ + (void) tc; + (void) arg; + + return 1; +} + +static struct testcase_setup_t test_setup = { + hs_subsystem_setup_fn, hs_subsystem_cleanup_fn +}; + struct testcase_t hs_intropoint_tests[] = { { "intro_point_registration", - test_intro_point_registration, TT_FORK, NULL, NULL }, + test_intro_point_registration, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_keytype", - test_establish_intro_wrong_keytype, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_keytype, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_keytype2", - test_establish_intro_wrong_keytype2, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_keytype2, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_purpose", - test_establish_intro_wrong_purpose, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_purpose, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_sig", - test_establish_intro_wrong_sig, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_sig, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_sig_len", - test_establish_intro_wrong_sig_len, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_sig_len, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_auth_key_len", - test_establish_intro_wrong_auth_key_len, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_auth_key_len, TT_FORK, NULL, &test_setup}, { "receive_establish_intro_wrong_mac", - test_establish_intro_wrong_mac, TT_FORK, NULL, NULL }, + test_establish_intro_wrong_mac, TT_FORK, NULL, &test_setup}, { "introduce1_suitable_circuit", - test_introduce1_suitable_circuit, TT_FORK, NULL, NULL }, + test_introduce1_suitable_circuit, TT_FORK, NULL, &test_setup}, { "introduce1_is_legacy", - test_introduce1_is_legacy, TT_FORK, NULL, NULL }, + test_introduce1_is_legacy, TT_FORK, NULL, &test_setup}, { "introduce1_validation", - test_introduce1_validation, TT_FORK, NULL, NULL }, + test_introduce1_validation, TT_FORK, NULL, &test_setup}, { "received_introduce1_handling", - test_received_introduce1_handling, TT_FORK, NULL, NULL }, + test_received_introduce1_handling, TT_FORK, NULL, &test_setup}, END_OF_TESTCASES }; From c45f0b4ec1b0bdc93c1aeb7342347f1b81eb9f1e Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 2 Jul 2019 07:36:36 -0400 Subject: [PATCH 7/8] hs-v3: Rename HS DoS default defines Signed-off-by: David Goulet --- src/feature/hs/hs_dos.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c index da898dc3a0..a4586dd700 100644 --- a/src/feature/hs/hs_dos.c +++ b/src/feature/hs/hs_dos.c @@ -33,13 +33,13 @@ /* 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 +#define HS_DOS_INTRODUCE_DEFAULT_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 +#define HS_DOS_INTRODUCE_DEFAULT_CELL_BURST_PER_SEC 200 /* Default value of the consensus parameter enabling or disabling the * introduction DoS defense. Disabled by default. */ @@ -47,9 +47,9 @@ /* Consensus parameters. */ static uint32_t hs_dos_introduce_rate_per_sec = - HS_DOS_INTRODUCE_CELL_RATE_PER_SEC; + HS_DOS_INTRODUCE_DEFAULT_CELL_RATE_PER_SEC; static uint32_t hs_dos_introduce_burst_per_sec = - HS_DOS_INTRODUCE_CELL_BURST_PER_SEC; + HS_DOS_INTRODUCE_DEFAULT_CELL_BURST_PER_SEC; static uint32_t hs_dos_introduce_enabled = HS_DOS_INTRODUCE_ENABLED_DEFAULT; @@ -65,7 +65,7 @@ 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, + HS_DOS_INTRODUCE_DEFAULT_CELL_RATE_PER_SEC, 0, INT32_MAX); } @@ -74,7 +74,7 @@ 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, + HS_DOS_INTRODUCE_DEFAULT_CELL_BURST_PER_SEC, 0, INT32_MAX); } From 2b225aaa77f38741509b0cb49bdef0b3d6b39936 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 6 Aug 2019 08:01:26 -0400 Subject: [PATCH 8/8] practracker: Make it happy after rebase Signed-off-by: David Goulet --- scripts/maint/practracker/exceptions.txt | 28 ++---------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt index af3ab33042..75a8b50967 100644 --- a/scripts/maint/practracker/exceptions.txt +++ b/scripts/maint/practracker/exceptions.txt @@ -39,29 +39,15 @@ 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 problem function-size /src/app/config/config.c:parse_port_config() 446 problem function-size /src/app/config/config.c:parse_ports() 168 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:tor_init() 137 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 @@ -220,23 +206,13 @@ 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 include-count /src/feature/nodelist/networkstatus.c 63 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 problem function-size /src/feature/nodelist/node_select.c:router_pick_directory_server_impl() 122 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