Added a non-blocking, skipping variant of IKE_SA enumerator
authorMartin Willi <martin@revosec.ch>
Mon, 2 May 2011 13:28:33 +0000 (15:28 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 16 May 2011 13:24:13 +0000 (15:24 +0200)
13 files changed:
src/conftest/actions.c
src/libcharon/control/controller.c
src/libcharon/control/controller.h
src/libcharon/plugins/ha/ha_cache.c
src/libcharon/plugins/ha/ha_segments.c
src/libcharon/plugins/nm/nm_service.c
src/libcharon/plugins/smp/smp.c
src/libcharon/plugins/stroke/stroke_control.c
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/uci/uci_control.c
src/libcharon/processing/jobs/roam_job.c
src/libcharon/sa/ike_sa_manager.c
src/libcharon/sa/ike_sa_manager.h

index e66e9d7..d07e563 100644 (file)
@@ -85,7 +85,8 @@ static job_requeue_t rekey_ike(char *config)
        job_t *job = NULL;
        ike_sa_t *ike_sa;
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                if (strcaseeq(config, ike_sa->get_name(ike_sa)))
@@ -120,7 +121,8 @@ static job_requeue_t rekey_child(char *config)
        u_int32_t reqid = 0, spi = 0;
        protocol_id_t proto = PROTO_ESP;
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                children = ike_sa->create_child_sa_iterator(ike_sa);
@@ -159,7 +161,8 @@ static job_requeue_t liveness(char *config)
        job_t *job = NULL;
        ike_sa_t *ike_sa;
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                if (strcaseeq(config, ike_sa->get_name(ike_sa)))
@@ -191,7 +194,8 @@ static job_requeue_t close_ike(char *config)
        ike_sa_t *ike_sa;
        int id = 0;
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                if (strcaseeq(config, ike_sa->get_name(ike_sa)))
@@ -224,7 +228,8 @@ static job_requeue_t close_child(char *config)
        child_sa_t *child_sa;
        int id = 0;
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
 
index 5bc19d1..99b4de7 100644 (file)
@@ -206,9 +206,10 @@ static void recheckin(interface_job_t *job)
 /**
  * Implementation of controller_t.create_ike_sa_iterator.
  */
-static enumerator_t* create_ike_sa_enumerator(controller_t *this)
+static enumerator_t* create_ike_sa_enumerator(controller_t *this, bool wait)
 {
-       return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+       return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager,
+                                                                                                        wait);
 }
 
 /**
@@ -448,7 +449,7 @@ controller_t *controller_create(void)
 {
        private_controller_t *this = malloc_thing(private_controller_t);
 
-       this->public.create_ike_sa_enumerator = (enumerator_t*(*)(controller_t*))create_ike_sa_enumerator;
+       this->public.create_ike_sa_enumerator = (enumerator_t*(*)(controller_t*, bool))create_ike_sa_enumerator;
        this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,controller_cb_t,void*))initiate;
        this->public.terminate_ike = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void*))terminate_ike;
        this->public.terminate_child = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void *param))terminate_child;
index 31b69c7..cf0f0a1 100644 (file)
@@ -67,9 +67,10 @@ struct controller_t {
         * The enumerator blocks the IKE_SA manager until it gets destroyed. Do
         * not call another interface/manager method while the iterator is alive.
         *
+        * @param wait                  TRUE to wait for checked out SAs, FALSE to skip
         * @return                              enumerator, locks IKE_SA manager until destroyed
         */
