Annotation of embedaddon/ipsec-tools/src/racoon/evt.c, revision 1.1.1.1
1.1 misho 1: /* $NetBSD: evt.c,v 1.10 2010/10/21 06:15:28 tteras Exp $ */
2:
3: /* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */
4:
5: /*
6: * Copyright (C) 2004 Emmanuel Dreyfus
7: * Copyright (C) 2008 Timo Teras
8: * All rights reserved.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. Neither the name of the project nor the names of its contributors
19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
35: #include "config.h"
36:
37: #include <errno.h>
38: #include <string.h>
39: #include <stdio.h>
40: #include <time.h>
41: #include <unistd.h>
42: #include <stdlib.h>
43: #include <sys/queue.h>
44: #include <sys/socket.h>
45:
46: #include "vmbuf.h"
47: #include "plog.h"
48: #include "misc.h"
49: #include "admin.h"
50: #include "handler.h"
51: #include "session.h"
52: #include "gcmalloc.h"
53: #include "evt.h"
54: #include "var.h"
55:
56: #ifdef ENABLE_ADMINPORT
57:
58: static EVT_LISTENER_LIST(evt_listeners);
59:
60: struct evt_message {
61: struct admin_com adm;
62: struct evt_async evt;
63: };
64:
65: struct evt {
66: struct evtdump *dump;
67: TAILQ_ENTRY(evt) next;
68: };
69:
70: TAILQ_HEAD(evtlist, evt);
71:
72: #define EVTLIST_MAX 32
73:
74: static struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
75: static int evtlist_len = 0;
76: static int evtlist_inuse = 0;
77:
78: static struct {
79: int newtype, oldtype;
80: } evttype_map[] = {
81: { EVT_RACOON_QUIT, EVTT_RACOON_QUIT },
82: { EVT_PHASE1_UP, EVTT_PHASE1_UP },
83: { EVT_PHASE1_DOWN, EVTT_PHASE1_DOWN },
84: { EVT_PHASE1_NO_RESPONSE, EVTT_PEER_NO_RESPONSE },
85: { EVT_PHASE1_NO_PROPOSAL, EVTT_PEERPH1_NOPROP },
86: { EVT_PHASE1_AUTH_FAILED, EVTT_PEERPH1AUTH_FAILED },
87: { EVT_PHASE1_DPD_TIMEOUT, EVTT_DPD_TIMEOUT },
88: { EVT_PHASE1_PEER_DELETED, EVTT_PEER_DELETE },
89: { EVT_PHASE1_MODE_CFG, EVTT_ISAKMP_CFG_DONE },
90: { EVT_PHASE1_XAUTH_SUCCESS, EVTT_XAUTH_SUCCESS },
91: { EVT_PHASE1_XAUTH_FAILED, EVTT_XAUTH_FAILED },
92: { EVT_PHASE2_NO_PHASE1, -1 },
93: { EVT_PHASE2_UP, EVTT_PHASE2_UP },
94: { EVT_PHASE2_DOWN, EVTT_PHASE2_DOWN },
95: { EVT_PHASE2_NO_RESPONSE, EVTT_PEER_NO_RESPONSE },
96: };
97:
98: static void
99: evt_push(src, dst, type, optdata)
100: struct sockaddr *src;
101: struct sockaddr *dst;
102: int type;
103: vchar_t *optdata;
104: {
105: struct evtdump *evtdump;
106: struct evt *evt;
107: size_t len;
108: int i;
109:
110: /* If admin socket is disabled, silently discard anything */
111: if (adminsock_path == NULL || !evtlist_inuse)
112: return;
113:
114: /* Map the event type to old */
115: for (i = 0; i < sizeof(evttype_map) / sizeof(evttype_map[0]); i++)
116: if (evttype_map[i].newtype == type)
117: break;
118: if (i >= sizeof(evttype_map) / sizeof(evttype_map[0]))
119: return;
120:
121: type = evttype_map[i].oldtype;
122: if (type < 0)
123: return;
124:
125: /* If we are above the limit, don't record anything */
126: if (evtlist_len > EVTLIST_MAX) {
127: plog(LLV_DEBUG, LOCATION, NULL,
128: "Cannot record event: event queue overflowed\n");
129: return;
130: }
131:
132: /* If we hit the limit, record an overflow event instead */
133: if (evtlist_len == EVTLIST_MAX) {
134: plog(LLV_ERROR, LOCATION, NULL,
135: "Cannot record event: event queue overflow\n");
136: src = NULL;
137: dst = NULL;
138: type = EVTT_OVERFLOW;
139: optdata = NULL;
140: }
141:
142: len = sizeof(*evtdump);
143: if (optdata)
144: len += optdata->l;
145:
146: if ((evtdump = racoon_malloc(len)) == NULL) {
147: plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
148: strerror(errno));
149: return;
150: }
151:
152: if ((evt = racoon_malloc(sizeof(*evt))) == NULL) {
153: plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
154: strerror(errno));
155: racoon_free(evtdump);
156: return;
157: }
158:
159: if (src)
160: memcpy(&evtdump->src, src, sysdep_sa_len(src));
161: if (dst)
162: memcpy(&evtdump->dst, dst, sysdep_sa_len(dst));
163: evtdump->len = len;
164: evtdump->type = type;
165: time(&evtdump->timestamp);
166:
167: if (optdata)
168: memcpy(evtdump + 1, optdata->v, optdata->l);
169:
170: evt->dump = evtdump;
171: TAILQ_INSERT_TAIL(&evtlist, evt, next);
172:
173: evtlist_len++;
174:
175: return;
176: }
177:
178: static struct evtdump *
179: evt_pop(void) {
180: struct evtdump *evtdump;
181: struct evt *evt;
182:
183: if ((evt = TAILQ_FIRST(&evtlist)) == NULL)
184: return NULL;
185:
186: evtdump = evt->dump;
187: TAILQ_REMOVE(&evtlist, evt, next);
188: racoon_free(evt);
189: evtlist_len--;
190:
191: return evtdump;
192: }
193:
194: vchar_t *
195: evt_dump(void) {
196: struct evtdump *evtdump;
197: vchar_t *buf = NULL;
198:
199: if (!evtlist_inuse) {
200: evtlist_inuse = 1;
201: plog(LLV_ERROR, LOCATION, NULL,
202: "evt_dump: deprecated event polling used\n");
203: }
204:
205: if ((evtdump = evt_pop()) != NULL) {
206: if ((buf = vmalloc(evtdump->len)) == NULL) {
207: plog(LLV_ERROR, LOCATION, NULL,
208: "evt_dump failed: %s\n", strerror(errno));
209: return NULL;
210: }
211: memcpy(buf->v, evtdump, evtdump->len);
212: racoon_free(evtdump);
213: }
214:
215: return buf;
216: }
217:
218: static struct evt_message *
219: evtmsg_create(type, optdata)
220: int type;
221: vchar_t *optdata;
222: {
223: struct evt_message *e;
224: size_t len;
225:
226: len = sizeof(struct evt_message);
227: if (optdata != NULL)
228: len += optdata->l;
229:
230: if ((e = racoon_malloc(len)) == NULL) {
231: plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate event: %s\n",
232: strerror(errno));
233: return NULL;
234: }
235:
236: memset(e, 0, sizeof(struct evt_message));
237: e->adm.ac_len = len;
238: e->adm.ac_cmd = ADMIN_SHOW_EVT;
239: e->adm.ac_errno = 0;
240: e->adm.ac_proto = 0;
241: e->evt.ec_type = type;
242: time(&e->evt.ec_timestamp);
243: if (optdata != NULL)
244: memcpy(e + 1, optdata->v, optdata->l);
245:
246: return e;
247: }
248:
249: static void
250: evt_unsubscribe(l)
251: struct evt_listener *l;
252: {
253: plog(LLV_DEBUG, LOCATION, NULL,
254: "[%d] admin connection released\n", l->fd);
255:
256: LIST_REMOVE(l, ll_chain);
257: unmonitor_fd(l->fd);
258: close(l->fd);
259: racoon_free(l);
260: }
261:
262: static int
263: evt_unsubscribe_cb(ctx, fd)
264: void *ctx;
265: int fd;
266: {
267: evt_unsubscribe((struct evt_listener *) ctx);
268: return 0;
269: }
270:
271: static void
272: evtmsg_broadcast(ll, e)
273: const struct evt_listener_list *ll;
274: struct evt_message *e;
275: {
276: struct evt_listener *l, *nl;
277:
278: for (l = LIST_FIRST(ll); l != NULL; l = nl) {
279: nl = LIST_NEXT(l, ll_chain);
280:
281: if (send(l->fd, e, e->adm.ac_len, MSG_DONTWAIT) < 0) {
282: plog(LLV_DEBUG, LOCATION, NULL, "Cannot send event to fd: %s\n",
283: strerror(errno));
284: evt_unsubscribe(l);
285: }
286: }
287: }
288:
289: void
290: evt_generic(type, optdata)
291: int type;
292: vchar_t *optdata;
293: {
294: struct evt_message *e;
295:
296: if ((e = evtmsg_create(type, optdata)) == NULL)
297: return;
298:
299: evtmsg_broadcast(&evt_listeners, e);
300: evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
301:
302: racoon_free(e);
303: }
304:
305: void
306: evt_phase1(ph1, type, optdata)
307: const struct ph1handle *ph1;
308: int type;
309: vchar_t *optdata;
310: {
311: struct evt_message *e;
312:
313: if ((e = evtmsg_create(type, optdata)) == NULL)
314: return;
315:
316: if (ph1->local)
317: memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local));
318: if (ph1->remote)
319: memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote));
320:
321: evtmsg_broadcast(&ph1->evt_listeners, e);
322: evtmsg_broadcast(&evt_listeners, e);
323: evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
324:
325: racoon_free(e);
326: }
327:
328: void
329: evt_phase2(ph2, type, optdata)
330: const struct ph2handle *ph2;
331: int type;
332: vchar_t *optdata;
333: {
334: struct evt_message *e;
335: struct ph1handle *ph1 = ph2->ph1;
336:
337: if ((e = evtmsg_create(type, optdata)) == NULL)
338: return;
339:
340: if (ph1) {
341: if (ph1->local)
342: memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local));
343: if (ph1->remote)
344: memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote));
345: }
346: e->evt.ec_ph2msgid = ph2->msgid;
347:
348: evtmsg_broadcast(&ph2->evt_listeners, e);
349: if (ph1)
350: evtmsg_broadcast(&ph1->evt_listeners, e);
351: evtmsg_broadcast(&evt_listeners, e);
352: evt_push(&e->evt.ec_ph1src, &e->evt.ec_ph1dst, type, optdata);
353:
354: racoon_free(e);
355: }
356:
357: int
358: evt_subscribe(list, fd)
359: struct evt_listener_list *list;
360: int fd;
361: {
362: struct evt_listener *l;
363:
364: if ((l = racoon_malloc(sizeof(*l))) == NULL) {
365: plog(LLV_ERROR, LOCATION, NULL,
366: "Cannot allocate event listener: %s\n",
367: strerror(errno));
368: return errno;
369: }
370:
371: if (list == NULL)
372: list = &evt_listeners;
373:
374: LIST_INSERT_HEAD(list, l, ll_chain);
375: l->fd = fd;
376: monitor_fd(l->fd, evt_unsubscribe_cb, l, 0);
377:
378: plog(LLV_DEBUG, LOCATION, NULL,
379: "[%d] admin connection is polling events\n", fd);
380:
381: return -2;
382: }
383:
384: void
385: evt_list_init(list)
386: struct evt_listener_list *list;
387: {
388: LIST_INIT(list);
389: }
390:
391: void
392: evt_list_cleanup(list)
393: struct evt_listener_list *list;
394: {
395: while (!LIST_EMPTY(list))
396: evt_unsubscribe(LIST_FIRST(list));
397: }
398:
399: #endif /* ENABLE_ADMINPORT */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>