From 60b01c6d5e7afbb4eee6f7e57583fae4a7278d58 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 15 Dec 2009 13:53:53 -0500 Subject: [PATCH] Change interface for configuring cell ewma algorithm. The rule is now: take the value from the CircuitPriorityHalflife config option if it is set. If it zero, disable the cell_ewma algorithm. If it is set, use it to calculate the scaling factor. If it is not set, look for a CircPriorityHalflifeMsec parameter in the consensus networkstatus. If *that* is zero, then disable the cell_ewma algorithm; if it is set, use it to calculate the scaling factor. If it is not set at all, disable the algorithm. --- src/or/config.c | 8 +++---- src/or/networkstatus.c | 1 + src/or/or.h | 24 ++++++++++++------- src/or/relay.c | 53 +++++++++++++++++++++++++++++++----------- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/or/config.c b/src/or/config.c index a22ec4b13d..bb762ee311 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -167,6 +167,7 @@ static config_var_t _option_vars[] = { V(CircuitBuildTimeout, INTERVAL, "0"), V(CircuitIdleTimeout, INTERVAL, "1 hour"), V(CircuitStreamTimeout, INTERVAL, "0"), + V(CircuitPriorityHalflife, DOUBLE, "-100.0"), /*negative:'Use default'*/ V(ClientDNSRejectInternalAddresses, BOOL,"1"), V(ClientOnly, BOOL, "0"), V(ConsensusParams, STRING, NULL), @@ -212,6 +213,7 @@ static config_var_t _option_vars[] = { V(ExitPolicyRejectPrivate, BOOL, "1"), V(ExitPortStatistics, BOOL, "0"), V(ExtraInfoStatistics, BOOL, "0"), + V(FallbackNetworkstatusFile, FILENAME, SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"), V(FascistFirewall, BOOL, "0"), @@ -356,10 +358,6 @@ static config_var_t _option_vars[] = { NULL), V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"), - /* Options for EWMA selection of circuit to write from */ - VAR("EWMASignificance", DOUBLE, EWMASignificance, "-1.0"), - VAR("EWMAInterval", DOUBLE, EWMAInterval, "-1.0"), - { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL } }; @@ -1380,7 +1378,7 @@ options_act(or_options_t *old_options) configure_accounting(time(NULL)); /* Change the cell EWMA settings */ - cell_ewma_set_scale_factor(options); + cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus()); /* Check for transitions that need action. */ if (old_options) { diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index f3925f1b89..bebe87353b 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1679,6 +1679,7 @@ networkstatus_set_current_consensus(const char *consensus, update_consensus_networkstatus_fetch_time(now); dirvote_recalculate_timing(get_options(), now); routerstatus_list_update_named_server_map(); + cell_ewma_set_scale_factor(get_options(), current_consensus); } if (!from_cache) { diff --git a/src/or/or.h b/src/or/or.h index fd913ce4ef..745a0ce919 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2783,13 +2783,20 @@ typedef struct { * to make this false. */ int ReloadTorrcOnSIGHUP; - /* The EWMA parameters for circuit selection within a connection. - * The most recent EWMAInterval seconds will account for an - * EWMASignificance (between 0 and 1) portion of the weight. - * If these values are negative, use the global defaults (soon to be - * set in the consensus). */ - double EWMASignificance; - double EWMAInterval; + /* The main parameter for picking circuits within a connection. + * + * If this value is positive, when picking a cell to relay on a connection, + * we always relay from the circuit whose weighted cell count is lowest. + * Cells are weighted exponentially such that if one cell is sent + * 'CircuitPriorityHalflife' seconds before another, it counts for half as + * much. + * + * If this value is zero, we're disabling the cell-EWMA algorithm. + * + * If this value is negative, we're using the default approach + * according to either Tor or a parameter set in the consensus. + */ + double CircuitPriorityHalflife; } or_options_t; @@ -4491,7 +4498,8 @@ const char *decode_address_from_payload(tor_addr_t *addr_out, const char *payload, int payload_len); unsigned cell_ewma_get_tick(void); -void cell_ewma_set_scale_factor(or_options_t *options); +void cell_ewma_set_scale_factor(or_options_t *options, + networkstatus_t *consensus); /********************************* rephist.c ***************************/ diff --git a/src/or/relay.c b/src/or/relay.c index 1be09e1df0..ae1b062cf6 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1814,8 +1814,8 @@ cell_ewma_to_circuit(cell_ewma_t *ewma) #define EWMA_TICK_LEN 10 /** The default per-tick scale factor, if it hasn't been overridden by a - * consensus or a configuration setting. */ -#define EWMA_DEFAULT_SCALE_FACTOR 0.9 + * consensus or a configuration setting. zero means "disabled". */ +#define EWMA_DEFAULT_HALFLIFE 0.0 /** Given a timeval now, compute the cell_ewma tick in which it occurs * and the fraction of the tick that has elapsed between the start of the tick @@ -1846,24 +1846,51 @@ cell_ewma_get_tick(void) /** The per-tick scale factor to be used when computing cell-count EWMA * values. (A cell sent N ticks before the start of the current tick * has value ewma_scale_factor ** N.) - * - * If ewma_scale_factor is <= 0, the EWMA algorithm is disabled. */ -static double ewma_scale_factor = EWMA_DEFAULT_SCALE_FACTOR; +static double ewma_scale_factor = 0.1; +static int ewma_enabled = 0; + +#define EPSILON 0.00001 +#define LOG_ONEHALF -0.69314718055994529 /** Adjust the global cell scale factor based on options */ void -cell_ewma_set_scale_factor(or_options_t *options) +cell_ewma_set_scale_factor(or_options_t *options, networkstatus_t *consensus) { - double f; - if (options->EWMAInterval > 0.0001) { - f = pow(options->EWMASignificance, - EWMA_TICK_LEN / options->EWMAInterval); + int32_t halflife_ms; + double halflife; + const char *source; + if (options && options->CircuitPriorityHalflife >= -EPSILON) { + halflife = options->CircuitPriorityHalflife; + source = "CircuitPriorityHalflife in configuration"; + } else if (consensus && + (halflife_ms = networkstatus_get_param( + consensus, "CircPriorityHalflifeMsec", -1) >= 0)) { + halflife = ((double)halflife_ms)/1000.0; + source = "CircPriorityHalflifeMsec in consensus"; } else { - f = EWMA_DEFAULT_SCALE_FACTOR; + halflife = EWMA_DEFAULT_HALFLIFE; + source = "Default value"; } - ewma_scale_factor = f; + if (halflife <= EPSILON) { + /* The cell EWMA algorithm is disabled. */ + ewma_scale_factor = 0.1; + ewma_enabled = 0; + log_info(LD_OR, + "Disabled cell_ewma algorithm because of value in %s", + source); + } else { + /* convert halflife into halflife-per-tick. */ + halflife /= EWMA_TICK_LEN; + /* compute per-tick scale factor. */ + ewma_scale_factor = exp( LOG_ONEHALF / halflife ); + ewma_enabled = 1; + log_info(LD_OR, + "Enabled cell_ewma algorithm because of value in %s; " + "scale factor is %lf per %d seconds", + source, ewma_scale_factor, EWMA_TICK_LEN); + } } /** Return the multiplier necessary to convert the value of a cell sent in @@ -2108,7 +2135,7 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max, assert_active_circuits_ok_paranoid(conn); /* See if we're doing the ewma circuit selection algorithm. */ - if (ewma_scale_factor > 0.0) { + if (ewma_enabled) { unsigned tick; double fractional_tick; tor_gettimeofday_cached(&now_hires);