IKEv1 XAuth: Added new MIGRATE status type to status_t.

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
This commit is contained in:
Clavister OpenSource
2012-03-20 17:30:52 +01:00
parent 46897273d7
commit b94f248ea9
2 changed files with 54 additions and 0 deletions
+48
View 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;
+6
View 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,
};
/**