- added function create_and_checkout to the ike_sa_manager_t
authorJan Hutter <jhutter@hsr.ch>
Thu, 24 Nov 2005 16:57:53 +0000 (16:57 -0000)
committerJan Hutter <jhutter@hsr.ch>
Thu, 24 Nov 2005 16:57:53 +0000 (16:57 -0000)
Source/charon/sa/ike_sa_manager.c
Source/charon/sa/ike_sa_manager.h
Source/charon/threads/thread_pool.c

index 31bc74a..8348dae 100644 (file)
@@ -363,7 +363,73 @@ static status_t get_next_spi(private_ike_sa_manager_t *this, u_int64_t *spi)
 }
 
 /**
- * @see ike_sa_manager_s.checkout_ike_sa
+ * Implementation of ike_sa_manager.create_and_checkout.
+ */
+static status_t create_and_checkout(private_ike_sa_manager_t *this,ike_sa_t **ike_sa)
+{
+       status_t retval;
+       u_int64_t initiator_spi;
+       ike_sa_entry_t *new_ike_sa_entry;
+       ike_sa_id_t *new_ike_sa_id;
+
+       retval = this->get_next_spi(this, &initiator_spi);
+       if (retval == SUCCESS)
+       {
+               new_ike_sa_id =         ike_sa_id_create(0, 0, TRUE);
+               if (new_ike_sa_id != NULL)
+               {
+                       new_ike_sa_id->set_initiator_spi(new_ike_sa_id, initiator_spi);
+       
+                       /* create entry */
+                       new_ike_sa_entry = ike_sa_entry_create(new_ike_sa_id);
+                       new_ike_sa_id->destroy(new_ike_sa_id);
+                       if (new_ike_sa_entry != NULL)
+                       { 
+                               /* each access is locked */
+                               pthread_mutex_lock(&(this->mutex));
+                               
+                               retval = this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
+       
+                               if (retval == SUCCESS)
+                               {
+                                       /* check ike_sa out */
+                                       this->logger->log(this->logger,CONTROL | MORE ,"New IKE_SA created and added to list of known IKE_SA's");
+                                       new_ike_sa_entry->checked_out = TRUE;
+                                       *ike_sa = new_ike_sa_entry->ike_sa;
+                                       /* DON'T use return, we must unlock the mutex! */
+                               }
+                               else
+                               {
+                                       /* ike_sa_entry could not be added to list*/
+                                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry_t could not be added to list");
+                               }
+                               pthread_mutex_unlock(&(this->mutex));
+                       }
+                       else
+                       {
+                               /* new ike_sa_entry could not be created */
+                               this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry_t could not be created");       
+                               retval = OUT_OF_RES;
+                       }
+               }
+               else
+               {
+                       /* new ike_sa_id could not be created */
+                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_id_t could not be created");  
+                       retval = OUT_OF_RES;
+               }
+       }
+       else
+       {
+               /* next SPI could not be created */
+               this->logger->log(this->logger,ERROR,"Fatal error: Next SPI could not be created");
+       }
+
+       return retval;
+}
+
+/**
+ * Implementation of ike_sa_manager.checkout.
  */
 static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_t **ike_sa)
 {
@@ -480,6 +546,7 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id,
                        {
                                /* new ike_sa_entry could not be created */
                                this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be created");                 
+                               retval = OUT_OF_RES;
                        }
                }
                else
@@ -488,55 +555,6 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id,
                }
                
        }
-       else if (!initiator_spi_set && !responder_spi_set)
-       {
-               /* creation of an IKE_SA from local site,
-                * we are the initiator!
-                */
-               u_int64_t initiator_spi;
-               ike_sa_entry_t *new_ike_sa_entry;
-               
-               retval = this->get_next_spi(this, &initiator_spi);
-               if (retval == SUCCESS)
-               {
-                       /* we also set arguments SPI, so its still valid */
-                       ike_sa_id->set_initiator_spi(ike_sa_id, initiator_spi);
-
-                       /* create entry */
-                       new_ike_sa_entry = ike_sa_entry_create(ike_sa_id);
-                       if (new_ike_sa_entry != NULL)
-                       { 
-                               retval = this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
-
-                               if (retval == SUCCESS)
-                               {
-                                       /* check ike_sa out */
-                                       this->logger->log(this->logger,CONTROL | MORE ,"New IKE_SA created and added to list of known IKE_SA's");
-                                       new_ike_sa_entry->checked_out = TRUE;
-                                       *ike_sa = new_ike_sa_entry->ike_sa;
-                       
-                                       /* DON'T use return, we must unlock the mutex! */
-                               }
-                               else
-                               {
-                                       /* ike_sa_entry could not be added to list*/
-                                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be added to list");
-                               }               
-                       }
-                       else
-                       {
-                               /* new ike_sa_entry could not be created */
-                               this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be created"); 
-                       }
-               }
-               else
-               {
-                       /* next SPI could not be created */
-                       this->logger->log(this->logger,ERROR,"Fatal error: Next SPI could not be created");
-               }
-
-
-       }
        else
        {
                /* responder set, initiator not: here is something seriously wrong! */
@@ -756,6 +774,7 @@ ike_sa_manager_t *ike_sa_manager_create()
 
        /* assign public functions */
        this->public.destroy = (status_t(*)(ike_sa_manager_t*))destroy;
+       this->public.create_and_checkout = (status_t(*)(ike_sa_manager_t*, ike_sa_t **sa))create_and_checkout;
        this->public.checkout = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t *sa_id, ike_sa_t **sa))checkout;
        this->public.checkin = (status_t(*)(ike_sa_manager_t*, ike_sa_t *sa))checkin;
        this->public.delete = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t *sa_id))delete;
