enabling acquire for mediated connections
authorTobias Brunner <tobias@strongswan.org>
Thu, 10 Apr 2008 12:51:04 +0000 (12:51 -0000)
committerTobias Brunner <tobias@strongswan.org>
Thu, 10 Apr 2008 12:51:04 +0000 (12:51 -0000)
src/charon/processing/jobs/initiate_mediation_job.c
src/charon/processing/jobs/initiate_mediation_job.h
src/charon/sa/connect_manager.c
src/charon/sa/connect_manager.h
src/charon/sa/ike_sa.c
src/charon/sa/ike_sa.h

index 483420b..d4eb2a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -38,11 +38,6 @@ struct private_initiate_mediation_job_t {
        ike_sa_id_t *mediated_sa_id;
        
        /**
-        * Child config of the CHILD_SA of the mediated connection.
-        */
-       child_cfg_t *mediated_child;
-       
-       /**
         * ID of the IKE_SA of the mediation connection.
         */
        ike_sa_id_t *mediation_sa_id;
@@ -55,7 +50,6 @@ static void destroy(private_initiate_mediation_job_t *this)
 {
        DESTROY_IF(this->mediation_sa_id);
        DESTROY_IF(this->mediated_sa_id);
-       DESTROY_IF(this->mediated_child);
        free(this);
 }
 
@@ -99,7 +93,7 @@ static void initiate(private_initiate_mediation_job_t *this)
                if (charon->connect_manager->check_and_register(charon->connect_manager,
                                mediation_cfg->get_my_id(mediation_cfg),
                                mediated_cfg->get_peer_id(mediated_cfg),
-                               this->mediated_sa_id, this->mediated_child))
+                               this->mediated_sa_id))
                {
                        mediated_cfg->destroy(mediated_cfg);
                        mediation_cfg->destroy(mediation_cfg);
@@ -211,7 +205,6 @@ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
        /* private variables */
        this->mediation_sa_id = NULL;
        this->mediated_sa_id = NULL;
-       this->mediated_child = NULL;
 
        return this;
 }
@@ -219,16 +212,13 @@ static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
 /*
  * Described in header
  */
-initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id,
-               child_cfg_t *child_cfg)
+initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
 {
        private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
        
        this->public.job_interface.execute = (void (*) (job_t *)) initiate;
        
        this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
-       child_cfg->get_ref(child_cfg);
-       this->mediated_child = child_cfg;
 
        return &this->public;
 }
index dbc6cca..cd761f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2008 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 typedef struct initiate_mediation_job_t initiate_mediation_job_t;
 
 #include <processing/jobs/job.h>
-#include <config/child_cfg.h>
 #include <sa/ike_sa_id.h>
 
 /**
@@ -46,11 +45,9 @@ struct initiate_mediation_job_t {
  * Creates a job of type INITIATE_MEDIATION.
  * 
  * @param ike_sa_id            identification of the ike_sa as ike_sa_id_t object (gets cloned)
- * @param child_cfg            child config of the child_sa (gets cloned)
  * @return                             job object
  */
-initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id,
-               child_cfg_t *child_cfg);
+initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id);
 
 /**
  * Creates a special job of type INITIATE_MEDIATION that reinitiates a
index a7c070c..0f156cf 100644 (file)
@@ -255,43 +255,6 @@ static check_list_t *check_list_create(identification_t *initiator, identificati
        return this;
 }
 
-
-typedef struct waiting_sa_t waiting_sa_t;
-
-/**
- * For an initiator, the data stored about a waiting mediated sa
- */
-struct waiting_sa_t {
-       /** ike sa id */
-       ike_sa_id_t *ike_sa_id;
-       
-       /** list of child_cfg_t */
-       linked_list_t *childs;
-};
-
-/**
- * Destroys a queued mediated sa
- */
-static void waiting_sa_destroy(waiting_sa_t *this)
-{
-       DESTROY_IF(this->ike_sa_id);
-       this->childs->destroy_offset(this->childs, offsetof(child_cfg_t, destroy));
-       free(this);
-}
-
-/**
- * Creates a new mediated sa object
- */
-static waiting_sa_t *waiting_sa_create(ike_sa_id_t *ike_sa_id)
-{
-       waiting_sa_t *this = malloc_thing(waiting_sa_t);
-       
-       this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
-       this->childs = linked_list_create();
-    
-       return this;
-}
-
 typedef struct initiated_t initiated_t;
 
 /**
@@ -315,7 +278,7 @@ static void initiated_destroy(initiated_t *this)
 {
        DESTROY_IF(this->id);
        DESTROY_IF(this->peer_id);
-       this->mediated->destroy_function(this->mediated, (void*)waiting_sa_destroy);
+       this->mediated->destroy_offset(this->mediated, offsetof(ike_sa_id_t, destroy));
        free(this);
 }
 
@@ -518,21 +481,6 @@ static void remove_initiated(private_connect_manager_t *this, initiated_t *initi
 }
 
 /**
- * Finds a waiting sa
- */
-static bool match_waiting_sa(waiting_sa_t *current, ike_sa_id_t *ike_sa_id)
-{
-       return ike_sa_id->equals(ike_sa_id, current->ike_sa_id);
-}
-
-static status_t get_waiting_sa(initiated_t *initiated, ike_sa_id_t *ike_sa_id, waiting_sa_t **waiting_sa)
-{
-       return initiated->mediated->find_first(initiated->mediated,
-                               (linked_list_match_t)match_waiting_sa,
-                               (void**)waiting_sa, ike_sa_id);
-}
-
-/**
  * Find the checklist with a specific connect ID
  */
 static bool match_checklist_by_id(check_list_t *current, chunk_t *connect_id)
@@ -1205,13 +1153,12 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
        endpoint_pair_t *pair;
        if (get_best_valid_pair(checklist, &pair) == SUCCESS)
        {
-               waiting_sa_t *waiting_sa;
+               ike_sa_id_t *waiting_sa;
                iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
                while (iterator->iterate(iterator, (void**)&waiting_sa))
                {
-                       ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa->ike_sa_id);
-                       if (sa->initiate_mediated(sa, pair->local, pair->remote, waiting_sa->childs,
-                                       checklist->connect_id) != SUCCESS)
+                       ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa);
+                       if (sa->initiate_mediated(sa, pair->local, pair->remote, checklist->connect_id) != SUCCESS)
                        {
                                SIG(IKE_UP_FAILED, "establishing the mediated connection failed");
                                charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, sa);
@@ -1440,7 +1387,7 @@ static void process_check(private_connect_manager_t *this, message_t *message)
  */
 static bool check_and_register(private_connect_manager_t *this,
                        identification_t *id, identification_t *peer_id,
-                       ike_sa_id_t *mediated_sa, child_cfg_t *child)
+                       ike_sa_id_t *mediated_sa)
 {
        initiated_t *initiated;
        bool already_there = TRUE;
@@ -1455,16 +1402,12 @@ static bool check_and_register(private_connect_manager_t *this,
                already_there = FALSE;
        }
        
-       waiting_sa_t *waiting_sa;
-       if (get_waiting_sa(initiated, mediated_sa, &waiting_sa) != SUCCESS)
+       if (initiated->mediated->find_first(initiated->mediated, 
+                       (linked_list_match_t)mediated_sa->equals, NULL, mediated_sa) != SUCCESS)
        {
-               waiting_sa = waiting_sa_create(mediated_sa);
-               initiated->mediated->insert_last(initiated->mediated, waiting_sa);
+               initiated->mediated->insert_last(initiated->mediated, mediated_sa->clone(mediated_sa));
        }
 
-       child->get_ref(child);
-       waiting_sa->childs->insert_last(waiting_sa->childs, child);
-
        pthread_mutex_unlock(&(this->mutex));
 
        return already_there;
@@ -1487,12 +1430,11 @@ static void check_and_initiate(private_connect_manager_t *this, ike_sa_id_t *med
                return;
        }
        
-       waiting_sa_t *waiting_sa;
+       ike_sa_id_t *waiting_sa;
        iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
        while (iterator->iterate(iterator, (void**)&waiting_sa))
        {
-               job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa,
-                               waiting_sa->ike_sa_id);
+               job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa, waiting_sa);
                charon->processor->queue_job(charon->processor, job);
        }
        iterator->destroy(iterator);
