summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/task_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/task_manager.c')
-rw-r--r--src/libcharon/sa/task_manager.c139
1 files changed, 73 insertions, 66 deletions
diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c
index eeda6c860..a68826440 100644
--- a/src/libcharon/sa/task_manager.c
+++ b/src/libcharon/sa/task_manager.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2010 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -195,10 +195,8 @@ static bool activate_task(private_task_manager_t *this, task_type_t type)
return found;
}
-/**
- * Implementation of task_manager_t.retransmit
- */
-static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
+METHOD(task_manager_t, retransmit, status_t,
+ private_task_manager_t *this, u_int32_t message_id)
{
if (message_id == this->initiating.mid)
{
@@ -281,11 +279,8 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
return SUCCESS;
}
-/**
- * build a request using the active task list
- * Implementation of task_manager_t.initiate
- */
-static status_t build_request(private_task_manager_t *this)
+METHOD(task_manager_t, initiate, status_t,
+ private_task_manager_t *this)
{
iterator_t *iterator;
task_t *task;
@@ -296,7 +291,8 @@ static status_t build_request(private_task_manager_t *this)
if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED)
{
- DBG2(DBG_IKE, "delaying task initiation, exchange in progress");
+ DBG2(DBG_IKE, "delaying task initiation, %N exchange in progress",
+ exchange_type_names, this->initiating.type);
/* do not initiate if we already have a message in the air */
return SUCCESS;
}
@@ -534,7 +530,7 @@ static status_t process_response(private_task_manager_t *this,
{ /* start all over again if we were reset */
this->reset = FALSE;
iterator->destroy(iterator);
- return build_request(this);
+ return initiate(this);
}
}
iterator->destroy(iterator);
@@ -544,7 +540,7 @@ static status_t process_response(private_task_manager_t *this,
this->initiating.packet->destroy(this->initiating.packet);
this->initiating.packet = NULL;
- return build_request(this);
+ return initiate(this);
}
/**
@@ -883,10 +879,8 @@ static status_t process_request(private_task_manager_t *this,
return build_response(this, message);
}
-/**
- * Implementation of task_manager_t.process_message
- */
-static status_t process_message(private_task_manager_t *this, message_t *msg)
+METHOD(task_manager_t, process_message, status_t,
+ private_task_manager_t *this, message_t *msg)
{
u_int32_t mid = msg->get_message_id(msg);
@@ -943,10 +937,8 @@ static status_t process_message(private_task_manager_t *this, message_t *msg)
return SUCCESS;
}
-/**
- * Implementation of task_manager_t.queue_task
- */
-static void queue_task(private_task_manager_t *this, task_t *task)
+METHOD(task_manager_t, queue_task, void,
+ 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 */
@@ -969,11 +961,10 @@ static void queue_task(private_task_manager_t *this, task_t *task)
this->queued_tasks->insert_last(this->queued_tasks, task);
}
-/**
- * Implementation of task_manager_t.adopt_tasks
- */
-static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *other)
+METHOD(task_manager_t, adopt_tasks, void,
+ private_task_manager_t *this, task_manager_t *other_public)
{
+ private_task_manager_t *other = (private_task_manager_t*)other_public;
task_t *task;
/* move queued tasks from other to this */
@@ -986,20 +977,16 @@ static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *ot
}
}
-/**
- * Implementation of task_manager_t.busy
- */
-static bool busy(private_task_manager_t *this)
+METHOD(task_manager_t, busy, bool,
+ private_task_manager_t *this)
{
return (this->active_tasks->get_count(this->active_tasks) > 0);
}
-/**
- * Implementation of task_manager_t.reset
- */
-static void reset(private_task_manager_t *this,
- u_int32_t initiate, u_int32_t respond)
+METHOD(task_manager_t, reset, void,
+ private_task_manager_t *this, u_int32_t initiate, u_int32_t respond)
{
+ enumerator_t *enumerator;
task_t *task;
/* reset message counters and retransmit packets */
@@ -1017,6 +1004,14 @@ static void reset(private_task_manager_t *this,
}
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
+ /* reset queued tasks */
+ enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
+ while (enumerator->enumerate(enumerator, &task))
+ {
+ task->migrate(task, this->ike_sa);
+ }
+ enumerator->destroy(enumerator);
+
/* reset active tasks */
while (this->active_tasks->remove_last(this->active_tasks,
(void**)&task) == SUCCESS)
@@ -1028,10 +1023,24 @@ static void reset(private_task_manager_t *this,
this->reset = TRUE;
}
-/**
- * Implementation of task_manager_t.destroy
- */
-static void destroy(private_task_manager_t *this)
+METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
+ private_task_manager_t *this, task_queue_t queue)
+{
+ switch (queue)
+ {
+ case TASK_QUEUE_ACTIVE:
+ return this->active_tasks->create_enumerator(this->active_tasks);
+ case TASK_QUEUE_PASSIVE:
+ return this->passive_tasks->create_enumerator(this->passive_tasks);
+ case TASK_QUEUE_QUEUED:
+ return this->queued_tasks->create_enumerator(this->queued_tasks);
+ default:
+ return enumerator_create_empty();
+ }
+}
+
+METHOD(task_manager_t, destroy, void,
+ private_task_manager_t *this)
{
flush(this);
@@ -1049,34 +1058,32 @@ static void destroy(private_task_manager_t *this)
*/
task_manager_t *task_manager_create(ike_sa_t *ike_sa)
{
- private_task_manager_t *this = malloc_thing(private_task_manager_t);
-
- this->public.process_message = (status_t(*)(task_manager_t*,message_t*))process_message;
- 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*,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;
-
- this->ike_sa = ike_sa;
- this->responding.packet = NULL;
- this->initiating.packet = NULL;
- this->responding.mid = 0;
- this->initiating.mid = 0;
- this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
- this->queued_tasks = linked_list_create();
- this->active_tasks = linked_list_create();
- this->passive_tasks = linked_list_create();
- this->reset = FALSE;
-
- this->retransmit_tries = lib->settings->get_int(lib->settings,
- "charon.retransmit_tries", RETRANSMIT_TRIES);
- this->retransmit_timeout = lib->settings->get_double(lib->settings,
- "charon.retransmit_timeout", RETRANSMIT_TIMEOUT);
- this->retransmit_base = lib->settings->get_double(lib->settings,
- "charon.retransmit_base", RETRANSMIT_BASE);
+ private_task_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .process_message = _process_message,
+ .queue_task = _queue_task,
+ .initiate = _initiate,
+ .retransmit = _retransmit,
+ .reset = _reset,
+ .adopt_tasks = _adopt_tasks,
+ .busy = _busy,
+ .create_task_enumerator = _create_task_enumerator,
+ .destroy = _destroy,
+ },
+ .ike_sa = ike_sa,
+ .initiating.type = EXCHANGE_TYPE_UNDEFINED,
+ .queued_tasks = linked_list_create(),
+ .active_tasks = linked_list_create(),
+ .passive_tasks = linked_list_create(),
+ .retransmit_tries = lib->settings->get_int(lib->settings,
+ "charon.retransmit_tries", RETRANSMIT_TRIES),
+ .retransmit_timeout = lib->settings->get_double(lib->settings,
+ "charon.retransmit_timeout", RETRANSMIT_TIMEOUT),
+ .retransmit_base = lib->settings->get_double(lib->settings,
+ "charon.retransmit_base", RETRANSMIT_BASE),
+ );
return &this->public;
}