reuse an existing IKE_SA to set up additional CHILD_SAs
authorMartin Willi <martin@strongswan.org>
Thu, 20 Jul 2006 14:57:49 +0000 (14:57 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 20 Jul 2006 14:57:49 +0000 (14:57 -0000)
21 files changed:
src/charon/Makefile.am
src/charon/queues/jobs/delete_half_open_ike_sa_job.c
src/charon/queues/jobs/incoming_packet_job.c
src/charon/queues/jobs/initiate_ike_sa_job.c [deleted file]
src/charon/queues/jobs/initiate_ike_sa_job.h [deleted file]
src/charon/queues/jobs/initiate_job.c [new file with mode: 0644]
src/charon/queues/jobs/initiate_job.h [new file with mode: 0644]
src/charon/queues/jobs/job.c
src/charon/queues/jobs/job.h
src/charon/queues/jobs/retransmit_request_job.c
src/charon/queues/jobs/send_dpd_job.c
src/charon/queues/jobs/send_keepalive_job.c
src/charon/sa/child_sa.c
src/charon/sa/ike_sa.c
src/charon/sa/ike_sa_manager.c
src/charon/sa/ike_sa_manager.h
src/charon/sa/transactions/ike_auth.c
src/charon/sa/transactions/ike_sa_init.c
src/charon/threads/stroke_interface.c
src/libstrongswan/crypto/crypters/crypter.c
src/libstrongswan/crypto/signers/signer.c

index a0f8541..2a8735f 100644 (file)
@@ -38,10 +38,10 @@ encoding/payloads/vendor_id_payload.h encoding/payloads/proposal_substructure.c
 encoding/parser.h encoding/message.c encoding/generator.c encoding/message.h encoding/generator.h \
 encoding/parser.c daemon.c daemon.h network/packet.c \
 network/interfaces.c network/interfaces.h network/socket.c network/packet.h network/socket.h queues/jobs/job.h queues/jobs/job.c \
-queues/jobs/delete_established_ike_sa_job.c queues/jobs/retransmit_request_job.h queues/jobs/initiate_ike_sa_job.h \
+queues/jobs/delete_established_ike_sa_job.c queues/jobs/retransmit_request_job.h queues/jobs/initiate_job.h \
 queues/jobs/incoming_packet_job.c queues/jobs/delete_half_open_ike_sa_job.c \
 queues/jobs/delete_established_ike_sa_job.h queues/jobs/delete_half_open_ike_sa_job.h \
-queues/jobs/incoming_packet_job.h queues/jobs/retransmit_request_job.c queues/jobs/initiate_ike_sa_job.c \
+queues/jobs/incoming_packet_job.h queues/jobs/retransmit_request_job.c queues/jobs/initiate_job.c \
 queues/jobs/send_keepalive_job.c queues/jobs/send_keepalive_job.h \
 queues/jobs/rekey_child_sa_job.c queues/jobs/rekey_child_sa_job.h \
 queues/jobs/delete_child_sa_job.c queues/jobs/delete_child_sa_job.h \
index 4e6fb08..7b79480 100644 (file)
@@ -62,9 +62,10 @@ static status_t execute(private_delete_half_open_ike_sa_job_t *this)
 {
        ike_sa_t *ike_sa;
        
-       if (charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id, 
-                                                                                &ike_sa) != SUCCESS)
+       ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id);
+       if (ike_sa == NULL)
        {
+               /* hm, somebody was faster ;-) */
                return DESTROY_ME;
        }
        
index e24f625..d966103 100644 (file)
@@ -142,8 +142,8 @@ static status_t execute(private_incoming_packet_job_t *this)
        ike_sa_id = message->get_ike_sa_id(message);
        ike_sa_id = ike_sa_id->clone(ike_sa_id);
        ike_sa_id->switch_initiator(ike_sa_id);
