From e5239fc26e88f70909c9c2b6b75906ad8898f974 Mon Sep 17 00:00:00 2001 From: james Date: Thu, 13 Apr 2006 20:02:27 +0000 Subject: Re-added backtrack handling code. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1008 e7ae566f-a301-0410-adde-c780ea21d3b5 --- otime.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- otime.h | 36 ++++++++++++++++++++++++++++++++++++ syshead.h | 2 +- 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? -- cgit