mediation connections should now properly rekey
authorTobias Brunner <tobias@strongswan.org>
Wed, 9 Apr 2008 18:12:22 +0000 (18:12 -0000)
committerTobias Brunner <tobias@strongswan.org>
Wed, 9 Apr 2008 18:12:22 +0000 (18:12 -0000)
src/charon/sa/ike_sa.c
src/charon/sa/ike_sa.h
src/charon/sa/tasks/ike_me.c

index 20bbd06..cdc5a43 100644 (file)
@@ -144,6 +144,11 @@ struct private_ike_sa_t {
        
 #ifdef ME
        /**
+        * Are we mediation server
+        */
+       bool is_mediation_server;
+       
+       /**
         * Server reflexive host
         */
        host_t *server_reflexive_host;
@@ -932,6 +937,16 @@ static void send_notify_response(private_ike_sa_t *this, message_t *request,
 
 #ifdef ME
 /**
+ * Implementation of ike_sa_t.act_as_mediation_server.
+ */
+static void act_as_mediation_server(private_ike_sa_t *this)
+{
+       charon->mediation_manager->update_sa_id(charon->mediation_manager,
+                       this->other_id, this->ike_sa_id);
+       this->is_mediation_server = TRUE;
+}
+
+/**
  * Implementation of ike_sa_t.get_server_reflexive_host.
  */
 static host_t *get_server_reflexive_host(private_ike_sa_t *this)
@@ -2127,6 +2142,18 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
        {
                send_keepalive(this);
        }
+       
+#ifdef ME
+       if (other->is_mediation_server)
+       {
+               act_as_mediation_server(this);
+       }
+       else if (other->server_reflexive_host)
+       {
+               this->server_reflexive_host = other->server_reflexive_host->clone(
+                               other->server_reflexive_host);
+       }
+#endif /* ME */
 
        /* adopt all children */
        while (other->child_sas->remove_last(other->child_sas,
@@ -2332,10 +2359,8 @@ static void destroy(private_ike_sa_t *this)
        this->additional_addresses->destroy_offset(this->additional_addresses,
                                                                                                        offsetof(host_t, destroy));
 #ifdef ME
-       if (this->peer_cfg && this->peer_cfg->is_mediation(this->peer_cfg) &&
-                       !this->ike_sa_id->is_initiator(this->ike_sa_id))
+       if (this->is_mediation_server)
        {
-               /* mediation server */
                charon->mediation_manager->remove(charon->mediation_manager, this->ike_sa_id);
        }
        DESTROY_IF(this->server_reflexive_host);
@@ -2427,6 +2452,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip;
        this->public.add_dns_server = (void (*)(ike_sa_t*,host_t*))add_dns_server;
 #ifdef ME
+       this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server;
        this->public.get_server_reflexive_host = (host_t* (*)(ike_sa_t*)) get_server_reflexive_host;
        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;
@@ -2474,6 +2500,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->keyingtry = 0;
        this->ike_initiator = FALSE;
 #ifdef ME
+       this->is_mediation_server = FALSE;
        this->server_reflexive_host = NULL;
        this->connect_id = chunk_empty;
 #endif /* ME */
index 00dbcd3..58e6e01 100644 (file)
@@ -436,6 +436,11 @@ struct ike_sa_t {
 
 #ifdef ME
        /**
+        * Activate mediation server functionality for this IKE_SA.
+        */
+       void (*act_as_mediation_server) (ike_sa_t *this);
+       
+       /**
         * Get the server reflexive host.
         * 
         * @return                              server reflexive host
index 44f5c9f..4d70a9c 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
@@ -480,9 +480,7 @@ static status_t process_i(private_ike_me_t *this, message_t *message)
                        if (this->failed)
                        {
                                DBG1(DBG_IKE, "peer '%D' is not online", this->peer_id);
-                               /* FIXME: notify the mediated connection (job?)
-                                * FIXME: probably delete the created checklist, at least as 
-                                * responder */
+                               /* FIXME: notify the mediated connection (job?) */
                        }
                        else
                        {
@@ -501,6 +499,8 @@ static status_t process_i(private_ike_me_t *this, message_t *message)
                                                this->ike_sa->get_my_id(this->ike_sa), this->peer_id,
                                                this->connect_id, this->connect_key, this->local_endpoints,
                                                TRUE);
+                                       /* FIXME: also start a timer for the whole transaction (maybe
+                                        * within the connect_manager?) */
                                }
                        }
                        break;
@@ -646,10 +646,8 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message)
                                endpoint->destroy(endpoint);
                        }
                        
-                       /* FIXME: we must delete any existing IKE_SAs */
-                       charon->mediation_manager->update_sa_id(charon->mediation_manager,
-                                       this->ike_sa->get_other_id(this->ike_sa),
-                                       this->ike_sa->get_id(this->ike_sa));
+                       /* FIXME: we actually must delete any existing IKE_SAs with the same remote id */
+                       this->ike_sa->act_as_mediation_server(this->ike_sa);
                        
                        SIG(CHILD_UP_SUCCESS, "established mediation connection without CHILD_SA successfully");
                        
@@ -700,6 +698,10 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message)
  */
 static status_t process_i_ms(private_ike_me_t *this, message_t *message)
 {
+       /* FIXME: theoretically we should be prepared to receive a ME_CONNECT_FAILED
+        * here if the responding peer is not able to proceed. in this case we shall
+        * notify the initiating peer with a ME_CONNECT request containing only a
+        * ME_CONNECT_FAILED */
        return SUCCESS;
 }