Pass a list instead of a single virtual IP to attribute enumerators

This commit is contained in:
Martin Willi
2012-08-30 16:43:42 +02:00
parent 96c2b3cf89
commit feb8550401
15 changed files with 199 additions and 110 deletions
+9 -7
View File
@@ -92,15 +92,17 @@ static bool enumerate_dns(enumerator_t *this,
} }
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, 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) if (vips->get_count(vips))
{ /* no IPv6 attributes yet */ {
enumerator_t *enumerator = malloc_thing(enumerator_t); enumerator_t *enumerator;
/* enumerate DNS attribute first ... */
enumerator->enumerate = (void*)enumerate_dns;
enumerator->destroy = (void*)free;
INIT(enumerator,
/* enumerate DNS attribute first ... */
.enumerate = (void*)enumerate_dns,
.destroy = (void*)free,
);
return enumerator; return enumerator;
} }
return enumerator_create_empty(); return enumerator_create_empty();
@@ -80,7 +80,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
} }
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, 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; enumerator_t *enumerator;
@@ -196,7 +196,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
} }
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, 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; enumerator_t *enumerator;
+15 -8
View File
@@ -130,17 +130,24 @@ METHOD(attribute_provider_t, release_address, bool,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_dhcp_provider_t *this, char *pool, identification_t *id, 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)
{
return NULL;
}
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
transaction = this->transactions->get(this->transactions, enumerator = vips->create_enumerator(vips);
(void*)hash_id_host(id, vip)); while (enumerator->enumerate(enumerator, &vip))
{
transaction = this->transactions->get(this->transactions,
(void*)hash_id_host(id, vip));
if (transaction)
{
break;
}
}
enumerator->destroy(enumerator);
if (!transaction) if (!transaction)
{ {
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
@@ -149,7 +149,7 @@ static bool attr_filter(void *lock, host_t **in,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_stroke_attribute_t *this, char *pool, identification_t *id, private_stroke_attribute_t *this, char *pool, identification_t *id,
host_t *vip) linked_list_t *vips)
{ {
ike_sa_t *ike_sa; ike_sa_t *ike_sa;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
@@ -94,7 +94,8 @@ static bool attr_filter(void *lock, host_t **in,
} }
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, 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; ike_sa_t *ike_sa;
peer_cfg_t *peer_cfg; peer_cfg_t *peer_cfg;
+39 -15
View File
@@ -239,30 +239,44 @@ METHOD(task_t, build_i, status_t,
peer_cfg_t *config; peer_cfg_t *config;
configuration_attribute_type_t type; configuration_attribute_type_t type;
chunk_t data; 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 */ /* reuse virtual IP if we already have one */
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE); enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
if (!enumerator->enumerate(enumerator, &vip)) while (enumerator->enumerate(enumerator, &host))
{ {
enumerator->destroy(enumerator); vips->insert_last(vips, host);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
enumerator = config->create_virtual_ip_enumerator(config);
if (!enumerator->enumerate(enumerator, &vip))
{
vip = NULL;
}
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (vip) if (vips->get_count(vips) == 0)
{ {
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST); config = this->ike_sa->get_peer_cfg(this->ike_sa);
cp->add_attribute(cp, build_vip(vip)); enumerator = config->create_virtual_ip_enumerator(config);
while (enumerator->enumerate(enumerator, &host))
{
vips->insert_last(vips, host);
}
enumerator->destroy(enumerator);
} }
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes, if (vips->get_count(vips))
this->ike_sa->get_other_id(this->ike_sa), vip); {
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
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), vips);
while (enumerator->enumerate(enumerator, &handler, &type, &data)) while (enumerator->enumerate(enumerator, &handler, &type, &data))
{ {
configuration_attribute_t *ca; configuration_attribute_t *ca;
@@ -286,6 +300,8 @@ METHOD(task_t, build_i, status_t,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
vips->destroy(vips);
if (cp) if (cp)
{ {
message->add_payload(message, (payload_t*)cp); message->add_payload(message, (payload_t*)cp);
@@ -310,6 +326,7 @@ METHOD(task_t, build_r, status_t,
cp_payload_t *cp = NULL; cp_payload_t *cp = NULL;
peer_cfg_t *config; peer_cfg_t *config;
identification_t *id; identification_t *id;
linked_list_t *vips;
char *pool; char *pool;
id = this->ike_sa->get_other_eap_id(this->ike_sa); 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 */ /* 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( enumerator = hydra->attributes->create_responder_enumerator(
hydra->attributes, pool, id, vip); hydra->attributes, pool, id, vips);
while (enumerator->enumerate(enumerator, &type, &value)) while (enumerator->enumerate(enumerator, &type, &value))
{ {
if (!cp) if (!cp)
@@ -357,6 +380,7 @@ METHOD(task_t, build_r, status_t,
type, value)); type, value));
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
vips->destroy(vips);
if (cp) if (cp)
{ {
+40 -15
View File
@@ -242,30 +242,45 @@ METHOD(task_t, build_i, status_t,
peer_cfg_t *config; peer_cfg_t *config;
configuration_attribute_type_t type; configuration_attribute_type_t type;
chunk_t data; 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 */ /* reuse virtual IP if we already have one */
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
TRUE); TRUE);
if (!enumerator->enumerate(enumerator, &vip)) while (enumerator->enumerate(enumerator, &host))
{ {
enumerator->destroy(enumerator); vips->insert_last(vips, host);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
enumerator = config->create_virtual_ip_enumerator(config);
if (!enumerator->enumerate(enumerator, &vip))
{
vip = NULL;
}
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
if (vip)
if (vips->get_count(vips) == 0)
{ {
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST); config = this->ike_sa->get_peer_cfg(this->ike_sa);
cp->add_attribute(cp, build_vip(vip)); enumerator = config->create_virtual_ip_enumerator(config);
while (enumerator->enumerate(enumerator, &host))
{
vips->insert_last(vips, host);
}
enumerator->destroy(enumerator);
} }
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes, if (vips->get_count(vips))
this->ike_sa->get_other_id(this->ike_sa), vip); {
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST);
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), vips);
while (enumerator->enumerate(enumerator, &handler, &type, &data)) while (enumerator->enumerate(enumerator, &handler, &type, &data))
{ {
configuration_attribute_t *ca; configuration_attribute_t *ca;
@@ -291,6 +306,8 @@ METHOD(task_t, build_i, status_t,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
vips->destroy(vips);
if (cp) if (cp)
{ {
message->add_payload(message, (payload_t*)cp); message->add_payload(message, (payload_t*)cp);
@@ -321,6 +338,7 @@ METHOD(task_t, build_r, status_t,
cp_payload_t *cp = NULL; cp_payload_t *cp = NULL;
peer_cfg_t *config; peer_cfg_t *config;
identification_t *id; identification_t *id;
linked_list_t *vips;
char *pool; char *pool;
id = this->ike_sa->get_other_eap_id(this->ike_sa); 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 */ /* 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( enumerator = hydra->attributes->create_responder_enumerator(
hydra->attributes, pool, id, vip); hydra->attributes, pool, id, vips);
while (enumerator->enumerate(enumerator, &type, &value)) while (enumerator->enumerate(enumerator, &type, &value))
{ {
if (!cp) if (!cp)
@@ -372,6 +396,7 @@ METHOD(task_t, build_r, status_t,
type, value)); type, value));
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
vips->destroy(vips);
if (cp) if (cp)
{ {
+3 -3
View File
@@ -22,8 +22,8 @@
#define ATTRIBUTE_HANDLER_H_ #define ATTRIBUTE_HANDLER_H_
#include <chunk.h> #include <chunk.h>
#include <utils/host.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/linked_list.h>
#include "attributes.h" #include "attributes.h"
@@ -62,11 +62,11 @@ struct attribute_handler_t {
* Enumerate attributes to request from a server. * Enumerate attributes to request from a server.
* *
* @param server server identity to request attributes from * @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) * @return enumerator (configuration_attribute_type_t, chunk_t)
*/ */
enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this, 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_ @}*/ #endif /** ATTRIBUTE_HANDLER_H_ @}*/
+25 -21
View File
@@ -55,8 +55,8 @@ typedef struct {
char *pool; char *pool;
/** server/peer identity */ /** server/peer identity */
identification_t *id; identification_t *id;
/** requesting/assigned virtual IP */ /** requesting/assigned virtual IPs */
host_t *vip; linked_list_t *vips;
} enum_data_t; } enum_data_t;
METHOD(attribute_manager_t, acquire_address, host_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) enum_data_t *data)
{ {
return provider->create_attribute_enumerator(provider, data->pool, 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*, METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
private_attribute_manager_t *this, char *pool, identification_t *id, 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; INIT(data,
data->id = id; .pool = pool,
data->vip = vip; .id = id,
.vips = vips,
);
this->lock->read_lock(this->lock); this->lock->read_lock(this->lock);
return enumerator_create_cleaner( return enumerator_create_cleaner(
enumerator_create_nested( enumerator_create_nested(
@@ -235,8 +237,8 @@ typedef struct {
enumerator_t *inner; enumerator_t *inner;
/** server ID we want attributes for */ /** server ID we want attributes for */
identification_t *id; identification_t *id;
/** virtual IP we are requesting along with attriubutes */ /** virtual IPs we are requesting along with attriubutes */
host_t *vip; linked_list_t *vips;
} initiator_enumerator_t; } initiator_enumerator_t;
/** /**
@@ -256,7 +258,7 @@ static bool initiator_enumerate(initiator_enumerator_t *this,
} }
DESTROY_IF(this->inner); DESTROY_IF(this->inner);
this->inner = this->handler->create_attribute_enumerator(this->handler, this->inner = this->handler->create_attribute_enumerator(this->handler,
this->id, this->vip); this->id, this->vips);
} }
/* inject the handler as additional attribute */ /* inject the handler as additional attribute */
*handler = this->handler; *handler = this->handler;
@@ -275,20 +277,22 @@ static void initiator_destroy(initiator_enumerator_t *this)
} }
METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*, 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); 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; return &enumerator->public;
} }
+4 -4
View File
@@ -64,11 +64,11 @@ struct attribute_manager_t {
* *
* @param pool pool name to get attributes from * @param pool pool name to get attributes from
* @param id peer identity to hand out attributes to * @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) * @return enumerator (configuration_attribute_type_t, chunk_t)
*/ */
enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this, 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. * Register an attribute provider to the manager.
@@ -115,11 +115,11 @@ struct attribute_manager_t {
* Create an enumerator over attributes to request from server. * Create an enumerator over attributes to request from server.
* *
* @param id server identity to hand out attributes to * @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) * @return enumerator (attribute_handler_t, ca_type_t, chunk_t)
*/ */
enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this, 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. * Register an attribute handler to the manager.
+3 -2
View File
@@ -23,6 +23,7 @@
#include <utils/host.h> #include <utils/host.h>
#include <utils/identification.h> #include <utils/identification.h>
#include <utils/linked_list.h>
typedef struct attribute_provider_t attribute_provider_t; 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 pool pool name to get attributes from
* @param id peer ID * @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) * @return enumerator (configuration_attribute_type_t, chunk_t)
*/ */
enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this, 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_ @}*/ #endif /** ATTRIBUTE_PROVIDER_H_ @}*/
+2 -2
View File
@@ -78,9 +78,9 @@ static bool attr_enum_filter(void *null, attribute_entry_t **in,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_attr_provider_t *this, char *pool, 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); this->lock->read_lock(this->lock);
return enumerator_create_filter( return enumerator_create_filter(
@@ -340,11 +340,11 @@ METHOD(attribute_provider_t, release_address, bool,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_sql_attribute_t *this, char *names, identification_t *id, private_sql_attribute_t *this, char *names, identification_t *id,
host_t *vip) linked_list_t *vips)
{ {
enumerator_t *attr_enumerator = NULL; enumerator_t *attr_enumerator = NULL;
if (vip) if (vips->get_count(vips))
{ {
enumerator_t *names_enumerator; enumerator_t *names_enumerator;
u_int count; u_int count;
+52 -27
View File
@@ -267,46 +267,71 @@ METHOD(attribute_handler_t, release, void,
typedef struct { typedef struct {
/** implements enumerator_t interface */ /** implements enumerator_t interface */
enumerator_t public; enumerator_t public;
/** virtual IP we are requesting */ /** request IPv4 DNS? */
host_t *vip; bool v4;
/** request IPv6 DNS? */
bool v6;
} attribute_enumerator_t; } attribute_enumerator_t;
static bool attribute_enumerate(attribute_enumerator_t *this, static bool attribute_enumerate(attribute_enumerator_t *this,
configuration_attribute_type_t *type, configuration_attribute_type_t *type,
chunk_t *data) chunk_t *data)
{ {
switch (this->vip->get_family(this->vip)) if (this->v4)
{ {
case AF_INET: *type = INTERNAL_IP4_DNS;
*type = INTERNAL_IP4_DNS; *data = chunk_empty;
break; this->v4 = FALSE;
case AF_INET6: return TRUE;
*type = INTERNAL_IP6_DNS;
break;
default:
return FALSE;
} }
*data = chunk_empty; if (this->v6)
/* enumerate only once */ {
this->public.enumerate = (void*)return_false; *type = INTERNAL_IP6_DNS;
return TRUE; *data = chunk_empty;
this->v6 = FALSE;
return TRUE;
}
return FALSE;
}
/**
* Check if a list has a host of given family
*/
static bool has_host_family(linked_list_t *list, int family)
{
enumerator_t *enumerator;
host_t *host;
bool found = FALSE;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &host))
{
if (host->get_family(host) == family)
{
found = TRUE;
break;
}
}
enumerator->destroy(enumerator);
return found;
} }
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
private_resolve_handler_t *this, identification_t *server, host_t *vip) private_resolve_handler_t *this, identification_t *server,
linked_list_t *vips)
{ {
if (vip) attribute_enumerator_t *enumerator;
{
attribute_enumerator_t *enumerator;
enumerator = malloc_thing(attribute_enumerator_t); INIT(enumerator,
enumerator->public.enumerate = (void*)attribute_enumerate; .public = {
enumerator->public.destroy = (void*)free; .enumerate = (void*)attribute_enumerate,
enumerator->vip = vip; .destroy = (void*)free,
},
return &enumerator->public; .v4 = has_host_family(vips, AF_INET),
} .v6 = has_host_family(vips, AF_INET6),
return enumerator_create_empty(); );
return &enumerator->public;
} }
METHOD(resolve_handler_t, destroy, void, METHOD(resolve_handler_t, destroy, void,