diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-10-19 02:15:47 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-10-19 02:15:47 +0000 |
commit | 29dfdac923dc0c20ce3f386c868bc4d43f816bf9 (patch) | |
tree | 0f75a77a241871d313ba9c919a4a6cef33a06a5d | |
parent | 90de3ca9aeaddbbad092255f7e599a45ea503f24 (diff) | |
download | tor-29dfdac923dc0c20ce3f386c868bc4d43f816bf9.tar tor-29dfdac923dc0c20ce3f386c868bc4d43f816bf9.tar.gz |
r15939@catbus: nickm | 2007-10-18 22:14:15 -0400
Remember the valid-until time of the most recent consensus that listed
a router, and (if we are a cache) never delete the routerdesc until
that conensus is expired. This is way easier than retaining multiple
consensuses. (Of course, the info isn't retained across restarts,
but that only affects a few caches at a time.)
svn:r12041
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/or/networkstatus.c | 32 | ||||
-rw-r--r-- | src/or/or.h | 6 | ||||
-rw-r--r-- | src/or/routerlist.c | 13 | ||||
-rw-r--r-- | src/or/routerparse.c | 4 |
5 files changed, 53 insertions, 5 deletions
@@ -21,6 +21,9 @@ Changes in version 0.2.0.9-alpha - 2007-10-?? - If we find a cached-routers file that's been sitting around for more than 28 days unmodified, then most likely it's a leftover from when we upgraded to 0.2.0.8-alpha. Remove it. It has no good routers anyway. + - When we (as a cache) download a descriptor because it was listed in a + consensus, remember when the consensus was supposed to expire, and + don't expire the descriptor until then. o Minor features (performance): - Call routerlist_remove_old_routers() much less often. This should diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 83029627e..b1afddfb8 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1049,6 +1049,8 @@ routers_update_all_from_networkstatus(time_t now) routers_update_status_from_consensus_networkstatus(rl->routers, 0); SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, ri->routerlist_index = ri_sl_idx); + if (rl->old_routers) + signed_descs_update_status_from_consensus_networkstatus(rl->old_routers); entry_guards_compute_status(); me = router_get_my_routerinfo(); @@ -1216,6 +1218,11 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers, else router->is_named = 0; } + if (!memcmp(router->cache_info.signed_descriptor_digest, + rs->descriptor_digest, DIGEST_LEN)) { + if (ns->valid_until > router->cache_info.last_listed_as_valid_until) + router->cache_info.last_listed_as_valid_until = ns->valid_until; + } if (!authdir) { /* If we're not an authdir, believe others. */ @@ -1239,6 +1246,31 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers, router_dir_info_changed(); } +/**DOCDOC*/ +void +signed_descs_update_status_from_consensus_networkstatus(smartlist_t *descs) +{ + networkstatus_vote_t *ns = current_consensus; + if (!ns) + return; + + if (!ns->desc_digest_map) { + char dummy[DIGEST_LEN]; + /* instantiates the digest map. */ + memset(dummy, 0, sizeof(dummy)); + router_get_consensus_status_by_descriptor_digest(dummy); + } + SMARTLIST_FOREACH(descs, signed_descriptor_t *, d, + { + routerstatus_t *rs = digestmap_get(ns->desc_digest_map, + d->signed_descriptor_digest); + if (rs) { + if (ns->valid_until > d->last_listed_as_valid_until) + d->last_listed_as_valid_until = ns->valid_until; + } + }); +} + /** Generate networkstatus lines for a single routerstatus_t object, and * return the result in a newly allocated string. Used only by controller * interface (for now.) */ diff --git a/src/or/or.h b/src/or/or.h index f37e8865b..afee5ce8d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1102,6 +1102,9 @@ typedef struct signed_descriptor_t { /** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of * this descriptor in the corresponding file. */ off_t saved_offset; + /** The valid-until time of the most recent consensus that listed this + * descriptor. 0 for "never listed in a consensus, so far as we know." */ + time_t last_listed_as_valid_until; /* If true, we do not ever try to save this object in the cache. */ unsigned int do_not_cache : 1; /* If true, this item is meant to represent an extrainfo. */ @@ -3098,6 +3101,9 @@ void routers_update_all_from_networkstatus(time_t now); void routerstatus_list_update_from_consensus_networkstatus(time_t now); void routers_update_status_from_consensus_networkstatus(smartlist_t *routers, int reset_failures); +void signed_descs_update_status_from_consensus_networkstatus( + smartlist_t *descs); + char *networkstatus_getinfo_helper_single(routerstatus_t *rs); int getinfo_helper_networkstatus(control_connection_t *conn, const char *question, char **answer); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 6c7b252d9..27fb2dbf8 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2791,7 +2791,8 @@ _compare_duration_idx(const void *_d1, const void *_d2) * indices <b>lo</b> or higher may be changed. */ static void -routerlist_remove_old_cached_routers_with_id(time_t cutoff, int lo, int hi, +routerlist_remove_old_cached_routers_with_id(time_t now, + time_t cutoff, int lo, int hi, digestmap_t *retain) { int i, n = hi-lo+1; @@ -2827,7 +2828,8 @@ routerlist_remove_old_cached_routers_with_id(time_t cutoff, int lo, int hi, signed_descriptor_t *r = smartlist_get(lst, i); signed_descriptor_t *r_next; lifespans[i-lo].idx = i; - if (retain && digestmap_get(retain, r->signed_descriptor_digest)) { + if (r->last_listed_as_valid_until >= now || + (retain && digestmap_get(retain, r->signed_descriptor_digest))) { must_keep[i-lo] = 1; } if (i < hi) { @@ -2933,6 +2935,7 @@ routerlist_remove_old_routers(void) for (i = 0; i < smartlist_len(routerlist->routers); ++i) { router = smartlist_get(routerlist->routers, i); if (router->cache_info.published_on <= cutoff && + router->cache_info.last_listed_as_valid_until < now && !digestmap_get(retain,router->cache_info.signed_descriptor_digest)) { /* Too old: remove it. (If we're a cache, just move it into * old_routers.) */ @@ -2952,6 +2955,7 @@ routerlist_remove_old_routers(void) for (i = 0; i < smartlist_len(routerlist->old_routers); ++i) { sd = smartlist_get(routerlist->old_routers, i); if (sd->published_on <= cutoff && + sd->last_listed_as_valid_until < now && !digestmap_get(retain, sd->signed_descriptor_digest)) { /* Too old. Remove it. */ routerlist_remove_old(routerlist, sd, i--); @@ -2987,13 +2991,14 @@ routerlist_remove_old_routers(void) hi = i; } if (memcmp(cur_id, r->identity_digest, DIGEST_LEN)) { - routerlist_remove_old_cached_routers_with_id(cutoff, i+1, hi, retain); + routerlist_remove_old_cached_routers_with_id(now, + cutoff, i+1, hi, retain); cur_id = r->identity_digest; hi = i; } } if (hi>=0) - routerlist_remove_old_cached_routers_with_id(cutoff, 0, hi, retain); + routerlist_remove_old_cached_routers_with_id(now, cutoff, 0, hi, retain); //routerlist_assert_ok(routerlist); done: diff --git a/src/or/routerparse.c b/src/or/routerparse.c index d186af50c..2b5c29882 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -74,6 +74,7 @@ typedef enum { K_VOTE_DIGEST, K_CONSENSUS_DIGEST, K_CONSENSUS_METHODS, + K_CONSENSUS_METHOD, A_PURPOSE, _A_UNKNOWN, @@ -339,7 +340,8 @@ static token_rule_t networkstatus_consensus_token_table[] = { T1( "known-flags", K_KNOWN_FLAGS, CONCAT_ARGS, NO_OBJ ), T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ), - T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ), + T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ), + T01("consensus-method", K_CONSENSUS_METHOD, EQ(1), NO_OBJ), END_OF_TABLE }; |