*/
/*
* This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
+ * Copyright (C) 1997-2000,2003,2006,2014-2016,2020 Ian Jackson
* Copyright (C) 2014 Mark Wooding
* Copyright (C) 1999-2000,2003,2006 Tony Finch
* Copyright (C) 1991 Massachusetts Institute of Technology
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <time.h>
#include "internal.h"
#include "tvarith.h"
/* Timeout handling functions. */
+int adns__gettimeofday(adns_state ads, struct timeval *tv) {
+ if (!(ads->iflags & adns_if_monotonic))
+ return gettimeofday(tv,0);
+
+ struct timespec ts;
+ int r = clock_gettime(CLOCK_MONOTONIC,&ts);
+ if (r) return r;
+
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ return 0;
+}
+
void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
struct timeval *tv_buf) {
const struct timeval *now;
now= *now_io;
if (now) return;
- r= gettimeofday(tv_buf,0); if (!r) { *now_io= tv_buf; return; }
- adns__diag(ads,-1,0,"gettimeofday failed: %s",strerror(errno));
+ r= adns__gettimeofday(ads,tv_buf); if (!r) { *now_io= tv_buf; return; }
+ adns__diag(ads,-1,0,"gettimeofday/clock_gettime failed: %s",
+ strerror(errno));
adns_globalsystemfailure(ads);
return;
}
struct timeval **tv_io, struct timeval *tvbuf,
struct timeval now, struct query_queue *queue) {
adns_query qu, nqu;
+ struct timeval expires;
for (qu= queue->head; qu; qu= nqu) {
nqu= qu->next;
- if (!timercmp(&now,&qu->timeout,>)) {
- inter_maxtoabs(tv_io,tvbuf,now,qu->timeout);
+ if (timercmp(&now,&qu->timeout_started,<)) /* clock rewound */
+ qu->timeout_started= now;
+ expires= qu->timeout_started;
+ timevaladd(&expires, qu->timeout_ms);
+ if (!timercmp(&now,&expires,>)) {
+ inter_maxtoabs(tv_io,tvbuf,now,expires);
} else {
if (!act) { inter_immed(tv_io,tvbuf); return; }
LIST_UNLINK(*queue,qu);
adns__consistency(ads,0,cc_enter);
- r= gettimeofday(&now,0);
+ r= adns__gettimeofday(ads,&now);
if (!r) adns_processtimeouts(ads,&now);
/* We just use adns__fdevents to loop over the fd's trying them.
int r;
adns__consistency(ads,*query_io,cc_enter);
- r= gettimeofday(&now,0);
+ r= adns__gettimeofday(ads,&now);
if (!r) adns__autosys(ads,now);
r= adns__internal_check(ads,query_io,answer_r,context_r);