From bee5408506a4923fbf94c891e16a126a3506321e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 5 Mar 2017 21:17:47 +0000 Subject: [PATCH] timeout robustness: Track start time and duration This allows us to detect if the clock rewinds, and restart our timeouts from the new time. Otherwise we might try to wait a very long time. The result is that clock instability may now produce spurious failures of some queries, but it should no longer cause queries to be indefinitely delayed. Signed-off-by: Ian Jackson --- src/event.c | 14 +++++++------- src/internal.h | 13 +++++++++---- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/event.c b/src/event.c index 845bc69..10d64b1 100644 --- a/src/event.c +++ b/src/event.c @@ -149,11 +149,6 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) { /* Timeout handling functions. */ -void adns__timeout_set(adns_query qu, struct timeval now, int ms) { - qu->timeout_expires= now; - timevaladd(&qu->timeout_expires,ms); -} - void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, struct timeval *tv_buf) { const struct timeval *now; @@ -214,11 +209,16 @@ static void timeouts_queue(adns_state ads, int act, 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_expires,>)) { - inter_maxtoabs(tv_io,tvbuf,now,qu->timeout_expires); + 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); diff --git a/src/internal.h b/src/internal.h index 23c7aa6..121c6d8 100644 --- a/src/internal.h +++ b/src/internal.h @@ -298,7 +298,8 @@ struct adns__query { int id, flags, retries; int udpnextserver; unsigned long udpsent; /* bitmap indexed by server */ - struct timeval timeout_expires; + int timeout_ms; + struct timeval timeout_started; time_t expires; /* Earliest expiry time of any record we used. */ qcontext ctx; @@ -885,9 +886,13 @@ void adns__autosys(adns_state ads, struct timeval now); * lest we end up in recursive descent ! */ -void adns__timeout_set(adns_query qu, struct timeval now, int ms); -static inline void adns__timeout_clear(adns_query qu) - { timerclear(&qu->timeout_expires); } +static inline void +adns__timeout_set(adns_query qu, struct timeval now, long ms) + { qu->timeout_ms= ms; qu->timeout_started= now; } + +static inline void +adns__timeout_clear(adns_query qu) + { qu->timeout_ms= 0; timerclear(&qu->timeout_started); } void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io, -- 2.30.2