Use monotonic clock for timeouts
authorSteven Barth <steven@midlink.org>
Tue, 28 Oct 2014 08:57:24 +0000 (09:57 +0100)
committerSteven Barth <steven@midlink.org>
Tue, 28 Oct 2014 11:31:47 +0000 (12:31 +0100)
Signed-off-by: Steven Barth <steven@midlink.org>
cache.c
service.c
util.c
util.h

diff --git a/cache.c b/cache.c
index f2687e115b50a386dfdc50e1abf9210d5d028e5c..11d359dff9c512c3608058bb150ea039d4a60181 100644 (file)
--- a/cache.c
+++ b/cache.c
@@ -63,7 +63,7 @@ cache_service_free(struct cache_service *s)
 static int
 cache_is_expired(time_t t, uint32_t ttl, int frac)
 {
-       if (time(NULL) - t >= ttl * frac / 100)
+       if (monotonic_time() - t >= ttl * frac / 100)
                return 1;
 
        return 0;
@@ -142,7 +142,7 @@ cache_service(struct interface *iface, char *entry, int hlen, int ttl)
        avl_for_each_element_safe(&services, s, avl, t)
                if (!strcmp(s->entry, entry)) {
                        s->refresh = 50;
-                       s->time = time(NULL);
+                       s->time = monotonic_time();
                        return s;
                }
 
@@ -151,7 +151,7 @@ cache_service(struct interface *iface, char *entry, int hlen, int ttl)
                &host_buf, hlen ? hlen + 1 : 0);
 
        s->avl.key = s->entry = strcpy(entry_buf, entry);
-       s->time = time(NULL);
+       s->time = monotonic_time();
        s->ttl = ttl;
        s->iface = iface;
        s->refresh = 50;
@@ -311,7 +311,7 @@ cache_answer(struct interface *iface, uint8_t *base, int blen, char *name, struc
        if (r) {
                if (!a->ttl) {
                        DBG(1, "D -> %s %s ttl:%d\n", dns_type_string(r->type), r->record, r->ttl);
-                       r->time = time(0) + 1 - r->ttl;
+                       r->time = monotonic_time() + 1 - r->ttl;
                } else {
                        r->ttl = a->ttl;
                        DBG(1, "A -> %s %s ttl:%d\n", dns_type_string(r->type), r->record, r->ttl);
@@ -332,7 +332,7 @@ cache_answer(struct interface *iface, uint8_t *base, int blen, char *name, struc
        r->ttl = a->ttl;
        r->port = port;
        r->rdlength = dlen;
-       r->time = time(NULL);
+       r->time = monotonic_time();
        r->iface = iface;
 
        if (tlen)
index db4694ebc7309991ac8e8fe5e8b8cf1a9cd65b06..0b42aeeb3c47c90bdc08c3f494044dd70df27e48 100644 (file)
--- a/service.c
+++ b/service.c
@@ -113,7 +113,7 @@ service_add_srv(struct service *s, int ttl)
 static int
 service_timeout(struct service *s)
 {
-       time_t t = time(NULL);
+       time_t t = monotonic_time();
 
        if (t - s->t <= TOUT_LOOKUP)
                return 0;
diff --git a/util.c b/util.c
index f0517b42fe30837ba7ef37712e1dc0ac727fc28b..d3d4d5541ae64b4e3891d53d2a5d0d289531549e 100644 (file)
--- a/util.c
+++ b/util.c
@@ -73,3 +73,10 @@ void get_hostname(void)
        snprintf(mdns_hostname, sizeof(mdns_hostname), "%s", utsname.nodename);
        snprintf(mdns_hostname_local, sizeof(mdns_hostname_local), "%s.local", utsname.nodename);
 }
+
+time_t monotonic_time(void)
+{
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+       return ts.tv_sec;
+}
diff --git a/util.h b/util.h
index 1a01fccd37b05eaeeccc29779e32dfd535374c70..efee5dc3589e3b42abc9cacd592c89b9bf7c32b9 100644 (file)
--- a/util.h
+++ b/util.h
@@ -15,6 +15,7 @@
 #define _UTIL_H__
 
 #include <stdint.h>
+#include <time.h>
 
 #define DBG(level, fmt, ...) do { \
        if (debug >= level) \
@@ -31,5 +32,6 @@ extern char mdns_hostname_local[HOSTNAME_LEN + 6];
 
 extern void get_hostname(void);
 extern uint32_t rand_time_delta(uint32_t t);
+extern time_t monotonic_time(void);
 
 #endif