Просмотр исходного кода

r15510@catbus: nickm | 2007-10-02 16:14:42 -0400
Add support for more vote URLs that weasel wanted. Weasel: please test this before I inflict it on anybody else. :)


svn:r11749

Nick Mathewson 17 лет назад
Родитель
Сommit
f4f780b526
5 измененных файлов с 102 добавлено и 30 удалено
  1. 4 0
      ChangeLog
  2. 9 0
      doc/spec/dir-spec.txt
  3. 15 4
      src/or/directory.c
  4. 70 24
      src/or/dirvote.c
  5. 4 2
      src/or/or.h

+ 4 - 0
ChangeLog

@@ -12,6 +12,10 @@ Changes in version 0.2.0.8-alpha - 2007-??-??
     - Use annotations to record the source for each descriptor.
     - Use annotations to record the source for each descriptor.
     - Use annotations to record the purpose of each descriptor.
     - Use annotations to record the purpose of each descriptor.
 
 
+  o Minor features (v3 authority system):
+    - Add more ways for tools to download the votes that lead to the current
+      consensus.
+
   o Major bugfixes (performance):
   o Major bugfixes (performance):
     - Fix really bad O(n^2) performance when parsing a long list of routers:
     - Fix really bad O(n^2) performance when parsing a long list of routers:
       Instead of searching the entire list for an "extra-info " string which
       Instead of searching the entire list for an "extra-info " string which

+ 9 - 0
doc/spec/dir-spec.txt

@@ -1152,6 +1152,9 @@ $Id$
    at
    at
       http://<hostname>/tor/status-vote/next/<fp>.z
       http://<hostname>/tor/status-vote/next/<fp>.z
    where <fp> is the fingerprint of the other authority's identity key.
    where <fp> is the fingerprint of the other authority's identity key.
+   And at
+      http://<hostname>/tor/status-vote/next/d/<d>.z
+   where <d> is the digest of the vote document.
 
 
    The consensus status, along with as many signatures as the server
    The consensus status, along with as many signatures as the server
    currently knows, should be available at
    currently knows, should be available at
@@ -1166,6 +1169,12 @@ $Id$
    and
    and
       http://<hostname>/tor/status-vote/current/consensus-signatures.z
       http://<hostname>/tor/status-vote/current/consensus-signatures.z
 
 
+   The other vote documents are analogously made available under
+     http://<hostname>/tor/status-vote/current/authority.z
+     http://<hostname>/tor/status-vote/current/<fp>.z
+     http://<hostname>/tor/status-vote/current/d/<d>.z
+   once the consensus is complete.
+
    Once an authority has computed and signed a consensus network status, it
    Once an authority has computed and signed a consensus network status, it
    should send its detached signature to each other authority in an HTTP POST
    should send its detached signature to each other authority in an HTTP POST
    request to the URL:
    request to the URL:

+ 15 - 4
src/or/directory.c

@@ -2124,16 +2124,27 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
       const char *item;
       const char *item;
       if ((item=dirvote_get_pending_detached_signatures()))
       if ((item=dirvote_get_pending_detached_signatures()))
         smartlist_add(items, (char*)item);
         smartlist_add(items, (char*)item);
-    } else if (!current && !strcmp(url, "authority")) {
+    } else if (!strcmp(url, "authority")) {
       const cached_dir_t *d;
       const cached_dir_t *d;
-      if ((d=dirvote_get_vote(NULL)))
+      if ((d=dirvote_get_vote(NULL, 1, current, !current)))
         smartlist_add(dir_items, (cached_dir_t*)d);
         smartlist_add(dir_items, (cached_dir_t*)d);
-    } else if (!current) {
+    } else {
       const cached_dir_t *d;
       const cached_dir_t *d;
       smartlist_t *fps = smartlist_create();
       smartlist_t *fps = smartlist_create();
+      int by_id, include_pending, include_previous;
+      if (!strcmpstart(url, "d/")) {
+        url += 2;
+        by_id = 0;
+        include_pending = include_previous = 1;
+      } else {
+        by_id = 1;
+        include_pending = current;
+        include_previous = !current;
+      }
       dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
       dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
       SMARTLIST_FOREACH(fps, char *, fp, {
       SMARTLIST_FOREACH(fps, char *, fp, {
-          if ((d = dirvote_get_vote(fp)))
+          if ((d = dirvote_get_vote(fp, by_id,
+                                    include_pending, include_previous)))
             smartlist_add(dir_items, (cached_dir_t*)d);
             smartlist_add(dir_items, (cached_dir_t*)d);
           tor_free(fp);
           tor_free(fp);
         });
         });

+ 70 - 24
src/or/dirvote.c

@@ -1133,8 +1133,7 @@ dirvote_recalculate_timing(time_t now)
   voting_schedule.fetch_missing_votes = start - dist_delay - (vote_delay/2);
   voting_schedule.fetch_missing_votes = start - dist_delay - (vote_delay/2);
   voting_schedule.voting_starts = start - dist_delay - vote_delay;
   voting_schedule.voting_starts = start - dist_delay - vote_delay;
 
 
-  voting_schedule.discard_old_votes = start +
+  voting_schedule.discard_old_votes = start;
-    ((end-start) - vote_delay - dist_delay)/2 ;
 }
 }
 
 
 /** Entry point: Take whatever voting actions are pending as of <b>now</b>. */
 /** Entry point: Take whatever voting actions are pending as of <b>now</b>. */
