1 /* $OpenBSD: timer.c,v 1.3 2011/01/21 11:56:00 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 35 struct 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 45 void timer_initiator_cb(int, short, void *); 46 47 #define IKED_TIMER_INITIATOR_INITIAL 2 48 #define IKED_TIMER_INITIATOR_INTERVAL 60 49 50 void 51 timer_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 tmr = &timer_initiator; 59 gettimeofday(&tmr->tmr_first, NULL); 60 gettimeofday(&tmr->tmr_last, NULL); 61 62 tmr->tmr_env = env; 63 tmr->tmr_initcb = cb; 64 tmr->tmr_active = 1; 65 evtimer_set(&tmr->tmr_ev, timer_initiator_cb, tmr); 66 67 tmr->tmr_tv.tv_sec = IKED_TIMER_INITIATOR_INITIAL; 68 tmr->tmr_tv.tv_usec = 0; 69 evtimer_add(&tmr->tmr_ev, &tmr->tmr_tv); 70 } 71 72 void 73 timer_unregister_initiator(struct iked *env) 74 { 75 struct timer_cbarg *tmr; 76 77 tmr = &timer_initiator; 78 if (!tmr->tmr_active) 79 return; 80 81 event_del(&tmr->tmr_ev); 82 bzero(tmr, sizeof(*tmr)); 83 } 84 85 void 86 timer_initiator_cb(int fd, short event, void *arg) 87 { 88 struct timer_cbarg *tmr = arg; 89 struct iked *env = tmr->tmr_env; 90 struct iked_policy *pol; 91 92 gettimeofday(&tmr->tmr_last, NULL); 93 94 TAILQ_FOREACH(pol, &env->sc_policies, pol_entry) { 95 if ((pol->pol_flags & IKED_POLICY_ACTIVE) == 0) 96 continue; 97 if (sa_peer_lookup(pol, &pol->pol_peer.addr) != NULL) { 98 log_debug("%s: \"%s\" is already active", 99 __func__, pol->pol_name); 100 continue; 101 } 102 103 log_debug("%s: initiating \"%s\"", __func__, pol->pol_name); 104 105 if (tmr->tmr_initcb != NULL) { 106 /* Ignore error but what should we do on failure? */ 107 (void)tmr->tmr_initcb(env, pol); 108 } 109 } 110 111 tmr->tmr_tv.tv_sec = IKED_TIMER_INITIATOR_INTERVAL; 112 tmr->tmr_tv.tv_usec = 0; 113 evtimer_add(&tmr->tmr_ev, &tmr->tmr_tv); 114 } 115