diff options
Diffstat (limited to 'src/charon/config/attributes')
-rw-r--r-- | src/charon/config/attributes/attribute_handler.h | 60 | ||||
-rw-r--r-- | src/charon/config/attributes/attribute_manager.c | 112 | ||||
-rw-r--r-- | src/charon/config/attributes/attribute_manager.h | 59 | ||||
-rw-r--r-- | src/charon/config/attributes/attribute_provider.h | 9 |
4 files changed, 238 insertions, 2 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..c92c7a451 --- /dev/null +++ b/src/charon/config/attributes/attribute_handler.h @@ -0,0 +1,60 @@ +/* + * 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. + * + * $Id$ + */ + +/** + * @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 f0ae4ffa0..5e6efe724 100644 --- a/src/charon/config/attributes/attribute_manager.c +++ b/src/charon/config/attributes/attribute_manager.c @@ -39,6 +39,11 @@ struct private_attribute_manager_t { linked_list_t *providers; /** + * list of registered handlers + */ + linked_list_t *handlers; + + /** * rwlock provider list */ rwlock_t *lock; @@ -105,6 +110,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 +155,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); } @@ -145,11 +251,17 @@ attribute_manager_t *attribute_manager_create() 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 750f83c58..ff6db0cf9 100644 --- a/src/charon/config/attributes/attribute_manager.h +++ b/src/charon/config/attributes/attribute_manager.h @@ -24,14 +24,20 @@ #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. * @@ -55,6 +61,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 @@ -68,6 +83,46 @@ 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); + + /** + * 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. */ diff --git a/src/charon/config/attributes/attribute_provider.h b/src/charon/config/attributes/attribute_provider.h index cbd0075ad..2b0efdeae 100644 --- a/src/charon/config/attributes/attribute_provider.h +++ b/src/charon/config/attributes/attribute_provider.h @@ -54,6 +54,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_ @}*/ |