refactored and cleaned up child_sa interface
[strongswan.git] / src / charon / processing / jobs / migrate_job.c
1 /*
2 * Copyright (C) 2008 Andreas Steffen
3 * Hochschule fuer Technik Rapperswil
4 *
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>.
9 *
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
13 * for more details.
14 *
15 * $Id$
16 */
17
18 #include "migrate_job.h"
19
20 #include <daemon.h>
21
22 #include <config/child_cfg.h>
23
24
25 typedef struct private_migrate_job_t private_migrate_job_t;
26
27 /**
28 * Private data of a migrate_job_t object.
29 */
30 struct private_migrate_job_t {
31 /**
32 * Public migrate_job_t interface.
33 */
34 migrate_job_t public;
35
36 /**
37 * reqid of the CHILD_SA if it already exists
38 */
39 u_int32_t reqid;
40
41 /**
42 * source traffic selector
43 */
44 traffic_selector_t *src_ts;
45
46 /**
47 * destination traffic selector
48 */
49 traffic_selector_t *dst_ts;
50
51 /**
52 * local host address to be used for IKE
53 */
54 host_t *local;
55
56 /**
57 * remote host address to be used for IKE
58 */
59 host_t *remote;
60 };
61
62 /**
63 * Implementation of job_t.destroy.
64 */
65 static void destroy(private_migrate_job_t *this)
66 {
67 DESTROY_IF(this->src_ts);
68 DESTROY_IF(this->dst_ts);
69 DESTROY_IF(this->local);
70 DESTROY_IF(this->remote);
71 free(this);
72 }
73
74 /**
75 * Implementation of job_t.execute.
76 */
77 static void execute(private_migrate_job_t *this)
78 {
79 ike_sa_t *ike_sa = NULL;
80
81 if (this->reqid)
82 {
83 ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
84 this->reqid, TRUE);
85 }
86 if (ike_sa)
87 {
88 iterator_t *children;
89 child_sa_t *child_sa;
90 host_t *host;
91
92 children = ike_sa->create_child_sa_iterator(ike_sa);
93 while (children->iterate(children, (void**)&child_sa))
94 {
95 if (child_sa->get_reqid(child_sa) == this->reqid)
96 {
97 break;
98 }
99 }
100 children->destroy(children);
101 DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid);
102
103 ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
104
105 host = this->local->clone(this->local);
106 host->set_port(host, IKEV2_UDP_PORT);
107 ike_sa->set_my_host(ike_sa, host);
108
109 host = this->remote->clone(this->remote);
110 host->set_port(host, IKEV2_UDP_PORT);
111 ike_sa->set_other_host(ike_sa, host);
112
113 if (child_sa->update(child_sa, this->local, this->remote,
114 ike_sa->get_virtual_ip(ike_sa, TRUE),
115 ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
116 {
117 ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
118 child_sa->get_spi(child_sa, TRUE));
119 }
120 charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
121 }
122 else
123 {
124 DBG1(DBG_JOB, "no CHILD_SA found with reqid {%d}", this->reqid);
125 }
126 destroy(this);
127 }
128
129 /*
130 * Described in header
131 */
132 migrate_job_t *migrate_job_create(u_int32_t reqid,
133 traffic_selector_t *src_ts,
134 traffic_selector_t *dst_ts,
135 policy_dir_t dir,
136 host_t *local, host_t *remote)
137 {
138 private_migrate_job_t *this = malloc_thing(private_migrate_job_t);
139
140 /* interface functions */
141 this->public.job_interface.execute = (void (*) (job_t *)) execute;
142 this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
143
144 /* private variables */
145 this->reqid = reqid;
146 this->src_ts = (dir == POLICY_OUT) ? src_ts : dst_ts;
147 this->dst_ts = (dir == POLICY_OUT) ? dst_ts : src_ts;
148 this->local = local;
149 this->remote = remote;
150
151 return &this->public;
152 }