From 03f61ba3d517e2d1b9b3656abfc693512734978c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:25:37 +0200 Subject: [PATCH 01/12] ikev2: Properly keep track of pending MOBIKE updates Because we only queue one MOBIKE task at a time, but destroy superfluous ones only after we already increased the counter for pending MOBIKE updates, we have to reduce the counter when such tasks are destroyed. Otherwise, the queued task would assume another task is queued when it is running and ignore any successful response. --- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 35 +++++++++++++++++------ 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index 00ca615d8..a51411358 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Tobias Brunner + * Copyright (C) 2010-2014 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -77,6 +77,11 @@ struct private_ike_mobike_t { * additional addresses got updated */ bool addresses_updated; + + /** + * whether the pending updates counter was increased + */ + bool pending_update; }; /** @@ -481,9 +486,7 @@ METHOD(task_t, process_i, status_t, } else if (message->get_exchange_type(message) == INFORMATIONAL) { - u_int32_t updates = this->ike_sa->get_pending_updates(this->ike_sa) - 1; - this->ike_sa->set_pending_updates(this->ike_sa, updates); - if (updates > 0) + if (this->ike_sa->get_pending_updates(this->ike_sa) > 1) { /* newer update queued, ignore this one */ return SUCCESS; @@ -560,7 +563,6 @@ METHOD(task_t, process_i, status_t, this->natd = ike_natd_create(this->ike_sa, this->initiator); } this->check = FALSE; - this->ike_sa->set_pending_updates(this->ike_sa, 1); return NEED_MORE; } } @@ -573,8 +575,12 @@ METHOD(ike_mobike_t, addresses, void, private_ike_mobike_t *this) { this->address = TRUE; - this->ike_sa->set_pending_updates(this->ike_sa, + if (!this->pending_update) + { + this->pending_update = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(ike_mobike_t, roam, void, @@ -582,8 +588,12 @@ METHOD(ike_mobike_t, roam, void, { this->check = TRUE; this->address = address; - this->ike_sa->set_pending_updates(this->ike_sa, + if (!this->pending_update) + { + this->pending_update = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(ike_mobike_t, dpd, void, @@ -593,8 +603,12 @@ METHOD(ike_mobike_t, dpd, void, { this->natd = ike_natd_create(this->ike_sa, this->initiator); } - this->ike_sa->set_pending_updates(this->ike_sa, + if (!this->pending_update) + { + this->pending_update = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(ike_mobike_t, is_probing, bool, @@ -623,6 +637,11 @@ METHOD(task_t, migrate, void, METHOD(task_t, destroy, void, private_ike_mobike_t *this) { + if (this->pending_update) + { + this->ike_sa->set_pending_updates(this->ike_sa, + this->ike_sa->get_pending_updates(this->ike_sa) - 1); + } chunk_free(&this->cookie2); if (this->natd) { From 40164bbe27576c68a6dc052a52f918a13d6d65e5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:30:24 +0200 Subject: [PATCH 02/12] ikev2: Migrate number of pending MOBIKE updates This will probably never be more than 1 since we only have one task queued at a time and we don't migrate running tasks. --- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index a51411358..dce6ecd7e 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -632,6 +632,11 @@ METHOD(task_t, migrate, void, { this->natd->task.migrate(&this->natd->task, ike_sa); } + if (this->pending_update) + { + this->ike_sa->set_pending_updates(this->ike_sa, + this->ike_sa->get_pending_updates(this->ike_sa) + 1); + } } METHOD(task_t, destroy, void, From 3293d146289d7c05e6c6089ae1f7cdbcea378e63 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:51:57 +0200 Subject: [PATCH 03/12] ikev2: Insert MOBIKE tasks at the front of the queue In case we have no usable path to the other peer there is no point in initiating any other tasks (like rekeying). --- src/libcharon/sa/ikev2/task_manager_v2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index ada798bdc..630c902f4 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1246,6 +1246,8 @@ METHOD(task_manager_t, process_message, status_t, METHOD(task_manager_t, queue_task, void, private_task_manager_t *this, task_t *task) { + int pos = ARRAY_TAIL; + if (task->get_type(task) == TASK_IKE_MOBIKE) { /* there is no need to queue more than one mobike task */ enumerator_t *enumerator; @@ -1262,9 +1264,12 @@ METHOD(task_manager_t, queue_task, void, } } enumerator->destroy(enumerator); + /* insert MOBIKE tasks first as we currently might not have a usable + * path to initiate any other tasks */ + pos = ARRAY_HEAD; } DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task)); - array_insert(this->queued_tasks, ARRAY_TAIL, task); + array_insert(this->queued_tasks, pos, task); } /** From ff601341572b0d38b4ddde3846a145f252d1e282 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:04:40 +0200 Subject: [PATCH 04/12] ikev2: Skip peer addresses we can't send packets to when looking for valid paths --- src/libcharon/sa/ike_sa.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index e63e0fa6c..516b2435b 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1911,11 +1911,29 @@ static bool is_any_path_valid(private_ike_sa_t *this) bool valid = FALSE; enumerator_t *enumerator; host_t *src = NULL, *addr; + int family = AF_UNSPEC; + + switch (charon->socket->supported_families(charon->socket)) + { + case SOCKET_FAMILY_IPV4: + family = AF_INET; + break; + case SOCKET_FAMILY_IPV6: + family = AF_INET6; + break; + case SOCKET_FAMILY_BOTH: + case SOCKET_FAMILY_NONE: + break; + } DBG1(DBG_IKE, "old path is not available anymore, try to find another"); enumerator = create_peer_address_enumerator(this); while (enumerator->enumerate(enumerator, &addr)) { + if (family != AF_UNSPEC && addr->get_family(addr) != family) + { + continue; + } DBG1(DBG_IKE, "looking for a route to %H ...", addr); src = hydra->kernel_interface->get_source_addr( hydra->kernel_interface, addr, NULL); From c5a5bc85d9930e9e5487fa8797bf79fa682a0144 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:09:16 +0200 Subject: [PATCH 05/12] ike-mobike: Skip peer addresses we can't send packets to when checking paths --- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index dce6ecd7e..8e1efb5a1 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -313,12 +313,26 @@ METHOD(ike_mobike_t, transmit, void, enumerator_t *enumerator; ike_cfg_t *ike_cfg; packet_t *copy; + int family = AF_UNSPEC; if (!this->check) { return; } + switch (charon->socket->supported_families(charon->socket)) + { + case SOCKET_FAMILY_IPV4: + family = AF_INET; + break; + case SOCKET_FAMILY_IPV6: + family = AF_INET6; + break; + case SOCKET_FAMILY_BOTH: + case SOCKET_FAMILY_NONE: + break; + } + me_old = this->ike_sa->get_my_host(this->ike_sa); other_old = this->ike_sa->get_other_host(this->ike_sa); ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); @@ -326,15 +340,14 @@ METHOD(ike_mobike_t, transmit, void, enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa); while (enumerator->enumerate(enumerator, (void**)&other)) { + if (family != AF_UNSPEC && other->get_family(other) != family) + { + continue; + } me = hydra->kernel_interface->get_source_addr( hydra->kernel_interface, other, NULL); if (me) { - if (me->get_family(me) != other->get_family(other)) - { - me->destroy(me); - continue; - } /* reuse port for an active address, 4500 otherwise */ apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg), TRUE); other = other->clone(other); From 2180ace937f45fd9e4022b098ebc0a10934a494d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:24:33 +0200 Subject: [PATCH 06/12] ike-mobike: Add method to enable path probing --- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 7 +++++++ src/libcharon/sa/ikev2/tasks/ike_mobike.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index 8e1efb5a1..7d26de144 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -630,6 +630,12 @@ METHOD(ike_mobike_t, is_probing, bool, return this->check; } +METHOD(ike_mobike_t, enable_probing, void, + private_ike_mobike_t *this) +{ + this->check = TRUE; +} + METHOD(task_t, get_type, task_type_t, private_ike_mobike_t *this) { @@ -687,6 +693,7 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator) .dpd = _dpd, .transmit = _transmit, .is_probing = _is_probing, + .enable_probing = _enable_probing, }, .ike_sa = ike_sa, .initiator = initiator, diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.h b/src/libcharon/sa/ikev2/tasks/ike_mobike.h index b145a9a8b..2946f5e4a 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.h +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.h @@ -79,6 +79,11 @@ struct ike_mobike_t { * @return TRUE if task is probing */ bool (*is_probing)(ike_mobike_t *this); + + /** + * Enable probing for routability. + */ + void (*enable_probing)(ike_mobike_t *this); }; /** From 1b17f647a5fa030b5efa4cf4c44173b9e2de61f1 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:25:01 +0200 Subject: [PATCH 07/12] ikev2: Enable path probing for currently active MOBIKE task This might not be the case if e.g. an address appeared but the old one is still available but not actually usable. Without this the MOBIKE task would eventually time out even though we might be able to switch to a working address. --- src/libcharon/sa/ikev2/task_manager_v2.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 630c902f4..cd663dd81 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1373,7 +1373,25 @@ METHOD(task_manager_t, queue_mobike, void, mobike = ike_mobike_create(this->ike_sa, TRUE); if (roam) { + enumerator_t *enumerator; + task_t *current; + mobike->roam(mobike, address); + + /* enable path probing for a currently active MOBIKE task. This might + * not be the case if an address appeared on a new interface while the + * current address is not working but has not yet disappeared. */ + enumerator = array_create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (current->get_type(current) == TASK_IKE_MOBIKE) + { + ike_mobike_t *active = (ike_mobike_t*)current; + active->enable_probing(active); + break; + } + } + enumerator->destroy(enumerator); } else { From 7840952edc49720627bd97f69eb472267ffb8c75 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:12:09 +0200 Subject: [PATCH 08/12] ike-mobike: Return FALSE in transmit() if no path was available --- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 7 +++++-- src/libcharon/sa/ikev2/tasks/ike_mobike.h | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index 7d26de144..65679016c 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -306,7 +306,7 @@ static void apply_port(host_t *host, host_t *old, u_int16_t port, bool local) host->set_port(host, port); } -METHOD(ike_mobike_t, transmit, void, +METHOD(ike_mobike_t, transmit, bool, private_ike_mobike_t *this, packet_t *packet) { host_t *me, *other, *me_old, *other_old; @@ -314,10 +314,11 @@ METHOD(ike_mobike_t, transmit, void, ike_cfg_t *ike_cfg; packet_t *copy; int family = AF_UNSPEC; + bool found = FALSE; if (!this->check) { - return; + return TRUE; } switch (charon->socket->supported_families(charon->socket)) @@ -357,9 +358,11 @@ METHOD(ike_mobike_t, transmit, void, copy->set_source(copy, me); copy->set_destination(copy, other); charon->sender->send(charon->sender, copy); + found = TRUE; } } enumerator->destroy(enumerator); + return found; } METHOD(task_t, build_i, status_t, diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.h b/src/libcharon/sa/ikev2/tasks/ike_mobike.h index 2946f5e4a..bb2318c9c 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.h +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.h @@ -70,8 +70,9 @@ struct ike_mobike_t { * probing. * * @param packet the packet to transmit + * @return TRUE if transmitted, FALSE if no path found */ - void (*transmit)(ike_mobike_t *this, packet_t *packet); + bool (*transmit)(ike_mobike_t *this, packet_t *packet); /** * Check if this task is probing for routability. From 10bad0fc23e41fe4d033177d18e1ff16ac98799a Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:12:20 +0200 Subject: [PATCH 09/12] ikev2: Defer path probing if no path is currently available We do the same before initiating the task, so we should probably do it too when we already initiated it, not just time out and destroy the SA. --- src/libcharon/sa/ikev2/task_manager_v2.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index cd663dd81..8094e34ac 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -120,6 +120,11 @@ struct private_task_manager_t { */ exchange_type_t type; + /** + * TRUE if exchange was deferred because no path was available + */ + bool deferred; + } initiating; /** @@ -289,7 +294,14 @@ METHOD(task_manager_t, retransmit, status_t, DBG1(DBG_IKE, "path probing attempt %d", this->initiating.retransmitted); } - mobike->transmit(mobike, this->initiating.packet); + if (!mobike->transmit(mobike, this->initiating.packet)) + { + DBG1(DBG_IKE, "no route found to reach peer, path probing " + "deferred"); + this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE); + this->initiating.deferred = TRUE; + return SUCCESS; + } } this->initiating.retransmitted++; @@ -315,6 +327,12 @@ METHOD(task_manager_t, initiate, status_t, DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress", exchange_type_names, this->initiating.type); /* do not initiate if we already have a message in the air */ + if (this->initiating.deferred) + { /* re-initiate deferred exchange */ + this->initiating.deferred = FALSE; + this->initiating.retransmitted = 0; + return retransmit(this, this->initiating.mid); + } return SUCCESS; } @@ -458,6 +476,7 @@ METHOD(task_manager_t, initiate, status_t, message->set_exchange_type(message, exchange); this->initiating.type = exchange; this->initiating.retransmitted = 0; + this->initiating.deferred = FALSE; enumerator = array_create_enumerator(this->active_tasks); while (enumerator->enumerate(enumerator, &task)) From 8956dcecd4f123da03993fcb22ea874610ca82f7 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:46:16 +0200 Subject: [PATCH 10/12] ike-mobike: Allow calling transmit() even when not currently path probing Path probing is enabled if the current path is not available anymore. --- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index 65679016c..d91fa5862 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -316,9 +316,25 @@ METHOD(ike_mobike_t, transmit, bool, int family = AF_UNSPEC; bool found = FALSE; + me_old = this->ike_sa->get_my_host(this->ike_sa); + other_old = this->ike_sa->get_other_host(this->ike_sa); + ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); + if (!this->check) { - return TRUE; + me = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, + other_old, me_old); + if (me) + { + if (me->ip_equals(me, me_old)) + { + charon->sender->send(charon->sender, packet->clone(packet)); + me->destroy(me); + return TRUE; + } + me->destroy(me); + } + this->check = TRUE; } switch (charon->socket->supported_families(charon->socket)) @@ -334,10 +350,6 @@ METHOD(ike_mobike_t, transmit, bool, break; } - me_old = this->ike_sa->get_my_host(this->ike_sa); - other_old = this->ike_sa->get_other_host(this->ike_sa); - ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa); while (enumerator->enumerate(enumerator, (void**)&other)) { From de6ab8e85a5f8e37a0e055b0eeb0a3e5042b1fb2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:51:27 +0200 Subject: [PATCH 11/12] ikev2: Defer MOBIKE updates if no path is available --- src/libcharon/sa/ikev2/task_manager_v2.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 8094e34ac..c73bf0168 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -241,16 +241,12 @@ METHOD(task_manager_t, retransmit, status_t, if (task->get_type(task) == TASK_IKE_MOBIKE) { mobike = (ike_mobike_t*)task; - if (!mobike->is_probing(mobike)) - { - mobike = NULL; - } break; } } enumerator->destroy(enumerator); - if (mobike == NULL) + if (!mobike || !mobike->is_probing(mobike)) { if (this->initiating.retransmitted <= this->retransmit_tries) { @@ -273,8 +269,19 @@ METHOD(task_manager_t, retransmit, status_t, charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND, this->initiating.packet); } - packet = this->initiating.packet->clone(this->initiating.packet); - charon->sender->send(charon->sender, packet); + if (!mobike) + { + packet = this->initiating.packet->clone(this->initiating.packet); + charon->sender->send(charon->sender, packet); + } + else if (!mobike->transmit(mobike, this->initiating.packet)) + { + DBG1(DBG_IKE, "no route found to reach peer, MOBIKE update " + "deferred"); + this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE); + this->initiating.deferred = TRUE; + return SUCCESS; + } } else { /* for routeability checks, we use a more aggressive behavior */ From acd69fc291bea4f8e85680505af0bd751e8b36a9 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 14:09:10 +0200 Subject: [PATCH 12/12] ikev2: Reduce timeout if path probing was enabled --- src/libcharon/sa/ikev2/task_manager_v2.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index c73bf0168..58f6bc61d 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -274,13 +274,20 @@ METHOD(task_manager_t, retransmit, status_t, packet = this->initiating.packet->clone(this->initiating.packet); charon->sender->send(charon->sender, packet); } - else if (!mobike->transmit(mobike, this->initiating.packet)) + else { - DBG1(DBG_IKE, "no route found to reach peer, MOBIKE update " - "deferred"); - this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE); - this->initiating.deferred = TRUE; - return SUCCESS; + if (!mobike->transmit(mobike, this->initiating.packet)) + { + DBG1(DBG_IKE, "no route found to reach peer, MOBIKE update " + "deferred"); + this->ike_sa->set_condition(this->ike_sa, COND_STALE, TRUE); + this->initiating.deferred = TRUE; + return SUCCESS; + } + else if (mobike->is_probing(mobike)) + { + timeout = ROUTEABILITY_CHECK_INTERVAL; + } } } else