test_routerlist.c (27327B)
1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #include "orconfig.h" 5 #include <math.h> 6 #include <time.h> 7 8 #define CONNECTION_PRIVATE 9 #define DIRCLIENT_PRIVATE 10 #define DIRVOTE_PRIVATE 11 #define ENTRYNODES_PRIVATE 12 #define HIBERNATE_PRIVATE 13 #define NETWORKSTATUS_PRIVATE 14 #define ROUTERLIST_PRIVATE 15 #define NODE_SELECT_PRIVATE 16 #define TOR_UNIT_TESTING 17 #include "core/or/or.h" 18 #include "app/config/config.h" 19 #include "core/mainloop/connection.h" 20 #include "feature/control/control.h" 21 #include "lib/crypt_ops/crypto_rand.h" 22 #include "feature/dircommon/directory.h" 23 #include "feature/dirclient/dirclient.h" 24 #include "feature/dirauth/dirvote.h" 25 #include "feature/client/entrynodes.h" 26 #include "feature/hibernate/hibernate.h" 27 #include "feature/nodelist/microdesc.h" 28 #include "feature/nodelist/networkstatus.h" 29 #include "feature/nodelist/nodelist.h" 30 #include "core/or/policies.h" 31 #include "feature/relay/router.h" 32 #include "feature/nodelist/authcert.h" 33 #include "feature/nodelist/node_select.h" 34 #include "feature/nodelist/routerlist.h" 35 #include "feature/nodelist/routerset.h" 36 #include "feature/dirparse/authcert_parse.h" 37 #include "feature/dirparse/ns_parse.h" 38 #include "feature/dirauth/shared_random.h" 39 #include "app/config/statefile.h" 40 41 #include "feature/nodelist/authority_cert_st.h" 42 #include "feature/dircommon/dir_connection_st.h" 43 #include "feature/nodelist/networkstatus_st.h" 44 #include "feature/nodelist/node_st.h" 45 #include "app/config/or_state_st.h" 46 #include "feature/nodelist/routerstatus_st.h" 47 48 #include "lib/encoding/confline.h" 49 #include "lib/buf/buffers.h" 50 51 #include "test/test.h" 52 #include "test/test_dir_common.h" 53 #include "test/log_test_helpers.h" 54 55 static authority_cert_t *mock_cert; 56 57 static authority_cert_t * 58 get_my_v3_authority_cert_m(void) 59 { 60 tor_assert(mock_cert); 61 return mock_cert; 62 } 63 64 /* 4 digests + 3 sep + pre + post + NULL */ 65 static char output[4*BASE64_DIGEST256_LEN+3+2+2+1]; 66 67 static void 68 mock_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, 69 const char *resource, int pds_flags, 70 download_want_authority_t want_authority) 71 { 72 (void)dir_purpose; 73 (void)router_purpose; 74 (void)pds_flags; 75 (void)want_authority; 76 tt_assert(resource); 77 strlcpy(output, resource, sizeof(output)); 78 done: 79 ; 80 } 81 82 static void 83 test_routerlist_initiate_descriptor_downloads(void *arg) 84 { 85 const char *prose = "unhurried and wise, we perceive."; 86 smartlist_t *digests = smartlist_new(); 87 (void)arg; 88 89 for (int i = 0; i < 20; i++) { 90 smartlist_add(digests, (char*)prose); 91 } 92 93 MOCK(directory_get_from_dirserver, mock_get_from_dirserver); 94 initiate_descriptor_downloads(NULL, DIR_PURPOSE_FETCH_MICRODESC, 95 digests, 3, 7, 0); 96 UNMOCK(directory_get_from_dirserver); 97 98 tt_str_op(output, OP_EQ, "d/" 99 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-" 100 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-" 101 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-" 102 "dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4" 103 ".z"); 104 105 done: 106 smartlist_free(digests); 107 } 108 109 static int count = 0; 110 111 static void 112 mock_initiate_descriptor_downloads(const routerstatus_t *source, 113 int purpose, smartlist_t *digests, 114 int lo, int hi, int pds_flags) 115 { 116 (void)source; 117 (void)purpose; 118 (void)digests; 119 (void)pds_flags; 120 (void)hi; 121 (void)lo; 122 count += 1; 123 } 124 125 static void 126 test_routerlist_launch_descriptor_downloads(void *arg) 127 { 128 smartlist_t *downloadable = smartlist_new(); 129 time_t now = time(NULL); 130 char *cp; 131 (void)arg; 132 133 for (int i = 0; i < 100; i++) { 134 cp = tor_malloc(DIGEST256_LEN); 135 tt_assert(cp); 136 crypto_rand(cp, DIGEST256_LEN); 137 smartlist_add(downloadable, cp); 138 } 139 140 MOCK(initiate_descriptor_downloads, mock_initiate_descriptor_downloads); 141 launch_descriptor_downloads(DIR_PURPOSE_FETCH_MICRODESC, downloadable, 142 NULL, now); 143 tt_int_op(3, OP_EQ, count); 144 UNMOCK(initiate_descriptor_downloads); 145 146 done: 147 SMARTLIST_FOREACH(downloadable, char *, cp1, tor_free(cp1)); 148 smartlist_free(downloadable); 149 } 150 151 static void 152 construct_consensus(char **consensus_text_md, time_t now) 153 { 154 networkstatus_t *vote = NULL; 155 networkstatus_t *v1 = NULL, *v2 = NULL, *v3 = NULL; 156 networkstatus_voter_info_t *voter = NULL; 157 authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL; 158 crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL; 159 crypto_pk_t *sign_skey_leg=NULL; 160 smartlist_t *votes = NULL; 161 int n_vrs; 162 163 tt_assert(!dir_common_authority_pk_init(&cert1, &cert2, &cert3, 164 &sign_skey_1, &sign_skey_2, 165 &sign_skey_3)); 166 sign_skey_leg = pk_generate(4); 167 168 dir_common_construct_vote_1(&vote, cert1, sign_skey_1, 169 &dir_common_gen_routerstatus_for_v3ns, 170 &v1, &n_vrs, now, 1); 171 networkstatus_vote_free(vote); 172 tt_assert(v1); 173 tt_int_op(n_vrs, OP_EQ, 4); 174 tt_int_op(smartlist_len(v1->routerstatus_list), OP_EQ, 4); 175 176 dir_common_construct_vote_2(&vote, cert2, sign_skey_2, 177 &dir_common_gen_routerstatus_for_v3ns, 178 &v2, &n_vrs, now, 1); 179 networkstatus_vote_free(vote); 180 tt_assert(v2); 181 tt_int_op(n_vrs, OP_EQ, 4); 182 tt_int_op(smartlist_len(v2->routerstatus_list), OP_EQ, 4); 183 184 dir_common_construct_vote_3(&vote, cert3, sign_skey_3, 185 &dir_common_gen_routerstatus_for_v3ns, 186 &v3, &n_vrs, now, 1); 187 188 tt_assert(v3); 189 tt_int_op(n_vrs, OP_EQ, 4); 190 tt_int_op(smartlist_len(v3->routerstatus_list), OP_EQ, 4); 191 networkstatus_vote_free(vote); 192 votes = smartlist_new(); 193 smartlist_add(votes, v1); 194 smartlist_add(votes, v2); 195 smartlist_add(votes, v3); 196 197 *consensus_text_md = networkstatus_compute_consensus(votes, 3, 198 cert1->identity_key, 199 sign_skey_1, 200 "AAAAAAAAAAAAAAAAAAAA", 201 sign_skey_leg, 202 FLAV_MICRODESC); 203 204 tt_assert(*consensus_text_md); 205 206 done: 207 tor_free(voter); 208 networkstatus_vote_free(v1); 209 networkstatus_vote_free(v2); 210 networkstatus_vote_free(v3); 211 smartlist_free(votes); 212 authority_cert_free(cert1); 213 authority_cert_free(cert2); 214 authority_cert_free(cert3); 215 crypto_pk_free(sign_skey_1); 216 crypto_pk_free(sign_skey_2); 217 crypto_pk_free(sign_skey_3); 218 crypto_pk_free(sign_skey_leg); 219 } 220 221 static int mock_usable_consensus_flavor_value = FLAV_NS; 222 223 static int 224 mock_usable_consensus_flavor(void) 225 { 226 return mock_usable_consensus_flavor_value; 227 } 228 229 static void 230 test_router_pick_directory_server_impl(void *arg) 231 { 232 (void)arg; 233 234 networkstatus_t *con_md = NULL; 235 char *consensus_text_md = NULL; 236 int flags = PDS_IGNORE_FASCISTFIREWALL|PDS_RETRY_IF_NO_SERVERS; 237 or_options_t *options = get_options_mutable(); 238 const routerstatus_t *rs = NULL; 239 options->UseMicrodescriptors = 1; 240 char *router1_id = NULL, *router2_id = NULL, *router3_id = NULL; 241 node_t *node_router1 = NULL, *node_router2 = NULL, *node_router3 = NULL; 242 config_line_t *policy_line = NULL; 243 time_t now = time(NULL); 244 int tmp_dirport1, tmp_dirport3; 245 246 (void)arg; 247 248 MOCK(usable_consensus_flavor, mock_usable_consensus_flavor); 249 250 /* With no consensus, we must be bootstrapping, regardless of time or flavor 251 */ 252 mock_usable_consensus_flavor_value = FLAV_NS; 253 tt_assert(networkstatus_consensus_is_bootstrapping(now)); 254 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2000)); 255 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2*24*60*60)); 256 tt_assert(networkstatus_consensus_is_bootstrapping(now - 2*24*60*60)); 257 258 mock_usable_consensus_flavor_value = FLAV_MICRODESC; 259 tt_assert(networkstatus_consensus_is_bootstrapping(now)); 260 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2000)); 261 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2*24*60*60)); 262 tt_assert(networkstatus_consensus_is_bootstrapping(now - 2*24*60*60)); 263 264 /* Init SR subsystem. */ 265 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); 266 mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, 267 strlen(AUTHORITY_CERT_1), 268 NULL); 269 sr_init(0); 270 UNMOCK(get_my_v3_authority_cert); 271 272 /* No consensus available, fail early */ 273 rs = router_pick_directory_server_impl(V3_DIRINFO, (const int) 0, NULL); 274 tt_ptr_op(rs, OP_EQ, NULL); 275 276 construct_consensus(&consensus_text_md, now); 277 tt_assert(consensus_text_md); 278 con_md = networkstatus_parse_vote_from_string(consensus_text_md, 279 strlen(consensus_text_md), 280 NULL, 281 NS_TYPE_CONSENSUS); 282 tt_assert(con_md); 283 tt_int_op(con_md->flavor,OP_EQ, FLAV_MICRODESC); 284 tt_assert(con_md->routerstatus_list); 285 tt_int_op(smartlist_len(con_md->routerstatus_list), OP_EQ, 3); 286 tt_assert(!networkstatus_set_current_consensus_from_ns(con_md, 287 "microdesc")); 288 289 /* If the consensus time or flavor doesn't match, we are still 290 * bootstrapping */ 291 mock_usable_consensus_flavor_value = FLAV_NS; 292 tt_assert(networkstatus_consensus_is_bootstrapping(now)); 293 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2000)); 294 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2*24*60*60)); 295 tt_assert(networkstatus_consensus_is_bootstrapping(now - 2*24*60*60)); 296 297 /* With a valid consensus for the current time and flavor, we stop 298 * bootstrapping, even if we have no certificates */ 299 mock_usable_consensus_flavor_value = FLAV_MICRODESC; 300 tt_assert(!networkstatus_consensus_is_bootstrapping(now + 2000)); 301 tt_assert(!networkstatus_consensus_is_bootstrapping(con_md->valid_after)); 302 tt_assert(!networkstatus_consensus_is_bootstrapping(con_md->valid_until)); 303 tt_assert(!networkstatus_consensus_is_bootstrapping(con_md->valid_until 304 + 24*60*60)); 305 /* These times are outside the test validity period */ 306 tt_assert(networkstatus_consensus_is_bootstrapping(now + 2*24*60*60)); 307 tt_assert(networkstatus_consensus_is_bootstrapping(now - 2*24*60*60)); 308 309 nodelist_set_consensus(con_md); 310 nodelist_assert_ok(); 311 312 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 313 /* We should not fail now we have a consensus and routerstatus_list 314 * and nodelist are populated. */ 315 tt_ptr_op(rs, OP_NE, NULL); 316 317 /* Manipulate the nodes so we get the dir server we expect */ 318 router1_id = tor_malloc(DIGEST_LEN); 319 memset(router1_id, TEST_DIR_ROUTER_ID_1, DIGEST_LEN); 320 router2_id = tor_malloc(DIGEST_LEN); 321 memset(router2_id, TEST_DIR_ROUTER_ID_2, DIGEST_LEN); 322 router3_id = tor_malloc(DIGEST_LEN); 323 memset(router3_id, TEST_DIR_ROUTER_ID_3, DIGEST_LEN); 324 325 node_router1 = node_get_mutable_by_id(router1_id); 326 node_router2 = node_get_mutable_by_id(router2_id); 327 node_router3 = node_get_mutable_by_id(router3_id); 328 329 node_router1->is_possible_guard = 1; 330 331 node_router1->is_running = 0; 332 node_router3->is_running = 0; 333 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 334 tt_ptr_op(rs, OP_NE, NULL); 335 tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN)); 336 rs = NULL; 337 node_router1->is_running = 1; 338 node_router3->is_running = 1; 339 340 node_router1->rs->is_v2_dir = 0; 341 node_router3->rs->is_v2_dir = 0; 342 tmp_dirport1 = node_router1->rs->ipv4_dirport; 343 tmp_dirport3 = node_router3->rs->ipv4_dirport; 344 node_router1->rs->ipv4_dirport = 0; 345 node_router3->rs->ipv4_dirport = 0; 346 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 347 tt_ptr_op(rs, OP_NE, NULL); 348 tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN)); 349 rs = NULL; 350 node_router1->rs->is_v2_dir = 1; 351 node_router3->rs->is_v2_dir = 1; 352 node_router1->rs->ipv4_dirport = tmp_dirport1; 353 node_router3->rs->ipv4_dirport = tmp_dirport3; 354 355 node_router1->is_valid = 0; 356 node_router3->is_valid = 0; 357 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 358 tt_ptr_op(rs, OP_NE, NULL); 359 tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN)); 360 rs = NULL; 361 node_router1->is_valid = 1; 362 node_router3->is_valid = 1; 363 364 /* Manipulate overloaded */ 365 366 node_router2->rs->last_dir_503_at = now; 367 node_router3->rs->last_dir_503_at = now; 368 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 369 tt_ptr_op(rs, OP_NE, NULL); 370 tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN)); 371 node_router2->rs->last_dir_503_at = 0; 372 node_router3->rs->last_dir_503_at = 0; 373 374 /* Set a Fascist firewall */ 375 flags &= ~ PDS_IGNORE_FASCISTFIREWALL; 376 policy_line = tor_malloc_zero(sizeof(config_line_t)); 377 policy_line->key = tor_strdup("ReachableORAddresses"); 378 policy_line->value = tor_strdup("accept *:442, reject *:*"); 379 options->ReachableORAddresses = policy_line; 380 policies_parse_from_options(options); 381 382 node_router1->rs->ipv4_orport = 444; 383 node_router2->rs->ipv4_orport = 443; 384 node_router3->rs->ipv4_orport = 442; 385 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 386 tt_ptr_op(rs, OP_NE, NULL); 387 tt_assert(tor_memeq(rs->identity_digest, router3_id, DIGEST_LEN)); 388 node_router1->rs->ipv4_orport = 442; 389 node_router2->rs->ipv4_orport = 443; 390 node_router3->rs->ipv4_orport = 444; 391 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 392 tt_ptr_op(rs, OP_NE, NULL); 393 tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN)); 394 395 /* Fascist firewall and overloaded */ 396 node_router1->rs->ipv4_orport = 442; 397 node_router2->rs->ipv4_orport = 443; 398 node_router3->rs->ipv4_orport = 442; 399 node_router3->rs->last_dir_503_at = now; 400 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 401 tt_ptr_op(rs, OP_NE, NULL); 402 tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN)); 403 node_router3->rs->last_dir_503_at = 0; 404 405 /* Fascists against OR and Dir */ 406 policy_line = tor_malloc_zero(sizeof(config_line_t)); 407 policy_line->key = tor_strdup("ReachableAddresses"); 408 policy_line->value = tor_strdup("accept *:80, reject *:*"); 409 options->ReachableDirAddresses = policy_line; 410 policies_parse_from_options(options); 411 node_router1->rs->ipv4_orport = 442; 412 node_router2->rs->ipv4_orport = 441; 413 node_router3->rs->ipv4_orport = 443; 414 node_router1->rs->ipv4_dirport = 80; 415 node_router2->rs->ipv4_dirport = 80; 416 node_router3->rs->ipv4_dirport = 81; 417 node_router1->rs->last_dir_503_at = now; 418 rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL); 419 tt_ptr_op(rs, OP_NE, NULL); 420 tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN)); 421 node_router1->rs->last_dir_503_at = 0; 422 423 done: 424 UNMOCK(usable_consensus_flavor); 425 426 if (router1_id) 427 tor_free(router1_id); 428 if (router2_id) 429 tor_free(router2_id); 430 if (router3_id) 431 tor_free(router3_id); 432 if (options->ReachableORAddresses || 433 options->ReachableDirAddresses) 434 policies_free_all(); 435 tor_free(consensus_text_md); 436 networkstatus_vote_free(con_md); 437 } 438 439 static or_state_t *dummy_state = NULL; 440 static or_state_t * 441 get_or_state_replacement(void) 442 { 443 return dummy_state; 444 } 445 446 static void 447 mock_directory_initiate_request(directory_request_t *req) 448 { 449 (void)req; 450 return; 451 } 452 453 static circuit_guard_state_t * 454 mock_circuit_guard_state_new(entry_guard_t *guard, unsigned state, 455 entry_guard_restriction_t *rst) 456 { 457 (void) guard; 458 (void) state; 459 (void) rst; 460 return NULL; 461 } 462 463 /** Test that we will use our directory guards to fetch mds even if we don't 464 * have any dirinfo (tests bug #23862). */ 465 static void 466 test_directory_guard_fetch_with_no_dirinfo(void *arg) 467 { 468 int retval; 469 char *consensus_text_md = NULL; 470 or_options_t *options = get_options_mutable(); 471 time_t now = time(NULL); 472 473 (void) arg; 474 475 hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE); 476 477 /* Initialize the SRV subsystem */ 478 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); 479 mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, 480 strlen(AUTHORITY_CERT_1), 481 NULL); 482 sr_init(0); 483 UNMOCK(get_my_v3_authority_cert); 484 485 /* Initialize the entry node configuration from the ticket */ 486 options->UseEntryGuards = 1; 487 options->StrictNodes = 1; 488 get_options_mutable()->EntryNodes = routerset_new(); 489 routerset_parse(get_options_mutable()->EntryNodes, 490 "2121212121212121212121212121212121212121", "foo"); 491 492 /* Mock some functions */ 493 dummy_state = tor_malloc_zero(sizeof(or_state_t)); 494 MOCK(get_or_state, get_or_state_replacement); 495 MOCK(directory_initiate_request, mock_directory_initiate_request); 496 /* we need to mock this one to avoid memleaks */ 497 MOCK(circuit_guard_state_new, mock_circuit_guard_state_new); 498 499 /* Call guards_update_all() to simulate loading our state file (see 500 * entry_guards_load_guards_from_state() and ticket #23989). */ 501 guards_update_all(); 502 503 /* Test logic: Simulate the arrival of a new consensus when we have no 504 * dirinfo at all. Tor will need to fetch the mds from the consensus. Make 505 * sure that Tor will use the specified entry guard instead of relying on the 506 * fallback directories. */ 507 508 /* Fixup the dirconn that will deliver the consensus */ 509 dir_connection_t *conn = dir_connection_new(AF_INET); 510 tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001); 511 conn->base_.port = 8800; 512 TO_CONN(conn)->address = tor_strdup("127.0.0.1"); 513 conn->base_.purpose = DIR_PURPOSE_FETCH_CONSENSUS; 514 conn->requested_resource = tor_strdup("ns"); 515 516 /* Construct a consensus */ 517 construct_consensus(&consensus_text_md, now); 518 tt_assert(consensus_text_md); 519 520 /* Place the consensus in the dirconn */ 521 response_handler_args_t args; 522 memset(&args, 0, sizeof(response_handler_args_t)); 523 args.status_code = 200; 524 args.body = consensus_text_md; 525 args.body_len = strlen(consensus_text_md); 526 527 /* Update approx time so that the consensus is considered live */ 528 update_approx_time(now+1010); 529 530 setup_capture_of_logs(LOG_DEBUG); 531 532 /* Now handle the consensus */ 533 retval = handle_response_fetch_consensus(conn, &args); 534 tt_int_op(retval, OP_EQ, 0); 535 536 /* Make sure that our primary guard was chosen */ 537 expect_log_msg_containing("Selected primary guard router3"); 538 539 done: 540 tor_free(consensus_text_md); 541 tor_free(dummy_state); 542 connection_free_minimal(TO_CONN(conn)); 543 entry_guards_free_all(); 544 teardown_capture_of_logs(); 545 } 546 547 static connection_t *mocked_connection = NULL; 548 549 /* Mock connection_get_by_type_addr_port_purpose by returning 550 * mocked_connection. */ 551 static connection_t * 552 mock_connection_get_by_type_addr_port_purpose(int type, 553 const tor_addr_t *addr, 554 uint16_t port, int purpose) 555 { 556 (void)type; 557 (void)addr; 558 (void)port; 559 (void)purpose; 560 561 return mocked_connection; 562 } 563 564 #define TEST_ADDR_STR "127.0.0.1" 565 #define TEST_DIR_PORT 12345 566 567 static void 568 test_routerlist_router_is_already_dir_fetching(void *arg) 569 { 570 (void)arg; 571 tor_addr_port_t test_ap, null_addr_ap, zero_port_ap; 572 573 /* Setup */ 574 tor_addr_parse(&test_ap.addr, TEST_ADDR_STR); 575 test_ap.port = TEST_DIR_PORT; 576 tor_addr_make_null(&null_addr_ap.addr, AF_INET6); 577 null_addr_ap.port = TEST_DIR_PORT; 578 tor_addr_parse(&zero_port_ap.addr, TEST_ADDR_STR); 579 zero_port_ap.port = 0; 580 MOCK(connection_get_by_type_addr_port_purpose, 581 mock_connection_get_by_type_addr_port_purpose); 582 583 /* Test that we never get 1 from a NULL connection */ 584 mocked_connection = NULL; 585 tt_int_op(router_is_already_dir_fetching(&test_ap, 1, 1), OP_EQ, 0); 586 tt_int_op(router_is_already_dir_fetching(&test_ap, 1, 0), OP_EQ, 0); 587 tt_int_op(router_is_already_dir_fetching(&test_ap, 0, 1), OP_EQ, 0); 588 /* We always expect 0 in these cases */ 589 tt_int_op(router_is_already_dir_fetching(&test_ap, 0, 0), OP_EQ, 0); 590 tt_int_op(router_is_already_dir_fetching(NULL, 1, 1), OP_EQ, 0); 591 tt_int_op(router_is_already_dir_fetching(&null_addr_ap, 1, 1), OP_EQ, 0); 592 tt_int_op(router_is_already_dir_fetching(&zero_port_ap, 1, 1), OP_EQ, 0); 593 594 /* Test that we get 1 with a connection in the appropriate circumstances */ 595 mocked_connection = connection_new(CONN_TYPE_DIR, AF_INET); 596 tt_int_op(router_is_already_dir_fetching(&test_ap, 1, 1), OP_EQ, 1); 597 tt_int_op(router_is_already_dir_fetching(&test_ap, 1, 0), OP_EQ, 1); 598 tt_int_op(router_is_already_dir_fetching(&test_ap, 0, 1), OP_EQ, 1); 599 600 /* Test that we get 0 even with a connection in the appropriate 601 * circumstances */ 602 tt_int_op(router_is_already_dir_fetching(&test_ap, 0, 0), OP_EQ, 0); 603 tt_int_op(router_is_already_dir_fetching(NULL, 1, 1), OP_EQ, 0); 604 tt_int_op(router_is_already_dir_fetching(&null_addr_ap, 1, 1), OP_EQ, 0); 605 tt_int_op(router_is_already_dir_fetching(&zero_port_ap, 1, 1), OP_EQ, 0); 606 607 done: 608 /* If a connection is never set up, connection_free chokes on it. */ 609 if (mocked_connection) { 610 buf_free(mocked_connection->inbuf); 611 buf_free(mocked_connection->outbuf); 612 } 613 tor_free(mocked_connection); 614 UNMOCK(connection_get_by_type_addr_port_purpose); 615 } 616 617 #undef TEST_ADDR_STR 618 #undef TEST_DIR_PORT 619 620 static long mock_apparent_skew = 0; 621 622 /** Store apparent_skew and assert that the other arguments are as 623 * expected. */ 624 static void 625 mock_clock_skew_warning(const connection_t *conn, long apparent_skew, 626 int trusted, log_domain_mask_t domain, 627 const char *received, const char *source) 628 { 629 (void)conn; 630 mock_apparent_skew = apparent_skew; 631 tt_int_op(trusted, OP_EQ, 1); 632 tt_i64_op(domain, OP_EQ, LD_GENERAL); 633 tt_str_op(received, OP_EQ, "microdesc flavor consensus"); 634 tt_str_op(source, OP_EQ, "CONSENSUS"); 635 done: 636 ; 637 } 638 639 /** Do common setup for test_timely_consensus() and 640 * test_early_consensus(). Call networkstatus_set_current_consensus() 641 * on a constructed consensus and with an appropriately-modified 642 * approx_time. Callers expect presence or absence of appropriate log 643 * messages and control events. */ 644 static int 645 test_skew_common(void *arg, time_t now, unsigned long *offset) 646 { 647 char *consensus = NULL; 648 int retval = 0; 649 650 *offset = strtoul(arg, NULL, 10); 651 652 /* Initialize the SRV subsystem */ 653 MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); 654 mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, 655 strlen(AUTHORITY_CERT_1), 656 NULL); 657 sr_init(0); 658 UNMOCK(get_my_v3_authority_cert); 659 660 construct_consensus(&consensus, now); 661 tt_assert(consensus); 662 663 update_approx_time(now + *offset); 664 665 mock_apparent_skew = 0; 666 /* Caller will call UNMOCK() */ 667 MOCK(clock_skew_warning, mock_clock_skew_warning); 668 /* Caller will call teardown_capture_of_logs() */ 669 setup_capture_of_logs(LOG_WARN); 670 retval = networkstatus_set_current_consensus(consensus, strlen(consensus), 671 "microdesc", 0, 672 NULL); 673 674 done: 675 tor_free(consensus); 676 return retval; 677 } 678 679 /** Test non-early consensus */ 680 static void 681 test_timely_consensus(void *arg) 682 { 683 time_t now = time(NULL); 684 unsigned long offset = 0; 685 int retval = 0; 686 687 retval = test_skew_common(arg, now, &offset); 688 (void)offset; 689 expect_no_log_msg_containing("behind the time published in the consensus"); 690 tt_int_op(retval, OP_EQ, 0); 691 tt_int_op(mock_apparent_skew, OP_EQ, 0); 692 done: 693 teardown_capture_of_logs(); 694 UNMOCK(clock_skew_warning); 695 } 696 697 /** Test early consensus */ 698 static void 699 test_early_consensus(void *arg) 700 { 701 time_t now = time(NULL); 702 unsigned long offset = 0; 703 int retval = 0; 704 705 retval = test_skew_common(arg, now, &offset); 706 /* Can't use expect_single_log_msg() because of unrecognized authorities */ 707 expect_log_msg_containing("behind the time published in the consensus"); 708 tt_int_op(retval, OP_EQ, 0); 709 /* This depends on construct_consensus() setting valid_after=now+1000 */ 710 tt_int_op(mock_apparent_skew, OP_EQ, offset - 1000); 711 done: 712 teardown_capture_of_logs(); 713 UNMOCK(clock_skew_warning); 714 } 715 716 /** Test warn_early_consensus(), expecting no warning */ 717 static void 718 test_warn_early_consensus_no(const networkstatus_t *c, time_t now, 719 long offset) 720 { 721 mock_apparent_skew = 0; 722 setup_capture_of_logs(LOG_WARN); 723 warn_early_consensus(c, "microdesc", now + offset); 724 expect_no_log_msg_containing("behind the time published in the consensus"); 725 tt_int_op(mock_apparent_skew, OP_EQ, 0); 726 done: 727 teardown_capture_of_logs(); 728 } 729 730 /** Test warn_early_consensus(), expecting a warning */ 731 static void 732 test_warn_early_consensus_yes(const networkstatus_t *c, time_t now, 733 long offset) 734 { 735 mock_apparent_skew = 0; 736 setup_capture_of_logs(LOG_WARN); 737 warn_early_consensus(c, "microdesc", now + offset); 738 /* Can't use expect_single_log_msg() because of unrecognized authorities */ 739 expect_log_msg_containing("behind the time published in the consensus"); 740 tt_int_op(mock_apparent_skew, OP_EQ, offset); 741 done: 742 teardown_capture_of_logs(); 743 } 744 745 /** 746 * Test warn_early_consensus() directly, checking both the non-warning 747 * case (consensus is not early) and the warning case (consensus is 748 * early). Depends on EARLY_CONSENSUS_NOTICE_SKEW=60. 749 */ 750 static void 751 test_warn_early_consensus(void *arg) 752 { 753 networkstatus_t *c = NULL; 754 time_t now = time(NULL); 755 756 (void)arg; 757 c = tor_malloc_zero(sizeof *c); 758 c->valid_after = now; 759 c->dist_seconds = 300; 760 mock_apparent_skew = 0; 761 MOCK(clock_skew_warning, mock_clock_skew_warning); 762 test_warn_early_consensus_no(c, now, 60); 763 test_warn_early_consensus_no(c, now, 0); 764 test_warn_early_consensus_no(c, now, -60); 765 test_warn_early_consensus_no(c, now, -360); 766 test_warn_early_consensus_yes(c, now, -361); 767 test_warn_early_consensus_yes(c, now, -600); 768 UNMOCK(clock_skew_warning); 769 tor_free(c); 770 } 771 772 #define NODE(name, flags) \ 773 { #name, test_routerlist_##name, (flags), NULL, NULL } 774 #define ROUTER(name,flags) \ 775 { #name, test_router_##name, (flags), NULL, NULL } 776 777 #define TIMELY(name, arg) \ 778 { name, test_timely_consensus, TT_FORK, &passthrough_setup, \ 779 (char *)(arg) } 780 #define EARLY(name, arg) \ 781 { name, test_early_consensus, TT_FORK, &passthrough_setup, \ 782 (char *)(arg) } 783 784 struct testcase_t routerlist_tests[] = { 785 NODE(initiate_descriptor_downloads, 0), 786 NODE(launch_descriptor_downloads, 0), 787 NODE(router_is_already_dir_fetching, TT_FORK), 788 ROUTER(pick_directory_server_impl, TT_FORK), 789 { "directory_guard_fetch_with_no_dirinfo", 790 test_directory_guard_fetch_with_no_dirinfo, TT_FORK, NULL, NULL }, 791 /* These depend on construct_consensus() setting 792 * valid_after=now+1000 and dist_seconds=250 */ 793 TIMELY("timely_consensus1", "1010"), 794 TIMELY("timely_consensus2", "1000"), 795 TIMELY("timely_consensus3", "690"), 796 EARLY("early_consensus1", "689"), 797 { "warn_early_consensus", test_warn_early_consensus, 0, NULL, NULL }, 798 END_OF_TESTCASES 799 };