implemented child_up() bus hook
authorMartin Willi <martin@strongswan.org>
Thu, 9 Jul 2009 11:11:46 +0000 (13:11 +0200)
committerMartin Willi <martin@strongswan.org>
Thu, 9 Jul 2009 13:25:15 +0000 (15:25 +0200)
src/charon/bus/bus.c
src/charon/bus/bus.h
src/charon/sa/ike_sa.c
src/charon/sa/task_manager.c
src/charon/sa/tasks/child_create.c
src/charon/sa/tasks/child_create.h
src/charon/sa/tasks/child_rekey.c

index 3a31122..71b120a 100644 (file)
@@ -543,6 +543,39 @@ static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new)
 }
 
 /**
+ * Implementation of bus_t.child_updown
+ */
+static void child_updown(private_bus_t *this, child_sa_t *child_sa, bool up)
+{
+       enumerator_t *enumerator;
+       ike_sa_t *ike_sa;
+       entry_t *entry;
+       bool keep;
+       
+       ike_sa = pthread_getspecific(this->thread_sa);
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->calling || !entry->listener->child_updown)
+               {
+                       continue;
+               }
+               entry->calling++;
+               keep = entry->listener->child_updown(entry->listener,
+                                                                                        ike_sa, child_sa, up);
+               entry->calling--;
+               if (!keep)
+               {
+                       unregister_listener(this, entry, enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
  * Implementation of bus_t.child_rekey
  */
 static void child_rekey(private_bus_t *this, child_sa_t *old, child_sa_t *new)
@@ -641,6 +674,7 @@ bus_t *bus_create()
        this->public.ike_keys = (void(*)(bus_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys;
        this->public.child_keys = (void(*)(bus_t*, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys;
        this->public.ike_rekey = (void(*)(bus_t*, ike_sa_t *old, ike_sa_t *new))ike_rekey;
+       this->public.child_updown = (void(*)(bus_t*, child_sa_t *child_sa, bool up))child_updown;
        this->public.child_rekey = (void(*)(bus_t*, child_sa_t *old, child_sa_t *new))child_rekey;
        this->public.authorize = (bool(*)(bus_t*, linked_list_t *auth, bool final))authorize;
        this->public.destroy = (void(*)(bus_t*)) destroy;
index f8de63a..53437f9 100644 (file)
@@ -270,6 +270,14 @@ struct bus_t {
        void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new);
        
        /**
+        * CHILD_SA up/down hook.
+        *
+        * @param child_sa      CHILD_SA coming up/going down
+        * @param up            TRUE for an up event, FALSE for a down event
+        */
+       void (*child_updown)(bus_t *this, child_sa_t *child_sa, bool up);
+       
+       /**
         * CHILD_SA rekeying hook.
         *
         * @param old           rekeyed and obsolete CHILD_SA
index e7408fc..1c2de17 100644 (file)
@@ -1169,7 +1169,8 @@ static status_t initiate(private_ike_sa_t *this,
 #endif /* ME */
        {
                /* normal IKE_SA with CHILD_SA */
-               task = (task_t*)child_create_create(&this->public, child_cfg, tsi, tsr);
+               task = (task_t*)child_create_create(&this->public, child_cfg, FALSE,
+                                                                                       tsi, tsr);
                child_cfg->destroy(child_cfg);
                if (reqid)
                {
index 2cd9532..976ac2c 100644 (file)
@@ -678,7 +678,8 @@ static status_t process_request(private_task_manager_t *this,
                                this->passive_tasks->insert_last(this->passive_tasks, task);
                                task = (task_t*)ike_config_create(this->ike_sa, FALSE);
                                this->passive_tasks->insert_last(this->passive_tasks, task);
-                               task = (task_t*)child_create_create(this->ike_sa, NULL, NULL, NULL);
+                               task = (task_t*)child_create_create(this->ike_sa, NULL, FALSE,
+                                                                                                       NULL, NULL);
                                this->passive_tasks->insert_last(this->passive_tasks, task);
                                task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
                                this->passive_tasks->insert_last(this->passive_tasks, task);
@@ -726,8 +727,8 @@ static status_t process_request(private_task_manager_t *this,
                                        }
                                        else
                                        {
-                                               task = (task_t*)child_create_create(this->ike_sa,
-                                                                                                                       NULL, NULL, NULL);
+                                               task = (task_t*)child_create_create(this->ike_sa, NULL,
+                                                                                                                       FALSE, NULL, NULL);
                                        }
                                }
                                else
index f514437..b610ad4 100644 (file)
@@ -158,6 +158,11 @@ struct private_child_create_t {
         * successfully established the CHILD?
         */
        bool established;
+       
+       /**
+        * whether the CHILD_SA rekeys an existing one
+        */
+       bool rekey;
 };
 
 /**
@@ -939,7 +944,11 @@ static status_t build_r(private_child_create_t *this, message_t *message)
                 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
                 this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
                 this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
-
+       
+       if (!this->rekey)
+       {       /* invoke the child_up() hook if we are not rekeying */
+               charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
+       }
        return SUCCESS;
 }
 
@@ -1052,6 +1061,11 @@ static status_t process_i(private_child_create_t *this, message_t *message)
                         ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
                         this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
                         this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
+               
+               if (!this->rekey)
+               {       /* invoke the child_up() hook if we are not rekeying */
+                       charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
+               }
        }
        else
        {
@@ -1174,7 +1188,8 @@ static void destroy(private_child_create_t *this)
 /*
  * Described in header.
  */
-child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
+child_create_t *child_create_create(ike_sa_t *ike_sa,
+                                                       child_cfg_t *config, bool rekey,
                                                        traffic_selector_t *tsi, traffic_selector_t *tsr)
 {
        private_child_create_t *this = malloc_thing(private_child_create_t);
@@ -1222,6 +1237,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
        this->other_cpi = 0;
        this->reqid = 0;
        this->established = FALSE;
+       this->rekey = rekey;
        
        return &this->public;
 }
index ce2829a..41f4fe2 100644 (file)
@@ -71,11 +71,13 @@ struct child_create_t {
  *
  * @param ike_sa               IKE_SA this task works for
  * @param config               child_cfg if task initiator, NULL if responder
+ * @param rekey                        whether we do a rekey or not
  * @param tsi                  source of triggering packet, or NULL
  * @param tsr                  destination of triggering packet, or NULL
  * @return                             child_create task to handle by the task_manager
  */
-child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
+child_create_t *child_create_create(ike_sa_t *ike_sa,
+                                                       child_cfg_t *config, bool rekey,
                                                        traffic_selector_t *tsi, traffic_selector_t *tsr);
 
 #endif /** CHILD_CREATE_H_ @}*/
index b5e3789..601e054 100644 (file)
@@ -157,7 +157,8 @@ static status_t build_i(private_child_rekey_t *this, message_t *message)
        
        /* ... our CHILD_CREATE task does the hard work for us. */
        reqid = this->child_sa->get_reqid(this->child_sa);
-       this->child_create = child_create_create(this->ike_sa, config, NULL, NULL);
+       this->child_create = child_create_create(this->ike_sa, config, TRUE,
+                                                                                        NULL, NULL);
        this->child_create->use_reqid(this->child_create, reqid);
        this->child_create->task.build(&this->child_create->task, message);
        
@@ -426,7 +427,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
                this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
                this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
                this->initiator = FALSE;
-               this->child_create = child_create_create(ike_sa, NULL, NULL, NULL);
+               this->child_create = child_create_create(ike_sa, NULL, TRUE, NULL, NULL);
        }
        
        this->ike_sa = ike_sa;