From 194bd56c8a4d6bdb49f6896712bae422887975e2 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 8 Feb 2013 11:52:51 -0500 Subject: Refactor generating the m lines in a vote into its own function --- src/or/dirserv.c | 34 ++-------------------------------- src/or/dirvote.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/or/dirvote.h | 5 +++++ 3 files changed, 48 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 620984288..294beb5cf 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..baaff488d 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -3651,6 +3651,47 @@ 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} +}; + +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; + vote_microdesc_hash_t *result = NULL; + + for (cmr = microdesc_consensus_methods; + cmr->low != -1 && cmr->high != -1; + cmr++) { + microdesc_t *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 = result; + result = h; + md->last_listed = now; + smartlist_add(microdescriptors_out, md); + } + } + + return result; +} + /** If vrs has a hash made for the consensus method method with * the digest algorithm alg, decode it and copy it into * digest256_out 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, -- cgit v1.2.3 From 2403ef66bada5f1fb851ce424af4ab5916faca67 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 8 Feb 2013 12:09:46 -0500 Subject: Coalesce identical adjacent microdescriptor vote lines. --- changes/bug8158 | 3 +++ src/or/dirvote.c | 55 +++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 changes/bug8158 (limited to 'src') diff --git a/changes/bug8158 b/changes/bug8158 new file mode 100644 index 000000000..65b21c2a2 --- /dev/null +++ b/changes/bug8158 @@ -0,0 +1,3 @@ + o Minor bugfixes: + - Use less space when formatting identical microdescriptor lines in + directory votes. Fixes bug 8158; bugfix on 0.2.4.1-alpha. diff --git a/src/or/dirvote.c b/src/or/dirvote.c index baaff488d..c10a60fa7 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -3664,31 +3664,66 @@ static const struct consensus_method_range_t { {-1, -1} }; +typedef struct microdesc_vote_line_t { + int low; + int high; + microdesc_t *md; + struct microdesc_vote_line_t *next; +} microdesc_vote_line_t; + 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) { - 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 = result; - result = h; - md->last_listed = now; - smartlist_add(microdescriptors_out, 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; } -- cgit v1.2.3 From c8f5f35d6237de0ecd5ddac0a9a4c84915cbe177 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 8 Feb 2013 12:12:09 -0500 Subject: Add doxygen for bug8158 functions --- src/or/dirvote.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/or/dirvote.c b/src/or/dirvote.c index c10a60fa7..66dc50deb 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -3664,6 +3664,8 @@ static const struct consensus_method_range_t { {-1, -1} }; +/** Helper type used when generating the microdescriptor lines in a directory + * vote. */ typedef struct microdesc_vote_line_t { int low; int high; @@ -3671,6 +3673,9 @@ typedef struct microdesc_vote_line_t { 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 microdescriptors_out. */ vote_microdesc_hash_t * dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now, smartlist_t *microdescriptors_out) -- cgit v1.2.3