Annotation of embedaddon/strongswan/src/libcharon/sa/eap/eap_manager.c, revision 1.1.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>