timer.c revision 1.4
1/*	$OpenBSD: timer.c,v 1.4 2011/01/26 17:07:59 reyk Exp $	*/
2
3/*
4 * Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/queue.h>
21#include <sys/socket.h>
22#include <sys/uio.h>
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <string.h>
28#include <errno.h>
29#include <fcntl.h>
30#include <ctype.h>
31#include <event.h>
32
33#include "iked.h"
34
35struct timer_cbarg {
36	int		 tmr_active;
37	struct event	 tmr_ev;
38	struct iked	*tmr_env;
39	struct timeval	 tmr_first;
40	struct timeval	 tmr_last;
41	struct timeval	 tmr_tv;
42	int		(*tmr_initcb)(struct iked *, struct iked_policy *);
43} timer_initiator;
44
45void	 timer_initiator_cb(int, short, void *);
46
47#define IKED_TIMER_INITIATOR_INITIAL	2
48#define IKED_TIMER_INITIATOR_INTERVAL	60
49
50void
51timer_register_initiator(struct iked *env,
52    int (*cb)(struct iked *, struct iked_policy *))
53{
54	struct timer_cbarg	*tmr;
55
56	timer_unregister_initiator(env);
57
58	if (env->sc_passive)
59		return;
60
61	tmr = &timer_initiator;
62	gettimeofday(&tmr->tmr_first, NULL);
63	gettimeofday(&tmr->tmr_last, NULL);
64
65	tmr->tmr_env = env;
66	tmr->tmr_initcb = cb;
67	tmr->tmr_active = 1;
68	evtimer_set(&tmr->tmr_ev, timer_initiator_cb, tmr);
69
70	tmr->tmr_tv.tv_sec = IKED_TIMER_INITIATOR_INITIAL;
71	tmr->tmr_tv.tv_usec = 0;
72	evtimer_add(&tmr->tmr_ev, &tmr->tmr_tv);
73}
74
75void
76timer_unregister_initiator(struct iked *env)
77{
78	struct timer_cbarg	*tmr;
79
80	tmr = &timer_initiator;
81	if (!tmr->tmr_active)
82		return;
83
84	event_del(&tmr->tmr_ev);
85	bzero(tmr, sizeof(*tmr));
86}
87
88void
89timer_initiator_cb(int fd, short event, void *arg)
90{
91	struct timer_cbarg	*tmr = arg;
92	struct iked		*env = tmr->tmr_env;
93	struct iked_policy	*pol;
94
95	gettimeofday(&tmr->tmr_last, NULL);
96
97	TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) {
98		if ((pol->pol_flags & IKED_POLICY_ACTIVE) == 0)
99			continue;
100		if (sa_peer_lookup(pol, &pol->pol_peer.addr) != NULL) {
101			log_debug("%s: \"%s\" is already active",
102			    __func__, pol->pol_name);
103			continue;
104		}
105
106		log_debug("%s: initiating \"%s\"", __func__, pol->pol_name);
107
108		if (tmr->tmr_initcb != NULL) {
109			/* Ignore error but what should we do on failure? */
110			(void)tmr->tmr_initcb(env, pol);
111		}
112	}
113
114	tmr->tmr_tv.tv_sec = IKED_TIMER_INITIATOR_INTERVAL;
115	tmr->tmr_tv.tv_usec = 0;
116	evtimer_add(&tmr->tmr_ev, &tmr->tmr_tv);
117}
118