diff options
author | George Kadianakis <desnacked@riseup.net> | 2015-01-29 14:57:00 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-02-18 09:09:33 -0500 |
commit | f4a63f8eabbdd842ebeb97aabba92ea47c37a607 (patch) | |
tree | 4e2cc251b585f2c941e8b3dafc0283d6e840ab2a /src | |
parent | db805b91708c02e9b2b4d0c25ec17a45e81929aa (diff) | |
download | tor-f4a63f8eabbdd842ebeb97aabba92ea47c37a607.tar.gz tor-f4a63f8eabbdd842ebeb97aabba92ea47c37a607.zip |
Parse GuardFraction info from consensuses and votes.
Also introduce the UseGuardFraction torrc option which decides whether
clients should use guardfraction information found in the consensus.
Diffstat (limited to 'src')
-rw-r--r-- | src/or/config.c | 1 | ||||
-rw-r--r-- | src/or/entrynodes.c | 21 | ||||
-rw-r--r-- | src/or/entrynodes.h | 2 | ||||
-rw-r--r-- | src/or/or.h | 6 | ||||
-rw-r--r-- | src/or/routerparse.c | 65 | ||||
-rw-r--r-- | src/or/routerparse.h | 7 |
6 files changed, 102 insertions, 0 deletions
diff --git a/src/or/config.c b/src/or/config.c index 6349445bc1..230ea7fff8 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -411,6 +411,7 @@ static config_var_t option_vars_[] = { V(UseBridges, BOOL, "0"), V(UseEntryGuards, BOOL, "1"), V(UseEntryGuardsAsDirGuards, BOOL, "1"), + V(UseGuardFraction, AUTOBOOL, "auto"), V(UseMicrodescriptors, AUTOBOOL, "auto"), V(UseNTorHandshake, AUTOBOOL, "1"), V(User, STRING, NULL), diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 5b0e342662..a766f6cba3 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1694,6 +1694,27 @@ getinfo_helper_entry_guards(control_connection_t *conn, return 0; } +/** Return 0 if we should apply guardfraction information found in the + * consensus. A specific consensus can be specified with the + * <b>ns</b> argument, if NULL the most recent one will be picked.*/ +int +should_apply_guardfraction(const networkstatus_t *ns) +{ + /* We need to check the corresponding torrc option and the consensus + * parameter if we need to. */ + const or_options_t *options = get_options(); + + /* If UseGuardFraction is 'auto' then check the same-named consensus + * parameter. If the consensus parameter is not present, default to + * "off". */ + if (options->UseGuardFraction == -1) { + return networkstatus_get_param(ns, "UseGuardFraction", + 0, /* default to "off" */ + 0, 1); + } + + return options->UseGuardFraction; +} /** A list of configured bridges. Whenever we actually get a descriptor * for one, we add it as an entry guard. Note that the order of bridges * in this list does not necessarily correspond to the order of bridges diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index 7f3a4fb29c..96d832ea2a 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -160,5 +160,7 @@ int validate_pluggable_transports_config(void); double pathbias_get_close_success_count(entry_guard_t *guard); double pathbias_get_use_success_count(entry_guard_t *guard); +int should_apply_guardfraction(const networkstatus_t *ns); + #endif diff --git a/src/or/or.h b/src/or/or.h index 1f2231e78c..b8d4e1a3ef 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3818,6 +3818,12 @@ typedef struct { int NumEntryGuards; /**< How many entry guards do we try to establish? */ int UseEntryGuardsAsDirGuards; /** Boolean: Do we try to get directory info * from a smallish number of fixed nodes? */ + + /** If 1, we use any guardfraction information we see in the + * consensus. If 0, we don't. If -1, let the consensus parameter + * decide. */ + int UseGuardFraction; + int NumDirectoryGuards; /**< How many dir guards do we try to establish? * If 0, use value from NumEntryGuards. */ int RephistTrackTime; /**< How many seconds do we keep rephist info? */ diff --git a/src/or/routerparse.c b/src/or/routerparse.c index a2bc8fbb93..8a00544742 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -9,6 +9,8 @@ * \brief Code to parse and validate router descriptors and directories. **/ +#define ROUTERPARSE_PRIVATE + #include "or.h" #include "config.h" #include "circuitstats.h" @@ -23,6 +25,7 @@ #include "networkstatus.h" #include "rephist.h" #include "routerparse.h" +#include "entrynodes.h" #undef log #include <math.h> @@ -1792,6 +1795,63 @@ find_start_of_next_routerstatus(const char *s) return eos; } +/** Parse the GuardFraction string from a consensus or vote. + * + * If <b>vote</b> or <b>vote_rs</b> are set the document getting + * parsed is a vote routerstatus. Otherwise it's a consensus. This is + * the same semantic as in routerstatus_parse_entry_from_string(). */ +STATIC int +routerstatus_parse_guardfraction(const char *guardfraction_str, + networkstatus_t *vote, + vote_routerstatus_t *vote_rs, + routerstatus_t *rs) +{ + int ok; + const char *end_of_header = NULL; + int is_consensus = !vote_rs; + uint32_t guardfraction; + + tor_assert(bool_eq(vote, vote_rs)); + + /* If this info comes from a consensus, but we should't apply + guardfraction, just exit. */ + if (is_consensus && !should_apply_guardfraction(NULL)) { + return 0; + } + + end_of_header = strchr(guardfraction_str, '='); + if (!end_of_header) { + return -1; + } + + guardfraction = (uint32_t)tor_parse_ulong(end_of_header+1, + 10, 0, 100, &ok, NULL); + if (!ok) { + log_warn(LD_DIR, "Invalid GuardFraction %s", escaped(guardfraction_str)); + return -1; + } + + log_warn(LD_GENERAL, "[*] Parsed %s guardfraction '%s' for '%s'.", + is_consensus ? "consensus" : "vote", + guardfraction_str, rs->nickname); + + if (!is_consensus) { /* We are parsing a vote */ + vote_rs->status.guardfraction_percentage = guardfraction; + vote_rs->status.has_guardfraction = 1; + } else { + /* We are parsing a consensus. Only apply guardfraction to guards. */ + if (rs->is_possible_guard) { + rs->guardfraction_percentage = guardfraction; + rs->has_guardfraction = 1; + } else { + log_warn(LD_BUG, "Got GuardFraction for non-guard %s. " + "This is not supposed to happen. Not applying. ", rs->nickname); + } + } + + return 0; +} + /** Given a string at *<b>s</b>, containing a routerstatus object, and an * empty smartlist at <b>tokens</b>, parse and return the first router status * object in the string, and advance *<b>s</b> to just after the end of the @@ -1994,6 +2054,11 @@ routerstatus_parse_entry_from_string(memarea_t *area, vote->has_measured_bws = 1; } else if (!strcmpstart(tok->args[i], "Unmeasured=1")) { rs->bw_is_unmeasured = 1; + } else if (!strcmpstart(tok->args[i], "GuardFraction=")) { + if (routerstatus_parse_guardfraction(tok->args[i], + vote, vote_rs, rs) < 0) { + goto err; + } } } } diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 18a7d2563c..fc21cb1041 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -85,5 +85,12 @@ int rend_parse_introduction_points(rend_service_descriptor_t *parsed, size_t intro_points_encoded_size); int rend_parse_client_keys(strmap_t *parsed_clients, const char *str); +#ifdef ROUTERPARSE_PRIVATE +STATIC int routerstatus_parse_guardfraction(const char *guardfraction_str, + networkstatus_t *vote, + vote_routerstatus_t *vote_rs, + routerstatus_t *rs); +#endif + #endif |