[or-cvs] r10490: More code to generate a consensus from a list of votes. Now, (in tor/trunk: . src/or)

nickm at seul.org nickm at seul.org
Mon Jun 4 19:54:02 UTC 2007


Author: nickm
Date: 2007-06-04 15:54:02 -0400 (Mon, 04 Jun 2007)
New Revision: 10490

Modified:
   tor/trunk/
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
Log:
 r13248 at catbus:  nickm | 2007-06-04 15:53:23 -0400
 More code to generate a consensus from a list of votes.  Now, we handle Named, and we actually generate and sign the signed consensus.  Yippee.  Still needs testing.  Still not actually called.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r13248] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-06-04 19:19:01 UTC (rev 10489)
+++ tor/trunk/src/or/dirvote.c	2007-06-04 19:54:02 UTC (rev 10490)
@@ -161,6 +161,8 @@
     return r;
   if ((r = (b->status.published_on - a->status.published_on)))
     return r;
+  if ((r = strcmp(b->status.nickname, a->status.nickname)))
+    return r;
   if ((r = (((int)b->status.or_port) - ((int)a->status.or_port))))
     return r;
   if ((r = (((int)b->status.dir_port) - ((int)a->status.dir_port))))
@@ -212,13 +214,25 @@
   return most;
 }
 
+/** DOCDOC */
+static void
+hash_list_members(char *digest_out, smartlist_t *lst)
+{
+  crypto_digest_env_t *d = crypto_new_digest_env();
+  SMARTLIST_FOREACH(lst, const char *, cp,
+                    crypto_digest_add_bytes(d, cp, strlen(cp)));
+  crypto_digest_get_digest(d, digest_out, DIGEST_LEN);
+  crypto_free_digest_env(d);
+}
 
 /** DOCDOC */
 char *
-networkstatus_compute_consensus(smartlist_t *votes)
+networkstatus_compute_consensus(smartlist_t *votes,
+                                crypto_pk_env_t *identity_key,
+                                crypto_pk_env_t *signing_key)
 {
-  int n_rs=0;
   smartlist_t *chunks;
+  char *result = NULL;
 
   time_t valid_after, fresh_until, valid_until;
   int vote_seconds, dist_seconds;
@@ -249,7 +263,6 @@
     int j;
     SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
     {
-      n_rs += smartlist_len(v->routerstatus_list);
       smartlist_add(va_times, &v->valid_after);
       smartlist_add(fu_times, &v->fresh_until);
       smartlist_add(vu_times, &v->valid_until);
@@ -385,12 +398,16 @@
                          * about flags[f]. */
     int **flag_map; /* flag_map[j][b] is an index f such that flag_map[f]
                      * is the same flag as votes[j]->known_flags[b]. */
+    int *named_flag;
 
     index = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
     size = tor_malloc_zero(sizeof(int)*smartlist_len(votes));
     n_voter_flags = tor_malloc_zero(sizeof(int) * smartlist_len(votes));
     n_flag_voters = tor_malloc_zero(sizeof(int) * smartlist_len(flags));
     flag_map = tor_malloc_zero(sizeof(int*) * smartlist_len(votes));
+    named_flag = tor_malloc_zero(sizeof(int*) * smartlist_len(votes));
+    for (i = 0; i < smartlist_len(votes); ++i)
+      named_flag[i] = -1;
     SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
     {
       for (i = 0; v->known_flags[i]; ++i) {
@@ -398,6 +415,8 @@
         tor_assert(p >= 0);
         flag_map[v_sl_idx][i] = p;
         ++n_flag_voters[p];
+        if (!strcmp(v->known_flags[i], "Named"))
+          named_flag[v_sl_idx] = i;
         /* XXXX020 somebody needs to make sure that there are no duplicate
          * entries in anybody's flag list. */
       }
@@ -413,6 +432,8 @@
       routerstatus_t rs_out;
       const char *lowest_id = NULL;
       const char *chosen_version;
+      const char *chosen_name = NULL;
+      int naming_conflict = 0;
       int n_listing = 0;
       int i;
       char buf[256];
@@ -454,8 +475,13 @@
         for (i = 0; i < n_voter_flags[v_sl_idx]; ++i) {
           if (rs->flags & (U64_LITERAL(1) << i))
             ++flag_counts[flag_map[v_sl_idx][i]];
-          /* XXXX020 named is special. */
         }
+        if (rs->flags & (U64_LITERAL(1) << named_flag[v_sl_idx])) {
+          if (chosen_name && strcmp(chosen_name, rs->status.nickname))
+            naming_conflict = 1;
+          chosen_name = rs->status.nickname;
+        }
+
       });
 
       /* We don't include this router at all unless more than half of
@@ -475,17 +501,25 @@
       rs_out.dir_port = rs->status.dir_port;
       rs_out.or_port = rs->status.or_port;
 
+      if (chosen_name && !naming_conflict) {
+        strlcpy(rs_out.nickname, chosen_name, sizeof(rs_out.nickname));
+      } else {
+        strlcpy(rs_out.nickname, rs->status.nickname, sizeof(rs_out.nickname));
+      }
+
       /* Set the flags. */
       smartlist_add(chosen_flags, (char*)"s"); /* for the start of the line. */
       SMARTLIST_FOREACH(flags, const char *, fl,
       {
-        if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2)
-          smartlist_add(chosen_flags, (char*)fl);
-        /* XXXX020 named is special. */
+        if (strcmp(fl, "Named")) {
+          if (flag_counts[fl_sl_idx] > n_flag_voters[fl_sl_idx]/2)
+            smartlist_add(chosen_flags, (char*)fl);
+        } else {
+          if (!naming_conflict && flag_counts[fl_sl_idx])
+            smartlist_add(chosen_flags, (char*)"Named");
+        }
       });
 
