diff options
Diffstat (limited to 'src/charon/config/attributes')
-rw-r--r-- | src/charon/config/attributes/attribute_handler.h | 58 | ||||
-rw-r--r-- | src/charon/config/attributes/attribute_manager.c | 120 | ||||
-rw-r--r-- | src/charon/config/attributes/attribute_manager.h | 74 | ||||
-rw-r--r-- | src/charon/config/attributes/attribute_provider.h | 16 |
4 files changed, 247 insertions, 21 deletions
diff --git a/src/charon/config/attributes/attribute_handler.h b/src/charon/config/attributes/attribute_handler.h new file mode 100644 index 000000000..de1c4414d --- /dev/null +++ b/src/charon/config/attributes/attribute_handler.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup attribute_handler attribute_handler + * @{ @ingroup attributes + */ + +#ifndef ATTRIBUTE_HANDLER_H_ +#define ATTRIBUTE_HANDLER_H_ + +#include <sa/ike_sa.h> +#include <encoding/payloads/configuration_attribute.h> + +typedef struct attribute_handler_t attribute_handler_t; + +/** + * Interface to handle configuration payload attributes. + */ +struct attribute_handler_t { + + /** + * Handle a configuration attribute. + * + * After receiving a configuration attriubte, it is passed to each + * attribute handler until it is handled. + * + * @param type type of configuration attribute to handle + * @param data associated attribute data + * @return TRUE if attribute handled + */ + bool (*handle)(attribute_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data); + + /** + * Release an attribute handled during handle(). + * + * A handler that handle()d an attribute gets a call to release() when the + * IKE_SA gets closed. Depending on the implementation, this is required + * to remove the attribute. + */ + void (*release)(attribute_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data); +}; + +#endif /* ATTRIBUTE_HANDLER_ @}*/ diff --git a/src/charon/config/attributes/attribute_manager.c b/src/charon/config/attributes/attribute_manager.c index a069c954a..83e431c43 100644 --- a/src/charon/config/attributes/attribute_manager.c +++ b/src/charon/config/attributes/attribute_manager.c @@ -11,8 +11,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * $Id$ */ #include "attribute_manager.h" @@ -39,6 +37,11 @@ struct private_attribute_manager_t { linked_list_t *providers; /** + * list of registered handlers + */ + linked_list_t *handlers; + + /** * rwlock provider list */ rwlock_t *lock; @@ -49,7 +52,7 @@ struct private_attribute_manager_t { */ static host_t* acquire_address(private_attribute_manager_t *this, char *pool, identification_t *id, - auth_info_t *auth, host_t *requested) + host_t *requested) { enumerator_t *enumerator; attribute_provider_t *current; @@ -59,7 +62,7 @@ static host_t* acquire_address(private_attribute_manager_t *this, enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, ¤t)) { - host = current->acquire_address(current, pool, id, auth, requested); + host = current->acquire_address(current, pool, id, requested); if (host) { break; @@ -105,6 +108,29 @@ static void release_address(private_attribute_manager_t *this, } /** + * inner enumerator constructor for attributes + */ +static enumerator_t *attrib_enum_create(attribute_provider_t *provider, + identification_t *id) +{ + return provider->create_attribute_enumerator(provider, id); +} + +/** + * Implementation of attribute_manager_t.create_attribute_enumerator + */ +static enumerator_t* create_attribute_enumerator( + private_attribute_manager_t *this, identification_t *id) +{ + this->lock->read_lock(this->lock); + return enumerator_create_cleaner( + enumerator_create_nested( + this->providers->create_enumerator(this->providers), + (void*)attrib_enum_create, id, NULL), + (void*)this->lock->unlock, this->lock); +} + +/** * Implementation of attribute_manager_t.add_provider. */ static void add_provider(private_attribute_manager_t *this, @@ -127,11 +153,89 @@ static void remove_provider(private_attribute_manager_t *this, } /** + * Implementation of attribute_manager_t.handle + */ +static attribute_handler_t* handle(private_attribute_manager_t *this, + ike_sa_t *ike_sa, configuration_attribute_type_t type, + chunk_t data) +{ + enumerator_t *enumerator; + attribute_handler_t *current, *handled = NULL; + + this->lock->read_lock(this->lock); + enumerator = this->handlers->create_enumerator(this->handlers); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (current->handle(current, ike_sa, type, data)) + { + handled = current; + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + if (!handled) + { + DBG1(DBG_CFG, "handling %N attribute failed", + configuration_attribute_type_names, type); + } + return handled; +} + +/** + * Implementation of attribute_manager_t.release + */ +static void release(private_attribute_manager_t *this, + attribute_handler_t *handler, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + enumerator_t *enumerator; + attribute_handler_t *current; + + this->lock->read_lock(this->lock); + enumerator = this->handlers->create_enumerator(this->handlers); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (current == handler) + { + current->release(current, ike_sa, type, data); + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); +} + +/** + * Implementation of attribute_manager_t.add_handler + */ +static void add_handler(private_attribute_manager_t *this, + attribute_handler_t *handler) +{ + this->lock->write_lock(this->lock); + this->handlers->insert_last(this->handlers, handler); + this->lock->unlock(this->lock); +} + +/** + * Implementation of attribute_manager_t.remove_handler + */ +static void remove_handler(private_attribute_manager_t *this, + attribute_handler_t *handler) +{ + this->lock->write_lock(this->lock); + this->handlers->remove(this->handlers, handler, NULL); + this->lock->unlock(this->lock); +} + +/** * Implementation of attribute_manager_t.destroy */ static void destroy(private_attribute_manager_t *this) { this->providers->destroy(this->providers); + this->handlers->destroy(this->handlers); this->lock->destroy(this->lock); free(this); } @@ -143,13 +247,19 @@ attribute_manager_t *attribute_manager_create() { private_attribute_manager_t *this = malloc_thing(private_attribute_manager_t); - this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,auth_info_t*,host_t*))acquire_address; + this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address; this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address; + this->public.create_attribute_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t *id))create_attribute_enumerator; this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider; this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider; + this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data))handle; + this->public.release = (void(*)(attribute_manager_t*, attribute_handler_t *handler, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data))release; + this->public.add_handler = (void(*)(attribute_manager_t*, attribute_handler_t *handler))add_handler; + this->public.remove_handler = (void(*)(attribute_manager_t*, attribute_handler_t *handler))remove_handler; this->public.destroy = (void(*)(attribute_manager_t*))destroy; this->providers = linked_list_create(); + this->handlers = linked_list_create(); this->lock = rwlock_create(RWLOCK_DEFAULT); return &this->public; diff --git a/src/charon/config/attributes/attribute_manager.h b/src/charon/config/attributes/attribute_manager.h index aef6e7b6e..ceea06581 100644 --- a/src/charon/config/attributes/attribute_manager.h +++ b/src/charon/config/attributes/attribute_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Martin Willi + * Copyright (C) 2008-2009 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -11,8 +11,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * $Id$ */ /** @@ -24,26 +22,31 @@ #define ATTRIBUTE_MANAGER_H_ #include <config/attributes/attribute_provider.h> +#include <config/attributes/attribute_handler.h> typedef struct attribute_manager_t attribute_manager_t; /** - * Provide configuration attributes to include in CFG Payloads. + * The attribute manager hands out attributes or handles them. + * + * The attribute manager manages both, attribute providers and attribute + * handlers. Attribute providers are responsible to hand out attributes if + * a connecting peer requests them. Handlers handle such attributes if they + * are received on the requesting peer. */ struct attribute_manager_t { - + /** * Acquire a virtual IP address to assign to a peer. * * @param pool pool name to acquire address from - * @param id peer identity to get address for - * @param auth authorization infos of peer + * @param id peer identity to get address forua * @param requested IP in configuration request * @return allocated address, NULL to serve none */ host_t* (*acquire_address)(attribute_manager_t *this, char *pool, identification_t *id, - auth_info_t *auth, host_t *requested); + host_t *requested); /** * Release a previously acquired address. @@ -56,6 +59,15 @@ struct attribute_manager_t { char *pool, host_t *address, identification_t *id); /** + * Create an enumerator over attributes to hand out to a peer. + * + * @param id peer identity to hand out attributes to + * @return enumerator (configuration_attribute_type_t, chunk_t) + */ + enumerator_t* (*create_attribute_enumerator)(attribute_manager_t *this, + identification_t *id); + + /** * Register an attribute provider to the manager. * * @param provider attribute provider to register @@ -69,10 +81,50 @@ struct attribute_manager_t { */ void (*remove_provider)(attribute_manager_t *this, attribute_provider_t *provider); + + /** + * Handle a configuration attribute by passing them to the handlers. + * + * @param ike_sa IKE_SA where attribute was received + * @param type type of configuration attribute + * @param data associated attribute data + * @return handler which handled this attribute, NULL if none + */ + attribute_handler_t* (*handle)(attribute_manager_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data); + /** - * Destroy a attribute_manager instance. - */ - void (*destroy)(attribute_manager_t *this); + * Release an attribute previously handle()d by a handler. + * + * @param handler handler returned by handle() for this attribute + * @param ike_sa IKE_SA owning the attribute + * @param type type of attribute to release + * @param data associated attribute data + */ + void (*release)(attribute_manager_t *this, attribute_handler_t *handler, + ike_sa_t *ike_sa, configuration_attribute_type_t type, + chunk_t data); + + /** + * Register an attribute handler to the manager. + * + * @param handler attribute handler to register + */ + void (*add_handler)(attribute_manager_t *this, + attribute_handler_t *handler); + + /** + * Unregister an attribute handler from the manager. + * + * @param handler attribute handler to unregister + */ + void (*remove_handler)(attribute_manager_t *this, + attribute_handler_t *handler); + + /** + * Destroy a attribute_manager instance. + */ + void (*destroy)(attribute_manager_t *this); }; /** diff --git a/src/charon/config/attributes/attribute_provider.h b/src/charon/config/attributes/attribute_provider.h index 5d563e86b..0f1057af4 100644 --- a/src/charon/config/attributes/attribute_provider.h +++ b/src/charon/config/attributes/attribute_provider.h @@ -11,8 +11,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * $Id$ */ /** @@ -25,7 +23,7 @@ #include <library.h> #include <utils/host.h> -#include <credentials/auth_info.h> +#include <utils/identification.h> typedef struct attribute_provider_t attribute_provider_t; @@ -39,13 +37,12 @@ struct attribute_provider_t { * * @param pool name of the pool to acquire address from * @param id peer ID - * @param auth authorization infos * @param requested IP in configuration request * @return allocated address, NULL to serve none */ host_t* (*acquire_address)(attribute_provider_t *this, char *pool, identification_t *id, - auth_info_t *auth, host_t *requested); + host_t *requested); /** * Release a previously acquired address. * @@ -56,6 +53,15 @@ struct attribute_provider_t { */ bool (*release_address)(attribute_provider_t *this, char *pool, host_t *address, identification_t *id); + + /** + * Create an enumerator over attributes to hand out to a peer. + * + * @param id peer ID + * @return enumerator (configuration_attribute_type_t, chunk_t) + */ + enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this, + identification_t *id); }; #endif /** ATTRIBUTE_PROVIDER_H_ @}*/ |