9#define TOR_CONFLUX_PRIVATE
31#define USEC_PER_SEC 1000000
34 uint64_t in_usec, uint64_t our_usec);
38static uint64_t total_ooo_q_bytes = 0;
49 switch (relay_command) {
52 case RELAY_COMMAND_BEGIN:
53 case RELAY_COMMAND_DATA:
54 case RELAY_COMMAND_END:
55 case RELAY_COMMAND_CONNECTED:
60 case RELAY_COMMAND_SENDME:
61 case RELAY_COMMAND_EXTEND:
62 case RELAY_COMMAND_EXTENDED:
63 case RELAY_COMMAND_TRUNCATE:
64 case RELAY_COMMAND_TRUNCATED:
65 case RELAY_COMMAND_DROP:
70 case RELAY_COMMAND_RESOLVE:
71 case RELAY_COMMAND_RESOLVED:
75 case RELAY_COMMAND_BEGIN_DIR:
76 case RELAY_COMMAND_EXTEND2:
77 case RELAY_COMMAND_EXTENDED2:
78 case RELAY_COMMAND_ESTABLISH_INTRO:
79 case RELAY_COMMAND_ESTABLISH_RENDEZVOUS:
80 case RELAY_COMMAND_INTRODUCE1:
81 case RELAY_COMMAND_INTRODUCE2:
82 case RELAY_COMMAND_RENDEZVOUS1:
83 case RELAY_COMMAND_RENDEZVOUS2:
84 case RELAY_COMMAND_INTRO_ESTABLISHED:
85 case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
86 case RELAY_COMMAND_INTRODUCE_ACK:
87 case RELAY_COMMAND_PADDING_NEGOTIATE:
88 case RELAY_COMMAND_PADDING_NEGOTIATED:
93 case RELAY_COMMAND_XOFF:
94 case RELAY_COMMAND_XON:
100 case RELAY_COMMAND_CONFLUX_SWITCH:
101 case RELAY_COMMAND_CONFLUX_LINK:
102 case RELAY_COMMAND_CONFLUX_LINKED:
103 case RELAY_COMMAND_CONFLUX_LINKED_ACK:
107 log_warn(
LD_BUG,
"Conflux asked to multiplex unknown relay command %d",
123 if (leg->circ == circ) {
127 } CONFLUX_FOR_EACH_LEG_END(leg);
138 uint64_t max_seq_sent = 0;
141 if (leg->last_seq_sent > max_seq_sent) {
142 max_seq_sent = leg->last_seq_sent;
144 } CONFLUX_FOR_EACH_LEG_END(leg);
155 uint64_t max_seq_recv = 0;
158 if (leg->last_seq_recv > max_seq_recv) {
159 max_seq_recv = leg->last_seq_recv;
161 } CONFLUX_FOR_EACH_LEG_END(leg);
183 return total_ooo_q_bytes;
190 (void) bytes_to_remove;
196 log_info(
LD_CIRC,
"OOM handler triggered. OOO queus allocation: %" PRIu64,
209 bool cc_sendable =
true;
242 uint64_t min_rtt = UINT64_MAX;
251 if (leg->circ_rtts_usec && leg->circ_rtts_usec < min_rtt) {
253 min_rtt = leg->circ_rtts_usec;
255 } CONFLUX_FOR_EACH_LEG_END(leg);
274 uint64_t low_rtt = UINT64_MAX;
287 if (leg->circ_rtts_usec && leg->circ_rtts_usec < low_rtt) {
288 low_rtt = leg->circ_rtts_usec;
291 } CONFLUX_FOR_EACH_LEG_END(leg);
301static inline uint64_t
319static inline uint64_t
327 if (our_usec == 0 || in_usec == 0) {
329 "cwnd_sendable: Missing RTT data. in_usec: %" PRIu64
330 " our_usec: %" PRIu64, in_usec, our_usec);
331 return cwnd_adjusted;
335 return cwnd_adjusted;
343 uint64_t sendable = cwnd_adjusted*in_usec/our_usec;
344 return MIN(cc->
cwnd, sendable);
399 uint64_t min_rtt = UINT64_MAX;
408 if (l->circ_rtts_usec && l->circ_rtts_usec < min_rtt) {
409 min_rtt = l->circ_rtts_usec;
412 } CONFLUX_FOR_EACH_LEG_END(l);
429 if (l->circ_rtts_usec &&
433 } CONFLUX_FOR_EACH_LEG_END(l);
456 uint8_t relay_command)
470 if (!new_circ && relay_command != RELAY_COMMAND_DATA) {
474 log_warn(
LD_BUG,
"No current leg for conflux with relay command %d",
535 log_fn(LOG_PROTOCOL_WARN,
LD_BUG,
"No Conflux leg after sending a cell");
559 if (leg->circ_rtts_usec > 0) {
564 } CONFLUX_FOR_EACH_LEG_END(leg);
570 if (BUG(smartlist_len(cfx->
legs) <= 0)) {
573 log_warn(
LD_BUG,
"Matching client sets:");
575 log_warn(
LD_BUG,
"Matching server sets:");
577 log_warn(
LD_BUG,
"End conflux set dump");
581 min_leg = smartlist_get(cfx->
legs, 0);
584 log_warn(
LD_BUG,
"Conflux has no legs with non-zero RTT. "
635 log_info(
LD_CIRC,
"Conflux can't switch; no circuit to send on.");
639 switch (cfx->
params.alg) {
640 case CONFLUX_ALG_MINRTT:
642 case CONFLUX_ALG_LOWRTT:
644 case CONFLUX_ALG_CWNDRTT:
660 log_warn(
LD_BUG,
"Got RTT update for circuit not in conflux");
689 if (cell_a->
seq < cell_b->
seq) {
691 }
else if (cell_a->
seq > cell_b->
seq) {
713 tor_assert(CONST_TO_ORIGIN_CIRCUIT(circ)->cpath);
714 tor_assert(CONST_TO_ORIGIN_CIRCUIT(circ)->cpath->prev);
729#define CONFLUX_MIN_LINK_INCREMENT 31
743 uint32_t relative_seq;
746 if (!conflux_is_enabled(in_circ)) {
747 circuit_mark_for_close(in_circ, END_CIRC_REASON_TORPROTOCOL);
754 log_warn(
LD_BUG,
"Got a conflux switch command on a circuit without "
755 "conflux negotiated. Closing circuit.");
757 circuit_mark_for_close(in_circ, END_CIRC_REASON_TORPROTOCOL);
770 log_warn(
LD_BUG,
"Got a conflux switch command on a circuit without "
771 "conflux leg. Closing circuit.");
772 circuit_mark_for_close(in_circ, END_CIRC_REASON_INTERNAL);
778 log_warn(
LD_BUG,
"Got a conflux switch command on a circuit with "
779 "invalid source hop. Closing circuit.");
780 circuit_mark_for_close(in_circ, END_CIRC_REASON_TORPROTOCOL);
842 log_warn(
LD_BUG,
"Got a conflux cell on a circuit without "
843 "conflux leg. Closing circuit.");
844 circuit_mark_for_close(in_circ, END_CIRC_REASON_INTERNAL);
851 circuit_mark_for_close(in_circ, END_CIRC_REASON_TORPROTOCOL);
865 log_warn(
LD_BUG,
"Got a conflux cell with a sequence number "
866 "less than the last delivered. Closing circuit.");
867 circuit_mark_for_close(in_circ, END_CIRC_REASON_INTERNAL);
877 total_ooo_q_bytes +=
sizeof(
cell_t);
895 if (smartlist_len(cfx->
ooo_q) == 0)
898 top = smartlist_get(cfx->
ooo_q, 0);
905 total_ooo_q_bytes -=
sizeof(
cell_t);
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
void circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len)
Header file for circuituse.c.
Functions and types for monotonic times.
Header file for config.c.
void conflux_note_cell_sent(conflux_t *cfx, circuit_t *circ, uint8_t relay_command)
static uint64_t cwnd_sendable(const circuit_t *on_circ, uint64_t in_usec, uint64_t our_usec)
static bool conflux_pick_first_leg(conflux_t *cfx)
void conflux_update_rtt(conflux_t *cfx, circuit_t *circ, uint64_t rtt_usec)
bool conflux_process_cell(conflux_t *cfx, circuit_t *in_circ, crypt_path_t *layer_hint, cell_t *cell)
int conflux_process_switch_command(circuit_t *in_circ, crypt_path_t *layer_hint, cell_t *cell, relay_header_t *rh)
bool conflux_should_multiplex(int relay_command)
circuit_t * conflux_decide_next_circ(conflux_t *cfx)
static int conflux_queue_cmp(const void *a, const void *b)
static const circuit_t * conflux_decide_circ_lowrtt(const conflux_t *cfx)
static uint64_t cwnd_available(const circuit_t *on_circ)
uint64_t conflux_get_circ_bytes_allocation(const circuit_t *circ)
const congestion_control_t * circuit_ccontrol(const circuit_t *circ)
conflux_cell_t * conflux_dequeue_cell(conflux_t *cfx)
uint64_t conflux_get_max_seq_recv(const conflux_t *cfx)
uint64_t conflux_get_max_seq_sent(const conflux_t *cfx)
static bool conflux_can_switch(const conflux_t *cfx)
circuit_t * conflux_decide_circ_for_send(conflux_t *cfx, circuit_t *orig_circ, uint8_t relay_command)
static const circuit_t * conflux_decide_circ_cwndrtt(const conflux_t *cfx)
conflux_leg_t * conflux_get_leg(conflux_t *cfx, const circuit_t *circ)
static const circuit_t * conflux_decide_circ_minrtt(const conflux_t *cfx)
size_t conflux_handle_oom(size_t bytes_to_remove)
static bool circuit_ready_to_send(const circuit_t *circ)
uint64_t conflux_get_total_bytes_allocation(void)
Public APIs for conflux multipath support.
#define CONFLUX_FOR_EACH_LEG_BEGIN(cfx, var)
#define CONFLUX_NUM_LEGS(cfx)
uint32_t conflux_cell_parse_switch(const cell_t *cell, uint16_t rh_len)
bool conflux_send_switch_command(circuit_t *send_circ, uint64_t relative_seq)
Header file for conflux_cell.c.
Header file for conflux_params.c.
uint8_t conflux_params_get_drain_pct(void)
void conflux_log_set(int loglevel, const conflux_t *cfx, bool is_client)
Header file for conflux_pool.c.
Structure definitions for conflux multipath.
void conflux_validate_stream_lists(const conflux_t *cfx)
void conflux_validate_legs(const conflux_t *cfx)
bool conflux_validate_source_hop(circuit_t *in_circ, crypt_path_t *layer_hint)
Header file for conflux_util.c.
Public APIs for congestion control.
Structure definitions for congestion control.
#define log_fn(severity, domain, args,...)
Master header file for Tor-specific functionality.
Origin circuit structure.
Header file for sendme.c.
void * smartlist_pqueue_pop(smartlist_t *sl, int(*compare)(const void *a, const void *b), ptrdiff_t idx_field_offset)
void smartlist_pqueue_add(smartlist_t *sl, int(*compare)(const void *a, const void *b), ptrdiff_t idx_field_offset, void *item)
unsigned int circuit_blocked_on_n_chan
unsigned int circuit_blocked_on_p_chan
struct conflux_t * conflux
struct congestion_control_t * ccontrol
uint64_t linked_sent_usec
struct conflux_leg_t * curr_leg
struct conflux_params_t params
struct conflux_leg_t * prev_leg
uint64_t cells_until_switch
uint64_t last_seq_delivered
struct crypt_path_t * prev
struct congestion_control_t * ccontrol