diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 53afe843d..81e1ff414 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1928,9 +1928,10 @@ METHOD(ike_sa_t, reauth, status_t, } /** - * Check if tasks to create CHILD_SAs are queued in the given queue + * Check if any tasks of a specific type are queued in the given queue. */ -static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue) +static bool is_task_queued(private_ike_sa_t *this, task_queue_t queue, + task_type_t type) { enumerator_t *enumerator; task_t *task; @@ -1940,8 +1941,7 @@ static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue) queue); while (enumerator->enumerate(enumerator, &task)) { - if (task->get_type(task) == TASK_CHILD_CREATE || - task->get_type(task) == TASK_QUICK_MODE) + if (task->get_type(task) == type) { found = TRUE; break; @@ -1951,6 +1951,24 @@ static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue) return found; } +/** + * Check if any tasks to create CHILD_SAs are queued in the given queue. + */ +static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue) +{ + return is_task_queued(this, queue, + this->version == IKEV1 ? TASK_QUICK_MODE : TASK_CHILD_CREATE); +} + +/** + * Check if any tasks to delete the IKE_SA are queued in the given queue. + */ +static bool is_delete_queued(private_ike_sa_t *this, task_queue_t queue) +{ + return is_task_queued(this, queue, + this->version == IKEV1 ? TASK_ISAKMP_DELETE : TASK_IKE_DELETE); +} + /** * Reestablish CHILD_SAs and migrate queued tasks. * @@ -2036,6 +2054,12 @@ METHOD(ike_sa_t, reestablish, status_t, bool restart = FALSE; status_t status = FAILED; + if (is_delete_queued(this, TASK_QUEUE_QUEUED)) + { /* don't reestablish IKE_SAs that have explicitly been deleted in the + * mean time */ + return FAILED; + } + if (has_condition(this, COND_REAUTHENTICATING)) { /* only reauthenticate if we have children */ if (array_count(this->child_sas) == 0