ikev2: Add possibility to delay initiation of a queued task
Such a task is not initiated unless a certain time has passed. This allows delaying certain tasks but avoids problems if we'd do this via a scheduled job (e.g. if the IKE_SA is rekeyed in the meantime). If the IKE_SA is rekeyed the delay of such tasks is reset when the tasks are adopted i.e. they get executed immediately on the new IKE_SA. This hasn't been implemented for IKEv1 yet.
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015 Tobias Brunner
|
* Copyright (C) 2006-2016 Tobias Brunner
|
||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -2620,6 +2620,12 @@ METHOD(ike_sa_t, queue_task, void,
|
|||||||
this->task_manager->queue_task(this->task_manager, task);
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(ike_sa_t, queue_task_delayed, void,
|
||||||
|
private_ike_sa_t *this, task_t *task, uint32_t delay)
|
||||||
|
{
|
||||||
|
this->task_manager->queue_task_delayed(this->task_manager, task, delay);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_t, inherit_pre, void,
|
METHOD(ike_sa_t, inherit_pre, void,
|
||||||
private_ike_sa_t *this, ike_sa_t *other_public)
|
private_ike_sa_t *this, ike_sa_t *other_public)
|
||||||
{
|
{
|
||||||
@@ -2938,6 +2944,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
|||||||
.create_task_enumerator = _create_task_enumerator,
|
.create_task_enumerator = _create_task_enumerator,
|
||||||
.flush_queue = _flush_queue,
|
.flush_queue = _flush_queue,
|
||||||
.queue_task = _queue_task,
|
.queue_task = _queue_task,
|
||||||
|
.queue_task_delayed = _queue_task_delayed,
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
.act_as_mediation_server = _act_as_mediation_server,
|
.act_as_mediation_server = _act_as_mediation_server,
|
||||||
.get_server_reflexive_host = _get_server_reflexive_host,
|
.get_server_reflexive_host = _get_server_reflexive_host,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2015 Tobias Brunner
|
* Copyright (C) 2006-2016 Tobias Brunner
|
||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -1123,6 +1123,15 @@ struct ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
void (*queue_task)(ike_sa_t *this, task_t *task);
|
void (*queue_task)(ike_sa_t *this, task_t *task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a task in the manager, but delay its initiation for at least the
|
||||||
|
* given number of seconds.
|
||||||
|
*
|
||||||
|
* @param task task to queue
|
||||||
|
* @param delay minimum delay in s before initiating the task
|
||||||
|
*/
|
||||||
|
void (*queue_task_delayed)(ike_sa_t *this, task_t *task, uint32_t delay);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inherit required attributes to new SA before rekeying.
|
* Inherit required attributes to new SA before rekeying.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007-2016 Tobias Brunner
|
* Copyright (C) 2007-2016 Tobias Brunner
|
||||||
* Copyright (C) 2007-2011 Martin Willi
|
* Copyright (C) 2007-2011 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -1513,8 +1513,8 @@ static bool has_queued(private_task_manager_t *this, task_type_t type)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, queue_task, void,
|
METHOD(task_manager_t, queue_task_delayed, void,
|
||||||
private_task_manager_t *this, task_t *task)
|
private_task_manager_t *this, task_t *task, uint32_t delay)
|
||||||
{
|
{
|
||||||
task_type_t type = task->get_type(task);
|
task_type_t type = task->get_type(task);
|
||||||
|
|
||||||
@@ -1535,6 +1535,12 @@ METHOD(task_manager_t, queue_task, void,
|
|||||||
this->queued_tasks->insert_last(this->queued_tasks, task);
|
this->queued_tasks->insert_last(this->queued_tasks, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(task_manager_t, queue_task, void,
|
||||||
|
private_task_manager_t *this, task_t *task)
|
||||||
|
{
|
||||||
|
queue_task_delayed(this, task, 0);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, queue_ike, void,
|
METHOD(task_manager_t, queue_ike, void,
|
||||||
private_task_manager_t *this)
|
private_task_manager_t *this)
|
||||||
{
|
{
|
||||||
@@ -1975,6 +1981,7 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
|
|||||||
.task_manager = {
|
.task_manager = {
|
||||||
.process_message = _process_message,
|
.process_message = _process_message,
|
||||||
.queue_task = _queue_task,
|
.queue_task = _queue_task,
|
||||||
|
.queue_task_delayed = _queue_task_delayed,
|
||||||
.queue_ike = _queue_ike,
|
.queue_ike = _queue_ike,
|
||||||
.queue_ike_rekey = _queue_ike_rekey,
|
.queue_ike_rekey = _queue_ike_rekey,
|
||||||
.queue_ike_reauth = _queue_ike_reauth,
|
.queue_ike_reauth = _queue_ike_reauth,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007-2016 Tobias Brunner
|
* Copyright (C) 2007-2016 Tobias Brunner
|
||||||
* Copyright (C) 2007-2010 Martin Willi
|
* Copyright (C) 2007-2010 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -43,30 +43,14 @@
|
|||||||
#include <encoding/payloads/unknown_payload.h>
|
#include <encoding/payloads/unknown_payload.h>
|
||||||
#include <processing/jobs/retransmit_job.h>
|
#include <processing/jobs/retransmit_job.h>
|
||||||
#include <processing/jobs/delete_ike_sa_job.h>
|
#include <processing/jobs/delete_ike_sa_job.h>
|
||||||
|
#include <processing/jobs/initiate_tasks_job.h>
|
||||||
|
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
#include <sa/ikev2/tasks/ike_me.h>
|
#include <sa/ikev2/tasks/ike_me.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct exchange_t exchange_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exchange in the air, used do detect and handle retransmission
|
|
||||||
*/
|
|
||||||
struct exchange_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Message ID used for this transaction
|
|
||||||
*/
|
|
||||||
uint32_t mid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* generated packet for retransmission
|
|
||||||
*/
|
|
||||||
packet_t *packet;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct private_task_manager_t private_task_manager_t;
|
typedef struct private_task_manager_t private_task_manager_t;
|
||||||
|
typedef struct queued_task_t queued_task_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* private data of the task manager
|
* private data of the task manager
|
||||||
@@ -181,6 +165,22 @@ struct private_task_manager_t {
|
|||||||
bool make_before_break;
|
bool make_before_break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queued tasks
|
||||||
|
*/
|
||||||
|
struct queued_task_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queued task
|
||||||
|
*/
|
||||||
|
task_t *task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time before which the task is not to be initiated
|
||||||
|
*/
|
||||||
|
timeval_t time;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset retransmission packet list
|
* Reset retransmission packet list
|
||||||
*/
|
*/
|
||||||
@@ -216,6 +216,12 @@ METHOD(task_manager_t, flush_queue, void,
|
|||||||
}
|
}
|
||||||
while (array_remove(array, ARRAY_TAIL, &task))
|
while (array_remove(array, ARRAY_TAIL, &task))
|
||||||
{
|
{
|
||||||
|
if (queue == TASK_QUEUE_QUEUED)
|
||||||
|
{
|
||||||
|
queued_task_t *queued = (queued_task_t*)task;
|
||||||
|
task = queued->task;
|
||||||
|
free(queued);
|
||||||
|
}
|
||||||
task->destroy(task);
|
task->destroy(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,22 +235,28 @@ METHOD(task_manager_t, flush, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* move a task of a specific type from the queue to the active list
|
* Move a task of a specific type from the queue to the active list, if it is
|
||||||
|
* not delayed.
|
||||||
*/
|
*/
|
||||||
static bool activate_task(private_task_manager_t *this, task_type_t type)
|
static bool activate_task(private_task_manager_t *this, task_type_t type)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
task_t *task;
|
queued_task_t *queued;
|
||||||
|
timeval_t now;
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
|
|
||||||
|
time_monotonic(&now);
|
||||||
|
|
||||||
enumerator = array_create_enumerator(this->queued_tasks);
|
enumerator = array_create_enumerator(this->queued_tasks);
|
||||||
while (enumerator->enumerate(enumerator, (void**)&task))
|
while (enumerator->enumerate(enumerator, (void**)&queued))
|
||||||
{
|
{
|
||||||
if (task->get_type(task) == type)
|
if (queued->task->get_type(queued->task) == type &&
|
||||||
|
!timercmp(&now, &queued->time, <))
|
||||||
{
|
{
|
||||||
DBG2(DBG_IKE, " activating %N task", task_type_names, type);
|
DBG2(DBG_IKE, " activating %N task", task_type_names, type);
|
||||||
array_remove_at(this->queued_tasks, enumerator);
|
array_remove_at(this->queued_tasks, enumerator);
|
||||||
array_insert(this->active_tasks, ARRAY_TAIL, task);
|
array_insert(this->active_tasks, ARRAY_TAIL, queued->task);
|
||||||
|
free(queued);
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1524,18 +1536,19 @@ METHOD(task_manager_t, process_message, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, queue_task, void,
|
METHOD(task_manager_t, queue_task_delayed, void,
|
||||||
private_task_manager_t *this, task_t *task)
|
private_task_manager_t *this, task_t *task, uint32_t delay)
|
||||||
{
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
queued_task_t *queued;
|
||||||
|
timeval_t time;
|
||||||
|
|
||||||
if (task->get_type(task) == TASK_IKE_MOBIKE)
|
if (task->get_type(task) == TASK_IKE_MOBIKE)
|
||||||
{ /* there is no need to queue more than one mobike task */
|
{ /* there is no need to queue more than one mobike task */
|
||||||
enumerator_t *enumerator;
|
|
||||||
task_t *current;
|
|
||||||
|
|
||||||
enumerator = array_create_enumerator(this->queued_tasks);
|
enumerator = array_create_enumerator(this->queued_tasks);
|
||||||
while (enumerator->enumerate(enumerator, ¤t))
|
while (enumerator->enumerate(enumerator, &queued))
|
||||||
{
|
{
|
||||||
if (current->get_type(current) == TASK_IKE_MOBIKE)
|
if (queued->task->get_type(queued->task) == TASK_IKE_MOBIKE)
|
||||||
{
|
{
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
task->destroy(task);
|
task->destroy(task);
|
||||||
@@ -1544,8 +1557,35 @@ METHOD(task_manager_t, queue_task, void,
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
|
time_monotonic(&time);
|
||||||
array_insert(this->queued_tasks, ARRAY_TAIL, task);
|
if (delay)
|
||||||
|
{
|
||||||
|
job_t *job;
|
||||||
|
|
||||||
|
DBG2(DBG_IKE, "queueing %N task (delayed by %us)", task_type_names,
|
||||||
|
task->get_type(task), delay);
|
||||||
|
time.tv_sec += delay;
|
||||||
|
|
||||||
|
job = (job_t*)initiate_tasks_job_create(
|
||||||
|
this->ike_sa->get_id(this->ike_sa));
|
||||||
|
lib->scheduler->schedule_job_tv(lib->scheduler, job, time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG2(DBG_IKE, "queueing %N task", task_type_names,
|
||||||
|
task->get_type(task));
|
||||||
|
}
|
||||||
|
INIT(queued,
|
||||||
|
.task = task,
|
||||||
|
.time = time,
|
||||||
|
);
|
||||||
|
array_insert(this->queued_tasks, ARRAY_TAIL, queued);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_manager_t, queue_task, void,
|
||||||
|
private_task_manager_t *this, task_t *task)
|
||||||
|
{
|
||||||
|
queue_task_delayed(this, task, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1555,12 +1595,12 @@ static bool has_queued(private_task_manager_t *this, task_type_t type)
|
|||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
task_t *task;
|
queued_task_t *queued;
|
||||||
|
|
||||||
enumerator = array_create_enumerator(this->queued_tasks);
|
enumerator = array_create_enumerator(this->queued_tasks);
|
||||||
while (enumerator->enumerate(enumerator, &task))
|
while (enumerator->enumerate(enumerator, &queued))
|
||||||
{
|
{
|
||||||
if (task->get_type(task) == type)
|
if (queued->task->get_type(queued->task) == type)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -1639,7 +1679,7 @@ static void trigger_mbb_reauth(private_task_manager_t *this)
|
|||||||
child_cfg_t *cfg;
|
child_cfg_t *cfg;
|
||||||
ike_sa_t *new;
|
ike_sa_t *new;
|
||||||
host_t *host;
|
host_t *host;
|
||||||
task_t *task;
|
queued_task_t *queued;
|
||||||
|
|
||||||
new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
||||||
this->ike_sa->get_version(this->ike_sa), TRUE);
|
this->ike_sa->get_version(this->ike_sa), TRUE);
|
||||||
@@ -1670,13 +1710,14 @@ static void trigger_mbb_reauth(private_task_manager_t *this)
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
enumerator = array_create_enumerator(this->queued_tasks);
|
enumerator = array_create_enumerator(this->queued_tasks);
|
||||||
while (enumerator->enumerate(enumerator, &task))
|
while (enumerator->enumerate(enumerator, &queued))
|
||||||
{
|
{
|
||||||
if (task->get_type(task) == TASK_CHILD_CREATE)
|
if (queued->task->get_type(queued->task) == TASK_CHILD_CREATE)
|
||||||
{
|
{
|
||||||
task->migrate(task, new);
|
queued->task->migrate(queued->task, new);
|
||||||
new->queue_task(new, task);
|
new->queue_task(new, queued->task);
|
||||||
array_remove_at(this->queued_tasks, enumerator);
|
array_remove_at(this->queued_tasks, enumerator);
|
||||||
|
free(queued);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
@@ -1801,34 +1842,62 @@ METHOD(task_manager_t, adopt_tasks, void,
|
|||||||
private_task_manager_t *this, task_manager_t *other_public)
|
private_task_manager_t *this, task_manager_t *other_public)
|
||||||
{
|
{
|
||||||
private_task_manager_t *other = (private_task_manager_t*)other_public;
|
private_task_manager_t *other = (private_task_manager_t*)other_public;
|
||||||
task_t *task;
|
queued_task_t *queued;
|
||||||
|
timeval_t now;
|
||||||
|
|
||||||
|
time_monotonic(&now);
|
||||||
|
|
||||||
/* move queued tasks from other to this */
|
/* move queued tasks from other to this */
|
||||||
while (array_remove(other->queued_tasks, ARRAY_TAIL, &task))
|
while (array_remove(other->queued_tasks, ARRAY_TAIL, &queued))
|
||||||
{
|
{
|
||||||
DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
|
DBG2(DBG_IKE, "migrating %N task", task_type_names,
|
||||||
task->migrate(task, this->ike_sa);
|
queued->task->get_type(queued->task));
|
||||||
array_insert(this->queued_tasks, ARRAY_HEAD, task);
|
queued->task->migrate(queued->task, this->ike_sa);
|
||||||
|
/* don't delay tasks on the new IKE_SA */
|
||||||
|
queued->time = now;
|
||||||
|
array_insert(this->queued_tasks, ARRAY_HEAD, queued);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrates child-creating tasks from src to dst
|
* Migrates child-creating tasks from other to this
|
||||||
*/
|
*/
|
||||||
static void migrate_child_tasks(private_task_manager_t *this,
|
static void migrate_child_tasks(private_task_manager_t *this,
|
||||||
array_t *src, array_t *dst)
|
private_task_manager_t *other,
|
||||||
|
task_queue_t queue)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
array_t *array;
|
||||||
task_t *task;
|
task_t *task;
|
||||||
|
|
||||||
enumerator = array_create_enumerator(src);
|
switch (queue)
|
||||||
|
{
|
||||||
|
case TASK_QUEUE_ACTIVE:
|
||||||
|
array = other->active_tasks;
|
||||||
|
break;
|
||||||
|
case TASK_QUEUE_QUEUED:
|
||||||
|
array = other->queued_tasks;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enumerator = array_create_enumerator(array);
|
||||||
while (enumerator->enumerate(enumerator, &task))
|
while (enumerator->enumerate(enumerator, &task))
|
||||||
{
|
{
|
||||||
|
queued_task_t *queued = NULL;
|
||||||
|
|
||||||
|
if (queue == TASK_QUEUE_QUEUED)
|
||||||
|
{
|
||||||
|
queued = (queued_task_t*)task;
|
||||||
|
task = queued->task;
|
||||||
|
}
|
||||||
if (task->get_type(task) == TASK_CHILD_CREATE)
|
if (task->get_type(task) == TASK_CHILD_CREATE)
|
||||||
{
|
{
|
||||||
array_remove_at(src, enumerator);
|
array_remove_at(array, enumerator);
|
||||||
task->migrate(task, this->ike_sa);
|
task->migrate(task, this->ike_sa);
|
||||||
array_insert(dst, ARRAY_TAIL, task);
|
queue_task(this, task);
|
||||||
|
free(queued);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
@@ -1840,9 +1909,9 @@ METHOD(task_manager_t, adopt_child_tasks, void,
|
|||||||
private_task_manager_t *other = (private_task_manager_t*)other_public;
|
private_task_manager_t *other = (private_task_manager_t*)other_public;
|
||||||
|
|
||||||
/* move active child tasks from other to this */
|
/* move active child tasks from other to this */
|
||||||
migrate_child_tasks(this, other->active_tasks, this->queued_tasks);
|
migrate_child_tasks(this, other, TASK_QUEUE_ACTIVE);
|
||||||
/* do the same for queued tasks */
|
/* do the same for queued tasks */
|
||||||
migrate_child_tasks(this, other->queued_tasks, this->queued_tasks);
|
migrate_child_tasks(this, other, TASK_QUEUE_QUEUED);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, busy, bool,
|
METHOD(task_manager_t, busy, bool,
|
||||||
@@ -1855,7 +1924,9 @@ METHOD(task_manager_t, reset, void,
|
|||||||
private_task_manager_t *this, uint32_t initiate, uint32_t respond)
|
private_task_manager_t *this, uint32_t initiate, uint32_t respond)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
queued_task_t *queued;
|
||||||
task_t *task;
|
task_t *task;
|
||||||
|
timeval_t now;
|
||||||
|
|
||||||
/* reset message counters and retransmit packets */
|
/* reset message counters and retransmit packets */
|
||||||
clear_packets(this->responding.packets);
|
clear_packets(this->responding.packets);
|
||||||
@@ -1874,11 +1945,13 @@ METHOD(task_manager_t, reset, void,
|
|||||||
}
|
}
|
||||||
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
|
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
|
||||||
|
|
||||||
|
time_monotonic(&now);
|
||||||
/* reset queued tasks */
|
/* reset queued tasks */
|
||||||
enumerator = array_create_enumerator(this->queued_tasks);
|
enumerator = array_create_enumerator(this->queued_tasks);
|
||||||
while (enumerator->enumerate(enumerator, &task))
|
while (enumerator->enumerate(enumerator, &queued))
|
||||||
{
|
{
|
||||||
task->migrate(task, this->ike_sa);
|
queued->time = now;
|
||||||
|
queued->task->migrate(queued->task, this->ike_sa);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
@@ -1886,12 +1959,25 @@ METHOD(task_manager_t, reset, void,
|
|||||||
while (array_remove(this->active_tasks, ARRAY_TAIL, &task))
|
while (array_remove(this->active_tasks, ARRAY_TAIL, &task))
|
||||||
{
|
{
|
||||||
task->migrate(task, this->ike_sa);
|
task->migrate(task, this->ike_sa);
|
||||||
array_insert(this->queued_tasks, ARRAY_HEAD, task);
|
INIT(queued,
|
||||||
|
.task = task,
|
||||||
|
.time = now,
|
||||||
|
);
|
||||||
|
array_insert(this->queued_tasks, ARRAY_HEAD, queued);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->reset = TRUE;
|
this->reset = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter queued tasks
|
||||||
|
*/
|
||||||
|
static bool filter_queued(void *unused, queued_task_t **queued, task_t **task)
|
||||||
|
{
|
||||||
|
*task = (*queued)->task;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
|
METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
|
||||||
private_task_manager_t *this, task_queue_t queue)
|
private_task_manager_t *this, task_queue_t queue)
|
||||||
{
|
{
|
||||||
@@ -1902,7 +1988,9 @@ METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
|
|||||||
case TASK_QUEUE_PASSIVE:
|
case TASK_QUEUE_PASSIVE:
|
||||||
return array_create_enumerator(this->passive_tasks);
|
return array_create_enumerator(this->passive_tasks);
|
||||||
case TASK_QUEUE_QUEUED:
|
case TASK_QUEUE_QUEUED:
|
||||||
return array_create_enumerator(this->queued_tasks);
|
return enumerator_create_filter(
|
||||||
|
array_create_enumerator(this->queued_tasks),
|
||||||
|
(void*)filter_queued, NULL, NULL);
|
||||||
default:
|
default:
|
||||||
return enumerator_create_empty();
|
return enumerator_create_empty();
|
||||||
}
|
}
|
||||||
@@ -1938,6 +2026,7 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
|
|||||||
.task_manager = {
|
.task_manager = {
|
||||||
.process_message = _process_message,
|
.process_message = _process_message,
|
||||||
.queue_task = _queue_task,
|
.queue_task = _queue_task,
|
||||||
|
.queue_task_delayed = _queue_task_delayed,
|
||||||
.queue_ike = _queue_ike,
|
.queue_ike = _queue_ike,
|
||||||
.queue_ike_rekey = _queue_ike_rekey,
|
.queue_ike_rekey = _queue_ike_rekey,
|
||||||
.queue_ike_reauth = _queue_ike_reauth,
|
.queue_ike_reauth = _queue_ike_reauth,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2013-2016 Tobias Brunner
|
||||||
* Copyright (C) 2006 Martin Willi
|
* Copyright (C) 2006 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
@@ -122,7 +123,17 @@ struct task_manager_t {
|
|||||||
*
|
*
|
||||||
* @param task task to queue
|
* @param task task to queue
|
||||||
*/
|
*/
|
||||||
void (*queue_task) (task_manager_t *this, task_t *task);
|
void (*queue_task)(task_manager_t *this, task_t *task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a task in the manager, but delay its initiation for at least the
|
||||||
|
* given number of seconds.
|
||||||
|
*
|
||||||
|
* @param task task to queue
|
||||||
|
* @param delay minimum delay in s before initiating the task
|
||||||
|
*/
|
||||||
|
void (*queue_task_delayed)(task_manager_t *this, task_t *task,
|
||||||
|
uint32_t delay);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue IKE_SA establishing tasks.
|
* Queue IKE_SA establishing tasks.
|
||||||
|
|||||||
Reference in New Issue
Block a user