87
79
name: Name of the pool to resize\n\
88
80
end: New end address for the pool\n\
90
ipsec pool --leases <name> [--filter <filter>] [--utc]\n\
82
ipsec pool --leases [--filter <filter>] [--utc]\n\
91
83
Show lease information using filters:\n\
92
name: Name of the pool to show leases from\n\
93
84
filter: Filter string containing comma separated key=value filters,\n\
94
85
e.g. id=alice@strongswan.org,addr=1.1.1.1\n\
95
86
pool: name of the pool\n\
131
printf("%8s %15s %15s %8s %6s %11s %11s\n",
132
"name", "start", "end", "timeout", "size", "online", "leases");
122
printf("%8s %15s %15s %8s %6s %11s %11s\n", "name", "start",
123
"end", "timeout", "size", "online", "usage");
136
start = host_create_from_blob(start_chunk);
137
end = host_create_from_blob(end_chunk);
127
start = host_create_from_chunk(AF_UNSPEC, start_chunk, 0);
128
end = host_create_from_chunk(AF_UNSPEC, end_chunk, 0);
138
129
size = get_pool_size(start_chunk, end_chunk);
139
130
printf("%8s %15H %15H ", name, start, end);
158
149
printf("%5d (%2d%%) ", online, online*100/size);
159
150
/* get number of online or valid lieases */
160
lease = db->query(db, "SELECT COUNT(*) FROM leases JOIN pools "
161
"ON leases.pool = pools.id "
162
"WHERE pools.id = ? "
163
"AND (released IS NULL OR released > ? - timeout) ",
164
DB_UINT, id, DB_UINT, time(NULL), DB_UINT);
151
lease = db->query(db, "SELECT COUNT(*) FROM addresses "
152
"WHERE addresses.pool = ? "
153
"AND ((? AND acquired != 0) "
154
" OR released = 0 OR released > ?) ",
155
DB_UINT, id, DB_UINT, !timeout,
156
DB_UINT, time(NULL) - timeout, DB_UINT);
167
159
lease->enumerate(lease, &used);
178
* increment a chunk, as it would reprensent a network order integer
180
static void increment_chunk(chunk_t chunk)
184
for (i = chunk.len - 1; i >= 0; i--)
186
if (++chunk.ptr[i] != 0)
186
194
* ipsec pool --add - add a new pool
188
196
static void add(char *name, host_t *start, host_t *end, int timeout)
190
chunk_t start_addr, end_addr;
198
chunk_t start_addr, end_addr, cur_addr;
192
201
start_addr = start->get_address(start);
193
202
end_addr = end->get_address(end);
203
cur_addr = chunk_clonea(start_addr);
204
count = get_pool_size(start_addr, end_addr);
195
206
if (start_addr.len != end_addr.len ||
196
207
memcmp(start_addr.ptr, end_addr.ptr, start_addr.len) > 0)
198
209
fprintf(stderr, "invalid start/end pair specified.\n");
201
if (db->execute(db, NULL,
202
"INSERT INTO pools (name, start, end, next, timeout) "
203
"VALUES (?, ?, ?, ?, ?)",
212
if (db->execute(db, &id,
213
"INSERT INTO pools (name, start, end, timeout) "
214
"VALUES (?, ?, ?, ?)",
204
215
DB_TEXT, name, DB_BLOB, start_addr,
205
DB_BLOB, end_addr, DB_BLOB, start_addr,
206
DB_INT, timeout*3600) != 1)
216
DB_BLOB, end_addr, DB_INT, timeout*3600) != 1)
208
218
fprintf(stderr, "creating pool failed.\n");
221
printf("allocating %d addresses... ", count);
223
if (db->get_driver(db) == DB_SQLITE)
224
{ /* run population in a transaction for sqlite */
225
db->execute(db, NULL, "BEGIN TRANSACTION");
229
db->execute(db, NULL,
230
"INSERT INTO addresses (pool, address, identity, acquired, released) "
231
"VALUES (?, ?, ?, ?, ?)",
232
DB_UINT, id, DB_BLOB, cur_addr, DB_UINT, 0, DB_UINT, 0, DB_UINT, 1);
233
if (chunk_equals(cur_addr, end_addr))
237
increment_chunk(cur_addr);
239
if (db->get_driver(db) == DB_SQLITE)
241
db->execute(db, NULL, "END TRANSACTION");
243
printf("done.\n", count);
233
267
if (db->execute(db, NULL,
234
"DELETE FROM pools WHERE id = ?", DB_UINT, id) != 1 ||
235
db->execute(db, NULL,
236
"DELETE FROM leases WHERE pool = ?", DB_UINT, id) < 0)
268
"DELETE FROM leases WHERE address IN ("
269
" SELECT id FROM addresses WHERE pool = ?)", DB_UINT, id) < 0 ||
270
db->execute(db, NULL,
271
"DELETE FROM addresses WHERE pool = ?", DB_UINT, id) < 0 ||
272
db->execute(db, NULL,
273
"DELETE FROM pools WHERE id = ?", DB_UINT, id) < 0)
238
275
fprintf(stderr, "deleting pool failed.\n");
239
276
query->destroy(query);
255
292
static void resize(char *name, host_t *end)
257
294
enumerator_t *query;
258
chunk_t next_addr, end_addr;
260
end_addr = end->get_address(end);
262
query = db->query(db, "SELECT next FROM pools WHERE name = ?",
263
DB_TEXT, name, DB_BLOB);
264
if (!query || !query->enumerate(query, &next_addr))
295
chunk_t old_addr, new_addr, cur_addr;
298
new_addr = end->get_address(end);
300
query = db->query(db, "SELECT id, end FROM pools WHERE name = ?",
301
DB_TEXT, name, DB_UINT, DB_BLOB);
302
if (!query || !query->enumerate(query, &id, &old_addr))
266
304
DESTROY_IF(query);
267
305
fprintf(stderr, "resizing pool failed.\n");
270
if (next_addr.len != end_addr.len ||
271
memcmp(end_addr.ptr, next_addr.ptr, end_addr.len) < 0)
308
if (old_addr.len != new_addr.len ||
309
memcmp(new_addr.ptr, old_addr.ptr, old_addr.len) < 0)
273
end = host_create_from_blob(next_addr);
274
fprintf(stderr, "pool addresses up to %H in use, resizing failed.\n", end);
311
fprintf(stderr, "shrinking of pools not supported.\n");
276
312
query->destroy(query);
315
cur_addr = chunk_clonea(old_addr);
316
count = get_pool_size(old_addr, new_addr) - 1;
279
317
query->destroy(query);
281
319
if (db->execute(db, NULL,
282
320
"UPDATE pools SET end = ? WHERE name = ?",
283
DB_BLOB, end_addr, DB_TEXT, name) <= 0)
321
DB_BLOB, new_addr, DB_TEXT, name) <= 0)
285
323
fprintf(stderr, "pool '%s' not found.\n", name);
327
printf("allocating %d new addresses... ", count);
329
if (db->get_driver(db) == DB_SQLITE)
330
{ /* run population in a transaction for sqlite */
331
db->execute(db, NULL, "BEGIN TRANSACTION");
335
increment_chunk(cur_addr);
336
db->execute(db, NULL,
337
"INSERT INTO addresses (pool, address, identity, acquired, released) "
338
"VALUES (?, ?, ?, ?, ?)",
339
DB_UINT, id, DB_BLOB, cur_addr, DB_UINT, 0, DB_UINT, 0, DB_UINT, 1);
341
if (db->get_driver(db) == DB_SQLITE)
343
db->execute(db, NULL, "END TRANSACTION");
345
printf("done.\n", count);
400
459
query = db->query(db,
401
"SELECT name, address, identities.type, "
402
"identities.data, acquired, released, timeout "
403
"FROM leases JOIN pools ON leases.pool = pools.id "
460
"SELECT name, addresses.address, identities.type, "
461
"identities.data, leases.acquired, leases.released, timeout "
462
"FROM leases JOIN addresses ON leases.address = addresses.id "
463
"JOIN pools ON addresses.pool = pools.id "
404
464
"JOIN identities ON leases.identity = identities.id "
405
465
"WHERE (? OR name = ?) "
406
466
"AND (? OR (identities.type = ? AND identities.data = ?)) "
407
"AND (? OR address = ?) "
408
"AND (? OR (? >= acquired AND (? <= released OR released IS NULL))) "
409
"AND (? OR released IS NULL) "
410
"AND (? OR released > ? - timeout) "
411
"AND (? OR released < ? - timeout)",
467
"AND (? OR addresses.address = ?) "
468
"AND (? OR (? >= leases.acquired AND (? <= leases.released))) "
469
"AND (? OR leases.released > ? - timeout) "
470
"AND (? OR leases.released < ? - timeout) "
473
"SELECT name, address, identities.type, identities.data, "
474
"acquired, released, timeout FROM addresses "
475
"JOIN pools ON addresses.pool = pools.id "
476
"JOIN identities ON addresses.identity = identities.id "
477
"WHERE ? AND released = 0 "
478
"AND (? OR name = ?) "
479
"AND (? OR (identities.type = ? AND identities.data = ?)) "
480
"AND (? OR address = ?)",
412
481
DB_INT, pool == NULL, DB_TEXT, pool,
413
482
DB_INT, id == NULL,
414
483
DB_INT, id ? id->get_type(id) : 0,
416
485
DB_INT, addr == NULL,
417
486
DB_BLOB, addr ? addr->get_address(addr) : chunk_empty,
418
487
DB_INT, tstamp == 0, DB_UINT, tstamp, DB_UINT, tstamp,
420
488
DB_INT, !valid, DB_INT, time(NULL),
421
489
DB_INT, !expired, DB_INT, time(NULL),
492
DB_INT, !(valid || expired),
493
DB_INT, pool == NULL, DB_TEXT, pool,
495
DB_INT, id ? id->get_type(id) : 0,
496
DB_BLOB, id ? id->get_encoding(id) : chunk_empty,
497
DB_INT, addr == NULL,
498
DB_BLOB, addr ? addr->get_address(addr) : chunk_empty,
422
500
DB_TEXT, DB_BLOB, DB_INT, DB_BLOB, DB_UINT, DB_UINT, DB_UINT);
423
501
/* id and addr leak but we can't destroy them until query is destroyed. */
455
533
printf("%-8s %-15s %-7s %-*s %-*s %s\n",
456
534
"name", "address", "status", len, "start", len, "end", "identity");
458
address = host_create_from_blob(address_chunk);
536
address = host_create_from_chunk(AF_UNSPEC, address_chunk, 0);
459
537
identity = identification_create_from_encoding(identity_type, identity_chunk);
461
539
printf("%-8s %-15H ", name, address);
508
586
static void purge(char *name)
511
u_int id, timeout, purged = 0;
513
query = db->query(db, "SELECT id, timeout FROM pools WHERE name = ?",
514
DB_TEXT, name, DB_UINT, DB_UINT);
590
purged = db->execute(db, NULL,
591
"DELETE FROM leases WHERE address IN ("
592
" SELECT id FROM addresses WHERE pool IN ("
593
" SELECT id FROM pools WHERE name = ?))",
517
fprintf(stderr, "purging pool failed.\n");
597
fprintf(stderr, "purging pool '%s' failed.\n", name);
520
/* we have to keep one lease if we purge. It wouldn't be reallocateable
521
* as we move on the "next" address for speedy allocation */
522
if (query->enumerate(query, &id, &timeout))
524
timeout = time(NULL) - timeout;
525
purged = db->execute(db, NULL,
526
"DELETE FROM leases WHERE pool = ? "
527
"AND released IS NOT NULL AND released < ? AND id NOT IN ("
528
" SELECT id FROM leases "
529
" WHERE released IS NOT NULL and released < ? "
530
" GROUP BY address)",
531
DB_UINT, id, DB_UINT, timeout, DB_UINT, timeout);
533
query->destroy(query);
534
600
fprintf(stderr, "purged %d leases in pool '%s'.\n", purged, name);