}
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();
}
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;
}
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;
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);
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;
}
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;
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;
}
enumerator->destroy(enumerator);
+ vips->destroy(vips);
+
if (cp)
{
message->add_payload(message, (payload_t*)cp);
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);
}
}
/* 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)
type, value));
}
enumerator->destroy(enumerator);
+ vips->destroy(vips);
if (cp)
{
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;
}
enumerator->destroy(enumerator);
+ vips->destroy(vips);
+
if (cp)
{
message->add_payload(message, (payload_t*)cp);
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);
}
/* 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)
type, value));
}
enumerator->destroy(enumerator);
+ vips->destroy(vips);
if (cp)
{
#define ATTRIBUTE_HANDLER_H_
#include <chunk.h>
-#include <utils/host.h>
#include <utils/identification.h>
+#include <utils/linked_list.h>
#include "attributes.h"
* 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_ @}*/
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*,
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(
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;
/**
}
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;
}
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;
}
*
* @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.
* 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.
#include <utils/host.h>
#include <utils/identification.h>
+#include <utils/linked_list.h>
typedef struct attribute_provider_t 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_ @}*/
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(
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;
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,