From 03f61ba3d517e2d1b9b3656abfc693512734978c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:25:37 +0200 Subject: 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(-) (limited to 'src') 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) { -- cgit v1.2.3 From 40164bbe27576c68a6dc052a52f918a13d6d65e5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:30:24 +0200 Subject: 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(+) (limited to 'src') 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, -- cgit v1.2.3 From 3293d146289d7c05e6c6089ae1f7cdbcea378e63 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:51:57 +0200 Subject: 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(-) (limited to 'src') 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); } /** -- cgit v1.2.3 From ff601341572b0d38b4ddde3846a145f252d1e282 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:04:40 +0200 Subject: 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(+) (limited to 'src') 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); -- cgit v1.2.3 From c5a5bc85d9930e9e5487fa8797bf79fa682a0144 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:09:16 +0200 Subject: 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(-) (limited to 'src') 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); -- cgit v1.2.3 From 2180ace937f45fd9e4022b098ebc0a10934a494d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:24:33 +0200 Subject: 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(+) (limited to 'src') 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); }; /** -- cgit v1.2.3 From 1b17f647a5fa030b5efa4cf4c44173b9e2de61f1 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 12:25:01 +0200 Subject: 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(+) (limited to 'src') 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 { -- cgit v1.2.3 From 7840952edc49720627bd97f69eb472267ffb8c75 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:12:09 +0200 Subject: 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(-) (limited to 'src') 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. -- cgit v1.2.3 From 10bad0fc23e41fe4d033177d18e1ff16ac98799a Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:12:20 +0200 Subject: 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(-) (limited to 'src') 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)) -- cgit v1.2.3 From 8956dcecd4f123da03993fcb22ea874610ca82f7 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:46:16 +0200 Subject: 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(-) (limited to 'src') 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)) { -- cgit v1.2.3 From de6ab8e85a5f8e37a0e055b0eeb0a3e5042b1fb2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 13:51:27 +0200 Subject: 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(-) (limited to 'src') 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 */ -- cgit v1.2.3 From acd69fc291bea4f8e85680505af0bd751e8b36a9 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 28 Jul 2014 14:09:10 +0200 Subject: ikev2: Reduce timeout if path probing was enabled --- src/libcharon/sa/ikev2/task_manager_v2.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src') 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 -- cgit v1.2.3