aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init.c2
-rw-r--r--interval.h4
-rw-r--r--multi.c2
-rw-r--r--multi.h2
-rw-r--r--otime.c49
-rw-r--r--otime.h55
-rw-r--r--pkcs11-helper.c6
-rw-r--r--shaper.h4
-rw-r--r--syshead.h6
9 files changed, 119 insertions, 11 deletions
diff --git a/init.c b/init.c
index 0c9a509..53d1851 100644
--- a/init.c
+++ b/init.c
@@ -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;
}
diff --git a/interval.h b/interval.h
index 9845066..f56ed4d 100644
--- a/interval.h
+++ b/interval.h
@@ -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 */
diff --git a/multi.c b/multi.c
index f72d73b..f0b630b 100644
--- a/multi.c
+++ b/multi.c
@@ -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 */
diff --git a/multi.h b/multi.h
index da1e471..c796c23 100644
--- a/multi.h
+++ b/multi.h
@@ -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 (&current, NULL));
+ ASSERT (!openvpn_gettimeofday (&current, NULL));
tv_delta (dest, &current, &tv);
if (dest->tv_sec >= REAP_MAX_WAKEUP)
{
diff --git a/otime.c b/otime.c
index ad9cbbf..fbef02d 100644
--- a/otime.c
+++ b/otime.c
@@ -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.
diff --git a/otime.h b/otime.h
index 974d0af..6744c4d 100644
--- a/otime.h
+++ b/otime.h
@@ -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
);
}
diff --git a/shaper.h b/shaper.h
index 3aba241..975e825 100644
--- a/shaper.h
+++ b/shaper.h
@@ -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
diff --git a/syshead.h b/syshead.h
index 4c79286..9737a4b 100644
--- a/syshead.h
+++ b/syshead.h
@@ -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