From 1cd67443383966687af3b2f9086ceeb7915017bf Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 16 May 2012 17:04:51 -0400 Subject: [PATCH] New consensus method: clip the maximum votable unmeasured bw If we're deciding on a node's bandwidth based on "Bandwidth=" declarations, clip it to "20" or to the maxunmeasuredbw parameter, if it's voted on. This adds a new consensus method. This is "part A" of bug 2286 --- src/or/dirvote.c | 31 +++++++++++++++++++++++++++++++ src/or/dirvote.h | 6 +++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 43b9f5eb12..08a9eb4c02 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -1388,6 +1388,8 @@ networkstatus_compute_consensus(smartlist_t *votes, char *client_versions = NULL, *server_versions = NULL; smartlist_t *flags; const char *flavor_name; +#define DEFAULT_MAX_UNMEASURED_BW 20 + uint32_t max_unmeasured_bw = DEFAULT_MAX_UNMEASURED_BW; int64_t G=0, M=0, E=0, D=0, T=0; /* For bandwidth weights */ const routerstatus_format_type_t rs_format = flavor == FLAV_NS ? NS_V3_CONSENSUS : NS_V3_CONSENSUS_MICRODESC; @@ -1586,6 +1588,30 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_free(dir_sources); } + if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW) { + char *max_unmeasured_param = NULL; + if (params) { + if (strcmpstart(params, "maxunmeasuredbw=") == 0) + max_unmeasured_param = params; + else + max_unmeasured_param = strstr(params, " maxunmeasuredbw="); + } + if (max_unmeasured_param) { + int ok = 0; + char *eq = strchr(max_unmeasured_param, '='); + if (eq) { + max_unmeasured_bw = (uint32_t) + tor_parse_ulong(eq+1, 10, 1, UINT32_MAX, &ok, NULL); + if (!ok) { + log_warn(LD_DIR, "Bad element '%s' in max unmeasured bw param", + escaped(max_unmeasured_param)); + max_unmeasured_bw = DEFAULT_MAX_UNMEASURED_BW; + } + } + } + } + + /* Add the actual router entries. */ { int *index; /* index[j] is the current index into votes[j]. */ @@ -1867,6 +1893,11 @@ networkstatus_compute_consensus(smartlist_t *votes, } else if (consensus_method >= 5 && num_bandwidths > 0) { rs_out.has_bandwidth = 1; rs_out.bandwidth = median_uint32(bandwidths, num_bandwidths); + if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW) { + /* Cap non-measured bandwidths to 20k. */ + if (rs_out.bandwidth > max_unmeasured_bw) + rs_out.bandwidth = max_unmeasured_bw; + } } /* Fix bug 2203: Do not count BadExit nodes as Exits for bw weights */ diff --git a/src/or/dirvote.h b/src/or/dirvote.h index f134454321..a7398743b0 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -20,7 +20,7 @@ #define MIN_VOTE_INTERVAL 300 /** The highest consensus method that we currently support. */ -#define MAX_SUPPORTED_CONSENSUS_METHOD 16 +#define MAX_SUPPORTED_CONSENSUS_METHOD 17 /** Lowest consensus method that contains a 'directory-footer' marker */ #define MIN_METHOD_FOR_FOOTER 9 @@ -52,6 +52,10 @@ * line */ #define MIN_METHOD_FOR_NTOR_KEY 16 +/** Lowest consensus method that ensures that authorities output an + * Unmeasured=1 flag for unmeasured bandwidths */ +#define MIN_METHOD_TO_CLIP_UNMEASURED_BW 17 + void dirvote_free_all(void); /* vote manipulation */