diff options
Diffstat (limited to 'openvpn/src/compat/compat-gettimeofday.c')
-rw-r--r-- | openvpn/src/compat/compat-gettimeofday.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/openvpn/src/compat/compat-gettimeofday.c b/openvpn/src/compat/compat-gettimeofday.c new file mode 100644 index 00000000..0f32d5d1 --- /dev/null +++ b/openvpn/src/compat/compat-gettimeofday.c @@ -0,0 +1,131 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#ifndef HAVE_GETTIMEOFDAY + +#include "compat.h" + +#ifdef WIN32 +/* + * NOTICE: mingw has much faster gettimeofday! + * autoconf will set HAVE_GETTIMEOFDAY + */ + +#include <windows.h> +#include <time.h> + +static time_t gtc_base = 0; +static DWORD gtc_last = 0; +static time_t last_sec = 0; +static unsigned int last_msec = 0; +static int bt_last = 0; + +static void +gettimeofday_calibrate (void) +{ + const time_t t = time(NULL); + const DWORD gtc = GetTickCount(); + gtc_base = t - gtc/1000; + 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) +{ + const DWORD gtc = GetTickCount(); + int bt = 0; + time_t sec; + unsigned int msec; + const int backtrack_hold_seconds = 10; + + (void)tz; + + /* recalibrate at the dreaded 49.7 day mark */ + if (!gtc_base || gtc < gtc_last) + gettimeofday_calibrate (); + gtc_last = gtc; + + sec = gtc_base + gtc / 1000; + msec = gtc % 1000; + + if (sec == last_sec) + { + if (msec < last_msec) + { + msec = last_msec; + bt = 1; + } + } + 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; + msec = last_msec; + } + bt = 1; + } + + tv->tv_sec = (long)last_sec = (long)sec; + tv->tv_usec = (last_msec = msec) * 1000; + + if (bt && !bt_last) + gettimeofday_calibrate (); + bt_last = bt; + + return 0; +} + +#else + +#ifdef HAVE_TIME_H +#include <time.h> +#endif + +int +gettimeofday (struct timeval *tv, void *tz) +{ + (void)tz; + tv->tv_sec = time(NULL); + tv->tv_usec = 0; + return 0; +} + +#endif /* WIN32 */ + +#endif /* HAVE_GETTIMEOFDAY */ |