Annotation of embedaddon/strongswan/src/libipsec/ipsec_event_relay.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012 Tobias Brunner
3: * Copyright (C) 2012 Giuliano Grassi
4: * Copyright (C) 2012 Ralf Sager
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #include "ipsec_event_relay.h"
19:
20: #include <library.h>
21: #include <utils/debug.h>
22: #include <threading/rwlock.h>
23: #include <collections/linked_list.h>
24: #include <collections/blocking_queue.h>
25: #include <processing/jobs/callback_job.h>
26:
27: typedef struct private_ipsec_event_relay_t private_ipsec_event_relay_t;
28:
29: /**
30: * Private additions to ipsec_event_relay_t.
31: */
32: struct private_ipsec_event_relay_t {
33:
34: /**
35: * Public members
36: */
37: ipsec_event_relay_t public;
38:
39: /**
40: * Registered listeners
41: */
42: linked_list_t *listeners;
43:
44: /**
45: * Lock to safely access the list of listeners
46: */
47: rwlock_t *lock;
48:
49: /**
50: * Blocking queue for events
51: */
52: blocking_queue_t *queue;
53: };
54:
55: /**
56: * Helper struct used to manage events in a queue
57: */
58: typedef struct {
59:
60: /**
61: * Type of the event
62: */
63: enum {
64: IPSEC_EVENT_EXPIRE,
65: } type;
66:
67: /**
68: * Protocol of the SA
69: */
70: uint8_t protocol;
71:
72: /**
73: * SPI of the SA, if any
74: */
75: uint32_t spi;
76:
77: /**
78: * SA destination address
79: */
80: host_t *dst;
81:
82: /**
83: * Additional data for specific event types
84: */
85: union {
86:
87: struct {
88: /** TRUE in case of a hard expire */
89: bool hard;
90: } expire;
91:
92: } data;
93:
94: } ipsec_event_t;
95:
96: /**
97: * Destroy IPsec event data
98: */
99: static void ipsec_event_destroy(ipsec_event_t *event)
100: {
101: event->dst->destroy(event->dst);
102: free(event);
103: }
104:
105: /**
106: * Dequeue events and relay them to listeners
107: */
108: static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
109: {
110: enumerator_t *enumerator;
111: ipsec_event_listener_t *current;
112: ipsec_event_t *event;
113:
114: event = this->queue->dequeue(this->queue);
115:
116: this->lock->read_lock(this->lock);
117: enumerator = this->listeners->create_enumerator(this->listeners);
118: while (enumerator->enumerate(enumerator, (void**)¤t))
119: {
120: switch (event->type)
121: {
122: case IPSEC_EVENT_EXPIRE:
123: if (current->expire)
124: {
125: current->expire(event->protocol, event->spi, event->dst,
126: event->data.expire.hard);
127: }
128: break;
129: }
130: }
131: enumerator->destroy(enumerator);
132: this->lock->unlock(this->lock);
133: ipsec_event_destroy(event);
134: return JOB_REQUEUE_DIRECT;
135: }
136:
137: METHOD(ipsec_event_relay_t, expire, void,
138: private_ipsec_event_relay_t *this, uint8_t protocol, uint32_t spi,
139: host_t *dst, bool hard)
140: {
141: ipsec_event_t *event;
142:
143: INIT(event,
144: .type = IPSEC_EVENT_EXPIRE,
145: .protocol = protocol,
146: .spi = spi,
147: .dst = dst->clone(dst),
148: .data = {
149: .expire = {
150: .hard = hard,
151: },
152: },
153: );
154: this->queue->enqueue(this->queue, event);
155: }
156:
157: METHOD(ipsec_event_relay_t, register_listener, void,
158: private_ipsec_event_relay_t *this, ipsec_event_listener_t *listener)
159: {
160: this->lock->write_lock(this->lock);
161: this->listeners->insert_last(this->listeners, listener);
162: this->lock->unlock(this->lock);
163: }
164:
165: METHOD(ipsec_event_relay_t, unregister_listener, void,
166: private_ipsec_event_relay_t *this, ipsec_event_listener_t *listener)
167: {
168: this->lock->write_lock(this->lock);
169: this->listeners->remove(this->listeners, listener, NULL);
170: this->lock->unlock(this->lock);
171: }
172:
173: METHOD(ipsec_event_relay_t, destroy, void,
174: private_ipsec_event_relay_t *this)
175: {
176: this->queue->destroy_function(this->queue, free);
177: this->listeners->destroy(this->listeners);
178: this->lock->destroy(this->lock);
179: free(this);
180: }
181:
182: /**
183: * Described in header.
184: */
185: ipsec_event_relay_t *ipsec_event_relay_create()
186: {
187: private_ipsec_event_relay_t *this;
188:
189: INIT(this,
190: .public = {
191: .expire = _expire,
192: .register_listener = _register_listener,
193: .unregister_listener = _unregister_listener,
194: .destroy = _destroy,
195: },
196: .listeners = linked_list_create(),
197: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
198: .queue = blocking_queue_create(),
199: );
200:
201: lib->processor->queue_job(lib->processor,
202: (job_t*)callback_job_create((callback_job_cb_t)handle_events, this,
203: NULL, (callback_job_cancel_t)return_false));
204:
205: return &this->public;
206: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>