mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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.
This commit is contained in:
committed by
Nick Mathewson
parent
db805b9170
commit
f4a63f8eab
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user