ike-mobike: Only ignore MOBIKE responses if an actual update is queued
authorTobias Brunner <tobias@strongswan.org>
Mon, 29 Jan 2018 11:34:33 +0000 (12:34 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 9 Feb 2018 10:21:02 +0000 (11:21 +0100)
The counter does not tell us what task is actually queued, so we might
ignore the response to an update (with NAT-D payloads) if only an address
update is queued.

src/libcharon/sa/ikev2/tasks/ike_mobike.c

index 249f025..59b5591 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2010-2014 Tobias Brunner
+ * Copyright (C) 2010-2018 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -76,14 +76,36 @@ struct private_ike_mobike_t {
         * additional addresses got updated
         */
        bool addresses_updated;
-
-       /**
-        * whether the pending updates counter was increased
-        */
-       bool pending_update;
 };
 
 /**
+ * Check if a newer MOBIKE update task is queued
+ */
+static bool is_newer_update_queued(private_ike_mobike_t *this)
+{
+       enumerator_t *enumerator;
+       private_ike_mobike_t *mobike;
+       task_t *task;
+       bool found = FALSE;
+
+       enumerator = this->ike_sa->create_task_enumerator(this->ike_sa,
+                                                                                                         TASK_QUEUE_QUEUED);
+       while (enumerator->enumerate(enumerator, &task))
+       {
+               if (task->get_type(task) == TASK_IKE_MOBIKE)
+               {
+                       mobike = (private_ike_mobike_t*)task;
+                       /* a queued check or update might invalidate the results of the
+                        * current task */
+                       found = mobike->check || mobike->update;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
  * read notifys from message and evaluate them
  */
 static void process_payloads(private_ike_mobike_t *this, message_t *message)
@@ -526,9 +548,8 @@ METHOD(task_t, process_i, status_t,
        }
        else if (message->get_exchange_type(message) == INFORMATIONAL)
        {
-               if (this->ike_sa->get_pending_updates(this->ike_sa) > 1)
+               if (is_newer_update_queued(this))
                {
-                       /* newer update queued, ignore this one */
                        return SUCCESS;
                }
                if (this->cookie2.ptr)
@@ -615,12 +636,6 @@ METHOD(ike_mobike_t, addresses, void,
           private_ike_mobike_t *this)
 {
        this->address = TRUE;
-       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,
@@ -628,12 +643,6 @@ METHOD(ike_mobike_t, roam, void,
 {
        this->check = TRUE;
        this->address |= address;
-       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,
@@ -643,12 +652,6 @@ METHOD(ike_mobike_t, dpd, void,
        {
                this->natd = ike_natd_create(this->ike_sa, this->initiator);
        }
-       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,
@@ -678,21 +681,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,
           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)
        {