Line data Source code
1 : /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #define CIRCUITBUILD_PRIVATE
5 : #define RELAY_PRIVATE
6 : #define BWHIST_PRIVATE
7 : #include "core/or/or.h"
8 : #include "core/or/circuitbuild.h"
9 : #include "core/or/circuitlist.h"
10 : #include "core/or/channeltls.h"
11 : #include "feature/stats/bwhist.h"
12 : #include "core/or/relay.h"
13 : #include "lib/container/order.h"
14 : #include "lib/encoding/confline.h"
15 : /* For init/free stuff */
16 : #include "core/or/scheduler.h"
17 :
18 : #include "core/or/cell_st.h"
19 : #include "core/or/or_circuit_st.h"
20 :
21 : #define RESOLVE_ADDR_PRIVATE
22 : #include "feature/nodelist/dirlist.h"
23 : #include "feature/relay/relay_find_addr.h"
24 : #include "feature/relay/routermode.h"
25 : #include "feature/dirclient/dir_server_st.h"
26 :
27 : #define CONFIG_PRIVATE
28 : #include "app/config/config.h"
29 : #include "app/config/resolve_addr.h"
30 :
31 : /* Test suite stuff */
32 : #include "test/test.h"
33 : #include "test/fakechans.h"
34 : #include "test/fakecircs.h"
35 :
36 : static void test_relay_append_cell_to_circuit_queue(void *arg);
37 :
38 : static int
39 8 : mock_server_mode_true(const or_options_t *options)
40 : {
41 8 : (void) options;
42 8 : return 1;
43 : }
44 :
45 : static void
46 1 : assert_circuit_ok_mock(const circuit_t *c)
47 : {
48 1 : (void) c;
49 1 : return;
50 : }
51 :
52 : static void
53 1 : test_relay_close_circuit(void *arg)
54 : {
55 1 : channel_t *nchan = NULL, *pchan = NULL;
56 1 : or_circuit_t *orcirc = NULL;
57 1 : cell_t *cell = NULL;
58 1 : int old_count, new_count;
59 :
60 1 : (void)arg;
61 :
62 : /* Make fake channels to be nchan and pchan for the circuit */
63 1 : nchan = new_fake_channel();
64 1 : tt_assert(nchan);
65 :
66 1 : pchan = new_fake_channel();
67 1 : tt_assert(pchan);
68 :
69 : /* Make a fake orcirc */
70 1 : orcirc = new_fake_orcirc(nchan, pchan);
71 1 : tt_assert(orcirc);
72 1 : circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
73 : CELL_DIRECTION_OUT);
74 1 : circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
75 : CELL_DIRECTION_IN);
76 :
77 : /* Make a cell */
78 1 : cell = tor_malloc_zero(sizeof(cell_t));
79 1 : make_fake_cell(cell);
80 :
81 1 : MOCK(scheduler_channel_has_waiting_cells,
82 : scheduler_channel_has_waiting_cells_mock);
83 1 : MOCK(assert_circuit_ok,
84 : assert_circuit_ok_mock);
85 :
86 : /* Append it */
87 1 : old_count = get_mock_scheduler_has_waiting_cells_count();
88 1 : append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
89 : CELL_DIRECTION_OUT, 0);
90 1 : new_count = get_mock_scheduler_has_waiting_cells_count();
91 1 : tt_int_op(new_count, OP_EQ, old_count + 1);
92 :
93 : /* Now try the reverse direction */
94 1 : old_count = get_mock_scheduler_has_waiting_cells_count();
95 1 : append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
96 : CELL_DIRECTION_IN, 0);
97 1 : new_count = get_mock_scheduler_has_waiting_cells_count();
98 1 : tt_int_op(new_count, OP_EQ, old_count + 1);
99 :
100 : /* Ensure our write totals are 0 */
101 1 : tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
102 :
103 : /* Mark the circuit for close */
104 1 : circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
105 :
106 : /* Check our write totals. */
107 1 : advance_obs(write_array);
108 1 : commit_max(write_array);
109 : /* Check for two cells plus overhead */
110 1 : tt_u64_op(find_largest_max(write_array), OP_EQ,
111 : 2*(get_cell_network_size(nchan->wide_circ_ids)
112 : +TLS_PER_CELL_OVERHEAD));
113 :
114 1 : UNMOCK(scheduler_channel_has_waiting_cells);
115 :
116 : /* Get rid of the fake channels */
117 1 : MOCK(scheduler_release_channel, scheduler_release_channel_mock);
118 1 : channel_mark_for_close(nchan);
119 1 : channel_mark_for_close(pchan);
120 1 : UNMOCK(scheduler_release_channel);
121 :
122 : /* Shut down channels */
123 1 : channel_free_all();
124 :
125 1 : done:
126 1 : tor_free(cell);
127 1 : if (orcirc) {
128 1 : circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
129 1 : circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
130 1 : cell_queue_clear(&orcirc->base_.n_chan_cells);
131 1 : cell_queue_clear(&orcirc->p_chan_cells);
132 : }
133 1 : free_fake_orcirc(orcirc);
134 1 : free_fake_channel(nchan);
135 1 : free_fake_channel(pchan);
136 1 : UNMOCK(assert_circuit_ok);
137 :
138 1 : return;
139 : }
140 :
141 : static void
142 1 : test_relay_append_cell_to_circuit_queue(void *arg)
143 : {
144 1 : channel_t *nchan = NULL, *pchan = NULL;
145 1 : or_circuit_t *orcirc = NULL;
146 1 : cell_t *cell = NULL;
147 1 : int old_count, new_count;
148 :
149 1 : (void)arg;
150 :
151 : /* Make fake channels to be nchan and pchan for the circuit */
152 1 : nchan = new_fake_channel();
153 1 : tt_assert(nchan);
154 :
155 1 : pchan = new_fake_channel();
156 1 : tt_assert(pchan);
157 :
158 : /* Make a fake orcirc */
159 1 : orcirc = new_fake_orcirc(nchan, pchan);
160 1 : tt_assert(orcirc);
161 1 : circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
162 : CELL_DIRECTION_OUT);
163 1 : circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
164 : CELL_DIRECTION_IN);
165 :
166 : /* Make a cell */
167 1 : cell = tor_malloc_zero(sizeof(cell_t));
168 1 : make_fake_cell(cell);
169 :
170 1 : MOCK(scheduler_channel_has_waiting_cells,
171 : scheduler_channel_has_waiting_cells_mock);
172 :
173 : /* Append it */
174 1 : old_count = get_mock_scheduler_has_waiting_cells_count();
175 1 : append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
176 : CELL_DIRECTION_OUT, 0);
177 1 : new_count = get_mock_scheduler_has_waiting_cells_count();
178 1 : tt_int_op(new_count, OP_EQ, old_count + 1);
179 :
180 : /* Now try the reverse direction */
181 1 : old_count = get_mock_scheduler_has_waiting_cells_count();
182 1 : append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
183 : CELL_DIRECTION_IN, 0);
184 1 : new_count = get_mock_scheduler_has_waiting_cells_count();
185 1 : tt_int_op(new_count, OP_EQ, old_count + 1);
186 :
187 1 : UNMOCK(scheduler_channel_has_waiting_cells);
188 :
189 : /* Get rid of the fake channels */
190 1 : MOCK(scheduler_release_channel, scheduler_release_channel_mock);
191 1 : channel_mark_for_close(nchan);
192 1 : channel_mark_for_close(pchan);
193 1 : UNMOCK(scheduler_release_channel);
194 :
195 : /* Shut down channels */
196 1 : channel_free_all();
197 :
198 1 : done:
199 1 : tor_free(cell);
200 1 : if (orcirc) {
201 1 : circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
202 1 : circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
203 1 : cell_queue_clear(&orcirc->base_.n_chan_cells);
204 1 : cell_queue_clear(&orcirc->p_chan_cells);
205 : }
206 1 : free_fake_orcirc(orcirc);
207 1 : free_fake_channel(nchan);
208 1 : free_fake_channel(pchan);
209 :
210 1 : return;
211 : }
212 :
213 : static void
214 1 : test_suggested_address(void *arg)
215 : {
216 1 : int ret;
217 1 : const char *untrusted_id = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
218 1 : dir_server_t *ds = NULL;
219 1 : tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
220 1 : tor_addr_t trusted_addr, untrusted_addr;
221 1 : tor_addr_port_t trusted_ap_v6 = { .port = 443 };
222 :
223 1 : (void) arg;
224 :
225 1 : MOCK(server_mode, mock_server_mode_true);
226 :
227 : /* Unstrusted relay source. */
228 1 : ret = tor_addr_parse(&untrusted_addr, "8.8.8.8");
229 1 : tt_int_op(ret, OP_EQ, AF_INET);
230 :
231 : /* Add gabelmoo as a trusted directory authority. */
232 1 : ret = tor_addr_parse(&trusted_addr, "[2001:638:a000:4140::ffff:189]");
233 1 : tt_int_op(ret, OP_EQ, AF_INET6);
234 1 : tor_addr_copy(&trusted_ap_v6.addr, &trusted_addr);
235 :
236 1 : ds = trusted_dir_server_new("gabelmoo", "131.188.40.189", 80, 443,
237 : &trusted_ap_v6,
238 : "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281",
239 : "ED03BB616EB2F60BEC80151114BB25CEF515B226",
240 : V3_DIRINFO, 1.0);
241 1 : tt_assert(ds);
242 1 : dir_server_add(ds);
243 :
244 : /* 1. Valid IPv4 from a trusted authority (gabelmoo). */
245 1 : ret = tor_addr_parse(&ipv4_addr, "1.2.3.4");
246 1 : relay_address_new_suggestion(&ipv4_addr, &ds->ipv4_addr, ds->digest);
247 1 : resolved_addr_get_suggested(AF_INET, &cache_addr);
248 1 : tt_assert(tor_addr_eq(&cache_addr, &ipv4_addr));
249 1 : resolve_addr_reset_suggested(AF_INET);
250 :
251 : /* 2. Valid IPv6 from a trusted authority (gabelmoo). */
252 1 : ret = tor_addr_parse(&ipv6_addr, "[4242::4242]");
253 1 : relay_address_new_suggestion(&ipv6_addr, &ds->ipv6_addr, ds->digest);
254 1 : resolved_addr_get_suggested(AF_INET6, &cache_addr);
255 1 : tt_assert(tor_addr_eq(&cache_addr, &ipv6_addr));
256 1 : resolve_addr_reset_suggested(AF_INET6);
257 :
258 : /* 3. Valid IPv4 but untrusted source. */
259 1 : ret = tor_addr_parse(&ipv4_addr, "1.2.3.4");
260 1 : relay_address_new_suggestion(&ipv4_addr, &untrusted_addr, untrusted_id);
261 1 : resolved_addr_get_suggested(AF_INET, &cache_addr);
262 1 : tt_assert(tor_addr_is_unspec(&cache_addr));
263 :
264 : /* 4. Valid IPv6 but untrusted source. */
265 1 : ret = tor_addr_parse(&ipv6_addr, "[4242::4242]");
266 1 : relay_address_new_suggestion(&ipv6_addr, &untrusted_addr, untrusted_id);
267 1 : resolved_addr_get_suggested(AF_INET6, &cache_addr);
268 1 : tt_assert(tor_addr_is_unspec(&cache_addr));
269 :
270 : /* 5. Internal IPv4 from a trusted authority (gabelmoo). */
271 1 : ret = tor_addr_parse(&ipv4_addr, "127.0.0.1");
272 1 : relay_address_new_suggestion(&ipv4_addr, &ds->ipv4_addr, ds->digest);
273 1 : resolved_addr_get_suggested(AF_INET, &cache_addr);
274 1 : tt_assert(tor_addr_is_unspec(&cache_addr));
275 :
276 : /* 6. Internal IPv6 from a trusted authority (gabelmoo). */
277 1 : ret = tor_addr_parse(&ipv6_addr, "[::1]");
278 1 : relay_address_new_suggestion(&ipv6_addr, &ds->ipv6_addr, ds->digest);
279 1 : resolved_addr_get_suggested(AF_INET6, &cache_addr);
280 1 : tt_assert(tor_addr_is_unspec(&cache_addr));
281 :
282 : /* 7. IPv4 from a trusted authority (gabelmoo). */
283 1 : relay_address_new_suggestion(&ds->ipv4_addr, &ds->ipv4_addr, ds->digest);
284 1 : resolved_addr_get_suggested(AF_INET, &cache_addr);
285 1 : tt_assert(tor_addr_is_unspec(&cache_addr));
286 :
287 : /* 8. IPv6 from a trusted authority (gabelmoo). */
288 1 : relay_address_new_suggestion(&ds->ipv6_addr, &ds->ipv6_addr, ds->digest);
289 1 : resolved_addr_get_suggested(AF_INET6, &cache_addr);
290 1 : tt_assert(tor_addr_is_unspec(&cache_addr));
291 :
292 1 : done:
293 1 : dirlist_free_all();
294 :
295 1 : UNMOCK(server_mode);
296 1 : }
297 :
298 : static void
299 1 : test_find_addr_to_publish(void *arg)
300 : {
301 1 : int family;
302 1 : bool ret;
303 1 : tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
304 1 : or_options_t *options;
305 :
306 1 : (void) arg;
307 :
308 1 : options = options_new();
309 1 : options_init(options);
310 :
311 : /* Populate our resolved cache with a valid IPv4 and IPv6. */
312 1 : family = tor_addr_parse(&ipv4_addr, "1.2.3.4");
313 1 : tt_int_op(family, OP_EQ, AF_INET);
314 1 : resolved_addr_set_last(&ipv4_addr, RESOLVED_ADDR_CONFIGURED, NULL);
315 1 : resolved_addr_get_last(AF_INET, &cache_addr);
316 1 : tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
317 :
318 1 : family = tor_addr_parse(&ipv6_addr, "[4242::4242]");
319 1 : tt_int_op(family, OP_EQ, AF_INET6);
320 1 : resolved_addr_set_last(&ipv6_addr, RESOLVED_ADDR_CONFIGURED, NULL);
321 1 : resolved_addr_get_last(AF_INET6, &cache_addr);
322 1 : tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
323 :
324 : /* Setup ORPort config. */
325 : {
326 1 : int n, w, r;
327 1 : char *msg = NULL;
328 :
329 1 : config_line_append(&options->ORPort_lines, "ORPort", "9001");
330 :
331 1 : r = parse_ports(options, 0, &msg, &n, &w);
332 1 : tt_int_op(r, OP_EQ, 0);
333 : }
334 :
335 : /* 1. Address located in the resolved cache. */
336 1 : ret = relay_find_addr_to_publish(options, AF_INET,
337 : RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
338 1 : tt_assert(ret);
339 1 : tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
340 :
341 1 : ret = relay_find_addr_to_publish(options, AF_INET6,
342 : RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
343 1 : tt_assert(ret);
344 1 : tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
345 1 : resolved_addr_reset_last(AF_INET);
346 1 : resolved_addr_reset_last(AF_INET6);
347 :
348 : /* 2. No IP in the resolve cache, go to the suggested cache. We will ignore
349 : * the find_my_address() code path because that is extensively tested in
350 : * another unit tests. */
351 1 : resolved_addr_set_suggested(&ipv4_addr);
352 1 : ret = relay_find_addr_to_publish(options, AF_INET,
353 : RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
354 1 : tt_assert(ret);
355 1 : tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));
356 :
357 1 : resolved_addr_set_suggested(&ipv6_addr);
358 1 : ret = relay_find_addr_to_publish(options, AF_INET6,
359 : RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
360 1 : tt_assert(ret);
361 1 : tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
362 1 : resolve_addr_reset_suggested(AF_INET);
363 1 : resolve_addr_reset_suggested(AF_INET6);
364 :
365 : /* 3. No IP anywhere. */
366 1 : ret = relay_find_addr_to_publish(options, AF_INET,
367 : RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
368 1 : tt_assert(!ret);
369 1 : ret = relay_find_addr_to_publish(options, AF_INET6,
370 : RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
371 1 : tt_assert(!ret);
372 :
373 1 : done:
374 1 : or_options_free(options);
375 1 : }
376 :
377 : struct testcase_t relay_tests[] = {
378 : { "append_cell_to_circuit_queue", test_relay_append_cell_to_circuit_queue,
379 : TT_FORK, NULL, NULL },
380 : { "close_circ_rephist", test_relay_close_circuit,
381 : TT_FORK, NULL, NULL },
382 : { "suggested_address", test_suggested_address,
383 : TT_FORK, NULL, NULL },
384 : { "find_addr_to_publish", test_find_addr_to_publish,
385 : TT_FORK, NULL, NULL },
386 :
387 : END_OF_TESTCASES
388 : };
|