diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/config.c | 38 | ||||
-rw-r--r-- | src/or/or.h | 5 | ||||
-rw-r--r-- | src/or/routerlist.c | 20 |
3 files changed, 40 insertions, 23 deletions
diff --git a/src/or/config.c b/src/or/config.c index 5fad240ef..39f4698d0 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -299,10 +299,12 @@ static config_var_t _state_vars[] = { VAR("AccountingExpectedUsage", MEMUNIT, AccountingExpectedUsage, NULL), VAR("AccountingIntervalStart", ISOTIME, AccountingIntervalStart, NULL), VAR("AccountingSecondsActive", INTERVAL, AccountingSecondsActive, NULL), + VAR("EntryGuard", LINELIST_S, EntryGuards, NULL), VAR("EntryGuardDownSince", LINELIST_S, EntryGuards, NULL), VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL), VAR("EntryGuards", LINELIST_V, EntryGuards, NULL), + VAR("GuardVersion", UINT, GuardVersion, "0"), VAR("BWHistoryReadEnds", ISOTIME, BWHistoryReadEnds, NULL), VAR("BWHistoryReadInterval", UINT, BWHistoryReadInterval, "900"), @@ -529,6 +531,8 @@ static config_var_description_t state_description[] = { "The last entry guard has been unreachable since this time." }, { "EntryGuardUnlistedSince", "The last entry guard has been unusable since this time." }, + { "GuardVersion", "Which algorithm did we use to pick these guards?" }, + { "LastRotatedOnionKey", "The last time at which we changed the medium-term private key used for " "building circuits." }, @@ -4332,6 +4336,12 @@ get_or_state_fname(void) return fname; } +/** What's the newest known version for our guard-picking algorithm? + * If the version in the state file is older than this (or if there is + * no version listed in the state file), we want to ignore the guards + * in the state file and pick new ones. */ +#define RECOMMENDED_GUARD_VERSION 1 + /** Return 0 if every setting in <b>state</b> is reasonable, and a * permissible transition from <b>old_state</b>. Else warn and return -1. * Should have no side effects, except for normalizing the contents of @@ -4346,27 +4356,17 @@ or_state_validate(or_state_t *old_state, or_state_t *state, * signature. */ (void) from_setconf; (void) old_state; - if (entry_guards_parse_state(state, 0, msg)<0) { + + if (state->GuardVersion < RECOMMENDED_GUARD_VERSION) { + config_free_lines(state->EntryGuards); + state->EntryGuards = NULL; + log_notice(LD_CONFIG, "Detected state file from old version '%s'. " + "Choosing new entry guards for you.", + state->TorVersion ? state->TorVersion : "unknown"); + state->GuardVersion = RECOMMENDED_GUARD_VERSION; + } else if (entry_guards_parse_state(state, 0, msg)<0) { return -1; } - if (state->TorVersion) { - tor_version_t v; - if (tor_version_parse(state->TorVersion, &v)) { - log_warn(LD_GENERAL, "Can't parse Tor version '%s' from your state " - "file. Proceeding anyway.", state->TorVersion); - } else { /* take action based on v */ - if ((tor_version_as_new_as(state->TorVersion, "0.1.1.10-alpha") && - !tor_version_as_new_as(state->TorVersion, "0.1.2.17-dev")) - || (tor_version_as_new_as(state->TorVersion, "0.2.0.0-alpha") && - !tor_version_as_new_as(state->TorVersion, "0.2.0.6-alpha-dev"))) { - log_notice(LD_CONFIG, "Detected state file from buggy version '%s'. " - "Enabling workaround to choose working entry guards.", - state->TorVersion); - config_free_lines(state->EntryGuards); - state->EntryGuards = NULL; - } - } - } return 0; } diff --git a/src/or/or.h b/src/or/or.h index c2f9952df..fc6726550 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2111,6 +2111,11 @@ typedef struct { /** A list of Entry Guard-related configuration lines. */ config_line_t *EntryGuards; + /** What algorithm did we use to select these guards? 0 if we didn't + * know about the GuardVersion concept when we picked them. We use + * this to expire and re-pick our guards if Tor knows about a newer + * version than the state file lists. */ + int GuardVersion; /** These fields hold information on the history of bandwidth usage for * servers. The "Ends" fields hold the time when we last updated the diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 66286a569..c439d48f1 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1262,7 +1262,18 @@ router_get_advertised_bandwidth(routerinfo_t *router) /** Do not weight any declared bandwidth more than this much when picking * routers by bandwidth. */ -#define MAX_BELIEVABLE_BANDWIDTH 10000000 /* 10 MB/sec */ +#define DEFAULT_MAX_BELIEVABLE_BANDWIDTH 10000000 /* 10 MB/sec */ + +/** Eventually, the number we return will come from the directory + * consensus, so clients can dynamically update to better numbers. + * + * But for now, or in case there is no consensus available, just return + * a sufficient default. */ +static uint32_t +get_max_believable_bandwidth(void) +{ + return DEFAULT_MAX_BELIEVABLE_BANDWIDTH; +} /** Helper function: * choose a random element of smartlist <b>sl</b>, weighted by @@ -1301,6 +1312,7 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, int for_exit, int for_guard, int n_unknown = 0; bitarray_t *exit_bits; bitarray_t *guard_bits; + uint32_t max_believable_bw = get_max_believable_bandwidth(); /* Can't choose exit and guard at same time */ tor_assert(!(for_exit && for_guard)); @@ -1344,7 +1356,7 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, int for_exit, int for_guard, if (is_guard) bitarray_set(guard_bits, i); /* if they claim something huge, don't believe it */ - if (this_bw > MAX_BELIEVABLE_BANDWIDTH) { + if (this_bw > max_believable_bw) { char fp[HEX_DIGEST_LEN+1]; if (status) { base16_encode(fp, sizeof(fp), @@ -1357,8 +1369,8 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, int for_exit, int for_guard, "Bandwidth %d for router %s (%s) exceeds allowed max %d, capping", this_bw, router ? router->nickname : "(null)", status || router ? fp : "0", - MAX_BELIEVABLE_BANDWIDTH); - this_bw = MAX_BELIEVABLE_BANDWIDTH; + max_believable_bw); + this_bw = max_believable_bw; } if (is_known) { bandwidths[i] = (int32_t) this_bw; // safe since MAX_BELIEVABLE<INT32_MAX |