]> git.ipfire.org Git - people/ms/strongswan.git/blame - src/libcharon/sa/ikev2/tasks/ike_mobike.c
ike-mobike: Make task a no-op if MOBIKE is not supported
[people/ms/strongswan.git] / src / libcharon / sa / ikev2 / tasks / ike_mobike.c
CommitLineData
17d92e97 1/*
2b255f01 2 * Copyright (C) 2010-2020 Tobias Brunner
17d92e97 3 * Copyright (C) 2007 Martin Willi
9f049781 4 * HSR Hochschule fuer Technik Rapperswil
17d92e97
MW
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17#include "ike_mobike.h"
18
19#include <string.h>
20
21#include <daemon.h>
15a682f4 22#include <sa/ikev2/tasks/ike_natd.h>
17d92e97
MW
23#include <encoding/payloads/notify_payload.h>
24
85a119bc 25#define COOKIE2_SIZE 16
a1466a3e 26#define MAX_ADDITIONAL_ADDRS 8
17d92e97
MW
27
28typedef struct private_ike_mobike_t private_ike_mobike_t;
29
30/**
31 * Private members of a ike_mobike_t task.
32 */
33struct private_ike_mobike_t {
7daf5226 34
17d92e97
MW
35 /**
36 * Public methods and task_t interface.
37 */
38 ike_mobike_t public;
7daf5226 39
17d92e97
MW
40 /**
41 * Assigned IKE_SA.
42 */
43 ike_sa_t *ike_sa;
7daf5226 44
17d92e97
MW
45 /**
46 * Are we the initiator?
47 */
48 bool initiator;
7daf5226 49
17d92e97 50 /**
3bc62fe7 51 * cookie2 value to verify new addresses
17d92e97 52 */
3bc62fe7 53 chunk_t cookie2;
7daf5226 54
17d92e97 55 /**
a09972df 56 * NAT discovery reusing the TASK_IKE_NATD task
17d92e97 57 */
3bc62fe7 58 ike_natd_t *natd;
7daf5226 59
4cb9d7a7 60 /**
3bc62fe7 61 * use task to update addresses
4cb9d7a7 62 */
5474dc65 63 bool update;
7daf5226 64
5474dc65
MW
65 /**
66 * do routability check
67 */
68 bool check;
7daf5226 69
4cb9d7a7 70 /**
3bc62fe7 71 * include address list update
4cb9d7a7 72 */
3bc62fe7 73 bool address;
769c69fa
TB
74
75 /**
76 * additional addresses got updated
77 */
78 bool addresses_updated;
17d92e97
MW
79};
80
9f049781
TB
81/**
82 * Check if a newer MOBIKE update task is queued
83 */
84static bool is_newer_update_queued(private_ike_mobike_t *this)
85{
86 enumerator_t *enumerator;
87 private_ike_mobike_t *mobike;
88 task_t *task;
89 bool found = FALSE;
90
91 enumerator = this->ike_sa->create_task_enumerator(this->ike_sa,
92 TASK_QUEUE_QUEUED);
93 while (enumerator->enumerate(enumerator, &task))
94 {
95 if (task->get_type(task) == TASK_IKE_MOBIKE)
96 {
97 mobike = (private_ike_mobike_t*)task;
98 /* a queued check or update might invalidate the results of the
99 * current task */
100 found = mobike->check || mobike->update;
101 break;
102 }
103 }
104 enumerator->destroy(enumerator);
105 return found;
106}
107
17d92e97
MW
108/**
109 * read notifys from message and evaluate them
110 */
111static void process_payloads(private_ike_mobike_t *this, message_t *message)
112{
a44bb934 113 enumerator_t *enumerator;
17d92e97
MW
114 payload_t *payload;
115 bool first = TRUE;
7daf5226 116
a44bb934
MW
117 enumerator = message->create_payload_enumerator(message);
118 while (enumerator->enumerate(enumerator, &payload))
17d92e97
MW
119 {
120 int family = AF_INET;
121 notify_payload_t *notify;
122 chunk_t data;
123 host_t *host;
7daf5226 124
3ecfc83c 125 if (payload->get_type(payload) != PLV2_NOTIFY)
17d92e97
MW
126 {
127 continue;
128 }
129 notify = (notify_payload_t*)payload;
130 switch (notify->get_notify_type(notify))
131 {
132 case MOBIKE_SUPPORTED:
133 {
78279973 134 peer_cfg_t *peer_cfg;
7daf5226 135
78279973 136 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
7daf5226 137 if (!this->initiator &&
78279973
MW
138 peer_cfg && !peer_cfg->use_mobike(peer_cfg))
139 {
140 DBG1(DBG_IKE, "peer supports MOBIKE, but disabled in config");
141 }
142 else
143 {
144 DBG1(DBG_IKE, "peer supports MOBIKE");
145 this->ike_sa->enable_extension(this->ike_sa, EXT_MOBIKE);
146 }
17d92e97
MW
147 break;
148 }
85a119bc
MW
149 case COOKIE2:
150 {
151 chunk_free(&this->cookie2);
152 this->cookie2 = chunk_clone(notify->get_notification_data(notify));
153 break;
154 }
17d92e97
MW
155 case ADDITIONAL_IP6_ADDRESS:
156 {
157 family = AF_INET6;
158 /* fall through */
159 }
160 case ADDITIONAL_IP4_ADDRESS:
161 {
162 if (first)
163 { /* an ADDITIONAL_*_ADDRESS means replace, so flush once */
94bbc602 164 this->ike_sa->clear_peer_addresses(this->ike_sa);
4cb9d7a7 165 first = FALSE;
2fe624cc 166 /* add the peer's current address to the list */
53915f14 167 host = message->get_source(message);
94bbc602
TB
168 this->ike_sa->add_peer_address(this->ike_sa,
169 host->clone(host));
17d92e97
MW
170 }
171 data = notify->get_notification_data(notify);
172 host = host_create_from_chunk(family, data, 0);
173 DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host);
94bbc602 174 this->ike_sa->add_peer_address(this->ike_sa, host);
769c69fa 175 this->addresses_updated = TRUE;
17d92e97
MW
176 break;
177 }
3bc62fe7
MW
178 case UPDATE_SA_ADDRESSES:
179 {
5474dc65 180 this->update = TRUE;
3bc62fe7
MW
181 break;
182 }
17d92e97
MW
183 case NO_ADDITIONAL_ADDRESSES:
184 {
94bbc602 185 this->ike_sa->clear_peer_addresses(this->ike_sa);
2fe624cc 186 /* add the peer's current address to the list */
53915f14 187 host = message->get_source(message);
94bbc602 188 this->ike_sa->add_peer_address(this->ike_sa, host->clone(host));
769c69fa 189 this->addresses_updated = TRUE;
17d92e97
MW
190 break;
191 }
fc2d1c42
MW
192 case NAT_DETECTION_SOURCE_IP:
193 case NAT_DETECTION_DESTINATION_IP:
194 {
195 /* NAT check in this MOBIKE exchange, create subtask for it */
3a05566d 196 if (!this->natd)
fc2d1c42
MW
197 {
198 this->natd = ike_natd_create(this->ike_sa, this->initiator);
199 }
200 break;
201 }
17d92e97
MW
202 default:
203 break;
204 }
205 }
a44bb934 206 enumerator->destroy(enumerator);
17d92e97
MW
207}
208
209/**
210 * Add ADDITIONAL_*_ADDRESS notifys depending on our address list
211 */
212static void build_address_list(private_ike_mobike_t *this, message_t *message)
213{
507f26f6 214 enumerator_t *enumerator;
17d92e97
MW
215 host_t *host, *me;
216 notify_type_t type;
a1466a3e 217 int added = 0;
7daf5226 218
17d92e97 219 me = this->ike_sa->get_my_host(this->ike_sa);
8394ea2a
TB
220 enumerator = charon->kernel->create_address_enumerator(charon->kernel,
221 ADDR_TYPE_REGULAR);
507f26f6 222 while (enumerator->enumerate(enumerator, (void**)&host))
17d92e97
MW
223 {
224 if (me->ip_equals(me, host))
225 { /* "ADDITIONAL" means do not include IKE_SAs host */
226 continue;
227 }
228 switch (host->get_family(host))
229 {
230 case AF_INET:
231 type = ADDITIONAL_IP4_ADDRESS;
232 break;
233 case AF_INET6:
234 type = ADDITIONAL_IP6_ADDRESS;
235 break;
236 default:
237 continue;
238 }
239 message->add_notify(message, FALSE, type, host->get_address(host));
a1466a3e
MW
240 if (++added >= MAX_ADDITIONAL_ADDRS)
241 { /* limit number of notifys, some implementations do not like too
242 * many of them (f.e. strongSwan ;-) */
243 break;
244 }
17d92e97 245 }
a1466a3e 246 if (!added)
17d92e97
MW
247 {
248 message->add_notify(message, FALSE, NO_ADDITIONAL_ADDRESSES, chunk_empty);
249 }
507f26f6 250 enumerator->destroy(enumerator);
17d92e97
MW
251}
252
85a119bc 253/**
7daf5226 254 * build a cookie and add it to the message
85a119bc 255 */
50491834 256static bool build_cookie(private_ike_mobike_t *this, message_t *message)
85a119bc
MW
257{
258 rng_t *rng;
259
260 chunk_free(&this->cookie2);
261 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
50491834 262 if (!rng || !rng->allocate_bytes(rng, COOKIE2_SIZE, &this->cookie2))
85a119bc 263 {
50491834
TB
264 DESTROY_IF(rng);
265 return FALSE;
85a119bc 266 }
50491834
TB
267 message->add_notify(message, FALSE, COOKIE2, this->cookie2);
268 rng->destroy(rng);
269 return TRUE;
85a119bc
MW
270}
271
cc2eadde 272/**
be901342 273 * Apply the port of the old host, if its ip equals the new, use port otherwise.
cc2eadde 274 */
b12c53ce 275static void apply_port(host_t *host, host_t *old, uint16_t port, bool local)
cc2eadde
MW
276{
277 if (host->ip_equals(host, old))
278 {
be901342 279 port = old->get_port(old);
cc2eadde 280 }
b223d517 281 else if (local && port == charon->socket->get_port(charon->socket, FALSE))
cc2eadde 282 {
b223d517
TB
283 port = charon->socket->get_port(charon->socket, TRUE);
284 }
285 else if (!local && port == IKEV2_UDP_PORT)
286 {
287 port = IKEV2_NATT_PORT;
cc2eadde 288 }
be901342 289 host->set_port(host, port);
cc2eadde
MW
290}
291
7840952e 292METHOD(ike_mobike_t, transmit, bool,
c817e7bb 293 private_ike_mobike_t *this, packet_t *packet)
5474dc65
MW
294{
295 host_t *me, *other, *me_old, *other_old;
572abc6c 296 enumerator_t *enumerator;
cc2eadde 297 ike_cfg_t *ike_cfg;
5474dc65 298 packet_t *copy;
c5a5bc85 299 int family = AF_UNSPEC;
7840952e 300 bool found = FALSE;
7daf5226 301
8956dcec
TB
302 me_old = this->ike_sa->get_my_host(this->ike_sa);
303 other_old = this->ike_sa->get_other_host(this->ike_sa);
304 ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
305
5474dc65
MW
306 if (!this->check)
307 {
8394ea2a 308 me = charon->kernel->get_source_addr(charon->kernel, other_old, me_old);
8956dcec
TB
309 if (me)
310 {
311 if (me->ip_equals(me, me_old))
312 {
72cc029e
TB
313 copy = packet->clone(packet);
314 /* hosts might have been updated by a peer's MOBIKE exchange */
315 copy->set_source(copy, me_old->clone(me_old));
316 copy->set_destination(copy, other_old->clone(other_old));
317 charon->sender->send(charon->sender, copy);
8956dcec
TB
318 me->destroy(me);
319 return TRUE;
320 }
321 me->destroy(me);
322 }
323 this->check = TRUE;
5474dc65
MW
324 }
325
c5a5bc85
TB
326 switch (charon->socket->supported_families(charon->socket))
327 {
328 case SOCKET_FAMILY_IPV4:
329 family = AF_INET;
330 break;
331 case SOCKET_FAMILY_IPV6:
332 family = AF_INET6;
333 break;
334 case SOCKET_FAMILY_BOTH:
335 case SOCKET_FAMILY_NONE:
336 break;
337 }
338
94bbc602 339 enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa);
572abc6c 340 while (enumerator->enumerate(enumerator, (void**)&other))
5474dc65 341 {
c5a5bc85
TB
342 if (family != AF_UNSPEC && other->get_family(other) != family)
343 {
344 continue;
345 }
8394ea2a 346 me = charon->kernel->get_source_addr(charon->kernel, other, NULL);
5474dc65
MW
347 if (me)
348 {
349 /* reuse port for an active address, 4500 otherwise */
e7ea057f 350 apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg), TRUE);
5474dc65 351 other = other->clone(other);
e7ea057f 352 apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg), FALSE);
d9d69536 353 DBG1(DBG_IKE, "checking path %#H - %#H", me, other);
5474dc65
MW
354 copy = packet->clone(packet);
355 copy->set_source(copy, me);
356 copy->set_destination(copy, other);
357 charon->sender->send(charon->sender, copy);
7840952e 358 found = TRUE;
5474dc65
MW
359 }
360 }
572abc6c 361 enumerator->destroy(enumerator);
7840952e 362 return found;
5474dc65
MW
363}
364
c817e7bb
TB
365METHOD(task_t, build_i, status_t,
366 private_ike_mobike_t *this, message_t *message)
17d92e97 367{
31e7dc4d
TB
368 if (message->get_exchange_type(message) == IKE_AUTH &&
369 message->get_message_id(message) == 1)
a44bb934 370 { /* only in first IKE_AUTH */
17d92e97
MW
371 message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
372 build_address_list(this, message);
373 }
c8739590 374 else if (message->get_exchange_type(message) == INFORMATIONAL)
3bc62fe7 375 {
f0974eb2 376 host_t *old, *new;
7daf5226 377
90b1d09e
TB
378 /* this task might have been queued before we knew if MOBIKE will be
379 * supported */
380 if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
381 {
382 message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);
383 return SUCCESS;
384 }
385
7daf5226 386 /* we check if the existing address is still valid */
f0974eb2 387 old = message->get_source(message);
8394ea2a 388 new = charon->kernel->get_source_addr(charon->kernel,
f0974eb2
MW
389 message->get_destination(message), old);
390 if (new)
391 {
392 if (!new->ip_equals(new, old))
393 {
394 new->set_port(new, old->get_port(old));
395 message->set_source(message, new);
396 }
397 else
398 {
399 new->destroy(new);
400 }
401 }
5474dc65 402 if (this->update)
fc2d1c42 403 {
31e7dc4d
TB
404 message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES,
405 chunk_empty);
50491834
TB
406 if (!build_cookie(this, message))
407 {
408 return FAILED;
409 }
fc2d1c42 410 }
1dbf0ed9 411 if (this->address && !this->check)
3bc62fe7
MW
412 {
413 build_address_list(this, message);
414 }
5474dc65
MW
415 if (this->natd)
416 {
417 this->natd->task.build(&this->natd->task, message);
418 }
4cb9d7a7 419 }
17d92e97
MW
420 return NEED_MORE;
421}
422
c817e7bb
TB
423METHOD(task_t, process_r, status_t,
424 private_ike_mobike_t *this, message_t *message)
4cb9d7a7 425{
31e7dc4d
TB
426 if (message->get_exchange_type(message) == IKE_AUTH &&
427 message->get_message_id(message) == 1)
a44bb934 428 { /* only first IKE_AUTH */
4cb9d7a7
MW
429 process_payloads(this, message);
430 }
fc2d1c42
MW
431 else if (message->get_exchange_type(message) == INFORMATIONAL)
432 {
2b255f01 433 host_t *me_new = NULL, *other, *other_old, *other_new = NULL;
7daf5226 434
2b255f01 435 process_payloads(this, message);
7daf5226 436
fc2d1c42
MW
437 if (this->natd)
438 {
439 this->natd->task.process(&this->natd->task, message);
440 }
2b255f01
TB
441
442 if (this->update)
443 {
444 me_new = message->get_destination(message);
445 other_new = message->get_source(message);
446 }
447 else if (this->addresses_updated &&
448 this->ike_sa->has_condition(this->ike_sa, COND_ORIGINAL_INITIATOR))
769c69fa 449 {
2b255f01
TB
450 other = message->get_source(message);
451 other_old = this->ike_sa->get_other_host(this->ike_sa);
769c69fa
TB
452 if (!other->equals(other, other_old))
453 {
2b255f01
TB
454 other_new = other;
455 /* our address might have changed too if the responder used
456 * a different address from our list to reach us */
457 me_new = message->get_destination(message);
769c69fa
TB
458 }
459 }
2b255f01
TB
460
461 if (me_new || other_new)
462 {
463 this->ike_sa->update_hosts(this->ike_sa, me_new,
464 other_new, UPDATE_HOSTS_FORCE_ALL);
465 }
fc2d1c42 466 }
17d92e97
MW
467 return NEED_MORE;
468}
469
c817e7bb
TB
470METHOD(task_t, build_r, status_t,
471 private_ike_mobike_t *this, message_t *message)
17d92e97
MW
472{
473 if (message->get_exchange_type(message) == IKE_AUTH &&
b8249ff5 474 this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
17d92e97
MW
475 {
476 if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
477 {
478 message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
479 build_address_list(this, message);
480 }
481 return SUCCESS;
482 }
2b3100b5
MW
483 else if (message->get_exchange_type(message) == INFORMATIONAL)
484 {
fc2d1c42
MW
485 if (this->natd)
486 {
487 this->natd->task.build(&this->natd->task, message);
488 }
85a119bc
MW
489 if (this->cookie2.ptr)
490 {
491 message->add_notify(message, FALSE, COOKIE2, this->cookie2);
492 chunk_free(&this->cookie2);
493 }
2b3100b5
MW
494 return SUCCESS;
495 }
17d92e97
MW
496 return NEED_MORE;
497}
498
c817e7bb
TB
499METHOD(task_t, process_i, status_t,
500 private_ike_mobike_t *this, message_t *message)
17d92e97
MW
501{
502 if (message->get_exchange_type(message) == IKE_AUTH &&
b8249ff5 503 this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
17d92e97
MW
504 {
505 process_payloads(this, message);
506 return SUCCESS;
507 }
2b3100b5
MW
508 else if (message->get_exchange_type(message) == INFORMATIONAL)
509 {
abe51389
TB
510 bool force = FALSE;
511
9f049781 512 if (is_newer_update_queued(this))
3bc62fe7 513 {
3bc62fe7
MW
514 return SUCCESS;
515 }
85a119bc 516 if (this->cookie2.ptr)
9d9a772e 517 { /* check cookie if we included one */
85a119bc 518 chunk_t cookie2;
7daf5226 519
85a119bc
MW
520 cookie2 = this->cookie2;
521 this->cookie2 = chunk_empty;
522 process_payloads(this, message);
161a0157 523 if (!chunk_equals_const(cookie2, this->cookie2))
85a119bc
MW
524 {
525 chunk_free(&cookie2);
526 DBG1(DBG_IKE, "COOKIE2 mismatch, closing IKE_SA");
527 return FAILED;
528 }
529 chunk_free(&cookie2);
530 }
531 else
532 {
533 process_payloads(this, message);
534 }
fc2d1c42
MW
535 if (this->natd)
536 {
537 this->natd->task.process(&this->natd->task, message);
2b255f01
TB
538
539 if (this->update)
540 { /* update children again, as NAT state may have changed */
541 this->ike_sa->update_hosts(this->ike_sa, NULL, NULL,
542 UPDATE_HOSTS_FORCE_CHILDREN);
543 }
544 else if (this->natd->has_mapping_changed(this->natd))
545 { /* force a check/update if mappings have changed during a DPD */
abe51389 546 force = TRUE;
2b255f01 547 this->check = TRUE;
9d9a772e
MW
548 DBG1(DBG_IKE, "detected changes in NAT mappings, "
549 "initiating MOBIKE update");
550 }
fc2d1c42 551 }
5474dc65
MW
552 if (this->check)
553 {
2b255f01 554 host_t *me, *me_new = NULL, *other, *other_new = NULL;
7daf5226 555
2b255f01
TB
556 me = message->get_destination(message);
557 other = message->get_source(message);
7daf5226 558
2b255f01 559 if (!me->equals(me, this->ike_sa->get_my_host(this->ike_sa)))
5474dc65 560 {
2b255f01 561 me_new = me;
7daf5226 562 }
2b255f01 563 if (!other->equals(other, this->ike_sa->get_other_host(this->ike_sa)))
5474dc65 564 {
2b255f01 565 other_new = other;
5474dc65 566 }
abe51389 567 if (me_new || other_new || force)
5474dc65 568 {
2b255f01
TB
569 this->ike_sa->update_hosts(this->ike_sa, me_new, other_new,
570 UPDATE_HOSTS_FORCE_ALL);
1dbf0ed9 571 /* use the same task to ... */
c5770f86
TB
572 if (!this->ike_sa->has_condition(this->ike_sa,
573 COND_ORIGINAL_INITIATOR))
1dbf0ed9 574 { /*... send an updated list of addresses as responder */
2b255f01 575 this->address = TRUE;
c5770f86 576 }
1dbf0ed9
TB
577 else
578 { /* ... send the update as original initiator */
2b255f01 579 this->update = TRUE;
1dbf0ed9
TB
580 if (this->natd)
581 {
582 this->natd->task.destroy(&this->natd->task);
583 }
584 this->natd = ike_natd_create(this->ike_sa, this->initiator);
12d4186f 585 }
1dbf0ed9 586 this->check = FALSE;
5474dc65
MW
587 return NEED_MORE;
588 }
589 }
2b3100b5
MW
590 return SUCCESS;
591 }
17d92e97
MW
592 return NEED_MORE;
593}
594
13876431
TB
595METHOD(ike_mobike_t, addresses, void,
596 private_ike_mobike_t *this)
597{
598 this->address = TRUE;
13876431
TB
599}
600
c817e7bb
TB
601METHOD(ike_mobike_t, roam, void,
602 private_ike_mobike_t *this, bool address)
17d92e97 603{
5474dc65 604 this->check = TRUE;
43bbe070 605 this->address |= address;
17d92e97
MW
606}
607
c817e7bb
TB
608METHOD(ike_mobike_t, dpd, void,
609 private_ike_mobike_t *this)
9d9a772e 610{
3a05566d 611 if (!this->natd && this->ike_sa->has_condition(this->ike_sa, COND_NAT_HERE))
9d9a772e
MW
612 {
613 this->natd = ike_natd_create(this->ike_sa, this->initiator);
614 }
9d9a772e
MW
615}
616
c817e7bb
TB
617METHOD(ike_mobike_t, is_probing, bool,
618 private_ike_mobike_t *this)
f215e919
MW
619{
620 return this->check;
621}
622
2180ace9
TB
623METHOD(ike_mobike_t, enable_probing, void,
624 private_ike_mobike_t *this)
625{
626 this->check = TRUE;
627}
628
c817e7bb
TB
629METHOD(task_t, get_type, task_type_t,
630 private_ike_mobike_t *this)
17d92e97 631{
a09972df 632 return TASK_IKE_MOBIKE;
17d92e97
MW
633}
634
c817e7bb
TB
635METHOD(task_t, migrate, void,
636 private_ike_mobike_t *this, ike_sa_t *ike_sa)
17d92e97 637{
4cb9d7a7 638 chunk_free(&this->cookie2);
17d92e97 639 this->ike_sa = ike_sa;
4cb9d7a7
MW
640 if (this->natd)
641 {
642 this->natd->task.migrate(&this->natd->task, ike_sa);
643 }
17d92e97
MW
644}
645
c817e7bb
TB
646METHOD(task_t, destroy, void,
647 private_ike_mobike_t *this)
17d92e97 648{
4cb9d7a7
MW
649 chunk_free(&this->cookie2);
650 if (this->natd)
651 {
652 this->natd->task.destroy(&this->natd->task);
653 }
17d92e97
MW
654 free(this);
655}
656
657/*
658 * Described in header.
659 */
660ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
661{
c817e7bb
TB
662 private_ike_mobike_t *this;
663
664 INIT(this,
665 .public = {
666 .task = {
667 .get_type = _get_type,
668 .migrate = _migrate,
669 .destroy = _destroy,
670 },
13876431 671 .addresses = _addresses,
c817e7bb
TB
672 .roam = _roam,
673 .dpd = _dpd,
674 .transmit = _transmit,
675 .is_probing = _is_probing,
2180ace9 676 .enable_probing = _enable_probing,
c817e7bb
TB
677 },
678 .ike_sa = ike_sa,
679 .initiator = initiator,
c817e7bb 680 );
7daf5226 681
17d92e97
MW
682 if (initiator)
683 {
c817e7bb
TB
684 this->public.task.build = _build_i;
685 this->public.task.process = _process_i;
17d92e97
MW
686 }
687 else
688 {
c817e7bb
TB
689 this->public.task.build = _build_r;
690 this->public.task.process = _process_r;
17d92e97 691 }
7daf5226 692
17d92e97
MW
693 return &this->public;
694}