Pass full pool list to release_address
authorMartin Willi <martin@revosec.ch>
Tue, 11 Sep 2012 09:19:56 +0000 (11:19 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 11 Sep 2012 14:18:28 +0000 (16:18 +0200)
src/libcharon/plugins/dhcp/dhcp_provider.c
src/libcharon/plugins/ha/ha_attribute.c
src/libcharon/plugins/stroke/stroke_attribute.c
src/libcharon/plugins/unit_tester/tests/test_pool.c
src/libcharon/sa/ike_sa.c
src/libhydra/attributes/attribute_manager.c
src/libhydra/attributes/attribute_manager.h
src/libhydra/attributes/attribute_provider.h
src/libhydra/plugins/attr_sql/sql_attribute.c

index eaaad45..8bc5474 100644 (file)
@@ -119,13 +119,25 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 }
 
 METHOD(attribute_provider_t, release_address, bool,
-       private_dhcp_provider_t *this, char *pool,
+       private_dhcp_provider_t *this, linked_list_t *pools,
        host_t *address, identification_t *id)
 {
-       if (streq(pool, "dhcp") && address->get_family(address) == AF_INET)
-       {
-               dhcp_transaction_t *transaction;
+       dhcp_transaction_t *transaction;
+       enumerator_t *enumerator;
+       bool found = FALSE;
+       char *pool;
 
+       if (address->get_family(address) != AF_INET)
+       {
+               return FALSE;
+       }
+       enumerator = pools->create_enumerator(pools);
+       while (enumerator->enumerate(enumerator, &pool))
+       {
+               if (!streq(pool, "dhcp"))
+               {
+                       continue;
+               }
                this->mutex->lock(this->mutex);
                transaction = this->transactions->remove(this->transactions,
                                                                                (void*)hash_id_host(id, address));
@@ -134,10 +146,12 @@ METHOD(attribute_provider_t, release_address, bool,
                {
                        this->socket->release(this->socket, transaction);
                        transaction->destroy(transaction);
-                       return TRUE;
+                       found = TRUE;
+                       break;
                }
        }
-       return FALSE;
+       enumerator->destroy(enumerator);
+       return found;
 }
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
index d9f460a..ae62964 100644 (file)
@@ -232,26 +232,40 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 }
 
 METHOD(attribute_provider_t, release_address, bool,
-       private_ha_attribute_t *this, char *name, host_t *address,
+       private_ha_attribute_t *this, linked_list_t *pools, host_t *address,
        identification_t *id)
 {
+       enumerator_t *enumerator;
        pool_t *pool;
        int offset;
+       char *name;
        bool found = FALSE;
 
+       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) != address->get_family(address))
+               {
+                       continue;
+               }
                offset = host2offset(pool, address);
                if (offset > 0 && offset < pool->size)
                {
                        pool->mask[offset / 8] &= ~(1 << (offset % 8));
                        DBG1(DBG_CFG, "released address %H to HA pool '%s'", address, name);
                        found = TRUE;
+                       break;
                }
        }
        this->mutex->unlock(this->mutex);
+       enumerator->destroy(enumerator);
+
        return found;
 }
 
index 99392bf..e0c8360 100644 (file)
@@ -119,19 +119,31 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 }
 
 METHOD(attribute_provider_t, release_address, bool,
-       private_stroke_attribute_t *this, char *name, host_t *address,
+       private_stroke_attribute_t *this, linked_list_t *pools, host_t *address,
        identification_t *id)
 {
+       enumerator_t *enumerator;
        mem_pool_t *pool;
        bool found = FALSE;
+       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))
        {
-               found = pool->release_address(pool, address, id);
+               pool = find_pool(this, name);
+               if (pool)
+               {
+                       found = pool->release_address(pool, address, id);
+                       if (found)
+                       {
+                               break;
+                       }
+               }
        }
        this->lock->unlock(this->lock);
+       enumerator->destroy(enumerator);
+
        return found;
 }
 
index f67353d..f36953f 100644 (file)
@@ -53,15 +53,15 @@ static void* testing(void *thread)
                }
        }
 
-       pools->destroy(pools);
-
        /* release addresses */
        for (i = 0; i < ALLOCS; i++)
        {
                hydra->attributes->release_address(hydra->attributes,
-                                                                                  "test", addr[i], id[i]);
+                                                                                  pools, addr[i], id[i]);
        }
 
