Annotation of embedaddon/strongswan/src/libcharon/sa/eap/eap_manager.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2012 Tobias Brunner
        !             3:  * Copyright (C) 2008 Martin Willi
        !             4:  * HSR Hochschule fuer Technik Rapperswil
        !             5:  *
        !             6:  * This program is free software; you can redistribute it and/or modify it
        !             7:  * under the terms of the GNU General Public License as published by the
        !             8:  * Free Software Foundation; either version 2 of the License, or (at your
        !             9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            10:  *
        !            11:  * This program is distributed in the hope that it will be useful, but
        !            12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            14:  * for more details.
        !            15:  */
        !            16: 
        !            17: #include "eap_manager.h"
        !            18: 
        !            19: #include <collections/linked_list.h>
        !            20: #include <threading/rwlock.h>
        !            21: 
        !            22: typedef struct private_eap_manager_t private_eap_manager_t;
        !            23: typedef struct eap_entry_t eap_entry_t;
        !            24: 
        !            25: /**
        !            26:  * EAP constructor entry
        !            27:  */
        !            28: struct eap_entry_t {
        !            29: 
        !            30:        /**
        !            31:         * EAP method type, vendor specific if vendor is set
        !            32:         */
        !            33:        eap_type_t type;
        !            34: 
        !            35:        /**
        !            36:         * vendor ID, 0 for default EAP methods
        !            37:         */
        !            38:        uint32_t vendor;
        !            39: 
        !            40:        /**
        !            41:         * Role of the method returned by the constructor, EAP_SERVER or EAP_PEER
        !            42:         */
        !            43:        eap_role_t role;
        !            44: 
        !            45:        /**
        !            46:         * constructor function to create instance
        !            47:         */
        !            48:        eap_constructor_t constructor;
        !            49: };
        !            50: 
        !            51: /**
        !            52:  * private data of eap_manager
        !            53:  */
        !            54: struct private_eap_manager_t {
        !            55: 
        !            56:        /**
        !            57:         * public functions
        !            58:         */
        !            59:        eap_manager_t public;
        !            60: 
        !            61:        /**
        !            62:         * list of eap_entry_t's
        !            63:         */
        !            64:        linked_list_t *methods;
        !            65: 
        !            66:        /**
        !            67:         * rwlock to lock methods
        !            68:         */
        !            69:        rwlock_t *lock;
        !            70: };
        !            71: 
        !            72: METHOD(eap_manager_t, add_method, void,
        !            73:        private_eap_manager_t *this, eap_type_t type, uint32_t vendor,
        !            74:        eap_role_t role, eap_constructor_t constructor)
        !            75: {
        !            76:        eap_entry_t *entry = malloc_thing(eap_entry_t);
        !            77: 
        !            78:        entry->type = type;
        !            79:        entry->vendor = vendor;
        !            80:        entry->role = role;
        !            81:        entry->constructor = constructor;
        !            82: 
        !            83:        this->lock->write_lock(this->lock);
        !            84:        this->methods->insert_last(this->methods, entry);
        !            85:        this->lock->unlock(this->lock);
        !            86: }
        !            87: 
        !            88: METHOD(eap_manager_t, remove_method, void,
        !            89:        private_eap_manager_t *this, eap_constructor_t constructor)
        !            90: {
        !            91:        enumerator_t *enumerator;
        !            92:        eap_entry_t *entry;
        !            93: 
        !            94:        this->lock->write_lock(this->lock);
        !            95:        enumerator = this->methods->create_enumerator(this->methods);
        !            96:        while (enumerator->enumerate(enumerator, &entry))
        !            97:        {
        !            98:                if (constructor == entry->constructor)
        !            99:                {
        !           100:                        this->methods->remove_at(this->methods, enumerator);
        !           101:                        free(entry);
        !           102:                }
        !           103:        }
        !           104:        enumerator->destroy(enumerator);
        !           105:        this->lock->unlock(this->lock);
        !           106: }
        !           107: 
        !           108: CALLBACK(filter_methods, bool,
        !           109:        uintptr_t role, enumerator_t *orig, va_list args)
        !           110: {
        !           111:        eap_entry_t *entry;
        !           112:        eap_type_t *type;
        !           113:        uint32_t *vendor;
        !           114: 
        !           115:        VA_ARGS_VGET(args, type, vendor);
        !           116: 
        !           117:        while (orig->enumerate(orig, &entry))
        !           118:        {
        !           119:                if (entry->role != (eap_role_t)role)
        !           120:                {
        !           121:                        continue;
        !           122:                }
        !           123:                if (entry->vendor == 0 &&
        !           124:                   (entry->type < 4 || entry->type == EAP_EXPANDED ||
        !           125:                    entry->type > EAP_EXPERIMENTAL))
        !           126:                {       /* filter invalid types */
        !           127:                        continue;
        !           128:                }
        !           129:                if (type)
        !           130:                {
        !           131:                        *type = entry->type;
        !           132:                }
        !           133:                if (vendor)
        !           134:                {
        !           135:                        *vendor = entry->vendor;
        !           136:                }
        !           137:                return TRUE;
        !           138:        }
        !           139:        return FALSE;
        !           140: }
        !           141: 
        !           142: METHOD(eap_manager_t, create_enumerator, enumerator_t*,
        !           143:        private_eap_manager_t *this, eap_role_t role)
        !           144: {
        !           145:        this->lock->read_lock(this->lock);
        !           146:        return enumerator_create_cleaner(
        !           147:                                enumerator_create_filter(
        !           148:                                        this->methods->create_enumerator(this->methods),
        !           149:                                        filter_methods, (void*)(uintptr_t)role, NULL),
        !           150:                                (void*)this->lock->unlock, this->lock);
        !           151: }
        !           152: 
        !           153: METHOD(eap_manager_t, create_instance, eap_method_t*,
        !           154:        private_eap_manager_t *this, eap_type_t type, uint32_t vendor,
        !           155:        eap_role_t role, identification_t *server, identification_t *peer)
        !           156: {
        !           157:        enumerator_t *enumerator;
        !           158:        eap_entry_t *entry;
        !           159:        eap_method_t *method = NULL;
        !           160: 
        !           161:        this->lock->read_lock(this->lock);
        !           162:        enumerator = this->methods->create_enumerator(this->methods);
        !           163:        while (enumerator->enumerate(enumerator, &entry))
        !           164:        {
        !           165:                if (type == entry->type && vendor == entry->vendor &&
        !           166:                        role == entry->role)
        !           167:                {
        !           168:                        method = entry->constructor(server, peer);
        !           169:                        if (method)
        !           170:                        {
        !           171:                                break;
        !           172:                        }
        !           173:                }
        !           174:        }
        !           175:        enumerator->destroy(enumerator);
        !           176:        this->lock->unlock(this->lock);
        !           177:        return method;
        !           178: }
        !           179: 
        !           180: METHOD(eap_manager_t, destroy, void,
        !           181:        private_eap_manager_t *this)
        !           182: {
        !           183:        this->methods->destroy_function(this->methods, free);
        !           184:        this->lock->destroy(this->lock);
        !           185:        free(this);
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * See header
        !           190:  */
        !           191: eap_manager_t *eap_manager_create()
        !           192: {
        !           193:        private_eap_manager_t *this;
        !           194: 
        !           195:        INIT(this,
        !           196:                        .public = {
        !           197:                                .add_method = _add_method,
        !           198:                                .remove_method = _remove_method,
        !           199:                                .create_enumerator = _create_enumerator,
        !           200:                                .create_instance = _create_instance,
        !           201:                                .destroy = _destroy,
        !           202:                        },
        !           203:                        .methods = linked_list_create(),
        !           204:                        .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        !           205:        );
        !           206: 
        !           207:        return &this->public;
        !           208: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>