extended interface_manager (more work needed here)
authorMartin Willi <martin@strongswan.org>
Thu, 3 May 2007 14:22:52 +0000 (14:22 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 3 May 2007 14:22:52 +0000 (14:22 -0000)
src/charon/config/backends/local_backend.c
src/charon/control/interface_manager.c
src/charon/control/interface_manager.h

index b1e68ee..4100af8 100644 (file)
@@ -219,5 +219,5 @@ backend_t *backend_create(void)
        this->cfgs = linked_list_create();
        pthread_mutex_init(&this->mutex, NULL);
        
-       return (&this->public.backend.backend);
+       return &this->public.backend.backend;
 }
index 5f4a7e8..a50b574 100644 (file)
@@ -35,6 +35,7 @@
 
 
 typedef struct private_interface_manager_t private_interface_manager_t;
+typedef struct interface_bus_listener_t interface_bus_listener_t;
 
 /**
  * Private data of an stroke_t object.
@@ -56,14 +57,47 @@ struct private_interface_manager_t {
         */
        linked_list_t *handles;
 };
+
+/**
+ * helper struct to map bus listener callbacks to interface callbacks
+ */
+struct interface_bus_listener_t {
+
+       /**
+        * bus listener callback function (called)
+        */
+       bus_listener_t listener;
+       
+       /**
+        * IKE_SA to use for message filtering
+        */
+       ike_sa_t *ike_sa;
+       
+       /**
+        *  interface callback (listener gets redirected to here)
+        */
+       interface_manager_cb_t callback;
        
+       /**
+        * user parameter to pass to callback
+        */
+       void *param;
+};
+
+/**
+ * Implementation of interface_manager_t.create_ike_sa_iterator.
+ */
+static iterator_t* create_ike_sa_iterator(interface_manager_t *this)
+{
+       return charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
+}
+
 /**
  * Implementation of interface_manager_t.initiate.
  */
 static status_t initiate(private_interface_manager_t *this,
                                                 peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-                                                bool(*cb)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),
-                                                void *param)
+                                                interface_manager_cb_t cb, void *param)
 {
        ike_sa_t *ours = NULL;
        job_t *job;
@@ -129,6 +163,132 @@ static status_t initiate(private_interface_manager_t *this,
 }
 
 /**
+ * listener function for terminate_ike
+ */
+static bool terminate_listener(interface_bus_listener_t *this, signal_t signal,
+                                                          level_t level, int thread, ike_sa_t *ike_sa,
+                                                          char* format, va_list args)
+{
+       if (this->ike_sa == ike_sa)
+       {
+               if (!this->callback(this->param, signal, level, ike_sa, format, args))
+               {
+                       return FALSE;
+               }
+               switch (signal)
+               {
+                       case IKE_DOWN_FAILED:
+                       case IKE_DOWN_SUCCESS:
+                       {
+                               return FALSE;
+                       }
+                       default:
+                               break;
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * Implementation of interface_manager_t.terminate_ike.
+ */
+static status_t terminate_ike(interface_manager_t *this, u_int32_t unique_id, 
+                                                         interface_manager_cb_t callback, void *param)
+{
+       ike_sa_t *ike_sa;
+       status_t status;
+       
+       ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
+                                                                                                       unique_id, FALSE);                                                      
+       if (ike_sa == NULL)
+       {
+               return NOT_FOUND;
+       }
+       
+       /* we listen passively first, to catch the signals we are raising */
+       if (callback)
+       {
+               interface_bus_listener_t listener;
+       
+               listener.listener.signal = (void*)terminate_listener;
+               listener.callback = callback;
+               listener.ike_sa = ike_sa;
+               listener.param = param;
+               charon->bus->add_listener(charon->bus, &listener.listener);
+       }
+       charon->bus->set_listen_state(charon->bus, TRUE);
+       status = ike_sa->delete(ike_sa);
+       if (status == DESTROY_ME)
+       {
+               charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+       }
+       else
+       {
+               charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+               
+               /* wait until IKE_SA is cleanly deleted using a delete message */
+               while (TRUE)
+               {
+                       level_t level;
+                       signal_t signal;
+                       int thread;
+                       ike_sa_t *current;
+                       char* format;
+                       va_list args;
+                       
+                       signal = charon->bus->listen(charon->bus, &level, &thread, 
+                                                                                &current, &format, &args);
+                       
+                       if (ike_sa == current)
+                       {
+                               switch (signal)
+                               {
+                                       case IKE_DOWN_FAILED:
+                                       case IKE_DOWN_SUCCESS:
+                                       {
+                                                break;
+                                       }
+                                       default:
+                                               continue;
+                               }
+                               break;
+                       }
+               }
+       }
+       charon->bus->set_listen_state(charon->bus, FALSE);
+
+       return SUCCESS;
+}
+
+/**
+ * Implementation of interface_manager_t.terminate_child.
+ */
+static status_t terminate_child(interface_manager_t *this, u_int32_t reqid, 
+                                                               interface_manager_cb_t callback, void *param)
+{
+       return FAILED;
+}
+
+/**
+ * Implementation of interface_manager_t.route.
+ */
+static status_t route(interface_manager_t *this,
+                                         peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+                                         interface_manager_cb_t callback, void *param)
+{
+       return FAILED;
+}
+
+/**
+ * Implementation of interface_manager_t.unroute.
+ */
+static status_t unroute(interface_manager_t *this, u_int32_t reqid, 
+                                               interface_manager_cb_t callback, void *param)
+{
+       return FAILED;
+}
+
+/**
  * load the control interface modules
  */
 static void load_interfaces(private_interface_manager_t *this)
@@ -226,7 +386,12 @@ interface_manager_t *interface_manager_create(void)
 {
        private_interface_manager_t *this = malloc_thing(private_interface_manager_t);
        
+       this->public.create_ike_sa_iterator = (iterator_t*(*)(interface_manager_t*))create_ike_sa_iterator;
        this->public.initiate = (status_t(*)(interface_manager_t*,peer_cfg_t*,child_cfg_t*,bool(*)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),void*))initiate;
+       this->public.terminate_ike = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t, void*))terminate_ike;
+       this->public.terminate_child = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t, void *param))terminate_child;
+       this->public.route = (status_t(*)(interface_manager_t*,peer_cfg_t*, child_cfg_t*,interface_manager_cb_t,void*))route;
+       this->public.unroute = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t,void*))unroute;
        this->public.destroy = (void (*)(interface_manager_t*))destroy;
        
        this->interfaces = linked_list_create();
