test_circuitpadding.c (114293B)
1 #define CHANNEL_OBJECT_PRIVATE 2 #define TOR_TIMERS_PRIVATE 3 #define CIRCUITPADDING_PRIVATE 4 #define CIRCUITPADDING_MACHINES_PRIVATE 5 #define NETWORKSTATUS_PRIVATE 6 #define CRYPT_PATH_PRIVATE 7 #define RELAY_PRIVATE 8 9 #include "core/or/or.h" 10 #include "test/test.h" 11 #include "test/log_test_helpers.h" 12 #include "lib/testsupport/testsupport.h" 13 #include "core/or/connection_or.h" 14 #include "core/or/channel.h" 15 #include "core/or/channeltls.h" 16 #include "core/or/crypt_path.h" 17 #include <event.h> 18 #include "lib/evloop/compat_libevent.h" 19 #include "lib/time/compat_time.h" 20 #include "lib/defs/time.h" 21 #include "core/or/relay.h" 22 #include "core/or/circuitlist.h" 23 #include "core/or/circuitbuild.h" 24 #include "core/or/circuitpadding.h" 25 #include "core/or/circuitpadding_machines.h" 26 #include "core/or/extendinfo.h" 27 #include "core/or/relay_msg.h" 28 #include "core/mainloop/netstatus.h" 29 #include "core/crypto/relay_crypto.h" 30 #include "core/or/protover.h" 31 #include "feature/nodelist/nodelist.h" 32 #include "app/config/config.h" 33 34 #include "feature/nodelist/routerstatus_st.h" 35 #include "feature/nodelist/networkstatus_st.h" 36 #include "feature/nodelist/node_st.h" 37 #include "core/or/cell_st.h" 38 #include "core/or/crypt_path_st.h" 39 #include "core/or/or_circuit_st.h" 40 #include "core/or/origin_circuit_st.h" 41 42 #include "test/fakecircs.h" 43 #include "test/rng_test_helpers.h" 44 45 /* Start our monotime mocking at 1 second past whatever monotime_init() 46 * thought the actual wall clock time was, for platforms with bad resolution 47 * and weird timevalues during monotime_init() before mocking. */ 48 #define MONOTIME_MOCK_START (monotime_absolute_nsec()+\ 49 TOR_NSEC_PER_USEC*TOR_USEC_PER_SEC) 50 51 extern smartlist_t *connection_array; 52 void circuit_expire_old_circuits_clientside(void); 53 54 circid_t get_unique_circ_id_by_chan(channel_t *chan); 55 void helper_create_basic_machine(void); 56 static void helper_create_conditional_machines(void); 57 58 channel_t *new_fake_channel(void); 59 void test_circuitpadding_negotiation(void *arg); 60 void test_circuitpadding_wronghop(void *arg); 61 void test_circuitpadding_conditions(void *arg); 62 63 void test_circuitpadding_serialize(void *arg); 64 void test_circuitpadding_rtt(void *arg); 65 void test_circuitpadding_tokens(void *arg); 66 void test_circuitpadding_state_length(void *arg); 67 68 static void 69 simulate_single_hop_extend(circuit_t *client, circuit_t *mid_relay, 70 int padding); 71 void free_fake_origin_circuit(origin_circuit_t *circ); 72 73 static int deliver_negotiated = 1; 74 static int64_t curr_mocked_time; 75 76 static node_t padding_node; 77 static node_t non_padding_node; 78 79 static channel_t dummy_channel; 80 static circpad_machine_spec_t circ_client_machine; 81 82 static void 83 timers_advance_and_run(int64_t msec_update) 84 { 85 curr_mocked_time += msec_update*TOR_NSEC_PER_MSEC; 86 monotime_coarse_set_mock_time_nsec(curr_mocked_time); 87 monotime_set_mock_time_nsec(curr_mocked_time); 88 timers_run_pending(); 89 } 90 91 static void 92 nodes_init(void) 93 { 94 padding_node.rs = tor_malloc_zero(sizeof(routerstatus_t)); 95 padding_node.rs->pv.supports_hs_setup_padding = 1; 96 97 non_padding_node.rs = tor_malloc_zero(sizeof(routerstatus_t)); 98 non_padding_node.rs->pv.supports_hs_setup_padding = 0; 99 } 100 101 static void 102 nodes_free(void) 103 { 104 tor_free(padding_node.rs); 105 106 tor_free(non_padding_node.rs); 107 } 108 109 static const node_t * 110 node_get_by_id_mock(const char *identity_digest) 111 { 112 if (identity_digest[0] == 1) { 113 return &padding_node; 114 } else if (identity_digest[0] == 0) { 115 return &non_padding_node; 116 } 117 118 return NULL; 119 } 120 121 static const node_t * 122 circuit_get_nth_node_mock(origin_circuit_t *circ, int hop) 123 { 124 (void) circ; 125 (void) hop; 126 127 return &padding_node; 128 } 129 130 void 131 free_fake_origin_circuit(origin_circuit_t *circ) 132 { 133 circpad_circuit_free_all_machineinfos(TO_CIRCUIT(circ)); 134 circuit_clear_cpath(circ); 135 tor_free(circ); 136 } 137 138 void dummy_nop_timer(void); 139 140 //static int dont_stop_libevent = 0; 141 142 static circuit_t *client_side; 143 static circuit_t *relay_side; 144 145 static int n_client_cells = 0; 146 static int n_relay_cells = 0; 147 148 static int 149 circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ, 150 cell_direction_t cell_direction, 151 crypt_path_t *layer_hint, streamid_t on_stream, 152 const char *filename, int lineno); 153 154 static void 155 circuitmux_attach_circuit_mock(circuitmux_t *cmux, circuit_t *circ, 156 cell_direction_t direction); 157 158 static void 159 circuitmux_attach_circuit_mock(circuitmux_t *cmux, circuit_t *circ, 160 cell_direction_t direction) 161 { 162 (void)cmux; 163 (void)circ; 164 (void)direction; 165 166 return; 167 } 168 169 static int 170 circuit_package_relay_cell_mock(cell_t *cell, circuit_t *circ, 171 cell_direction_t cell_direction, 172 crypt_path_t *layer_hint, streamid_t on_stream, 173 const char *filename, int lineno) 174 { 175 (void)cell; (void)on_stream; (void)filename; (void)lineno; 176 relay_msg_t *msg = NULL; 177 178 msg = relay_msg_decode_cell(RELAY_CELL_FORMAT_V0, cell); 179 if (! msg) 180 goto done; 181 182 if (circ == client_side) { 183 if (cell->payload[0] == RELAY_COMMAND_PADDING_NEGOTIATE) { 184 // Deliver to relay 185 circpad_handle_padding_negotiate(relay_side, msg); 186 } else { 187 188 int is_target_hop = circpad_padding_is_from_expected_hop(circ, 189 layer_hint); 190 tt_int_op(cell_direction, OP_EQ, CELL_DIRECTION_OUT); 191 tt_int_op(is_target_hop, OP_EQ, 1); 192 193 // No need to pretend a padding cell was sent: This event is 194 // now emitted internally when the circuitpadding code sends them. 195 //circpad_cell_event_padding_sent(client_side); 196 197 // Receive padding cell at middle 198 circpad_deliver_recognized_relay_cell_events(relay_side, 199 msg->command, NULL); 200 } 201 n_client_cells++; 202 } else if (circ == relay_side) { 203 tt_int_op(cell_direction, OP_EQ, CELL_DIRECTION_IN); 204 205 if (cell->payload[0] == RELAY_COMMAND_PADDING_NEGOTIATED) { 206 // XXX: blah need right layer_hint.. 207 if (deliver_negotiated) 208 circpad_handle_padding_negotiated(client_side, msg, 209 TO_ORIGIN_CIRCUIT(client_side) 210 ->cpath->next); 211 } else if (cell->payload[0] == RELAY_COMMAND_PADDING_NEGOTIATE) { 212 circpad_handle_padding_negotiate(client_side, msg); 213 } else { 214 // No need to pretend a padding cell was sent: This event is 215 // now emitted internally when the circuitpadding code sends them. 216 //circpad_cell_event_padding_sent(relay_side); 217 218 // Receive padding cell at client 219 circpad_deliver_recognized_relay_cell_events(client_side, 220 msg->command, 221 TO_ORIGIN_CIRCUIT(client_side)->cpath->next); 222 } 223 224 n_relay_cells++; 225 } 226 227 done: 228 relay_msg_free(msg); 229 timers_advance_and_run(1); 230 return 0; 231 } 232 233 // Test reading and writing padding to strings (or options_t + consensus) 234 void 235 test_circuitpadding_serialize(void *arg) 236 { 237 (void)arg; 238 } 239 240 static signed_error_t 241 circpad_send_command_to_hop_mock(origin_circuit_t *circ, uint8_t hopnum, 242 uint8_t relay_command, const uint8_t *payload, 243 ssize_t payload_len) 244 { 245 (void) circ; 246 (void) hopnum; 247 (void) relay_command; 248 (void) payload; 249 (void) payload_len; 250 return 0; 251 } 252 253 void 254 test_circuitpadding_rtt(void *arg) 255 { 256 /* Test Plan: 257 * 258 * 1. Test RTT measurement server side 259 * a. test usage of measured RTT 260 * 2. Test termination of RTT measurement 261 * a. test non-update of RTT 262 * 3. Test client side circuit and non-application of RTT.. 263 */ 264 circpad_delay_t rtt_estimate; 265 int64_t actual_mocked_monotime_start; 266 (void)arg; 267 268 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 269 MOCK(circpad_send_command_to_hop, circpad_send_command_to_hop_mock); 270 testing_enable_reproducible_rng(); 271 272 dummy_channel.cmux = circuitmux_alloc(); 273 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 274 client_side = TO_CIRCUIT(origin_circuit_new()); 275 relay_side->purpose = CIRCUIT_PURPOSE_OR; 276 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 277 278 monotime_init(); 279 monotime_enable_test_mocking(); 280 actual_mocked_monotime_start = MONOTIME_MOCK_START; 281 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 282 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 283 curr_mocked_time = actual_mocked_monotime_start; 284 285 timers_initialize(); 286 circpad_machines_init(); 287 helper_create_basic_machine(); 288 289 MOCK(circuit_package_relay_cell, 290 circuit_package_relay_cell_mock); 291 292 client_side->padding_machine[0] = &circ_client_machine; 293 client_side->padding_info[0] = circpad_circuit_machineinfo_new(client_side, 294 0); 295 296 relay_side->padding_machine[0] = &circ_client_machine; 297 relay_side->padding_info[0] = circpad_circuit_machineinfo_new(client_side,0); 298 299 /* Test 1: Test measuring RTT */ 300 circpad_cell_event_nonpadding_received(relay_side); 301 tt_u64_op(relay_side->padding_info[0]->last_received_time_usec, OP_NE, 0); 302 303 timers_advance_and_run(20); 304 305 circpad_cell_event_nonpadding_sent(relay_side); 306 tt_u64_op(relay_side->padding_info[0]->last_received_time_usec, OP_EQ, 0); 307 308 tt_int_op(relay_side->padding_info[0]->rtt_estimate_usec, OP_GE, 19000); 309 tt_int_op(relay_side->padding_info[0]->rtt_estimate_usec, OP_LE, 30000); 310 tt_int_op(circpad_histogram_bin_to_usec(relay_side->padding_info[0], 0), 311 OP_EQ, 312 relay_side->padding_info[0]->rtt_estimate_usec+ 313 circpad_machine_current_state( 314 relay_side->padding_info[0])->histogram_edges[0]); 315 316 circpad_cell_event_nonpadding_received(relay_side); 317 circpad_cell_event_nonpadding_received(relay_side); 318 tt_u64_op(relay_side->padding_info[0]->last_received_time_usec, OP_NE, 0); 319 timers_advance_and_run(20); 320 circpad_cell_event_nonpadding_sent(relay_side); 321 circpad_cell_event_nonpadding_sent(relay_side); 322 tt_u64_op(relay_side->padding_info[0]->last_received_time_usec, OP_EQ, 0); 323 324 tt_int_op(relay_side->padding_info[0]->rtt_estimate_usec, OP_GE, 20000); 325 tt_int_op(relay_side->padding_info[0]->rtt_estimate_usec, OP_LE, 21000); 326 tt_int_op(circpad_histogram_bin_to_usec(relay_side->padding_info[0], 0), 327 OP_EQ, 328 relay_side->padding_info[0]->rtt_estimate_usec+ 329 circpad_machine_current_state( 330 relay_side->padding_info[0])->histogram_edges[0]); 331 332 /* Test 2: Termination of RTT measurement (from the previous test) */ 333 tt_int_op(relay_side->padding_info[0]->stop_rtt_update, OP_EQ, 1); 334 rtt_estimate = relay_side->padding_info[0]->rtt_estimate_usec; 335 336 circpad_cell_event_nonpadding_received(relay_side); 337 timers_advance_and_run(4); 338 circpad_cell_event_nonpadding_sent(relay_side); 339 340 tt_int_op(relay_side->padding_info[0]->rtt_estimate_usec, OP_EQ, 341 rtt_estimate); 342 tt_u64_op(relay_side->padding_info[0]->last_received_time_usec, OP_EQ, 0); 343 tt_int_op(relay_side->padding_info[0]->stop_rtt_update, OP_EQ, 1); 344 tt_int_op(circpad_histogram_bin_to_usec(relay_side->padding_info[0], 0), 345 OP_EQ, 346 relay_side->padding_info[0]->rtt_estimate_usec+ 347 circpad_machine_current_state( 348 relay_side->padding_info[0])->histogram_edges[0]); 349 350 /* Test 3: Make sure client side machine properly ignores RTT */ 351 circpad_cell_event_nonpadding_received(client_side); 352 tt_u64_op(client_side->padding_info[0]->last_received_time_usec, OP_EQ, 0); 353 354 timers_advance_and_run(20); 355 circpad_cell_event_nonpadding_sent(client_side); 356 tt_u64_op(client_side->padding_info[0]->last_received_time_usec, OP_EQ, 0); 357 358 tt_int_op(client_side->padding_info[0]->rtt_estimate_usec, OP_EQ, 0); 359 tt_int_op(circpad_histogram_bin_to_usec(client_side->padding_info[0], 0), 360 OP_NE, client_side->padding_info[0]->rtt_estimate_usec); 361 tt_int_op(circpad_histogram_bin_to_usec(client_side->padding_info[0], 0), 362 OP_EQ, 363 circpad_machine_current_state( 364 client_side->padding_info[0])->histogram_edges[0]); 365 done: 366 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 367 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 368 circuitmux_free(dummy_channel.cmux); 369 timers_shutdown(); 370 monotime_disable_test_mocking(); 371 UNMOCK(circuit_package_relay_cell); 372 UNMOCK(circuitmux_attach_circuit); 373 tor_free(circ_client_machine.states); 374 testing_disable_reproducible_rng(); 375 376 return; 377 } 378 379 void 380 helper_create_basic_machine(void) 381 { 382 /* Start, burst */ 383 circpad_machine_states_init(&circ_client_machine, 2); 384 385 circ_client_machine.name = "basic"; 386 387 circ_client_machine.states[CIRCPAD_STATE_START]. 388 next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_BURST; 389 circ_client_machine.states[CIRCPAD_STATE_START].use_rtt_estimate = 1; 390 391 circ_client_machine.states[CIRCPAD_STATE_BURST]. 392 next_state[CIRCPAD_EVENT_PADDING_RECV] = CIRCPAD_STATE_BURST; 393 circ_client_machine.states[CIRCPAD_STATE_BURST]. 394 next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_BURST; 395 396 circ_client_machine.states[CIRCPAD_STATE_BURST]. 397 next_state[CIRCPAD_EVENT_NONPADDING_SENT] = CIRCPAD_STATE_CANCEL; 398 399 circ_client_machine.states[CIRCPAD_STATE_BURST].token_removal = 400 CIRCPAD_TOKEN_REMOVAL_HIGHER; 401 402 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_len = 5; 403 404 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[0] = 500; 405 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[1] = 2500; 406 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[2] = 5000; 407 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[3] = 10000; 408 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[4] = 20000; 409 410 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram[0] = 1; 411 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram[1] = 0; 412 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram[2] = 2; 413 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram[3] = 2; 414 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram[4] = 2; 415 416 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_total_tokens = 7; 417 circ_client_machine.states[CIRCPAD_STATE_BURST].use_rtt_estimate = 1; 418 419 return; 420 } 421 422 #define BIG_HISTOGRAM_LEN 10 423 424 /** Setup a machine with a big histogram */ 425 static void 426 helper_create_machine_with_big_histogram(circpad_removal_t removal_strategy) 427 { 428 const int tokens_per_bin = 2; 429 430 /* Start, burst */ 431 circpad_machine_states_init(&circ_client_machine, 2); 432 433 circpad_state_t *burst_state = 434 &circ_client_machine.states[CIRCPAD_STATE_BURST]; 435 436 circ_client_machine.states[CIRCPAD_STATE_START]. 437 next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_BURST; 438 439 burst_state->next_state[CIRCPAD_EVENT_PADDING_RECV] = CIRCPAD_STATE_BURST; 440 burst_state->next_state[CIRCPAD_EVENT_NONPADDING_RECV] =CIRCPAD_STATE_BURST; 441 442 burst_state->next_state[CIRCPAD_EVENT_NONPADDING_SENT] =CIRCPAD_STATE_CANCEL; 443 444 burst_state->token_removal = CIRCPAD_TOKEN_REMOVAL_HIGHER; 445 446 burst_state->histogram_len = BIG_HISTOGRAM_LEN; 447 448 int n_tokens = 0; 449 int i; 450 for (i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 451 burst_state->histogram[i] = tokens_per_bin; 452 n_tokens += tokens_per_bin; 453 } 454 455 burst_state->histogram_edges[0] = 0; 456 burst_state->histogram_edges[1] = 1; 457 burst_state->histogram_edges[2] = 7; 458 burst_state->histogram_edges[3] = 15; 459 burst_state->histogram_edges[4] = 31; 460 burst_state->histogram_edges[5] = 62; 461 burst_state->histogram_edges[6] = 125; 462 burst_state->histogram_edges[7] = 250; 463 burst_state->histogram_edges[8] = 500; 464 burst_state->histogram_edges[9] = 1000; 465 466 burst_state->histogram_total_tokens = n_tokens; 467 burst_state->length_dist.type = CIRCPAD_DIST_UNIFORM; 468 burst_state->length_dist.param1 = n_tokens; 469 burst_state->length_dist.param2 = n_tokens; 470 burst_state->max_length = n_tokens; 471 burst_state->length_includes_nonpadding = 1; 472 burst_state->use_rtt_estimate = 0; 473 burst_state->token_removal = removal_strategy; 474 } 475 476 static circpad_decision_t 477 circpad_machine_schedule_padding_mock(circpad_machine_runtime_t *mi) 478 { 479 (void)mi; 480 return 0; 481 } 482 483 static uint64_t 484 mock_monotime_absolute_usec(void) 485 { 486 return 100; 487 } 488 489 /** Test higher token removal strategy by bin */ 490 static void 491 test_circuitpadding_token_removal_higher(void *arg) 492 { 493 circpad_machine_runtime_t *mi; 494 (void)arg; 495 496 /* Mock it up */ 497 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 498 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 499 testing_enable_reproducible_rng(); 500 501 /* Setup test environment (time etc.) */ 502 client_side = TO_CIRCUIT(origin_circuit_new()); 503 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 504 monotime_enable_test_mocking(); 505 506 /* Create test machine */ 507 helper_create_machine_with_big_histogram(CIRCPAD_TOKEN_REMOVAL_HIGHER); 508 client_side->padding_machine[0] = &circ_client_machine; 509 client_side->padding_info[0] = 510 circpad_circuit_machineinfo_new(client_side, 0); 511 512 /* move the machine to the right state */ 513 circpad_cell_event_nonpadding_received(client_side); 514 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 515 CIRCPAD_STATE_BURST); 516 517 /* Get the machine and setup tokens */ 518 mi = client_side->padding_info[0]; 519 tt_assert(mi); 520 521 /*************************************************************************/ 522 523 uint64_t current_time = monotime_absolute_usec(); 524 525 /* Test left boundaries of each histogram bin: */ 526 const circpad_delay_t bin_left_bounds[] = 527 {0, 1, 7, 15, 31, 62, 125, 250, 500, 1000, CIRCPAD_DELAY_INFINITE}; 528 for (int i = 0; i <= BIG_HISTOGRAM_LEN ; i++) { 529 tt_uint_op(bin_left_bounds[i], OP_EQ, 530 circpad_histogram_bin_to_usec(mi, i)); 531 } 532 533 /* Test right boundaries of each histogram bin: */ 534 const circpad_delay_t bin_right_bounds[] = 535 {0, 6, 14, 30, 61, 124, 249, 499, 999, CIRCPAD_DELAY_INFINITE-1}; 536 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 537 tt_uint_op(bin_right_bounds[i], OP_EQ, 538 histogram_get_bin_upper_bound(mi, i)); 539 } 540 541 /* Check that all bins have two tokens right now */ 542 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 543 tt_int_op(mi->histogram[i], OP_EQ, 2); 544 } 545 546 /* This is the right order to remove tokens from this histogram. That is, we 547 * first remove tokens from the 4th bin since 57 usec is nearest to the 4th 548 * bin midpoint (31 + (62-31)/2 == 46). Then we remove from the 3rd bin for 549 * the same reason, then from the 5th, etc. */ 550 const int bin_removal_order[] = {4, 5, 6, 7, 8}; 551 unsigned i; 552 553 /* Remove all tokens from all bins apart from the infinity bin */ 554 for (i = 0; i < sizeof(bin_removal_order)/sizeof(int) ; i++) { 555 int bin_to_remove = bin_removal_order[i]; 556 log_debug(LD_GENERAL, "Testing that %d attempt removes %d bin", 557 i, bin_to_remove); 558 559 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 2); 560 561 mi->padding_scheduled_at_usec = current_time - 57; 562 circpad_cell_event_nonpadding_sent(client_side); 563 564 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 1); 565 566 mi->padding_scheduled_at_usec = current_time - 57; 567 circpad_cell_event_nonpadding_sent(client_side); 568 569 /* Test that we cleaned out this bin. Don't do this in the case of the last 570 bin since the tokens will get refilled */ 571 if (i != BIG_HISTOGRAM_LEN - 2) { 572 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 0); 573 } 574 } 575 576 /* Check that all lower bins are not touched */ 577 for (i=0; i < 4 ; i++) { 578 tt_int_op(mi->histogram[i], OP_EQ, 2); 579 } 580 581 /* Test below the lowest bin, for coverage */ 582 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 583 CIRCPAD_STATE_BURST); 584 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[0] = 100; 585 mi->padding_scheduled_at_usec = current_time; 586 circpad_cell_event_nonpadding_sent(client_side); 587 tt_int_op(mi->histogram[0], OP_EQ, 1); 588 589 done: 590 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 591 monotime_disable_test_mocking(); 592 tor_free(circ_client_machine.states); 593 testing_disable_reproducible_rng(); 594 } 595 596 /** Test lower token removal strategy by bin */ 597 static void 598 test_circuitpadding_token_removal_lower(void *arg) 599 { 600 circpad_machine_runtime_t *mi; 601 (void)arg; 602 603 /* Mock it up */ 604 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 605 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 606 testing_enable_reproducible_rng(); 607 608 /* Setup test environment (time etc.) */ 609 client_side = TO_CIRCUIT(origin_circuit_new()); 610 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 611 monotime_enable_test_mocking(); 612 613 /* Create test machine */ 614 helper_create_machine_with_big_histogram(CIRCPAD_TOKEN_REMOVAL_LOWER); 615 client_side->padding_machine[0] = &circ_client_machine; 616 client_side->padding_info[0] = 617 circpad_circuit_machineinfo_new(client_side, 0); 618 619 /* move the machine to the right state */ 620 circpad_cell_event_nonpadding_received(client_side); 621 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 622 CIRCPAD_STATE_BURST); 623 624 /* Get the machine and setup tokens */ 625 mi = client_side->padding_info[0]; 626 tt_assert(mi); 627 628 /*************************************************************************/ 629 630 uint64_t current_time = monotime_absolute_usec(); 631 632 /* Test left boundaries of each histogram bin: */ 633 const circpad_delay_t bin_left_bounds[] = 634 {0, 1, 7, 15, 31, 62, 125, 250, 500, 1000, CIRCPAD_DELAY_INFINITE}; 635 for (int i = 0; i <= BIG_HISTOGRAM_LEN ; i++) { 636 tt_uint_op(bin_left_bounds[i], OP_EQ, 637 circpad_histogram_bin_to_usec(mi, i)); 638 } 639 640 /* Check that all bins have two tokens right now */ 641 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 642 tt_int_op(mi->histogram[i], OP_EQ, 2); 643 } 644 645 /* This is the right order to remove tokens from this histogram. That is, we 646 * first remove tokens from the 4th bin since 57 usec is nearest to the 4th 647 * bin midpoint (31 + (62-31)/2 == 46). Then we remove from the 3rd bin for 648 * the same reason, then from the 5th, etc. */ 649 const int bin_removal_order[] = {4, 3, 2, 1, 0}; 650 unsigned i; 651 652 /* Remove all tokens from all bins apart from the infinity bin */ 653 for (i = 0; i < sizeof(bin_removal_order)/sizeof(int) ; i++) { 654 int bin_to_remove = bin_removal_order[i]; 655 log_debug(LD_GENERAL, "Testing that %d attempt removes %d bin", 656 i, bin_to_remove); 657 658 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 2); 659 660 mi->padding_scheduled_at_usec = current_time - 57; 661 circpad_cell_event_nonpadding_sent(client_side); 662 663 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 1); 664 665 mi->padding_scheduled_at_usec = current_time - 57; 666 circpad_cell_event_nonpadding_sent(client_side); 667 668 /* Test that we cleaned out this bin. Don't do this in the case of the last 669 bin since the tokens will get refilled */ 670 if (i != BIG_HISTOGRAM_LEN - 2) { 671 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 0); 672 } 673 } 674 675 /* Check that all higher bins are untouched */ 676 for (i = 5; i < BIG_HISTOGRAM_LEN ; i++) { 677 tt_int_op(mi->histogram[i], OP_EQ, 2); 678 } 679 680 /* Test above the highest bin, for coverage */ 681 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 682 CIRCPAD_STATE_BURST); 683 circ_client_machine.states[CIRCPAD_STATE_BURST]. 684 histogram_edges[BIG_HISTOGRAM_LEN-2] = 100; 685 mi->padding_scheduled_at_usec = current_time - 29202; 686 circpad_cell_event_nonpadding_sent(client_side); 687 tt_int_op(mi->histogram[BIG_HISTOGRAM_LEN-2], OP_EQ, 1); 688 689 done: 690 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 691 monotime_disable_test_mocking(); 692 tor_free(circ_client_machine.states); 693 testing_disable_reproducible_rng(); 694 } 695 696 /** Test closest token removal strategy by bin */ 697 static void 698 test_circuitpadding_closest_token_removal(void *arg) 699 { 700 circpad_machine_runtime_t *mi; 701 (void)arg; 702 703 /* Mock it up */ 704 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 705 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 706 testing_enable_reproducible_rng(); 707 708 /* Setup test environment (time etc.) */ 709 client_side = TO_CIRCUIT(origin_circuit_new()); 710 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 711 monotime_enable_test_mocking(); 712 713 /* Create test machine */ 714 helper_create_machine_with_big_histogram(CIRCPAD_TOKEN_REMOVAL_CLOSEST); 715 client_side->padding_machine[0] = &circ_client_machine; 716 client_side->padding_info[0] = 717 circpad_circuit_machineinfo_new(client_side, 0); 718 719 /* move the machine to the right state */ 720 circpad_cell_event_nonpadding_received(client_side); 721 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 722 CIRCPAD_STATE_BURST); 723 724 /* Get the machine and setup tokens */ 725 mi = client_side->padding_info[0]; 726 tt_assert(mi); 727 728 /*************************************************************************/ 729 730 uint64_t current_time = monotime_absolute_usec(); 731 732 /* Test left boundaries of each histogram bin: */ 733 const circpad_delay_t bin_left_bounds[] = 734 {0, 1, 7, 15, 31, 62, 125, 250, 500, 1000, CIRCPAD_DELAY_INFINITE}; 735 for (int i = 0; i <= BIG_HISTOGRAM_LEN ; i++) { 736 tt_uint_op(bin_left_bounds[i], OP_EQ, 737 circpad_histogram_bin_to_usec(mi, i)); 738 } 739 740 /* Check that all bins have two tokens right now */ 741 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 742 tt_int_op(mi->histogram[i], OP_EQ, 2); 743 } 744 745 /* This is the right order to remove tokens from this histogram. That is, we 746 * first remove tokens from the 4th bin since 57 usec is nearest to the 4th 747 * bin midpoint (31 + (62-31)/2 == 46). Then we remove from the 3rd bin for 748 * the same reason, then from the 5th, etc. */ 749 const int bin_removal_order[] = {4, 3, 5, 2, 6, 1, 7, 0, 8, 9}; 750 751 /* Remove all tokens from all bins apart from the infinity bin */ 752 for (int i = 0; i < BIG_HISTOGRAM_LEN-1 ; i++) { 753 int bin_to_remove = bin_removal_order[i]; 754 log_debug(LD_GENERAL, "Testing that %d attempt removes %d bin", 755 i, bin_to_remove); 756 757 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 2); 758 759 mi->padding_scheduled_at_usec = current_time - 57; 760 circpad_cell_event_nonpadding_sent(client_side); 761 762 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 1); 763 764 mi->padding_scheduled_at_usec = current_time - 57; 765 circpad_cell_event_nonpadding_sent(client_side); 766 767 /* Test that we cleaned out this bin. Don't do this in the case of the last 768 bin since the tokens will get refilled */ 769 if (i != BIG_HISTOGRAM_LEN - 2) { 770 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 0); 771 } 772 } 773 774 /* Check that all bins have been refilled */ 775 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 776 tt_int_op(mi->histogram[i], OP_EQ, 2); 777 } 778 779 /* Test below the lowest bin, for coverage */ 780 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 781 CIRCPAD_STATE_BURST); 782 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[0] = 100; 783 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[1] = 101; 784 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[2] = 120; 785 mi->padding_scheduled_at_usec = current_time - 102; 786 mi->histogram[0] = 0; 787 circpad_cell_event_nonpadding_sent(client_side); 788 tt_int_op(mi->histogram[1], OP_EQ, 1); 789 790 /* Test above the highest bin, for coverage */ 791 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 792 CIRCPAD_STATE_BURST); 793 mi->padding_scheduled_at_usec = current_time - 29202; 794 circpad_cell_event_nonpadding_sent(client_side); 795 tt_int_op(mi->histogram[BIG_HISTOGRAM_LEN-2], OP_EQ, 1); 796 797 done: 798 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 799 monotime_disable_test_mocking(); 800 tor_free(circ_client_machine.states); 801 testing_disable_reproducible_rng(); 802 } 803 804 /** Test closest token removal strategy with usec */ 805 static void 806 test_circuitpadding_closest_token_removal_usec(void *arg) 807 { 808 circpad_machine_runtime_t *mi; 809 (void)arg; 810 811 /* Mock it up */ 812 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 813 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 814 testing_enable_reproducible_rng(); 815 816 /* Setup test environment (time etc.) */ 817 client_side = TO_CIRCUIT(origin_circuit_new()); 818 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 819 monotime_enable_test_mocking(); 820 821 /* Create test machine */ 822 helper_create_machine_with_big_histogram(CIRCPAD_TOKEN_REMOVAL_CLOSEST_USEC); 823 client_side->padding_machine[0] = &circ_client_machine; 824 client_side->padding_info[0] = 825 circpad_circuit_machineinfo_new(client_side, 0); 826 827 /* move the machine to the right state */ 828 circpad_cell_event_nonpadding_received(client_side); 829 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 830 CIRCPAD_STATE_BURST); 831 832 /* Get the machine and setup tokens */ 833 mi = client_side->padding_info[0]; 834 tt_assert(mi); 835 836 /*************************************************************************/ 837 838 uint64_t current_time = monotime_absolute_usec(); 839 840 /* Test left boundaries of each histogram bin: */ 841 const circpad_delay_t bin_left_bounds[] = 842 {0, 1, 7, 15, 31, 62, 125, 250, 500, 1000, CIRCPAD_DELAY_INFINITE}; 843 for (int i = 0; i <= BIG_HISTOGRAM_LEN ; i++) { 844 tt_uint_op(bin_left_bounds[i], OP_EQ, 845 circpad_histogram_bin_to_usec(mi, i)); 846 } 847 848 /* XXX we want to test remove_token_exact and 849 circpad_machine_remove_closest_token() with usec */ 850 851 /* Check that all bins have two tokens right now */ 852 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 853 tt_int_op(mi->histogram[i], OP_EQ, 2); 854 } 855 856 /* This is the right order to remove tokens from this histogram. That is, we 857 * first remove tokens from the 4th bin since 57 usec is nearest to the 4th 858 * bin midpoint (31 + (62-31)/2 == 46). Then we remove from the 3rd bin for 859 * the same reason, then from the 5th, etc. */ 860 const int bin_removal_order[] = {4, 3, 5, 2, 1, 0, 6, 7, 8, 9}; 861 862 /* Remove all tokens from all bins apart from the infinity bin */ 863 for (int i = 0; i < BIG_HISTOGRAM_LEN-1 ; i++) { 864 int bin_to_remove = bin_removal_order[i]; 865 log_debug(LD_GENERAL, "Testing that %d attempt removes %d bin", 866 i, bin_to_remove); 867 868 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 2); 869 870 mi->padding_scheduled_at_usec = current_time - 57; 871 circpad_cell_event_nonpadding_sent(client_side); 872 873 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 1); 874 875 mi->padding_scheduled_at_usec = current_time - 57; 876 circpad_cell_event_nonpadding_sent(client_side); 877 878 /* Test that we cleaned out this bin. Don't do this in the case of the last 879 bin since the tokens will get refilled */ 880 if (i != BIG_HISTOGRAM_LEN - 2) { 881 tt_int_op(mi->histogram[bin_to_remove], OP_EQ, 0); 882 } 883 } 884 885 /* Check that all bins have been refilled */ 886 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 887 tt_int_op(mi->histogram[i], OP_EQ, 2); 888 } 889 890 /* Test below the lowest bin, for coverage */ 891 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 892 CIRCPAD_STATE_BURST); 893 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[0] = 100; 894 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[1] = 101; 895 circ_client_machine.states[CIRCPAD_STATE_BURST].histogram_edges[2] = 120; 896 mi->padding_scheduled_at_usec = current_time - 102; 897 mi->histogram[0] = 0; 898 circpad_cell_event_nonpadding_sent(client_side); 899 tt_int_op(mi->histogram[1], OP_EQ, 1); 900 901 /* Test above the highest bin, for coverage */ 902 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 903 CIRCPAD_STATE_BURST); 904 circ_client_machine.states[CIRCPAD_STATE_BURST]. 905 histogram_edges[BIG_HISTOGRAM_LEN-2] = 100; 906 mi->padding_scheduled_at_usec = current_time - 29202; 907 circpad_cell_event_nonpadding_sent(client_side); 908 tt_int_op(mi->histogram[BIG_HISTOGRAM_LEN-2], OP_EQ, 1); 909 910 done: 911 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 912 monotime_disable_test_mocking(); 913 tor_free(circ_client_machine.states); 914 testing_disable_reproducible_rng(); 915 } 916 917 /** Test closest token removal strategy with usec */ 918 static void 919 test_circuitpadding_token_removal_exact(void *arg) 920 { 921 circpad_machine_runtime_t *mi; 922 (void)arg; 923 924 /* Mock it up */ 925 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 926 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 927 testing_enable_reproducible_rng(); 928 929 /* Setup test environment (time etc.) */ 930 client_side = TO_CIRCUIT(origin_circuit_new()); 931 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 932 monotime_enable_test_mocking(); 933 934 /* Create test machine */ 935 helper_create_machine_with_big_histogram(CIRCPAD_TOKEN_REMOVAL_EXACT); 936 client_side->padding_machine[0] = &circ_client_machine; 937 client_side->padding_info[0] = 938 circpad_circuit_machineinfo_new(client_side, 0); 939 940 /* move the machine to the right state */ 941 circpad_cell_event_nonpadding_received(client_side); 942 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 943 CIRCPAD_STATE_BURST); 944 945 /* Get the machine and setup tokens */ 946 mi = client_side->padding_info[0]; 947 tt_assert(mi); 948 949 /**********************************************************************/ 950 uint64_t current_time = monotime_absolute_usec(); 951 952 /* Ensure that we will clear out bin #4 with this usec */ 953 mi->padding_scheduled_at_usec = current_time - 57; 954 tt_int_op(mi->histogram[4], OP_EQ, 2); 955 circpad_cell_event_nonpadding_sent(client_side); 956 mi->padding_scheduled_at_usec = current_time - 57; 957 tt_int_op(mi->histogram[4], OP_EQ, 1); 958 circpad_cell_event_nonpadding_sent(client_side); 959 tt_int_op(mi->histogram[4], OP_EQ, 0); 960 961 /* Ensure that we will not remove any other tokens even tho we try to, since 962 * this is what the exact strategy dictates */ 963 mi->padding_scheduled_at_usec = current_time - 57; 964 circpad_cell_event_nonpadding_sent(client_side); 965 for (int i = 0; i < BIG_HISTOGRAM_LEN ; i++) { 966 if (i != 4) { 967 tt_int_op(mi->histogram[i], OP_EQ, 2); 968 } 969 } 970 971 done: 972 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 973 monotime_disable_test_mocking(); 974 tor_free(circ_client_machine.states); 975 testing_disable_reproducible_rng(); 976 } 977 978 #undef BIG_HISTOGRAM_LEN 979 980 void 981 test_circuitpadding_tokens(void *arg) 982 { 983 const circpad_state_t *state; 984 circpad_machine_runtime_t *mi; 985 int64_t actual_mocked_monotime_start; 986 (void)arg; 987 988 testing_enable_reproducible_rng(); 989 990 /** Test plan: 991 * 992 * 1. Test symmetry between bin_to_usec and usec_to_bin 993 * a. Test conversion 994 * b. Test edge transitions (lower, upper) 995 * 2. Test remove higher on an empty bin 996 * a. Normal bin 997 * b. Infinity bin 998 * c. Bin 0 999 * d. No higher 1000 * 3. Test remove lower 1001 * a. Normal bin 1002 * b. Bin 0 1003 * c. No lower 1004 * 4. Test remove closest 1005 * a. Closest lower 1006 * b. Closest higher 1007 * c. Closest 0 1008 * d. Closest Infinity 1009 */ 1010 client_side = TO_CIRCUIT(origin_circuit_new()); 1011 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1012 1013 monotime_init(); 1014 monotime_enable_test_mocking(); 1015 actual_mocked_monotime_start = MONOTIME_MOCK_START; 1016 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 1017 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 1018 curr_mocked_time = actual_mocked_monotime_start; 1019 1020 /* This is needed so that we are not considered to be dormant */ 1021 note_user_activity(20); 1022 1023 timers_initialize(); 1024 1025 helper_create_basic_machine(); 1026 client_side->padding_machine[0] = &circ_client_machine; 1027 client_side->padding_info[0] = circpad_circuit_machineinfo_new(client_side, 1028 0); 1029 1030 mi = client_side->padding_info[0]; 1031 1032 // Pretend a non-padding cell was sent 1033 circpad_cell_event_nonpadding_received(client_side); 1034 circpad_cell_event_nonpadding_sent(client_side); 1035 /* We have to save the infinity bin because one inf delay 1036 * could have been chosen when we transition to burst */ 1037 circpad_hist_token_t inf_bin = mi->histogram[4]; 1038 1039 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 1040 CIRCPAD_STATE_BURST); 1041 1042 state = circpad_machine_current_state(client_side->padding_info[0]); 1043 1044 // Test 0: convert bin->usec->bin 1045 // Bin 0+1 have different semantics 1046 for (int bin = 0; bin < 2; bin++) { 1047 circpad_delay_t usec = 1048 circpad_histogram_bin_to_usec(client_side->padding_info[0], bin); 1049 int bin2 = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1050 usec); 1051 tt_int_op(bin, OP_EQ, bin2); 1052 } 1053 for (int bin = 2; bin < state->histogram_len-1; bin++) { 1054 circpad_delay_t usec = 1055 circpad_histogram_bin_to_usec(client_side->padding_info[0], bin); 1056 int bin2 = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1057 usec); 1058 tt_int_op(bin, OP_EQ, bin2); 1059 /* Verify we round down */ 1060 bin2 = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1061 usec+3); 1062 tt_int_op(bin, OP_EQ, bin2); 1063 1064 bin2 = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1065 usec-1); 1066 tt_int_op(bin, OP_EQ, bin2+1); 1067 } 1068 1069 // Test 1: converting usec->bin->usec->bin 1070 // Bin 0+1 have different semantics. 1071 for (circpad_delay_t i = 0; i <= state->histogram_edges[0]; i++) { 1072 int bin = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1073 i); 1074 circpad_delay_t usec = 1075 circpad_histogram_bin_to_usec(client_side->padding_info[0], bin); 1076 int bin2 = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1077 usec); 1078 tt_int_op(bin, OP_EQ, bin2); 1079 tt_int_op(i, OP_LE, usec); 1080 } 1081 for (circpad_delay_t i = state->histogram_edges[0]+1; 1082 i <= state->histogram_edges[0] + 1083 state->histogram_edges[state->histogram_len-2]; i++) { 1084 int bin = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1085 i); 1086 circpad_delay_t usec = 1087 circpad_histogram_bin_to_usec(client_side->padding_info[0], bin); 1088 int bin2 = circpad_histogram_usec_to_bin(client_side->padding_info[0], 1089 usec); 1090 tt_int_op(bin, OP_EQ, bin2); 1091 tt_int_op(i, OP_GE, usec); 1092 } 1093 1094 /* 2.a. Normal higher bin */ 1095 { 1096 tt_int_op(mi->histogram[2], OP_EQ, 2); 1097 tt_int_op(mi->histogram[3], OP_EQ, 2); 1098 circpad_machine_remove_higher_token(mi, 1099 circpad_histogram_bin_to_usec(mi, 2)+1); 1100 tt_int_op(mi->histogram[3], OP_EQ, 2); 1101 tt_int_op(mi->histogram[2], OP_EQ, 1); 1102 1103 circpad_machine_remove_higher_token(mi, 1104 circpad_histogram_bin_to_usec(mi, 2)+1); 1105 tt_int_op(mi->histogram[2], OP_EQ, 0); 1106 1107 tt_int_op(mi->histogram[3], OP_EQ, 2); 1108 circpad_machine_remove_higher_token(mi, 1109 circpad_histogram_bin_to_usec(mi, 2)+1); 1110 circpad_machine_remove_higher_token(mi, 1111 circpad_histogram_bin_to_usec(mi, 2)+1); 1112 tt_int_op(mi->histogram[3], OP_EQ, 0); 1113 circpad_machine_remove_higher_token(mi, 1114 circpad_histogram_bin_to_usec(mi, 2)+1); 1115 tt_int_op(mi->histogram[3], OP_EQ, 0); 1116 } 1117 1118 /* 2.b. Higher Infinity bin */ 1119 { 1120 tt_int_op(mi->histogram[4], OP_EQ, inf_bin); 1121 circpad_machine_remove_higher_token(mi, 1122 circpad_histogram_bin_to_usec(mi, 2)+1); 1123 tt_int_op(mi->histogram[4], OP_EQ, inf_bin); 1124 1125 /* Test past the infinity bin */ 1126 circpad_machine_remove_higher_token(mi, 1127 circpad_histogram_bin_to_usec(mi, 5)+1000000); 1128 1129 tt_int_op(mi->histogram[4], OP_EQ, inf_bin); 1130 } 1131 1132 /* 2.c. Bin 0 */ 1133 { 1134 tt_int_op(mi->histogram[0], OP_EQ, 0); 1135 mi->histogram[0] = 1; 1136 circpad_machine_remove_higher_token(mi, state->histogram_edges[0]/2); 1137 tt_int_op(mi->histogram[0], OP_EQ, 0); 1138 } 1139 1140 /* Drain the infinity bin and cause a refill */ 1141 while (inf_bin != 0) { 1142 tt_int_op(mi->histogram[4], OP_EQ, inf_bin); 1143 circpad_cell_event_nonpadding_received(client_side); 1144 inf_bin--; 1145 } 1146 1147 circpad_cell_event_nonpadding_sent(client_side); 1148 1149 // We should have refilled here. 1150 tt_int_op(mi->histogram[4], OP_EQ, 2); 1151 1152 /* 3.a. Bin 0 */ 1153 { 1154 tt_int_op(mi->histogram[0], OP_EQ, 1); 1155 circpad_machine_remove_higher_token(mi, state->histogram_edges[0]/2); 1156 tt_int_op(mi->histogram[0], OP_EQ, 0); 1157 } 1158 1159 /* 3.b. Test remove lower normal bin */ 1160 { 1161 tt_int_op(mi->histogram[3], OP_EQ, 2); 1162 circpad_machine_remove_lower_token(mi, 1163 circpad_histogram_bin_to_usec(mi, 3)+1); 1164 circpad_machine_remove_lower_token(mi, 1165 circpad_histogram_bin_to_usec(mi, 3)+1); 1166 tt_int_op(mi->histogram[3], OP_EQ, 0); 1167 tt_int_op(mi->histogram[2], OP_EQ, 2); 1168 circpad_machine_remove_lower_token(mi, 1169 circpad_histogram_bin_to_usec(mi, 3)+1); 1170 circpad_machine_remove_lower_token(mi, 1171 circpad_histogram_bin_to_usec(mi, 3)+1); 1172 /* 3.c. No lower */ 1173 circpad_machine_remove_lower_token(mi, 1174 circpad_histogram_bin_to_usec(mi, 3)+1); 1175 tt_int_op(mi->histogram[2], OP_EQ, 0); 1176 } 1177 1178 /* 4. Test remove closest 1179 * a. Closest lower 1180 * b. Closest higher 1181 * c. Closest 0 1182 * d. Closest Infinity 1183 */ 1184 circpad_machine_setup_tokens(mi); 1185 tt_int_op(mi->histogram[2], OP_EQ, 2); 1186 circpad_machine_remove_closest_token(mi, 1187 circpad_histogram_bin_to_usec(mi, 2)+1, 0); 1188 circpad_machine_remove_closest_token(mi, 1189 circpad_histogram_bin_to_usec(mi, 2)+1, 0); 1190 tt_int_op(mi->histogram[2], OP_EQ, 0); 1191 tt_int_op(mi->histogram[3], OP_EQ, 2); 1192 circpad_machine_remove_closest_token(mi, 1193 circpad_histogram_bin_to_usec(mi, 2)+1, 0); 1194 circpad_machine_remove_closest_token(mi, 1195 circpad_histogram_bin_to_usec(mi, 2)+1, 0); 1196 tt_int_op(mi->histogram[3], OP_EQ, 0); 1197 tt_int_op(mi->histogram[0], OP_EQ, 1); 1198 circpad_machine_remove_closest_token(mi, 1199 circpad_histogram_bin_to_usec(mi, 2)+1, 0); 1200 tt_int_op(mi->histogram[0], OP_EQ, 0); 1201 tt_int_op(mi->histogram[4], OP_EQ, 2); 1202 circpad_machine_remove_closest_token(mi, 1203 circpad_histogram_bin_to_usec(mi, 2)+1, 0); 1204 tt_int_op(mi->histogram[4], OP_EQ, 2); 1205 1206 /* 5. Test remove closest usec 1207 * a. Closest 0 1208 * b. Closest lower (below midpoint) 1209 * c. Closest higher (above midpoint) 1210 * d. Closest Infinity 1211 */ 1212 circpad_machine_setup_tokens(mi); 1213 1214 tt_int_op(mi->histogram[0], OP_EQ, 1); 1215 circpad_machine_remove_closest_token(mi, 1216 circpad_histogram_bin_to_usec(mi, 0)/3, 1); 1217 tt_int_op(mi->histogram[0], OP_EQ, 0); 1218 tt_int_op(mi->histogram[2], OP_EQ, 2); 1219 circpad_machine_remove_closest_token(mi, 1220 circpad_histogram_bin_to_usec(mi, 0)/3, 1); 1221 circpad_machine_remove_closest_token(mi, 1222 circpad_histogram_bin_to_usec(mi, 0)/3, 1); 1223 tt_int_op(mi->histogram[2], OP_EQ, 0); 1224 tt_int_op(mi->histogram[3], OP_EQ, 2); 1225 circpad_machine_remove_closest_token(mi, 1226 circpad_histogram_bin_to_usec(mi, 4), 1); 1227 circpad_machine_remove_closest_token(mi, 1228 circpad_histogram_bin_to_usec(mi, 4), 1); 1229 tt_int_op(mi->histogram[3], OP_EQ, 0); 1230 tt_int_op(mi->histogram[4], OP_EQ, 2); 1231 circpad_machine_remove_closest_token(mi, 1232 circpad_histogram_bin_to_usec(mi, 4), 1); 1233 circpad_machine_remove_closest_token(mi, 1234 circpad_histogram_bin_to_usec(mi, 4), 1); 1235 tt_int_op(mi->histogram[4], OP_EQ, 2); 1236 1237 // XXX: Need more coverage of the actual usec branches 1238 1239 done: 1240 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1241 monotime_disable_test_mocking(); 1242 tor_free(circ_client_machine.states); 1243 testing_disable_reproducible_rng(); 1244 } 1245 1246 void 1247 test_circuitpadding_wronghop(void *arg) 1248 { 1249 /** 1250 * Test plan: 1251 * 1. Padding sent from hop 1 and 3 to client 1252 * 2. Send negotiated from hop 1 and 3 to client 1253 * 3. Garbled negotiated cell 1254 * 4. Padding negotiate sent to client 1255 * 5. Send negotiate stop command for unknown machine 1256 * 6. Send negotiated to relay 1257 * 7. Garbled padding negotiate cell 1258 */ 1259 (void)arg; 1260 uint32_t read_bw = 0, overhead_bw = 0; 1261 relay_msg_t msg; 1262 signed_error_t ret; 1263 origin_circuit_t *orig_client; 1264 int64_t actual_mocked_monotime_start; 1265 1266 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 1267 1268 /* Mock this function so that our cell counting tests don't get confused by 1269 * padding that gets sent by scheduled timers. */ 1270 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 1271 testing_enable_reproducible_rng(); 1272 1273 client_side = TO_CIRCUIT(origin_circuit_new()); 1274 dummy_channel.cmux = circuitmux_alloc(); 1275 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, 1276 &dummy_channel)); 1277 orig_client = TO_ORIGIN_CIRCUIT(client_side); 1278 1279 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1280 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1281 nodes_init(); 1282 1283 monotime_init(); 1284 monotime_enable_test_mocking(); 1285 actual_mocked_monotime_start = MONOTIME_MOCK_START; 1286 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 1287 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 1288 curr_mocked_time = actual_mocked_monotime_start; 1289 1290 timers_initialize(); 1291 circpad_machines_init(); 1292 1293 MOCK(node_get_by_id, 1294 node_get_by_id_mock); 1295 1296 MOCK(circuit_package_relay_cell, 1297 circuit_package_relay_cell_mock); 1298 1299 /* Build three hops */ 1300 simulate_single_hop_extend(client_side, relay_side, 1); 1301 simulate_single_hop_extend(client_side, relay_side, 1); 1302 simulate_single_hop_extend(client_side, relay_side, 1); 1303 1304 /* verify padding was negotiated */ 1305 tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL); 1306 tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL); 1307 1308 /* verify echo was sent */ 1309 tt_int_op(n_relay_cells, OP_EQ, 1); 1310 tt_int_op(n_client_cells, OP_EQ, 1); 1311 1312 read_bw = orig_client->n_delivered_read_circ_bw; 1313 overhead_bw = orig_client->n_overhead_read_circ_bw; 1314 1315 /* 1. Test padding from first and third hop */ 1316 circpad_deliver_recognized_relay_cell_events(client_side, 1317 RELAY_COMMAND_DROP, 1318 TO_ORIGIN_CIRCUIT(client_side)->cpath); 1319 tt_int_op(read_bw, OP_EQ, 1320 orig_client->n_delivered_read_circ_bw); 1321 tt_int_op(overhead_bw, OP_EQ, 1322 orig_client->n_overhead_read_circ_bw); 1323 1324 circpad_deliver_recognized_relay_cell_events(client_side, 1325 RELAY_COMMAND_DROP, 1326 TO_ORIGIN_CIRCUIT(client_side)->cpath->next->next); 1327 tt_int_op(read_bw, OP_EQ, 1328 orig_client->n_delivered_read_circ_bw); 1329 tt_int_op(overhead_bw, OP_EQ, 1330 orig_client->n_overhead_read_circ_bw); 1331 1332 circpad_deliver_recognized_relay_cell_events(client_side, 1333 RELAY_COMMAND_DROP, 1334 TO_ORIGIN_CIRCUIT(client_side)->cpath->next); 1335 tt_int_op(read_bw, OP_EQ, 1336 orig_client->n_delivered_read_circ_bw); 1337 tt_int_op(overhead_bw, OP_LT, 1338 orig_client->n_overhead_read_circ_bw); 1339 1340 /* 2. Test padding negotiated not handled from hops 1,3 */ 1341 memset(&msg, 0, sizeof(msg)); 1342 ret = circpad_handle_padding_negotiated(client_side, &msg, 1343 TO_ORIGIN_CIRCUIT(client_side)->cpath); 1344 tt_int_op(ret, OP_EQ, -1); 1345 1346 ret = circpad_handle_padding_negotiated(client_side, &msg, 1347 TO_ORIGIN_CIRCUIT(client_side)->cpath->next->next); 1348 tt_int_op(ret, OP_EQ, -1); 1349 1350 /* 3. Garbled negotiated cell */ 1351 memset(&msg, 0, sizeof(msg)); 1352 uint8_t buf[99]; 1353 memset(buf, 0xff, 99); 1354 msg.body = buf; 1355 ret = circpad_handle_padding_negotiated(client_side, &msg, 1356 TO_ORIGIN_CIRCUIT(client_side)->cpath->next); 1357 tt_int_op(ret, OP_EQ, -1); 1358 1359 /* 4. Test that negotiate is dropped at origin */ 1360 read_bw = orig_client->n_delivered_read_circ_bw; 1361 overhead_bw = orig_client->n_overhead_read_circ_bw; 1362 relay_send_command_from_edge(0, relay_side, 1363 RELAY_COMMAND_PADDING_NEGOTIATE, 1364 "xyz", 1365 (size_t)3, NULL); 1366 tt_int_op(read_bw, OP_EQ, 1367 orig_client->n_delivered_read_circ_bw); 1368 tt_int_op(overhead_bw, OP_EQ, 1369 orig_client->n_overhead_read_circ_bw); 1370 1371 tt_int_op(n_relay_cells, OP_EQ, 2); 1372 tt_int_op(n_client_cells, OP_EQ, 1); 1373 1374 /* 5. Test that asking to stop the wrong machine does nothing */ 1375 circpad_negotiate_padding(TO_ORIGIN_CIRCUIT(client_side), 1376 255, 2, CIRCPAD_COMMAND_STOP, 0); 1377 tt_ptr_op(client_side->padding_machine[0], OP_NE, NULL); 1378 tt_ptr_op(client_side->padding_info[0], OP_NE, NULL); 1379 tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL); 1380 tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL); 1381 tt_int_op(n_relay_cells, OP_EQ, 2); 1382 tt_int_op(n_client_cells, OP_EQ, 2); 1383 1384 /* 6. Sending negotiated command to relay does nothing */ 1385 ret = circpad_handle_padding_negotiated(relay_side, &msg, NULL); 1386 tt_int_op(ret, OP_EQ, -1); 1387 1388 /* 7. Test garbled negotiated cell (bad command 255) */ 1389 relay_msg_clear(&msg); 1390 ret = circpad_handle_padding_negotiate(relay_side, &msg); 1391 tt_int_op(ret, OP_EQ, -1); 1392 tt_int_op(n_client_cells, OP_EQ, 2); 1393 1394 /* Test 2: Test no padding */ 1395 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1396 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 1397 1398 client_side = TO_CIRCUIT(origin_circuit_new()); 1399 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, 1400 &dummy_channel)); 1401 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1402 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1403 1404 simulate_single_hop_extend(client_side, relay_side, 1); 1405 simulate_single_hop_extend(client_side, relay_side, 0); 1406 1407 /* verify no padding was negotiated */ 1408 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1409 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1410 1411 /* verify no echo was sent */ 1412 tt_int_op(n_relay_cells, OP_EQ, 2); 1413 tt_int_op(n_client_cells, OP_EQ, 2); 1414 1415 /* Finish circuit */ 1416 simulate_single_hop_extend(client_side, relay_side, 1); 1417 1418 /* Spoof padding negotiated on circuit with no padding */ 1419 circpad_padding_negotiated(relay_side, 1420 CIRCPAD_MACHINE_CIRC_SETUP, 1421 CIRCPAD_COMMAND_START, 1422 CIRCPAD_RESPONSE_OK, 0); 1423 1424 /* verify no padding was negotiated */ 1425 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1426 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1427 1428 circpad_padding_negotiated(relay_side, 1429 CIRCPAD_MACHINE_CIRC_SETUP, 1430 CIRCPAD_COMMAND_START, 1431 CIRCPAD_RESPONSE_ERR, 0); 1432 1433 /* verify no padding was negotiated */ 1434 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1435 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1436 1437 done: 1438 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1439 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 1440 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 1441 circuitmux_free(dummy_channel.cmux); 1442 monotime_disable_test_mocking(); 1443 UNMOCK(node_get_by_id); 1444 UNMOCK(circuit_package_relay_cell); 1445 UNMOCK(circuitmux_attach_circuit); 1446 nodes_free(); 1447 testing_disable_reproducible_rng(); 1448 relay_msg_clear(&msg); 1449 } 1450 1451 void 1452 test_circuitpadding_negotiation(void *arg) 1453 { 1454 /** 1455 * Test plan: 1456 * 1. Test circuit where padding is supported by middle 1457 * a. Make sure padding negotiation is sent 1458 * b. Test padding negotiation delivery and parsing 1459 * 2. Test circuit where padding is unsupported by middle 1460 * a. Make sure padding negotiation is not sent 1461 * 3. Test failure to negotiate a machine due to desync. 1462 */ 1463 int64_t actual_mocked_monotime_start; 1464 (void)arg; 1465 1466 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 1467 1468 client_side = TO_CIRCUIT(origin_circuit_new()); 1469 dummy_channel.cmux = circuitmux_alloc(); 1470 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 1471 1472 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1473 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1474 nodes_init(); 1475 1476 monotime_init(); 1477 monotime_enable_test_mocking(); 1478 actual_mocked_monotime_start = MONOTIME_MOCK_START; 1479 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 1480 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 1481 curr_mocked_time = actual_mocked_monotime_start; 1482 1483 timers_initialize(); 1484 circpad_machines_init(); 1485 1486 MOCK(node_get_by_id, 1487 node_get_by_id_mock); 1488 1489 MOCK(circuit_package_relay_cell, 1490 circuit_package_relay_cell_mock); 1491 1492 /* Build two hops */ 1493 simulate_single_hop_extend(client_side, relay_side, 1); 1494 simulate_single_hop_extend(client_side, relay_side, 1); 1495 1496 /* verify padding was negotiated */ 1497 tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL); 1498 tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL); 1499 1500 /* verify echo was sent */ 1501 tt_int_op(n_relay_cells, OP_EQ, 1); 1502 tt_int_op(n_client_cells, OP_EQ, 1); 1503 1504 /* Finish circuit */ 1505 simulate_single_hop_extend(client_side, relay_side, 1); 1506 1507 /* Test 2: Test no padding */ 1508 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1509 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 1510 1511 client_side = TO_CIRCUIT(origin_circuit_new()); 1512 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 1513 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1514 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1515 1516 simulate_single_hop_extend(client_side, relay_side, 1); 1517 simulate_single_hop_extend(client_side, relay_side, 0); 1518 1519 /* verify no padding was negotiated */ 1520 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1521 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1522 tt_int_op(n_relay_cells, OP_EQ, 1); 1523 tt_int_op(n_client_cells, OP_EQ, 1); 1524 1525 /* verify no echo was sent */ 1526 tt_int_op(n_relay_cells, OP_EQ, 1); 1527 tt_int_op(n_client_cells, OP_EQ, 1); 1528 1529 /* Finish circuit */ 1530 simulate_single_hop_extend(client_side, relay_side, 1); 1531 1532 /* Force negotiate padding. */ 1533 circpad_negotiate_padding(TO_ORIGIN_CIRCUIT(client_side), 1534 CIRCPAD_MACHINE_CIRC_SETUP, 1535 2, CIRCPAD_COMMAND_START, 0); 1536 1537 /* verify no padding was negotiated */ 1538 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1539 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1540 1541 /* verify no echo was sent */ 1542 tt_int_op(n_relay_cells, OP_EQ, 1); 1543 tt_int_op(n_client_cells, OP_EQ, 1); 1544 1545 /* 3. Test failure to negotiate a machine due to desync */ 1546 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1547 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 1548 1549 client_side = TO_CIRCUIT(origin_circuit_new()); 1550 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 1551 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1552 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1553 1554 SMARTLIST_FOREACH(relay_padding_machines, 1555 circpad_machine_spec_t *, 1556 m, tor_free(m->states); tor_free(m)); 1557 smartlist_free(relay_padding_machines); 1558 relay_padding_machines = smartlist_new(); 1559 1560 simulate_single_hop_extend(client_side, relay_side, 1); 1561 simulate_single_hop_extend(client_side, relay_side, 1); 1562 1563 /* verify echo was sent */ 1564 tt_int_op(n_client_cells, OP_EQ, 2); 1565 tt_int_op(n_relay_cells, OP_EQ, 2); 1566 1567 /* verify no padding was negotiated */ 1568 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 1569 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1570 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1571 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 1572 1573 done: 1574 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1575 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 1576 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 1577 circuitmux_free(dummy_channel.cmux); 1578 monotime_disable_test_mocking(); 1579 UNMOCK(node_get_by_id); 1580 UNMOCK(circuit_package_relay_cell); 1581 UNMOCK(circuitmux_attach_circuit); 1582 nodes_free(); 1583 } 1584 1585 static void 1586 simulate_single_hop_extend(circuit_t *client, circuit_t *mid_relay, 1587 int padding) 1588 { 1589 char whatevs_key[CPATH_KEY_MATERIAL_LEN]; 1590 char digest[DIGEST_LEN]; 1591 tor_addr_t addr = TOR_ADDR_NULL; 1592 1593 // Pretend a non-padding cell was sent 1594 circpad_cell_event_nonpadding_sent(client); 1595 1596 // Receive extend cell at middle 1597 circpad_cell_event_nonpadding_received(mid_relay); 1598 1599 // Advance time a tiny bit so we can calculate an RTT 1600 curr_mocked_time += 10 * TOR_NSEC_PER_MSEC; 1601 monotime_coarse_set_mock_time_nsec(curr_mocked_time); 1602 monotime_set_mock_time_nsec(curr_mocked_time); 1603 1604 // Receive extended cell at middle 1605 circpad_cell_event_nonpadding_sent(mid_relay); 1606 1607 // Receive extended cell at first hop 1608 circpad_cell_event_nonpadding_received(client); 1609 1610 // Add a hop to cpath 1611 crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t)); 1612 cpath_extend_linked_list(&TO_ORIGIN_CIRCUIT(client)->cpath, hop); 1613 1614 hop->magic = CRYPT_PATH_MAGIC; 1615 hop->state = CPATH_STATE_OPEN; 1616 1617 // add an extend info to indicate if this node supports padding or not. 1618 // (set the first byte of the digest for our mocked node_get_by_id) 1619 digest[0] = padding; 1620 1621 hop->extend_info = extend_info_new( 1622 padding ? "padding" : "non-padding", 1623 digest, NULL, NULL, 1624 &addr, padding, NULL, false); 1625 1626 cpath_init_circuit_crypto(RELAY_CRYPTO_ALG_TOR1, hop, 1627 whatevs_key, sizeof(whatevs_key)); 1628 1629 hop->package_window = circuit_initial_package_window(); 1630 hop->deliver_window = CIRCWINDOW_START; 1631 1632 // Signal that the hop was added 1633 circpad_machine_event_circ_added_hop(TO_ORIGIN_CIRCUIT(client)); 1634 } 1635 1636 static circpad_machine_spec_t * 1637 helper_create_length_machine(void) 1638 { 1639 circpad_machine_spec_t *ret = 1640 tor_malloc_zero(sizeof(circpad_machine_spec_t)); 1641 1642 /* Start, burst */ 1643 circpad_machine_states_init(ret, 2); 1644 1645 ret->states[CIRCPAD_STATE_START]. 1646 next_state[CIRCPAD_EVENT_PADDING_SENT] = CIRCPAD_STATE_BURST; 1647 1648 ret->states[CIRCPAD_STATE_BURST]. 1649 next_state[CIRCPAD_EVENT_PADDING_SENT] = CIRCPAD_STATE_BURST; 1650 1651 ret->states[CIRCPAD_STATE_BURST]. 1652 next_state[CIRCPAD_EVENT_LENGTH_COUNT] = CIRCPAD_STATE_END; 1653 1654 ret->states[CIRCPAD_STATE_BURST]. 1655 next_state[CIRCPAD_EVENT_BINS_EMPTY] = CIRCPAD_STATE_END; 1656 1657 /* No token removal.. end via state_length only */ 1658 ret->states[CIRCPAD_STATE_BURST].token_removal = 1659 CIRCPAD_TOKEN_REMOVAL_NONE; 1660 1661 /* Let's have this one end after 12 packets */ 1662 ret->states[CIRCPAD_STATE_BURST].length_dist.type = CIRCPAD_DIST_UNIFORM; 1663 ret->states[CIRCPAD_STATE_BURST].length_dist.param1 = 12; 1664 ret->states[CIRCPAD_STATE_BURST].length_dist.param2 = 13; 1665 ret->states[CIRCPAD_STATE_BURST].max_length = 12; 1666 1667 ret->states[CIRCPAD_STATE_BURST].histogram_len = 4; 1668 1669 ret->states[CIRCPAD_STATE_BURST].histogram_edges[0] = 0; 1670 ret->states[CIRCPAD_STATE_BURST].histogram_edges[1] = 1; 1671 ret->states[CIRCPAD_STATE_BURST].histogram_edges[2] = 1000000; 1672 ret->states[CIRCPAD_STATE_BURST].histogram_edges[3] = 10000000; 1673 1674 ret->states[CIRCPAD_STATE_BURST].histogram[0] = 0; 1675 ret->states[CIRCPAD_STATE_BURST].histogram[1] = 0; 1676 ret->states[CIRCPAD_STATE_BURST].histogram[2] = 6; 1677 1678 ret->states[CIRCPAD_STATE_BURST].histogram_total_tokens = 6; 1679 ret->states[CIRCPAD_STATE_BURST].use_rtt_estimate = 0; 1680 ret->states[CIRCPAD_STATE_BURST].length_includes_nonpadding = 0; 1681 1682 return ret; 1683 } 1684 1685 static circpad_machine_spec_t * 1686 helper_create_conditional_machine(void) 1687 { 1688 circpad_machine_spec_t *ret = 1689 tor_malloc_zero(sizeof(circpad_machine_spec_t)); 1690 1691 /* Start, burst */ 1692 circpad_machine_states_init(ret, 2); 1693 1694 ret->states[CIRCPAD_STATE_START]. 1695 next_state[CIRCPAD_EVENT_PADDING_SENT] = CIRCPAD_STATE_BURST; 1696 1697 ret->states[CIRCPAD_STATE_BURST]. 1698 next_state[CIRCPAD_EVENT_PADDING_SENT] = CIRCPAD_STATE_BURST; 1699 1700 ret->states[CIRCPAD_STATE_BURST]. 1701 next_state[CIRCPAD_EVENT_LENGTH_COUNT] = CIRCPAD_STATE_END; 1702 1703 /* Use EXACT removal strategy, otherwise setup_tokens() does not work */ 1704 ret->states[CIRCPAD_STATE_BURST].token_removal = 1705 CIRCPAD_TOKEN_REMOVAL_EXACT; 1706 1707 ret->states[CIRCPAD_STATE_BURST].histogram_len = 3; 1708 1709 ret->states[CIRCPAD_STATE_BURST].histogram_edges[0] = 0; 1710 ret->states[CIRCPAD_STATE_BURST].histogram_edges[1] = 1; 1711 ret->states[CIRCPAD_STATE_BURST].histogram_edges[2] = 1000000; 1712 1713 ret->states[CIRCPAD_STATE_BURST].histogram[0] = 6; 1714 ret->states[CIRCPAD_STATE_BURST].histogram[1] = 0; 1715 ret->states[CIRCPAD_STATE_BURST].histogram[2] = 0; 1716 1717 ret->states[CIRCPAD_STATE_BURST].histogram_total_tokens = 6; 1718 ret->states[CIRCPAD_STATE_BURST].use_rtt_estimate = 0; 1719 ret->states[CIRCPAD_STATE_BURST].length_includes_nonpadding = 1; 1720 1721 return ret; 1722 } 1723 1724 static void 1725 helper_create_conditional_machines(void) 1726 { 1727 circpad_machine_spec_t *add = helper_create_conditional_machine(); 1728 1729 if (!origin_padding_machines) 1730 origin_padding_machines = smartlist_new(); 1731 if (!relay_padding_machines) 1732 relay_padding_machines = smartlist_new(); 1733 1734 add->machine_num = 2; 1735 add->is_origin_side = 1; 1736 add->should_negotiate_end = 1; 1737 add->target_hopnum = 2; 1738 1739 /* Let's have this one end after 4 packets */ 1740 add->states[CIRCPAD_STATE_BURST].length_dist.type = CIRCPAD_DIST_UNIFORM; 1741 add->states[CIRCPAD_STATE_BURST].length_dist.param1 = 4; 1742 add->states[CIRCPAD_STATE_BURST].length_dist.param2 = 4; 1743 add->states[CIRCPAD_STATE_BURST].max_length = 4; 1744 1745 add->conditions.requires_vanguards = 0; 1746 add->conditions.min_hops = 2; 1747 add->conditions.apply_state_mask = CIRCPAD_CIRC_BUILDING| 1748 CIRCPAD_CIRC_NO_STREAMS|CIRCPAD_CIRC_HAS_RELAY_EARLY; 1749 add->conditions.apply_purpose_mask = CIRCPAD_PURPOSE_ALL; 1750 circpad_register_padding_machine(add, origin_padding_machines); 1751 1752 add = helper_create_conditional_machine(); 1753 add->machine_num = 3; 1754 add->is_origin_side = 1; 1755 add->should_negotiate_end = 1; 1756 add->target_hopnum = 2; 1757 1758 /* Let's have this one end after 4 packets */ 1759 add->states[CIRCPAD_STATE_BURST].length_dist.type = CIRCPAD_DIST_UNIFORM; 1760 add->states[CIRCPAD_STATE_BURST].length_dist.param1 = 4; 1761 add->states[CIRCPAD_STATE_BURST].length_dist.param2 = 4; 1762 add->states[CIRCPAD_STATE_BURST].max_length = 4; 1763 1764 add->conditions.requires_vanguards = 1; 1765 add->conditions.min_hops = 3; 1766 add->conditions.apply_state_mask = CIRCPAD_CIRC_OPENED| 1767 CIRCPAD_CIRC_STREAMS|CIRCPAD_CIRC_HAS_NO_RELAY_EARLY; 1768 add->conditions.apply_purpose_mask = CIRCPAD_PURPOSE_ALL; 1769 circpad_register_padding_machine(add, origin_padding_machines); 1770 1771 add = helper_create_conditional_machine(); 1772 add->machine_num = 2; 1773 circpad_register_padding_machine(add, relay_padding_machines); 1774 1775 add = helper_create_conditional_machine(); 1776 add->machine_num = 3; 1777 circpad_register_padding_machine(add, relay_padding_machines); 1778 } 1779 1780 void 1781 test_circuitpadding_state_length(void *arg) 1782 { 1783 /** 1784 * Test plan: 1785 * * Explicitly test that with no token removal enabled, we hit 1786 * the state length limit due to either padding, or non-padding. 1787 * * Repeat test with an arbitrary token removal strategy, and 1788 * verify that if we run out of tokens due to padding before we 1789 * hit the state length, we still go to state end (all our 1790 * token removal tests only test nonpadding token removal). 1791 */ 1792 int64_t actual_mocked_monotime_start; 1793 (void)arg; 1794 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 1795 MOCK(circpad_send_command_to_hop, circpad_send_command_to_hop_mock); 1796 1797 nodes_init(); 1798 dummy_channel.cmux = circuitmux_alloc(); 1799 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, 1800 &dummy_channel)); 1801 client_side = TO_CIRCUIT(origin_circuit_new()); 1802 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1803 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1804 1805 monotime_init(); 1806 monotime_enable_test_mocking(); 1807 actual_mocked_monotime_start = MONOTIME_MOCK_START; 1808 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 1809 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 1810 curr_mocked_time = actual_mocked_monotime_start; 1811 1812 /* This is needed so that we are not considered to be dormant */ 1813 note_user_activity(20); 1814 1815 timers_initialize(); 1816 circpad_machine_spec_t *client_machine = 1817 helper_create_length_machine(); 1818 1819 MOCK(circuit_package_relay_cell, 1820 circuit_package_relay_cell_mock); 1821 MOCK(node_get_by_id, 1822 node_get_by_id_mock); 1823 1824 client_side->padding_machine[0] = client_machine; 1825 client_side->padding_info[0] = 1826 circpad_circuit_machineinfo_new(client_side, 0); 1827 circpad_machine_runtime_t *mi = client_side->padding_info[0]; 1828 1829 circpad_cell_event_padding_sent(client_side); 1830 tt_i64_op(mi->state_length, OP_EQ, 12); 1831 tt_ptr_op(mi->histogram, OP_EQ, NULL); 1832 1833 /* Verify that non-padding does not change our state length */ 1834 circpad_cell_event_nonpadding_sent(client_side); 1835 tt_i64_op(mi->state_length, OP_EQ, 12); 1836 1837 /* verify that sending padding changes our state length */ 1838 for (uint64_t i = mi->state_length-1; i > 0; i--) { 1839 circpad_send_padding_cell_for_callback(mi); 1840 tt_i64_op(mi->state_length, OP_EQ, i); 1841 } 1842 circpad_send_padding_cell_for_callback(mi); 1843 1844 tt_i64_op(mi->state_length, OP_EQ, -1); 1845 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END); 1846 1847 /* Restart machine */ 1848 mi->current_state = CIRCPAD_STATE_START; 1849 1850 /* Now, count nonpadding as part of the state length */ 1851 client_machine->states[CIRCPAD_STATE_BURST].length_includes_nonpadding = 1; 1852 1853 circpad_cell_event_padding_sent(client_side); 1854 tt_i64_op(mi->state_length, OP_EQ, 12); 1855 1856 /* Verify that non-padding does change our state length now */ 1857 for (uint64_t i = mi->state_length-1; i > 0; i--) { 1858 circpad_cell_event_nonpadding_sent(client_side); 1859 tt_i64_op(mi->state_length, OP_EQ, i); 1860 } 1861 1862 circpad_cell_event_nonpadding_sent(client_side); 1863 tt_i64_op(mi->state_length, OP_EQ, -1); 1864 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END); 1865 1866 /* Now, just test token removal when we send padding */ 1867 client_machine->states[CIRCPAD_STATE_BURST].token_removal = 1868 CIRCPAD_TOKEN_REMOVAL_EXACT; 1869 1870 /* Restart machine */ 1871 mi->current_state = CIRCPAD_STATE_START; 1872 circpad_cell_event_padding_sent(client_side); 1873 tt_i64_op(mi->state_length, OP_EQ, 12); 1874 tt_ptr_op(mi->histogram, OP_NE, NULL); 1875 tt_int_op(mi->chosen_bin, OP_EQ, 2); 1876 1877 /* verify that sending padding changes our state length and 1878 * our histogram now */ 1879 for (uint32_t i = mi->histogram[2]-1; i > 0; i--) { 1880 circpad_send_padding_cell_for_callback(mi); 1881 tt_int_op(mi->chosen_bin, OP_EQ, 2); 1882 tt_int_op(mi->histogram[2], OP_EQ, i); 1883 } 1884 1885 tt_i64_op(mi->state_length, OP_EQ, 7); 1886 tt_int_op(mi->histogram[2], OP_EQ, 1); 1887 1888 circpad_send_padding_cell_for_callback(mi); 1889 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END); 1890 1891 done: 1892 tor_free(client_machine->states); 1893 tor_free(client_machine); 1894 1895 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 1896 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 1897 1898 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 1899 circuitmux_free(dummy_channel.cmux); 1900 timers_shutdown(); 1901 monotime_disable_test_mocking(); 1902 UNMOCK(circuit_package_relay_cell); 1903 UNMOCK(circuitmux_attach_circuit); 1904 UNMOCK(node_get_by_id); 1905 1906 return; 1907 } 1908 1909 void 1910 test_circuitpadding_conditions(void *arg) 1911 { 1912 /** 1913 * Test plan: 1914 * 0. Make a few origin and client machines with diff conditions 1915 * * vanguards, purposes, has_opened circs, no relay early 1916 * * Client side should_negotiate_end 1917 * * Length limits 1918 * 1. Test STATE_END transitions 1919 * 2. Test new machine after end with same conditions 1920 * 3. Test new machine due to changed conditions 1921 * * Esp: built event, no relay early, no streams 1922 * XXX: Diff test: 1923 * 1. Test STATE_END with pending timers 1924 * 2. Test marking a circuit before padding callback fires 1925 * 3. Test freeing a circuit before padding callback fires 1926 */ 1927 int64_t actual_mocked_monotime_start; 1928 (void)arg; 1929 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 1930 testing_enable_reproducible_rng(); 1931 1932 nodes_init(); 1933 dummy_channel.cmux = circuitmux_alloc(); 1934 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, 1935 &dummy_channel)); 1936 client_side = TO_CIRCUIT(origin_circuit_new()); 1937 relay_side->purpose = CIRCUIT_PURPOSE_OR; 1938 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 1939 1940 monotime_init(); 1941 monotime_enable_test_mocking(); 1942 actual_mocked_monotime_start = MONOTIME_MOCK_START; 1943 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 1944 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 1945 curr_mocked_time = actual_mocked_monotime_start; 1946 1947 /* This is needed so that we are not considered to be dormant */ 1948 note_user_activity(20); 1949 1950 timers_initialize(); 1951 helper_create_conditional_machines(); 1952 1953 MOCK(circuit_package_relay_cell, 1954 circuit_package_relay_cell_mock); 1955 MOCK(node_get_by_id, 1956 node_get_by_id_mock); 1957 1958 /* Simulate extend. This should result in the original machine getting 1959 * added, since the circuit is not built */ 1960 simulate_single_hop_extend(client_side, relay_side, 1); 1961 simulate_single_hop_extend(client_side, relay_side, 1); 1962 1963 /* Verify that machine #2 is added */ 1964 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 1965 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 1966 1967 /* Deliver a padding cell to the client, to trigger burst state */ 1968 circpad_cell_event_padding_sent(client_side); 1969 1970 /* This should have trigger length shutdown condition on client.. */ 1971 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 1972 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 1973 1974 /* Verify machine is gone from both sides */ 1975 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 1976 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 1977 1978 /* Send another event.. verify machine gets re-added properly 1979 * (test race with shutdown) */ 1980 simulate_single_hop_extend(client_side, relay_side, 1); 1981 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 1982 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 1983 1984 TO_ORIGIN_CIRCUIT(client_side)->p_streams = 0; 1985 circpad_machine_event_circ_has_no_streams(TO_ORIGIN_CIRCUIT(client_side)); 1986 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 1987 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 1988 1989 /* Now make the circuit opened and send built event */ 1990 TO_ORIGIN_CIRCUIT(client_side)->has_opened = 1; 1991 circpad_machine_event_circ_built(TO_ORIGIN_CIRCUIT(client_side)); 1992 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 1993 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 1994 1995 TO_ORIGIN_CIRCUIT(client_side)->remaining_relay_early_cells = 0; 1996 circpad_machine_event_circ_has_no_relay_early( 1997 TO_ORIGIN_CIRCUIT(client_side)); 1998 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 1999 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 2000 2001 get_options_mutable()->HSLayer2Nodes = (void*)1; 2002 TO_ORIGIN_CIRCUIT(client_side)->p_streams = (void*)1; 2003 circpad_machine_event_circ_has_streams(TO_ORIGIN_CIRCUIT(client_side)); 2004 2005 /* Verify different machine is added */ 2006 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 3); 2007 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 3); 2008 2009 /* Hold off on negotiated */ 2010 deliver_negotiated = 0; 2011 2012 /* Deliver a padding cell to the client, to trigger burst state */ 2013 circpad_cell_event_padding_sent(client_side); 2014 2015 /* This should have trigger length shutdown condition on client 2016 * but not the response for the padding machine */ 2017 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 2018 tt_ptr_op(client_side->padding_machine[0], OP_NE, NULL); 2019 2020 /* Verify machine is gone from the relay (but negotiated not back yet */ 2021 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 2022 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 2023 2024 /* Add another hop and verify it's back */ 2025 simulate_single_hop_extend(client_side, relay_side, 1); 2026 2027 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 3); 2028 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 3); 2029 2030 tt_ptr_op(client_side->padding_info[0], OP_NE, NULL); 2031 tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL); 2032 2033 done: 2034 /* XXX: Free everything */ 2035 testing_disable_reproducible_rng(); 2036 return; 2037 } 2038 2039 /** Disabled unstable test until #29298 is implemented (see #29122) */ 2040 #if 0 2041 void 2042 test_circuitpadding_circuitsetup_machine(void *arg) 2043 { 2044 int64_t actual_mocked_monotime_start; 2045 /** 2046 * Test case plan: 2047 * 2048 * 1. Simulate a normal circuit setup pattern 2049 * a. Application traffic 2050 * 2051 * FIXME: This should focus more on exercising the machine 2052 * features rather than actual traffic patterns. For example, 2053 * test cancellation and bins empty/refill 2054 */ 2055 (void)arg; 2056 2057 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 2058 2059 dummy_channel.cmux = circuitmux_alloc(); 2060 client_side = TO_CIRCUIT(origin_circuit_new()); 2061 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 2062 2063 relay_side->purpose = CIRCUIT_PURPOSE_OR; 2064 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2065 2066 nodes_init(); 2067 2068 monotime_init(); 2069 monotime_enable_test_mocking(); 2070 actual_mocked_monotime_start = MONOTIME_MOCK_START; 2071 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 2072 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 2073 curr_mocked_time = actual_mocked_monotime_start; 2074 2075 timers_initialize(); 2076 circpad_machines_init(); 2077 2078 MOCK(circuit_package_relay_cell, 2079 circuit_package_relay_cell_mock); 2080 MOCK(node_get_by_id, 2081 node_get_by_id_mock); 2082 2083 /* Test case #1: Build a 3 hop circuit, then wait and let pad */ 2084 simulate_single_hop_extend(client_side, relay_side, 1); 2085 simulate_single_hop_extend(client_side, relay_side, 1); 2086 simulate_single_hop_extend(client_side, relay_side, 1); 2087 2088 tt_int_op(n_client_cells, OP_EQ, 1); 2089 tt_int_op(n_relay_cells, OP_EQ, 1); 2090 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 2091 CIRCPAD_STATE_BURST); 2092 tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, 2093 CIRCPAD_STATE_BURST); 2094 2095 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2096 OP_NE, 0); 2097 tt_int_op(relay_side->padding_info[0]->is_padding_timer_scheduled, 2098 OP_EQ, 0); 2099 timers_advance_and_run(2000); 2100 tt_int_op(n_client_cells, OP_EQ, 2); 2101 tt_int_op(n_relay_cells, OP_EQ, 1); 2102 2103 tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, 2104 CIRCPAD_STATE_GAP); 2105 2106 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2107 OP_EQ, 0); 2108 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2109 OP_NE, 0); 2110 timers_advance_and_run(5000); 2111 tt_int_op(n_client_cells, OP_EQ, 2); 2112 tt_int_op(n_relay_cells, OP_EQ, 2); 2113 2114 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2115 OP_NE, 0); 2116 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2117 OP_EQ, 0); 2118 timers_advance_and_run(2000); 2119 tt_int_op(n_client_cells, OP_EQ, 3); 2120 tt_int_op(n_relay_cells, OP_EQ, 2); 2121 2122 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2123 OP_EQ, 0); 2124 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2125 OP_NE, 0); 2126 timers_advance_and_run(5000); 2127 tt_int_op(n_client_cells, OP_EQ, 3); 2128 tt_int_op(n_relay_cells, OP_EQ, 3); 2129 2130 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2131 OP_NE, 0); 2132 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2133 OP_EQ, 0); 2134 timers_advance_and_run(2000); 2135 tt_int_op(n_client_cells, OP_EQ, 4); 2136 tt_int_op(n_relay_cells, OP_EQ, 3); 2137 2138 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2139 OP_EQ, 0); 2140 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2141 OP_NE, 0); 2142 timers_advance_and_run(5000); 2143 tt_int_op(n_client_cells, OP_EQ, 4); 2144 tt_int_op(n_relay_cells, OP_EQ, 4); 2145 2146 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2147 OP_NE, 0); 2148 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2149 OP_EQ, 0); 2150 timers_advance_and_run(2000); 2151 tt_int_op(n_client_cells, OP_EQ, 5); 2152 tt_int_op(n_relay_cells, OP_EQ, 4); 2153 2154 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2155 OP_EQ, 0); 2156 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2157 OP_NE, 0); 2158 timers_advance_and_run(5000); 2159 tt_int_op(n_client_cells, OP_EQ, 5); 2160 tt_int_op(n_relay_cells, OP_EQ, 5); 2161 2162 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2163 OP_NE, 0); 2164 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2165 OP_EQ, 0); 2166 timers_advance_and_run(2000); 2167 tt_int_op(n_client_cells, OP_EQ, 6); 2168 tt_int_op(n_relay_cells, OP_EQ, 5); 2169 2170 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2171 OP_EQ, 0); 2172 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2173 OP_NE, 0); 2174 timers_advance_and_run(5000); 2175 tt_int_op(n_client_cells, OP_EQ, 6); 2176 tt_int_op(n_relay_cells, OP_EQ, 6); 2177 2178 tt_int_op(client_side->padding_info[0]->current_state, 2179 OP_EQ, CIRCPAD_STATE_END); 2180 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2181 OP_EQ, 0); 2182 tt_int_op(relay_side->padding_info[0]->current_state, 2183 OP_EQ, CIRCPAD_STATE_GAP); 2184 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2185 OP_EQ, 0); 2186 2187 /* Verify we can't schedule padding in END state */ 2188 circpad_decision_t ret = 2189 circpad_machine_schedule_padding(client_side->padding_info[0]); 2190 tt_int_op(ret, OP_EQ, CIRCPAD_STATE_UNCHANGED); 2191 2192 /* Simulate application traffic */ 2193 circpad_cell_event_nonpadding_sent(client_side); 2194 circpad_deliver_unrecognized_cell_events(relay_side, CELL_DIRECTION_OUT); 2195 circpad_deliver_unrecognized_cell_events(relay_side, CELL_DIRECTION_IN); 2196 circpad_deliver_recognized_relay_cell_events(client_side, RELAY_COMMAND_DATA, 2197 TO_ORIGIN_CIRCUIT(client_side)->cpath->next); 2198 2199 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 2200 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 2201 2202 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 2203 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 2204 tt_int_op(n_client_cells, OP_EQ, 6); 2205 tt_int_op(n_relay_cells, OP_EQ, 7); 2206 2207 // Test timer cancellation 2208 simulate_single_hop_extend(client_side, relay_side, 1); 2209 simulate_single_hop_extend(client_side, relay_side, 1); 2210 timers_advance_and_run(5000); 2211 circpad_cell_event_padding_received(client_side); 2212 2213 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 2214 CIRCPAD_STATE_BURST); 2215 tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, 2216 CIRCPAD_STATE_GAP); 2217 2218 tt_int_op(n_client_cells, OP_EQ, 8); 2219 tt_int_op(n_relay_cells, OP_EQ, 8); 2220 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2221 OP_NE, 0); 2222 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2223 OP_NE, 0); 2224 2225 /* Test timer cancel due to state rules */ 2226 circpad_cell_event_nonpadding_sent(client_side); 2227 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2228 OP_EQ, 0); 2229 circpad_cell_event_padding_received(client_side); 2230 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2231 OP_NE, 0); 2232 2233 /* Simulate application traffic to cancel timer */ 2234 circpad_cell_event_nonpadding_sent(client_side); 2235 circpad_deliver_unrecognized_cell_events(relay_side, CELL_DIRECTION_OUT); 2236 circpad_deliver_unrecognized_cell_events(relay_side, CELL_DIRECTION_IN); 2237 circpad_deliver_recognized_relay_cell_events(client_side, RELAY_COMMAND_DATA, 2238 TO_ORIGIN_CIRCUIT(client_side)->cpath->next); 2239 2240 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 2241 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 2242 2243 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 2244 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 2245 2246 /* No cells sent, except negotiate end from relay */ 2247 tt_int_op(n_client_cells, OP_EQ, 8); 2248 tt_int_op(n_relay_cells, OP_EQ, 9); 2249 2250 /* Test mark for close and free */ 2251 simulate_single_hop_extend(client_side, relay_side, 1); 2252 simulate_single_hop_extend(client_side, relay_side, 1); 2253 timers_advance_and_run(5000); 2254 circpad_cell_event_padding_received(client_side); 2255 2256 tt_int_op(n_client_cells, OP_EQ, 10); 2257 tt_int_op(n_relay_cells, OP_EQ, 10); 2258 2259 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 2260 CIRCPAD_STATE_BURST); 2261 tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, 2262 CIRCPAD_STATE_GAP); 2263 2264 tt_u64_op(client_side->padding_info[0]->padding_scheduled_at_usec, 2265 OP_NE, 0); 2266 tt_u64_op(relay_side->padding_info[0]->padding_scheduled_at_usec, 2267 OP_NE, 0); 2268 circuit_mark_for_close(client_side, END_CIRC_REASON_FLAG_REMOTE); 2269 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 2270 timers_advance_and_run(5000); 2271 2272 /* No cells sent */ 2273 tt_int_op(n_client_cells, OP_EQ, 10); 2274 tt_int_op(n_relay_cells, OP_EQ, 10); 2275 2276 done: 2277 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 2278 2279 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 2280 circuitmux_free(dummy_channel.cmux); 2281 timers_shutdown(); 2282 monotime_disable_test_mocking(); 2283 UNMOCK(circuit_package_relay_cell); 2284 UNMOCK(circuitmux_attach_circuit); 2285 2286 return; 2287 } 2288 #endif /* 0 */ 2289 2290 /** Helper function: Initializes a padding machine where every state uses the 2291 * uniform probability distribution. */ 2292 static void 2293 helper_circpad_circ_distribution_machine_setup(int min, int max) 2294 { 2295 circpad_machine_states_init(&circ_client_machine, 7); 2296 2297 circpad_state_t *zero_st = &circ_client_machine.states[0]; 2298 zero_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 1; 2299 zero_st->iat_dist.type = CIRCPAD_DIST_UNIFORM; 2300 /* param2 is upper bound, param1 is lower */ 2301 zero_st->iat_dist.param1 = min; 2302 zero_st->iat_dist.param2 = max; 2303 zero_st->dist_added_shift_usec = min; 2304 zero_st->dist_max_sample_usec = max; 2305 2306 circpad_state_t *first_st = &circ_client_machine.states[1]; 2307 first_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 2; 2308 first_st->iat_dist.type = CIRCPAD_DIST_LOGISTIC; 2309 /* param1 is Mu, param2 is sigma. */ 2310 first_st->iat_dist.param1 = 9; 2311 first_st->iat_dist.param2 = 3; 2312 first_st->dist_added_shift_usec = min; 2313 first_st->dist_max_sample_usec = max; 2314 2315 circpad_state_t *second_st = &circ_client_machine.states[2]; 2316 second_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 3; 2317 second_st->iat_dist.type = CIRCPAD_DIST_LOG_LOGISTIC; 2318 /* param1 is Alpha, param2 is 1.0/Beta */ 2319 second_st->iat_dist.param1 = 1; 2320 second_st->iat_dist.param2 = 0.5; 2321 second_st->dist_added_shift_usec = min; 2322 second_st->dist_max_sample_usec = max; 2323 2324 circpad_state_t *third_st = &circ_client_machine.states[3]; 2325 third_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 4; 2326 third_st->iat_dist.type = CIRCPAD_DIST_GEOMETRIC; 2327 /* param1 is 'p' (success probability) */ 2328 third_st->iat_dist.param1 = 0.2; 2329 third_st->dist_added_shift_usec = min; 2330 third_st->dist_max_sample_usec = max; 2331 2332 circpad_state_t *fourth_st = &circ_client_machine.states[4]; 2333 fourth_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 5; 2334 fourth_st->iat_dist.type = CIRCPAD_DIST_WEIBULL; 2335 /* param1 is k, param2 is Lambda */ 2336 fourth_st->iat_dist.param1 = 1.5; 2337 fourth_st->iat_dist.param2 = 1; 2338 fourth_st->dist_added_shift_usec = min; 2339 fourth_st->dist_max_sample_usec = max; 2340 2341 circpad_state_t *fifth_st = &circ_client_machine.states[5]; 2342 fifth_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 6; 2343 fifth_st->iat_dist.type = CIRCPAD_DIST_PARETO; 2344 /* param1 is sigma, param2 is xi */ 2345 fifth_st->iat_dist.param1 = 1; 2346 fifth_st->iat_dist.param2 = 5; 2347 fifth_st->dist_added_shift_usec = min; 2348 fifth_st->dist_max_sample_usec = max; 2349 } 2350 2351 /** Simple test that the padding delays sampled from a uniform distribution 2352 * actually fail within the uniform distribution range. */ 2353 static void 2354 test_circuitpadding_sample_distribution(void *arg) 2355 { 2356 circpad_machine_runtime_t *mi; 2357 int n_samples; 2358 int n_states; 2359 2360 (void) arg; 2361 2362 /* mock this function so that we dont actually schedule any padding */ 2363 MOCK(circpad_machine_schedule_padding, 2364 circpad_machine_schedule_padding_mock); 2365 testing_enable_reproducible_rng(); 2366 2367 /* Initialize a machine with multiple probability distributions */ 2368 circpad_machines_init(); 2369 helper_circpad_circ_distribution_machine_setup(0, 10); 2370 2371 /* Initialize machine and circuits */ 2372 client_side = TO_CIRCUIT(origin_circuit_new()); 2373 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2374 client_side->padding_machine[0] = &circ_client_machine; 2375 client_side->padding_info[0] = 2376 circpad_circuit_machineinfo_new(client_side, 0); 2377 mi = client_side->padding_info[0]; 2378 2379 /* For every state, sample a bunch of values from the distribution and ensure 2380 * they fall within range. */ 2381 for (n_states = 0 ; n_states < 6; n_states++) { 2382 /* Make sure we in the right state */ 2383 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, n_states); 2384 2385 for (n_samples = 0; n_samples < 100; n_samples++) { 2386 circpad_delay_t delay = circpad_machine_sample_delay(mi); 2387 tt_int_op(delay, OP_GE, 0); 2388 tt_int_op(delay, OP_LE, 10); 2389 } 2390 2391 /* send a non-padding cell to move to the next machine state */ 2392 circpad_cell_event_nonpadding_received(client_side); 2393 } 2394 2395 done: 2396 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 2397 UNMOCK(circpad_machine_schedule_padding); 2398 testing_disable_reproducible_rng(); 2399 } 2400 2401 static circpad_decision_t 2402 circpad_machine_spec_transition_mock(circpad_machine_runtime_t *mi, 2403 circpad_event_t event) 2404 { 2405 (void) mi; 2406 (void) event; 2407 2408 return CIRCPAD_STATE_UNCHANGED; 2409 } 2410 2411 /* Test per-machine padding rate limits */ 2412 static void 2413 test_circuitpadding_machine_rate_limiting(void *arg) 2414 { 2415 (void) arg; 2416 bool retval; 2417 circpad_machine_runtime_t *mi; 2418 int i; 2419 2420 /* Ignore machine transitions for the purposes of this function, we only 2421 * really care about padding counts */ 2422 MOCK(circpad_machine_spec_transition, circpad_machine_spec_transition_mock); 2423 MOCK(circpad_send_command_to_hop, circpad_send_command_to_hop_mock); 2424 testing_enable_reproducible_rng(); 2425 2426 /* Setup machine and circuits */ 2427 client_side = TO_CIRCUIT(origin_circuit_new()); 2428 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2429 helper_create_basic_machine(); 2430 client_side->padding_machine[0] = &circ_client_machine; 2431 client_side->padding_info[0] = 2432 circpad_circuit_machineinfo_new(client_side, 0); 2433 mi = client_side->padding_info[0]; 2434 /* Set up the machine info so that we can get through the basic functions */ 2435 mi->state_length = CIRCPAD_STATE_LENGTH_INFINITE; 2436 2437 /* First we are going to test the per-machine rate limits */ 2438 circ_client_machine.max_padding_percent = 50; 2439 circ_client_machine.allowed_padding_count = 100; 2440 2441 /* Check padding limit, should be fine since we haven't sent anything yet. */ 2442 retval = circpad_machine_reached_padding_limit(mi); 2443 tt_int_op(retval, OP_EQ, 0); 2444 2445 /* Send 99 padding cells which is below circpad_global_allowed_cells=100, so 2446 * the rate limit will not trigger */ 2447 for (i=0;i<99;i++) { 2448 circpad_send_padding_cell_for_callback(mi); 2449 } 2450 retval = circpad_machine_reached_padding_limit(mi); 2451 tt_int_op(retval, OP_EQ, 0); 2452 2453 /* Now send another padding cell to pass circpad_global_allowed_cells=100, 2454 and see that the limit will trigger */ 2455 circpad_send_padding_cell_for_callback(mi); 2456 retval = circpad_machine_reached_padding_limit(mi); 2457 tt_int_op(retval, OP_EQ, 1); 2458 2459 retval = circpad_machine_schedule_padding(mi); 2460 tt_int_op(retval, OP_EQ, CIRCPAD_STATE_UNCHANGED); 2461 2462 /* Cover wrap */ 2463 for (;i<UINT16_MAX;i++) { 2464 circpad_send_padding_cell_for_callback(mi); 2465 } 2466 tt_int_op(mi->padding_sent, OP_EQ, UINT16_MAX/2+1); 2467 2468 tt_ptr_op(client_side->padding_info[0], OP_EQ, mi); 2469 for (i=0;i<UINT16_MAX;i++) { 2470 circpad_cell_event_nonpadding_sent(client_side); 2471 } 2472 2473 tt_int_op(mi->nonpadding_sent, OP_EQ, UINT16_MAX/2); 2474 tt_int_op(mi->padding_sent, OP_EQ, UINT16_MAX/4+1); 2475 2476 done: 2477 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 2478 testing_disable_reproducible_rng(); 2479 } 2480 2481 /* Test global padding rate limits */ 2482 static void 2483 test_circuitpadding_global_rate_limiting(void *arg) 2484 { 2485 (void) arg; 2486 bool retval; 2487 circpad_machine_runtime_t *mi; 2488 int i; 2489 int64_t actual_mocked_monotime_start; 2490 2491 /* Ignore machine transitions for the purposes of this function, we only 2492 * really care about padding counts */ 2493 MOCK(circpad_machine_spec_transition, circpad_machine_spec_transition_mock); 2494 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 2495 MOCK(circuit_package_relay_cell, 2496 circuit_package_relay_cell_mock); 2497 MOCK(monotime_absolute_usec, mock_monotime_absolute_usec); 2498 testing_enable_reproducible_rng(); 2499 2500 monotime_init(); 2501 monotime_enable_test_mocking(); 2502 actual_mocked_monotime_start = MONOTIME_MOCK_START; 2503 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 2504 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 2505 curr_mocked_time = actual_mocked_monotime_start; 2506 timers_initialize(); 2507 2508 client_side = TO_CIRCUIT(origin_circuit_new()); 2509 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2510 dummy_channel.cmux = circuitmux_alloc(); 2511 2512 /* Setup machine and circuits */ 2513 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 2514 relay_side->purpose = CIRCUIT_PURPOSE_OR; 2515 helper_create_basic_machine(); 2516 relay_side->padding_machine[0] = &circ_client_machine; 2517 relay_side->padding_info[0] = 2518 circpad_circuit_machineinfo_new(relay_side, 0); 2519 mi = relay_side->padding_info[0]; 2520 /* Set up the machine info so that we can get through the basic functions */ 2521 mi->state_length = CIRCPAD_STATE_LENGTH_INFINITE; 2522 2523 simulate_single_hop_extend(client_side, relay_side, 1); 2524 simulate_single_hop_extend(client_side, relay_side, 1); 2525 2526 /* Now test the global limits by setting up the consensus */ 2527 networkstatus_t vote1; 2528 vote1.net_params = smartlist_new(); 2529 smartlist_split_string(vote1.net_params, 2530 "circpad_global_allowed_cells=100 circpad_global_max_padding_pct=50", 2531 NULL, 0, 0); 2532 /* Register global limits with the padding subsystem */ 2533 circpad_new_consensus_params(&vote1); 2534 2535 /* Check padding limit, should be fine since we haven't sent anything yet. */ 2536 retval = circpad_machine_reached_padding_limit(mi); 2537 tt_int_op(retval, OP_EQ, 0); 2538 2539 /* Send 99 padding cells which is below circpad_global_allowed_cells=100, so 2540 * the rate limit will not trigger */ 2541 for (i=0;i<99;i++) { 2542 circpad_send_padding_cell_for_callback(mi); 2543 } 2544 retval = circpad_machine_reached_padding_limit(mi); 2545 tt_int_op(retval, OP_EQ, 0); 2546 2547 /* Now send another padding cell to pass circpad_global_allowed_cells=100, 2548 and see that the limit will trigger */ 2549 circpad_send_padding_cell_for_callback(mi); 2550 retval = circpad_machine_reached_padding_limit(mi); 2551 tt_int_op(retval, OP_EQ, 1); 2552 2553 retval = circpad_machine_schedule_padding(mi); 2554 tt_int_op(retval, OP_EQ, CIRCPAD_STATE_UNCHANGED); 2555 2556 /* Now send 92 non-padding cells to get near the 2557 * circpad_global_max_padding_pct=50 limit; in particular with 96 non-padding 2558 * cells, the padding traffic is still 51% of total traffic so limit should 2559 * trigger */ 2560 for (i=0;i<92;i++) { 2561 circpad_cell_event_nonpadding_sent(relay_side); 2562 } 2563 retval = circpad_machine_reached_padding_limit(mi); 2564 tt_int_op(retval, OP_EQ, 1); 2565 2566 /* Send another non-padding cell to bring the padding traffic to 50% of total 2567 * traffic and get past the limit */ 2568 circpad_cell_event_nonpadding_sent(relay_side); 2569 retval = circpad_machine_reached_padding_limit(mi); 2570 tt_int_op(retval, OP_EQ, 0); 2571 2572 done: 2573 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 2574 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 2575 circuitmux_free(dummy_channel.cmux); 2576 SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp)); 2577 smartlist_free(vote1.net_params); 2578 testing_disable_reproducible_rng(); 2579 } 2580 2581 /* Test reduced and disabled padding */ 2582 static void 2583 test_circuitpadding_reduce_disable(void *arg) 2584 { 2585 (void) arg; 2586 int64_t actual_mocked_monotime_start; 2587 2588 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 2589 testing_enable_reproducible_rng(); 2590 2591 nodes_init(); 2592 dummy_channel.cmux = circuitmux_alloc(); 2593 relay_side = (circuit_t *)new_fake_orcirc(&dummy_channel, 2594 &dummy_channel); 2595 client_side = (circuit_t *)origin_circuit_new(); 2596 relay_side->purpose = CIRCUIT_PURPOSE_OR; 2597 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2598 2599 circpad_machines_init(); 2600 helper_create_conditional_machines(); 2601 2602 monotime_init(); 2603 monotime_enable_test_mocking(); 2604 actual_mocked_monotime_start = MONOTIME_MOCK_START; 2605 monotime_set_mock_time_nsec(actual_mocked_monotime_start); 2606 monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); 2607 curr_mocked_time = actual_mocked_monotime_start; 2608 timers_initialize(); 2609 2610 /* This is needed so that we are not considered to be dormant */ 2611 note_user_activity(20); 2612 2613 MOCK(circuit_package_relay_cell, 2614 circuit_package_relay_cell_mock); 2615 MOCK(node_get_by_id, 2616 node_get_by_id_mock); 2617 2618 /* Simulate extend. This should result in the original machine getting 2619 * added, since the circuit is not built */ 2620 simulate_single_hop_extend(client_side, relay_side, 1); 2621 simulate_single_hop_extend(client_side, relay_side, 1); 2622 2623 /* Verify that machine #2 is added */ 2624 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 2625 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 2626 2627 /* Deliver a padding cell to the client, to trigger burst state */ 2628 circpad_cell_event_padding_sent(client_side); 2629 2630 /* This should have trigger length shutdown condition on client.. */ 2631 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 2632 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 2633 2634 /* Verify machine is gone from both sides */ 2635 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 2636 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 2637 2638 /* Now test the reduced padding machine by setting up the consensus */ 2639 networkstatus_t vote1; 2640 vote1.net_params = smartlist_new(); 2641 smartlist_split_string(vote1.net_params, 2642 "circpad_padding_reduced=1", NULL, 0, 0); 2643 2644 /* Register reduced padding machine with the padding subsystem */ 2645 circpad_new_consensus_params(&vote1); 2646 2647 simulate_single_hop_extend(client_side, relay_side, 1); 2648 2649 /* Verify that machine #0 is added */ 2650 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 2651 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 2652 2653 tt_int_op( 2654 circpad_machine_reached_padding_limit(client_side->padding_info[0]), 2655 OP_EQ, 0); 2656 tt_int_op( 2657 circpad_machine_reached_padding_limit(relay_side->padding_info[0]), 2658 OP_EQ, 0); 2659 2660 /* Test that machines get torn down when padding is disabled */ 2661 SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp)); 2662 smartlist_free(vote1.net_params); 2663 vote1.net_params = smartlist_new(); 2664 smartlist_split_string(vote1.net_params, 2665 "circpad_padding_disabled=1", NULL, 0, 0); 2666 2667 /* Register reduced padding machine with the padding subsystem */ 2668 circpad_new_consensus_params(&vote1); 2669 2670 tt_int_op( 2671 circpad_machine_schedule_padding(client_side->padding_info[0]), 2672 OP_EQ, CIRCPAD_STATE_UNCHANGED); 2673 tt_int_op( 2674 circpad_machine_schedule_padding(relay_side->padding_info[0]), 2675 OP_EQ, CIRCPAD_STATE_UNCHANGED); 2676 2677 /* Signal that circuit is built: this event causes us to re-evaluate 2678 * machine conditions (which don't apply because padding is disabled). */ 2679 circpad_machine_event_circ_built(TO_ORIGIN_CIRCUIT(client_side)); 2680 2681 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 2682 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 2683 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 2684 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 2685 2686 SMARTLIST_FOREACH(vote1.net_params, char *, cp, tor_free(cp)); 2687 smartlist_free(vote1.net_params); 2688 vote1.net_params = NULL; 2689 circpad_new_consensus_params(&vote1); 2690 2691 get_options_mutable()->ReducedCircuitPadding = 1; 2692 2693 simulate_single_hop_extend(client_side, relay_side, 1); 2694 2695 /* Verify that machine #0 is added */ 2696 tt_int_op(client_side->padding_machine[0]->machine_num, OP_EQ, 2); 2697 tt_int_op(relay_side->padding_machine[0]->machine_num, OP_EQ, 2); 2698 2699 tt_int_op( 2700 circpad_machine_reached_padding_limit(client_side->padding_info[0]), 2701 OP_EQ, 0); 2702 tt_int_op( 2703 circpad_machine_reached_padding_limit(relay_side->padding_info[0]), 2704 OP_EQ, 0); 2705 2706 get_options_mutable()->CircuitPadding = 0; 2707 2708 tt_int_op( 2709 circpad_machine_schedule_padding(client_side->padding_info[0]), 2710 OP_EQ, CIRCPAD_STATE_UNCHANGED); 2711 tt_int_op( 2712 circpad_machine_schedule_padding(relay_side->padding_info[0]), 2713 OP_EQ, CIRCPAD_STATE_UNCHANGED); 2714 2715 /* Signal that circuit is built: this event causes us to re-evaluate 2716 * machine conditions (which don't apply because padding is disabled). */ 2717 2718 circpad_machine_event_circ_built(TO_ORIGIN_CIRCUIT(client_side)); 2719 2720 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 2721 tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL); 2722 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 2723 tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL); 2724 2725 done: 2726 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 2727 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 2728 circuitmux_free(dummy_channel.cmux); 2729 testing_disable_reproducible_rng(); 2730 } 2731 2732 /** Just a basic machine whose whole purpose is to reach the END state */ 2733 static void 2734 helper_create_ender_machine(void) 2735 { 2736 /* Start, burst */ 2737 circpad_machine_states_init(&circ_client_machine, 2); 2738 2739 circ_client_machine.states[CIRCPAD_STATE_START]. 2740 next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_END; 2741 2742 circ_client_machine.conditions.apply_state_mask = CIRCPAD_STATE_ALL; 2743 circ_client_machine.conditions.apply_purpose_mask = CIRCPAD_PURPOSE_ALL; 2744 } 2745 2746 static time_t mocked_timeofday; 2747 /** Set timeval to a mock date and time. This is necessary 2748 * to make tor_gettimeofday() mockable. */ 2749 static void 2750 mock_tor_gettimeofday(struct timeval *timeval) 2751 { 2752 timeval->tv_sec = mocked_timeofday; 2753 timeval->tv_usec = 0; 2754 } 2755 2756 /** Test manual managing of circuit lifetimes by the circuitpadding 2757 * subsystem. In particular this test goes through all the cases of the 2758 * circpad_marked_circuit_for_padding() function, via 2759 * circuit_mark_for_close() as well as 2760 * circuit_expire_old_circuits_clientside(). */ 2761 static void 2762 test_circuitpadding_manage_circuit_lifetime(void *arg) 2763 { 2764 circpad_machine_runtime_t *mi; 2765 2766 (void) arg; 2767 2768 client_side = (circuit_t *)origin_circuit_new(); 2769 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2770 monotime_enable_test_mocking(); 2771 MOCK(tor_gettimeofday, mock_tor_gettimeofday); 2772 mocked_timeofday = 23; 2773 2774 helper_create_ender_machine(); 2775 2776 /* Enable manual circuit lifetime manage for this test */ 2777 circ_client_machine.manage_circ_lifetime = 1; 2778 2779 /* Test setup */ 2780 client_side->padding_machine[0] = &circ_client_machine; 2781 client_side->padding_info[0] = 2782 circpad_circuit_machineinfo_new(client_side, 0); 2783 mi = client_side->padding_info[0]; 2784 2785 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_START); 2786 2787 /* Check that the circuit is not marked for close */ 2788 tt_int_op(client_side->marked_for_close, OP_EQ, 0); 2789 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL); 2790 2791 /* Mark this circuit for close due to a remote reason */ 2792 circuit_mark_for_close(client_side, 2793 END_CIRC_REASON_FLAG_REMOTE|END_CIRC_REASON_NONE); 2794 tt_ptr_op(client_side->padding_info[0], OP_NE, NULL); 2795 tt_int_op(client_side->marked_for_close, OP_NE, 0); 2796 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL); 2797 client_side->marked_for_close = 0; 2798 2799 /* Mark this circuit for close due to a protocol issue */ 2800 circuit_mark_for_close(client_side, END_CIRC_REASON_TORPROTOCOL); 2801 tt_int_op(client_side->marked_for_close, OP_NE, 0); 2802 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL); 2803 client_side->marked_for_close = 0; 2804 2805 /* Mark a measurement circuit for close */ 2806 client_side->purpose = CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT; 2807 circuit_mark_for_close(client_side, END_CIRC_REASON_NONE); 2808 tt_int_op(client_side->marked_for_close, OP_NE, 0); 2809 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT); 2810 client_side->marked_for_close = 0; 2811 2812 /* Mark a general circuit for close */ 2813 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2814 circuit_mark_for_close(client_side, END_CIRC_REASON_NONE); 2815 2816 /* Check that this circuit is still not marked for close since we are 2817 * managing the lifetime manually, but the circuit was tagged as such by the 2818 * circpadding subsystem */ 2819 tt_int_op(client_side->marked_for_close, OP_EQ, 0); 2820 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_CIRCUIT_PADDING); 2821 2822 /* We just tested case (1) from the comments of 2823 * circpad_circuit_should_be_marked_for_close() */ 2824 2825 /* Transition the machine to the END state but did not delete its machine */ 2826 tt_ptr_op(client_side->padding_info[0], OP_NE, NULL); 2827 circpad_cell_event_nonpadding_received(client_side); 2828 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END); 2829 2830 /* We just tested case (3) from the comments of 2831 * circpad_circuit_should_be_marked_for_close(). 2832 * Now let's go for case (2). */ 2833 2834 /* Reset the close mark */ 2835 client_side->marked_for_close = 0; 2836 2837 /* Mark this circuit for close */ 2838 circuit_mark_for_close(client_side, 0); 2839 2840 /* See that the circ got closed since we are already in END state */ 2841 tt_int_op(client_side->marked_for_close, OP_NE, 0); 2842 2843 /* We just tested case (2). Now let's see that case (4) is unreachable as 2844 that comment claims */ 2845 2846 /* First, reset all close marks and tags */ 2847 client_side->marked_for_close = 0; 2848 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2849 2850 /* Now re-create the ender machine so that we can transition to END again */ 2851 /* Free up some stuff first */ 2852 circpad_circuit_free_all_machineinfos(client_side); 2853 tor_free(circ_client_machine.states); 2854 helper_create_ender_machine(); 2855 2856 client_side->padding_machine[0] = &circ_client_machine; 2857 client_side->padding_info[0] = 2858 circpad_circuit_machineinfo_new(client_side, 0); 2859 mi = client_side->padding_info[0]; 2860 2861 /* Check we are in START. */ 2862 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_START); 2863 2864 /* Test that we don't expire this circuit yet */ 2865 client_side->timestamp_dirty = 0; 2866 client_side->state = CIRCUIT_STATE_OPEN; 2867 tor_gettimeofday(&client_side->timestamp_began); 2868 TO_ORIGIN_CIRCUIT(client_side)->circuit_idle_timeout = 23; 2869 mocked_timeofday += 24; 2870 circuit_expire_old_circuits_clientside(); 2871 circuit_expire_old_circuits_clientside(); 2872 circuit_expire_old_circuits_clientside(); 2873 tt_int_op(client_side->timestamp_dirty, OP_NE, 0); 2874 tt_int_op(client_side->marked_for_close, OP_EQ, 0); 2875 tt_int_op(client_side->purpose, OP_EQ, CIRCUIT_PURPOSE_C_CIRCUIT_PADDING); 2876 2877 /* Runaway circpad test: if the machine does not transition to end, 2878 * test that after CIRCPAD_DELAY_MAX_SECS, we get marked anyway */ 2879 mocked_timeofday = client_side->timestamp_dirty 2880 + get_options()->MaxCircuitDirtiness + 2; 2881 client_side->padding_info[0]->last_cell_time_sec = 2882 approx_time()-(CIRCPAD_DELAY_MAX_SECS+10); 2883 circuit_expire_old_circuits_clientside(); 2884 tt_int_op(client_side->marked_for_close, OP_NE, 0); 2885 2886 /* Test back to normal: if we had activity, we won't close */ 2887 client_side->padding_info[0]->last_cell_time_sec = approx_time(); 2888 client_side->marked_for_close = 0; 2889 circuit_expire_old_circuits_clientside(); 2890 tt_int_op(client_side->marked_for_close, OP_EQ, 0); 2891 2892 /* Transition to END, but before we're past the dirty timer */ 2893 mocked_timeofday = client_side->timestamp_dirty; 2894 circpad_cell_event_nonpadding_received(client_side); 2895 tt_int_op(mi->current_state, OP_EQ, CIRCPAD_STATE_END); 2896 2897 /* Verify that the circuit was not closed. */ 2898 tt_int_op(client_side->marked_for_close, OP_EQ, 0); 2899 2900 /* Now that we are in END state, we can be closed by expiry, but via 2901 * the timestamp_dirty path, not the idle path. So first test not dirty 2902 * enough. */ 2903 mocked_timeofday = client_side->timestamp_dirty; 2904 circuit_expire_old_circuits_clientside(); 2905 tt_int_op(client_side->marked_for_close, OP_EQ, 0); 2906 mocked_timeofday = client_side->timestamp_dirty 2907 + get_options()->MaxCircuitDirtiness + 2; 2908 circuit_expire_old_circuits_clientside(); 2909 tt_int_op(client_side->marked_for_close, OP_NE, 0); 2910 2911 done: 2912 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 2913 tor_free(circ_client_machine.states); 2914 monotime_disable_test_mocking(); 2915 UNMOCK(tor_gettimeofday); 2916 } 2917 2918 /** Helper for the test_circuitpadding_hs_machines test: 2919 * 2920 * - Create a client and relay circuit. 2921 * - Setup right circuit purpose and attach a machine to the client circuit. 2922 * - Verify that state transitions work as intended and state length gets 2923 * enforced. 2924 * 2925 * This function is able to do this test both for intro and rend circuits 2926 * depending on the value of <b>test_intro_circs</b>. 2927 */ 2928 static void 2929 helper_test_hs_machines(bool test_intro_circs) 2930 { 2931 /* Setup the circuits */ 2932 origin_circuit_t *origin_client_side = origin_circuit_new(); 2933 client_side = TO_CIRCUIT(origin_client_side); 2934 client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; 2935 2936 dummy_channel.cmux = circuitmux_alloc(); 2937 relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); 2938 relay_side->purpose = CIRCUIT_PURPOSE_OR; 2939 2940 /* extend the client circ to two hops */ 2941 simulate_single_hop_extend(client_side, relay_side, 1); 2942 simulate_single_hop_extend(client_side, relay_side, 1); 2943 2944 /* machines only apply on opened circuits */ 2945 origin_client_side->has_opened = 1; 2946 2947 /************************************/ 2948 2949 /* Attaching the client machine now won't work here because of a wrong 2950 * purpose */ 2951 tt_assert(!client_side->padding_machine[0]); 2952 circpad_add_matching_machines(origin_client_side, origin_padding_machines); 2953 tt_assert(!client_side->padding_machine[0]); 2954 2955 /* Change the purpose, see the machine getting attached */ 2956 client_side->purpose = test_intro_circs ? 2957 CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT : CIRCUIT_PURPOSE_C_REND_JOINED; 2958 circpad_add_matching_machines(origin_client_side, origin_padding_machines); 2959 tt_ptr_op(client_side->padding_info[0], OP_NE, NULL); 2960 tt_ptr_op(client_side->padding_machine[0], OP_NE, NULL); 2961 2962 tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL); 2963 tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL); 2964 2965 /* Verify that the right machine is attached */ 2966 tt_str_op(client_side->padding_machine[0]->name, OP_EQ, 2967 test_intro_circs ? "client_ip_circ" : "client_rp_circ"); 2968 tt_str_op(relay_side->padding_machine[0]->name, OP_EQ, 2969 test_intro_circs ? "relay_ip_circ": "relay_rp_circ"); 2970 2971 /***********************************/ 2972 2973 /* Intro machines are at START state, but rend machines have already skipped 2974 * to OBFUSCATE_CIRC_SETUP because of the sent PADDING_NEGOTIATE. */ 2975 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 2976 CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); 2977 tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, 2978 CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); 2979 2980 /*Send non-padding to move the machines from START to OBFUSCATE_CIRC_SETUP */ 2981 circpad_cell_event_nonpadding_received(client_side); 2982 circpad_cell_event_nonpadding_received(relay_side); 2983 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 2984 CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); 2985 tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, 2986 CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); 2987 2988 /* Check that the state lengths have been sampled and are within range */ 2989 circpad_machine_runtime_t *client_machine_runtime = 2990 client_side->padding_info[0]; 2991 circpad_machine_runtime_t *relay_machine_runtime = 2992 relay_side->padding_info[0]; 2993 2994 if (test_intro_circs) { 2995 /* on the client side, we don't send any padding so 2996 * state length is not set */ 2997 tt_i64_op(client_machine_runtime->state_length, OP_EQ, -1); 2998 /* relay side has state limits. check them */ 2999 tt_i64_op(relay_machine_runtime->state_length, OP_GE, 3000 INTRO_MACHINE_MINIMUM_PADDING); 3001 tt_i64_op(relay_machine_runtime->state_length, OP_LT, 3002 INTRO_MACHINE_MAXIMUM_PADDING); 3003 } else { 3004 tt_i64_op(client_machine_runtime->state_length, OP_EQ, 1); 3005 tt_i64_op(relay_machine_runtime->state_length, OP_EQ, 1); 3006 } 3007 3008 if (test_intro_circs) { 3009 int i; 3010 /* Send state_length worth of padding from the relay and see that the 3011 * client state goes to END */ 3012 for (i = (int) relay_machine_runtime->state_length ; i > 0 ; i--) { 3013 circpad_send_padding_cell_for_callback(relay_machine_runtime); 3014 } 3015 /* See that the machine has been teared down after all the length has been 3016 * exhausted (the padding info should now be null on both sides) */ 3017 tt_ptr_op(relay_side->padding_info[0], OP_EQ, NULL); 3018 tt_ptr_op(client_side->padding_info[0], OP_EQ, NULL); 3019 } else { 3020 int i; 3021 /* Send state_length worth of padding and see that the state goes to END */ 3022 for (i = (int) client_machine_runtime->state_length ; i > 0 ; i--) { 3023 circpad_send_padding_cell_for_callback(client_machine_runtime); 3024 } 3025 /* See that the machine has been teared down after all the length has been 3026 * exhausted. */ 3027 tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, 3028 CIRCPAD_STATE_END); 3029 } 3030 3031 done: 3032 free_fake_orcirc(TO_OR_CIRCUIT(relay_side)); 3033 circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); 3034 circuitmux_free(dummy_channel.cmux); 3035 free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); 3036 } 3037 3038 /** Test that the HS circuit padding machines work as intended. */ 3039 static void 3040 test_circuitpadding_hs_machines(void *arg) 3041 { 3042 (void)arg; 3043 3044 /* Test logic: 3045 * 3046 * 1) Register the HS machines, which aim to hide the presence of 3047 * onion service traffic on the client-side 3048 * 3049 * 2) Call helper_test_hs_machines() to perform tests for the intro circuit 3050 * machines and for the rend circuit machines. 3051 */ 3052 3053 MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); 3054 MOCK(circuit_package_relay_cell, circuit_package_relay_cell_mock); 3055 MOCK(circuit_get_nth_node, circuit_get_nth_node_mock); 3056 MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); 3057 3058 origin_padding_machines = smartlist_new(); 3059 relay_padding_machines = smartlist_new(); 3060 3061 nodes_init(); 3062 3063 monotime_init(); 3064 monotime_enable_test_mocking(); 3065 monotime_set_mock_time_nsec(1*TOR_NSEC_PER_USEC); 3066 monotime_coarse_set_mock_time_nsec(1*TOR_NSEC_PER_USEC); 3067 curr_mocked_time = 1*TOR_NSEC_PER_USEC; 3068 3069 timers_initialize(); 3070 3071 /* This is needed so that we are not considered to be dormant */ 3072 note_user_activity(20); 3073 3074 /************************************/ 3075 3076 /* Register the HS machines */ 3077 circpad_machine_client_hide_intro_circuits(origin_padding_machines); 3078 circpad_machine_client_hide_rend_circuits(origin_padding_machines); 3079 circpad_machine_relay_hide_intro_circuits(relay_padding_machines); 3080 circpad_machine_relay_hide_rend_circuits(relay_padding_machines); 3081 3082 /***********************************/ 3083 3084 /* Do the tests for the intro circuit machines */ 3085 helper_test_hs_machines(true); 3086 /* Do the tests for the rend circuit machines */ 3087 helper_test_hs_machines(false); 3088 3089 timers_shutdown(); 3090 monotime_disable_test_mocking(); 3091 3092 SMARTLIST_FOREACH_BEGIN(origin_padding_machines, 3093 circpad_machine_spec_t *, m) { 3094 machine_spec_free(m); 3095 } SMARTLIST_FOREACH_END(m); 3096 3097 SMARTLIST_FOREACH_BEGIN(relay_padding_machines, 3098 circpad_machine_spec_t *, m) { 3099 machine_spec_free(m); 3100 } SMARTLIST_FOREACH_END(m); 3101 3102 smartlist_free(origin_padding_machines); 3103 smartlist_free(relay_padding_machines); 3104 3105 UNMOCK(circuitmux_attach_circuit); 3106 UNMOCK(circuit_package_relay_cell); 3107 UNMOCK(circuit_get_nth_node); 3108 UNMOCK(circpad_machine_schedule_padding); 3109 } 3110 3111 /** Test that we effectively ignore non-padding cells in padding circuits. */ 3112 static void 3113 test_circuitpadding_ignore_non_padding_cells(void *arg) 3114 { 3115 int retval; 3116 3117 (void) arg; 3118 3119 client_side = (circuit_t *)origin_circuit_new(); 3120 client_side->purpose = CIRCUIT_PURPOSE_C_CIRCUIT_PADDING; 3121 3122 relay_msg_t msg; 3123 memset(&msg, 0, sizeof(msg)); 3124 msg.command = RELAY_COMMAND_BEGIN; 3125 3126 setup_full_capture_of_logs(LOG_INFO); 3127 retval = handle_relay_msg(&msg, client_side, NULL, NULL, 0); 3128 tt_int_op(retval, OP_EQ, 0); 3129 expect_log_msg_containing("Ignored cell"); 3130 3131 done: 3132 ; 3133 } 3134 3135 #define TEST_CIRCUITPADDING(name, flags) \ 3136 { #name, test_##name, (flags), NULL, NULL } 3137 3138 struct testcase_t circuitpadding_tests[] = { 3139 TEST_CIRCUITPADDING(circuitpadding_tokens, TT_FORK), 3140 TEST_CIRCUITPADDING(circuitpadding_state_length, TT_FORK), 3141 TEST_CIRCUITPADDING(circuitpadding_negotiation, TT_FORK), 3142 TEST_CIRCUITPADDING(circuitpadding_wronghop, TT_FORK), 3143 /** Disabled unstable test until #29298 is implemented (see #29122) */ 3144 // TEST_CIRCUITPADDING(circuitpadding_circuitsetup_machine, TT_FORK), 3145 TEST_CIRCUITPADDING(circuitpadding_conditions, TT_FORK), 3146 TEST_CIRCUITPADDING(circuitpadding_rtt, TT_FORK), 3147 TEST_CIRCUITPADDING(circuitpadding_sample_distribution, TT_FORK), 3148 TEST_CIRCUITPADDING(circuitpadding_machine_rate_limiting, TT_FORK), 3149 TEST_CIRCUITPADDING(circuitpadding_global_rate_limiting, TT_FORK), 3150 TEST_CIRCUITPADDING(circuitpadding_reduce_disable, TT_FORK), 3151 TEST_CIRCUITPADDING(circuitpadding_token_removal_lower, TT_FORK), 3152 TEST_CIRCUITPADDING(circuitpadding_token_removal_higher, TT_FORK), 3153 TEST_CIRCUITPADDING(circuitpadding_closest_token_removal, TT_FORK), 3154 TEST_CIRCUITPADDING(circuitpadding_closest_token_removal_usec, TT_FORK), 3155 TEST_CIRCUITPADDING(circuitpadding_token_removal_exact, TT_FORK), 3156 TEST_CIRCUITPADDING(circuitpadding_manage_circuit_lifetime, TT_FORK), 3157 TEST_CIRCUITPADDING(circuitpadding_hs_machines, TT_FORK), 3158 TEST_CIRCUITPADDING(circuitpadding_ignore_non_padding_cells, TT_FORK), 3159 END_OF_TESTCASES 3160 };