diff options
author | Nick Mathewson <nickm@torproject.org> | 2010-09-03 12:06:04 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2010-09-03 12:19:17 -0400 |
commit | 80b3de8753225f169e4269503d63c273562345e7 (patch) | |
tree | 346b02df7a9e7ab1e3694242fd0394c98f94566f /src/or/hibernate.c | |
parent | 20817403173dcd2f8128c9c8b14491117cdc40b6 (diff) | |
download | tor-80b3de8753225f169e4269503d63c273562345e7.tar.gz tor-80b3de8753225f169e4269503d63c273562345e7.zip |
Tolerate a little skew in accounting intervals.
This will make changes for DST still work, and avoid double-spending
bytes when there are slight changes to configurations.
Fixes bug 1511; the DST issue is a bugfix on 0.0.9pre5.
Diffstat (limited to 'src/or/hibernate.c')
-rw-r--r-- | src/or/hibernate.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/or/hibernate.c b/src/or/hibernate.c index d50d05ed5e..994b7ea932 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -341,6 +341,15 @@ start_of_accounting_period_after(time_t now) return edge_of_accounting_period_containing(now, 1); } +/** Return the length of the accounting period containing the time + * <b>now</b>. */ +static long +length_of_accounting_period_containing(time_t now) +{ + return edge_of_accounting_period_containing(now, 1) - + edge_of_accounting_period_containing(now, 0); +} + /** Initialize the accounting subsystem. */ void configure_accounting(time_t now) @@ -356,14 +365,26 @@ configure_accounting(time_t now) log_info(LD_ACCT, "Starting new accounting interval."); reset_accounting(now); } else if (interval_start_time == - start_of_accounting_period_containing(interval_start_time)) { + start_of_accounting_period_containing(interval_start_time)) { log_info(LD_ACCT, "Continuing accounting interval."); /* We are in the interval we thought we were in. Do nothing.*/ interval_end_time = start_of_accounting_period_after(interval_start_time); } else { - log_warn(LD_ACCT, - "Mismatched accounting interval; starting a fresh one."); - reset_accounting(now); + time_t s_now = start_of_accounting_period_containing(interval_start_time); + long duration = length_of_accounting_period_containing(interval_start_time); + double delta = ((double)(s_now - interval_start_time)) / duration; + if (-0.50 <= delta && delta <= 0.50) { + /* The start of the period is now a little later than we remembered. + * That's fine; we might lose a little time, but that's ok. */ + log_info(LD_ACCT, "Accounting interval moved by %.02f%%; " + "that's fine.", delta*100); + interval_end_time = start_of_accounting_period_after(interval_start_time); + } else { + log_warn(LD_ACCT, + "Mismatched accounting interval: moved by %.02f%%. " + "Starting a fresh one.", delta*100); + reset_accounting(now); + } } accounting_set_wakeup_time(); } |