[or-cvs] r11841: Retry consensus and certificate downloads properly. Do not f (in tor/trunk: . doc src/or)

nickm at seul.org nickm at seul.org
Wed Oct 10 19:33:23 UTC 2007


Author: nickm
Date: 2007-10-10 15:33:19 -0400 (Wed, 10 Oct 2007)
New Revision: 11841

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/networkstatus.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
Log:
 r15636 at catbus:  nickm | 2007-10-10 15:28:12 -0400
 Retry consensus and certificate downloads properly.  Do not fail when there are no certificates to download.  Do not download certificates we already have when retrying.



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

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-10-10 19:33:14 UTC (rev 11840)
+++ tor/trunk/ChangeLog	2007-10-10 19:33:19 UTC (rev 11841)
@@ -13,6 +13,8 @@
     - Caches now download v3 network status documents as needed.
     - Caches now download descriptors listed in their v3 network status
       documents.
+    - All hosts now attempt to download and keep fresh v3 authority
+      certificates, and re-attempt after failures.
 
   o Minor features (router descriptor cache):
     - Store routers in a file called cached-descriptors instead of in

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-10-10 19:33:14 UTC (rev 11840)
+++ tor/trunk/doc/TODO	2007-10-10 19:33:19 UTC (rev 11841)
@@ -85,8 +85,12 @@
         them
         o Download code
         o Code to schedule downloads
-        - Code to retry failed downloads
-        - Code to delay next download while fetching certificates
+        o Code to retry failed downloads
+        - Code to delay next download while fetching certificates to verify
+          a consensus we already got.
+        - Code to retry consensus download if we got one we already have.
+        - Use if-modified-since on consensus download
+        - Use if-modified-since on certificate download
         o Code to download routers listed in v3 networkstatus consensuses.
         - Enable for non-caches
       - Code to use v3 networkstatus documents once clients are

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2007-10-10 19:33:14 UTC (rev 11840)
+++ tor/trunk/src/or/directory.c	2007-10-10 19:33:19 UTC (rev 11841)
@@ -1411,7 +1411,7 @@
            status_code, escaped(reason), conn->_base.address,
            conn->_base.port);
       tor_free(body); tor_free(headers); tor_free(reason);
-      /* XXXX020NMNM retry. */
+      networkstatus_consensus_download_failed(status_code);
       return -1;
     }
     log_info(LD_DIR,"Received consensus directory (size %d) from server "

Modified: tor/trunk/src/or/networkstatus.c
===================================================================
--- tor/trunk/src/or/networkstatus.c	2007-10-10 19:33:14 UTC (rev 11840)
+++ tor/trunk/src/or/networkstatus.c	2007-10-10 19:33:19 UTC (rev 11841)
@@ -45,12 +45,10 @@
  * mirrors).  Clients don't use this now. */
 static time_t last_networkstatus_download_attempted = 0;
 
-/** The last time we tried to download a networkstatus, or 0 for "never".  We
- * use this to rate-limit download attempts for directory caches (including
- * mirrors).  Clients don't use this now. */
-static time_t last_consensus_networkstatus_download_attempted = 0;
 /**DOCDOC*/
 static time_t time_to_download_next_consensus = 0;
+/**DOCDOC*/
+static download_status_t consensus_dl_status = { 0, 0};
 
 /** List of strings for nicknames or fingerprints we've already warned about
  * and that are still conflicted. */ /*XXXX020 obsoleted by v3 dirs? */
@@ -644,7 +642,7 @@
  * network-statuses.
  */
 static void
-update_networkstatus_cache_downloads(time_t now)
+update_v2_networkstatus_cache_downloads(time_t now)
 {
   int authority = authdir_mode_v2(get_options());
   int interval =
@@ -706,7 +704,7 @@
  * necessary".  See function comments for implementation details.
  */
 static void
-update_networkstatus_client_downloads(time_t now)
+update_v2_networkstatus_client_downloads(time_t now)
 {
   int n_live = 0, n_dirservers, n_running_dirservers, needed = 0;
   int fetch_latest = 0;
@@ -836,18 +834,24 @@
     return;
   if (authdir_mode_v3(options))
     return;
+  if (!download_status_is_ready(&consensus_dl_status, now, 8))
+    return; /*XXXX020 magic number 8.*/
   if (connection_get_by_type_purpose(CONN_TYPE_DIR,
                                      DIR_PURPOSE_FETCH_CONSENSUS))
     return;
-  /* XXXX020 on failure, delay until next retry. */
 
-  last_consensus_networkstatus_download_attempted = now;/*XXXX020 use this*/
   directory_get_from_dirserver(DIR_PURPOSE_FETCH_CONSENSUS,
                                ROUTER_PURPOSE_GENERAL, NULL, 1);
-  // XXXX020 time_to_download_next_consensus = put it off for a while?
 }
 
 /** DOCDOC */
+void
+networkstatus_consensus_download_failed(int status_code)
+{
+  download_status_failed(&consensus_dl_status, status_code);
+}
+
+/** DOCDOC */
 static void
 update_consensus_networkstatus_fetch_time(time_t now)
 {
@@ -888,7 +892,8 @@
   return 0;
 }
 
-/** Launch requests for networkstatus documents as appropriate. */
+/** Launch requests for networkstatus documents and authority certificates as
+ * appropriate. */
 void
 update_networkstatus_downloads(time_t now)
 {
@@ -896,10 +901,14 @@
   if (should_delay_dir_fetches(options))
     return;
   if (dirserver_mode(options))
-    update_networkstatus_cache_downloads(now);
+    update_v2_networkstatus_cache_downloads(now);
   else
-    update_networkstatus_client_downloads(now);
+    update_v2_networkstatus_client_downloads(now);
   update_consensus_networkstatus_downloads(now);
+  if (consensus_waiting_for_certs)
+    authority_certs_fetch_missing(consensus_waiting_for_certs, now);
+  else
+    authority_certs_fetch_missing(current_consensus, now);
 }
 
 /** Return the network status with a given identity digest. */
@@ -978,7 +987,7 @@
                        options->DataDirectory);
           write_str_to_file(filename, consensus, 0);
         }
