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
8 #define CONNECTION_PRIVATE
9 #define TOR_CONGESTION_CONTROL_COMMON_PRIVATE
10 #define TOR_CONGESTION_CONTROL_PRIVATE
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"
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/mainloop/netstatus.h"
33 #include "core/crypto/relay_crypto.h"
34 #include "core/or/protover.h"
35 #include "feature/nodelist/nodelist.h"
36 #include "app/config/config.h"
38 #include "feature/nodelist/routerstatus_st.h"
39 #include "feature/nodelist/networkstatus_st.h"
40 #include "feature/nodelist/node_st.h"
41 #include "core/or/cell_st.h"
42 #include "core/or/crypt_path_st.h"
43 #include "core/or/or_circuit_st.h"
44 #include "core/or/origin_circuit_st.h"
46 #include "core/mainloop/connection.h"
47 #include "core/or/connection_edge.h"
48 #include "core/or/edge_connection_st.h"
50 #include "test/fakecircs.h"
51 #include "test/rng_test_helpers.h"
52 #include "core/or/conflux_pool.h"
53 #include "core/or/conflux_util.h"
54 #include "core/or/conflux_params.h"
55 #include "core/or/conflux.h"
56 #include "core/or/conflux_st.h"
57 #include "trunnel/conflux.h"
58 #include "lib/crypt_ops/crypto_rand.h"
60 /* Start our monotime mocking at 1 second past whatever monotime_init()
61 * thought the actual wall clock time was, for platforms with bad resolution
62 * and weird timevalues during monotime_init() before mocking. */
63 #define MONOTIME_MOCK_START (monotime_absolute_nsec()+\
64 TOR_NSEC_PER_USEC*TOR_USEC_PER_SEC)
66 extern smartlist_t
*connection_array
;
67 void circuit_expire_old_circuits_clientside(void);
69 circid_t
get_unique_circ_id_by_chan(channel_t
*chan
);
71 channel_t
*new_fake_channel(void);
73 static void simulate_single_hop_extend(origin_circuit_t
*client
, int exit
);
74 static void free_fake_origin_circuit(origin_circuit_t
*circ
);
75 static circuit_t
* get_exit_circ(circuit_t
*client_circ
);
76 static circuit_t
* get_client_circ(circuit_t
*exit_circ
);
77 static void simulate_circuit_build(circuit_t
*client_circ
);
79 static int64_t curr_mocked_time
;
81 static channel_t dummy_channel
;
84 timers_advance_and_run(int64_t msec_update
)
86 curr_mocked_time
+= msec_update
*TOR_NSEC_PER_MSEC
;
87 monotime_coarse_set_mock_time_nsec(curr_mocked_time
);
88 monotime_set_mock_time_nsec(curr_mocked_time
);
91 /* These lists of circuit endpoints send to eachother via
92 * circuit_package_relay_cell_mocked */
93 static smartlist_t
*client_circs
;
94 static smartlist_t
*exit_circs
;
95 static smartlist_t
*client_streams
;
96 static smartlist_t
*exit_streams
;
102 static smartlist_t
*circ_pairs
;
105 simulate_circuit_built(circuit_t
*client
, circuit_t
*exit
)
107 circ_pair_t
*pair
= tor_malloc_zero(sizeof(circ_pair_t
));
108 pair
->client
= client
;
110 smartlist_add(circ_pairs
, pair
);
113 static origin_circuit_t
*
114 circuit_establish_circuit_conflux_mock(const uint8_t *conflux_nonce
,
115 uint8_t purpose
, extend_info_t
*exit_ei
,
120 origin_circuit_t
*circ
= origin_circuit_init(purpose
, flags
);
121 circ
->base_
.conflux_pending_nonce
= tor_memdup(conflux_nonce
, DIGEST256_LEN
);
122 circ
->base_
.purpose
= CIRCUIT_PURPOSE_CONFLUX_UNLINKED
;
123 smartlist_add(client_circs
, circ
);
125 // This also moves the clock forward as if these hops were opened..
126 // Not a problem, unless we want to accurately test buildtimeouts
127 simulate_single_hop_extend(circ
, 0);
128 simulate_single_hop_extend(circ
, 0);
129 simulate_single_hop_extend(circ
, 1);
130 circ
->cpath
->prev
->ccontrol
= tor_malloc_zero(sizeof(congestion_control_t
));
131 circ
->cpath
->prev
->ccontrol
->sendme_pending_timestamps
= smartlist_new();
132 circ
->cpath
->prev
->ccontrol
->sendme_inc
= 31;
138 free_fake_origin_circuit(origin_circuit_t
*circ
)
140 circuit_clear_cpath(circ
);
144 void dummy_nop_timer(void);
147 circuit_package_relay_cell_mock(cell_t
*cell
, circuit_t
*circ
,
148 cell_direction_t cell_direction
,
149 crypt_path_t
*layer_hint
, streamid_t on_stream
,
150 const char *filename
, int lineno
);
153 circuitmux_attach_circuit_mock(circuitmux_t
*cmux
, circuit_t
*circ
,
154 cell_direction_t direction
);
157 circuitmux_attach_circuit_mock(circuitmux_t
*cmux
, circuit_t
*circ
,
158 cell_direction_t direction
)
166 /* For use in the mock_net smartlist queue:
167 * this struct contains a circuit and a cell to
174 static smartlist_t
*mock_cell_delivery
= NULL
;
177 circuit_package_relay_cell_mock(cell_t
*cell
, circuit_t
*circ
,
178 cell_direction_t cell_direction
,
179 crypt_path_t
*layer_hint
, streamid_t on_stream
,
180 const char *filename
, int lineno
)
182 (void)cell
; (void)on_stream
; (void)filename
; (void)lineno
;
183 (void)cell_direction
;
184 circuit_t
*dest_circ
= NULL
;
186 // If we have a layer hint, we are sending to the exit. Look
187 // up the exit circ based on our circuit index in the smartlist
189 tor_assert(CIRCUIT_IS_ORIGIN(circ
));
190 tt_int_op(cell_direction
, OP_EQ
, CELL_DIRECTION_OUT
);
192 // Search the circ pairs list for the pair whose client is this circ,
193 // and set dest_circ to the exit circ in that pair
194 SMARTLIST_FOREACH_BEGIN(circ_pairs
, circ_pair_t
*, pair
) {
195 if (pair
->client
== circ
) {
196 dest_circ
= pair
->exit
;
199 } SMARTLIST_FOREACH_END(pair
);
201 tt_int_op(cell_direction
, OP_EQ
, CELL_DIRECTION_IN
);
203 // Search the circ pairs list for the pair whose exit is this circ,
204 // and set dest_circ to the client circ in that pair
205 SMARTLIST_FOREACH_BEGIN(circ_pairs
, circ_pair_t
*, pair
) {
206 if (pair
->exit
== circ
) {
207 dest_circ
= pair
->client
;
210 } SMARTLIST_FOREACH_END(pair
);
213 cell_delivery_t
*delivery
= tor_malloc_zero(sizeof(cell_delivery_t
));
214 delivery
->circ
= dest_circ
;
215 delivery
->cell
= tor_memdup(cell
, sizeof(cell_t
));
216 smartlist_add(mock_cell_delivery
, delivery
);
221 /** Pull the next cell from the mock delivery queue and deliver it. */
223 process_mock_cell_delivery(void)
227 cell_delivery_t
*delivery
= smartlist_pop_last(mock_cell_delivery
);
228 tor_assert(delivery
);
229 cell_t
*cell
= delivery
->cell
;
230 circuit_t
*dest_circ
= delivery
->circ
;
231 relay_header_unpack(&rh
, cell
->payload
);
233 timers_advance_and_run(1);
235 switch (cell
->payload
[0]) {
236 case RELAY_COMMAND_CONFLUX_LINK
:
237 tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ
));
238 conflux_process_link(dest_circ
, cell
, rh
.length
);
240 case RELAY_COMMAND_CONFLUX_LINKED
:
241 tor_assert(CIRCUIT_IS_ORIGIN(dest_circ
));
242 conflux_process_linked(dest_circ
,
243 TO_ORIGIN_CIRCUIT(dest_circ
)->cpath
->prev
,
246 case RELAY_COMMAND_CONFLUX_LINKED_ACK
:
247 tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ
));
248 conflux_process_linked_ack(dest_circ
);
250 case RELAY_COMMAND_CONFLUX_SWITCH
:
251 // We only test the case where the switch is initiated by the client.
252 // It is symmetric, so this should not matter. If we ever want to test
253 // the case where the switch is initiated by the exit, we will need to
254 // get the cpath layer hint for the client.
255 tor_assert(!CIRCUIT_IS_ORIGIN(dest_circ
));
256 conflux_process_switch_command(dest_circ
, NULL
, cell
, &rh
);
266 mock_monotime_absolute_usec(void)
272 channel_get_addr_if_possible_mock(const channel_t
*chan
, tor_addr_t
*addr_out
)
275 tt_int_op(AF_INET
,OP_EQ
, tor_addr_parse(addr_out
, "18.0.0.1"));
283 circuit_mark_for_close_mock(circuit_t
*circ
, int reason
,
284 int line
, const char *file
)
291 log_info(LD_CIRC
, "Marking circuit for close at %s:%d", file
, line
);
293 if (BUG(circ
->marked_for_close
)) {
295 "Duplicate call to circuit_mark_for_close at %s:%d"
296 " (first at %s:%d)", file
, line
,
297 circ
->marked_for_close_file
, circ
->marked_for_close
);
301 circ
->marked_for_close
= line
;
302 circ
->marked_for_close_file
= file
;
303 circ
->marked_for_close_reason
= reason
;
305 if (CIRCUIT_IS_CONFLUX(circ
)) {
306 conflux_circuit_has_closed(circ
);
309 // Mark the other side for close too. No idea if this even improves things;
310 // We might also want to make this go through the cell queue as a destroy
311 if (CIRCUIT_IS_ORIGIN(circ
)) {
312 circuit_t
*exit_circ
= get_exit_circ(circ
);
313 if (!exit_circ
->marked_for_close
)
314 circuit_mark_for_close_mock(get_exit_circ(circ
), reason
, line
, file
);
316 circuit_t
*client_circ
= get_client_circ(circ
);
317 if (!client_circ
->marked_for_close
)
318 circuit_mark_for_close_mock(get_client_circ(circ
), reason
, line
, file
);
321 // XXX: Should we do this?
322 //if (circuits_pending_close == NULL)
323 // circuits_pending_close = smartlist_new();
324 //smartlist_add(circuits_pending_close, circ);
328 simulate_single_hop_extend(origin_circuit_t
*client
, int exit
)
330 char whatevs_key
[CPATH_KEY_MATERIAL_LEN
];
331 char digest
[DIGEST_LEN
];
334 // Advance time a tiny bit so we can calculate an RTT
335 curr_mocked_time
+= 10 * TOR_NSEC_PER_MSEC
;
336 monotime_coarse_set_mock_time_nsec(curr_mocked_time
);
337 monotime_set_mock_time_nsec(curr_mocked_time
);
339 // Add a hop to cpath
340 crypt_path_t
*hop
= tor_malloc_zero(sizeof(crypt_path_t
));
341 cpath_extend_linked_list(&client
->cpath
, hop
);
343 hop
->magic
= CRYPT_PATH_MAGIC
;
344 hop
->state
= CPATH_STATE_OPEN
;
346 // add an extend info to indicate if this node supports padding or not.
347 // (set the first byte of the digest for our mocked node_get_by_id)
350 hop
->extend_info
= extend_info_new(
351 exit
? "exit" : "non-exit",
352 digest
, NULL
, NULL
, NULL
,
353 &addr
, exit
, NULL
, exit
);
355 cpath_init_circuit_crypto(hop
, whatevs_key
, sizeof(whatevs_key
), 0, 0);
357 hop
->package_window
= circuit_initial_package_window();
358 hop
->deliver_window
= CIRCWINDOW_START
;
364 int64_t actual_mocked_monotime_start
;
366 MOCK(circuitmux_attach_circuit
, circuitmux_attach_circuit_mock
);
367 MOCK(channel_get_addr_if_possible
, channel_get_addr_if_possible_mock
);
368 MOCK(circuit_establish_circuit_conflux
,
369 circuit_establish_circuit_conflux_mock
);
370 MOCK(circuit_package_relay_cell
,
371 circuit_package_relay_cell_mock
);
372 MOCK(circuit_mark_for_close_
,
373 circuit_mark_for_close_mock
);
374 MOCK(monotime_absolute_usec
, mock_monotime_absolute_usec
);
375 testing_enable_reproducible_rng();
378 monotime_enable_test_mocking();
379 actual_mocked_monotime_start
= MONOTIME_MOCK_START
;
380 monotime_set_mock_time_nsec(actual_mocked_monotime_start
);
381 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start
);
382 curr_mocked_time
= actual_mocked_monotime_start
;
384 client_circs
= smartlist_new();
385 exit_circs
= smartlist_new();
386 circ_pairs
= smartlist_new();
387 mock_cell_delivery
= smartlist_new();
388 dummy_channel
.cmux
= circuitmux_alloc();
390 get_circuit_build_times_mutable()->timeout_ms
= 1000;
392 congestion_control_set_cc_enabled();
393 max_unlinked_leg_retry
= UINT32_MAX
;
397 test_clear_circs(void)
399 conflux_notify_shutdown();
400 SMARTLIST_FOREACH(circ_pairs
, circ_pair_t
*, circ_pair
, {
403 SMARTLIST_FOREACH(client_circs
, circuit_t
*, client_side
, {
404 conflux_circuit_about_to_free(client_side
);
405 circuit_free(client_side
);
407 SMARTLIST_FOREACH(exit_circs
, or_circuit_t
*, relay_side
, {
408 free_fake_orcirc(relay_side
);
411 smartlist_clear(circ_pairs
);
412 smartlist_clear(client_circs
);
413 smartlist_clear(exit_circs
);
415 if (client_streams
) {
416 // Free each edge connection
417 SMARTLIST_FOREACH(client_streams
, edge_connection_t
*, edge_conn
, {
418 connection_free_minimal(TO_CONN(edge_conn
));
420 smartlist_free(client_streams
);
424 // Free each edge connection
425 SMARTLIST_FOREACH(exit_streams
, edge_connection_t
*, edge_conn
, {
426 connection_free_minimal(TO_CONN(edge_conn
));
428 smartlist_free(exit_streams
);
431 tor_assert(smartlist_len(mock_cell_delivery
) == 0);
433 (void)free_fake_origin_circuit
;
435 /* Clear shutdown flag so we can resume testing again. */
436 conflux_clear_shutdown();
442 conflux_pool_free_all();
443 smartlist_free(client_circs
);
444 smartlist_free(exit_circs
);
445 smartlist_free(mock_cell_delivery
);
446 circuitmux_detach_all_circuits(dummy_channel
.cmux
, NULL
);
447 circuitmux_free(dummy_channel
.cmux
);
448 testing_disable_reproducible_rng();
451 /* Test linking a conflux circuit */
453 test_conflux_link(void *arg
)
460 // For each circuit in the client_circs list, we need to create an
461 // exit side circuit and simulate two extends
462 SMARTLIST_FOREACH(client_circs
, circuit_t
*, client_side
, {
463 simulate_circuit_build(client_side
);
465 /* Handle network activity*/
466 while (smartlist_len(mock_cell_delivery
) > 0) {
467 process_mock_cell_delivery();
471 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
472 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
474 // Test that the cells have all been delivered
475 tt_int_op(smartlist_len(mock_cell_delivery
), OP_EQ
, 0);
477 // Test that the client side circuits are linked
478 conflux_t
*cfx
= ((circuit_t
*)smartlist_get(client_circs
, 0))->conflux
;
479 SMARTLIST_FOREACH_BEGIN(client_circs
, circuit_t
*, client_side
) {
480 tt_int_op(client_side
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
481 tt_ptr_op(client_side
->conflux
, OP_EQ
, cfx
);
482 tt_ptr_op(client_side
->conflux_pending_nonce
, OP_EQ
, NULL
);
483 } SMARTLIST_FOREACH_END(client_side
);
485 // Test circuit teardown
486 SMARTLIST_FOREACH_BEGIN(client_circs
, circuit_t
*, client_side
) {
487 circuit_mark_for_close(client_side
, END_CIRC_REASON_FINISHED
);
488 } SMARTLIST_FOREACH_END(client_side
);
496 simulate_circuit_build(circuit_t
*client_circ
)
498 // Create a relay circuit, and simulate the extend and open
499 circuit_t
*relay_side
= NULL
;
501 relay_side
= (circuit_t
*)new_fake_orcirc(&dummy_channel
, &dummy_channel
);
502 relay_side
->purpose
= CIRCUIT_PURPOSE_OR
;
503 relay_side
->n_chan
= NULL
; // No next hop
504 relay_side
->ccontrol
= tor_malloc_zero(sizeof(congestion_control_t
));
505 relay_side
->ccontrol
->sendme_pending_timestamps
= smartlist_new();
506 relay_side
->ccontrol
->sendme_inc
= 31;
507 smartlist_add(exit_circs
, relay_side
);
508 simulate_circuit_built(client_circ
, relay_side
);
509 conflux_circuit_has_opened(TO_ORIGIN_CIRCUIT(client_circ
));
513 simulate_close_retry(circuit_t
*close
, bool manual_launch
)
515 // Find the dest pair for the circuit in the circ pair list,
517 circuit_t
*dest
= NULL
;
518 uint8_t *nonce
= NULL
;
521 nonce
= tor_memdup(close
->conflux
->nonce
, DIGEST256_LEN
);
524 SMARTLIST_FOREACH_BEGIN(circ_pairs
, circ_pair_t
*, pair
) {
525 if (pair
->client
== close
) {
527 SMARTLIST_DEL_CURRENT_KEEPORDER(circ_pairs
, pair
);
529 } else if (pair
->exit
== close
) {
530 // This function should not be called on the exit side..
533 } SMARTLIST_FOREACH_END(pair
);
536 log_info(LD_CIRC
, "Simulating close of %p->%p, dest %p->%p",
537 close
, close
->conflux
, dest
, dest
->conflux
);
539 // Free all pending cells related to this close in mock_cell_delivery
540 SMARTLIST_FOREACH(mock_cell_delivery
, cell_delivery_t
*, cd
, {
541 if (cd
->circ
== close
|| cd
->circ
== dest
) {
542 SMARTLIST_DEL_CURRENT_KEEPORDER(mock_cell_delivery
, cd
);
548 // When a circuit closes, both ends get notification,
549 // and the client will launch a new circuit. We need to find
550 // that circuit at the end of the list, and then simulate
551 // building it, and creating a relay circuit for it.
552 conflux_circuit_has_closed(close
);
553 conflux_circuit_has_closed(dest
);
555 //tor_assert(digest256map_size(get_unlinked_pool(true)) != 0);
557 // Find these legs in our circuit lists, and free them
558 tor_assert(CIRCUIT_IS_ORIGIN(close
));
559 tor_assert(!CIRCUIT_IS_ORIGIN(dest
));
560 SMARTLIST_FOREACH_BEGIN(client_circs
, circuit_t
*, client_side
) {
561 if (client_side
== close
) {
562 SMARTLIST_DEL_CURRENT_KEEPORDER(client_circs
, client_side
);
563 conflux_circuit_about_to_free(client_side
);
564 circuit_free(client_side
);
566 } SMARTLIST_FOREACH_END(client_side
);
567 SMARTLIST_FOREACH_BEGIN(exit_circs
, or_circuit_t
*, exit_side
) {
568 if (exit_side
== (or_circuit_t
*)dest
) {
569 SMARTLIST_DEL_CURRENT_KEEPORDER(exit_circs
, exit_side
);
570 free_fake_orcirc(exit_side
);
572 } SMARTLIST_FOREACH_END(exit_side
);
575 // Launch a new leg for this nonce
577 conflux_launch_leg(nonce
);
581 if (smartlist_len(client_circs
) == 0) {
582 // No new circuit was launched
586 // At this point, a new circuit will have launched on the client
587 // list. Get that circuit from the end of the list and return it
588 circuit_t
* circ
= smartlist_get(client_circs
,
589 smartlist_len(client_circs
) - 1);
591 //tor_assert(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED);
599 log_info(LD_CIRC
, "==========NEW RUN ===========");
602 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
603 circuit_t
*client1
= smartlist_get(client_circs
, 0);
604 circuit_t
*client2
= smartlist_get(client_circs
, 1);
606 get_circuit_build_times_mutable()->timeout_ms
= 1000;
608 // Dice roll on which leg builds first
609 if (crypto_rand_int(2) == 0) {
610 simulate_circuit_build(client1
);
611 simulate_circuit_build(client2
);
613 simulate_circuit_build(client2
);
614 simulate_circuit_build(client1
);
617 while (smartlist_len(mock_cell_delivery
) > 0) {
618 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
619 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
620 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
622 if (crypto_rand_int(2) == 0) {
623 if (crypto_rand_int(2) == 0) {
624 if (client1
->purpose
!= CIRCUIT_PURPOSE_CONFLUX_LINKED
) {
625 client1
= simulate_close_retry(client1
, false);
626 simulate_circuit_build(client1
);
629 if (client2
->purpose
!= CIRCUIT_PURPOSE_CONFLUX_LINKED
) {
630 client2
= simulate_close_retry(client2
, false);
631 simulate_circuit_build(client2
);
636 process_mock_cell_delivery();
639 // Test that the cells have all been delivered
640 tt_int_op(smartlist_len(mock_cell_delivery
), OP_EQ
, 0);
641 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
642 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
643 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
645 conflux_t
*cfx
= ((circuit_t
*)smartlist_get(client_circs
, 0))->conflux
;
646 SMARTLIST_FOREACH_BEGIN(client_circs
, circuit_t
*, client_side
) {
647 tt_int_op(client_side
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
648 tt_ptr_op(client_side
->conflux
, OP_EQ
, cfx
);
649 tt_ptr_op(client_side
->conflux_pending_nonce
, OP_EQ
, NULL
);
650 } SMARTLIST_FOREACH_END(client_side
);
652 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
653 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
654 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
655 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
657 cfx
= ((circuit_t
*)smartlist_get(exit_circs
, 0))->conflux
;
658 SMARTLIST_FOREACH_BEGIN(exit_circs
, circuit_t
*, exit_side
) {
659 tt_ptr_op(exit_side
->conflux
, OP_EQ
, cfx
);
660 tt_ptr_op(exit_side
->conflux_pending_nonce
, OP_EQ
, NULL
);
661 } SMARTLIST_FOREACH_END(exit_side
);
663 // Test circuit teardown
664 SMARTLIST_FOREACH_BEGIN(client_circs
, circuit_t
*, client_side
) {
665 tt_int_op(client_side
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
666 circuit_mark_for_close(client_side
, END_CIRC_REASON_FINISHED
);
667 } SMARTLIST_FOREACH_END(client_side
);
669 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 0);
670 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
671 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
672 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 0);
680 /* Test linking a conflux circuit with build failures */
682 test_conflux_link_retry(void *arg
)
687 for (int i
= 0; i
< 500; i
++) {
695 /* Test closing both circuits in the set before the link handshake completes
696 * on either leg, by closing circuits before process_mock_cell_delivery.
698 * XXX: This test currently fails because conflux keeps relaunching closed
699 * circuits. We need to set a limit on the number of times we relaunch a
700 * circuit before we can fix this test.
703 test_conflux_link_fail(void *arg
)
710 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
711 circuit_t
*client1
= smartlist_get(client_circs
, 0);
712 circuit_t
*client2
= smartlist_get(client_circs
, 1);
714 get_circuit_build_times_mutable()->timeout_ms
= 1000;
716 // Close both circuits before the link handshake completes
717 conflux_circuit_has_closed(client1
);
718 conflux_circuit_has_closed(client2
);
720 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 0);
721 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
722 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
723 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 0);
731 // - More than 2 legs
732 // - Close one linked leg; relink
733 // - Test mismatching sequence numbers for link and data
734 // - This should destroy the whole set
735 // - RTT timeout relinking test
736 // - Three circuits; close 1; retry and link
738 test_conflux_link_relink(void *arg
)
745 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 3);
746 circuit_t
*client1
= smartlist_get(client_circs
, 0);
747 circuit_t
*client2
= smartlist_get(client_circs
, 1);
748 circuit_t
*client3
= smartlist_get(client_circs
, 2);
750 get_circuit_build_times_mutable()->timeout_ms
= 1000;
752 simulate_circuit_build(client1
);
753 simulate_circuit_build(client2
);
754 simulate_circuit_build(client3
);
756 while (smartlist_len(mock_cell_delivery
) > 0) {
757 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 3);
758 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 3);
759 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 3);
761 process_mock_cell_delivery();
764 // Now test closing and relinking the third leg
765 client3
= simulate_close_retry(client3
, true);
766 simulate_circuit_build(client3
);
767 while (smartlist_len(mock_cell_delivery
) > 0) {
768 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 3);
769 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 3);
770 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 3);
772 process_mock_cell_delivery();
775 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
776 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
777 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
778 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
780 // Now test closing all circuits and verify the conflux object is gone
781 simulate_close_retry(client1
, false);
782 simulate_close_retry(client2
, false);
783 simulate_close_retry(client3
, false);
785 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 0);
786 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
787 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
788 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 0);
797 test_conflux_close(void *arg
)
804 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
805 circuit_t
*client1
= smartlist_get(client_circs
, 0);
806 circuit_t
*client2
= smartlist_get(client_circs
, 1);
808 get_circuit_build_times_mutable()->timeout_ms
= 1000;
810 simulate_circuit_build(client1
);
811 simulate_circuit_build(client2
);
813 while (smartlist_len(mock_cell_delivery
) > 0) {
814 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
815 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
816 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
818 process_mock_cell_delivery();
821 // There are actually 3 kinds of close: mark, mark+free,
822 // and purpose change. We need to test these in link_retry, but
823 // here our focus is on after the set is linked.
825 // Additionally, we can close on an unlinked leg, or a non-critical linked
826 // leg, or a critical linked leg that causes teardown
827 // And we can close on linked legs when there are unlinked legs, or not.
829 // And we can do this at the client, or the exit.
830 // And we can do this with a circuit that has streams, or not.
832 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 0);
833 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
834 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
835 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 0);
842 // Test launching a new set and closing the first leg, but
843 // with mismatched sequence numbers (missing data)
844 // - Test this teardown with only linked circs, and with some
846 // Test mismatching sequence numbers for link and data:
847 // Test missing sent data from client (link cell mismatch):
848 // Test missing sent data from relay (linked cell mismatch):
851 get_exit_circ(circuit_t
*client_circ
)
853 circuit_t
*exit_circ
= NULL
;
854 SMARTLIST_FOREACH_BEGIN(circ_pairs
, circ_pair_t
*, pair
) {
855 if (pair
->client
== client_circ
) {
856 exit_circ
= pair
->exit
;
859 } SMARTLIST_FOREACH_END(pair
);
860 tor_assert(exit_circ
);
865 get_client_circ(circuit_t
*exit_circ
)
867 circuit_t
*client_circ
= NULL
;
868 SMARTLIST_FOREACH_BEGIN(circ_pairs
, circ_pair_t
*, pair
) {
869 if (pair
->exit
== exit_circ
) {
870 client_circ
= pair
->client
;
873 } SMARTLIST_FOREACH_END(pair
);
874 tor_assert(client_circ
);
878 static edge_connection_t
*
879 new_client_stream(origin_circuit_t
*on_circ
)
881 edge_connection_t
*stream
= edge_connection_new(CONN_TYPE_EXIT
, AF_INET
);
883 stream
->stream_id
= get_unique_stream_id_by_circ(on_circ
);
884 stream
->on_circuit
= TO_CIRCUIT(on_circ
);
885 stream
->cpath_layer
= on_circ
->cpath
->prev
;
887 stream
->next_stream
= on_circ
->p_streams
;
888 on_circ
->p_streams
= stream
;
889 conflux_update_p_streams(on_circ
, stream
);
891 smartlist_add(client_streams
, stream
);
896 static edge_connection_t
*
897 new_exit_stream(circuit_t
*on_circ
, streamid_t stream_id
)
899 edge_connection_t
*stream
= edge_connection_new(CONN_TYPE_EXIT
, AF_INET
);
901 stream
->stream_id
= stream_id
;
902 stream
->on_circuit
= on_circ
;
904 stream
->next_stream
= TO_OR_CIRCUIT(on_circ
)->n_streams
;
905 conflux_update_n_streams(TO_OR_CIRCUIT(on_circ
), stream
);
907 smartlist_add(exit_streams
, stream
);
913 validate_stream_counts(circuit_t
*circ
, int expected
)
917 conflux_validate_stream_lists(circ
->conflux
);
919 if (CIRCUIT_IS_ORIGIN(circ
)) {
920 origin_circuit_t
*ocirc
= TO_ORIGIN_CIRCUIT(circ
);
921 tor_assert_nonfatal(circ
->purpose
== CIRCUIT_PURPOSE_CONFLUX_LINKED
);
922 /* Iterate over stream list using next_stream pointer, until null */
923 for (edge_connection_t
*stream
= ocirc
->p_streams
; stream
;
924 stream
= stream
->next_stream
) {
928 or_circuit_t
*orcirc
= TO_OR_CIRCUIT(circ
);
929 /* Iterate over stream list using next_stream pointer, until null */
930 for (edge_connection_t
*stream
= orcirc
->n_streams
; stream
;
931 stream
= stream
->next_stream
) {
935 tt_int_op(count
, OP_EQ
, expected
);
943 // - Fail one leg, free it, attach new leg, new stream
946 // - With streams attached
948 test_conflux_link_streams(void *arg
)
955 client_streams
= smartlist_new();
956 exit_streams
= smartlist_new();
958 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
959 circuit_t
*client1
= smartlist_get(client_circs
, 0);
960 circuit_t
*client2
= smartlist_get(client_circs
, 1);
962 get_circuit_build_times_mutable()->timeout_ms
= 1000;
964 simulate_circuit_build(client1
);
965 simulate_circuit_build(client2
);
967 while (smartlist_len(mock_cell_delivery
) > 0) {
968 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
969 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
970 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
972 process_mock_cell_delivery();
975 // Attach a stream to the client1 circuit
976 new_client_stream(TO_ORIGIN_CIRCUIT(client1
));
977 new_client_stream(TO_ORIGIN_CIRCUIT(client2
));
978 new_client_stream(TO_ORIGIN_CIRCUIT(client1
));
979 new_exit_stream(get_exit_circ(client2
), 1);
980 new_exit_stream(get_exit_circ(client1
), 1);
981 new_exit_stream(get_exit_circ(client1
), 1);
983 // Test that we can close the first leg, and attach a new one
985 client1
= simulate_close_retry(client1
, true);
986 simulate_circuit_build(client1
);
988 while (smartlist_len(mock_cell_delivery
) > 0) {
989 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
990 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
991 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
993 process_mock_cell_delivery();
996 tt_ptr_op(client1
->conflux
, OP_EQ
, client2
->conflux
);
998 new_client_stream(TO_ORIGIN_CIRCUIT(client1
));
999 new_exit_stream(get_exit_circ(client2
), 1);
1001 // Use Ensure that there are four streams on each circuit
1002 validate_stream_counts(client1
, 4);
1003 validate_stream_counts(client2
, 4);
1004 validate_stream_counts(get_exit_circ(client1
), 4);
1005 validate_stream_counts(get_exit_circ(client2
), 4);
1007 // Test that we can close all streams on either circuit,
1009 circuit_detach_stream(get_exit_circ(client1
),
1010 TO_OR_CIRCUIT(get_exit_circ(client1
))->n_streams
);
1011 validate_stream_counts(get_exit_circ(client2
), 3);
1012 circuit_detach_stream(get_exit_circ(client2
),
1013 TO_OR_CIRCUIT(get_exit_circ(client2
))->n_streams
->next_stream
);
1014 validate_stream_counts(get_exit_circ(client1
), 2);
1015 circuit_detach_stream(get_exit_circ(client1
),
1016 TO_OR_CIRCUIT(get_exit_circ(client1
))->n_streams
);
1017 validate_stream_counts(get_exit_circ(client1
), 1);
1018 circuit_detach_stream(get_exit_circ(client1
),
1019 TO_OR_CIRCUIT(get_exit_circ(client1
))->n_streams
);
1020 validate_stream_counts(get_exit_circ(client1
), 0);
1022 circuit_detach_stream(client1
,
1023 TO_ORIGIN_CIRCUIT(client1
)->p_streams
->next_stream
->
1024 next_stream
->next_stream
);
1025 circuit_detach_stream(client2
,
1026 TO_ORIGIN_CIRCUIT(client2
)->p_streams
);
1027 circuit_detach_stream(client2
,
1028 TO_ORIGIN_CIRCUIT(client2
)->p_streams
->next_stream
);
1029 circuit_detach_stream(client2
,
1030 TO_ORIGIN_CIRCUIT(client2
)->p_streams
);
1031 validate_stream_counts(client1
, 0);
1032 validate_stream_counts(client2
, 0);
1039 // Right now this does not involve congestion control.. But it could,
1040 // if we actually build and send real RELAY_DATA cells (and also handle them
1041 // and SENDME cells in the mocked cell delivery)
1043 send_fake_cell(circuit_t
*client_circ
)
1045 circuit_t
*exit_circ
= get_exit_circ(client_circ
);
1046 conflux_leg_t
*exit_leg
= conflux_get_leg(exit_circ
->conflux
,
1049 TO_ORIGIN_CIRCUIT(client_circ
)->cpath
->prev
->ccontrol
->inflight
++;
1050 conflux_note_cell_sent(client_circ
->conflux
, client_circ
,
1051 RELAY_COMMAND_DATA
);
1053 exit_leg
->last_seq_recv
++;
1054 exit_circ
->conflux
->last_seq_delivered
++;
1058 send_until_switch(circuit_t
*client_circ
)
1060 conflux_leg_t
*client_leg
= conflux_get_leg(client_circ
->conflux
,
1062 circuit_t
*exit_circ
= get_exit_circ(client_circ
);
1063 conflux_leg_t
*exit_leg
= conflux_get_leg(exit_circ
->conflux
,
1065 circuit_t
*next_circ
= client_circ
;
1068 // XXX: This is a hack so the tests pass using cc->sendme_inc
1069 // (There is another hack in circuit_ready_to_send() that causes
1070 // us to block early below, and return NULL for next_circ)
1071 TO_ORIGIN_CIRCUIT(client_circ
)->cpath
->prev
->ccontrol
->sendme_inc
= 0;
1073 while (client_circ
== next_circ
) {
1074 next_circ
= conflux_decide_circ_for_send(client_circ
->conflux
, client_circ
,
1075 RELAY_COMMAND_DATA
);
1076 tor_assert(next_circ
);
1077 send_fake_cell(next_circ
);
1082 TO_ORIGIN_CIRCUIT(client_circ
)->cpath
->prev
->ccontrol
->sendme_inc
= 31;
1084 log_info(LD_CIRC
, "Sent %d cells on client circ", i
-1);
1085 process_mock_cell_delivery();
1087 circuit_t
*new_client
=
1088 (circuit_t
*)conflux_decide_next_circ(client_circ
->conflux
);
1089 tt_ptr_op(new_client
, OP_NE
, client_circ
);
1090 conflux_leg_t
*new_client_leg
= conflux_get_leg(new_client
->conflux
,
1092 circuit_t
*new_exit
= get_exit_circ(new_client
);
1093 conflux_leg_t
*new_exit_leg
= conflux_get_leg(new_exit
->conflux
,
1096 // Verify sequence numbers make sense
1097 tt_int_op(new_client_leg
->last_seq_sent
, OP_EQ
, client_leg
->last_seq_sent
+1);
1098 tt_int_op(new_client_leg
->last_seq_recv
, OP_EQ
, client_leg
->last_seq_recv
);
1099 tt_int_op(exit_leg
->last_seq_sent
, OP_EQ
, new_exit_leg
->last_seq_sent
);
1100 tt_int_op(exit_leg
->last_seq_recv
+1, OP_EQ
, new_exit_leg
->last_seq_recv
);
1102 tt_int_op(client_leg
->last_seq_sent
+1, OP_EQ
, new_exit_leg
->last_seq_recv
);
1103 tt_int_op(client_leg
->last_seq_recv
, OP_EQ
, new_exit_leg
->last_seq_sent
);
1110 * This tests switching as well as the UDP optimization that attaches
1111 * a third circuit and closes the slowest one. (This optimization is not
1112 * implemented in C-Tor but must be supported at exits, for arti).
1115 test_conflux_switch(void *arg
)
1119 DEFAULT_EXIT_UX
= CONFLUX_UX_HIGH_THROUGHPUT
;
1123 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
1124 circuit_t
*client1
= smartlist_get(client_circs
, 0);
1125 circuit_t
*client2
= smartlist_get(client_circs
, 1);
1126 get_circuit_build_times_mutable()->timeout_ms
= 1000;
1128 simulate_circuit_build(client1
);
1129 simulate_circuit_build(client2
);
1131 circuit_t
*exit1
= get_exit_circ(client1
);
1132 circuit_t
*exit2
= get_exit_circ(client2
);
1133 circuit_t
*next_circ
= client1
;
1135 while (smartlist_len(mock_cell_delivery
) > 0) {
1136 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
1137 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
1138 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
1140 process_mock_cell_delivery();
1143 // Check to make sure everything is linked`up
1144 tt_ptr_op(client1
->conflux
, OP_EQ
, client2
->conflux
);
1145 tt_ptr_op(exit1
->conflux
, OP_EQ
, exit2
->conflux
);
1146 tt_ptr_op(client1
->conflux
, OP_NE
, NULL
);
1147 tt_ptr_op(exit1
->conflux
, OP_NE
, NULL
);
1148 tt_int_op(smartlist_len(client1
->conflux
->legs
), OP_EQ
, 2);
1149 tt_int_op(smartlist_len(exit1
->conflux
->legs
), OP_EQ
, 2);
1150 tt_int_op(client1
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1151 tt_int_op(client2
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1153 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
1154 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
1155 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
1156 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
1157 tt_ptr_op(get_exit_circ(client1
), OP_EQ
, exit1
);
1158 tt_ptr_op(get_exit_circ(client2
), OP_EQ
, exit2
);
1160 // Give circuits approximately equal RTT:
1161 conflux_update_rtt(client1
->conflux
, client1
, 100);
1162 conflux_update_rtt(client2
->conflux
, client2
, 125);
1164 client1
->conflux
->params
.alg
= CONFLUX_ALG_LOWRTT
;
1165 get_exit_circ(client1
)->conflux
->params
.alg
= CONFLUX_ALG_LOWRTT
;
1166 TO_ORIGIN_CIRCUIT(client1
)->cpath
->prev
->ccontrol
->cwnd
= 300;
1167 TO_ORIGIN_CIRCUIT(client2
)->cpath
->prev
->ccontrol
->cwnd
= 300;
1169 // Keep sending fake cells until we decide to switch four times
1170 for (int i
= 0; i
< 4; i
++) {
1171 next_circ
= send_until_switch(next_circ
);
1173 // XXX: This can't be set to 0 or we will decide we can switch immediately,
1174 // because the client1 has a lower RTT
1175 TO_ORIGIN_CIRCUIT(client1
)->cpath
->prev
->ccontrol
->inflight
= 1;
1177 // Check to make sure everything is linked`up
1178 tt_ptr_op(client1
->conflux
, OP_EQ
, client2
->conflux
);
1179 tt_ptr_op(exit1
->conflux
, OP_EQ
, exit2
->conflux
);
1180 tt_ptr_op(client1
->conflux
, OP_NE
, NULL
);
1181 tt_ptr_op(exit1
->conflux
, OP_NE
, NULL
);
1182 tt_int_op(smartlist_len(client1
->conflux
->legs
), OP_EQ
, 2);
1183 tt_int_op(smartlist_len(exit1
->conflux
->legs
), OP_EQ
, 2);
1184 tt_int_op(client1
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1185 tt_int_op(client2
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1187 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
1188 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
1189 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
1190 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
1192 tt_ptr_op(get_exit_circ(client1
), OP_EQ
, exit1
);
1193 tt_ptr_op(get_exit_circ(client2
), OP_EQ
, exit2
);
1194 tt_ptr_op(next_circ
, OP_EQ
, client2
);
1196 next_circ
= send_until_switch(next_circ
);
1198 // Check to make sure everything is linked`up
1199 tt_ptr_op(client1
->conflux
, OP_EQ
, client2
->conflux
);
1200 tt_ptr_op(exit1
->conflux
, OP_EQ
, exit2
->conflux
);
1201 tt_ptr_op(client1
->conflux
, OP_NE
, NULL
);
1202 tt_ptr_op(exit1
->conflux
, OP_NE
, NULL
);
1203 tt_int_op(smartlist_len(client1
->conflux
->legs
), OP_EQ
, 2);
1204 tt_int_op(smartlist_len(exit1
->conflux
->legs
), OP_EQ
, 2);
1205 tt_int_op(client1
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1206 tt_int_op(client2
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1208 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
1209 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
1210 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
1211 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
1213 tt_ptr_op(get_exit_circ(client1
), OP_EQ
, exit1
);
1214 tt_ptr_op(get_exit_circ(client2
), OP_EQ
, exit2
);
1215 tt_ptr_op(next_circ
, OP_EQ
, client1
);
1217 TO_ORIGIN_CIRCUIT(client2
)->cpath
->prev
->ccontrol
->inflight
= 0;
1220 // Try the UDP minRTT reconnect optimization a few times
1221 for (int i
= 0; i
< 500; i
++) {
1222 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
1223 client1
= smartlist_get(client_circs
, 0);
1224 client2
= smartlist_get(client_circs
, 1);
1225 exit1
= get_exit_circ(client1
);
1226 exit2
= get_exit_circ(client2
);
1228 // Attach a third leg
1229 conflux_launch_leg(client1
->conflux
->nonce
);
1231 // It should be added to the end of the local test list
1232 circuit_t
*client3
= smartlist_get(client_circs
,
1233 smartlist_len(client_circs
)-1);
1234 simulate_circuit_build(client3
);
1236 while (smartlist_len(mock_cell_delivery
) > 0) {
1237 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 3);
1238 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 3);
1239 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 3);
1241 process_mock_cell_delivery();
1244 circuit_t
*exit3
= get_exit_circ(client3
);
1246 // Check to make sure everything is linked`up
1247 tt_ptr_op(client3
->conflux
, OP_EQ
, client2
->conflux
);
1248 tt_ptr_op(exit3
->conflux
, OP_EQ
, exit2
->conflux
);
1249 tt_ptr_op(client3
->conflux
, OP_NE
, NULL
);
1250 tt_ptr_op(exit3
->conflux
, OP_NE
, NULL
);
1251 tt_int_op(smartlist_len(client1
->conflux
->legs
), OP_EQ
, 3);
1252 tt_int_op(smartlist_len(exit1
->conflux
->legs
), OP_EQ
, 3);
1253 tt_int_op(client3
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1255 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
1256 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
1257 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
1258 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
1260 conflux_update_rtt(client3
->conflux
, client3
,
1261 crypto_rand_int_range(90, 200));
1262 TO_ORIGIN_CIRCUIT(client3
)->cpath
->prev
->ccontrol
->cwnd
= 300;
1264 circuit_t
*circ_close
= NULL
;
1265 uint64_t max_rtt
= 0;
1266 // Pick the leg with the highest RTT and close it
1267 tor_assert(client3
);
1268 tor_assert(client3
->conflux
);
1269 tor_assert(client3
->conflux
->legs
);
1270 CONFLUX_FOR_EACH_LEG_BEGIN(client3
->conflux
, leg
) {
1271 if (client3
->conflux
->curr_leg
== leg
)
1274 if (leg
->circ_rtts_usec
> max_rtt
) {
1275 max_rtt
= leg
->circ_rtts_usec
;
1276 circ_close
= leg
->circ
;
1278 } CONFLUX_FOR_EACH_LEG_END(leg
);
1280 // Let the second leg "send" all data and close it.
1281 tor_assert(circ_close
);
1282 tor_assert(circ_close
->conflux
);
1283 tor_assert(circ_close
->conflux
->legs
);
1284 CONFLUX_FOR_EACH_LEG_BEGIN(circ_close
->conflux
, leg
) {
1285 TO_ORIGIN_CIRCUIT(leg
->circ
)->cpath
->prev
->ccontrol
->inflight
= 0;
1286 } CONFLUX_FOR_EACH_LEG_END(leg
);
1288 // Close without manual launch (code will not relaunch for linked)
1289 simulate_close_retry(circ_close
, false);
1291 tt_int_op(smartlist_len(mock_cell_delivery
), OP_EQ
, 0);
1292 tt_int_op(smartlist_len(client_circs
), OP_EQ
, 2);
1293 tt_int_op(smartlist_len(exit_circs
), OP_EQ
, 2);
1294 tt_int_op(smartlist_len(circ_pairs
), OP_EQ
, 2);
1296 // Send until we switch to the third leg
1297 next_circ
= send_until_switch(next_circ
);
1299 // Check to make sure everything is linked`up
1300 tt_ptr_op(next_circ
->conflux
, OP_NE
, NULL
);
1301 tt_int_op(smartlist_len(next_circ
->conflux
->legs
), OP_EQ
, 2);
1302 tt_int_op(next_circ
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1304 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
1305 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
1306 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
1307 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
1309 CONFLUX_FOR_EACH_LEG_BEGIN(next_circ
->conflux
, leg
) {
1310 TO_ORIGIN_CIRCUIT(leg
->circ
)->cpath
->prev
->ccontrol
->inflight
= 0;
1311 } CONFLUX_FOR_EACH_LEG_END(leg
);
1313 // send until we switch back to the first leg
1314 next_circ
= send_until_switch(next_circ
);
1316 // Check to make sure everything is linked`up
1317 tt_ptr_op(next_circ
->conflux
, OP_NE
, NULL
);
1318 tt_int_op(smartlist_len(next_circ
->conflux
->legs
), OP_EQ
, 2);
1319 tt_int_op(next_circ
->purpose
, OP_EQ
, CIRCUIT_PURPOSE_CONFLUX_LINKED
);
1321 tt_int_op(digest256map_size(get_linked_pool(true)), OP_EQ
, 1);
1322 tt_int_op(digest256map_size(get_unlinked_pool(true)), OP_EQ
, 0);
1323 tt_int_op(digest256map_size(get_unlinked_pool(false)), OP_EQ
, 0);
1324 tt_int_op(digest256map_size(get_linked_pool(false)), OP_EQ
, 1);
1333 struct testcase_t conflux_pool_tests
[] = {
1334 { "link", test_conflux_link
, TT_FORK
, NULL
, NULL
},
1335 { "link_retry", test_conflux_link_retry
, TT_FORK
, NULL
, NULL
},
1336 { "link_relink", test_conflux_link_relink
, TT_FORK
, NULL
, NULL
},
1337 { "link_streams", test_conflux_link_streams
, TT_FORK
, NULL
, NULL
},
1338 { "switch", test_conflux_switch
, TT_FORK
, NULL
, NULL
},
1339 // XXX: These two currently fail, because they are not finished:
1340 //{ "link_fail", test_conflux_link_fail, TT_FORK, NULL, NULL },
1341 //{ "close", test_conflux_close, TT_FORK, NULL, NULL },