[or-cvs] r11430: When we get a consensus for which we are missing the right c (in tor/trunk: . doc src/or)

nickm at seul.org nickm at seul.org
Tue Sep 11 20:17:29 UTC 2007


Author: nickm
Date: 2007-09-11 16:17:28 -0400 (Tue, 11 Sep 2007)
New Revision: 11430

Modified:
   tor/trunk/
   tor/trunk/doc/TODO
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
Log:
 r15049 at catbus:  nickm | 2007-09-11 16:05:50 -0400
 When we get a consensus for which we are missing the right certificates, keep it around pending more certificates; do not just drop it.



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

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-09-11 20:17:25 UTC (rev 11429)
+++ tor/trunk/doc/TODO	2007-09-11 20:17:28 UTC (rev 11430)
@@ -53,12 +53,12 @@
           o Download as needed.
             o Code to download
             . Code to retry download.
-        . Code to generate consensus from a list of votes
-          * Detect whether votes are really all for the same period.
+        o Code to generate consensus from a list of votes
+          o Detect whether votes are really all for the same period.
         . Push/pull documents as appropriate.
           - Pull votes and signatures if we don't get them.
         - Cache votes and signatures on disk.
-          - Code to keep consensus docs in limbo if they don't have
+          o Code to keep consensus docs in limbo if they don't have
             have enough signatures.
         o Have clients know which authorities are v3 authorities, and what
           their keys are.

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-09-11 20:17:25 UTC (rev 11429)
+++ tor/trunk/src/or/dirvote.c	2007-09-11 20:17:28 UTC (rev 11430)
@@ -735,7 +735,7 @@
 /** Given a v3 networkstatus consensus in <b>consensus</b>, check every
  * as-yet-unchecked signature on <b>consensus.  Return 0 if there are enough
  * good signatures from recognized authorities on it, and -1 otherwise.
- * DOCDOC warn. */
+ * DOCDOC warn. DOCDOC -2 rerturn. */
 int
 networkstatus_check_consensus_signature(networkstatus_vote_t *consensus,
                                         int warn)
@@ -832,8 +832,10 @@
 
   if (n_good >= n_required)
     return 0;
+  else if (n_good + n_missing_key >= n_required)
+    return -1;
   else
-    return -1;
+    return -2;
 }
 
 /** Given a consensus vote <b>target</b> and a list of
@@ -1681,7 +1683,7 @@
     return -1;
   }
 
-  if (networkstatus_set_current_consensus(pending_consensus_body, 0))
+  if (networkstatus_set_current_consensus(pending_consensus_body, 0, 0))
     log_warn(LD_DIR, "Error publishing consensus");
   else
     log_warn(LD_DIR, "Consensus published.");

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-09-11 20:17:25 UTC (rev 11429)
+++ tor/trunk/src/or/or.h	2007-09-11 20:17:28 UTC (rev 11430)
@@ -3550,7 +3550,8 @@
 int router_reload_consensus_networkstatus(void);
 networkstatus_vote_t *networkstatus_get_latest_consensus(void);
 networkstatus_vote_t *networkstatus_get_live_consensus(time_t now);
-int networkstatus_set_current_consensus(const char *consensus, int from_cache);
+int networkstatus_set_current_consensus(const char *consensus, int from_cache,
+                                        int was_waiting_for_certs);
 
 //routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest);
 int should_delay_dir_fetches(or_options_t *options);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-09-11 20:17:25 UTC (rev 11429)
+++ tor/trunk/src/or/routerlist.c	2007-09-11 20:17:28 UTC (rev 11430)
@@ -65,9 +65,14 @@
  * about.  This list is kept sorted by published_on. */
 static smartlist_t *networkstatus_list = NULL;
 
-/** Most recently received v3 consensus network status. */
+/** Most recently received and validated v3 consensus network status. */
 static networkstatus_vote_t *current_consensus = NULL;
 
+/** A v3 consensus networkstatus that we've received, but which we don't
+ * have enough certificates to be happy about. */
+static networkstatus_vote_t *consensus_waiting_for_certs = NULL;
+static char *consensus_waiting_for_certs_body = NULL;
+
 /** Global list of local_routerstatus_t for each router, known or unknown.
  * Kept sorted by digest. */
 static smartlist_t *routerstatus_list = NULL;
@@ -184,14 +189,26 @@
   tor_snprintf(filename,sizeof(filename),"%s"PATH_SEPARATOR"cached-consensus",
                get_options()->DataDirectory);
   s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
