diff options
author | Martin Willi <martin@strongswan.org> | 2008-06-04 13:18:55 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-06-04 13:18:55 +0000 |
commit | f3e11fc47877bffc4ab6aaced86dcf3a2d0bc4f8 (patch) | |
tree | 983e2e33f4f68e197cda372f340af8b45ccce42f /src | |
parent | f13e23754f33e5370d4a4f88ed2252f3200d23ff (diff) | |
download | strongswan-f3e11fc47877bffc4ab6aaced86dcf3a2d0bc4f8.tar.bz2 strongswan-f3e11fc47877bffc4ab6aaced86dcf3a2d0bc4f8.tar.xz |
some input validation checks for --add and --resize
--purge keeps an entry for each address to allow their reallaction
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/plugins/sql/pool.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/src/charon/plugins/sql/pool.c b/src/charon/plugins/sql/pool.c index a5ddcb29b..77a7a674e 100644 --- a/src/charon/plugins/sql/pool.c +++ b/src/charon/plugins/sql/pool.c @@ -150,11 +150,22 @@ static void status(void) */ static void add(char *name, host_t *start, host_t *end, int timeout) { + chunk_t start_addr, end_addr; + + start_addr = start->get_address(start); + end_addr = end->get_address(end); + + if (start_addr.len != end_addr.len || + memcmp(start_addr.ptr, end_addr.ptr, start_addr.len) > 0) + { + fprintf(stderr, "invalid start/end pair specified.\n"); + exit(-1); + } if (db->execute(db, NULL, "INSERT INTO pools (name, start, end, next, timeout) " "VALUES (?, ?, ?, ?, ?)", - DB_TEXT, name, DB_BLOB, start->get_address(start), - DB_BLOB, end->get_address(end), DB_BLOB, start->get_address(start), + DB_TEXT, name, DB_BLOB, start_addr, + DB_BLOB, end_addr, DB_BLOB, start_addr, DB_INT, timeout*3600) != 1) { fprintf(stderr, "creating pool failed.\n"); @@ -206,10 +217,33 @@ static void del(char *name) */ static void resize(char *name, host_t *end) { - /* TODO: check for active leases if we are decreasing pool size */ + enumerator_t *query; + chunk_t next_addr, end_addr; + + end_addr = end->get_address(end); + + query = db->query(db, "SELECT next FROM pools WHERE name = ?", + DB_TEXT, name, DB_BLOB); + if (!query || !query->enumerate(query, &next_addr)) + { + DESTROY_IF(query); + fprintf(stderr, "resizing pool failed.\n"); + exit(-1); + } + if (next_addr.len != end_addr.len || + memcmp(end_addr.ptr, next_addr.ptr, end_addr.len) < 0) + { + end = host_create_from_blob(next_addr); + fprintf(stderr, "pool addresses up to %H in use, resizing failed.\n", end); + end->destroy(end); + query->destroy(query); + exit(-1); + } + query->destroy(query); + if (db->execute(db, NULL, "UPDATE pools SET end = ? WHERE name = ?", - DB_BLOB, end->get_address(end), DB_TEXT, name) <= 0) + DB_BLOB, end_addr, DB_TEXT, name) <= 0) { fprintf(stderr, "pool '%s' not found.\n", name); exit(-1); @@ -307,17 +341,24 @@ static void purge(char *name) fprintf(stderr, "purging pool failed.\n"); exit(-1); } + /* we have to keep one lease if we purge. It wouldn't be reallocateable + * as we move on the "next" address for speedy allocation */ if (query->enumerate(query, &id, &timeout)) { + timeout = time(NULL) - timeout; purged = db->execute(db, NULL, "DELETE FROM leases WHERE pool = ? " - "AND released IS NOT NULL AND released < ?", - DB_UINT, id, DB_UINT, time(NULL) - timeout); + "AND released IS NOT NULL AND released < ? AND id NOT IN (" + " SELECT id FROM leases " + " WHERE released IS NOT NULL and released < ? " + " GROUP BY address)", + DB_UINT, id, DB_UINT, timeout, DB_UINT, timeout); } query->destroy(query); fprintf(stderr, "purged %d leases in pool '%s'.\n", purged, name); exit(0); } + /** * atexit handler to close db on shutdown */ |