diff options
author | Nick Mathewson <nickm@torproject.org> | 2010-09-23 23:16:25 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2010-09-23 23:16:25 -0400 |
commit | 9b49a89430eac9a50fdb067aefec9d1561872796 (patch) | |
tree | 12307ab312c799363905d6e3c725bb7166b4c452 | |
parent | c9cb4f0a0e9eb3411dfdc446e4543d48b152f8f5 (diff) | |
parent | 52db5c2539413aded9a7fb855030c6a3a7a25798 (diff) | |
download | tor-9b49a89430eac9a50fdb067aefec9d1561872796.tar.gz tor-9b49a89430eac9a50fdb067aefec9d1561872796.zip |
Merge branch 'bug1511'
-rw-r--r-- | changes/bug1511 | 9 | ||||
-rw-r--r-- | src/or/hibernate.c | 46 |
2 files changed, 46 insertions, 9 deletions
diff --git a/changes/bug1511 b/changes/bug1511 new file mode 100644 index 0000000000..8e9652b90e --- /dev/null +++ b/changes/bug1511 @@ -0,0 +1,9 @@ + o Minor bugfixes: + - Tolerate skew in stored vs computed interval starts for bandwidth + accounting. Now, if we change our configuration so that the start + of the period changes by no more than 50% of the period's duration, + we remember bytes that we transferred in the old one. The upshot + of this is that daylight savings time should no longer mess up + bandwidth accounting and make each period potentially happen + twice. Fixes bug 1511; bugfix on 0.0.9pre5. + diff --git a/src/or/hibernate.c b/src/or/hibernate.c index d0d09798ca..3c6a3fa033 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -348,29 +348,57 @@ 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) { + time_t s_now; /* Try to remember our recorded usage. */ if (!interval_start_time) read_bandwidth_usage(); /* If we fail, we'll leave values at zero, and * reset below.*/ - if (!interval_start_time || - start_of_accounting_period_after(interval_start_time) <= now) { - /* We didn't have recorded usage, or we don't have recorded usage - * for this interval. Start a new interval. */ + + s_now = start_of_accounting_period_containing(now); + + if (!interval_start_time) { + /* We didn't have recorded usage; Start a new interval. */ log_info(LD_ACCT, "Starting new accounting interval."); reset_accounting(now); - } else if (interval_start_time == - start_of_accounting_period_containing(interval_start_time)) { + } else if (s_now == 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); + long duration = length_of_accounting_period_containing(now); + 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 or earlier than we + * remembered. That's fine; we might lose some bytes we could otherwise + * have written, but better to err on the side of obeying people's + * accounting settings. */ + log_info(LD_ACCT, "Accounting interval moved by %.02f%%; " + "that's fine.", delta*100); + interval_end_time = start_of_accounting_period_after(now); + } else if (delta >= 0.99) { + /* This is the regular time-moved-forward case; don't be too noisy + * about it or people will complain */ + log_info(LD_ACCT, "Accounting interval elapsed; starting a new one"); + reset_accounting(now); + } else { + log_warn(LD_ACCT, + "Mismatched accounting interval: moved by %.02f%%. " + "Starting a fresh one.", delta*100); + reset_accounting(now); + } } accounting_set_wakeup_time(); } |