summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-05-19 22:21:46 +0000
committerNick Mathewson <nickm@torproject.org>2007-05-19 22:21:46 +0000
commit9091d0c49a57b6263fd9a76fed54b6e8d61ac442 (patch)
tree2dddcae65bbe25dda33433a778f79317fce4c007
parentdc76c31c79ac0323e641b48dab08d8ae4df5abb0 (diff)
downloadtor-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--ChangeLog2
-rw-r--r--src/or/directory.c29
-rw-r--r--src/or/or.h3
-rw-r--r--src/or/routerlist.c25
4 files changed, 49 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 14686c6830..b08cdc7375 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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