The dnsmasq_time() function, in the case of HAVE_BROKEN_RTC, was calling times() to read the number of ticks "elapsed since an arbitrary point in the past" and then dividing that by sysconf(_SC_CLK_TCK) to compute the number of seconds elapsed since that arbitrary instant. This works fine until the number of ticks exceeds 2^31, beyond which time the function would begin erroneously returning negative times. On my system this happens after approximately 248 days of uptime. A symptom is that dnsmasq no longer populates the resolver cache with DHCP-derived names at startup, as the inserted cache entries immediately expire due to having negative expiration times that cause is_expired() to return true when called with now==0.
This commit replaces the archaic implementation of dnsmasq_time() with a call to the POSIX-standardized clock_gettime(CLOCK_MONOTONIC), thereby eliminating the need to convert manually from ticks to seconds. The new implementation will yield correct results until the system uptime exceeds approximately 68 years. Signed-off-by: Matt Whitlock <dnsm...@mattwhitlock.name> --- src/util.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/util.c b/src/util.c index 1425764..b2179d0 100644 --- a/src/util.c +++ b/src/util.c @@ -408,13 +408,12 @@ int hostname_issubdomain(char *a, char *b) time_t dnsmasq_time(void) { #ifdef HAVE_BROKEN_RTC - struct tms dummy; - static long tps = 0; + struct timespec ts; - if (tps == 0) - tps = sysconf(_SC_CLK_TCK); + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) + die(_("cannot read monotonic clock: %s"), NULL, EC_MISC); - return (time_t)(times(&dummy)/tps); + return ts.tv_sec; #else return time(NULL); #endif -- 2.33.0 _______________________________________________ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss