some improvements in signaling code
[strongswan.git] / src / charon / sa / transactions / delete_ike_sa.c
index 7377632..26817bb 100644 (file)
@@ -25,7 +25,6 @@
 #include <daemon.h>
 #include <encoding/payloads/delete_payload.h>
 
-
 typedef struct private_delete_ike_sa_t private_delete_ike_sa_t;
 
 /**
@@ -59,9 +58,9 @@ struct private_delete_ike_sa_t {
        u_int32_t requested;
        
        /**
-        * Assigned logger.
+        * is the IKE_SA redundant and gets deleted without further notification?
         */
-       logger_t *logger;
+       bool redundant;
 };
 
 /**
@@ -86,7 +85,6 @@ static u_int32_t requested(private_delete_ike_sa_t *this)
 static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
 {
        message_t *request;
-       connection_t *connection;
        host_t *me, *other;
        delete_payload_t *delete_payload;
        
@@ -97,9 +95,14 @@ static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
                return SUCCESS;
        }
        
-       connection = this->ike_sa->get_connection(this->ike_sa);
-       me = connection->get_my_host(connection);
-       other = connection->get_other_host(connection);
+       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();
@@ -107,6 +110,7 @@ static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
        request->set_destination(request, other->clone(other));
        request->set_exchange_type(request, INFORMATIONAL);
        request->set_request(request, TRUE);
+       this->message_id = this->ike_sa->get_next_message_id(this->ike_sa);
        request->set_message_id(request, this->message_id);
        request->set_ike_sa_id(request, this->ike_sa->get_id(this->ike_sa));
        /* apply for caller */
@@ -118,7 +122,7 @@ static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
        request->add_payload(request, (payload_t*)delete_payload);
        
        /* transit to state SA_DELETING */
-       this->ike_sa->set_state(this->ike_sa, SA_DELETING);
+       this->ike_sa->set_state(this->ike_sa, IKE_DELETING);
        
        return SUCCESS;
 }
@@ -132,8 +136,8 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
        host_t *me, *other;
        message_t *response;
        iterator_t *payloads;
+       payload_t *payload;
        delete_payload_t *delete_request = NULL;
-       connection_t *connection;
        
        /* check if we already have built a response (retransmission) 
         * this only happens in special simultanous transaction cases,
@@ -144,9 +148,15 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
                return SUCCESS;
        }
        
-       connection = this->ike_sa->get_connection(this->ike_sa);
-       me = connection->get_my_host(connection);
-       other = connection->get_other_host(connection);
+       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();
@@ -162,18 +172,17 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
        /* check message type */
        if (request->get_exchange_type(request) != INFORMATIONAL)
        {
-               this->logger->log(this->logger, ERROR,
-                                                 "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;
        }
        
        /* iterate over all payloads */
        payloads = request->get_payload_iterator(request);      
-       while (payloads->has_next(payloads))
+       while (payloads->iterate(payloads, (void**)&payload))
        {
-               payload_t *payload;
-               payloads->current(payloads, (void**)&payload);
-               
                switch (payload->get_type(payload))
                {
                        case DELETE:
@@ -183,9 +192,8 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
                        }
                        default:
                        {
-                               this->logger->log(this->logger, ERROR|LEVEL1, "ignoring payload %s (%d)",
-                                                                 mapping_find(payload_type_m, payload->get_type(payload)),
-                                                                 payload->get_type(payload));
+                               DBG1(DBG_IKE, "ignoring payload %N",
+                                        payload_type_names, payload->get_type(payload));
                                break;
                        }
                }
@@ -195,22 +203,24 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
        if (delete_request && 
                delete_request->get_protocol_id(delete_request) == PROTO_IKE)
        {
-               this->logger->log(this->logger, CONTROL, 
-                                                 "DELETE request for IKE_SA received, deleting IKE_SA");
+               DBG1(DBG_IKE, "DELETE request for IKE_SA received, deleting IKE_SA");
        }
        else
        {
                /* should not happen, as we preparsed this at transaction construction */
-               this->logger->log(this->logger, CONTROL, 
-                                                 "received a weird DELETE request for IKE_SA, deleting anyway");
+               DBG1(DBG_IKE, "received a weird DELETE request for IKE_SA, deleting anyway");
        }
-       if (this->ike_sa->get_state(this->ike_sa) == SA_DELETING)
+       if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
        {
                /* if we are already deleting an IKE_SA, we do not destroy. We wait
                 * until we get the response for our initiated delete. */
                return SUCCESS;
        }
-       this->ike_sa->set_state(this->ike_sa, SA_DELETING);
+       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;
 }
 
@@ -224,12 +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)
        {
-               this->logger->log(this->logger, ERROR,
-                                                 "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;
 }
 
@@ -238,17 +254,14 @@ static status_t conclude(private_delete_ike_sa_t *this, message_t *response,
  */
 static void destroy(private_delete_ike_sa_t *this)
 {
-       if (this->message)
-       {
-               this->message->destroy(this->message);
-       }
+       DESTROY_IF(this->message);
        free(this);
 }
 
 /*
  * Described in header.
  */
-delete_ike_sa_t *delete_ike_sa_create(ike_sa_t *ike_sa, u_int32_t message_id)
+delete_ike_sa_t *delete_ike_sa_create(ike_sa_t *ike_sa)
 {
        private_delete_ike_sa_t *this = malloc_thing(private_delete_ike_sa_t);
        
@@ -262,10 +275,10 @@ delete_ike_sa_t *delete_ike_sa_create(ike_sa_t *ike_sa, u_int32_t message_id)
        
        /* private data */
        this->ike_sa = ike_sa;
-       this->message_id = message_id;
+       this->message_id = 0;
        this->message = NULL;
        this->requested = 0;
-       this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
+       this->redundant = FALSE;
        
        return &this->public;
 }