2 * Copyright (C) 2008 Andreas Steffen
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 #include "migrate_job.h"
22 #include <config/child_cfg.h>
25 typedef struct private_migrate_job_t private_migrate_job_t
;
28 * Private data of a migrate_job_t object.
30 struct private_migrate_job_t
{
32 * Public migrate_job_t interface.
37 * reqid of the CHILD_SA if it already exists
42 * source traffic selector
44 traffic_selector_t
*src_ts
;
47 * destination traffic selector
49 traffic_selector_t
*dst_ts
;
52 * local host address to be used for IKE
57 * remote host address to be used for IKE
63 * Implementation of job_t.destroy.
65 static void destroy(private_migrate_job_t
*this)
67 DESTROY_IF(this->src_ts
);
68 DESTROY_IF(this->dst_ts
);
69 DESTROY_IF(this->local
);
70 DESTROY_IF(this->remote
);
75 * Implementation of job_t.execute.
77 static void execute(private_migrate_job_t
*this)
79 ike_sa_t
*ike_sa
= NULL
;
83 ike_sa
= charon
->ike_sa_manager
->checkout_by_id(charon
->ike_sa_manager
,
88 enumerator_t
*enumerator
, *children
;
90 child_cfg_t
*found_cfg
= NULL
;
92 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
);
93 while (enumerator
->enumerate(enumerator
, (void**)&peer_cfg
))
95 child_cfg_t
*child_cfg
;
97 if (peer_cfg
->get_ike_version(peer_cfg
) != 2)
102 children
= peer_cfg
->create_child_cfg_enumerator(peer_cfg
);
103 while (children
->enumerate(children
, &child_cfg
))
105 if (child_cfg
->equal_traffic_selectors(child_cfg
, TRUE
, this->src_ts
) &&
106 child_cfg
->equal_traffic_selectors(child_cfg
, FALSE
, this->dst_ts
))
108 found_cfg
= child_cfg
;
112 children
->destroy(children
);
118 enumerator
->destroy(enumerator
);
120 if (found_cfg
== NULL
)
122 DBG1(DBG_JOB
, "no matching child config found for policy %R === %R",
123 this->src_ts
, this->dst_ts
);
127 DBG1(DBG_JOB
, "found matching child config '%s' for policy %R === %R",
128 found_cfg
->get_name(found_cfg
),
129 this->src_ts
, this->dst_ts
);
131 ike_sa
= charon
->ike_sa_manager
->checkout_by_config(charon
->ike_sa_manager
,
133 if (ike_sa
->get_peer_cfg(ike_sa
) == NULL
)
135 host_t
*my_host
, *other_host
;
138 ike_sa
->set_peer_cfg(ike_sa
, peer_cfg
);
139 ike_cfg
= peer_cfg
->get_ike_cfg(peer_cfg
);
140 my_host
= host_create_from_dns(ike_cfg
->get_my_addr(ike_cfg
), 0, 0);
141 other_host
= host_create_from_dns(ike_cfg
->get_other_addr(ike_cfg
), 0, 0);
142 ike_sa
->set_my_host(ike_sa
, my_host
);
143 ike_sa
->set_other_host(ike_sa
, other_host
);
147 ike_sa
->set_my_host(ike_sa
, this->local
->clone(this->local
));
151 ike_sa
->set_other_host(ike_sa
, this->remote
->clone(this->remote
));
153 /* add a CHILD_SA for 'found_cfg' with a policy that has already been
154 * installed in the kernel
159 DBG1(DBG_JOB
, "found CHILD_SA with reqid {%d}", this->reqid
);
162 ike_sa
->set_my_host(ike_sa
, this->local
);
166 ike_sa
->set_other_host(ike_sa
, this->remote
->clone(this->remote
));
169 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
174 * Described in header
176 migrate_job_t
*migrate_job_create(u_int32_t reqid
,
177 traffic_selector_t
*src_ts
,
178 traffic_selector_t
*dst_ts
,
180 host_t
*local
, host_t
*remote
)
182 private_migrate_job_t
*this = malloc_thing(private_migrate_job_t
);
184 /* interface functions */
185 this->public.job_interface
.execute
= (void (*) (job_t
*)) execute
;
186 this->public.job_interface
.destroy
= (void (*)(job_t
*)) destroy
;
188 /* private variables */
190 this->src_ts
= (dir
== POLICY_OUT
) ? src_ts
: dst_ts
;
191 this->dst_ts
= (dir
== POLICY_OUT
) ? dst_ts
: src_ts
;
193 this->remote
= remote
;
195 return &this->public;