38#include "core/or/or_circuit_st.h"
44#define ONION_QUEUE_WAIT_CUTOFF_DEFAULT 5
45#define ONION_QUEUE_WAIT_CUTOFF_MIN 0
46#define ONION_QUEUE_WAIT_CUTOFF_MAX INT32_MAX
49#define ONION_QUEUE_MAX_DELAY_DEFAULT 1750
50#define ONION_QUEUE_MAX_DELAY_MIN 1
51#define ONION_QUEUE_MAX_DELAY_MAX INT32_MAX
53#define NUM_NTORS_PER_TAP_DEFAULT 10
54#define NUM_NTORS_PER_TAP_MIN 1
55#define NUM_NTORS_PER_TAP_MAX 100000
68typedef struct onion_queue_head_t onion_queue_head_t;
71#define MAX_QUEUE_IDX ONION_HANDSHAKE_TYPE_NTOR
76{ TOR_TAILQ_HEAD_INITIALIZER(
ol_list[0]),
77 TOR_TAILQ_HEAD_INITIALIZER(
ol_list[1]),
78 TOR_TAILQ_HEAD_INITIALIZER(
ol_list[2]),
89static uint32_t ns_onion_queue_max_delay = ONION_QUEUE_MAX_DELAY_DEFAULT;
102 return ns_onion_queue_wait_cutoff;
107static inline uint32_t
110 if (options && options->MaxOnionQueueDelay > 0) {
111 return options->MaxOnionQueueDelay;
113 return ns_onion_queue_max_delay;
120static inline uint16_t
123 if (type == ONION_HANDSHAKE_TYPE_NTOR_V3) {
124 return ONION_HANDSHAKE_TYPE_NTOR;
148 uint64_t max_onion_queue_delay;
149 uint64_t tap_usec, ntor_usec;
150 uint64_t ntor_during_tap_usec, tap_during_ntor_usec;
170 ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
175 ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
182 ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
189 ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
193 if (type == ONION_HANDSHAKE_TYPE_NTOR &&
194 (ntor_usec + tap_during_ntor_usec) / 1000 > max_onion_queue_delay)
197 if (type == ONION_HANDSHAKE_TYPE_TAP &&
198 (tap_usec + ntor_during_tap_usec) / 1000 > max_onion_queue_delay)
203 if (type == ONION_HANDSHAKE_TYPE_TAP &&
204 tap_usec / 1000 > max_onion_queue_delay * 2 / 3)
217 time_t now = time(NULL);
218 uint16_t queue_idx = 0;
223 log_warn(
LD_BUG,
"Handshake %d out of range! Dropping.",
233 tmp->queue_idx = queue_idx;
234 tmp->onionskin = onionskin;
235 tmp->when_added = now;
238#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
240 RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
246 if (queue_idx == ONION_HANDSHAKE_TYPE_NTOR) {
250 "Your computer is too slow to handle this many circuit "
251 "creation requests! Please consider using the "
252 "MaxAdvertisedBandwidth config option or choosing a more "
253 "restricted exit policy.%s",
263 log_info(
LD_OR,
"New create (%s). Queues now ntor=%d and tap=%d.",
264 queue_idx == ONION_HANDSHAKE_TYPE_NTOR ?
"ntor" :
"tap",
269 TOR_TAILQ_INSERT_TAIL(&
ol_list[queue_idx], tmp, next);
281 "Circuit create request is too old; canceling due to overload.");
283 circuit_mark_for_close(
TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
296 static int recently_chosen_ntors = 0;
299 return ONION_HANDSHAKE_TYPE_TAP;
313 ++recently_chosen_ntors;
315 return ONION_HANDSHAKE_TYPE_NTOR;
321 return ONION_HANDSHAKE_TYPE_NTOR;
325 recently_chosen_ntors = 0;
326 return ONION_HANDSHAKE_TYPE_TAP;
350 log_info(
LD_OR,
"Processing create (%s). Queues now ntor=%d and tap=%d.",
351 head->queue_idx == ONION_HANDSHAKE_TYPE_NTOR ?
"ntor" :
"tap",
355 *onionskin_out = head->onionskin;
356 head->onionskin = NULL;
396 log_warn(
LD_BUG,
"Handshake %d out of range! Dropping.",
403 TOR_TAILQ_REMOVE(&
ol_list[victim->queue_idx], victim, next);
406 victim->circ->onionqueue_entry = NULL;
408 if (victim->onionskin)
422 for (victim = TOR_TAILQ_FIRST(&
ol_list[i]); victim; victim = next) {
423 next = TOR_TAILQ_NEXT(victim,next);
437 ns_onion_queue_max_delay =
439 ONION_QUEUE_MAX_DELAY_DEFAULT,
440 ONION_QUEUE_MAX_DELAY_MIN,
441 ONION_QUEUE_MAX_DELAY_MAX);
443 ns_onion_queue_wait_cutoff =
446 ONION_QUEUE_WAIT_CUTOFF_MIN,
447 ONION_QUEUE_WAIT_CUTOFF_MAX);
451 NUM_NTORS_PER_TAP_DEFAULT,
452 NUM_NTORS_PER_TAP_MIN,
453 NUM_NTORS_PER_TAP_MAX);
int channel_is_client(const channel_t *chan)
Header file for channel.c.
Header file for circuitlist.c.
const or_options_t * get_options(void)
Header file for config.c.
void cpuworker_cancel_circ_handshake(or_circuit_t *circ)
unsigned int cpuworker_get_n_threads(void)
uint64_t estimated_usec_for_onionskins(uint32_t n_requests, uint16_t onionskin_type)
Header file for cpuworker.c.
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.
void clear_pending_onions(void)
static int ol_entries[MAX_QUEUE_IDX+1]
static time_t get_onion_queue_wait_cutoff(void)
static uint32_t get_onion_queue_max_delay(const or_options_t *options)
static int32_t get_num_ntors_per_tap(void)
#define ONION_QUEUE_WAIT_CUTOFF_DEFAULT
void onion_consensus_has_changed(const networkstatus_t *ns)
static onion_queue_head_t ol_list[MAX_QUEUE_IDX+1]
int onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
int onion_num_pending(uint16_t handshake_type)
static int have_room_for_onionskin(uint16_t type)
static int32_t ns_num_ntors_per_tap
void onion_pending_remove(or_circuit_t *circ)
or_circuit_t * onion_next_task(create_cell_t **onionskin_out)
static void onion_queue_entry_remove(onion_queue_t *victim)
static uint16_t onionskin_type_to_queue(uint16_t type)
static uint16_t decide_next_handshake_type(void)
Header file for onion_queue.c.
Master header file for Tor-specific functionality.
char * rate_limit_log(ratelim_t *lim, time_t now)
void rep_hist_note_circuit_handshake_dropped(uint16_t type)
Header file for rephist.c.
struct onion_queue_t * onionqueue_entry