-        authority_certs_fetch_missing(c);
+        authority_certs_fetch_missing(c, now);
       }
       return 0;
     } else {
@@ -992,7 +1001,7 @@
 
   /* Are we missing any certificates at all? */
   if (r != 1)
-    authority_certs_fetch_missing(c);
+    authority_certs_fetch_missing(c, now);
 
   if (current_consensus)
     networkstatus_vote_free(current_consensus);

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-10-10 19:33:14 UTC (rev 11840)
+++ tor/trunk/src/or/or.h	2007-10-10 19:33:19 UTC (rev 11841)
@@ -3043,10 +3043,11 @@
 
 /********************************* networkstatus.c *********************/
 
-/** How old do we allow a network-status to get before removing it
+/** How old do we allow a v2 network-status to get before removing it
  * completely? */
 #define MAX_NETWORKSTATUS_AGE (10*24*60*60)
 
+void networkstatus_consensus_download_failed(int status_code);
 void networkstatus_reset_warnings(void);
 int router_reload_networkstatus(void);
 /* for consensuses. */
@@ -3511,7 +3512,7 @@
 authority_cert_t *authority_cert_get_by_sk_digest(const char *sk_digest);
 authority_cert_t *authority_cert_get_by_digests(const char *id_digest,
                                                 const char *sk_digest);
-void authority_certs_fetch_missing(networkstatus_vote_t *status);
+void authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now);
 void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
 void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
                                     int must_be_running);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-10-10 19:33:14 UTC (rev 11840)
+++ tor/trunk/src/or/routerlist.c	2007-10-10 19:33:19 UTC (rev 11841)
@@ -97,6 +97,7 @@
   if (!contents)
     return 0;
   r = trusted_dirs_load_certs_from_string(contents, 1);
+  log_notice(LD_DIR, "Loaded %d certs from cache.", r);
   tor_free(contents);
   return r;
 }
@@ -279,6 +280,9 @@
   return NULL;
 }
 
+/** How many times will we try to fetch a certificate before giving up? */
+#define MAX_CERT_DL_FAILURES 8
+
 /** Try to download any v3 authority certificates that we may be missing.  If
  * <b>status</b> is provided, try to get all the ones that were used to sign
  * <b>status</b>.  Additionally, try to have a non-expired certificate for
@@ -286,12 +290,11 @@
  * already have.
  **/
 void
-authority_certs_fetch_missing(networkstatus_vote_t *status)
+authority_certs_fetch_missing(networkstatus_vote_t *status, time_t now)
 {
   digestmap_t *pending = digestmap_new();
   smartlist_t *missing_digests = smartlist_create();
-  char *resource;
-  time_t now = time(NULL);
+  char *resource = NULL;
 
   list_pending_downloads(pending, DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
   if (status) {
@@ -299,9 +302,15 @@
       {
         trusted_dir_server_t *ds
           = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
-        if (ds &&
-            !authority_cert_get_by_digests(voter->identity_digest,
-                                           voter->signing_key_digest))
+        if (!ds)
+          continue;
+        if (authority_cert_get_by_digests(voter->identity_digest,
+                                          voter->signing_key_digest)) {
+          download_status_reset(&ds->cert_dl_status);
+          continue;
+        }
+        if (download_status_is_ready(&ds->cert_dl_status, now,
+                                     MAX_CERT_DL_FAILURES))
           smartlist_add(missing_digests, voter->identity_digest);
       });
   }
@@ -312,18 +321,26 @@
         continue;
       if (smartlist_digest_isin(missing_digests, ds->v3_identity_digest))
         continue;
+      if (!ds->v3_certs)
+        ds->v3_certs = smartlist_create();
       SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
         {
-          if (ftime_definitely_before(cert->expires, now)) {
-            /* It's definitely expired. */
+          if (!ftime_definitely_after(now, cert->expires)) {
+            /* It's not expired, and we weren't looking for something to
+             * verify a consensus with.  Call it done. */
+            download_status_reset(&ds->cert_dl_status);
             found = 1;
             break;
           }
         });
-      smartlist_add(missing_digests, ds->v3_identity_digest);
+      if (!found && download_status_is_ready(&ds->cert_dl_status, now,
+                                             MAX_CERT_DL_FAILURES))
+        smartlist_add(missing_digests, ds->v3_identity_digest);
     });
 
-  {
+  if (!smartlist_len(missing_digests)) {
+    goto done;
+  } else {
     smartlist_t *fps = smartlist_create();
     smartlist_add(fps, tor_strdup("fp/"));
     SMARTLIST_FOREACH(missing_digests, const char *, d, {
@@ -341,12 +358,14 @@
     SMARTLIST_FOREACH(fps, char *, cp, tor_free(cp));
     smartlist_free(fps);
   }
-  log_notice(LD_DIR, "Launching request for %d missing certificates.",
-             smartlist_len(missing_digests)); /*XXXX020 downgrade to INFO*/
-  smartlist_free(missing_digests);
+  log_notice(LD_DIR, "Launching request for %d missing certificates",
+             smartlist_len(missing_digests));
   directory_get_from_dirserver(DIR_PURPOSE_FETCH_CERTIFICATE, 0,
                                resource, 1);
+
+ done:
   tor_free(resource);
+  smartlist_free(missing_digests);
   digestmap_free(pending, NULL);
 }
 



More information about the tor-commits mailing list