summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Perry <mikeperry-git@torproject.org>2022-07-31 15:14:22 +0000
committerDavid Goulet <dgoulet@torproject.org>2022-08-11 09:26:51 -0400
commitacdc0ecdd47879e202b1406236ce80e028b71d40 (patch)
treeda73bf276fb0ca8f8a046d4c01616c70cccc0829
parent4444f5f4ed968f08d26735a2531f03a6c4369226 (diff)
downloadtor-acdc0ecdd47879e202b1406236ce80e028b71d40.tar.gz
tor-acdc0ecdd47879e202b1406236ce80e028b71d40.zip
Reset the min value if we hit cwnd_min.
This can avoid circuits getting stuck due to an abnormally low min value.
-rw-r--r--src/core/or/congestion_control_common.c33
-rw-r--r--src/core/or/congestion_control_common.h23
2 files changed, 55 insertions, 1 deletions
diff --git a/src/core/or/congestion_control_common.c b/src/core/or/congestion_control_common.c
index b90c78729a..25446621d1 100644
--- a/src/core/or/congestion_control_common.c
+++ b/src/core/or/congestion_control_common.c
@@ -54,6 +54,8 @@
#define N_EWMA_MAX_DFLT (10)
#define N_EWMA_SS_DFLT (2)
+#define RTT_RESET_PCT_DFLT (100)
+
/* BDP algorithms for each congestion control algorithms use the piecewise
* estimattor. See section 3.1.4 of proposal 324. */
#define WESTWOOD_BDP_ALG BDP_ALG_PIECEWISE
@@ -119,6 +121,12 @@ static uint8_t n_ewma_ss;
static uint8_t bwe_sendme_min;
/**
+ * Percentage of the current RTT to use when reseting the minimum RTT
+ * for a circuit. (RTT is reset when the cwnd hits cwnd_min).
+ */
+static uint8_t rtt_reset_pct;
+
+/**
* Update global congestion control related consensus parameter values,
* every consensus update.
*/
@@ -163,6 +171,14 @@ congestion_control_new_consensus_params(const networkstatus_t *ns)
CWND_MAX_MIN,
CWND_MAX_MAX);
+#define RTT_RESET_PCT_MIN (0)
+#define RTT_RESET_PCT_MAX (100)
+ rtt_reset_pct =
+ networkstatus_get_param(NULL, "cc_rtt_reset_pct",
+ RTT_RESET_PCT_DFLT,
+ RTT_RESET_PCT_MIN,
+ RTT_RESET_PCT_MAX);
+
#define SENDME_INC_MIN 1
#define SENDME_INC_MAX (255)
cc_sendme_inc =
@@ -857,7 +873,22 @@ congestion_control_update_circuit_rtt(congestion_control_t *cc,
cc->max_rtt_usec = rtt;
}
- if (cc->min_rtt_usec == 0 || cc->ewma_rtt_usec < cc->min_rtt_usec) {
+ if (cc->min_rtt_usec == 0) {
+ // If we do not have a min_rtt yet, use current ewma
+ cc->min_rtt_usec = cc->ewma_rtt_usec;
+ } else if (cc->cwnd == cc->cwnd_min) {
+ // Raise min rtt if cwnd hit cwnd_min. This gets us out of a wedge state
+ // if we hit cwnd_min due to an abnormally low rtt.
+ uint64_t new_rtt = percent_max_mix(cc->ewma_rtt_usec, cc->min_rtt_usec,
+ rtt_reset_pct);
+
+ static ratelim_t rtt_notice_limit = RATELIM_INIT(300);
+ log_fn_ratelim(&rtt_notice_limit, LOG_NOTICE, LD_CIRC,
+ "Resetting circ RTT from %"PRIu64" to %"PRIu64" due to low cwnd",
+ cc->min_rtt_usec/1000, new_rtt/1000);
+
+ cc->min_rtt_usec = new_rtt;
+ } else if (cc->ewma_rtt_usec < cc->min_rtt_usec) {
// Using the EWMA for min instead of current RTT helps average out
// effects from other conns
cc->min_rtt_usec = cc->ewma_rtt_usec;
diff --git a/src/core/or/congestion_control_common.h b/src/core/or/congestion_control_common.h
index 71e984f914..50af945d62 100644
--- a/src/core/or/congestion_control_common.h
+++ b/src/core/or/congestion_control_common.h
@@ -145,6 +145,29 @@ n_count_ewma(uint64_t curr, uint64_t prev, uint64_t N)
return (2*curr + (N-1)*prev)/(N+1);
}
+/**
+ * Helper function that gives us a percentile weighted-average between
+ * two values. The pct_max argument specifies the percentage weight of the
+ * maximum of a and b, when computing this weighted-average.
+ *
+ * This also allows this function to be used as either MIN() or a MAX()
+ * by this parameterization. It is MIN() when pct_max==0;
+ * it is MAX() when pct_max==100; it is avg() when pct_max==50; it is a
+ * weighted-average for values in between.
+ */
+static inline uint64_t
+percent_max_mix(uint64_t a, uint64_t b, uint8_t pct_max)
+{
+ uint64_t max = MAX(a, b);
+ uint64_t min = MIN(a, b);
+
+ if (BUG(pct_max > 100)) {
+ return max;
+ }
+
+ return pct_max*max/100 + (100-pct_max)*min/100;
+}
+
/* Private section starts. */
#ifdef TOR_CONGESTION_CONTROL_PRIVATE