diff --git a/configure.ac b/configure.ac index 14147eef77..78597e511d 100644 --- a/configure.ac +++ b/configure.ac @@ -1210,6 +1210,11 @@ if test "$fragile_hardening" = "yes"; then AC_MSG_ERROR([The compiler supports -fsanitize=undefined, but for some reason I was not able to link when using it. Are you missing run-time support? With GCC you need libasan.*, and with Clang you need libclang_rt.ubsan*]) fi + TOR_TRY_COMPILE_WITH_CFLAGS([-fno-sanitize=float-divide-by-zero], also_link, CFLAGS_UBSAN="-fno-sanitize=float-divide-by-zero", true) + if test "$tor_cv_cflags__fno_sanitize_float_divide_by_zero" = "yes" && test "$tor_can_link__fno_sanitize_float_divide_by_zero" != "yes"; then + AC_MSG_ERROR([The compiler supports -fno-sanitize=float-divide-by-zero, but for some reason I was not able to link when using it. Are you missing run-time support? With GCC you need libasan.*, and with Clang you need libclang_rt.ubsan*]) + fi + TOR_CHECK_CFLAGS([-fno-omit-frame-pointer]) fi diff --git a/src/core/or/circuitpadding.c b/src/core/or/circuitpadding.c index 2895d49e18..9d129f15ed 100644 --- a/src/core/or/circuitpadding.c +++ b/src/core/or/circuitpadding.c @@ -393,11 +393,14 @@ circpad_distribution_sample_iat_delay(const circpad_state_t *state, double val = circpad_distribution_sample(state->iat_dist); /* These comparisons are safe, because the output is in the range * [0, 2**32), and double has a precision of 53 bits. */ + /* We want a positive sample value */ val = MAX(0, val); + /* Respect the maximum sample setting */ val = MIN(val, state->dist_max_sample_usec); - /* This addition is exact: val is at most 2**32-1, min_delay - * is at most 2**32-1, and doubles have a precision of 53 bits. */ + /* Now apply the shift: + * This addition is exact: val is at most 2**32-1, delay_shift is at most + * 2**32-1, and doubles have a precision of 53 bits. */ val += delay_shift; /* Clamp the distribution at infinite delay val */ diff --git a/src/core/or/circuitpadding.h b/src/core/or/circuitpadding.h index 54039fa59a..a49ec069df 100644 --- a/src/core/or/circuitpadding.h +++ b/src/core/or/circuitpadding.h @@ -198,14 +198,23 @@ typedef enum { * These can be used instead of histograms for the inter-packet * timing distribution, or to specify a distribution on the number * of cells that can be sent while in a specific state of the state - * machine. */ + * machine. + * + * Each distribution takes up to two parameters which are described below. */ typedef enum { + /* No probability distribution is used */ CIRCPAD_DIST_NONE = 0, + /* Uniform distribution: param1 is lower bound and param2 is upper bound */ CIRCPAD_DIST_UNIFORM = 1, + /* Logistic distribution: param1 is Mu, param2 is sigma. */ CIRCPAD_DIST_LOGISTIC = 2, + /* Log-logistic distribution: param1 is Alpha, param2 is 1.0/Beta */ CIRCPAD_DIST_LOG_LOGISTIC = 3, + /* Geometric distribution: param1 is 'p' (success probability) */ CIRCPAD_DIST_GEOMETRIC = 4, + /* Weibull distribution: param1 is k, param2 is Lambda */ CIRCPAD_DIST_WEIBULL = 5, + /* Generalized Pareto distribution: param1 is sigma, param2 is xi */ CIRCPAD_DIST_PARETO = 6 } circpad_distribution_type_t; diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c index 1976e54bb9..a2381023ca 100644 --- a/src/test/test_circuitpadding.c +++ b/src/test/test_circuitpadding.c @@ -2097,6 +2097,7 @@ helper_circpad_circ_distribution_machine_setup(int min, int max) circpad_state_t *zero_st = &circ_client_machine.states[0]; zero_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 1; zero_st->iat_dist.type = CIRCPAD_DIST_UNIFORM; + /* param2 is upper bound, param1 is lower */ zero_st->iat_dist.param1 = min; zero_st->iat_dist.param2 = max; zero_st->dist_added_shift_usec = min; @@ -2105,48 +2106,50 @@ helper_circpad_circ_distribution_machine_setup(int min, int max) circpad_state_t *first_st = &circ_client_machine.states[1]; first_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 2; first_st->iat_dist.type = CIRCPAD_DIST_LOGISTIC; - first_st->iat_dist.param1 = min; - first_st->iat_dist.param2 = max; + /* param1 is Mu, param2 is sigma. */ + first_st->iat_dist.param1 = 9; + first_st->iat_dist.param2 = 3; first_st->dist_added_shift_usec = min; first_st->dist_max_sample_usec = max; circpad_state_t *second_st = &circ_client_machine.states[2]; second_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 3; second_st->iat_dist.type = CIRCPAD_DIST_LOG_LOGISTIC; - second_st->iat_dist.param1 = min; - second_st->iat_dist.param2 = max; + /* param1 is Alpha, param2 is 1.0/Beta */ + second_st->iat_dist.param1 = 1; + second_st->iat_dist.param2 = 0.5; second_st->dist_added_shift_usec = min; second_st->dist_max_sample_usec = max; circpad_state_t *third_st = &circ_client_machine.states[3]; third_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 4; third_st->iat_dist.type = CIRCPAD_DIST_GEOMETRIC; - third_st->iat_dist.param1 = min; - third_st->iat_dist.param2 = max; + /* param1 is 'p' (success probability) */ + third_st->iat_dist.param1 = 0.2; third_st->dist_added_shift_usec = min; third_st->dist_max_sample_usec = max; circpad_state_t *fourth_st = &circ_client_machine.states[4]; fourth_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 5; fourth_st->iat_dist.type = CIRCPAD_DIST_WEIBULL; - fourth_st->iat_dist.param1 = min; - fourth_st->iat_dist.param2 = max; + /* param1 is k, param2 is Lambda */ + fourth_st->iat_dist.param1 = 1.5; + fourth_st->iat_dist.param2 = 1; fourth_st->dist_added_shift_usec = min; fourth_st->dist_max_sample_usec = max; circpad_state_t *fifth_st = &circ_client_machine.states[5]; fifth_st->next_state[CIRCPAD_EVENT_NONPADDING_RECV] = 6; fifth_st->iat_dist.type = CIRCPAD_DIST_PARETO; - fifth_st->iat_dist.param1 = min; - fifth_st->iat_dist.param2 = max; + /* param1 is sigma, param2 is xi */ + fifth_st->iat_dist.param1 = 1; + fifth_st->iat_dist.param2 = 5; fifth_st->dist_added_shift_usec = min; fifth_st->dist_max_sample_usec = max; } /** Simple test that the padding delays sampled from a uniform distribution * actually faill within the uniform distribution range. */ -/* TODO: Upgrade this test so that each state tests a different prob - * distribution */ static void test_circuitpadding_sample_distribution(void *arg) { @@ -2160,8 +2163,7 @@ test_circuitpadding_sample_distribution(void *arg) MOCK(circpad_machine_schedule_padding, circpad_machine_schedule_padding_mock); - /* Initialize a machine with multiple probability distributions that should - * return values between 0 and 5 */ + /* Initialize a machine with multiple probability distributions */ circpad_machines_init(); helper_circpad_circ_distribution_machine_setup(0, 10);