some improvements in signaling code
authorMartin Willi <martin@strongswan.org>
Fri, 27 Oct 2006 10:46:56 +0000 (10:46 -0000)
committerMartin Willi <martin@strongswan.org>
Fri, 27 Oct 2006 10:46:56 +0000 (10:46 -0000)
src/charon/doc/Todo-list.txt
src/charon/sa/transactions/delete_ike_sa.c
src/charon/sa/transactions/ike_auth.c
src/charon/sa/transactions/rekey_ike_sa.c
src/charon/threads/stroke_interface.c

index 7bb4643..b096faa 100644 (file)
@@ -60,11 +60,13 @@ Todo-List for charon
 
 + use dpdaction/dpddelay parameters from ipsec.conf
 / add firewall script support
-- do not link unneeded libraries in bins
-- include only a minimum of NATD payloads
-- implement 3DES to load encrypted pem files
-- implement a "event bus" mechanism
-  - add more output to to up/down, somehow...
++ do not link unneeded libraries in bins
++ include only a minimum of NATD payloads
++ implement 3DES to load encrypted pem files
++ implement a "event bus" mechanism
+  / add more output to to up/down, somehow...
+  - detach console after first keyingtry
+  - proper handling of CTRL+C console detach (SIG_PIPE)
 - configure flag which allows to ommit vendor id in pluto
 - ikelifetime should optionally enforce reauthentication
 - cookies/DDoS prevention
@@ -74,7 +76,8 @@ Todo-List for charon
 - add support for CERTREQs
 - proper handling of multiple certificate payloads (import order)
 - add a Rekey-Counter for SAs in "statusall"
-- ipsec status: 
-  - on one line: ip, id, spi
+- ipsec status:
+  + on one line: ip, id, spi
   - no key age, rekey for IKE
-  - byte count
\ No newline at end of file
+  - byte count
+- retry transaction on failure while keyingtries > 1
\ No newline at end of file
index af1da3a..26817bb 100644 (file)
@@ -56,6 +56,11 @@ struct private_delete_ike_sa_t {
         * Times we did send the request
         */
        u_int32_t requested;
+       
+       /**
+        * is the IKE_SA redundant and gets deleted without further notification?
+        */
+       bool redundant;
 };
 
 /**
@@ -92,6 +97,12 @@ static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
        
        me = this->ike_sa->get_my_host(this->ike_sa);
        other = this->ike_sa->get_other_host(this->ike_sa);
+       this->redundant = this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING;
+       
+       if (!this->redundant)
+       {
+               SIG(IKE_DOWN_START, "deleting IKE_SA");
+       }
        
        /* build the request */
        request = message_create();
@@ -140,6 +151,12 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
        me = this->ike_sa->get_my_host(this->ike_sa);
        other = this->ike_sa->get_other_host(this->ike_sa);
        this->message_id = request->get_message_id(request);
+       this->redundant = this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING;
+       
+       if (!this->redundant)
+       {
+               SIG(IKE_DOWN_START, "deleting IKE_SA");
+       }
        
        /* set up response */
        response = message_create();
@@ -155,7 +172,10 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
        /* check message type */
        if (request->get_exchange_type(request) != INFORMATIONAL)
        {
-               DBG1(DBG_IKE, "INFORMATIONAL response of invalid type, deleting IKE_SA");
+               if (!this->redundant)
+               {
+                       SIG(IKE_DOWN_FAILED, "INFORMATIONAL response of invalid type, deleting IKE_SA");
+               }
                return DESTROY_ME;
        }
        
@@ -197,6 +217,10 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
                return SUCCESS;
        }
        this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
+       if (!this->redundant)
+       {
+               SIG(IKE_DOWN_SUCCESS, "IKE_SA deleted on request");
+       }
        return DESTROY_ME;
 }
 
@@ -210,11 +234,18 @@ static status_t conclude(private_delete_ike_sa_t *this, message_t *response,
        /* check message type */
        if (response->get_exchange_type(response) != INFORMATIONAL)
        {
-               DBG1(DBG_IKE, "INFORMATIONAL response of invalid type, deleting IKE_SA");
+               if (!this->redundant)
+               {
+                       SIG(IKE_DOWN_FAILED, "INFORMATIONAL response of invalid type, deleting IKE_SA");
+               }
                return DESTROY_ME;
        }
        /* this is only an acknowledge. We can't do anything here, but delete
         * the IKE_SA. */
+       if (!this->redundant)
+       {
+               SIG(IKE_DOWN_SUCCESS, "IKE_SA deleted");
+       }
        return DESTROY_ME;
 }
 
