diff options
Diffstat (limited to 'src/libcharon/sa/ikev1')
-rw-r--r-- | src/libcharon/sa/ikev1/phase1.c | 3 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/task_manager_v1.c | 134 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c | 1 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c | 1 | ||||
-rw-r--r-- | src/libcharon/sa/ikev1/tasks/quick_mode.c | 9 |
5 files changed, 96 insertions, 52 deletions
diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index b99d75142..ac2899f11 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -251,7 +251,8 @@ METHOD(phase1_t, derive_keys, bool, return FALSE; } charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, this->dh_value, - this->nonce_i, this->nonce_r, NULL, shared_key); + this->nonce_i, this->nonce_r, NULL, shared_key, + method); DESTROY_IF(shared_key); return TRUE; } 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, diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c b/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c index 7dbbdc92f..b652d926f 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_cert_post.c @@ -287,7 +287,6 @@ METHOD(task_t, process_i, status_t, default: return FAILED; } - break; } case AGGRESSIVE: { diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c b/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c index 58f856e3f..566bfe83a 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_cert_pre.c @@ -605,7 +605,6 @@ METHOD(task_t, process_i, status_t, default: return FAILED; } - break; } case AGGRESSIVE: { diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 007e94d96..b0a42b8bd 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -1110,14 +1110,17 @@ METHOD(task_t, process_r, status_t, this->tsi = select_ts(this, FALSE, tsi); this->tsr = select_ts(this, TRUE, tsr); } - tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); - tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); if (!this->config || !this->tsi || !this->tsr || this->mode != this->config->get_mode(this->config)) { - DBG1(DBG_IKE, "no matching CHILD_SA config found"); + DBG1(DBG_IKE, "no matching CHILD_SA config found for " + "%#R === %#R", tsi, tsr); + tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); + tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); return send_notify(this, INVALID_ID_INFORMATION); } + tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); + tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); if (this->config->has_option(this->config, OPT_IPCOMP)) { |