@@ -1610,7 +1552,7 @@ connect_manager_t *connect_manager_create()
        private_connect_manager_t *this = malloc_thing(private_connect_manager_t);
 
        this->public.destroy = (void(*)(connect_manager_t*))destroy;
-       this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*,child_cfg_t*))check_and_register;
+       this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*))check_and_register;
        this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate;
        this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data;
        this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
index ad6ac94..a98fc1b 100644 (file)
@@ -26,7 +26,6 @@
 typedef struct connect_manager_t connect_manager_t;
 
 #include <encoding/message.h>
-#include <config/child_cfg.h>
 #include <sa/ike_sa_id.h>
 #include <utils/identification.h>
 
@@ -43,14 +42,12 @@ struct connect_manager_t {
         * @param id                            my id
         * @param peer_id                       the other peer's id
         * @param mediated_sa           the IKE_SA ID of the mediated connection
-        * @param child                         the CHILD_SA config of the mediated connection 
         * @returns                             
         *                                                      - TRUE, if there was already a mediated connection registered
         *                                                      - FALSE, otherwise
         */
        bool (*check_and_register) (connect_manager_t *this,
-                       identification_t *id, identification_t *peer_id,
-                       ike_sa_id_t *mediated_sa, child_cfg_t *child);
+                       identification_t *id, identification_t *peer_id, ike_sa_id_t *mediated_sa);
        
        /**
         * Checks if there are waiting connections with a specific peer.
index 4d8226f..911270a 100644 (file)
@@ -1030,29 +1030,21 @@ static status_t initiate_mediation(private_ike_sa_t *this, peer_cfg_t *mediated_
  * Implementation of ike_sa_t.initiate_mediated
  */
 static status_t initiate_mediated(private_ike_sa_t *this, host_t *me, host_t *other,
-               linked_list_t *childs, chunk_t connect_id)
+               chunk_t connect_id)
 {
        set_my_host(this, me->clone(me));
        set_other_host(this, other->clone(other));
+       chunk_free(&this->connect_id);
        this->connect_id = chunk_clone(connect_id);
        
-       task_t *task;
-       child_cfg_t *child_cfg; 
-       iterator_t *iterator = childs->create_iterator(childs, TRUE);
-       while (iterator->iterate(iterator, (void**)&child_cfg))
-       {
-               task = (task_t*)child_create_create(&this->public, child_cfg);
-               this->task_manager->queue_task(this->task_manager, task);
-       }
-       iterator->destroy(iterator);
        return this->task_manager->initiate(this->task_manager);
 }
 #endif /* ME */
 
 /**
- * Implementation of ike_sa_t.initiate.
+ * Initiates a CHILD_SA using the appropriate reqid
  */
-static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
+static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid)
 {
        task_t *task;
        
@@ -1098,16 +1090,9 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
        }
 
 #ifdef ME