-       status = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id, &ike_sa);
-       if (status != SUCCESS)
+       ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id);
+       if (ike_sa == NULL)
        {
                this->logger->log(this->logger, ERROR,
                                                  "received packet with SPIs %llx:%llx, but no such IKE_SA",
@@ -158,11 +158,11 @@ static status_t execute(private_incoming_packet_job_t *this)
        status = ike_sa->process_message(ike_sa, message);
        if (status == DESTROY_ME)
        {
-               status = charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+               charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
        }
        else
        {
-               status = charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+               charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
        }
        ike_sa_id->destroy(ike_sa_id);
        message->destroy(message);
diff --git a/src/charon/queues/jobs/initiate_ike_sa_job.c b/src/charon/queues/jobs/initiate_ike_sa_job.c
deleted file mode 100644 (file)
index 38108ca..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file initiate_ike_sa_job.c
- * 
- * @brief Implementation of initiate_ike_sa_job_t.
- * 
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-
-#include <stdlib.h>
-
-#include "initiate_ike_sa_job.h"
-
-#include <daemon.h>
-#include <queues/jobs/delete_half_open_ike_sa_job.h>
-
-typedef struct private_initiate_ike_sa_job_t private_initiate_ike_sa_job_t;
-
-/**
- * Private data of an initiate_ike_sa_job_t Object
- */
-struct private_initiate_ike_sa_job_t {
-       /**
-        * public initiate_ike_sa_job_t interface
-        */
-       initiate_ike_sa_job_t public;
-       
-       /**
-        * associated connection to initiate
-        */
-       connection_t *connection;
-       
-       /**
-        * associated policy to initiate
-        */
-       policy_t *policy;
-       
-       /**
-        * logger
-        */
-       logger_t *logger;
-};
-
-/**
- * Implements initiate_ike_sa_job_t.get_type.
- */
-static job_type_t get_type(private_initiate_ike_sa_job_t *this)
-{
-       return INITIATE_IKE_SA;
-}
-
-/**
- * Implementation of job_t.execute.
- */
-static status_t execute(private_initiate_ike_sa_job_t *this)
-{
-       /* Initiatie an IKE_SA:
-        * - is defined by a connection
-        * - create an empty IKE_SA via manager
-        * - call initiate() on this IKE_SA
-        */
-       ike_sa_t *ike_sa;
-       status_t status;
-       
-       this->logger->log(this->logger, CONTROL|LEVEL2, "Creating and checking out IKE SA");
-       charon->ike_sa_manager->create_and_checkout(charon->ike_sa_manager, &ike_sa);
-       
-       this->connection->get_ref(this->connection);
-       this->policy->get_ref(this->policy);
-       status = ike_sa->initiate(ike_sa, this->connection, this->policy);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR,
-                                                 "initiation returned %s, going to delete IKE_SA.",
-                                                 mapping_find(status_m, status));
-               charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
-               return DESTROY_ME;
-       }
-       
-       charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
-       return DESTROY_ME;
-}
-
-/**
- * Implements job_t.destroy.
- */
-static void destroy(private_initiate_ike_sa_job_t *this)
-{
-       this->connection->destroy(this->connection);
-       this->policy->destroy(this->policy);
-       free(this);
-}
-
-/*
- * Described in header
- */
-initiate_ike_sa_job_t *initiate_ike_sa_job_create(connection_t *connection, policy_t *policy)
-{
-       private_initiate_ike_sa_job_t *this = malloc_thing(private_initiate_ike_sa_job_t);
-       
-       /* interface functions */
-       this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
-       this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
-       this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
-       
-       /* private variables */
-       this->connection = connection;
-       this->policy = policy;
-       this->logger = logger_manager->get_logger(logger_manager, WORKER);
-       
-       return &this->public;
-}
diff --git a/src/charon/queues/jobs/initiate_ike_sa_job.h b/src/charon/queues/jobs/initiate_ike_sa_job.h
deleted file mode 100644 (file)
index c119cf3..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file initiate_ike_sa_job.h
- * 
- * @brief Interface of initiate_ike_sa_job_t.
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef INITIATE_IKE_SA_JOB_H_
-#define INITIATE_IKE_SA_JOB_H_
-
-#include <types.h>
-#include <queues/jobs/job.h>
-#include <config/connections/connection.h>
-#include <config/policies/policy.h>
-
-
-typedef struct initiate_ike_sa_job_t initiate_ike_sa_job_t;
-
-/**
- * @brief Class representing an INITIATE_IKE_SA Job.
- * 
- * This job is created if an IKE_SA should be iniated.
- * 
- * @b Constructors:
- * - initiate_ike_sa_job_create()
- * 
- * @ingroup jobs
- */
-struct initiate_ike_sa_job_t {
-       /**
-        * implements job_t interface
-        */
-       job_t job_interface;
-};
-
-/**
- * @brief Creates a job of type INITIATE_IKE_SA.
- * 
- * @param connection   connection_t to initializes
- * @param policy               policy to set up
- * @return                             initiate_ike_sa_job_t object
- * 
- * @ingroup jobs
- */
-initiate_ike_sa_job_t *initiate_ike_sa_job_create(connection_t *connection,
-                                                                                                 policy_t *policy);
-
-#endif /*INITIATE_IKE_SA_JOB_H_*/
diff --git a/src/charon/queues/jobs/initiate_job.c b/src/charon/queues/jobs/initiate_job.c
new file mode 100644 (file)
index 0000000..4367048
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * @file initiate_job.c
+ * 
+ * @brief Implementation of initiate_job_t.
+ * 
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+
+#include <stdlib.h>
+
+#include "initiate_job.h"
+
+#include <daemon.h>
+#include <queues/jobs/delete_half_open_ike_sa_job.h>
+
+typedef struct private_initiate_job_t private_initiate_job_t;
+
+/**
+ * Private data of an initiate_job_t Object
+ */
+struct private_initiate_job_t {
+       /**
+        * public initiate_job_t interface
+        */
+       initiate_job_t public;
+       
+       /**
+        * associated connection to initiate
+        */
+       connection_t *connection;
+       
+       /**
+        * associated policy to initiate
+        */
+       policy_t *policy;
+       
+       /**
+        * logger
+        */
+       logger_t *logger;
+};
+
+/**
+ * Implements initiate_job_t.get_type.
+ */
+static job_type_t get_type(private_initiate_job_t *this)
+{
+       return INITIATE;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_initiate_job_t *this)
+{
+       ike_sa_t *ike_sa;
+       
+       this->logger->log(this->logger, CONTROL|LEVEL2, "getting an IKE SA");
+       ike_sa = charon->ike_sa_manager->checkout_by_ids(charon->ike_sa_manager,
+                                                                               this->policy->get_my_id(this->policy),
+                                                                               this->policy->get_other_id(this->policy));
+       
+       this->connection->get_ref(this->connection);
+       this->policy->get_ref(this->policy);
+       if (ike_sa->initiate(ike_sa, this->connection, this->policy) != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR,
+                                                 "initiation failed, going to delete IKE_SA");
+               charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+               return DESTROY_ME;
+       }
+       
+       charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+       return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_initiate_job_t *this)
+{
+       this->connection->destroy(this->connection);
+       this->policy->destroy(this->policy);
+       free(this);
+}
+
+/*
+ * Described in header
+ */
+initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy)
+{
+       private_initiate_job_t *this = malloc_thing(private_initiate_job_t);
+       
+       /* interface functions */
+       this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+       this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+       this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
+       
+       /* private variables */
+       this->connection = connection;
+       this->policy = policy;
+       this->logger = logger_manager->get_logger(logger_manager, WORKER);
+       
+       return &this->public;
+}
diff --git a/src/charon/queues/jobs/initiate_job.h b/src/charon/queues/jobs/initiate_job.h
new file mode 100644 (file)
index 0000000..cb6acf3
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * @file initiate_job.h
+ * 
+ * @brief Interface of initiate_job_t.
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef INITIATE_IKE_SA_JOB_H_
+#define INITIATE_IKE_SA_JOB_H_
+
+#include <types.h>
+#include <queues/jobs/job.h>
+#include <config/connections/connection.h>
+#include <config/policies/policy.h>
+
+
+typedef struct initiate_job_t initiate_job_t;
+
+/**
+ * @brief Class representing an INITIATE_IKE_SA Job.
+ * 
+ * This job is created if an IKE_SA should be iniated.
+ * 
+ * @b Constructors:
+ * - initiate_job_create()
+ * 
+ * @ingroup jobs
+ */
+struct initiate_job_t {
+       /**
+        * implements job_t interface
+        */
+       job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type INITIATE_IKE_SA.
+ * 
+ * @param connection   connection_t to initialize
+ * @param policy               policy to set up
+ * @return                             initiate_job_t object
+ * 
+ * @ingroup jobs
+ */
+initiate_job_t *initiate_job_create(connection_t *connection,
+                                                                                                 policy_t *policy);
+
+#endif /*INITIATE_IKE_SA_JOB_H_*/
index c870baf..1808a3f 100644 (file)
@@ -28,7 +28,7 @@
 mapping_t job_type_m[] = {
        {INCOMING_PACKET, "INCOMING_PACKET"},
        {RETRANSMIT_REQUEST, "RETRANSMIT_REQUEST"},
-       {INITIATE_IKE_SA, "INITIATE_IKE_SA"},
+       {INITIATE, "INITIATE"},
        {DELETE_HALF_OPEN_IKE_SA, "DELETE_HALF_OPEN_IKE_SA"},
        {DELETE_ESTABLISHED_IKE_SA, "DELETE_ESTABLISHED_IKE_SA"},
        {SEND_KEEPALIVE, "SEND_KEEPALIVE"},
index 57fc8a8..6063a21 100644 (file)
@@ -51,11 +51,11 @@ enum job_type_t {
        RETRANSMIT_REQUEST,
        
        /** 
-        * Establish an ike sa as initiator.
+        * Set up a CHILD_SA, optional with an IKE_SA.
         * 
-        * Job is implemented in class initiate_ike_sa_job_t
+        * Job is implemented in class initiate_job_t
         */
-       INITIATE_IKE_SA,
+       INITIATE,
        
        /** 
         * Delete an ike sa which is still not established.
index f3b75d2..6a533ec 100644 (file)
@@ -66,10 +66,9 @@ static job_type_t get_type(private_retransmit_request_job_t *this)
 static status_t execute(private_retransmit_request_job_t *this)
 {
        ike_sa_t *ike_sa;
-       status_t status;
                                
-       status = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id, &ike_sa);
-       if (status != SUCCESS)
+       ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id);
+       if (ike_sa == NULL)
        {
                this->logger->log(this->logger, ERROR|LEVEL1, 
                                                  "IKE SA could not be checked out. Already deleted?");
index 56b1fac..b36593b 100644 (file)
@@ -65,16 +65,15 @@ static job_type_t get_type(private_send_dpd_job_t *this)
 static status_t execute(private_send_dpd_job_t *this)
 {
        ike_sa_t *ike_sa;
-       status_t status;
        
-       status = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
-                                                                                         this->ike_sa_id, &ike_sa);
-       if (status != SUCCESS)
+       ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+                                                                                         this->ike_sa_id);
+       if (ike_sa == NULL)
        {
                return DESTROY_ME;
        }
-       status = ike_sa->send_dpd(ike_sa);
-       if (status == DESTROY_ME)
+       
+       if (ike_sa->send_dpd(ike_sa) == DESTROY_ME)
        {
                charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
        }
index 6c7dceb..0a305fa 100644 (file)
@@ -65,11 +65,10 @@ static job_type_t get_type(private_send_keepalive_job_t *this)
 static status_t execute(private_send_keepalive_job_t *this)
 {
        ike_sa_t *ike_sa;
-       status_t status;
        
-       status = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
-                                                                                         this->ike_sa_id, &ike_sa);
-       if (status != SUCCESS)
+       ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+                                                                                         this->ike_sa_id);
+       if (ike_sa == NULL)
        {
                return DESTROY_ME;
        }
index 38b4fa8..5805993 100644 (file)
@@ -111,6 +111,16 @@ struct private_child_sa_t {
        u_int32_t reqid;
        
        /**
+        * encryption algorithm used for this SA
+        */
+       algorithm_t encryption;
+       
+       /**
+        * integrity protection algorithm used for this SA
+        */
+       algorithm_t integrity;
+       
+       /**
         * time, on which SA was installed
         */
        time_t install_time;
@@ -358,6 +368,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
                                                                                          enc_algo, int_algo,
                                                                                          prf_plus, natt, mine);
        
+       this->encryption = *enc_algo;
+       this->integrity = *int_algo;
        this->install_time = time(NULL);
        
        return status;
@@ -574,6 +586,8 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
        char use_in_str[12] = "unused";
        char use_out_str[12] = "unused";
        char rekey_str[12] = "disabled";
+       char enc_str[32] = "";
+       char int_str[32] = "";
        u_int32_t use_in, use_out, use_fwd, now, rekeying;
        status_t status;
        
@@ -604,10 +618,38 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
                snprintf(rekey_str, sizeof(rekey_str), "%ds", (int)rekeying);
        }
        
+       /* algorithms used */
+       if (this->protocol == PROTO_ESP)
+       {
+               if (this->encryption.key_size)
+               {
+                       snprintf(enc_str, sizeof(enc_str), "%s-%d,", 
+                                       mapping_find(encryption_algorithm_m, this->encryption.algorithm),
+                                       this->encryption.key_size);
+               }
+               else
+               {
+                       snprintf(enc_str, sizeof(enc_str), "%s,", 
+                                       mapping_find(encryption_algorithm_m, this->encryption.algorithm));
+               }
+       }
+       if (this->integrity.key_size)
+       {
+               snprintf(int_str, sizeof(int_str), "%s-%d", 
+                                mapping_find(integrity_algorithm_m, this->integrity.algorithm),
+                                this->integrity.key_size);
+       }
+       else
+       {
+               snprintf(int_str, sizeof(int_str), "%s", 
+                                mapping_find(integrity_algorithm_m, this->integrity.algorithm));
+       }
+       
        logger->log(logger, CONTROL|LEVEL1,
-                               "  \"%s\":   using %s, SPIs (in/out): 0x%x/0x%x, reqid: %d",
+                               "  \"%s\":   %s (%s%s), SPIs (in/out): 0x%x/0x%x, reqid: %d",
                                name,
                                this->protocol == PROTO_ESP ? "ESP" : "AH",
+                               enc_str, int_str,
                                htonl(this->me.spi), htonl(this->other.spi),
                                this->reqid);
        logger->log(logger, CONTROL|LEVEL1,
@@ -898,6 +940,10 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
        this->state = CHILD_CREATED;
        /* reuse old reqid if we are rekeying an existing CHILD_SA */
        this->reqid = rekey ? rekey : ++reqid;
+       this->encryption.algorithm = ENCR_UNDEFINED;
+       this->encryption.key_size = 0;
+       this->integrity.algorithm = AUTH_UNDEFINED;
+       this->encryption.key_size = 0;
        this->policies = linked_list_create();
        this->my_ts = linked_list_create();
        this->other_ts = linked_list_create();
index 569d879..bfffdad 100644 (file)
@@ -782,23 +782,53 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
 static status_t initiate(private_ike_sa_t *this,
                                                 connection_t *connection, policy_t *policy)
 {
-       ike_sa_init_t *ike_sa_init;
-       
-       set_name(this, connection->get_name(connection));
-       
-       /* apply hosts from connection */
-       this->my_host = connection->get_my_host(connection);
-       this->my_host = this->my_host->clone(this->my_host);
-       this->other_host = connection->get_other_host(connection);
-       this->other_host = this->other_host->clone(this->other_host);
-       
-       this->message_id_out = 1;
-       ike_sa_init = ike_sa_init_create(&this->public);
-       ike_sa_init->set_config(ike_sa_init, connection, policy);
-       return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
+       switch (this->state)
+       {
+               case IKE_CREATED:
+               {
+                       /* in state CREATED, we must do the ike_sa_init
+                        * and ike_auth transactions. Along with these,
+                        * a CHILD_SA with the supplied policy is set up.
+                        */
+                       ike_sa_init_t *ike_sa_init;
+                       
+                       set_name(this, connection->get_name(connection));
+                       this->my_host = connection->get_my_host(connection);
+                       this->my_host = this->my_host->clone(this->my_host);
+                       this->other_host = connection->get_other_host(connection);
+                       this->other_host = this->other_host->clone(this->other_host);
+                       
+                       this->message_id_out = 1;
+                       ike_sa_init = ike_sa_init_create(&this->public);
+                       ike_sa_init->set_config(ike_sa_init, connection, policy);
+                       return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
+               }
+               case IKE_DELETING:
+               {
+                       /* if we are in DELETING, we deny set up of a policy. */
+                       policy->destroy(policy);
+                       connection->destroy(connection);
+                       return FAILED;
+               }
+               case IKE_CONNECTING:
+               case IKE_ESTABLISHED:
+               {
+                       /* if we are ESTABLISHED or CONNECTING,we queue the 
+                        * transaction to create the CHILD_SA. It gets processed
+                        * when the IKE_SA is ready to do so. We don't need the
+                        * connection, as the IKE_SA is already established/establishing.
+                        */
+                       create_child_sa_t *create_child;
+                       
+                       connection->destroy(connection);
+                       create_child = create_child_sa_create(&this->public);
+                       create_child->set_policy(create_child, policy);
+                       return queue_transaction(this, (transaction_t*)create_child, FALSE);
+               }
+       }
+       return FAILED;
 }
 
-
 /**
  * Implementation of ike_sa_t.acquire.
  */
@@ -990,6 +1020,7 @@ static identification_t* get_my_id(private_ike_sa_t *this)
  */
 static void set_my_id(private_ike_sa_t *this, identification_t *me)
 {
+       DESTROY_IF(this->my_id);
        this->my_id = me;
 }
 
@@ -1006,6 +1037,7 @@ static identification_t* get_other_id(private_ike_sa_t *this)
  */
 static void set_other_id(private_ike_sa_t *this, identification_t *other)
 {
+       DESTROY_IF(this->other_id);
        this->other_id = other;
 }
 
index b0822ac..c8e4d71 100644 (file)
@@ -333,6 +333,34 @@ static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *ent
        return status;  
 }
 
+/**
+ * Wait until no other thread is using an IKE_SA, return FALSE if entry not
+ * acquireable
+ */
+static bool wait_for_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *entry)
+{
+       if (entry->driveout_new_threads)
+       {
+               /* we are not allowed to get this */
+               return FALSE;
+       }
+       while (entry->checked_out && !entry->driveout_waiting_threads)  
+       {
+               /* so wait until we can get it for us.
+               * we register us as waiting. */
+               entry->waiting_threads++;
+               pthread_cond_wait(&(entry->condvar), &(this->mutex));
+               entry->waiting_threads--;
+       }
+       /* hm, a deletion request forbids us to get this SA, get next one */
+       if (entry->driveout_waiting_threads)
+       {
+               /* we must signal here, others may be waiting on it, too */
+               pthread_cond_signal(&(entry->condvar));
+               return FALSE;
+       }
+       return TRUE;
+}
 
 /**
  * Implementation of private_ike_sa_manager_t.get_next_spi.
@@ -349,48 +377,92 @@ static u_int64_t get_next_spi(private_ike_sa_manager_t *this)
 /**
  * Implementation of of ike_sa_manager.create_and_checkout.
  */
