implemented more aggressive MOBIKE path probing
authorMartin Willi <martin@strongswan.org>
Fri, 28 Sep 2007 08:22:37 +0000 (08:22 -0000)
committerMartin Willi <martin@strongswan.org>
Fri, 28 Sep 2007 08:22:37 +0000 (08:22 -0000)
do not queue more than one MOBIKE task

src/charon/sa/task_manager.c
src/charon/sa/task_manager.h
src/charon/sa/tasks/ike_mobike.c
src/charon/sa/tasks/ike_mobike.h

index a8f6622..1b2c0f5 100644 (file)
@@ -220,42 +220,70 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
                iterator_t *iterator;
                packet_t *packet;
                task_t *task;
                iterator_t *iterator;
                packet_t *packet;
                task_t *task;
-
-               if (this->initiating.retransmitted <= RETRANSMIT_TRIES)
-               {
-                       timeout = (u_int32_t)(RETRANSMIT_TIMEOUT *
-                                               pow(RETRANSMIT_BASE, this->initiating.retransmitted));
-               }
-               else
-               {
-                       DBG1(DBG_IKE, "giving up after %d retransmits",
-                                this->initiating.retransmitted - 1);
-                       return DESTROY_ME;
-               }
+               ike_mobike_t *mobike = NULL;
                
                
-               if (this->initiating.retransmitted)
-               {
-                       DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
-                                this->initiating.retransmitted, message_id);
-               }
-               this->initiating.retransmitted++;
-               
-               packet = this->initiating.packet->clone(this->initiating.packet);
-               
-               /* mobike needs to now when we retransmit, so we call it here */
+               /* check if we are retransmitting a MOBIKE routability check */
                iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
                while (iterator->iterate(iterator, (void*)&task))
                {
                        if (task->get_type(task) == IKE_MOBIKE)
                        {
                iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
                while (iterator->iterate(iterator, (void*)&task))
                {
                        if (task->get_type(task) == IKE_MOBIKE)
                        {
-                               ike_mobike_t *mobike = (ike_mobike_t*)task;
-                               mobike->transmit(mobike, packet);
+                               mobike = (ike_mobike_t*)task;
+                               if (!mobike->is_probing(mobike))
+                               {
+                                       mobike = NULL;
+                               }
                                break;
                        }
                }
                iterator->destroy(iterator);
                                break;
                        }
                }
                iterator->destroy(iterator);
+
+               if (mobike == NULL)
+               {
+                       if (this->initiating.retransmitted <= RETRANSMIT_TRIES)
+                       {
+                               timeout = (u_int32_t)(RETRANSMIT_TIMEOUT *
+                                                       pow(RETRANSMIT_BASE, this->initiating.retransmitted));
+                       }
+                       else
+                       {
+                               DBG1(DBG_IKE, "giving up after %d retransmits",
+                                        this->initiating.retransmitted - 1);
+                               return DESTROY_ME;
+                       }
+                       
+                       if (this->initiating.retransmitted)
+                       {
+                               DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
+                                        this->initiating.retransmitted, message_id);
+                       }
+                       packet = this->initiating.packet->clone(this->initiating.packet);
+               }
+               else
+               {       /* for routeability checks, we use a more aggressive behavior */
+                       if (this->initiating.retransmitted <= ROUTEABILITY_CHECK_TRIES)
+                       {
+                               timeout = ROUTEABILITY_CHECK_INTERVAL;
+                       }
+                       else
+                       {
+                               DBG1(DBG_IKE, "giving up after %d path probings",
+                                        this->initiating.retransmitted - 1);
+                               return DESTROY_ME;
+                       }
+                       
+                       if (this->initiating.retransmitted)
+                       {
+                               DBG1(DBG_IKE, "path probing attempt %d",
+                                        this->initiating.retransmitted);
+                       }
+                       packet = this->initiating.packet->clone(this->initiating.packet);
+                       mobike->transmit(mobike, packet);
+               }
                
                charon->sender->send(charon->sender, packet);
                
                charon->sender->send(charon->sender, packet);
+               
+               this->initiating.retransmitted++;
                job = (job_t*)retransmit_job_create(this->initiating.mid,
                                                                                        this->ike_sa->get_id(this->ike_sa));
                charon->scheduler->schedule_job(charon->scheduler, job, timeout);
                job = (job_t*)retransmit_job_create(this->initiating.mid,
                                                                                        this->ike_sa->get_id(this->ike_sa));
                charon->scheduler->schedule_job(charon->scheduler, job, timeout);
@@ -852,6 +880,23 @@ static status_t process_message(private_task_manager_t *this, message_t *msg)
  */
 static void queue_task(private_task_manager_t *this, task_t *task)
 {
  */
 static void queue_task(private_task_manager_t *this, task_t *task)
 {
+       if (task->get_type(task) == IKE_MOBIKE)
+       {       /*  there is no need to queue more than one mobike task */
+               iterator_t *iterator;
+               task_t *current;
+               
+               iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
+               while (iterator->iterate(iterator, (void**)&current))
+               {
+                       if (current->get_type(current) == IKE_MOBIKE)
+                       {
+                               iterator->destroy(iterator);
+                               task->destroy(task);
+                               return;
+                       }
+               }
+               iterator->destroy(iterator);
+       }
        DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
        this->queued_tasks->insert_last(this->queued_tasks, task);
 }
        DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
        this->queued_tasks->insert_last(this->queued_tasks, task);
 }
index fb34aab..38c63c1 100644 (file)
@@ -51,6 +51,20 @@ typedef struct task_manager_t task_manager_t;
  */
 #define RETRANSMIT_TRIES 5
 
  */
 #define RETRANSMIT_TRIES 5
 
+/**
+ * Interval for mobike routability checks in ms.
+ *
+ * @ingroup sa
+ */
+#define ROUTEABILITY_CHECK_INTERVAL 2500
+
+/**
+ * Number of routability checks before giving up
+ * 
+ * @ingroup sa
+ */
+#define ROUTEABILITY_CHECK_TRIES 10
+
 
 /**
  * @brief The task manager, juggles task and handles message exchanges.
 
 /**
  * @brief The task manager, juggles task and handles message exchanges.
index a32f7e5..d1fc8c6 100644 (file)
@@ -448,6 +448,14 @@ static void roam(private_ike_mobike_t *this, bool address)
 }
 
 /**
 }
 
 /**
+ * Implementation of ike_mobike_t.is_probing.
+ */
+static bool is_probing(private_ike_mobike_t *this)
+{
+       return this->check;
+}
+
+/**
  * Implementation of task_t.get_type
  */
 static task_type_t get_type(private_ike_mobike_t *this)
  * Implementation of task_t.get_type
  */
 static task_type_t get_type(private_ike_mobike_t *this)
@@ -490,6 +498,7 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
 
        this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
        this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit;
 
        this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
        this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit;
+       this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing;
        this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
        this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
        this->public.task.destroy = (void(*)(task_t*))destroy;
        this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
        this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
        this->public.task.destroy = (void(*)(task_t*))destroy;
index cee9da0..bb51507 100644 (file)
@@ -71,6 +71,14 @@ struct ike_mobike_t {
         * @param packet                the packet to transmit
         */
        void (*transmit)(ike_mobike_t *this, packet_t *packet);
         * @param packet                the packet to transmit
         */
        void (*transmit)(ike_mobike_t *this, packet_t *packet);
+       
+       /**
+        * @brief Check if this task is probing for routability.
+        *
+        * @param this                  calling object
+        * @return                              TRUE if task is probing
+        */
+       bool (*is_probing)(ike_mobike_t *this); 
 };
 
 /**
 };
 
 /**