diff options
author | Martin Willi <martin@revosec.ch> | 2012-09-11 10:41:11 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-09-11 16:18:28 +0200 |
commit | 594c58e1118e496eadd284647755b16b74665337 (patch) | |
tree | 743e0f33a01beffab57e363fe1e154944c63dd01 /src/libcharon | |
parent | dc7b79d8a5c8104001bba4c52a8b3716a0cf6d88 (diff) | |
download | strongswan-594c58e1118e496eadd284647755b16b74665337.tar.bz2 strongswan-594c58e1118e496eadd284647755b16b74665337.tar.xz |
Pass the full list of pools to acquire_address, enumerate in providers
If the provider has access to the full pool list, it can enumerate
them twice, for example to search for existing leases first, and
only search for new leases in a second step.
Fixes lease enumeration in attr-sql using multiple pools.
Diffstat (limited to 'src/libcharon')
-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 |
6 files changed, 69 insertions, 58 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); |