diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/sa/task_manager.c | 93 | ||||
-rw-r--r-- | src/charon/sa/task_manager.h | 14 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_mobike.c | 9 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_mobike.h | 8 |
4 files changed, 100 insertions, 24 deletions
diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index a8f662263..1b2c0f590 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -220,42 +220,70 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id) iterator_t *iterator; packet_t *packet; task_t *task; - - 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; - } + ike_mobike_t *mobike = NULL; - 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 */ + /* check if we are retransmitting a MOBIKE routability check */ iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE); while (iterator->iterate(iterator, (void*)&task)) { if (task->get_type(task) == IKE_MOBIKE) { - ike_mobike_t *mobike = (ike_mobike_t*)task; - mobike->transmit(mobike, packet); + mobike = (ike_mobike_t*)task; + if (!mobike->is_probing(mobike)) + { + mobike = NULL; + } break; } } 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); + + this->initiating.retransmitted++; job = (job_t*)retransmit_job_create(this->initiating.mid, this->ike_sa->get_id(this->ike_sa)); 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) { + 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)); this->queued_tasks->insert_last(this->queued_tasks, task); } diff --git a/src/charon/sa/task_manager.h b/src/charon/sa/task_manager.h index fb34aab6a..38c63c1a9 100644 --- a/src/charon/sa/task_manager.h +++ b/src/charon/sa/task_manager.h @@ -51,6 +51,20 @@ typedef struct task_manager_t task_manager_t; */ #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. diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c index a32f7e5e0..d1fc8c695 100644 --- a/src/charon/sa/tasks/ike_mobike.c +++ b/src/charon/sa/tasks/ike_mobike.c @@ -448,6 +448,14 @@ static void roam(private_ike_mobike_t *this, bool address) } /** + * 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 */ static task_type_t get_type(private_ike_mobike_t *this) @@ -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.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.migrate = (void(*)(task_t*,ike_sa_t*))migrate; this->public.task.destroy = (void(*)(task_t*))destroy; diff --git a/src/charon/sa/tasks/ike_mobike.h b/src/charon/sa/tasks/ike_mobike.h index cee9da047..bb5150723 100644 --- a/src/charon/sa/tasks/ike_mobike.h +++ b/src/charon/sa/tasks/ike_mobike.h @@ -71,6 +71,14 @@ struct ike_mobike_t { * @param packet the packet to transmit */ 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); }; /** |