Hi,
These events are meants to fire after an interval has elapsed,
so we should use the monotonic clock to measure.
The pattern throughout the daemon of loading the current time,
adding a timeout to the structure member, and then passing a
pointer to said structure to timer_add_event() seemed redundant,
so I modified timer_add_event() to accept the timeout in seconds
and populate the expiration structure itself before inserting
the event into the event list.
A number of files no longer need <sys/time.h>, so I dropped those
#includes. ipsec.c doesn't use anything in timer.h so I dropped it.
I didn't touch log.c because it seems to work just fine as-is with
gettimeofday(2).
I don't have a real IPSec gateway set up to test this with, but my
testing with a dummy configuration shows that with the patch the
events fire punctually, regardless of what I've done to the system
clock in the meanwhile.
Thoughts and feedback?
--
Scott Cheloha
Index: sbin/isakmpd/connection.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/connection.c,v
retrieving revision 1.38
diff -u -p -r1.38 connection.c
--- sbin/isakmpd/connection.c 6 Aug 2017 13:54:04 -0000 1.38
+++ sbin/isakmpd/connection.c 24 Nov 2017 20:54:37 -0000
@@ -31,8 +31,8 @@
*/
#include <sys/queue.h>
-#include <sys/time.h>
#include <sys/socket.h>
+
#include <stdlib.h>
#include <string.h>
@@ -71,7 +71,7 @@ struct connection_passive {
/* XXX Potential additions to 'connection_passive'. */
char *isakmp_peer;
struct sa *sa; /* XXX "Soft" ref to active sa? */
- struct timeval sa_expiration; /* XXX *sa may expire. */
+ struct timespec sa_expiration; /* XXX *sa may expire. */
#endif
};
@@ -144,15 +144,13 @@ connection_init(void)
static void
connection_checker(void *vconn)
{
- struct timeval now;
struct connection *conn = vconn;
char *name;
+ int interval;
- gettimeofday(&now, 0);
- now.tv_sec += conf_get_num("General", "check-interval",
- CHECK_INTERVAL);
+ interval = conf_get_num("General", "check-interval", CHECK_INTERVAL);
conn->ev = timer_add_event("connection_checker",
- connection_checker, conn, &now);
+ connection_checker, conn, interval);
if (!conn->ev)
log_print("%s: could not add timer event", __func__);
if (ui_daemon_passive)
@@ -272,7 +270,6 @@ int
connection_setup(char *name)
{
struct connection *conn = 0;
- struct timeval now;
/* Check for trials to add duplicate connections. */
if (connection_lookup(name)) {
@@ -291,9 +288,8 @@ connection_setup(char *name)
log_error("connection_setup: strdup (\"%s\") failed", name);
goto fail;
}
- gettimeofday(&now, 0);
conn->ev = timer_add_event("connection_checker", connection_checker,
- conn, &now);
+ conn, 0);
if (!conn->ev) {
log_print("connection_setup: could not add timer event");
goto fail;
@@ -405,11 +401,11 @@ void
connection_report(void)
{
struct connection *conn;
- struct timeval now;
+ struct timespec now;
struct connection_passive *pconn;
struct doi *doi = doi_lookup(ISAKMP_DOI_ISAKMP);
- gettimeofday(&now, 0);
+ clock_gettime(CLOCK_MONOTONIC, &now);
for (conn = TAILQ_FIRST(&connections); conn;
conn = TAILQ_NEXT(conn, link))
LOG_DBG((LOG_REPORT, 0,
Index: sbin/isakmpd/dpd.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/dpd.c,v
retrieving revision 1.19
diff -u -p -r1.19 dpd.c
--- sbin/isakmpd/dpd.c 10 Dec 2015 17:27:00 -0000 1.19
+++ sbin/isakmpd/dpd.c 24 Nov 2017 20:54:37 -0000
@@ -216,23 +216,18 @@ dpd_timer_interval(u_int32_t offset)
static void
dpd_timer_reset(struct sa *sa, u_int32_t time_passed, enum dpd_tstate mode)
{
- struct timeval tv;
-
if (sa->dpd_event)
timer_remove_event(sa->dpd_event);
- gettimeofday(&tv, 0);
switch (mode) {
case DPD_TIMER_NORMAL:
sa->dpd_failcount = 0;
- tv.tv_sec += dpd_timer_interval(time_passed);
sa->dpd_event = timer_add_event("dpd_event", dpd_event, sa,
- &tv);
+ dpd_timer_interval(time_passed));
break;
case DPD_TIMER_CHECK:
- tv.tv_sec += DPD_RETRANS_WAIT;
sa->dpd_event = timer_add_event("dpd_check_event",
- dpd_check_event, sa, &tv);
+ dpd_check_event, sa, DPD_RETRANS_WAIT);
break;
default:
break;
@@ -267,7 +262,7 @@ dpd_check_time(struct sa *sa, void *v_ar
struct sockaddr *dst;
struct proto *proto;
struct sa_kinfo *ksa;
- struct timeval tv;
+ struct timespec ts;
if (sa->phase == 1 || (args->isakmp_sa->flags & SA_FLAG_DPD) == 0 ||
dpd_find_sa(sa, args->isakmp_sa) == 0)
@@ -278,7 +273,7 @@ dpd_check_time(struct sa *sa, void *v_ar
return 0;
sa->transport->vtbl->get_src(sa->transport, &dst);
- gettimeofday(&tv, 0);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
ksa = pf_key_v2_get_kernel_sa(proto->spi[1], proto->spi_sz[1],
proto->proto, dst);
@@ -287,10 +282,10 @@ dpd_check_time(struct sa *sa, void *v_ar
LOG_DBG((LOG_MESSAGE, 80, "dpd_check_time: "
"SA %p last use %u second(s) ago", sa,
- (u_int32_t)(tv.tv_sec - ksa->last_used)));
+ (u_int32_t)(ts.tv_sec - ksa->last_used)));
- if ((u_int32_t)(tv.tv_sec - ksa->last_used) < args->interval) {
- args->interval = (u_int32_t)(tv.tv_sec - ksa->last_used);
+ if ((u_int32_t)(ts.tv_sec - ksa->last_used) < args->interval) {
+ args->interval = (u_int32_t)(ts.tv_sec - ksa->last_used);
return 1;
}
return 0;
Index: sbin/isakmpd/exchange.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/exchange.c,v
retrieving revision 1.139
diff -u -p -r1.139 exchange.c
--- sbin/isakmpd/exchange.c 18 Sep 2017 07:42:52 -0000 1.139
+++ sbin/isakmpd/exchange.c 24 Nov 2017 20:54:37 -0000
@@ -587,7 +587,6 @@ static struct exchange *
exchange_create(int phase, int initiator, int doi, int type)
{
struct exchange *exchange;
- struct timeval expiration;
int delta;
/*
@@ -623,12 +622,10 @@ exchange_create(int phase, int initiator
return 0;
}
}
- gettimeofday(&expiration, 0);
delta = conf_get_num("General", "Exchange-max-time",
EXCHANGE_MAX_TIME);
- expiration.tv_sec += delta;
exchange->death = timer_add_event("exchange_free_aux",
- exchange_free_aux, exchange, &expiration);
+ exchange_free_aux, exchange, delta);
if (!exchange->death) {
/* If we don't give up we might start leaking... */
exchange_free_aux(exchange);
Index: sbin/isakmpd/ipsec.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/ipsec.c,v
retrieving revision 1.148
diff -u -p -r1.148 ipsec.c
--- sbin/isakmpd/ipsec.c 27 Oct 2017 08:29:32 -0000 1.148
+++ sbin/isakmpd/ipsec.c 24 Nov 2017 20:54:37 -0000
@@ -68,7 +68,6 @@
#include "pf_key_v2.h"
#include "prf.h"
#include "sa.h"
-#include "timer.h"
#include "transport.h"
#include "util.h"
#include "x509.h"
Index: sbin/isakmpd/isakmpd.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/isakmpd.c,v
retrieving revision 1.104
diff -u -p -r1.104 isakmpd.c
--- sbin/isakmpd/isakmpd.c 2 Apr 2016 14:37:42 -0000 1.104
+++ sbin/isakmpd/isakmpd.c 24 Nov 2017 20:54:37 -0000
@@ -391,7 +391,7 @@ main(int argc, char *argv[])
fd_set *rfds, *wfds;
int n, m;
size_t mask_size;
- struct timeval tv, *timeout;
+ struct timespec ts, *timeout;
closefrom(STDERR_FILENO + 1);
@@ -505,10 +505,10 @@ main(int argc, char *argv[])
n = m;
/* Find out when the next timed event is. */
- timeout = &tv;
+ timeout = &ts;
timer_next_event(&timeout);
- n = select(n, rfds, wfds, 0, timeout);
+ n = pselect(n, rfds, wfds, NULL, timeout, NULL);
if (n == -1) {
if (errno != EINTR) {
log_error("main: select");
Index: sbin/isakmpd/nat_traversal.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/nat_traversal.c,v
retrieving revision 1.24
diff -u -p -r1.24 nat_traversal.c
--- sbin/isakmpd/nat_traversal.c 20 Aug 2015 22:05:51 -0000 1.24
+++ sbin/isakmpd/nat_traversal.c 24 Nov 2017 20:54:37 -0000
@@ -387,7 +387,6 @@ nat_t_send_keepalive(void *v_arg)
{
struct sa *sa = (struct sa *)v_arg;
struct transport *t;
- struct timeval now;
int interval;
/* Send the keepalive message. */
@@ -398,11 +397,8 @@ nat_t_send_keepalive(void *v_arg)
interval = conf_get_num("General", "NAT-T-Keepalive", 0);
if (interval < 1)
interval = NAT_T_KEEPALIVE_INTERVAL;
- gettimeofday(&now, 0);
- now.tv_sec += interval;
-
sa->nat_t_keepalive = timer_add_event("nat_t_send_keepalive",
- nat_t_send_keepalive, v_arg, &now);
+ nat_t_send_keepalive, v_arg, interval);
if (!sa->nat_t_keepalive)
log_print("nat_t_send_keepalive: "
"timer_add_event() failed, will send no more keepalives");
@@ -412,7 +408,6 @@ void
nat_t_setup_keepalive(struct sa *sa)
{
struct sockaddr *src;
- struct timeval now;
if (sa->initiator)
sa->transport->vtbl->get_src(sa->transport, &src);
@@ -422,11 +417,8 @@ nat_t_setup_keepalive(struct sa *sa)
if (!virtual_listen_lookup(src))
return;
- gettimeofday(&now, 0);
- now.tv_sec += NAT_T_KEEPALIVE_INTERVAL;
-
sa->nat_t_keepalive = timer_add_event("nat_t_send_keepalive",
- nat_t_send_keepalive, sa, &now);
+ nat_t_send_keepalive, sa, NAT_T_KEEPALIVE_INTERVAL);
if (!sa->nat_t_keepalive)
log_print("nat_t_setup_keepalive: "
"timer_add_event() failed, will not send keepalives");
Index: sbin/isakmpd/pf_key_v2.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/pf_key_v2.c,v
retrieving revision 1.199
diff -u -p -r1.199 pf_key_v2.c
--- sbin/isakmpd/pf_key_v2.c 6 Aug 2017 13:54:04 -0000 1.199
+++ sbin/isakmpd/pf_key_v2.c 24 Nov 2017 20:54:37 -0000
@@ -35,7 +35,6 @@
#include <sys/ioctl.h>
#include <sys/queue.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <sys/uio.h>
#include <net/pfkeyv2.h>
@@ -204,7 +203,6 @@ pf_key_v2_read(u_int32_t seq)
struct sadb_msg *msg;
struct sadb_msg hdr;
struct sadb_ext *ext;
- struct timeval tv;
struct pollfd pfd[1];
pfd[0].fd = pf_key_v2_socket;
@@ -298,9 +296,8 @@ pf_key_v2_read(u_int32_t seq)
*/
if (seq && (msg->sadb_msg_pid != (u_int32_t) getpid() ||
msg->sadb_msg_seq != seq)) {
- gettimeofday(&tv, 0);
timer_add_event("pf_key_v2_notify",
- (void (*) (void *)) pf_key_v2_notify, ret, &tv);
+ (void (*) (void *)) pf_key_v2_notify, ret, 0);
ret = 0;
continue;
}
Index: sbin/isakmpd/sa.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/sa.c,v
retrieving revision 1.123
diff -u -p -r1.123 sa.c
--- sbin/isakmpd/sa.c 9 Dec 2015 21:41:50 -0000 1.123
+++ sbin/isakmpd/sa.c 24 Nov 2017 20:54:37 -0000
@@ -1348,7 +1348,6 @@ sa_replace(struct sa *sa, struct sa *new
int
sa_setup_expirations(struct sa *sa)
{
- struct timeval expiration;
u_int64_t seconds = sa->seconds;
/*
@@ -1362,7 +1361,6 @@ sa_setup_expirations(struct sa *sa)
* XXX Better scheme to come?
*/
if (!sa->soft_death) {
- gettimeofday(&expiration, 0);
/*
* XXX This should probably be configuration controlled
* somehow.
@@ -1371,9 +1369,8 @@ sa_setup_expirations(struct sa *sa)
LOG_DBG((LOG_TIMER, 95,
"sa_setup_expirations: SA %p soft timeout in %llu seconds",
sa, seconds));
- expiration.tv_sec += seconds;
sa->soft_death = timer_add_event("sa_soft_expire",
- sa_soft_expire, sa, &expiration);
+ sa_soft_expire, sa, seconds);
if (!sa->soft_death) {
/* If we don't give up we might start leaking... */
sa_delete(sa, 1);
@@ -1382,13 +1379,11 @@ sa_setup_expirations(struct sa *sa)
sa_reference(sa);
}
if (!sa->death) {
- gettimeofday(&expiration, 0);
LOG_DBG((LOG_TIMER, 95,
"sa_setup_expirations: SA %p hard timeout in %llu seconds",
sa, sa->seconds));
- expiration.tv_sec += sa->seconds;
sa->death = timer_add_event("sa_hard_expire", sa_hard_expire,
- sa, &expiration);
+ sa, sa->seconds);
if (!sa->death) {
/* If we don't give up we might start leaking... */
sa_delete(sa, 1);
Index: sbin/isakmpd/timer.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/timer.c,v
retrieving revision 1.17
diff -u -p -r1.17 timer.c
--- sbin/isakmpd/timer.c 20 Aug 2015 22:02:21 -0000 1.17
+++ sbin/isakmpd/timer.c 24 Nov 2017 20:54:37 -0000
@@ -30,8 +30,11 @@
*/
#include <sys/queue.h>
+#include <sys/time.h>
+
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include "log.h"
#include "timer.h"
@@ -45,29 +48,30 @@ timer_init(void)
}
void
-timer_next_event(struct timeval **timeout)
+timer_next_event(struct timespec **timeout)
{
- struct timeval now;
+ struct timespec now;
if (TAILQ_FIRST(&events)) {
- gettimeofday(&now, 0);
- if (timercmp(&now, &TAILQ_FIRST(&events)->expiration, >=))
- timerclear(*timeout);
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ if (timespeccmp(&now, &TAILQ_FIRST(&events)->expiration, >=))
+ timespecclear(*timeout);
else
- timersub(&TAILQ_FIRST(&events)->expiration, &now,
+ timespecsub(&TAILQ_FIRST(&events)->expiration, &now,
*timeout);
} else
- *timeout = 0;
+ *timeout = NULL;
}
void
timer_handle_expirations(void)
{
- struct timeval now;
+ struct timespec now;
struct event *n;
- gettimeofday(&now, 0);
- for (n = TAILQ_FIRST(&events); n && timercmp(&now, &n->expiration, >=);
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ for (n = TAILQ_FIRST(&events);
+ n && timespeccmp(&now, &n->expiration, >=);
n = TAILQ_FIRST(&events)) {
LOG_DBG((LOG_TIMER, 10,
"timer_handle_expirations: event %s(%p)", n->name,
@@ -79,34 +83,33 @@ timer_handle_expirations(void)
}
struct event *
-timer_add_event(char *name, void (*func)(void *), void *arg,
- struct timeval *expiration)
+timer_add_event(char *name, void (*func)(void *), void *arg, int seconds)
{
struct event *ev = malloc(sizeof *ev);
struct event *n;
- struct timeval now;
+ struct timespec interval, now;
if (!ev)
return 0;
ev->name = name;
ev->func = func;
ev->arg = arg;
- gettimeofday(&now, 0);
- memcpy(&ev->expiration, expiration, sizeof *expiration);
+ timespecclear(&interval);
+ interval.tv_sec += seconds;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timespecadd(&now, &interval, &ev->expiration);
for (n = TAILQ_FIRST(&events);
- n && timercmp(expiration, &n->expiration, >=);
+ n && timespeccmp(&ev->expiration, &n->expiration, >=);
n = TAILQ_NEXT(n, link))
;
if (n) {
LOG_DBG((LOG_TIMER, 10,
"timer_add_event: event %s(%p) added before %s(%p), "
- "expiration in %llds", name, arg, n->name, n->arg,
- (long long)(expiration->tv_sec - now.tv_sec)));
+ "expiration in %ds", name, arg, n->name, n->arg, seconds));
TAILQ_INSERT_BEFORE(n, ev, link);
} else {
LOG_DBG((LOG_TIMER, 10, "timer_add_event: event %s(%p) added "
- "last, expiration in %ds", name, arg,
- (int)(expiration->tv_sec - now.tv_sec)));
+ "last, expiration in %ds", name, arg, seconds));
TAILQ_INSERT_TAIL(&events, ev, link);
}
return ev;
@@ -125,9 +128,9 @@ void
timer_report(void)
{
struct event *ev;
- struct timeval now;
+ struct timespec now;
- gettimeofday(&now, 0);
+ clock_gettime(CLOCK_MONOTONIC, &now);
for (ev = TAILQ_FIRST(&events); ev; ev = TAILQ_NEXT(ev, link))
LOG_DBG((LOG_REPORT, 0,
Index: sbin/isakmpd/timer.h
===================================================================
RCS file: /cvs/src/sbin/isakmpd/timer.h,v
retrieving revision 1.8
diff -u -p -r1.8 timer.h
--- sbin/isakmpd/timer.h 16 Jan 2015 06:39:59 -0000 1.8
+++ sbin/isakmpd/timer.h 24 Nov 2017 20:54:37 -0000
@@ -33,21 +33,21 @@
#define _TIMER_H_
#include <sys/queue.h>
-#include <sys/time.h>
+
+#include <time.h>
struct event {
TAILQ_ENTRY(event) link;
char *name;
void (*func) (void *);
void *arg;
- struct timeval expiration;
+ struct timespec expiration;
};
extern void timer_init(void);
-extern void timer_next_event(struct timeval **);
+extern void timer_next_event(struct timespec **);
extern void timer_handle_expirations(void);
-extern struct event *timer_add_event(char *, void (*) (void *), void *,
- struct timeval *);
+extern struct event *timer_add_event(char *, void (*) (void *), void *, int);
extern void timer_remove_event(struct event *);
extern void timer_report(void);
Index: sbin/isakmpd/transport.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/transport.c,v
retrieving revision 1.37
diff -u -p -r1.37 transport.c
--- sbin/isakmpd/transport.c 10 Mar 2016 07:32:16 -0000 1.37
+++ sbin/isakmpd/transport.c 24 Nov 2017 20:54:37 -0000
@@ -255,7 +255,6 @@ transport_send_messages(fd_set * fds)
struct message *msg;
struct exchange *exchange;
struct sockaddr *dst;
- struct timeval expiration;
int expiry, ok_to_drop_message;
char peer[NI_MAXHOST], peersv[NI_MAXSERV];
@@ -332,14 +331,11 @@ transport_send_messages(fd_set * fds)
exchange = 0;
#endif
} else {
- gettimeofday(&expiration, 0);
-
/*
* XXX Calculate from round trip
* timings and a backoff func.
*/
expiry = msg->xmits * 2 + 5;
- expiration.tv_sec += expiry;
LOG_DBG((LOG_TRANSPORT, 30,
"transport_send_messages: "
"message %p scheduled for "
@@ -350,7 +346,7 @@ transport_send_messages(fd_set * fds)
msg->retrans
=
timer_add_event("message_send_expire",
(void (*) (void *))
message_send_expire,
- msg, &expiration);
+ msg, expiry);
/*
* If we cannot retransmit, we
* cannot...
Index: sbin/isakmpd/ui.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/ui.c,v
retrieving revision 1.56
diff -u -p -r1.56 ui.c
--- sbin/isakmpd/ui.c 1 Dec 2014 23:05:18 -0000 1.56
+++ sbin/isakmpd/ui.c 24 Nov 2017 20:54:37 -0000
@@ -197,16 +197,10 @@ ui_conn_reinit_event(void *v)
static void
ui_conn_reinit(void)
{
- struct timeval tv;
-
if (ui_cr_event)
timer_remove_event(ui_cr_event);
-
- gettimeofday(&tv, 0);
- tv.tv_sec += 5;
-
ui_cr_event = timer_add_event("ui_conn_reinit", ui_conn_reinit_event,
- 0, &tv);
+ NULL, 5);
if (!ui_cr_event)
log_print("ui_conn_reinit: timer_add_event() failed. "
"Connections will not be updated.");
Index: sbin/isakmpd/util.c
===================================================================
RCS file: /cvs/src/sbin/isakmpd/util.c,v
retrieving revision 1.69
diff -u -p -r1.69 util.c
--- sbin/isakmpd/util.c 20 Aug 2015 22:02:21 -0000 1.69
+++ sbin/isakmpd/util.c 24 Nov 2017 20:54:37 -0000
@@ -552,17 +552,14 @@ check_file_secrecy_fd(int fd, char *name
return 0;
}
-/* Calculate timeout. Returns -1 on error. */
+/* Calculate timeout. */
long
-get_timeout(struct timeval *timeout)
+get_timeout(struct timespec *timeout)
{
- struct timeval now, result;
-
- if (gettimeofday(&now, NULL) < 0)
- return -1;
-
- timersub(timeout, &now, &result);
+ struct timespec now, result;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timespecsub(timeout, &now, &result);
return result.tv_sec;
}
Index: sbin/isakmpd/util.h
===================================================================
RCS file: /cvs/src/sbin/isakmpd/util.h,v
retrieving revision 1.32
diff -u -p -r1.32 util.h
--- sbin/isakmpd/util.h 23 Jan 2014 01:04:28 -0000 1.32
+++ sbin/isakmpd/util.h 24 Nov 2017 20:54:37 -0000
@@ -34,7 +34,8 @@
#define _UTIL_H_
#include <sys/types.h>
-#include <sys/time.h>
+
+#include <time.h>
extern int allow_name_lookups;
@@ -60,7 +61,7 @@ extern int text2sockaddr(char *, ch
sa_family_t, int);
extern void util_ntoa(char **, int, u_int8_t *);
extern int zero_test(const u_int8_t *, size_t);
-extern long get_timeout(struct timeval *);
+extern long get_timeout(struct timespec *);
extern int expand_string(char *, size_t, const char *, const char *);
#endif /* _UTIL_H_ */