From 3f310c0d1f664f5811327c5a89b5d6c2f3e42bdc Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 31 Aug 2009 15:03:35 +0200 Subject: [PATCH] implemented a monotonic timestamping function, unaffected from system time changes --- configure.in | 6 ++++++ src/libstrongswan/Makefile.am | 2 +- src/libstrongswan/utils.c | 33 +++++++++++++++++++++++++++++++++ src/libstrongswan/utils.h | 17 +++++++++++++++-- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index cc378169a..7caa8c1b3 100644 --- a/configure.in +++ b/configure.in @@ -908,6 +908,12 @@ AC_SEARCH_LIBS(socket, socket, [SOCKLIB=$LIBS], ) AC_SUBST(SOCKLIB) +dnl FreeBSD has clock_gettime in libc, Linux needs librt +LIBS="" +AC_SEARCH_LIBS(clock_gettime, rt, [RTLIB=$LIBS]) +AC_CHECK_FUNCS(clock_gettime) +AC_SUBST(RTLIB) + LIBS=$saved_LIBS dnl ====================== diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 922a37614..570c14e40 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -49,7 +49,7 @@ utils/mutex.c utils/mutex.h \ utils/backtrace.c utils/backtrace.h \ plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h -libstrongswan_la_LIBADD = -lpthread $(DLLIB) $(BTLIB) $(SOCKLIB) +libstrongswan_la_LIBADD = -lpthread $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) INCLUDES = -I$(top_srcdir)/src/libstrongswan AM_CFLAGS = \ diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c index 305841172..91242da2e 100644 --- a/src/libstrongswan/utils.c +++ b/src/libstrongswan/utils.c @@ -162,6 +162,39 @@ bool mkdir_p(const char *path, mode_t mode) return TRUE; } +/** + * Return monotonic time + */ +time_t time_monotonic(timeval_t *tv) +{ +#if defined(HAVE_CLOCK_GETTIME) + timespec_t ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + if (tv) + { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + } + return ts.tv_sec; + } +#endif /* HAVE_CLOCK_MONOTONIC */ + /* Fallback to non-monotonic timestamps: + * On MAC OS X, creating monotonic timestamps is rather difficult. We + * could use mach_absolute_time() and catch sleep/wakeup notifications. + * We stick to the simpler (non-monotonic) gettimeofday() for now. */ + if (!tv) + { + return time(NULL); + } + if (gettimeofday(tv, NULL) != 0) + { /* should actually never fail if passed pointers are valid */ + return -1; + } + return tv->tv_sec; +} + /** * return null */ diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h index 5d273d272..6b0990f5e 100644 --- a/src/libstrongswan/utils.h +++ b/src/libstrongswan/utils.h @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -269,12 +270,24 @@ void *memstr(const void *haystack, const char *needle, size_t n); /** * Creates a directory and all required parent directories. * - * @param path path to the new directory - * @param mode permissions of the new directory/directories + * @param path path to the new directory + * @param mode permissions of the new directory/directories * @return TRUE on success */ bool mkdir_p(const char *path, mode_t mode); +/** + * Get a timestamp from a monotonic time source. + * + * While the time()/gettimeofday() functions are affected by leap seconds + * and system time changes, this function returns ever increasing monotonic + * time stamps. + * + * @param tv timeval struct receiving monotonic timestamps, or NULL + * @return monotonic timestamp in seconds + */ +time_t time_monotonic(timeval_t *tv); + /** * returns null */