Annotation of embedaddon/strongswan/src/libipsec/ipsec_event_relay.c, revision 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>