index 1481ebb..4ef1bf7 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * @file ike_sa_manager.h
  * 
- * @brief Central point for managing IKE-SAs (creation, locking, deleting...)
+ * @brief Interface of ike_sa_manager_t.
  * 
  */
 
@@ -33,7 +33,7 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
  * @brief The IKE_SA-Manager manages the IKE_SAs ;-).
  *
  * To avoid access from multiple threads, IKE_SAs must be checked out from
- * the manager, and checked back in after usage. 
+ * the manager, and checked in after usage. 
  * The manager also handles deletion of SAs.
  *
  * @todo checking of double-checkouts from the same threads would be nice.
@@ -46,7 +46,6 @@ struct ike_sa_manager_t {
         * 
         * Checks out a SA by its ID. An SA will be created, when:
         * - Responder SPI is not set (when received an IKE_SA_INIT from initiator)
-        * - Both SPIs are not set (for initiating IKE_SA_INIT)
         * Management of SPIs is the managers job, he will set it.
         * This function blocks until SA is available for checkout.
         * 
@@ -62,16 +61,34 @@ struct ike_sa_manager_t {
         *                                                      - OUT_OF_RES
         */
        status_t (*checkout) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *sa_id, ike_sa_t **ike_sa);
+       
+       /**
+        * @brief Create and checkout an IKE_SA as original initator.
+        * 
+        * Creates and checks out a SA as initiator. An SA will be created, when:
+        * Management of SPIs is the managers job, he will set it.
+        * 
+        * @warning checking out two times without checking in will
+        * result in a deadlock!
+        * 
+        * @param ike_sa_manager        the manager object
+        * @param ike_sa[out]           checked out SA
+        * @returns                                     
+        *                                                      - SUCCESS if checkout successful
+        *                                                      - OUT_OF_RES
+        */
+       status_t (*create_and_checkout) (ike_sa_manager_t* ike_sa_manager,ike_sa_t **ike_sa);
+       
        /**
         * @brief Checkin the SA after usage
         * 
-        * @warning the SA pointer MUST NOT be used after checkin! The SA must be checked
-        * out again!
+        * @warning the SA pointer MUST NOT be used after checkin! 
+        * The SA must be checked out again!
         *  
         * @param ike_sa_manager        the manager object
         * @param ike_sa_id[in/out]     the SA identifier, will be updated
         * @param ike_sa[out]           checked out SA
-        * @returns                             SUCCESS if checked in
+        * @returns                                     SUCCESS if checked in
         *                                                      NOT_FOUND when not found (shouldn't happen!)
         */
        status_t (*checkin) (ike_sa_manager_t* ike_sa_manager, ike_sa_t *ike_sa);
@@ -83,7 +100,7 @@ struct ike_sa_manager_t {
         *  
         * @param ike_sa_manager        the manager object
         * @param ike_sa_id[in/out]     the SA identifier
-        * @returns                             SUCCESS if found
+        * @returns                                     SUCCESS if found
         *                                                      NOT_FOUND when no such SA is available
         */
        status_t (*delete) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *ike_sa_id);
index 7cf802b..1ed3a20 100644 (file)
@@ -192,27 +192,14 @@ static void job_processing(private_thread_pool_t *this)
                                 * - call initiate_connection on this sa
                                 */
                                initiate_ike_sa_job_t *initiate_job;
-                               ike_sa_id_t *ike_sa_id;
                                ike_sa_t *ike_sa;
                                status_t status;
                                
                                initiate_job = (initiate_ike_sa_job_t *)job;                    
+                                       
+                               this->worker_logger->log(this->worker_logger, CONTROL|MOST, "create and checking out IKE SA");
                                
-                               ike_sa_id = ike_sa_id_create(0, 0, TRUE);
-                               if (ike_sa_id == NULL)
-                               {
-                                       this->worker_logger->log(this->worker_logger, ERROR, "%s by creating ike_sa_id_t, job rejected.", 
-                                                                               mapping_find(status_m, status));
-                                       break;
-                               }
-                               
-                               this->worker_logger->log(this->worker_logger, CONTROL|MOST, "checking out IKE SA %lld:%lld, role %s", 
-                                                                       ike_sa_id->get_initiator_spi(ike_sa_id),
-                                                                       ike_sa_id->get_responder_spi(ike_sa_id),
-                                                                       ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder");
-                               
-                               status = global_ike_sa_manager->checkout(global_ike_sa_manager, ike_sa_id, &ike_sa);
-                               ike_sa_id->destroy(ike_sa_id);
+                               status = global_ike_sa_manager->create_and_checkout(global_ike_sa_manager, &ike_sa);
                                if (status != SUCCESS)
                                {
                                        this->worker_logger->log(this->worker_logger, ERROR, "%s by checking out new IKE_SA, job rejected.",