index ccd9c49..3c1613a 100644 (file)
@@ -71,6 +71,17 @@ typedef struct interface_manager_t interface_manager_t;
 struct interface_manager_t {
 
        /**
+        * @brief Create an iterator for all IKE_SAs.
+        *
+        * The iterator blocks the IKE_SA manager until it gets destroyed. Do
+        * not call another interface/manager method while the iterator is alive.
+        *
+        * @param this                  calling object
+        * @return                              iterator, locks IKE_SA manager until destroyed
+        */
+       iterator_t* (*create_ike_sa_iterator)(interface_manager_t *this);
+
+       /**
         * @brief Initiate a CHILD_SA, and if required, an IKE_SA.
         *
         * @param this                  calling object
@@ -86,6 +97,70 @@ struct interface_manager_t {
        status_t (*initiate)(interface_manager_t *this,
                                                 peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
                                                 interface_manager_cb_t callback, void *param);
+
+       /**
+        * @brief Terminate an IKE_SA and all of its CHILD_SAs.
+        *
+        * @param this                  calling object
+        * @param unique_id             unique id of the IKE_SA to terminate.
+        * @param cb                    logging callback
+        * @param param                 parameter to include in each call of cb
+        * @return
+        *                                              - SUCCESS, if CHILD_SA terminated
+        *                                              - NOT_FOUND, if no such CHILD_SA found
+        *                                              - NEED_MORE, if callback returned FALSE
+        */
+       status_t (*terminate_ike)(interface_manager_t *this, u_int32_t unique_id, 
+                                                         interface_manager_cb_t callback, void *param);
+       
+       /**
+        * @brief Terminate a CHILD_SA.
+        *
+        * @param this                  calling object
+        * @param reqid                 reqid of the CHILD_SA to terminate
+        * @param cb                    logging callback
+        * @param param                 parameter to include in each call of cb
+        * @return
+        *                                              - SUCCESS, if CHILD_SA terminated
+        *                                              - NOT_FOUND, if no such CHILD_SA found
+        *                                              - NEED_MORE, if callback returned FALSE
+        */
+       status_t (*terminate_child)(interface_manager_t *this, u_int32_t reqid, 
+                                                               interface_manager_cb_t callback, void *param);
+       
+       /**
+        * @brief Route a CHILD_SA (install triggering policies).
+        *
+        * @param this                  calling object
+        * @param peer_cfg              peer_cfg to use for IKE_SA setup, if triggered
+        * @param child_cfg             child_cfg to route
+        * @param cb                    logging callback
+        * @param param                 parameter to include in each call of cb
+        * @return
+        *                                              - SUCCESS, if CHILD_SA routed
+        *                                              - FAILED, if routing failed
+        *                                              - NEED_MORE, if callback returned FALSE
+        */
+       status_t (*route)(interface_manager_t *this,
+                                         peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+                                         interface_manager_cb_t callback, void *param);
+       
+       /**
+        * @brief Unroute a routed CHILD_SA (uninstall triggering policies).
+        *
+        * Only the route is removed, not the CHILD_SAs the route triggered.
+        *
+        * @param this                  calling object
+        * @param reqid                 reqid of the CHILD_SA to unroute
+        * @param cb                    logging callback
+        * @param param                 parameter to include in each call of cb
+        * @return
+        *                                              - SUCCESS, if CHILD_SA terminated
+        *                                              - NOT_FOUND, if no such CHILD_SA routed
+        *                                              - NEED_MORE, if callback returned FALSE
+        */
+       status_t (*unroute)(interface_manager_t *this, u_int32_t reqid, 
+                                               interface_manager_cb_t callback, void *param);
        
        /**
         * @brief Destroy a interface_manager_t instance.