LCOV - code coverage report
Current view: top level - test - test_circuitpadding.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1508 1512 99.7 %
Date: 2021-11-24 03:28:48 Functions: 40 41 97.6 %

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

Generated by: LCOV version 1.14