10#define TOR_CONFLUX_PRIVATE
32#define USEC_PER_SEC 1000000
35 uint64_t in_usec, uint64_t our_usec);
39static uint64_t total_ooo_q_bytes = 0;
50 switch (relay_command) {
53 case RELAY_COMMAND_BEGIN:
54 case RELAY_COMMAND_DATA:
55 case RELAY_COMMAND_END:
56 case RELAY_COMMAND_CONNECTED:
61 case RELAY_COMMAND_SENDME:
62 case RELAY_COMMAND_EXTEND:
63 case RELAY_COMMAND_EXTENDED:
64 case RELAY_COMMAND_TRUNCATE:
65 case RELAY_COMMAND_TRUNCATED:
66 case RELAY_COMMAND_DROP:
71 case RELAY_COMMAND_RESOLVE:
72 case RELAY_COMMAND_RESOLVED:
76 case RELAY_COMMAND_BEGIN_DIR:
77 case RELAY_COMMAND_EXTEND2:
78 case RELAY_COMMAND_EXTENDED2:
79 case RELAY_COMMAND_ESTABLISH_INTRO:
80 case RELAY_COMMAND_ESTABLISH_RENDEZVOUS:
81 case RELAY_COMMAND_INTRODUCE1:
82 case RELAY_COMMAND_INTRODUCE2:
83 case RELAY_COMMAND_RENDEZVOUS1:
84 case RELAY_COMMAND_RENDEZVOUS2:
85 case RELAY_COMMAND_INTRO_ESTABLISHED:
86 case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED:
87 case RELAY_COMMAND_INTRODUCE_ACK:
88 case RELAY_COMMAND_PADDING_NEGOTIATE:
89 case RELAY_COMMAND_PADDING_NEGOTIATED:
94 case RELAY_COMMAND_XOFF:
95 case RELAY_COMMAND_XON:
101 case RELAY_COMMAND_CONFLUX_SWITCH:
102 case RELAY_COMMAND_CONFLUX_LINK:
103 case RELAY_COMMAND_CONFLUX_LINKED:
104 case RELAY_COMMAND_CONFLUX_LINKED_ACK:
108 log_warn(
LD_BUG,
"Conflux asked to multiplex unknown relay command %d",
124 if (leg->circ == circ) {
128 } CONFLUX_FOR_EACH_LEG_END(leg);
139 uint64_t max_seq_sent = 0;
142 if (leg->last_seq_sent > max_seq_sent) {
143 max_seq_sent = leg->last_seq_sent;
145 } CONFLUX_FOR_EACH_LEG_END(leg);
156 uint64_t max_seq_recv = 0;
159 if (leg->last_seq_recv > max_seq_recv) {
160 max_seq_recv = leg->last_seq_recv;
162 } CONFLUX_FOR_EACH_LEG_END(leg);
184 return total_ooo_q_bytes;
191 (void) bytes_to_remove;
197 log_info(
LD_CIRC,
"OOM handler triggered. OOO queus allocation: %" PRIu64,
210 bool cc_sendable =
true;
243 uint64_t min_rtt = UINT64_MAX;
252 if (leg->circ_rtts_usec && leg->circ_rtts_usec < min_rtt) {
254 min_rtt = leg->circ_rtts_usec;
256 } CONFLUX_FOR_EACH_LEG_END(leg);
275 uint64_t low_rtt = UINT64_MAX;
288 if (leg->circ_rtts_usec && leg->circ_rtts_usec < low_rtt) {
289 low_rtt = leg->circ_rtts_usec;
292 } CONFLUX_FOR_EACH_LEG_END(leg);
302static inline uint64_t
320static inline uint64_t
328 if (our_usec == 0 || in_usec == 0) {
330 "cwnd_sendable: Missing RTT data. in_usec: %" PRIu64
331 " our_usec: %" PRIu64, in_usec, our_usec);
332 return cwnd_adjusted;
336 return cwnd_adjusted;
344 uint64_t sendable = cwnd_adjusted*in_usec/our_usec;
345 return MIN(cc->
cwnd, sendable);
400 uint64_t min_rtt = UINT64_MAX;
409 if (l->circ_rtts_usec && l->circ_rtts_usec < min_rtt) {
410 min_rtt = l->circ_rtts_usec;
413 } CONFLUX_FOR_EACH_LEG_END(l);
430 if (l->circ_rtts_usec &&
434 } CONFLUX_FOR_EACH_LEG_END(l);
457 uint8_t relay_command)
471 if (!new_circ && relay_command != RELAY_COMMAND_DATA) {
475 log_warn(
LD_BUG,
"No current leg for conflux with relay command %d",
536 log_fn(LOG_PROTOCOL_WARN,
LD_BUG,
"No Conflux leg after sending a cell");
560 if (leg->circ_rtts_usec > 0) {
565 } CONFLUX_FOR_EACH_LEG_END(leg);
571 if (BUG(smartlist_len(cfx->
legs) <= 0)) {
574 log_warn(
LD_BUG,
"Matching client sets:");
576 log_warn(
LD_BUG,
"Matching server sets:");
578 log_warn(
LD_BUG,
"End conflux set dump");
582 min_leg = smartlist_get(cfx->
legs, 0);
585 log_warn(
LD_BUG,
"Conflux has no legs with non-zero RTT. "
636 log_info(
LD_CIRC,
"Conflux can't switch; no circuit to send on.");
640 switch (cfx->
params.alg) {
641 case CONFLUX_ALG_MINRTT:
643 case CONFLUX_ALG_LOWRTT:
645 case CONFLUX_ALG_CWNDRTT:
661 log_warn(
LD_BUG,
"Got RTT update for circuit not in conflux");
690 if (cell_a->
seq < cell_b->
seq) {
692 }
else if (cell_a->
seq > cell_b->
seq) {
714 tor_assert(CONST_TO_ORIGIN_CIRCUIT(circ)->cpath);
715 tor_assert(CONST_TO_ORIGIN_CIRCUIT(circ)->cpath->prev);
730#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);
882 total_ooo_q_bytes +=
sizeof(msg->length);
900 if (smartlist_len(cfx->
ooo_q) == 0)
903 top = smartlist_get(cfx->
ooo_q, 0);
910 total_ooo_q_bytes -=
sizeof(top->
msg->length);
923 relay_msg_free(msg->
msg);
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_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)
uint64_t conflux_get_max_seq_recv(const conflux_t *cfx)
uint64_t conflux_get_max_seq_sent(const conflux_t *cfx)
void conflux_relay_msg_free_(conflux_msg_t *msg)
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_msg_t * conflux_dequeue_relay_msg(conflux_t *cfx)
conflux_leg_t * conflux_get_leg(conflux_t *cfx, const circuit_t *circ)
bool conflux_process_relay_msg(conflux_t *cfx, circuit_t *in_circ, crypt_path_t *layer_hint, const relay_msg_t *msg)
static const circuit_t * conflux_decide_circ_minrtt(const conflux_t *cfx)
int conflux_process_switch_command(circuit_t *in_circ, crypt_path_t *layer_hint, const relay_msg_t *msg)
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 relay_msg_t *msg)
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.
relay_msg_t * relay_msg_copy(const relay_msg_t *msg)
Header file for relay_msg.c.
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