diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-05-19 22:21:46 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-05-19 22:21:46 +0000 |
commit | 9091d0c49a57b6263fd9a76fed54b6e8d61ac442 (patch) | |
tree | 2dddcae65bbe25dda33433a778f79317fce4c007 | |
parent | dc76c31c79ac0323e641b48dab08d8ae4df5abb0 (diff) | |
download | tor-9091d0c49a57b6263fd9a76fed54b6e8d61ac442.tar.gz tor-9091d0c49a57b6263fd9a76fed54b6e8d61ac442.zip |
r12816@catbus: nickm | 2007-05-19 18:21:44 -0400
Backport the gist of r10210.
svn:r10225
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | src/or/directory.c | 29 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routerlist.c | 25 |
4 files changed, 49 insertions, 10 deletions
@@ -22,6 +22,8 @@ Changes in version 0.1.2.14 - 2007-0?-?? - When we have k non-v2 authorities in our DirServer config, we ignored as many as k v2 authorities while updating our network-statuses. + - Correctly back-off from requesting router descriptors that we are + having a hard time downloading. o Minor features: - When routers publish SVN revisions in their router descriptors, diff --git a/src/or/directory.c b/src/or/directory.c index 72e57114de..3d1f066414 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2015,14 +2015,21 @@ dir_networkstatus_download_failed(smartlist_t *failed, int status_code) static void dir_routerdesc_download_failed(smartlist_t *failed, int status_code) { - char digest[DIGEST_LEN]; - local_routerstatus_t *rs; time_t now = time(NULL); int server = server_mode(get_options()) && get_options()->DirPort; + smartlist_t *routerstatuses, *digests = smartlist_create(); + SMARTLIST_FOREACH(failed, const char *, cp, { - base16_decode(digest, DIGEST_LEN, cp, strlen(cp)); - rs = router_get_combined_status_by_digest(digest); + char *d = tor_malloc(DIGEST_LEN); + base16_decode(d, DIGEST_LEN, cp, strlen(cp)); + smartlist_add(digests, d); + }); + routerstatuses = router_get_combined_status_by_descriptor_digests(digests); + SMARTLIST_FOREACH(digests, char *, d, tor_free(d)); + smartlist_free(digests); + + SMARTLIST_FOREACH(routerstatuses, local_routerstatus_t *, rs, { if (!rs || rs->n_download_failures >= MAX_ROUTERDESC_DOWNLOAD_FAILURES) continue; if (status_code != 503 || server) @@ -2050,17 +2057,19 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code) } } if (rs->next_attempt_at == 0) - log_debug(LD_DIR, "%s failed %d time(s); I'll try again immediately.", - cp, (int)rs->n_download_failures); + log_debug(LD_DIR, "dl failed %d time(s); I'll try again immediately.", + (int)rs->n_download_failures); else if (rs->next_attempt_at < TIME_MAX) - log_debug(LD_DIR, "%s failed %d time(s); I'll try again in %d seconds.", - cp, (int)rs->n_download_failures, + log_debug(LD_DIR, "dl failed %d time(s); I'll try again in %d seconds.", + (int)rs->n_download_failures, (int)(rs->next_attempt_at-now)); else - log_debug(LD_DIR, "%s failed %d time(s); Giving up for a while.", - cp, (int)rs->n_download_failures); + log_debug(LD_DIR, "dl failed %d time(s); Giving up for a while.", + (int)rs->n_download_failures); }); + smartlist_free(routerstatuses); + /* No need to relaunch descriptor downloads here: we already do it * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */ } diff --git a/src/or/or.h b/src/or/or.h index 585645c8cf..e66f45f02c 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2966,6 +2966,9 @@ void clear_trusted_dir_servers(void); int any_trusted_dir_is_v1_authority(void); networkstatus_t *networkstatus_get_by_digest(const char *digest); local_routerstatus_t *router_get_combined_status_by_digest(const char *digest); +smartlist_t *router_get_combined_status_by_descriptor_digests( + smartlist_t *digests); + routerstatus_t *routerstatus_get_by_hexdigest(const char *hexdigest); void update_networkstatus_downloads(time_t now); void update_router_descriptor_downloads(time_t now); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 8abd03e5b8..bb2b7d4e00 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2662,6 +2662,31 @@ router_get_combined_status_by_digest(const char *digest) _compare_digest_to_routerstatus_entry); } +/** Return a newly allocated list of the local_routerstatus_t for all routers + * where we believe that the digest of their current descriptor is some digest + * listed in <b>digests</b>. */ +smartlist_t * +router_get_combined_status_by_descriptor_digests(smartlist_t *digests) +{ + digestmap_t *map; + smartlist_t *result; + + if (!routerstatus_list) + return NULL; + + map = digestmap_new(); + result = smartlist_create(); + SMARTLIST_FOREACH(digests, const char *, d, digestmap_set(map, d, (void*)1)); + + SMARTLIST_FOREACH(routerstatus_list, local_routerstatus_t *, lrs, { + if (digestmap_get(map, lrs->status.descriptor_digest)) + smartlist_add(result, lrs); + }); + + digestmap_free(map, NULL); + return result; +} + /** Given a nickname (possibly verbose, possibly a hexadecimal digest), return * the corresponding local_routerstatus_t, or NULL if none exists. Warn the * user if <b>warn_if_unnamed</b> is set, and they have specified a router by |