aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/sa/task_manager_v1.c
diff options
context:
space:
mode:
authorClavister OpenSource <opensource@clavister.com>2011-11-24 16:48:41 +0100
committerClavister OpenSource <opensource@clavister.com>2012-03-20 17:30:52 +0100
commitb94f248ea967aef936db3a323134c030b4f05add (patch)
tree72e7bb710e41818631f7cdff0d931d7d853c6744 /src/libcharon/sa/task_manager_v1.c
parent46897273d76c9f1cfa4fa6f2184adb5e84f01836 (diff)
downloadstrongswan-b94f248ea967aef936db3a323134c030b4f05add.tar.bz2
strongswan-b94f248ea967aef936db3a323134c030b4f05add.tar.xz
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
Diffstat (limited to 'src/libcharon/sa/task_manager_v1.c')
-rw-r--r--src/libcharon/sa/task_manager_v1.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/libcharon/sa/task_manager_v1.c b/src/libcharon/sa/task_manager_v1.c
index 32f847f8a..d5474d962 100644
--- a/src/libcharon/sa/task_manager_v1.c
+++ b/src/libcharon/sa/task_manager_v1.c
@@ -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;