Replace timeval with timespec.

This commit is contained in:
Roy Marples 2015-03-03 17:27:25 +00:00
parent 3a8b97eed2
commit 573d048785
15 changed files with 181 additions and 165 deletions

12
arp.c
View File

@ -253,24 +253,24 @@ arp_probe1(void *arg)
{
struct arp_state *astate = arg;
struct interface *ifp = astate->iface;
struct timeval tv;
struct timespec tv;
if (++astate->probes < PROBE_NUM) {
tv.tv_sec = PROBE_MIN;
tv.tv_usec = (suseconds_t)arc4random_uniform(
(PROBE_MAX - PROBE_MIN) * 1000000);
timernorm(&tv);
tv.tv_nsec = (suseconds_t)arc4random_uniform(
(PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC);
timespecnorm(&tv);
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
} else {
tv.tv_sec = ANNOUNCE_WAIT;
tv.tv_usec = 0;
tv.tv_nsec = 0;
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
}
syslog(LOG_DEBUG,
"%s: ARP probing %s (%d of %d), next in %0.1f seconds",
ifp->name, inet_ntoa(astate->addr),
astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
timeval_to_double(&tv));
timespec_to_double(&tv));
if (arp_send(ifp, ARPOP_REQUEST, 0, astate->addr.s_addr) == -1)
syslog(LOG_ERR, "send_arp: %m");
}

View File

@ -89,18 +89,13 @@ get_hostname(char *buf, size_t buflen, int short_hostname)
*/
#define NO_MONOTONIC "host does not support a monotonic clock - timing can skew"
int
get_monotonic(struct timeval *tp)
get_monotonic(struct timespec *ts)
{
#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
tp->tv_sec = ts.tv_sec;
tp->tv_usec = (suseconds_t)(ts.tv_nsec / 1000);
#if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, ts);
return 0;
}
#elif defined(__APPLE__)
#define NSEC_PER_SEC 1000000000
/* We can use mach kernel functions here.
* This is crap though - why can't they implement clock_gettime?*/
static struct mach_timebase_info info = { 0, 0 };
@ -118,13 +113,12 @@ get_monotonic(struct timeval *tp)
nano = mach_absolute_time();
if ((info.denom != 1 || info.numer != 1) && factor != 0.0)
nano *= factor;
tp->tv_sec = nano / NSEC_PER_SEC;
rem = nano % NSEC_PER_SEC;
if (rem < 0) {
tp->tv_sec--;
rem += NSEC_PER_SEC;
ts->tv_sec = nano / NSEC_PER_SEC;
ts->tv_nsec = nano % NSEC_PER_SEC;
if (ts->tv_nsec < 0) {
ts->tv_sec--;
ts->tv_nsec += NSEC_PER_SEC;
}
tp->tv_usec = rem / 1000;
return 0;
}
#endif
@ -136,7 +130,15 @@ get_monotonic(struct timeval *tp)
posix_clock_set = 1;
}
#endif
return gettimeofday(tp, NULL);
{
struct timeval tv;
if (gettimeofday(&tv, NULL) == 0) {
TIMEVAL_TO_TIMESPEC(&tv, ts);
return 0;
}
}
return -1;
}
ssize_t
@ -172,7 +174,7 @@ setvard(char ***e, const char *prefix, const char *var, size_t value)
time_t
uptime(void)
{
struct timeval tv;
struct timespec tv;
if (get_monotonic(&tv) == -1)
return -1;

View File

@ -48,28 +48,34 @@
#define STRINGIFY(a) #a
#define TOSTRING(a) STRINGIFY(a)
#define USECINSEC 1000000
#define timeval_to_double(tv) \
((double)(tv)->tv_sec + (double)((tv)->tv_usec) * 1.0e-6)
#define timernorm(tv) do { \
while ((tv)->tv_usec >= USECINSEC) { \
(tv)->tv_sec++; \
(tv)->tv_usec -= USECINSEC; \
} \
#define USEC_PER_SEC 1000000L
#define USEC_PER_NSEC 1000L
#define NSEC_PER_SEC 1000000000L
#define MSEC_PER_SEC 1000L
#define MSEC_PER_NSEC 1000000L
#define timespec_to_double(tv) \
((double)(tv)->tv_sec + (double)((tv)->tv_nsec) / 1000000000.0)
#define timespecnorm(tv) do { \
while ((tv)->tv_nsec >= NSEC_PER_SEC) { \
(tv)->tv_sec++; \
(tv)->tv_nsec -= NSEC_PER_SEC; \
} \
} while (0 /* CONSTCOND */);
#define tv_to_ms(ms, tv) do { \
ms = (tv)->tv_sec * 1000; \
ms += (tv)->tv_usec / 1000; \
#define ts_to_ms(ms, tv) do { \
ms = (tv)->tv_sec * MSEC_PER_SEC; \
ms += (tv)->tv_nsec / MSEC_PER_NSEC; \
} while (0 /* CONSTCOND */);
#define ms_to_tv(tv, ms) do { \
(tv)->tv_sec = ms / 1000; \
(tv)->tv_usec = (suseconds_t)(ms - ((tv)->tv_sec * 1000)) * 1000; \
#define ms_to_ts(tv, ms) do { \
(tv)->tv_sec = ms / MSEC_PER_SEC; \
(tv)->tv_nsec = (suseconds_t)(ms - ((tv)->tv_sec * MSEC_PER_SEC)) \
* MSEC_PER_NSEC; \
} while (0 /* CONSTCOND */);
#ifndef TIMEVAL_TO_TIMESPEC
#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
(ts)->tv_nsec = (tv)->tv_usec * USEC_PER_NSEC; \
} while (0 /* CONSTCOND */)
#endif
@ -110,7 +116,7 @@
void get_line_free(void);
const char *get_hostname(char *, size_t, int);
extern int clock_monotonic;
int get_monotonic(struct timeval *);
int get_monotonic(struct timespec *);
ssize_t setvar(char ***, const char *, const char *, const char *);
ssize_t setvard(char ***, const char *, const char *, size_t);
time_t uptime(void);