-       enumerator_t* (*create_ike_sa_enumerator)(controller_t *this);
+       enumerator_t* (*create_ike_sa_enumerator)(controller_t *this, bool wait);
 
        /**
         * Initiate a CHILD_SA, and if required, an IKE_SA.
index 9ff3fd5..c27cd0b 100644 (file)
@@ -228,7 +228,7 @@ static void rekey_segment(private_ha_cache_t *this, u_int segment)
        list = linked_list_create();
 
        enumerator = charon->ike_sa_manager->create_enumerator(
-                                                                                               charon->ike_sa_manager);
+                                                                                               charon->ike_sa_manager, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
index 7c7bef8..70b8d1d 100644 (file)
@@ -166,7 +166,8 @@ static void enable_disable(private_ha_segments_t *this, u_int segment,
 
        if (changes)
        {
-               enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+               enumerator = charon->ike_sa_manager->create_enumerator(
+                                                                                               charon->ike_sa_manager, TRUE);
                while (enumerator->enumerate(enumerator, &ike_sa))
                {
                        if (ike_sa->get_state(ike_sa) != old)
index 4300b57..236a7e5 100644 (file)
@@ -632,7 +632,8 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
        u_int id;
 
        /* our ike_sa pointer might be invalid, lookup sa */
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                if (priv->ike_sa == ike_sa)
index d20f322..8fb59d3 100644 (file)
@@ -208,7 +208,8 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
        /* <ikesalist> */
        xmlTextWriterStartElement(writer, "ikesalist");
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                ike_sa_id_t *id;
@@ -394,7 +395,8 @@ static void request_control_terminate(xmlTextReaderPtr reader,
                        enumerator_t *enumerator;
                        ike_sa_t *ike_sa;
 
-                       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+                       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
                        while (enumerator->enumerate(enumerator, &ike_sa))
                        {
                                if (streq(str, ike_sa->get_name(ike_sa)))
index 4943ee6..7df225a 100644 (file)
@@ -287,7 +287,8 @@ METHOD(stroke_control_t, terminate, void,
 
        ike_list = linked_list_create();
        child_list = linked_list_create();
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                child_sa_t *child_sa;
@@ -366,7 +367,8 @@ METHOD(stroke_control_t, rekey, void,
                DBG1(DBG_CFG, "error parsing specifier string");
                return;
        }
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                child_sa_t *child_sa;
@@ -442,7 +444,8 @@ METHOD(stroke_control_t, terminate_srcip, void,
                chunk_end = end->get_address(end);
        }
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
@@ -493,7 +496,8 @@ METHOD(stroke_control_t, purge_ike, void,
        info.level = msg->output_verbosity;
 
        list = linked_list_create();
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                iterator = ike_sa->create_child_sa_iterator(ike_sa);
index 49402e0..9dd1ca4 100644 (file)
@@ -530,7 +530,8 @@ METHOD(stroke_list_t, status, void,
        enumerator->destroy(enumerator);
 
        fprintf(out, "Security Associations:\n");
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                bool ike_printed = FALSE;
index aee2505..8296c41 100644 (file)
@@ -92,7 +92,8 @@ static void status(private_uci_control_t *this, char *name)
                {
                        continue;
                }
-               sas = charon->controller->create_ike_sa_enumerator(charon->controller);
+               sas = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
                while (sas->enumerate(sas, &ike_sa))
                {
                        if (!streq(ike_sa->get_name(ike_sa), peer_cfg->get_name(peer_cfg)))
@@ -174,7 +175,8 @@ static void terminate(private_uci_control_t *this, char *name)
        ike_sa_t *ike_sa;
        u_int id;
 
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       enumerator = charon->controller->create_ike_sa_enumerator(
+                                                                                                       charon->controller, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                if (streq(name, ike_sa->get_name(ike_sa)))
index 2e9d887..951ac5a 100644 (file)
@@ -55,7 +55,8 @@ METHOD(job_t, execute, void,
        /* enumerator over all IKE_SAs gives us no way to checkin_and_destroy
         * after a DESTROY_ME, so we check out each available IKE_SA by hand. */
        list = linked_list_create();
-       enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+       enumerator = charon->ike_sa_manager->create_enumerator(
+                                                                                               charon->ike_sa_manager, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                id = ike_sa->get_id(ike_sa);
index d695c7f..891bb8e 100644 (file)
@@ -1238,10 +1238,10 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
 }
 
 /**
- * enumerator filter function
+ * enumerator filter function, waiting variant
  */
-static bool enumerator_filter(private_ike_sa_manager_t *this,
-                                                         entry_t **in, ike_sa_t **out, u_int *segment)
+static bool enumerator_filter_wait(private_ike_sa_manager_t *this,
+                                                                  entry_t **in, ike_sa_t **out, u_int *segment)
 {
        if (wait_for_entry(this, *in, *segment))
        {
@@ -1251,11 +1251,28 @@ static bool enumerator_filter(private_ike_sa_manager_t *this,
        return FALSE;
 }
 
+/**
+ * enumerator filter function, skipping variant
+ */
+static bool enumerator_filter_skip(private_ike_sa_manager_t *this,
+                                                                  entry_t **in, ike_sa_t **out, u_int *segment)
+{
+       if (!(*in)->driveout_new_threads &&
+               !(*in)->driveout_waiting_threads &&
+               !(*in)->checked_out)
+       {
+               *out = (*in)->ike_sa;
+               return TRUE;
+       }
+       return FALSE;
+}
+
 METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*,
-       private_ike_sa_manager_t* this)
+       private_ike_sa_manager_t* this, bool wait)
 {
        return enumerator_create_filter(create_table_enumerator(this),
-                                                                       (void*)enumerator_filter, this, NULL);
+                       wait ? (void*)enumerator_filter_wait : (void*)enumerator_filter_skip,
+                       this, NULL);
 }
 
 METHOD(ike_sa_manager_t, checkin, void,
index ec157ab..315e235 100644 (file)
@@ -162,9 +162,10 @@ struct ike_sa_manager_t {
         * While enumerating an IKE_SA, it is temporarily checked out and
         * automatically checked in after the current enumeration step.
         *
+        * @param wait                          TRUE to wait for checked out SAs, FALSE to skip
         * @return                                      enumerator over all IKE_SAs.
         */
-       enumerator_t *(*create_enumerator) (ike_sa_manager_t* this);
+       enumerator_t *(*create_enumerator) (ike_sa_manager_t* this, bool wait);
 
        /**
         * Checkin the SA after usage.