From e73bbea26271dd6db75ca5c676f3c4ba8fc735e4 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 22 May 2012 09:48:10 -0400 Subject: [PATCH] Tweak consensus method 17 based on arma's comments Instead of capping whenever a router has fewer than 3 measurements, we cap whenever a router has fewer than 3 measurements *AND* there are at least 3 authorities publishing measured bandwidths. We also generate bandwidth lines with a new "Unmeasured=1" flag, meaning that we didn't have enough observations for a node to use measured bandwidth values in the authority's input, whether we capped it or not. --- changes/bug2286 | 5 +++++ src/or/dirvote.c | 23 +++++++++++++++++++---- src/or/or.h | 3 +++ src/or/routerparse.c | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 changes/bug2286 diff --git a/changes/bug2286 b/changes/bug2286 new file mode 100644 index 0000000000..4f8dfbbf68 --- /dev/null +++ b/changes/bug2286 @@ -0,0 +1,5 @@ + o Major features (directory authority): + - Directory authorities now support a new consensus method (17) + where they cap the published bandwidth of servers for which + insufficient bandwidth measurements exist. Fixes part of bug + 2286. diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 08a9eb4c02..d1ac8f8e94 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -1638,6 +1638,7 @@ networkstatus_compute_consensus(smartlist_t *votes, int *named_flag; /* Index of the flag "Named" for votes[j] */ int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */ int chosen_named_idx; + int n_authorities_measuring_bandwidth; strmap_t *name_to_id_map = strmap_new(); char conflict[DIGEST_LEN]; @@ -1726,6 +1727,14 @@ networkstatus_compute_consensus(smartlist_t *votes, } SMARTLIST_FOREACH_END(v); } + /* We need to know how many votes measure bandwidth. */ + n_authorities_measuring_bandwidth = 0; + SMARTLIST_FOREACH(votes, networkstatus_t *, v, + if (v->has_measured_bws) { + ++n_authorities_measuring_bandwidth; + } + ); + /* Now go through all the votes */ flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags)); while (1) { @@ -1889,14 +1898,17 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Pick a bandwidth */ if (consensus_method >= 6 && num_mbws > 2) { rs_out.has_bandwidth = 1; + rs_out.has_measured_bw = 1; rs_out.bandwidth = median_uint32(measured_bws, num_mbws); } 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) + if (consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW && + n_authorities_measuring_bandwidth > 2) { + /* Cap non-measured bandwidths. */ + if (rs_out.bandwidth > max_unmeasured_bw) { rs_out.bandwidth = max_unmeasured_bw; + } } } @@ -2039,7 +2051,10 @@ networkstatus_compute_consensus(smartlist_t *votes, smartlist_add(chunks, tor_strdup("\n")); /* Now the weight line. */ if (rs_out.has_bandwidth) { - smartlist_add_asprintf(chunks, "w Bandwidth=%d\n", rs_out.bandwidth); + int unmeasured = ! rs_out.has_measured_bw && + consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW; + smartlist_add_asprintf(chunks, "w Bandwidth=%d%s\n", rs_out.bandwidth, + unmeasured?" Unmeasured=1":""); } /* Now the exitpolicy summary line. */ diff --git a/src/or/or.h b/src/or/or.h index a0a921a9f4..d53d9ae6c8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2383,6 +2383,9 @@ typedef enum { typedef struct networkstatus_t { ENUM_BF(networkstatus_type_t) type : 8; /**< Vote, consensus, or opinion? */ ENUM_BF(consensus_flavor_t) flavor : 8; /**< If a consensus, what kind? */ + unsigned int has_measured_bws : 1;/**< True iff this networkstatus contains + * measured= bandwidth values. */ + time_t published; /**< Vote only: Time when vote was written. */ time_t valid_after; /**< Time after which this vote or consensus applies. */ time_t fresh_until; /**< Time before which this is the most recent vote or diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 2a3de12c35..c5a584c53f 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1985,6 +1985,7 @@ routerstatus_parse_entry_from_string(memarea_t *area, goto err; } rs->has_measured_bw = 1; + vote->has_measured_bws = 1; } } }