diff -upNr b/lib/isc/include/isc/util.h a/lib/isc/include/isc/util.h --- b/lib/isc/include/isc/util.h 2019-07-30 19:52:09.600000000 +0800 +++ a/lib/isc/include/isc/util.h 2019-07-30 21:39:03.400000000 +0800 @@ -233,7 +233,7 @@ * Time */ #define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS) - +#define TIME_REAL_NOW(tp) RUNTIME_CHECK(isc_time_real_now((tp)) == ISC_R_SUCCESS) /*% * Alignment */ diff -upNr b/lib/isc/log.c a/lib/isc/log.c --- b/lib/isc/log.c 2019-07-30 19:52:09.610000000 +0800 +++ a/lib/isc/log.c 2019-07-30 21:39:03.410000000 +0800 @@ -1498,7 +1498,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcat time_string[0] == '\0') { isc_time_t isctime; - TIME_NOW(&isctime); + TIME_REAL_NOW(&isctime); isc_time_formattimestamp(&isctime, time_string, sizeof(time_string)); } @@ -1545,7 +1545,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcat * which fall within the duplicate_interval * range. */ - TIME_NOW(&oldest); + TIME_REAL_NOW(&oldest); if (isc_time_subtract(&oldest, &interval, &oldest) != ISC_R_SUCCESS) @@ -1622,7 +1622,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcat strlcpy(message->text, lctx->buffer, size); - TIME_NOW(&message->time); + TIME_REAL_NOW(&message->time); ISC_LINK_INIT(message, link); ISC_LIST_APPEND(lctx->messages, diff -upNr b/lib/isc/unix/include/isc/time.h a/lib/isc/unix/include/isc/time.h --- b/lib/isc/unix/include/isc/time.h 2019-07-30 19:52:09.600000000 +0800 +++ a/lib/isc/unix/include/isc/time.h 2019-07-30 21:39:03.400000000 +0800 @@ -149,6 +149,8 @@ isc_time_now(isc_time_t *t); */ isc_result_t +isc_time_real_now(isc_time_t *t); +isc_result_t isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i); /*%< * Set *t to the current absolute time + i. diff -upNr b/lib/isc/unix/time.c a/lib/isc/unix/time.c --- b/lib/isc/unix/time.c 2019-07-30 19:52:09.600000000 +0800 +++ a/lib/isc/unix/time.c 2019-07-30 21:39:03.400000000 +0800 @@ -36,6 +36,9 @@ #define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */ #define US_PER_S 1000000 /*%< Microseconds per second. */ +#ifndef ISC_FIX_TV_USEC +#define ISC_FIX_TV_USEC 1 +#endif #define CLOCKSOURCE CLOCK_MONOTONIC /*% @@ -44,6 +47,27 @@ static const isc_interval_t zero_interval = { 0, 0 }; const isc_interval_t * const isc_interval_zero = &zero_interval; +#if ISC_FIX_TV_USEC +static inline void +fix_tv_usec(struct timeval *tv) { + isc_boolean_t fixed = ISC_FALSE; + if (tv->tv_usec < 0) { + fixed = ISC_TRUE; + do { + tv->tv_sec -= 1; + tv->tv_usec += US_PER_S; + } while (tv->tv_usec < 0); + } else if (tv->tv_usec >= US_PER_S) { + fixed = ISC_TRUE; + do { + tv->tv_sec += 1; + tv->tv_usec -= US_PER_S; + } while (tv->tv_usec >=US_PER_S); + } + if (fixed) + (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected"); +} +#endif void isc_interval_set(isc_interval_t *i, @@ -105,6 +129,50 @@ isc_time_isepoch(const isc_time_t *t) { isc_result_t +isc_time_real_now(isc_time_t *t) { + struct timeval tv; + char strbuf[ISC_STRERRORSIZE]; + + REQUIRE(t != NULL); + + if (gettimeofday(&tv, NULL) == -1) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf); + return (ISC_R_UNEXPECTED); + } + + /* + * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, + * then this test will generate warnings for platforms on which it is + * unsigned. In any event, the chances of any of these problems + * happening are pretty much zero, but since the libisc library ensures + * certain things to be true ... + */ +#if ISC_FIX_TV_USEC + fix_tv_usec(&tv); + if (tv.tv_sec < 0) + return (ISC_R_UNEXPECTED); +#else + if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S) + return (ISC_R_UNEXPECTED); +#endif + + /* + * Ensure the tv_sec value fits in t->seconds. + */ + if (sizeof(tv.tv_sec) > sizeof(t->seconds) && + ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U) + return (ISC_R_RANGE); + + t->seconds = tv.tv_sec; + t->nanoseconds = tv.tv_usec * NS_PER_US; + + return (ISC_R_SUCCESS); +} + + + +isc_result_t isc_time_now(isc_time_t *t) { struct timespec ts; char strbuf[ISC_STRERRORSIZE];