summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-11-07 15:19:53 +0000
committerNick Mathewson <nickm@torproject.org>2007-11-07 15:19:53 +0000
commitacaa9a7f6967793bd62e5f5b80375f408ca6c95f (patch)
tree495c6eca82fc4dac4bbf50cc604ae54195d8fd9c
parent0fa00d8ec6f9d769ff05c7542b260fa4bc33c0e9 (diff)
downloadtor-acaa9a7f6967793bd62e5f5b80375f408ca6c95f.tar.gz
tor-acaa9a7f6967793bd62e5f5b80375f408ca6c95f.zip
r16518@catbus: nickm | 2007-11-07 10:18:31 -0500
First attempt at fixing bug 543. Needs testing. Too slow. svn:r12408
-rw-r--r--ChangeLog3
-rw-r--r--src/or/routerlist.c81
2 files changed, 75 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 8e7861c05a..6bf665e6b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,9 @@ Changes in version 0.2.0.10-alpha - 2007-11-0?
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
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 6c165347f6..a9f40e88e5 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -2464,6 +2464,39 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
#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 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
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 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
*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 @@ update_consensus_router_descriptor_downloads(time_t now)
{
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 @@ update_consensus_router_descriptor_downloads(time_t now)
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 @@ update_consensus_router_descriptor_downloads(time_t now)
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 @@ update_consensus_router_descriptor_downloads(time_t now)
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 @@ update_consensus_router_descriptor_downloads(time_t now)
launch_router_descriptor_downloads(downloadable, now);
- smartlist_free(downloadable);
digestmap_free(map, NULL);
+ done:
+ smartlist_free(downloadable);
+ smartlist_free(no_longer_old);
}
/** Launch downloads for router status as needed. */