-       if (this->peer_cfg->get_mediated_by(this->peer_cfg))
-       {
-               /* mediated connection, initiate mediation process */
-               job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id, child_cfg);
-               child_cfg->destroy(child_cfg);
-               charon->processor->queue_job(charon->processor, job);
-               return SUCCESS;
-       }
-       else if (this->peer_cfg->is_mediation(this->peer_cfg))
+       if (this->peer_cfg->is_mediation(this->peer_cfg))
        {
+               /* mediation connection */
                if (this->state == IKE_ESTABLISHED)
                {       /* FIXME: we should try to find a better solution to this */
                        SIG(CHILD_UP_SUCCESS, "mediation connection is already up and running");
@@ -1120,22 +1105,43 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
                /* normal IKE_SA with CHILD_SA */
                task = (task_t*)child_create_create(&this->public, child_cfg);
                child_cfg->destroy(child_cfg);
+               if (reqid)
+               {
+                       child_create_t *child_create = (child_create_t*)task;
+                       child_create->use_reqid(child_create, reqid);
+               }
                this->task_manager->queue_task(this->task_manager, task);
+
+#ifdef ME
+               if (this->peer_cfg->get_mediated_by(this->peer_cfg))
+               {
+                       /* mediated connection, initiate mediation process */
+                       job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
+                       charon->processor->queue_job(charon->processor, job);
+                       return SUCCESS;
+               }
+#endif /* ME */
        }
        
        return this->task_manager->initiate(this->task_manager);
 }
 
 /**
+ * Implementation of ike_sa_t.initiate.
+ */
+static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
+{
+       return initiate_with_reqid(this, child_cfg, 0);
+}
+
+/**
  * Implementation of ike_sa_t.acquire.
  */
 static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
-{      /* FIXME: IKE-ME */
+{
        child_cfg_t *child_cfg;
        iterator_t *iterator;
        child_sa_t *current, *child_sa = NULL;
-       task_t *task;
-       child_create_t *child_create;
        
        if (this->state == IKE_DELETING)
        {
@@ -1164,36 +1170,10 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
                return FAILED;
        }
        
-       
-       if (this->state == IKE_CREATED)
-       {
-               task = (task_t*)ike_init_create(&this->public, TRUE, NULL);
-               this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_natd_create(&this->public, TRUE);
-               this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
-               this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_auth_create(&this->public, TRUE);
-               this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_cert_post_create(&this->public, TRUE);
-               this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_config_create(&this->public, TRUE);
-               this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
-               this->task_manager->queue_task(this->task_manager, task);
-               if (this->peer_cfg->use_mobike(this->peer_cfg))
-               {
-                       task = (task_t*)ike_mobike_create(&this->public, TRUE);
-                       this->task_manager->queue_task(this->task_manager, task);
-               }
-       }
-       
        child_cfg = child_sa->get_config(child_sa);
-       child_create = child_create_create(&this->public, child_cfg);
-       child_create->use_reqid(child_create, reqid);
-       this->task_manager->queue_task(this->task_manager, (task_t*)child_create);
+       child_cfg->get_ref(child_cfg);
        
-       return this->task_manager->initiate(this->task_manager);
+       return initiate_with_reqid(this, child_cfg, reqid);
 }
 
 /**
@@ -2472,7 +2452,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->public.set_server_reflexive_host = (void (*)(ike_sa_t*,host_t*)) set_server_reflexive_host;
        this->public.get_connect_id = (chunk_t (*)(ike_sa_t*)) get_connect_id;
        this->public.initiate_mediation = (status_t (*)(ike_sa_t*,peer_cfg_t*)) initiate_mediation;
-       this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,linked_list_t*,chunk_t)) initiate_mediated;
+       this->public.initiate_mediated = (status_t (*)(ike_sa_t*,host_t*,host_t*,chunk_t)) initiate_mediated;
        this->public.relay = (status_t (*)(ike_sa_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool)) relay;
        this->public.callback = (status_t (*)(ike_sa_t*,identification_t*)) callback;
        this->public.respond = (status_t (*)(ike_sa_t*,identification_t*,chunk_t)) respond;
index e290c5b..af25f27 100644 (file)
@@ -484,14 +484,13 @@ struct ike_sa_t {
         * 
         * @param me                            local endpoint (gets cloned)
         * @param other                         remote endpoint (gets cloned)
-        * @param childs                        linked list of child_cfg_t of CHILD_SAs (gets cloned)
         * @param connect_id            connect ID (gets cloned)
         * @return                              
         *                                                      - SUCCESS if initialization started
         *                                                      - DESTROY_ME if initialization failed
         */
        status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other,
-                       linked_list_t *childs, chunk_t connect_id);
+                       chunk_t connect_id);
        
        /**
         * Relay data from one peer to another (i.e. initiate a