diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | src/or/dirserv.c | 38 |
2 files changed, 33 insertions, 17 deletions
@@ -1,4 +1,14 @@ -Changes in version 0.2.0.15-alpha - 2008-01-?? +Changes in version 0.2.0.15-alpha - 2007-12-?? + o Major bugfixes: + - Fix several remotely triggerable asserts based on DirPort requests + for a v2 or v3 networkstatus object before we were prepared. This + was particularly bad for 0.2.0.13 and later bridge relays, who + would never have a v2 networkstatus and would thus always crash + when used. Bugfixes on 0.2.0.x. + - Estimate the v3 networkstatus size more accurately, rather than + estimating it at zero bytes and giving it artificially high priority + compared to other directory requests. Bugfix on 0.2.0.x. + o Minor bugfixes: - Fix configure.in logic for cross-compilation. - When we load a bridge descriptor from the cache, and it was diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 5733da1adb..97243ef6e3 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2757,6 +2757,24 @@ dirserv_test_reachability(time_t now, int try_all) ctr = (ctr + 1) % 128; } + +/** Given a fingerprint <b>fp</b> which is either set if we're looking + * for a v2 status, or zeroes if we're looking for a v3 status, return + * a pointer to the appropriate cached dir object, or NULL if there isn't + * one available. */ +static cached_dir_t * +lookup_cached_dir_by_fp(const char *fp) +{ + cached_dir_t *d = NULL; + if (tor_digest_is_zero(fp) && cached_v3_networkstatus) + d = cached_v3_networkstatus; + else if (router_digest_is_me(fp) && the_v2_networkstatus) + d = the_v2_networkstatus; + else if (cached_v2_networkstatus) + d = digestmap_get(cached_v2_networkstatus, fp); + return d; +} + /** Remove from <b>fps</b> every networkstatus key where both * a) we have a networkstatus document and * b) it is not newer than <b>cutoff</b>. @@ -2769,13 +2787,7 @@ dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff) int found_any = 0; SMARTLIST_FOREACH(fps, char *, digest, { - cached_dir_t *d; - if (router_digest_is_me(digest) && the_v2_networkstatus) - d = the_v2_networkstatus; - else if (tor_digest_is_zero(digest) && cached_v3_networkstatus) - d = cached_v3_networkstatus; - else - d = digestmap_get(cached_v2_networkstatus, digest); + cached_dir_t *d = lookup_cached_dir_by_fp(digest); if (!d) continue; found_any = 1; @@ -2864,8 +2876,8 @@ dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs, result /= 2; /* observed compressability is between 35 and 55%. */ } else { result = 0; - SMARTLIST_FOREACH(fps, const char *, d, { - cached_dir_t *dir = digestmap_get(cached_v2_networkstatus, d); + SMARTLIST_FOREACH(fps, const char *, digest, { + cached_dir_t *dir = lookup_cached_dir_by_fp(digest); if (dir) result += compressed ? dir->dir_z_len : dir->dir_len; }); @@ -3019,13 +3031,7 @@ connection_dirserv_add_networkstatus_bytes_to_outbuf(dir_connection_t *conn) smartlist_len(conn->fingerprint_stack)) { /* Add another networkstatus; start serving it. */ char *fp = smartlist_pop_last(conn->fingerprint_stack); - cached_dir_t *d; - if (tor_digest_is_zero(fp)) - d = cached_v3_networkstatus; - else if (router_digest_is_me(fp)) - d = the_v2_networkstatus; - else - d = digestmap_get(cached_v2_networkstatus, fp); + cached_dir_t *d = lookup_cached_dir_by_fp(fp); tor_free(fp); if (d) { ++d->refcnt; |