added support for xfrm remote kmaddress
[strongswan.git] / src / charon / processing / jobs / migrate_job.c
index c9c835d..100158a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Andreas Steffen
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -12,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * $Id: acquire_job.c 4535 2008-10-31 01:43:23Z andreas $
+ * $Id$
  */
 
 #include "migrate_job.h"
@@ -49,9 +49,14 @@ struct private_migrate_job_t {
        traffic_selector_t *dst_ts;
 
        /**
-        * local host address to be used
+        * local host address to be used for IKE
         */
        host_t *local;
+
+       /**
+        * remote host address to be used for IKE
+        */
+       host_t *remote;
 };
 
 /**
@@ -62,6 +67,7 @@ static void destroy(private_migrate_job_t *this)
        DESTROY_IF(this->src_ts);
        DESTROY_IF(this->dst_ts);
        DESTROY_IF(this->local);
+       DESTROY_IF(this->remote);
        free(this);
 }
 
@@ -86,7 +92,6 @@ static void execute(private_migrate_job_t *this)
                enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
                while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
                {
-                       ike_cfg_t *ike_cfg;
                        child_cfg_t *child_cfg;
 
                        if (peer_cfg->get_ike_version(peer_cfg) != 2)
@@ -94,7 +99,6 @@ static void execute(private_migrate_job_t *this)
                                continue;
                        }
 
-                       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
                        children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
                        while (children->enumerate(children, &child_cfg))
                        {
@@ -112,23 +116,57 @@ static void execute(private_migrate_job_t *this)
                        }
                }
                enumerator->destroy(enumerator);
-               if (found_cfg)
+
+               if (found_cfg == NULL)
                {
-                       DBG1(DBG_JOB, "found matching child_cfg '%s'",
-                                                  found_cfg->get_name(found_cfg));
+                       DBG1(DBG_JOB, "no matching child config found for policy %R === %R",
+                                                  this->src_ts, this->dst_ts);
+                       destroy(this);
+                       return;
                }
-               else
+               DBG1(DBG_JOB, "found matching child config '%s' for policy %R === %R",
+                                          found_cfg->get_name(found_cfg),
+                                          this->src_ts, this->dst_ts);
+
+               ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
+                                                                                                                       peer_cfg);
+               if (ike_sa->get_peer_cfg(ike_sa) == NULL)
                {
-                       DBG1(DBG_JOB, "no matching child_cfg found");
+                       host_t *my_host, *other_host;
+                       ike_cfg_t *ike_cfg;
+
+                       ike_sa->set_peer_cfg(ike_sa, peer_cfg);
+                       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+                       my_host = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg), 0, 0);
+                       other_host = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg), 0, 0);
+                       ike_sa->set_my_host(ike_sa, my_host);
+                       ike_sa->set_other_host(ike_sa, other_host);
                }
+               if (this->local)
+               {
+                       ike_sa->set_my_host(ike_sa, this->local->clone(this->local));
+               }
+               if (this->remote)
+               {
+                       ike_sa->set_other_host(ike_sa, this->remote->clone(this->remote));
+               }
+               /* add a CHILD_SA for 'found_cfg' with a policy that has already been
+         * installed in the kernel
+         */
        }
        else
        {
-               DBG1(DBG_JOB, "migrate job found CHILD_SA with reqid {%d}", this->reqid);
-
-               /* set my_host to local */
-               charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+               DBG1(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid);
+               if (this->local)
+               {
+                       ike_sa->set_my_host(ike_sa, this->local);
+               }
+               if (this->remote)
+               {
+                       ike_sa->set_other_host(ike_sa, this->remote->clone(this->remote));
+               }
        }
+       charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
        destroy(this);
 }
 
@@ -139,7 +177,7 @@ migrate_job_t *migrate_job_create(u_int32_t reqid,
                                                                  traffic_selector_t *src_ts,
                                                                  traffic_selector_t *dst_ts,
                                                                  policy_dir_t dir,
-                                                                 host_t *local)
+                                                                 host_t *local, host_t *remote)
 {
        private_migrate_job_t *this = malloc_thing(private_migrate_job_t);
        
@@ -152,6 +190,7 @@ migrate_job_t *migrate_job_create(u_int32_t reqid,
        this->src_ts = (dir == POLICY_OUT) ? src_ts : dst_ts;
        this->dst_ts = (dir == POLICY_OUT) ? dst_ts : src_ts;
        this->local = local;
+       this->remote = remote;
        
        return &this->public;
 }