fallbackdir: Update list generated on August 30, 2023
[tor.git] / src / test / test_hs_dos.c
blob81410f7b9b11136be0e5cf98cfacabe458fc7920
1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file test_hs_cell.c
6 * \brief Test hidden service cell functionality.
7 */
9 #define CIRCUITLIST_PRIVATE
10 #define NETWORKSTATUS_PRIVATE
11 #define HS_DOS_PRIVATE
12 #define HS_INTROPOINT_PRIVATE
14 #include "test/test.h"
15 #include "test/test_helpers.h"
16 #include "test/log_test_helpers.h"
18 #include "app/config/config.h"
19 #include "lib/time/compat_time.h"
21 #include "core/or/circuitlist.h"
22 #include "core/or/circuituse.h"
23 #include "core/or/or_circuit_st.h"
25 #include "feature/hs/hs_dos.h"
26 #include "feature/hs/hs_intropoint.h"
27 #include "feature/nodelist/networkstatus.h"
29 static void
30 setup_mock_consensus(void)
32 current_ns_consensus = tor_malloc_zero(sizeof(networkstatus_t));
33 current_ns_consensus->net_params = smartlist_new();
34 smartlist_add(current_ns_consensus->net_params,
35 (void *) "HiddenServiceEnableIntroDoSDefense=1");
36 hs_dos_consensus_has_changed(current_ns_consensus);
39 static void
40 free_mock_consensus(void)
42 smartlist_free(current_ns_consensus->net_params);
43 tor_free(current_ns_consensus);
46 static void
47 test_can_send_intro2(void *arg)
49 static const uint64_t BILLION = 1000000000;
50 uint64_t now = 12345;
51 or_circuit_t *or_circ = NULL;
53 (void) arg;
55 hs_init();
56 hs_dos_init();
58 get_options_mutable()->ORPort_set = 1;
59 setup_mock_consensus();
60 monotime_enable_test_mocking();
61 monotime_coarse_set_mock_time_nsec(now);
63 or_circ = or_circuit_new(1, NULL);
65 /* Make that circuit a service intro point. */
66 circuit_change_purpose(TO_CIRCUIT(or_circ), CIRCUIT_PURPOSE_INTRO_POINT);
67 hs_dos_setup_default_intro2_defenses(or_circ);
68 or_circ->introduce2_dos_defense_enabled = 1;
70 /* Brand new circuit, we should be able to send INTRODUCE2 cells. */
71 tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ));
73 /* Simulate that 10 cells have arrived in 1 second. There should be no
74 * refill since the bucket is already at maximum on the first cell. */
75 monotime_coarse_set_mock_time_nsec(now += BILLION);
76 for (int i = 0; i < 10; i++) {
77 tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ));
79 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ,
80 get_intro2_burst_consensus_param(NULL) - 10);
82 /* Fully refill the bucket minus 1 cell. */
83 monotime_coarse_set_mock_time_nsec(now += BILLION);
84 tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ));
85 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ,
86 get_intro2_burst_consensus_param(NULL) - 1);
88 /* Receive an INTRODUCE2 at each second. We should have the bucket full
89 * since at every second it gets refilled. */
90 for (int i = 0; i < 10; i++) {
91 monotime_coarse_set_mock_time_nsec(now += BILLION);
92 tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ));
94 /* Last check if we can send the cell decrements the bucket so minus 1. */
95 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ,
96 get_intro2_burst_consensus_param(NULL) - 1);
98 /* Manually reset bucket for next test. */
99 token_bucket_ctr_reset(&or_circ->introduce2_bucket,
100 (uint32_t) monotime_coarse_absolute_sec());
101 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ,
102 get_intro2_burst_consensus_param(NULL));
104 /* Do a full burst in the current second which should empty the bucket and
105 * we shouldn't be allowed to send one more cell after that. We go minus 1
106 * cell else the very last check if we can send the INTRO2 cell returns
107 * false because the bucket goes down to 0. */
108 for (uint32_t i = 0; i < get_intro2_burst_consensus_param(NULL) - 1; i++) {
109 tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ));
111 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, 1);
112 /* Get the last remaining cell, we shouldn't be allowed to send it. */
113 tt_int_op(false, OP_EQ, hs_dos_can_send_intro2(or_circ));
114 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, 0);
116 /* Make sure the next 100 cells aren't allowed and bucket stays at 0. */
117 for (int i = 0; i < 100; i++) {
118 tt_int_op(false, OP_EQ, hs_dos_can_send_intro2(or_circ));
119 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ, 0);
122 /* One second has passed, we should have the rate minus 1 cell added. */
123 monotime_coarse_set_mock_time_nsec(now += BILLION);
124 tt_int_op(true, OP_EQ, hs_dos_can_send_intro2(or_circ));
125 tt_uint_op(token_bucket_ctr_get(&or_circ->introduce2_bucket), OP_EQ,
126 get_intro2_rate_consensus_param(NULL) - 1);
128 done:
129 circuit_free_(TO_CIRCUIT(or_circ));
131 hs_free_all();
132 free_mock_consensus();
133 monotime_disable_test_mocking();
136 static void
137 test_validate_dos_extension_params(void *arg)
139 bool ret;
141 (void) arg;
143 /* Validate the default values. */
144 ret = cell_dos_extension_parameters_are_valid(
145 get_intro2_rate_consensus_param(NULL),
146 get_intro2_burst_consensus_param(NULL));
147 tt_assert(ret);
149 /* Valid custom rate/burst. */
150 ret = cell_dos_extension_parameters_are_valid(17, 42);
151 tt_assert(ret);
152 ret = cell_dos_extension_parameters_are_valid(INT32_MAX, INT32_MAX);
153 tt_assert(ret);
155 /* Invalid rate. */
156 ret = cell_dos_extension_parameters_are_valid(UINT64_MAX, 42);
157 tt_assert(!ret);
159 /* Invalid burst. */
160 ret = cell_dos_extension_parameters_are_valid(42, UINT64_MAX);
161 tt_assert(!ret);
163 /* Value of 0 is valid (but should disable defenses) */
164 ret = cell_dos_extension_parameters_are_valid(0, 0);
165 tt_assert(ret);
167 /* Can't have burst smaller than rate. */
168 ret = cell_dos_extension_parameters_are_valid(42, 40);
169 tt_assert(!ret);
171 done:
172 return;
175 struct testcase_t hs_dos_tests[] = {
176 { "can_send_intro2", test_can_send_intro2, TT_FORK,
177 NULL, NULL },
178 { "validate_dos_extension_params", test_validate_dos_extension_params,
179 TT_FORK, NULL, NULL },
181 END_OF_TESTCASES