Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : #define CIRCUITLIST_PRIVATE
7 :
8 : #include "core/or/or.h"
9 : #include "test/test.h"
10 : #include "test/test_helpers.h"
11 : #include "app/config/config.h"
12 : #include "core/or/circuitlist.h"
13 : #include "core/or/circuituse.h"
14 : #include "core/or/circuitbuild.h"
15 : #include "feature/nodelist/nodelist.h"
16 :
17 : #include "core/or/cpath_build_state_st.h"
18 : #include "core/or/origin_circuit_st.h"
19 :
20 : static void
21 1 : test_circuit_is_available_for_use_ret_false_when_marked_for_close(void *arg)
22 : {
23 1 : (void)arg;
24 :
25 1 : circuit_t *circ = tor_malloc(sizeof(circuit_t));
26 1 : circ->marked_for_close = 1;
27 :
28 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
29 :
30 1 : done:
31 1 : tor_free(circ);
32 1 : }
33 :
34 : static void
35 1 : test_circuit_is_available_for_use_ret_false_when_timestamp_dirty(void *arg)
36 : {
37 1 : (void)arg;
38 :
39 1 : circuit_t *circ = tor_malloc(sizeof(circuit_t));
40 1 : circ->timestamp_dirty = 1;
41 :
42 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
43 :
44 1 : done:
45 1 : tor_free(circ);
46 1 : }
47 :
48 : static void
49 1 : test_circuit_is_available_for_use_ret_false_for_non_general_purpose(void *arg)
50 : {
51 1 : (void)arg;
52 :
53 1 : circuit_t *circ = tor_malloc(sizeof(circuit_t));
54 1 : circ->purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
55 :
56 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
57 :
58 1 : done:
59 1 : tor_free(circ);
60 1 : }
61 :
62 : static void
63 1 : test_circuit_is_available_for_use_ret_false_for_non_general_origin(void *arg)
64 : {
65 1 : (void)arg;
66 :
67 1 : circuit_t *circ = tor_malloc(sizeof(circuit_t));
68 1 : circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT;
69 :
70 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
71 :
72 1 : done:
73 1 : tor_free(circ);
74 1 : }
75 :
76 : static void
77 1 : test_circuit_is_available_for_use_ret_false_for_non_origin_purpose(void *arg)
78 : {
79 1 : (void)arg;
80 :
81 1 : circuit_t *circ = tor_malloc(sizeof(circuit_t));
82 1 : circ->purpose = CIRCUIT_PURPOSE_OR;
83 :
84 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
85 :
86 1 : done:
87 1 : tor_free(circ);
88 1 : }
89 :
90 : static void
91 1 : test_circuit_is_available_for_use_ret_false_unusable_for_new_conns(void *arg)
92 : {
93 1 : (void)arg;
94 :
95 1 : circuit_t *circ = dummy_origin_circuit_new(30);
96 1 : mark_circuit_unusable_for_new_conns(TO_ORIGIN_CIRCUIT(circ));
97 :
98 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
99 :
100 1 : done:
101 1 : circuit_free(circ);
102 1 : }
103 :
104 : static void
105 1 : test_circuit_is_available_for_use_returns_false_for_onehop_tunnel(void *arg)
106 : {
107 1 : (void)arg;
108 :
109 1 : circuit_t *circ = dummy_origin_circuit_new(30);
110 1 : origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
111 1 : oc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
112 1 : oc->build_state->onehop_tunnel = 1;
113 :
114 1 : tt_int_op(0, OP_EQ, circuit_is_available_for_use(circ));
115 :
116 1 : done:
117 1 : circuit_free(circ);
118 1 : }
119 :
120 : static void
121 1 : test_circuit_is_available_for_use_returns_true_for_clean_circuit(void *arg)
122 : {
123 1 : (void)arg;
124 :
125 1 : circuit_t *circ = dummy_origin_circuit_new(30);
126 1 : origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
127 1 : oc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
128 1 : oc->build_state->onehop_tunnel = 0;
129 :
130 1 : tt_int_op(1, OP_EQ, circuit_is_available_for_use(circ));
131 :
132 1 : done:
133 1 : circuit_free(circ);
134 1 : }
135 :
136 : static int
137 4 : mock_circuit_all_predicted_ports_handled(time_t now,
138 : int *need_uptime,
139 : int *need_capacity)
140 : {
141 4 : (void)now;
142 :
143 4 : if (need_uptime && need_capacity)
144 4 : return 0;
145 : return 1;
146 : }
147 :
148 : static consensus_path_type_t
149 2 : mock_router_have_unknown_consensus_path(void)
150 : {
151 2 : return CONSENSUS_PATH_UNKNOWN;
152 : }
153 :
154 : static consensus_path_type_t
155 4 : mock_router_have_exit_consensus_path(void)
156 : {
157 4 : return CONSENSUS_PATH_EXIT;
158 : }
159 :
160 : static void
161 1 : test_needs_exit_circuits_ret_false_for_predicted_ports_and_path(void *arg)
162 : {
163 1 : (void)arg;
164 :
165 1 : MOCK(circuit_all_predicted_ports_handled,
166 : mock_circuit_all_predicted_ports_handled);
167 1 : int needs_uptime = 1;
168 1 : int needs_capacity = 0;
169 :
170 1 : time_t now = time(NULL);
171 1 : tt_int_op(0, OP_EQ,
172 : needs_exit_circuits(now, &needs_uptime, &needs_capacity));
173 :
174 1 : done:
175 1 : UNMOCK(circuit_all_predicted_ports_handled);
176 1 : }
177 :
178 : static void
179 1 : test_needs_exit_circuits_ret_false_for_non_exit_consensus_path(void *arg)
180 : {
181 1 : (void)arg;
182 :
183 1 : MOCK(circuit_all_predicted_ports_handled,
184 : mock_circuit_all_predicted_ports_handled);
185 1 : int needs_uptime = 1;
186 1 : int needs_capacity = 1;
187 1 : MOCK(router_have_consensus_path, mock_router_have_unknown_consensus_path);
188 :
189 1 : time_t now = time(NULL);
190 1 : tt_int_op(0, OP_EQ,
191 : needs_exit_circuits(now, &needs_uptime, &needs_capacity));
192 :
193 1 : done:
194 1 : UNMOCK(circuit_all_predicted_ports_handled);
195 1 : UNMOCK(router_have_consensus_path);
196 1 : }
197 :
198 : static void
199 2 : test_needs_exit_circuits_ret_true_for_predicted_ports_and_path(void *arg)
200 : {
201 2 : (void)arg;
202 :
203 2 : MOCK(circuit_all_predicted_ports_handled,
204 : mock_circuit_all_predicted_ports_handled);
205 2 : int needs_uptime = 1;
206 2 : int needs_capacity = 1;
207 2 : MOCK(router_have_consensus_path, mock_router_have_exit_consensus_path);
208 :
209 2 : time_t now = time(NULL);
210 2 : tt_int_op(1, OP_EQ,
211 : needs_exit_circuits(now, &needs_uptime, &needs_capacity));
212 :
213 2 : done:
214 2 : UNMOCK(circuit_all_predicted_ports_handled);
215 2 : UNMOCK(router_have_consensus_path);
216 2 : }
217 :
218 : static void
219 1 : test_needs_circuits_for_build_ret_false_consensus_path_unknown(void *arg)
220 : {
221 1 : (void)arg;
222 1 : MOCK(router_have_consensus_path, mock_router_have_unknown_consensus_path);
223 1 : tt_int_op(0, OP_EQ, needs_circuits_for_build(0));
224 1 : done: ;
225 1 : }
226 :
227 : static void
228 1 : test_needs_circuits_for_build_ret_false_if_num_less_than_max(void *arg)
229 : {
230 1 : (void)arg;
231 1 : MOCK(router_have_consensus_path, mock_router_have_exit_consensus_path);
232 1 : tt_int_op(0, OP_EQ, needs_circuits_for_build(13));
233 1 : done:
234 1 : UNMOCK(router_have_consensus_path);
235 1 : }
236 :
237 : static void
238 1 : test_needs_circuits_for_build_returns_true_when_more_are_needed(void *arg)
239 : {
240 1 : (void)arg;
241 1 : MOCK(router_have_consensus_path, mock_router_have_exit_consensus_path);
242 1 : tt_int_op(1, OP_EQ, needs_circuits_for_build(0));
243 1 : done:
244 1 : UNMOCK(router_have_consensus_path);
245 1 : }
246 :
247 : struct testcase_t circuituse_tests[] = {
248 : { "marked",
249 : test_circuit_is_available_for_use_ret_false_when_marked_for_close,
250 : TT_FORK, NULL, NULL
251 : },
252 : { "timestamp",
253 : test_circuit_is_available_for_use_ret_false_when_timestamp_dirty,
254 : TT_FORK, NULL, NULL
255 : },
256 : { "non_general",
257 : test_circuit_is_available_for_use_ret_false_for_non_general_purpose,
258 : TT_FORK, NULL, NULL
259 : },
260 : { "non_general",
261 : test_circuit_is_available_for_use_ret_false_for_non_general_origin,
262 : TT_FORK, NULL, NULL
263 : },
264 : { "origin",
265 : test_circuit_is_available_for_use_ret_false_for_non_origin_purpose,
266 : TT_FORK, NULL, NULL
267 : },
268 : { "clean",
269 : test_circuit_is_available_for_use_ret_false_unusable_for_new_conns,
270 : TT_FORK, NULL, NULL
271 : },
272 : { "onehop",
273 : test_circuit_is_available_for_use_returns_false_for_onehop_tunnel,
274 : TT_FORK, NULL, NULL
275 : },
276 : { "clean_circ",
277 : test_circuit_is_available_for_use_returns_true_for_clean_circuit,
278 : TT_FORK, NULL, NULL
279 : },
280 : { "exit_f",
281 : test_needs_exit_circuits_ret_false_for_predicted_ports_and_path,
282 : TT_FORK, NULL, NULL
283 : },
284 : { "exit_t",
285 : test_needs_exit_circuits_ret_true_for_predicted_ports_and_path,
286 : TT_FORK, NULL, NULL
287 : },
288 : { "non_exit",
289 : test_needs_exit_circuits_ret_false_for_non_exit_consensus_path,
290 : TT_FORK, NULL, NULL
291 : },
292 : { "true",
293 : test_needs_exit_circuits_ret_true_for_predicted_ports_and_path,
294 : TT_FORK, NULL, NULL
295 : },
296 : { "consensus_path_unknown",
297 : test_needs_circuits_for_build_ret_false_consensus_path_unknown,
298 : TT_FORK, NULL, NULL
299 : },
300 : { "less_than_max",
301 : test_needs_circuits_for_build_ret_false_if_num_less_than_max,
302 : TT_FORK, NULL, NULL
303 : },
304 : { "more_needed",
305 : test_needs_circuits_for_build_returns_true_when_more_are_needed,
306 : TT_FORK, NULL, NULL
307 : },
308 : END_OF_TESTCASES
309 : };
310 :
|