-# $OpenBSD: Makefile,v 1.8 2015/11/30 20:52:28 jca Exp $
+# $OpenBSD: Makefile,v 1.9 2016/08/02 17:00:09 jca Exp $
PROG= rtadvd
-SRCS= rtadvd.c advcap.c if.c config.c timer.c dump.c log.c
+SRCS= rtadvd.c advcap.c if.c config.c dump.c log.c
CFLAGS+=-Wall
MAN= rtadvd.8 rtadvd.conf.5
+LDADD= -levent
+DPADD+= ${LIBEVENT}
+
.include <bsd.prog.mk>
-/* $OpenBSD: config.c,v 1.57 2016/06/29 14:19:38 jca Exp $ */
+/* $OpenBSD: config.c,v 1.58 2016/08/02 17:00:09 jca Exp $ */
/* $KAME: config.c,v 1.62 2002/05/29 10:13:10 itojun Exp $ */
/*
#include <unistd.h>
#include <ifaddrs.h>
#include <stdint.h>
+#include <event.h>
#include "rtadvd.h"
#include "advcap.h"
-#include "timer.h"
#include "if.h"
#include "config.h"
#include "log.h"
make_packet(tmp);
/* set timer */
- tmp->timer = rtadvd_add_timer(ra_timeout, ra_timer_update,
- tmp, tmp);
- ra_timer_update(tmp, &tmp->timer->tm);
- rtadvd_set_timer(&tmp->timer->tm, tmp->timer);
+ ra_timer_update(tmp);
}
void
* reset the timer so that the new prefix will be advertised quickly.
*/
rai->initcounter = 0;
- ra_timer_update(rai, &rai->timer->tm);
- rtadvd_set_timer(&rai->timer->tm, rai->timer);
+ ra_timer_update(rai);
}
/*
-/* $OpenBSD: dump.c,v 1.20 2016/06/29 14:19:38 jca Exp $ */
+/* $OpenBSD: dump.c,v 1.21 2016/08/02 17:00:09 jca Exp $ */
/* $KAME: dump.c,v 1.27 2002/05/29 14:23:55 itojun Exp $ */
/*
#include <string.h>
#include <errno.h>
#include <netdb.h>
+#include <event.h>
#include "rtadvd.h"
-#include "timer.h"
#include "if.h"
#include "log.h"
#include "dump.h"
struct dnssldom *dnsd;
char prefixbuf[INET6_ADDRSTRLEN];
int first;
- struct timeval now;
+ struct timeval now, next;
char *origin, *vltime, *pltime, *flags;
char *vltimexpire=NULL, *pltimexpire=NULL;
+ char ctimebuf[26];
gettimeofday(&now, NULL);
SLIST_FOREACH(rai, &ralist, entry) {
/* control information */
if (rai->lastsent.tv_sec) {
time_t t = rai->lastsent.tv_sec;
- /* note that ctime() appends CR by itself */
- log_info(" Last RA sent: %s", ctime(&t));
+ (void)strlcpy(ctimebuf, ctime(&t), sizeof(ctimebuf));
+ ctimebuf[strcspn(ctimebuf, "\n")] = '\0';
+ log_info(" Last RA sent: %s", ctimebuf);
}
- if (rai->timer) {
- time_t t = rai->timer->tm.tv_sec;
- log_info(" Next RA will be sent: %s", ctime(&t));
+ if (evtimer_pending(&rai->timer.ev, &next)) {
+ time_t t = next.tv_sec;
+ (void)strlcpy(ctimebuf, ctime(&t), sizeof(ctimebuf));
+ ctimebuf[strcspn(ctimebuf, "\n")] = '\0';
+ log_info(" Next RA will be sent: %s", ctimebuf);
} else
log_info(" RA timer is stopped");
log_info(" waits: %u, initcount: %u",
-/* $OpenBSD: if.c,v 1.40 2016/06/29 14:19:38 jca Exp $ */
+/* $OpenBSD: if.c,v 1.41 2016/08/02 17:00:09 jca Exp $ */
/* $KAME: if.c,v 1.17 2001/01/21 15:27:30 itojun Exp $ */
/*
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <event.h>
#include "rtadvd.h"
#include "if.h"
-/* $OpenBSD: rtadvd.c,v 1.75 2016/06/30 10:17:18 florian Exp $ */
+/* $OpenBSD: rtadvd.c,v 1.76 2016/08/02 17:00:09 jca Exp $ */
/* $KAME: rtadvd.c,v 1.66 2002/05/29 14:18:36 itojun Exp $ */
/*
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
-#include <poll.h>
#include <err.h>
#include <errno.h>
+#include <event.h>
#include <string.h>
#include <pwd.h>
#include <signal.h>
#include "rtadvd.h"
#include "advcap.h"
-#include "timer.h"
#include "if.h"
#include "config.h"
#include "dump.h"
static size_t rcvcmsgbuflen;
static u_char *sndcmsgbuf = NULL;
static size_t sndcmsgbuflen;
-volatile sig_atomic_t do_dump;
-volatile sig_atomic_t do_die;
struct msghdr sndmhdr;
struct iovec rcviov[2];
struct iovec sndiov[2];
};
static __dead void usage(void);
-static void set_die(int);
-static __dead void die(void);
static void sock_open(void);
static void rtsock_open(void);
-static void rtadvd_input(void);
static void rs_input(int, struct nd_router_solicit *,
struct in6_pktinfo *, struct sockaddr_in6 *);
static void ra_input(int, struct nd_router_advert *,
union nd_opts *, u_int32_t);
static void free_ndopts(union nd_opts *);
static void ra_output(struct rainfo *);
-static void rtmsg_input(void);
-static void rtadvd_set_dump(int);
static struct rainfo *if_indextorainfo(int);
+static void dump_cb(int, short, void *);
+static void die_cb(int, short, void *);
+static void rtsock_cb(int, short, void *);
+static void sock_cb(int, short, void *);
+static void timer_cb(int, short, void *);
+
int
main(int argc, char *argv[])
{
- struct pollfd pfd[2];
- struct timeval *timeout;
struct passwd *pw;
- int i, ch, npfd, tmout;
+ int ch;
+ struct event ev_sock;
+ struct event ev_rtsock;
+ struct event ev_sigterm;
+ struct event ev_sigusr1;
+ struct rainfo *rai;
log_init(1); /* log to stderr until daemonized */
if (pledge("stdio inet route", NULL) == -1)
err(1, "pledge");
- npfd = 1;
- pfd[0].fd = sock;
- pfd[0].events = POLLIN;
- if (rtsock >= 0) {
- pfd[1].fd = rtsock;
- pfd[1].events = POLLIN;
- npfd++;
- }
+ event_init();
- signal(SIGTERM, set_die);
- signal(SIGUSR1, rtadvd_set_dump);
+ signal_set(&ev_sigterm, SIGTERM, die_cb, NULL);
+ signal_add(&ev_sigterm, NULL);
+ signal_set(&ev_sigusr1, SIGUSR1, dump_cb, NULL);
+ signal_add(&ev_sigusr1, NULL);
- while (1) {
- if (do_dump) { /* SIGUSR1 */
- do_dump = 0;
- rtadvd_dump();
- }
+ event_set(&ev_sock, sock, EV_READ|EV_PERSIST, sock_cb, NULL);
+ event_add(&ev_sock, NULL);
+ if (rtsock != -1) {
+ event_set(&ev_rtsock, rtsock, EV_READ|EV_PERSIST, rtsock_cb,
+ NULL);
+ event_add(&ev_rtsock, NULL);
+ }
- if (do_die) {
- die();
- /*NOTREACHED*/
- }
+ SLIST_FOREACH(rai, &ralist, entry) {
+ evtimer_set(&rai->timer.ev, timer_cb, rai);
+ evtimer_add(&rai->timer.ev, &rai->timer.tm);
+ }
- /* timer expiration check and reset the timer */
- timeout = rtadvd_check_timer();
-
- if (timeout != NULL) {
- tmout = timeout->tv_sec * 1000 + timeout->tv_usec /
- 1000;
- log_debug("set timer to %lld.%ld. waiting for "
- "inputs or timeout",
- (long long)timeout->tv_sec,
- timeout->tv_usec);
- } else {
- tmout = INFTIM;
- log_debug("there's no timer. waiting for inputs");
- }
+ event_dispatch();
- if ((i = poll(pfd, npfd, tmout)) < 0) {
- /* EINTR would occur upon SIGUSR1 for status dump */
- if (errno != EINTR)
- log_warn("poll");
- continue;
- }
- if (i == 0) /* timeout */
- continue;
- if (rtsock != -1 && (pfd[1].revents & POLLIN))
- rtmsg_input();
- if (pfd[0].revents & POLLIN)
- rtadvd_input();
- }
- exit(0); /* NOTREACHED */
+ log_warn("event_dispatch returned");
+
+ return 1;
}
static void
}
static void
-rtadvd_set_dump(int signo)
+dump_cb(int sig, short event, void *arg)
{
- do_dump = 1;
+ rtadvd_dump();
}
static void
-set_die(int signo)
-{
- do_die = 1;
-}
-
-static void
-die(void)
+die_cb(int sig, short event, void *arg)
{
struct rainfo *ra;
int i;
}
static void
-rtmsg_input(void)
+rtsock_cb(int fd, short event, void *arg)
{
int n, type, ifindex = 0, plen;
size_t len;
(iflist[ifindex]->ifm_flags & IFF_UP) == 0) {
log_info("interface %s becomes down. stop timer.",
rai->ifname);
- rtadvd_remove_timer(&rai->timer);
+ evtimer_del(&rai->timer.ev);
} else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */
(iflist[ifindex]->ifm_flags & IFF_UP) != 0) {
log_info("interface %s becomes up. restart timer.",
rai->initcounter = 0; /* reset the counter */
rai->waiting = 0; /* XXX */
- rai->timer = rtadvd_add_timer(ra_timeout,
- ra_timer_update, rai, rai);
- ra_timer_update(rai, &rai->timer->tm);
- rtadvd_set_timer(&rai->timer->tm, rai->timer);
+ ra_timer_update(rai);
+ evtimer_add(&rai->timer.ev, &rai->timer.tm);
}
}
}
void
-rtadvd_input(void)
+sock_cb(int fd, short event, void *arg)
{
int i;
int *hlimp = NULL;
*/
{
long delay; /* must not be greater than 1000000 */
- struct timeval interval, now, min_delay, tm_tmp, *rest;
+ struct timeval interval, now, min_delay, tm_tmp, next,
+ computed;
/*
* If there is already a waiting RS packet, don't
if (ra->waiting++)
goto done;
+ gettimeofday(&now, NULL);
+
/*
* Compute a random delay. If the computed value
* corresponds to a time later than the time the next
delay = arc4random_uniform(MAX_RA_DELAY_TIME);
interval.tv_sec = 0;
interval.tv_usec = delay;
- rest = rtadvd_timer_rest(ra->timer);
- if (timercmp(rest, &interval, <)) {
+ /*
+ * Could happen if an interface has transitioned from DOWN to
+ * UP and we haven't re-enabled the timer yet.
+ */
+ if (!evtimer_pending(&ra->timer.ev, &next))
+ goto done;
+ timeradd(&now, &interval, &computed);
+ if (timercmp(&computed, &next, >)) {
log_debug("random delay is larger than "
"the rest of normal timer");
- interval = *rest;
+ goto done;
}
/*
* MIN_DELAY_BETWEEN_RAS plus the random value after the
* previous advertisement was sent.
*/
- gettimeofday(&now, NULL);
- timersub(&now, &ra->lastsent, &tm_tmp);
min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
min_delay.tv_usec = 0;
- if (timercmp(&tm_tmp, &min_delay, <)) {
- timersub(&min_delay, &tm_tmp, &min_delay);
- timeradd(&min_delay, &interval, &interval);
- }
- rtadvd_set_timer(&interval, ra->timer);
- goto done;
+ timeradd(&ra->lastsent, &min_delay, &tm_tmp);
+ if (timercmp(&computed, &tm_tmp, <))
+ computed = tm_tmp;
+ timersub(&computed, &now, &computed);
+ evtimer_add(&ra->timer.ev, &computed);
}
done:
/* process RA timer */
void
-ra_timeout(void *data)
+timer_cb(int fd, short event, void *data)
{
struct rainfo *rai = (struct rainfo *)data;
log_debug("RA timer on %s is expired", rai->ifname);
ra_output(rai);
+
+ ra_timer_update(rai);
+ evtimer_add(&rai->timer.ev, &rai->timer.tm);
}
/* update RA timer */
void
-ra_timer_update(void *data, struct timeval *tm)
+ra_timer_update(struct rainfo *rai)
{
- struct rainfo *rai = (struct rainfo *)data;
+ struct timeval *tm = &rai->timer.tm;
long interval;
/*
-/* $OpenBSD: rtadvd.h,v 1.25 2016/06/29 14:19:38 jca Exp $ */
+/* $OpenBSD: rtadvd.h,v 1.26 2016/08/02 17:00:09 jca Exp $ */
/* $KAME: rtadvd.h,v 1.20 2002/05/29 10:13:10 itojun Exp $ */
/*
#define PREFIX_FROM_CONFIG 2
#define PREFIX_FROM_DYNAMIC 3
+struct rtadvd_timer {
+ struct event ev;
+ struct timeval tm;
+};
+
struct prefix {
TAILQ_ENTRY(prefix) entry;
SLIST_ENTRY(rainfo) entry;
/* timer related parameters */
- struct rtadvd_timer *timer;
+ struct rtadvd_timer timer;
unsigned int initcounter; /* counter for the first few advertisements */
struct timeval lastsent; /* timestamp when the latest RA was sent */
unsigned int waiting; /* number of RS waiting for RA */
};
SLIST_HEAD(ralist, rainfo);
-void ra_timeout(void *);
-void ra_timer_update(void *, struct timeval *);
+void ra_timer_update(struct rainfo *);
struct prefix *find_prefix(struct rainfo *, struct in6_addr *, int);
+++ /dev/null
-/* $OpenBSD: timer.c,v 1.16 2016/03/01 20:51:05 jca Exp $ */
-/* $KAME: timer.c,v 1.7 2002/05/21 14:26:55 itojun Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include "timer.h"
-#include "log.h"
-
-SLIST_HEAD(, rtadvd_timer) timer_head = SLIST_HEAD_INITIALIZER(timer_head);
-
-struct rtadvd_timer *
-rtadvd_add_timer(void (*timeout)(void *),
- void (*update)(void *, struct timeval *),
- void *timeodata, void *updatedata)
-{
- struct rtadvd_timer *newtimer;
-
- if ((newtimer = calloc(1, sizeof(*newtimer))) == NULL)
- fatal(NULL);
-
- if (timeout == NULL)
- fatalx("timeout function unspecified");
- if (update == NULL)
- fatalx("update function unspecified");
- newtimer->expire = timeout;
- newtimer->update = update;
- newtimer->expire_data = timeodata;
- newtimer->update_data = updatedata;
-
- /* link into chain */
- SLIST_INSERT_HEAD(&timer_head, newtimer, entries);
-
- return(newtimer);
-}
-
-void
-rtadvd_remove_timer(struct rtadvd_timer **timer)
-{
- SLIST_REMOVE(&timer_head, *timer, rtadvd_timer, entries);
- free(*timer);
- *timer = NULL;
-}
-
-void
-rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer)
-{
- struct timeval now;
-
- /* reset the timer */
- gettimeofday(&now, NULL);
-
- timeradd(&now, tm, &timer->tm);
-}
-
-/*
- * Check expiration for each timer. If a timer is expired,
- * call the expire function for the timer and update the timer.
- * Return the next interval.
- */
-struct timeval *
-rtadvd_check_timer(void)
-{
- static struct timeval returnval;
- struct timeval now;
- struct rtadvd_timer *tm;
- int timers;
-
- timers = 0;
- gettimeofday(&now, NULL);
-
- SLIST_FOREACH(tm, &timer_head, entries) {
- if (timercmp(&tm->tm, &now, <=)) {
- (*tm->expire)(tm->expire_data);
- (*tm->update)(tm->update_data, &tm->tm);
- timeradd(&tm->tm, &now, &tm->tm);
- }
- if (timers == 0 || timercmp(&tm->tm, &returnval, <))
- returnval = tm->tm;
- timers ++;
- }
-
- if (timers == 0) {
- /* no need to timeout */
- return(NULL);
- } else if (timercmp(&returnval, &now, <)) {
- /* this may occur when the interval is too small */
- timerclear(&returnval);
- } else
- timersub(&returnval, &now, &returnval);
- return(&returnval);
-}
-
-struct timeval *
-rtadvd_timer_rest(struct rtadvd_timer *timer)
-{
- static struct timeval returnval, now;
-
- gettimeofday(&now, NULL);
- if (timercmp(&timer->tm, &now, <=)) {
- log_debug("a timer must be expired, but not yet");
- timerclear(&returnval);
- }
- else
- timersub(&timer->tm, &now, &returnval);
-
- return(&returnval);
-}
+++ /dev/null
-/* $OpenBSD: timer.h,v 1.8 2016/02/08 23:19:00 jca Exp $ */
-/* $KAME: timer.h,v 1.3 2000/05/27 11:30:43 jinmei Exp $ */
-
-/*
- * Copyright (C) 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-struct rtadvd_timer {
- SLIST_ENTRY(rtadvd_timer) entries;
- struct rainfo *rai;
- struct timeval tm;
-
- void (*expire)(void *); /* expiration function */
- void *expire_data;
- void (*update)(void *, struct timeval *); /* update function */
- void *update_data;
-};
-
-struct rtadvd_timer *rtadvd_add_timer(void (*)(void *),
- void (*)(void *, struct timeval *), void *, void *);
-void rtadvd_set_timer(struct timeval *, struct rtadvd_timer *);
-void rtadvd_remove_timer(struct rtadvd_timer **);
-struct timeval * rtadvd_check_timer(void);
-struct timeval * rtadvd_timer_rest(struct rtadvd_timer *);