Commit acaa9a7f authored by Nick Mathewson's avatar Nick Mathewson 🎨
Browse files

r16518@catbus: nickm | 2007-11-07 10:18:31 -0500

 First attempt at fixing bug 543.  Needs testing. Too slow.


svn:r12408
parent 0fa00d8e
......@@ -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
......
......@@ -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. */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment