/**
* 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;
{
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);
}
/**
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;
*
* 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
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);
}
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);
}
{
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