summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-04-13 20:02:27 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-04-13 20:02:27 +0000
commite5239fc26e88f70909c9c2b6b75906ad8898f974 (patch)
treeb6cdfb08aa66f46d1757afda4d50ce971123cc7f
parenta8105c67473b78923a2cadae41e01ad3f4934b4e (diff)
downloadopenvpn-e5239fc26e88f70909c9c2b6b75906ad8898f974.tar.gz
openvpn-e5239fc26e88f70909c9c2b6b75906ad8898f974.tar.xz
openvpn-e5239fc26e88f70909c9c2b6b75906ad8898f974.zip
Re-added backtrack handling code.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1008 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--otime.c49
-rw-r--r--otime.h36
-rw-r--r--syshead.h2
3 files changed, 84 insertions, 3 deletions
diff --git a/otime.c b/otime.c
index e172805..690fe27 100644
--- a/otime.c
+++ b/otime.c
@@ -36,11 +36,47 @@
time_t now = 0; /* GLOBAL */
-#ifdef HAVE_GETTIMEOFDAY
+#if TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY)
+static time_t now_adj = 0; /* GLOBAL */
time_t now_usec = 0; /* GLOBAL */
-#endif
+/*
+ * Try to filter out time instability caused by the system
+ * clock backtracking or jumping forward.
+ */
+
+void
+update_now (const time_t system_time)
+{
+ const int forward_threshold = 86400; /* threshold at which to dampen forward jumps */
+ const int backward_trigger = 10; /* backward jump must be >= this many seconds before we adjust */
+ time_t real_time = system_time + now_adj;
+
+ if (real_time > now)
+ {
+ const time_t overshoot = real_time - now - 1;
+ if (overshoot > forward_threshold && now_adj >= overshoot)
+ {
+ now_adj -= overshoot;
+ real_time -= overshoot;
+ }
+ now = real_time;
+ }
+ else if (real_time < now - backward_trigger)
+ now_adj += (now - real_time);
+}
+
+void
+update_now_usec (struct timeval *tv)
+{
+ const time_t last = now;
+ update_now (tv->tv_sec);
+ if (now > last || (now == last && tv->tv_usec > now_usec))
+ now_usec = tv->tv_usec;
+}
+
+#endif /* TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) */
/*
* Return a numerical string describing a struct timeval.
@@ -167,6 +203,11 @@ gettimeofday_calibrate (void)
gtc_last = gtc;
}
+/*
+ * Rewritten by JY for OpenVPN 2.1, after I realized that
+ * QueryPerformanceCounter takes nearly 2 orders of magnitude
+ * more processor cycles than GetTickCount.
+ */
int
gettimeofday (struct timeval *tv, void *tz)
{
@@ -176,6 +217,7 @@ gettimeofday (struct timeval *tv, void *tz)
unsigned int msec;
const int backtrack_hold_seconds = 10;
+ /* recalibrate at the dreaded 49.7 day mark */
if (!gtc_base || gtc < gtc_last)
gettimeofday_calibrate ();
gtc_last = gtc;
@@ -193,6 +235,9 @@ gettimeofday (struct timeval *tv, void *tz)
}
else if (sec < last_sec)
{
+ /* We try to dampen out backtracks of less than backtrack_hold_seconds.
+ Larger backtracks will be passed through and dealt with by the
+ TIME_BACKTRACK_PROTECTION code (if enabled) */
if (sec > last_sec - backtrack_hold_seconds)
{
sec = last_sec;
diff --git a/otime.h b/otime.h
index 2dca396..2e01bb2 100644
--- a/otime.h
+++ b/otime.h
@@ -58,6 +58,40 @@ extern time_t now; /* updated frequently to time(NULL) */
void time_test (void);
+#if TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY)
+
+void update_now (const time_t system_time);
+
+extern time_t now_usec;
+void update_now_usec (struct timeval *tv);
+
+static inline int
+openvpn_gettimeofday (struct timeval *tv, void *tz)
+{
+ const int status = gettimeofday (tv, tz);
+ if (!status)
+ {
+ update_now_usec (tv);
+ tv->tv_sec = now;
+ tv->tv_usec = now_usec;
+ }
+ return status;
+}
+
+static inline void
+update_time (void)
+{
+#ifdef WIN32
+ /* on WIN32, gettimeofday is faster than time(NULL) */
+ struct timeval tv;
+ openvpn_gettimeofday (&tv, NULL);
+#else
+ update_now (time (NULL));
+#endif
+}
+
+#else /* !(TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY)) */
+
static inline void
update_time (void)
{
@@ -85,6 +119,8 @@ openvpn_gettimeofday (struct timeval *tv, void *tz)
#endif
+#endif /* TIME_BACKTRACK_PROTECTION && defined(HAVE_GETTIMEOFDAY) */
+
static inline time_t
openvpn_time (time_t *t)
{
diff --git a/syshead.h b/syshead.h
index 78eeebd..f296fe0 100644
--- a/syshead.h
+++ b/syshead.h
@@ -498,7 +498,7 @@ socket_defined (const socket_descriptor_t sd)
* Reduce sensitivity to system clock instability
* and backtracks.
*/
-//#define TIME_BACKTRACK_PROTECTION 1 // JYFIXME
+#define TIME_BACKTRACK_PROTECTION 1
/*
* Is non-blocking connect() supported?