diff options
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_provider.c | 28 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_attribute.c | 18 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_attribute.c | 20 | ||||
-rw-r--r-- | src/libcharon/plugins/unit_tester/tests/test_pool.c | 9 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/mode_config.c | 26 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/ike_config.c | 26 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_manager.c | 6 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_manager.h | 4 | ||||
-rw-r--r-- | src/libhydra/attributes/attribute_provider.h | 4 | ||||
-rw-r--r-- | src/libhydra/plugins/attr_sql/sql_attribute.c | 41 |
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, ¤t)) { - 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; |