-static void create_and_checkout(private_ike_sa_manager_t *this,ike_sa_t **ike_sa)
+static ike_sa_t* checkout_by_ids(private_ike_sa_manager_t *this,
+                                                                identification_t *my_id,
+                                                                identification_t *other_id)
 {
-       u_int64_t initiator_spi;
-       ike_sa_entry_t *new_ike_sa_entry;
-       ike_sa_id_t *new_ike_sa_id;
-
-       initiator_spi = this->get_next_spi(this);
-       new_ike_sa_id = ike_sa_id_create(0, 0, TRUE);
-       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);
-       this->logger->log(this->logger, CONTROL|LEVEL2,
-                                         "created IKE_SA %llx:%llx, role %s",
-                                         new_ike_sa_id->get_initiator_spi(new_ike_sa_id),
-                                         new_ike_sa_id->get_responder_spi(new_ike_sa_id),
-                                         new_ike_sa_id->is_initiator(new_ike_sa_id) ? "initiator" : "responder");
-       new_ike_sa_id->destroy(new_ike_sa_id);
-
-       /* each access is locked */
+       iterator_t *iterator;
+       ike_sa_t *ike_sa = NULL;
+       
        pthread_mutex_lock(&(this->mutex));
        
-       this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
-
-       /* check ike_sa out */
-       this->logger->log(this->logger, CONTROL|LEVEL1, 
-                                         "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;
-
+       iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE);
+       while (iterator->has_next(iterator))
+       {
+               ike_sa_entry_t *entry;
+               identification_t *found_my_id, *found_other_id;
+               int wc;
+               
+               iterator->current(iterator, (void**)&entry);
+               if (!wait_for_entry(this, entry))
+               {
+                       continue;
+               }
+               
+               found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
+               found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
+               
+               if (!found_my_id || !found_other_id)
+               {
+                       /* IKE_SA has no IDs yet, so we can't use it */
+                       continue;
+               }
+               
+               if (found_my_id->matches(found_my_id, my_id, &wc) &&
+                       found_other_id->matches(found_other_id, other_id, &wc))
+               {
+                       /* looks good, we take this one */
+                       this->logger->log(this->logger, CONTROL|LEVEL1, 
+                                                         "found an existing IKE_SA for IDs %s - %s",
+                                                         my_id->get_string(my_id), other_id->get_string(other_id));
+                       entry->checked_out = TRUE;
+                       ike_sa = entry->ike_sa;
+               }
+       }
+       iterator->destroy(iterator);
+       
+       if (!ike_sa)
+       {
+               u_int64_t initiator_spi;
+               ike_sa_entry_t *new_ike_sa_entry;
+               ike_sa_id_t *new_ike_sa_id;
+               
+               initiator_spi = this->get_next_spi(this);
+               new_ike_sa_id = ike_sa_id_create(0, 0, TRUE);
+               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);
+               this->logger->log(this->logger, CONTROL|LEVEL2,
+                                                 "created IKE_SA %llx:%llx, role %s",
+                                                 new_ike_sa_id->get_initiator_spi(new_ike_sa_id),
+                                                 new_ike_sa_id->get_responder_spi(new_ike_sa_id),
+                                                 new_ike_sa_id->is_initiator(new_ike_sa_id) ? "initiator" : "responder");
+               new_ike_sa_id->destroy(new_ike_sa_id);
+               
+               this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
+               
+               /* check ike_sa out */
+               this->logger->log(this->logger, CONTROL|LEVEL1, 
+                                                 "new IKE_SA created for IDs %s - %s",
+                                                 my_id->get_string(my_id), other_id->get_string(other_id));
+               new_ike_sa_entry->checked_out = TRUE;
+               ike_sa = new_ike_sa_entry->ike_sa;              
+       }
        pthread_mutex_unlock(&(this->mutex));
