]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Tolerate a little skew in accounting intervals.
authorNick Mathewson <nickm@torproject.org>
Fri, 3 Sep 2010 16:06:04 +0000 (12:06 -0400)
committerNick Mathewson <nickm@torproject.org>
Fri, 3 Sep 2010 16:19:17 +0000 (12:19 -0400)
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.

changes/bug1511 [new file with mode: 0644]
src/or/hibernate.c

diff --git a/changes/bug1511 b/changes/bug1511
new file mode 100644 (file)
index 0000000..8e9652b
--- /dev/null
@@ -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.
+
index d50d05ed5eef3a058da9d0334c68b833c030df4b..994b7ea9329e5a63b89e0ed4f691a1eddcc618d9 100644 (file)
@@ -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();
 }