aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_circuitpadding.c
diff options
context:
space:
mode:
authorGeorge Kadianakis <desnacked@riseup.net>2019-05-16 14:02:16 +0300
committerGeorge Kadianakis <desnacked@riseup.net>2019-05-16 14:23:17 +0300
commitac895fa40552b78744eddfb648dadde23834e553 (patch)
tree09eb7b3ccea1ad3ae63ab82bdd9ba9e52e19dd9e /src/test/test_circuitpadding.c
parent9b582edddb3a56d0eb2049820c6e14bfead7b143 (diff)
downloadtor-ac895fa40552b78744eddfb648dadde23834e553.tar.gz
tor-ac895fa40552b78744eddfb648dadde23834e553.zip
Add client-side onion service circuit hiding machines.
Diffstat (limited to 'src/test/test_circuitpadding.c')
-rw-r--r--src/test/test_circuitpadding.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c
index c5aad0f5d9..7835b438f8 100644
--- a/src/test/test_circuitpadding.c
+++ b/src/test/test_circuitpadding.c
@@ -415,6 +415,8 @@ helper_create_basic_machine(void)
/* Start, burst */
circpad_machine_states_init(&circ_client_machine, 2);
+ circ_client_machine.name = "basic";
+
circ_client_machine.states[CIRCPAD_STATE_START].
next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_BURST;
circ_client_machine.states[CIRCPAD_STATE_START].use_rtt_estimate = 1;
@@ -2917,6 +2919,192 @@ test_circuitpadding_manage_circuit_lifetime(void *arg)
UNMOCK(tor_gettimeofday);
}
+/** Helper for the test_circuitpadding_hs_machines test:
+ *
+ * - Create a client and relay circuit.
+ * - Setup right circuit purpose and attach a machine to the client circuit.
+ * - Verify that state transitions work as intended and state length gets
+ * enforced.
+ *
+ * This function is able to do this test both for intro and rend circuits
+ * depending on the value of <b>test_intro_circs</b>.
+ */
+static void
+helper_test_hs_machines(bool test_intro_circs)
+{
+ /* Setup the circuits */
+ origin_circuit_t *origin_client_side = origin_circuit_new();
+ client_side = TO_CIRCUIT(origin_client_side);
+ client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL;
+
+ dummy_channel.cmux = circuitmux_alloc();
+ relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel));
+ relay_side->purpose = CIRCUIT_PURPOSE_OR;
+
+ /* extend the client circ to two hops */
+ simulate_single_hop_extend(client_side, relay_side, 1);
+ simulate_single_hop_extend(client_side, relay_side, 1);
+
+ /* machines only apply on opened circuits */
+ origin_client_side->has_opened = 1;
+
+ /************************************/
+
+ /* Attaching the client machine now won't work here because of a wrong
+ * purpose */
+ tt_assert(!client_side->padding_machine[0]);
+ circpad_add_matching_machines(origin_client_side, origin_padding_machines);
+ tt_assert(!client_side->padding_machine[0]);
+
+ /* Change the purpose, see the machine getting attached */
+ client_side->purpose = test_intro_circs ?
+ CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT : CIRCUIT_PURPOSE_C_REND_JOINED;
+ circpad_add_matching_machines(origin_client_side, origin_padding_machines);
+ tt_ptr_op(client_side->padding_info[0], OP_NE, NULL);
+ tt_ptr_op(client_side->padding_machine[0], OP_NE, NULL);
+
+ tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL);
+ tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL);
+
+ /* Verify that the right machine is attached */
+ tt_str_op(client_side->padding_machine[0]->name, OP_EQ,
+ test_intro_circs ? "client_ip_circ" : "client_rp_circ");
+ tt_str_op(relay_side->padding_machine[0]->name, OP_EQ,
+ test_intro_circs ? "relay_ip_circ": "relay_rp_circ");
+
+ /***********************************/
+
+ /* Intro machines are at START state, but rend machines have already skipped
+ * to OBFUSCATE_CIRC_SETUP because of the sent PADDING_NEGOTIATE. */
+ tt_int_op(client_side->padding_info[0]->current_state, OP_EQ,
+ CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP);
+ tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ,
+ CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP);
+
+ /*Send non-padding to move the machines from START to OBFUSCATE_CIRC_SETUP */
+ circpad_cell_event_nonpadding_received(client_side);
+ circpad_cell_event_nonpadding_received(relay_side);
+ tt_int_op(client_side->padding_info[0]->current_state, OP_EQ,
+ CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP);
+ tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ,
+ CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP);
+
+ /* For rendezvous circuit machines we can stop early since are simpler than
+ * the intro circuit machines. */
+ if (!test_intro_circs) {
+ tt_int_op(client_side->padding_info[0]->histogram[0], OP_EQ, 1);
+ goto done;
+ }
+
+ /* Check that the state lengths have been sampled and are within range */
+ circpad_machine_runtime_t *client_machine_runtime =
+ client_side->padding_info[0];
+ circpad_machine_runtime_t *relay_machine_runtime =
+ relay_side->padding_info[0];
+ if (test_intro_circs) {
+ tt_int_op(client_machine_runtime->state_length, OP_GE,
+ INTRO_MACHINE_MINIMUM_PADDING);
+ tt_int_op(client_machine_runtime->state_length, OP_LT,
+ INTRO_MACHINE_MAXIMUM_PADDING);
+ tt_int_op(relay_machine_runtime->state_length, OP_GE,
+ INTRO_MACHINE_MINIMUM_PADDING);
+ tt_int_op(relay_machine_runtime->state_length, OP_LT,
+ INTRO_MACHINE_MAXIMUM_PADDING);
+ } else {
+ tt_int_op(client_machine_runtime->state_length, OP_EQ, 1);
+ tt_int_op(relay_machine_runtime->state_length, OP_EQ, 1);
+ }
+
+ /* Send state_length worth of padding and see that the state goes to END */
+ int i;
+ for (i = (int) client_machine_runtime->state_length ; i > 0 ; i--) {
+ circpad_send_padding_cell_for_callback(client_machine_runtime);
+ }
+ /* See that the machine has been teared down after all the length has been
+ * exhausted. */
+ tt_int_op(client_side->padding_info[0]->current_state, OP_EQ,
+ CIRCPAD_STATE_END);
+
+ done:
+ free_fake_orcirc(relay_side);
+ circuitmux_detach_all_circuits(dummy_channel.cmux, NULL);
+ circuitmux_free(dummy_channel.cmux);
+ free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side));
+}
+
+/** Test that the HS circuit padding machines work as intended. */
+static void
+test_circuitpadding_hs_machines(void *arg)
+{
+ (void)arg;
+
+ /* Test logic:
+ *
+ * 1) Register the HS machines, which aim to hide the presense of
+ * onion service traffic on the client-side
+ *
+ * 2) Call helper_test_hs_machines() to perform tests for the intro circuit
+ * machines and for the rend circuit machines.
+ */
+
+ MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock);
+ MOCK(circuit_package_relay_cell, circuit_package_relay_cell_mock);
+ MOCK(circuit_get_nth_node, circuit_get_nth_node_mock);
+ MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock);
+
+ origin_padding_machines = smartlist_new();
+ relay_padding_machines = smartlist_new();
+
+ nodes_init();
+
+ monotime_init();
+ monotime_enable_test_mocking();
+ monotime_set_mock_time_nsec(1*TOR_NSEC_PER_USEC);
+ monotime_coarse_set_mock_time_nsec(1*TOR_NSEC_PER_USEC);
+ curr_mocked_time = 1*TOR_NSEC_PER_USEC;
+
+ timers_initialize();
+
+ /* This is needed so that we are not considered to be dormant */
+ note_user_activity(20);
+
+ /************************************/
+
+ /* Register the HS machines */
+ circpad_machine_client_hide_intro_circuits(origin_padding_machines);
+ circpad_machine_client_hide_rend_circuits(origin_padding_machines);
+ circpad_machine_relay_hide_intro_circuits(relay_padding_machines);
+ circpad_machine_relay_hide_rend_circuits(relay_padding_machines);
+
+ /***********************************/
+
+ /* Do the tests for the intro circuit machines */
+ helper_test_hs_machines(true);
+ /* Do the tests for the rend circuit machines */
+ helper_test_hs_machines(false);
+
+ timers_shutdown();
+ monotime_disable_test_mocking();
+
+ SMARTLIST_FOREACH_BEGIN(origin_padding_machines,
+ circpad_machine_spec_t *, m) {
+ machine_spec_free(m);
+ } SMARTLIST_FOREACH_END(m);
+
+ SMARTLIST_FOREACH_BEGIN(relay_padding_machines,
+ circpad_machine_spec_t *, m) {
+ machine_spec_free(m);
+ } SMARTLIST_FOREACH_END(m);
+
+ smartlist_free(origin_padding_machines);
+ smartlist_free(relay_padding_machines);
+
+ UNMOCK(circuitmux_attach_circuit);
+ UNMOCK(circuit_package_relay_cell);
+ UNMOCK(circuit_get_nth_node);
+ UNMOCK(circpad_machine_schedule_padding);
+}
+
#define TEST_CIRCUITPADDING(name, flags) \
{ #name, test_##name, (flags), NULL, NULL }