Tor  0.4.8.0-alpha-dev
congestion_control_nola.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_nola.c
6  * \brief Code that implements the TOR_NOLA congestion control algorithm
7  * from Proposal #324.
8  */
9 
10 #define TOR_CONGESTION_CONTROL_NOLA_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/circuituse.h"
21 #include "core/or/circuitlist.h"
23 #include "core/or/channel.h"
26 
27 #define NOLA_BDP_OVERSHOOT 100
28 
29 /**
30  * Cache NOLA consensus parameters.
31  */
32 void
34 {
36 
37  cc->nola_params.bdp_overshoot =
38  networkstatus_get_param(NULL, "cc_nola_overshoot",
39  NOLA_BDP_OVERSHOOT,
40  0,
41  1000);
42 }
43 
44 /**
45 * Process a SENDME and update the congestion window according to the
46 * rules specified in TOR_NOLA of Proposal #324.
47 *
48 * TOR_NOLA updates the congestion window to match the current
49 * BDP estimate, every sendme. Because this can result in downward
50 * drift, a fixed overhead is added to the BDP estimate. This will
51 * cause some queuing, but ensures that the algorithm always uses
52 * the full BDP.
53 *
54 * To handle the case where the local orconn blocks, TOR_NOLA uses
55 * the 'piecewise' BDP estimate, which uses more a conservative BDP
56 * estimate method when blocking occurs, but a more aggressive BDP
57 * estimate when there is no local blocking. This minimizes local
58 * client queues.
59 */
60 int
62  const circuit_t *circ,
63  const crypt_path_t *layer_hint)
64 {
65  tor_assert(cc && cc->cc_alg == CC_ALG_NOLA);
66  tor_assert(circ);
67 
68  if (cc->next_cc_event)
69  cc->next_cc_event--;
70 
71  /* If we get a congestion event, the only thing NOLA
72  * does is note this as if we exited slow-start
73  * (which for NOLA just means we finished our ICW). */
74  if (cc->next_cc_event == 0) {
75  if (cc->in_slow_start) {
76  cc->in_slow_start = 0;
77 
78  /* We need to report that slow start has exited ASAP,
79  * for sbws bandwidth measurement. */
80  if (CIRCUIT_IS_ORIGIN(circ)) {
81  /* We must discard const here because the event modifies fields :/ */
84  }
85  }
86  }
87 
88  /* If we did not successfully update BDP, we must return. Otherwise,
89  * NOLA can drift downwards */
90  if (!congestion_control_update_circuit_estimates(cc, circ, layer_hint)) {
91  cc->inflight = cc->inflight - cc->sendme_inc;
92  return 0;
93  }
94 
95  /* We overshoot the BDP by the cwnd_inc param amount, because BDP
96  * may otherwise drift down. This helps us probe for more capacity.
97  * But there is no sense to do it if the local channel is blocked. */
98  if (cc->blocked_chan)
99  cc->cwnd = cc->bdp[cc->bdp_alg];
100  else
101  cc->cwnd = cc->bdp[cc->bdp_alg] + cc->nola_params.bdp_overshoot;
102 
103  /* cwnd can never fall below 1 increment */
104  cc->cwnd = MAX(cc->cwnd, cc->cwnd_min);
105 
106  if (CIRCUIT_IS_ORIGIN(circ)) {
107  log_info(LD_CIRC,
108  "CC TOR_NOLA: Circuit %d "
109  "CWND: %"PRIu64", "
110  "INFL: %"PRIu64", "
111  "NCCE: %"PRIu16", "
112  "SS: %d",
113  CONST_TO_ORIGIN_CIRCUIT(circ)->global_identifier,
114  cc->cwnd,
115  cc->inflight,
116  cc->next_cc_event,
117  cc->in_slow_start
118  );
119  } else {
120  log_info(LD_CIRC,
121  "CC TOR_NOLA: Circuit %"PRIu64":%d "
122  "CWND: %"PRIu64", "
123  "INFL: %"PRIu64", "
124  "NCCE: %"PRIu16", "
125  "SS: %d",
126  CONST_TO_OR_CIRCUIT(circ)->p_chan->global_identifier,
127  CONST_TO_OR_CIRCUIT(circ)->p_circ_id,
128  cc->cwnd,
129  cc->inflight,
130  cc->next_cc_event,
131  cc->in_slow_start
132  );
133  }
134 
135  /* Update inflight with ack */
136  cc->inflight = cc->inflight - cc->sendme_inc;
137 
138  return 0;
139 }
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
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.
int congestion_control_nola_process_sendme(congestion_control_t *cc, const circuit_t *circ, const crypt_path_t *layer_hint)
void congestion_control_nola_set_params(congestion_control_t *cc)
Private-ish APIs for the TOR_NOLA congestion control algorithm.
Structure definitions for congestion control.
@ CC_ALG_NOLA
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.
Origin circuit structure.
Header file for sendme.c.
#define tor_assert(expr)
Definition: util_bug.h:102