Remove support for generating consensuses with methods <= 9.

The last patch disabled these; this one removes the code to implement
them.
This commit is contained in:
Nick Mathewson
2014-08-15 18:05:53 -04:00
parent df99ce2395
commit 908bd4cee3
2 changed files with 26 additions and 352 deletions
+26 -340
View File
@@ -455,8 +455,7 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
smartlist_free(alt_orports);
}
if (consensus_method >= MIN_METHOD_FOR_MICRODESC &&
microdesc_digest256_out) {
if (microdesc_digest256_out) {
smartlist_t *digests = smartlist_new();
const char *best_microdesc_digest;
SMARTLIST_FOREACH_BEGIN(votes, vote_routerstatus_t *, rs) {
@@ -1003,300 +1002,6 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G,
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
return 1;
}
/**
* This function computes the bandwidth weights for consensus method 9.
*
* It has been obsoleted in favor of consensus method 10.
*/
static void
networkstatus_compute_bw_weights_v9(smartlist_t *chunks, int64_t G, int64_t M,
int64_t E, int64_t D, int64_t T,
int64_t weight_scale)
{
int64_t Wgg = -1, Wgd = -1;
int64_t Wmg = -1, Wme = -1, Wmd = -1;
int64_t Wed = -1, Wee = -1;
const char *casename;
if (G <= 0 || M <= 0 || E <= 0 || D <= 0) {
log_warn(LD_DIR, "Consensus with empty bandwidth: "
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
" D="I64_FORMAT" T="I64_FORMAT,
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
return;
}
/*
* Computed from cases in 3.4.3 of dir-spec.txt
*
* 1. Neither are scarce
* 2. Both Guard and Exit are scarce
* a. R+D <= S
* b. R+D > S
* 3. One of Guard or Exit is scarce
* a. S+D < T/3
* b. S+D >= T/3
*/
if (3*E >= T && 3*G >= T) { // E >= T/3 && G >= T/3
bw_weights_error_t berr = 0;
/* Case 1: Neither are scarce.
*
* Attempt to ensure that we have a large amount of exit bandwidth
* in the middle position.
*/
casename = "Case 1 (Wme*E = Wmd*D)";
Wgg = (weight_scale*(D+E+G+M))/(3*G);
if (D==0) Wmd = 0;
else Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
Wgd = 0;
Wmg = weight_scale - Wgg;
Wed = weight_scale - Wmd;
berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
weight_scale, G, M, E, D, T, 10, 1);
if (berr) {
log_warn(LD_DIR, "Bw Weights error %d for case %s. "
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
" D="I64_FORMAT" T="I64_FORMAT,
berr, casename,
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
}
} else if (3*E < T && 3*G < T) { // E < T/3 && G < T/3
int64_t R = MIN(E, G);
int64_t S = MAX(E, G);
/*
* Case 2: Both Guards and Exits are scarce
* Balance D between E and G, depending upon
* D capacity and scarcity.
*/
if (R+D < S) { // Subcase a
Wgg = weight_scale;
Wee = weight_scale;
Wmg = 0;
Wme = 0;
Wmd = 0;
if (E < G) {
casename = "Case 2a (E scarce)";
Wed = weight_scale;
Wgd = 0;
} else { /* E >= G */
casename = "Case 2a (G scarce)";
Wed = 0;
Wgd = weight_scale;
}
} else { // Subcase b: R+D > S
bw_weights_error_t berr = 0;
casename = "Case 2b (Wme*E == Wmd*D)";
if (D != 0) {
Wgg = weight_scale;
Wgd = (weight_scale*(D + E - 2*G + M))/(3*D); // T/3 >= G (Ok)
Wmd = (weight_scale*(D + E + G - 2*M))/(6*D); // T/3 >= M
Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E); // 2E+M >= T/3
Wmg = 0;
Wed = weight_scale - Wgd - Wmd;
berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed,
weight_scale, G, M, E, D, T, 10, 1);
}
if (D == 0 || berr) { // Can happen if M > T/3
casename = "Case 2b (E=G)";
Wgg = weight_scale;
Wee = weight_scale;
Wmg = 0;
Wme = 0;
Wmd = 0;
if (D == 0) Wgd = 0;
else Wgd = (weight_scale*(D+E-G))/(2*D);
Wed = weight_scale - Wgd;
berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
Wed, weight_scale, G, M, E, D, T, 10, 1);
}
if (berr != BW_WEIGHTS_NO_ERROR &&
berr != BW_WEIGHTS_BALANCE_MID_ERROR) {
log_warn(LD_DIR, "Bw Weights error %d for case %s. "
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
" D="I64_FORMAT" T="I64_FORMAT,
berr, casename,
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
}
}
} else { // if (E < T/3 || G < T/3) {
int64_t S = MIN(E, G);
// Case 3: Exactly one of Guard or Exit is scarce
if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) {
log_warn(LD_BUG,
"Bw-Weights Case 3 but with G="I64_FORMAT" M="
I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
}
if (3*(S+D) < T) { // Subcase a: S+D < T/3
if (G < E) {
casename = "Case 3a (G scarce)";
Wgg = Wgd = weight_scale;
Wmd = Wed = Wmg = 0;
// Minor subcase, if E is more scarce than M,
// keep its bandwidth in place.
if (E < M) Wme = 0;
else Wme = (weight_scale*(E-M))/(2*E);
Wee = weight_scale-Wme;
} else { // G >= E
casename = "Case 3a (E scarce)";
Wee = Wed = weight_scale;
Wmd = Wgd = Wme = 0;
// Minor subcase, if G is more scarce than M,
// keep its bandwidth in place.
if (G < M) Wmg = 0;
else Wmg = (weight_scale*(G-M))/(2*G);
Wgg = weight_scale-Wmg;
}
} else { // Subcase b: S+D >= T/3
bw_weights_error_t berr = 0;
// D != 0 because S+D >= T/3
if (G < E) {
casename = "Case 3b (G scarce, Wme*E == Wmd*D)";
Wgd = (weight_scale*(D + E - 2*G + M))/(3*D);
Wmd = (weight_scale*(D + E + G - 2*M))/(6*D);
Wme = (weight_scale*(D + E + G - 2*M))/(6*E);
Wee = (weight_scale*(-D + 5*E - G + 2*M))/(6*E);
Wgg = weight_scale;
Wmg = 0;
Wed = weight_scale - Wgd - Wmd;
berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
Wed, weight_scale, G, M, E, D, T, 10, 1);
} else { // G >= E
casename = "Case 3b (E scarce, Wme*E == Wmd*D)";
Wgg = (weight_scale*(D + E + G + M))/(3*G);
Wmd = (weight_scale*(2*D + 2*E - G - M))/(6*D);
Wme = (weight_scale*(2*D + 2*E - G - M))/(6*E);
Wee = (weight_scale*(-2*D + 4*E + G + M))/(6*E);
Wgd = 0;
Wmg = weight_scale - Wgg;
Wed = weight_scale - Wmd;
berr = networkstatus_check_weights(Wgg, Wgd, Wmg, Wme, Wmd, Wee,
Wed, weight_scale, G, M, E, D, T, 10, 1);
}
if (berr) {
log_warn(LD_DIR, "Bw Weights error %d for case %s. "
"G="I64_FORMAT" M="I64_FORMAT
" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT,
berr, casename,
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
}
}
}
/* We cast down the weights to 32 bit ints on the assumption that
* weight_scale is ~= 10000. We need to ensure a rogue authority
* doesn't break this assumption to rig our weights */
tor_assert(0 < weight_scale && weight_scale <= INT32_MAX);
if (Wgg < 0 || Wgg > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wgg="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wgg),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wgg = MAX(MIN(Wgg, weight_scale), 0);
}
if (Wgd < 0 || Wgd > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wgd="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wgd),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wgd = MAX(MIN(Wgd, weight_scale), 0);
}
if (Wmg < 0 || Wmg > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wmg="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wmg),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wmg = MAX(MIN(Wmg, weight_scale), 0);
}
if (Wme < 0 || Wme > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wme="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wme),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wme = MAX(MIN(Wme, weight_scale), 0);
}
if (Wmd < 0 || Wmd > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wmd="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wmd),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wmd = MAX(MIN(Wmd, weight_scale), 0);
}
if (Wee < 0 || Wee > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wee="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wee),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wee = MAX(MIN(Wee, weight_scale), 0);
}
if (Wed < 0 || Wed > weight_scale) {
log_warn(LD_DIR, "Bw %s: Wed="I64_FORMAT"! G="I64_FORMAT
" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename, I64_PRINTF_ARG(Wed),
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
Wed = MAX(MIN(Wed, weight_scale), 0);
}
// Add consensus weight keywords
smartlist_add(chunks, tor_strdup("bandwidth-weights "));
/*
* Provide Wgm=Wgg, Wmm=1, Wem=Wee, Weg=Wed. May later determine
* that middle nodes need different bandwidth weights for dirport traffic,
* or that weird exit policies need special weight, or that bridges
* need special weight.
*
* NOTE: This list is sorted.
*/
smartlist_add_asprintf(chunks,
"Wbd=%d Wbe=%d Wbg=%d Wbm=%d "
"Wdb=%d "
"Web=%d Wed=%d Wee=%d Weg=%d Wem=%d "
"Wgb=%d Wgd=%d Wgg=%d Wgm=%d "
"Wmb=%d Wmd=%d Wme=%d Wmg=%d Wmm=%d\n",
(int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale,
(int)weight_scale,
(int)weight_scale, (int)Wed, (int)Wee, (int)Wed, (int)Wee,
(int)weight_scale, (int)Wgd, (int)Wgg, (int)Wgg,
(int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale);
log_notice(LD_CIRC, "Computed bandwidth weights for %s with v9: "
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
" T="I64_FORMAT,
casename,
I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E),
I64_PRINTF_ARG(D), I64_PRINTF_ARG(T));
}
/** Given a list of vote networkstatus_t in <b>votes</b>, our public
* authority <b>identity_key</b>, our private authority <b>signing_key</b>,
@@ -1439,10 +1144,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
flavor == FLAV_NS ? "" : " ",
flavor == FLAV_NS ? "" : flavor_name);
if (consensus_method >= 2) {
smartlist_add_asprintf(chunks, "consensus-method %d\n",
consensus_method);
}
smartlist_add_asprintf(chunks, "consensus-method %d\n",
consensus_method);
smartlist_add_asprintf(chunks,
"valid-after %s\n"
@@ -1459,14 +1162,12 @@ networkstatus_compute_consensus(smartlist_t *votes,
tor_free(flaglist);
}
if (consensus_method >= MIN_METHOD_FOR_PARAMS) {
params = dirvote_compute_params(votes, consensus_method,
total_authorities);
if (params) {
smartlist_add(chunks, tor_strdup("params "));
smartlist_add(chunks, params);
smartlist_add(chunks, tor_strdup("\n"));
}
params = dirvote_compute_params(votes, consensus_method,
total_authorities);
if (params) {
smartlist_add(chunks, tor_strdup("params "));
smartlist_add(chunks, params);
smartlist_add(chunks, tor_strdup("\n"));
}
/* Sort the votes. */
@@ -1480,8 +1181,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
e->digest = get_voter(v)->identity_digest;
e->is_legacy = 0;
smartlist_add(dir_sources, e);
if (consensus_method >= 3 &&
!tor_digest_is_zero(get_voter(v)->legacy_id_digest)) {
if (!tor_digest_is_zero(get_voter(v)->legacy_id_digest)) {
dir_src_ent_t *e_legacy = tor_malloc_zero(sizeof(dir_src_ent_t));
e_legacy->v = v;
e_legacy->digest = get_voter(v)->legacy_id_digest;
@@ -1497,9 +1197,6 @@ networkstatus_compute_consensus(smartlist_t *votes,
networkstatus_t *v = e->v;
networkstatus_voter_info_t *voter = get_voter(v);
if (e->is_legacy)
tor_assert(consensus_method >= 2);
base16_encode(fingerprint, sizeof(fingerprint), e->digest, DIGEST_LEN);
base16_encode(votedigest, sizeof(votedigest), voter->vote_digest,
DIGEST_LEN);
@@ -1620,7 +1317,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
} SMARTLIST_FOREACH_END(v);
/* Named and Unnamed get treated specially */
if (consensus_method >= 2) {
{
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
uint64_t nf;
if (named_flag[v_sl_idx]<0)
@@ -1789,10 +1486,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
}
if (consensus_method == 1) {
is_named = chosen_named_idx >= 0 &&
(!naming_conflict && flag_counts[chosen_named_idx]);
} else {
{
const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
if (!d) {
is_named = is_unnamed = 0;
@@ -1809,7 +1503,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (!strcmp(fl, "Named")) {
if (is_named)
smartlist_add(chosen_flags, (char*)fl);
} else if (!strcmp(fl, "Unnamed") && consensus_method >= 2) {
} else if (!strcmp(fl, "Unnamed")) {
if (is_unnamed)
smartlist_add(chosen_flags, (char*)fl);
} else {
@@ -1829,7 +1523,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
/* Starting with consensus method 4 we do not list servers
* that are not running in a consensus. See Proposal 138 */
if (consensus_method >= 4 && !is_running)
if (!is_running)
continue;
/* Pick the version. */
@@ -1841,11 +1535,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
/* Pick a bandwidth */
if (consensus_method >= 6 && num_mbws > 2) {
if (num_mbws > 2) {
rs_out.has_bandwidth = 1;
rs_out.bw_is_unmeasured = 0;
rs_out.bandwidth_kb = median_uint32(measured_bws_kb, num_mbws);
} else if (consensus_method >= 5 && num_bandwidths > 0) {
} else if (num_bandwidths > 0) {
rs_out.has_bandwidth = 1;
rs_out.bw_is_unmeasured = 1;
rs_out.bandwidth_kb = median_uint32(bandwidths_kb, num_bandwidths);
@@ -1863,7 +1557,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
is_exit = is_exit && !is_bad_exit;
}
if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
{
if (rs_out.has_bandwidth) {
T += rs_out.bandwidth_kb;
if (is_exit && is_guard)
@@ -1894,7 +1588,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
* the policy that was most often listed in votes, again breaking
* ties like in the previous case.
*/
if (consensus_method >= 5) {
{
/* Okay, go through all the votes for this router. We prepared
* that list previously */
const char *chosen_exitsummary = NULL;
@@ -2031,13 +1725,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
tor_free(measured_bws_kb);
}
if (consensus_method >= MIN_METHOD_FOR_FOOTER) {
/* Starting with consensus method 9, we clearly mark the directory
* footer region */
smartlist_add(chunks, tor_strdup("directory-footer\n"));
}
/* Mark the directory footer region */
smartlist_add(chunks, tor_strdup("directory-footer\n"));
if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS) {
{
int64_t weight_scale = BW_WEIGHT_SCALE;
char *bw_weight_param = NULL;
@@ -2070,13 +1761,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
}
if (consensus_method < 10) {
networkstatus_compute_bw_weights_v9(chunks, G, M, E, D, T, weight_scale);
added_weights = 1;
} else {
added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
T, weight_scale);
}
added_weights = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D,
T, weight_scale);
}
/* Add a signature. */
@@ -2117,7 +1803,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
smartlist_add(chunks, signature);
if (legacy_id_key_digest && legacy_signing_key && consensus_method >= 3) {
if (legacy_id_key_digest && legacy_signing_key) {
smartlist_add(chunks, tor_strdup("directory-signature "));
base16_encode(fingerprint, sizeof(fingerprint),
legacy_id_key_digest, DIGEST_LEN);
@@ -2153,7 +1839,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
goto done;
}
// Verify balancing parameters
if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS && added_weights) {
if (added_weights) {
networkstatus_verify_bw_weights(c, consensus_method);
}
networkstatus_vote_free(c);
@@ -3662,7 +3348,7 @@ static const struct consensus_method_range_t {
int low;
int high;
} microdesc_consensus_methods[] = {
{MIN_METHOD_FOR_MICRODESC, MIN_METHOD_FOR_A_LINES - 1},
{MIN_SUPPORTED_CONSENSUS_METHOD, MIN_METHOD_FOR_A_LINES - 1},
{MIN_METHOD_FOR_A_LINES, MIN_METHOD_FOR_P6_LINES - 1},
{MIN_METHOD_FOR_P6_LINES, MIN_METHOD_FOR_NTOR_KEY - 1},
{MIN_METHOD_FOR_NTOR_KEY, MIN_METHOD_FOR_ID_HASH_IN_MD - 1},
-12
View File
@@ -27,18 +27,6 @@
/** The highest consensus method that we currently support. */
#define MAX_SUPPORTED_CONSENSUS_METHOD 18
/** Lowest consensus method that contains a 'directory-footer' marker */
#define MIN_METHOD_FOR_FOOTER 9
/** Lowest consensus method that contains bandwidth weights */
#define MIN_METHOD_FOR_BW_WEIGHTS 9
/** Lowest consensus method that contains consensus params */
#define MIN_METHOD_FOR_PARAMS 7
/** Lowest consensus method that generates microdescriptors */
#define MIN_METHOD_FOR_MICRODESC 8
/** Lowest consensus method that doesn't count bad exits as exits for weight */
#define MIN_METHOD_TO_CUT_BADEXIT_WEIGHT 11