@@ -1185,7 +1184,7 @@ dirvote_act(time_t now)
   }
   }
   if (voting_schedule.discard_old_votes < now) {
   if (voting_schedule.discard_old_votes < now) {
     log_notice(LD_DIR, "Time to discard old votes.");
     log_notice(LD_DIR, "Time to discard old votes.");
-    dirvote_clear_pending_votes();
+    dirvote_clear_votes(0);
     dirvote_recalculate_timing(now);
     dirvote_recalculate_timing(now);
   }
   }
 }
 }
@@ -1198,8 +1197,12 @@ typedef struct pending_vote_t {
   networkstatus_vote_t *vote;
   networkstatus_vote_t *vote;
 } pending_vote_t;
 } pending_vote_t;
 
 
-/** List of pending_vote_t for the current vote. */
+/** List of pending_vote_t for the current vote.  Before we've used them to
+ * build a consensus, the votes go here. */
 static smartlist_t *pending_vote_list = NULL;
 static smartlist_t *pending_vote_list = NULL;
+/** List of pending_vote_t for the previous vote.  After we've used them to
+ * build a consensus, the votes go here for the next period. */
+static smartlist_t *previous_vote_list = NULL;
 /** The body of the consensus that we're currently building.  Once we
 /** The body of the consensus that we're currently building.  Once we
  * have it built, it goes into dirserv.c */
  * have it built, it goes into dirserv.c */
 static char *pending_consensus_body = NULL;
 static char *pending_consensus_body = NULL;
@@ -1251,7 +1254,7 @@ dirvote_fetch_missing_votes(void)
     {
     {
       if (!(ds->type & V3_AUTHORITY))
       if (!(ds->type & V3_AUTHORITY))
         continue;
         continue;
-      if (!dirvote_get_vote(ds->v3_identity_digest)) {
+      if (!dirvote_get_vote(ds->v3_identity_digest, 1, 1, 0)) {
         char *cp = tor_malloc(HEX_DIGEST_LEN+1);
         char *cp = tor_malloc(HEX_DIGEST_LEN+1);
         base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest,
         base16_encode(cp, HEX_DIGEST_LEN+1, ds->v3_identity_digest,
                       DIGEST_LEN);
                       DIGEST_LEN);
@@ -1288,17 +1291,36 @@ dirvote_fetch_missing_signatures(void)
 
 
 /** Drop all currently pending votes, consensus, and detached signatures. */
 /** Drop all currently pending votes, consensus, and detached signatures. */
 void
 void
-dirvote_clear_pending_votes(void)
+dirvote_clear_votes(int all_votes)
 {
 {
-  if (pending_vote_list) {
+  if (!previous_vote_list)
+    previous_vote_list = smartlist_create();
+  if (!pending_vote_list)
+    pending_vote_list = smartlist_create();
+
+  /* All "previous" votes are now junk. */
+  SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, v, {
+      cached_dir_decref(v->vote_body);
+      v->vote_body = NULL;
+      networkstatus_vote_free(v->vote);
+      tor_free(v);
+    });
+  smartlist_clear(previous_vote_list);
+
+  if (all_votes) {
+    /* If we're dumping all the votes, we delete the pending ones. */
     SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
     SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
         cached_dir_decref(v->vote_body);
         cached_dir_decref(v->vote_body);
         v->vote_body = NULL;
         v->vote_body = NULL;
         networkstatus_vote_free(v->vote);
         networkstatus_vote_free(v->vote);
         tor_free(v);
         tor_free(v);
       });
       });
-    smartlist_clear(pending_vote_list);
+  } else {
+    /* Otherwise, we move them into "previous". */
+    smartlist_add_all(previous_vote_list, pending_vote_list);
   }
   }
