aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_provider.c28
-rw-r--r--src/libcharon/plugins/ha/ha_attribute.c18
-rw-r--r--src/libcharon/plugins/stroke/stroke_attribute.c20
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_pool.c9
-rw-r--r--src/libcharon/sa/ikev1/tasks/mode_config.c26
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_config.c26
-rw-r--r--src/libhydra/attributes/attribute_manager.c6
-rw-r--r--src/libhydra/attributes/attribute_manager.h4
-rw-r--r--src/libhydra/attributes/attribute_provider.h4
-rw-r--r--src/libhydra/plugins/attr_sql/sql_attribute.c41
10 files changed, 109 insertions, 73 deletions
diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c
index e46cc4d90..eaaad45d1 100644
--- a/src/libcharon/plugins/dhcp/dhcp_provider.c
+++ b/src/libcharon/plugins/dhcp/dhcp_provider.c
@@ -81,18 +81,29 @@ static uintptr_t hash_transaction(dhcp_transaction_t *transaction)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_dhcp_provider_t *this, char *pool,
+ private_dhcp_provider_t *this, linked_list_t *pools,
identification_t *id, host_t *requested)
{
- if (streq(pool, "dhcp") && requested->get_family(requested) == AF_INET)
- {
- dhcp_transaction_t *transaction, *old;
- host_t *vip;
+ dhcp_transaction_t *transaction, *old;
+ enumerator_t *enumerator;
+ char *pool;
+ host_t *vip = NULL;
+ if (requested->get_family(requested) != AF_INET)
+ {
+ return NULL;
+ }
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &pool))
+ {
+ if (!streq(pool, "dhcp"))
+ {
+ continue;
+ }
transaction = this->socket->enroll(this->socket, id);
if (!transaction)
{
- return NULL;
+ continue;
}
vip = transaction->get_address(transaction);
vip = vip->clone(vip);
@@ -101,9 +112,10 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
(void*)hash_transaction(transaction), transaction);
this->mutex->unlock(this->mutex);
DESTROY_IF(old);
- return vip;
+ break;
}
- return NULL;
+ enumerator->destroy(enumerator);
+ return vip;
}
METHOD(attribute_provider_t, release_address, bool,
diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c
index f18c58b6a..d9f460ade 100644
--- a/src/libcharon/plugins/ha/ha_attribute.c
+++ b/src/libcharon/plugins/ha/ha_attribute.c
@@ -170,22 +170,28 @@ static bool responsible_for(private_ha_attribute_t *this, int bit)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_ha_attribute_t *this, char *name, identification_t *id,
+ private_ha_attribute_t *this, linked_list_t *pools, identification_t *id,
host_t *requested)
{
+ enumerator_t *enumerator;
pool_t *pool;
int offset = -1, byte, bit;
host_t *address;
+ char *name;
+ enumerator = pools->create_enumerator(pools);
this->mutex->lock(this->mutex);
- pool = get_pool(this, name);
- if (pool)
+ while (enumerator->enumerate(enumerator, &name))
{
+ pool = get_pool(this, name);
+ if (!pool)
+ {
+ continue;
+ }
if (pool->base->get_family(pool->base) !=
requested->get_family(requested))
{
- this->mutex->unlock(this->mutex);
- return NULL;
+ continue;
}
for (byte = 0; byte < pool->size / 8; byte++)
{
@@ -214,6 +220,8 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
}
}
this->mutex->unlock(this->mutex);
+ enumerator->destroy(enumerator);
+
if (offset != -1)
{
address = offset2host(pool, offset);
diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c
index fa58a24e3..99392bfd7 100644
--- a/src/libcharon/plugins/stroke/stroke_attribute.c
+++ b/src/libcharon/plugins/stroke/stroke_attribute.c
@@ -90,19 +90,31 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_stroke_attribute_t *this, char *name, identification_t *id,
+ private_stroke_attribute_t *this, linked_list_t *pools, identification_t *id,
host_t *requested)
{
+ enumerator_t *enumerator;
mem_pool_t *pool;
host_t *addr = NULL;
+ char *name;
+ enumerator = pools->create_enumerator(pools);
this->lock->read_lock(this->lock);
- pool = find_pool(this, name);
- if (pool)
+ while (enumerator->enumerate(enumerator, &name))
{
- addr = pool->acquire_address(pool, id, requested);
+ pool = find_pool(this, name);
+ if (pool)
+ {
+ addr = pool->acquire_address(pool, id, requested);
+ if (addr)
+ {
+ break;
+ }
+ }
}
this->lock->unlock(this->lock);
+ enumerator->destroy(enumerator);
+
return addr;
}
diff --git a/src/libcharon/plugins/unit_tester/tests/test_pool.c b/src/libcharon/plugins/unit_tester/tests/test_pool.c
index a68246fff..f67353dff 100644
--- a/src/libcharon/plugins/unit_tester/tests/test_pool.c
+++ b/src/libcharon/plugins/unit_tester/tests/test_pool.c
@@ -27,6 +27,7 @@ static void* testing(void *thread)
int i;
host_t *addr[ALLOCS];
identification_t *id[ALLOCS];
+ linked_list_t *pools;
/* prepare identities */
for (i = 0; i < ALLOCS; i++)
@@ -37,17 +38,23 @@ static void* testing(void *thread)
id[i] = identification_create_from_string(buf);
}
+ pools = linked_list_create();
+ pools->insert_last(pools, "test");
+
/* allocate addresses */
for (i = 0; i < ALLOCS; i++)
{
addr[i] = hydra->attributes->acquire_address(hydra->attributes,
- "test", id[i], NULL);
+ pools, id[i], NULL);
if (!addr[i])
{
+ pools->destroy(pools);
return (void*)FALSE;
}
}
+ pools->destroy(pools);
+
/* release addresses */
for (i = 0; i < ALLOCS; i++)
{
diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c
index a134ad562..6a5bac92a 100644
--- a/src/libcharon/sa/ikev1/tasks/mode_config.c
+++ b/src/libcharon/sa/ikev1/tasks/mode_config.c
@@ -330,29 +330,23 @@ METHOD(task_t, build_r, status_t,
id = this->ike_sa->get_other_eap_id(this->ike_sa);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
vips = linked_list_create();
- pools = linked_list_create();
+ pools = linked_list_create_from_enumerator(
+ config->create_pool_enumerator(config));
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &requested))
{
- enumerator_t *poolenum;
- char *pool;
host_t *found = NULL;
/* query all pools until we get an address */
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
- poolenum = config->create_pool_enumerator(config);
- while (poolenum->enumerate(poolenum, &pool))
+ found = hydra->attributes->acquire_address(hydra->attributes,
+ pools, id, requested);
+ if (found)
{
- found = hydra->attributes->acquire_address(hydra->attributes,
- pool, id, requested);
- if (!found)
- {
- continue;
- }
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
if (!cp)
@@ -360,17 +354,9 @@ METHOD(task_t, build_r, status_t,
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY);
}
cp->add_attribute(cp, build_vip(found));
- /* use pool to request other attributes */
- if (pools->find_first(pools, NULL, (void**)&pool) == NOT_FOUND)
- {
- pools->insert_last(pools, pool);
- }
vips->insert_last(vips, found);
- break;
}
- poolenum->destroy(poolenum);
-
- if (!found)
+ else
{
DBG1(DBG_IKE, "no virtual IP found for %H requested by '%Y'",
requested, id);
diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c
index fbfcb0ea9..d624fd170 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_config.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_config.c
@@ -342,29 +342,23 @@ METHOD(task_t, build_r, status_t,
id = this->ike_sa->get_other_eap_id(this->ike_sa);
config = this->ike_sa->get_peer_cfg(this->ike_sa);
vips = linked_list_create();
- pools = linked_list_create();
+ pools = linked_list_create_from_enumerator(
+ config->create_pool_enumerator(config));
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &requested))
{
- enumerator_t *poolenum;
- char *pool;
host_t *found = NULL;
/* query all pools until we get an address */
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
- poolenum = config->create_pool_enumerator(config);
- while (poolenum->enumerate(poolenum, &pool))
+ found = hydra->attributes->acquire_address(hydra->attributes,
+ pools, id, requested);
+ if (found)
{
- found = hydra->attributes->acquire_address(hydra->attributes,
- pool, id, requested);
- if (!found)
- {
- continue;
- }
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
if (!cp)
@@ -372,17 +366,9 @@ METHOD(task_t, build_r, status_t,
cp = cp_payload_create_type(CONFIGURATION, CFG_REPLY);
}
cp->add_attribute(cp, build_vip(found));
- /* use pool to request other attributes */
- if (pools->find_first(pools, NULL, (void**)&pool) == NOT_FOUND)
- {
- pools->insert_last(pools, pool);
- }
vips->insert_last(vips, found);
- break;
}
- poolenum->destroy(poolenum);
-
- if (!found)
+ else
{
DBG1(DBG_IKE, "no virtual IP found for %H requested by '%Y'",
requested, id);
diff --git a/src/libhydra/attributes/attribute_manager.c b/src/libhydra/attributes/attribute_manager.c
index 64dc9c7c9..e7a687a50 100644
--- a/src/libhydra/attributes/attribute_manager.c
+++ b/src/libhydra/attributes/attribute_manager.c
@@ -60,8 +60,8 @@ typedef struct {
} enum_data_t;
METHOD(attribute_manager_t, acquire_address, host_t*,
- private_attribute_manager_t *this, char *pool, identification_t *id,
- host_t *requested)
+ private_attribute_manager_t *this, linked_list_t *pools,
+ identification_t *id, host_t *requested)
{
enumerator_t *enumerator;
attribute_provider_t *current;
@@ -71,7 +71,7 @@ METHOD(attribute_manager_t, acquire_address, host_t*,
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &current))
{
- host = current->acquire_address(current, pool, id, requested);
+ host = current->acquire_address(current, pools, id, requested);
if (host)
{
break;
diff --git a/src/libhydra/attributes/attribute_manager.h b/src/libhydra/attributes/attribute_manager.h
index 8bc80ca11..45e5a40f1 100644
--- a/src/libhydra/attributes/attribute_manager.h
+++ b/src/libhydra/attributes/attribute_manager.h
@@ -39,13 +39,13 @@ struct attribute_manager_t {
/**
* Acquire a virtual IP address to assign to a peer.
*
- * @param pool pool name to acquire address from
+ * @param pools list of pool names (char*) to acquire from
* @param id peer identity to get address forua
* @param requested IP in configuration request
* @return allocated address, NULL to serve none
*/
host_t* (*acquire_address)(attribute_manager_t *this,
- char *pool, identification_t *id,
+ linked_list_t *pool, identification_t *id,
host_t *requested);
/**
diff --git a/src/libhydra/attributes/attribute_provider.h b/src/libhydra/attributes/attribute_provider.h
index 327135ffe..7d0acdbac 100644
--- a/src/libhydra/attributes/attribute_provider.h
+++ b/src/libhydra/attributes/attribute_provider.h
@@ -35,13 +35,13 @@ struct attribute_provider_t {
/**
* Acquire a virtual IP address to assign to a peer.
*
- * @param pool name of the pool to acquire address from
+ * @param pools list of pool names (char*) to acquire from
* @param id peer ID
* @param requested IP in configuration request
* @return allocated address, NULL to serve none
*/
host_t* (*acquire_address)(attribute_provider_t *this,
- char *pool, identification_t *id,
+ linked_list_t *pools, identification_t *id,
host_t *requested);
/**
* Release a previously acquired address.
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libhydra/plugins/attr_sql/sql_attribute.c
index 8055be71c..28e59850e 100644
--- a/src/libhydra/plugins/attr_sql/sql_attribute.c
+++ b/src/libhydra/plugins/attr_sql/sql_attribute.c
@@ -233,25 +233,50 @@ static host_t* get_lease(private_sql_attribute_t *this, char *name,
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_sql_attribute_t *this, char *name, identification_t *id,
+ private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
host_t *requested)
{
+ enumerator_t *enumerator;
host_t *address = NULL;
u_int identity, pool, timeout;
+ char *name;
identity = get_identity(this, id);
if (identity)
{
- pool = get_pool(this, name, &timeout);
- if (pool)
+ /* check for an existing lease in all pools */
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &name))
{
- /* check for an existing lease */
- address = check_lease(this, name, pool, identity);
- if (address == NULL)
+ pool = get_pool(this, name, &timeout);
+ if (pool)
{
- /* get an unallocated address or expired lease */
- address = get_lease(this, name, pool, timeout, identity);
+ address = check_lease(this, name, pool, identity);
+ if (address)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!address)
+ {
+ /* get an unallocated address or expired lease */
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &name))
+ {
+ pool = get_pool(this, name, &timeout);
+ if (pool)
+ {
+ address = get_lease(this, name, pool, timeout, identity);
+ if (address)
+ {
+ break;
+ }
+ }
}
+ enumerator->destroy(enumerator);
}
}
return address;