test_conflux_pool.c (45308B)
1 #define CHANNEL_OBJECT_PRIVATE 2 #define TOR_TIMERS_PRIVATE 3 #define TOR_CONFLUX_PRIVATE 4 #define CIRCUITLIST_PRIVATE 5 #define NETWORKSTATUS_PRIVATE 6 #define CRYPT_PATH_PRIVATE 7 #define RELAY_PRIVATE 8 #define CONNECTION_PRIVATE 9 #define TOR_CONGESTION_CONTROL_COMMON_PRIVATE 10 #define TOR_CONGESTION_CONTROL_PRIVATE 11 12 #include "core/or/or.h" 13 #include "test/test.h" 14 #include "test/log_test_helpers.h" 15 #include "lib/testsupport/testsupport.h" 16 #include "core/or/connection_or.h" 17 #include "core/or/channel.h" 18 #include "core/or/channeltls.h" 19 #include "core/or/crypt_path.h" 20 #include <event.h> 21 #include "lib/evloop/compat_libevent.h" 22 #include "lib/time/compat_time.h" 23 #include "lib/defs/time.h" 24 #include "core/or/relay.h" 25 #include "core/or/circuitlist.h" 26 #include "core/or/circuitstats.h" 27 #include "core/or/circuitbuild.h" 28 #include "core/or/circuituse.h" 29 #include "core/or/congestion_control_st.h" 30 #include "core/or/congestion_control_common.h" 31 #include "core/or/extendinfo.h" 32 #include "core/or/relay_msg.h" 33 #include "core/mainloop/netstatus.h" 34 #include "core/crypto/relay_crypto.h" 35 #include "core/or/protover.h" 36 #include "feature/nodelist/nodelist.h" 37 #include "app/config/config.h" 38 39 #include "feature/nodelist/routerstatus_st.h" 40 #include "feature/nodelist/networkstatus_st.h" 41 #include "feature/nodelist/node_st.h" 42 #include "core/or/cell_st.h" 43 #include "core/or/crypt_path_st.h" 44 #include "core/or/or_circuit_st.h" 45 #include "core/or/origin_circuit_st.h" 46 47 #include "core/mainloop/connection.h" 48 #include "core/or/connection_edge.h" 49 #include "core/or/edge_connection_st.h" 50 51 #include "test/fakecircs.h" 52 #include "test/rng_test_helpers.h" 53 #include "core/or/conflux_pool.h" 54 #include "core/or/conflux_util.h" 55 #include "core/or/conflux_params.h" 56 #include "core/or/conflux.h" 57 #include "core/or/conflux_st.h" 58 #include "trunnel/conflux.h" 59 #include "lib/crypt_ops/crypto_rand.h" 60 61 /* Start our monotime mocking at 1 second past whatever monotime_init() 62 * thought the actual wall clock time was, for platforms with bad resolution 63 * and weird timevalues during monotime_init() before mocking. */ 64 #define MONOTIME_MOCK_START (monotime_absolute_nsec()+\ 65 TOR_NSEC_PER_USEC*TOR_USEC_PER_SEC) 66 67 extern smartlist_t *connection_array; 68 void circuit_expire_old_circuits_clientside(void); 69 70 circid_t get_unique_circ_id_by_chan(channel_t *chan); 71 72 channel_t *new_fake_channel(void); 73 74 static void simulate_single_hop_extend(origin_circuit_t *client, int exit); 75 static void free_fake_origin_circuit(origin_circuit_t *circ); 76 static circuit_t * get_exit_circ(circuit_t *client_circ); 77 static circuit_t * get_client_circ(circuit_t *exit_circ); 78 static void simulate_circuit_build(circuit_t *client_circ); 79 80 static int64_t curr_mocked_time; 81 82 static channel_t dummy_channel; 83 84 static void 85 timers_advance_and_run(int64_t msec_update) 86 { 87 curr_mocked_time += msec_update*TOR_NSEC_PER_MSEC; 88 monotime_coarse_set_mock_time_nsec(curr_mocked_time); 89 monotime_set_mock_time_nsec(curr_mocked_time); 90 } 91 92 /* These lists of circuit endpoints send to eachother via 93 * circuit_package_relay_cell_mocked */ 94 static smartlist_t *client_circs; 95 static smartlist_t *exit_circs; 96 static smartlist_t *client_streams; 97 static smartlist_t *exit_streams; 98 99 typedef struct { 100 circuit_t *client; 101 circuit_t *exit; 102 } circ_pair_t; 103 static smartlist_t *circ_pairs; 104 105 static void 106 simulate_circuit_built(circuit_t *client, circuit_t *exit) 107 { 108 circ_pair_t *pair = tor_malloc_zero(sizeof(circ_pair_t)); 109 pair->client = client; 110 pair->exit = exit; 111 smartlist_add(circ_pairs, pair); 112 } 113 114 static origin_circuit_t * 115 circuit_establish_circuit_conflux_mock(const uint8_t *conflux_nonce, 116 uint8_t purpose, extend_info_t *exit_ei, 117 int flags) 118 { 119 (void)exit_ei; 120 (void)flags; 121 origin_circuit_t *circ = origin_circuit_init(purpose, flags); 122 circ->base_.conflux_pending_nonce = tor_memdup(conflux_nonce, DIGEST256_LEN); 123 circ->base_.purpose = CIRCUIT_PURPOSE_CONFLUX_UNLINKED; 124 smartlist_add(client_circs, circ); 125 126 // This also moves the clock forward as if these hops were opened.. 127 // Not a problem, unless we want to accurately test buildtimeouts 128 simulate_single_hop_extend(circ, 0); 129 simulate_single_hop_extend(circ, 0); 130 simulate_single_hop_extend(circ, 1); 131 circ->cpath->prev->ccontrol = tor_malloc_zero(sizeof(congestion_control_t)); 132 circ->cpath->prev->ccontrol->sendme_pending_timestamps = smartlist_new(); 133 circ->cpath->prev->ccontrol->sendme_inc = 31; 134 135 return circ; 136 } 137 138 static void 139 free_fake_origin_circuit(origin_circuit_t *circ) 140 { 141 circuit_clear_cpath(circ); 142 tor_free(circ); 143 } 144 145 void dummy_nop_timer(void); 146 147 static int 148 circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ, 149 cell_direction_t cell_direction, 150 crypt_path_t *layer_hint, streamid_t on_stream, 151 const char *filename, int lineno); 152 153 static void 154 circuitmux_attach_circuit_mock(circuitmux_t *cmux, circuit_t *circ, 155 cell_direction_t direction); 156 157 static void 158 circuitmux_attach_circuit_mock(circuitmux_t *cmux, circuit_t *circ, 159 cell_direction_t direction) 160 { 161 (void)cmux; 162 (void)circ; 163 (void)direction; 164 165 return; 166 } 167 /* For use in the mock_net smartlist queue: 168 * this struct contains a circuit and a cell to 169 * deliver on it. */ 170 typedef struct { 171 circuit_t *circ; 172 cell_t *cell; 173 } cell_delivery_t; 174 175 static smartlist_t *mock_cell_delivery = NULL; 176 177 static int 178 circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ, 179 cell_direction_t cell_direction, 180 crypt_path_t *layer_hint, streamid_t on_stream, 181 const char *filename, int lineno) 182 { 183 (void)cell; (void)on_stream; (void)filename; (void)lineno; 184 (void)cell_direction; 185 circuit_t *dest_circ = NULL; 186 187 // If we have a layer hint, we are sending to the exit. Look 188 // up the exit circ based on our circuit index in the smartlist 189 if (layer_hint) { 190 tor_assert(CIRCUIT_IS_ORIGIN(circ)); 191 tt_int_op(cell_direction, OP_EQ, CELL_DIRECTION_OUT); 192 193 // Search the circ pairs list for the pair whose client is this circ, 194 // and set dest_circ to the exit circ in that pair 195 SMARTLIST_FOREACH_BEGIN(circ_pairs, circ_pair_t *, pair) { 196 if (pair->client == circ) { 197 dest_circ = pair->exit; 198 break; 199 } 200 } SMARTLIST_FOREACH_END(pair); 201 } else { 202 tt_int_op(cell_direction, OP_EQ, CELL_DIRECTION_IN); 203 204 // Search the circ pairs list for the pair whose exit is this circ, 205 // and set dest_circ to the client circ in that pair 206 SMARTLIST_FOREACH_BEGIN(circ_pairs, circ_pair_t *, pair) { 207 if (pair->exit == circ) { 208 dest_circ = pair->client; 209 break; 210 } 211 } SMARTLIST_FOREACH_END(pair); 212 } 213 214 cell_delivery_t *delivery = tor_malloc_zero(sizeof(cell_delivery_t)); 215 delivery->circ = dest_circ; 216 delivery->cell = tor_memdup(cell, sizeof(cell_t)); 217 smartlist_add(mock_cell_delivery, delivery); 218 done: 219 return 0; 220 } 221 222 /** Pull the next cell from the mock delivery queue and deliver it. */ 223 static void 224 process_mock_cell_delivery(void) 225 { 226 relay_header_t rh; 227 relay_msg_t *msg = NULL; 228 229 cell_delivery_t *delivery = smartlist_pop_last(mock_cell_delivery); 230 tor_assert(delivery); 231 cell_t *cell = delivery->cell; 232 circuit_t *dest_circ = delivery->circ; 233 relay_header_unpack(&rh, cell->payload); 234 235 timers_advance_and_run(1); 236 237 msg = relay_msg_decode_cell(RELAY_CELL_FORMAT_V0, cell); 238 239 tor_assert(msg); 240 241 switch (msg->command) { 242 case RELAY_COMMAND_CONFLUX_LINK: 243 tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ)); 244 conflux_process_link(dest_circ, msg); 245 break; 246 case RELAY_COMMAND_CONFLUX_LINKED: 247 tor_assert(CIRCUIT_IS_ORIGIN(dest_circ)); 248 conflux_process_linked(dest_circ, 249 TO_ORIGIN_CIRCUIT(dest_circ)->cpath->prev, 250 msg); 251 break; 252 case RELAY_COMMAND_CONFLUX_LINKED_ACK: 253 tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ)); 254 conflux_process_linked_ack(dest_circ); 255 break; 256 case RELAY_COMMAND_CONFLUX_SWITCH: 257 // We only test the case where the switch is initiated by the client. 258 // It is symmetric, so this should not matter. If we ever want to test 259 // the case where the switch is initiated by the exit, we will need to 260 // get the cpath layer hint for the client. 261 tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ)); 262 conflux_process_switch_command(dest_circ, NULL, msg); 263 break; 264 } 265 266 tor_free(delivery); 267 tor_free(cell); 268 relay_msg_free(msg); 269 return; 270 } 271 272 static uint64_t 273 mock_monotime_absolute_usec(void) 274 { 275 return 100; 276 } 277 278 static int 279 channel_get_addr_if_possible_mock(const channel_t *chan, tor_addr_t *addr_out) 280 { 281 (void)chan; 282 tt_int_op(AF_INET,OP_EQ, tor_addr_parse(addr_out, "18.0.0.1")); 283 return 1; 284 285 done: 286 return 0; 287 } 288 289 static void 290 circuit_mark_for_close_mock(circuit_t *circ, int reason, 291 int line, const char *file) 292 { 293 (void)circ; 294 (void)reason; 295 (void)line; 296 (void)file; 297 298 log_info(LD_CIRC, "Marking circuit for close at %s:%d", file, line); 299 300 if (BUG(circ->marked_for_close)) { 301 log_warn(LD_BUG, 302 "Duplicate call to circuit_mark_for_close at %s:%d" 303 " (first at %s:%d)", file, line, 304 circ->marked_for_close_file, circ->marked_for_close); 305 return; 306 } 307 308 circ->marked_for_close = line; 309 circ->marked_for_close_file = file; 310 circ->marked_for_close_reason = reason; 311 312 if (CIRCUIT_IS_CONFLUX(circ)) { 313 conflux_circuit_has_closed(circ); 314 } 315 316 // Mark the other side for close too. No idea if this even improves things; 317 // We might also want to make this go through the cell queue as a destroy 318 if (CIRCUIT_IS_ORIGIN(circ)) { 319 circuit_t *exit_circ = get_exit_circ(circ); 320 if (!exit_circ->marked_for_close) 321 circuit_mark_for_close_mock(get_exit_circ(circ), reason, line, file); 322 } else { 323 circuit_t *client_circ = get_client_circ(circ); 324 if (!client_circ->marked_for_close) 325 circuit_mark_for_close_mock(get_client_circ(circ), reason, line, file); 326 } 327 328 // XXX: Should we do this? 329 //if (circuits_pending_close == NULL) 330 // circuits_pending_close = smartlist_new(); 331 //smartlist_add(circuits_pending_close, circ); 332 } 333 334 static void 335 simulate_single_hop_extend(origin_circuit_t *client, int exit) 336 { 337 char whatevs_key[CPATH_KEY_MATERIAL_LEN]; 338 char digest[DIGEST_LEN]; 339 tor_addr_t addr = TOR_ADDR_NULL; 340 341 // Advance time a tiny bit so we can calculate an RTT 342 curr_mocked_time += 10 * TOR_NSEC_PER_MSEC; 343 monotime_coarse_set_mock_time_nsec(curr_mocked_time); 344 monotime_set_mock_time_nsec(curr_mocked_time); 345 346 // Add a hop to cpath 347 crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t)); 348 cpath_extend_linked_list(&client->cpath, hop); 349 350 hop->magic = CRYPT_PATH_MAGIC; 351 hop->state = CPATH_STATE_OPEN; 352 353 // add an extend info to indicate if this node supports padding or not. 354 // (set the first byte of the digest for our mocked node_get_by_id) 355 digest[0] = exit; 356 357 hop->extend_info = extend_info_new( 358 exit ? "exit" : "non-exit", 359 digest, NULL, NULL, 360 &addr, exit, NULL, exit); 361 362 cpath_init_circuit_crypto(RELAY_CRYPTO_ALG_TOR1, hop, 363 whatevs_key, sizeof(whatevs_key)); 364 365 hop->package_window = circuit_initial_package_window(); 366 hop->deliver_window = CIRCWINDOW_START; 367 } 368 369 static void 370 test_setup(void) 371 { 372 int64_t actual_mocked_monotime_start; 373 374 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 375 MOCK(channel_get_addr_if_possible, channel_get_addr_if_possible_mock); 376 MOCK(circuit_establish_circuit_conflux, 377 circuit_establish_circuit_conflux_mock); 378 MOCK(circuit_package_relay_cell, 379 circuit_package_relay_cell_mock); 380 MOCK(circuit_mark_for_close_, 381 circuit_mark_for_close_mock); 382 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 383 testing_enable_reproducible_rng(); 384 385 monotime_init(); 386 monotime_enable_test_mocking(); 387 actual_mocked_monotime_start = MONOTIME_MOCK_START; 388 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 389 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 390 curr_mocked_time = actual_mocked_monotime_start; 391 392 client_circs = smartlist_new(); 393 exit_circs = smartlist_new(); 394 circ_pairs = smartlist_new(); 395 mock_cell_delivery = smartlist_new(); 396 dummy_channel.cmux = circuitmux_alloc(); 397 398 get_circuit_build_times_mutable()->timeout_ms = 1000; 399 400 congestion_control_set_cc_enabled(); 401 max_unlinked_leg_retry = UINT32_MAX; 402 } 403 404 static void 405 test_clear_circs(void) 406 { 407 conflux_notify_shutdown(); 408 SMARTLIST_FOREACH(circ_pairs, circ_pair_t *, circ_pair, { 409 tor_free(circ_pair); 410 }); 411 SMARTLIST_FOREACH(client_circs, circuit_t *, client_side, { 412 conflux_circuit_about_to_free(client_side); 413 circuit_free(client_side); 414 }); 415 SMARTLIST_FOREACH(exit_circs, or_circuit_t *, relay_side, { 416 free_fake_orcirc(relay_side); 417 }); 418 419 smartlist_clear(circ_pairs); 420 smartlist_clear(client_circs); 421 smartlist_clear(exit_circs); 422 423 if (client_streams) { 424 // Free each edge connection 425 SMARTLIST_FOREACH(client_streams, edge_connection_t *, edge_conn, { 426 connection_free_minimal(TO_CONN(edge_conn)); 427 }); 428 smartlist_free(client_streams); 429 } 430 431 if (exit_streams) { 432 // Free each edge connection 433 SMARTLIST_FOREACH(exit_streams, edge_connection_t *, edge_conn, { 434 connection_free_minimal(TO_CONN(edge_conn)); 435 }); 436 smartlist_free(exit_streams); 437 } 438 439 tor_assert(smartlist_len(mock_cell_delivery) == 0); 440 441 (void)free_fake_origin_circuit; 442 443 /* Clear shutdown flag so we can resume testing again. */ 444 conflux_clear_shutdown(); 445 } 446 447 static void 448 test_teardown(void) 449 { 450 conflux_pool_free_all(); 451 smartlist_free(client_circs); 452 smartlist_free(exit_circs); 453 smartlist_free(mock_cell_delivery); 454 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 455 circuitmux_free(dummy_channel.cmux); 456 testing_disable_reproducible_rng(); 457 } 458 459 /* Test linking a conflux circuit */ 460 static void 461 test_conflux_link(void *arg) 462 { 463 (void) arg; 464 test_setup(); 465 466 launch_new_set(2); 467 468 // For each circuit in the client_circs list, we need to create an 469 // exit side circuit and simulate two extends 470 SMARTLIST_FOREACH(client_circs, circuit_t *, client_side, { 471 simulate_circuit_build(client_side); 472 473 /* Handle network activity*/ 474 while (smartlist_len(mock_cell_delivery) > 0) { 475 process_mock_cell_delivery(); 476 } 477 }); 478 479 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 480 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 481 482 // Test that the cells have all been delivered 483 tt_int_op(smartlist_len(mock_cell_delivery), OP_EQ, 0); 484 485 // Test that the client side circuits are linked 486 conflux_t *cfx = ((circuit_t*)smartlist_get(client_circs, 0))->conflux; 487 SMARTLIST_FOREACH_BEGIN(client_circs, circuit_t *, client_side) { 488 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 489 tt_ptr_op(client_side->conflux, OP_EQ, cfx); 490 tt_ptr_op(client_side->conflux_pending_nonce, OP_EQ, NULL); 491 } SMARTLIST_FOREACH_END(client_side); 492 493 // Test circuit teardown 494 SMARTLIST_FOREACH_BEGIN(client_circs, circuit_t *, client_side) { 495 circuit_mark_for_close(client_side, END_CIRC_REASON_FINISHED); 496 } SMARTLIST_FOREACH_END(client_side); 497 498 done: 499 test_clear_circs(); 500 test_teardown(); 501 } 502 503 static void 504 simulate_circuit_build(circuit_t *client_circ) 505 { 506 // Create a relay circuit, and simulate the extend and open 507 circuit_t *relay_side = NULL; 508 509 relay_side = (circuit_t*)new_fake_orcirc(&dummy_channel, &dummy_channel); 510 relay_side->purpose = CIRCUIT_PURPOSE_OR; 511 relay_side->n_chan = NULL; // No next hop 512 relay_side->ccontrol = tor_malloc_zero(sizeof(congestion_control_t)); 513 relay_side->ccontrol->sendme_pending_timestamps = smartlist_new(); 514 relay_side->ccontrol->sendme_inc = 31; 515 smartlist_add(exit_circs, relay_side); 516 simulate_circuit_built(client_circ, relay_side); 517 conflux_circuit_has_opened(TO_ORIGIN_CIRCUIT(client_circ)); 518 } 519 520 static circuit_t * 521 simulate_close_retry(circuit_t *close, bool manual_launch) 522 { 523 // Find the dest pair for the circuit in the circ pair list, 524 // and close it too 525 circuit_t *dest = NULL; 526 uint8_t *nonce = NULL; 527 528 if (manual_launch) { 529 nonce = tor_memdup(close->conflux->nonce, DIGEST256_LEN); 530 } 531 532 SMARTLIST_FOREACH_BEGIN(circ_pairs, circ_pair_t *, pair) { 533 if (pair->client == close) { 534 dest = pair->exit; 535 SMARTLIST_DEL_CURRENT_KEEPORDER(circ_pairs, pair); 536 tor_free(pair); 537 } else if (pair->exit == close) { 538 // This function should not be called on the exit side.. 539 tor_assert(0); 540 } 541 } SMARTLIST_FOREACH_END(pair); 542 543 tor_assert(dest); 544 log_info(LD_CIRC, "Simulating close of %p->%p, dest %p->%p", 545 close, close->conflux, dest, dest->conflux); 546 547 // Free all pending cells related to this close in mock_cell_delivery 548 SMARTLIST_FOREACH(mock_cell_delivery, cell_delivery_t *, cd, { 549 if (cd->circ == close || cd->circ == dest) { 550 SMARTLIST_DEL_CURRENT_KEEPORDER(mock_cell_delivery, cd); 551 tor_free(cd->cell); 552 tor_free(cd); 553 } 554 }); 555 556 // When a circuit closes, both ends get notification, 557 // and the client will launch a new circuit. We need to find 558 // that circuit at the end of the list, and then simulate 559 // building it, and creating a relay circuit for it. 560 conflux_circuit_has_closed(close); 561 conflux_circuit_has_closed(dest); 562 563 //tor_assert(digest256map_size(get_unlinked_pool(true)) != 0); 564 565 // Find these legs in our circuit lists, and free them 566 tor_assert(CIRCUIT_IS_ORIGIN(close)); 567 tor_assert(!CIRCUIT_IS_ORIGIN(dest)); 568 SMARTLIST_FOREACH_BEGIN(client_circs, circuit_t *, client_side) { 569 if (client_side == close) { 570 SMARTLIST_DEL_CURRENT_KEEPORDER(client_circs, client_side); 571 conflux_circuit_about_to_free(client_side); 572 circuit_free(client_side); 573 } 574 } SMARTLIST_FOREACH_END(client_side); 575 SMARTLIST_FOREACH_BEGIN(exit_circs, or_circuit_t *, exit_side) { 576 if (exit_side == (or_circuit_t *)dest) { 577 SMARTLIST_DEL_CURRENT_KEEPORDER(exit_circs, exit_side); 578 free_fake_orcirc(exit_side); 579 } 580 } SMARTLIST_FOREACH_END(exit_side); 581 582 if (manual_launch) { 583 // Launch a new leg for this nonce 584 tor_assert(nonce); 585 conflux_launch_leg(nonce); 586 tor_free(nonce); 587 } 588 589 if (smartlist_len(client_circs) == 0) { 590 // No new circuit was launched 591 return NULL; 592 } 593 594 // At this point, a new circuit will have launched on the client 595 // list. Get that circuit from the end of the list and return it 596 circuit_t * circ = smartlist_get(client_circs, 597 smartlist_len(client_circs) - 1); 598 599 //tor_assert(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 600 601 return circ; 602 } 603 604 static void 605 test_retry(void) 606 { 607 log_info(LD_CIRC, "==========NEW RUN ==========="); 608 launch_new_set(2); 609 610 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 611 circuit_t *client1 = smartlist_get(client_circs, 0); 612 circuit_t *client2 = smartlist_get(client_circs, 1); 613 614 get_circuit_build_times_mutable()->timeout_ms = 1000; 615 616 // Dice roll on which leg builds first 617 if (crypto_rand_int(2) == 0) { 618 simulate_circuit_build(client1); 619 simulate_circuit_build(client2); 620 } else { 621 simulate_circuit_build(client2); 622 simulate_circuit_build(client1); 623 } 624 625 while (smartlist_len(mock_cell_delivery) > 0) { 626 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 627 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 628 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 629 630 if (crypto_rand_int(2) == 0) { 631 if (crypto_rand_int(2) == 0) { 632 if (client1->purpose != CIRCUIT_PURPOSE_CONFLUX_LINKED) { 633 client1 = simulate_close_retry(client1, false); 634 simulate_circuit_build(client1); 635 } 636 } else { 637 if (client2->purpose != CIRCUIT_PURPOSE_CONFLUX_LINKED) { 638 client2 = simulate_close_retry(client2, false); 639 simulate_circuit_build(client2); 640 } 641 } 642 } 643 644 process_mock_cell_delivery(); 645 } 646 647 // Test that the cells have all been delivered 648 tt_int_op(smartlist_len(mock_cell_delivery), OP_EQ, 0); 649 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 650 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 651 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 652 653 conflux_t *cfx = ((circuit_t *)smartlist_get(client_circs, 0))->conflux; 654 SMARTLIST_FOREACH_BEGIN(client_circs, circuit_t *, client_side) { 655 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 656 tt_ptr_op(client_side->conflux, OP_EQ, cfx); 657 tt_ptr_op(client_side->conflux_pending_nonce, OP_EQ, NULL); 658 } SMARTLIST_FOREACH_END(client_side); 659 660 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 661 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 662 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 663 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 664 665 cfx = ((circuit_t *)smartlist_get(exit_circs, 0))->conflux; 666 SMARTLIST_FOREACH_BEGIN(exit_circs, circuit_t *, exit_side) { 667 tt_ptr_op(exit_side->conflux, OP_EQ, cfx); 668 tt_ptr_op(exit_side->conflux_pending_nonce, OP_EQ, NULL); 669 } SMARTLIST_FOREACH_END(exit_side); 670 671 // Test circuit teardown 672 SMARTLIST_FOREACH_BEGIN(client_circs, circuit_t *, client_side) { 673 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 674 circuit_mark_for_close(client_side, END_CIRC_REASON_FINISHED); 675 } SMARTLIST_FOREACH_END(client_side); 676 677 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 0); 678 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 679 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 680 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 0); 681 682 test_clear_circs(); 683 684 done: 685 return; 686 } 687 688 /* Test linking a conflux circuit with build failures */ 689 static void 690 test_conflux_link_retry(void *arg) 691 { 692 (void) arg; 693 test_setup(); 694 695 for (int i = 0; i < 500; i++) { 696 test_retry(); 697 } 698 699 test_teardown(); 700 } 701 702 #if 0 703 /* Test closing both circuits in the set before the link handshake completes 704 * on either leg, by closing circuits before process_mock_cell_delivery. 705 * 706 * XXX: This test currently fails because conflux keeps relaunching closed 707 * circuits. We need to set a limit on the number of times we relaunch a 708 * circuit before we can fix this test. 709 */ 710 static void 711 test_conflux_link_fail(void *arg) 712 { 713 (void) arg; 714 test_setup(); 715 716 launch_new_set(2); 717 718 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 719 circuit_t *client1 = smartlist_get(client_circs, 0); 720 circuit_t *client2 = smartlist_get(client_circs, 1); 721 722 get_circuit_build_times_mutable()->timeout_ms = 1000; 723 724 // Close both circuits before the link handshake completes 725 conflux_circuit_has_closed(client1); 726 conflux_circuit_has_closed(client2); 727 728 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 0); 729 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 730 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 731 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 0); 732 done: 733 test_clear_circs(); 734 test_teardown(); 735 } 736 #endif 737 738 // - Relink test: 739 // - More than 2 legs 740 // - Close one linked leg; relink 741 // - Test mismatching sequence numbers for link and data 742 // - This should destroy the whole set 743 // - RTT timeout relinking test 744 // - Three circuits; close 1; retry and link 745 static void 746 test_conflux_link_relink(void *arg) 747 { 748 (void) arg; 749 test_setup(); 750 751 launch_new_set(3); 752 753 tt_int_op(smartlist_len(client_circs), OP_EQ, 3); 754 circuit_t *client1 = smartlist_get(client_circs, 0); 755 circuit_t *client2 = smartlist_get(client_circs, 1); 756 circuit_t *client3 = smartlist_get(client_circs, 2); 757 758 get_circuit_build_times_mutable()->timeout_ms = 1000; 759 760 simulate_circuit_build(client1); 761 simulate_circuit_build(client2); 762 simulate_circuit_build(client3); 763 764 while (smartlist_len(mock_cell_delivery) > 0) { 765 tt_int_op(smartlist_len(client_circs), OP_EQ, 3); 766 tt_int_op(smartlist_len(exit_circs), OP_EQ, 3); 767 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 3); 768 769 process_mock_cell_delivery(); 770 } 771 772 // Now test closing and relinking the third leg 773 client3 = simulate_close_retry(client3, true); 774 simulate_circuit_build(client3); 775 while (smartlist_len(mock_cell_delivery) > 0) { 776 tt_int_op(smartlist_len(client_circs), OP_EQ, 3); 777 tt_int_op(smartlist_len(exit_circs), OP_EQ, 3); 778 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 3); 779 780 process_mock_cell_delivery(); 781 } 782 783 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 784 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 785 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 786 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 787 788 // Now test closing all circuits and verify the conflux object is gone 789 simulate_close_retry(client1, false); 790 simulate_close_retry(client2, false); 791 simulate_close_retry(client3, false); 792 793 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 0); 794 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 795 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 796 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 0); 797 798 done: 799 test_clear_circs(); 800 test_teardown(); 801 } 802 803 #if 0 804 static void 805 test_conflux_close(void *arg) 806 { 807 (void) arg; 808 test_setup(); 809 810 launch_new_set(2); 811 812 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 813 circuit_t *client1 = smartlist_get(client_circs, 0); 814 circuit_t *client2 = smartlist_get(client_circs, 1); 815 816 get_circuit_build_times_mutable()->timeout_ms = 1000; 817 818 simulate_circuit_build(client1); 819 simulate_circuit_build(client2); 820 821 while (smartlist_len(mock_cell_delivery) > 0) { 822 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 823 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 824 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 825 826 process_mock_cell_delivery(); 827 } 828 829 // There are actually 3 kinds of close: mark, mark+free, 830 // and purpose change. We need to test these in link_retry, but 831 // here our focus is on after the set is linked. 832 833 // Additionally, we can close on an unlinked leg, or a non-critical linked 834 // leg, or a critical linked leg that causes teardown 835 // And we can close on linked legs when there are unlinked legs, or not. 836 837 // And we can do this at the client, or the exit. 838 // And we can do this with a circuit that has streams, or not. 839 840 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 0); 841 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 842 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 843 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 0); 844 done: 845 test_clear_circs(); 846 test_teardown(); 847 } 848 #endif 849 850 // Test launching a new set and closing the first leg, but 851 // with mismatched sequence numbers (missing data) 852 // - Test this teardown with only linked circs, and with some 853 // unlinked circs 854 // Test mismatching sequence numbers for link and data: 855 // Test missing sent data from client (link cell mismatch): 856 // Test missing sent data from relay (linked cell mismatch): 857 858 static circuit_t * 859 get_exit_circ(circuit_t *client_circ) 860 { 861 circuit_t *exit_circ = NULL; 862 SMARTLIST_FOREACH_BEGIN(circ_pairs, circ_pair_t *, pair) { 863 if (pair->client == client_circ) { 864 exit_circ = pair->exit; 865 break; 866 } 867 } SMARTLIST_FOREACH_END(pair); 868 tor_assert(exit_circ); 869 return exit_circ; 870 } 871 872 static circuit_t * 873 get_client_circ(circuit_t *exit_circ) 874 { 875 circuit_t *client_circ = NULL; 876 SMARTLIST_FOREACH_BEGIN(circ_pairs, circ_pair_t *, pair) { 877 if (pair->exit == exit_circ) { 878 client_circ = pair->client; 879 break; 880 } 881 } SMARTLIST_FOREACH_END(pair); 882 tor_assert(client_circ); 883 return client_circ; 884 } 885 886 static edge_connection_t * 887 new_client_stream(origin_circuit_t *on_circ) 888 { 889 edge_connection_t *stream = edge_connection_new(CONN_TYPE_EXIT, AF_INET); 890 891 stream->stream_id = get_unique_stream_id_by_circ(on_circ); 892 stream->on_circuit = TO_CIRCUIT(on_circ); 893 stream->cpath_layer = on_circ->cpath->prev; 894 895 stream->next_stream = on_circ->p_streams; 896 on_circ->p_streams = stream; 897 conflux_update_p_streams(on_circ, stream); 898 899 smartlist_add(client_streams, stream); 900 901 return stream; 902 } 903 904 static edge_connection_t * 905 new_exit_stream(circuit_t *on_circ, streamid_t stream_id) 906 { 907 edge_connection_t *stream = edge_connection_new(CONN_TYPE_EXIT, AF_INET); 908 909 stream->stream_id = stream_id; 910 stream->on_circuit = on_circ; 911 912 stream->next_stream = TO_OR_CIRCUIT(on_circ)->n_streams; 913 conflux_update_n_streams(TO_OR_CIRCUIT(on_circ), stream); 914 915 smartlist_add(exit_streams, stream); 916 917 return stream; 918 } 919 920 static void 921 validate_stream_counts(circuit_t *circ, int expected) 922 { 923 int count = 0; 924 925 conflux_validate_stream_lists(circ->conflux); 926 927 if (CIRCUIT_IS_ORIGIN(circ)) { 928 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); 929 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED); 930 /* Iterate over stream list using next_stream pointer, until null */ 931 for (edge_connection_t *stream = ocirc->p_streams; stream; 932 stream = stream->next_stream) { 933 count++; 934 } 935 } else { 936 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); 937 /* Iterate over stream list using next_stream pointer, until null */ 938 for (edge_connection_t *stream = orcirc->n_streams; stream; 939 stream = stream->next_stream) { 940 count++; 941 } 942 } 943 tt_int_op(count, OP_EQ, expected); 944 945 done: 946 return; 947 } 948 949 // - Streams test 950 // - Attach streams 951 // - Fail one leg, free it, attach new leg, new stream 952 // - Fail both legs 953 // - Shutdown 954 // - With streams attached 955 static void 956 test_conflux_link_streams(void *arg) 957 { 958 (void) arg; 959 test_setup(); 960 961 launch_new_set(2); 962 963 client_streams = smartlist_new(); 964 exit_streams = smartlist_new(); 965 966 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 967 circuit_t *client1 = smartlist_get(client_circs, 0); 968 circuit_t *client2 = smartlist_get(client_circs, 1); 969 970 get_circuit_build_times_mutable()->timeout_ms = 1000; 971 972 simulate_circuit_build(client1); 973 simulate_circuit_build(client2); 974 975 while (smartlist_len(mock_cell_delivery) > 0) { 976 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 977 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 978 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 979 980 process_mock_cell_delivery(); 981 } 982 983 // Attach a stream to the client1 circuit 984 new_client_stream(TO_ORIGIN_CIRCUIT(client1)); 985 new_client_stream(TO_ORIGIN_CIRCUIT(client2)); 986 new_client_stream(TO_ORIGIN_CIRCUIT(client1)); 987 new_exit_stream(get_exit_circ(client2), 1); 988 new_exit_stream(get_exit_circ(client1), 1); 989 new_exit_stream(get_exit_circ(client1), 1); 990 991 // Test that we can close the first leg, and attach a new one 992 // with a new stream 993 client1 = simulate_close_retry(client1, true); 994 simulate_circuit_build(client1); 995 996 while (smartlist_len(mock_cell_delivery) > 0) { 997 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 998 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 999 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 1000 1001 process_mock_cell_delivery(); 1002 } 1003 1004 tt_ptr_op(client1->conflux, OP_EQ, client2->conflux); 1005 1006 new_client_stream(TO_ORIGIN_CIRCUIT(client1)); 1007 new_exit_stream(get_exit_circ(client2), 1); 1008 1009 // Use Ensure that there are four streams on each circuit 1010 validate_stream_counts(client1, 4); 1011 validate_stream_counts(client2, 4); 1012 validate_stream_counts(get_exit_circ(client1), 4); 1013 validate_stream_counts(get_exit_circ(client2), 4); 1014 1015 // Test that we can close all streams on either circuit, 1016 // in any order 1017 circuit_detach_stream(get_exit_circ(client1), 1018 TO_OR_CIRCUIT(get_exit_circ(client1))->n_streams); 1019 validate_stream_counts(get_exit_circ(client2), 3); 1020 circuit_detach_stream(get_exit_circ(client2), 1021 TO_OR_CIRCUIT(get_exit_circ(client2))->n_streams->next_stream); 1022 validate_stream_counts(get_exit_circ(client1), 2); 1023 circuit_detach_stream(get_exit_circ(client1), 1024 TO_OR_CIRCUIT(get_exit_circ(client1))->n_streams); 1025 validate_stream_counts(get_exit_circ(client1), 1); 1026 circuit_detach_stream(get_exit_circ(client1), 1027 TO_OR_CIRCUIT(get_exit_circ(client1))->n_streams); 1028 validate_stream_counts(get_exit_circ(client1), 0); 1029 1030 circuit_detach_stream(client1, 1031 TO_ORIGIN_CIRCUIT(client1)->p_streams->next_stream-> 1032 next_stream->next_stream); 1033 circuit_detach_stream(client2, 1034 TO_ORIGIN_CIRCUIT(client2)->p_streams); 1035 circuit_detach_stream(client2, 1036 TO_ORIGIN_CIRCUIT(client2)->p_streams->next_stream); 1037 circuit_detach_stream(client2, 1038 TO_ORIGIN_CIRCUIT(client2)->p_streams); 1039 validate_stream_counts(client1, 0); 1040 validate_stream_counts(client2, 0); 1041 1042 done: 1043 test_clear_circs(); 1044 test_teardown(); 1045 } 1046 1047 // Right now this does not involve congestion control.. But it could, 1048 // if we actually build and send real RELAY_DATA cells (and also handle them 1049 // and SENDME cells in the mocked cell delivery) 1050 static void 1051 send_fake_cell(circuit_t *client_circ) 1052 { 1053 circuit_t *exit_circ = get_exit_circ(client_circ); 1054 conflux_leg_t *exit_leg = conflux_get_leg(exit_circ->conflux, 1055 exit_circ); 1056 1057 TO_ORIGIN_CIRCUIT(client_circ)->cpath->prev->ccontrol->inflight++; 1058 conflux_note_cell_sent(client_circ->conflux, client_circ, 1059 RELAY_COMMAND_DATA); 1060 1061 exit_leg->last_seq_recv++; 1062 exit_circ->conflux->last_seq_delivered++; 1063 } 1064 1065 static circuit_t * 1066 send_until_switch(circuit_t *client_circ) 1067 { 1068 conflux_leg_t *client_leg = conflux_get_leg(client_circ->conflux, 1069 client_circ); 1070 circuit_t *exit_circ = get_exit_circ(client_circ); 1071 conflux_leg_t *exit_leg = conflux_get_leg(exit_circ->conflux, 1072 exit_circ); 1073 circuit_t *next_circ = client_circ; 1074 int i = 0; 1075 1076 // XXX: This is a hack so the tests pass using cc->sendme_inc 1077 // (There is another hack in circuit_ready_to_send() that causes 1078 // us to block early below, and return NULL for next_circ) 1079 TO_ORIGIN_CIRCUIT(client_circ)->cpath->prev->ccontrol->sendme_inc = 0; 1080 1081 while (client_circ == next_circ) { 1082 next_circ = conflux_decide_circ_for_send(client_circ->conflux, client_circ, 1083 RELAY_COMMAND_DATA); 1084 tor_assert(next_circ); 1085 send_fake_cell(next_circ); 1086 i++; 1087 } 1088 1089 // XXX: This too: 1090 TO_ORIGIN_CIRCUIT(client_circ)->cpath->prev->ccontrol->sendme_inc = 31; 1091 1092 log_info(LD_CIRC, "Sent %d cells on client circ", i-1); 1093 process_mock_cell_delivery(); 1094 1095 circuit_t *new_client = 1096 (circuit_t*)conflux_decide_next_circ(client_circ->conflux); 1097 tt_ptr_op(new_client, OP_NE, client_circ); 1098 conflux_leg_t *new_client_leg = conflux_get_leg(new_client->conflux, 1099 new_client); 1100 circuit_t *new_exit = get_exit_circ(new_client); 1101 conflux_leg_t *new_exit_leg = conflux_get_leg(new_exit->conflux, 1102 new_exit); 1103 1104 // Verify sequence numbers make sense 1105 tt_int_op(new_client_leg->last_seq_sent, OP_EQ, client_leg->last_seq_sent+1); 1106 tt_int_op(new_client_leg->last_seq_recv, OP_EQ, client_leg->last_seq_recv); 1107 tt_int_op(exit_leg->last_seq_sent, OP_EQ, new_exit_leg->last_seq_sent); 1108 tt_int_op(exit_leg->last_seq_recv+1, OP_EQ, new_exit_leg->last_seq_recv); 1109 1110 tt_int_op(client_leg->last_seq_sent+1, OP_EQ, new_exit_leg->last_seq_recv); 1111 tt_int_op(client_leg->last_seq_recv, OP_EQ, new_exit_leg->last_seq_sent); 1112 1113 done: 1114 return new_client; 1115 } 1116 1117 /** 1118 * This tests switching as well as the UDP optimization that attaches 1119 * a third circuit and closes the slowest one. (This optimization is not 1120 * implemented in C-Tor but must be supported at exits, for arti). 1121 */ 1122 static void 1123 test_conflux_switch(void *arg) 1124 { 1125 (void) arg; 1126 test_setup(); 1127 DEFAULT_EXIT_UX = CONFLUX_UX_HIGH_THROUGHPUT; 1128 1129 launch_new_set(2); 1130 1131 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 1132 circuit_t *client1 = smartlist_get(client_circs, 0); 1133 circuit_t *client2 = smartlist_get(client_circs, 1); 1134 get_circuit_build_times_mutable()->timeout_ms = 1000; 1135 1136 simulate_circuit_build(client1); 1137 simulate_circuit_build(client2); 1138 1139 circuit_t *exit1 = get_exit_circ(client1); 1140 circuit_t *exit2 = get_exit_circ(client2); 1141 circuit_t *next_circ = client1; 1142 1143 while (smartlist_len(mock_cell_delivery) > 0) { 1144 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 1145 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 1146 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 1147 1148 process_mock_cell_delivery(); 1149 } 1150 1151 // Check to make sure everything is linked`up 1152 tt_ptr_op(client1->conflux, OP_EQ, client2->conflux); 1153 tt_ptr_op(exit1->conflux, OP_EQ, exit2->conflux); 1154 tt_ptr_op(client1->conflux, OP_NE, NULL); 1155 tt_ptr_op(exit1->conflux, OP_NE, NULL); 1156 tt_int_op(smartlist_len(client1->conflux->legs), OP_EQ, 2); 1157 tt_int_op(smartlist_len(exit1->conflux->legs), OP_EQ, 2); 1158 tt_int_op(client1->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1159 tt_int_op(client2->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1160 1161 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 1162 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 1163 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 1164 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 1165 tt_ptr_op(get_exit_circ(client1), OP_EQ, exit1); 1166 tt_ptr_op(get_exit_circ(client2), OP_EQ, exit2); 1167 1168 // Give circuits approximately equal RTT: 1169 conflux_update_rtt(client1->conflux, client1, 100); 1170 conflux_update_rtt(client2->conflux, client2, 125); 1171 1172 client1->conflux->params.alg = CONFLUX_ALG_LOWRTT; 1173 get_exit_circ(client1)->conflux->params.alg = CONFLUX_ALG_LOWRTT; 1174 TO_ORIGIN_CIRCUIT(client1)->cpath->prev->ccontrol->cwnd = 300; 1175 TO_ORIGIN_CIRCUIT(client2)->cpath->prev->ccontrol->cwnd = 300; 1176 1177 // Keep sending fake cells until we decide to switch four times 1178 for (int i = 0; i < 4; i++) { 1179 next_circ = send_until_switch(next_circ); 1180 1181 // XXX: This can't be set to 0 or we will decide we can switch immediately, 1182 // because the client1 has a lower RTT 1183 TO_ORIGIN_CIRCUIT(client1)->cpath->prev->ccontrol->inflight = 1; 1184 1185 // Check to make sure everything is linked`up 1186 tt_ptr_op(client1->conflux, OP_EQ, client2->conflux); 1187 tt_ptr_op(exit1->conflux, OP_EQ, exit2->conflux); 1188 tt_ptr_op(client1->conflux, OP_NE, NULL); 1189 tt_ptr_op(exit1->conflux, OP_NE, NULL); 1190 tt_int_op(smartlist_len(client1->conflux->legs), OP_EQ, 2); 1191 tt_int_op(smartlist_len(exit1->conflux->legs), OP_EQ, 2); 1192 tt_int_op(client1->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1193 tt_int_op(client2->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1194 1195 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 1196 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 1197 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 1198 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 1199 1200 tt_ptr_op(get_exit_circ(client1), OP_EQ, exit1); 1201 tt_ptr_op(get_exit_circ(client2), OP_EQ, exit2); 1202 tt_ptr_op(next_circ, OP_EQ, client2); 1203 1204 next_circ = send_until_switch(next_circ); 1205 1206 // Check to make sure everything is linked`up 1207 tt_ptr_op(client1->conflux, OP_EQ, client2->conflux); 1208 tt_ptr_op(exit1->conflux, OP_EQ, exit2->conflux); 1209 tt_ptr_op(client1->conflux, OP_NE, NULL); 1210 tt_ptr_op(exit1->conflux, OP_NE, NULL); 1211 tt_int_op(smartlist_len(client1->conflux->legs), OP_EQ, 2); 1212 tt_int_op(smartlist_len(exit1->conflux->legs), OP_EQ, 2); 1213 tt_int_op(client1->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1214 tt_int_op(client2->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1215 1216 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 1217 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 1218 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 1219 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 1220 1221 tt_ptr_op(get_exit_circ(client1), OP_EQ, exit1); 1222 tt_ptr_op(get_exit_circ(client2), OP_EQ, exit2); 1223 tt_ptr_op(next_circ, OP_EQ, client1); 1224 1225 TO_ORIGIN_CIRCUIT(client2)->cpath->prev->ccontrol->inflight = 0; 1226 } 1227 1228 // Try the UDP minRTT reconnect optimization a few times 1229 for (int i = 0; i < 500; i++) { 1230 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 1231 client1 = smartlist_get(client_circs, 0); 1232 client2 = smartlist_get(client_circs, 1); 1233 exit1 = get_exit_circ(client1); 1234 exit2 = get_exit_circ(client2); 1235 1236 // Attach a third leg 1237 conflux_launch_leg(client1->conflux->nonce); 1238 1239 // It should be added to the end of the local test list 1240 circuit_t *client3 = smartlist_get(client_circs, 1241 smartlist_len(client_circs)-1); 1242 simulate_circuit_build(client3); 1243 1244 while (smartlist_len(mock_cell_delivery) > 0) { 1245 tt_int_op(smartlist_len(client_circs), OP_EQ, 3); 1246 tt_int_op(smartlist_len(exit_circs), OP_EQ, 3); 1247 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 3); 1248 1249 process_mock_cell_delivery(); 1250 } 1251 1252 circuit_t *exit3 = get_exit_circ(client3); 1253 1254 // Check to make sure everything is linked`up 1255 tt_ptr_op(client3->conflux, OP_EQ, client2->conflux); 1256 tt_ptr_op(exit3->conflux, OP_EQ, exit2->conflux); 1257 tt_ptr_op(client3->conflux, OP_NE, NULL); 1258 tt_ptr_op(exit3->conflux, OP_NE, NULL); 1259 tt_int_op(smartlist_len(client1->conflux->legs), OP_EQ, 3); 1260 tt_int_op(smartlist_len(exit1->conflux->legs), OP_EQ, 3); 1261 tt_int_op(client3->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1262 1263 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 1264 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 1265 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 1266 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 1267 1268 conflux_update_rtt(client3->conflux, client3, 1269 crypto_rand_int_range(90, 200)); 1270 TO_ORIGIN_CIRCUIT(client3)->cpath->prev->ccontrol->cwnd = 300; 1271 1272 circuit_t *circ_close = NULL; 1273 uint64_t max_rtt = 0; 1274 // Pick the leg with the highest RTT and close it 1275 tor_assert(client3); 1276 tor_assert(client3->conflux); 1277 tor_assert(client3->conflux->legs); 1278 CONFLUX_FOR_EACH_LEG_BEGIN(client3->conflux, leg) { 1279 if (client3->conflux->curr_leg == leg) 1280 continue; 1281 1282 if (leg->circ_rtts_usec > max_rtt) { 1283 max_rtt = leg->circ_rtts_usec; 1284 circ_close = leg->circ; 1285 } 1286 } CONFLUX_FOR_EACH_LEG_END(leg); 1287 1288 // Let the second leg "send" all data and close it. 1289 tor_assert(circ_close); 1290 tor_assert(circ_close->conflux); 1291 tor_assert(circ_close->conflux->legs); 1292 CONFLUX_FOR_EACH_LEG_BEGIN(circ_close->conflux, leg) { 1293 TO_ORIGIN_CIRCUIT(leg->circ)->cpath->prev->ccontrol->inflight = 0; 1294 } CONFLUX_FOR_EACH_LEG_END(leg); 1295 1296 // Close without manual launch (code will not relaunch for linked) 1297 simulate_close_retry(circ_close, false); 1298 1299 tt_int_op(smartlist_len(mock_cell_delivery), OP_EQ, 0); 1300 tt_int_op(smartlist_len(client_circs), OP_EQ, 2); 1301 tt_int_op(smartlist_len(exit_circs), OP_EQ, 2); 1302 tt_int_op(smartlist_len(circ_pairs), OP_EQ, 2); 1303 1304 // Send until we switch to the third leg 1305 next_circ = send_until_switch(next_circ); 1306 1307 // Check to make sure everything is linked`up 1308 tt_ptr_op(next_circ->conflux, OP_NE, NULL); 1309 tt_int_op(smartlist_len(next_circ->conflux->legs), OP_EQ, 2); 1310 tt_int_op(next_circ->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1311 1312 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 1313 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 1314 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 1315 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 1316 1317 CONFLUX_FOR_EACH_LEG_BEGIN(next_circ->conflux, leg) { 1318 TO_ORIGIN_CIRCUIT(leg->circ)->cpath->prev->ccontrol->inflight = 0; 1319 } CONFLUX_FOR_EACH_LEG_END(leg); 1320 1321 // send until we switch back to the first leg 1322 next_circ = send_until_switch(next_circ); 1323 1324 // Check to make sure everything is linked`up 1325 tt_ptr_op(next_circ->conflux, OP_NE, NULL); 1326 tt_int_op(smartlist_len(next_circ->conflux->legs), OP_EQ, 2); 1327 tt_int_op(next_circ->purpose, OP_EQ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 1328 1329 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ, 1); 1330 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ, 0); 1331 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ, 0); 1332 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ, 1); 1333 } 1334 1335 done: 1336 test_clear_circs(); 1337 test_teardown(); 1338 return; 1339 } 1340 1341 struct testcase_t conflux_pool_tests[] = { 1342 { "link", test_conflux_link, TT_FORK, NULL, NULL }, 1343 { "link_retry", test_conflux_link_retry, TT_FORK, NULL, NULL }, 1344 { "link_relink", test_conflux_link_relink, TT_FORK, NULL, NULL }, 1345 { "link_streams", test_conflux_link_streams, TT_FORK, NULL, NULL }, 1346 { "switch", test_conflux_switch, TT_FORK, NULL, NULL }, 1347 // XXX: These two currently fail, because they are not finished: 1348 //{ "link_fail", test_conflux_link_fail, TT_FORK, NULL, NULL }, 1349 //{ "close", test_conflux_close, TT_FORK, NULL, NULL }, 1350 END_OF_TESTCASES 1351 };