diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/sa/ike_sa.c | 10 | ||||
-rw-r--r-- | src/charon/sa/ike_sa.h | 5 | ||||
-rw-r--r-- | src/charon/sa/task_manager.c | 2 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_rekey.c | 4 |
4 files changed, 16 insertions, 5 deletions
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index 70f6dec4f..e4e603e28 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -1609,7 +1609,7 @@ static void reestablish(private_ike_sa_t *this) /** * Implementation of ike_sa_t.inherit. */ -static void inherit(private_ike_sa_t *this, private_ike_sa_t *other) +static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other) { child_sa_t *child_sa; host_t *ip; @@ -1649,6 +1649,12 @@ static void inherit(private_ike_sa_t *this, private_ike_sa_t *other) { this->child_sas->insert_first(this->child_sas, (void*)child_sa); } + + /* move pending tasks to the new IKE_SA */ + this->task_manager->adopt_tasks(this->task_manager, other->task_manager); + + /* we have to initate here, there may be new tasks to handle */ + return this->task_manager->initiate(this->task_manager); } /** @@ -1989,7 +1995,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->public.is_natt_enabled = (bool(*)(ike_sa_t*)) is_natt_enabled; this->public.rekey = (status_t(*)(ike_sa_t*))rekey; this->public.reestablish = (void(*)(ike_sa_t*))reestablish; - this->public.inherit = (void(*)(ike_sa_t*,ike_sa_t*))inherit; + this->public.inherit = (status_t(*)(ike_sa_t*,ike_sa_t*))inherit; this->public.generate_message = (status_t(*)(ike_sa_t*,message_t*,packet_t**))generate_message; this->public.reset = (void(*)(ike_sa_t*))reset; this->public.get_unique_id = (u_int32_t(*)(ike_sa_t*))get_unique_id; diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h index 2ba9313ab..604ec94a9 100644 --- a/src/charon/sa/ike_sa.h +++ b/src/charon/sa/ike_sa.h @@ -613,10 +613,13 @@ struct ike_sa_t { * * When rekeying is completed, all CHILD_SAs, the virtual IP and all * outstanding tasks are moved from other to this. + * As this call may initiate inherited tasks, a status is returned. * * @param this calling object + * @param other other task to inherit from + * @return DESTROY_ME if initiation of inherited task failed */ - void (*inherit) (ike_sa_t *this, ike_sa_t *other); + status_t (*inherit) (ike_sa_t *this, ike_sa_t *other); /** * @brief Reset the IKE_SA, useable when initiating fails diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index 3852d8f3b..5bfc04840 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -761,6 +761,7 @@ static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *ot while (other->queued_tasks->remove_last(other->queued_tasks, (void**)&task) == SUCCESS) { + DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task)); task->migrate(task, this->ike_sa); this->queued_tasks->insert_first(this->queued_tasks, task); } @@ -769,6 +770,7 @@ static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *ot while (other->active_tasks->remove_last(other->active_tasks, (void**)&task) == SUCCESS) { + DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task)); task->migrate(task, this->ike_sa); this->queued_tasks->insert_first(this->queued_tasks, task); } diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c index 1ed542e7f..7a6b353ba 100644 --- a/src/charon/sa/tasks/ike_rekey.c +++ b/src/charon/sa/tasks/ike_rekey.c @@ -282,9 +282,9 @@ static void destroy(private_ike_rekey_t *this) { if (this->new_sa) { - if (this->new_sa->get_state(this->new_sa) == IKE_ESTABLISHED) + if (this->new_sa->get_state(this->new_sa) == IKE_ESTABLISHED && + this->new_sa->inherit(this->new_sa, this->ike_sa) != DESTROY_ME) { - this->new_sa->inherit(this->new_sa, this->ike_sa); charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa); } else |