]>
Commit | Line | Data |
---|---|---|
17d92e97 MW |
1 | /* |
2 | * Copyright (C) 2007 Martin Willi | |
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. | |
552cc11b MW |
14 | * |
15 | * $Id$ | |
17d92e97 MW |
16 | */ |
17 | ||
18 | #include "ike_mobike.h" | |
19 | ||
20 | #include <string.h> | |
21 | ||
22 | #include <daemon.h> | |
4cb9d7a7 | 23 | #include <sa/tasks/ike_natd.h> |
17d92e97 MW |
24 | #include <encoding/payloads/notify_payload.h> |
25 | ||
85a119bc | 26 | #define COOKIE2_SIZE 16 |
a1466a3e | 27 | #define MAX_ADDITIONAL_ADDRS 8 |
17d92e97 MW |
28 | |
29 | typedef struct private_ike_mobike_t private_ike_mobike_t; | |
30 | ||
31 | /** | |
32 | * Private members of a ike_mobike_t task. | |
33 | */ | |
34 | struct private_ike_mobike_t { | |
35 | ||
36 | /** | |
37 | * Public methods and task_t interface. | |
38 | */ | |
39 | ike_mobike_t public; | |
40 | ||
41 | /** | |
42 | * Assigned IKE_SA. | |
43 | */ | |
44 | ike_sa_t *ike_sa; | |
45 | ||
46 | /** | |
47 | * Are we the initiator? | |
48 | */ | |
49 | bool initiator; | |
50 | ||
51 | /** | |
3bc62fe7 | 52 | * cookie2 value to verify new addresses |
17d92e97 | 53 | */ |
3bc62fe7 | 54 | chunk_t cookie2; |
17d92e97 MW |
55 | |
56 | /** | |
3bc62fe7 | 57 | * NAT discovery reusing the IKE_NATD task |
17d92e97 | 58 | */ |
3bc62fe7 | 59 | ike_natd_t *natd; |
4cb9d7a7 MW |
60 | |
61 | /** | |
3bc62fe7 | 62 | * use task to update addresses |
4cb9d7a7 | 63 | */ |
5474dc65 MW |
64 | bool update; |
65 | ||
66 | /** | |
67 | * do routability check | |
68 | */ | |
69 | bool check; | |
4cb9d7a7 MW |
70 | |
71 | /** | |
3bc62fe7 | 72 | * include address list update |
4cb9d7a7 | 73 | */ |
3bc62fe7 | 74 | bool address; |
17d92e97 MW |
75 | }; |
76 | ||
77 | /** | |
78 | * flush the IKE_SAs list of additional addresses | |
79 | */ | |
80 | static void flush_additional_addresses(private_ike_mobike_t *this) | |
81 | { | |
82 | iterator_t *iterator; | |
83 | host_t *host; | |
84 | ||
85 | iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa); | |
86 | while (iterator->iterate(iterator, (void**)&host)) | |
87 | { | |
88 | iterator->remove(iterator); | |
89 | host->destroy(host); | |
90 | } | |
91 | iterator->destroy(iterator); | |
92 | } | |
93 | ||
94 | ||
95 | /** | |
96 | * read notifys from message and evaluate them | |
97 | */ | |
98 | static void process_payloads(private_ike_mobike_t *this, message_t *message) | |
99 | { | |
100 | iterator_t *iterator; | |
101 | payload_t *payload; | |
102 | bool first = TRUE; | |
103 | ||
104 | iterator = message->get_payload_iterator(message); | |
105 | while (iterator->iterate(iterator, (void**)&payload)) | |
106 | { | |
107 | int family = AF_INET; | |
108 | notify_payload_t *notify; | |
109 | chunk_t data; | |
110 | host_t *host; | |
111 | ||
112 | if (payload->get_type(payload) != NOTIFY) | |
113 | { | |
114 | continue; | |
115 | } | |
116 | notify = (notify_payload_t*)payload; | |
117 | switch (notify->get_notify_type(notify)) | |
118 | { | |
119 | case MOBIKE_SUPPORTED: | |
120 | { | |
78279973 MW |
121 | peer_cfg_t *peer_cfg; |
122 | ||
123 | peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); | |
124 | if (!this->initiator && | |
125 | peer_cfg && !peer_cfg->use_mobike(peer_cfg)) | |
126 | { | |
127 | DBG1(DBG_IKE, "peer supports MOBIKE, but disabled in config"); | |
128 | } | |
129 | else | |
130 | { | |
131 | DBG1(DBG_IKE, "peer supports MOBIKE"); | |
132 | this->ike_sa->enable_extension(this->ike_sa, EXT_MOBIKE); | |
133 | } | |
17d92e97 MW |
134 | break; |
135 | } | |
85a119bc MW |
136 | case COOKIE2: |
137 | { | |
138 | chunk_free(&this->cookie2); | |
139 | this->cookie2 = chunk_clone(notify->get_notification_data(notify)); | |
140 | break; | |
141 | } | |
17d92e97 MW |
142 | case ADDITIONAL_IP6_ADDRESS: |
143 | { | |
144 | family = AF_INET6; | |
145 | /* fall through */ | |
146 | } | |
147 | case ADDITIONAL_IP4_ADDRESS: | |
148 | { | |
149 | if (first) | |
150 | { /* an ADDITIONAL_*_ADDRESS means replace, so flush once */ | |
151 | flush_additional_addresses(this); | |
4cb9d7a7 | 152 | first = FALSE; |
17d92e97 MW |
153 | } |
154 | data = notify->get_notification_data(notify); | |
155 | host = host_create_from_chunk(family, data, 0); | |
156 | DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host); | |
157 | this->ike_sa->add_additional_address(this->ike_sa, host); | |
158 | break; | |
159 | } | |
3bc62fe7 MW |
160 | case UPDATE_SA_ADDRESSES: |
161 | { | |
5474dc65 | 162 | this->update = TRUE; |
3bc62fe7 MW |
163 | break; |
164 | } | |
17d92e97 MW |
165 | case NO_ADDITIONAL_ADDRESSES: |
166 | { | |
167 | flush_additional_addresses(this); | |
168 | break; | |
169 | } | |
fc2d1c42 MW |
170 | case NAT_DETECTION_SOURCE_IP: |
171 | case NAT_DETECTION_DESTINATION_IP: | |
172 | { | |
173 | /* NAT check in this MOBIKE exchange, create subtask for it */ | |
174 | if (this->natd == NULL) | |
175 | { | |
176 | this->natd = ike_natd_create(this->ike_sa, this->initiator); | |
177 | } | |
178 | break; | |
179 | } | |
17d92e97 MW |
180 | default: |
181 | break; | |
182 | } | |
183 | } | |
184 | iterator->destroy(iterator); | |
185 | } | |
186 | ||
187 | /** | |
188 | * Add ADDITIONAL_*_ADDRESS notifys depending on our address list | |
189 | */ | |
190 | static void build_address_list(private_ike_mobike_t *this, message_t *message) | |
191 | { | |
507f26f6 | 192 | enumerator_t *enumerator; |
17d92e97 MW |
193 | host_t *host, *me; |
194 | notify_type_t type; | |
a1466a3e MW |
195 | int added = 0; |
196 | ||
17d92e97 | 197 | me = this->ike_sa->get_my_host(this->ike_sa); |
507f26f6 TB |
198 | enumerator = charon->kernel_interface->create_address_enumerator( |
199 | charon->kernel_interface, FALSE, FALSE); | |
200 | while (enumerator->enumerate(enumerator, (void**)&host)) | |
17d92e97 MW |
201 | { |
202 | if (me->ip_equals(me, host)) | |
203 | { /* "ADDITIONAL" means do not include IKE_SAs host */ | |
204 | continue; | |
205 | } | |
206 | switch (host->get_family(host)) | |
207 | { | |
208 | case AF_INET: | |
209 | type = ADDITIONAL_IP4_ADDRESS; | |
210 | break; | |
211 | case AF_INET6: | |
212 | type = ADDITIONAL_IP6_ADDRESS; | |
213 | break; | |
214 | default: | |
215 | continue; | |
216 | } | |
217 | message->add_notify(message, FALSE, type, host->get_address(host)); | |
a1466a3e MW |
218 | if (++added >= MAX_ADDITIONAL_ADDRS) |
219 | { /* limit number of notifys, some implementations do not like too | |
220 | * many of them (f.e. strongSwan ;-) */ | |
221 | break; | |
222 | } | |
17d92e97 | 223 | } |
a1466a3e | 224 | if (!added) |
17d92e97 MW |
225 | { |
226 | message->add_notify(message, FALSE, NO_ADDITIONAL_ADDRESSES, chunk_empty); | |
227 | } | |
507f26f6 | 228 | enumerator->destroy(enumerator); |
17d92e97 MW |
229 | } |
230 | ||
85a119bc MW |
231 | /** |
232 | * build a cookie and add it to the message | |
233 | */ | |
234 | static void build_cookie(private_ike_mobike_t *this, message_t *message) | |
235 | { | |
236 | rng_t *rng; | |
237 | ||
238 | chunk_free(&this->cookie2); | |
239 | rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); | |
240 | if (rng) | |
241 | { | |
242 | rng->allocate_bytes(rng, COOKIE2_SIZE, &this->cookie2); | |
243 | rng->destroy(rng); | |
244 | message->add_notify(message, FALSE, COOKIE2, this->cookie2); | |
245 | } | |
246 | } | |
247 | ||
3bc62fe7 MW |
248 | /** |
249 | * update addresses of associated CHILD_SAs | |
250 | */ | |
251 | static void update_children(private_ike_mobike_t *this) | |
252 | { | |
253 | iterator_t *iterator; | |
254 | child_sa_t *child_sa; | |
255 | ||
256 | iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa); | |
257 | while (iterator->iterate(iterator, (void**)&child_sa)) | |
258 | { | |
3aaf7908 | 259 | if (child_sa->update(child_sa, |
ea625fab TB |
260 | this->ike_sa->get_my_host(this->ike_sa), |
261 | this->ike_sa->get_other_host(this->ike_sa), | |
262 | this->ike_sa->get_virtual_ip(this->ike_sa, TRUE), | |
263 | this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED) | |
264 | { | |
265 | this->ike_sa->rekey_child_sa(this->ike_sa, | |
266 | child_sa->get_protocol(child_sa), | |
267 | child_sa->get_spi(child_sa, TRUE)); | |
268 | } | |
3bc62fe7 MW |
269 | } |
270 | iterator->destroy(iterator); | |
271 | } | |
272 | ||
5474dc65 MW |
273 | /** |
274 | * Implementation of ike_mobike_t.transmit | |
275 | */ | |
276 | static void transmit(private_ike_mobike_t *this, packet_t *packet) | |
277 | { | |
278 | host_t *me, *other, *me_old, *other_old; | |
279 | iterator_t *iterator; | |
280 | packet_t *copy; | |
281 | ||
282 | if (!this->check) | |
283 | { | |
284 | return; | |
285 | } | |
286 | ||
287 | me_old = this->ike_sa->get_my_host(this->ike_sa); | |
288 | other_old = this->ike_sa->get_other_host(this->ike_sa); | |
289 | ||
290 | me = charon->kernel_interface->get_source_addr( | |
ce5b1708 | 291 | charon->kernel_interface, other_old, NULL); |
5474dc65 MW |
292 | if (me) |
293 | { | |
294 | me->set_port(me, me->ip_equals(me, me_old) ? | |
295 | me_old->get_port(me_old) : IKEV2_NATT_PORT); | |
296 | packet->set_source(packet, me); | |
297 | } | |
298 | ||
299 | iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa); | |
300 | while (iterator->iterate(iterator, (void**)&other)) | |
301 | { | |
302 | me = charon->kernel_interface->get_source_addr( | |
ce5b1708 | 303 | charon->kernel_interface, other, NULL); |
5474dc65 MW |
304 | if (me) |
305 | { | |
de3d65a1 MW |
306 | if (me->get_family(me) != other->get_family(other)) |
307 | { | |
308 | me->destroy(me); | |
309 | continue; | |
310 | } | |
5474dc65 MW |
311 | /* reuse port for an active address, 4500 otherwise */ |
312 | me->set_port(me, me->ip_equals(me, me_old) ? | |
313 | me_old->get_port(me_old) : IKEV2_NATT_PORT); | |
314 | other = other->clone(other); | |
315 | other->set_port(other, other->ip_equals(other, other_old) ? | |
316 | other_old->get_port(other_old) : IKEV2_NATT_PORT); | |
d9d69536 | 317 | DBG1(DBG_IKE, "checking path %#H - %#H", me, other); |
5474dc65 MW |
318 | copy = packet->clone(packet); |
319 | copy->set_source(copy, me); | |
320 | copy->set_destination(copy, other); | |
321 | charon->sender->send(charon->sender, copy); | |
322 | } | |
323 | } | |
324 | iterator->destroy(iterator); | |
d9d69536 MW |
325 | me = packet->get_source(packet); |
326 | other = packet->get_destination(packet); | |
327 | DBG1(DBG_IKE, "checking path %#H - %#H", me, other); | |
5474dc65 MW |
328 | } |
329 | ||
17d92e97 MW |
330 | /** |
331 | * Implementation of task_t.process for initiator | |
332 | */ | |
333 | static status_t build_i(private_ike_mobike_t *this, message_t *message) | |
334 | { | |
335 | if (message->get_exchange_type(message) == IKE_AUTH && | |
b8249ff5 | 336 | message->get_payload(message, ID_INITIATOR)) |
4cb9d7a7 | 337 | { |
17d92e97 MW |
338 | message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty); |
339 | build_address_list(this, message); | |
340 | } | |
c8739590 | 341 | else if (message->get_exchange_type(message) == INFORMATIONAL) |
3bc62fe7 | 342 | { |
f0974eb2 MW |
343 | host_t *old, *new; |
344 | ||
345 | /* we check if the existing address is still valid */ | |
346 | old = message->get_source(message); | |
347 | new = charon->kernel_interface->get_source_addr(charon->kernel_interface, | |
348 | message->get_destination(message), old); | |
349 | if (new) | |
350 | { | |
351 | if (!new->ip_equals(new, old)) | |
352 | { | |
353 | new->set_port(new, old->get_port(old)); | |
354 | message->set_source(message, new); | |
355 | } | |
356 | else | |
357 | { | |
358 | new->destroy(new); | |
359 | } | |
360 | } | |
5474dc65 | 361 | if (this->update) |
fc2d1c42 | 362 | { |
3bc62fe7 | 363 | message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty); |
85a119bc | 364 | build_cookie(this, message); |
5474dc65 | 365 | update_children(this); |
fc2d1c42 | 366 | } |
3bc62fe7 MW |
367 | if (this->address) |
368 | { | |
369 | build_address_list(this, message); | |
370 | } | |
5474dc65 MW |
371 | if (this->natd) |
372 | { | |
373 | this->natd->task.build(&this->natd->task, message); | |
374 | } | |
4cb9d7a7 | 375 | } |
17d92e97 MW |
376 | return NEED_MORE; |
377 | } | |
378 | ||
379 | /** | |
380 | * Implementation of task_t.process for responder | |
381 | */ | |
382 | static status_t process_r(private_ike_mobike_t *this, message_t *message) | |
4cb9d7a7 | 383 | { |
fc2d1c42 | 384 | if (message->get_exchange_type(message) == IKE_AUTH && |
b8249ff5 | 385 | message->get_payload(message, ID_INITIATOR)) |
4cb9d7a7 MW |
386 | { |
387 | process_payloads(this, message); | |
388 | } | |
fc2d1c42 MW |
389 | else if (message->get_exchange_type(message) == INFORMATIONAL) |
390 | { | |
391 | process_payloads(this, message); | |
5474dc65 | 392 | if (this->update) |
3bc62fe7 MW |
393 | { |
394 | host_t *me, *other; | |
395 | ||
396 | me = message->get_destination(message); | |
397 | other = message->get_source(message); | |
398 | this->ike_sa->set_my_host(this->ike_sa, me->clone(me)); | |
399 | this->ike_sa->set_other_host(this->ike_sa, other->clone(other)); | |
400 | } | |
401 | ||
fc2d1c42 MW |
402 | if (this->natd) |
403 | { | |
404 | this->natd->task.process(&this->natd->task, message); | |
405 | } | |
406 | } | |
17d92e97 MW |
407 | return NEED_MORE; |
408 | } | |
409 | ||
410 | /** | |
411 | * Implementation of task_t.build for responder | |
412 | */ | |
413 | static status_t build_r(private_ike_mobike_t *this, message_t *message) | |
414 | { | |
415 | if (message->get_exchange_type(message) == IKE_AUTH && | |
b8249ff5 | 416 | this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) |
17d92e97 MW |
417 | { |
418 | if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) | |
419 | { | |
420 | message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty); | |
421 | build_address_list(this, message); | |
422 | } | |
423 | return SUCCESS; | |
424 | } | |
2b3100b5 MW |
425 | else if (message->get_exchange_type(message) == INFORMATIONAL) |
426 | { | |
fc2d1c42 MW |
427 | if (this->natd) |
428 | { | |
429 | this->natd->task.build(&this->natd->task, message); | |
430 | } | |
85a119bc MW |
431 | if (this->cookie2.ptr) |
432 | { | |
433 | message->add_notify(message, FALSE, COOKIE2, this->cookie2); | |
434 | chunk_free(&this->cookie2); | |
435 | } | |
5474dc65 | 436 | if (this->update) |
3bc62fe7 MW |
437 | { |
438 | update_children(this); | |
439 | } | |
2b3100b5 MW |
440 | return SUCCESS; |
441 | } | |
17d92e97 MW |
442 | return NEED_MORE; |
443 | } | |
444 | ||
445 | /** | |
446 | * Implementation of task_t.process for initiator | |
447 | */ | |
448 | static status_t process_i(private_ike_mobike_t *this, message_t *message) | |
449 | { | |
450 | if (message->get_exchange_type(message) == IKE_AUTH && | |
b8249ff5 | 451 | this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) |
17d92e97 MW |
452 | { |
453 | process_payloads(this, message); | |
454 | return SUCCESS; | |
455 | } | |
2b3100b5 MW |
456 | else if (message->get_exchange_type(message) == INFORMATIONAL) |
457 | { | |
3bc62fe7 MW |
458 | u_int32_t updates = this->ike_sa->get_pending_updates(this->ike_sa) - 1; |
459 | this->ike_sa->set_pending_updates(this->ike_sa, updates); | |
460 | if (updates > 0) | |
461 | { | |
462 | /* newer update queued, ignore this one */ | |
463 | return SUCCESS; | |
464 | } | |
85a119bc | 465 | if (this->cookie2.ptr) |
9d9a772e | 466 | { /* check cookie if we included one */ |
85a119bc MW |
467 | chunk_t cookie2; |
468 | ||
469 | cookie2 = this->cookie2; | |
470 | this->cookie2 = chunk_empty; | |
471 | process_payloads(this, message); | |
472 | if (!chunk_equals(cookie2, this->cookie2)) | |
473 | { | |
474 | chunk_free(&cookie2); | |
475 | DBG1(DBG_IKE, "COOKIE2 mismatch, closing IKE_SA"); | |
476 | return FAILED; | |
477 | } | |
478 | chunk_free(&cookie2); | |
479 | } | |
480 | else | |
481 | { | |
482 | process_payloads(this, message); | |
483 | } | |
fc2d1c42 MW |
484 | if (this->natd) |
485 | { | |
486 | this->natd->task.process(&this->natd->task, message); | |
9d9a772e MW |
487 | if (this->natd->has_mapping_changed(this->natd)) |
488 | { | |
489 | /* force an update if mappings have changed */ | |
490 | this->update = this->check = TRUE; | |
491 | DBG1(DBG_IKE, "detected changes in NAT mappings, " | |
492 | "initiating MOBIKE update"); | |
493 | } | |
fc2d1c42 | 494 | } |
5474dc65 | 495 | if (this->update) |
3bc62fe7 MW |
496 | { |
497 | /* update again, as NAT state may have changed */ | |
498 | update_children(this); | |
499 | } | |
5474dc65 MW |
500 | if (this->check) |
501 | { | |
502 | host_t *me_new, *me_old, *other_new, *other_old; | |
503 | ||
504 | me_new = message->get_destination(message); | |
505 | other_new = message->get_source(message); | |
506 | me_old = this->ike_sa->get_my_host(this->ike_sa); | |
507 | other_old = this->ike_sa->get_other_host(this->ike_sa); | |
508 | ||
509 | if (!me_new->equals(me_new, me_old)) | |
510 | { | |
511 | this->update = TRUE; | |
512 | this->ike_sa->set_my_host(this->ike_sa, me_new->clone(me_new)); | |
513 | } | |
514 | if (!other_new->equals(other_new, other_old)) | |
515 | { | |
516 | this->update = TRUE; | |
517 | this->ike_sa->set_other_host(this->ike_sa, other_new->clone(other_new)); | |
518 | } | |
519 | if (this->update) | |
520 | { | |
521 | /* start the update with the same task */ | |
522 | this->check = FALSE; | |
523 | this->address = FALSE; | |
12d4186f MW |
524 | if (this->natd) |
525 | { | |
526 | this->natd->task.destroy(&this->natd->task); | |
527 | } | |
12fa4387 | 528 | this->natd = ike_natd_create(this->ike_sa, this->initiator); |
5474dc65 MW |
529 | this->ike_sa->set_pending_updates(this->ike_sa, 1); |
530 | return NEED_MORE; | |
531 | } | |
532 | } | |
2b3100b5 MW |
533 | return SUCCESS; |
534 | } | |
17d92e97 MW |
535 | return NEED_MORE; |
536 | } | |
537 | ||
538 | /** | |
539 | * Implementation of ike_mobike_t.roam. | |
540 | */ | |
3bc62fe7 | 541 | static void roam(private_ike_mobike_t *this, bool address) |
17d92e97 | 542 | { |
5474dc65 | 543 | this->check = TRUE; |
3bc62fe7 MW |
544 | this->address = address; |
545 | this->ike_sa->set_pending_updates(this->ike_sa, | |
546 | this->ike_sa->get_pending_updates(this->ike_sa) + 1); | |
17d92e97 MW |
547 | } |
548 | ||
9d9a772e MW |
549 | /** |
550 | * Implementation of ike_mobike_t.dpd | |
551 | */ | |
552 | static void dpd(private_ike_mobike_t *this) | |
553 | { | |
554 | if (!this->natd) | |
555 | { | |
556 | this->natd = ike_natd_create(this->ike_sa, this->initiator); | |
557 | } | |
558 | this->address = FALSE; | |
559 | this->ike_sa->set_pending_updates(this->ike_sa, | |
560 | this->ike_sa->get_pending_updates(this->ike_sa) + 1); | |
561 | } | |
562 | ||
f215e919 MW |
563 | /** |
564 | * Implementation of ike_mobike_t.is_probing. | |
565 | */ | |
566 | static bool is_probing(private_ike_mobike_t *this) | |
567 | { | |
568 | return this->check; | |
569 | } | |
570 | ||
17d92e97 MW |
571 | /** |
572 | * Implementation of task_t.get_type | |
573 | */ | |
574 | static task_type_t get_type(private_ike_mobike_t *this) | |
575 | { | |
576 | return IKE_MOBIKE; | |
577 | } | |
578 | ||
579 | /** | |
580 | * Implementation of task_t.migrate | |
581 | */ | |
582 | static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa) | |
583 | { | |
4cb9d7a7 | 584 | chunk_free(&this->cookie2); |
17d92e97 | 585 | this->ike_sa = ike_sa; |
4cb9d7a7 MW |
586 | if (this->natd) |
587 | { | |
588 | this->natd->task.migrate(&this->natd->task, ike_sa); | |
589 | } | |
17d92e97 MW |
590 | } |
591 | ||
592 | /** | |
593 | * Implementation of task_t.destroy | |
594 | */ | |
595 | static void destroy(private_ike_mobike_t *this) | |
596 | { | |
4cb9d7a7 MW |
597 | chunk_free(&this->cookie2); |
598 | if (this->natd) | |
599 | { | |
600 | this->natd->task.destroy(&this->natd->task); | |
601 | } | |
17d92e97 MW |
602 | free(this); |
603 | } | |
604 | ||
605 | /* | |
606 | * Described in header. | |
607 | */ | |
608 | ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator) | |
609 | { | |
610 | private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t); | |
611 | ||
3bc62fe7 | 612 | this->public.roam = (void(*)(ike_mobike_t*,bool))roam; |
9d9a772e | 613 | this->public.dpd = (void(*)(ike_mobike_t*))dpd; |
5474dc65 | 614 | this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit; |
f215e919 | 615 | this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing; |
17d92e97 MW |
616 | this->public.task.get_type = (task_type_t(*)(task_t*))get_type; |
617 | this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; | |
618 | this->public.task.destroy = (void(*)(task_t*))destroy; | |
619 | ||
620 | if (initiator) | |
621 | { | |
622 | this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; | |
623 | this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; | |
624 | } | |
625 | else | |
626 | { | |
627 | this->public.task.build = (status_t(*)(task_t*,message_t*))build_r; | |
628 | this->public.task.process = (status_t(*)(task_t*,message_t*))process_r; | |
629 | } | |
630 | ||
631 | this->ike_sa = ike_sa; | |
632 | this->initiator = initiator; | |
5474dc65 MW |
633 | this->update = FALSE; |
634 | this->check = FALSE; | |
3bc62fe7 | 635 | this->address = TRUE; |
4cb9d7a7 MW |
636 | this->cookie2 = chunk_empty; |
637 | this->natd = NULL; | |
17d92e97 MW |
638 | |
639 | return &this->public; | |
640 | } | |
641 |