diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/sa/task_manager_v1.c | 48 | ||||
-rw-r--r-- | src/libstrongswan/utils.h | 6 |
2 files changed, 54 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; diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h index 0f06fec6a..f98de4139 100644 --- a/src/libstrongswan/utils.h +++ b/src/libstrongswan/utils.h @@ -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, }; /** |