diff options
author | Martin Willi <martin@strongswan.org> | 2009-11-17 17:51:30 +0100 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-11-17 17:51:30 +0100 |
commit | 1860bfa2eada127dabd64e7ede103219aa2d215f (patch) | |
tree | 0b2fca14d86207f1bc346537fcc6d30469222cbc /src | |
parent | 1427c93fcdab3eb3bfb83a657cd834c547339361 (diff) | |
download | strongswan-1860bfa2eada127dabd64e7ede103219aa2d215f.tar.bz2 strongswan-1860bfa2eada127dabd64e7ede103219aa2d215f.tar.xz |
Correctly enumerate attributes to request as initiator with the actually requesting handler
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/attributes/attribute_manager.c | 73 |
1 files changed, 61 insertions, 12 deletions
diff --git a/src/libstrongswan/attributes/attribute_manager.c b/src/libstrongswan/attributes/attribute_manager.c index 0615316f9..66f1d27e8 100644 --- a/src/libstrongswan/attributes/attribute_manager.c +++ b/src/libstrongswan/attributes/attribute_manager.c @@ -238,12 +238,58 @@ static void release(private_attribute_manager_t *this, } /** - * inner enumerator constructor for initiator attributes + * Enumerator implementation to enumerate nested initiator attributes */ -static enumerator_t *initiator_enum_create(attribute_handler_t *handler, - enum_data_t *data) +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** back ref */ + private_attribute_manager_t *this; + /** currently processing handler */ + attribute_handler_t *handler; + /** outer enumerator over handlers */ + enumerator_t *outer; + /** inner enumerator over current handlers attributes */ + enumerator_t *inner; + /** server ID we want attributes for */ + identification_t *id; + /** virtual IP we are requesting along with attriubutes */ + host_t *vip; +} initiator_enumerator_t; + +/** + * Enumerator implementation for initiator attributes + */ +static bool initiator_enumerate(initiator_enumerator_t *this, + attribute_handler_t **handler, + configuration_attribute_type_t *type, + chunk_t *value) { - return handler->create_attribute_enumerator(handler, data->id, data->vip); + /* enumerate inner attributes using outer handler enumerator */ + while (!this->inner || !this->inner->enumerate(this->inner, type, value)) + { + if (!this->outer->enumerate(this->outer, &this->handler)) + { + return FALSE; + } + DESTROY_IF(this->inner); + this->inner = this->handler->create_attribute_enumerator(this->handler, + this->id, this->vip); + } + /* inject the handler as additional attribute */ + *handler = this->handler; + return TRUE; +} + +/** + * Cleanup function of initiator attribute enumerator + */ +static void initiator_destroy(initiator_enumerator_t *this) +{ + this->this->lock->unlock(this->this->lock); + this->outer->destroy(this->outer); + DESTROY_IF(this->inner); + free(this); } /** @@ -252,16 +298,19 @@ static enumerator_t *initiator_enum_create(attribute_handler_t *handler, static enumerator_t* create_initiator_enumerator( private_attribute_manager_t *this, identification_t *id, host_t *vip) { - enum_data_t *data = malloc_thing(enum_data_t); + initiator_enumerator_t *enumerator = malloc_thing(initiator_enumerator_t); - data->id = id; - data->vip = vip; this->lock->read_lock(this->lock); - return enumerator_create_cleaner( - enumerator_create_nested( - this->handlers->create_enumerator(this->handlers), - (void*)initiator_enum_create, data, free), - (void*)this->lock->unlock, this->lock); + enumerator->public.enumerate = (void*)initiator_enumerate; + enumerator->public.destroy = (void*)initiator_destroy; + enumerator->this = this; + enumerator->id = id; + enumerator->vip = vip; + enumerator->outer = this->handlers->create_enumerator(this->handlers); + enumerator->inner = NULL; + enumerator->handler = NULL; + + return &enumerator->public; } /** |