+       
+       return ike_sa;
 }
 
 /**
  * Implementation of 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)
+static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
 {
        bool responder_spi_set;
        bool initiator_spi_set;
        bool original_initiator;
-       status_t retval;
+       ike_sa_t *ike_sa = NULL;
        
        this->logger->log(this->logger, CONTROL|LEVEL2,
                                          "checkout IKE_SA %llx:%llx, role %s",
@@ -418,56 +490,25 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id,
                /* look for the entry */
                if (this->get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
                {
-                       /* can we give this ike_sa out to new requesters?*/
-                       if (entry->driveout_new_threads)
+                       if (wait_for_entry(this, entry))
                        {
-                               this->logger->log(this->logger, CONTROL|LEVEL1, 
-                                                                 "drive out new thread for existing IKE_SA");
-                               /* no we can't */
-                               retval = NOT_FOUND;
+                               this->logger->log(this->logger, CONTROL|LEVEL2, 
+                                                                 "IKE_SA successfully checked out");
+                               /* ok, this IKE_SA is finally ours */
+                               entry->checked_out = TRUE;
+                               ike_sa = entry->ike_sa;
                        }
                        else
                        {
-                               /* is this IKE_SA already checked out ?? 
-                                * are we welcome to get this SA ? */
-                               while (entry->checked_out && !entry->driveout_waiting_threads)  
-                               { 
-                                       /* so wait until we can get it for us.
-                                        * we register us as waiting.
-                                        */
-                                       entry->waiting_threads++;
-                                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
-                                       entry->waiting_threads--;
-                               }
-                               
-                               /* hm, a deletion request forbids us to get this SA, go home */
-                               if (entry->driveout_waiting_threads)
-                               {
-                                       /* we must signal here, others are interested that we leave */
-                                       pthread_cond_signal(&(entry->condvar));
-                                       this->logger->log(this->logger, CONTROL|LEVEL1, 
-                                                                         "drive out waiting thread for existing IKE_SA");
-                                       retval = NOT_FOUND;
-                               }
-                               else
-                               {
-                                       this->logger->log(this->logger, CONTROL|LEVEL2, 
-                                                                         "IKE SA successfully checked out");
-                                       /* ok, this IKE_SA is finally ours */
-                                       entry->checked_out = TRUE;
-                                       *ike_sa = entry->ike_sa;
-                                       /* DON'T use return, we must unlock the mutex! */
-                                       retval = SUCCESS; 
-                               }
+                               this->logger->log(this->logger, CONTROL|LEVEL2, 
+                                                                 "IKE_SA found, but not allowed to check it out");
                        }
                }
                else
                {
                        this->logger->log(this->logger, ERROR|LEVEL1, 
-                                                         "IKE SA not stored in known IKE_SA list");
+                                                         "IKE_SA not stored in list");
                        /* looks like there is no such IKE_SA, better luck next time... */
-                       /* DON'T use return, we must unlock the mutex! */
-                       retval = NOT_FOUND;
                }
        }
        else if ((initiator_spi_set && !responder_spi_set) && (!original_initiator))
