Loading doc/TODO +2 −2 Original line number Diff line number Diff line Loading @@ -100,8 +100,8 @@ Things we'd like to do in 0.2.0.x: o Don't reject Unnamed routers. . Implement consensus side o Generic "pick which voting method to use" code. - When version 2 is set, set the Unnamed flag right. - Mention that we support method 2. o When version 2 is set, set the Unnamed flag right. - Mention (and admit to ourself) that we support method 2. o Implement client side - Refactoring: Loading src/or/dirvote.c +87 −6 Original line number Diff line number Diff line Loading @@ -516,6 +516,13 @@ networkstatus_compute_consensus(smartlist_t *votes, * is the same flag as votes[j]->known_flags[b]. */ 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, chosen_unnamed_idx; strmap_t *name_to_id_map = strmap_new(); char conflict[DIGEST_LEN]; char unknown[DIGEST_LEN]; memset(conflict, 0, sizeof(conflict)); memset(unknown, 0xff, sizeof(conflict)); index = tor_malloc_zero(sizeof(int)*smartlist_len(votes)); size = tor_malloc_zero(sizeof(int)*smartlist_len(votes)); Loading @@ -526,6 +533,10 @@ networkstatus_compute_consensus(smartlist_t *votes, unnamed_flag = tor_malloc_zero(sizeof(int*) * smartlist_len(votes)); for (i = 0; i < smartlist_len(votes); ++i) unnamed_flag[i] = named_flag[i] = -1; chosen_named_idx = smartlist_string_pos(flags, "Named"); chosen_unnamed_idx = smartlist_string_pos(flags, "Unnamed"); /* Build the flag index. */ SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, { flag_map[v_sl_idx] = tor_malloc_zero( Loading @@ -538,13 +549,65 @@ networkstatus_compute_consensus(smartlist_t *votes, ++n_flag_voters[p]; if (!strcmp(fl, "Named")) named_flag[v_sl_idx] = fl_sl_idx; if (!strcmp(fl, "Named")) if (!strcmp(fl, "Unnamed")) unnamed_flag[v_sl_idx] = fl_sl_idx; }); n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags); size[v_sl_idx] = smartlist_len(v->routerstatus_list); }); /* Named and Unnamed get treated specially */ if (consensus_method >= 2) { SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, { uint64_t nf; if (named_flag[v_sl_idx]<0) continue; nf = U64_LITERAL(1) << named_flag[v_sl_idx]; SMARTLIST_FOREACH(v->routerstatus_list, vote_routerstatus_t *, rs, { if ((rs->flags & nf) != 0) { const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname); if (!d) { /* We have no name officially mapped to this digest. */ strmap_set_lc(name_to_id_map, rs->status.nickname, rs->status.identity_digest); } else if (d != conflict && memcmp(d, rs->status.identity_digest, DIGEST_LEN)) { /* Authorities disagree about this nickname. */ strmap_set_lc(name_to_id_map, rs->status.nickname, conflict); } else { /* It's already a conflict, or it's already this ID. */ } } }); }); SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, { uint64_t uf; if (unnamed_flag[v_sl_idx]<0) continue; uf = U64_LITERAL(1) << unnamed_flag[v_sl_idx]; SMARTLIST_FOREACH(v->routerstatus_list, vote_routerstatus_t *, rs, { if ((rs->flags & uf) != 0) { const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname); if (d == conflict || d == unknown) { /* Leave it alone; we know what it is. */ } else if (!d) { /* We have no name officially mapped to this digest. */ strmap_set_lc(name_to_id_map, rs->status.nickname, unknown); } else if (!memcmp(d, rs->status.identity_digest, DIGEST_LEN)) { /* Authorities disagree about this nickname. */ strmap_set_lc(name_to_id_map, rs->status.nickname, conflict); } else { /* It's mapped to a different name. */ } } }); }); } /* Now go through all the votes */ flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags)); while (1) { Loading @@ -553,6 +616,7 @@ networkstatus_compute_consensus(smartlist_t *votes, const char *lowest_id = NULL; const char *chosen_version; const char *chosen_name = NULL; int is_named = 0, is_unnamed = 0; int naming_conflict = 0; int n_listing = 0; int i; Loading Loading @@ -605,7 +669,6 @@ networkstatus_compute_consensus(smartlist_t *votes, } chosen_name = rs->status.nickname; } }); /* We don't include this router at all unless more than half of Loading @@ -632,16 +695,33 @@ 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; } else if (!memcmp(d, lowest_id, DIGEST_LEN)) { is_named = 1; is_unnamed = 0; } else { is_named = 0; is_unnamed = 1; } } /* Set the flags. */ smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */ SMARTLIST_FOREACH(flags, const char *, fl, { if (strcmp(fl, "Named")) { if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) if (!strcmp(fl, "Named")) { if (is_named) smartlist_add(chosen_flags, (char*)fl); } else if (!strcmp(fl, "Unnamed") && consensus_method >= 2) { if (is_unnamed) smartlist_add(chosen_flags, (char*)fl); } else { if (!naming_conflict && flag_counts[fl_sl_idx]) smartlist_add(chosen_flags, (char*)"Named"); if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) smartlist_add(chosen_flags, (char*)fl); } }); Loading Loading @@ -680,6 +760,7 @@ networkstatus_compute_consensus(smartlist_t *votes, tor_free(flag_counts); tor_free(named_flag); tor_free(unnamed_flag); strmap_free(name_to_id_map, NULL); smartlist_free(matching_descs); smartlist_free(chosen_flags); smartlist_free(versions); Loading Loading
doc/TODO +2 −2 Original line number Diff line number Diff line Loading @@ -100,8 +100,8 @@ Things we'd like to do in 0.2.0.x: o Don't reject Unnamed routers. . Implement consensus side o Generic "pick which voting method to use" code. - When version 2 is set, set the Unnamed flag right. - Mention that we support method 2. o When version 2 is set, set the Unnamed flag right. - Mention (and admit to ourself) that we support method 2. o Implement client side - Refactoring: Loading
src/or/dirvote.c +87 −6 Original line number Diff line number Diff line Loading @@ -516,6 +516,13 @@ networkstatus_compute_consensus(smartlist_t *votes, * is the same flag as votes[j]->known_flags[b]. */ 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, chosen_unnamed_idx; strmap_t *name_to_id_map = strmap_new(); char conflict[DIGEST_LEN]; char unknown[DIGEST_LEN]; memset(conflict, 0, sizeof(conflict)); memset(unknown, 0xff, sizeof(conflict)); index = tor_malloc_zero(sizeof(int)*smartlist_len(votes)); size = tor_malloc_zero(sizeof(int)*smartlist_len(votes)); Loading @@ -526,6 +533,10 @@ networkstatus_compute_consensus(smartlist_t *votes, unnamed_flag = tor_malloc_zero(sizeof(int*) * smartlist_len(votes)); for (i = 0; i < smartlist_len(votes); ++i) unnamed_flag[i] = named_flag[i] = -1; chosen_named_idx = smartlist_string_pos(flags, "Named"); chosen_unnamed_idx = smartlist_string_pos(flags, "Unnamed"); /* Build the flag index. */ SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, { flag_map[v_sl_idx] = tor_malloc_zero( Loading @@ -538,13 +549,65 @@ networkstatus_compute_consensus(smartlist_t *votes, ++n_flag_voters[p]; if (!strcmp(fl, "Named")) named_flag[v_sl_idx] = fl_sl_idx; if (!strcmp(fl, "Named")) if (!strcmp(fl, "Unnamed")) unnamed_flag[v_sl_idx] = fl_sl_idx; }); n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags); size[v_sl_idx] = smartlist_len(v->routerstatus_list); }); /* Named and Unnamed get treated specially */ if (consensus_method >= 2) { SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, { uint64_t nf; if (named_flag[v_sl_idx]<0) continue; nf = U64_LITERAL(1) << named_flag[v_sl_idx]; SMARTLIST_FOREACH(v->routerstatus_list, vote_routerstatus_t *, rs, { if ((rs->flags & nf) != 0) { const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname); if (!d) { /* We have no name officially mapped to this digest. */ strmap_set_lc(name_to_id_map, rs->status.nickname, rs->status.identity_digest); } else if (d != conflict && memcmp(d, rs->status.identity_digest, DIGEST_LEN)) { /* Authorities disagree about this nickname. */ strmap_set_lc(name_to_id_map, rs->status.nickname, conflict); } else { /* It's already a conflict, or it's already this ID. */ } } }); }); SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v, { uint64_t uf; if (unnamed_flag[v_sl_idx]<0) continue; uf = U64_LITERAL(1) << unnamed_flag[v_sl_idx]; SMARTLIST_FOREACH(v->routerstatus_list, vote_routerstatus_t *, rs, { if ((rs->flags & uf) != 0) { const char *d = strmap_get_lc(name_to_id_map, rs->status.nickname); if (d == conflict || d == unknown) { /* Leave it alone; we know what it is. */ } else if (!d) { /* We have no name officially mapped to this digest. */ strmap_set_lc(name_to_id_map, rs->status.nickname, unknown); } else if (!memcmp(d, rs->status.identity_digest, DIGEST_LEN)) { /* Authorities disagree about this nickname. */ strmap_set_lc(name_to_id_map, rs->status.nickname, conflict); } else { /* It's mapped to a different name. */ } } }); }); } /* Now go through all the votes */ flag_counts = tor_malloc(sizeof(int) * smartlist_len(flags)); while (1) { Loading @@ -553,6 +616,7 @@ networkstatus_compute_consensus(smartlist_t *votes, const char *lowest_id = NULL; const char *chosen_version; const char *chosen_name = NULL; int is_named = 0, is_unnamed = 0; int naming_conflict = 0; int n_listing = 0; int i; Loading Loading @@ -605,7 +669,6 @@ networkstatus_compute_consensus(smartlist_t *votes, } chosen_name = rs->status.nickname; } }); /* We don't include this router at all unless more than half of Loading @@ -632,16 +695,33 @@ 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; } else if (!memcmp(d, lowest_id, DIGEST_LEN)) { is_named = 1; is_unnamed = 0; } else { is_named = 0; is_unnamed = 1; } } /* Set the flags. */ smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */ SMARTLIST_FOREACH(flags, const char *, fl, { if (strcmp(fl, "Named")) { if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) if (!strcmp(fl, "Named")) { if (is_named) smartlist_add(chosen_flags, (char*)fl); } else if (!strcmp(fl, "Unnamed") && consensus_method >= 2) { if (is_unnamed) smartlist_add(chosen_flags, (char*)fl); } else { if (!naming_conflict && flag_counts[fl_sl_idx]) smartlist_add(chosen_flags, (char*)"Named"); if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2) smartlist_add(chosen_flags, (char*)fl); } }); Loading Loading @@ -680,6 +760,7 @@ networkstatus_compute_consensus(smartlist_t *votes, tor_free(flag_counts); tor_free(named_flag); tor_free(unnamed_flag); strmap_free(name_to_id_map, NULL); smartlist_free(matching_descs); smartlist_free(chosen_flags); smartlist_free(versions); Loading