list assigned leases using "ipsec leases"
authorMartin Willi <martin@strongswan.org>
Wed, 10 Dec 2008 13:00:02 +0000 (13:00 -0000)
committerMartin Willi <martin@strongswan.org>
Wed, 10 Dec 2008 13:00:02 +0000 (13:00 -0000)
src/charon/plugins/stroke/stroke_attribute.c
src/charon/plugins/stroke/stroke_attribute.h
src/charon/plugins/stroke/stroke_list.c
src/charon/plugins/stroke/stroke_list.h
src/charon/plugins/stroke/stroke_socket.c
src/ipsec/ipsec.in
src/stroke/stroke.c
src/stroke/stroke_keywords.h
src/stroke/stroke_keywords.txt
src/stroke/stroke_msg.h

index 24f083b..666d948 100644 (file)
@@ -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;
 }
index 3d6b935..5060dc9 100644 (file)
@@ -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);
index b0791ce..f9e6567 100644 (file)
@@ -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);
index 525e955..1f7f19d 100644 (file)
@@ -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);
 };
 
 /**
index 45358d3..53edde0 100644 (file)
@@ -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;
index c4e1041..8b5ac7c 100755 (executable)
@@ -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 [<poolname> [<address>]]"
        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|\
index 9a15547..6602890 100644 (file)
@@ -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);
        }
index 0d71d24..2925890 100644 (file)
@@ -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
index 21aa80f..64ee397 100644 (file)
@@ -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
index 59fa109..3061e2d 100644 (file)
@@ -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];
 };