@@ -496,23 +537,18 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id,
                
                /* check ike_sa out */
                this->logger->log(this->logger, CONTROL|LEVEL1,
-                                                 "IKE_SA added to list of known IKE_SA's");
+                                                 "IKE_SA added to list of known IKE_SAs");
                new_ike_sa_entry->checked_out = TRUE;
-               *ike_sa = new_ike_sa_entry->ike_sa;
-               
-               retval = SUCCESS;
+               ike_sa = new_ike_sa_entry->ike_sa;
        }
        else
        {
                /* responder set, initiator not: here is something seriously wrong! */
-               this->logger->log(this->logger, ERROR|LEVEL1, "invalid IKE_SA SPI's");
-               /* DON'T use return, we must unlock the mutex! */
-               retval = INVALID_ARG;
+               this->logger->log(this->logger, ERROR|LEVEL1, "invalid IKE_SA SPIs");
        }
        
        pthread_mutex_unlock(&(this->mutex));
-       /* OK, unlocked... */
-       return retval;
+       return ike_sa;
 }
 
 /**
@@ -533,34 +569,17 @@ static status_t checkout_by_child(private_ike_sa_manager_t *this,
                ike_sa_entry_t *entry;
                
                iterator->current(iterator, (void**)&entry);
-               if (entry->driveout_new_threads)
+               if (wait_for_entry(this, entry))
                {
-                       /* we are not allowed to get this, get next one */
-                       continue;
-               }
-               while (entry->checked_out && !entry->driveout_waiting_threads)  
-               {
-                       /* so wait until we can get it for us.
-                        * we register us as waiting. */
-                       entry->waiting_threads++;
-                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
-                       entry->waiting_threads--;
-               }
-               /* hm, a deletion request forbids us to get this SA, get next one */
-               if (entry->driveout_waiting_threads)
-               {
-                       /* we must signal here, others may be waiting on it, too */
-                       pthread_cond_signal(&(entry->condvar));
-                       continue;
-               }
-               /* ok, access is exclusive for us, check for child */
-               if (entry->ike_sa->get_child_sa(entry->ike_sa, protocol, spi, TRUE) != NULL)
-               {
-                       /* match */
-                       entry->checked_out = TRUE;
-                       *ike_sa = entry->ike_sa;
-                       status = SUCCESS;
-                       break;
+                       /* ok, access is exclusive for us, check for child */
+                       if (entry->ike_sa->get_child_sa(entry->ike_sa, protocol, spi, TRUE) != NULL)
+                       {
+                               /* match */
+                               entry->checked_out = TRUE;
+                               *ike_sa = entry->ike_sa;
+                               status = SUCCESS;
+                               break;
+                       }
                }
        }
        iterator->destroy(iterator);
