Return to eap_manager.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / sa / eap |
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: }