From 6b83549d1aef788102346cda1ab95d7191025579 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 10 Dec 2008 13:00:02 +0000 Subject: [PATCH] list assigned leases using "ipsec leases" --- src/charon/plugins/stroke/stroke_attribute.c | 89 +++++++++++++++++++++++++++- src/charon/plugins/stroke/stroke_attribute.h | 11 ++++ src/charon/plugins/stroke/stroke_list.c | 72 ++++++++++++++++++++++ src/charon/plugins/stroke/stroke_list.h | 14 ++++- src/charon/plugins/stroke/stroke_socket.c | 15 +++++ src/ipsec/ipsec.in | 16 +++++ src/stroke/stroke.c | 18 ++++++ src/stroke/stroke_keywords.h | 3 +- src/stroke/stroke_keywords.txt | 5 +- src/stroke/stroke_msg.h | 10 +++- 10 files changed, 245 insertions(+), 8 deletions(-) diff --git a/src/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c index 24f083b..666d948 100644 --- a/src/charon/plugins/stroke/stroke_attribute.c +++ b/src/charon/plugins/stroke/stroke_attribute.c @@ -413,6 +413,92 @@ static enumerator_t* create_pool_enumerator(private_stroke_attribute_t *this) } /** + * lease enumerator + */ +typedef struct { + /** implemented enumerator interface */ + enumerator_t public; + /** inner hash-table enumerator */ + enumerator_t *inner; + /** enumerated pool */ + pool_t *pool; + /** mutex to unlock on destruction */ + mutex_t *mutex; + /** currently enumerated lease address */ + host_t *current; +} lease_enumerator_t; + +/** + * Implementation of lease_enumerator_t.enumerate + */ +static bool lease_enumerate(lease_enumerator_t *this, identification_t **id_out, + host_t **addr_out, bool *online) +{ + identification_t *id; + uintptr_t offset; + + DESTROY_IF(this->current); + this->current = NULL; + + if (this->inner->enumerate(this->inner, &id, NULL)) + { + offset = (uintptr_t)this->pool->online->get(this->pool->online, id); + if (offset) + { + *id_out = id; + *addr_out = this->current = offset2host(this->pool, offset); + *online = TRUE; + return TRUE; + } + offset = (uintptr_t)this->pool->offline->get(this->pool->offline, id); + if (offset) + { + *id_out = id; + *addr_out = this->current = offset2host(this->pool, offset); + *online = FALSE; + return TRUE; + } + } + return FALSE; +} + +/** + * Implementation of lease_enumerator_t.destroy + */ +static void lease_enumerator_destroy(lease_enumerator_t *this) +{ + DESTROY_IF(this->current); + this->inner->destroy(this->inner); + this->mutex->unlock(this->mutex); + free(this); +} + +/** + * Implementation of stroke_attribute_t.create_lease_enumerator + */ +static enumerator_t* create_lease_enumerator(private_stroke_attribute_t *this, + char *pool) +{ + lease_enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = malloc_thing(lease_enumerator_t); + enumerator->pool = find_pool(this, pool); + if (!enumerator->pool) + { + this->mutex->unlock(this->mutex); + free(enumerator); + return NULL; + } + enumerator->public.enumerate = (void*)lease_enumerate; + enumerator->public.destroy = (void*)lease_enumerator_destroy; + enumerator->inner = enumerator->pool->ids->create_enumerator(enumerator->pool->ids); + enumerator->mutex = this->mutex; + enumerator->current = NULL; + return &enumerator->public; +} + +/** * Implementation of stroke_attribute_t.destroy */ static void destroy(private_stroke_attribute_t *this) @@ -434,10 +520,11 @@ stroke_attribute_t *stroke_attribute_create() this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool; this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool; this->public.create_pool_enumerator = (enumerator_t*(*)(stroke_attribute_t*))create_pool_enumerator; + this->public.create_lease_enumerator = (enumerator_t*(*)(stroke_attribute_t*, char *pool))create_lease_enumerator; this->public.destroy = (void(*)(stroke_attribute_t*))destroy; this->pools = linked_list_create(); - this->mutex = mutex_create(MUTEX_DEFAULT); + this->mutex = mutex_create(MUTEX_RECURSIVE); return &this->public; } diff --git a/src/charon/plugins/stroke/stroke_attribute.h b/src/charon/plugins/stroke/stroke_attribute.h index 3d6b935..5060dc9 100644 --- a/src/charon/plugins/stroke/stroke_attribute.h +++ b/src/charon/plugins/stroke/stroke_attribute.h @@ -64,6 +64,17 @@ struct stroke_attribute_t { enumerator_t* (*create_pool_enumerator)(stroke_attribute_t *this); /** + * Create an enumerator over the leases of a pool. + * + * Enumerator enumerates over + * identification_t *id, host_t *address, bool online + * + * @param pool name of the pool to enumerate + * @return enumerator, NULL if pool not found + */ + enumerator_t* (*create_lease_enumerator)(stroke_attribute_t *this, + char *pool); + /** * Destroy a stroke_attribute instance. */ void (*destroy)(stroke_attribute_t *this); diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c index b0791ce..f9e6567 100644 --- a/src/charon/plugins/stroke/stroke_list.c +++ b/src/charon/plugins/stroke/stroke_list.c @@ -1000,6 +1000,77 @@ static void list(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) } /** + * Print leases of a single pool + */ +static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool, + host_t *address, u_int size, u_int online, u_int offline) +{ + enumerator_t *enumerator; + identification_t *id; + host_t *lease; + bool on; + int found = 0; + + fprintf(out, "Leases in pool '%s', usage: %lu/%lu, %lu online\n", + pool, online + offline, size, online); + enumerator = this->attribute->create_lease_enumerator(this->attribute, pool); + while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on)) + { + if (!address || address->ip_equals(address, lease)) + { + fprintf(out, " %15H %s '%D'\n", + lease, on ? "online" : "offline", id); + found++; + } + } + enumerator->destroy(enumerator); + if (!found) + { + fprintf(out, " no matching leases found\n"); + } +} + +/** + * Implementation of stroke_list_t.leases + */ +static void leases(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) +{ + enumerator_t *enumerator; + u_int size, offline, online; + host_t *address = NULL; + char *pool; + int found = 0; + + if (msg->leases.address) + { + address = host_create_from_string(msg->leases.address, 0); + } + + enumerator = this->attribute->create_pool_enumerator(this->attribute); + while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline)) + { + if (!msg->leases.pool || streq(msg->leases.pool, pool)) + { + pool_leases(this, out, pool, address, size, online, offline); + found++; + } + } + enumerator->destroy(enumerator); + if (!found) + { + if (msg->leases.pool) + { + fprintf(out, "pool '%s' not found\n", msg->leases.pool); + } + else + { + fprintf(out, "no pools found\n"); + } + } + DESTROY_IF(address); +} + +/** * Implementation of stroke_list_t.destroy */ static void destroy(private_stroke_list_t *this) @@ -1016,6 +1087,7 @@ stroke_list_t *stroke_list_create(stroke_attribute_t *attribute) this->public.list = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))list; this->public.status = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out,bool))status; + this->public.leases = (void(*)(stroke_list_t*, stroke_msg_t *msg, FILE *out))leases; this->public.destroy = (void(*)(stroke_list_t*))destroy; this->uptime = time(NULL); diff --git a/src/charon/plugins/stroke/stroke_list.h b/src/charon/plugins/stroke/stroke_list.h index 525e955..1f7f19d 100644 --- a/src/charon/plugins/stroke/stroke_list.h +++ b/src/charon/plugins/stroke/stroke_list.h @@ -53,9 +53,17 @@ struct stroke_list_t { void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all); /** - * Destroy a stroke_list instance. - */ - void (*destroy)(stroke_list_t *this); + * Log pool leases to stroke console. + * + * @param msg stroke message + * @param out stroke console stream + */ + void (*leases)(stroke_list_t *this, stroke_msg_t *msg, FILE *out); + + /** + * Destroy a stroke_list instance. + */ + void (*destroy)(stroke_list_t *this); }; /** diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c index 45358d3..53edde0 100644 --- a/src/charon/plugins/stroke/stroke_socket.c +++ b/src/charon/plugins/stroke/stroke_socket.c @@ -337,6 +337,18 @@ static void stroke_purge(private_stroke_socket_t *this, CERT_X509_OCSP_RESPONSE); } +/** + * list pool leases + */ +static void stroke_leases(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + pop_string(msg, &msg->leases.pool); + pop_string(msg, &msg->leases.address); + + this->list->leases(this->list, msg, out); +} + debug_t get_group_from_name(char *type) { if (strcasecmp(type, "any") == 0) return DBG_ANY; @@ -498,6 +510,9 @@ static job_requeue_t process(stroke_job_context_t *ctx) case STR_PURGE: stroke_purge(this, msg, out); break; + case STR_LEASES: + stroke_leases(this, msg, out); + break; default: DBG1(DBG_CFG, "received unknown stroke"); break; diff --git a/src/ipsec/ipsec.in b/src/ipsec/ipsec.in index c4e1041..8b5ac7c 100755 --- a/src/ipsec/ipsec.in +++ b/src/ipsec/ipsec.in @@ -63,6 +63,7 @@ case "$1" in echo " listcacerts|listaacerts|listocspcerts [--utc]" echo " listacerts|listgroups|listcainfos [--utc]" echo " listcrls|listocsp|listcards|listall [--utc]" + echo " listpool [ [
]]" echo " rereadsecrets|rereadgroups" echo " rereadcacerts|rereadaacerts|rereadocspcerts" echo " rereadacerts|rereadcrls|rereadall" @@ -146,6 +147,21 @@ listcards|rereadgroups) exit 7 fi ;; +leases) + op="$1" + rc=7 + shift + if [ -e $IPSEC_CHARON_PID ] + then + case "$#" in + 0) $IPSEC_STROKE "$op" ;; + 1) $IPSEC_STROKE "$op" "$1" ;; + *) $IPSEC_STROKE "$op" "$1" "$2" ;; + esac + rc="$?" + fi + exit "$rc" + ;; listalgs|\listpubkeys|\ listcerts|listcacerts|listaacerts|\ listacerts|listgroups|listocspcerts|\ diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c index 9a15547..6602890 100644 --- a/src/stroke/stroke.c +++ b/src/stroke/stroke.c @@ -259,6 +259,18 @@ static int purge(stroke_keyword_t kw) return send_stroke_msg(&msg); } +static int leases(stroke_keyword_t kw, char *pool, char *address) +{ + + stroke_msg_t msg; + + msg.type = STR_LEASES; + msg.length = offsetof(stroke_msg_t, buffer); + msg.leases.pool = push_string(&msg, pool); + msg.leases.address = push_string(&msg, address); + return send_stroke_msg(&msg); +} + static int set_loglevel(char *type, u_int level) { stroke_msg_t msg; @@ -318,6 +330,8 @@ static void exit_usage(char *error) printf(" stroke rereadsecrets|rereadcrls|rereadall\n"); printf(" Purge ocsp cache entries:\n"); printf(" stroke purgeocsp\n"); + printf(" Show leases of a pool:\n"); + printf(" stroke leases [POOL [ADDRESS]]\n"); exit_error(error); } @@ -429,6 +443,10 @@ int main(int argc, char *argv[]) case STROKE_PURGE_OCSP: res = purge(token->kw); break; + case STROKE_LEASES: + res = leases(token->kw, argc > 2 ? argv[2] : NULL, + argc > 3 ? argv[3] : NULL); + break; default: exit_usage(NULL); } diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h index 0d71d24..2925890 100644 --- a/src/stroke/stroke_keywords.h +++ b/src/stroke/stroke_keywords.h @@ -49,7 +49,8 @@ typedef enum { STROKE_REREAD_ACERTS, STROKE_REREAD_CRLS, STROKE_REREAD_ALL, - STROKE_PURGE_OCSP + STROKE_PURGE_OCSP, + STROKE_LEASES } stroke_keyword_t; #define STROKE_LIST_FIRST STROKE_LIST_PUBKEYS diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt index 21aa80f..64ee397 100644 --- a/src/stroke/stroke_keywords.txt +++ b/src/stroke/stroke_keywords.txt @@ -52,8 +52,9 @@ listall, STROKE_LIST_ALL rereadsecrets, STROKE_REREAD_SECRETS rereadcacerts, STROKE_REREAD_CACERTS rereadocspcerts, STROKE_REREAD_OCSPCERTS -rereadaacerts, STROKE_REREAD_AACERTS, -rereadacerts, STROKE_REREAD_ACERTS, +rereadaacerts, STROKE_REREAD_AACERTS +rereadacerts, STROKE_REREAD_ACERTS rereadcrls, STROKE_REREAD_CRLS rereadall, STROKE_REREAD_ALL purgeocsp, STROKE_PURGE_OCSP +leases, STROKE_LEASES diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index 59fa109..3061e2d 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -181,7 +181,9 @@ struct stroke_msg_t { /* reread various objects */ STR_REREAD, /* purge various objects */ - STR_PURGE + STR_PURGE, + /* show pool leases */ + STR_LEASES, /* more to come */ } type; @@ -278,6 +280,12 @@ struct stroke_msg_t { struct { purge_flag_t flags; } purge; + + /* data for STR_LEASES */ + struct { + char *pool; + char *address; + } leases; }; char buffer[STROKE_BUF_LEN]; }; -- 2.7.4