Fix the handling of reverse time in the ratelimit code.
authorTony Finch <dot@dot.at>
Tue, 13 Sep 2005 18:06:30 +0000 (18:06 +0000)
committerTony Finch <dot@dot.at>
Tue, 13 Sep 2005 18:06:30 +0000 (18:06 +0000)
doc/doc-txt/ChangeLog
src/src/acl.c
src/util/ratelimit.pl

index 2fc2eefa6a76c371ff735be918607e0c87ca304e..523caa763bed09220d4c9d4ded8de8c6808e3a9f 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.230 2005/09/13 17:51:05 fanf2 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.231 2005/09/13 18:06:30 fanf2 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -190,6 +190,9 @@ PH/47 Added an interface to a fake DNS resolver for use by the new test suite,
 
 TF/02 Added util/ratelimit.pl
 
+TF/03 Minor fix to the ratelimit code to improve its behaviour in case the
+      clock is set back in time.
+
 
 Exim version 4.52
 -----------------
index 06fa6e8985add3795d19ddcddf39f9bf2ca94c94..b582df7ea1029f7c6fc15cb4f7bbb84980864709 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.47 2005/09/12 10:08:54 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.48 2005/09/13 18:06:30 fanf2 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2164,16 +2164,16 @@ else
                    + (double)tv.tv_usec / 1000000.0;
   double prev_time = (double)dbd->time_stamp
                    + (double)dbd->time_usec / 1000000.0;
-  double interval = this_time - prev_time;
-
-  double i_over_p = interval / period;
-  double a = exp(-i_over_p);
 
   /* We must avoid division by zero, and deal gracefully with the clock going
   backwards. If we blunder ahead when time is in reverse then the computed
-  rate will become bogusly huge. Clamp i/p to a very small number instead. */
+  rate will be bogus. To be safe we clamp interval to a very small number. */
 
-  if (i_over_p <= 0.0) i_over_p = 1e-9;
+  double interval = this_time - prev_time <= 0.0 ? 1e-9
+                  : this_time - prev_time;
+
+  double i_over_p = interval / period;
+  double a = exp(-i_over_p);
 
   dbd->time_stamp = tv.tv_sec;
   dbd->time_usec = tv.tv_usec;
index a30cfb60a36f8ace22d13888d7b354fc8d73754e..bb2abbb5af30099167d7d65aea7f5214fcc9216b 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -wT
 #
-# $Cambridge: exim/src/util/ratelimit.pl,v 1.1 2005/09/13 17:51:06 fanf2 Exp $
+# $Cambridge: exim/src/util/ratelimit.pl,v 1.2 2005/09/13 18:06:31 fanf2 Exp $
 
 use strict;
 
@@ -118,9 +118,9 @@ while (<>) {
   }
   # see acl_ratelimit() for details of the following
   my $interval = $time - $time{$key};
+  $interval = 1e-9 if $interval <= 0.0;
   my $i_over_p = $interval / $period;
   my $a = exp(-$i_over_p);
-  $i_over_p = 1e-9 if $i_over_p <= 0.0;
   $time{$key} = $time;
   $rate{$key} = $size * (1.0 - $a) / $i_over_p + $a * $rate{$key};
   $max{$key} = $rate{$key} if $rate{$key} > $max{$key};