aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/sa/task_manager_v1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/task_manager_v1.c')
-rw-r--r--src/libcharon/sa/task_manager_v1.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/src/libcharon/sa/task_manager_v1.c b/src/libcharon/sa/task_manager_v1.c
index 1764a8036..fbc8da7cc 100644
--- a/src/libcharon/sa/task_manager_v1.c
+++ b/src/libcharon/sa/task_manager_v1.c
@@ -131,6 +131,13 @@ struct private_task_manager_t {
* Base to calculate retransmission timeout
*/
double retransmit_base;
+
+ /**
+ * Flag to tell the task manager to initiate a transaction at
+ * a later time.
+ */
+ bool initiate_later_flag;
+
};
/**
@@ -149,12 +156,6 @@ static void flush(private_task_manager_t *this)
this->active_tasks = linked_list_create();
}
-METHOD(task_manager_t, retransmit, status_t,
- private_task_manager_t *this, u_int32_t message_id)
-{
- return FAILED;
-}
-
/**
* move a task of a specific type from the queue to the active list
*/
@@ -180,6 +181,49 @@ static bool activate_task(private_task_manager_t *this, task_type_t type)
return found;
}
+METHOD(task_manager_t, retransmit, status_t,
+ private_task_manager_t *this, u_int32_t message_id)
+{
+ if (message_id == this->initiating.mid)
+ {
+ u_int32_t timeout;
+ job_t *job;
+ enumerator_t *enumerator;
+ packet_t *packet;
+ task_t *task;
+
+ if (this->initiating.retransmitted <= this->retransmit_tries)
+ {
+ timeout = (u_int32_t)(this->retransmit_timeout * 1000.0 *
+ pow(this->retransmit_base, this->initiating.retransmitted));
+ }
+ else
+ {
+ DBG1(DBG_IKE, "giving up after %d retransmits",
+ this->initiating.retransmitted - 1);
+ if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
+ {
+ charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
+ }
+ 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);
+ 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));
+ lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
+ }
+ return SUCCESS;
+}
+
METHOD(task_manager_t, initiate, status_t,
private_task_manager_t *this)
{
@@ -220,6 +264,11 @@ METHOD(task_manager_t, initiate, status_t,
{
exchange = QUICK_MODE;
}
+
+ if (activate_task(this, TASK_XAUTH_REQUEST))
+ {
+ exchange = TRANSACTION;
+ }
break;
default:
break;