diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/sa/task_manager.c | 1 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_create.c | 6 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_create.h | 4 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_delete.c | 11 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_delete.h | 8 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_rekey.c | 26 |
6 files changed, 47 insertions, 9 deletions
diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index 8308c1425..3852d8f3b 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -463,7 +463,6 @@ static void handle_collisions(private_task_manager_t *this, task_t *task) } continue; case CHILD_REKEY: - /* TODO: check if it is the SAME child we are talking about! */ if (type == CHILD_REKEY || type == CHILD_DELETE) { child_rekey_t *rekey = (child_rekey_t*)active; diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c index 60172cf20..781d679f2 100644 --- a/src/charon/sa/tasks/child_create.c +++ b/src/charon/sa/tasks/child_create.c @@ -680,11 +680,7 @@ static void use_reqid(private_child_create_t *this, u_int32_t reqid) */ static child_sa_t* get_child(private_child_create_t *this) { - if (this->established) - { - return this->child_sa; - } - return NULL; + return this->child_sa; } /** diff --git a/src/charon/sa/tasks/child_create.h b/src/charon/sa/tasks/child_create.h index 7ff2fb22d..200d37457 100644 --- a/src/charon/sa/tasks/child_create.h +++ b/src/charon/sa/tasks/child_create.h @@ -68,9 +68,7 @@ struct child_create_t { chunk_t (*get_lower_nonce) (child_create_t *this); /** - * @brief Get the CHILD_SA established by this task. - * - * This call returns a child only when it has been established successfully. + * @brief Get the CHILD_SA established/establishing by this task. * * @param this calling object * @return child_sa diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c index 30270f27e..23d509de5 100644 --- a/src/charon/sa/tasks/child_delete.c +++ b/src/charon/sa/tasks/child_delete.c @@ -231,6 +231,16 @@ static task_type_t get_type(private_child_delete_t *this) } /** + * Implementation of child_delete_t.get_child + */ +static child_sa_t* get_child(private_child_delete_t *this) +{ + child_sa_t *child_sa = NULL; + this->child_sas->get_first(this->child_sas, (void**)&child_sa); + return child_sa; +} + +/** * Implementation of task_t.migrate */ static void migrate(private_child_delete_t *this, ike_sa_t *ike_sa) @@ -257,6 +267,7 @@ child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa) { private_child_delete_t *this = malloc_thing(private_child_delete_t); + this->public.get_child = (child_sa_t*(*)(child_delete_t*))get_child; this->public.task.get_type = (task_type_t(*)(task_t*))get_type; this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; this->public.task.destroy = (void(*)(task_t*))destroy; diff --git a/src/charon/sa/tasks/child_delete.h b/src/charon/sa/tasks/child_delete.h index 327a2ec15..a7e676a50 100644 --- a/src/charon/sa/tasks/child_delete.h +++ b/src/charon/sa/tasks/child_delete.h @@ -44,6 +44,14 @@ struct child_delete_t { * Implements the task_t interface */ task_t task; + + /** + * @brief Get the CHILD_SA to delete by this task. + * + * @param this calling object + * @return child_sa + */ + child_sa_t* (*get_child) (child_delete_t *this); }; /** diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c index 84d10be1f..745895dbb 100644 --- a/src/charon/sa/tasks/child_rekey.c +++ b/src/charon/sa/tasks/child_rekey.c @@ -26,6 +26,7 @@ #include <daemon.h> #include <encoding/payloads/notify_payload.h> #include <sa/tasks/child_create.h> +#include <sa/tasks/child_delete.h> #include <queues/jobs/rekey_child_sa_job.h> @@ -258,6 +259,31 @@ static task_type_t get_type(private_child_rekey_t *this) */ static void collide(private_child_rekey_t *this, task_t *other) { + /* the task manager only detects exchange collision, but not if + * the collision is for the same child. we check it here. */ + if (other->get_type(other) == CHILD_REKEY) + { + private_child_rekey_t *rekey = (private_child_rekey_t*)other; + if (rekey == NULL || rekey->child_sa != this->child_sa) + { + /* not the same child => no collision */ + return; + } + } + else if (other->get_type(other) == CHILD_DELETE) + { + child_delete_t *del = (child_delete_t*)other; + if (del == NULL || del->get_child(del) != this->child_sa) + { + /* not the same child => no collision */ + return; + } + } + else + { + /* any other task is not critical for collisisions, ignore */ + return; + } DESTROY_IF(this->collision); this->collision = other; } |