@@ -638,9 +657,12 @@ static void log_status(private_ike_sa_manager_t* this, logger_t* logger, char* n
        while (iterator->has_next(iterator))
        {
                ike_sa_entry_t *entry;
-
+               
                iterator->current(iterator, (void**)&entry);
-               entry->ike_sa->log_status(entry->ike_sa, logger, name);
+               if (wait_for_entry(this, entry))
+               {
+                       entry->ike_sa->log_status(entry->ike_sa, logger, name);
+               }
        }
        iterator->destroy(iterator);
        
@@ -891,8 +913,8 @@ ike_sa_manager_t *ike_sa_manager_create()
 
        /* assign public functions */
        this->public.destroy = (void(*)(ike_sa_manager_t*))destroy;
-       this->public.create_and_checkout = (void(*)(ike_sa_manager_t*,ike_sa_t**))create_and_checkout;
-       this->public.checkout = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t*,ike_sa_t**))checkout;
+       this->public.checkout_by_ids = (ike_sa_t*(*)(ike_sa_manager_t*,identification_t*,identification_t*))checkout_by_ids;
+       this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout;
        this->public.checkout_by_child = (status_t(*)(ike_sa_manager_t*,protocol_id_t,u_int32_t,ike_sa_t**))checkout_by_child;
        this->public.get_ike_sa_list = (linked_list_t*(*)(ike_sa_manager_t*))get_ike_sa_list;
        this->public.get_ike_sa_list_by_name = (linked_list_t*(*)(ike_sa_manager_t*,const char*))get_ike_sa_list_by_name;