+       pools->destroy(pools);
+
        /* cleanup */
        for (i = 0; i < ALLOCS; i++)
        {
index c55d2b6..453a50c 100644 (file)
@@ -2080,19 +2080,14 @@ METHOD(ike_sa_t, destroy, void,
        {
                if (this->peer_cfg)
                {
-                       enumerator_t *enumerator;
-                       char *pool;
-
-                       enumerator = this->peer_cfg->create_pool_enumerator(this->peer_cfg);
-                       while (enumerator->enumerate(enumerator, &pool))
-                       {
-                               if (hydra->attributes->release_address(hydra->attributes, pool,
-                                                                                               vip, get_other_eap_id(this)))
-                               {
-                                       break;
-                               }
-                       }
-                       enumerator->destroy(enumerator);
+                       linked_list_t *pools;
+                       identification_t *id;
+
+                       id = get_other_eap_id(this);
+                       pools = linked_list_create_from_enumerator(
+                                               this->peer_cfg->create_pool_enumerator(this->peer_cfg));
+                       hydra->attributes->release_address(hydra->attributes, pools, vip, id);
+                       pools->destroy(pools);
                }
                vip->destroy(vip);
        }
index e7a687a..000d2e0 100644 (file)
@@ -84,7 +84,7 @@ METHOD(attribute_manager_t, acquire_address, host_t*,
 }
 
 METHOD(attribute_manager_t, release_address, bool,
-       private_attribute_manager_t *this, char *pool, host_t *address,
+       private_attribute_manager_t *this, linked_list_t *pools, host_t *address,
        identification_t *id)
 {
        enumerator_t *enumerator;
@@ -95,7 +95,7 @@ METHOD(attribute_manager_t, release_address, bool,
        enumerator = this->providers->create_enumerator(this->providers);
        while (enumerator->enumerate(enumerator, &current))
        {
-               if (current->release_address(current, pool, address, id))
+               if (current->release_address(current, pools, address, id))
                {
                        found = TRUE;
                        break;
index 45e5a40..99f4177 100644 (file)
@@ -51,13 +51,14 @@ struct attribute_manager_t {
        /**
         * Release a previously acquired address.
         *
-        * @param pool                  pool name from which the address was acquired
+        * @param pools                 list of pool names (char*) to release to
         * @param address               address to release
         * @param id                    peer identity to get address for
         * @return                              TRUE if address released to pool
         */
        bool (*release_address)(attribute_manager_t *this,
-                                                       char *pool, host_t *address, identification_t *id);
+                                                       linked_list_t *pools, host_t *address,
+                                                       identification_t *id);
 
        /**
         * Create an enumerator over attributes to hand out to a peer.
index 7d0acdb..e5e556f 100644 (file)
@@ -46,13 +46,14 @@ struct attribute_provider_t {
        /**
         * Release a previously acquired address.
         *
-        * @param pool                  name of the pool this address was acquired from
+        * @param pools                 list of pool names (char*) to release to
         * @param address               address to release
         * @param id                    peer ID
         * @return                              TRUE if the address has been released by the provider
         */
        bool (*release_address)(attribute_provider_t *this,
-                                                       char *pool, host_t *address, identification_t *id);
+                                                       linked_list_t *pools, host_t *address,
+                                                       identification_t *id);
 
        /**
         * Create an enumerator over attributes to hand out to a peer.
index 28e5985..a7d90e7 100644 (file)
@@ -283,33 +283,44 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 }
 
 METHOD(attribute_provider_t, release_address, bool,
-       private_sql_attribute_t *this, char *name, host_t *address,
+       private_sql_attribute_t *this, linked_list_t *pools, host_t *address,
        identification_t *id)
 {
+       enumerator_t *enumerator;
        u_int pool, timeout;
        time_t now = time(NULL);
+       bool found = FALSE;
+       char *name;
 
-       pool = get_pool(this, name, &timeout);
-       if (pool)
+       enumerator = pools->create_enumerator(pools);
+       while (enumerator->enumerate(enumerator, &name))
        {
-               if (this->history)
+               pool = get_pool(this, name, &timeout);
+               if (!pool)
                {
-                       this->db->execute(this->db, NULL,
-                               "INSERT INTO leases (address, identity, acquired, released)"
-                               " SELECT id, identity, acquired, ? FROM addresses "
-                               " WHERE pool = ? AND address = ?",
-                               DB_UINT, now, DB_UINT, pool,
-                               DB_BLOB, address->get_address(address));
+                       continue;
                }
                if (this->db->execute(this->db, NULL,
                                "UPDATE addresses SET released = ? WHERE "
                                "pool = ? AND address = ?", DB_UINT, time(NULL),
                                DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
                {
-                       return TRUE;
+                       if (this->history)
+                       {
+                               this->db->execute(this->db, NULL,
+                                       "INSERT INTO leases (address, identity, acquired, released)"
+                                       " SELECT id, identity, acquired, ? FROM addresses "
+                                       " WHERE pool = ? AND address = ?",
+                                       DB_UINT, now, DB_UINT, pool,
+                                       DB_BLOB, address->get_address(address));
+                       }
+                       found = TRUE;
+                       break;
                }
        }
-       return FALSE;
+       enumerator->destroy(enumerator);
+
+       return found;
 }
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,