aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-10-19 02:15:47 +0000
committerNick Mathewson <nickm@torproject.org>2007-10-19 02:15:47 +0000
commit29dfdac923dc0c20ce3f386c868bc4d43f816bf9 (patch)
tree0f75a77a241871d313ba9c919a4a6cef33a06a5d
parent90de3ca9aeaddbbad092255f7e599a45ea503f24 (diff)
downloadtor-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--ChangeLog3
-rw-r--r--src/or/networkstatus.c32
-rw-r--r--src/or/or.h6
-rw-r--r--src/or/routerlist.c13
-rw-r--r--src/or/routerparse.c4
5 files changed, 53 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c8f6d5ef..cdbad9619 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
};