split connections with different virtual IPs in different peer_cfgs
authorMartin Willi <martin@strongswan.org>
Tue, 5 Feb 2008 12:39:30 +0000 (12:39 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 5 Feb 2008 12:39:30 +0000 (12:39 -0000)
respect different peer_cfg's when initiating a CHILD_SA within an existing IKE_SA

src/charon/control/interface_manager.c
src/charon/control/interfaces/stroke_interface.c
src/charon/sa/ike_sa_manager.c
src/charon/sa/ike_sa_manager.h

index c14903c..4d5aa2e 100644 (file)
@@ -171,14 +171,11 @@ static bool initiate_listener(interface_bus_listener_t *this, signal_t signal,
 static status_t initiate_execute(interface_job_t *job)
 {
        ike_sa_t *ike_sa;
-       ike_cfg_t *ike_cfg;
        interface_bus_listener_t *listener = &job->listener;
        peer_cfg_t *peer_cfg = listener->peer_cfg;
 
-       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-       ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
-                               ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg),
-                               peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg));
+       ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
+                                                                                                               peer_cfg);
        listener->ike_sa = ike_sa;
 
        if (ike_sa->get_peer_cfg(ike_sa) == NULL)
@@ -435,15 +432,11 @@ static bool route_listener(interface_bus_listener_t *this, signal_t signal,
 static status_t route_execute(interface_job_t *job)
 {
        ike_sa_t *ike_sa;
-       ike_cfg_t *ike_cfg;
        interface_bus_listener_t *listener = &job->listener;
        peer_cfg_t *peer_cfg = listener->peer_cfg;
        
-       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-       
-       ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
-                               ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg),
-                               peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg));
+       ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
+                                                                                                               peer_cfg);
        listener->ike_sa = ike_sa;
        
        if (ike_sa->get_peer_cfg(ike_sa) == NULL)