@@ -247,6 +278,7 @@ delete_ike_sa_t *delete_ike_sa_create(ike_sa_t *ike_sa)
        this->message_id = 0;
        this->message = NULL;
        this->requested = 0;
+       this->redundant = FALSE;
        
        return &this->public;
 }
index ec54dd6..1bb2534 100644 (file)
@@ -995,8 +995,14 @@ static void destroy(private_ike_auth_t *this)
        DESTROY_IF(this->child_sa);
        DESTROY_IF(this->policy);
        DESTROY_IF(this->connection);
-       this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
-       this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
+       if (this->tsi)
+       {
+               this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
+       }
+       if (this->tsr)
+       {
+               this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
+       }
        chunk_free(&this->nonce_i);
        chunk_free(&this->nonce_r);
        chunk_free(&this->init_request);
index d2dfe01..59fc6f8 100644 (file)
@@ -757,9 +757,10 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
        
        if (switchto_new_sa(this, TRUE) != SUCCESS)
        {
-               /* this should not happen. But if, we destroy both SAs */
+               /* this should not happen. But if, we destroy the new SAs */
+               this->new_sa->set_state(this->new_sa, IKE_REKEYING);
                *next = (transaction_t*)delete_ike_sa_create(this->new_sa);
-               return DESTROY_ME;
+               return FAILED;
        }
        
        /* IKE_SA successfully created. If the other peer initiated rekeying
@@ -800,7 +801,12 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
                        /* the other has won, he gets our children */
                        other_trans->new_sa->adopt_children(other_trans->new_sa, this->ike_sa);
                        /* we have lost simlutaneous rekeying, delete the SA we just have created */
-                       this->new_sa->delete(this->new_sa);
+                       this->new_sa->set_state(this->new_sa, IKE_REKEYING);
+                       *next = (transaction_t*)delete_ike_sa_create(this->new_sa);
+               }
+               else
+               {
+                       other_trans->new_sa->set_state(other_trans->new_sa, IKE_REKEYING);
                }
                /* other trans' SA is still not checked in, so do it now. It's SA will get
                 * deleted by remote peer. */
@@ -811,8 +817,8 @@ static status_t conclude(private_rekey_ike_sa_t *this, message_t *response,
        if (!this->lost)
        {
                /* we have won. delete old IKE_SA, and migrate all children */
-               *next = (transaction_t*)delete_ike_sa_create(this->ike_sa);
                this->new_sa->adopt_children(this->new_sa, this->ike_sa);
+               *next = (transaction_t*)delete_ike_sa_create(this->ike_sa);
        }
        
        charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa);
index 62d71dd..0163f18 100755 (executable)
@@ -30,6 +30,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <pthread.h>
+#include <signal.h>
 
 #include "stroke_interface.h"
 
@@ -507,7 +508,7 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
                connection->destroy(connection);
                return;
        }
-               
+       
        policy = charon->policies->get_policy_by_name(charon->policies, 
                                                                                                  msg->initiate.name);
        if (policy == NULL)
@@ -521,6 +522,14 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
        }
        
        job = initiate_job_create(connection, policy);
+       /*
+       if (msg->output_verbosity < 0)
+       {
+       TODO: detach immediately if verbosity is SILENT. Local credential store
+       is not threadsave yet, so this would cause crashes!!
+               charon->job_queue->add(charon->job_queue, (job_t*)job);
+               return;
+}*/
        
        charon->bus->set_listen_state(charon->bus, TRUE);
        charon->job_queue->add(charon->job_queue, (job_t*)job);
@@ -541,11 +550,11 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
                                fprintf(this->out, "\n") < 0 ||
                                fflush(this->out))
                        {
+                               charon->bus->set_listen_state(charon->bus, FALSE);
                                break;
                        }
                }
                
-               /* TODO: Handle INVALID_KE_PAYLOAD signal (ike_sa switch) */
                switch (signal)
                {
                        case CHILD_UP_SUCCESS:
@@ -885,6 +894,10 @@ static void stroke_receive(private_stroke_t *this)
        int strokefd;
        int oldstate;
        
+       /* ignore sigpipe. writing over the pipe back to the console
+        * only fails if SIGPIPE is ignored. */
+       signal(SIGPIPE, SIG_IGN);
+       
        /* disable cancellation by default */
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);