Merge branch 'maint-0.4.8'
[tor.git] / src / core / or / congestion_control_common.h
blobe185a5d29e8d63e51b1e15c4a22afbc58e627755
1 /* Copyright (c) 2019-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file congestion_control_common.h
6 * \brief Public APIs for congestion control
7 **/
9 #ifndef TOR_CONGESTION_CONTROL_COMMON_H
10 #define TOR_CONGESTION_CONTROL_COMMON_H
12 #include "core/crypto/onion_crypto.h"
13 #include "core/or/crypt_path_st.h"
14 #include "core/or/circuit_st.h"
16 /* The maximum whole number of cells that can fit in a
17 * full TLS record. This is 31. */
18 #define TLS_RECORD_MAX_CELLS ((16 * 1024) / CELL_MAX_NETWORK_SIZE)
20 typedef struct congestion_control_t congestion_control_t;
22 /**
23 * Specifies the path type to help choose congestion control
24 * parameters. Since these paths are different lengths, they
25 * will need different queue parameters. */
26 typedef enum {
27 CC_PATH_EXIT = 0,
28 CC_PATH_ONION = 1,
29 CC_PATH_ONION_SOS = 2,
30 CC_PATH_ONION_VG = 3,
31 CC_PATH_SBWS = 4,
32 } cc_path_t;
34 /** The length of a path for sbws measurement */
35 #define SBWS_ROUTE_LEN 2
37 /** Wrapper for the free function, set the CC pointer to NULL after free */
38 #define congestion_control_free(cc) \
39 FREE_AND_NULL(congestion_control_t, congestion_control_free_, cc)
41 void congestion_control_free_(congestion_control_t *cc);
43 struct circuit_params_t;
44 congestion_control_t *congestion_control_new(
45 const struct circuit_params_t *params,
46 cc_path_t path);
48 int congestion_control_dispatch_cc_alg(congestion_control_t *cc,
49 circuit_t *circ);
51 void congestion_control_note_cell_sent(congestion_control_t *cc,
52 const circuit_t *circ,
53 const crypt_path_t *cpath);
55 bool congestion_control_update_circuit_estimates(congestion_control_t *,
56 const circuit_t *);
58 int congestion_control_get_package_window(const circuit_t *,
59 const crypt_path_t *);
61 int sendme_get_inc_count(const circuit_t *, const crypt_path_t *);
62 bool circuit_sent_cell_for_sendme(const circuit_t *, const crypt_path_t *);
63 bool is_monotime_clock_reliable(void);
65 void congestion_control_new_consensus_params(const networkstatus_t *ns);
67 bool congestion_control_enabled(void);
69 int congestion_control_build_ext_request(uint8_t **msg_out,
70 size_t *msg_len_out);
71 int congestion_control_parse_ext_request(const uint8_t *msg,
72 const size_t msg_len);
73 int congestion_control_build_ext_response(const circuit_params_t *our_params,
74 const circuit_params_t *circ_params,
75 uint8_t **msg_out,
76 size_t *msg_len_out);
77 int congestion_control_parse_ext_response(const uint8_t *msg,
78 const size_t msg_len,
79 circuit_params_t *params_out);
80 bool congestion_control_validate_sendme_increment(uint8_t sendme_inc);
81 char *congestion_control_get_control_port_fields(const origin_circuit_t *);
83 uint64_t congestion_control_get_num_rtt_reset(void);
84 uint64_t congestion_control_get_num_clock_stalls(void);
86 extern uint64_t cc_stats_circs_created;
88 /* Ugh, C.. these are private. Use the getter instead, when
89 * external to the congestion control code. */
90 extern uint32_t or_conn_highwater;
91 extern uint32_t or_conn_lowwater;
92 extern int32_t cell_queue_high;
93 extern int32_t cell_queue_low;
94 extern uint8_t cc_sendme_inc;
96 /** Stop writing on an orconn when its outbuf is this large */
97 static inline uint32_t
98 or_conn_highwatermark(void)
100 return or_conn_highwater;
103 /** Resume writing on an orconn when its outbuf is less than this */
104 static inline uint32_t
105 or_conn_lowwatermark(void)
107 return or_conn_lowwater;
110 /** Stop reading on edge connections when we have this many cells
111 * waiting on the appropriate queue. */
112 static inline int32_t
113 cell_queue_highwatermark(void)
115 return cell_queue_high;
118 /** Start reading from edge connections again when we get down to this many
119 * cells. */
120 static inline int32_t
121 cell_queue_lowwatermark(void)
123 return cell_queue_low;
126 /** Returns the sendme inc rate cached from the most recent consensus */
127 static inline uint8_t
128 congestion_control_sendme_inc(void)
130 return cc_sendme_inc;
134 * Compute an N-count EWMA, aka N-EWMA. N-EWMA is defined as:
135 * EWMA = alpha*value + (1-alpha)*EWMA_prev
136 * with alpha = 2/(N+1).
138 * This works out to:
139 * EWMA = value*2/(N+1) + EMA_prev*(N-1)/(N+1)
140 * = (value*2 + EWMA_prev*(N-1))/(N+1)
142 static inline uint64_t
143 n_count_ewma(uint64_t curr, uint64_t prev, uint64_t N)
145 if (prev == 0)
146 return curr;
147 else
148 return (2*curr + (N-1)*prev)/(N+1);
152 * Helper function that gives us a percentile weighted-average between
153 * two values. The pct_max argument specifies the percentage weight of the
154 * maximum of a and b, when computing this weighted-average.
156 * This also allows this function to be used as either MIN() or a MAX()
157 * by this parameterization. It is MIN() when pct_max==0;
158 * it is MAX() when pct_max==100; it is avg() when pct_max==50; it is a
159 * weighted-average for values in between.
161 static inline uint64_t
162 percent_max_mix(uint64_t a, uint64_t b, uint8_t pct_max)
164 uint64_t max = MAX(a, b);
165 uint64_t min = MIN(a, b);
167 if (BUG(pct_max > 100)) {
168 return max;
171 return pct_max*max/100 + (100-pct_max)*min/100;
174 /* Private section starts. */
175 #ifdef TOR_CONGESTION_CONTROL_COMMON_PRIVATE
176 STATIC uint64_t congestion_control_update_circuit_rtt(congestion_control_t *,
177 uint64_t);
179 STATIC bool time_delta_stalled_or_jumped(const congestion_control_t *cc,
180 uint64_t old_delta, uint64_t new_delta);
182 STATIC void enqueue_timestamp(smartlist_t *timestamps_u64,
183 uint64_t timestamp_usec);
186 * Unit tests declaractions.
188 #ifdef TOR_UNIT_TESTS
190 extern bool is_monotime_clock_broken;
191 extern cc_alg_t cc_alg;
192 void congestion_control_set_cc_enabled(void);
193 void congestion_control_set_cc_disabled(void);
195 #endif /* defined(TOR_UNIT_TESTS) */
197 #endif /* defined(TOR_CONGESTION_CONTROL_PRIVATE) */
199 #endif /* !defined(TOR_CONGESTION_CONTROL_COMMON_H) */