+  smartlist_clear(pending_vote_list);
+
   if (pending_consensus_signature_list) {
   if (pending_consensus_signature_list) {
     SMARTLIST_FOREACH(pending_consensus_signature_list, char *, cp,
     SMARTLIST_FOREACH(pending_consensus_signature_list, char *, cp,
                       tor_free(cp));
                       tor_free(cp));
@@ -1685,12 +1707,13 @@ dirvote_publish_consensus(void)
 void
 void
 dirvote_free_all(void)
 dirvote_free_all(void)
 {
 {
-  dirvote_clear_pending_votes();
+  dirvote_clear_votes(1);
-  if (pending_vote_list) {
+  /* now empty as a result of clear_pending_votes. */
-    /* now empty as a result of clear_pending_votes. */
+  smartlist_free(pending_vote_list);
-    smartlist_free(pending_vote_list);
+  pending_vote_list = NULL;
-    pending_vote_list = NULL;
+  smartlist_free(previous_vote_list);
-  }
+  previous_vote_list = NULL;
+
   tor_free(pending_consensus_body);
   tor_free(pending_consensus_body);
   tor_free(pending_consensus_signatures);
   tor_free(pending_consensus_signatures);
   if (pending_consensus) {
   if (pending_consensus) {
@@ -1725,22 +1748,45 @@ dirvote_get_pending_detached_signatures(void)
 
 
 /** Return the vote for the authority with the v3 authority identity key
 /** Return the vote for the authority with the v3 authority identity key
  * digest <b>id</b>.  If <b>id</b> is NULL, return our own vote. May return
  * digest <b>id</b>.  If <b>id</b> is NULL, return our own vote. May return
- * NULL if we have no vote for the authority in question. */
+ * NULL if we have no vote for the authority in question.
+ * DOCDOC args */
 const cached_dir_t *
 const cached_dir_t *
-dirvote_get_vote(const char *id)
+dirvote_get_vote(const char *fp, int by_id, int include_previous,
+                 int include_pending)
 {
 {
-  if (!pending_vote_list)
+  if (!pending_vote_list && !previous_vote_list)
     return NULL;
     return NULL;
-  if (id == NULL) {
+  if (fp == NULL) {
     authority_cert_t *c = get_my_v3_authority_cert();
     authority_cert_t *c = get_my_v3_authority_cert();
-    if (c)
+    if (c) {
-      id = c->cache_info.identity_digest;
+      fp = c->cache_info.identity_digest;
-    else
+      by_id = 1;
+    } else
       return NULL;
       return NULL;
   }
   }
-  SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
+  if (by_id) {
-       if (!memcmp(get_voter(pv->vote)->identity_digest, id, DIGEST_LEN))
+    if (pending_vote_list && include_pending) {
-         return pv->vote_body);
+      SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
+        if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
+          return pv->vote_body);
+    }
+    if (previous_vote_list && include_previous) {
+      SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
+        if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
+          return pv->vote_body);
+    }
+  } else {
+    if (pending_vote_list && include_pending) {
+      SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
+        if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
+          return pv->vote_body);
+    }
+    if (previous_vote_list && include_previous) {
+      SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
+        if (!memcmp(pv->vote->networkstatus_digest, fp, DIGEST_LEN))
+          return pv->vote_body);
+    }
+  }
   return NULL;
   return NULL;
 }
 }
 
 

+ 4 - 2
src/or/or.h

@@ -2887,7 +2887,7 @@ void dirvote_act(time_t now);
 
 
 /* invoked on timers and by outside triggers. */
 /* invoked on timers and by outside triggers. */
 void dirvote_perform_vote(void);
 void dirvote_perform_vote(void);
-void dirvote_clear_pending_votes(void);
+void dirvote_clear_votes(int all_votes);
 struct pending_vote_t * dirvote_add_vote(const char *vote_body,
 struct pending_vote_t * dirvote_add_vote(const char *vote_body,
                                          const char **msg_out,
                                          const char **msg_out,
                                          int *status_out);
                                          int *status_out);
@@ -2898,7 +2898,9 @@ int dirvote_publish_consensus(void);
 /* Item access */
 /* Item access */
 const char *dirvote_get_pending_consensus(void);
 const char *dirvote_get_pending_consensus(void);
 const char *dirvote_get_pending_detached_signatures(void);
 const char *dirvote_get_pending_detached_signatures(void);
-const cached_dir_t *dirvote_get_vote(const char *id);
+const cached_dir_t *dirvote_get_vote(const char *fp, int by_id,
+                                     int include_pending,
+                                     int include_previous);
 
 
 #ifdef DIRVOTE_PRIVATE
 #ifdef DIRVOTE_PRIVATE
 int networkstatus_check_voter_signature(networkstatus_vote_t *consensus,
 int networkstatus_check_voter_signature(networkstatus_vote_t *consensus,