aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2007-12-24 11:25:45 +0000
committerRoger Dingledine <arma@torproject.org>2007-12-24 11:25:45 +0000
commit15c048bdc558e6e8f37d69667b6d282733287116 (patch)
treeffa099496251709a5d35647d0ecede3fcec058f0
parent44ca13ceaa1b376601ac30cc56465e1e644f37cd (diff)
downloadtor-15c048bdc558e6e8f37d69667b6d282733287116.tar.gz
tor-15c048bdc558e6e8f37d69667b6d282733287116.zip
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. svn:r12952
-rw-r--r--ChangeLog12
-rw-r--r--src/or/dirserv.c38
2 files changed, 33 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 37db6f3bed..ecefc1c674 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;