ike-sa-manager: Avoid initiating CHILD_SAs on IKE_SAs with queued DELETE

The IKE_SA might be busy with a different task while a request to
terminate it is getting queued, we don't want to use such an IKE_SA to
initiate new CHILD_SAs as these tasks will get lost once the IKE_SA is
terminated.
This commit is contained in:
Tobias Brunner 2024-07-04 14:43:37 +02:00
parent 07ce6b44c5
commit da00a04f60
3 changed files with 22 additions and 12 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2020 Tobias Brunner
* Copyright (C) 2006-2024 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
@ -2012,12 +2012,13 @@ static bool is_child_queued(private_ike_sa_t *this, task_queue_t 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.
/*
* Described in header
*/
static bool is_delete_queued(private_ike_sa_t *this, task_queue_t queue)
bool ike_sa_is_delete_queued(ike_sa_t *ike_sa)
{
return is_task_queued(this, queue,
private_ike_sa_t *this = (private_ike_sa_t*)ike_sa;
return is_task_queued(this, TASK_QUEUE_QUEUED,
this->version == IKEV1 ? TASK_ISAKMP_DELETE : TASK_IKE_DELETE);
}
@ -2101,7 +2102,7 @@ METHOD(ike_sa_t, reestablish, status_t,
bool restart = FALSE;
status_t status = FAILED;
if (is_delete_queued(this, TASK_QUEUE_QUEUED))
if (ike_sa_is_delete_queued((ike_sa_t*)this))
{ /* don't reestablish IKE_SAs that have explicitly been deleted in the
* mean time */
return FAILED;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2020 Tobias Brunner
* Copyright (C) 2006-2024 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
@ -1261,7 +1261,7 @@ struct ike_sa_t {
* @param ike_sa_id ike_sa_id_t to associate with new IKE_SA/ISAKMP_SA
* @param initiator TRUE to create this IKE_SA as initiator
* @param version IKE version of this SA
* @return ike_sa_t object
* @return ike_sa_t object
*/
ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
ike_version_t version);
@ -1271,16 +1271,24 @@ ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
* parameters or the authentication method prevent it.
*
* @param this IKE_SA to check
* @return TRUE if active reauthentication is possible
* @return TRUE if active reauthentication is possible
*/
bool ike_sa_can_reauthenticate(ike_sa_t *this);
/**
* Check if a task to delete this IKE_SA is queued.
*
* @param this IKE_SA to check
* @return TRUE if a task is queued
*/
bool ike_sa_is_delete_queued(ike_sa_t *this);
/**
* Get hosts, virtual or physical, for deriving dynamic traffic selectors.
*
* @param this IKE_SA to retrieve addresses from
* @param local TRUE to get local hosts
* @return list of hosts (internal objects)
* @return list of hosts (internal objects)
*/
linked_list_t *ike_sa_get_dynamic_hosts(ike_sa_t *this, bool local);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2022 Tobias Brunner
* Copyright (C) 2008-2024 Tobias Brunner
* Copyright (C) 2005-2011 Martin Willi
* Copyright (C) 2005 Jan Hutter
*
@ -1562,7 +1562,8 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
continue;
}
if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING ||
entry->ike_sa->get_state(entry->ike_sa) == IKE_REKEYED)
entry->ike_sa->get_state(entry->ike_sa) == IKE_REKEYED ||
ike_sa_is_delete_queued(entry->ike_sa))
{ /* skip IKE_SAs which are not usable, wake other waiting threads */
entry->condvar->signal(entry->condvar);
continue;