1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 /* Copyright (c) 2017, isis agora lovecruft */
3 /* See LICENSE for licensing information */
7 * \brief Unittests for code in router.c
10 #define CONFIG_PRIVATE
11 #define CONNECTION_PRIVATE
12 #define ROUTER_PRIVATE
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"
33 #include "core/or/listener_connection_st.h"
35 /* Test suite stuff */
36 #include "test/test.h"
37 #include "test/log_test_helpers.h"
40 rtr_tests_gen_routerinfo(crypto_pk_t
*ident_key
, crypto_pk_t
*tap_key
)
44 routerinfo_t
*mock_routerinfo
;
46 /* Mock the published timestamp, otherwise router_dump_router_to_string()
47 * will poop its pants. */
50 /* We'll need keys, or router_dump_router_to_string() would return NULL. */
51 tor_assert(ident_key
!= NULL
);
52 tor_assert(tap_key
!= NULL
);
54 mock_routerinfo
= tor_malloc_zero(sizeof(routerinfo_t
));
55 mock_routerinfo
->nickname
= tor_strdup("ConlonNancarrow");
56 tor_addr_from_ipv4h(&mock_routerinfo
->ipv4_addr
, 123456789);
57 mock_routerinfo
->ipv4_orport
= 443;
58 mock_routerinfo
->platform
= tor_strdup("unittest");
59 mock_routerinfo
->cache_info
.published_on
= now
;
60 mock_routerinfo
->identity_pkey
= crypto_pk_dup_key(ident_key
);
61 mock_routerinfo
->protocol_list
=
62 tor_strdup("Cons=1-2 Desc=1-2 DirCache=1-2");
63 router_set_rsa_onion_pkey(tap_key
, &mock_routerinfo
->onion_pkey
,
64 &mock_routerinfo
->onion_pkey_len
);
65 mock_routerinfo
->bandwidthrate
= 9001;
66 mock_routerinfo
->bandwidthburst
= 9002;
68 return mock_routerinfo
;
71 /* If no distribution option was set, then check_bridge_distribution_setting()
72 * should have set it to "any". */
74 test_router_dump_router_to_string_no_bridge_distribution_method(void *arg
)
76 const char* needle
= "bridge-distribution-request any";
77 or_options_t
* options
= get_options_mutable();
78 routerinfo_t
* router
= NULL
;
79 curve25519_keypair_t ntor_keypair
;
80 ed25519_keypair_t signing_keypair
;
81 ed25519_keypair_t identity_keypair
;
85 crypto_pk_t
*ident_key
= pk_generate(0);
86 crypto_pk_t
*tap_key
= pk_generate(0);
88 options
->ORPort_set
= 1;
89 options
->BridgeRelay
= 1;
91 /* Generate keys which router_dump_router_to_string() expects to exist. */
92 tt_int_op(0, OP_EQ
, curve25519_keypair_generate(&ntor_keypair
, 0));
93 tt_int_op(0, OP_EQ
, ed25519_keypair_generate(&signing_keypair
, 0));
94 tt_int_op(0, OP_EQ
, ed25519_keypair_generate(&identity_keypair
, 0));
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 router
= rtr_tests_gen_routerinfo(ident_key
, tap_key
);
99 tt_ptr_op(router
, OP_NE
, NULL
);
101 router
->cache_info
.signing_key_cert
=
102 tor_cert_create_ed25519(&identity_keypair
,
103 CERT_TYPE_ID_SIGNING
,
104 &signing_keypair
.pubkey
,
107 CERT_FLAG_INCLUDE_SIGNING_KEY
);
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
112 router
->onion_curve25519_pkey
= &ntor_keypair
.pubkey
;
114 /* Generate our server descriptor and ensure that the substring
115 * "bridge-distribution-request any" occurs somewhere within it. */
116 desc
= router_dump_router_to_string(router
,
121 tt_ptr_op(desc
, OP_NE
, NULL
);
122 found
= strstr(desc
, needle
);
123 tt_ptr_op(found
, OP_NE
, NULL
);
127 router
->onion_curve25519_pkey
= NULL
; // avoid double-free
128 routerinfo_free(router
);
130 crypto_pk_free(ident_key
);
131 crypto_pk_free(tap_key
);
134 static routerinfo_t
*mock_router_get_my_routerinfo_result
= NULL
;
136 static const routerinfo_t
*
137 mock_router_get_my_routerinfo(void)
139 return mock_router_get_my_routerinfo_result
;
143 mock_get_uptime_3h(void)
149 mock_get_uptime_1d(void)
155 mock_rep_hist_bandwidth_assess(void)
161 mock_we_are_not_hibernating(void)
167 mock_we_are_hibernating(void)
173 test_router_check_descriptor_bandwidth_changed(void *arg
)
176 routerinfo_t routerinfo
;
177 memset(&routerinfo
, 0, sizeof(routerinfo
));
178 mock_router_get_my_routerinfo_result
= NULL
;
180 MOCK(we_are_hibernating
, mock_we_are_not_hibernating
);
181 MOCK(router_get_my_routerinfo
, mock_router_get_my_routerinfo
);
182 mock_router_get_my_routerinfo_result
= &routerinfo
;
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 routerinfo
.bandwidthcapacity
= 0;
187 MOCK(get_uptime
, mock_get_uptime_3h
);
188 setup_full_capture_of_logs(LOG_INFO
);
189 check_descriptor_bandwidth_changed(time(NULL
));
190 expect_log_msg_not_containing(
191 "Measured bandwidth has changed; rebuilding descriptor.");
192 teardown_capture_of_logs();
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 routerinfo
.bandwidthcapacity
= 10000;
198 setup_full_capture_of_logs(LOG_INFO
);
199 check_descriptor_bandwidth_changed(time(NULL
));
200 expect_log_msg_containing(
201 "Measured bandwidth has changed; rebuilding descriptor.");
202 teardown_capture_of_logs();
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 */
208 UNMOCK(we_are_hibernating
);
209 MOCK(we_are_hibernating
, mock_we_are_hibernating
);
210 routerinfo
.bandwidthcapacity
= 10000;
211 setup_full_capture_of_logs(LOG_INFO
);
212 check_descriptor_bandwidth_changed(time(NULL
));
213 expect_log_msg_not_containing(
214 "Measured bandwidth has changed; rebuilding descriptor.");
215 teardown_capture_of_logs();
216 UNMOCK(we_are_hibernating
);
217 MOCK(we_are_hibernating
, mock_we_are_not_hibernating
);
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 setup_full_capture_of_logs(LOG_INFO
);
222 check_descriptor_bandwidth_changed(time(NULL
));
223 expect_log_msg_not_containing(
224 "Measured bandwidth has changed; rebuilding descriptor.");
225 teardown_capture_of_logs();
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 MOCK(bwhist_bandwidth_assess
, mock_rep_hist_bandwidth_assess
);
230 setup_full_capture_of_logs(LOG_INFO
);
231 check_descriptor_bandwidth_changed(time(NULL
) + 6*60*60 + 1);
232 expect_log_msg_containing(
233 "Measured bandwidth has changed; rebuilding descriptor.");
235 UNMOCK(bwhist_bandwidth_assess
);
236 teardown_capture_of_logs();
238 /* When uptime is more than 24h */
239 MOCK(get_uptime
, mock_get_uptime_1d
);
240 setup_full_capture_of_logs(LOG_INFO
);
241 check_descriptor_bandwidth_changed(time(NULL
));
242 expect_log_msg_not_containing(
243 "Measured bandwidth has changed; rebuilding descriptor.");
244 teardown_capture_of_logs();
248 UNMOCK(router_get_my_routerinfo
);
249 UNMOCK(we_are_hibernating
);
252 static networkstatus_t
*mock_ns
= NULL
;
253 static networkstatus_t
*
254 mock_networkstatus_get_live_consensus(time_t now
)
260 static routerstatus_t
*mock_rs
= NULL
;
261 static const routerstatus_t
*
262 mock_networkstatus_vote_find_entry(networkstatus_t
*ns
, const char *digest
)
270 test_router_mark_if_too_old(void *arg
)
273 time_t now
= approx_time();
274 MOCK(networkstatus_get_live_consensus
,
275 mock_networkstatus_get_live_consensus
);
276 MOCK(networkstatus_vote_find_entry
, mock_networkstatus_vote_find_entry
);
280 memset(&rs
, 0, sizeof(rs
));
281 memset(&ns
, 0, sizeof(ns
));
283 mock_ns
->valid_after
= now
-3600;
286 // no reason to mark this time.
287 desc_clean_since
= now
-10;
288 desc_dirty_reason
= NULL
;
289 mark_my_descriptor_dirty_if_too_old(now
);
290 tt_i64_op(desc_clean_since
, OP_EQ
, now
-10);
292 // Doesn't appear in consensus? Still don't mark it.
294 mark_my_descriptor_dirty_if_too_old(now
);
295 tt_i64_op(desc_clean_since
, OP_EQ
, now
-10);
298 // No new descriptor in a long time? Mark it.
299 desc_clean_since
= now
- 3600 * 96;
300 mark_my_descriptor_dirty_if_too_old(now
);
301 tt_i64_op(desc_clean_since
, OP_EQ
, 0);
302 tt_str_op(desc_dirty_reason
, OP_EQ
, "time for new descriptor");
304 desc_clean_since
= now
- 10;
305 desc_dirty_reason
= NULL
;
306 mark_my_descriptor_dirty_if_too_old(now
);
307 tt_i64_op(desc_clean_since
, OP_EQ
, now
- 10);
309 // Version in consensus marked as stale? We'll mark it.
310 desc_clean_since
= now
- 2 * 3600;
311 desc_dirty_reason
= NULL
;
312 mock_rs
->is_staledesc
= 1;
313 mark_my_descriptor_dirty_if_too_old(now
);
314 tt_i64_op(desc_clean_since
, OP_EQ
, 0);
315 tt_str_op(desc_dirty_reason
, OP_EQ
,
316 "listed as stale in consensus");
318 // same deal if we're absent from the consensus.
319 desc_clean_since
= now
- 2 * 3600;
320 desc_dirty_reason
= NULL
;
322 mark_my_descriptor_dirty_if_too_old(now
);
323 tt_i64_op(desc_clean_since
, OP_EQ
, 0);
324 tt_str_op(desc_dirty_reason
, OP_EQ
,
325 "not listed in consensus");
328 UNMOCK(networkstatus_get_live_consensus
);
329 UNMOCK(networkstatus_vote_find_entry
);
332 static node_t fake_node
;
333 static const node_t
*
334 mock_node_get_by_nickname(const char *name
, unsigned flags
)
337 if (!strcasecmp(name
, "crumpet"))
344 test_router_get_my_family(void *arg
)
347 or_options_t
*options
= options_new();
348 smartlist_t
*sl
= NULL
;
350 // Overwrite the result of router_get_my_identity_digest(). This
351 // happens to be okay, but only for testing.
352 set_server_identity_key_digest_testing(
353 (const uint8_t*)"holeinthebottomofthe");
355 setup_capture_of_logs(LOG_WARN
);
357 // No family listed -- so there's no list.
358 sl
= get_my_declared_family(options
);
359 tt_ptr_op(sl
, OP_EQ
, NULL
);
360 expect_no_log_entry();
362 #define CLEAR() do { \
364 SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); \
365 smartlist_free(sl); \
368 mock_clean_saved_logs(); \
371 // Add a single nice friendly hex member. This should be enough
372 // to have our own ID added.
373 tt_ptr_op(options
->MyFamily
, OP_EQ
, NULL
);
374 config_line_append(&options
->MyFamily
, "MyFamily",
375 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
377 sl
= get_my_declared_family(options
);
378 tt_ptr_op(sl
, OP_NE
, NULL
);
379 tt_int_op(smartlist_len(sl
), OP_EQ
, 2);
380 join
= smartlist_join_strings(sl
, " ", 0, NULL
);
381 tt_str_op(join
, OP_EQ
,
382 "$686F6C65696E746865626F74746F6D6F66746865 "
383 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
384 expect_no_log_entry();
387 // Add a hex member with a ~. The ~ part should get removed.
388 config_line_append(&options
->MyFamily
, "MyFamily",
389 "$0123456789abcdef0123456789abcdef01234567~Muffin");
390 sl
= get_my_declared_family(options
);
391 tt_ptr_op(sl
, OP_NE
, NULL
);
392 tt_int_op(smartlist_len(sl
), OP_EQ
, 3);
393 join
= smartlist_join_strings(sl
, " ", 0, NULL
);
394 tt_str_op(join
, OP_EQ
,
395 "$0123456789ABCDEF0123456789ABCDEF01234567 "
396 "$686F6C65696E746865626F74746F6D6F66746865 "
397 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
398 expect_no_log_entry();
401 // Nickname lookup will fail, so a nickname will appear verbatim.
402 config_line_append(&options
->MyFamily
, "MyFamily",
404 sl
= get_my_declared_family(options
);
405 tt_ptr_op(sl
, OP_NE
, NULL
);
406 tt_int_op(smartlist_len(sl
), OP_EQ
, 4);
407 join
= smartlist_join_strings(sl
, " ", 0, NULL
);
408 tt_str_op(join
, OP_EQ
,
409 "$0123456789ABCDEF0123456789ABCDEF01234567 "
410 "$686F6C65696E746865626F74746F6D6F66746865 "
411 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
413 expect_single_log_msg_containing(
414 "There is a router named \"BAGEL\" in my declared family, but "
415 "I have no descriptor for it.");
418 // A bogus digest should fail entirely.
419 config_line_append(&options
->MyFamily
, "MyFamily",
421 sl
= get_my_declared_family(options
);
422 tt_ptr_op(sl
, OP_NE
, NULL
);
423 tt_int_op(smartlist_len(sl
), OP_EQ
, 4);
424 join
= smartlist_join_strings(sl
, " ", 0, NULL
);
425 tt_str_op(join
, OP_EQ
,
426 "$0123456789ABCDEF0123456789ABCDEF01234567 "
427 "$686F6C65696E746865626F74746F6D6F66746865 "
428 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
430 // "BAGEL" is still there, but it won't make a warning, because we already
432 expect_single_log_msg_containing(
433 "There is a router named \"$painauchocolat\" in my declared "
434 "family, but that isn't a legal digest or nickname. Skipping it.");
437 // Let's introduce a node we can look up by nickname
438 memset(&fake_node
, 0, sizeof(fake_node
));
439 memcpy(fake_node
.identity
, "whydoyouasknonononon", DIGEST_LEN
);
440 MOCK(node_get_by_nickname
, mock_node_get_by_nickname
);
442 config_line_append(&options
->MyFamily
, "MyFamily",
444 sl
= get_my_declared_family(options
);
445 tt_ptr_op(sl
, OP_NE
, NULL
);
446 tt_int_op(smartlist_len(sl
), OP_EQ
, 5);
447 join
= smartlist_join_strings(sl
, " ", 0, NULL
);
448 tt_str_op(join
, OP_EQ
,
449 "$0123456789ABCDEF0123456789ABCDEF01234567 "
450 "$686F6C65696E746865626F74746F6D6F66746865 "
451 "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E "
452 "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
454 // "BAGEL" is still there, but it won't make a warning, because we already
455 // warned about it. Some with "$painauchocolat".
456 expect_single_log_msg_containing(
457 "There is a router named \"CRUmpeT\" in my declared "
458 "family, but it wasn't listed by digest. Please consider saying "
459 "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E instead, if that's "
462 UNMOCK(node_get_by_nickname
);
464 // Try a singleton list containing only us: It should give us NULL.
465 config_free_lines(options
->MyFamily
);
466 config_line_append(&options
->MyFamily
, "MyFamily",
467 "$686F6C65696E746865626F74746F6D6F66746865");
468 sl
= get_my_declared_family(options
);
469 tt_ptr_op(sl
, OP_EQ
, NULL
);
470 expect_no_log_entry();
473 or_options_free(options
);
474 teardown_capture_of_logs();
476 UNMOCK(node_get_by_nickname
);
481 static smartlist_t
*fake_connection_array
= NULL
;
483 mock_get_connection_array(void)
485 return fake_connection_array
;
489 test_router_get_advertised_or_port(void *arg
)
494 or_options_t
*opts
= options_new();
495 listener_connection_t
*listener
= NULL
;
496 tor_addr_port_t ipv6
;
498 // Test one failing case of routerconf_find_ipv6_or_ap().
499 routerconf_find_ipv6_or_ap(opts
, &ipv6
);
500 tt_str_op(fmt_addrport(&ipv6
.addr
, ipv6
.port
), OP_EQ
, "[::]:0");
502 // And one failing case of routerconf_find_or_port().
503 tt_int_op(0, OP_EQ
, routerconf_find_or_port(opts
, AF_INET
));
505 // Set up a couple of configured ports.
506 config_line_append(&opts
->ORPort_lines
, "ORPort", "[1234::5678]:auto");
507 config_line_append(&opts
->ORPort_lines
, "ORPort", "5.6.7.8:9999");
508 r
= parse_ports(opts
, 0, &msg
, &n
, &w
);
511 // There are no listeners, so the "auto" case will turn up no results.
512 tt_int_op(0, OP_EQ
, routerconf_find_or_port(opts
, AF_INET6
));
513 routerconf_find_ipv6_or_ap(opts
, &ipv6
);
514 tt_str_op(fmt_addrport(&ipv6
.addr
, ipv6
.port
), OP_EQ
, "[::]:0");
516 // This will return the matching value from the configured port.
517 tt_int_op(9999, OP_EQ
, routerconf_find_or_port(opts
, AF_INET
));
519 // Now set up a dummy listener.
520 MOCK(get_connection_array
, mock_get_connection_array
);
521 fake_connection_array
= smartlist_new();
522 listener
= listener_connection_new(CONN_TYPE_OR_LISTENER
, AF_INET6
);
523 TO_CONN(listener
)->port
= 54321;
524 smartlist_add(fake_connection_array
, TO_CONN(listener
));
526 // We should get a port this time.
527 tt_int_op(54321, OP_EQ
, routerconf_find_or_port(opts
, AF_INET6
));
529 // Test one succeeding case of routerconf_find_ipv6_or_ap().
530 routerconf_find_ipv6_or_ap(opts
, &ipv6
);
531 tt_str_op(fmt_addrport(&ipv6
.addr
, ipv6
.port
), OP_EQ
,
532 "[1234::5678]:54321");
534 // This will return the matching value from the configured port.
535 tt_int_op(9999, OP_EQ
, routerconf_find_or_port(opts
, AF_INET
));
538 or_options_free(opts
);
540 smartlist_free(fake_connection_array
);
541 connection_free_minimal(TO_CONN(listener
));
542 UNMOCK(get_connection_array
);
546 test_router_get_advertised_or_port_localhost(void *arg
)
551 or_options_t
*opts
= options_new();
552 tor_addr_port_t ipv6
;
554 // Set up a couple of configured ports on localhost.
555 config_line_append(&opts
->ORPort_lines
, "ORPort", "[::1]:9999");
556 config_line_append(&opts
->ORPort_lines
, "ORPort", "127.0.0.1:8888");
557 r
= parse_ports(opts
, 0, &msg
, &n
, &w
);
560 // We should refuse to advertise them, since we have default dirauths.
561 routerconf_find_ipv6_or_ap(opts
, &ipv6
);
562 tt_str_op(fmt_addrport(&ipv6
.addr
, ipv6
.port
), OP_EQ
, "[::]:0");
563 // But the lower-level function should still report the correct value
564 tt_int_op(9999, OP_EQ
, routerconf_find_or_port(opts
, AF_INET6
));
566 // The IPv4 checks are done in resolve_my_address(), which doesn't use
567 // ORPorts so we can't test them here. (See #33681.) Both these lower-level
568 // functions should still report the correct value.
569 tt_int_op(8888, OP_EQ
, routerconf_find_or_port(opts
, AF_INET
));
571 // Now try with a fake authority set up.
572 config_line_append(&opts
->DirAuthorities
, "DirAuthority",
574 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
576 tt_int_op(9999, OP_EQ
, routerconf_find_or_port(opts
, AF_INET6
));
577 routerconf_find_ipv6_or_ap(opts
, &ipv6
);
578 tt_str_op(fmt_addrport(&ipv6
.addr
, ipv6
.port
), OP_EQ
, "[::1]:9999");
580 tt_int_op(8888, OP_EQ
, routerconf_find_or_port(opts
, AF_INET
));
583 or_options_free(opts
);
587 #define ROUTER_TEST(name, flags) \
588 { #name, test_router_ ## name, flags, NULL, NULL }
590 struct testcase_t router_tests
[] = {
591 ROUTER_TEST(check_descriptor_bandwidth_changed
, TT_FORK
),
592 ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method
, TT_FORK
),
593 ROUTER_TEST(mark_if_too_old
, TT_FORK
),
594 ROUTER_TEST(get_my_family
, TT_FORK
),
595 ROUTER_TEST(get_advertised_or_port
, TT_FORK
),
596 ROUTER_TEST(get_advertised_or_port_localhost
, TT_FORK
),