diff options
Diffstat (limited to 'src/libcharon/sa/ikev1/task_manager_v1.c')
-rw-r--r-- | src/libcharon/sa/ikev1/task_manager_v1.c | 134 |
1 files changed, 88 insertions, 46 deletions
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 5f6c3bbe8..f76471e78 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2016 Tobias Brunner + * Copyright (C) 2007-2018 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -544,20 +544,20 @@ METHOD(task_manager_t, initiate, status_t, new_mid = TRUE; break; } - if (!mode_config_expected(this) && - activate_task(this, TASK_QUICK_MODE)) + if (activate_task(this, TASK_ISAKMP_DPD)) { - exchange = QUICK_MODE; + exchange = INFORMATIONAL_V1; new_mid = TRUE; break; } - if (activate_task(this, TASK_INFORMATIONAL)) + if (!mode_config_expected(this) && + activate_task(this, TASK_QUICK_MODE)) { - exchange = INFORMATIONAL_V1; + exchange = QUICK_MODE; new_mid = TRUE; break; } - if (activate_task(this, TASK_ISAKMP_DPD)) + if (activate_task(this, TASK_INFORMATIONAL)) { exchange = INFORMATIONAL_V1; new_mid = TRUE; @@ -1121,7 +1121,15 @@ static status_t process_request(private_task_manager_t *this, } } else - { /* We don't send a response, so don't retransmit one if we get + { + if (this->responding.retransmitted > 1) + { + packet_t *packet = NULL; + array_get(this->responding.packets, 0, &packet); + charon->bus->alert(charon->bus, ALERT_RETRANSMIT_SEND_CLEARED, + packet); + } + /* We don't send a response, so don't retransmit one if we get * the same message again. */ clear_packets(this->responding.packets); } @@ -1883,39 +1891,6 @@ 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, - linked_list_t *src, linked_list_t *dst) -{ - enumerator_t *enumerator; - task_t *task; - - enumerator = src->create_enumerator(src); - while (enumerator->enumerate(enumerator, &task)) - { - if (task->get_type(task) == TASK_QUICK_MODE) - { - src->remove_at(src, enumerator); - task->migrate(task, this->ike_sa); - dst->insert_last(dst, 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) { @@ -1976,19 +1951,86 @@ METHOD(task_manager_t, reset, void, } } +/** + * Data for a task queue enumerator + */ +typedef struct { + enumerator_t public; + task_queue_t queue; + enumerator_t *inner; +} task_enumerator_t; + +METHOD(enumerator_t, task_enumerator_destroy, void, + task_enumerator_t *this) +{ + this->inner->destroy(this->inner); + free(this); +} + +METHOD(enumerator_t, task_enumerator_enumerate, bool, + task_enumerator_t *this, va_list args) +{ + task_t **task; + + VA_ARGS_VGET(args, task); + return this->inner->enumerate(this->inner, task); +} + METHOD(task_manager_t, create_task_enumerator, enumerator_t*, private_task_manager_t *this, task_queue_t queue) { + task_enumerator_t *enumerator; + + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _task_enumerator_enumerate, + .destroy = _task_enumerator_destroy, + }, + .queue = queue, + ); switch (queue) { case TASK_QUEUE_ACTIVE: - return this->active_tasks->create_enumerator(this->active_tasks); + enumerator->inner = this->active_tasks->create_enumerator( + this->active_tasks); + break; + case TASK_QUEUE_PASSIVE: + enumerator->inner = this->passive_tasks->create_enumerator( + this->passive_tasks); + break; + case TASK_QUEUE_QUEUED: + enumerator->inner = this->queued_tasks->create_enumerator( + this->queued_tasks); + break; + default: + enumerator->inner = enumerator_create_empty(); + break; + } + return &enumerator->public; +} + +METHOD(task_manager_t, remove_task, void, + private_task_manager_t *this, enumerator_t *enumerator_public) +{ + task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public; + + switch (enumerator->queue) + { + case TASK_QUEUE_ACTIVE: + this->active_tasks->remove_at(this->active_tasks, + enumerator->inner); + break; case TASK_QUEUE_PASSIVE: - return this->passive_tasks->create_enumerator(this->passive_tasks); + this->passive_tasks->remove_at(this->passive_tasks, + enumerator->inner); + break; case TASK_QUEUE_QUEUED: - return this->queued_tasks->create_enumerator(this->queued_tasks); + this->queued_tasks->remove_at(this->queued_tasks, + enumerator->inner); + break; default: - return enumerator_create_empty(); + break; } } @@ -2039,9 +2081,9 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa) .get_mid = _get_mid, .reset = _reset, .adopt_tasks = _adopt_tasks, - .adopt_child_tasks = _adopt_child_tasks, .busy = _busy, .create_task_enumerator = _create_task_enumerator, + .remove_task = _remove_task, .flush = _flush, .flush_queue = _flush_queue, .destroy = _destroy, |