{
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");
}
*/
#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 };
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
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
time_t
uptime(void)
{
- struct timeval tv;
+ struct timespec tv;
if (get_monotonic(&tv) == -1)
return -1;
#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
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);
ssize_t r;
struct in_addr from, to;
in_addr_t a = INADDR_ANY;
- struct timeval tv;
+ struct timespec tv;
int s;
if (!callback)
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)
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)
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 =
struct if_options *ifo = ifp->options;
struct dhcp_state *state;
struct stat st;
- struct timeval now;
uint32_t l;
int nolease;
} 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",
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;
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);
}
uint32_t renewaltime;
uint32_t rebindtime;
struct in_addr server;
- time_t leasedfrom;
uint8_t frominfo;
uint32_t cookie;
};
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;
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:
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) {
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;
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;
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;
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);
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) {
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,
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;
time_t start_uptime;
/* Message retransmission timings */
- struct timeval RT;
+ struct timespec RT;
unsigned int IMD;
unsigned int RTC;
time_t IRT;
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;
}
size_t i;
char buf[DUID_LEN * 3];
int carrier;
- struct timeval tv;
+ struct timespec tv;
if (ifo->options & DHCPCD_LINK) {
switch (ifp->carrier) {
* 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
* 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;
}
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;
}
}
}
- 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;
/* 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;
}
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);
}
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) {
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;
}
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 */
struct eloop_timeout {
TAILQ_ENTRY(eloop_timeout) next;
- struct timeval when;
+ struct timespec when;
void (*callback)(void *);
void *arg;
int queue;
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);
else {
#ifdef RTF_CLONING
rtm.hdr.rtm_flags |= RTF_CLONING;
+#endif
+#ifdef RTP_CONNECTED
+ rtm.hdr.rtm_priority = RTP_CONNECTED;
#endif
}
}
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;
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);
}
}
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;
/* 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)
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);
}
{
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) {
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);
}
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;
if (!(ap->iface->options->options &
DHCPCD_EXITING) && apf)
{
- if (!timerisset(&now))
+ if (!timespecisset(&now))
get_monotonic(&now);
ipv6_addaddr(apf, &now);
}
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);
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,
}
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;
}
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;
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);
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;
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 *);
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) {}
TAILQ_FOREACH(rao, &rap->options, next) {
if (rao->type == ND_OPT_RDNSS &&
rao->option &&
- timerisset(&rao->expire))
+ timespecisset(&rao->expire))
{
hasdns = 1;
break;
struct interface *ifp;
struct ra *rap;
int wascompleted, found;
- struct timeval tv;
+ struct timespec tv;
char buf[INET6_ADDRSTRLEN];
const char *p;
int dadcounter;
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;
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;
} 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;
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)
valid = 0;
if (rap->lifetime) {
lt.tv_sec = (time_t)rap->lifetime;
- lt.tv_usec = 0;
- timeradd(&rap->received, <, &expire);
- if (rap->lifetime == 0 || timercmp(&now, &expire, >)) {
+ lt.tv_nsec = 0;
+ timespecadd(&rap->received, <, &expire);
+ if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
+ {
if (!rap->expired) {
syslog(LOG_WARNING,
"%s: %s: router expired",
}
} else {
valid = 1;
- timersub(&expire, &now, <);
- if (!timerisset(&next) ||
- timercmp(&next, <, >))
+ timespecsub(&expire, &now, <);
+ if (!timespecisset(&next) ||
+ timespeccmp(&next, <, >))
next = lt;
}
}
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,
continue;
}
valid = 1;
- timersub(&rao->expire, &now, <);
- if (!timerisset(&next) || timercmp(&next, <, >))
+ timespecsub(&rao->expire, &now, <);
+ if (!timespecisset(&next) || timespeccmp(&next, <, >))
next = lt;
}
ipv6nd_free_ra(rap);
}
- if (timerisset(&next))
+ if (timespecisset(&next))
eloop_timeout_add_tv(ifp->ctx->eloop,
&next, ipv6nd_expirera, ifp);
if (expired) {
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;
}
struct ra_opt {
TAILQ_ENTRY(ra_opt) next;
uint16_t type;
- struct timeval expire;
+ struct timespec expire;
char *option;
};
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;