[or-cvs] r12408: First attempt at fixing bug 543. Needs testing. Too slow. (in tor/trunk: . src/or)

nickm at seul.org nickm at seul.org
Wed Nov 7 15:19:54 UTC 2007


Author: nickm
Date: 2007-11-07 10:19:53 -0500 (Wed, 07 Nov 2007)
New Revision: 12408

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/src/or/routerlist.c
Log:
 r16518 at catbus:  nickm | 2007-11-07 10:18:31 -0500
 First attempt at fixing bug 543.  Needs testing. Too slow.



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

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-11-07 08:56:58 UTC (rev 12407)
+++ tor/trunk/ChangeLog	2007-11-07 15:19:53 UTC (rev 12408)
@@ -19,6 +19,9 @@
       by Fabian Keil.
     - When the clock jumps forward a lot, do not allow the bandwidth
       buckets to become negative.  Bugfix on 0.1.2.x; fixes Bug 544.
+    - When the consensus lists a router descriptor that we previously were
+      mirroring, but that we considered non-canonical, reload the
+      descriptor as canonical.
 
   o Major bugfixes (v3 dir, bugfixes on 0.2.0.9-alpha):
     - Consider replacing the current consensus when certificates arrive

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-11-07 08:56:58 UTC (rev 12407)
+++ tor/trunk/src/or/routerlist.c	2007-11-07 15:19:53 UTC (rev 12408)
@@ -2464,6 +2464,39 @@
 #endif
 }
 
+/** DOCDOC */
+static routerinfo_t *
+routerlist_reparse_old(routerlist_t * rl, signed_descriptor_t *sd)
+{
+  routerinfo_t *ri;
+  const char *body;
+
+  body = signed_descriptor_get_body(sd);
+
+  ri = router_parse_entry_from_string(body, body+sd->signed_descriptor_len,
+                                      0, 0, NULL);
+  if (!ri)
+    return NULL;
+  memcpy(&ri->cache_info, sd, sizeof(signed_descriptor_t));
+  if (sd->signed_descriptor_body) {
+    /* Nasty, but we can't have it get freed. Do better. XXXX020 */
+    ri->cache_info->signed_descriptor_body =
+      tor_strndup(sd->signed_descriptor_body, sd->signed_descriptor_len);
+  }
+
+  /* Awful and inefficient.  Store the index in signed_descriptor_t, or do a
+   * single big linear scan of old_routers, or _something_. XXXX020 */
+  {
+    SMARTLIST_FOREACH(rl->old_routers, signed_descriptor_t *, s,
+                      if (s == sd) {
+                        routerlist_remove_old(rl, s, s_sl_idx);
+                        break;
+                      });
+  }
+
+  return ri;
+}
+
 /** Free all memory held by the routerlist module. */
 void
 routerlist_free_all(void)
@@ -2656,9 +2689,9 @@
   old_router = rimap_get(routerlist->identity_map,
                          router->cache_info.identity_digest);
   if (old_router) {
-    if (router->cache_info.published_on <=
-        old_router->cache_info.published_on) {
-      /* Same key, but old */
+    if (!in_consensus && (router->cache_info.published_on <=
+                          old_router->cache_info.published_on)) {
+      /* Same key, but old.  This one is not listed in the consensus. */
       log_debug(LD_DIR, "Skipping not-new descriptor for router '%s'",
                 router->nickname);
       /* Only journal this desc if we'll be serving it. */
@@ -2669,7 +2702,7 @@
       *msg = "Router descriptor was not new.";
       return -1;
     } else {
-      /* Same key, new. */
+      /* Same key, and either new, or listed in the consensus. */
       log_debug(LD_DIR, "Replacing entry for router '%s/%s' [%s]",
                 router->nickname, old_router->nickname,
                 hex_str(id_digest,DIGEST_LEN));
@@ -3704,6 +3737,7 @@
 {
   or_options_t *options = get_options();
   digestmap_t *map = NULL;
+  smartlist_t *no_longer_old = smartlist_create();
   smartlist_t *downloadable = smartlist_create();
   int authdir = authdir_mode(options);
   int dirserver = dirserver_mode(options);
@@ -3714,10 +3748,10 @@
 
   if (!dirserver) {
     if (rep_hist_circbuilding_dormant(now))
-      return;
+      goto done;
   }
   if (!consensus)
-    return;
+    goto done;
 
   map = digestmap_new();
   list_pending_descriptor_downloads(map, 0);
@@ -3730,7 +3764,8 @@
         if (!(ri = router_get_by_digest(rs->identity_digest)) ||
             memcmp(ri->cache_info.signed_descriptor_digest,
                    sd->signed_descriptor_digest, DIGEST_LEN)) {
-          ++n_in_oldrouters;
+          smartlist_add(no_longer_old, sd);
+          ++n_in_oldrouters; /* We have it in old_routers. */
         }
         continue; /* We have it already. */
       }
@@ -3754,8 +3789,34 @@
       smartlist_add(downloadable, rs->descriptor_digest);
     });
 
+  if (smartlist_len(no_longer_old)) {
+    routerlist_t *rl = router_get_routerlist();
+    /* XXXX020 downgrade to info */
+    log_notice(LD_DIR, "%d router descriptors listed in consensus are "
+               "currently in in old_routers; making them current.",
+               smartlist_len(no_longer_old));
+    log_notice(LD_DIR, "Before: %d in routerlist; %d in old_routers",
+               smartlist_len(rl->routers), smartlist_len(rl->old_routers));
+    SMARTLIST_FOREACH(no_longer_old, signed_descriptor_t *, sd, {
+        const char *msg;
+        int r;
+        routerinfo_t *ri = routerlist_reparse_old(rl, sd);
+        if (!ri) {
+          log_notice(LD_DIR, "Failed to re-parse.");
+          continue;
+        }
+        r = router_add_to_routerlist(ri, &msg, 1, 0);
+        if (r == -1) {
+          log_notice(LD_DIR, "Couldn't add: %s", msg?msg:"???");
+        }
+      });
+    log_notice(LD_DIR, "After: %d in routerlist; %d in old_routers",
+               smartlist_len(rl->routers), smartlist_len(rl->old_routers));
+    routerlist_assert_ok(rl);
+  }
+
   log_info(LD_DIR,
-           "%d routers downloadable. %d delayed; %d present "
+           "%d router descriptors downloadable. %d delayed; %d present "
            "(%d of those in old_routers); %d would_reject; "
            "%d wouldnt_use, %d in progress.",
            smartlist_len(downloadable), n_delayed, n_have, n_in_oldrouters,
@@ -3763,8 +3824,10 @@
 
   launch_router_descriptor_downloads(downloadable, now);
 
+  digestmap_free(map, NULL);
+ done:
   smartlist_free(downloadable);
-  digestmap_free(map, NULL);
+  smartlist_free(no_longer_old);
 }
 
 /** Launch downloads for router status as needed. */



More information about the tor-commits mailing list