diff options
Diffstat (limited to 'src/libcharon/sa/ikev2/task_manager_v2.c')
-rw-r--r-- | src/libcharon/sa/ikev2/task_manager_v2.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 79a9aa5a0..a2a968b46 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1426,6 +1426,39 @@ METHOD(task_manager_t, adopt_tasks, void, } } +/** + * Migrates child-creating tasks from src to dst + */ +static void migrate_child_tasks(private_task_manager_t *this, + array_t *src, array_t *dst) +{ + enumerator_t *enumerator; + task_t *task; + + enumerator = array_create_enumerator(src); + while (enumerator->enumerate(enumerator, &task)) + { + if (task->get_type(task) == TASK_CHILD_CREATE) + { + array_remove_at(src, enumerator); + task->migrate(task, this->ike_sa); + array_insert(dst, ARRAY_TAIL, task); + } + } + enumerator->destroy(enumerator); +} + +METHOD(task_manager_t, adopt_child_tasks, void, + private_task_manager_t *this, task_manager_t *other_public) +{ + private_task_manager_t *other = (private_task_manager_t*)other_public; + + /* move active child tasks from other to this */ + migrate_child_tasks(this, other->active_tasks, this->queued_tasks); + /* do the same for queued tasks */ + migrate_child_tasks(this, other->queued_tasks, this->queued_tasks); +} + METHOD(task_manager_t, busy, bool, private_task_manager_t *this) { @@ -1527,6 +1560,7 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa) .incr_mid = _incr_mid, .reset = _reset, .adopt_tasks = _adopt_tasks, + .adopt_child_tasks = _adopt_child_tasks, .busy = _busy, .create_task_enumerator = _create_task_enumerator, .flush_queue = _flush_queue, |