summaryrefslogtreecommitdiff
path: root/src/libhydra/plugins/attr_sql/sql_attribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libhydra/plugins/attr_sql/sql_attribute.c')
-rw-r--r--src/libhydra/plugins/attr_sql/sql_attribute.c128
1 files changed, 62 insertions, 66 deletions
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libhydra/plugins/attr_sql/sql_attribute.c
index 714bbcd72..e91e1ed15 100644
--- a/src/libhydra/plugins/attr_sql/sql_attribute.c
+++ b/src/libhydra/plugins/attr_sql/sql_attribute.c
@@ -15,7 +15,7 @@
#include <time.h>
-#include <debug.h>
+#include <utils/debug.h>
#include <library.h>
#include "sql_attribute.h"
@@ -94,19 +94,26 @@ static u_int get_attr_pool(private_sql_attribute_t *this, char *name)
}
/**
- * Lookup pool by name
+ * Lookup pool by name and address family
*/
-static u_int get_pool(private_sql_attribute_t *this, char *name, u_int *timeout)
+static u_int get_pool(private_sql_attribute_t *this, char *name, int family,
+ u_int *timeout)
{
enumerator_t *e;
+ chunk_t start;
u_int pool;
- e = this->db->query(this->db, "SELECT id, timeout FROM pools WHERE name = ?",
- DB_TEXT, name, DB_UINT, DB_UINT);
- if (e && e->enumerate(e, &pool, timeout))
+ e = this->db->query(this->db,
+ "SELECT id, start, timeout FROM pools WHERE name = ?",
+ DB_TEXT, name, DB_UINT, DB_BLOB, DB_UINT);
+ if (e && e->enumerate(e, &pool, &start, timeout))
{
- e->destroy(e);
- return pool;
+ if ((family == AF_INET && start.len == 4) ||
+ (family == AF_INET6 && start.len == 16))
+ {
+ e->destroy(e);
+ return pool;
+ }
}
DESTROY_IF(e);
return 0;
@@ -233,57 +240,42 @@ 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 *names, 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;
+ int family;
identity = get_identity(this, id);
if (identity)
{
- /* check for a single pool first (no concatenation and enumeration) */
- if (strchr(names, ',') == NULL)
+ family = requested->get_family(requested);
+ /* check for an existing lease in all pools */
+ enumerator = pools->create_enumerator(pools);
+ while (enumerator->enumerate(enumerator, &name))
{
- pool = get_pool(this, names, &timeout);
+ pool = get_pool(this, name, family, &timeout);
if (pool)
{
- /* check for an existing lease */
- address = check_lease(this, names, pool, identity);
- if (address == NULL)
+ address = check_lease(this, name, pool, identity);
+ if (address)
{
- /* get an unallocated address or expired lease */
- address = get_lease(this, names, pool, timeout, identity);
+ break;
}
}
}
- else
- {
- enumerator_t *enumerator;
- char *name;
-
- /* in a first step check for an existing lease over all pools */
- enumerator = enumerator_create_token(names, ",", " ");
- while (enumerator->enumerate(enumerator, &name))
- {
- pool = get_pool(this, name, &timeout);
- if (pool)
- {
- address = check_lease(this, name, pool, identity);
- if (address)
- {
- enumerator->destroy(enumerator);
- return address;
- }
- }
- }
- enumerator->destroy(enumerator);
+ enumerator->destroy(enumerator);
- /* in a second step get an unallocated address or expired lease */
- enumerator = enumerator_create_token(names, ",", " ");
+ 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);
+ pool = get_pool(this, name, family, &timeout);
if (pool)
{
address = get_lease(this, name, pool, timeout, identity);
@@ -300,20 +292,29 @@ 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;
- bool found = FALSE;
+ u_int pool, timeout;
time_t now = time(NULL);
+ bool found = FALSE;
+ char *name;
+ int family;
- enumerator = enumerator_create_token(name, ",", " ");
+ family = address->get_family(address);
+ enumerator = pools->create_enumerator(pools);
while (enumerator->enumerate(enumerator, &name))
{
- u_int pool, timeout;
-
- pool = get_pool(this, name, &timeout);
- if (pool)
+ pool = get_pool(this, name, family, &timeout);
+ if (!pool)
+ {
+ 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)
{
if (this->history)
{
@@ -324,29 +325,24 @@ METHOD(attribute_provider_t, release_address, bool,
DB_UINT, now, DB_UINT, pool,
DB_BLOB, address->get_address(address));
}
- 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)
- {
- found = TRUE;
- break;
- }
+ found = TRUE;
+ break;
}
}
enumerator->destroy(enumerator);
+
return found;
}
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
- private_sql_attribute_t *this, char *names, identification_t *id,
- host_t *vip)
+ private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
+ linked_list_t *vips)
{
enumerator_t *attr_enumerator = NULL;
- if (vip)
+ if (vips->get_count(vips))
{
- enumerator_t *names_enumerator;
+ enumerator_t *pool_enumerator;
u_int count;
char *name;
@@ -357,8 +353,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
{
u_int identity = get_identity(this, id);
- names_enumerator = enumerator_create_token(names, ",", " ");
- while (names_enumerator->enumerate(names_enumerator, &name))
+ pool_enumerator = pools->create_enumerator(pools);
+ while (pool_enumerator->enumerate(pool_enumerator, &name))
{
u_int attr_pool = get_attr_pool(this, name);
if (!attr_pool)
@@ -385,14 +381,14 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
DESTROY_IF(attr_enumerator);
attr_enumerator = NULL;
}
- names_enumerator->destroy(names_enumerator);
+ pool_enumerator->destroy(pool_enumerator);
}
/* in a second step check for attributes that match name */
if (!attr_enumerator)
{
- names_enumerator = enumerator_create_token(names, ",", " ");
- while (names_enumerator->enumerate(names_enumerator, &name))
+ pool_enumerator = pools->create_enumerator(pools);
+ while (pool_enumerator->enumerate(pool_enumerator, &name))
{
u_int attr_pool = get_attr_pool(this, name);
if (!attr_pool)
@@ -419,7 +415,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
DESTROY_IF(attr_enumerator);
attr_enumerator = NULL;
}
- names_enumerator->destroy(names_enumerator);
+ pool_enumerator->destroy(pool_enumerator);
}
this->db->execute(this->db, NULL, "END TRANSACTION");