index 4c40939..1c8dbad 100644 (file)
@@ -52,8 +52,8 @@ struct ike_sa_manager_t {
        /**
         * @brief Checkout an IKE_SA, create it when necesarry.
         * 
-        * 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)
+        * Checks out a SA by its ID. An SA will be created, when the responder
+        * SPI is not set (when received an IKE_SA_INIT from initiator).
         * Management of SPIs is the managers job, he will set it.
         * This function blocks until SA is available for checkout.
         * 
@@ -62,24 +62,27 @@ struct ike_sa_manager_t {
         * 
         * @param this                          the manager object
         * @param[in/out] ike_sa_id     the SA identifier, will be updated
-        * @param[out] ike_sa           checked out SA
         * @returns                                     
-        *                                                      - SUCCESS if checkout successful
-        *                                                      - NOT_FOUND when no such SA is available
-        *                                                      - CREATED if a new IKE_SA got created
+        *                                                      - checked out IKE_SA if found
+        *                                                      - NULL, if no such IKE_SA available
         */
-       status_t (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id, ike_sa_t **ike_sa);
+       ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id);
        
        /**
-        * @brief Create and checkout an IKE_SA as original initator.
-        * 
-        * Creates and checks out a SA as initiator.
-        * Management of SPIs is the managers job, he will set it.
-        * 
+        * @brief Checkout an IKE_SA by two identifications.
+        *
+        * Allows the lookup of an IKE_SA by two user IDs. It returns the
+        * first found occurence, if there are multiple canddates. Supplied IDs
+        * may contain wildcards. If no IKE_SA is found, a new one is created.
+        *
         * @param this                          the manager object
-        * @param[out] ike_sa           checked out SA
+        * @param my_id                         ID used by us
+        * @param other_id                      ID used by other
+        * @return                                      checked out/created IKE_SA
         */
-       void (*create_and_checkout) (ike_sa_manager_t* this,ike_sa_t **ike_sa);
+       ike_sa_t* (*checkout_by_ids) (ike_sa_manager_t* this,
+                                                                 identification_t *my_id, 
+                                                                 identification_t *other_id);
        
        /**
         * @brief Check out an IKE_SA by protocol and SPI of one of its CHILD_SA.
@@ -102,7 +105,7 @@ struct ike_sa_manager_t {
        /**
         * @brief Get a list of all IKE_SA SAs currently set up.
         * 
-        * The resulting list with all IDs must be destroyd by 
+        * The resulting list with all IDs must be destroyed by 
         * the caller. There is no guarantee an ike_sa with the 
         * corrensponding ID really exists, since it may be deleted
         * in the meantime by another thread.
@@ -153,7 +156,7 @@ struct ike_sa_manager_t {
         * @brief Delete a SA, which was not checked out.
         *
         * If the state allows it, the IKE SA is destroyed immediately. If it is
-        * in the state ike_sa_established or further, a delete message
+        * in the state ESTABLSIHED, a delete message
         * is sent to the remote peer, which has to be acknowledged.
         *
         * @warning do not use this when the SA is already checked out, this will
index 2bf12f7..f423665 100644 (file)
@@ -228,7 +228,6 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
        {       /* build ID payload */
                my_id_payload = id_payload_create_from_identification(TRUE, my_id);
                request->add_payload(request, (payload_t*)my_id_payload);
-               this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
        }
        
        {       /* TODO: build certreq payload */
@@ -889,6 +888,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
                                                          configured_other_id->get_string(configured_other_id));
                        return DESTROY_ME;
                }
+               /* update other ID. It was already set, but may contain wildcards */
                this->ike_sa->set_other_id(this->ike_sa, other_id);
        }
        
