diff options
-rw-r--r-- | init.c | 2 | ||||
-rw-r--r-- | interval.h | 4 | ||||
-rw-r--r-- | multi.c | 2 | ||||
-rw-r--r-- | multi.h | 2 | ||||
-rw-r--r-- | otime.c | 49 | ||||
-rw-r--r-- | otime.h | 55 | ||||
-rw-r--r-- | pkcs11-helper.c | 6 | ||||
-rw-r--r-- | shaper.h | 4 | ||||
-rw-r--r-- | syshead.h | 6 |
9 files changed, 119 insertions, 11 deletions
@@ -2160,9 +2160,11 @@ do_setup_fast_io (struct context *c) msg (M_INFO, "NOTE: --fast-io is disabled since we are not using UDP"); else { +#ifdef HAVE_GETTIMEOFDAY if (c->options.shaper) msg (M_INFO, "NOTE: --fast-io is disabled since we are using --shaper"); else +#endif { c->c2.fast_io = true; } @@ -213,13 +213,13 @@ static inline void usec_timer_start (struct usec_timer *obj) { CLEAR (*obj); - gettimeofday (&obj->start, NULL); + openvpn_gettimeofday (&obj->start, NULL); } static inline void usec_timer_end (struct usec_timer *obj) { - gettimeofday (&obj->end, NULL); + openvpn_gettimeofday (&obj->end, NULL); } #endif /* HAVE_GETTIMEOFDAY */ @@ -1667,7 +1667,7 @@ multi_process_post (struct multi_context *m, struct multi_instance *mi, const un if (!IS_SIG (&mi->context)) { /* calculate an absolute wakeup time */ - ASSERT (!gettimeofday (&mi->wakeup, NULL)); + ASSERT (!openvpn_gettimeofday (&mi->wakeup, NULL)); tv_add (&mi->wakeup, &mi->context.c2.timeval); /* tell scheduler to wake us up at some point in the future */ @@ -376,7 +376,7 @@ multi_get_timeout (struct multi_context *m, struct timeval *dest) m->earliest_wakeup = (struct multi_instance *) schedule_get_earliest_wakeup (m->schedule, &tv); if (m->earliest_wakeup) { - ASSERT (!gettimeofday (¤t, NULL)); + ASSERT (!openvpn_gettimeofday (¤t, NULL)); tv_delta (dest, ¤t, &tv); if (dest->tv_sec >= REAP_MAX_WAKEUP) { @@ -34,7 +34,54 @@ #include "memdbg.h" -volatile time_t now; /* GLOBAL */ +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 /* * Return a numerical string describing a struct timeval. @@ -54,7 +54,39 @@ const char* time_string (time_t t, int usec, bool show_usec, struct gc_arena *gc const char *tv_string (const struct timeval *tv, struct gc_arena *gc); const char *tv_string_abs (const struct timeval *tv, struct gc_arena *gc); -extern volatile time_t now; /* updated frequently to time(NULL) */ +extern time_t now; /* updated frequently to time(NULL) */ + +#if TIME_BACKTRACK_PROTECTION + +void update_now (const time_t system_time); + +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) + { + update_now_usec (tv); + tv->tv_sec = now; + tv->tv_usec = now_usec; + } + return status; +} + +#endif + +#else static inline void update_time (void) @@ -64,6 +96,27 @@ update_time (void) now = real_time; } +#ifdef HAVE_GETTIMEOFDAY + +static inline int +openvpn_gettimeofday (struct timeval *tv, void *tz) +{ + return gettimeofday (tv, tz); +} + +#endif + +#endif + +static inline time_t +openvpn_time (time_t *t) +{ + update_time (); + if (t) + *t = now; + return now; +} + static inline void tv_clear (struct timeval *tv) { diff --git a/pkcs11-helper.c b/pkcs11-helper.c index 9eb074e..181c31f 100644 --- a/pkcs11-helper.c +++ b/pkcs11-helper.c @@ -870,7 +870,7 @@ _pkcs11h_getSession ( } else { (*session)->timePINExpire = ( - time (NULL) + + openvpn_time (NULL) + (time_t)nPINCachePeriod ); (*session)->nPINCachePeriod = nPINCachePeriod; @@ -1095,7 +1095,7 @@ _pkcs11h_validateSession ( if ( session->timePINExpire != (time_t)0 && - session->timePINExpire < time (NULL) + session->timePINExpire < openvpn_time (NULL) ) { _pkcs11h_logout (session); } @@ -1195,7 +1195,7 @@ _pkcs11h_login ( } else { session->timePINExpire = ( - time (NULL) + + openvpn_time (NULL) + (time_t)session->nPINCachePeriod ); } @@ -109,7 +109,7 @@ shaper_delay (struct shaper* s) if (tv_defined (&s->wakeup)) { - ASSERT (!gettimeofday (&tv, NULL)); + ASSERT (!openvpn_gettimeofday (&tv, NULL)); delay = tv_subtract (&s->wakeup, &tv, SHAPER_MAX_TIMEOUT); #ifdef SHAPER_DEBUG dmsg (D_SHAPER_DEBUG, "SHAPER shaper_delay delay=%d", delay); @@ -143,7 +143,7 @@ shaper_wrote_bytes (struct shaper* s, int nbytes) if (tv.tv_usec) { - ASSERT (!gettimeofday (&s->wakeup, NULL)); + ASSERT (!openvpn_gettimeofday (&s->wakeup, NULL)); tv_add (&s->wakeup, &tv); #ifdef SHAPER_DEBUG @@ -472,4 +472,10 @@ socket_defined (const socket_descriptor_t sd) */ #define ENABLE_INLINE_FILES 1 +/* + * Reduce sensitivity to system clock instability + * and backtracks. + */ +#define TIME_BACKTRACK_PROTECTION 1 + #endif |