From 03f61ba3d517e2d1b9b3656abfc693512734978c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 22 Jul 2014 18:25:37 +0200 Subject: [PATCH] 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) {