-      /* XXXX020 set the nickname! */
-
       /* Pick the version. */
       if (smartlist_len(versions)) {
         sort_version_list(versions, 0);
@@ -503,7 +537,7 @@
                     smartlist_join_strings(chosen_flags, " ", 0, NULL));
       /*     Now the version line. */
       if (chosen_version) {
-        /* XXXX020 fails on very big version. */
+        /* XXXX020 fails on very long version string */
         tor_snprintf(buf, sizeof(buf), "\nv %s\n", chosen_version);
         smartlist_add(chunks, tor_strdup(buf));
       } else {
@@ -526,14 +560,36 @@
     smartlist_free(versions);
   }
 
-  /* Concatenate everything. */
-
   /* Add a signature. */
+  {
+    char digest[DIGEST_LEN];
+    char fingerprint[HEX_DIGEST_LEN+1];
+    char hex_digest[HEX_DIGEST_LEN+1];
+    char buf[4096];
+    smartlist_add(chunks, tor_strdup("directory-signature "));
 
-  /* Free everything. */
+    /* Compute the hash of the chunks. */
+    hash_list_members(digest, chunks);
 
+    /* Get hex stuff as needed. */
+    base16_encode(hex_digest, sizeof(hex_digest), digest, DIGEST_LEN);
+    crypto_pk_get_fingerprint(identity_key, fingerprint, 0);
+
+    /* add the junk that will go at the end of the line. */
+    tor_snprintf(buf, sizeof(buf), "%s %s\n", hex_digest, fingerprint);
+    /* And the signature. */
+    /* XXXX020 check return */
+    router_append_dirobj_signature(buf, sizeof(buf), digest, signing_key);
+    smartlist_add(chunks, tor_strdup(buf));
+  }
+
+  result = smartlist_join_strings(chunks, "", 0, NULL);
+
   tor_free(client_versions);
   tor_free(server_versions);
+  smartlist_free(flags);
+  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+  smartlist_free(chunks);
 
-  return NULL;
+  return result;
 }

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-06-04 19:19:01 UTC (rev 10489)
+++ tor/trunk/src/or/or.h	2007-06-04 19:54:02 UTC (rev 10490)
@@ -2715,7 +2715,9 @@
 /********************************* dirvote.c ************************/
 
 void networkstatus_vote_free(networkstatus_vote_t *ns);
-char *networkstatus_compute_consensus(smartlist_t *votes);
+char *networkstatus_compute_consensus(smartlist_t *votes,
+                                      crypto_pk_env_t *identity_key,
+                                      crypto_pk_env_t *signing_key);
 
 /********************************* dns.c ***************************/
 



More information about the tor-commits mailing list