]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/sa/ike_sa.c
ikev2: Return to the original host if connection fails after redirection
[thirdparty/strongswan.git] / src / libcharon / sa / ike_sa.c
CommitLineData
7ba38761 1/*
3a54206c 2 * Copyright (C) 2006-2020 Tobias Brunner
d5cc1758 3 * Copyright (C) 2006 Daniel Roethlisberger
a44bb934 4 * Copyright (C) 2005-2009 Martin Willi
c71d53ba 5 * Copyright (C) 2005 Jan Hutter
208678e6 6 * HSR Hochschule fuer Technik Rapperswil
7ba38761
JH
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
1396815a 18
05db0f97
VR
19/*
20 * Copyright (c) 2014 Volker RĂ¼melin
21 *
22 * Permission is hereby granted, free of charge, to any person obtaining a copy
23 * of this software and associated documentation files (the "Software"), to deal
24 * in the Software without restriction, including without limitation the rights
25 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 * copies of the Software, and to permit persons to whom the Software is
27 * furnished to do so, subject to the following conditions:
28 *
29 * The above copyright notice and this permission notice shall be included in
30 * all copies or substantial portions of the Software.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38 * THE SOFTWARE.
39 */
40
5113680f 41#include <string.h>
c60c7694 42#include <sys/stat.h>
db97fd82 43#include <errno.h>
e13389a7 44#include <time.h>
7ba38761 45
88878242
MW
46#include "ike_sa.h"
47
db7ef624 48#include <library.h>
c5f7146b 49#include <daemon.h>
893da041 50#include <collections/array.h>
c60c7694 51#include <utils/lexparser.h>
e0fe7651
MW
52#include <processing/jobs/retransmit_job.h>
53#include <processing/jobs/delete_ike_sa_job.h>
54#include <processing/jobs/send_dpd_job.h>
55#include <processing/jobs/send_keepalive_job.h>
56#include <processing/jobs/rekey_ike_sa_job.h>
60c82591 57#include <processing/jobs/retry_initiate_job.h>
b1f2f05c 58#include <sa/ikev2/tasks/ike_auth_lifetime.h>
f20e00fe 59#include <sa/ikev2/tasks/ike_reauth_complete.h>
71c70705 60#include <sa/ikev2/tasks/ike_redirect.h>
1b9c1ae0 61#include <credentials/sets/auth_cfg_wrapper.h>
7ba38761 62
dc04b7c7 63#ifdef ME
15a682f4 64#include <sa/ikev2/tasks/ike_me.h>
38951252 65#include <processing/jobs/initiate_mediation_job.h>
d5cc1758 66#endif
c60c7694 67
a985db3f 68ENUM(ike_sa_state_names, IKE_CREATED, IKE_DESTROYING,
60356f33
MW
69 "CREATED",
70 "CONNECTING",
71 "ESTABLISHED",
c610f424 72 "PASSIVE",
60356f33 73 "REKEYING",
bb389973 74 "REKEYED",
60356f33 75 "DELETING",
a985db3f 76 "DESTROYING",
60356f33 77);
7ba38761 78
aad398a7 79typedef struct private_ike_sa_t private_ike_sa_t;
7f56b494 80typedef struct attribute_entry_t attribute_entry_t;
aad398a7
JH
81
82/**
83 * Private data of an ike_sa_t object.
84 */
85struct private_ike_sa_t {
7daf5226 86
aad398a7 87 /**
3dd3c5f3 88 * Public members
2f89902d 89 */
3dd3c5f3 90 ike_sa_t public;
7daf5226 91
aad398a7 92 /**
a374d1ee 93 * Identifier for the current IKE_SA.
aad398a7
JH
94 */
95 ike_sa_id_t *ike_sa_id;
7daf5226 96
0b611540
TB
97 /**
98 * IKE version of this SA.
99 */
100 ike_version_t version;
101
c60c7694
MW
102 /**
103 * unique numerical ID for this IKE_SA.
104 */
b12c53ce 105 uint32_t unique_id;
7daf5226 106
aad398a7 107 /**
8dfbe71b 108 * Current state of the IKE_SA
aad398a7 109 */
7f56b494 110 ike_sa_state_t state;
7daf5226 111
a9428251 112 /**
e0fe7651 113 * IKE configuration used to set up this IKE_SA
a9428251 114 */
e0fe7651 115 ike_cfg_t *ike_cfg;
7daf5226 116
c60c7694
MW
117 /**
118 * Peer and authentication information to establish IKE_SA.
119 */
e0fe7651 120 peer_cfg_t *peer_cfg;
7daf5226 121
552cc11b 122 /**
893da041 123 * currently used authentication ruleset, local
552cc11b 124 */
a44bb934 125 auth_cfg_t *my_auth;
7daf5226 126
44ce7493 127 /**
893da041 128 * currently used authentication constraints, remote
44ce7493 129 */
893da041 130 auth_cfg_t *other_auth;
44ce7493
MW
131
132 /**
893da041 133 * Array of completed local authentication rounds (as auth_cfg_t)
44ce7493 134 */
893da041 135 array_t *my_auths;
44ce7493 136
552cc11b 137 /**
893da041 138 * Array of completed remote authentication rounds (as auth_cfg_t)
552cc11b 139 */
893da041 140 array_t *other_auths;
7daf5226 141
5dffdea1
MW
142 /**
143 * Selected IKE proposal
144 */
145 proposal_t *proposal;
7daf5226 146
c60c7694
MW
147 /**
148 * Juggles tasks to process messages
149 */
150 task_manager_t *task_manager;
7daf5226 151
8dfbe71b
MW
152 /**
153 * Address of local host
154 */
155 host_t *my_host;
7daf5226 156
8dfbe71b
MW
157 /**
158 * Address of remote host
159 */
160 host_t *other_host;
7daf5226 161
dc04b7c7 162#ifdef ME
22452f70
TB
163 /**
164 * Are we mediation server
165 */
166 bool is_mediation_server;
7daf5226 167
d5cc1758
TB
168 /**
169 * Server reflexive host
170 */
171 host_t *server_reflexive_host;
7daf5226 172
9c2a905d
TB
173 /**
174 * Connect ID
175 */
176 chunk_t connect_id;
dc04b7c7 177#endif /* ME */
7daf5226 178
8dfbe71b
MW
179 /**
180 * Identification used for us
181 */
182 identification_t *my_id;
7daf5226 183
a9428251 184 /**
8dfbe71b 185 * Identification used for other
a9428251 186 */
8dfbe71b 187 identification_t *other_id;
7daf5226 188
3b04350a
MW
189 /**
190 * set of extensions the peer supports
191 */
192 ike_extension_t extensions;
7daf5226 193
17d92e97
MW
194 /**
195 * set of condition flags currently enabled for this IKE_SA
196 */
197 ike_condition_t conditions;
7daf5226 198
aad398a7 199 /**
893da041 200 * Array containing the child sa's of the current IKE_SA.
aad398a7 201 */
893da041 202 array_t *child_sas;
7daf5226 203
bc997f65 204 /**
6a4ff35c 205 * keymat of this IKE_SA
bc997f65 206 */
6a4ff35c 207 keymat_t *keymat;
7daf5226 208
3dd3c5f3 209 /**
101d26ba 210 * Virtual IPs on local host
3dd3c5f3 211 */
893da041 212 array_t *my_vips;
7daf5226 213
c60c7694 214 /**
101d26ba 215 * Virtual IPs on remote host
c60c7694 216 */
893da041 217 array_t *other_vips;
7daf5226 218
31e5d441 219 /**
7f56b494 220 * List of configuration attributes (attribute_entry_t)
31e5d441 221 */
893da041 222 array_t *attributes;
7daf5226 223
17d92e97 224 /**
94bbc602 225 * list of peer's addresses, additional ones transmitted via MOBIKE
17d92e97 226 */
893da041 227 array_t *peer_addresses;
7daf5226 228
9d9a772e
MW
229 /**
230 * previously value of received DESTINATION_IP hash
231 */
232 chunk_t nat_detection_dest;
7daf5226 233
3dfecde4
AS
234 /**
235 * NAT keep alive interval
236 */
b12c53ce 237 uint32_t keepalive_interval;
7daf5226 238
efd7fa7b 239 /**
b3ab7a48 240 * The scheduled keep alive job, if any
efd7fa7b
TB
241 */
242 send_keepalive_job_t *keepalive_job;
243
60c82591
TB
244 /**
245 * interval for retries during initiation (e.g. if DNS resolution failed),
246 * 0 to disable (default)
247 */
b12c53ce 248 uint32_t retry_initiate_interval;
60c82591 249
77e42826
TB
250 /**
251 * TRUE if a retry_initiate_job has been queued
252 */
253 bool retry_initiate_queued;
254
1396815a 255 /**
fe04e93a 256 * Timestamps for this IKE_SA
1396815a 257 */
b12c53ce 258 uint32_t stats[STAT_MAX];
7daf5226 259
fdb9b2bd
MW
260 /**
261 * how many times we have retried so far (keyingtries)
262 */
b12c53ce 263 uint32_t keyingtry;
7daf5226 264
d487b4b7
AS
265 /**
266 * local host address to be used for IKE, set via MIGRATE kernel message
267 */
268 host_t *local_host;
7daf5226 269
d487b4b7
AS
270 /**
271 * remote host address to be used for IKE, set via MIGRATE kernel message
272 */
273 host_t *remote_host;
b24b73b7
MW
274
275 /**
276 * Flush auth configs once established?
277 */
278 bool flush_auth_cfg;
40bab9a1
TB
279
280 /**
281 * Maximum length of a single fragment, 0 for address-specific defaults
282 */
283 size_t fragment_size;
489d154e
TB
284
285 /**
286 * Whether to follow IKEv2 redirects
287 */
288 bool follow_redirects;
e4af6e6b
TB
289
290 /**
291 * Original gateway address from which we got redirected
292 */
293 host_t *redirected_from;
c6ebd033
TB
294
295 /**
296 * Timestamps of redirect attempts to handle loops
297 */
298 array_t *redirected_at;
dec3c184
TB
299
300 /**
301 * Inbound interface ID
302 */
303 uint32_t if_id_in;
304
305 /**
306 * Outbound interface ID
307 */
308 uint32_t if_id_out;
aad398a7
JH
309};
310
7f56b494
MW
311/**
312 * Entry to maintain install configuration attributes during IKE_SA lifetime
313 */
314struct attribute_entry_t {
315 /** handler used to install this attribute */
316 attribute_handler_t *handler;
317 /** attribute type */
318 configuration_attribute_type_t type;
319 /** attribute data */
320 chunk_t data;
321};
322
0b2abb8c 323/**
3dd3c5f3 324 * get the time of the latest traffic processed by the kernel
0b2abb8c 325 */
c60c7694 326static time_t get_use_time(private_ike_sa_t* this, bool inbound)
3a8f9f44 327{
6e10aead 328 enumerator_t *enumerator;
3dd3c5f3 329 child_sa_t *child_sa;
c3a78360 330 time_t use_time, current;
7daf5226 331
c60c7694
MW
332 if (inbound)
333 {
85ac2fa5 334 use_time = this->stats[STAT_INBOUND];
c60c7694
MW
335 }
336 else
337 {
85ac2fa5 338 use_time = this->stats[STAT_OUTBOUND];
c60c7694 339 }
893da041
MW
340
341 enumerator = array_create_enumerator(this->child_sas);
6e10aead
MW
342 while (enumerator->enumerate(enumerator, &child_sa))
343 {
d954a208 344 child_sa->get_usestats(child_sa, inbound, &current, NULL, NULL);
c3a78360 345 use_time = max(use_time, current);
6e10aead
MW
346 }
347 enumerator->destroy(enumerator);
7daf5226 348
6e10aead 349 return use_time;
a9428251
JH
350}
351
b12c53ce 352METHOD(ike_sa_t, get_unique_id, uint32_t,
8bced61b 353 private_ike_sa_t *this)
aad398a7 354{
c60c7694 355 return this->unique_id;
aad398a7
JH
356}
357
8bced61b
MW
358METHOD(ike_sa_t, get_name, char*,
359 private_ike_sa_t *this)
0fdc3c7f 360{
e0fe7651 361 if (this->peer_cfg)
c60c7694 362 {
e0fe7651 363 return this->peer_cfg->get_name(this->peer_cfg);
c60c7694
MW
364 }
365 return "(unnamed)";
0fdc3c7f
JH
366}
367
b12c53ce 368METHOD(ike_sa_t, get_statistic, uint32_t,
8bced61b 369 private_ike_sa_t *this, statistic_t kind)
a3ce4bc2 370{
85ac2fa5 371 if (kind < STAT_MAX)
a3ce4bc2 372 {
85ac2fa5 373 return this->stats[kind];
a3ce4bc2 374 }
ee614711 375 return 0;
a3ce4bc2
MW
376}
377
44ff1153 378METHOD(ike_sa_t, set_statistic, void,
b12c53ce 379 private_ike_sa_t *this, statistic_t kind, uint32_t value)
44ff1153
TB
380{
381 if (kind < STAT_MAX)
382 {
383 this->stats[kind] = value;
384 }
385}
386
8bced61b
MW
387METHOD(ike_sa_t, get_my_host, host_t*,
388 private_ike_sa_t *this)
8dfbe71b 389{
e0fe7651 390 return this->my_host;
8dfbe71b
MW
391}
392
8bced61b
MW
393METHOD(ike_sa_t, set_my_host, void,
394 private_ike_sa_t *this, host_t *me)
8dfbe71b 395{
e0fe7651
MW
396 DESTROY_IF(this->my_host);
397 this->my_host = me;
8dfbe71b
MW
398}
399
8bced61b
MW
400METHOD(ike_sa_t, get_other_host, host_t*,
401 private_ike_sa_t *this)
397f3448 402{
e0fe7651 403 return this->other_host;
c60c7694
MW
404}
405
8bced61b
MW
406METHOD(ike_sa_t, set_other_host, void,
407 private_ike_sa_t *this, host_t *other)
c60c7694 408{
e0fe7651
MW
409 DESTROY_IF(this->other_host);
410 this->other_host = other;
397f3448
MW
411}
412
e4af6e6b
TB
413METHOD(ike_sa_t, get_redirected_from, host_t*,
414 private_ike_sa_t *this)
415{
416 return this->redirected_from;
417}
418
8bced61b
MW
419METHOD(ike_sa_t, get_peer_cfg, peer_cfg_t*,
420 private_ike_sa_t *this)
8dfbe71b 421{
e0fe7651 422 return this->peer_cfg;
8dfbe71b
MW
423}
424
8bced61b
MW
425METHOD(ike_sa_t, set_peer_cfg, void,
426 private_ike_sa_t *this, peer_cfg_t *peer_cfg)
fe04e93a 427{
e0fe7651 428 peer_cfg->get_ref(peer_cfg);
dbd21695 429 DESTROY_IF(this->peer_cfg);
e0fe7651 430 this->peer_cfg = peer_cfg;
7daf5226 431
dec3c184 432 if (!this->ike_cfg)
e0fe7651
MW
433 {
434 this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
435 this->ike_cfg->get_ref(this->ike_cfg);
436 }
dec3c184
TB
437
438 this->if_id_in = peer_cfg->get_if_id(peer_cfg, TRUE);
439 this->if_id_out = peer_cfg->get_if_id(peer_cfg, FALSE);
440 allocate_unique_if_ids(&this->if_id_in, &this->if_id_out);
552cc11b
MW
441}
442
8bced61b
MW
443METHOD(ike_sa_t, get_auth_cfg, auth_cfg_t*,
444 private_ike_sa_t *this, bool local)
552cc11b 445{
a44bb934
MW
446 if (local)
447 {
448 return this->my_auth;
449 }
552cc11b
MW
450 return this->other_auth;
451}
452
8bced61b
MW
453METHOD(ike_sa_t, add_auth_cfg, void,
454 private_ike_sa_t *this, bool local, auth_cfg_t *cfg)
44ce7493
MW
455{
456 if (local)
457 {
893da041 458 array_insert(this->my_auths, ARRAY_TAIL, cfg);
44ce7493
MW
459 }
460 else
461 {
893da041 462 array_insert(this->other_auths, ARRAY_TAIL, cfg);
44ce7493
MW
463 }
464}
465
8bced61b
MW
466METHOD(ike_sa_t, create_auth_cfg_enumerator, enumerator_t*,
467 private_ike_sa_t *this, bool local)
44ce7493
MW
468{
469 if (local)
470 {
893da041 471 return array_create_enumerator(this->my_auths);
44ce7493 472 }
893da041 473 return array_create_enumerator(this->other_auths);
44ce7493
MW
474}
475
e41adf5f
TB
476/**
477 * Flush the stored authentication round information
478 */
479static void flush_auth_cfgs(private_ike_sa_t *this)
480{
481 auth_cfg_t *cfg;
482
483 this->my_auth->purge(this->my_auth, FALSE);
484 this->other_auth->purge(this->other_auth, FALSE);
485
486 while (array_remove(this->my_auths, ARRAY_TAIL, &cfg))
487 {
488 cfg->destroy(cfg);
489 }
490 while (array_remove(this->other_auths, ARRAY_TAIL, &cfg))
491 {
492 cfg->destroy(cfg);
493 }
494}
495
1b9c1ae0
TB
496METHOD(ike_sa_t, verify_peer_certificate, bool,
497 private_ike_sa_t *this)
498{
499 enumerator_t *e1, *e2, *certs;
500 auth_cfg_t *cfg, *cfg_done;
501 certificate_t *peer, *cert;
502 public_key_t *key;
503 auth_cfg_t *auth;
504 auth_cfg_wrapper_t *wrapper;
505 time_t not_before, not_after;
506 bool valid = TRUE, found;
507
508 if (this->state != IKE_ESTABLISHED)
509 {
510 DBG1(DBG_IKE, "unable to verify peer certificate in state %N",
511 ike_sa_state_names, this->state);
512 return FALSE;
513 }
514
e41adf5f
TB
515 if (!this->flush_auth_cfg &&
516 lib->settings->get_bool(lib->settings,
1b9c1ae0 517 "%s.flush_auth_cfg", FALSE, lib->ns))
e41adf5f 518 { /* we can do this check only once if auth configs are flushed */
1b9c1ae0
TB
519 DBG1(DBG_IKE, "unable to verify peer certificate as authentication "
520 "information has been flushed");
521 return FALSE;
522 }
e41adf5f
TB
523 this->public.set_condition(&this->public, COND_ONLINE_VALIDATION_SUSPENDED,
524 FALSE);
1b9c1ae0
TB
525
526 e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
527 e2 = array_create_enumerator(this->other_auths);
528 while (e1->enumerate(e1, &cfg))
529 {
530 if (!e2->enumerate(e2, &cfg_done))
531 { /* this should not happen as the authentication should never have
532 * succeeded */
533 valid = FALSE;
534 break;
535 }
536 if ((uintptr_t)cfg_done->get(cfg_done,
537 AUTH_RULE_AUTH_CLASS) != AUTH_CLASS_PUBKEY)
538 {
539 continue;
540 }
541 peer = cfg_done->get(cfg_done, AUTH_RULE_SUBJECT_CERT);
542 if (!peer)
543 {
544 DBG1(DBG_IKE, "no subject certificate found, skipping certificate "
545 "verification");
546 continue;
547 }
548 if (!peer->get_validity(peer, NULL, &not_before, &not_after))
549 {
1b9c1ae0
TB
550 DBG1(DBG_IKE, "peer certificate invalid (valid from %T to %T)",
551 &not_before, FALSE, &not_after, FALSE);
552 valid = FALSE;
553 break;
554 }
555 key = peer->get_public_key(peer);
556 if (!key)
557 {
558 DBG1(DBG_IKE, "unable to retrieve public key, skipping certificate "
559 "verification");
560 continue;
561 }
562 DBG1(DBG_IKE, "verifying peer certificate");
563 /* serve received certificates */
564 wrapper = auth_cfg_wrapper_create(cfg_done);
565 lib->credmgr->add_local_set(lib->credmgr, &wrapper->set, FALSE);
566 certs = lib->credmgr->create_trusted_enumerator(lib->credmgr,
567 key->get_type(key), peer->get_subject(peer), TRUE);
568 key->destroy(key);
569
570 found = FALSE;
571 while (certs->enumerate(certs, &cert, &auth))
572 {
573 if (peer->equals(peer, cert))
574 {
575 cfg_done->add(cfg_done, AUTH_RULE_CERT_VALIDATION_SUSPENDED,
576 FALSE);
577 cfg_done->merge(cfg_done, auth, FALSE);
578 valid = cfg_done->complies(cfg_done, cfg, TRUE);
579 found = TRUE;
580 break;
581 }
582 }
583 certs->destroy(certs);
584 lib->credmgr->remove_local_set(lib->credmgr, &wrapper->set);
585 wrapper->destroy(wrapper);
586 if (!found || !valid)
587 {
588 valid = FALSE;
589 break;
590 }
591 }
592 e1->destroy(e1);
593 e2->destroy(e2);
1b9c1ae0 594
e41adf5f 595 if (this->flush_auth_cfg)
44ce7493 596 {
e41adf5f
TB
597 this->flush_auth_cfg = FALSE;
598 flush_auth_cfgs(this);
44ce7493 599 }
e41adf5f 600 return valid;
44ce7493
MW
601}
602
8bced61b
MW
603METHOD(ike_sa_t, get_proposal, proposal_t*,
604 private_ike_sa_t *this)
5dffdea1
MW
605{
606 return this->proposal;
607}
608
8bced61b
MW
609METHOD(ike_sa_t, set_proposal, void,
610 private_ike_sa_t *this, proposal_t *proposal)
5dffdea1
MW
611{
612 DESTROY_IF(this->proposal);
a2cb2c9c 613 this->proposal = proposal->clone(proposal, 0);
5dffdea1
MW
614}
615
8bced61b 616METHOD(ike_sa_t, set_message_id, void,
b12c53ce 617 private_ike_sa_t *this, bool initiate, uint32_t mid)
b09ca747
MW
618{
619 if (initiate)
620 {
f1f09810 621 this->task_manager->reset(this->task_manager, mid, UINT_MAX);
b09ca747
MW
622 }
623 else
624 {
f1f09810 625 this->task_manager->reset(this->task_manager, UINT_MAX, mid);
b09ca747
MW
626 }
627}
628
347c403c
TB
629METHOD(ike_sa_t, get_message_id, uint32_t,
630 private_ike_sa_t *this, bool initiate)
631{
632 return this->task_manager->get_mid(this->task_manager, initiate);
633}
634
8bced61b 635METHOD(ike_sa_t, send_keepalive, void,
efd7fa7b 636 private_ike_sa_t *this, bool scheduled)
2b3100b5 637{
2b3100b5 638 time_t last_out, now, diff;
7daf5226 639
efd7fa7b
TB
640 if (scheduled)
641 {
642 this->keepalive_job = NULL;
643 }
34f7d3b7
TB
644 if (!this->keepalive_interval || this->state == IKE_PASSIVE)
645 { /* keepalives disabled either by configuration or for passive IKE_SAs */
646 return;
647 }
648 if (!(this->conditions & COND_NAT_HERE) || (this->conditions & COND_STALE))
649 { /* disable keepalives if we are not NATed anymore, or the SA is stale */
3d928c9f
MW
650 return;
651 }
7daf5226 652
2b3100b5 653 last_out = get_use_time(this, FALSE);
6180a558 654 now = time_monotonic(NULL);
7daf5226 655
2b3100b5 656 diff = now - last_out;
7daf5226 657
3dfecde4 658 if (diff >= this->keepalive_interval)
2b3100b5
MW
659 {
660 packet_t *packet;
661 chunk_t data;
7daf5226 662
2b3100b5
MW
663 packet = packet_create();
664 packet->set_source(packet, this->my_host->clone(this->my_host));
665 packet->set_destination(packet, this->other_host->clone(this->other_host));
666 data.ptr = malloc(1);
667 data.ptr[0] = 0xFF;
668 data.len = 1;
669 packet->set_data(packet, data);
f3fefb18 670 DBG1(DBG_IKE, "sending keep alive to %#H", this->other_host);
75f83163 671 charon->sender->send_no_marker(charon->sender, packet);
2b3100b5
MW
672 diff = 0;
673 }
efd7fa7b
TB
674 if (!this->keepalive_job)
675 {
676 this->keepalive_job = send_keepalive_job_create(this->ike_sa_id);
677 lib->scheduler->schedule_job(lib->scheduler, (job_t*)this->keepalive_job,
678 this->keepalive_interval - diff);
679 }
2b3100b5
MW
680}
681
8bced61b
MW
682METHOD(ike_sa_t, get_ike_cfg, ike_cfg_t*,
683 private_ike_sa_t *this)
8dfbe71b 684{
e0fe7651 685 return this->ike_cfg;
8dfbe71b 686}
5b97779f 687
8bced61b
MW
688METHOD(ike_sa_t, set_ike_cfg, void,
689 private_ike_sa_t *this, ike_cfg_t *ike_cfg)
fe04e93a 690{
054ee5e7 691 DESTROY_IF(this->ike_cfg);
e0fe7651
MW
692 ike_cfg->get_ref(ike_cfg);
693 this->ike_cfg = ike_cfg;
fe04e93a 694}
4a035181 695
8bced61b
MW
696METHOD(ike_sa_t, enable_extension, void,
697 private_ike_sa_t *this, ike_extension_t extension)
2b3100b5
MW
698{
699 this->extensions |= extension;
700}
701
8bced61b
MW
702METHOD(ike_sa_t, supports_extension, bool,
703 private_ike_sa_t *this, ike_extension_t extension)
2b3100b5
MW
704{
705 return (this->extensions & extension) != FALSE;
706}
707
8bced61b
MW
708METHOD(ike_sa_t, has_condition, bool,
709 private_ike_sa_t *this, ike_condition_t condition)
2b3100b5
MW
710{
711 return (this->conditions & condition) != FALSE;
712}
713
8bced61b
MW
714METHOD(ike_sa_t, set_condition, void,
715 private_ike_sa_t *this, ike_condition_t condition, bool enable)
2b3100b5
MW
716{
717 if (has_condition(this, condition) != enable)
718 {
719 if (enable)
720 {
fc2d1c42 721 this->conditions |= condition;
2b3100b5
MW
722 switch (condition)
723 {
2b3100b5
MW
724 case COND_NAT_HERE:
725 DBG1(DBG_IKE, "local host is behind NAT, sending keep alives");
726 this->conditions |= COND_NAT_ANY;
efd7fa7b 727 send_keepalive(this, FALSE);
2b3100b5
MW
728 break;
729 case COND_NAT_THERE:
730 DBG1(DBG_IKE, "remote host is behind NAT");
731 this->conditions |= COND_NAT_ANY;
732 break;
9dae1bed 733 case COND_NAT_FAKE:
f53b74c9 734 DBG1(DBG_IKE, "faking NAT situation to enforce UDP encapsulation");
9dae1bed
MW
735 this->conditions |= COND_NAT_ANY;
736 break;
2b3100b5
MW
737 default:
738 break;
739 }
2b3100b5
MW
740 }
741 else
742 {
fc2d1c42 743 this->conditions &= ~condition;
2b3100b5
MW
744 switch (condition)
745 {
fc2d1c42
MW
746 case COND_NAT_HERE:
747 case COND_NAT_THERE:
f9056115
TB
748 DBG1(DBG_IKE, "%s host is not behind NAT anymore",
749 condition == COND_NAT_HERE ? "local" : "remote");
750 /* fall-through */
751 case COND_NAT_FAKE:
fc2d1c42
MW
752 set_condition(this, COND_NAT_ANY,
753 has_condition(this, COND_NAT_HERE) ||
9dae1bed
MW
754 has_condition(this, COND_NAT_THERE) ||
755 has_condition(this, COND_NAT_FAKE));
fc2d1c42 756 break;
34f7d3b7 757 case COND_STALE:
efd7fa7b 758 send_keepalive(this, FALSE);
34f7d3b7 759 break;
2b3100b5
MW
760 default:
761 break;
762 }
2b3100b5
MW
763 }
764 }
765}
fe04e93a 766
8bced61b
MW
767METHOD(ike_sa_t, send_dpd, status_t,
768 private_ike_sa_t *this)
fdb9b2bd 769{
6554b5e4 770 job_t *job;
fdb9b2bd 771 time_t diff, delay;
bcf8cdd5 772 bool task_queued = FALSE;
7daf5226 773
916cdca8
MW
774 if (this->state == IKE_PASSIVE)
775 {
776 return INVALID_STATE;
777 }
f15c85a4
TB
778 if (this->version == IKEV1 && this->state == IKE_REKEYING)
779 { /* don't send DPDs for rekeyed IKEv1 SAs */
780 return SUCCESS;
781 }
96926b00 782 delay = this->peer_cfg->get_dpd(this->peer_cfg);
fdb9b2bd
MW
783 if (this->task_manager->busy(this->task_manager))
784 {
785 /* an exchange is in the air, no need to start a DPD check */
786 diff = 0;
787 }
788 else
789 {
790 /* check if there was any inbound traffic */
791 time_t last_in, now;
792 last_in = get_use_time(this, TRUE);
6180a558 793 now = time_monotonic(NULL);
fdb9b2bd 794 diff = now - last_in;
6c2d466b 795 if (!delay || diff >= delay)
fdb9b2bd 796 {
bcf8cdd5 797 /* too long ago, initiate dead peer detection */
fdb9b2bd 798 DBG1(DBG_IKE, "sending DPD request");
244d715d 799 this->task_manager->queue_dpd(this->task_manager);
bcf8cdd5 800 task_queued = TRUE;
244d715d 801 diff = 0;
fdb9b2bd
MW
802 }
803 }
804 /* recheck in "interval" seconds */
6c2d466b
MW
805 if (delay)
806 {
807 job = (job_t*)send_dpd_job_create(this->ike_sa_id);
808 lib->scheduler->schedule_job(lib->scheduler, job, delay - diff);
809 }
bcf8cdd5
TB
810 if (task_queued)
811 {
812 return this->task_manager->initiate(this->task_manager);
813 }
814 return SUCCESS;
fdb9b2bd
MW
815}
816
8bced61b
MW
817METHOD(ike_sa_t, get_state, ike_sa_state_t,
818 private_ike_sa_t *this)
fdb9b2bd
MW
819{
820 return this->state;
821}
822
8bced61b
MW
823METHOD(ike_sa_t, set_state, void,
824 private_ike_sa_t *this, ike_sa_state_t state)
fdb9b2bd 825{
edaba56e 826 bool trigger_dpd = FALSE, keepalives = FALSE;
85dd6a8d 827
98ba96f1 828 DBG2(DBG_IKE, "IKE_SA %s[%d] state change: %N => %N",
51c8f826 829 get_name(this), this->unique_id,
fdb9b2bd
MW
830 ike_sa_state_names, this->state,
831 ike_sa_state_names, state);
7daf5226 832
0f33e826 833 switch (state)
fdb9b2bd 834 {
0f33e826 835 case IKE_ESTABLISHED:
fdb9b2bd 836 {
405cc1d9
MW
837 if (this->state == IKE_CONNECTING ||
838 this->state == IKE_PASSIVE)
0f33e826
MW
839 {
840 job_t *job;
b12c53ce 841 uint32_t t;
7daf5226 842
ee614711 843 /* calculate rekey, reauth and lifetime */
6180a558 844 this->stats[STAT_ESTABLISHED] = time_monotonic(NULL);
7daf5226 845
ee614711
MW
846 /* schedule rekeying if we have a time which is smaller than
847 * an already scheduled rekeying */
d08269c7 848 t = this->peer_cfg->get_rekey_time(this->peer_cfg, TRUE);
484a06bc 849 if (t && (this->stats[STAT_REKEY] == 0 ||
85ac2fa5 850 (this->stats[STAT_REKEY] > t + this->stats[STAT_ESTABLISHED])))
0f33e826 851 {
85ac2fa5 852 this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED];
ee614711 853 job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
bb381e26 854 lib->scheduler->schedule_job(lib->scheduler, job, t);
ee614711 855 DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
0f33e826 856 }
d08269c7 857 t = this->peer_cfg->get_reauth_time(this->peer_cfg, TRUE);
484a06bc 858 if (t && (this->stats[STAT_REAUTH] == 0 ||
85ac2fa5 859 (this->stats[STAT_REAUTH] > t + this->stats[STAT_ESTABLISHED])))
ee614711 860 {
85ac2fa5 861 this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED];
ee614711 862 job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
bb381e26 863 lib->scheduler->schedule_job(lib->scheduler, job, t);
ee614711
MW
864 DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
865 }
866 t = this->peer_cfg->get_over_time(this->peer_cfg);
85ac2fa5 867 if (this->stats[STAT_REKEY] || this->stats[STAT_REAUTH])
0f33e826 868 {
85ac2fa5 869 if (this->stats[STAT_REAUTH] == 0)
ee614711 870 {
85ac2fa5 871 this->stats[STAT_DELETE] = this->stats[STAT_REKEY];
ee614711 872 }
85ac2fa5 873 else if (this->stats[STAT_REKEY] == 0)
ee614711 874 {
85ac2fa5 875 this->stats[STAT_DELETE] = this->stats[STAT_REAUTH];
ee614711
MW
876 }
877 else
878 {
85ac2fa5
MW
879 this->stats[STAT_DELETE] = min(this->stats[STAT_REKEY],
880 this->stats[STAT_REAUTH]);
ee614711 881 }
85ac2fa5
MW
882 this->stats[STAT_DELETE] += t;
883 t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED];
0f33e826 884 job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
bb381e26 885 lib->scheduler->schedule_job(lib->scheduler, job, t);
ee614711 886 DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
0f33e826 887 }
85dd6a8d 888 trigger_dpd = this->peer_cfg->get_dpd(this->peer_cfg);
b76e96e2
MW
889 if (trigger_dpd)
890 {
891 /* Some peers delay the DELETE after rekeying an IKE_SA.
892 * If this delay is longer than our DPD delay, we would
893 * send a DPD request here. The IKE_SA is not ready to do
894 * so yet, so prevent that. */
895 this->stats[STAT_INBOUND] = this->stats[STAT_ESTABLISHED];
896 }
edaba56e
TE
897 if (this->state == IKE_PASSIVE)
898 {
899 keepalives = TRUE;
900 }
e4af6e6b
TB
901 DESTROY_IF(this->redirected_from);
902 this->redirected_from = NULL;
0f33e826
MW
903 }
904 break;
fdb9b2bd 905 }
0f33e826
MW
906 default:
907 break;
fdb9b2bd 908 }
a985db3f 909 charon->bus->ike_state_change(charon->bus, &this->public, state);
fdb9b2bd 910 this->state = state;
85dd6a8d
MW
911
912 if (trigger_dpd)
913 {
f98af1dd
MW
914 if (supports_extension(this, EXT_DPD))
915 {
916 send_dpd(this);
917 }
918 else
919 {
920 DBG1(DBG_IKE, "DPD not supported by peer, disabled");
921 }
85dd6a8d 922 }
edaba56e
TE
923 if (keepalives)
924 {
efd7fa7b 925 send_keepalive(this, FALSE);
edaba56e 926 }
fdb9b2bd
MW
927}
928
8bced61b 929METHOD(ike_sa_t, reset, void,
c3539961 930 private_ike_sa_t *this, bool new_spi)
fdb9b2bd 931{
c3539961
TB
932 /* reset the initiator SPI if requested */
933 if (new_spi)
934 {
935 charon->ike_sa_manager->new_initiator_spi(charon->ike_sa_manager,
936 &this->public);
3a54206c
TB
937
938 /* when starting from scratch, connect to the original peer again e.g.
939 * if we got redirected but weren't able to connect successfully */
940 if (this->redirected_from)
941 {
942 this->redirected_from->destroy(this->redirected_from);
943 this->redirected_from = NULL;
944 /* we can't restore the original value, if there was any */
945 DESTROY_IF(this->remote_host);
946 this->remote_host = NULL;
947 }
c3539961
TB
948 }
949 /* the responder ID is reset, as peer may choose another one */
fdb9b2bd
MW
950 if (this->ike_sa_id->is_initiator(this->ike_sa_id))
951 {
952 this->ike_sa_id->set_responder_spi(this->ike_sa_id, 0);
953 }
7daf5226 954
fdb9b2bd 955 set_state(this, IKE_CREATED);
7daf5226 956
550d9085
MW
957 flush_auth_cfgs(this);
958
959 this->keymat->destroy(this->keymat);
4b64a1a1
TB
960 this->keymat = keymat_create(this->version,
961 this->ike_sa_id->is_initiator(this->ike_sa_id));
550d9085 962
b09ca747 963 this->task_manager->reset(this->task_manager, 0, 0);
d9fe0ec7 964 this->task_manager->queue_ike(this->task_manager);
fdb9b2bd
MW
965}
966
8bced61b
MW
967METHOD(ike_sa_t, get_keymat, keymat_t*,
968 private_ike_sa_t *this)
6a4ff35c
MW
969{
970 return this->keymat;
971}
972
101d26ba 973METHOD(ike_sa_t, add_virtual_ip, void,
8bced61b 974 private_ike_sa_t *this, bool local, host_t *ip)
c532d646
MW
975{
976 if (local)
977 {
b185cdd1
MW
978 char *iface;
979
8394ea2a
TB
980 if (charon->kernel->get_interface(charon->kernel, this->my_host,
981 &iface))
c532d646 982 {
b185cdd1 983 DBG1(DBG_IKE, "installing new virtual IP %H", ip);
8394ea2a
TB
984 if (charon->kernel->add_ip(charon->kernel, ip, -1,
985 iface) == SUCCESS)
b185cdd1 986 {
893da041 987 array_insert_create(&this->my_vips, ARRAY_TAIL, ip->clone(ip));
b185cdd1
MW
988 }
989 else
990 {
991 DBG1(DBG_IKE, "installing virtual IP %H failed", ip);
992 }
993 free(iface);
c532d646
MW
994 }
995 else
996 {
b185cdd1 997 DBG1(DBG_IKE, "looking up interface for virtual IP %H failed", ip);
c532d646
MW
998 }
999 }
1000 else
1001 {
893da041 1002 array_insert_create(&this->other_vips, ARRAY_TAIL, ip->clone(ip));
c532d646
MW
1003 }
1004}
1005
d2e8f20d
TB
1006
1007METHOD(ike_sa_t, clear_virtual_ips, void,
1008 private_ike_sa_t *this, bool local)
1009{
893da041 1010 array_t *vips;
d2e8f20d
TB
1011 host_t *vip;
1012
893da041
MW
1013 vips = local ? this->my_vips : this->other_vips;
1014 if (!local && array_count(vips))
12fa1784
AS
1015 {
1016 charon->bus->assign_vips(charon->bus, &this->public, FALSE);
1017 }
893da041 1018 while (array_remove(vips, ARRAY_HEAD, &vip))
d2e8f20d
TB
1019 {
1020 if (local)
1021 {
8394ea2a 1022 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
d2e8f20d
TB
1023 }
1024 vip->destroy(vip);
1025 }
1026}
1027
101d26ba 1028METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
8bced61b 1029 private_ike_sa_t *this, bool local)
c532d646
MW
1030{
1031 if (local)
1032 {
893da041 1033 return array_create_enumerator(this->my_vips);
c532d646 1034 }
893da041 1035 return array_create_enumerator(this->other_vips);
c532d646
MW
1036}
1037
94bbc602 1038METHOD(ike_sa_t, add_peer_address, void,
8bced61b 1039 private_ike_sa_t *this, host_t *host)
c532d646 1040{
893da041 1041 array_insert_create(&this->peer_addresses, ARRAY_TAIL, host);
c532d646 1042}
7daf5226 1043
94bbc602 1044METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*,
8bced61b 1045 private_ike_sa_t *this)
c532d646 1046{
893da041 1047 if (this->peer_addresses)
12715f19 1048 {
893da041 1049 return array_create_enumerator(this->peer_addresses);
12715f19
TB
1050 }
1051 /* in case we don't have MOBIKE */
1052 return enumerator_create_single(this->other_host, NULL);
572abc6c
TB
1053}
1054
94bbc602 1055METHOD(ike_sa_t, clear_peer_addresses, void,
572abc6c
TB
1056 private_ike_sa_t *this)
1057{
893da041
MW
1058 array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy));
1059 this->peer_addresses = NULL;
c532d646 1060}
9d9a772e 1061
8bced61b
MW
1062METHOD(ike_sa_t, has_mapping_changed, bool,
1063 private_ike_sa_t *this, chunk_t hash)
9d9a772e
MW
1064{
1065 if (this->nat_detection_dest.ptr == NULL)
1066 {
1067 this->nat_detection_dest = chunk_clone(hash);
1068 return FALSE;
1069 }
1070 if (chunk_equals(hash, this->nat_detection_dest))
1071 {
1072 return FALSE;
1073 }
1074 free(this->nat_detection_dest.ptr);
1075 this->nat_detection_dest = chunk_clone(hash);
1076 return TRUE;
1077}
1078
277f02ce
TB
1079METHOD(ike_sa_t, float_ports, void,
1080 private_ike_sa_t *this)
1081{
85bfab62
TB
1082 /* even if the remote port is not 500 (e.g. because the response was natted)
1083 * we switch the remote port if we used port 500 */
1084 if (this->other_host->get_port(this->other_host) == IKEV2_UDP_PORT ||
1085 this->my_host->get_port(this->my_host) == IKEV2_UDP_PORT)
1086 {
1087 this->other_host->set_port(this->other_host, IKEV2_NATT_PORT);
1088 }
b223d517
TB
1089 if (this->my_host->get_port(this->my_host) ==
1090 charon->socket->get_port(charon->socket, FALSE))
277f02ce 1091 {
b223d517
TB
1092 this->my_host->set_port(this->my_host,
1093 charon->socket->get_port(charon->socket, TRUE));
277f02ce 1094 }
277f02ce
TB
1095}
1096
8bced61b 1097METHOD(ike_sa_t, update_hosts, void,
2082417d 1098 private_ike_sa_t *this, host_t *me, host_t *other, bool force)
0fdc3c7f 1099{
2b3100b5 1100 bool update = FALSE;
7daf5226 1101
2b3100b5 1102 if (me == NULL)
8dfbe71b 1103 {
2b3100b5 1104 me = this->my_host;
8dfbe71b 1105 }
2b3100b5 1106 if (other == NULL)
3dd3c5f3 1107 {
2b3100b5 1108 other = this->other_host;
3dd3c5f3 1109 }
7daf5226 1110
2b3100b5
MW
1111 /* apply hosts on first received message */
1112 if (this->my_host->is_anyaddr(this->my_host) ||
1113 this->other_host->is_anyaddr(this->other_host))
3dd3c5f3 1114 {
2b3100b5
MW
1115 set_my_host(this, me->clone(me));
1116 set_other_host(this, other->clone(other));
1117 update = TRUE;
3dd3c5f3
MW
1118 }
1119 else
1120 {
2b3100b5 1121 /* update our address in any case */
21dd4c4b 1122 if (force && !me->equals(me, this->my_host))
3dd3c5f3 1123 {
e1fe2781 1124 charon->bus->ike_update(charon->bus, &this->public, TRUE, me);
2b3100b5
MW
1125 set_my_host(this, me->clone(me));
1126 update = TRUE;
3dd3c5f3 1127 }
7daf5226 1128
472156ee
TB
1129 if (!other->equals(other, this->other_host) &&
1130 (force || has_condition(this, COND_NAT_THERE)))
3dd3c5f3 1131 {
472156ee
TB
1132 /* only update other's address if we are behind a static NAT,
1133 * which we assume is the case if we are not initiator */
1134 if (force ||
1135 (!has_condition(this, COND_NAT_HERE) ||
1136 !has_condition(this, COND_ORIGINAL_INITIATOR)))
2b3100b5 1137 {
e1fe2781 1138 charon->bus->ike_update(charon->bus, &this->public, FALSE, other);
2b3100b5
MW
1139 set_other_host(this, other->clone(other));
1140 update = TRUE;
1141 }
3dd3c5f3
MW
1142 }
1143 }
7daf5226 1144
2b3100b5
MW
1145 /* update all associated CHILD_SAs, if required */
1146 if (update)
3dd3c5f3 1147 {
e2630434 1148 enumerator_t *enumerator;
2b3100b5 1149 child_sa_t *child_sa;
893da041 1150 linked_list_t *vips;
7daf5226 1151
893da041
MW
1152 vips = linked_list_create_from_enumerator(
1153 array_create_enumerator(this->my_vips));
1154
1155 enumerator = array_create_enumerator(this->child_sas);
1156 while (enumerator->enumerate(enumerator, &child_sa))
2b3100b5 1157 {
38227d0e
MW
1158 charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
1159 charon->child_sa_manager->add(charon->child_sa_manager,
1160 child_sa, &this->public);
1161
893da041
MW
1162 if (child_sa->update(child_sa, this->my_host, this->other_host,
1163 vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
ea625fab
TB
1164 {
1165 this->public.rekey_child_sa(&this->public,
1166 child_sa->get_protocol(child_sa),
1167 child_sa->get_spi(child_sa, TRUE));
1168 }
38227d0e 1169
2b3100b5 1170 }
e2630434 1171 enumerator->destroy(enumerator);
893da041
MW
1172
1173 vips->destroy(vips);
3dd3c5f3 1174 }
8d77edde
MW
1175}
1176
5b15bd5f
MW
1177/**
1178 * Set configured DSCP value on packet
1179 */
1180static void set_dscp(private_ike_sa_t *this, packet_t *packet)
1181{
1182 ike_cfg_t *ike_cfg;
1183
1184 /* prefer IKE config on peer_cfg, as its selection is more accurate
1185 * then the initial IKE config */
1186 if (this->peer_cfg)
1187 {
1188 ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
1189 }
1190 else
1191 {
1192 ike_cfg = this->ike_cfg;
1193 }
1194 if (ike_cfg)
1195 {
1196 packet->set_dscp(packet, ike_cfg->get_dscp(ike_cfg));
1197 }
1198}
1199
8bced61b
MW
1200METHOD(ike_sa_t, generate_message, status_t,
1201 private_ike_sa_t *this, message_t *message, packet_t **packet)
8d77edde 1202{
47b8f6ef
MW
1203 status_t status;
1204
9ca5d028 1205 if (message->is_encoded(message))
5b15bd5f 1206 { /* already encoded in task, but set DSCP value */
9ca5d028 1207 *packet = message->get_packet(message);
5b15bd5f 1208 set_dscp(this, *packet);
9ca5d028
MW
1209 return SUCCESS;
1210 }
6180a558 1211 this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
c60c7694 1212 message->set_ike_sa_id(message, this->ike_sa_id);
47b8f6ef
MW
1213 charon->bus->message(charon->bus, message, FALSE, TRUE);
1214 status = message->generate(message, this->keymat, packet);
1215 if (status == SUCCESS)
c60c7694 1216 {
5b15bd5f 1217 set_dscp(this, *packet);
47b8f6ef 1218 charon->bus->message(charon->bus, message, FALSE, FALSE);
b9d9f188 1219 }
47b8f6ef 1220 return status;
3dd3c5f3
MW
1221}
1222
525cc46c
TB
1223CALLBACK(filter_fragments, bool,
1224 private_ike_sa_t *this, enumerator_t *orig, va_list args)
40bab9a1 1225{
525cc46c
TB
1226 packet_t *fragment, **packet;
1227
1228 VA_ARGS_VGET(args, packet);
1229
1230 if (orig->enumerate(orig, &fragment))
1231 {
1232 *packet = fragment->clone(fragment);
1233 set_dscp(this, *packet);
1234 return TRUE;
1235 }
1236 return FALSE;
40bab9a1
TB
1237}
1238
1239METHOD(ike_sa_t, generate_message_fragmented, status_t,
1240 private_ike_sa_t *this, message_t *message, enumerator_t **packets)
1241{
1242 enumerator_t *fragments;
1243 packet_t *packet;
1244 status_t status;
1245 bool use_frags = FALSE;
e35bb6e9 1246 bool pre_generated = FALSE;
40bab9a1 1247
1446fd8a 1248 if (this->ike_cfg)
40bab9a1
TB
1249 {
1250 switch (this->ike_cfg->fragmentation(this->ike_cfg))
1251 {
1252 case FRAGMENTATION_FORCE:
1253 use_frags = TRUE;
1254 break;
1255 case FRAGMENTATION_YES:
1256 use_frags = supports_extension(this, EXT_IKE_FRAGMENTATION);
05db0f97
VR
1257 if (use_frags && this->version == IKEV1 &&
1258 supports_extension(this, EXT_MS_WINDOWS))
1259 {
1260 /* It seems Windows 7 and 8 peers only accept proprietary
1261 * fragmented messages if they expect certificates. */
1262 use_frags = message->get_payload(message,
1263 PLV1_CERTIFICATE) != NULL;
1264 }
40bab9a1
TB
1265 break;
1266 default:
1267 break;
1268 }
1269 }
1270 if (!use_frags)
1271 {
1272 status = generate_message(this, message, &packet);
1273 if (status != SUCCESS)
1274 {
1275 return status;
1276 }
1277 *packets = enumerator_create_single(packet, NULL);
1278 return SUCCESS;
1279 }
1280
e35bb6e9 1281 pre_generated = message->is_encoded(message);
40bab9a1
TB
1282 this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
1283 message->set_ike_sa_id(message, this->ike_sa_id);
e35bb6e9
TB
1284 if (!pre_generated)
1285 {
1286 charon->bus->message(charon->bus, message, FALSE, TRUE);
1287 }
40bab9a1
TB
1288 status = message->fragment(message, this->keymat, this->fragment_size,
1289 &fragments);
1290 if (status == SUCCESS)
1291 {
e35bb6e9
TB
1292 if (!pre_generated)
1293 {
1294 charon->bus->message(charon->bus, message, FALSE, FALSE);
1295 }
525cc46c 1296 *packets = enumerator_create_filter(fragments, filter_fragments,
40bab9a1
TB
1297 this, NULL);
1298 }
1299 return status;
1300}
1301
8bced61b
MW
1302METHOD(ike_sa_t, set_kmaddress, void,
1303 private_ike_sa_t *this, host_t *local, host_t *remote)
d487b4b7
AS
1304{
1305 DESTROY_IF(this->local_host);
1306 DESTROY_IF(this->remote_host);
1307 this->local_host = local->clone(local);
1308 this->remote_host = remote->clone(remote);
1309}
1310
dc04b7c7 1311#ifdef ME
8bced61b
MW
1312METHOD(ike_sa_t, act_as_mediation_server, void,
1313 private_ike_sa_t *this)
22452f70
TB
1314{
1315 charon->mediation_manager->update_sa_id(charon->mediation_manager,
1316 this->other_id, this->ike_sa_id);
1317 this->is_mediation_server = TRUE;
1318}
1319
8bced61b
MW
1320METHOD(ike_sa_t, get_server_reflexive_host, host_t*,
1321 private_ike_sa_t *this)
d5cc1758
TB
1322{
1323 return this->server_reflexive_host;
1324}
1325
8bced61b
MW
1326METHOD(ike_sa_t, set_server_reflexive_host, void,
1327 private_ike_sa_t *this, host_t *host)
d5cc1758
TB
1328{
1329 DESTROY_IF(this->server_reflexive_host);
1330 this->server_reflexive_host = host;
1331}
1332
8bced61b
MW
1333METHOD(ike_sa_t, get_connect_id, chunk_t,
1334 private_ike_sa_t *this)
9c2a905d
TB
1335{
1336 return this->connect_id;
1337}
1338
8bced61b
MW
1339METHOD(ike_sa_t, respond, status_t,
1340 private_ike_sa_t *this, identification_t *peer_id, chunk_t connect_id)
d5cc1758 1341{
dc04b7c7
TB
1342 ike_me_t *task = ike_me_create(&this->public, TRUE);
1343 task->respond(task, peer_id, connect_id);
d5cc1758
TB
1344 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1345 return this->task_manager->initiate(this->task_manager);
1346}
1347
8bced61b
MW
1348METHOD(ike_sa_t, callback, status_t,
1349 private_ike_sa_t *this, identification_t *peer_id)
d5cc1758 1350{
dc04b7c7 1351 ike_me_t *task = ike_me_create(&this->public, TRUE);
d5cc1758
TB
1352 task->callback(task, peer_id);
1353 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1354 return this->task_manager->initiate(this->task_manager);
1355}
1356
8bced61b
MW
1357METHOD(ike_sa_t, relay, status_t,
1358 private_ike_sa_t *this, identification_t *requester, chunk_t connect_id,
1359 chunk_t connect_key, linked_list_t *endpoints, bool response)
d5cc1758 1360{
dc04b7c7
TB
1361 ike_me_t *task = ike_me_create(&this->public, TRUE);
1362 task->relay(task, requester, connect_id, connect_key, endpoints, response);
d5cc1758
TB
1363 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1364 return this->task_manager->initiate(this->task_manager);
1365}
1366
8bced61b
MW
1367METHOD(ike_sa_t, initiate_mediation, status_t,
1368 private_ike_sa_t *this, peer_cfg_t *mediated_cfg)
d5cc1758 1369{
dc04b7c7 1370 ike_me_t *task = ike_me_create(&this->public, TRUE);
d5cc1758
TB
1371 task->connect(task, mediated_cfg->get_peer_id(mediated_cfg));
1372 this->task_manager->queue_task(this->task_manager, (task_t*)task);
1373 return this->task_manager->initiate(this->task_manager);
1374}
1375
8bced61b
MW
1376METHOD(ike_sa_t, initiate_mediated, status_t,
1377 private_ike_sa_t *this, host_t *me, host_t *other, chunk_t connect_id)
d5cc1758 1378{
471f9230
TB
1379 set_my_host(this, me->clone(me));
1380 set_other_host(this, other->clone(other));
4a6474c2 1381 chunk_free(&this->connect_id);
9c2a905d 1382 this->connect_id = chunk_clone(connect_id);
d5cc1758
TB
1383 return this->task_manager->initiate(this->task_manager);
1384}
dc04b7c7 1385#endif /* ME */
d5cc1758 1386
5a22a021
MW
1387/**
1388 * Resolve DNS host in configuration
1389 */
1390static void resolve_hosts(private_ike_sa_t *this)
1391{
1392 host_t *host;
0edce687 1393 int family = AF_UNSPEC;
bf92887a
TB
1394
1395 switch (charon->socket->supported_families(charon->socket))
1396 {
1397 case SOCKET_FAMILY_IPV4:
1398 family = AF_INET;
1399 break;
1400 case SOCKET_FAMILY_IPV6:
1401 family = AF_INET6;
1402 break;
1403 case SOCKET_FAMILY_BOTH:
1404 case SOCKET_FAMILY_NONE:
1405 break;
1406 }
7daf5226 1407
a11048ad
TB
1408 /* if an IP address is set locally, use the same family to resolve remote */
1409 if (family == AF_UNSPEC && !this->remote_host)
1410 {
1411 if (this->local_host)
1412 {
1413 family = this->local_host->get_family(this->local_host);
1414 }
1415 else
1416 {
1417 family = ike_cfg_get_family(this->ike_cfg, TRUE);
1418 }
1419 }
1420
d487b4b7
AS
1421 if (this->remote_host)
1422 {
1423 host = this->remote_host->clone(this->remote_host);
1424 host->set_port(host, IKEV2_UDP_PORT);
1425 }
1426 else
1427 {
0edce687 1428 host = this->ike_cfg->resolve_other(this->ike_cfg, family);
d487b4b7 1429 }
5a22a021
MW
1430 if (host)
1431 {
6f7a3b33
TB
1432 if (!host->is_anyaddr(host) ||
1433 this->other_host->is_anyaddr(this->other_host))
1434 { /* don't set to %any if we currently have an address, but the
1435 * address family might have changed */
1436 set_other_host(this, host);
1437 }
faebdeac 1438 else
2d14cb4d
TB
1439 { /* reuse the original port as some implementations might not like
1440 * initial IKE messages on other ports */
1441 this->other_host->set_port(this->other_host, host->get_port(host));
faebdeac
TB
1442 host->destroy(host);
1443 }
5a22a021 1444 }
7daf5226 1445
d487b4b7 1446 if (this->local_host)
e7991a2e 1447 {
d487b4b7 1448 host = this->local_host->clone(this->local_host);
b223d517 1449 host->set_port(host, charon->socket->get_port(charon->socket, FALSE));
d487b4b7
AS
1450 }
1451 else
1452 {
c6a8990b
MW
1453 /* use same address family as for other */
1454 if (!this->other_host->is_anyaddr(this->other_host))
1455 {
1456 family = this->other_host->get_family(this->other_host);
1457 }
0edce687 1458 host = this->ike_cfg->resolve_me(this->ike_cfg, family);
7daf5226 1459
d487b4b7
AS
1460 if (host && host->is_anyaddr(host) &&
1461 !this->other_host->is_anyaddr(this->other_host))
5353f22e 1462 {
d487b4b7 1463 host->destroy(host);
8394ea2a
TB
1464 host = charon->kernel->get_source_addr(charon->kernel,
1465 this->other_host, NULL);
d487b4b7
AS
1466 if (host)
1467 {
cc2eadde 1468 host->set_port(host, this->ike_cfg->get_my_port(this->ike_cfg));
d487b4b7 1469 }
9717826f
MW
1470 else
1471 { /* fallback to address family specific %any(6), if configured */
0edce687 1472 host = this->ike_cfg->resolve_me(this->ike_cfg, family);
9717826f 1473 }
5353f22e 1474 }
e7991a2e 1475 }
5a22a021
MW
1476 if (host)
1477 {
e7991a2e 1478 set_my_host(this, host);
5a22a021
MW
1479 }
1480}
1481
8bced61b 1482METHOD(ike_sa_t, initiate, status_t,
b12c53ce 1483 private_ike_sa_t *this, child_cfg_t *child_cfg, uint32_t reqid,
8bced61b 1484 traffic_selector_t *tsi, traffic_selector_t *tsr)
aad398a7 1485{
60c82591
TB
1486 bool defer_initiate = FALSE;
1487
c60c7694 1488 if (this->state == IKE_CREATED)
c0593835 1489 {
a994050e
MW
1490 if (this->my_host->is_anyaddr(this->my_host) ||
1491 this->other_host->is_anyaddr(this->other_host))
1492 {
1493 resolve_hosts(this);
1494 }
7daf5226 1495
d5cc1758 1496 if (this->other_host->is_anyaddr(this->other_host)
dc04b7c7 1497#ifdef ME
d5cc1758 1498 && !this->peer_cfg->get_mediated_by(this->peer_cfg)
dc04b7c7 1499#endif /* ME */
d5cc1758 1500 )
128ca073 1501 {
0edce687
MW
1502 char *addr;
1503
be8af56e 1504 addr = this->ike_cfg->get_other_addr(this->ike_cfg);
53d2164c 1505 if (!this->retry_initiate_interval)
60c82591 1506 {
53d2164c
TB
1507 DBG1(DBG_IKE, "unable to resolve %s, initiate aborted",
1508 addr);
60c82591
TB
1509 DESTROY_IF(child_cfg);
1510 charon->bus->alert(charon->bus, ALERT_PEER_ADDR_FAILED);
1511 return DESTROY_ME;
1512 }
1513 DBG1(DBG_IKE, "unable to resolve %s, retrying in %ds",
1514 addr, this->retry_initiate_interval);
1515 defer_initiate = TRUE;
128ca073 1516 }
7daf5226 1517
faf9569f 1518 set_condition(this, COND_ORIGINAL_INITIATOR, TRUE);
a60daa07 1519 this->task_manager->queue_ike(this->task_manager);
d5cc1758
TB
1520 }
1521
dc04b7c7 1522#ifdef ME
4a6474c2 1523 if (this->peer_cfg->is_mediation(this->peer_cfg))
f967db31
TB
1524 {
1525 if (this->state == IKE_ESTABLISHED)
1526 {
484a06bc
TB
1527 /* mediation connection is already established, retrigger state
1528 * change to notify bus listeners */
f967db31
TB
1529 DBG1(DBG_IKE, "mediation connection is already up");
1530 set_state(this, IKE_ESTABLISHED);
1531 }
c3f803c4 1532 DESTROY_IF(child_cfg);
d5cc1758
TB
1533 }
1534 else
dc04b7c7 1535#endif /* ME */
9c64f214 1536 if (child_cfg)
d5cc1758 1537 {
38951252 1538 /* normal IKE_SA with CHILD_SA */
fe43d9a2
MW
1539 this->task_manager->queue_child(this->task_manager, child_cfg, reqid,
1540 tsi, tsr);
4a6474c2
TB
1541#ifdef ME
1542 if (this->peer_cfg->get_mediated_by(this->peer_cfg))
1543 {
1544 /* mediated connection, initiate mediation process */
1545 job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
bb381e26 1546 lib->processor->queue_job(lib->processor, job);
4a6474c2
TB
1547 return SUCCESS;
1548 }
1549#endif /* ME */
c60c7694 1550 }
7daf5226 1551
60c82591
TB
1552 if (defer_initiate)
1553 {
77e42826
TB
1554 if (!this->retry_initiate_queued)
1555 {
1556 job_t *job = (job_t*)retry_initiate_job_create(this->ike_sa_id);
1557 lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
1558 this->retry_initiate_interval);
1559 this->retry_initiate_queued = TRUE;
1560 }
60c82591
TB
1561 return SUCCESS;
1562 }
77e42826 1563 this->retry_initiate_queued = FALSE;
c60c7694 1564 return this->task_manager->initiate(this->task_manager);
aad398a7
JH
1565}
1566
77e42826
TB
1567METHOD(ike_sa_t, retry_initiate, status_t,
1568 private_ike_sa_t *this)
1569{
1570 if (this->retry_initiate_queued)
1571 {
1572 this->retry_initiate_queued = FALSE;
1573 return initiate(this, NULL, 0, NULL, NULL);
1574 }
1575 return SUCCESS;
1576}
1577
8bced61b
MW
1578METHOD(ike_sa_t, process_message, status_t,
1579 private_ike_sa_t *this, message_t *message)
98f97433
MW
1580{
1581 status_t status;
7daf5226 1582
c610f424
MW
1583 if (this->state == IKE_PASSIVE)
1584 { /* do not handle messages in passive state */
1585 return FAILED;
1586 }
448e2e29 1587 if (message->get_major_version(message) != this->version)
98f97433 1588 {
448e2e29 1589 DBG1(DBG_IKE, "ignoring %N IKEv%u exchange on %N SA",
98f97433 1590 exchange_type_names, message->get_exchange_type(message),
448e2e29
MW
1591 message->get_major_version(message),
1592 ike_version_names, this->version);
1593 /* TODO-IKEv1: fall back to IKEv1 if we receive an IKEv1
1594 * INVALID_MAJOR_VERSION on an IKEv2 SA. */
1595 return FAILED;
98f97433 1596 }
68c6863b 1597 status = this->task_manager->process_message(this->task_manager, message);
b24b73b7 1598 if (this->flush_auth_cfg && this->state == IKE_ESTABLISHED)
98f97433 1599 {
e41adf5f
TB
1600 /* authentication completed but if the online validation is suspended we
1601 * need the auth cfgs until we did the delayed verification, we flush
1602 * them afterwards */
1603 if (!has_condition(this, COND_ONLINE_VALIDATION_SUSPENDED))
1604 {
1605 this->flush_auth_cfg = FALSE;
1606 flush_auth_cfgs(this);
1607 }
98f97433 1608 }
44ce7493 1609 return status;
98f97433 1610}
8dfbe71b 1611
8bced61b
MW
1612METHOD(ike_sa_t, get_id, ike_sa_id_t*,
1613 private_ike_sa_t *this)
0df63d6b 1614{
8dfbe71b 1615 return this->ike_sa_id;
0df63d6b
JH
1616}
1617
0b611540
TB
1618METHOD(ike_sa_t, get_version, ike_version_t,
1619 private_ike_sa_t *this)
1620{
1621 return this->version;
1622}
1623
8bced61b
MW
1624METHOD(ike_sa_t, get_my_id, identification_t*,
1625 private_ike_sa_t *this)
0fdc3c7f 1626{
8dfbe71b 1627 return this->my_id;
8d68033e
JH
1628}
1629
8bced61b
MW
1630METHOD(ike_sa_t, set_my_id, void,
1631 private_ike_sa_t *this, identification_t *me)
8d68033e 1632{
c0593835 1633 DESTROY_IF(this->my_id);
8dfbe71b 1634 this->my_id = me;
0fdc3c7f
JH
1635}
1636
8bced61b
MW
1637METHOD(ike_sa_t, get_other_id, identification_t*,
1638 private_ike_sa_t *this)
30b5b412 1639{
8dfbe71b 1640 return this->other_id;
3dd3c5f3 1641}
8dfbe71b 1642
8bced61b
MW
1643METHOD(ike_sa_t, get_other_eap_id, identification_t*,
1644 private_ike_sa_t *this)
045833c7
MW
1645{
1646 identification_t *id = NULL, *current;
1647 enumerator_t *enumerator;
1648 auth_cfg_t *cfg;
1649
893da041 1650 enumerator = array_create_enumerator(this->other_auths);
045833c7
MW
1651 while (enumerator->enumerate(enumerator, &cfg))
1652 {
1653 /* prefer EAP-Identity of last round */
1654 current = cfg->get(cfg, AUTH_RULE_EAP_IDENTITY);
1655 if (!current || current->get_type(current) == ID_ANY)
beab4a90
MW
1656 {
1657 current = cfg->get(cfg, AUTH_RULE_XAUTH_IDENTITY);
1658 }
1659 if (!current || current->get_type(current) == ID_ANY)
045833c7
MW
1660 {
1661 current = cfg->get(cfg, AUTH_RULE_IDENTITY);
1662 }
1663 if (current && current->get_type(current) != ID_ANY)
1664 {
1665 id = current;
1666 continue;
1667 }
1668 }
1669 enumerator->destroy(enumerator);
1670 if (id)
1671 {
1672 return id;
1673 }
1674 return this->other_id;
1675}
1676
8bced61b
MW
1677METHOD(ike_sa_t, set_other_id, void,
1678 private_ike_sa_t *this, identification_t *other)
3dd3c5f3 1679{
c0593835 1680 DESTROY_IF(this->other_id);
8dfbe71b 1681 this->other_id = other;
30b5b412
MW
1682}
1683
dec3c184
TB
1684METHOD(ike_sa_t, get_if_id, uint32_t,
1685 private_ike_sa_t *this, bool inbound)
1686{
1687 return inbound ? this->if_id_in : this->if_id_out;
1688}
1689
8bced61b
MW
1690METHOD(ike_sa_t, add_child_sa, void,
1691 private_ike_sa_t *this, child_sa_t *child_sa)
32b6500f 1692{
893da041 1693 array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
38227d0e
MW
1694 charon->child_sa_manager->add(charon->child_sa_manager,
1695 child_sa, &this->public);
32b6500f
MW
1696}
1697
8bced61b 1698METHOD(ike_sa_t, get_child_sa, child_sa_t*,
b12c53ce 1699 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi, bool inbound)
695723d4 1700{
e2630434 1701 enumerator_t *enumerator;
695723d4 1702 child_sa_t *current, *found = NULL;
7daf5226 1703
893da041 1704 enumerator = array_create_enumerator(this->child_sas);
e2630434 1705 while (enumerator->enumerate(enumerator, (void**)&current))
c60c7694 1706 {
698d7749 1707 if (current->get_spi(current, inbound) == spi &&
191a26a6 1708 current->get_protocol(current) == protocol)
695723d4
MW
1709 {
1710 found = current;
1711 }
1712 }
e2630434 1713 enumerator->destroy(enumerator);
695723d4 1714 return found;
8d77edde
MW
1715}
1716
4bbce1ef 1717METHOD(ike_sa_t, get_child_count, int,
8bced61b 1718 private_ike_sa_t *this)
3183006d 1719{
893da041 1720 return array_count(this->child_sas);
4bbce1ef
TB
1721}
1722
38227d0e
MW
1723/**
1724 * Private data of a create_child_sa_enumerator()
1725 */
1726typedef struct {
1727 /** implements enumerator */
1728 enumerator_t public;
1729 /** inner array enumerator */
1730 enumerator_t *inner;
1731 /** current item */
1732 child_sa_t *current;
1733} child_enumerator_t;
1734
1735METHOD(enumerator_t, child_enumerate, bool,
95a63bf2 1736 child_enumerator_t *this, va_list args)
38227d0e 1737{
95a63bf2
TB
1738 child_sa_t **child_sa;
1739
1740 VA_ARGS_VGET(args, child_sa);
38227d0e
MW
1741 if (this->inner->enumerate(this->inner, &this->current))
1742 {
1743 *child_sa = this->current;
1744 return TRUE;
1745 }
1746 return FALSE;
1747}
1748
1749METHOD(enumerator_t, child_enumerator_destroy, void,
1750 child_enumerator_t *this)
1751{
1752 this->inner->destroy(this->inner);
1753 free(this);
1754}
1755
4bbce1ef
TB
1756METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
1757 private_ike_sa_t *this)
1758{
38227d0e
MW
1759 child_enumerator_t *enumerator;
1760
1761 INIT(enumerator,
1762 .public = {
95a63bf2
TB
1763 .enumerate = enumerator_enumerate_default,
1764 .venumerate = _child_enumerate,
38227d0e
MW
1765 .destroy = _child_enumerator_destroy,
1766 },
1767 .inner = array_create_enumerator(this->child_sas),
1768 );
1769 return &enumerator->public;
4bbce1ef
TB
1770}
1771
1772METHOD(ike_sa_t, remove_child_sa, void,
1773 private_ike_sa_t *this, enumerator_t *enumerator)
1774{
38227d0e
MW
1775 child_enumerator_t *ce = (child_enumerator_t*)enumerator;
1776
1777 charon->child_sa_manager->remove(charon->child_sa_manager, ce->current);
1778 array_remove_at(this->child_sas, ce->inner);
3183006d
MW
1779}
1780
8bced61b 1781METHOD(ike_sa_t, rekey_child_sa, status_t,
b12c53ce 1782 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi)
8d77edde 1783{
916cdca8
MW
1784 if (this->state == IKE_PASSIVE)
1785 {
1786 return INVALID_STATE;
1787 }
463a73cc 1788 this->task_manager->queue_child_rekey(this->task_manager, protocol, spi);
394eb35b 1789 return this->task_manager->initiate(this->task_manager);
698d7749
MW
1790}
1791
8bced61b 1792METHOD(ike_sa_t, delete_child_sa, status_t,
b12c53ce 1793 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi, bool expired)
698d7749 1794{
916cdca8
MW
1795 if (this->state == IKE_PASSIVE)
1796 {
1797 return INVALID_STATE;
1798 }
3a925f74
MW
1799 this->task_manager->queue_child_delete(this->task_manager,
1800 protocol, spi, expired);
394eb35b 1801 return this->task_manager->initiate(this->task_manager);
698d7749
MW
1802}
1803
8bced61b 1804METHOD(ike_sa_t, destroy_child_sa, status_t,
b12c53ce 1805 private_ike_sa_t *this, protocol_id_t protocol, uint32_t spi)
698d7749 1806{
e2630434 1807 enumerator_t *enumerator;
698d7749
MW
1808 child_sa_t *child_sa;
1809 status_t status = NOT_FOUND;
7daf5226 1810
38227d0e 1811 enumerator = create_child_sa_enumerator(this);
e2630434 1812 while (enumerator->enumerate(enumerator, (void**)&child_sa))
698d7749
MW
1813 {
1814 if (child_sa->get_protocol(child_sa) == protocol &&
1815 child_sa->get_spi(child_sa, TRUE) == spi)
1816 {
38227d0e 1817 remove_child_sa(this, enumerator);
698d7749 1818 child_sa->destroy(child_sa);
698d7749
MW
1819 status = SUCCESS;
1820 break;
1821 }
8d77edde 1822 }
e2630434 1823 enumerator->destroy(enumerator);
698d7749 1824 return status;
8d77edde
MW
1825}
1826
8bced61b 1827METHOD(ike_sa_t, delete_, status_t,
a79d5103 1828 private_ike_sa_t *this, bool force)
6fe03b0a 1829{
a79d5103
TB
1830 status_t status = DESTROY_ME;
1831
6fe03b0a
MW
1832 switch (this->state)
1833 {
3a0b67bc 1834 case IKE_ESTABLISHED:
ebc6445d
TB
1835 case IKE_REKEYING:
1836 if (time_monotonic(NULL) >= this->stats[STAT_DELETE] &&
1837 !(this->version == IKEV1 && this->state == IKE_REKEYING))
1838 { /* IKE_SA hard lifetime hit, ignored for reauthenticated
1839 * IKEv1 SAs */
c45cf904
MW
1840 charon->bus->alert(charon->bus, ALERT_IKE_SA_EXPIRED);
1841 }
3ed148b3 1842 this->task_manager->queue_ike_delete(this->task_manager);
a79d5103
TB
1843 status = this->task_manager->initiate(this->task_manager);
1844 break;
98f97433 1845 case IKE_CREATED:
a985db3f 1846 DBG1(DBG_IKE, "deleting unestablished IKE_SA");
98f97433 1847 break;
c610f424
MW
1848 case IKE_PASSIVE:
1849 break;
6fe03b0a 1850 default:
a79d5103
TB
1851 DBG1(DBG_IKE, "destroying IKE_SA in state %N without notification",
1852 ike_sa_state_names, this->state);
1853 force = TRUE;
c60c7694 1854 break;
6fe03b0a 1855 }
a79d5103
TB
1856
1857 if (force)
1858 {
1859 status = DESTROY_ME;
1860
1861 if (this->version == IKEV2)
1862 { /* for IKEv1 we trigger this in the ISAKMP delete task */
1863 switch (this->state)
1864 {
1865 case IKE_ESTABLISHED:
1866 case IKE_REKEYING:
1867 case IKE_DELETING:
1868 charon->bus->ike_updown(charon->bus, &this->public, FALSE);
1869 default:
1870 break;
1871 }
1872 }
1873 }
1874 return status;
6fe03b0a
MW
1875}
1876
8bced61b
MW
1877METHOD(ike_sa_t, rekey, status_t,
1878 private_ike_sa_t *this)
fe04e93a 1879{
916cdca8
MW
1880 if (this->state == IKE_PASSIVE)
1881 {
1882 return INVALID_STATE;
1883 }
dab60d64 1884 this->task_manager->queue_ike_rekey(this->task_manager);
c60c7694 1885 return this->task_manager->initiate(this->task_manager);
fe04e93a
MW
1886}
1887
8bced61b
MW
1888METHOD(ike_sa_t, reauth, status_t,
1889 private_ike_sa_t *this)
6fe03b0a 1890{
916cdca8
MW
1891 if (this->state == IKE_PASSIVE)
1892 {
1893 return INVALID_STATE;
1894 }
34e402ef
TB
1895 if (this->state == IKE_CONNECTING)
1896 {
1897 DBG0(DBG_IKE, "reinitiating IKE_SA %s[%d]",
1898 get_name(this), this->unique_id);
c3539961 1899 reset(this, TRUE);
34e402ef
TB
1900 return this->task_manager->initiate(this->task_manager);
1901 }
ee614711
MW
1902 /* we can't reauthenticate as responder when we use EAP or virtual IPs.
1903 * If the peer does not support RFC4478, there is no way to keep the
1904 * IKE_SA up. */
faf9569f 1905 if (!has_condition(this, COND_ORIGINAL_INITIATOR))
ee614711
MW
1906 {
1907 DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
893da041 1908 if (array_count(this->other_vips) != 0 ||
7e9e1f96 1909 has_condition(this, COND_XAUTH_AUTHENTICATED) ||
78abba42
TB
1910 has_condition(this, COND_EAP_AUTHENTICATED)
1911#ifdef ME
484a06bc 1912 /* as mediation server we too cannot reauth the IKE_SA */
78abba42
TB
1913 || this->is_mediation_server
1914#endif /* ME */
1915 )
ee614711 1916 {
e9fcf1c6 1917 time_t del, now;
7daf5226 1918
e9fcf1c6
MW
1919 del = this->stats[STAT_DELETE];
1920 now = time_monotonic(NULL);
fbaf5cd2
MW
1921 DBG1(DBG_IKE, "IKE_SA %s[%d] will timeout in %V",
1922 get_name(this), this->unique_id, &now, &del);
ee614711
MW
1923 return FAILED;
1924 }
1925 else
1926 {
fbaf5cd2
MW
1927 DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d] actively",
1928 get_name(this), this->unique_id);
ee614711
MW
1929 }
1930 }
fbaf5cd2
MW
1931 else
1932 {
1933 DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]",
1934 get_name(this), this->unique_id);
1935 }
873b63b7 1936 set_condition(this, COND_REAUTHENTICATING, TRUE);
cedb412e 1937 this->task_manager->queue_ike_reauth(this->task_manager);
26424f03 1938 return this->task_manager->initiate(this->task_manager);
6fe03b0a 1939}
face844a 1940
68db844f 1941/**
96b61792 1942 * Check if any tasks of a specific type are queued in the given queue.
68db844f 1943 */
96b61792
TB
1944static bool is_task_queued(private_ike_sa_t *this, task_queue_t queue,
1945 task_type_t type)
68db844f
TB
1946{
1947 enumerator_t *enumerator;
1948 task_t *task;
1949 bool found = FALSE;
1950
1951 enumerator = this->task_manager->create_task_enumerator(this->task_manager,
1952 queue);
1953 while (enumerator->enumerate(enumerator, &task))
1954 {
96b61792 1955 if (task->get_type(task) == type)
68db844f
TB
1956 {
1957 found = TRUE;
1958 break;
1959 }
1960 }
1961 enumerator->destroy(enumerator);
1962 return found;
1963}
1964
96b61792
TB
1965/**
1966 * Check if any tasks to create CHILD_SAs are queued in the given queue.
1967 */
1968static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
1969{
1970 return is_task_queued(this, queue,
1971 this->version == IKEV1 ? TASK_QUICK_MODE : TASK_CHILD_CREATE);
1972}
1973
1974/**
1975 * Check if any tasks to delete the IKE_SA are queued in the given queue.
1976 */
1977static bool is_delete_queued(private_ike_sa_t *this, task_queue_t queue)
1978{
1979 return is_task_queued(this, queue,
1980 this->version == IKEV1 ? TASK_ISAKMP_DELETE : TASK_IKE_DELETE);
1981}
1982
f20e00fe
TB
1983/**
1984 * Reestablish CHILD_SAs and migrate queued tasks.
1985 *
1986 * If force is true all SAs are restarted, otherwise their close/dpd_action
1987 * is followed.
1988 */
1989static status_t reestablish_children(private_ike_sa_t *this, ike_sa_t *new,
1990 bool force)
1991{
1992 enumerator_t *enumerator;
1993 child_sa_t *child_sa;
1994 child_cfg_t *child_cfg;
1995 action_t action;
1996 status_t status = FAILED;
1997
1998 /* handle existing CHILD_SAs */
1999 enumerator = create_child_sa_enumerator(this);
2000 while (enumerator->enumerate(enumerator, (void**)&child_sa))
2001 {
a747ad73
TB
2002 switch (child_sa->get_state(child_sa))
2003 {
2004 case CHILD_REKEYED:
2005 case CHILD_DELETED:
2006 /* ignore CHILD_SAs in these states */
2007 continue;
2008 default:
2009 break;
2010 }
f20e00fe
TB
2011 if (force)
2012 {
a1620c16 2013 action = ACTION_RESTART;
f20e00fe
TB
2014 }
2015 else
2016 { /* only restart CHILD_SAs that are configured accordingly */
2017 if (this->state == IKE_DELETING)
2018 {
2019 action = child_sa->get_close_action(child_sa);
2020 }
2021 else
2022 {
2023 action = child_sa->get_dpd_action(child_sa);
2024 }
2025 }
2026 switch (action)
2027 {
2028 case ACTION_RESTART:
2029 child_cfg = child_sa->get_config(child_sa);
2030 DBG1(DBG_IKE, "restarting CHILD_SA %s",
2031 child_cfg->get_name(child_cfg));
2032 child_cfg->get_ref(child_cfg);
2033 status = new->initiate(new, child_cfg,
2034 child_sa->get_reqid(child_sa), NULL, NULL);
2035 break;
2036 default:
2037 continue;
2038 }
2039 if (status == DESTROY_ME)
2040 {
2041 break;
2042 }
2043 }
2044 enumerator->destroy(enumerator);
2045 /* adopt any active or queued CHILD-creating tasks */
2046 if (status != DESTROY_ME)
2047 {
5e97a5e6 2048 new->adopt_child_tasks(new, &this->public);
f20e00fe
TB
2049 if (new->get_state(new) == IKE_CREATED)
2050 {
2051 status = new->initiate(new, NULL, 0, NULL, NULL);
2052 }
2053 }
2054 return status;
2055}
2056
8bced61b
MW
2057METHOD(ike_sa_t, reestablish, status_t,
2058 private_ike_sa_t *this)
96926b00
MW
2059{
2060 ike_sa_t *new;
2061 host_t *host;
348af092 2062 action_t action;
e2630434 2063 enumerator_t *enumerator;
96926b00 2064 child_sa_t *child_sa;
cf76c429 2065 bool restart = FALSE;
96926b00 2066 status_t status = FAILED;
7daf5226 2067
96b61792
TB
2068 if (is_delete_queued(this, TASK_QUEUE_QUEUED))
2069 { /* don't reestablish IKE_SAs that have explicitly been deleted in the
2070 * mean time */
2071 return FAILED;
2072 }
2073
873b63b7 2074 if (has_condition(this, COND_REAUTHENTICATING))
23470d84 2075 { /* only reauthenticate if we have children */
893da041 2076 if (array_count(this->child_sas) == 0
23470d84
TB
2077#ifdef ME
2078 /* allow reauth of mediation connections without CHILD_SAs */
2079 && !this->peer_cfg->is_mediation(this->peer_cfg)
2080#endif /* ME */
2081 )
348af092 2082 {
23470d84
TB
2083 DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA "
2084 "to recreate");
348af092
MW
2085 }
2086 else
2087 {
23470d84 2088 restart = TRUE;
348af092 2089 }
23470d84
TB
2090 }
2091 else
2092 { /* check if we have children to keep up at all */
893da041 2093 enumerator = array_create_enumerator(this->child_sas);
23470d84 2094 while (enumerator->enumerate(enumerator, (void**)&child_sa))
cadb5d16 2095 {
a747ad73
TB
2096 switch (child_sa->get_state(child_sa))
2097 {
2098 case CHILD_REKEYED:
2099 case CHILD_DELETED:
2100 /* ignore CHILD_SAs in these states */
2101 continue;
2102 default:
2103 break;
2104 }
23470d84
TB
2105 if (this->state == IKE_DELETING)
2106 {
2107 action = child_sa->get_close_action(child_sa);
2108 }
2109 else
2110 {
2111 action = child_sa->get_dpd_action(child_sa);
2112 }
2113 switch (action)
2114 {
2115 case ACTION_RESTART:
2116 restart = TRUE;
2117 break;
2118 case ACTION_ROUTE:
2119 charon->traps->install(charon->traps, this->peer_cfg,
24fa1bb0 2120 child_sa->get_config(child_sa));
23470d84
TB
2121 break;
2122 default:
2123 break;
2124 }
cadb5d16 2125 }
23470d84 2126 enumerator->destroy(enumerator);
68db844f 2127 /* check if we have tasks that recreate children */
07a9d5c9
TB
2128 if (!restart)
2129 {
2130 restart = is_child_queued(this, TASK_QUEUE_ACTIVE) ||
2131 is_child_queued(this, TASK_QUEUE_QUEUED);
2132 }
cadb5d16 2133#ifdef ME
23470d84
TB
2134 /* mediation connections have no children, keep them up anyway */
2135 if (this->peer_cfg->is_mediation(this->peer_cfg))
2136 {
2137 restart = TRUE;
2138 }
cadb5d16 2139#endif /* ME */
23470d84 2140 }
cf76c429 2141 if (!restart)
cadb5d16
MW
2142 {
2143 return FAILED;
2144 }
7daf5226 2145
cadb5d16 2146 /* check if we are able to reestablish this IKE_SA */
faf9569f 2147 if (!has_condition(this, COND_ORIGINAL_INITIATOR) &&
893da041 2148 (array_count(this->other_vips) != 0 ||
96926b00
MW
2149 has_condition(this, COND_EAP_AUTHENTICATED)
2150#ifdef ME
2151 || this->is_mediation_server
2152#endif /* ME */
2153 ))
2154 {
68447302 2155 DBG1(DBG_IKE, "unable to reestablish IKE_SA due to asymmetric setup");
96926b00
MW
2156 return FAILED;
2157 }
7daf5226 2158
0b611540
TB
2159 new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
2160 this->version, TRUE);
3d54ae94
MW
2161 if (!new)
2162 {
2163 return FAILED;
2164 }
96926b00
MW
2165 new->set_peer_cfg(new, this->peer_cfg);
2166 host = this->other_host;
2167 new->set_other_host(new, host->clone(host));
2168 host = this->my_host;
2169 new->set_my_host(new, host->clone(host));
614359a7 2170 charon->bus->ike_reestablish_pre(charon->bus, &this->public, new);
7505fb8d
TB
2171 if (!has_condition(this, COND_REAUTHENTICATING))
2172 { /* reauthenticate to the same addresses, but resolve hosts if
2173 * reestablishing (old addresses serve as fallback) */
2174 resolve_hosts((private_ike_sa_t*)new);
2175 }
96926b00 2176 /* if we already have a virtual IP, we reuse it */
893da041 2177 enumerator = array_create_enumerator(this->my_vips);
101d26ba 2178 while (enumerator->enumerate(enumerator, &host))
96926b00 2179 {
101d26ba 2180 new->add_virtual_ip(new, TRUE, host);
96926b00 2181 }
101d26ba 2182 enumerator->destroy(enumerator);
7daf5226 2183
96926b00 2184#ifdef ME
96926b00
MW
2185 if (this->peer_cfg->is_mediation(this->peer_cfg))
2186 {
a13c013b 2187 status = new->initiate(new, NULL, 0, NULL, NULL);
96926b00 2188 }
cadb5d16 2189 else
96926b00 2190#endif /* ME */
96926b00 2191 {
f20e00fe
TB
2192 status = reestablish_children(this, new,
2193 has_condition(this, COND_REAUTHENTICATING));
96926b00 2194 }
7daf5226 2195
cadb5d16 2196 if (status == DESTROY_ME)
96926b00 2197 {
614359a7
TB
2198 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2199 FALSE);
cadb5d16 2200 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
04d6583e 2201 status = FAILED;
96926b00
MW
2202 }
2203 else
2204 {
614359a7
TB
2205 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2206 TRUE);
cadb5d16 2207 charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
04d6583e 2208 status = SUCCESS;
96926b00 2209 }
04d6583e
MW
2210 charon->bus->set_sa(charon->bus, &this->public);
2211 return status;
96926b00
MW
2212}
2213
f20e00fe
TB
2214/**
2215 * Resolve the given gateway ID
2216 */
2217static host_t *resolve_gateway_id(identification_t *gateway)
c126ddd0
TB
2218{
2219 char gw[BUF_LEN];
f20e00fe 2220 host_t *addr;
c126ddd0 2221
f20e00fe
TB
2222 snprintf(gw, sizeof(gw), "%Y", gateway);
2223 gw[sizeof(gw)-1] = '\0';
2224 addr = host_create_from_dns(gw, AF_UNSPEC, IKEV2_UDP_PORT);
2225 if (!addr)
2226 {
2227 DBG1(DBG_IKE, "unable to resolve gateway ID '%Y', redirect failed",
2228 gateway);
2229 }
2230 return addr;
2231}
2232
2233/**
2234 * Redirect the current SA to the given target host
2235 */
2236static bool redirect_established(private_ike_sa_t *this, identification_t *to)
2237{
2238 private_ike_sa_t *new_priv;
2239 ike_sa_t *new;
2240 host_t *other;
c6ebd033 2241 time_t redirect;
f20e00fe
TB
2242
2243 new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
2244 this->version, TRUE);
2245 if (!new)
489d154e 2246 {
489d154e
TB
2247 return FALSE;
2248 }
f20e00fe
TB
2249 new_priv = (private_ike_sa_t*)new;
2250 new->set_peer_cfg(new, this->peer_cfg);
2251 new_priv->redirected_from = this->other_host->clone(this->other_host);
2252 charon->bus->ike_reestablish_pre(charon->bus, &this->public, new);
2253 other = resolve_gateway_id(to);
2254 if (other)
2255 {
2256 set_my_host(new_priv, this->my_host->clone(this->my_host));
2257 /* this allows us to force the remote address while we still properly
2258 * resolve the local address */
2259 new_priv->remote_host = other;
2260 resolve_hosts(new_priv);
c6ebd033
TB
2261 new_priv->redirected_at = array_create(sizeof(time_t), MAX_REDIRECTS);
2262 while (array_remove(this->redirected_at, ARRAY_HEAD, &redirect))
2263 {
2264 array_insert(new_priv->redirected_at, ARRAY_TAIL, &redirect);
2265 }
f20e00fe
TB
2266 if (reestablish_children(this, new, TRUE) != DESTROY_ME)
2267 {
2268#ifdef USE_IKEV2
2269 new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
2270 this->ike_sa_id));
2271#endif
2272 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2273 TRUE);
2274 charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
2275 charon->bus->set_sa(charon->bus, &this->public);
2276 return TRUE;
2277 }
2278 }
2279 charon->bus->ike_reestablish_post(charon->bus, &this->public, new,
2280 FALSE);
2281 charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
2282 charon->bus->set_sa(charon->bus, &this->public);
2283 return FALSE;
2284}
c126ddd0 2285
f20e00fe
TB
2286/**
2287 * Redirect the current connecting SA to the given target host
2288 */
2289static bool redirect_connecting(private_ike_sa_t *this, identification_t *to)
2290{
2291 host_t *other;
2292
2293 other = resolve_gateway_id(to);
c126ddd0
TB
2294 if (!other)
2295 {
c126ddd0
TB
2296 return FALSE;
2297 }
c3539961 2298 reset(this, TRUE);
f20e00fe
TB
2299 DESTROY_IF(this->redirected_from);
2300 this->redirected_from = this->other_host->clone(this->other_host);
f20e00fe
TB
2301 /* this allows us to force the remote address while we still properly
2302 * resolve the local address */
3a54206c 2303 DESTROY_IF(this->remote_host);
f20e00fe
TB
2304 this->remote_host = other;
2305 resolve_hosts(this);
2306 return TRUE;
2307}
2308
c6ebd033
TB
2309/**
2310 * Check if the current redirect exceeds the limits for redirects
2311 */
2312static bool redirect_count_exceeded(private_ike_sa_t *this)
2313{
2314 time_t now, redirect;
2315
2316 now = time_monotonic(NULL);
2317 /* remove entries outside the defined period */
2318 while (array_get(this->redirected_at, ARRAY_HEAD, &redirect) &&
2319 now - redirect >= REDIRECT_LOOP_DETECT_PERIOD)
2320 {
2321 array_remove(this->redirected_at, ARRAY_HEAD, NULL);
2322 }
2323 if (array_count(this->redirected_at) < MAX_REDIRECTS)
2324 {
2325 if (!this->redirected_at)
2326 {
2327 this->redirected_at = array_create(sizeof(time_t), MAX_REDIRECTS);
2328 }
2329 array_insert(this->redirected_at, ARRAY_TAIL, &now);
2330 return FALSE;
2331 }
2332 return TRUE;
2333}
2334
f20e00fe
TB
2335METHOD(ike_sa_t, handle_redirect, bool,
2336 private_ike_sa_t *this, identification_t *gateway)
2337{
2338 DBG1(DBG_IKE, "redirected to %Y", gateway);
2339 if (!this->follow_redirects)
2340 {
2341 DBG1(DBG_IKE, "server sent REDIRECT even though we disabled it");
2342 return FALSE;
2343 }
c6ebd033
TB
2344 if (redirect_count_exceeded(this))
2345 {
2346 DBG1(DBG_IKE, "only %d redirects are allowed within %d seconds",
2347 MAX_REDIRECTS, REDIRECT_LOOP_DETECT_PERIOD);
2348 return FALSE;
2349 }
f20e00fe 2350
c126ddd0
TB
2351 switch (this->state)
2352 {
2353 case IKE_CONNECTING:
f20e00fe
TB
2354 return redirect_connecting(this, gateway);
2355 case IKE_ESTABLISHED:
2356 return redirect_established(this, gateway);
c126ddd0
TB
2357 default:
2358 DBG1(DBG_IKE, "unable to handle redirect for IKE_SA in state %N",
2359 ike_sa_state_names, this->state);
c126ddd0
TB
2360 return FALSE;
2361 }
2362}
2363
71c70705
TB
2364METHOD(ike_sa_t, redirect, status_t,
2365 private_ike_sa_t *this, identification_t *gateway)
2366{
2367 switch (this->state)
2368 {
2369 case IKE_CONNECTING:
2370 case IKE_ESTABLISHED:
2371 case IKE_REKEYING:
2372 if (has_condition(this, COND_REDIRECTED))
2373 { /* IKE_SA already got redirected */
2374 return SUCCESS;
2375 }
2376 if (has_condition(this, COND_ORIGINAL_INITIATOR))
2377 {
2378 DBG1(DBG_IKE, "unable to redirect IKE_SA as initiator");
2379 return FAILED;
2380 }
2381 if (this->version == IKEV1)
2382 {
2383 DBG1(DBG_IKE, "unable to redirect IKEv1 SA");
2384 return FAILED;
2385 }
2386 if (!supports_extension(this, EXT_IKE_REDIRECTION))
2387 {
2388 DBG1(DBG_IKE, "client does not support IKE redirection");
2389 return FAILED;
2390 }
2391#ifdef USE_IKEV2
2392 this->task_manager->queue_task(this->task_manager,
2393 (task_t*)ike_redirect_create(&this->public, gateway));
2394#endif
2395 return this->task_manager->initiate(this->task_manager);
2396 default:
2397 DBG1(DBG_IKE, "unable to redirect IKE_SA in state %N",
2398 ike_sa_state_names, this->state);
2399 return INVALID_STATE;
2400 }
2401}
2402
8bced61b 2403METHOD(ike_sa_t, retransmit, status_t,
b12c53ce 2404 private_ike_sa_t *this, uint32_t message_id)
96926b00 2405{
916cdca8
MW
2406 if (this->state == IKE_PASSIVE)
2407 {
2408 return INVALID_STATE;
2409 }
6180a558 2410 this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
96926b00
MW
2411 if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
2412 {
2413 /* send a proper signal to brief interested bus listeners */
2414 switch (this->state)
2415 {
2416 case IKE_CONNECTING:
2417 {
d9c1dae2 2418 /* retry IKE_SA_INIT/Main Mode if we have multiple keyingtries */
b12c53ce 2419 uint32_t tries = this->peer_cfg->get_keyingtries(this->peer_cfg);
1d6dc627
TB
2420 charon->bus->alert(charon->bus, ALERT_PEER_INIT_UNREACHABLE,
2421 this->keyingtry);
96926b00
MW
2422 this->keyingtry++;
2423 if (tries == 0 || tries > this->keyingtry)
2424 {
a985db3f
MW
2425 DBG1(DBG_IKE, "peer not responding, trying again (%d/%d)",
2426 this->keyingtry + 1, tries);
c3539961 2427 reset(this, TRUE);
4d7a2128 2428 resolve_hosts(this);
96926b00
MW
2429 return this->task_manager->initiate(this->task_manager);
2430 }
a985db3f 2431 DBG1(DBG_IKE, "establishing IKE_SA failed, peer not responding");
ebc6defa
TB
2432
2433 if (this->version == IKEV1 && array_count(this->child_sas))
2434 {
eb822106
TB
2435 enumerator_t *enumerator;
2436 child_sa_t *child_sa;
2437
ebc6defa
TB
2438 /* if reauthenticating an IKEv1 SA failed (assumed for an SA
2439 * in this state with CHILD_SAs), try again from scratch */
2440 DBG1(DBG_IKE, "reauthentication failed, trying to "
2441 "reestablish IKE_SA");
2442 reestablish(this);
eb822106
TB
2443 /* trigger down events for the CHILD_SAs, as no down event
2444 * is triggered below for IKE SAs in this state */
2445 enumerator = array_create_enumerator(this->child_sas);
2446 while (enumerator->enumerate(enumerator, &child_sa))
2447 {
2448 if (child_sa->get_state(child_sa) != CHILD_REKEYED &&
2449 child_sa->get_state(child_sa) != CHILD_DELETED)
2450 {
2451 charon->bus->child_updown(charon->bus, child_sa,
2452 FALSE);
2453 }
2454 }
2455 enumerator->destroy(enumerator);
ebc6defa 2456 }
96926b00
MW
2457 break;
2458 }
96926b00 2459 case IKE_DELETING:
a985db3f 2460 DBG1(DBG_IKE, "proper IKE_SA delete failed, peer not responding");
10f8834b
TB
2461 if (has_condition(this, COND_REAUTHENTICATING) &&
2462 !lib->settings->get_bool(lib->settings,
2463 "%s.make_before_break", FALSE, lib->ns))
74571430
TB
2464 {
2465 DBG1(DBG_IKE, "delete during reauthentication failed, "
2466 "trying to reestablish IKE_SA anyway");
2467 reestablish(this);
2468 }
96926b00 2469 break;
348af092 2470 case IKE_REKEYING:
a985db3f 2471 DBG1(DBG_IKE, "rekeying IKE_SA failed, peer not responding");
348af092 2472 /* FALL */
96926b00 2473 default:
348af092 2474 reestablish(this);
96926b00
MW
2475 break;
2476 }
bb389973
TB
2477 if (this->state != IKE_CONNECTING &&
2478 this->state != IKE_REKEYED)
3babde90
TB
2479 {
2480 charon->bus->ike_updown(charon->bus, &this->public, FALSE);
2481 }
96926b00
MW
2482 return DESTROY_ME;
2483 }
2484 return SUCCESS;
2485}
2486
a07b6973 2487METHOD(ike_sa_t, set_auth_lifetime, status_t,
b12c53ce 2488 private_ike_sa_t *this, uint32_t lifetime)
ee614711 2489{
b12c53ce 2490 uint32_t diff, hard, soft, now;
a07b6973 2491 bool send_update;
ee614711 2492
bdcf4417
MW
2493 diff = this->peer_cfg->get_over_time(this->peer_cfg);
2494 now = time_monotonic(NULL);
2495 hard = now + lifetime;
2496 soft = hard - diff;
2497
a07b6973
MW
2498 /* check if we have to send an AUTH_LIFETIME to enforce the new lifetime.
2499 * We send the notify in IKE_AUTH if not yet ESTABLISHED. */
b1f2f05c 2500 send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 &&
a07b6973 2501 !has_condition(this, COND_ORIGINAL_INITIATOR) &&
893da041 2502 (array_count(this->other_vips) != 0 ||
a07b6973
MW
2503 has_condition(this, COND_EAP_AUTHENTICATED));
2504
bdcf4417 2505 if (lifetime < diff)
ee614711 2506 {
bdcf4417 2507 this->stats[STAT_REAUTH] = now;
a07b6973
MW
2508
2509 if (!send_update)
2510 {
2511 DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
2512 "starting reauthentication", lifetime);
2513 lib->processor->queue_job(lib->processor,
b9b8a98f 2514 (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE));
a07b6973 2515 }
ee614711 2516 }
85ac2fa5 2517 else if (this->stats[STAT_REAUTH] == 0 ||
bdcf4417 2518 this->stats[STAT_REAUTH] > soft)
ee614711 2519 {
bdcf4417 2520 this->stats[STAT_REAUTH] = soft;
a07b6973
MW
2521 if (!send_update)
2522 {
2523 DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling "
2524 "reauthentication in %ds", lifetime, lifetime - diff);
2525 lib->scheduler->schedule_job(lib->scheduler,
6554b5e4 2526 (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
bdcf4417 2527 lifetime - diff);
a07b6973 2528 }
3fd9c757
AS
2529 }
2530 else
2531 {
6180a558
MW
2532 DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
2533 "reauthentication already scheduled in %ds", lifetime,
2534 this->stats[STAT_REAUTH] - time_monotonic(NULL));
a07b6973 2535 send_update = FALSE;
ee614711 2536 }
bdcf4417
MW
2537 /* give at least some seconds to reauthenticate */
2538 this->stats[STAT_DELETE] = max(hard, now + 10);
a07b6973 2539
2d39f79b 2540#ifdef USE_IKEV2
a07b6973
MW
2541 if (send_update)
2542 {
2d39f79b
TB
2543 ike_auth_lifetime_t *task;
2544
a07b6973
MW
2545 task = ike_auth_lifetime_create(&this->public, TRUE);
2546 this->task_manager->queue_task(this->task_manager, &task->task);
2547 return this->task_manager->initiate(this->task_manager);
2548 }
2d39f79b 2549#endif
a07b6973 2550 return SUCCESS;
ee614711
MW
2551}
2552
bab56a4a
TB
2553/**
2554 * Check if the current combination of source and destination address is still
2555 * valid.
2556 */
2557static bool is_current_path_valid(private_ike_sa_t *this)
2558{
2559 bool valid = FALSE;
2560 host_t *src;
597e8c9e
MW
2561
2562 if (supports_extension(this, EXT_MOBIKE) &&
2563 lib->settings->get_bool(lib->settings,
2564 "%s.prefer_best_path", FALSE, lib->ns))
2565 {
2566 /* check if the current path is the best path; migrate otherwise */
2567 src = charon->kernel->get_source_addr(charon->kernel, this->other_host,
2568 NULL);
2569 if (src)
2570 {
2571 valid = src->ip_equals(src, this->my_host);
2572 src->destroy(src);
2573 }
2574 if (!valid)
2575 {
2576 DBG1(DBG_IKE, "old path is not preferred anymore");
2577 }
2578 return valid;
2579 }
8394ea2a
TB
2580 src = charon->kernel->get_source_addr(charon->kernel, this->other_host,
2581 this->my_host);
bab56a4a
TB
2582 if (src)
2583 {
2584 if (src->ip_equals(src, this->my_host))
2585 {
2586 valid = TRUE;
2587 }
2588 src->destroy(src);
2589 }
597e8c9e
MW
2590 if (!valid)
2591 {
2592 DBG1(DBG_IKE, "old path is not available anymore, try to find another");
2593 }
bab56a4a
TB
2594 return valid;
2595}
2596
2597/**
02b34840 2598 * Check if we have any path available for this IKE SA.
bab56a4a
TB
2599 */
2600static bool is_any_path_valid(private_ike_sa_t *this)
2601{
2602 bool valid = FALSE;
2603 enumerator_t *enumerator;
ae9ce835 2604 host_t *src = NULL, *addr;
ff601341
TB
2605 int family = AF_UNSPEC;
2606
2607 switch (charon->socket->supported_families(charon->socket))
2608 {
2609 case SOCKET_FAMILY_IPV4:
2610 family = AF_INET;
2611 break;
2612 case SOCKET_FAMILY_IPV6:
2613 family = AF_INET6;
2614 break;
2615 case SOCKET_FAMILY_BOTH:
2616 case SOCKET_FAMILY_NONE:
2617 break;
2618 }
72b28112 2619
12715f19 2620 enumerator = create_peer_address_enumerator(this);
72b28112 2621 while (enumerator->enumerate(enumerator, &addr))
bab56a4a 2622 {
ff601341
TB
2623 if (family != AF_UNSPEC && addr->get_family(addr) != family)
2624 {
2625 continue;
2626 }
72b28112 2627 DBG1(DBG_IKE, "looking for a route to %H ...", addr);
8394ea2a 2628 src = charon->kernel->get_source_addr(charon->kernel, addr, NULL);
72b28112 2629 if (src)
bab56a4a 2630 {
72b28112 2631 break;
bab56a4a 2632 }
bab56a4a 2633 }
72b28112 2634 enumerator->destroy(enumerator);
bab56a4a
TB
2635 if (src)
2636 {
2637 valid = TRUE;
2638 src->destroy(src);
2639 }
2640 return valid;
2641}
2642
8bced61b
MW
2643METHOD(ike_sa_t, roam, status_t,
2644 private_ike_sa_t *this, bool address)
17d92e97 2645{
011b1cca
MW
2646 switch (this->state)
2647 {
2648 case IKE_CREATED:
2649 case IKE_DELETING:
7afd9d66 2650 case IKE_DESTROYING:
c610f424 2651 case IKE_PASSIVE:
bb389973 2652 case IKE_REKEYED:
011b1cca
MW
2653 return SUCCESS;
2654 default:
2655 break;
2656 }
7daf5226 2657
007a2701
TB
2658 if (!this->ike_cfg)
2659 { /* this is the case for new HA SAs not yet in state IKE_PASSIVE and
2660 * without config assigned */
2661 return SUCCESS;
2662 }
8929c700
TB
2663 if (this->version == IKEV1)
2664 { /* ignore roam events for IKEv1 where we don't have MOBIKE and would
2665 * have to reestablish from scratch (reauth is not enough) */
2666 return SUCCESS;
2667 }
007a2701 2668
be27e768
TB
2669 /* ignore roam events if MOBIKE is not supported/enabled and the local
2670 * address is statically configured */
8929c700 2671 if (!supports_extension(this, EXT_MOBIKE) &&
be27e768
TB
2672 ike_cfg_has_address(this->ike_cfg, this->my_host, TRUE))
2673 {
2674 DBG2(DBG_IKE, "keeping statically configured path %H - %H",
2675 this->my_host, this->other_host);
2676 return SUCCESS;
2677 }
2678
ce5b1708 2679 /* keep existing path if possible */
bab56a4a 2680 if (is_current_path_valid(this))
face844a 2681 {
bab56a4a
TB
2682 DBG2(DBG_IKE, "keeping connection path %H - %H",
2683 this->my_host, this->other_host);
2684 set_condition(this, COND_STALE, FALSE);
261b2572
TB
2685
2686 if (supports_extension(this, EXT_MOBIKE) && address)
2687 { /* if any addresses changed, send an updated list */
2688 DBG1(DBG_IKE, "sending address list update using MOBIKE");
873df908 2689 this->task_manager->queue_mobike(this->task_manager, FALSE, TRUE);
261b2572
TB
2690 return this->task_manager->initiate(this->task_manager);
2691 }
bab56a4a 2692 return SUCCESS;
7afd9d66 2693 }
261b2572 2694
bab56a4a 2695 if (!is_any_path_valid(this))
7afd9d66 2696 {
bab56a4a
TB
2697 DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred",
2698 this->other_host);
2699 set_condition(this, COND_STALE, TRUE);
2700 return SUCCESS;
17d92e97 2701 }
7afd9d66 2702 set_condition(this, COND_STALE, FALSE);
7daf5226 2703
face844a
MW
2704 /* update addresses with mobike, if supported ... */
2705 if (supports_extension(this, EXT_MOBIKE))
2706 {
57744088
TB
2707 if (!has_condition(this, COND_ORIGINAL_INITIATOR))
2708 { /* responder updates the peer about changed address config */
2709 DBG1(DBG_IKE, "sending address list update using MOBIKE, "
2710 "implicitly requesting an address change");
2711 address = TRUE;
2712 }
2713 else
2714 {
2715 DBG1(DBG_IKE, "requesting address change using MOBIKE");
2716 }
873df908 2717 this->task_manager->queue_mobike(this->task_manager, TRUE, address);
face844a
MW
2718 return this->task_manager->initiate(this->task_manager);
2719 }
57744088 2720
96926b00 2721 /* ... reauth if not */
57744088
TB
2722 if (!has_condition(this, COND_ORIGINAL_INITIATOR))
2723 { /* responder does not reauthenticate */
2724 set_condition(this, COND_STALE, TRUE);
2725 return SUCCESS;
2726 }
2727 DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
a46fe568
TB
2728 /* since our previous path is not valid anymore, try and find a new one */
2729 resolve_hosts(this);
96926b00 2730 return reauth(this);
17d92e97 2731}
6fe03b0a 2732
8bced61b
MW
2733METHOD(ike_sa_t, add_configuration_attribute, void,
2734 private_ike_sa_t *this, attribute_handler_t *handler,
2735 configuration_attribute_type_t type, chunk_t data)
7f56b494 2736{
893da041
MW
2737 attribute_entry_t entry = {
2738 .handler = handler,
2739 .type = type,
2740 .data = chunk_clone(data),
2741 };
2742 array_insert(this->attributes, ARRAY_TAIL, &entry);
7f56b494
MW
2743}
2744
525cc46c
TB
2745CALLBACK(filter_attribute, bool,
2746 void *null, enumerator_t *orig, va_list args)
9d257034 2747{
525cc46c
TB
2748 attribute_entry_t *entry;
2749 configuration_attribute_type_t *type;
2750 chunk_t *data;
2751 bool *handled;
2752
2753 VA_ARGS_VGET(args, type, data, handled);
2754
2755 if (orig->enumerate(orig, &entry))
2756 {
2757 *type = entry->type;
2758 *data = entry->data;
2759 *handled = entry->handler != NULL;
2760 return TRUE;
2761 }
2762 return FALSE;
9d257034
MW
2763}
2764
2765METHOD(ike_sa_t, create_attribute_enumerator, enumerator_t*,
2766 private_ike_sa_t *this)
2767{
2768 return enumerator_create_filter(array_create_enumerator(this->attributes),
525cc46c 2769 filter_attribute, NULL, NULL);
9d257034
MW
2770}
2771
ea340ee8
MW
2772METHOD(ike_sa_t, create_task_enumerator, enumerator_t*,
2773 private_ike_sa_t *this, task_queue_t queue)
2774{
2775 return this->task_manager->create_task_enumerator(this->task_manager, queue);
2776}
2777
b7160401
TB
2778METHOD(ike_sa_t, remove_task, void,
2779 private_ike_sa_t *this, enumerator_t *enumerator)
2780{
2781 return this->task_manager->remove_task(this->task_manager, enumerator);
2782}
2783
cbc1a20f
MW
2784METHOD(ike_sa_t, flush_queue, void,
2785 private_ike_sa_t *this, task_queue_t queue)
2786{
2787 this->task_manager->flush_queue(this->task_manager, queue);
2788}
2789
69adeb5b
MW
2790METHOD(ike_sa_t, queue_task, void,
2791 private_ike_sa_t *this, task_t *task)
2792{
2793 this->task_manager->queue_task(this->task_manager, task);
2794}
2795
208678e6
TB
2796METHOD(ike_sa_t, queue_task_delayed, void,
2797 private_ike_sa_t *this, task_t *task, uint32_t delay)
2798{
2799 this->task_manager->queue_task_delayed(this->task_manager, task, delay);
2800}
2801
5e97a5e6
TB
2802/**
2803 * Migrate and queue child-creating tasks from another IKE_SA
2804 */
2805static void migrate_child_tasks(private_ike_sa_t *this, ike_sa_t *other,
2806 task_queue_t queue)
00c889f4 2807{
5e97a5e6
TB
2808 enumerator_t *enumerator;
2809 task_t *task;
00c889f4 2810
5e97a5e6
TB
2811 enumerator = other->create_task_enumerator(other, queue);
2812 while (enumerator->enumerate(enumerator, &task))
2813 {
2814 if (task->get_type(task) == TASK_CHILD_CREATE ||
2815 task->get_type(task) == TASK_QUICK_MODE)
2816 {
2817 other->remove_task(other, enumerator);
2818 task->migrate(task, &this->public);
2819 queue_task(this, task);
2820 }
2821 }
2822 enumerator->destroy(enumerator);
2823}
2824
2825METHOD(ike_sa_t, adopt_child_tasks, void,
2826 private_ike_sa_t *this, ike_sa_t *other)
2827{
2828 migrate_child_tasks(this, other, TASK_QUEUE_ACTIVE);
2829 migrate_child_tasks(this, other, TASK_QUEUE_QUEUED);
00c889f4
TB
2830}
2831
713a1122
MW
2832METHOD(ike_sa_t, inherit_pre, void,
2833 private_ike_sa_t *this, ike_sa_t *other_public)
2834{
2835 private_ike_sa_t *other = (private_ike_sa_t*)other_public;
2836
2837 /* apply config and hosts */
2838 set_peer_cfg(this, other->peer_cfg);
2839 set_my_host(this, other->my_host->clone(other->my_host));
2840 set_other_host(this, other->other_host->clone(other->other_host));
094963d1
MW
2841
2842 /* apply extensions and conditions with a few exceptions */
2843 this->extensions = other->extensions;
2844 this->conditions = other->conditions;
2845 this->conditions &= ~COND_STALE;
2846 this->conditions &= ~COND_REAUTHENTICATING;
713a1122
MW
2847}
2848
2849METHOD(ike_sa_t, inherit_post, void,
8bced61b 2850 private_ike_sa_t *this, ike_sa_t *other_public)
3183006d 2851{
8bced61b 2852 private_ike_sa_t *other = (private_ike_sa_t*)other_public;
c60c7694 2853 child_sa_t *child_sa;
5d6b9815 2854 enumerator_t *enumerator;
893da041 2855 attribute_entry_t entry;
5d6b9815 2856 auth_cfg_t *cfg;
101d26ba 2857 host_t *vip;
7daf5226 2858
c60c7694
MW
2859 /* apply hosts and ids */
2860 this->my_host->destroy(this->my_host);
2861 this->other_host->destroy(this->other_host);
2862 this->my_id->destroy(this->my_id);
2863 this->other_id->destroy(this->other_id);
2864 this->my_host = other->my_host->clone(other->my_host);
2865 this->other_host = other->other_host->clone(other->other_host);
2866 this->my_id = other->my_id->clone(other->my_id);
2867 this->other_id = other->other_id->clone(other->other_id);
dec3c184
TB
2868 this->if_id_in = other->if_id_in;
2869 this->if_id_out = other->if_id_out;
7daf5226 2870
101d26ba 2871 /* apply assigned virtual IPs... */
893da041 2872 while (array_remove(other->my_vips, ARRAY_HEAD, &vip))
c60c7694 2873 {
893da041 2874 array_insert_create(&this->my_vips, ARRAY_TAIL, vip);
c60c7694 2875 }
893da041 2876 while (array_remove(other->other_vips, ARRAY_HEAD, &vip))
c60c7694 2877 {
893da041 2878 array_insert_create(&this->other_vips, ARRAY_TAIL, vip);
c60c7694 2879 }
7daf5226 2880
b8ecdfd8
MW
2881 /* MOBIKE additional addresses */
2882 while (array_remove(other->peer_addresses, ARRAY_HEAD, &vip))
2883 {
2884 array_insert_create(&this->peer_addresses, ARRAY_TAIL, vip);
2885 }
2886
5d6b9815 2887 /* authentication information */
893da041 2888 enumerator = array_create_enumerator(other->my_auths);
5d6b9815
MW
2889 while (enumerator->enumerate(enumerator, &cfg))
2890 {
893da041 2891 array_insert(this->my_auths, ARRAY_TAIL, cfg->clone(cfg));
5d6b9815
MW
2892 }
2893 enumerator->destroy(enumerator);
893da041 2894 enumerator = array_create_enumerator(other->other_auths);
5d6b9815
MW
2895 while (enumerator->enumerate(enumerator, &cfg))
2896 {
893da041 2897 array_insert(this->other_auths, ARRAY_TAIL, cfg->clone(cfg));
5d6b9815
MW
2898 }
2899 enumerator->destroy(enumerator);
2900
7f56b494 2901 /* ... and configuration attributes */
893da041 2902 while (array_remove(other->attributes, ARRAY_HEAD, &entry))
c60c7694 2903 {
893da041 2904 array_insert(this->attributes, ARRAY_TAIL, &entry);
c60c7694 2905 }
b0e40caa 2906
faf9569f 2907 /* inherit all conditions */
b0e40caa
AS
2908 this->conditions = other->conditions;
2909 if (this->conditions & COND_NAT_HERE)
2910 {
efd7fa7b 2911 send_keepalive(this, FALSE);
b0e40caa 2912 }
7daf5226 2913
22452f70
TB
2914#ifdef ME
2915 if (other->is_mediation_server)
2916 {
2917 act_as_mediation_server(this);
2918 }
2919 else if (other->server_reflexive_host)
2920 {
2921 this->server_reflexive_host = other->server_reflexive_host->clone(
2922 other->server_reflexive_host);
2923 }
2924#endif /* ME */
b0e40caa 2925
c60c7694 2926 /* adopt all children */
893da041 2927 while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa))
c60c7694 2928 {
38227d0e
MW
2929 charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
2930 add_child_sa(this, child_sa);
c60c7694 2931 }
7daf5226 2932
e23a59f6
MW
2933 /* move pending tasks to the new IKE_SA */
2934 this->task_manager->adopt_tasks(this->task_manager, other->task_manager);
7daf5226 2935
ee614711 2936 /* reauthentication timeout survives a rekeying */
85ac2fa5 2937 if (other->stats[STAT_REAUTH])
ee614711 2938 {
6180a558 2939 time_t reauth, delete, now = time_monotonic(NULL);
7daf5226 2940
85ac2fa5
MW
2941 this->stats[STAT_REAUTH] = other->stats[STAT_REAUTH];
2942 reauth = this->stats[STAT_REAUTH] - now;
ee614711 2943 delete = reauth + this->peer_cfg->get_over_time(this->peer_cfg);
85ac2fa5 2944 this->stats[STAT_DELETE] = this->stats[STAT_REAUTH] + delete;
ee614711
MW
2945 DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
2946 "lifetime reduced to %ds", reauth, delete);
bb381e26 2947 lib->scheduler->schedule_job(lib->scheduler,
6554b5e4 2948 (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth);
bb381e26 2949 lib->scheduler->schedule_job(lib->scheduler,
6554b5e4 2950 (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete);
ee614711 2951 }
3183006d
MW
2952}
2953
8bced61b
MW
2954METHOD(ike_sa_t, destroy, void,
2955 private_ike_sa_t *this)
60356f33 2956{
893da041 2957 attribute_entry_t entry;
2b0c8ee3 2958 child_sa_t *child_sa;
101d26ba 2959 host_t *vip;
7daf5226 2960
65c907cd 2961 charon->bus->set_sa(charon->bus, &this->public);
7daf5226 2962
a985db3f 2963 set_state(this, IKE_DESTROYING);
b1908994
TE
2964 if (this->task_manager)
2965 {
2966 this->task_manager->flush(this->task_manager);
2967 }
7daf5226 2968
7f56b494 2969 /* remove attributes first, as we pass the IKE_SA to the handler */
eef7427b 2970 charon->bus->handle_vips(charon->bus, &this->public, FALSE);
893da041 2971 while (array_remove(this->attributes, ARRAY_TAIL, &entry))
7f56b494 2972 {
5ae32210
MW
2973 if (entry.handler)
2974 {
75136327 2975 charon->attributes->release(charon->attributes, entry.handler,
a12f357b 2976 &this->public, entry.type, entry.data);
5ae32210 2977 }
893da041 2978 free(entry.data.ptr);
7f56b494 2979 }
2b0c8ee3
MW
2980 /* uninstall CHILD_SAs before virtual IPs, otherwise we might kill
2981 * routes that the CHILD_SA tries to uninstall. */
2982 while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa))
2983 {
38227d0e 2984 charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
2b0c8ee3
MW
2985 child_sa->destroy(child_sa);
2986 }
893da041 2987 while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
c60c7694 2988 {
8394ea2a 2989 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
101d26ba 2990 vip->destroy(vip);
c60c7694 2991 }
893da041 2992 if (array_count(this->other_vips))
12fa1784
AS
2993 {
2994 charon->bus->assign_vips(charon->bus, &this->public, FALSE);
2995 }
893da041 2996 while (array_remove(this->other_vips, ARRAY_TAIL, &vip))
cdcfe777 2997 {
497ce2cf 2998 if (this->peer_cfg)
cdcfe777 2999 {
28a3d5bf 3000 linked_list_t *pools;
28a3d5bf 3001
28a3d5bf
MW
3002 pools = linked_list_create_from_enumerator(
3003 this->peer_cfg->create_pool_enumerator(this->peer_cfg));
75136327 3004 charon->attributes->release_address(charon->attributes,
a16058a4 3005 pools, vip, &this->public);
28a3d5bf 3006 pools->destroy(pools);
cdcfe777 3007 }
101d26ba 3008 vip->destroy(vip);
cdcfe777 3009 }
a3854d83
MW
3010
3011 /* unset SA after here to avoid usage by the listeners */
3012 charon->bus->set_sa(charon->bus, NULL);
3013
2b0c8ee3 3014 array_destroy(this->child_sas);
b1908994 3015 DESTROY_IF(this->task_manager);
a3854d83 3016 DESTROY_IF(this->keymat);
893da041
MW
3017 array_destroy(this->attributes);
3018 array_destroy(this->my_vips);
3019 array_destroy(this->other_vips);
3020 array_destroy_offset(this->peer_addresses, offsetof(host_t, destroy));
dc04b7c7 3021#ifdef ME
22452f70 3022 if (this->is_mediation_server)
d5cc1758 3023 {
484a06bc
TB
3024 charon->mediation_manager->remove(charon->mediation_manager,
3025 this->ike_sa_id);
d5cc1758
TB
3026 }
3027 DESTROY_IF(this->server_reflexive_host);
9c2a905d 3028 chunk_free(&this->connect_id);
dc04b7c7 3029#endif /* ME */
9d9a772e 3030 free(this->nat_detection_dest.ptr);
7daf5226 3031
8dfbe71b
MW
3032 DESTROY_IF(this->my_host);
3033 DESTROY_IF(this->other_host);
3034 DESTROY_IF(this->my_id);
3035 DESTROY_IF(this->other_id);
d487b4b7
AS
3036 DESTROY_IF(this->local_host);
3037 DESTROY_IF(this->remote_host);
e4af6e6b 3038 DESTROY_IF(this->redirected_from);
c6ebd033 3039 array_destroy(this->redirected_at);
7daf5226 3040
e0fe7651
MW
3041 DESTROY_IF(this->ike_cfg);
3042 DESTROY_IF(this->peer_cfg);
5dffdea1 3043 DESTROY_IF(this->proposal);
a44bb934
MW
3044 this->my_auth->destroy(this->my_auth);
3045 this->other_auth->destroy(this->other_auth);
893da041
MW
3046 array_destroy_offset(this->my_auths, offsetof(auth_cfg_t, destroy));
3047 array_destroy_offset(this->other_auths, offsetof(auth_cfg_t, destroy));
7daf5226 3048
87a217f9 3049 this->ike_sa_id->destroy(this->ike_sa_id);
5113680f 3050 free(this);
7ba38761
JH
3051}
3052
3053/*
39b2903f 3054 * Described in header.
7ba38761 3055 */
17ec1c74
MW
3056ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
3057 ike_version_t version)
7ba38761 3058{
8bced61b 3059 private_ike_sa_t *this;
3568abe7 3060 static refcount_t unique_id = 0;
7daf5226 3061
3d54ae94
MW
3062 if (version == IKE_ANY)
3063 { /* prefer IKEv2 if protocol not specified */
3064#ifdef USE_IKEV2
3065 version = IKEV2;
3066#else
3067 version = IKEV1;
3068#endif
3069 }
3070
8bced61b
MW
3071 INIT(this,
3072 .public = {
0b611540 3073 .get_version = _get_version,
8bced61b
MW
3074 .get_state = _get_state,
3075 .set_state = _set_state,
3076 .get_name = _get_name,
3077 .get_statistic = _get_statistic,
44ff1153 3078 .set_statistic = _set_statistic,
8bced61b
MW
3079 .process_message = _process_message,
3080 .initiate = _initiate,
77e42826 3081 .retry_initiate = _retry_initiate,
8bced61b
MW
3082 .get_ike_cfg = _get_ike_cfg,
3083 .set_ike_cfg = _set_ike_cfg,
3084 .get_peer_cfg = _get_peer_cfg,
3085 .set_peer_cfg = _set_peer_cfg,
3086 .get_auth_cfg = _get_auth_cfg,
3087 .create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
1b9c1ae0 3088 .verify_peer_certificate = _verify_peer_certificate,
8bced61b
MW
3089 .add_auth_cfg = _add_auth_cfg,
3090 .get_proposal = _get_proposal,
3091 .set_proposal = _set_proposal,
3092 .get_id = _get_id,
3093 .get_my_host = _get_my_host,
3094 .set_my_host = _set_my_host,
3095 .get_other_host = _get_other_host,
3096 .set_other_host = _set_other_host,
3097 .set_message_id = _set_message_id,
347c403c 3098 .get_message_id = _get_message_id,
277f02ce 3099 .float_ports = _float_ports,
8bced61b
MW
3100 .update_hosts = _update_hosts,
3101 .get_my_id = _get_my_id,
3102 .set_my_id = _set_my_id,
3103 .get_other_id = _get_other_id,
3104 .set_other_id = _set_other_id,
3105 .get_other_eap_id = _get_other_eap_id,
3106 .enable_extension = _enable_extension,
3107 .supports_extension = _supports_extension,
3108 .set_condition = _set_condition,
3109 .has_condition = _has_condition,
94bbc602
TB
3110 .create_peer_address_enumerator = _create_peer_address_enumerator,
3111 .add_peer_address = _add_peer_address,
3112 .clear_peer_addresses = _clear_peer_addresses,
8bced61b
MW
3113 .has_mapping_changed = _has_mapping_changed,
3114 .retransmit = _retransmit,
3115 .delete = _delete_,
3116 .destroy = _destroy,
3117 .send_dpd = _send_dpd,
3118 .send_keepalive = _send_keepalive,
71c70705 3119 .redirect = _redirect,
c126ddd0 3120 .handle_redirect = _handle_redirect,
e4af6e6b 3121 .get_redirected_from = _get_redirected_from,
8bced61b
MW
3122 .get_keymat = _get_keymat,
3123 .add_child_sa = _add_child_sa,
3124 .get_child_sa = _get_child_sa,
4bbce1ef
TB
3125 .get_child_count = _get_child_count,
3126 .create_child_sa_enumerator = _create_child_sa_enumerator,
3127 .remove_child_sa = _remove_child_sa,
8bced61b
MW
3128 .rekey_child_sa = _rekey_child_sa,
3129 .delete_child_sa = _delete_child_sa,
3130 .destroy_child_sa = _destroy_child_sa,
3131 .rekey = _rekey,
3132 .reauth = _reauth,
3133 .reestablish = _reestablish,
3134 .set_auth_lifetime = _set_auth_lifetime,
3135 .roam = _roam,
713a1122
MW
3136 .inherit_pre = _inherit_pre,
3137 .inherit_post = _inherit_post,
8bced61b 3138 .generate_message = _generate_message,
40bab9a1 3139 .generate_message_fragmented = _generate_message_fragmented,
8bced61b
MW
3140 .reset = _reset,
3141 .get_unique_id = _get_unique_id,
101d26ba 3142 .add_virtual_ip = _add_virtual_ip,
d2e8f20d 3143 .clear_virtual_ips = _clear_virtual_ips,
101d26ba 3144 .create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
8bced61b 3145 .add_configuration_attribute = _add_configuration_attribute,
9d257034 3146 .create_attribute_enumerator = _create_attribute_enumerator,
dec3c184 3147 .get_if_id = _get_if_id,
8bced61b 3148 .set_kmaddress = _set_kmaddress,
ea340ee8 3149 .create_task_enumerator = _create_task_enumerator,
b7160401 3150 .remove_task = _remove_task,
cbc1a20f 3151 .flush_queue = _flush_queue,
69adeb5b 3152 .queue_task = _queue_task,
208678e6 3153 .queue_task_delayed = _queue_task_delayed,
00c889f4 3154 .adopt_child_tasks = _adopt_child_tasks,
dc04b7c7 3155#ifdef ME
8bced61b
MW
3156 .act_as_mediation_server = _act_as_mediation_server,
3157 .get_server_reflexive_host = _get_server_reflexive_host,
3158 .set_server_reflexive_host = _set_server_reflexive_host,
3159 .get_connect_id = _get_connect_id,
3160 .initiate_mediation = _initiate_mediation,
3161 .initiate_mediated = _initiate_mediated,
3162 .relay = _relay,
3163 .callback = _callback,
3164 .respond = _respond,
dc04b7c7 3165#endif /* ME */
8bced61b
MW
3166 },
3167 .ike_sa_id = ike_sa_id->clone(ike_sa_id),
0b611540 3168 .version = version,
8bced61b
MW
3169 .my_host = host_create_any(AF_INET),
3170 .other_host = host_create_any(AF_INET),
3171 .my_id = identification_create_from_encoding(ID_ANY, chunk_empty),
3172 .other_id = identification_create_from_encoding(ID_ANY, chunk_empty),
17ec1c74 3173 .keymat = keymat_create(version, initiator),
8bced61b
MW
3174 .state = IKE_CREATED,
3175 .stats[STAT_INBOUND] = time_monotonic(NULL),
3176 .stats[STAT_OUTBOUND] = time_monotonic(NULL),
3177 .my_auth = auth_cfg_create(),
3178 .other_auth = auth_cfg_create(),
893da041
MW
3179 .my_auths = array_create(0, 0),
3180 .other_auths = array_create(0, 0),
3181 .attributes = array_create(sizeof(attribute_entry_t), 0),
3568abe7 3182 .unique_id = ref_get(&unique_id),
8bced61b 3183 .keepalive_interval = lib->settings->get_time(lib->settings,
d223fe80 3184 "%s.keep_alive", KEEPALIVE_INTERVAL, lib->ns),
60c82591 3185 .retry_initiate_interval = lib->settings->get_time(lib->settings,
d223fe80 3186 "%s.retry_initiate_interval", 0, lib->ns),
b24b73b7 3187 .flush_auth_cfg = lib->settings->get_bool(lib->settings,
d223fe80 3188 "%s.flush_auth_cfg", FALSE, lib->ns),
40bab9a1 3189 .fragment_size = lib->settings->get_int(lib->settings,
0642f42b 3190 "%s.fragment_size", 1280, lib->ns),
489d154e
TB
3191 .follow_redirects = lib->settings->get_bool(lib->settings,
3192 "%s.follow_redirects", TRUE, lib->ns),
8bced61b 3193 );
4b64a1a1 3194
11aadd77
MW
3195 if (version == IKEV2)
3196 { /* always supported with IKEv2 */
3197 enable_extension(this, EXT_DPD);
3198 }
3199
5baaaa5e 3200 this->task_manager = task_manager_create(&this->public);
b223d517
TB
3201 this->my_host->set_port(this->my_host,
3202 charon->socket->get_port(charon->socket, FALSE));
7daf5226 3203
3d54ae94
MW
3204 if (!this->task_manager || !this->keymat)
3205 {
3206 DBG1(DBG_IKE, "IKE version %d not supported", this->version);
3207 destroy(this);
3208 return NULL;
3209 }
3dd3c5f3 3210 return &this->public;
7ba38761 3211}