Line data Source code
1 : /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 : /* Copyright (c) 2017, isis agora lovecruft */
3 : /* See LICENSE for licensing information */
4 :
5 : /**
6 : * \file test_router.c
7 : * \brief Unittests for code in router.c
8 : **/
9 :
10 : #define CONFIG_PRIVATE
11 : #define CONNECTION_PRIVATE
12 : #define ROUTER_PRIVATE
13 :
14 : #include "core/or/or.h"
15 : #include "app/config/config.h"
16 : #include "core/mainloop/mainloop.h"
17 : #include "core/mainloop/connection.h"
18 : #include "feature/hibernate/hibernate.h"
19 : #include "feature/nodelist/networkstatus.h"
20 : #include "feature/nodelist/networkstatus_st.h"
21 : #include "feature/nodelist/node_st.h"
22 : #include "feature/nodelist/nodelist.h"
23 : #include "feature/nodelist/routerinfo_st.h"
24 : #include "feature/nodelist/routerlist.h"
25 : #include "feature/nodelist/routerstatus_st.h"
26 : #include "feature/nodelist/torcert.h"
27 : #include "feature/relay/router.h"
28 : #include "feature/stats/bwhist.h"
29 : #include "lib/crypt_ops/crypto_curve25519.h"
30 : #include "lib/crypt_ops/crypto_ed25519.h"
31 : #include "lib/encoding/confline.h"
32 :
33 : #include "core/or/listener_connection_st.h"
34 :
35 : /* Test suite stuff */
36 : #include "test/test.h"
37 : #include "test/log_test_helpers.h"
38 :
39 : static routerinfo_t *
40 1 : rtr_tests_gen_routerinfo(crypto_pk_t *ident_key, crypto_pk_t *tap_key)
41 : {
42 1 : time_t now;
43 :
44 1 : routerinfo_t *mock_routerinfo;
45 :
46 : /* Mock the published timestamp, otherwise router_dump_router_to_string()
47 : * will poop its pants. */
48 1 : time(&now);
49 :
50 : /* We'll need keys, or router_dump_router_to_string() would return NULL. */
51 1 : tor_assert(ident_key != NULL);
52 1 : tor_assert(tap_key != NULL);
53 :
54 1 : mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
55 1 : mock_routerinfo->nickname = tor_strdup("ConlonNancarrow");
56 1 : tor_addr_from_ipv4h(&mock_routerinfo->ipv4_addr, 123456789);
57 1 : mock_routerinfo->ipv4_orport = 443;
58 1 : mock_routerinfo->platform = tor_strdup("unittest");
59 1 : mock_routerinfo->cache_info.published_on = now;
60 1 : mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
61 2 : mock_routerinfo->protocol_list =
62 1 : tor_strdup("Cons=1-2 Desc=1-2 DirCache=1-2");
63 1 : router_set_rsa_onion_pkey(tap_key, &mock_routerinfo->onion_pkey,
64 : &mock_routerinfo->onion_pkey_len);
65 1 : mock_routerinfo->bandwidthrate = 9001;
66 1 : mock_routerinfo->bandwidthburst = 9002;
67 :
68 1 : return mock_routerinfo;
69 : }
70 :
71 : /* If no distribution option was set, then check_bridge_distribution_setting()
72 : * should have set it to "any". */
73 : static void
74 1 : test_router_dump_router_to_string_no_bridge_distribution_method(void *arg)
75 : {
76 1 : const char* needle = "bridge-distribution-request any";
77 1 : or_options_t* options = get_options_mutable();
78 1 : routerinfo_t* router = NULL;
79 1 : curve25519_keypair_t ntor_keypair;
80 1 : ed25519_keypair_t signing_keypair;
81 1 : ed25519_keypair_t identity_keypair;
82 1 : char* desc = NULL;
83 1 : char* found = NULL;
84 1 : (void)arg;
85 1 : crypto_pk_t *ident_key = pk_generate(0);
86 1 : crypto_pk_t *tap_key = pk_generate(0);
87 :
88 1 : options->ORPort_set = 1;
89 1 : options->BridgeRelay = 1;
90 :
91 : /* Generate keys which router_dump_router_to_string() expects to exist. */
92 1 : tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ntor_keypair, 0));
93 1 : tt_int_op(0, OP_EQ, ed25519_keypair_generate(&signing_keypair, 0));
94 1 : tt_int_op(0, OP_EQ, ed25519_keypair_generate(&identity_keypair, 0));
95 :
96 : /* Set up part of our routerinfo_t so that we don't trigger any other
97 : * assertions in router_dump_router_to_string(). */
98 1 : router = rtr_tests_gen_routerinfo(ident_key, tap_key);
99 1 : tt_ptr_op(router, OP_NE, NULL);
100 :
101 2 : router->cache_info.signing_key_cert =
102 1 : tor_cert_create_ed25519(&identity_keypair,
103 : CERT_TYPE_ID_SIGNING,
104 : &signing_keypair.pubkey,
105 : time(NULL),
106 : 86400,
107 : CERT_FLAG_INCLUDE_SIGNING_KEY);
108 :
109 : /* The real router_get_my_routerinfo() looks up onion_curve25519_pkey using
110 : * get_current_curve25519_keypair(), but we don't initialise static data in
111 : * this test. */
112 1 : router->onion_curve25519_pkey = &ntor_keypair.pubkey;
113 :
114 : /* Generate our server descriptor and ensure that the substring
115 : * "bridge-distribution-request any" occurs somewhere within it. */
116 1 : desc = router_dump_router_to_string(router,
117 : ident_key,
118 : tap_key,
119 : &ntor_keypair,
120 : &signing_keypair);
121 1 : tt_ptr_op(desc, OP_NE, NULL);
122 1 : found = strstr(desc, needle);
123 1 : tt_ptr_op(found, OP_NE, NULL);
124 :
125 1 : done:
126 1 : if (router)
127 1 : router->onion_curve25519_pkey = NULL; // avoid double-free
128 1 : routerinfo_free(router);
129 1 : tor_free(desc);
130 1 : crypto_pk_free(ident_key);
131 1 : crypto_pk_free(tap_key);
132 1 : }
133 :
134 : static routerinfo_t *mock_router_get_my_routerinfo_result = NULL;
135 :
136 : static const routerinfo_t *
137 6 : mock_router_get_my_routerinfo(void)
138 : {
139 6 : return mock_router_get_my_routerinfo_result;
140 : }
141 :
142 : static long
143 5 : mock_get_uptime_3h(void)
144 : {
145 5 : return 3*60*60;
146 : }
147 :
148 : static long
149 1 : mock_get_uptime_1d(void)
150 : {
151 1 : return 24*60*60;
152 : }
153 :
154 : static int
155 1 : mock_rep_hist_bandwidth_assess(void)
156 : {
157 1 : return 20001;
158 : }
159 :
160 : static int
161 5 : mock_we_are_not_hibernating(void)
162 : {
163 5 : return 0;
164 : }
165 :
166 : static int
167 1 : mock_we_are_hibernating(void)
168 : {
169 1 : return 0;
170 : }
171 :
172 : static void
173 1 : test_router_check_descriptor_bandwidth_changed(void *arg)
174 : {
175 1 : (void)arg;
176 1 : routerinfo_t routerinfo;
177 1 : memset(&routerinfo, 0, sizeof(routerinfo));
178 1 : mock_router_get_my_routerinfo_result = NULL;
179 :
180 1 : MOCK(we_are_hibernating, mock_we_are_not_hibernating);
181 1 : MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
182 1 : mock_router_get_my_routerinfo_result = &routerinfo;
183 :
184 : /* When uptime is less than 24h, no previous bandwidth, no last_changed
185 : * Uptime: 10800, last_changed: 0, Previous bw: 0, Current bw: 0 */
186 1 : routerinfo.bandwidthcapacity = 0;
187 1 : MOCK(get_uptime, mock_get_uptime_3h);
188 1 : setup_full_capture_of_logs(LOG_INFO);
189 1 : check_descriptor_bandwidth_changed(time(NULL));
190 1 : expect_log_msg_not_containing(
191 1 : "Measured bandwidth has changed; rebuilding descriptor.");
192 1 : teardown_capture_of_logs();
193 :
194 : /* When uptime is less than 24h, previous bandwidth,
195 : * last_changed more than 3h ago
196 : * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
197 1 : routerinfo.bandwidthcapacity = 10000;
198 1 : setup_full_capture_of_logs(LOG_INFO);
199 1 : check_descriptor_bandwidth_changed(time(NULL));
200 1 : expect_log_msg_containing(
201 1 : "Measured bandwidth has changed; rebuilding descriptor.");
202 1 : teardown_capture_of_logs();
203 :
204 : /* When uptime is less than 24h, previous bandwidth,
205 : * last_changed more than 3h ago, and hibernating
206 : * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
207 :
208 1 : UNMOCK(we_are_hibernating);
209 1 : MOCK(we_are_hibernating, mock_we_are_hibernating);
210 1 : routerinfo.bandwidthcapacity = 10000;
211 1 : setup_full_capture_of_logs(LOG_INFO);
212 1 : check_descriptor_bandwidth_changed(time(NULL));
213 1 : expect_log_msg_not_containing(
214 1 : "Measured bandwidth has changed; rebuilding descriptor.");
215 1 : teardown_capture_of_logs();
216 1 : UNMOCK(we_are_hibernating);
217 1 : MOCK(we_are_hibernating, mock_we_are_not_hibernating);
218 :
219 : /* When uptime is less than 24h, last_changed is not more than 3h ago
220 : * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 0 */
221 1 : setup_full_capture_of_logs(LOG_INFO);
222 1 : check_descriptor_bandwidth_changed(time(NULL));
223 1 : expect_log_msg_not_containing(
224 1 : "Measured bandwidth has changed; rebuilding descriptor.");
225 1 : teardown_capture_of_logs();
226 :
227 : /* When uptime is less than 24h and bandwidthcapacity does not change
228 : * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 20001 */
229 1 : MOCK(bwhist_bandwidth_assess, mock_rep_hist_bandwidth_assess);
230 1 : setup_full_capture_of_logs(LOG_INFO);
231 1 : check_descriptor_bandwidth_changed(time(NULL) + 6*60*60 + 1);
232 1 : expect_log_msg_containing(
233 1 : "Measured bandwidth has changed; rebuilding descriptor.");
234 1 : UNMOCK(get_uptime);
235 1 : UNMOCK(bwhist_bandwidth_assess);
236 1 : teardown_capture_of_logs();
237 :
238 : /* When uptime is more than 24h */
239 1 : MOCK(get_uptime, mock_get_uptime_1d);
240 1 : setup_full_capture_of_logs(LOG_INFO);
241 1 : check_descriptor_bandwidth_changed(time(NULL));
242 1 : expect_log_msg_not_containing(
243 1 : "Measured bandwidth has changed; rebuilding descriptor.");
244 1 : teardown_capture_of_logs();
245 :
246 1 : done:
247 1 : UNMOCK(get_uptime);
248 1 : UNMOCK(router_get_my_routerinfo);
249 1 : UNMOCK(we_are_hibernating);
250 1 : }
251 :
252 : static networkstatus_t *mock_ns = NULL;
253 : static networkstatus_t *
254 6 : mock_networkstatus_get_live_consensus(time_t now)
255 : {
256 6 : (void)now;
257 6 : return mock_ns;
258 : }
259 :
260 : static routerstatus_t *mock_rs = NULL;
261 : static const routerstatus_t *
262 5 : mock_networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
263 : {
264 5 : (void)ns;
265 5 : (void)digest;
266 5 : return mock_rs;
267 : }
268 :
269 : static void
270 1 : test_router_mark_if_too_old(void *arg)
271 : {
272 1 : (void)arg;
273 1 : time_t now = approx_time();
274 1 : MOCK(networkstatus_get_live_consensus,
275 : mock_networkstatus_get_live_consensus);
276 1 : MOCK(networkstatus_vote_find_entry, mock_networkstatus_vote_find_entry);
277 :
278 1 : routerstatus_t rs;
279 1 : networkstatus_t ns;
280 1 : memset(&rs, 0, sizeof(rs));
281 1 : memset(&ns, 0, sizeof(ns));
282 1 : mock_ns = &ns;
283 1 : mock_ns->valid_after = now-3600;
284 1 : mock_rs = &rs;
285 1 : mock_rs->published_on = now - 10;
286 :
287 : // no reason to mark this time.
288 1 : desc_clean_since = now-10;
289 1 : desc_dirty_reason = NULL;
290 1 : mark_my_descriptor_dirty_if_too_old(now);
291 1 : tt_i64_op(desc_clean_since, OP_EQ, now-10);
292 :
293 : // Doesn't appear in consensus? Still don't mark it.
294 1 : mock_ns = NULL;
295 1 : mark_my_descriptor_dirty_if_too_old(now);
296 1 : tt_i64_op(desc_clean_since, OP_EQ, now-10);
297 1 : mock_ns = &ns;
298 :
299 : // No new descriptor in a long time? Mark it.
300 1 : desc_clean_since = now - 3600 * 96;
301 1 : mark_my_descriptor_dirty_if_too_old(now);
302 1 : tt_i64_op(desc_clean_since, OP_EQ, 0);
303 1 : tt_str_op(desc_dirty_reason, OP_EQ, "time for new descriptor");
304 :
305 : // Version in consensus published a long time ago? We won't mark it
306 : // if it's been clean for only a short time.
307 1 : desc_clean_since = now - 10;
308 1 : desc_dirty_reason = NULL;
309 1 : mock_rs->published_on = now - 3600 * 96;
310 1 : mark_my_descriptor_dirty_if_too_old(now);
311 1 : tt_i64_op(desc_clean_since, OP_EQ, now - 10);
312 :
313 : // ... but if it's been clean a while, we mark.
314 1 : desc_clean_since = now - 2 * 3600;
315 1 : mark_my_descriptor_dirty_if_too_old(now);
316 1 : tt_i64_op(desc_clean_since, OP_EQ, 0);
317 1 : tt_str_op(desc_dirty_reason, OP_EQ,
318 : "version listed in consensus is quite old");
319 :
320 : // same deal if we're marked stale.
321 1 : desc_clean_since = now - 2 * 3600;
322 1 : desc_dirty_reason = NULL;
323 1 : mock_rs->published_on = now - 10;
324 1 : mock_rs->is_staledesc = 1;
325 1 : mark_my_descriptor_dirty_if_too_old(now);
326 1 : tt_i64_op(desc_clean_since, OP_EQ, 0);
327 1 : tt_str_op(desc_dirty_reason, OP_EQ,
328 : "listed as stale in consensus");
329 :
330 : // same deal if we're absent from the consensus.
331 1 : desc_clean_since = now - 2 * 3600;
332 1 : desc_dirty_reason = NULL;
333 1 : mock_rs = NULL;
334 1 : mark_my_descriptor_dirty_if_too_old(now);
335 1 : tt_i64_op(desc_clean_since, OP_EQ, 0);
336 1 : tt_str_op(desc_dirty_reason, OP_EQ,
337 : "not listed in consensus");
338 :
339 1 : done:
340 1 : UNMOCK(networkstatus_get_live_consensus);
341 1 : UNMOCK(networkstatus_vote_find_entry);
342 1 : }
343 :
344 : static node_t fake_node;
345 : static const node_t *
346 5 : mock_node_get_by_nickname(const char *name, unsigned flags)
347 : {
348 5 : (void)flags;
349 5 : if (!strcasecmp(name, "crumpet"))
350 : return &fake_node;
351 : else
352 4 : return NULL;
353 : }
354 :
355 : static void
356 1 : test_router_get_my_family(void *arg)
357 : {
358 1 : (void)arg;
359 1 : or_options_t *options = options_new();
360 1 : smartlist_t *sl = NULL;
361 1 : char *join = NULL;
362 : // Overwrite the result of router_get_my_identity_digest(). This
363 : // happens to be okay, but only for testing.
364 1 : set_server_identity_key_digest_testing(
365 : (const uint8_t*)"holeinthebottomofthe");
366 :
367 1 : setup_capture_of_logs(LOG_WARN);
368 :
369 : // No family listed -- so there's no list.
370 1 : sl = get_my_declared_family(options);
371 1 : tt_ptr_op(sl, OP_EQ, NULL);
372 1 : expect_no_log_entry();
373 :
374 : #define CLEAR() do { \
375 : if (sl) { \
376 : SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); \
377 : smartlist_free(sl); \
378 : } \
379 : tor_free(join); \
380 : mock_clean_saved_logs(); \
381 : } while (0)
382 :
383 : // Add a single nice friendly hex member. This should be enough
384 : // to have our own ID added.
385 1 : tt_ptr_op(options->MyFamily, OP_EQ, NULL);
386 1 : config_line_append(&options->MyFamily, "MyFamily",
387 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
388 :
389 1 : sl = get_my_declared_family(options);
390 1 : tt_ptr_op(sl, OP_NE, NULL);
391 1 : tt_int_op(smartlist_len(sl), OP_EQ, 2);
392 1 : join = smartlist_join_strings(sl, " ", 0, NULL);
393 1 : tt_str_op(join, OP_EQ,
394 : "$686F6C65696E746865626F74746F6D6F66746865 "
395 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
396 1 : expect_no_log_entry();
397 3 : CLEAR();
398 :
399 : // Add a hex member with a ~. The ~ part should get removed.
400 1 : config_line_append(&options->MyFamily, "MyFamily",
401 : "$0123456789abcdef0123456789abcdef01234567~Muffin");
402 1 : sl = get_my_declared_family(options);
403 1 : tt_ptr_op(sl, OP_NE, NULL);
404 1 : tt_int_op(smartlist_len(sl), OP_EQ, 3);
405 1 : join = smartlist_join_strings(sl, " ", 0, NULL);
406 1 : tt_str_op(join, OP_EQ,
407 : "$0123456789ABCDEF0123456789ABCDEF01234567 "
408 : "$686F6C65696E746865626F74746F6D6F66746865 "
409 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
410 1 : expect_no_log_entry();
411 4 : CLEAR();
412 :
413 : // Nickname lookup will fail, so a nickname will appear verbatim.
414 1 : config_line_append(&options->MyFamily, "MyFamily",
415 : "BAGEL");
416 1 : sl = get_my_declared_family(options);
417 1 : tt_ptr_op(sl, OP_NE, NULL);
418 1 : tt_int_op(smartlist_len(sl), OP_EQ, 4);
419 1 : join = smartlist_join_strings(sl, " ", 0, NULL);
420 1 : tt_str_op(join, OP_EQ,
421 : "$0123456789ABCDEF0123456789ABCDEF01234567 "
422 : "$686F6C65696E746865626F74746F6D6F66746865 "
423 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
424 : "bagel");
425 1 : expect_single_log_msg_containing(
426 : "There is a router named \"BAGEL\" in my declared family, but "
427 : "I have no descriptor for it.");
428 5 : CLEAR();
429 :
430 : // A bogus digest should fail entirely.
431 1 : config_line_append(&options->MyFamily, "MyFamily",
432 : "$painauchocolat");
433 1 : sl = get_my_declared_family(options);
434 1 : tt_ptr_op(sl, OP_NE, NULL);
435 1 : tt_int_op(smartlist_len(sl), OP_EQ, 4);
436 1 : join = smartlist_join_strings(sl, " ", 0, NULL);
437 1 : tt_str_op(join, OP_EQ,
438 : "$0123456789ABCDEF0123456789ABCDEF01234567 "
439 : "$686F6C65696E746865626F74746F6D6F66746865 "
440 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
441 : "bagel");
442 : // "BAGEL" is still there, but it won't make a warning, because we already
443 : // warned about it.
444 1 : expect_single_log_msg_containing(
445 : "There is a router named \"$painauchocolat\" in my declared "
446 : "family, but that isn't a legal digest or nickname. Skipping it.");
447 5 : CLEAR();
448 :
449 : // Let's introduce a node we can look up by nickname
450 1 : memset(&fake_node, 0, sizeof(fake_node));
451 1 : memcpy(fake_node.identity, "whydoyouasknonononon", DIGEST_LEN);
452 1 : MOCK(node_get_by_nickname, mock_node_get_by_nickname);
453 :
454 1 : config_line_append(&options->MyFamily, "MyFamily",
455 : "CRUmpeT");
456 1 : sl = get_my_declared_family(options);
457 1 : tt_ptr_op(sl, OP_NE, NULL);
458 1 : tt_int_op(smartlist_len(sl), OP_EQ, 5);
459 1 : join = smartlist_join_strings(sl, " ", 0, NULL);
460 1 : tt_str_op(join, OP_EQ,
461 : "$0123456789ABCDEF0123456789ABCDEF01234567 "
462 : "$686F6C65696E746865626F74746F6D6F66746865 "
463 : "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E "
464 : "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
465 : "bagel");
466 : // "BAGEL" is still there, but it won't make a warning, because we already
467 : // warned about it. Some with "$painauchocolat".
468 1 : expect_single_log_msg_containing(
469 : "There is a router named \"CRUmpeT\" in my declared "
470 : "family, but it wasn't listed by digest. Please consider saying "
471 : "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E instead, if that's "
472 : "what you meant.");
473 6 : CLEAR();
474 1 : UNMOCK(node_get_by_nickname);
475 :
476 : // Try a singleton list containing only us: It should give us NULL.
477 1 : config_free_lines(options->MyFamily);
478 1 : config_line_append(&options->MyFamily, "MyFamily",
479 : "$686F6C65696E746865626F74746F6D6F66746865");
480 1 : sl = get_my_declared_family(options);
481 1 : tt_ptr_op(sl, OP_EQ, NULL);
482 1 : expect_no_log_entry();
483 :
484 1 : done:
485 1 : or_options_free(options);
486 1 : teardown_capture_of_logs();
487 1 : CLEAR();
488 1 : UNMOCK(node_get_by_nickname);
489 :
490 : #undef CLEAR
491 1 : }
492 :
493 : static smartlist_t *fake_connection_array = NULL;
494 : static smartlist_t *
495 2 : mock_get_connection_array(void)
496 : {
497 2 : return fake_connection_array;
498 : }
499 :
500 : static void
501 1 : test_router_get_advertised_or_port(void *arg)
502 : {
503 1 : (void)arg;
504 1 : int r, w=0, n=0;
505 1 : char *msg=NULL;
506 1 : or_options_t *opts = options_new();
507 1 : listener_connection_t *listener = NULL;
508 1 : tor_addr_port_t ipv6;
509 :
510 : // Test one failing case of routerconf_find_ipv6_or_ap().
511 1 : routerconf_find_ipv6_or_ap(opts, &ipv6);
512 1 : tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
513 :
514 : // And one failing case of routerconf_find_or_port().
515 1 : tt_int_op(0, OP_EQ, routerconf_find_or_port(opts, AF_INET));
516 :
517 : // Set up a couple of configured ports.
518 1 : config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:auto");
519 1 : config_line_append(&opts->ORPort_lines, "ORPort", "5.6.7.8:9999");
520 1 : r = parse_ports(opts, 0, &msg, &n, &w);
521 1 : tt_assert(r == 0);
522 :
523 : // There are no listeners, so the "auto" case will turn up no results.
524 1 : tt_int_op(0, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
525 1 : routerconf_find_ipv6_or_ap(opts, &ipv6);
526 1 : tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
527 :
528 : // This will return the matching value from the configured port.
529 1 : tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET));
530 :
531 : // Now set up a dummy listener.
532 1 : MOCK(get_connection_array, mock_get_connection_array);
533 1 : fake_connection_array = smartlist_new();
534 1 : listener = listener_connection_new(CONN_TYPE_OR_LISTENER, AF_INET6);
535 1 : TO_CONN(listener)->port = 54321;
536 1 : smartlist_add(fake_connection_array, TO_CONN(listener));
537 :
538 : // We should get a port this time.
539 1 : tt_int_op(54321, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
540 :
541 : // Test one succeeding case of routerconf_find_ipv6_or_ap().
542 1 : routerconf_find_ipv6_or_ap(opts, &ipv6);
543 1 : tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ,
544 : "[1234::5678]:54321");
545 :
546 : // This will return the matching value from the configured port.
547 1 : tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET));
548 :
549 1 : done:
550 1 : or_options_free(opts);
551 1 : config_free_all();
552 1 : smartlist_free(fake_connection_array);
553 1 : connection_free_minimal(TO_CONN(listener));
554 1 : UNMOCK(get_connection_array);
555 1 : }
556 :
557 : static void
558 1 : test_router_get_advertised_or_port_localhost(void *arg)
559 : {
560 1 : (void)arg;
561 1 : int r, w=0, n=0;
562 1 : char *msg=NULL;
563 1 : or_options_t *opts = options_new();
564 1 : tor_addr_port_t ipv6;
565 :
566 : // Set up a couple of configured ports on localhost.
567 1 : config_line_append(&opts->ORPort_lines, "ORPort", "[::1]:9999");
568 1 : config_line_append(&opts->ORPort_lines, "ORPort", "127.0.0.1:8888");
569 1 : r = parse_ports(opts, 0, &msg, &n, &w);
570 1 : tt_assert(r == 0);
571 :
572 : // We should refuse to advertise them, since we have default dirauths.
573 1 : routerconf_find_ipv6_or_ap(opts, &ipv6);
574 1 : tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
575 : // But the lower-level function should still report the correct value
576 1 : tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
577 :
578 : // The IPv4 checks are done in resolve_my_address(), which doesn't use
579 : // ORPorts so we can't test them here. (See #33681.) Both these lower-level
580 : // functions should still report the correct value.
581 1 : tt_int_op(8888, OP_EQ, routerconf_find_or_port(opts, AF_INET));
582 :
583 : // Now try with a fake authority set up.
584 1 : config_line_append(&opts->DirAuthorities, "DirAuthority",
585 : "127.0.0.1:1066 "
586 : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
587 :
588 1 : tt_int_op(9999, OP_EQ, routerconf_find_or_port(opts, AF_INET6));
589 1 : routerconf_find_ipv6_or_ap(opts, &ipv6);
590 1 : tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::1]:9999");
591 :
592 1 : tt_int_op(8888, OP_EQ, routerconf_find_or_port(opts, AF_INET));
593 :
594 1 : done:
595 1 : or_options_free(opts);
596 1 : config_free_all();
597 1 : }
598 :
599 : #define ROUTER_TEST(name, flags) \
600 : { #name, test_router_ ## name, flags, NULL, NULL }
601 :
602 : struct testcase_t router_tests[] = {
603 : ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
604 : ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
605 : ROUTER_TEST(mark_if_too_old, TT_FORK),
606 : ROUTER_TEST(get_my_family, TT_FORK),
607 : ROUTER_TEST(get_advertised_or_port, TT_FORK),
608 : ROUTER_TEST(get_advertised_or_port_localhost, TT_FORK),
609 : END_OF_TESTCASES
610 : };
|