49#define CIRCUITPADDING_PRIVATE
73#include "core/or/or_circuit_st.h"
87static void circpad_setup_machine_on_circ(
circuit_t *on_circ,
96static uint8_t circpad_padding_reduced;
97static uint8_t circpad_global_max_padding_percent;
98static uint16_t circpad_global_allowed_cells;
99static uint16_t circpad_max_circ_queued_cells;
103static uint64_t circpad_global_nonpadding_sent;
124#define FOR_EACH_CIRCUIT_MACHINE_BEGIN(loop_var) \
126 for (int loop_var = 0; loop_var < CIRCPAD_MAX_MACHINES; loop_var++) {
127#define FOR_EACH_CIRCUIT_MACHINE_END } STMT_END ;
131#define FOR_EACH_ACTIVE_CIRCUIT_MACHINE_BEGIN(loop_var, circ) \
132 FOR_EACH_CIRCUIT_MACHINE_BEGIN(loop_var) \
133 if (!(circ)->padding_info[loop_var]) \
135#define FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END } STMT_END ;
190 if (!(reason == END_CIRC_REASON_NONE ||
191 reason == END_CIRC_REASON_FINISHED ||
192 reason == END_CIRC_REASON_IP_NOW_REDUNDANT)) {
221 log_info(
LD_CIRC,
"Circuit %d is not marked for close because of a "
222 "pending padding machine in index %d.",
234 log_notice(
LD_BUG,
"Circuit %d was not marked for close because of a "
235 "pending padding machine in index %d for over an hour. "
266 } FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
281 uint32_t machine_ctr)
292 "Padding shutdown for wrong (old?) machine ctr: %u vs %u",
300 } FOR_EACH_CIRCUIT_MACHINE_END;
313 } FOR_EACH_CIRCUIT_MACHINE_END;
348 "Invalid circuit padding state %d",
375 if (BUG(state == NULL)) {
390 return state->histogram_edges[bin] + rtt_add_usec;
412 return left_bound + (right_bound - left_bound)/2;
433 if (BUG(state == NULL)) {
540 if (!state || state->
length_dist.type == CIRCPAD_DIST_NONE) {
546 length =
MAX(0, length);
555 log_info(
LD_CIRC,
"State length sampled to %"PRIu64
" for circuit %u",
576 val = MIN(val, state->dist_max_sample_usec);
604 uint64_t curr_weight = 0;
605 uint64_t histogram_total_tokens = 0;
610 if (state->
iat_dist.type != CIRCPAD_DIST_NONE) {
614 state->dist_added_shift_usec;
619 histogram_total_tokens += histogram[b];
627 if (!histogram_total_tokens) {
632 histogram_total_tokens);
635 while (!histogram[curr_bin]) {
638 curr_weight = histogram[curr_bin];
642 while (curr_weight < bin_choice) {
648 curr_weight += histogram[curr_bin];
653 BUG(histogram[curr_bin] == 0)) {
681 if (BUG(bin_start >= bin_end)) {
701 case CIRCPAD_DIST_NONE:
707 case CIRCPAD_DIST_UNIFORM:
711 .base = UNIFORM(my_uniform),
715 return dist_sample(&my_uniform.base);
717 case CIRCPAD_DIST_LOGISTIC:
721 .base = LOGISTIC(my_logistic),
723 .sigma = dist.param2,
725 return dist_sample(&my_logistic.base);
727 case CIRCPAD_DIST_LOG_LOGISTIC:
731 .base = LOG_LOGISTIC(my_log_logistic),
732 .alpha = dist.param1,
735 return dist_sample(&my_log_logistic.base);
737 case CIRCPAD_DIST_GEOMETRIC:
741 .base = GEOMETRIC(my_geometric),
744 return dist_sample(&my_geometric.base);
746 case CIRCPAD_DIST_WEIBULL:
750 .base = WEIBULL(my_weibull),
752 .lambda = dist.param2,
754 return dist_sample(&my_weibull.base);
756 case CIRCPAD_DIST_PARETO:
760 .base = GENPARETO(my_genpareto),
762 .sigma = dist.param1,
765 return dist_sample(&my_genpareto.base);
810 for (; bin >= 0; bin--) {
865#define ENSURE_BIN_CAPACITY(bin_index) \
866 if (BUG(mi->histogram[bin_index] == 0)) { \
893 if (BUG(lower > current) || BUG(higher < current)) {
903 ENSURE_BIN_CAPACITY(lower);
906 }
else if (lower == -1) {
908 ENSURE_BIN_CAPACITY(higher);
920 if (target_bin_usec < lower_usec) {
922 ENSURE_BIN_CAPACITY(lower);
923 bin_to_remove = lower;
924 }
else if (target_bin_usec > higher_usec) {
926 ENSURE_BIN_CAPACITY(higher);
927 bin_to_remove = higher;
928 }
else if (target_bin_usec-lower_usec > higher_usec-target_bin_usec) {
930 ENSURE_BIN_CAPACITY(higher);
931 bin_to_remove = higher;
934 ENSURE_BIN_CAPACITY(lower);
935 bin_to_remove = lower;
938 log_debug(
LD_CIRC,
"Removing token from bin %d", bin_to_remove);
941 if (current - lower > higher - current) {
943 ENSURE_BIN_CAPACITY(higher);
948 ENSURE_BIN_CAPACITY(lower);
955#undef ENSURE_BIN_CAPACITY
984 uint32_t histogram_total_tokens = 0;
995 histogram_total_tokens += mi->
histogram[b];
998 if (histogram_total_tokens == 0) {
1000 return CIRCPAD_STATE_CHANGED;
1008 return CIRCPAD_STATE_UNCHANGED;
1021 if (mi->
state_length != CIRCPAD_STATE_LENGTH_INFINITE &&
1170 log_warn(
LD_BUG,
"Circpad: Unknown token removal strategy %d",
1188 uint8_t relay_command,
const uint8_t *payload,
1189 ssize_t payload_len))
1202 if (target_hop->
state != CPATH_STATE_OPEN) {
1204 "Padding circuit %u has %d hops, not %d",
1211 ret = relay_send_command_from_edge(0,
TO_CIRCUIT(circ), relay_command,
1212 (
const char*)payload, payload_len,
1240 "Padding callback on circuit marked for close (%u). Ignoring.",
1243 return CIRCPAD_STATE_CHANGED;
1251 RELAY_COMMAND_DROP, NULL, 0);
1252 log_info(
LD_CIRC,
"Callback: Sending padding to origin circuit %u"
1253 " (%d) [length: %"PRIu64
"]",
1259 if (
TO_OR_CIRCUIT(circ)->p_chan_cells.n <= circpad_max_circ_queued_cells) {
1260 log_info(
LD_CIRC,
"Callback: Sending padding to circuit (%d)"
1262 relay_send_command_from_edge(0, mi->
on_circ, RELAY_COMMAND_DROP, NULL,
1266 static ratelim_t cell_lim = RATELIM_INIT(600);
1268 "Too many cells (%d) in circ queue to send padding.",
1282 return CIRCPAD_STATE_CHANGED;
1286 return CIRCPAD_STATE_CHANGED;
1303 (void)timer; (void)time;
1311 "Circuit closed while waiting for padding timer.");
1329 circpad_padding_reduced =
1333 circpad_global_allowed_cells =
1335 0, 0, UINT16_MAX-1);
1337 circpad_global_max_padding_percent =
1341 circpad_max_circ_queued_cells =
1343 CIRCWINDOW_START_MAX, 0, 50*CIRCWINDOW_START_MAX);
1399 if (circpad_global_max_padding_percent &&
1402 circpad_global_nonpadding_sent;
1406 circpad_global_max_padding_percent) {
1434 static ratelim_t padding_lim = RATELIM_INIT(600);
1436 "Padding has been disabled, but machine still on circuit %"PRIu64
1441 return CIRCPAD_STATE_UNCHANGED;
1446 log_info(
LD_CIRC,
"Not scheduling padding because we are dormant.");
1447 return CIRCPAD_STATE_UNCHANGED;
1456 return CIRCPAD_STATE_UNCHANGED;
1463 "Padding machine has reached padding limit on circuit %u",
1466 static ratelim_t padding_lim = RATELIM_INIT(600);
1468 "Padding machine has reached padding limit on circuit %"PRIu64
1473 return CIRCPAD_STATE_UNCHANGED;
1511 return CIRCPAD_STATE_UNCHANGED;
1538 return CIRCPAD_STATE_UNCHANGED;
1585 CIRCPAD_COMMAND_STOP,
1593 CIRCPAD_COMMAND_STOP,
1594 CIRCPAD_RESPONSE_OK,
1619 return CIRCPAD_STATE_UNCHANGED;
1624 return CIRCPAD_STATE_UNCHANGED;
1633 return CIRCPAD_STATE_UNCHANGED;
1644 "Circuit %u circpad machine %d transitioning from %u to %u",
1663 return CIRCPAD_STATE_CHANGED;
1668 return CIRCPAD_STATE_CHANGED;
1676 return CIRCPAD_STATE_UNCHANGED;
1717 "Stopping padding RTT estimation on circuit (%"PRIu64
1718 ", %d) after two back to back packets. Current RTT: %d",
1724 static ratelim_t rtt_lim = RATELIM_INIT(600);
1726 "Circuit got two cells back to back before estimating RTT.");
1776 if (rtt_time >= INT32_MAX) {
1778 "Circuit padding RTT estimate overflowed: %"PRIu64
1801 static ratelim_t rtt_lim = RATELIM_INIT(600);
1803 "Circuit sent two cells back to back before estimating RTT.");
1821 circpad_global_nonpadding_sent++;
1835 == CIRCPAD_STATE_UNCHANGED) {
1839 CIRCPAD_EVENT_NONPADDING_SENT);
1841 } FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
1856 case RELAY_COMMAND_DROP:
1859 case RELAY_COMMAND_PADDING_NEGOTIATE:
1862 case RELAY_COMMAND_PADDING_NEGOTIATED:
1890 "Ignored cell (%d) that arrived in padding circuit "
1916 CIRCPAD_EVENT_NONPADDING_RECV);
1917 } FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
1935 == CIRCPAD_STATE_UNCHANGED) {
1941 CIRCPAD_EVENT_PADDING_SENT);
1943 } FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
1961 CIRCPAD_EVENT_PADDING_RECV);
1962 } FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
1992 == CIRCPAD_STATE_CHANGED) {
1993 return CIRCPAD_STATE_CHANGED;
1997 return CIRCPAD_STATE_UNCHANGED;
2028 if (circpad_padding_reduced ||
get_options()->ReducedCircuitPadding) {
2094 retmask |= CIRCPAD_CIRC_STREAMS;
2096 retmask |= CIRCPAD_CIRC_NO_STREAMS;
2100 retmask |= CIRCPAD_CIRC_OPENED;
2102 retmask |= CIRCPAD_CIRC_BUILDING;
2105 retmask |= CIRCPAD_CIRC_HAS_RELAY_EARLY;
2107 retmask |= CIRCPAD_CIRC_HAS_NO_RELAY_EARLY;
2120 if (BUG(circ_purpose <= CIRCUIT_PURPOSE_OR_MAX_)) {
2126 if (BUG(circ_purpose - CIRCUIT_PURPOSE_OR_MAX_ - 1 > 32)) {
2131 return 1 << (circ_purpose - CIRCUIT_PURPOSE_OR_MAX_ - 1);
2158 CIRCPAD_COMMAND_STOP,
2161 } FOR_EACH_ACTIVE_CIRCUIT_MACHINE_END;
2180#ifdef TOR_UNIT_TESTS
2187 if (on_circ->padding_negotiation_failed)
2207 if (machine->machine_index == i &&
2214 machine->target_hopnum)
2223 circpad_setup_machine_on_circ(circ, machine);
2225 machine->target_hopnum,
2226 CIRCPAD_COMMAND_START,
2229 "Padding not negotiated. Cleaning machine from circuit %u",
2234 on_circ->padding_negotiation_failed = 1;
2240 } SMARTLIST_FOREACH_END(machine);
2241 } FOR_EACH_CIRCUIT_MACHINE_END;
2356 if (target_hop == from_hop)
2358 } FOR_EACH_CIRCUIT_MACHINE_END;
2403 uint8_t relay_command,
2406 if (relay_command == RELAY_COMMAND_DROP) {
2440 uint8_t relay_command)
2448 if (relay_command == RELAY_COMMAND_DROP) {
2479 for (
int e = 0; e < CIRCPAD_NUM_EVENTS; e++) {
2486circpad_setup_machine_on_circ(
circuit_t *on_circ,
2491 "Can't set up non-origin machine on origin circuit!");
2497 "Can't set up origin machine on non-origin circuit!");
2510 log_info(
LD_CIRC,
"Registering machine %s to origin circ %u (%d)",
2514 log_info(
LD_CIRC,
"Registering machine %s to non-origin circ (%d)",
2515 machine->name, on_circ->
purpose);
2539 uint32_t tokens_count = 0;
2549 log_warn(
LD_CIRC,
"You can't have a histogram with less than 2 bins");
2558 if (prev_bin_edge >= state->histogram_edges[b] && b > 0) {
2559 log_warn(
LD_CIRC,
"Histogram edges are not increasing [%u/%u]",
2560 prev_bin_edge, state->histogram_edges[b]);
2564 prev_bin_edge = state->histogram_edges[b];
2571 log_warn(
LD_CIRC,
"Histogram token count is wrong [%u/%u]",
2586 for (i = 0 ; i < machine->
num_states ; i++) {
2602 log_warn(
LD_CIRC,
"Machine #%u is invalid. Ignoring.",
2612#ifdef TOR_UNIT_TESTS
2615circpad_circ_client_machine_init(
void)
2622 CIRCPAD_CIRC_BUILDING|CIRCPAD_CIRC_OPENED|CIRCPAD_CIRC_HAS_RELAY_EARLY;
2665 circpad_register_padding_machine(circ_client_machine,
2670circpad_circ_responder_machine_init(
void)
2724 histogram_total_tokens = 1;
2766 circpad_register_padding_machine(circ_responder_machine,
2795#ifdef TOR_UNIT_TESTS
2796 circpad_circ_client_machine_init();
2797 circpad_circ_responder_machine_init();
2831 "supported" :
"unsupported");
2850 if (!iter || iter->
state != CPATH_STATE_OPEN)
2881 uint8_t target_hopnum,
2883 uint32_t machine_ctr)
2885 circpad_negotiate_t type;
2895 memset(&cell, 0,
sizeof(
cell_t));
2896 memset(&type, 0,
sizeof(circpad_negotiate_t));
2902 circpad_negotiate_set_command(&type,
command);
2903 circpad_negotiate_set_version(&type, 0);
2904 circpad_negotiate_set_machine_type(&type, machine);
2905 circpad_negotiate_set_machine_ctr(&type, machine_ctr);
2912 "Negotiating padding on circuit %u (%d), command %d, for ctr %u",
2917 RELAY_COMMAND_PADDING_NEGOTIATE,
2931 uint32_t machine_ctr)
2933 circpad_negotiated_t type;
2937 memset(&cell, 0,
sizeof(
cell_t));
2938 memset(&type, 0,
sizeof(circpad_negotiated_t));
2944 circpad_negotiated_set_command(&type,
command);
2945 circpad_negotiated_set_response(&type, response);
2946 circpad_negotiated_set_version(&type, 0);
2947 circpad_negotiated_set_machine_type(&type, machine);
2948 circpad_negotiated_set_machine_ctr(&type, machine_ctr);
2956 return relay_send_command_from_edge(0, circ,
2957 RELAY_COMMAND_PADDING_NEGOTIATED,
2959 (
size_t)len, NULL) == 0;
2976 bool respond_with_stop =
true;
2977 circpad_negotiate_t *negotiate;
2981 "Padding negotiate cell unsupported at origin (circuit %u)",
2989 "Received malformed PADDING_NEGOTIATE cell; dropping.");
2993 if (negotiate->command == CIRCPAD_COMMAND_STOP) {
2996 negotiate->machine_type,
2997 negotiate->machine_ctr)) {
2998 log_info(
LD_CIRC,
"Received STOP command for machine %u, ctr %u",
2999 negotiate->machine_type, negotiate->machine_ctr);
3006 respond_with_stop =
false;
3009 log_info(
LD_CIRC,
"Received STOP command for old machine %u, ctr %u",
3010 negotiate->machine_type, negotiate->machine_ctr);
3015 "Received circuit padding stop command for unknown machine.");
3018 }
else if (negotiate->command == CIRCPAD_COMMAND_START) {
3021 if (m->machine_num == negotiate->machine_type) {
3022 circpad_setup_machine_on_circ(circ, m);
3023 if (negotiate->machine_ctr &&
3026 "Client and relay have different counts for padding machines: "
3032 } SMARTLIST_FOREACH_END(m);
3039 if (respond_with_stop) {
3042 (retval == 0) ? CIRCPAD_RESPONSE_OK : CIRCPAD_RESPONSE_ERR,
3043 negotiate->machine_ctr);
3046 circpad_negotiate_free(negotiate);
3063 circpad_negotiated_t *negotiated;
3067 "Padding negotiated cell unsupported at non-origin.");
3074 "Padding negotiated cell from wrong hop on circuit %u",
3082 "Received malformed PADDING_NEGOTIATED cell on circuit %u; "
3087 if (negotiated->command == CIRCPAD_COMMAND_STOP) {
3089 "Received STOP command on PADDING_NEGOTIATED for circuit %u",
3097 negotiated->machine_ctr);
3098 }
else if (negotiated->command == CIRCPAD_COMMAND_START &&
3099 negotiated->response == CIRCPAD_RESPONSE_ERR) {
3103 negotiated->machine_ctr)) {
3107 "Middle node did not accept our padding request on circuit "
3114 circpad_negotiated_free(negotiated);
3135 machine_spec_free(m);
3136 } SMARTLIST_FOREACH_END(m);
3142 machine_spec_free(m);
3143 } SMARTLIST_FOREACH_END(m);
3162 state->transition_cancel_events);
3164 for (
int i = 0; i < CIRCPAD_NUM_STATES; i++) {
3166 state->transition_events[i]);
3181 circpad_state_serialize(&machine->start, chunks);
3182 circpad_state_serialize(&machine->gap, chunks);
3183 circpad_state_serialize(&machine->burst, chunks);
3188 smartlist_free(chunks);
3194circpad_string_to_machine(
const char *str)
Fixed-size cell structure.
Header file for channel.c.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
int circuit_get_cpath_len(origin_circuit_t *circ)
int circuit_get_cpath_opened_len(const origin_circuit_t *circ)
void assert_circuit_ok(const circuit_t *c)
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
crypt_path_t * circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
const char * circuit_purpose_to_string(uint8_t purpose)
Header file for circuitlist.c.
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING
#define CIRCUIT_STATE_OPEN
#define CIRCUIT_IS_ORIGIN(c)
#define CIRCUIT_PURPOSE_C_CIRCUIT_PADDING
STATIC const circpad_state_t * circpad_machine_current_state(const circpad_machine_runtime_t *mi)
static bool padding_machine_state_is_valid(const circpad_state_t *state)
static void circpad_send_padding_callback(tor_timer_t *timer, void *args, const struct monotime_t *time)
static void circpad_estimate_circ_rtt_on_send(circuit_t *circ, circpad_machine_runtime_t *mi)
void circpad_machines_init(void)
STATIC circpad_delay_t histogram_get_bin_upper_bound(const circpad_machine_runtime_t *mi, circpad_hist_index_t bin)
void circpad_cell_event_nonpadding_received(circuit_t *on_circ)
void circpad_machine_event_circ_added_hop(origin_circuit_t *on_circ)
static void circpad_circuit_machineinfo_free_idx(circuit_t *circ, int idx)
void circpad_new_consensus_params(const networkstatus_t *ns)
circpad_decision_t circpad_internal_event_infinity(circpad_machine_runtime_t *mi)
static bool padding_machine_is_valid(const circpad_machine_spec_t *machine)
STATIC void machine_spec_free_(circpad_machine_spec_t *m)
STATIC bool circpad_machine_reached_padding_limit(circpad_machine_runtime_t *mi)
void circpad_circuit_free_all_machineinfos(circuit_t *circ)
static int free_circ_machineinfos_with_machine_num(circuit_t *circ, int machine_num, uint32_t machine_ctr)
circpad_decision_t circpad_send_padding_cell_for_callback(circpad_machine_runtime_t *mi)
STATIC const node_t * circuit_get_nth_node(origin_circuit_t *circ, int hop)
static circpad_decision_t check_machine_token_supply(circpad_machine_runtime_t *mi)
static double circpad_distribution_sample(circpad_distribution_t dist)
STATIC circpad_machine_runtime_t * circpad_circuit_machineinfo_new(circuit_t *on_circ, int machine_index)
#define FOR_EACH_CIRCUIT_MACHINE_BEGIN(loop_var)
static void circpad_machine_count_padding_sent(circpad_machine_runtime_t *mi)
static bool circpad_machine_conditions_keep(origin_circuit_t *circ, const circpad_machine_spec_t *machine)
static void circpad_machine_update_state_length_for_nonpadding(circpad_machine_runtime_t *mi)
void circpad_deliver_sent_relay_cell_events(circuit_t *circ, uint8_t relay_command)
bool circpad_padding_negotiated(circuit_t *circ, circpad_machine_num_t machine, uint8_t command, uint8_t response, uint32_t machine_ctr)
void circpad_deliver_unrecognized_cell_events(circuit_t *circ, cell_direction_t dir)
static void circpad_choose_state_length(circpad_machine_runtime_t *mi)
STATIC void circpad_machine_setup_tokens(circpad_machine_runtime_t *mi)
static circpad_hist_index_t circpad_machine_first_lower_index(const circpad_machine_runtime_t *mi, circpad_delay_t target_bin_usec)
static void circpad_machine_count_nonpadding_sent(circpad_machine_runtime_t *mi)
void circpad_cell_event_padding_received(circuit_t *on_circ)
STATIC circpad_hist_index_t circpad_histogram_usec_to_bin(const circpad_machine_runtime_t *mi, circpad_delay_t usec)
static uint64_t circpad_global_padding_sent
void circpad_free_all(void)
signed_error_t circpad_handle_padding_negotiated(circuit_t *circ, cell_t *cell, crypt_path_t *layer_hint)
STATIC void circpad_machine_remove_higher_token(circpad_machine_runtime_t *mi, circpad_delay_t target_bin_usec)
static circpad_delay_t circpad_distribution_sample_iat_delay(const circpad_state_t *state, circpad_delay_t delay_shift)
STATIC signed_error_t circpad_send_command_to_hop(origin_circuit_t *circ, uint8_t hopnum, uint8_t relay_command, const uint8_t *payload, ssize_t payload_len)
void circpad_machines_free(void)
void circpad_machine_event_circ_purpose_changed(origin_circuit_t *circ)
void circpad_machine_event_circ_has_no_streams(origin_circuit_t *circ)
STATIC void circpad_machine_remove_closest_token(circpad_machine_runtime_t *mi, circpad_delay_t target_bin_usec, bool use_usec)
signed_error_t circpad_handle_padding_negotiate(circuit_t *circ, cell_t *cell)
int circpad_marked_circuit_for_padding(circuit_t *circ, int reason)
bool circpad_padding_is_from_expected_hop(circuit_t *circ, crypt_path_t *from_hop)
static circpad_hist_index_t circpad_machine_first_higher_index(const circpad_machine_runtime_t *mi, circpad_delay_t target_bin_usec)
static void circpad_estimate_circ_rtt_on_received(circuit_t *circ, circpad_machine_runtime_t *mi)
void circpad_machine_event_circ_has_no_relay_early(origin_circuit_t *circ)
void circpad_deliver_recognized_relay_cell_events(circuit_t *circ, uint8_t relay_command, crypt_path_t *layer_hint)
void circpad_machine_states_init(circpad_machine_spec_t *machine, circpad_statenum_t num_states)
STATIC void circpad_add_matching_machines(origin_circuit_t *on_circ, smartlist_t *machines_sl)
static bool circpad_is_padding_allowed(void)
STATIC smartlist_t * relay_padding_machines
void circpad_machine_event_circ_has_streams(origin_circuit_t *circ)
static bool circpad_machine_conditions_apply(origin_circuit_t *circ, const circpad_machine_spec_t *machine)
static bool circpad_node_supports_padding(const node_t *node)
STATIC circpad_delay_t circpad_histogram_bin_to_usec(const circpad_machine_runtime_t *mi, circpad_hist_index_t bin)
STATIC void circpad_machine_remove_lower_token(circpad_machine_runtime_t *mi, circpad_delay_t target_bin_usec)
static circpad_circuit_state_t circpad_circuit_state(origin_circuit_t *circ)
circpad_purpose_mask_t circpad_circ_purpose_to_mask(uint8_t circ_purpose)
circpad_decision_t circpad_machine_schedule_padding(circpad_machine_runtime_t *mi)
static int circpad_is_token_removal_supported(circpad_machine_runtime_t *mi)
STATIC void circpad_machine_remove_token(circpad_machine_runtime_t *mi)
STATIC smartlist_t * origin_padding_machines
static uint8_t circpad_padding_disabled
STATIC circpad_delay_t circpad_machine_sample_delay(circpad_machine_runtime_t *mi)
static void circpad_machine_spec_transitioned_to_end(circpad_machine_runtime_t *mi)
static circpad_delay_t circpad_get_histogram_bin_midpoint(const circpad_machine_runtime_t *mi, int bin_index)
signed_error_t circpad_negotiate_padding(origin_circuit_t *circ, circpad_machine_num_t machine, uint8_t target_hopnum, uint8_t command, uint32_t machine_ctr)
void circpad_cell_event_padding_sent(circuit_t *on_circ)
static void circpad_shutdown_old_machines(origin_circuit_t *on_circ)
#define FOR_EACH_ACTIVE_CIRCUIT_MACHINE_BEGIN(loop_var, circ)
circpad_decision_t circpad_internal_event_bins_empty(circpad_machine_runtime_t *mi)
circpad_decision_t circpad_internal_event_state_length_up(circpad_machine_runtime_t *mi)
circpad_decision_t circpad_machine_spec_transition(circpad_machine_runtime_t *mi, circpad_event_t event)
void circpad_cell_event_nonpadding_sent(circuit_t *on_circ)
void circpad_machine_event_circ_built(origin_circuit_t *circ)
int circpad_check_received_cell(cell_t *cell, circuit_t *circ, crypt_path_t *layer_hint, const relay_header_t *rh)
static void circpad_machine_remove_exact(circpad_machine_runtime_t *mi, circpad_delay_t target_bin_usec)
static bool circpad_circuit_supports_padding(origin_circuit_t *circ, int target_hopnum)
Header file for circuitpadding.c.
int8_t circpad_hist_index_t
#define CIRCPAD_DELAY_INFINITE
#define CIRCPAD_GET_MACHINE(machineinfo)
uint8_t circpad_machine_num_t
#define CIRCPAD_STATE_CANCEL
#define CIRCPAD_INFINITY_BIN(mi)
uint32_t circpad_hist_token_t
#define CIRCPAD_STATE_START
uint16_t circpad_statenum_t
uint32_t circpad_purpose_mask_t
#define CIRCPAD_STATE_GAP
char * circpad_machine_spec_to_string(const circpad_machine_spec_t *machine)
#define CIRCPAD_DELAY_MAX_SECS
#define CIRCPAD_STATE_IGNORE
#define CIRCPAD_MAX_MACHINE_STATES
#define CIRCPAD_STATE_BURST
#define CIRCPAD_STATE_END
#define CIRCPAD_PURPOSE_ALL
@ CIRCPAD_TOKEN_REMOVAL_LOWER
@ CIRCPAD_TOKEN_REMOVAL_HIGHER
@ CIRCPAD_TOKEN_REMOVAL_NONE
@ CIRCPAD_TOKEN_REMOVAL_CLOSEST_USEC
@ CIRCPAD_TOKEN_REMOVAL_EXACT
@ CIRCPAD_TOKEN_REMOVAL_CLOSEST
void circpad_machine_client_hide_rend_circuits(smartlist_t *machines_sl)
void circpad_machine_client_hide_intro_circuits(smartlist_t *machines_sl)
void circpad_machine_relay_hide_intro_circuits(smartlist_t *machines_sl)
void circpad_machine_relay_hide_rend_circuits(smartlist_t *machines_sl)
Header file for circuitpadding_machines.c.
void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
void circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
Header file for circuituse.c.
uint64_t monotime_absolute_usec(void)
Functions and types for monotonic times.
const or_options_t * get_options(void)
tor_cmdline_mode_t command
Header file for config.c.
void conflux_sync_circ_fields(conflux_t *cfx, origin_circuit_t *ref_circ)
Header file for conflux_util.c.
Path structures for origin circuits.
Common functions for using (pseudo-)random number generators.
uint64_t crypto_fast_rng_uint64_range(crypto_fast_rng_t *rng, uint64_t min, uint64_t max)
crypto_fast_rng_t * get_thread_fast_rng(void)
uint64_t crypto_fast_rng_get_uint64(crypto_fast_rng_t *rng, uint64_t limit)
int64_t clamp_double_to_int64(double number)
int64_t tor_llround(double d)
#define log_fn(severity, domain, args,...)
#define log_fn_ratelim(ratelim, severity, domain, args,...)
bool is_participating_on_network(void)
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
Node information structure.
const node_t * node_get_by_id(const char *identity_digest)
Header file for nodelist.c.
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
#define RELAY_HEADER_SIZE
Origin circuit structure.
Header for relay_crypto.c.
void rep_hist_padding_count_write(padding_type_t type)
void rep_hist_padding_count_read(padding_type_t type)
Header file for rephist.c.
Routerstatus (consensus entry) structure.
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
#define SMARTLIST_FOREACH_REVERSE_BEGIN(sl, type, var)
uint8_t payload[CELL_PAYLOAD_SIZE]
uint64_t global_identifier
circpad_purpose_mask_t apply_purpose_mask
circpad_purpose_mask_t keep_purpose_mask
unsigned reduced_padding_ok
circpad_circuit_state_t apply_state_mask
circpad_circuit_state_t keep_state_mask
unsigned requires_vanguards
unsigned is_padding_timer_scheduled
tor_timer_t * padding_timer
struct circuit_t * on_circ
circpad_hist_token_t * histogram
circpad_time_t padding_scheduled_at_usec
circpad_time_t last_received_time_usec
circpad_statenum_t current_state
circpad_hist_index_t histogram_len
time_t last_cell_time_sec
circpad_delay_t rtt_estimate_usec
circpad_hist_index_t chosen_bin
unsigned manage_circ_lifetime
unsigned should_negotiate_end
circpad_statenum_t num_states
uint8_t max_padding_percent
uint16_t allowed_padding_count
circpad_machine_num_t machine_num
circpad_machine_conditions_t conditions
circpad_distribution_t iat_dist
circpad_hist_token_t histogram[CIRCPAD_MAX_HISTOGRAM_LEN]
unsigned use_rtt_estimate
uint32_t histogram_total_tokens
circpad_distribution_t length_dist
circpad_statenum_t next_state[CIRCPAD_NUM_EVENTS]
circpad_removal_t token_removal
circpad_hist_index_t histogram_len
unsigned length_includes_nonpadding
struct circpad_machine_runtime_t * padding_info[CIRCPAD_MAX_MACHINES]
uint16_t marked_for_close
struct conflux_t * conflux
const struct circpad_machine_spec_t * padding_machine[CIRCPAD_MAX_MACHINES]
uint32_t padding_machine_ctr
extend_info_t * extend_info
char identity_digest[DIGEST_LEN]
struct routerset_t * HSLayer2Nodes
struct routerset_t * HSLayer3Nodes
uint32_t global_identifier
edge_connection_t * p_streams
unsigned int remaining_relay_early_cells
unsigned int supports_hs_setup_padding
protover_summary_flags_t pv
#define MOCK_IMPL(rv, funcname, arglist)
Definitions for timing-related constants.
void timer_set_cb(tor_timer_t *t, timer_cb_fn_t cb, void *arg)
void timer_schedule(tor_timer_t *t, const struct timeval *tv)
tor_timer_t * timer_new(timer_cb_fn_t cb, void *arg)
void timer_disable(tor_timer_t *t)
#define tor_assert_nonfatal_unreached()
#define tor_fragile_assert()
#define IF_BUG_ONCE(cond)