child-rekey: Add method to check for the redundant SA created in a collision

This commit is contained in:
Tobias Brunner
2016-06-17 18:48:04 +02:00
parent f97bac5594
commit 4f1012b3e1
2 changed files with 37 additions and 18 deletions
+20 -14
View File
@@ -1,7 +1,8 @@
/*
* Copyright (C) 2009-2016 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -434,6 +435,18 @@ METHOD(task_t, get_type, task_type_t,
return TASK_CHILD_REKEY;
}
METHOD(child_rekey_t, is_redundant, bool,
private_child_rekey_t *this, child_sa_t *child)
{
if (this->collision &&
this->collision->get_type(this->collision) == TASK_CHILD_REKEY)
{
private_child_rekey_t *rekey = (private_child_rekey_t*)this->collision;
return child == rekey->child_create->get_child(rekey->child_create);
}
return FALSE;
}
METHOD(child_rekey_t, collide, void,
private_child_rekey_t *this, task_t *other)
{
@@ -452,19 +465,11 @@ METHOD(child_rekey_t, collide, void,
else if (other->get_type(other) == TASK_CHILD_DELETE)
{
child_delete_t *del = (child_delete_t*)other;
if (this->collision &&
this->collision->get_type(this->collision) == TASK_CHILD_REKEY)
if (is_redundant(this, del->get_child(del)))
{
private_child_rekey_t *rekey;
rekey = (private_child_rekey_t*)this->collision;
if (del->get_child(del) == rekey->child_create->get_child(rekey->child_create))
{
/* peer deletes redundant child created in collision */
this->other_child_destroyed = TRUE;
other->destroy(other);
return;
}
this->other_child_destroyed = TRUE;
other->destroy(other);
return;
}
if (del->get_child(del) != this->child_sa)
{
@@ -475,7 +480,7 @@ METHOD(child_rekey_t, collide, void,
}
else
{
/* any other task is not critical for collisisions, ignore */
/* any other task is not critical for collisions, ignore */
other->destroy(other);
return;
}
@@ -532,6 +537,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
.migrate = _migrate,
.destroy = _destroy,
},
.is_redundant = _is_redundant,
.collide = _collide,
},
.ike_sa = ike_sa,
+17 -4
View File
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2016 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -39,13 +40,25 @@ struct child_rekey_t {
task_t task;
/**
* Register a rekeying task which collides with this one
* Check if the given SA is the redundant CHILD_SA created during a rekey
* collision.
*
* This is called if the other peer deletes the redundant SA before we were
* able to handle the CREATE_CHILD_SA response.
*
* @param child CHILD_SA to check
* @return TRUE if the SA is the redundant CHILD_SA
*/
bool (*is_redundant)(child_rekey_t *this, child_sa_t *child);
/**
* 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 (adopted)
*/
void (*collide)(child_rekey_t* this, task_t *other);
};