Tor  0.4.8.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 (2*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 (6*OUTBUF_CELLS)
44 #define VEGAS_SSCAP_EXIT_DFLT (500)
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 (7*OUTBUF_CELLS)
49 #define VEGAS_GAMMA_ONION_DFLT (5*OUTBUF_CELLS)
50 #define VEGAS_DELTA_ONION_DFLT (9*OUTBUF_CELLS)
51 #define VEGAS_SSCAP_ONION_DFLT (600)
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 (1)
57 static 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 (75)
64 static 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)
70 static 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. */
74 double cc_stats_vegas_exit_ss_bdp_ma = 0;
75 double cc_stats_vegas_exit_ss_inc_ma = 0;
76 double cc_stats_vegas_gamma_drop_ma = 0;
77 double cc_stats_vegas_delta_drop_ma = 0;
78 double cc_stats_vegas_ss_csig_blocked_ma = 0;
79 double cc_stats_vegas_csig_blocked_ma = 0;
80 double cc_stats_vegas_csig_alpha_ma = 0;
81 double cc_stats_vegas_csig_beta_ma = 0;
82 double cc_stats_vegas_csig_delta_ma = 0;
83 
84 double cc_stats_vegas_ss_queue_ma = 0;
85 double cc_stats_vegas_queue_ma = 0;
86 double 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. */
92 uint64_t cc_stats_vegas_below_ss_inc_floor = 0;
93 uint64_t cc_stats_vegas_circ_exited_ss = 0;
94 
95 /**
96  * The original TCP Vegas congestion window BDP estimator.
97  */
98 static inline uint64_t
100 {
101  return cc->bdp[BDP_ALG_CWND_RTT];
102 }
103 
104 /**
105  * Cache Vegas consensus parameters.
106  */
107 void
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 
160  cc->vegas_params.ss_cwnd_cap =
161  networkstatus_get_param(NULL, sscap_str,
162  ss_cwnd_cap,
163  100,
164  INT32_MAX);
165 
166  cc->vegas_params.ss_cwnd_max =
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  */
218 static 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,
243  cc->cwnd*CELL_MAX_NETWORK_SIZE*1000/
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,
264  cc->cwnd*CELL_MAX_NETWORK_SIZE*1000/
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  */
275 static 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  */
301 static 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 :/ */
326  TO_ORIGIN_CIRCUIT((circuit_t*)circ));
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  */
338 static 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  */
354 static 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  */
376 static 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  */
406 int
408  const circuit_t *circ,
409  const crypt_path_t *layer_hint)
410 {
411  uint64_t queue_use;
412 
413  tor_assert(cc && cc->cc_alg == CC_ALG_VEGAS);
414  tor_assert(circ);
415 
416  /* Update ack counter until next congestion signal event is allowed */
417  if (cc->next_cc_event)
418  cc->next_cc_event--;
419 
420  /* Update ack counter until a full cwnd is processed */
421  if (cc->next_cwnd_event)
422  cc->next_cwnd_event--;
423 
424  /* Compute BDP and RTT. If we did not update, don't run the alg */
425  if (!congestion_control_update_circuit_estimates(cc, circ, layer_hint)) {
426  cc->inflight = cc->inflight - cc->sendme_inc;
427  return 0;
428  }
429 
430  /* The queue use is the amount in which our cwnd is above BDP;
431  * if it is below, then 0 queue use. */
432  if (vegas_bdp(cc) > cc->cwnd)
433  queue_use = 0; // This should not happen anymore..
434  else
435  queue_use = cc->cwnd - vegas_bdp(cc);
436 
437  /* Update the full state */
438  if (cwnd_became_full(cc))
439  cc->cwnd_full = 1;
440  else if (cwnd_became_nonfull(cc))
441  cc->cwnd_full = 0;
442 
443  if (cc->in_slow_start) {
444  if (queue_use < cc->vegas_params.gamma && !cc->blocked_chan) {
445  /* If the congestion window is not fully in use, skip any
446  * increment of cwnd in slow start */
447  if (cc->cwnd_full) {
448  /* Get the "Limited Slow Start" increment */
449  uint64_t inc = rfc3742_ss_inc(cc);
450  cc->cwnd += inc;
451 
452  // Check if inc is less than what we would do in steady-state
453  // avoidance. Note that this is likely never to happen
454  // in practice, but we keep this block and the metrics to make
455  // sure.
456  if (inc*SENDME_PER_CWND(cc) <= CWND_INC(cc)*cc->cwnd_inc_rate) {
458 
459  cc_stats_vegas_below_ss_inc_floor++;
460 
461  /* We exited slow start without being blocked */
462  cc_stats_vegas_ss_csig_blocked_ma =
463  stats_update_running_avg(cc_stats_vegas_ss_csig_blocked_ma,
464  0);
465  }
466  }
467  } else {
468  uint64_t old_cwnd = cc->cwnd;
469 
470  /* Congestion signal: Set cwnd to gamma threshold */
471  cc->cwnd = vegas_bdp(cc) + cc->vegas_params.gamma;
472 
473  /* Compute the percentage we experience a blocked csig vs RTT sig */
474  if (cc->blocked_chan) {
475  cc_stats_vegas_ss_csig_blocked_ma =
476  stats_update_running_avg(cc_stats_vegas_ss_csig_blocked_ma,
477  100);
478  } else {
479  uint64_t cwnd_diff = (old_cwnd > cc->cwnd ? old_cwnd - cc->cwnd : 0);
480 
481  cc_stats_vegas_ss_csig_blocked_ma =
482  stats_update_running_avg(cc_stats_vegas_ss_csig_blocked_ma,
483  0);
484 
485  /* Account the amount we reduced the cwnd by for the gamma cutoff */
486  cc_stats_vegas_gamma_drop_ma =
487  stats_update_running_avg(cc_stats_vegas_gamma_drop_ma,
488  cwnd_diff);
489  }
490 
492  }
493 
494  if (cc->cwnd >= cc->vegas_params.ss_cwnd_max) {
495  cc->cwnd = cc->vegas_params.ss_cwnd_max;
498  }
499 
500  cc_stats_vegas_ss_queue_ma =
501  stats_update_running_avg(cc_stats_vegas_ss_queue_ma,
502  queue_use);
503  /* After slow start, We only update once per window */
504  } else if (cc->next_cc_event == 0) {
505  if (queue_use > cc->vegas_params.delta) {
506  uint64_t old_cwnd = cc->cwnd;
507  uint64_t cwnd_diff;
508 
509  /* If we are above the delta threshold, drop cwnd down to the
510  * delta threshold. */
511  cc->cwnd = vegas_bdp(cc) + cc->vegas_params.delta - CWND_INC(cc);
512 
513  /* Account the amount we reduced the cwnd by for the gamma cutoff */
514  cwnd_diff = (old_cwnd > cc->cwnd ? old_cwnd - cc->cwnd : 0);
515  cc_stats_vegas_delta_drop_ma =
516  stats_update_running_avg(cc_stats_vegas_delta_drop_ma,
517  cwnd_diff);
518 
520 
521  /* Percentage metrics: Add 100% delta, 0 for other two */
522  cc_stats_vegas_csig_alpha_ma =
523  stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
524  0);
525  cc_stats_vegas_csig_beta_ma =
526  stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
527  0);
528  cc_stats_vegas_csig_delta_ma =
529  stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
530  100);
531  } else if (queue_use > cc->vegas_params.beta || cc->blocked_chan) {
532  cc->cwnd -= CWND_INC(cc);
533 
534  /* Compute the percentage we experience a blocked csig vs RTT sig */
535  if (cc->blocked_chan) {
536  cc_stats_vegas_csig_blocked_ma =
537  stats_update_running_avg(cc_stats_vegas_csig_blocked_ma,
538  100);
539  } else {
540  cc_stats_vegas_csig_blocked_ma =
541  stats_update_running_avg(cc_stats_vegas_csig_blocked_ma,
542  0);
543  }
544 
545  /* Percentage counters: Add 100% beta, 0 for other two */
546  cc_stats_vegas_csig_alpha_ma =
547  stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
548  0);
549  cc_stats_vegas_csig_beta_ma =
550  stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
551  100);
552  cc_stats_vegas_csig_delta_ma =
553  stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
554  0);
555  } else if (cc->cwnd_full &&
556  queue_use < cc->vegas_params.alpha) {
557  cc->cwnd += CWND_INC(cc);
558 
559  /* Percentage counters: Add 100% alpha, 0 for other two */
560  cc_stats_vegas_csig_alpha_ma =
561  stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
562  100);
563  cc_stats_vegas_csig_beta_ma =
564  stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
565  0);
566  cc_stats_vegas_csig_delta_ma =
567  stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
568  0);
569  } else {
570  /* Percentage counters: No signal this round. Add 0% to all */
571  cc_stats_vegas_csig_alpha_ma =
572  stats_update_running_avg(cc_stats_vegas_csig_alpha_ma,
573  0);
574  cc_stats_vegas_csig_beta_ma =
575  stats_update_running_avg(cc_stats_vegas_csig_beta_ma,
576  0);
577  cc_stats_vegas_csig_delta_ma =
578  stats_update_running_avg(cc_stats_vegas_csig_delta_ma,
579  0);
580  }
581 
582  /* cwnd can never fall below 1 increment */
583  cc->cwnd = MAX(cc->cwnd, cc->cwnd_min);
584 
586 
587  /* Update metrics */
588  cc_stats_vegas_queue_ma =
589  stats_update_running_avg(cc_stats_vegas_queue_ma,
590  queue_use);
591  cc_stats_vegas_bdp_ma =
592  stats_update_running_avg(cc_stats_vegas_bdp_ma,
593  vegas_bdp(cc));
594 
595  /* Log if we're above the ss_cap */
596  if (cc->cwnd >= cc->vegas_params.ss_cwnd_max) {
597  log_info(LD_CIRC,
598  "CC: TOR_VEGAS above ss_max in steady state for circ %d: %"PRIu64,
599  circ->purpose, cc->cwnd);
600  }
601  }
602 
603  /* Reset event counters */
604  if (cc->next_cwnd_event == 0) {
606  }
607  if (cc->next_cc_event == 0) {
609  }
610 
611  /* Decide if enough time has passed to reset the cwnd utilization */
612  if (cwnd_full_reset(cc))
613  cc->cwnd_full = 0;
614 
615  /* Update inflight with ack */
616  cc->inflight = cc->inflight - cc->sendme_inc;
617 
618  return 0;
619 }
Header file for channel.c.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:177
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:147
#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, const crypt_path_t *layer_hint)
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, const crypt_path_t *layer_hint)
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:459
Origin circuit structure.
Header file for sendme.c.
Header for stats.c.
uint8_t purpose
Definition: circuit_st.h:112
#define tor_assert(expr)
Definition: util_bug.h:102