mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
ikev2: Let ike/child-rekey tasks indicate if the passive task was adopted
This gives us more flexibility with tasks that return NEED_MORE (currently none of the colliding tasks do, but that will change with multi-KE rekeyings). The active task has to check itself if the passive task is done and should be removed from the task manager.
This commit is contained in:
parent
7ffeed01c0
commit
b6652ababe
@ -872,13 +872,15 @@ static status_t process_response(private_task_manager_t *this,
|
||||
}
|
||||
|
||||
/**
|
||||
* handle exchange collisions
|
||||
* Handle exchange collisions, returns TRUE if the given passive task was
|
||||
* adopted by the active task and the task manager lost control over it.
|
||||
*/
|
||||
static bool handle_collisions(private_task_manager_t *this, task_t *task)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
task_t *active;
|
||||
task_type_t type;
|
||||
bool adopted = FALSE;
|
||||
|
||||
type = task->get_type(task);
|
||||
|
||||
@ -896,7 +898,7 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
|
||||
if (type == TASK_IKE_REKEY || type == TASK_IKE_DELETE)
|
||||
{
|
||||
ike_rekey_t *rekey = (ike_rekey_t*)active;
|
||||
rekey->collide(rekey, task);
|
||||
adopted = rekey->collide(rekey, task);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
@ -904,7 +906,7 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
|
||||
if (type == TASK_CHILD_REKEY || type == TASK_CHILD_DELETE)
|
||||
{
|
||||
child_rekey_t *rekey = (child_rekey_t*)active;
|
||||
rekey->collide(rekey, task);
|
||||
adopted = rekey->collide(rekey, task);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
@ -912,11 +914,11 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
|
||||
continue;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return TRUE;
|
||||
return adopted;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
return FALSE;
|
||||
return adopted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -528,7 +528,7 @@ METHOD(child_rekey_t, is_redundant, bool,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(child_rekey_t, collide, void,
|
||||
METHOD(child_rekey_t, collide, bool,
|
||||
private_child_rekey_t *this, task_t *other)
|
||||
{
|
||||
/* the task manager only detects exchange collision, but not if
|
||||
@ -540,16 +540,14 @@ METHOD(child_rekey_t, collide, void,
|
||||
|
||||
if (rekey->child_sa != this->child_sa)
|
||||
{ /* not the same child => no collision */
|
||||
other->destroy(other);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
/* ignore passive tasks that did not successfully create a CHILD_SA */
|
||||
other_child = rekey->child_create->get_child(rekey->child_create);
|
||||
if (!other_child ||
|
||||
other_child->get_state(other_child) != CHILD_INSTALLED)
|
||||
{
|
||||
other->destroy(other);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (other->get_type(other) == TASK_CHILD_DELETE)
|
||||
@ -558,26 +556,24 @@ METHOD(child_rekey_t, collide, void,
|
||||
if (is_redundant(this, del->get_child(del)))
|
||||
{
|
||||
this->other_child_destroyed = TRUE;
|
||||
other->destroy(other);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
if (del->get_child(del) != this->child_sa)
|
||||
{
|
||||
/* not the same child => no collision */
|
||||
other->destroy(other);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* any other task is not critical for collisions, ignore */
|
||||
other->destroy(other);
|
||||
return;
|
||||
/* shouldn't happen */
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_IKE, "detected %N collision with %N", task_type_names,
|
||||
TASK_CHILD_REKEY, task_type_names, other->get_type(other));
|
||||
DESTROY_IF(this->collision);
|
||||
this->collision = other;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(task_t, migrate, void,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Tobias Brunner
|
||||
* Copyright (C) 2016-2020 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
@ -59,9 +59,11 @@ struct child_rekey_t {
|
||||
* be handled gracefully. The task manager is aware of what exchanges
|
||||
* are going on and notifies the active task by passing the passive.
|
||||
*
|
||||
* @param other passive task (adopted)
|
||||
* @param other passive task
|
||||
* @return whether the task was adopted and should be removed from
|
||||
* the task manager's control
|
||||
*/
|
||||
void (*collide)(child_rekey_t* this, task_t *other);
|
||||
bool (*collide)(child_rekey_t* this, task_t *other);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -430,7 +430,7 @@ METHOD(ike_rekey_t, did_collide, bool,
|
||||
return this->collision != NULL;
|
||||
}
|
||||
|
||||
METHOD(ike_rekey_t, collide, void,
|
||||
METHOD(ike_rekey_t, collide, bool,
|
||||
private_ike_rekey_t* this, task_t *other)
|
||||
{
|
||||
DBG1(DBG_IKE, "detected %N collision with %N", task_type_names,
|
||||
@ -440,7 +440,6 @@ METHOD(ike_rekey_t, collide, void,
|
||||
{
|
||||
case TASK_IKE_DELETE:
|
||||
conclude_undetected_collision(this);
|
||||
other->destroy(other);
|
||||
break;
|
||||
case TASK_IKE_REKEY:
|
||||
{
|
||||
@ -450,17 +449,17 @@ METHOD(ike_rekey_t, collide, void,
|
||||
{
|
||||
DBG1(DBG_IKE, "colliding exchange did not result in an IKE_SA, "
|
||||
"ignore");
|
||||
other->destroy(other);
|
||||
break;
|
||||
}
|
||||
DESTROY_IF(&this->collision->public.task);
|
||||
this->collision = rekey;
|
||||
break;
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
/* shouldn't happen */
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Tobias Brunner
|
||||
* Copyright (C) 2016-2020 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
@ -47,15 +47,17 @@ struct ike_rekey_t {
|
||||
bool (*did_collide)(ike_rekey_t *this);
|
||||
|
||||
/**
|
||||
* Register a rekeying task which collides with this one.
|
||||
* Register a rekeying/delete task which collides with this one.
|
||||
*
|
||||
* If two peers initiate rekeying at the same time, the collision must
|
||||
* be handled gracefully. The task manager is aware of what exchanges
|
||||
* are going on and notifies the outgoing task by passing the incoming.
|
||||
* are going on and notifies the active task by passing the passive.
|
||||
*
|
||||
* @param other incoming task
|
||||
* @param other passive task
|
||||
* @return whether the task was adopted and should be removed from
|
||||
* the task manager's control
|
||||
*/
|
||||
void (*collide)(ike_rekey_t* this, task_t *other);
|
||||
bool (*collide)(ike_rekey_t* this, task_t *other);
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user