[tor-commits] [tor/master] Generate microdescriptors with "a" lines.

nickm at torproject.org nickm at torproject.org
Tue Sep 4 22:24:07 UTC 2012


commit 68901da5a1dcfb210f7e8210af0b63c6161f9b63
Author: Linus Nordberg <linus at torproject.org>
Date:   Fri Aug 31 23:02:19 2012 +0200

    Generate microdescriptors with "a" lines.
    
    Generate and store all supported microdescriptor formats. Generate
    votes with one "m" line for each format. Only "m" lines with version
    info matching chosen consensus method will be voted upon.
    
    An optimisation would be to combine "m" lines with identical hashes,
    i.e. instead of "m 1,2,3 H1" and "m 4,5 H1", say "m 1,2,3,4,5 H1".
---
 src/or/dirserv.c |   37 +++++++++++++++++++++--------
 src/or/dirvote.c |   69 ++++++++++++++++++++---------------------------------
 src/or/dirvote.h |   33 +++++++++++++++++++++++--
 3 files changed, 83 insertions(+), 56 deletions(-)

diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 5814171..44e5291 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -62,6 +62,16 @@ 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, 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);
@@ -2685,7 +2695,8 @@ dirserv_read_measured_bandwidths(const char *from_file,
 }
 
 /** Return a new networkstatus_t* containing our current opinion. (For v3
- * authorities) */
+ * authorities)
+ */
 networkstatus_t *
 dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
                                         authority_cert_t *cert)
@@ -2757,6 +2768,7 @@ 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;
@@ -2778,15 +2790,20 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
         rs->is_flagged_running = 0;
 
       vrs->version = version_from_platform(ri->platform);
-      md = dirvote_create_microdescriptor(ri);
-      if (md) {
-        char buf[128];
-        vote_microdesc_hash_t *h;
-        dirvote_format_microdesc_vote_line(buf, sizeof(buf), md);
-        h = tor_malloc(sizeof(vote_microdesc_hash_t));
-        h->microdesc_hash_line = tor_strdup(buf);
-        h->next = NULL;
-        vrs->microdesc = h;
+      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(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);
       }
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 9056cf5..e6601cf 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -53,32 +53,6 @@ static int dirvote_compute_consensuses(void);
 static int dirvote_publish_consensus(void);
 static char *make_consensus_method_list(int low, int high, const char *sep);
 
-/** The highest consensus method that we currently support. */
-#define MAX_SUPPORTED_CONSENSUS_METHOD 14
-
-/** 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 ensures a majority of authorities voted
-  * for a param. */
-#define MIN_METHOD_FOR_MAJORITY_PARAMS 12
-
-/** Lowest consensus method where microdesc consensuses omit any entry
- * with no microdesc. */
-#define MIN_METHOD_FOR_MANDATORY_MICRODESC 13
-
-/** Lowest consensus method that contains "a" lines. */
-#define MIN_METHOD_FOR_A_LINES 14
-
 /* =====
  * Voting
  * =====*/
@@ -3570,7 +3544,7 @@ dirvote_get_vote(const char *fp, int flags)
  * particular method.
  **/
 microdesc_t *
-dirvote_create_microdescriptor(const routerinfo_t *ri)
+dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
 {
   microdesc_t *result = NULL;
   char *key = NULL, *summary = NULL, *family = NULL;
@@ -3586,6 +3560,12 @@ dirvote_create_microdescriptor(const routerinfo_t *ri)
 
   smartlist_add_asprintf(chunks, "onion-key\n%s", key);
 
+  if (consensus_method >= MIN_METHOD_FOR_A_LINES &&
+      !tor_addr_is_null(&ri->ipv6_addr) && ri->ipv6_orport)
+    smartlist_add_asprintf(chunks, "a %s:%d\n",
+                           fmt_and_decorate_addr(&ri->ipv6_addr),
+                           ri->ipv6_orport);
+
   if (family)
     smartlist_add_asprintf(chunks, "family %s\n", family);
 
@@ -3619,33 +3599,36 @@ dirvote_create_microdescriptor(const routerinfo_t *ri)
   return result;
 }
 
-/** Cached space-separated string to hold */
-static char *microdesc_consensus_methods = NULL;
-
 /** Format the appropriate vote line to describe the microdescriptor <b>md</b>
  * in a consensus vote document.  Write it into the <b>out_len</b>-byte buffer
  * in <b>out</b>.  Return -1 on failure and the number of characters written
  * on success. */
 ssize_t
-dirvote_format_microdesc_vote_line(char *out, size_t out_len,
-                                   const microdesc_t *md)
+dirvote_format_microdesc_vote_line(char *out_buf, size_t out_buf_len,
+                                   const microdesc_t *md,
+                                   int consensus_method_low,
+                                   int consensus_method_high)
 {
+  int ret = -1;
   char d64[BASE64_DIGEST256_LEN+1];
-  if (!microdesc_consensus_methods) {
-    microdesc_consensus_methods =
-      make_consensus_method_list(MIN_METHOD_FOR_MICRODESC,
-                                 MAX_SUPPORTED_CONSENSUS_METHOD,
-                                 ",");
-    tor_assert(microdesc_consensus_methods);
-  }
+  char *microdesc_consensus_methods =
+    make_consensus_method_list(consensus_method_low,
+                               consensus_method_high,
+                               ",");
+  tor_assert(microdesc_consensus_methods);
+
   if (digest256_to_base64(d64, md->digest)<0)
-    return -1;
+    goto out;
 
-  if (tor_snprintf(out, out_len, "m %s sha256=%s\n",
+  if (tor_snprintf(out_buf, out_buf_len, "m %s sha256=%s\n",
                    microdesc_consensus_methods, d64)<0)
-    return -1;
+    goto out;
 
-  return strlen(out);
+  ret = strlen(out_buf);
+
+ out:
+  tor_free(microdesc_consensus_methods);
+  return ret;
 }
 
 /** If <b>vrs</b> has a hash made for the consensus method <b>method</b> with
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
index e6f9700..b3feeff 100644
--- a/src/or/dirvote.h
+++ b/src/or/dirvote.h
@@ -19,6 +19,32 @@
 /** Smallest allowable voting interval. */
 #define MIN_VOTE_INTERVAL 300
 
+/** The highest consensus method that we currently support. */
+#define MAX_SUPPORTED_CONSENSUS_METHOD 14
+
+/** 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 ensures a majority of authorities voted
+  * for a param. */
+#define MIN_METHOD_FOR_MAJORITY_PARAMS 12
+
+/** Lowest consensus method where microdesc consensuses omit any entry
+ * with no microdesc. */
+#define MIN_METHOD_FOR_MANDATORY_MICRODESC 13
+
+/** Lowest consensus method that contains "a" lines. */
+#define MIN_METHOD_FOR_A_LINES 14
+
 void dirvote_free_all(void);
 
 /* vote manipulation */
@@ -70,10 +96,11 @@ networkstatus_t *
 dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
                                         authority_cert_t *cert);
 
-microdesc_t *dirvote_create_microdescriptor(const routerinfo_t *ri);
+microdesc_t *dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method);
 ssize_t dirvote_format_microdesc_vote_line(char *out, size_t out_len,
-                                       const microdesc_t *md);
-
+                                           const microdesc_t *md,
+                                           int consensus_method_low,
+                                           int consensus_method_high);
 int vote_routerstatus_find_microdesc_hash(char *digest256_out,
                                           const vote_routerstatus_t *vrs,
                                           int method,





More information about the tor-commits mailing list