test_connection.c (39071B)
1 /* Copyright (c) 2015-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #include "orconfig.h" 5 6 #define CONNECTION_PRIVATE 7 #define MAINLOOP_PRIVATE 8 #define CONNECTION_OR_PRIVATE 9 10 #include "core/or/or.h" 11 #include "test/test.h" 12 13 #include "app/config/config.h" 14 #include "app/config/or_options_st.h" 15 #include "core/mainloop/connection.h" 16 #include "core/or/connection_edge.h" 17 #include "feature/hs/hs_common.h" 18 #include "core/mainloop/mainloop.h" 19 #include "feature/nodelist/microdesc.h" 20 #include "feature/nodelist/nodelist.h" 21 #include "feature/nodelist/networkstatus.h" 22 #include "feature/dircommon/directory.h" 23 #include "core/or/connection_or.h" 24 #include "lib/net/resolve.h" 25 #include "lib/evloop/compat_libevent.h" 26 27 #include "test/test_connection.h" 28 #include "test/test_helpers.h" 29 30 #include "feature/dircommon/dir_connection_st.h" 31 #include "core/or/entry_connection_st.h" 32 #include "feature/nodelist/node_st.h" 33 #include "core/or/or_connection_st.h" 34 #include "feature/nodelist/routerinfo_st.h" 35 #include "core/or/socks_request_st.h" 36 37 static void * test_conn_get_basic_setup(const struct testcase_t *tc); 38 static int test_conn_get_basic_teardown(const struct testcase_t *tc, 39 void *arg); 40 41 static void * test_conn_get_rsrc_setup(const struct testcase_t *tc); 42 static int test_conn_get_rsrc_teardown(const struct testcase_t *tc, 43 void *arg); 44 45 /* Arbitrary choice - IPv4 Directory Connection to localhost */ 46 #define TEST_CONN_TYPE (CONN_TYPE_DIR) 47 /* We assume every machine has IPv4 localhost, is that ok? */ 48 #define TEST_CONN_ADDRESS "127.0.0.1" 49 #define TEST_CONN_PORT (12345) 50 #define TEST_CONN_ADDRESS_PORT "127.0.0.1:12345" 51 #define TEST_CONN_FAMILY (AF_INET) 52 #define TEST_CONN_STATE (DIR_CONN_STATE_MIN_) 53 #define TEST_CONN_ADDRESS_2 "127.0.0.2" 54 55 #define TEST_CONN_BASIC_PURPOSE (DIR_PURPOSE_MIN_) 56 57 #define TEST_CONN_REND_ADDR "cfs3rltphxxvabci" 58 #define TEST_CONN_REND_PURPOSE (DIR_PURPOSE_FETCH_RENDDESC_V2) 59 #define TEST_CONN_REND_PURPOSE_SUCCESSFUL (DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2) 60 #define TEST_CONN_REND_TYPE_2 (CONN_TYPE_AP) 61 #define TEST_CONN_REND_ADDR_2 "icbavxxhptlr3sfc" 62 63 #define TEST_CONN_RSRC (networkstatus_get_flavor_name(FLAV_MICRODESC)) 64 #define TEST_CONN_RSRC_PURPOSE (DIR_PURPOSE_FETCH_CONSENSUS) 65 #define TEST_CONN_RSRC_STATE_SUCCESSFUL (DIR_CONN_STATE_CLIENT_FINISHED) 66 #define TEST_CONN_RSRC_2 (networkstatus_get_flavor_name(FLAV_NS)) 67 68 #define TEST_CONN_DL_STATE (DIR_CONN_STATE_CLIENT_READING) 69 70 /* see AP_CONN_STATE_IS_UNATTACHED() */ 71 #define TEST_CONN_UNATTACHED_STATE (AP_CONN_STATE_CIRCUIT_WAIT) 72 #define TEST_CONN_ATTACHED_STATE (AP_CONN_STATE_CONNECT_WAIT) 73 74 void 75 test_conn_lookup_addr_helper(const char *address, int family, tor_addr_t *addr) 76 { 77 int rv = 0; 78 79 tt_assert(addr); 80 81 rv = tor_addr_lookup(address, family, addr); 82 /* XXXX - should we retry on transient failure? */ 83 tt_int_op(rv, OP_EQ, 0); 84 tt_assert(tor_addr_is_loopback(addr)); 85 tt_assert(tor_addr_is_v4(addr)); 86 87 return; 88 89 done: 90 tor_addr_make_null(addr, TEST_CONN_FAMILY); 91 } 92 93 static void * 94 test_conn_get_basic_setup(const struct testcase_t *tc) 95 { 96 (void)tc; 97 return test_conn_get_connection(TEST_CONN_STATE, TEST_CONN_TYPE, 98 TEST_CONN_BASIC_PURPOSE); 99 } 100 101 static int 102 test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg) 103 { 104 (void)tc; 105 connection_t *conn = arg; 106 107 tt_assert(conn); 108 assert_connection_ok(conn, time(NULL)); 109 110 /* teardown the connection as fast as possible */ 111 if (conn->linked_conn) { 112 assert_connection_ok(conn->linked_conn, time(NULL)); 113 114 /* We didn't call tor_libevent_initialize(), so event_base was NULL, 115 * so we can't rely on connection_unregister_events() use of event_del(). 116 */ 117 tor_event_free(conn->linked_conn->read_event); 118 tor_event_free(conn->linked_conn->write_event); 119 120 if (!conn->linked_conn->marked_for_close) { 121 connection_close_immediate(conn->linked_conn); 122 if (CONN_IS_EDGE(conn->linked_conn)) { 123 /* Suppress warnings about all the stuff we didn't do */ 124 TO_EDGE_CONN(conn->linked_conn)->edge_has_sent_end = 1; 125 TO_EDGE_CONN(conn->linked_conn)->end_reason = 126 END_STREAM_REASON_INTERNAL; 127 if (conn->linked_conn->type == CONN_TYPE_AP) { 128 TO_ENTRY_CONN(conn->linked_conn)->socks_request->has_finished = 1; 129 } 130 } 131 connection_mark_for_close(conn->linked_conn); 132 } 133 134 close_closeable_connections(); 135 } 136 137 /* We didn't set the events up properly, so we can't use event_del() in 138 * close_closeable_connections() > connection_free() 139 * > connection_unregister_events() */ 140 tor_event_free(conn->read_event); 141 tor_event_free(conn->write_event); 142 143 if (!conn->marked_for_close) { 144 connection_close_immediate(conn); 145 if (CONN_IS_EDGE(conn)) { 146 /* Suppress warnings about all the stuff we didn't do */ 147 TO_EDGE_CONN(conn)->edge_has_sent_end = 1; 148 TO_EDGE_CONN(conn)->end_reason = END_STREAM_REASON_INTERNAL; 149 if (conn->type == CONN_TYPE_AP) { 150 TO_ENTRY_CONN(conn)->socks_request->has_finished = 1; 151 } 152 } 153 connection_mark_for_close(conn); 154 } 155 156 close_closeable_connections(); 157 158 /* The unit test will fail if we return 0 */ 159 return 1; 160 161 /* When conn == NULL, we can't cleanup anything */ 162 done: 163 return 0; 164 } 165 166 static dir_connection_t * 167 test_conn_download_status_add_a_connection(const char *resource) 168 { 169 dir_connection_t *conn = DOWNCAST(dir_connection_t, 170 test_conn_get_connection( 171 TEST_CONN_STATE, 172 TEST_CONN_TYPE, 173 TEST_CONN_RSRC_PURPOSE)); 174 175 tt_assert(conn); 176 assert_connection_ok(&conn->base_, time(NULL)); 177 178 /* Replace the existing resource with the one we want */ 179 if (resource) { 180 if (conn->requested_resource) { 181 tor_free(conn->requested_resource); 182 } 183 conn->requested_resource = tor_strdup(resource); 184 assert_connection_ok(&conn->base_, time(NULL)); 185 } 186 187 return conn; 188 189 done: 190 test_conn_get_rsrc_teardown(NULL, conn); 191 return NULL; 192 } 193 194 static void * 195 test_conn_get_rsrc_setup(const struct testcase_t *tc) 196 { 197 (void)tc; 198 return test_conn_download_status_add_a_connection(TEST_CONN_RSRC); 199 } 200 201 static int 202 test_conn_get_rsrc_teardown(const struct testcase_t *tc, void *arg) 203 { 204 int rv = 0; 205 206 connection_t *conn = (connection_t *)arg; 207 tt_assert(conn); 208 assert_connection_ok(conn, time(NULL)); 209 210 if (conn->type == CONN_TYPE_DIR) { 211 dir_connection_t *dir_conn = DOWNCAST(dir_connection_t, arg); 212 213 tt_assert(dir_conn); 214 assert_connection_ok(&dir_conn->base_, time(NULL)); 215 216 /* avoid a last-ditch attempt to refetch the consensus */ 217 dir_conn->base_.state = TEST_CONN_RSRC_STATE_SUCCESSFUL; 218 assert_connection_ok(&dir_conn->base_, time(NULL)); 219 } 220 221 /* connection_free_() cleans up requested_resource */ 222 rv = test_conn_get_basic_teardown(tc, conn); 223 224 done: 225 return rv; 226 } 227 228 static void * 229 test_conn_download_status_setup(const struct testcase_t *tc) 230 { 231 return (void*)tc; 232 } 233 234 static int 235 test_conn_download_status_teardown(const struct testcase_t *tc, void *arg) 236 { 237 (void)arg; 238 int rv = 0; 239 240 /* Ignore arg, and just loop through the connection array */ 241 SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) { 242 if (conn) { 243 assert_connection_ok(conn, time(NULL)); 244 245 /* connection_free_() cleans up requested_resource */ 246 rv = test_conn_get_rsrc_teardown(tc, conn); 247 tt_int_op(rv, OP_EQ, 1); 248 } 249 } SMARTLIST_FOREACH_END(conn); 250 251 done: 252 return rv; 253 } 254 255 static void * 256 test_conn_proxy_connect_setup(const struct testcase_t *tc) 257 { 258 return test_conn_get_proxy_or_connection(*(unsigned int *)tc->setup_data); 259 } 260 261 static int 262 test_conn_proxy_connect_teardown(const struct testcase_t *tc, void *arg) 263 { 264 (void)tc; 265 or_connection_t *conn = arg; 266 267 tt_assert(conn); 268 assert_connection_ok(&conn->base_, time(NULL)); 269 270 done: 271 return 1; 272 } 273 274 /* Like connection_ap_make_link(), but does much less */ 275 static connection_t * 276 test_conn_get_linked_connection(connection_t *l_conn, uint8_t state) 277 { 278 tt_assert(l_conn); 279 assert_connection_ok(l_conn, time(NULL)); 280 281 /* AP connections don't seem to have purposes */ 282 connection_t *conn = test_conn_get_connection(state, CONN_TYPE_AP, 283 0); 284 285 tt_assert(conn); 286 assert_connection_ok(conn, time(NULL)); 287 288 conn->linked = 1; 289 l_conn->linked = 1; 290 conn->linked_conn = l_conn; 291 l_conn->linked_conn = conn; 292 /* we never opened a real socket, so we can just overwrite it */ 293 conn->s = TOR_INVALID_SOCKET; 294 l_conn->s = TOR_INVALID_SOCKET; 295 296 assert_connection_ok(conn, time(NULL)); 297 assert_connection_ok(l_conn, time(NULL)); 298 299 return conn; 300 301 done: 302 test_conn_download_status_teardown(NULL, NULL); 303 return NULL; 304 } 305 306 static struct testcase_setup_t test_conn_get_basic_st = { 307 test_conn_get_basic_setup, test_conn_get_basic_teardown 308 }; 309 310 static struct testcase_setup_t test_conn_get_rsrc_st = { 311 test_conn_get_rsrc_setup, test_conn_get_rsrc_teardown 312 }; 313 314 static struct testcase_setup_t test_conn_download_status_st = { 315 test_conn_download_status_setup, test_conn_download_status_teardown 316 }; 317 318 static struct testcase_setup_t test_conn_proxy_connect_st = { 319 test_conn_proxy_connect_setup, test_conn_proxy_connect_teardown 320 }; 321 322 static void 323 test_conn_get_basic(void *arg) 324 { 325 connection_t *conn = (connection_t*)arg; 326 tor_addr_t addr, addr2; 327 328 tt_assert(conn); 329 assert_connection_ok(conn, time(NULL)); 330 331 test_conn_lookup_addr_helper(TEST_CONN_ADDRESS, TEST_CONN_FAMILY, &addr); 332 tt_assert(!tor_addr_is_null(&addr)); 333 test_conn_lookup_addr_helper(TEST_CONN_ADDRESS_2, TEST_CONN_FAMILY, &addr2); 334 tt_assert(!tor_addr_is_null(&addr2)); 335 336 /* Check that we get this connection back when we search for it by 337 * its attributes, but get NULL when we supply a different value. */ 338 339 tt_assert(connection_get_by_global_id(conn->global_identifier) == conn); 340 tt_ptr_op(connection_get_by_global_id(!conn->global_identifier), OP_EQ, 341 NULL); 342 343 tt_assert(connection_get_by_type(conn->type) == conn); 344 tt_assert(connection_get_by_type(TEST_CONN_TYPE) == conn); 345 tt_ptr_op(connection_get_by_type(!conn->type), OP_EQ, NULL); 346 tt_ptr_op(connection_get_by_type(!TEST_CONN_TYPE), OP_EQ, NULL); 347 348 tt_assert(connection_get_by_type_state(conn->type, conn->state) 349 == conn); 350 tt_assert(connection_get_by_type_state(TEST_CONN_TYPE, TEST_CONN_STATE) 351 == conn); 352 tt_assert(connection_get_by_type_state(!conn->type, !conn->state) 353 == NULL); 354 tt_assert(connection_get_by_type_state(!TEST_CONN_TYPE, !TEST_CONN_STATE) 355 == NULL); 356 357 /* Match on the connection fields themselves */ 358 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 359 &conn->addr, 360 conn->port, 361 conn->purpose) 362 == conn); 363 /* Match on the original inputs to the connection */ 364 tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE, 365 &conn->addr, 366 conn->port, 367 conn->purpose) 368 == conn); 369 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 370 &addr, 371 conn->port, 372 conn->purpose) 373 == conn); 374 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 375 &conn->addr, 376 TEST_CONN_PORT, 377 conn->purpose) 378 == conn); 379 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 380 &conn->addr, 381 conn->port, 382 TEST_CONN_BASIC_PURPOSE) 383 == conn); 384 tt_assert(connection_get_by_type_addr_port_purpose(TEST_CONN_TYPE, 385 &addr, 386 TEST_CONN_PORT, 387 TEST_CONN_BASIC_PURPOSE) 388 == conn); 389 /* Then try each of the not-matching combinations */ 390 tt_assert(connection_get_by_type_addr_port_purpose(!conn->type, 391 &conn->addr, 392 conn->port, 393 conn->purpose) 394 == NULL); 395 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 396 &addr2, 397 conn->port, 398 conn->purpose) 399 == NULL); 400 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 401 &conn->addr, 402 !conn->port, 403 conn->purpose) 404 == NULL); 405 tt_assert(connection_get_by_type_addr_port_purpose(conn->type, 406 &conn->addr, 407 conn->port, 408 !conn->purpose) 409 == NULL); 410 /* Then try everything not-matching */ 411 tt_assert(connection_get_by_type_addr_port_purpose(!conn->type, 412 &addr2, 413 !conn->port, 414 !conn->purpose) 415 == NULL); 416 tt_assert(connection_get_by_type_addr_port_purpose(!TEST_CONN_TYPE, 417 &addr2, 418 !TEST_CONN_PORT, 419 !TEST_CONN_BASIC_PURPOSE) 420 == NULL); 421 422 done: 423 ; 424 } 425 426 #define sl_is_conn_assert(sl_input, conn) \ 427 do { \ 428 the_sl = (sl_input); \ 429 tt_int_op(smartlist_len((the_sl)), OP_EQ, 1); \ 430 tt_assert(smartlist_get((the_sl), 0) == (conn)); \ 431 smartlist_free(the_sl); the_sl = NULL; \ 432 } while (0) 433 434 #define sl_no_conn_assert(sl_input) \ 435 do { \ 436 the_sl = (sl_input); \ 437 tt_int_op(smartlist_len((the_sl)), OP_EQ, 0); \ 438 smartlist_free(the_sl); the_sl = NULL; \ 439 } while (0) 440 441 static void 442 test_conn_get_rsrc(void *arg) 443 { 444 dir_connection_t *conn = DOWNCAST(dir_connection_t, arg); 445 smartlist_t *the_sl = NULL; 446 tt_assert(conn); 447 assert_connection_ok(&conn->base_, time(NULL)); 448 449 sl_is_conn_assert(connection_dir_list_by_purpose_and_resource( 450 conn->base_.purpose, 451 conn->requested_resource), 452 conn); 453 sl_is_conn_assert(connection_dir_list_by_purpose_and_resource( 454 TEST_CONN_RSRC_PURPOSE, 455 TEST_CONN_RSRC), 456 conn); 457 sl_no_conn_assert(connection_dir_list_by_purpose_and_resource( 458 !conn->base_.purpose, 459 "")); 460 sl_no_conn_assert(connection_dir_list_by_purpose_and_resource( 461 !TEST_CONN_RSRC_PURPOSE, 462 TEST_CONN_RSRC_2)); 463 464 sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state( 465 conn->base_.purpose, 466 conn->requested_resource, 467 conn->base_.state), 468 conn); 469 sl_is_conn_assert(connection_dir_list_by_purpose_resource_and_state( 470 TEST_CONN_RSRC_PURPOSE, 471 TEST_CONN_RSRC, 472 TEST_CONN_STATE), 473 conn); 474 sl_no_conn_assert(connection_dir_list_by_purpose_resource_and_state( 475 !conn->base_.purpose, 476 "", 477 !conn->base_.state)); 478 sl_no_conn_assert(connection_dir_list_by_purpose_resource_and_state( 479 !TEST_CONN_RSRC_PURPOSE, 480 TEST_CONN_RSRC_2, 481 !TEST_CONN_STATE)); 482 483 tt_int_op(connection_dir_count_by_purpose_and_resource( 484 conn->base_.purpose, conn->requested_resource), 485 OP_EQ, 1); 486 tt_int_op(connection_dir_count_by_purpose_and_resource( 487 TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC), 488 OP_EQ, 1); 489 tt_int_op(connection_dir_count_by_purpose_and_resource( 490 !conn->base_.purpose, ""), 491 OP_EQ, 0); 492 tt_int_op(connection_dir_count_by_purpose_and_resource( 493 !TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC_2), 494 OP_EQ, 0); 495 496 tt_int_op(connection_dir_count_by_purpose_resource_and_state( 497 conn->base_.purpose, conn->requested_resource, 498 conn->base_.state), 499 OP_EQ, 1); 500 tt_int_op(connection_dir_count_by_purpose_resource_and_state( 501 TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC, TEST_CONN_STATE), 502 OP_EQ, 1); 503 tt_int_op(connection_dir_count_by_purpose_resource_and_state( 504 !conn->base_.purpose, "", !conn->base_.state), 505 OP_EQ, 0); 506 tt_int_op(connection_dir_count_by_purpose_resource_and_state( 507 !TEST_CONN_RSRC_PURPOSE, TEST_CONN_RSRC_2, !TEST_CONN_STATE), 508 OP_EQ, 0); 509 510 done: 511 smartlist_free(the_sl); 512 } 513 514 static void 515 test_conn_download_status(void *arg) 516 { 517 dir_connection_t *conn = NULL; 518 dir_connection_t *conn2 = NULL; 519 dir_connection_t *conn4 = NULL; 520 connection_t *ap_conn = NULL; 521 522 const struct testcase_t *tc = arg; 523 consensus_flavor_t usable_flavor = 524 networkstatus_parse_flavor_name((const char*) tc->setup_data); 525 526 /* The "other flavor" trick only works if there are two flavors */ 527 tor_assert(N_CONSENSUS_FLAVORS == 2); 528 consensus_flavor_t other_flavor = ((usable_flavor == FLAV_NS) 529 ? FLAV_MICRODESC 530 : FLAV_NS); 531 const char *res = networkstatus_get_flavor_name(usable_flavor); 532 const char *other_res = networkstatus_get_flavor_name(other_flavor); 533 534 /* no connections */ 535 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 536 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 537 0); 538 tt_int_op(connection_dir_count_by_purpose_and_resource( 539 TEST_CONN_RSRC_PURPOSE, res), 540 OP_EQ, 0); 541 tt_int_op(connection_dir_count_by_purpose_and_resource( 542 TEST_CONN_RSRC_PURPOSE, other_res), 543 OP_EQ, 0); 544 545 /* one connection, not downloading */ 546 conn = test_conn_download_status_add_a_connection(res); 547 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 548 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 549 0); 550 tt_int_op(connection_dir_count_by_purpose_and_resource( 551 TEST_CONN_RSRC_PURPOSE, res), 552 OP_EQ, 1); 553 tt_int_op(connection_dir_count_by_purpose_and_resource( 554 TEST_CONN_RSRC_PURPOSE, other_res), 555 OP_EQ, 0); 556 557 /* one connection, downloading but not linked (not possible on a client, 558 * but possible on a relay) */ 559 conn->base_.state = TEST_CONN_DL_STATE; 560 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 561 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 562 0); 563 tt_int_op(connection_dir_count_by_purpose_and_resource( 564 TEST_CONN_RSRC_PURPOSE, res), 565 OP_EQ, 1); 566 tt_int_op(connection_dir_count_by_purpose_and_resource( 567 TEST_CONN_RSRC_PURPOSE, other_res), 568 OP_EQ, 0); 569 570 /* one connection, downloading and linked, but not yet attached */ 571 ap_conn = test_conn_get_linked_connection(TO_CONN(conn), 572 TEST_CONN_UNATTACHED_STATE); 573 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 574 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 575 0); 576 tt_int_op(connection_dir_count_by_purpose_and_resource( 577 TEST_CONN_RSRC_PURPOSE, res), 578 OP_EQ, 1); 579 tt_int_op(connection_dir_count_by_purpose_and_resource( 580 TEST_CONN_RSRC_PURPOSE, other_res), 581 OP_EQ, 0); 582 583 /* one connection, downloading and linked and attached */ 584 ap_conn->state = TEST_CONN_ATTACHED_STATE; 585 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 586 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 587 0); 588 tt_int_op(connection_dir_count_by_purpose_and_resource( 589 TEST_CONN_RSRC_PURPOSE, res), 590 OP_EQ, 1); 591 tt_int_op(connection_dir_count_by_purpose_and_resource( 592 TEST_CONN_RSRC_PURPOSE, other_res), 593 OP_EQ, 0); 594 595 /* one connection, linked and attached but not downloading */ 596 conn->base_.state = TEST_CONN_STATE; 597 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 598 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 599 0); 600 tt_int_op(connection_dir_count_by_purpose_and_resource( 601 TEST_CONN_RSRC_PURPOSE, res), 602 OP_EQ, 1); 603 tt_int_op(connection_dir_count_by_purpose_and_resource( 604 TEST_CONN_RSRC_PURPOSE, other_res), 605 OP_EQ, 0); 606 607 /* two connections, both not downloading */ 608 conn2 = test_conn_download_status_add_a_connection(res); 609 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 610 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 611 0); 612 tt_int_op(connection_dir_count_by_purpose_and_resource( 613 TEST_CONN_RSRC_PURPOSE, res), 614 OP_EQ, 2); 615 tt_int_op(connection_dir_count_by_purpose_and_resource( 616 TEST_CONN_RSRC_PURPOSE, other_res), 617 OP_EQ, 0); 618 619 /* two connections, one downloading */ 620 conn->base_.state = TEST_CONN_DL_STATE; 621 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 622 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 623 0); 624 tt_int_op(connection_dir_count_by_purpose_and_resource( 625 TEST_CONN_RSRC_PURPOSE, res), 626 OP_EQ, 2); 627 tt_int_op(connection_dir_count_by_purpose_and_resource( 628 TEST_CONN_RSRC_PURPOSE, other_res), 629 OP_EQ, 0); 630 conn->base_.state = TEST_CONN_STATE; 631 632 /* more connections, all not downloading */ 633 /* ignore the return value, it's free'd using the connection list */ 634 (void)test_conn_download_status_add_a_connection(res); 635 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 0); 636 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 637 0); 638 tt_int_op(connection_dir_count_by_purpose_and_resource( 639 TEST_CONN_RSRC_PURPOSE, res), 640 OP_EQ, 3); 641 tt_int_op(connection_dir_count_by_purpose_and_resource( 642 TEST_CONN_RSRC_PURPOSE, other_res), 643 OP_EQ, 0); 644 645 /* more connections, one downloading */ 646 conn->base_.state = TEST_CONN_DL_STATE; 647 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 648 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 649 0); 650 tt_int_op(connection_dir_count_by_purpose_and_resource( 651 TEST_CONN_RSRC_PURPOSE, res), 652 OP_EQ, 3); 653 tt_int_op(connection_dir_count_by_purpose_and_resource( 654 TEST_CONN_RSRC_PURPOSE, other_res), 655 OP_EQ, 0); 656 657 /* more connections, two downloading (should never happen, but needs 658 * to be tested for completeness) */ 659 conn2->base_.state = TEST_CONN_DL_STATE; 660 /* ignore the return value, it's free'd using the connection list */ 661 (void)test_conn_get_linked_connection(TO_CONN(conn2), 662 TEST_CONN_ATTACHED_STATE); 663 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 664 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 665 0); 666 tt_int_op(connection_dir_count_by_purpose_and_resource( 667 TEST_CONN_RSRC_PURPOSE, res), 668 OP_EQ, 3); 669 tt_int_op(connection_dir_count_by_purpose_and_resource( 670 TEST_CONN_RSRC_PURPOSE, other_res), 671 OP_EQ, 0); 672 conn->base_.state = TEST_CONN_STATE; 673 674 /* more connections, a different one downloading */ 675 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 676 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 677 0); 678 tt_int_op(connection_dir_count_by_purpose_and_resource( 679 TEST_CONN_RSRC_PURPOSE, res), 680 OP_EQ, 3); 681 tt_int_op(connection_dir_count_by_purpose_and_resource( 682 TEST_CONN_RSRC_PURPOSE, other_res), 683 OP_EQ, 0); 684 685 /* a connection for the other flavor (could happen if a client is set to 686 * cache directory documents), one preferred flavor downloading 687 */ 688 conn4 = test_conn_download_status_add_a_connection(other_res); 689 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 690 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 691 0); 692 tt_int_op(connection_dir_count_by_purpose_and_resource( 693 TEST_CONN_RSRC_PURPOSE, res), 694 OP_EQ, 3); 695 tt_int_op(connection_dir_count_by_purpose_and_resource( 696 TEST_CONN_RSRC_PURPOSE, other_res), 697 OP_EQ, 1); 698 699 /* a connection for the other flavor (could happen if a client is set to 700 * cache directory documents), both flavors downloading 701 */ 702 conn4->base_.state = TEST_CONN_DL_STATE; 703 /* ignore the return value, it's free'd using the connection list */ 704 (void)test_conn_get_linked_connection(TO_CONN(conn4), 705 TEST_CONN_ATTACHED_STATE); 706 tt_int_op(networkstatus_consensus_is_already_downloading(res), OP_EQ, 1); 707 tt_int_op(networkstatus_consensus_is_already_downloading(other_res), OP_EQ, 708 1); 709 tt_int_op(connection_dir_count_by_purpose_and_resource( 710 TEST_CONN_RSRC_PURPOSE, res), 711 OP_EQ, 3); 712 tt_int_op(connection_dir_count_by_purpose_and_resource( 713 TEST_CONN_RSRC_PURPOSE, other_res), 714 OP_EQ, 1); 715 716 done: 717 /* the teardown function removes all the connections in the global list*/; 718 } 719 720 static void 721 test_conn_https_proxy_connect(void *arg) 722 { 723 size_t sz; 724 char *buf = NULL; 725 or_connection_t *conn = arg; 726 727 MOCK(connection_or_change_state, mock_connection_or_change_state); 728 729 tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HTTPS_WANT_CONNECT_OK); 730 731 buf = buf_get_contents(conn->base_.outbuf, &sz); 732 tt_str_op(buf, OP_EQ, "CONNECT 127.0.0.1:12345 HTTP/1.0\r\n\r\n"); 733 734 done: 735 UNMOCK(connection_or_change_state); 736 tor_free(buf); 737 } 738 739 static int handshake_start_called = 0; 740 741 static int 742 handshake_start(or_connection_t *conn, int receiving) 743 { 744 (void)receiving; 745 746 tor_assert(conn); 747 748 handshake_start_called = 1; 749 return 0; 750 } 751 752 static void 753 test_conn_haproxy_proxy_connect(void *arg) 754 { 755 size_t sz; 756 char *buf = NULL; 757 or_connection_t *conn = arg; 758 759 MOCK(connection_or_change_state, mock_connection_or_change_state); 760 MOCK(connection_tls_start_handshake, handshake_start); 761 762 tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_HAPROXY_WAIT_FOR_FLUSH); 763 764 buf = buf_get_contents(conn->base_.outbuf, &sz); 765 tt_str_op(buf, OP_EQ, "PROXY TCP4 0.0.0.0 127.0.0.1 0 12345\r\n"); 766 767 connection_or_finished_flushing(conn); 768 769 tt_int_op(conn->base_.proxy_state, OP_EQ, PROXY_CONNECTED); 770 tt_int_op(handshake_start_called, OP_EQ, 1); 771 772 done: 773 UNMOCK(connection_or_change_state); 774 UNMOCK(connection_tls_start_handshake); 775 tor_free(buf); 776 } 777 778 static node_t test_node; 779 780 static node_t * 781 mock_node_get_mutable_by_id(const char *digest) 782 { 783 (void) digest; 784 static routerinfo_t node_ri; 785 memset(&node_ri, 0, sizeof(node_ri)); 786 787 test_node.ri = &node_ri; 788 memset(test_node.identity, 'c', sizeof(test_node.identity)); 789 790 tor_addr_parse(&node_ri.ipv4_addr, "18.0.0.1"); 791 node_ri.ipv4_orport = 1; 792 793 return &test_node; 794 } 795 796 static const node_t * 797 mock_node_get_by_id(const char *digest) 798 { 799 (void) digest; 800 memset(test_node.identity, 'c', sizeof(test_node.identity)); 801 return &test_node; 802 } 803 804 /* Test whether we correctly track failed connections between relays. */ 805 static void 806 test_failed_orconn_tracker(void *arg) 807 { 808 (void) arg; 809 810 int can_connect; 811 time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ 812 (void) now; 813 814 update_approx_time(now); 815 816 /* Prepare the OR connection that will be used in this test */ 817 or_connection_t or_conn; 818 memset(&or_conn, 0, sizeof(or_conn)); 819 tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.canonical_orport.addr, 820 "18.0.0.1")); 821 tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.base_.addr, "18.0.0.1")); 822 or_conn.base_.port = 1; 823 memset(or_conn.identity_digest, 'c', sizeof(or_conn.identity_digest)); 824 825 /* Check whether we can connect with an empty failure cache: 826 * this should succeed */ 827 can_connect = should_connect_to_relay(&or_conn); 828 tt_int_op(can_connect, OP_EQ, 1); 829 830 /* Now add the destination to the failure cache */ 831 note_or_connect_failed(&or_conn); 832 833 /* Check again: now it shouldn't connect */ 834 can_connect = should_connect_to_relay(&or_conn); 835 tt_int_op(can_connect, OP_EQ, 0); 836 837 /* Move time forward and check again: the cache should have been cleared and 838 * now it should connect */ 839 now += 3600; 840 update_approx_time(now); 841 can_connect = should_connect_to_relay(&or_conn); 842 tt_int_op(can_connect, OP_EQ, 1); 843 844 /* Now mock the node_get_*by_id() functions to start using the node subsystem 845 * optimization. */ 846 MOCK(node_get_by_id, mock_node_get_by_id); 847 MOCK(node_get_mutable_by_id, mock_node_get_mutable_by_id); 848 849 /* Since we just started using the node subsystem it will allow connections 850 * now */ 851 can_connect = should_connect_to_relay(&or_conn); 852 tt_int_op(can_connect, OP_EQ, 1); 853 854 /* Mark it as failed */ 855 note_or_connect_failed(&or_conn); 856 857 /* Check that it shouldn't connect now */ 858 can_connect = should_connect_to_relay(&or_conn); 859 tt_int_op(can_connect, OP_EQ, 0); 860 861 /* Move time forward and check again: now it should connect */ 862 now += 3600; 863 update_approx_time(now); 864 can_connect = should_connect_to_relay(&or_conn); 865 tt_int_op(can_connect, OP_EQ, 1); 866 867 done: 868 ; 869 } 870 871 static void 872 test_conn_describe(void *arg) 873 { 874 (void)arg; 875 or_options_t *options = get_options_mutable(); 876 options->SafeLogging_ = SAFELOG_SCRUB_ALL; 877 878 // Let's start with a listener connection since they're simple. 879 connection_t *conn = connection_new(CONN_TYPE_OR_LISTENER, AF_INET); 880 tor_addr_parse(&conn->addr, "44.22.11.11"); 881 conn->port = 80; 882 tt_str_op(connection_describe(conn), OP_EQ, 883 "OR listener connection (ready) on 44.22.11.11:80"); 884 // If the address is unspec, we should still work. 885 tor_addr_make_unspec(&conn->addr); 886 tt_str_op(connection_describe(conn), OP_EQ, 887 "OR listener connection (ready) on <unset>:80"); 888 // Try making the address null. 889 tor_addr_make_null(&conn->addr, AF_INET); 890 tt_str_op(connection_describe(conn), OP_EQ, 891 "OR listener connection (ready) on 0.0.0.0:80"); 892 // What if the address is uninitialized? (This can happen if we log about the 893 // connection before we set the address.) 894 memset(&conn->addr, 0, sizeof(conn->addr)); 895 tt_str_op(connection_describe(conn), OP_EQ, 896 "OR listener connection (ready) on <unset>:80"); 897 connection_free_minimal(conn); 898 899 // Try a unix socket. 900 conn = connection_new(CONN_TYPE_CONTROL_LISTENER, AF_UNIX); 901 conn->address = tor_strdup("/a/path/that/could/exist"); 902 tt_str_op(connection_describe(conn), OP_EQ, 903 "Control listener connection (ready) on /a/path/that/could/exist"); 904 connection_free_minimal(conn); 905 906 // Try an IPv6 address. 907 conn = connection_new(CONN_TYPE_AP_LISTENER, AF_INET6); 908 tor_addr_parse(&conn->addr, "ff00::3"); 909 conn->port = 9050; 910 tt_str_op(connection_describe(conn), OP_EQ, 911 "Socks listener connection (ready) on [ff00::3]:9050"); 912 connection_free_minimal(conn); 913 914 // Now let's mess with exit connections. They have some special issues. 915 options->SafeLogging_ = SAFELOG_SCRUB_NONE; 916 conn = connection_new(CONN_TYPE_EXIT, AF_INET); 917 // If address and state are unset, we should say SOMETHING. 918 tt_str_op(connection_describe(conn), OP_EQ, 919 "Exit connection (uninitialized) to <unset> (DNS lookup pending)"); 920 // Now suppose that the address is set but we haven't resolved the hostname. 921 conn->port = 443; 922 conn->address = tor_strdup("www.torproject.org"); 923 conn->state = EXIT_CONN_STATE_RESOLVING; 924 tt_str_op(connection_describe(conn), OP_EQ, 925 "Exit connection (waiting for dest info) to " 926 "www.torproject.org:443 (DNS lookup pending)"); 927 // Now give it a hostname! 928 tor_addr_parse(&conn->addr, "192.168.8.8"); 929 conn->state = EXIT_CONN_STATE_OPEN; 930 tt_str_op(connection_describe(conn), OP_EQ, 931 "Exit connection (open) to 192.168.8.8:443"); 932 // But what if safelogging is on? 933 options->SafeLogging_ = SAFELOG_SCRUB_RELAY; 934 tt_str_op(connection_describe(conn), OP_EQ, 935 "Exit connection (open) to [scrubbed]"); 936 connection_free_minimal(conn); 937 938 // Now at last we look at OR addresses, which are complicated. 939 conn = connection_new(CONN_TYPE_OR, AF_INET6); 940 conn->state = OR_CONN_STATE_OPEN; 941 conn->port = 8080; 942 tor_addr_parse(&conn->addr, "[ffff:3333:1111::2]"); 943 // This should get scrubbed, since the lack of a set ID means we might be 944 // talking to a client. 945 tt_str_op(connection_describe(conn), OP_EQ, 946 "OR connection (open) with [scrubbed]"); 947 // But now suppose we aren't safelogging? We'll get the address then. 948 options->SafeLogging_ = SAFELOG_SCRUB_NONE; 949 tt_str_op(connection_describe(conn), OP_EQ, 950 "OR connection (open) with [ffff:3333:1111::2]:8080"); 951 // Suppose we have an ID, so we know it isn't a client. 952 TO_OR_CONN(conn)->identity_digest[3] = 7; 953 options->SafeLogging_ = SAFELOG_SCRUB_RELAY; // back to safelogging. 954 tt_str_op(connection_describe(conn), OP_EQ, 955 "OR connection (open) with [ffff:3333:1111::2]:8080 " 956 "ID=<none> RSA_ID=0000000700000000000000000000000000000000"); 957 // Add a 'canonical address' that is the same as the one we have. 958 tor_addr_parse(&TO_OR_CONN(conn)->canonical_orport.addr, 959 "[ffff:3333:1111::2]"); 960 TO_OR_CONN(conn)->canonical_orport.port = 8080; 961 tt_str_op(connection_describe(conn), OP_EQ, 962 "OR connection (open) with [ffff:3333:1111::2]:8080 " 963 "ID=<none> RSA_ID=0000000700000000000000000000000000000000"); 964 // Add a different 'canonical address' 965 tor_addr_parse(&TO_OR_CONN(conn)->canonical_orport.addr, 966 "[ffff:3333:1111::8]"); 967 tt_str_op(connection_describe(conn), OP_EQ, 968 "OR connection (open) with [ffff:3333:1111::2]:8080 " 969 "ID=<none> RSA_ID=0000000700000000000000000000000000000000 " 970 "canonical_addr=[ffff:3333:1111::8]:8080"); 971 972 // Clear identity_digest so that free_minimal won't complain. 973 memset(TO_OR_CONN(conn)->identity_digest, 0, DIGEST_LEN); 974 975 done: 976 connection_free_minimal(conn); 977 } 978 979 #ifndef COCCI 980 #define CONNECTION_TESTCASE(name, fork, setup) \ 981 { #name, test_conn_##name, fork, &setup, NULL } 982 983 #define STR(x) #x 984 /* where arg is an expression (constant, variable, compound expression) */ 985 #define CONNECTION_TESTCASE_ARG(name, extra, fork, setup, arg) \ 986 { STR(name)"/"extra, \ 987 test_conn_##name, \ 988 (fork), \ 989 &(setup), \ 990 (void *)(arg) } 991 #endif /* !defined(COCCI) */ 992 993 static const unsigned int PROXY_CONNECT_ARG = PROXY_CONNECT; 994 static const unsigned int PROXY_HAPROXY_ARG = PROXY_HAPROXY; 995 996 struct testcase_t connection_tests[] = { 997 CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st), 998 CONNECTION_TESTCASE(get_rsrc, TT_FORK, test_conn_get_rsrc_st), 999 1000 CONNECTION_TESTCASE_ARG(download_status, "microdesc", TT_FORK, 1001 test_conn_download_status_st, "microdesc"), 1002 CONNECTION_TESTCASE_ARG(download_status, "ns", TT_FORK, 1003 test_conn_download_status_st, "ns"), 1004 1005 CONNECTION_TESTCASE_ARG(https_proxy_connect, "https", TT_FORK, 1006 test_conn_proxy_connect_st, &PROXY_CONNECT_ARG), 1007 CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, "haproxy", TT_FORK, 1008 test_conn_proxy_connect_st, &PROXY_HAPROXY_ARG), 1009 1010 //CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair), 1011 { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL }, 1012 { "describe", test_conn_describe, TT_FORK, NULL, NULL }, 1013 END_OF_TESTCASES 1014 };