#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
*/
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.
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 =
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;
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