diff options
-rw-r--r-- | init.c | 5 | ||||
-rw-r--r-- | otime.c | 146 | ||||
-rw-r--r-- | otime.h | 37 | ||||
-rw-r--r-- | syshead.h | 2 |
4 files changed, 81 insertions, 109 deletions
@@ -286,6 +286,11 @@ init_static (void) return false; #endif +#ifdef TIME_TEST + time_test (); + return false; +#endif + return true; } @@ -36,51 +36,10 @@ time_t now = 0; /* GLOBAL */ -#if TIME_BACKTRACK_PROTECTION - -static time_t now_adj = 0; /* GLOBAL */ - -/* - * 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 threshold = 86400; /* threshold at which to dampen forward jumps */ - time_t real_time = system_time + now_adj; - if (real_time > now) - { - const time_t overshoot = real_time - now - 1; - if (overshoot > threshold && now_adj >= overshoot) - { - now_adj -= overshoot; - real_time -= overshoot; - } - now = real_time; - } - else if (real_time < now) - { - now_adj += (now - real_time); - } -} - #ifdef HAVE_GETTIMEOFDAY time_t now_usec = 0; /* GLOBAL */ -void -update_now_usec (struct timeval *tv) -{ - const time_t last = now; - update_now (tv->tv_sec); - if (now > last || tv->tv_usec > now_usec) - now_usec = tv->tv_usec; -} - -#endif - #endif /* @@ -193,53 +152,84 @@ frequency_limit_event_allowed (struct frequency_limit *f) #ifdef WIN32 -static double counterPerMicrosecond = -1.0; /* GLOBAL */ -static unsigned __int64 frequency = 0; /* GLOBAL */ -static unsigned __int64 timeSecOffset = 0; /* GLOBAL */ -static unsigned __int64 startPerformanceCounter = 0; /* GLOBAL */ +static time_t gtc_base = 0; +static DWORD gtc_last = 0; +static time_t last_sec = 0; +static unsigned int last_msec = 0; +static bool bt_last = false; -/* - * gettimeofday for windows - * - * CounterPerMicrosecond is the number of counts per microsecond. - * Double is required if we have less than 1 counter per microsecond. This has not been tested. - * On a PIII 700, I get about 3.579545. This is guaranteed not to change while the processor is running. - * We really don't need to check for loop detection. On my machine it would take about 59645564 days to loop. - * (2^64) / frequency / 60 / 60 / 24. - * - */ -int -gettimeofday(struct timeval *tv, void *tz) +static void +gettimeofday_calibrate (void) { - unsigned __int64 counter; - - QueryPerformanceCounter((LARGE_INTEGER *) &counter); - - if (counter < startPerformanceCounter || counterPerMicrosecond == -1.0) - { - time_t t; - mutex_lock (L_GETTIMEOFDAY); - - QueryPerformanceFrequency((LARGE_INTEGER *) &frequency); - - counterPerMicrosecond = (double) ((__int64) frequency) / 1000000.0f; + const time_t t = time(NULL); + const DWORD gtc = GetTickCount(); + gtc_base = t - gtc/1000; + gtc_last = gtc; +} - time(&t); - QueryPerformanceCounter((LARGE_INTEGER *) &counter); - startPerformanceCounter = counter; +int +gettimeofday (struct timeval *tv, void *tz) +{ + const DWORD gtc = GetTickCount(); + bool bt = false; + time_t sec; + unsigned int msec; + const int backtrack_hold_seconds = 10; - counter /= frequency; + if (!gtc_base || gtc < gtc_last) + gettimeofday_calibrate (); + gtc_last = gtc; - timeSecOffset = t - counter; + sec = gtc_base + gtc / 1000; + msec = gtc % 1000; - mutex_unlock (L_GETTIMEOFDAY); - QueryPerformanceCounter((LARGE_INTEGER *) &counter); + if (sec == last_sec) + { + if (msec < last_msec) + { + msec = last_msec; + bt = true; + } + } + else if (sec < last_sec) + { + if (sec > last_sec - backtrack_hold_seconds) + { + sec = last_sec; + msec = last_msec; + } + bt = true; } - tv->tv_sec = (counter / frequency) + timeSecOffset; - tv->tv_usec = ((__int64) (((__int64) counter) / counterPerMicrosecond) % 1000000); + tv->tv_sec = last_sec = sec; + tv->tv_usec = (last_msec = msec) * 1000; + + if (bt && !bt_last) + gettimeofday_calibrate (); + bt_last = bt; return 0; } #endif /* WIN32 */ + +#ifdef TIME_TEST +void +time_test (void) +{ + struct timeval tv; + time_t t; + int i; + for (i = 0; i < 10000; ++i) + { + t = time(NULL); + gettimeofday (&tv, NULL); +#if 1 + msg (M_INFO, "t=%u s=%u us=%u", + (unsigned int)t, + (unsigned int)tv.tv_sec, + (unsigned int)tv.tv_usec); +#endif + } +} +#endif @@ -56,44 +56,23 @@ const char *tv_string_abs (const struct timeval *tv, struct gc_arena *gc); extern time_t now; /* updated frequently to time(NULL) */ -#if TIME_BACKTRACK_PROTECTION - -void update_now (const time_t system_time); +void time_test (void); static inline void update_time (void) { - update_now (time (NULL)); -} - -#ifdef HAVE_GETTIMEOFDAY - -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) +#if defined(WIN32) && defined(HAVE_GETTIMEOFDAY) + struct timeval tv; + if (!gettimeofday (&tv, NULL)) { - update_now_usec (tv); - tv->tv_sec = now; - tv->tv_usec = now_usec; + if (tv.tv_sec != now) + now = tv.tv_sec; } - return status; -} - -#endif - #else - -static inline void -update_time (void) -{ const time_t real_time = time (NULL); if (real_time != now) now = real_time; +#endif } #ifdef HAVE_GETTIMEOFDAY @@ -106,8 +85,6 @@ openvpn_gettimeofday (struct timeval *tv, void *tz) #endif -#endif - static inline time_t openvpn_time (time_t *t) { @@ -498,7 +498,7 @@ socket_defined (const socket_descriptor_t sd) * Reduce sensitivity to system clock instability * and backtracks. */ -#define TIME_BACKTRACK_PROTECTION 1 +//#define TIME_BACKTRACK_PROTECTION 1 // JYFIXME /* * Is non-blocking connect() supported? |