-  if (!s)
-    return 0;
+  if (s) {
+    if (networkstatus_set_current_consensus(s, 1, 0)) {
+      log_warn(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
+               filename);
+    }
+    tor_free(s);
+  }
 
-  if (networkstatus_set_current_consensus(s, 1)) {
-    log_warn(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
-             filename);
+  tor_snprintf(filename,sizeof(filename),
+               "%s"PATH_SEPARATOR"unverified-consensus",
+               get_options()->DataDirectory);
+  s = read_file_to_str(filename, RFTS_IGNORE_MISSING, NULL);
+  if (s) {
+    if (networkstatus_set_current_consensus(s, 1, 1)) {
+      log_warn(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
+               filename);
+    }
+    tor_free(s);
   }
-  tor_free(s);
+
   return 0;
 }
 
@@ -266,6 +283,16 @@
 
   trusted_dirs_flush_certs_to_disk();
 
+  if (consensus_waiting_for_certs) {
+    if (!networkstatus_check_consensus_signature(
+                                    consensus_waiting_for_certs, 0)) {
+      if (!networkstatus_set_current_consensus(
+                                 consensus_waiting_for_certs_body, 0, 1)) {
+        tor_free(consensus_waiting_for_certs_body);
+      }
+    }
+  }
+
   return 0;
 }
 
@@ -2501,6 +2528,15 @@
   if (named_server_map) {
     strmap_free(named_server_map, _tor_free);
   }
+  if (current_consensus) {
+    networkstatus_vote_free(current_consensus);
+    current_consensus = NULL;
+  }
+  if (consensus_waiting_for_certs) {
+    networkstatus_vote_free(current_consensus);
+    current_consensus = NULL;
+  }
+  tor_free(consensus_waiting_for_certs_body);
 }
 
 /** Free all storage held by the routerstatus object <b>rs</b>. */
@@ -4027,9 +4063,11 @@
 
 /** DOCDOC */
 int
-networkstatus_set_current_consensus(const char *consensus, int from_cache)
+networkstatus_set_current_consensus(const char *consensus, int from_cache,
+                                    int was_waiting_for_certs)
 {
   networkstatus_vote_t *c;
+  int r;
   /* Make sure it's parseable. */
   c = networkstatus_parse_vote_from_string(consensus, 0);
   if (!c) {
@@ -4038,15 +4076,50 @@
   }
 
   /* Make sure it's signed enough. */
-  if (networkstatus_check_consensus_signature(c, 1)<0) {
-    log_warn(LD_DIR, "Not enough good signatures on networkstatus consensus");
-    networkstatus_vote_free(c);
-    return -1;
+  if ((r=networkstatus_check_consensus_signature(c, 1))<0) {
+    if (r == -1 && !was_waiting_for_certs) {
+      /* Okay, so it _might_ be signed enough if we get more certificates. */
+      if (!was_waiting_for_certs)
+        log_notice(LD_DIR, "Not enough certificates to check networkstatus "
+                   "consensus");
+      if (!current_consensus ||
+          c->valid_after > current_consensus->valid_after) {
+        if (consensus_waiting_for_certs)
+          networkstatus_vote_free(consensus_waiting_for_certs);
+        tor_free(consensus_waiting_for_certs_body);
+        consensus_waiting_for_certs = c;
+        consensus_waiting_for_certs_body = tor_strdup(consensus);
+        if (!from_cache) {
+          or_options_t *options = get_options();
+          char filename[512];
+          tor_snprintf(filename, sizeof(filename),
+                       "%s"PATH_SEPARATOR"unverified-consensus",
+                       options->DataDirectory);
+          write_str_to_file(filename, consensus, 0);
+        }
+        /* XXXX020 trigger the certificate download. */
+      }
+      return -1;
+    } else {
+      if (!was_waiting_for_certs)
+        log_warn(LD_DIR, "Not enough good signatures on networkstatus "
+                 "consensus");
+      networkstatus_vote_free(c);
+      return -1;
+    }
   }
 
   if (current_consensus)
     networkstatus_vote_free(current_consensus);
 
+  if (consensus_waiting_for_certs &&
+      consensus_waiting_for_certs->valid_after <= c->valid_after) {
+    networkstatus_vote_free(consensus_waiting_for_certs);
+    consensus_waiting_for_certs = NULL;
+    if (consensus != consensus_waiting_for_certs_body)
+      tor_free(consensus_waiting_for_certs_body);
+  }
+
   current_consensus = c;
 
   if (!from_cache) {



More information about the tor-commits mailing list