aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-02-11 13:32:38 -0500
committerNick Mathewson <nickm@torproject.org>2013-02-11 13:32:38 -0500
commit01184f164f027aa4e34a9f6b90c01120040f63cb (patch)
treeb8a7924c8be4ed8d6e57d1ab8d282748d4f025a2 /src
parent36e2eb6775a2f52d34423f1319a0be1472506649 (diff)
parentc8f5f35d6237de0ecd5ddac0a9a4c84915cbe177 (diff)
downloadtor-01184f164f027aa4e34a9f6b90c01120040f63cb.tar
tor-01184f164f027aa4e34a9f6b90c01120040f63cb.tar.gz
Merge remote-tracking branch 'public/bug8158'
Diffstat (limited to 'src')
-rw-r--r--src/or/dirserv.c34
-rw-r--r--src/or/dirvote.c81
-rw-r--r--src/or/dirvote.h5
3 files changed, 88 insertions, 32 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index a8f7d4659..0819d4bd2 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -66,19 +66,6 @@ static cached_dir_t *the_directory = NULL;
/** For authoritative directories: the current (v1) network status. */
static cached_dir_t the_runningrouters;
-/** Array of start and end of consensus methods used for supported
- microdescriptor formats. */
-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_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, MAX_SUPPORTED_CONSENSUS_METHOD},
- {-1, -1}
-};
-
static void directory_remove_invalid(void);
static cached_dir_t *dirserv_regenerate_directory(void);
static char *format_versions_list(config_line_t *ln);
@@ -2811,11 +2798,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
microdescriptors = smartlist_new();
SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
- const struct consensus_method_range_t *cmr = NULL;
if (ri->cache_info.published_on >= cutoff) {
routerstatus_t *rs;
vote_routerstatus_t *vrs;
- microdesc_t *md;
node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
if (!node)
continue;
@@ -2833,23 +2818,8 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
rs->is_flagged_running = 0;
vrs->version = version_from_platform(ri->platform);
- for (cmr = microdesc_consensus_methods;
- cmr->low != -1 && cmr->high != -1;
- cmr++) {
- md = dirvote_create_microdescriptor(ri, cmr->low);
- if (md) {
- char buf[128];
- vote_microdesc_hash_t *h;
- dirvote_format_microdesc_vote_line(buf, sizeof(buf), md,
- cmr->low, cmr->high);
- h = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
- h->microdesc_hash_line = tor_strdup(buf);
- h->next = vrs->microdesc;
- vrs->microdesc = h;
- md->last_listed = now;
- smartlist_add(microdescriptors, md);
- }
- }
+ vrs->microdesc = dirvote_format_all_microdesc_vote_lines(ri, now,
+ microdescriptors);
smartlist_add(routerstatuses, vrs);
}
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 469c86c7c..66dc50deb 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -3651,6 +3651,87 @@ dirvote_format_microdesc_vote_line(char *out_buf, size_t out_buf_len,
return ret;
}
+/** Array of start and end of consensus methods used for supported
+ microdescriptor formats. */
+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_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, MAX_SUPPORTED_CONSENSUS_METHOD},
+ {-1, -1}
+};
+
+/** Helper type used when generating the microdescriptor lines in a directory
+ * vote. */
+typedef struct microdesc_vote_line_t {
+ int low;
+ int high;
+ microdesc_t *md;
+ struct microdesc_vote_line_t *next;
+} microdesc_vote_line_t;
+
+/** Generate and return a linked list of all the lines that should appear to
+ * describe a router's microdescriptor versions in a directory vote.
+ * Add the generated microdescriptors to <b>microdescriptors_out</b>. */
+vote_microdesc_hash_t *
+dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now,
+ smartlist_t *microdescriptors_out)
+{
+ const struct consensus_method_range_t *cmr;
+ microdesc_vote_line_t *entries = NULL, *ep;
+ vote_microdesc_hash_t *result = NULL;
+
+ /* Generate the microdescriptors. */
+ for (cmr = microdesc_consensus_methods;
+ cmr->low != -1 && cmr->high != -1;
+ cmr++) {
+ microdesc_t *md = dirvote_create_microdescriptor(ri, cmr->low);
+ if (md) {
+ microdesc_vote_line_t *e =
+ tor_malloc_zero(sizeof(microdesc_vote_line_t));
+ e->md = md;
+ e->low = cmr->low;
+ e->high = cmr->high;
+ e->next = entries;
+ entries = e;
+ }
+ }
+
+ /* Compress adjacent identical ones */
+ for (ep = entries; ep; ep = ep->next) {
+ while (ep->next &&
+ fast_memeq(ep->md->digest, ep->next->md->digest, DIGEST256_LEN) &&
+ ep->low == ep->next->high + 1) {
+ microdesc_vote_line_t *next = ep->next;
+ ep->low = next->low;
+ microdesc_free(next->md);
+ ep->next = next->next;
+ tor_free(next);
+ }
+ }
+
+ /* Format them into vote_microdesc_hash_t, and add to microdescriptors_out.*/
+ while ((ep = entries)) {
+ char buf[128];
+ vote_microdesc_hash_t *h;
+ dirvote_format_microdesc_vote_line(buf, sizeof(buf), ep->md,
+ ep->low, ep->high);
+ h = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
+ h->microdesc_hash_line = tor_strdup(buf);
+ h->next = result;
+ result = h;
+ ep->md->last_listed = now;
+ smartlist_add(microdescriptors_out, ep->md);
+ entries = ep->next;
+ tor_free(ep);
+ }
+
+ return result;
+}
+
/** If <b>vrs</b> has a hash made for the consensus method <b>method</b> with
* the digest algorithm <b>alg</b>, decode it and copy it into
* <b>digest256_out</b> and return 0. Otherwise return -1. */
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
index f13445432..366b7cf03 100644
--- a/src/or/dirvote.h
+++ b/src/or/dirvote.h
@@ -109,6 +109,11 @@ ssize_t dirvote_format_microdesc_vote_line(char *out, size_t out_len,
const microdesc_t *md,
int consensus_method_low,
int consensus_method_high);
+vote_microdesc_hash_t *dirvote_format_all_microdesc_vote_lines(
+ const routerinfo_t *ri,
+ time_t now,
+ smartlist_t *microdescriptors_out);
+
int vote_routerstatus_find_microdesc_hash(char *digest256_out,
const vote_routerstatus_t *vrs,
int method,