diff --git a/changes/bug29500 b/changes/bug29500 new file mode 100644 index 0000000000..16550935b2 --- /dev/null +++ b/changes/bug29500 @@ -0,0 +1,3 @@ + o Minor bugfixes (circuitpadding testing): + - Minor tweaks to avoid very rare test failures related to timers and + monotime. Fixes bug 29500; bugfix on 0.4.0.1-alpha diff --git a/src/core/or/circuitpadding.c b/src/core/or/circuitpadding.c index d9b3a0fb58..d30edf9db8 100644 --- a/src/core/or/circuitpadding.c +++ b/src/core/or/circuitpadding.c @@ -1458,7 +1458,8 @@ circpad_estimate_circ_rtt_on_send(circuit_t *circ, /* If the old RTT estimate is lower than this one, use this one, because * the circuit is getting longer. If this estimate is somehow - * faster than the previous, then maybe that was network jitter. + * faster than the previous, then maybe that was network jitter, or a + * bad monotonic clock source (so our ratchet returned a zero delta). * In that case, average them. */ if (mi->rtt_estimate_usec < (circpad_delay_t)rtt_time) { mi->rtt_estimate_usec = (circpad_delay_t)rtt_time; diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c index 3ae1860c24..3289c866cf 100644 --- a/src/test/test_circuitpadding.c +++ b/src/test/test_circuitpadding.c @@ -32,6 +32,12 @@ #include "core/or/or_circuit_st.h" #include "core/or/origin_circuit_st.h" +/* Start our monotime mocking at 1 second past whatever monotime_init() + * thought the actual wall clock time was, for platforms with bad resolution + * and weird timevalues during monotime_init() before mocking. */ +#define MONOTIME_MOCK_START (monotime_absolute_nsec()+\ + TOR_NSEC_PER_USEC*TOR_USEC_PER_SEC) + extern smartlist_t *connection_array; circid_t get_unique_circ_id_by_chan(channel_t *chan); @@ -287,6 +293,7 @@ test_circuitpadding_rtt(void *arg) * 3. Test client side circuit and non-application of RTT.. */ circpad_delay_t rtt_estimate; + int64_t actual_mocked_monotime_start; (void)arg; MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); @@ -300,9 +307,10 @@ test_circuitpadding_rtt(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; timers_initialize(); circpad_machines_init(); @@ -590,7 +598,7 @@ test_circuitpadding_token_removal_higher(void *arg) } } - /* Check that all lowe bins are not touched */ + /* Check that all lower bins are not touched */ for (i=0; i < 4 ; i++) { tt_int_op(mi->histogram[i], OP_EQ, 2); } @@ -990,6 +998,7 @@ test_circuitpadding_tokens(void *arg) { const circpad_state_t *state; circpad_machine_runtime_t *mi; + int64_t actual_mocked_monotime_start; (void)arg; /** Test plan: @@ -1017,9 +1026,10 @@ test_circuitpadding_tokens(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; /* This is needed so that we are not considered to be dormant */ note_user_activity(20); @@ -1034,9 +1044,8 @@ test_circuitpadding_tokens(void *arg) mi = client_side->padding_info[0]; // Pretend a non-padding cell was sent - // XXX: This messes us up.. Padding gets scheduled.. - circpad_cell_event_nonpadding_sent((circuit_t*)client_side); circpad_cell_event_nonpadding_received((circuit_t*)client_side); + circpad_cell_event_nonpadding_sent((circuit_t*)client_side); /* We have to save the infinity bin because one inf delay * could have been chosen when we transition to burst */ circpad_hist_token_t inf_bin = mi->histogram[4]; @@ -1136,7 +1145,8 @@ test_circuitpadding_tokens(void *arg) /* 2.c. Bin 0 */ { - tt_int_op(mi->histogram[0], OP_EQ, 1); + tt_int_op(mi->histogram[0], OP_EQ, 0); + mi->histogram[0] = 1; circpad_machine_remove_higher_token(mi, state->histogram_edges[0]/2); tt_int_op(mi->histogram[0], OP_EQ, 0); } @@ -1264,6 +1274,7 @@ test_circuitpadding_wronghop(void *arg) cell_t cell; signed_error_t ret; origin_circuit_t *orig_client; + int64_t actual_mocked_monotime_start; MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); @@ -1283,9 +1294,10 @@ test_circuitpadding_wronghop(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; timers_initialize(); circpad_machines_init(); @@ -1456,6 +1468,7 @@ test_circuitpadding_negotiation(void *arg) * a. Make sure padding negotiation is not sent * 3. Test failure to negotiate a machine due to desync. */ + int64_t actual_mocked_monotime_start; (void)arg; MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); @@ -1470,9 +1483,10 @@ test_circuitpadding_negotiation(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; timers_initialize(); circpad_machines_init(); @@ -1736,6 +1750,7 @@ test_circuitpadding_conditions(void *arg) * 2. Test marking a circuit before padding callback fires * 3. Test freeing a circuit before padding callback fires */ + int64_t actual_mocked_monotime_start; (void)arg; MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); @@ -1749,9 +1764,10 @@ test_circuitpadding_conditions(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; /* This is needed so that we are not considered to be dormant */ note_user_activity(20); @@ -1849,6 +1865,7 @@ test_circuitpadding_conditions(void *arg) void test_circuitpadding_circuitsetup_machine(void *arg) { + int64_t actual_mocked_monotime_start; /** * Test case plan: * @@ -1874,9 +1891,10 @@ test_circuitpadding_circuitsetup_machine(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; timers_initialize(); circpad_machines_init(); @@ -2288,6 +2306,7 @@ test_circuitpadding_global_rate_limiting(void *arg) bool retval; circpad_machine_runtime_t *mi; int i; + int64_t actual_mocked_monotime_start; /* Ignore machine transitions for the purposes of this function, we only * really care about padding counts */ @@ -2299,9 +2318,10 @@ test_circuitpadding_global_rate_limiting(void *arg) 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; + actual_mocked_monotime_start = MONOTIME_MOCK_START; + monotime_set_mock_time_nsec(actual_mocked_monotime_start); + monotime_coarse_set_mock_time_nsec(actual_mocked_monotime_start); + curr_mocked_time = actual_mocked_monotime_start; timers_initialize(); client_side = (circuit_t *)origin_circuit_new();