summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bug176685
-rw-r--r--src/or/dircollate.c4
-rw-r--r--src/or/dirvote.c28
-rw-r--r--src/or/or.h5
4 files changed, 40 insertions, 2 deletions
diff --git a/changes/bug17668 b/changes/bug17668
new file mode 100644
index 0000000000..fa5c1c8081
--- /dev/null
+++ b/changes/bug17668
@@ -0,0 +1,5 @@
+ o Major bugfixes (voting):
+ - When collating votes by Ed25519 identities, authorities now
+ include a "NoEdConsensus" flag if the ed25519 value (or lack thereof)
+ for a server does not reflect the majority consensus. Related to bug
+ 17668; bugfix on 0.2.7.2-alpha.
diff --git a/src/or/dircollate.c b/src/or/dircollate.c
index eeb0c24008..ca8b7ca847 100644
--- a/src/or/dircollate.c
+++ b/src/or/dircollate.c
@@ -81,6 +81,8 @@ dircollator_add_routerstatus(dircollator_t *dc,
{
const char *id = vrs->status.identity_digest;
+ vrs->ed25519_reflects_consensus = 0;
+
(void) vote;
vote_routerstatus_t **vrs_lst = digestmap_get(dc->by_rsa_sha1, id);
if (NULL == vrs_lst) {
@@ -92,7 +94,7 @@ dircollator_add_routerstatus(dircollator_t *dc,
const uint8_t *ed = vrs->ed25519_id;
- if (tor_mem_is_zero((char*)ed, DIGEST256_LEN))
+ if (! vrs->has_ed25519_listing)
return;
ddmap_entry_t search, *found;
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index be0635d92b..654d461dd6 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -1242,6 +1242,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
smartlist_free(combined_server_versions);
smartlist_free(combined_client_versions);
+ if (consensus_method >= MIN_METHOD_FOR_ED25519_ID_VOTING)
+ smartlist_add(flags, tor_strdup("NoEdConsensus"));
+
smartlist_sort_strings(flags);
smartlist_uniq_strings(flags);
@@ -1539,6 +1542,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
num_bandwidths = 0;
num_mbws = 0;
num_guardfraction_inputs = 0;
+ int ed_consensus = 0;
+ const uint8_t *ed_consensus_val = NULL;
/* Okay, go through all the entries for this digest. */
for (int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
@@ -1580,6 +1585,17 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (rs->status.has_bandwidth)
bandwidths_kb[num_bandwidths++] = rs->status.bandwidth_kb;
+
+ /* Count number for which ed25519 is canonical. */
+ if (rs->ed25519_reflects_consensus) {
+ ++ed_consensus;
+ if (ed_consensus_val) {
+ tor_assert(fast_memeq(ed_consensus_val, rs->ed25519_id,
+ ED25519_PUBKEY_LEN));
+ } else {
+ ed_consensus_val = rs->ed25519_id;
+ }
+ }
}
/* We don't include this router at all unless more than half of
@@ -1587,6 +1603,14 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (n_listing <= total_authorities/2)
continue;
+ if (ed_consensus > 0) {
+ tor_assert(consensus_method >= MIN_METHOD_FOR_ED25519_ID_VOTING);
+ if (ed_consensus <= total_authorities / 2) {
+ log_warn(LD_BUG, "Not enough entries had ed_consensus set; how "
+ "can we have a consensus of %d?", ed_consensus);
+ }
+ }
+
/* The clangalyzer can't figure out that this will never be NULL
* if n_listing is at least 1 */
tor_assert(current_rsa_id);
@@ -1640,6 +1664,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
} else if (!strcmp(fl, "Unnamed")) {
if (is_unnamed)
smartlist_add(chosen_flags, (char*)fl);
+ } else if (!strcmp(fl, "NoEdConsensus") &&
+ consensus_method >= MIN_METHOD_FOR_ED25519_ID_VOTING) {
+ if (ed_consensus <= total_authorities/2)
+ smartlist_add(chosen_flags, (char*)fl);
} else {
if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) {
smartlist_add(chosen_flags, (char*)fl);
diff --git a/src/or/or.h b/src/or/or.h
index b24b6a85e4..431927c7e7 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2380,7 +2380,10 @@ typedef struct vote_routerstatus_t {
/** True iff the vote included an entry for ed25519 ID, or included
* "id ed25519 none" to indicate that there was no ed25519 ID. */
unsigned int has_ed25519_listing:1;
- unsigned int ed25519_reflects_consensus:1; /** DOCDOC */
+ /** True if the Ed25519 listing here is the consensus-opinion for the
+ * Ed25519 listing; false if there was no consensus on Ed25519 key status,
+ * or if this VRS doesn't reflect it. */
+ unsigned int ed25519_reflects_consensus:1;
uint32_t measured_bw_kb; /**< Measured bandwidth (capacity) of the router */
/** The hash or hashes that the authority claims this microdesc has. */
vote_microdesc_hash_t *microdesc;