From 6f58481335ac4ce9a1bbeb35218aee3c2274744d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 31 Jul 2010 13:48:41 -0400 Subject: [PATCH] Scale CONSENSUS_MIN_SECONDS_BEFORE_CACHING by voting interval If the voting interval was short enough, the two-minutes delay of CONSENSUS_MIN_SECONDS_BEFORE_CACHING would confuse bridges to the point where they would assert before downloading a consensus. It it was even shorter (<4 minutes, I think), caches would assert too. This patch fixes that by having replacing the two-minutes value with MIN(2 minutes, interval/16). Bugfix for 1141; the cache bug could occur since 0.2.0.8-alpha, so I'm calling this a bugfix on that. Robert Hogan diagnosed this. Done as a patch against maint-0.2.1, since it makes it hard to run some kinds of testing networks. --- changes/bug1141 | 5 +++++ src/or/networkstatus.c | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 changes/bug1141 diff --git a/changes/bug1141 b/changes/bug1141 new file mode 100644 index 0000000000..9975e418d6 --- /dev/null +++ b/changes/bug1141 @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Fix an assertion failure that could occur in caches or bridge users + when using a very short voting interval on a testing network. + Diagnosed by Robert Hogan. Fixes bug 1141; bugfix on 0.2.0.8-alpha. + diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index a43ed52547..4721420bbd 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1132,11 +1132,21 @@ update_consensus_networkstatus_fetch_time(time_t now) if (c) { long dl_interval; long interval = c->fresh_until - c->valid_after; + long min_sec_before_caching = CONSENSUS_MIN_SECONDS_BEFORE_CACHING; time_t start; + + if (min_sec_before_caching > interval/16) { + /* Usually we allow 2-minutes slop factor in case clocks get + desynchronized a little. If we're on a private network with + a crazy-fast voting interval, though, 2 minutes may be too + much. */ + min_sec_before_caching = interval/16; + } + if (directory_fetches_dir_info_early(options)) { /* We want to cache the next one at some point after this one * is no longer fresh... */ - start = c->fresh_until + CONSENSUS_MIN_SECONDS_BEFORE_CACHING; + start = c->fresh_until + min_sec_before_caching; /* But only in the first half-interval after that. */ dl_interval = interval/2; } else { @@ -1150,10 +1160,9 @@ update_consensus_networkstatus_fetch_time(time_t now) * to choose the rest of the interval *after* them. */ if (directory_fetches_dir_info_later(options)) { /* Give all the *clients* enough time to download the consensus. */ - start = start + dl_interval + CONSENSUS_MIN_SECONDS_BEFORE_CACHING; + start = start + dl_interval + min_sec_before_caching; /* But try to get it before ours actually expires. */ - dl_interval = (c->valid_until - start) - - CONSENSUS_MIN_SECONDS_BEFORE_CACHING; + dl_interval = (c->valid_until - start) - min_sec_before_caching; } } if (dl_interval < 1)