1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define CIRCUITBUILD_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"
18 #include "core/or/cell_st.h"
19 #include "core/or/or_circuit_st.h"
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"
27 #define CONFIG_PRIVATE
28 #include "app/config/config.h"
29 #include "app/config/resolve_addr.h"
31 /* Test suite stuff */
32 #include "test/test.h"
33 #include "test/fakechans.h"
34 #include "test/fakecircs.h"
36 static void test_relay_append_cell_to_circuit_queue(void *arg
);
39 mock_server_mode_true(const or_options_t
*options
)
46 assert_circuit_ok_mock(const circuit_t
*c
)
53 test_relay_close_circuit(void *arg
)
55 channel_t
*nchan
= NULL
, *pchan
= NULL
;
56 or_circuit_t
*orcirc
= NULL
;
58 int old_count
, new_count
;
62 /* Make fake channels to be nchan and pchan for the circuit */
63 nchan
= new_fake_channel();
66 pchan
= new_fake_channel();
69 /* Make a fake orcirc */
70 orcirc
= new_fake_orcirc(nchan
, pchan
);
72 circuitmux_attach_circuit(nchan
->cmux
, TO_CIRCUIT(orcirc
),
74 circuitmux_attach_circuit(pchan
->cmux
, TO_CIRCUIT(orcirc
),
78 cell
= tor_malloc_zero(sizeof(cell_t
));
81 MOCK(scheduler_channel_has_waiting_cells
,
82 scheduler_channel_has_waiting_cells_mock
);
83 MOCK(assert_circuit_ok
,
84 assert_circuit_ok_mock
);
87 old_count
= get_mock_scheduler_has_waiting_cells_count();
88 append_cell_to_circuit_queue(TO_CIRCUIT(orcirc
), nchan
, cell
,
89 CELL_DIRECTION_OUT
, 0);
90 new_count
= get_mock_scheduler_has_waiting_cells_count();
91 tt_int_op(new_count
, OP_EQ
, old_count
+ 1);
93 /* Now try the reverse direction */
94 old_count
= get_mock_scheduler_has_waiting_cells_count();
95 append_cell_to_circuit_queue(TO_CIRCUIT(orcirc
), pchan
, cell
,
96 CELL_DIRECTION_IN
, 0);
97 new_count
= get_mock_scheduler_has_waiting_cells_count();
98 tt_int_op(new_count
, OP_EQ
, old_count
+ 1);
100 /* Ensure our write totals are 0 */
101 tt_u64_op(find_largest_max(write_array
, 86400), OP_EQ
, 0);
103 /* Mark the circuit for close */
104 circuit_mark_for_close(TO_CIRCUIT(orcirc
), 0);
106 /* Check our write totals. */
107 advance_obs(write_array
);
108 commit_max(write_array
);
109 /* Check for two cells plus overhead */
110 tt_u64_op(find_largest_max(write_array
, 86400), OP_EQ
,
111 2*(get_cell_network_size(nchan
->wide_circ_ids
)
112 +TLS_PER_CELL_OVERHEAD
));
114 UNMOCK(scheduler_channel_has_waiting_cells
);
116 /* Get rid of the fake channels */
117 MOCK(scheduler_release_channel
, scheduler_release_channel_mock
);
118 channel_mark_for_close(nchan
);
119 channel_mark_for_close(pchan
);
120 UNMOCK(scheduler_release_channel
);
122 /* Shut down channels */
128 circuitmux_detach_circuit(nchan
->cmux
, TO_CIRCUIT(orcirc
));
129 circuitmux_detach_circuit(pchan
->cmux
, TO_CIRCUIT(orcirc
));
130 cell_queue_clear(&orcirc
->base_
.n_chan_cells
);
131 cell_queue_clear(&orcirc
->p_chan_cells
);
133 free_fake_orcirc(orcirc
);
134 free_fake_channel(nchan
);
135 free_fake_channel(pchan
);
136 UNMOCK(assert_circuit_ok
);
142 test_relay_append_cell_to_circuit_queue(void *arg
)
144 channel_t
*nchan
= NULL
, *pchan
= NULL
;
145 or_circuit_t
*orcirc
= NULL
;
147 int old_count
, new_count
;
151 /* Make fake channels to be nchan and pchan for the circuit */
152 nchan
= new_fake_channel();
155 pchan
= new_fake_channel();
158 /* Make a fake orcirc */
159 orcirc
= new_fake_orcirc(nchan
, pchan
);
161 circuitmux_attach_circuit(nchan
->cmux
, TO_CIRCUIT(orcirc
),
163 circuitmux_attach_circuit(pchan
->cmux
, TO_CIRCUIT(orcirc
),
167 cell
= tor_malloc_zero(sizeof(cell_t
));
168 make_fake_cell(cell
);
170 MOCK(scheduler_channel_has_waiting_cells
,
171 scheduler_channel_has_waiting_cells_mock
);
174 old_count
= get_mock_scheduler_has_waiting_cells_count();
175 append_cell_to_circuit_queue(TO_CIRCUIT(orcirc
), nchan
, cell
,
176 CELL_DIRECTION_OUT
, 0);
177 new_count
= get_mock_scheduler_has_waiting_cells_count();
178 tt_int_op(new_count
, OP_EQ
, old_count
+ 1);
180 /* Now try the reverse direction */
181 old_count
= get_mock_scheduler_has_waiting_cells_count();
182 append_cell_to_circuit_queue(TO_CIRCUIT(orcirc
), pchan
, cell
,
183 CELL_DIRECTION_IN
, 0);
184 new_count
= get_mock_scheduler_has_waiting_cells_count();
185 tt_int_op(new_count
, OP_EQ
, old_count
+ 1);
187 UNMOCK(scheduler_channel_has_waiting_cells
);
189 /* Get rid of the fake channels */
190 MOCK(scheduler_release_channel
, scheduler_release_channel_mock
);
191 channel_mark_for_close(nchan
);
192 channel_mark_for_close(pchan
);
193 UNMOCK(scheduler_release_channel
);
195 /* Shut down channels */
201 circuitmux_detach_circuit(nchan
->cmux
, TO_CIRCUIT(orcirc
));
202 circuitmux_detach_circuit(pchan
->cmux
, TO_CIRCUIT(orcirc
));
203 cell_queue_clear(&orcirc
->base_
.n_chan_cells
);
204 cell_queue_clear(&orcirc
->p_chan_cells
);
206 free_fake_orcirc(orcirc
);
207 free_fake_channel(nchan
);
208 free_fake_channel(pchan
);
214 test_suggested_address(void *arg
)
217 const char *untrusted_id
= "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
218 dir_server_t
*ds
= NULL
;
219 tor_addr_t ipv4_addr
, ipv6_addr
, cache_addr
;
220 tor_addr_t trusted_addr
, untrusted_addr
;
221 tor_addr_port_t trusted_ap_v6
= { .port
= 443 };
225 MOCK(server_mode
, mock_server_mode_true
);
227 /* Unstrusted relay source. */
228 ret
= tor_addr_parse(&untrusted_addr
, "8.8.8.8");
229 tt_int_op(ret
, OP_EQ
, AF_INET
);
231 /* Add gabelmoo as a trusted directory authority. */
232 ret
= tor_addr_parse(&trusted_addr
, "[2001:638:a000:4140::ffff:189]");
233 tt_int_op(ret
, OP_EQ
, AF_INET6
);
234 tor_addr_copy(&trusted_ap_v6
.addr
, &trusted_addr
);
236 ds
= trusted_dir_server_new("gabelmoo", "131.188.40.189", 80, 443,
238 "F2044413DAC2E02E3D6BCF4735A19BCA1DE97281",
239 "ED03BB616EB2F60BEC80151114BB25CEF515B226",
244 /* 1. Valid IPv4 from a trusted authority (gabelmoo). */
245 ret
= tor_addr_parse(&ipv4_addr
, "1.2.3.4");
246 relay_address_new_suggestion(&ipv4_addr
, &ds
->ipv4_addr
, ds
->digest
);
247 resolved_addr_get_suggested(AF_INET
, &cache_addr
);
248 tt_assert(tor_addr_eq(&cache_addr
, &ipv4_addr
));
249 resolve_addr_reset_suggested(AF_INET
);
251 /* 2. Valid IPv6 from a trusted authority (gabelmoo). */
252 ret
= tor_addr_parse(&ipv6_addr
, "[4242::4242]");
253 relay_address_new_suggestion(&ipv6_addr
, &ds
->ipv6_addr
, ds
->digest
);
254 resolved_addr_get_suggested(AF_INET6
, &cache_addr
);
255 tt_assert(tor_addr_eq(&cache_addr
, &ipv6_addr
));
256 resolve_addr_reset_suggested(AF_INET6
);
258 /* 3. Valid IPv4 but untrusted source. */
259 ret
= tor_addr_parse(&ipv4_addr
, "1.2.3.4");
260 relay_address_new_suggestion(&ipv4_addr
, &untrusted_addr
, untrusted_id
);
261 resolved_addr_get_suggested(AF_INET
, &cache_addr
);
262 tt_assert(tor_addr_is_unspec(&cache_addr
));
264 /* 4. Valid IPv6 but untrusted source. */
265 ret
= tor_addr_parse(&ipv6_addr
, "[4242::4242]");
266 relay_address_new_suggestion(&ipv6_addr
, &untrusted_addr
, untrusted_id
);
267 resolved_addr_get_suggested(AF_INET6
, &cache_addr
);
268 tt_assert(tor_addr_is_unspec(&cache_addr
));
270 /* 5. Internal IPv4 from a trusted authority (gabelmoo). */
271 ret
= tor_addr_parse(&ipv4_addr
, "127.0.0.1");
272 relay_address_new_suggestion(&ipv4_addr
, &ds
->ipv4_addr
, ds
->digest
);
273 resolved_addr_get_suggested(AF_INET
, &cache_addr
);
274 tt_assert(tor_addr_is_unspec(&cache_addr
));
276 /* 6. Internal IPv6 from a trusted authority (gabelmoo). */
277 ret
= tor_addr_parse(&ipv6_addr
, "[::1]");
278 relay_address_new_suggestion(&ipv6_addr
, &ds
->ipv6_addr
, ds
->digest
);
279 resolved_addr_get_suggested(AF_INET6
, &cache_addr
);
280 tt_assert(tor_addr_is_unspec(&cache_addr
));
282 /* 7. IPv4 from a trusted authority (gabelmoo). */
283 relay_address_new_suggestion(&ds
->ipv4_addr
, &ds
->ipv4_addr
, ds
->digest
);
284 resolved_addr_get_suggested(AF_INET
, &cache_addr
);
285 tt_assert(tor_addr_is_unspec(&cache_addr
));
287 /* 8. IPv6 from a trusted authority (gabelmoo). */
288 relay_address_new_suggestion(&ds
->ipv6_addr
, &ds
->ipv6_addr
, ds
->digest
);
289 resolved_addr_get_suggested(AF_INET6
, &cache_addr
);
290 tt_assert(tor_addr_is_unspec(&cache_addr
));
299 test_find_addr_to_publish(void *arg
)
303 tor_addr_t ipv4_addr
, ipv6_addr
, cache_addr
;
304 or_options_t
*options
;
308 options
= options_new();
309 options_init(options
);
311 /* Populate our resolved cache with a valid IPv4 and IPv6. */
312 family
= tor_addr_parse(&ipv4_addr
, "1.2.3.4");
313 tt_int_op(family
, OP_EQ
, AF_INET
);
314 resolved_addr_set_last(&ipv4_addr
, RESOLVED_ADDR_CONFIGURED
, NULL
);
315 resolved_addr_get_last(AF_INET
, &cache_addr
);
316 tt_assert(tor_addr_eq(&ipv4_addr
, &cache_addr
));
318 family
= tor_addr_parse(&ipv6_addr
, "[4242::4242]");
319 tt_int_op(family
, OP_EQ
, AF_INET6
);
320 resolved_addr_set_last(&ipv6_addr
, RESOLVED_ADDR_CONFIGURED
, NULL
);
321 resolved_addr_get_last(AF_INET6
, &cache_addr
);
322 tt_assert(tor_addr_eq(&ipv6_addr
, &cache_addr
));
324 /* Setup ORPort config. */
329 config_line_append(&options
->ORPort_lines
, "ORPort", "9001");
331 r
= parse_ports(options
, 0, &msg
, &n
, &w
);
332 tt_int_op(r
, OP_EQ
, 0);
335 /* 1. Address located in the resolved cache. */
336 ret
= relay_find_addr_to_publish(options
, AF_INET
,
337 RELAY_FIND_ADDR_CACHE_ONLY
, &cache_addr
);
339 tt_assert(tor_addr_eq(&ipv4_addr
, &cache_addr
));
341 ret
= relay_find_addr_to_publish(options
, AF_INET6
,
342 RELAY_FIND_ADDR_CACHE_ONLY
, &cache_addr
);
344 tt_assert(tor_addr_eq(&ipv6_addr
, &cache_addr
));
345 resolved_addr_reset_last(AF_INET
);
346 resolved_addr_reset_last(AF_INET6
);
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 resolved_addr_set_suggested(&ipv4_addr
);
352 ret
= relay_find_addr_to_publish(options
, AF_INET
,
353 RELAY_FIND_ADDR_CACHE_ONLY
, &cache_addr
);
355 tt_assert(tor_addr_eq(&ipv4_addr
, &cache_addr
));
357 resolved_addr_set_suggested(&ipv6_addr
);
358 ret
= relay_find_addr_to_publish(options
, AF_INET6
,
359 RELAY_FIND_ADDR_CACHE_ONLY
, &cache_addr
);
361 tt_assert(tor_addr_eq(&ipv6_addr
, &cache_addr
));
362 resolve_addr_reset_suggested(AF_INET
);
363 resolve_addr_reset_suggested(AF_INET6
);
365 /* 3. No IP anywhere. */
366 ret
= relay_find_addr_to_publish(options
, AF_INET
,
367 RELAY_FIND_ADDR_CACHE_ONLY
, &cache_addr
);
369 ret
= relay_find_addr_to_publish(options
, AF_INET6
,
370 RELAY_FIND_ADDR_CACHE_ONLY
, &cache_addr
);
374 or_options_free(options
);
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
},