diff options
-rw-r--r-- | configure.in | 24 | ||||
-rw-r--r-- | src/libstrongswan/asn1/asn1.c | 35 |
2 files changed, 49 insertions, 10 deletions
diff --git a/configure.in b/configure.in index fe60e63b4..95635b740 100644 --- a/configure.in +++ b/configure.in @@ -774,10 +774,6 @@ AC_SEARCH_LIBS(dlopen, dl, [DLLIB=$LIBS]) LIBS=$saved_LIBS AC_SUBST(DLLIB) -AC_CHECK_FUNCS(backtrace) -AC_CHECK_FUNCS(prctl) -AC_CHECK_FUNCS(gethostbyname_r) - AC_MSG_CHECKING(for dladdr) AC_TRY_COMPILE( [#define _GNU_SOURCE @@ -788,6 +784,26 @@ AC_TRY_COMPILE( [AC_MSG_RESULT([no])] ) +AC_CHECK_FUNCS(backtrace) +AC_CHECK_FUNCS(prctl) +AC_CHECK_FUNCS(gethostbyname_r) +AC_CHECK_FUNCS(timegm) + +AC_MSG_CHECKING(for timezone variable) +AC_TRY_LINK( + [#include <time.h>], + [/* check for timezone function (e.g. FreeBSD) */ + return (int)timezone(0, 0);], + [AC_MSG_RESULT([no])], + [AC_TRY_LINK( + [#include <time.h>], + [/* check for global variable */ + return (int)timezone;], + [AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_VAR_TIMEZONE])], + [AC_MSG_RESULT([no])] + )] +) + AC_CHECK_HEADERS(net/pfkeyv2.h netipsec/ipsec.h) AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 5ca7e28f0..c4787d245 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -18,6 +18,7 @@ #include <stdio.h> #include <string.h> #include <time.h> +#include <pthread.h> #include <utils.h> #include <debug.h> @@ -300,13 +301,26 @@ u_int asn1_length(chunk_t *blob) #define TIME_MAX 0x7fffffff +#if !defined(HAVE_TIMEGM) && !defined(HAVE_VAR_TIMEZONE) +pthread_once_t utc_offset_once = PTHREAD_ONCE_INIT; +static time_t utc_offset; +static void init_utc_offset() +{ + time_t now; + struct tm utc; + now = time(NULL); + gmtime_r(&now, &utc); + utc_offset = mktime(&utc) - now; +} +#endif + /** * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time */ time_t asn1_to_time(const chunk_t *utctime, asn1_t type) { - struct tm t, local; - time_t tc, tz_offset, now; + struct tm t; + time_t tc, tz_offset; u_char *eot = NULL; if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL) @@ -372,17 +386,26 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type) t.tm_isdst = 0; /* convert to time_t */ +#ifdef HAVE_TIMEGM + tc = timegm(&t); +#else tc = mktime(&t); - +#endif if (tc == -1) { return TIME_MAX; } /* if no conversion overflow occurred, compensate timezone */ - now = time(NULL); - localtime_r(&now, &local); - return tc - local.tm_gmtoff - tz_offset; +#ifndef HAVE_TIMEGM +#ifdef HAVE_VAR_TIMEZONE + tz_offset += timezone; +#else + pthread_once(&utc_offset_once, init_utc_offset); + tz_offset += utc_offset; +#endif +#endif + return tc - tz_offset; } /** |