From 126a3f699a8ed6f9c4d2b6c5f4b09f8be159fdd8 Mon Sep 17 00:00:00 2001 From: Nick Mathewson <nickm@torproject.org> Date: Thu, 19 Oct 2006 23:04:56 +0000 Subject: [PATCH] r9273@Kushana: nickm | 2006-10-19 15:43:39 -0400 Never discard a descriptor for being too old until either it is recommended by no authorities, or until we download a better (more recent and recommended) one for the same router. This will eventually make it possible for servers to publish less often. svn:r8761 --- ChangeLog | 5 ++++ doc/TODO | 4 ++-- doc/dir-spec.txt | 8 ++++++- src/or/or.h | 4 ++-- src/or/routerlist.c | 57 +++++++++++++++++++++++---------------------- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9cd97f0710..c87c2aaab1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,11 @@ Changes in version 0.1.2.3-alpha - 2006-10-?? - If most authorities set a (newly defined) BadExit flag for a server, do not consider it as a general-purpose exit. Only consider authorities that advertise themselves as listing bad exits. + - Start making it possible for servers to publish less often: never + discard a descriptor simply for being too old until either it is + recommended by no authorities, or until we get a better one for the + same router. Make caches consider retaining old recommended + routers for even longer. o Minor features, controller: - Add a REASON field to CIRC events; for backward compatibility, this diff --git a/doc/TODO b/doc/TODO index 6d8b09ec33..0f15446a5c 100644 --- a/doc/TODO +++ b/doc/TODO @@ -142,8 +142,8 @@ x - Better estimates in the directory of whether servers have good uptime x - spec d - implement - - A more efficient dir protocol. -N - Later, servers will stop generating new descriptors simply + o Changes towards a more efficient dir protocol. + o Later, servers will stop generating new descriptors simply because 18 hours have passed: we must start tolerating this now. - Critical but minor bugs, backport candidates. diff --git a/doc/dir-spec.txt b/doc/dir-spec.txt index 92039ef251..949c2f91f4 100644 --- a/doc/dir-spec.txt +++ b/doc/dir-spec.txt @@ -628,7 +628,7 @@ $Id$ from an authority, they should not need to go to the authority directly again.) -5.2. Downloading router descriptors +5.2. Downloading and storing router descriptors Clients try to have the best descriptor for each router. A descriptor is "best" if: @@ -665,6 +665,12 @@ $Id$ No descriptors are downloaded until the client has downloaded more than half of the network-status documents. + Clients retain the most recent descriptor they have downloaded for each + router so long as it is not too old (currently, 48 hours), OR so long as + it is recommended by at least one networkstatus AND no "better" + descriptor has been downloaded. [Versions of Tor before 0.1.2.3-alpha + would discard descriptors simply for being published too far in the past.] + 5.3. Managing downloads When a client has no live network-status documents, it downloads diff --git a/src/or/or.h b/src/or/or.h index d617a95086..1ca35c46fb 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -188,8 +188,8 @@ /** How old can a router get before we (as a server) will no longer * consider it live? In seconds. */ #define ROUTER_MAX_AGE_TO_PUBLISH (60*60*20) -/** How old do we let a saved descriptor get before removing it? */ -#define OLD_ROUTER_DESC_MAX_AGE (60*60*60) +/** How old do we let a saved descriptor get before force-removing it? */ +#define OLD_ROUTER_DESC_MAX_AGE (60*60*24*5) /** How old do we let a networkstatus get before ignoring it? */ #define NETWORKSTATUS_MAX_AGE (60*60*24) diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 02e6f9650a..2f7e0e096e 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1999,8 +1999,8 @@ routerlist_remove_old_cached_routers_with_id(time_t cutoff, int lo, int hi, } /** Deactivate any routers from the routerlist that are more than - * ROUTER_MAX_AGE seconds old; remove old routers from the list of - * cached routers if we have too many. + * ROUTER_MAX_AGE seconds old and not recommended by any networkstatuses; + * remove old routers from the list of cached routers if we have too many. */ void routerlist_remove_old_routers(void) @@ -2012,32 +2012,37 @@ routerlist_remove_old_routers(void) routerinfo_t *router; signed_descriptor_t *sd; digestmap_t *retain; - or_options_t *options = get_options(); if (!routerlist || !networkstatus_list) return; retain = digestmap_new(); cutoff = now - OLD_ROUTER_DESC_MAX_AGE; - if (options->DirPort) { - SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns, - { - SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs, - if (rs->published_on >= cutoff) - digestmap_set(retain, rs->descriptor_digest, (void*)1)); - }); - } + /* Build a list of all the descriptors that _anybody_ recommends. */ + SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns, + { + SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs, + if (rs->published_on >= cutoff) + digestmap_set(retain, rs->descriptor_digest, (void*)1)); + }); - cutoff = now - ROUTER_MAX_AGE; - /* Remove too-old members of routerlist->routers. */ - for (i = 0; i < smartlist_len(routerlist->routers); ++i) { - router = smartlist_get(routerlist->routers, i); - if (router->cache_info.published_on <= cutoff && - !digestmap_get(retain, router->cache_info.signed_descriptor_digest)) { - /* Too old. Remove it. */ - log_info(LD_DIR, - "Forgetting obsolete (too old) routerinfo for router '%s'", - router->nickname); - routerlist_remove(routerlist, router, i--, 1); + /* If we have a bunch of networkstatuses, we should consider pruning current + * routers that are too old and that nobody recommends. (If we don't have + * enough networkstatuses, then we should get more before we decide to kill + * routers.) */ + if (smartlist_len(networkstatus_list) > get_n_v2_authorities() / 2) { + cutoff = now - ROUTER_MAX_AGE; + /* Remove too-old unrecommended members of routerlist->routers. */ + for (i = 0; i < smartlist_len(routerlist->routers); ++i) { + router = smartlist_get(routerlist->routers, i); + if (router->cache_info.published_on <= cutoff && + !digestmap_get(retain,router->cache_info.signed_descriptor_digest)) { + /* Too old: remove it. (If we're a cache, just move it into + * old_routers.) */ + log_info(LD_DIR, + "Forgetting obsolete (too old) routerinfo for router '%s'", + router->nickname); + routerlist_remove(routerlist, router, i--, 1); + } } } @@ -2052,8 +2057,8 @@ routerlist_remove_old_routers(void) } } - /* Now we're looking at routerlist->old_routers for extraneous - * members. (We'd keep all the members if we could, but we'd like to save + /* Now we might have to look at routerlist->old_routers for extraneous + * members. (We'd keep all the members if we could, but we need to save * space.) First, check whether we have too many router descriptors, total. * We're okay with having too many for some given router, so long as the * total number doesn't approach max_descriptors_per_router()*len(router). @@ -3595,10 +3600,6 @@ client_would_use_router(routerstatus_t *rs, time_t now, or_options_t *options) * But, if we want to have a complete list, fetch it anyway. */ return 0; } - if (rs->published_on + ROUTER_MAX_AGE < now) { - /* This one is too old to consider. */ - return 0; - } if (rs->published_on + ESTIMATED_PROPAGATION_TIME > now) { /* Most caches probably don't have this descriptor yet. */ return 0; -- GitLab