diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index d8932dd03..35c2448ec 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -409,6 +409,21 @@ static void set_proposal(private_ike_sa_t *this, proposal_t *proposal) this->proposal = proposal->clone(proposal); } +/** + * Implementation of ike_sa_t.set_message_id + */ +static void set_message_id(private_ike_sa_t *this, bool initiate, u_int32_t mid) +{ + if (initiate) + { + this->task_manager->reset(this->task_manager, UINT_MAX, mid); + } + else + { + this->task_manager->reset(this->task_manager, mid, UINT_MAX); + } +} + /** * Implementation of ike_sa_t.send_keepalive */ @@ -708,7 +723,7 @@ static void reset(private_ike_sa_t *this) set_state(this, IKE_CREATED); - this->task_manager->reset(this->task_manager); + this->task_manager->reset(this->task_manager, 0, 0); } /** @@ -2308,6 +2323,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->public.set_my_host = (void (*)(ike_sa_t*,host_t*)) set_my_host; this->public.get_other_host = (host_t* (*)(ike_sa_t*)) get_other_host; this->public.set_other_host = (void (*)(ike_sa_t*,host_t*)) set_other_host; + this->public.set_message_id = (void(*)(ike_sa_t*, bool inbound, u_int32_t mid))set_message_id; this->public.update_hosts = (void(*)(ike_sa_t*, host_t *me, host_t *other))update_hosts; this->public.get_my_id = (identification_t* (*)(ike_sa_t*)) get_my_id; this->public.set_my_id = (void (*)(ike_sa_t*,identification_t*)) set_my_id; diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h index f7672f2d8..634e78a31 100644 --- a/src/charon/sa/ike_sa.h +++ b/src/charon/sa/ike_sa.h @@ -413,6 +413,17 @@ struct ike_sa_t { */ void (*set_proposal)(ike_sa_t *this, proposal_t *proposal); + /** + * Set the message id of the IKE_SA. + * + * The IKE_SA stores two message IDs, one for initiating exchanges (send) + * and one to respond to exchanges (expect). + * + * @param initiate TRUE to set message ID for initiating + * @param mid message id to set + */ + void (*set_message_id)(ike_sa_t *this, bool initiate, u_int32_t mid); + /** * Add an additional address for the peer. * diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index 4006a8cd5..2da74f764 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -950,7 +950,8 @@ static bool busy(private_task_manager_t *this) /** * Implementation of task_manager_t.reset */ -static void reset(private_task_manager_t *this) +static void reset(private_task_manager_t *this, + u_int32_t initiate, u_int32_t respond) { task_t *task; @@ -959,8 +960,14 @@ static void reset(private_task_manager_t *this) DESTROY_IF(this->initiating.packet); this->responding.packet = NULL; this->initiating.packet = NULL; - this->responding.mid = 0; - this->initiating.mid = 0; + if (initiate != UINT_MAX) + { + this->initiating.mid = initiate; + } + if (respond != UINT_MAX) + { + this->responding.mid = respond; + } this->initiating.type = EXCHANGE_TYPE_UNDEFINED; /* reset active tasks */ @@ -1001,7 +1008,7 @@ task_manager_t *task_manager_create(ike_sa_t *ike_sa) this->public.queue_task = (void(*)(task_manager_t*,task_t*))queue_task; this->public.initiate = (status_t(*)(task_manager_t*))build_request; this->public.retransmit = (status_t(*)(task_manager_t*,u_int32_t))retransmit; - this->public.reset = (void(*)(task_manager_t*))reset; + this->public.reset = (void(*)(task_manager_t*,u_int32_t,u_int32_t))reset; this->public.adopt_tasks = (void(*)(task_manager_t*,task_manager_t*))adopt_tasks; this->public.busy = (bool(*)(task_manager_t*))busy; this->public.destroy = (void(*)(task_manager_t*))destroy; diff --git a/src/charon/sa/task_manager.h b/src/charon/sa/task_manager.h index 07cd8f557..b35b44fa4 100644 --- a/src/charon/sa/task_manager.h +++ b/src/charon/sa/task_manager.h @@ -25,6 +25,8 @@ typedef struct task_manager_t task_manager_t; +#include + #include #include #include @@ -125,7 +127,7 @@ struct task_manager_t { * - SUCCESS if retransmission sent */ status_t (*retransmit) (task_manager_t *this, u_int32_t message_id); - + /** * Migrate all tasks from other to this. * @@ -143,10 +145,12 @@ struct task_manager_t { * reset to zero (INVALID_KE_PAYLOAD, COOKIES, ...). The reset() method * resets the message IDs and resets all active tasks using the migrate() * method. - * - * @param other manager which gives away its tasks + * Use a value of UINT_MAX to keep the current message ID. + * + * @param initiate message ID to initiate exchanges (send) + * @param respond message ID to respond to exchanges (expect) */ - void (*reset) (task_manager_t *this); + void (*reset) (task_manager_t *this, u_int32_t initiate, u_int32_t respond); /** * Check if we are currently waiting for a reply.