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**)&current))
        !           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>