Tor 0.4.9.0-alpha-dev
congestion_control_vegas.c
Go to the documentation of this file.
1/* Copyright (c) 2019-2021, The Tor Project, Inc. */
2/* See LICENSE for licensing information */
3
4/**
5 * \file congestion_control_vegas.c
6 * \brief Code that implements the TOR_VEGAS congestion control algorithm
7 * from Proposal #324.
8 */
9
10#define TOR_CONGESTION_CONTROL_VEGAS_PRIVATE
11
12#include "core/or/or.h"
13
14#include "core/or/crypt_path.h"
15#include "core/or/or_circuit_st.h"
16#include "core/or/sendme.h"
20#include "core/or/circuitlist.h"
21#include "core/or/circuituse.h"
23#include "core/or/channel.h"
26#include "lib/math/stats.h"
27
28#define OUTBUF_CELLS (2*TLS_RECORD_MAX_CELLS)
29
30#define SS_CWND_MAX_DFLT (5000)
31
32/* sbws circs are two hops, so params are based on 2 outbufs of cells */
33#define VEGAS_ALPHA_SBWS_DFLT (2*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
34#define VEGAS_BETA_SBWS_DFLT (2*OUTBUF_CELLS+TLS_RECORD_MAX_CELLS)
35#define VEGAS_GAMMA_SBWS_DFLT (2*OUTBUF_CELLS)
36#define VEGAS_DELTA_SBWS_DFLT (4*OUTBUF_CELLS)
37#define VEGAS_SSCAP_SBWS_DFLT (400)
38
39/* Exits are three hops, so params are based on 3 outbufs of cells */
40#define VEGAS_ALPHA_EXIT_DFLT (3*OUTBUF_CELLS)
41#define VEGAS_BETA_EXIT_DFLT (4*OUTBUF_CELLS)
42#define VEGAS_GAMMA_EXIT_DFLT (3*OUTBUF_CELLS)
43#define VEGAS_DELTA_EXIT_DFLT (5*OUTBUF_CELLS)
44#define VEGAS_SSCAP_EXIT_DFLT (600)
45
46/* Onion rends are six hops, so params are based on 6 outbufs of cells */
47#define VEGAS_ALPHA_ONION_DFLT (3*OUTBUF_CELLS)
48#define VEGAS_BETA_ONION_DFLT (6*OUTBUF_CELLS)
49#define VEGAS_GAMMA_ONION_DFLT (4*OUTBUF_CELLS)
50#define VEGAS_DELTA_ONION_DFLT (7*OUTBUF_CELLS)
51#define VEGAS_SSCAP_ONION_DFLT (475)
52
53/**
54 * Number of sendme_incs between cwnd and inflight for cwnd to be
55 * still considered full */
56#define VEGAS_CWND_FULL_GAP_DFLT (4)
57static int cc_vegas_cwnd_full_gap = VEGAS_CWND_FULL_GAP_DFLT;
58
59/**
60 * If the cwnd becomes less than this percent full at any point,
61 * we declare it not full immediately.
62 */
63#define VEGAS_CWND_FULL_MINPCT_DFLT (25)
64static int cc_vegas_cwnd_full_minpct = VEGAS_CWND_FULL_MINPCT_DFLT;
65
66/**
67 * Param to decide when to reset the cwnd.
68 */
69#define VEGAS_CWND_FULL_PER_CWND_DFLT (1)
70static int cc_cwnd_full_per_cwnd = VEGAS_CWND_FULL_PER_CWND_DFLT;
71
72/** Moving average of the cc->cwnd from each circuit exiting slowstart. */
74double cc_stats_vegas_exit_ss_bdp_ma = 0;
75double cc_stats_vegas_exit_ss_inc_ma = 0;
76double cc_stats_vegas_gamma_drop_ma = 0;
77double cc_stats_vegas_delta_drop_ma = 0;
78double cc_stats_vegas_ss_csig_blocked_ma = 0;
79double cc_stats_vegas_csig_blocked_ma = 0;
80double cc_stats_vegas_csig_alpha_ma = 0;
81double cc_stats_vegas_csig_beta_ma = 0;
82double cc_stats_vegas_csig_delta_ma = 0;
83
84double cc_stats_vegas_ss_queue_ma = 0;
85double cc_stats_vegas_queue_ma = 0;
86double cc_stats_vegas_bdp_ma = 0;
87
88/** Stats on how many times we reached "delta" param. */
90/** Stats on how many times we reached "ss_cwnd_max" param. */
92uint64_t cc_stats_vegas_below_ss_inc_floor = 0;
93uint64_t cc_stats_vegas_circ_exited_ss = 0;
94
95/**
96 * The original TCP Vegas congestion window BDP estimator.
97 */
98static inline uint64_t
100{
101 return cc->bdp;
102}
103
104/**
105 * Cache Vegas consensus parameters.
106 */
107void
109 cc_path_t path)
110{
112 const char *alpha_str = NULL, *beta_str = NULL, *gamma_str = NULL;
113 const char *delta_str = NULL, *sscap_str = NULL;
114 int alpha, beta, gamma, delta, ss_cwnd_cap;
115
116 switch (path) {
117 case CC_PATH_SBWS:
118 alpha_str = "cc_vegas_alpha_sbws";
119 beta_str = "cc_vegas_beta_sbws";
120 gamma_str = "cc_vegas_gamma_sbws";
121 delta_str = "cc_vegas_delta_sbws";
122 sscap_str = "cc_sscap_sbws";
123 alpha = VEGAS_ALPHA_SBWS_DFLT;
124 beta = VEGAS_BETA_SBWS_DFLT;
125 gamma = VEGAS_GAMMA_SBWS_DFLT;
126 delta = VEGAS_DELTA_SBWS_DFLT;
127 ss_cwnd_cap = VEGAS_SSCAP_SBWS_DFLT;
128 break;
129 case CC_PATH_EXIT:
130 case CC_PATH_ONION_SOS:
131 alpha_str = "cc_vegas_alpha_exit";
132 beta_str = "cc_vegas_beta_exit";
133 gamma_str = "cc_vegas_gamma_exit";
134 delta_str = "cc_vegas_delta_exit";
135 sscap_str = "cc_sscap_exit";
136 alpha = VEGAS_ALPHA_EXIT_DFLT;
137 beta = VEGAS_BETA_EXIT_DFLT;
138 gamma = VEGAS_GAMMA_EXIT_DFLT;
139 delta = VEGAS_DELTA_EXIT_DFLT;
140 ss_cwnd_cap = VEGAS_SSCAP_EXIT_DFLT;
141 break;
142 case CC_PATH_ONION:
143 case CC_PATH_ONION_VG:
144 alpha_str = "cc_vegas_alpha_onion";
145 beta_str = "cc_vegas_beta_onion";
146 gamma_str = "cc_vegas_gamma_onion";
147 delta_str = "cc_vegas_delta_onion";
148 sscap_str = "cc_sscap_onion";
149 alpha = VEGAS_ALPHA_ONION_DFLT;
150 beta = VEGAS_BETA_ONION_DFLT;
151 gamma = VEGAS_GAMMA_ONION_DFLT;
152 delta = VEGAS_DELTA_ONION_DFLT;
153 ss_cwnd_cap = VEGAS_SSCAP_ONION_DFLT;
154 break;
155 default:
156 tor_assert(0);
157 break;
158 }
159
161 networkstatus_get_param(NULL, sscap_str,
162 ss_cwnd_cap,
163 100,
164 INT32_MAX);
165
167 networkstatus_get_param(NULL, "cc_ss_max",
168 SS_CWND_MAX_DFLT,
169 500,
170 INT32_MAX);
171
172 cc->vegas_params.alpha =
173 networkstatus_get_param(NULL, alpha_str,
174 alpha,
175 0,
176 1000);
177
178 cc->vegas_params.beta =
179 networkstatus_get_param(NULL, beta_str,
180 beta,
181 0,
182 1000);
183
184 cc->vegas_params.gamma =
185 networkstatus_get_param(NULL, gamma_str,
186 gamma,
187 0,
188 1000);
189
190 cc->vegas_params.delta =
191 networkstatus_get_param(NULL, delta_str,
192 delta,
193 0,
194 INT32_MAX);
195
196 cc_vegas_cwnd_full_minpct =
197 networkstatus_get_param(NULL, "cc_cwnd_full_minpct",
199 0,
200 100);
201
202 cc_vegas_cwnd_full_gap =
203 networkstatus_get_param(NULL, "cc_cwnd_full_gap",
205 0,
206 INT16_MAX);
207
208 cc_cwnd_full_per_cwnd =
209 networkstatus_get_param(NULL, "cc_cwnd_full_per_cwnd",
211 0,
212 1);
213}
214
215/**
216 * Common log function for tracking all vegas state.
217 */
218static void
220 const congestion_control_t *cc)
221{
222 uint64_t queue_use = cc->cwnd - vegas_bdp(cc);
223
224 if (CIRCUIT_IS_ORIGIN(circ) &&
226 log_info(LD_CIRC,
227 "CC: TOR_VEGAS Onion Circuit %d "
228 "RTT: %"PRIu64", %"PRIu64", %"PRIu64", "
229 "CWND: %"PRIu64", "
230 "INFL: %"PRIu64", "
231 "VBDP: %"PRIu64", "
232 "QUSE: %"PRIu64", "
233 "BWE: %"PRIu64", "
234 "SS: %d",
235 CONST_TO_ORIGIN_CIRCUIT(circ)->global_identifier,
236 cc->min_rtt_usec/1000,
237 cc->ewma_rtt_usec/1000,
238 cc->max_rtt_usec/1000,
239 cc->cwnd,
240 cc->inflight,
241 vegas_bdp(cc),
242 queue_use,
244 MAX(cc->min_rtt_usec,cc->ewma_rtt_usec),
245 cc->in_slow_start
246 );
247 } else {
248 log_info(LD_CIRC,
249 "CC: TOR_VEGAS "
250 "RTT: %"PRIu64", %"PRIu64", %"PRIu64", "
251 "CWND: %"PRIu64", "
252 "INFL: %"PRIu64", "
253 "VBDP: %"PRIu64", "
254 "QUSE: %"PRIu64", "
255 "BWE: %"PRIu64", "
256 "SS: %d",
257 cc->min_rtt_usec/1000,
258 cc->ewma_rtt_usec/1000,
259 cc->max_rtt_usec/1000,
260 cc->cwnd,
261 cc->inflight,
262 vegas_bdp(cc),
263 queue_use,
265 MAX(cc->min_rtt_usec,cc->ewma_rtt_usec),
266 cc->in_slow_start
267 );
268 }
269}
270
271/**
272 * Implements RFC3742: Limited Slow Start.
273 * https://datatracker.ietf.org/doc/html/rfc3742#section-2
274 */
275static inline uint64_t
277{
278 if (cc->cwnd <= cc->vegas_params.ss_cwnd_cap) {
279 /* If less than the cap, round and always grow by at least 1 sendme_inc. */
280 return ((uint64_t)cc->cwnd_inc_pct_ss*cc->sendme_inc + 50)/100;
281 } else {
282 // K = int(cwnd/(0.5 max_ssthresh));
283 // => K = 2*cwnd/max_ssthresh
284 // cwnd += int(MSS/K);
285 // => cwnd += MSS*max_ssthresh/(2*cwnd)
286 // Return at least 1 for inc.
287 return MAX(
288 ((uint64_t)cc->sendme_inc*cc->vegas_params.ss_cwnd_cap + cc->cwnd)/
289 (2*cc->cwnd),
290 1);
291 }
292}
293
294/**
295 * Exit Vegas slow start.
296 *
297 * This function sets our slow-start state to 0, and emits logs
298 * and control port information signifying end of slow start.
299 * It also schedules the next CWND update for steady-state.
300 */
301static void
304{
306 cc->in_slow_start = 0;
308
309 /* Update metricsport metrics */
311 stats_update_running_avg(cc_stats_vegas_exit_ss_cwnd_ma,
312 cc->cwnd);
313 cc_stats_vegas_exit_ss_bdp_ma =
314 stats_update_running_avg(cc_stats_vegas_exit_ss_bdp_ma,
315 vegas_bdp(cc));
316 cc_stats_vegas_exit_ss_inc_ma =
317 stats_update_running_avg(cc_stats_vegas_exit_ss_inc_ma,
318 rfc3742_ss_inc(cc));
319 cc_stats_vegas_circ_exited_ss++;
320
321 /* We need to report that slow start has exited ASAP,
322 * for sbws bandwidth measurement. */
323 if (CIRCUIT_IS_ORIGIN(circ)) {
324 /* We must discard const here because the event modifies fields :/ */
327 }
328}
329
330/**
331 * Returns true if the congestion window is considered full.
332 *
333 * We allow a number of sendme_incs gap in case buffering issues
334 * with edge conns cause the window to occasionally be not quite
335 * full. This can happen if several SENDMEs arrive before we
336 * return to the eventloop to fill the inbuf on edge connections.
337 */
338static inline bool
340{
341 if (cc->inflight + cc_vegas_cwnd_full_gap*cc->sendme_inc >= cc->cwnd) {
342 return true;
343 } else {
344 return false;
345 }
346}
347
348/**
349 * Returns true if the congestion window is no longer full.
350 *
351 * This functions as a low watermark, below which we stop
352 * allowing cwnd increments.
353 */
354static inline bool
356{
357 /* Use multiply form to avoid division */
358 if (100*cc->inflight < cc_vegas_cwnd_full_minpct * cc->cwnd) {
359 return true;
360 } else {
361 return false;
362 }
363}
364
365/**
366 * Decide if it is time to reset the cwnd_full status.
367 *
368 * If cc_cwnd_full_per_cwnd=1, we reset cwnd_full once per congestion
369 * window, ie:
370 * next_cwnd_event == SENDME_PER_CWND(cc)
371 *
372 * Otherwise, we reset cwnd_full whenever there is an update of
373 * the congestion window, ie:
374 * next_cc_event == CWND_UPDATE_RATE(cc)
375 */
376static inline bool
378{
379 if (cc_cwnd_full_per_cwnd) {
380 return (cc->next_cwnd_event == SENDME_PER_CWND(cc));
381 } else {
382 return (cc->next_cc_event == CWND_UPDATE_RATE(cc));
383 }
384}
385
386/**
387 * Process a SENDME and update the congestion window according to the
388 * rules specified in TOR_VEGAS of Proposal #324.
389 *
390 * Essentially, this algorithm attempts to measure queue lengths on
391 * the circuit by subtracting the bandwidth-delay-product estimate
392 * from the current congestion window.
393 *
394 * If the congestion window is larger than the bandwidth-delay-product,
395 * then data is assumed to be queuing. We reduce the congestion window
396 * in that case.
397 *
398 * If the congestion window is smaller than the bandwidth-delay-product,
399 * then there is spare bandwidth capacity on the circuit. We increase the
400 * congestion window in that case.
401 *
402 * The congestion window is updated only once every congestion window worth of
403 * packets, even if the signal persists. It is also updated whenever the
404 * upstream orcon blocks, or unblocks. This minimizes local client queues.
405 */
406int
408 const circuit_t *circ)
409{
410 uint64_t queue_use;
411
412 tor_assert(cc && cc->cc_alg == CC_ALG_VEGAS);
413 tor_assert(circ);
414
415 /* Update ack counter until next congestion signal event is allowed */
416 if (cc->next_cc_event)
417 cc->next_cc_event--;
418
419 /* Update ack counter until a full cwnd is processed */
420 if (cc->next_cwnd_event)
421 cc->next_cwnd_event--;
422
423 /* Compute BDP and RTT. If we did not update, don't run the alg */
425 cc->inflight = cc->inflight - cc->sendme_inc;
426 return 0;
427 }
428
429 /* The queue use is the amount in which our cwnd is above BDP;
430 * if it is below, then 0 queue use. */
431 if (vegas_bdp(cc) > cc->cwnd)
432 queue_use = 0; // This should not happen anymore..
433 else
434 queue_use = cc->cwnd - vegas_bdp(cc);
435
436 /* Update the full state */
437 if (cwnd_became_full(cc))
438 cc->cwnd_full = 1;
439 else if (cwnd_became_nonfull(cc))
440 cc->cwnd_full = 0;
441
442 if (cc->in_slow_start) {
443 if (queue_use < cc->vegas_params.gamma && !cc->blocked_chan) {
444 /* If the congestion window is not fully in use, skip any
445 * increment of cwnd in slow start */
446 if (cc->cwnd_full) {
447 /* Get the "Limited Slow Start" increment */
448 uint64_t inc = rfc3742_ss_inc(cc);
449 cc->cwnd += inc;
450
451 // Check if inc is less than what we would do in steady-state
452 // avoidance. Note that this is likely never to happen
453 // in practice, but we keep this block and the metrics to make
454 // sure.
455 if (inc*SENDME_PER_CWND(cc) <= CWND_INC(cc)*cc->cwnd_inc_rate) {
457
458 cc_stats_vegas_below_ss_inc_floor++;
459
460 /* We exited slow start without being blocked */
461 cc_stats_vegas_ss_csig_blocked_ma =
462 stats_update_running_avg(cc_stats_vegas_ss_csig_blocked_ma,
463 0);
464 }
465 }
466 } else {
467 uint64_t old_cwnd = cc->cwnd;
468
469 /* Congestion signal: Set cwnd to gamma threshold */
470 cc->cwnd = vegas_bdp(cc) + cc->vegas_params.gamma;
471
472 /* Compute the percentage we experience a blocked csig vs RTT sig */
473 if (cc->blocked_chan) {
474 cc_stats_vegas_ss_csig_blocked_ma =
475 stats_update_running_avg(cc_stats_vegas_ss_csig_blocked_ma,
476 100);
477 } else {
478 uint64_t cwnd_diff = (old_cwnd > cc->cwnd ? old_cwnd - cc->cwnd : 0);
479
480 cc_stats_vegas_ss_csig_blocked_ma =
481 stats_update_running_avg(cc_stats_vegas_ss_csig_blocked_ma,
482 0);
483
484 /* Account the amount we reduced the cwnd by for the gamma cutoff */
485 cc_stats_vegas_gamma_drop_ma =
486 stats_update_running_avg(cc_stats_vegas_gamma_drop_ma,
487 cwnd_diff);
488 }
489
491 }
492
493 if (cc->cwnd >= cc->vegas_params.ss_cwnd_max) {
494 cc->cwnd = cc->vegas_params.ss_cwnd_max;
497 }
498
499 cc_stats_vegas_ss_queue_ma =
500 stats_update_running_avg(cc_stats_vegas_ss_queue_ma,
501 queue_use);
502 /* After slow start, We only update once per window */
503 } else if (cc->next_cc_event == 0) {
504 if (queue_use > cc->vegas_params.delta) {
505 uint64_t old_cwnd = cc->cwnd;
506 uint64_t cwnd_diff;
507
508 /* If we are above the delta threshold, drop cwnd down to the
509 * delta threshold. */
510 cc->cwnd = vegas_bdp(cc) + cc->vegas_params.delta - CWND_INC(cc);
511
512 /* Account the amount we reduced the cwnd by for the gamma cutoff */
513 cwnd_diff = (old_cwnd > cc->cwnd ? old_cwnd - cc->cwnd : 0);
514 cc_stats_vegas_delta_drop_ma =
515 stats_update_running_avg(cc_stats_vegas_delta_drop_ma,
516 cwnd_diff);
517
519
520 /* Percentage metrics: Add 100% delta, 0 for other two */
521 cc_stats_vegas_csig_alpha_ma =
522 stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
523 0);
524 cc_stats_vegas_csig_beta_ma =
525 stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
526 0);
527 cc_stats_vegas_csig_delta_ma =
528 stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
529 100);
530 } else if (queue_use > cc->vegas_params.beta || cc->blocked_chan) {
531 cc->cwnd -= CWND_INC(cc);
532
533 /* Compute the percentage we experience a blocked csig vs RTT sig */
534 if (cc->blocked_chan) {
535 cc_stats_vegas_csig_blocked_ma =
536 stats_update_running_avg(cc_stats_vegas_csig_blocked_ma,
537 100);
538 } else {
539 cc_stats_vegas_csig_blocked_ma =
540 stats_update_running_avg(cc_stats_vegas_csig_blocked_ma,
541 0);
542 }
543
544 /* Percentage counters: Add 100% beta, 0 for other two */
545 cc_stats_vegas_csig_alpha_ma =
546 stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
547 0);
548 cc_stats_vegas_csig_beta_ma =
549 stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
550 100);
551 cc_stats_vegas_csig_delta_ma =
552 stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
553 0);
554 } else if (cc->cwnd_full &&
555 queue_use < cc->vegas_params.alpha) {
556 cc->cwnd += CWND_INC(cc);
557
558 /* Percentage counters: Add 100% alpha, 0 for other two */
559 cc_stats_vegas_csig_alpha_ma =
560 stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
561 100);
562 cc_stats_vegas_csig_beta_ma =
563 stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
564 0);
565 cc_stats_vegas_csig_delta_ma =
566 stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
567 0);
568 } else {
569 /* Percentage counters: No signal this round. Add 0% to all */
570 cc_stats_vegas_csig_alpha_ma =
571 stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
572 0);
573 cc_stats_vegas_csig_beta_ma =
574 stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
575 0);
576 cc_stats_vegas_csig_delta_ma =
577 stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
578 0);
579 }
580
581 /* cwnd can never fall below 1 increment */
582 cc->cwnd = MAX(cc->cwnd, cc->cwnd_min);
583
585
586 /* Update metrics */
587 cc_stats_vegas_queue_ma =
588 stats_update_running_avg(cc_stats_vegas_queue_ma,
589 queue_use);
590 cc_stats_vegas_bdp_ma =
591 stats_update_running_avg(cc_stats_vegas_bdp_ma,
592 vegas_bdp(cc));
593
594 /* Log if we're above the ss_cap */
595 if (cc->cwnd >= cc->vegas_params.ss_cwnd_max) {
596 log_info(LD_CIRC,
597 "CC: TOR_VEGAS above ss_max in steady state for circ %d: %"PRIu64,
598 circ->purpose, cc->cwnd);
599 }
600 }
601
602 /* Reset event counters */
603 if (cc->next_cwnd_event == 0) {
605 }
606 if (cc->next_cc_event == 0) {
608 }
609
610 /* Decide if enough time has passed to reset the cwnd utilization */
611 if (cwnd_full_reset(cc))
612 cc->cwnd_full = 0;
613
614 /* Update inflight with ack */
615 cc->inflight = cc->inflight - cc->sendme_inc;
616
617 return 0;
618}
Header file for channel.c.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:185
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:154
#define CIRCUIT_PURPOSE_S_REND_JOINED
Definition: circuitlist.h:110
Header file for circuituse.c.
#define MAX(a, b)
Definition: cmp.h:22
bool congestion_control_update_circuit_estimates(congestion_control_t *cc, const circuit_t *circ)
Public APIs for congestion control.
Structure definitions for congestion control.
static uint64_t SENDME_PER_CWND(const struct congestion_control_t *cc)
static uint64_t CWND_UPDATE_RATE(const struct congestion_control_t *cc)
@ CC_ALG_VEGAS
#define CWND_INC(cc)
static uint64_t vegas_bdp(const congestion_control_t *cc)
static bool cwnd_full_reset(const congestion_control_t *cc)
uint64_t cc_stats_vegas_above_ss_cwnd_max
uint64_t cc_stats_vegas_above_delta
double cc_stats_vegas_exit_ss_cwnd_ma
#define VEGAS_CWND_FULL_PER_CWND_DFLT
static bool cwnd_became_full(const congestion_control_t *cc)
#define VEGAS_CWND_FULL_GAP_DFLT
static uint64_t rfc3742_ss_inc(const congestion_control_t *cc)
static void congestion_control_vegas_exit_slow_start(const circuit_t *circ, congestion_control_t *cc)
void congestion_control_vegas_set_params(congestion_control_t *cc, cc_path_t path)
int congestion_control_vegas_process_sendme(congestion_control_t *cc, const circuit_t *circ)
static bool cwnd_became_nonfull(const congestion_control_t *cc)
#define VEGAS_CWND_FULL_MINPCT_DFLT
static void congestion_control_vegas_log(const circuit_t *circ, const congestion_control_t *cc)
Private-ish APIs for the TOR_VEGAS congestion control algorithm.
int control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc)
Header file for control_events.c.
Header file for crypt_path.c.
#define LD_CIRC
Definition: log.h:82
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.
Master header file for Tor-specific functionality.
#define CELL_MAX_NETWORK_SIZE
Definition: or.h:468
Origin circuit structure.
Header file for sendme.c.
Header for stats.c.
uint8_t purpose
Definition: circuit_st.h:112
struct vegas_params_t vegas_params
#define tor_assert(expr)
Definition: util_bug.h:103