These parameters will vary depending on path length, especially for onions.
V(UseMicrodescriptors, AUTOBOOL, "auto"),
OBSOLETE("UseNTorHandshake"),
VAR("__AlwaysCongestionControl", BOOL, AlwaysCongestionControl, "0"),
+ VAR("__SbwsExit", BOOL, SbwsExit, "0"),
V_IMMUTABLE(User, STRING, NULL),
OBSOLETE("UserspaceIOCPBuffers"),
OBSOLETE("V1AuthoritativeDirectory"),
/** Boolean: Switch to override consensus to enable congestion control */
int AlwaysCongestionControl;
+ /** Boolean: Switch to specify this is an sbws measurement exit */
+ int SbwsExit;
+
int RephistTrackTime; /**< How many seconds do we keep rephist info? */
/** Should we always fetch our dir info on the mirror schedule (which
* means directly from the authorities) no matter our other config? */
/* If the client asked for congestion control, if our consensus parameter
* allowed it to negotiate as enabled, allocate a congestion control obj. */
if (rpl.circ_params.cc_enabled) {
- TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&rpl.circ_params);
+ if (get_options()->SbwsExit) {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&rpl.circ_params,
+ CC_PATH_SBWS);
+ } else {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&rpl.circ_params,
+ CC_PATH_EXIT);
+ }
}
if (onionskin_answer(circ,
}
if (params.cc_enabled) {
- hop->ccontrol = congestion_control_new(¶ms);
+ int circ_len = circuit_get_cpath_len(circ);
+
+ if (circ_len == DEFAULT_ROUTE_LEN &&
+ circuit_get_cpath_hop(circ, DEFAULT_ROUTE_LEN) == hop) {
+ hop->ccontrol = congestion_control_new(¶ms, CC_PATH_EXIT);
+ } else if (circ_len == SBWS_ROUTE_LEN &&
+ circuit_get_cpath_hop(circ, SBWS_ROUTE_LEN) == hop) {
+ hop->ccontrol = congestion_control_new(¶ms, CC_PATH_SBWS);
+ } else {
+ static ratelim_t cc_path_limit = RATELIM_INIT(600);
+ log_fn_ratelim(&cc_path_limit, LOG_WARN, LD_CIRC,
+ "Unexpected path length %d for circuit",
+ circ_len);
+ hop->ccontrol = congestion_control_new(¶ms, CC_PATH_EXIT);
+ }
}
hop->state = CPATH_STATE_OPEN;
*/
static void
congestion_control_init_params(congestion_control_t *cc,
- const circuit_params_t *params)
+ const circuit_params_t *params,
+ cc_path_t path)
{
const or_options_t *opts = get_options();
cc->sendme_inc = params->sendme_inc_cells;
if (cc->cc_alg == CC_ALG_WESTWOOD) {
congestion_control_westwood_set_params(cc);
} else if (cc->cc_alg == CC_ALG_VEGAS) {
- congestion_control_vegas_set_params(cc);
+ congestion_control_vegas_set_params(cc, path);
} else if (cc->cc_alg == CC_ALG_NOLA) {
congestion_control_nola_set_params(cc);
}
*/
static void
congestion_control_init(congestion_control_t *cc,
- const circuit_params_t *params)
+ const circuit_params_t *params,
+ cc_path_t path)
{
cc->sendme_pending_timestamps = smartlist_new();
cc->sendme_arrival_timestamps = smartlist_new();
cc->in_slow_start = 1;
- congestion_control_init_params(cc, params);
+ congestion_control_init_params(cc, params, path);
cc->next_cc_event = CWND_UPDATE_RATE(cc);
}
/** Allocate and initialize a new congestion control object */
congestion_control_t *
-congestion_control_new(const circuit_params_t *params)
+congestion_control_new(const circuit_params_t *params, cc_path_t path)
{
congestion_control_t *cc = tor_malloc_zero(sizeof(congestion_control_t));
- congestion_control_init(cc, params);
+ congestion_control_init(cc, params, path);
return cc;
}
typedef struct congestion_control_t congestion_control_t;
+/**
+ * Specifies the path type to help choose congestion control
+ * parameters. Since these paths are different lengths, they
+ * will need different queue parameters. */
+typedef enum {
+ CC_PATH_EXIT = 0,
+ CC_PATH_ONION = 1,
+ CC_PATH_ONION_SOS = 2,
+ CC_PATH_ONION_VG = 3,
+ CC_PATH_SBWS = 4,
+} cc_path_t;
+
+/** The length of a path for sbws measurement */
+#define SBWS_ROUTE_LEN 2
+
/** Wrapper for the free function, set the CC pointer to NULL after free */
#define congestion_control_free(cc) \
FREE_AND_NULL(congestion_control_t, congestion_control_free_, cc)
struct circuit_params_t;
congestion_control_t *congestion_control_new(
- const struct circuit_params_t *params);
+ const struct circuit_params_t *params,
+ cc_path_t path);
int congestion_control_dispatch_cc_alg(congestion_control_t *cc,
const circuit_t *circ,
#define OUTBUF_CELLS (2*TLS_RECORD_MAX_CELLS)
-#define VEGAS_ALPHA(cc) (3*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
-#define VEGAS_BETA(cc) (3*OUTBUF_CELLS)
-#define VEGAS_GAMMA(cc) (3*OUTBUF_CELLS)
+/* sbws circs are two hops, so params are based on 2 outbufs of cells */
+#define VEGAS_ALPHA_SBWS_DFLT (2*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
+#define VEGAS_BETA_SBWS_DFLT (2*OUTBUF_CELLS)
+#define VEGAS_GAMMA_SBWS_DFLT (2*OUTBUF_CELLS)
+
+/* Exits are three hops, so params are based on 3 outbufs of cells */
+#define VEGAS_ALPHA_EXIT_DFLT (3*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
+#define VEGAS_BETA_EXIT_DFLT (3*OUTBUF_CELLS)
+#define VEGAS_GAMMA_EXIT_DFLT (3*OUTBUF_CELLS)
+
+/* Onion rends are six hops, so params are based on 6 outbufs of cells */
+#define VEGAS_ALPHA_ONION_DFLT (6*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
+#define VEGAS_BETA_ONION_DFLT (6*OUTBUF_CELLS)
+#define VEGAS_GAMMA_ONION_DFLT (6*OUTBUF_CELLS)
+
+/* Single Onions are three hops, so params are based on 3 outbufs of cells */
+#define VEGAS_ALPHA_SOS_DFLT (3*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
+#define VEGAS_BETA_SOS_DFLT (3*OUTBUF_CELLS)
+#define VEGAS_GAMMA_SOS_DFLT (3*OUTBUF_CELLS)
+
+/* Vanguard Onions are 7 hops (or 8 if both sides use vanguards, but that
+ * should be rare), so params are based on 7 outbufs of cells */
+#define VEGAS_ALPHA_VG_DFLT (7*OUTBUF_CELLS-TLS_RECORD_MAX_CELLS)
+#define VEGAS_BETA_VG_DFLT (7*OUTBUF_CELLS)
+#define VEGAS_GAMMA_VG_DFLT (7*OUTBUF_CELLS)
#define VEGAS_BDP_MIX_PCT 100
* Cache Vegas consensus parameters.
*/
void
-congestion_control_vegas_set_params(congestion_control_t *cc)
+congestion_control_vegas_set_params(congestion_control_t *cc,
+ cc_path_t path)
{
tor_assert(cc->cc_alg == CC_ALG_VEGAS);
+ const char *alpha_str = NULL, *beta_str = NULL, *gamma_str = NULL;
+ int alpha, beta, gamma;
- cc->vegas_params.gamma =
- networkstatus_get_param(NULL, "cc_vegas_gamma",
- VEGAS_GAMMA(cc),
- 0,
- 1000);
+ switch (path) {
+ case CC_PATH_SBWS:
+ alpha_str = "cc_vegas_alpha_sbws";
+ beta_str = "cc_vegas_beta_sbws";
+ gamma_str = "cc_vegas_gamma_sbws";
+ alpha = VEGAS_ALPHA_SBWS_DFLT;
+ beta = VEGAS_BETA_SBWS_DFLT;
+ gamma = VEGAS_GAMMA_SBWS_DFLT;
+ break;
+ case CC_PATH_EXIT:
+ alpha_str = "cc_vegas_alpha_exit";
+ beta_str = "cc_vegas_beta_exit";
+ gamma_str = "cc_vegas_gamma_exit";
+ alpha = VEGAS_ALPHA_EXIT_DFLT;
+ beta = VEGAS_BETA_EXIT_DFLT;
+ gamma = VEGAS_GAMMA_EXIT_DFLT;
+ break;
+ case CC_PATH_ONION:
+ alpha_str = "cc_vegas_alpha_onion";
+ beta_str = "cc_vegas_beta_onion";
+ gamma_str = "cc_vegas_gamma_onion";
+ alpha = VEGAS_ALPHA_ONION_DFLT;
+ beta = VEGAS_BETA_ONION_DFLT;
+ gamma = VEGAS_GAMMA_ONION_DFLT;
+ break;
+ case CC_PATH_ONION_SOS:
+ alpha_str = "cc_vegas_alpha_sos";
+ beta_str = "cc_vegas_beta_sos";
+ gamma_str = "cc_vegas_gamma_sos";
+ alpha = VEGAS_ALPHA_SOS_DFLT;
+ beta = VEGAS_BETA_SOS_DFLT;
+ gamma = VEGAS_GAMMA_SOS_DFLT;
+ break;
+ case CC_PATH_ONION_VG:
+ alpha_str = "cc_vegas_alpha_vg";
+ beta_str = "cc_vegas_beta_vg";
+ gamma_str = "cc_vegas_gamma_vg";
+ alpha = VEGAS_ALPHA_VG_DFLT;
+ beta = VEGAS_BETA_VG_DFLT;
+ gamma = VEGAS_GAMMA_VG_DFLT;
+ break;
+ default:
+ tor_assert(0);
+ break;
+ }
cc->vegas_params.alpha =
- networkstatus_get_param(NULL, "cc_vegas_alpha",
- VEGAS_ALPHA(cc),
+ networkstatus_get_param(NULL, alpha_str,
+ alpha,
0,
1000);
cc->vegas_params.beta =
- networkstatus_get_param(NULL, "cc_vegas_beta",
- VEGAS_BETA(cc),
+ networkstatus_get_param(NULL, beta_str,
+ beta,
+ 0,
+ 1000);
+
+ cc->vegas_params.gamma =
+ networkstatus_get_param(NULL, gamma_str,
+ gamma,
0,
1000);
int congestion_control_vegas_process_sendme(struct congestion_control_t *cc,
const circuit_t *circ,
const crypt_path_t *layer_hint);
-void congestion_control_vegas_set_params(struct congestion_control_t *cc);
+void congestion_control_vegas_set_params(struct congestion_control_t *cc,
+ cc_path_t path);
/* Private section starts. */
#ifdef TOR_CONGESTION_CONTROL_VEGAS_PRIVATE
.cc_enabled = data->cc_enabled,
.sendme_inc_cells = congestion_control_sendme_inc(),
};
- TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params);
+
+ /* Initialize ccontrol for appropriate path type */
+ if (service->config.is_single_onion) {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION_SOS);
+ } else {
+ if (get_options()->HSLayer3Nodes) {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION_VG);
+ } else {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION);
+ }
+ }
}
end:
.cc_enabled = 1,
.sendme_inc_cells = TO_CIRCUIT(circ)->ccontrol->sendme_inc,
};
- TO_CIRCUIT(new_circ)->ccontrol = congestion_control_new(&circ_params);
+
+ /* As per above, in this case, we are a full 3 hop rend, even if we're a
+ * single-onion service */
+ if (get_options()->HSLayer3Nodes) {
+ TO_CIRCUIT(new_circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION_VG);
+ } else {
+ TO_CIRCUIT(new_circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION_SOS);
+ }
}
done:
circ_params.cc_enabled = congestion_control_enabled();
if (circ_params.cc_enabled) {
circ_params.sendme_inc_cells = desc->encrypted_data.sendme_inc;
- TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params);
+
+ if (desc->encrypted_data.single_onion_service) {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION_SOS);
+ } else {
+ if (get_options()->HSLayer3Nodes) {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION_VG);
+ } else {
+ TO_CIRCUIT(circ)->ccontrol = congestion_control_new(&circ_params,
+ CC_PATH_ONION);
+ }
+ }
}
}