diff options
-rw-r--r-- | src/charon-nm/nm/nm_handler.c | 16 | ||||
-rw-r--r-- | src/frontends/android/jni/libandroidbridge/backend/android_attr.c | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/android/android_handler.c | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_provider.c | 21 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_attribute.c | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_handler.c | 3 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/mode_config.c | 46 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/ike_config.c | 47 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_handler.h | 6 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_manager.c | 46 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_manager.h | 8 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_provider.h | 5 | ||||
-rw-r--r-- | src/libhydra/plugins/attr/attr_provider.c | 4 | ||||
-rw-r--r-- | src/libhydra/plugins/attr_sql/sql_attribute.c | 4 | ||||
-rw-r--r-- | src/libhydra/plugins/resolve/resolve_handler.c | 77 |
15 files changed, 189 insertions, 100 deletions
diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c index 408129ebe..28aa04b31 100644 --- a/src/charon-nm/nm/nm_handler.c +++ b/src/charon-nm/nm/nm_handler.c @@ -92,15 +92,17 @@ static bool enumerate_dns(enumerator_t *this, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_nm_handler_t *this, identification_t *server, host_t *vip) + private_nm_handler_t *this, identification_t *server, linked_list_t *vips) { - if (vip && vip->get_family(vip) == AF_INET) - { /* no IPv6 attributes yet */ - enumerator_t *enumerator = malloc_thing(enumerator_t); - /* enumerate DNS attribute first ... */ - enumerator->enumerate = (void*)enumerate_dns; - enumerator->destroy = (void*)free; + if (vips->get_count(vips)) + { + enumerator_t *enumerator; + INIT(enumerator, + /* enumerate DNS attribute first ... */ + .enumerate = (void*)enumerate_dns, + .destroy = (void*)free, + ); return enumerator; } return enumerator_create_empty(); diff --git a/src/frontends/android/jni/libandroidbridge/backend/android_attr.c b/src/frontends/android/jni/libandroidbridge/backend/android_attr.c index e8c506950..f9e96a76c 100644 --- a/src/frontends/android/jni/libandroidbridge/backend/android_attr.c +++ b/src/frontends/android/jni/libandroidbridge/backend/android_attr.c @@ -80,7 +80,7 @@ METHOD(enumerator_t, enumerate_dns, bool, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_android_attr_t *this, identification_t *server, host_t *vip) + private_android_attr_t *this, identification_t *server, linked_list_t *vips) { enumerator_t *enumerator; diff --git a/src/libcharon/plugins/android/android_handler.c b/src/libcharon/plugins/android/android_handler.c index a53962f16..f1d3045ca 100644 --- a/src/libcharon/plugins/android/android_handler.c +++ b/src/libcharon/plugins/android/android_handler.c @@ -196,7 +196,7 @@ METHOD(enumerator_t, enumerate_dns, bool, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, - android_handler_t *this, identification_t *id, host_t *vip) + android_handler_t *this, identification_t *id, linked_list_t *vips) { enumerator_t *enumerator; diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c index a6a887780..705063493 100644 --- a/src/libcharon/plugins/dhcp/dhcp_provider.c +++ b/src/libcharon/plugins/dhcp/dhcp_provider.c @@ -130,17 +130,24 @@ METHOD(attribute_provider_t, release_address, bool, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_dhcp_provider_t *this, char *pool, identification_t *id, - host_t *vip) + linked_list_t *vips) { - dhcp_transaction_t *transaction; + dhcp_transaction_t *transaction = NULL; + enumerator_t *enumerator; + host_t *vip; - if (!vip) + this->mutex->lock(this->mutex); + enumerator = vips->create_enumerator(vips); + while (enumerator->enumerate(enumerator, &vip)) { - return NULL; + transaction = this->transactions->get(this->transactions, + (void*)hash_id_host(id, vip)); + if (transaction) + { + break; + } } - this->mutex->lock(this->mutex); - transaction = this->transactions->get(this->transactions, - (void*)hash_id_host(id, vip)); + enumerator->destroy(enumerator); if (!transaction) { this->mutex->unlock(this->mutex); diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index ebae6fcf1..cec6334ed 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -149,7 +149,7 @@ static bool attr_filter(void *lock, host_t **in, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_stroke_attribute_t *this, char *pool, identification_t *id, - host_t *vip) + linked_list_t *vips) { ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c index e15daf4a4..523151efb 100644 --- a/src/libcharon/plugins/stroke/stroke_handler.c +++ b/src/libcharon/plugins/stroke/stroke_handler.c @@ -94,7 +94,8 @@ static bool attr_filter(void *lock, host_t **in, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_stroke_handler_t *this, identification_t *server, host_t *vip) + private_stroke_handler_t *this, identification_t *server, + linked_list_t *vips) { ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c index bad599b83..6b8ed079b 100644 --- a/src/libcharon/sa/ikev1/tasks/mode_config.c +++ b/src/libcharon/sa/ikev1/tasks/mode_config.c @@ -239,30 +239,44 @@ METHOD(task_t, build_i, status_t, peer_cfg_t *config; configuration_attribute_type_t type; chunk_t data; - host_t *vip; + linked_list_t *vips; + host_t *host; + + vips = linked_list_create(); /* reuse virtual IP if we already have one */ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE); - if (!enumerator->enumerate(enumerator, &vip)) + while (enumerator->enumerate(enumerator, &host)) + { + vips->insert_last(vips, host); + } + enumerator->destroy(enumerator); + + if (vips->get_count(vips) == 0) { - enumerator->destroy(enumerator); config = this->ike_sa->get_peer_cfg(this->ike_sa); enumerator = config->create_virtual_ip_enumerator(config); - if (!enumerator->enumerate(enumerator, &vip)) + while (enumerator->enumerate(enumerator, &host)) { - vip = NULL; + vips->insert_last(vips, host); } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); - if (vip) + if (vips->get_count(vips)) { cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST); - cp->add_attribute(cp, build_vip(vip)); + enumerator = vips->create_enumerator(vips); + while (enumerator->enumerate(enumerator, &host)) + { + cp->add_attribute(cp, build_vip(host)); + } + enumerator->destroy(enumerator); } - enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes, - this->ike_sa->get_other_id(this->ike_sa), vip); + enumerator = hydra->attributes->create_initiator_enumerator( + hydra->attributes, + this->ike_sa->get_other_id(this->ike_sa), vips); while (enumerator->enumerate(enumerator, &handler, &type, &data)) { configuration_attribute_t *ca; @@ -286,6 +300,8 @@ METHOD(task_t, build_i, status_t, } enumerator->destroy(enumerator); + vips->destroy(vips); + if (cp) { message->add_payload(message, (payload_t*)cp); @@ -310,6 +326,7 @@ METHOD(task_t, build_r, status_t, cp_payload_t *cp = NULL; peer_cfg_t *config; identification_t *id; + linked_list_t *vips; char *pool; id = this->ike_sa->get_other_eap_id(this->ike_sa); @@ -342,8 +359,14 @@ METHOD(task_t, build_r, status_t, } } /* query registered providers for additional attributes to include */ + vips = linked_list_create(); + /* TODO: use list with all assigned VIPs */ + if (vip) + { + vips->insert_last(vips, vip); + } enumerator = hydra->attributes->create_responder_enumerator( - hydra->attributes, pool, id, vip); + hydra->attributes, pool, id, vips); while (enumerator->enumerate(enumerator, &type, &value)) { if (!cp) @@ -357,6 +380,7 @@ METHOD(task_t, build_r, status_t, type, value)); } enumerator->destroy(enumerator); + vips->destroy(vips); if (cp) { diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c index 5b0871fca..f3c0c2ffc 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_config.c +++ b/src/libcharon/sa/ikev2/tasks/ike_config.c @@ -242,30 +242,45 @@ METHOD(task_t, build_i, status_t, peer_cfg_t *config; configuration_attribute_type_t type; chunk_t data; - host_t *vip; + linked_list_t *vips; + host_t *host; + + vips = linked_list_create(); /* reuse virtual IP if we already have one */ enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE); - if (!enumerator->enumerate(enumerator, &vip)) + while (enumerator->enumerate(enumerator, &host)) + { + vips->insert_last(vips, host); + } + enumerator->destroy(enumerator); + + if (vips->get_count(vips) == 0) { - enumerator->destroy(enumerator); config = this->ike_sa->get_peer_cfg(this->ike_sa); enumerator = config->create_virtual_ip_enumerator(config); - if (!enumerator->enumerate(enumerator, &vip)) + while (enumerator->enumerate(enumerator, &host)) { - vip = NULL; + vips->insert_last(vips, host); } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); - if (vip) + + if (vips->get_count(vips)) { cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST); - cp->add_attribute(cp, build_vip(vip)); + enumerator = vips->create_enumerator(vips); + while (enumerator->enumerate(enumerator, &host)) + { + cp->add_attribute(cp, build_vip(host)); + } + enumerator->destroy(enumerator); } - enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes, - this->ike_sa->get_other_id(this->ike_sa), vip); + enumerator = hydra->attributes->create_initiator_enumerator( + hydra->attributes, + this->ike_sa->get_other_id(this->ike_sa), vips); while (enumerator->enumerate(enumerator, &handler, &type, &data)) { configuration_attribute_t *ca; @@ -291,6 +306,8 @@ METHOD(task_t, build_i, status_t, } enumerator->destroy(enumerator); + vips->destroy(vips); + if (cp) { message->add_payload(message, (payload_t*)cp); @@ -321,6 +338,7 @@ METHOD(task_t, build_r, status_t, cp_payload_t *cp = NULL; peer_cfg_t *config; identification_t *id; + linked_list_t *vips; char *pool; id = this->ike_sa->get_other_eap_id(this->ike_sa); @@ -357,8 +375,14 @@ METHOD(task_t, build_r, status_t, } /* query registered providers for additional attributes to include */ + vips = linked_list_create(); + /* TODO: use list with all assigned VIPs */ + if (vip) + { + vips->insert_last(vips, vip); + } enumerator = hydra->attributes->create_responder_enumerator( - hydra->attributes, pool, id, vip); + hydra->attributes, pool, id, vips); while (enumerator->enumerate(enumerator, &type, &value)) { if (!cp) @@ -372,6 +396,7 @@ METHOD(task_t, build_r, status_t, type, value)); } enumerator->destroy(enumerator); + vips->destroy(vips); if (cp) { diff --git a/src/libhydra/attributes/attribute_handler.h b/src/libhydra/attributes/attribute_handler.h index d042f47ef..6014ef0fa 100644 --- a/src/libhydra/attributes/attribute_handler.h +++ b/src/libhydra/attributes/attribute_handler.h @@ -22,8 +22,8 @@ #define ATTRIBUTE_HANDLER_H_ #include <chunk.h> -#include <utils/host.h> #include <utils/identification.h> +#include <utils/linked_list.h> #include "attributes.h" @@ -62,11 +62,11 @@ struct attribute_handler_t { * Enumerate attributes to request from a server. * * @param server server identity to request attributes from - * @param vip virtual IP we are requesting, if any + * @param vips list of virtual IPs (host_t*) we are requesting * @return enumerator (configuration_attribute_type_t, chunk_t) */ enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this, - identification_t *server, host_t *vip); + identification_t *server, linked_list_t *vips); }; #endif /** ATTRIBUTE_HANDLER_H_ @}*/ diff --git a/src/libhydra/attributes/attribute_manager.c b/src/libhydra/attributes/attribute_manager.c index 250302356..b1c2c9555 100644 --- a/src/libhydra/attributes/attribute_manager.c +++ b/src/libhydra/attributes/attribute_manager.c @@ -55,8 +55,8 @@ typedef struct { char *pool; /** server/peer identity */ identification_t *id; - /** requesting/assigned virtual IP */ - host_t *vip; + /** requesting/assigned virtual IPs */ + linked_list_t *vips; } enum_data_t; METHOD(attribute_manager_t, acquire_address, host_t*, @@ -118,18 +118,20 @@ static enumerator_t *responder_enum_create(attribute_provider_t *provider, enum_data_t *data) { return provider->create_attribute_enumerator(provider, data->pool, - data->id, data->vip); + data->id, data->vips); } METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*, private_attribute_manager_t *this, char *pool, identification_t *id, - host_t *vip) + linked_list_t *vips) { - enum_data_t *data = malloc_thing(enum_data_t); + enum_data_t *data; - data->pool = pool; - data->id = id; - data->vip = vip; + INIT(data, + .pool = pool, + .id = id, + .vips = vips, + ); this->lock->read_lock(this->lock); return enumerator_create_cleaner( enumerator_create_nested( @@ -235,8 +237,8 @@ typedef struct { enumerator_t *inner; /** server ID we want attributes for */ identification_t *id; - /** virtual IP we are requesting along with attriubutes */ - host_t *vip; + /** virtual IPs we are requesting along with attriubutes */ + linked_list_t *vips; } initiator_enumerator_t; /** @@ -256,7 +258,7 @@ static bool initiator_enumerate(initiator_enumerator_t *this, } DESTROY_IF(this->inner); this->inner = this->handler->create_attribute_enumerator(this->handler, - this->id, this->vip); + this->id, this->vips); } /* inject the handler as additional attribute */ *handler = this->handler; @@ -275,20 +277,22 @@ static void initiator_destroy(initiator_enumerator_t *this) } METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*, - private_attribute_manager_t *this, identification_t *id, host_t *vip) + private_attribute_manager_t *this, identification_t *id, linked_list_t *vips) { - initiator_enumerator_t *enumerator = malloc_thing(initiator_enumerator_t); + initiator_enumerator_t *enumerator; this->lock->read_lock(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; + INIT(enumerator, + .public = { + .enumerate = (void*)initiator_enumerate, + .destroy = (void*)initiator_destroy, + }, + .this = this, + .id = id, + .vips = vips, + .outer = this->handlers->create_enumerator(this->handlers), + ); return &enumerator->public; } diff --git a/src/libhydra/attributes/attribute_manager.h b/src/libhydra/attributes/attribute_manager.h index 37e872a10..385580e56 100644 --- a/src/libhydra/attributes/attribute_manager.h +++ b/src/libhydra/attributes/attribute_manager.h @@ -64,11 +64,11 @@ struct attribute_manager_t { * * @param pool pool name to get attributes from * @param id peer identity to hand out attributes to - * @param vip virtual IP to assign to peer, if any + * @param vip list of virtual IPs (host_t*) to assign to peer * @return enumerator (configuration_attribute_type_t, chunk_t) */ enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this, - char *pool, identification_t *id, host_t *vip); + char *pool, identification_t *id, linked_list_t *vips); /** * Register an attribute provider to the manager. @@ -115,11 +115,11 @@ struct attribute_manager_t { * Create an enumerator over attributes to request from server. * * @param id server identity to hand out attributes to - * @param vip virtual IP going to request, if any + * @param vip list of virtual IPs (host_t*) going to request * @return enumerator (attribute_handler_t, ca_type_t, chunk_t) */ enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this, - identification_t *id, host_t *vip); + identification_t *id, linked_list_t *vips); /** * Register an attribute handler to the manager. diff --git a/src/libhydra/attributes/attribute_provider.h b/src/libhydra/attributes/attribute_provider.h index e4b4e13f3..104e5ca29 100644 --- a/src/libhydra/attributes/attribute_provider.h +++ b/src/libhydra/attributes/attribute_provider.h @@ -23,6 +23,7 @@ #include <utils/host.h> #include <utils/identification.h> +#include <utils/linked_list.h> typedef struct attribute_provider_t attribute_provider_t; @@ -58,11 +59,11 @@ struct attribute_provider_t { * * @param pool pool name to get attributes from * @param id peer ID - * @param vip virtual IP to assign to peer, if any + * @param vip list of virtual IPs (host_t*) to assign to peer * @return enumerator (configuration_attribute_type_t, chunk_t) */ enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this, - char *pool, identification_t *id, host_t *vip); + char *pool, identification_t *id, linked_list_t *vips); }; #endif /** ATTRIBUTE_PROVIDER_H_ @}*/ diff --git a/src/libhydra/plugins/attr/attr_provider.c b/src/libhydra/plugins/attr/attr_provider.c index 6af8b473b..f81f643b0 100644 --- a/src/libhydra/plugins/attr/attr_provider.c +++ b/src/libhydra/plugins/attr/attr_provider.c @@ -78,9 +78,9 @@ static bool attr_enum_filter(void *null, attribute_entry_t **in, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_attr_provider_t *this, char *pool, - identification_t *id, host_t *vip) + identification_t *id, linked_list_t *vips) { - if (vip) + if (vips->get_count(vips)) { this->lock->read_lock(this->lock); return enumerator_create_filter( diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libhydra/plugins/attr_sql/sql_attribute.c index 714bbcd72..b0f8c166d 100644 --- a/src/libhydra/plugins/attr_sql/sql_attribute.c +++ b/src/libhydra/plugins/attr_sql/sql_attribute.c @@ -340,11 +340,11 @@ METHOD(attribute_provider_t, release_address, bool, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_sql_attribute_t *this, char *names, identification_t *id, - host_t *vip) + linked_list_t *vips) { enumerator_t *attr_enumerator = NULL; - if (vip) + if (vips->get_count(vips)) { enumerator_t *names_enumerator; u_int count; diff --git a/src/libhydra/plugins/resolve/resolve_handler.c b/src/libhydra/plugins/resolve/resolve_handler.c index 011ebbaaf..2bee45d0d 100644 --- a/src/libhydra/plugins/resolve/resolve_handler.c +++ b/src/libhydra/plugins/resolve/resolve_handler.c @@ -267,46 +267,71 @@ METHOD(attribute_handler_t, release, void, typedef struct { /** implements enumerator_t interface */ enumerator_t public; - /** virtual IP we are requesting */ - host_t *vip; + /** request IPv4 DNS? */ + bool v4; + /** request IPv6 DNS? */ + bool v6; } attribute_enumerator_t; static bool attribute_enumerate(attribute_enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data) { - switch (this->vip->get_family(this->vip)) + if (this->v4) { - case AF_INET: - *type = INTERNAL_IP4_DNS; - break; - case AF_INET6: - *type = INTERNAL_IP6_DNS; - break; - default: - return FALSE; + *type = INTERNAL_IP4_DNS; + *data = chunk_empty; + this->v4 = FALSE; + return TRUE; } - *data = chunk_empty; - /* enumerate only once */ - this->public.enumerate = (void*)return_false; - return TRUE; + if (this->v6) + { + *type = INTERNAL_IP6_DNS; + *data = chunk_empty; + this->v6 = FALSE; + return TRUE; + } + return FALSE; } -METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_resolve_handler_t *this, identification_t *server, host_t *vip) +/** + * Check if a list has a host of given family + */ +static bool has_host_family(linked_list_t *list, int family) { - if (vip) + enumerator_t *enumerator; + host_t *host; + bool found = FALSE; + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &host)) { - attribute_enumerator_t *enumerator; + if (host->get_family(host) == family) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); - enumerator = malloc_thing(attribute_enumerator_t); - enumerator->public.enumerate = (void*)attribute_enumerate; - enumerator->public.destroy = (void*)free; - enumerator->vip = vip; + return found; +} - return &enumerator->public; - } - return enumerator_create_empty(); +METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, + private_resolve_handler_t *this, identification_t *server, + linked_list_t *vips) +{ + attribute_enumerator_t *enumerator; + + INIT(enumerator, + .public = { + .enumerate = (void*)attribute_enumerate, + .destroy = (void*)free, + }, + .v4 = has_host_family(vips, AF_INET), + .v6 = has_host_family(vips, AF_INET6), + ); + return &enumerator->public; } METHOD(resolve_handler_t, destroy, void, |