implemented more aggressive MOBIKE path probing
do not queue more than one MOBIKE task
This commit is contained in:
@@ -220,42 +220,70 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
|
|||||||
iterator_t *iterator;
|
iterator_t *iterator;
|
||||||
packet_t *packet;
|
packet_t *packet;
|
||||||
task_t *task;
|
task_t *task;
|
||||||
|
ike_mobike_t *mobike = NULL;
|
||||||
|
|
||||||
if (this->initiating.retransmitted <= RETRANSMIT_TRIES)
|
/* check if we are retransmitting a MOBIKE routability check */
|
||||||
{
|
|
||||||
timeout = (u_int32_t)(RETRANSMIT_TIMEOUT *
|
|
||||||
pow(RETRANSMIT_BASE, this->initiating.retransmitted));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "giving up after %d retransmits",
|
|
||||||
this->initiating.retransmitted - 1);
|
|
||||||
return DESTROY_ME;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->initiating.retransmitted)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
|
|
||||||
this->initiating.retransmitted, message_id);
|
|
||||||
}
|
|
||||||
this->initiating.retransmitted++;
|
|
||||||
|
|
||||||
packet = this->initiating.packet->clone(this->initiating.packet);
|
|
||||||
|
|
||||||
/* mobike needs to now when we retransmit, so we call it here */
|
|
||||||
iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
|
iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
|
||||||
while (iterator->iterate(iterator, (void*)&task))
|
while (iterator->iterate(iterator, (void*)&task))
|
||||||
{
|
{
|
||||||
if (task->get_type(task) == IKE_MOBIKE)
|
if (task->get_type(task) == IKE_MOBIKE)
|
||||||
{
|
{
|
||||||
ike_mobike_t *mobike = (ike_mobike_t*)task;
|
mobike = (ike_mobike_t*)task;
|
||||||
mobike->transmit(mobike, packet);
|
if (!mobike->is_probing(mobike))
|
||||||
|
{
|
||||||
|
mobike = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
if (mobike == NULL)
|
||||||
|
{
|
||||||
|
if (this->initiating.retransmitted <= RETRANSMIT_TRIES)
|
||||||
|
{
|
||||||
|
timeout = (u_int32_t)(RETRANSMIT_TIMEOUT *
|
||||||
|
pow(RETRANSMIT_BASE, this->initiating.retransmitted));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "giving up after %d retransmits",
|
||||||
|
this->initiating.retransmitted - 1);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->initiating.retransmitted)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "retransmit %d of request with message ID %d",
|
||||||
|
this->initiating.retransmitted, message_id);
|
||||||
|
}
|
||||||
|
packet = this->initiating.packet->clone(this->initiating.packet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* for routeability checks, we use a more aggressive behavior */
|
||||||
|
if (this->initiating.retransmitted <= ROUTEABILITY_CHECK_TRIES)
|
||||||
|
{
|
||||||
|
timeout = ROUTEABILITY_CHECK_INTERVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "giving up after %d path probings",
|
||||||
|
this->initiating.retransmitted - 1);
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->initiating.retransmitted)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "path probing attempt %d",
|
||||||
|
this->initiating.retransmitted);
|
||||||
|
}
|
||||||
|
packet = this->initiating.packet->clone(this->initiating.packet);
|
||||||
|
mobike->transmit(mobike, packet);
|
||||||
|
}
|
||||||
|
|
||||||
charon->sender->send(charon->sender, packet);
|
charon->sender->send(charon->sender, packet);
|
||||||
|
|
||||||
|
this->initiating.retransmitted++;
|
||||||
job = (job_t*)retransmit_job_create(this->initiating.mid,
|
job = (job_t*)retransmit_job_create(this->initiating.mid,
|
||||||
this->ike_sa->get_id(this->ike_sa));
|
this->ike_sa->get_id(this->ike_sa));
|
||||||
charon->scheduler->schedule_job(charon->scheduler, job, timeout);
|
charon->scheduler->schedule_job(charon->scheduler, job, timeout);
|
||||||
@@ -852,6 +880,23 @@ static status_t process_message(private_task_manager_t *this, message_t *msg)
|
|||||||
*/
|
*/
|
||||||
static void queue_task(private_task_manager_t *this, task_t *task)
|
static void queue_task(private_task_manager_t *this, task_t *task)
|
||||||
{
|
{
|
||||||
|
if (task->get_type(task) == IKE_MOBIKE)
|
||||||
|
{ /* there is no need to queue more than one mobike task */
|
||||||
|
iterator_t *iterator;
|
||||||
|
task_t *current;
|
||||||
|
|
||||||
|
iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
|
||||||
|
while (iterator->iterate(iterator, (void**)¤t))
|
||||||
|
{
|
||||||
|
if (current->get_type(current) == IKE_MOBIKE)
|
||||||
|
{
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
task->destroy(task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
}
|
||||||
DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
|
DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
|
||||||
this->queued_tasks->insert_last(this->queued_tasks, task);
|
this->queued_tasks->insert_last(this->queued_tasks, task);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,20 @@ typedef struct task_manager_t task_manager_t;
|
|||||||
*/
|
*/
|
||||||
#define RETRANSMIT_TRIES 5
|
#define RETRANSMIT_TRIES 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interval for mobike routability checks in ms.
|
||||||
|
*
|
||||||
|
* @ingroup sa
|
||||||
|
*/
|
||||||
|
#define ROUTEABILITY_CHECK_INTERVAL 2500
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of routability checks before giving up
|
||||||
|
*
|
||||||
|
* @ingroup sa
|
||||||
|
*/
|
||||||
|
#define ROUTEABILITY_CHECK_TRIES 10
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The task manager, juggles task and handles message exchanges.
|
* @brief The task manager, juggles task and handles message exchanges.
|
||||||
|
|||||||
@@ -447,6 +447,14 @@ static void roam(private_ike_mobike_t *this, bool address)
|
|||||||
this->ike_sa->get_pending_updates(this->ike_sa) + 1);
|
this->ike_sa->get_pending_updates(this->ike_sa) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ike_mobike_t.is_probing.
|
||||||
|
*/
|
||||||
|
static bool is_probing(private_ike_mobike_t *this)
|
||||||
|
{
|
||||||
|
return this->check;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of task_t.get_type
|
* Implementation of task_t.get_type
|
||||||
*/
|
*/
|
||||||
@@ -490,6 +498,7 @@ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
|
|||||||
|
|
||||||
this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
|
this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
|
||||||
this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit;
|
this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit;
|
||||||
|
this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing;
|
||||||
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
|
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.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
|
||||||
this->public.task.destroy = (void(*)(task_t*))destroy;
|
this->public.task.destroy = (void(*)(task_t*))destroy;
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ struct ike_mobike_t {
|
|||||||
* @param packet the packet to transmit
|
* @param packet the packet to transmit
|
||||||
*/
|
*/
|
||||||
void (*transmit)(ike_mobike_t *this, packet_t *packet);
|
void (*transmit)(ike_mobike_t *this, packet_t *packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if this task is probing for routability.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @return TRUE if task is probing
|
||||||
|
*/
|
||||||
|
bool (*is_probing)(ike_mobike_t *this);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user