36
dhcp.c
View File

@ -1569,7 +1569,7 @@ send_message(struct interface *iface, uint8_t type,
ssize_t r;
struct in_addr from, to;
in_addr_t a = INADDR_ANY;
struct timeval tv;
struct timespec tv;
int s;
if (!callback)
@ -1584,13 +1584,13 @@ send_message(struct interface *iface, uint8_t type,
state->interval = 64;
}
tv.tv_sec = state->interval + DHCP_RAND_MIN;
tv.tv_usec = (suseconds_t)arc4random_uniform(
(DHCP_RAND_MAX - DHCP_RAND_MIN) * 1000000);
timernorm(&tv);
tv.tv_nsec = (suseconds_t)arc4random_uniform(
(DHCP_RAND_MAX - DHCP_RAND_MIN) * NSEC_PER_SEC);
timespecnorm(&tv);
syslog(LOG_DEBUG,
"%s: sending %s (xid 0x%x), next in %0.1f seconds",
iface->name, get_dhcp_op(type), state->xid,
timeval_to_double(&tv));
timespec_to_double(&tv));
}
if (dhcp_open(iface) == -1)
@ -1829,7 +1829,6 @@ dhcp_bind(struct interface *ifp, struct arp_state *astate)
struct dhcp_state *state = D_STATE(ifp);
struct if_options *ifo = ifp->options;
struct dhcp_lease *lease = &state->lease;
struct timeval tv;
uint8_t ipv4ll = 0;
if (state->state == DHS_BOUND)
@ -1862,9 +1861,7 @@ dhcp_bind(struct interface *ifp, struct arp_state *astate)
lease->leasetime = ~0U;
state->reason = "INFORM";
} else {
if (gettimeofday(&tv, NULL) == 0)
lease->leasedfrom = tv.tv_sec;
else if (lease->frominfo)
if (lease->frominfo)
state->reason = "TIMEOUT";
if (lease->leasetime == ~0U) {
lease->renewaltime =
@ -3071,7 +3068,6 @@ dhcp_start1(void *arg)
struct if_options *ifo = ifp->options;
struct dhcp_state *state;
struct stat st;
struct timeval now;
uint32_t l;
int nolease;
@ -3167,10 +3163,12 @@ dhcp_start1(void *arg)
} else if (state->lease.leasetime != ~0U &&
stat(state->leasefile, &st) == 0)
{
time_t now;
/* Offset lease times and check expiry */
gettimeofday(&now, NULL);
if ((time_t)state->lease.leasetime <
now.tv_sec - st.st_mtime)
now = time(NULL);
if (now == -1 ||
(time_t)state->lease.leasetime < now - st.st_mtime)
{
syslog(LOG_DEBUG,
"%s: discarding expired lease",
@ -3195,7 +3193,7 @@ dhcp_start1(void *arg)
dhcp_drop(ifp, "EXPIRE");
#endif
} else {
l = (uint32_t)(now.tv_sec - st.st_mtime);
l = (uint32_t)(now - st.st_mtime);
state->lease.leasetime -= l;
state->lease.renewaltime -= l;
state->lease.rebindtime -= l;
@ -3223,19 +3221,19 @@ dhcp_start1(void *arg)
void
dhcp_start(struct interface *ifp)
{
struct timeval tv;
struct timespec tv;
if (!(ifp->options->options & DHCPCD_IPV4))
return;
/* No point in delaying a static configuration */
tv.tv_sec = DHCP_MIN_DELAY;
tv.tv_usec = (suseconds_t)arc4random_uniform(
(DHCP_MAX_DELAY - DHCP_MIN_DELAY) * 1000000);
timernorm(&tv);
tv.tv_nsec = (suseconds_t)arc4random_uniform(
(DHCP_MAX_DELAY - DHCP_MIN_DELAY) * NSEC_PER_SEC);
timespecnorm(&tv);
syslog(LOG_DEBUG,
"%s: delaying IPv4 for %0.1f seconds",
ifp->name, timeval_to_double(&tv));
ifp->name, timespec_to_double(&tv));
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp);
}

1
dhcp.h
View File

@ -181,7 +181,6 @@ struct dhcp_lease {
uint32_t renewaltime;
uint32_t rebindtime;
struct in_addr server;
time_t leasedfrom;
uint8_t frominfo;
uint32_t cookie;
};

62
dhcp6.c
View File

@ -990,7 +990,7 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
struct sockaddr_in6 dst;
struct cmsghdr *cm;
struct in6_pktinfo pi;
struct timeval RTprev;
struct timespec RTprev;
double rnd;
time_t ms;
uint8_t neg;
@ -1037,49 +1037,49 @@ dhcp6_sendmessage(struct interface *ifp, void (*callback)(void *))
state->RT.tv_sec = 1;
else
state->RT.tv_sec = 0;
state->RT.tv_usec = (suseconds_t)arc4random_uniform(
state->IMD * 1000000);
timernorm(&state->RT);
state->RT.tv_nsec = (suseconds_t)arc4random_uniform(
state->IMD * NSEC_PER_SEC);
timespecnorm(&state->RT);
broad_uni = "delaying";
goto logsend;
}
if (state->RTC == 0) {
RTprev.tv_sec = state->IRT;
RTprev.tv_usec = 0;
RTprev.tv_nsec = 0;
state->RT.tv_sec = RTprev.tv_sec;
state->RT.tv_usec = 0;
state->RT.tv_nsec = 0;
} else {
RTprev = state->RT;
timeradd(&state->RT, &state->RT, &state->RT);
timespecadd(&state->RT, &state->RT, &state->RT);
}
rnd = DHCP6_RAND_MIN;
rnd += (suseconds_t)arc4random_uniform(
DHCP6_RAND_MAX - DHCP6_RAND_MIN);
rnd /= 1000;
rnd /= MSEC_PER_SEC;
neg = (rnd < 0.0);
if (neg)
rnd = -rnd;
tv_to_ms(ms, &RTprev);
ts_to_ms(ms, &RTprev);
ms *= rnd;
ms_to_tv(&RTprev, ms);
ms_to_ts(&RTprev, ms);
if (neg)
timersub(&state->RT, &RTprev, &state->RT);
timespecsub(&state->RT, &RTprev, &state->RT);
else
timeradd(&state->RT, &RTprev, &state->RT);
timespecadd(&state->RT, &RTprev, &state->RT);
if (state->RT.tv_sec > state->MRT) {
RTprev.tv_sec = state->MRT;
RTprev.tv_usec = 0;
RTprev.tv_nsec = 0;
state->RT.tv_sec = state->MRT;
state->RT.tv_usec = 0;
tv_to_ms(ms, &RTprev);
state->RT.tv_nsec = 0;
ts_to_ms(ms, &RTprev);
ms *= rnd;
ms_to_tv(&RTprev, ms);
ms_to_ts(&RTprev, ms);
if (neg)
timersub(&state->RT, &RTprev, &state->RT);
timespecsub(&state->RT, &RTprev, &state->RT);
else
timeradd(&state->RT, &RTprev, &state->RT);
timespecadd(&state->RT, &RTprev, &state->RT);
}
logsend:
@ -1092,7 +1092,7 @@ logsend:
state->send->xid[0],
state->send->xid[1],
state->send->xid[2],
timeval_to_double(&state->RT));
timespec_to_double(&state->RT));
/* Wait the initial delay */
if (state->IMD) {
@ -1695,7 +1695,7 @@ dhcp6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
static int
dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
const uint8_t *d, size_t l, const struct timeval *acquired)
const uint8_t *d, size_t l, const struct timespec *acquired)
{
struct dhcp6_state *state;
const struct dhcp6_option *o;
@ -1776,7 +1776,7 @@ dhcp6_findna(struct interface *ifp, uint16_t ot, const uint8_t *iaid,
static int
dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
const uint8_t *d, size_t l, const struct timeval *acquired)
const uint8_t *d, size_t l, const struct timespec *acquired)
{
struct dhcp6_state *state;
const struct dhcp6_option *o, *ex;
@ -1902,7 +1902,7 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
static int
dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
const char *sfrom, const struct timeval *acquired)
const char *sfrom, const struct timespec *acquired)
{
struct dhcp6_state *state;
const struct if_options *ifo;
@ -2051,11 +2051,11 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l,
static int
dhcp6_validatelease(struct interface *ifp,
const struct dhcp6_message *m, size_t len,
const char *sfrom, const struct timeval *acquired)
const char *sfrom, const struct timespec *acquired)
{
struct dhcp6_state *state;
int nia;
struct timeval aq;
struct timespec aq;
if (len <= sizeof(*m)) {
syslog(LOG_ERR, "%s: DHCPv6 lease truncated", ifp->name);
@ -2109,9 +2109,9 @@ dhcp6_readlease(struct interface *ifp)
struct stat st;
int fd;
ssize_t bytes;
struct timeval now;
const struct dhcp6_option *o;
struct timeval acquired;
struct timespec acquired;
time_t now;
state = D6_STATE(ifp);
if (stat(state->leasefile, &st) == -1) {
@ -2145,9 +2145,13 @@ dhcp6_readlease(struct interface *ifp)
goto ex;
}
gettimeofday(&now, NULL);
if ((now = time(NULL)) == -1) {
syslog(LOG_ERR, "%s: time: %m", __func__);
goto ex;
}
get_monotonic(&acquired);
acquired.tv_sec -= now.tv_sec - st.st_mtime;
acquired.tv_sec -= now - st.st_mtime;
/* Check to see if the lease is still valid */
fd = dhcp6_validatelease(ifp, state->new, state->new_len, NULL,
@ -2158,7 +2162,7 @@ dhcp6_readlease(struct interface *ifp)
if (!(ifp->ctx->options & DHCPCD_DUMPLEASE) &&
state->expire != ND6_INFINITE_LIFETIME)
{
if ((time_t)state->expire < now.tv_sec - st.st_mtime) {
if ((time_t)state->expire < now - st.st_mtime) {
syslog(LOG_DEBUG,"%s: discarding expired lease",
ifp->name);
goto ex;

View File

@ -172,7 +172,7 @@ struct dhcp6_state {
time_t start_uptime;
/* Message retransmission timings */
struct timeval RT;
struct timespec RT;
unsigned int IMD;
unsigned int RTC;
time_t IRT;

View File

@ -550,10 +550,10 @@ dhcpcd_pollup(void *arg)
carrier = if_carrier(ifp); /* will set ifp->flags */
if (carrier == LINK_UP && !(ifp->flags & IFF_UP)) {
struct timeval tv;
struct timespec tv;
tv.tv_sec = 0;
tv.tv_usec = IF_POLL_UP * 1000;
tv.tv_nsec = IF_POLL_UP * MSEC_PER_NSEC;
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcpcd_pollup, ifp);
return;
}
@ -681,7 +681,7 @@ dhcpcd_startinterface(void *arg)
size_t i;
char buf[DUID_LEN * 3];
int carrier;
struct timeval tv;
struct timespec tv;
if (ifo->options & DHCPCD_LINK) {
switch (ifp->carrier) {
@ -695,7 +695,7 @@ dhcpcd_startinterface(void *arg)
* Loop until both IFF_UP and IFF_RUNNING are set */
if ((carrier = if_carrier(ifp)) == LINK_UNKNOWN) {
tv.tv_sec = 0;
tv.tv_usec = IF_POLL_UP * 1000;
tv.tv_nsec = IF_POLL_UP * MSEC_PER_NSEC;
eloop_timeout_add_tv(ifp->ctx->eloop,
&tv, dhcpcd_startinterface, ifp);
} else
@ -1508,7 +1508,7 @@ main(int argc, char **argv)
* eloop removals as well, so init here. */
ctx.eloop = eloop_init();
if (ctx.eloop == NULL) {
syslog(LOG_ERR, "%s: %m", __func__);
syslog(LOG_ERR, "%s: eloop_init: %m", __func__);
goto exit_failure;
}

32
eloop.c
View File

@ -153,16 +153,15 @@ eloop_event_delete(struct eloop_ctx *ctx, int fd, int write_only)
int
eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
const struct timeval *when, void (*callback)(void *), void *arg)
const struct timespec *when, void (*callback)(void *), void *arg)
{
struct timeval now;
struct timeval w;
struct timespec now, w;
struct eloop_timeout *t, *tt = NULL;
get_monotonic(&now);
timeradd(&now, when, &w);
timespecadd(&now, when, &w);
/* Check for time_t overflow. */
if (timercmp(&w, &now, <)) {
if (timespeccmp(&w, &now, <)) {
errno = ERANGE;
return -1;
}
@ -188,8 +187,7 @@ eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
}
}
t->when.tv_sec = w.tv_sec;
t->when.tv_usec = w.tv_usec;
t->when = w;
t->callback = callback;
t->arg = arg;
t->queue = queue;
@ -197,7 +195,7 @@ eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue,
/* The timeout list should be in chronological order,
* soonest first. */
TAILQ_FOREACH(tt, &ctx->timeouts, next) {
if (timercmp(&t->when, &tt->when, <)) {
if (timespeccmp(&t->when, &tt->when, <)) {
TAILQ_INSERT_BEFORE(tt, t, next);
return 0;
}
@ -210,10 +208,10 @@ int
eloop_q_timeout_add_sec(struct eloop_ctx *ctx, int queue, time_t when,
void (*callback)(void *), void *arg)
{
struct timeval tv;
struct timespec tv;
tv.tv_sec = when;
tv.tv_usec = 0;
tv.tv_nsec = 0;
return eloop_q_timeout_add_tv(ctx, queue, &tv, callback, arg);
}
@ -261,6 +259,11 @@ struct eloop_ctx *
eloop_init(void)
{
struct eloop_ctx *ctx;
struct timespec now;
/* Check we have a working monotonic clock. */
if (get_monotonic(&now) == -1)
return NULL;
ctx = calloc(1, sizeof(*ctx));
if (ctx) {
@ -306,12 +309,10 @@ int
eloop_start(struct dhcpcd_ctx *dctx)
{
struct eloop_ctx *ctx;
struct timeval now;
int n;
struct eloop_event *e;
struct eloop_timeout *t;
struct timeval tv;
struct timespec ts, *tsp;
struct timespec now, ts, *tsp;
void (*t0)(void *);
#ifndef USE_SIGNALS
int timeout;
@ -331,14 +332,13 @@ eloop_start(struct dhcpcd_ctx *dctx)
}
if ((t = TAILQ_FIRST(&ctx->timeouts))) {
get_monotonic(&now);
if (timercmp(&now, &t->when, >)) {
if (timespeccmp(&now, &t->when, >)) {
TAILQ_REMOVE(&ctx->timeouts, t, next);
t->callback(t->arg);
TAILQ_INSERT_TAIL(&ctx->free_timeouts, t, next);
continue;
}
timersub(&t->when, &now, &tv);
TIMEVAL_TO_TIMESPEC(&tv, &ts);
timespecsub(&t->when, &now, &ts);
tsp = &ts;
} else
/* No timeouts, so wait forever */

View File

@ -50,7 +50,7 @@ struct eloop_event {
struct eloop_timeout {
TAILQ_ENTRY(eloop_timeout) next;
struct timeval when;
struct timespec when;
void (*callback)(void *);
void *arg;
int queue;
@ -88,7 +88,7 @@ void eloop_event_delete(struct eloop_ctx *, int, int);
int eloop_q_timeout_add_sec(struct eloop_ctx *, int queue,
time_t, void (*)(void *), void *);
int eloop_q_timeout_add_tv(struct eloop_ctx *, int queue,
const struct timeval *, void (*)(void *), void *);
const struct timespec *, void (*)(void *), void *);
int eloop_timeout_add_now(struct eloop_ctx *, void (*)(void *), void *);
void eloop_q_timeout_delete(struct eloop_ctx *, int, void (*)(void *), void *);
struct eloop_ctx * eloop_init(void);

View File

@ -599,6 +599,9 @@ if_route(unsigned char cmd, const struct rt *rt, struct rt *srt)
else {
#ifdef RTF_CLONING
rtm.hdr.rtm_flags |= RTF_CLONING;
#endif
#ifdef RTP_CONNECTED
rtm.hdr.rtm_priority = RTP_CONNECTED;
#endif
}
}
@ -952,6 +955,9 @@ if_route6(unsigned char cmd, const struct rt6 *rt, struct rt6 *srt)
if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
#ifdef RTF_CLONING
rtm.hdr.rtm_flags |= RTF_CLONING;
#endif
#ifdef RTP_CONNECTED
rtm.hdr.rtm_priority = RTP_CONNECTED;
#endif
} else
rtm.hdr.rtm_flags |= RTF_GATEWAY | RTF_STATIC;

40
ipv6.c
View File

@ -594,9 +594,9 @@ ipv6_checkaddrflags(void *arg)
ap->iface->ctx->ifaces, ap->iface->name,
&ap->addr, ap->prefix_len, ifa_flags);
} else {
struct timeval tv;
struct timespec tv;
ms_to_tv(&tv, RETRANS_TIMER / 2);
ms_to_ts(&tv, RETRANS_TIMER / 2);
eloop_timeout_add_tv(ap->iface->ctx->eloop, &tv,
ipv6_checkaddrflags, ap);
}
@ -627,7 +627,7 @@ ipv6_deleteaddr(struct ipv6_addr *addr)
}
int
ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
{
struct interface *ifp;
struct ipv6_state *state;
@ -676,17 +676,17 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
/* Adjust plftime and vltime based on acquired time */
pltime = ap->prefix_pltime;
vltime = ap->prefix_vltime;
if (timerisset(&ap->acquired) &&
if (timespecisset(&ap->acquired) &&
(ap->prefix_pltime != ND6_INFINITE_LIFETIME ||
ap->prefix_vltime != ND6_INFINITE_LIFETIME))
{
struct timeval n;
struct timespec n;
if (now == NULL) {
get_monotonic(&n);
now = &n;
}
timersub(now, &ap->acquired, &n);
timespecsub(now, &ap->acquired, &n);
if (ap->prefix_pltime != ND6_INFINITE_LIFETIME)
ap->prefix_pltime -= (uint32_t)n.tv_sec;
if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
@ -732,9 +732,9 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timeval *now)
eloop_timeout_delete(ap->iface->ctx->eloop,
ipv6_checkaddrflags, ap);
if (!(ap->flags & IPV6_AF_DADCOMPLETED)) {
struct timeval tv;
struct timespec tv;
ms_to_tv(&tv, RETRANS_TIMER / 2);
ms_to_ts(&tv, RETRANS_TIMER / 2);
eloop_timeout_add_tv(ap->iface->ctx->eloop,
&tv, ipv6_checkaddrflags, ap);
}
@ -766,10 +766,10 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs)
{
struct ipv6_addr *ap, *apn, *apf;
ssize_t i;
struct timeval now;
struct timespec now;
i = 0;
timerclear(&now);
timespecclear(&now);
TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
if (ap->prefix_vltime == 0) {
if (ap->flags & IPV6_AF_ADDED) {
@ -814,7 +814,7 @@ ipv6_addaddrs(struct ipv6_addrhead *addrs)
apf->flags &= ~IPV6_AF_ADDED;
if (ap->flags & IPV6_AF_NEW)
i++;
if (!timerisset(&now))
if (!timespecisset(&now))
get_monotonic(&now);
ipv6_addaddr(ap, &now);
}
@ -836,9 +836,9 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
const struct interface *ifd)
{
struct ipv6_addr *ap, *apn, *apf;
struct timeval now;
struct timespec now;
timerclear(&now);
timespecclear(&now);
TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
if (ifd && ap->delegating_iface != ifd)
continue;
@ -860,7 +860,7 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
if (!(ap->iface->options->options &
DHCPCD_EXITING) && apf)
{
if (!timerisset(&now))
if (!timespecisset(&now))
get_monotonic(&now);
ipv6_addaddr(apf, &now);
}
@ -997,9 +997,9 @@ ipv6_handleifa(struct dhcpcd_ctx *ctx,
if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
#ifdef IPV6_POLLADDRFLAG
if (ap->addr_flags & IN6_IFF_TENTATIVE) {
struct timeval tv;
struct timespec tv;
ms_to_tv(&tv, RETRANS_TIMER / 2);
ms_to_ts(&tv, RETRANS_TIMER / 2);
eloop_timeout_add_tv(
ap->iface->ctx->eloop,
&tv, ipv6_checkaddrflags, ap);
@ -1437,7 +1437,7 @@ ipv6_tempdadcallback(void *arg)
if (ia->flags & IPV6_AF_DUPLICATED) {
struct ipv6_addr *ia1;
struct timeval tv;
struct timespec tv;
if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
syslog(LOG_ERR,
@ -1457,7 +1457,7 @@ ipv6_tempdadcallback(void *arg)
}
struct ipv6_addr *
ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timeval *now)
ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timespec *now)
{
struct ipv6_state *state;
const struct ipv6_state *cstate;
@ -1649,7 +1649,7 @@ valid:
}
void
ipv6_addtempaddrs(struct interface *ifp, const struct timeval *now)
ipv6_addtempaddrs(struct interface *ifp, const struct timespec *now)
{
struct ipv6_state *state;
struct ipv6_addr *ia;
@ -1666,7 +1666,7 @@ static void
ipv6_regentempaddr(void *arg)
{
struct ipv6_addr *ia = arg, *ia1;
struct timeval tv;
struct timespec tv;
syslog(LOG_DEBUG, "%s: regen temp addr %s",
ia->iface->name, ia->saddr);

10
ipv6.h
View File

@ -104,8 +104,8 @@ struct ipv6_addr {
uint8_t prefix_len;
uint32_t prefix_vltime;
uint32_t prefix_pltime;
struct timeval created;
struct timeval acquired;
struct timespec created;
struct timespec acquired;
struct in6_addr addr;
int addr_flags;
short flags;
@ -238,7 +238,7 @@ uint8_t ipv6_prefixlen(const struct in6_addr *);
int ipv6_userprefix( const struct in6_addr *, short prefix_len,
uint64_t user_number, struct in6_addr *result, short result_len);
void ipv6_checkaddrflags(void *);
int ipv6_addaddr(struct ipv6_addr *, const struct timeval *);
int ipv6_addaddr(struct ipv6_addr *, const struct timespec *);
ssize_t ipv6_addaddrs(struct ipv6_addrhead *addrs);
void ipv6_freedrop_addrs(struct ipv6_addrhead *, int,
const struct interface *);
@ -261,9 +261,9 @@ void ipv6_freedrop(struct interface *, int);
void ipv6_gentempifid(struct interface *);
void ipv6_settempstale(struct interface *);
struct ipv6_addr *ipv6_createtempaddr(struct ipv6_addr *,
const struct timeval *);
const struct timespec *);
struct ipv6_addr *ipv6_settemptime(struct ipv6_addr *, int);
void ipv6_addtempaddrs(struct interface *, const struct timeval *);
void ipv6_addtempaddrs(struct interface *, const struct timespec *);
#else
#define ipv6_gentempifid(a) {}
#define ipv6_settempstale(a) {}

View File

@ -519,7 +519,7 @@ ipv6nd_scriptrun(struct ra *rap)
TAILQ_FOREACH(rao, &rap->options, next) {
if (rao->type == ND_OPT_RDNSS &&
rao->option &&
timerisset(&rao->expire))
timespecisset(&rao->expire))
{
hasdns = 1;
break;
@ -578,7 +578,7 @@ ipv6nd_dadcallback(void *arg)
struct interface *ifp;
struct ra *rap;
int wascompleted, found;
struct timeval tv;
struct timespec tv;
char buf[INET6_ADDRSTRLEN];
const char *p;
int dadcounter;
@ -630,9 +630,9 @@ ipv6nd_dadcallback(void *arg)
else
ap->saddr[0] = '\0';
tv.tv_sec = 0;
tv.tv_usec = (suseconds_t)arc4random_uniform(
IDGEN_DELAY * USECINSEC);
timernorm(&tv);
tv.tv_nsec = (suseconds_t)
arc4random_uniform(IDGEN_DELAY * NSEC_PER_SEC);
timespecnorm(&tv);
eloop_timeout_add_tv(ifp->ctx->eloop, &tv,
ipv6nd_addaddr, ap);
return;
@ -690,7 +690,7 @@ ipv6nd_handlera(struct ipv6_ctx *ctx, struct interface *ifp,
struct ra_opt *rao;
struct ipv6_addr *ap;
char *opt, *opt2, *tmp;
struct timeval expire;
struct timespec expire;
uint8_t new_rap, new_data;
#ifdef IPV6_MANAGETEMPADDR
uint8_t new_ap;
@ -1094,11 +1094,11 @@ extra_opt:
} else
free(opt);
if (lifetime == ~0U)
timerclear(&rao->expire);
timespecclear(&rao->expire);
else {
expire.tv_sec = (time_t)lifetime;
expire.tv_usec = 0;
timeradd(&rap->received, &expire, &rao->expire);
expire.tv_nsec = 0;
timespecadd(&rap->received, &expire, &rao->expire);
}
if (rao && rao->type == ND_OPT_PREFIX_INFORMATION && opt2) {
n = _ND_OPT_PREFIX_ADDR;
@ -1316,13 +1316,13 @@ ipv6nd_expirera(void *arg)
struct interface *ifp;
struct ra *rap, *ran;
struct ra_opt *rao, *raon;
struct timeval now, lt, expire, next;
struct timespec now, lt, expire, next;
int expired, valid;
ifp = arg;
get_monotonic(&now);
expired = 0;
timerclear(&next);
timespecclear(&next);
TAILQ_FOREACH_SAFE(rap, ifp->ctx->ipv6->ra_routers, next, ran) {
if (rap->iface != ifp)
@ -1330,9 +1330,10 @@ ipv6nd_expirera(void *arg)
valid = 0;
if (rap->lifetime) {
lt.tv_sec = (time_t)rap->lifetime;
lt.tv_usec = 0;
timeradd(&rap->received, &lt, &expire);
if (rap->lifetime == 0 || timercmp(&now, &expire, >)) {
lt.tv_nsec = 0;
timespecadd(&rap->received, &lt, &expire);
if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
{
if (!rap->expired) {
syslog(LOG_WARNING,
"%s: %s: router expired",
@ -1341,9 +1342,9 @@ ipv6nd_expirera(void *arg)
}
} else {
valid = 1;
timersub(&expire, &now, &lt);
if (!timerisset(&next) ||
timercmp(&next, &lt, >))
timespecsub(&expire, &now, &lt);
if (!timespecisset(&next) ||
timespeccmp(&next, &lt, >))
next = lt;
}
}
@ -1366,9 +1367,9 @@ ipv6nd_expirera(void *arg)
continue;
}
}
if (!timerisset(&rao->expire))
if (!timespecisset(&rao->expire))
continue;
if (timercmp(&now, &rao->expire, >)) {
if (timespeccmp(&now, &rao->expire, >)) {
/* Expired prefixes are logged above */
if (rao->type != ND_OPT_PREFIX_INFORMATION)
syslog(LOG_WARNING,
@ -1381,8 +1382,8 @@ ipv6nd_expirera(void *arg)
continue;
}
valid = 1;
timersub(&rao->expire, &now, &lt);
if (!timerisset(&next) || timercmp(&next, &lt, >))
timespecsub(&rao->expire, &now, &lt);
if (!timespecisset(&next) || timespeccmp(&next, &lt, >))
next = lt;
}
@ -1392,7 +1393,7 @@ ipv6nd_expirera(void *arg)
ipv6nd_free_ra(rap);
}
if (timerisset(&next))
if (timespecisset(&next))
eloop_timeout_add_tv(ifp->ctx->eloop,
&next, ipv6nd_expirera, ifp);
if (expired) {
@ -1624,16 +1625,16 @@ ipv6nd_startrs1(void *arg)
void
ipv6nd_startrs(struct interface *ifp)
{
struct timeval tv;
struct timespec tv;
eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
tv.tv_sec = 0;
tv.tv_usec = (suseconds_t)arc4random_uniform(
MAX_RTR_SOLICITATION_DELAY * 1000000);
timernorm(&tv);
tv.tv_nsec = (suseconds_t)arc4random_uniform(
MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC);
timespecnorm(&tv);
syslog(LOG_DEBUG,
"%s: delaying IPv6 router solicitation for %0.1f seconds",
ifp->name, timeval_to_double(&tv));
ifp->name, timespec_to_double(&tv));
eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);
return;
}

View File

@ -37,7 +37,7 @@
struct ra_opt {
TAILQ_ENTRY(ra_opt) next;
uint16_t type;
struct timeval expire;
struct timespec expire;
char *option;
};
@ -48,7 +48,7 @@ struct ra {
char sfrom[INET6_ADDRSTRLEN];
unsigned char *data;
size_t data_len;
struct timeval received;
struct timespec received;
unsigned char flags;
uint32_t lifetime;
uint32_t reachable;