index b51d53e..3b4b246 100755 (executable)
@@ -535,6 +535,24 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
        iterator = charon->backends->create_iterator(charon->backends);
        while (iterator->iterate(iterator, (void**)&peer_cfg))
        {
+               host_t *my_vip_conf, *other_vip_conf;
+               bool my_vip_equals = FALSE, other_vip_equals = FALSE;
+               
+               my_vip_conf = peer_cfg->get_my_virtual_ip(peer_cfg);
+               if ((my_vip && my_vip_conf && my_vip->equals(my_vip, my_vip_conf)) ||
+                       (!my_vip_conf && !my_vip))
+               {
+                       my_vip_equals = TRUE;
+               }
+               DESTROY_IF(my_vip_conf);
+               other_vip_conf = peer_cfg->get_other_virtual_ip(peer_cfg, NULL);
+               if ((other_vip && other_vip_conf && other_vip->equals(other_vip, other_vip_conf)) ||
+                       (!other_vip_conf && !other_vip))
+               {
+                       other_vip_equals = TRUE;
+               }
+               DESTROY_IF(other_vip_conf);
+               
                ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
                if (my_id->equals(my_id, peer_cfg->get_my_id(peer_cfg))
                &&      other_id->equals(other_id, peer_cfg->get_other_id(peer_cfg))
@@ -545,7 +563,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
                &&      peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1)
                &&      peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method
                &&      peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type
-               &&      vendor == msg->add_conn.eap_vendor)
+               &&      vendor == msg->add_conn.eap_vendor
+               &&  my_vip_equals && other_vip_equals)
                {
                        DBG1(DBG_CFG, "reusing existing configuration '%s'",
                                 peer_cfg->get_name(peer_cfg));
index 5014ea0..5e7f78a 100644 (file)
@@ -483,16 +483,23 @@ static ike_sa_t* checkout_by_message(private_ike_sa_manager_t* this,
 }
 
 /**
- * Implementation of of ike_sa_manager.checkout_by_peer.
+ * Implementation of of ike_sa_manager.checkout_by_config.
  */
-static ike_sa_t* checkout_by_peer(private_ike_sa_manager_t *this,
-                                                                 host_t *my_host, host_t *other_host,
-                                                                 identification_t *my_id,
-                                                                 identification_t *other_id)
+static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
+                                                                       peer_cfg_t *peer_cfg)
 {
        iterator_t *iterator;
        entry_t *entry;
        ike_sa_t *ike_sa = NULL;
+       identification_t *my_id, *other_id;
+       host_t *my_host, *other_host;
+       ike_cfg_t *ike_cfg;
+       
+       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+       my_host = ike_cfg->get_my_host(ike_cfg);
+       other_host =  ike_cfg->get_other_host(ike_cfg);
+       my_id = peer_cfg->get_my_id(peer_cfg);
+       other_id = peer_cfg->get_other_id(peer_cfg);
        
        pthread_mutex_lock(&(this->mutex));
        
@@ -535,7 +542,9 @@ static ike_sa_t* checkout_by_peer(private_ike_sa_manager_t *this,
                        (other_host->is_anyaddr(other_host) ||
                         other_host->ip_equals(other_host, found_other_host)) &&
                        found_my_id->matches(found_my_id, my_id, &wc) &&
-                       found_other_id->matches(found_other_id, other_id, &wc))
+                       found_other_id->matches(found_other_id, other_id, &wc) &&
+                       streq(peer_cfg->get_name(peer_cfg),
+                                 entry->ike_sa->get_name(entry->ike_sa)))
                {
                        /* looks good, we take this one */
                        DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
@@ -902,7 +911,7 @@ ike_sa_manager_t *ike_sa_manager_create()
        this->public.checkout = (ike_sa_t*(*)(ike_sa_manager_t*, ike_sa_id_t*))checkout;
        this->public.checkout_new = (ike_sa_t*(*)(ike_sa_manager_t*,bool))checkout_new;
        this->public.checkout_by_message = (ike_sa_t*(*)(ike_sa_manager_t*,message_t*))checkout_by_message;
-       this->public.checkout_by_peer = (ike_sa_t*(*)(ike_sa_manager_t*,host_t*,host_t*,identification_t*,identification_t*))checkout_by_peer;
+       this->public.checkout_by_config = (ike_sa_t*(*)(ike_sa_manager_t*,peer_cfg_t*))checkout_by_config;
        this->public.checkout_by_id = (ike_sa_t*(*)(ike_sa_manager_t*,u_int32_t,bool))checkout_by_id;
        this->public.checkout_by_name = (ike_sa_t*(*)(ike_sa_manager_t*,char*,bool))checkout_by_name;
        this->public.create_iterator = (iterator_t*(*)(ike_sa_manager_t*))create_iterator;
index 1125e5d..a73a106 100644 (file)
@@ -29,6 +29,7 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
 #include <library.h>
 #include <sa/ike_sa.h>
 #include <encoding/message.h>
+#include <config/peer_cfg.h>
 
 /**
  * @brief The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
@@ -94,25 +95,21 @@ struct ike_sa_manager_t {
        ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message);
        
        /**
-        * @brief Checkout an existing IKE_SA by hosts and identifications.
+        * @brief Checkout an IKE_SA for initiation by a peer_config.
         *
-        * Allows the lookup of an IKE_SA by user IDs and hosts. It returns the
-        * first found occurence, if there are multiple candidates. Supplied IDs
-        * may contain wildcards, hosts may be %any. 
+        * To initiate, a CHILD_SA may be established within an existing IKE_SA.
+        * This call checks for an existing IKE_SA by comparing the configuration.
+        * If the CHILD_SA can be created in an existing IKE_SA, the matching SA
+        * is returned.
         * If no IKE_SA is found, a new one is created. This is also the case when
         * the found IKE_SA is in the DELETING state.
         *
         * @param this                          the manager object
-        * @param my_host                       address of our host
-        * @param other_id                      address of remote host
-        * @param my_id                         ID used by us
-        * @param other_id                      ID used by remote
+        * @param peer_cfg                      configuration used to find an existing IKE_SA
         * @return                                      checked out/created IKE_SA
         */
-       ike_sa_t* (*checkout_by_peer) (ike_sa_manager_t* this,
-                                                                  host_t *my_host, host_t* other_host,
-                                                                  identification_t *my_id, 
-                                                                  identification_t *other_id);
+       ike_sa_t* (*checkout_by_config) (ike_sa_manager_t* this,
+                                                                        peer_cfg_t *peer_cfg);
        
        /**
         * @brief Check out an IKE_SA a unique ID.