controller: Use separate callbacks to track termination and initiation of SAs

If a local authentication failure occurs in IKEv1 we delete the IKE_SA, which
we don't want the controller to detect as success.

Fixes #1449.
This commit is contained in:
Tobias Brunner 2016-05-06 09:08:08 +02:00
parent 1b4e7fe1e8
commit 0a72d68ea8
1 changed files with 58 additions and 8 deletions

View File

@ -271,6 +271,28 @@ METHOD(listener_t, ike_state_change, bool,
break;
}
#endif /* ME */
case IKE_DESTROYING:
return listener_done(this);
default:
break;
}
}
return TRUE;
}
METHOD(listener_t, ike_state_change_terminate, bool,
interface_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
ike_sa_t *target;
this->lock->lock(this->lock);
target = this->ike_sa;
this->lock->unlock(this->lock);
if (target == ike_sa)
{
switch (state)
{
case IKE_DESTROYING:
if (ike_sa->get_state(ike_sa) == IKE_DELETING)
{ /* proper termination */
@ -304,10 +326,6 @@ METHOD(listener_t, child_state_change, bool,
case CHILD_DESTROYING:
switch (child_sa->get_state(child_sa))
{
case CHILD_DELETING:
/* proper delete */
this->status = SUCCESS;
break;
case CHILD_RETRYING:
/* retrying with a different DH group; survive another
* initiation round */
@ -331,6 +349,38 @@ METHOD(listener_t, child_state_change, bool,
return TRUE;
}
METHOD(listener_t, child_state_change_terminate, bool,
interface_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
child_sa_state_t state)
{
ike_sa_t *target;
this->lock->lock(this->lock);
target = this->ike_sa;
this->lock->unlock(this->lock);
if (target == ike_sa)
{
switch (state)
{
case CHILD_DESTROYING:
switch (child_sa->get_state(child_sa))
{
case CHILD_DELETING:
/* proper delete */
this->status = SUCCESS;
break;
default:
break;
}
return listener_done(this);
default:
break;
}
}
return TRUE;
}
METHOD(job_t, destroy_job, void,
interface_job_t *this)
{
@ -537,8 +587,8 @@ METHOD(controller_t, terminate_ike, status_t,
INIT(job,
.listener = {
.public = {
.ike_state_change = _ike_state_change,
.child_state_change = _child_state_change,
.ike_state_change = _ike_state_change_terminate,
.child_state_change = _child_state_change_terminate,
},
.logger = {
.public = {
@ -639,8 +689,8 @@ METHOD(controller_t, terminate_child, status_t,
INIT(job,
.listener = {
.public = {
.ike_state_change = _ike_state_change,
.child_state_change = _child_state_change,
.ike_state_change = _ike_state_change_terminate,
.child_state_change = _child_state_change_terminate,
},
.logger = {
.public = {