IKEv1 XAuth: Added new MIGRATE status type to status_t.
authorClavister OpenSource <opensource@clavister.com>
Thu, 24 Nov 2011 15:48:41 +0000 (16:48 +0100)
committerClavister OpenSource <opensource@clavister.com>
Tue, 20 Mar 2012 16:30:52 +0000 (17:30 +0100)
  When a task returns this status from a build or process method, it is a signal to the task manager that it should treat it as if the task returned SUCCESS.
  Additionally it will migrate all remaining tasks from the current queue to a different one, calling swap_initiator for each applicable task.
  Finally, the task manager will call "initiate", if applicable, to kick off tasks in the "queued_tasks" queue.
  Task queue relocation mapping:
  passive_tasks moves to queued_tasks (which is then fed to active by the initiate call).
  active_tasks moves to passive_tasks

src/libcharon/sa/task_manager_v1.c
src/libstrongswan/utils.h

index 32f847f..d5474d9 100644 (file)
@@ -234,6 +234,25 @@ METHOD(task_manager_t, retransmit, status_t,
        return SUCCESS;
 }
 
+void migrate_tasks(linked_list_t *from, linked_list_t *to)
+{
+       enumerator_t *enumerator;
+       task_t *task;
+
+       enumerator = from->create_enumerator(from);
+       while(enumerator->enumerate(enumerator, (void**)&task))
+       {
+               DBG4(DBG_IKE, "  Migrating %N task to new queue", task_type_names, task->get_type(task));
+               if(task->swap_initiator)
+               {
+                       task->swap_initiator(task);
+               }
+               to->insert_last(to, task);
+               from->remove_at(from, enumerator);
+       }
+       enumerator->destroy(enumerator);
+}
+
 METHOD(task_manager_t, initiate, status_t,
        private_task_manager_t *this)
 {
@@ -348,6 +367,13 @@ METHOD(task_manager_t, initiate, status_t,
                                this->active_tasks->remove_at(this->active_tasks, enumerator);
                                task->destroy(task);
                                break;
+                       case MIGRATE:
+                               /* task completed, remove it */
+                               this->active_tasks->remove_at(this->active_tasks, enumerator);
+                               task->destroy(task);
+                               /* migrate the remaining active tasks to the passive queue */
+                               migrate_tasks(this->active_tasks, this->passive_tasks);
+                               break;
                        case NEED_MORE:
                                /* processed, but task needs another exchange */
                                break;
@@ -409,6 +435,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
        host_t *me, *other;
        bool delete = FALSE;
        status_t status;
+       bool migrate = FALSE;
 
        me = request->get_destination(request);
        other = request->get_source(request);
@@ -426,6 +453,9 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
        {
                switch (task->build(task, message))
                {
+                       case MIGRATE:
+                               migrate = TRUE;
+                               /* FALL */
                        case SUCCESS:
                                /* task completed, remove it */
                                this->passive_tasks->remove_at(this->passive_tasks, enumerator);
@@ -472,6 +502,14 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
 
        charon->sender->send(charon->sender,
                                                 this->responding.packet->clone(this->responding.packet));
+
+       if (migrate)
+       {
+               migrate_tasks(this->passive_tasks, this->queued_tasks);
+               /* Kick off the newly installed tasks */
+               initiate(this);
+       }
+
        if (delete)
        {
                return DESTROY_ME;
@@ -526,6 +564,16 @@ static status_t process_request(private_task_manager_t *this,
                                task->destroy(task);
                                enumerator->destroy(enumerator);
                                return SUCCESS;
+                       case MIGRATE:
+                               /* task completed, remove it */
+                               this->passive_tasks->remove_at(this->passive_tasks, enumerator);
+                               task->destroy(task);
+                               enumerator->destroy(enumerator);
+                               /* migrate the remaining tasks */
+                               migrate_tasks(this->passive_tasks, this->queued_tasks);
+                               /* Kick off the newly installed tasks */
+                               initiate(this);
+                               return SUCCESS;
                        case NEED_MORE:
                                /* processed, but task needs at least another call to build() */
                                break;
index 0f06fec..f98de41 100644 (file)
@@ -299,6 +299,12 @@ enum status_t {
         * Another call to the method is required.
         */
        NEED_MORE,
+
+       /**
+        * For tasks only, same as SUCCESS, but also migrate all remaining tasks
+        * in the current queue to the opposite queue (passive->active or active->passive)
+        */
+       MIGRATE,
 };
 
 /**