]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Replace custom uptime() with clock_gettime(2) calls for more accurate
authorRoy Marples <roy@marples.name>
Mon, 29 Jun 2015 12:39:44 +0000 (12:39 +0000)
committerRoy Marples <roy@marples.name>
Mon, 29 Jun 2015 12:39:44 +0000 (12:39 +0000)
time handling.

common.c
common.h
dhcp.c
dhcp.h
dhcp6.c
dhcp6.h
ipv4ll.c
ipv4ll.h

index f81663f60bb3d45bdd933e0158f6e9582f546c80..39f5086e20c2175705910b4b6bf3875dacaf9d58 100644 (file)
--- a/common.c
+++ b/common.c
@@ -254,17 +254,6 @@ addvard(struct dhcpcd_ctx *ctx,
        return addvar(ctx, e, prefix, var, buffer);
 }
 
-
-time_t
-uptime(void)
-{
-       struct timespec tv;
-
-       if (clock_gettime(CLOCK_MONOTONIC, &tv) == -1)
-               return -1;
-       return tv.tv_sec;
-}
-
 char *
 hwaddr_ntoa(const unsigned char *hwaddr, size_t hwlen, char *buf, size_t buflen)
 {
index dfbc2e94218698d595d09090537ac06f2e0485a9..061e94ceb5938e6cbbf8c0092d4eca0fe9acc589 100644 (file)
--- a/common.h
+++ b/common.h
@@ -191,7 +191,6 @@ ssize_t addvar(struct dhcpcd_ctx *,
     char ***, const char *, const char *, const char *);
 ssize_t addvard(struct dhcpcd_ctx *,
     char ***, const char *, const char *, size_t);
-time_t uptime(void);
 
 char *hwaddr_ntoa(const unsigned char *, size_t, char *, size_t);
 size_t hwaddr_aton(unsigned char *, const char *);
diff --git a/dhcp.c b/dhcp.c
index 67f3f90e9092b3ba9491f8c5d9a32da9a5f43b3c..1b35924c0c8a80f07424b5bc50eab1ad1dd2f05c 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -736,7 +736,6 @@ make_message(struct dhcp_message **message,
        struct if_options *ifo = ifp->options;
        const struct dhcp_state *state = D_CSTATE(ifp);
        const struct dhcp_lease *lease = &state->lease;
-       time_t up = uptime() - state->start_uptime;
        char hbuf[HOSTNAME_MAX_LEN + 1];
        const char *hostname;
        const struct vivco *vivco;
@@ -776,10 +775,14 @@ make_message(struct dhcp_message **message,
                dhcp->flags = htons(BROADCAST_FLAG);
 
        if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
-               if (up < 0 || up > (time_t)UINT16_MAX)
+               struct timespec tv;
+
+               clock_gettime(CLOCK_MONOTONIC, &tv);
+               timespecsub(&tv, &state->started, &tv);
+               if (tv.tv_sec < 0 || tv.tv_sec > (time_t)UINT16_MAX)
                        dhcp->secs = htons((uint16_t)UINT16_MAX);
                else
-                       dhcp->secs = htons((uint16_t)up);
+                       dhcp->secs = htons((uint16_t)tv.tv_sec);
        }
        dhcp->xid = htonl(state->xid);
        dhcp->cookie = htonl(MAGIC_COOKIE);
@@ -3158,7 +3161,7 @@ dhcp_start1(void *arg)
        }
 
        state = D_STATE(ifp);
-       state->start_uptime = uptime();
+       clock_gettime(CLOCK_MONOTONIC, &state->started);
        free(state->offer);
        state->offer = NULL;
 
diff --git a/dhcp.h b/dhcp.h
index 78c6a0ea51d1708900a03944cc10248318832df3..04d1df8ab6f6d8eb579dd7a7d6f73887ea82884b 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -218,7 +218,7 @@ struct dhcp_state {
        uint8_t added;
 
        char leasefile[sizeof(LEASEFILE) + IF_NAMESIZE + (IF_SSIDSIZE * 4)];
-       time_t start_uptime;
+       struct timespec started;
        unsigned char *clientid;
        struct authstate auth;
        size_t arping_index;
diff --git a/dhcp6.c b/dhcp6.c
index d7c742bcfd4e63fa38fd5c5fb6d2d4bf4759ce42..8b6fbc130d3860049afe3aa882ce9ecf5767bdf8 100644 (file)
--- a/dhcp6.c
+++ b/dhcp6.c
@@ -299,7 +299,7 @@ dhcp6_updateelapsed(struct interface *ifp, struct dhcp6_message *m, size_t len)
        struct dhcp6_state *state;
        const struct dhcp6_option *co;
        struct dhcp6_option *o;
-       time_t up;
+       struct timespec tv;
        uint16_t u16;
 
        co = dhcp6_getmoption(D6_OPTION_ELAPSED, m, len);
@@ -308,10 +308,10 @@ dhcp6_updateelapsed(struct interface *ifp, struct dhcp6_message *m, size_t len)
 
        o = __UNCONST(co);
        state = D6_STATE(ifp);
-       up = uptime() - state->start_uptime;
-       if (up < 0 || up > (time_t)UINT16_MAX)
-               up = (time_t)UINT16_MAX;
-       u16 = htons((uint16_t)up);
+       clock_gettime(CLOCK_MONOTONIC, &tv);
+       if (tv.tv_sec < 0 || tv.tv_sec > (time_t)UINT16_MAX)
+               tv.tv_sec = (time_t)UINT16_MAX;
+       u16 = htons((uint16_t)tv.tv_sec);
        memcpy(D6_OPTION_DATA(o), &u16, sizeof(u16));
        return 0;
 }
@@ -1235,7 +1235,7 @@ dhcp6_startrenew(void *arg)
        ifp = arg;
        state = D6_STATE(ifp);
        state->state = DH6S_RENEW;
-       state->start_uptime = uptime();
+       clock_gettime(CLOCK_MONOTONIC, &state->started);
        state->RTC = 0;
        state->IRT = REN_TIMEOUT;
        state->MRT = REN_MAX_RT;
@@ -1375,7 +1375,7 @@ dhcp6_startdiscover(void *arg)
        logger(ifp->ctx, LOG_INFO, "%s: soliciting a DHCPv6 lease", ifp->name);
        state = D6_STATE(ifp);
        state->state = DH6S_DISCOVER;
-       state->start_uptime = uptime();
+       clock_gettime(CLOCK_MONOTONIC, &state->started);
        state->RTC = 0;
        state->IMD = SOL_MAX_DELAY;
        state->IRT = SOL_TIMEOUT;
@@ -1535,7 +1535,7 @@ dhcp6_startconfirm(struct interface *ifp)
 
        state = D6_STATE(ifp);
        state->state = DH6S_CONFIRM;
-       state->start_uptime = uptime();
+       clock_gettime(CLOCK_MONOTONIC, &state->started);
        state->RTC = 0;
        state->IMD = CNF_MAX_DELAY;
        state->IRT = CNF_TIMEOUT;
@@ -1566,7 +1566,7 @@ dhcp6_startinform(void *arg)
                logger(ifp->ctx, LOG_INFO,
                    "%s: requesting DHCPv6 information", ifp->name);
        state->state = DH6S_INFORM;
-       state->start_uptime = uptime();
+       clock_gettime(CLOCK_MONOTONIC, &state->started);
        state->RTC = 0;
        state->IMD = INF_MAX_DELAY;
        state->IRT = INF_TIMEOUT;
@@ -1621,7 +1621,7 @@ dhcp6_startrelease(struct interface *ifp)
                return;
 
        state->state = DH6S_RELEASE;
-       state->start_uptime = uptime();
+       clock_gettime(CLOCK_MONOTONIC, &state->started);
        state->RTC = 0;
        state->IRT = REL_TIMEOUT;
        state->MRT = 0;
diff --git a/dhcp6.h b/dhcp6.h
index c32d18ae322abe5919ef96d34738b84963fb1e9c..d1a4372329fe620cbb6e2a0d5740fc463ab535a5 100644 (file)
--- a/dhcp6.h
+++ b/dhcp6.h
@@ -170,7 +170,7 @@ enum DH6S {
 
 struct dhcp6_state {
        enum DH6S state;
-       time_t start_uptime;
+       struct timespec started;
 
        /* Message retransmission timings */
        struct timespec RT;
index f774424db3a0286a5baad62ac0942d2ac2a1b59f..136c5c9defdac9fcc8337bb1b6e265a8cda735ea 100644 (file)
--- a/ipv4ll.c
+++ b/ipv4ll.c
@@ -157,7 +157,7 @@ ipv4ll_probed(struct arp_state *astate)
            ifp->name, inet_ntoa(astate->addr));
 #endif
        state->addr = astate->addr;
-       state->defend = 0;
+       timespecclear(&state->defend);
        ipv4_buildroutes(ifp->ctx);
        arp_announce(astate);
        script_runreason(ifp, "IPV4LL");
@@ -214,11 +214,13 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
        arp_report_conflicted(astate, amsg);
 
        if (astate->failed.s_addr == state->addr.s_addr) {
-               time_t up;
+               struct timespec now, defend;
 
                /* RFC 3927 Section 2.5 */
-               up = uptime();
-               if (state->defend + DEFEND_INTERVAL > up) {
+               defend.tv_sec = state->defend.tv_sec + DEFEND_INTERVAL;
+               defend.tv_nsec = state->defend.tv_nsec;
+               clock_gettime(CLOCK_MONOTONIC, &now);
+               if (timespeccmp(&defend, &now, >)) {
                        logger(astate->iface->ctx, LOG_WARNING,
                            "%s: IPv4LL %d second defence failed for %s",
                            astate->iface->name, DEFEND_INTERVAL,
@@ -228,7 +230,7 @@ ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
                        logger(astate->iface->ctx, LOG_DEBUG,
                            "%s: defended IPv4LL address %s",
                            astate->iface->name, inet_ntoa(state->addr));
-                       state->defend = up;
+                       state->defend = now;
                        return;
                }
        }
index 9846b8b2e37d7c20c91e931657638b5dc730a288..b2072844fe5faf46550f95e9a737a9397365b823 100644 (file)
--- a/ipv4ll.h
+++ b/ipv4ll.h
@@ -42,7 +42,7 @@ struct ipv4ll_state {
        struct in_addr addr;
        struct arp_state *arp;
        unsigned int conflicts;
-       time_t defend;
+       struct timespec defend;
        char randomstate[128];
 };