index 29cdcaf..d69e6aa 100644 (file)
@@ -269,6 +269,7 @@ static status_t get_request(private_ike_sa_init_t *this, message_t **result)
 {
        message_t *request;
        host_t *me, *other;
+       identification_t *my_id, *other_id;
        
        /* check if we already have built a message (retransmission) */
        if (this->message)
@@ -280,6 +281,13 @@ static status_t get_request(private_ike_sa_init_t *this, message_t **result)
        me = this->connection->get_my_host(this->connection);
        other = this->connection->get_other_host(this->connection);
        
+       /* we already set up the IDs. Mine is already fully qualified, other
+       * will be updated in the ike_auth transaction */
+       my_id = this->policy->get_my_id(this->policy);
+       other_id = this->policy->get_other_id(this->policy);
+       this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
+       this->ike_sa->set_other_id(this->ike_sa, other_id->clone(other_id));
+       
        /* build the request */
        request = message_create();
        request->set_source(request, me->clone(me));
index 2242ea2..004e3ec 100755 (executable)
@@ -37,7 +37,7 @@
 #include <types.h>
 #include <daemon.h>
 #include <crypto/x509.h>
-#include <queues/jobs/initiate_ike_sa_job.h>
+#include <queues/jobs/initiate_job.h>
 
 #define IKE_PORT       500
 #define PATH_BUF       256
@@ -477,11 +477,9 @@ static void stroke_del_conn(private_stroke_t *this, stroke_msg_t *msg)
  */
 static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
 {
-       initiate_ike_sa_job_t *job;
+       initiate_job_t *job;
        connection_t *connection;
        policy_t *policy;
-       linked_list_t *ike_sas;
-       ike_sa_id_t *ike_sa_id;
        
        pop_string(msg, &(msg->initiate.name));
        this->logger->log(this->logger, CONTROL,
@@ -495,49 +493,29 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
                this->stroke_logger->log(this->stroke_logger, ERROR, 
                                                                 "no connection named \"%s\"", 
                                                                 msg->initiate.name);
+               return;
        }
-       /* only initiate if it is an IKEv2 connection, ignore IKEv1 */
-       else if (connection->is_ikev2(connection))
+       if (!connection->is_ikev2(connection))
        {
-               
-               policy = charon->policies->get_policy_by_name(charon->policies, 
-                                                                                                         msg->initiate.name);
-               if (policy == NULL)
-               {
-                       this->stroke_logger->log(this->stroke_logger, ERROR,
-                                                                        "no policy named \"%s\"",
-                                                                        msg->initiate.name);
-                       connection->destroy(connection);
-                       return;
-               }
-               /* check for already set up IKE_SAs befor initiating */
-               ike_sas = charon->ike_sa_manager->get_ike_sa_list_by_name(charon->ike_sa_manager,
-                                                                                                                                 msg->initiate.name);
-               if (ike_sas->get_count(ike_sas) > 0)
-               {
-                       this->stroke_logger->log(this->stroke_logger, CONTROL,
-                                                                        "connection \"%s\" already up", 
-                                                                        msg->initiate.name);
-                       /* TODO: setup CHILD_SA with policy */
-                       connection->destroy(connection);
-                       ike_sas->destroy(ike_sas);
-                       return;
-               }
-               this->stroke_logger->log(this->stroke_logger, CONTROL,
-                                                                "initiating connection \"%s\" (see log)...", 
-                                                                msg->initiate.name);
-               job = initiate_ike_sa_job_create(connection, policy);
-               charon->job_queue->add(charon->job_queue, (job_t*)job);
-               while (ike_sas->remove_last(ike_sas, (void**)&ike_sa_id) == SUCCESS)
-               {
-                       ike_sa_id->destroy(ike_sa_id);
-               }
-               ike_sas->destroy(ike_sas);
+               connection->destroy(connection);
+               return;
        }
-       else
+               
+       policy = charon->policies->get_policy_by_name(charon->policies, 
+                                                                                                 msg->initiate.name);
+       if (policy == NULL)
        {
+               this->stroke_logger->log(this->stroke_logger, ERROR,
+                                                                "no policy named \"%s\"",
+                                                                msg->initiate.name);
                connection->destroy(connection);
+               return;
        }
+       this->stroke_logger->log(this->stroke_logger, CONTROL,
+                                                        "initiating connection \"%s\" (see log)...", 
+                                                        msg->initiate.name);
+       job = initiate_job_create(connection, policy);
+       charon->job_queue->add(charon->job_queue, (job_t*)job);
 }
 
 /**
index b5c1d95..92f50e5 100644 (file)
  * String mappings for encryption_algorithm_t.
  */
 mapping_t encryption_algorithm_m[] = {
-{ENCR_UNDEFINED, "ENCR_UNDEFINED"},
-{ENCR_DES_IV64, "ENCR_DES_IV64"},
-{ENCR_DES, "ENCR_DES"},
-{ENCR_3DES, "ENCR_3DES"},
-{ENCR_RC5, "ENCR_RC5"},
-{ENCR_IDEA, "ENCR_IDEA"},
-{ENCR_CAST, "ENCR_CAST"},
-{ENCR_BLOWFISH, "ENCR_BLOWFISH"},
-{ENCR_3IDEA, "ENCR_3IDEA"},
-{ENCR_DES_IV32, "ENCR_DES_IV32"},
-{ENCR_NULL, "ENCR_NULL"},
-{ENCR_AES_CBC, "ENCR_AES_CBC"},
-{ENCR_AES_CTR, "ENCR_AES_CTR"},
-{MAPPING_END, NULL}
+       {ENCR_UNDEFINED, "UNDEFINED"},
+       {ENCR_DES_IV64, "DES_IV64"},
+       {ENCR_DES, "DES"},
+       {ENCR_3DES, "3DES"},
+       {ENCR_RC5, "RC5"},
+       {ENCR_IDEA, "IDEA"},
+       {ENCR_CAST, "CAST"},
+       {ENCR_BLOWFISH, "BLOWFISH"},
+       {ENCR_3IDEA, "3IDEA"},
+       {ENCR_DES_IV32, "DES_IV32"},
+       {ENCR_NULL, "NULL"},
+       {ENCR_AES_CBC, "AES_CBC"},
+       {ENCR_AES_CTR, "AES_CTR"},
+       {MAPPING_END, NULL}
 };
 
 /* 
index 7811746..67fbbd6 100644 (file)
  * String mappings for integrity_algorithm_t.
  */
 mapping_t integrity_algorithm_m[] = {
-       {AUTH_UNDEFINED, "AUTH_UNDEFINED"},
-       {AUTH_HMAC_MD5_96, "AUTH_HMAC_MD5_96"},
-       {AUTH_HMAC_SHA1_96, "AUTH_HMAC_SHA1_96"},
-       {AUTH_DES_MAC, "AUTH_DES_MAC"},
-       {AUTH_KPDK_MD5, "AUTH_KPDK_MD5"},
-       {AUTH_AES_XCBC_96, "AUTH_AES_XCBC_96"},
+       {AUTH_UNDEFINED, "UNDEFINED"},
+       {AUTH_HMAC_MD5_96, "HMAC_MD5_96"},
+       {AUTH_HMAC_SHA1_96, "HMAC_SHA1_96"},
+       {AUTH_DES_MAC, "DES_MAC"},
+       {AUTH_KPDK_MD5, "KPDK_MD5"},
+       {AUTH_AES_XCBC_96, "AES_XCBC_96"},
        {MAPPING_END, NULL}
 };