summaryrefslogtreecommitdiff
path: root/src/charon/queues
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/queues')
-rw-r--r--src/charon/queues/event_queue.c290
-rw-r--r--src/charon/queues/event_queue.h118
-rw-r--r--src/charon/queues/job_queue.c139
-rw-r--r--src/charon/queues/job_queue.h100
-rw-r--r--src/charon/queues/jobs/acquire_job.c98
-rw-r--r--src/charon/queues/jobs/acquire_job.h60
-rw-r--r--src/charon/queues/jobs/delete_child_sa_job.c113
-rw-r--r--src/charon/queues/jobs/delete_child_sa_job.h68
-rw-r--r--src/charon/queues/jobs/delete_ike_sa_job.c126
-rw-r--r--src/charon/queues/jobs/delete_ike_sa_job.h66
-rw-r--r--src/charon/queues/jobs/initiate_job.c112
-rw-r--r--src/charon/queues/jobs/initiate_job.h61
-rw-r--r--src/charon/queues/jobs/job.c39
-rw-r--r--src/charon/queues/jobs/job.h165
-rw-r--r--src/charon/queues/jobs/process_message_job.c106
-rw-r--r--src/charon/queues/jobs/process_message_job.h58
-rw-r--r--src/charon/queues/jobs/rekey_child_sa_job.c112
-rw-r--r--src/charon/queues/jobs/rekey_child_sa_job.h65
-rw-r--r--src/charon/queues/jobs/rekey_ike_sa_job.c120
-rw-r--r--src/charon/queues/jobs/rekey_ike_sa_job.h60
-rw-r--r--src/charon/queues/jobs/retransmit_job.c109
-rw-r--r--src/charon/queues/jobs/retransmit_job.h64
-rw-r--r--src/charon/queues/jobs/route_job.c125
-rw-r--r--src/charon/queues/jobs/route_job.h59
-rw-r--r--src/charon/queues/jobs/send_dpd_job.c110
-rw-r--r--src/charon/queues/jobs/send_dpd_job.h68
-rw-r--r--src/charon/queues/jobs/send_keepalive_job.c103
-rw-r--r--src/charon/queues/jobs/send_keepalive_job.h67
28 files changed, 2781 insertions, 0 deletions
diff --git a/src/charon/queues/event_queue.c b/src/charon/queues/event_queue.c
new file mode 100644
index 000000000..40bcb1ed8
--- /dev/null
+++ b/src/charon/queues/event_queue.c
@@ -0,0 +1,290 @@
+/**
+ * @file event_queue.c
+ *
+ * @brief Implementation of event_queue_t
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#include "event_queue.h"
+
+#include <library.h>
+#include <utils/linked_list.h>
+
+
+
+typedef struct event_t event_t;
+
+/**
+ * Event containing a job and a schedule time
+ */
+struct event_t {
+ /**
+ * Time to fire the event.
+ */
+ timeval_t time;
+
+ /**
+ * Every event has its assigned job.
+ */
+ job_t * job;
+};
+
+/**
+ * destroy an event and its job
+ */
+static void event_destroy(event_t *event)
+{
+ event->job->destroy(event->job);
+ free(event);
+}
+
+typedef struct private_event_queue_t private_event_queue_t;
+
+/**
+ * Private Variables and Functions of event_queue_t class.
+ */
+struct private_event_queue_t {
+ /**
+ * Public part.
+ */
+ event_queue_t public;
+
+ /**
+ * The events are stored in a linked list of type linked_list_t.
+ */
+ linked_list_t *list;
+
+ /**
+ * Access to linked_list is locked through this mutex.
+ */
+ pthread_mutex_t mutex;
+
+ /**
+ * If the queue is empty or an event has not to be fired
+ * a thread has to wait.
+ *
+ * This condvar is used to wake up such a thread.
+ */
+ pthread_cond_t condvar;
+};
+
+/**
+ * Returns the difference of to timeval structs in milliseconds
+ */
+static long time_difference(struct timeval *end_time, struct timeval *start_time)
+{
+ time_t s;
+ suseconds_t us;
+
+ s = (end_time->tv_sec - start_time->tv_sec);
+ us = (end_time->tv_usec - start_time->tv_usec);
+ return ((s * 1000) + us/1000);
+}
+
+/**
+ * Implements event_queue_t.get_count
+ */
+static int get_count(private_event_queue_t *this)
+{
+ int count;
+ pthread_mutex_lock(&(this->mutex));
+ count = this->list->get_count(this->list);
+ pthread_mutex_unlock(&(this->mutex));
+ return count;
+}
+
+/**
+ * Implements event_queue_t.get
+ */
+static job_t *get(private_event_queue_t *this)
+{
+ timespec_t timeout;
+ timeval_t current_time;
+ event_t * next_event;
+ job_t *job;
+ int oldstate;
+
+ pthread_mutex_lock(&(this->mutex));
+
+ while (TRUE)
+ {
+ while(this->list->get_count(this->list) == 0)
+ {
+ /* add mutex unlock handler for cancellation, enable cancellation */
+ pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+
+ pthread_cond_wait( &(this->condvar), &(this->mutex));
+
+ /* reset cancellation, remove mutex-unlock handler (without executing) */
+ pthread_setcancelstate(oldstate, NULL);
+ pthread_cleanup_pop(0);
+ }
+
+ this->list->get_first(this->list, (void **)&next_event);
+
+ gettimeofday(&current_time, NULL);
+ long difference = time_difference(&current_time,&(next_event->time));
+ if (difference <= 0)
+ {
+ timeout.tv_sec = next_event->time.tv_sec;
+ timeout.tv_nsec = next_event->time.tv_usec * 1000;
+
+ /* add mutex unlock handler for cancellation, enable cancellation */
+ pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+
+ pthread_cond_timedwait(&(this->condvar), &(this->mutex), &timeout);
+
+ /* reset cancellation, remove mutex-unlock handler (without executing) */
+ pthread_setcancelstate(oldstate, NULL);
+ pthread_cleanup_pop(0);
+ }
+ else
+ {
+ /* event available */
+ this->list->remove_first(this->list, (void **)&next_event);
+ job = next_event->job;
+ free(next_event);
+ break;
+ }
+ }
+ pthread_cond_signal( &(this->condvar));
+ pthread_mutex_unlock(&(this->mutex));
+
+ return job;
+}
+
+/**
+ * Implements function add_absolute of event_queue_t.
+ * See #event_queue_s.add_absolute for description.
+ */
+static void add_absolute(private_event_queue_t *this, job_t *job, timeval_t time)
+{
+ event_t *event;
+ event_t *current_event;
+ iterator_t *iterator;
+
+ /* create event */
+ event = malloc_thing(event_t);
+ event->time = time;
+ event->job = job;
+
+ pthread_mutex_lock(&(this->mutex));
+
+ /* while just used to break out */
+ while(TRUE)
+ {
+ if (this->list->get_count(this->list) == 0)
+ {
+ this->list->insert_first(this->list,event);
+ break;
+ }
+
+ /* check last entry */
+ this->list->get_last(this->list,(void **) &current_event);
+
+ if (time_difference(&(event->time), &(current_event->time)) >= 0)
+ {
+ /* my event has to be fired after the last event in list */
+ this->list->insert_last(this->list,event);
+ break;
+ }
+
+ /* check first entry */
+ this->list->get_first(this->list,(void **) &current_event);
+
+ if (time_difference(&(event->time), &(current_event->time)) < 0)
+ {
+ /* my event has to be fired before the first event in list */
+ this->list->insert_first(this->list,event);
+ break;
+ }
+
+ iterator = this->list->create_iterator(this->list,TRUE);
+ iterator->iterate(iterator, (void**)&current_event);
+ /* first element has not to be checked (already done) */
+ while(iterator->iterate(iterator, (void**)&current_event))
+ {
+ if (time_difference(&(event->time), &(current_event->time)) <= 0)
+ {
+ /* my event has to be fired before the current event in list */
+ iterator->insert_before(iterator,event);
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+ break;
+ }
+
+ pthread_cond_signal( &(this->condvar));
+ pthread_mutex_unlock(&(this->mutex));
+}
+
+/**
+ * Implements event_queue_t.add_relative.
+ */
+static void add_relative(event_queue_t *this, job_t *job, u_int32_t ms)
+{
+ timeval_t current_time;
+ timeval_t time;
+
+ time_t s = ms / 1000;
+ suseconds_t us = (ms - s * 1000) * 1000;
+
+ gettimeofday(&current_time, NULL);
+
+ time.tv_usec = (current_time.tv_usec + us) % 1000000;
+ time.tv_sec = current_time.tv_sec + (current_time.tv_usec + us)/1000000 + s;
+
+ this->add_absolute(this, job, time);
+}
+
+
+/**
+ * Implements event_queue_t.destroy.
+ */
+static void event_queue_destroy(private_event_queue_t *this)
+{
+ this->list->destroy_function(this->list, (void*)event_destroy);
+ free(this);
+}
+
+/*
+ * Documented in header
+ */
+event_queue_t *event_queue_create()
+{
+ private_event_queue_t *this = malloc_thing(private_event_queue_t);
+
+ this->public.get_count = (int (*) (event_queue_t *event_queue)) get_count;
+ this->public.get = (job_t *(*) (event_queue_t *event_queue)) get;
+ this->public.add_absolute = (void (*) (event_queue_t *event_queue, job_t *job, timeval_t time)) add_absolute;
+ this->public.add_relative = (void (*) (event_queue_t *event_queue, job_t *job, u_int32_t ms)) add_relative;
+ this->public.destroy = (void (*) (event_queue_t *event_queue)) event_queue_destroy;
+
+ this->list = linked_list_create();
+ pthread_mutex_init(&(this->mutex), NULL);
+ pthread_cond_init(&(this->condvar), NULL);
+
+ return (&this->public);
+}
diff --git a/src/charon/queues/event_queue.h b/src/charon/queues/event_queue.h
new file mode 100644
index 000000000..cd275123b
--- /dev/null
+++ b/src/charon/queues/event_queue.h
@@ -0,0 +1,118 @@
+/**
+ * @file event_queue.h
+ *
+ * @brief Interface of job_queue_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef EVENT_QUEUE_H_
+#define EVENT_QUEUE_H_
+
+typedef struct event_queue_t event_queue_t;
+
+#include <sys/time.h>
+
+#include <library.h>
+#include <queues/jobs/job.h>
+
+/**
+ * @brief Event-Queue used to store timed events.
+ *
+ * Added events are sorted. The get method blocks until
+ * the time is elapsed to process the next event. The get
+ * method is called from the scheduler_t thread, which
+ * will add the jobs to to job_queue_t for further processing.
+ *
+ * Although the event-queue is based on a linked_list_t
+ * all access functions are thread-save implemented.
+ *
+ * @b Constructors:
+ * - event_queue_create()
+ *
+ * @ingroup queues
+ */
+struct event_queue_t {
+
+ /**
+ * @brief Returns number of events in queue.
+ *
+ * @param event_queue calling object
+ * @return number of events in queue
+ */
+ int (*get_count) (event_queue_t *event_queue);
+
+ /**
+ * @brief Get the next job from the event-queue.
+ *
+ * If no event is pending, this function blocks until a job can be returned.
+ *
+ * @param event_queue calling object
+ * @param[out] job pointer to a job pointer where to job is returned to
+ * @return next job
+ */
+ job_t *(*get) (event_queue_t *event_queue);
+
+ /**
+ * @brief Adds a event to the queue, using a relative time.
+ *
+ * This function is non blocking and adds a job_t at a specific time to the list.
+ * The specific job object has to get destroyed by the thread which
+ * removes the job.
+ *
+ * @param event_queue calling object
+ * @param[in] job job to add to the queue (job is not copied)
+ * @param[in] time relative time, when the event has to get fired
+ */
+ void (*add_relative) (event_queue_t *event_queue, job_t *job, u_int32_t ms);
+
+ /**
+ * @brief Adds a event to the queue, using an absolute time.
+ *
+ * This function is non blocking and adds a job_t at a specific time to the list.
+ * The specific job object has to get destroyed by the thread which
+ * removes the job.
+ *
+ * @param event_queue calling object
+ * @param[in] job job to add to the queue (job is not copied)
+ * @param[in] time absolute time, when the event has to get fired
+ */
+ void (*add_absolute) (event_queue_t *event_queue, job_t *job, timeval_t time);
+
+ /**
+ * @brief Destroys a event_queue object.
+ *
+ * @warning The caller of this function has to make sure
+ * that no thread is going to add or get an event from the event_queue
+ * after calling this function.
+ *
+ * @param event_queue calling object
+ */
+ void (*destroy) (event_queue_t *event_queue);
+};
+
+/**
+ * @brief Creates an empty event_queue.
+ *
+ * @returns event_queue_t object
+ *
+ * @ingroup queues
+ */
+event_queue_t *event_queue_create(void);
+
+#endif /*EVENT_QUEUE_H_*/
diff --git a/src/charon/queues/job_queue.c b/src/charon/queues/job_queue.c
new file mode 100644
index 000000000..2310ca6ff
--- /dev/null
+++ b/src/charon/queues/job_queue.c
@@ -0,0 +1,139 @@
+/**
+ * @file job_queue.c
+ *
+ * @brief Implementation of job_queue_t
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "job_queue.h"
+
+#include <utils/linked_list.h>
+
+
+typedef struct private_job_queue_t private_job_queue_t;
+
+/**
+ * @brief Private Variables and Functions of job_queue class
+ *
+ */
+struct private_job_queue_t {
+
+ /**
+ * public members
+ */
+ job_queue_t public;
+
+ /**
+ * The jobs are stored in a linked list
+ */
+ linked_list_t *list;
+
+ /**
+ * access to linked_list is locked through this mutex
+ */
+ pthread_mutex_t mutex;
+
+ /**
+ * If the queue is empty a thread has to wait
+ * This condvar is used to wake up such a thread
+ */
+ pthread_cond_t condvar;
+};
+
+
+/**
+ * implements job_queue_t.get_count
+ */
+static int get_count(private_job_queue_t *this)
+{
+ int count;
+ pthread_mutex_lock(&(this->mutex));
+ count = this->list->get_count(this->list);
+ pthread_mutex_unlock(&(this->mutex));
+ return count;
+}
+
+/**
+ * implements job_queue_t.get
+ */
+static job_t *get(private_job_queue_t *this)
+{
+ int oldstate;
+ job_t *job;
+ pthread_mutex_lock(&(this->mutex));
+ /* go to wait while no jobs available */
+ while(this->list->get_count(this->list) == 0)
+ {
+ /* add mutex unlock handler for cancellation, enable cancellation */
+ pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+
+ pthread_cond_wait( &(this->condvar), &(this->mutex));
+
+ /* reset cancellation, remove mutex-unlock handler (without executing) */
+ pthread_setcancelstate(oldstate, NULL);
+ pthread_cleanup_pop(0);
+ }
+ this->list->remove_first(this->list, (void **)&job);
+ pthread_mutex_unlock(&(this->mutex));
+ return job;
+}
+
+/**
+ * implements function job_queue_t.add
+ */
+static void add(private_job_queue_t *this, job_t *job)
+{
+ pthread_mutex_lock(&(this->mutex));
+ this->list->insert_last(this->list,job);
+ pthread_cond_signal( &(this->condvar));
+ pthread_mutex_unlock(&(this->mutex));
+}
+
+/**
+ * implements job_queue_t.destroy
+ */
+static void job_queue_destroy (private_job_queue_t *this)
+{
+ this->list->destroy_offset(this->list, offsetof(job_t, destroy));
+ free(this);
+}
+
+/*
+ *
+ * Documented in header
+ */
+job_queue_t *job_queue_create(void)
+{
+ private_job_queue_t *this = malloc_thing(private_job_queue_t);
+
+ this->public.get_count = (int(*)(job_queue_t*))get_count;
+ this->public.get = (job_t*(*)(job_queue_t*))get;
+ this->public.add = (void(*)(job_queue_t*, job_t*))add;
+ this->public.destroy = (void(*)(job_queue_t*))job_queue_destroy;
+
+ this->list = linked_list_create();
+ pthread_mutex_init(&(this->mutex), NULL);
+ pthread_cond_init(&(this->condvar), NULL);
+
+ return (&this->public);
+}
diff --git a/src/charon/queues/job_queue.h b/src/charon/queues/job_queue.h
new file mode 100644
index 000000000..c971ba514
--- /dev/null
+++ b/src/charon/queues/job_queue.h
@@ -0,0 +1,100 @@
+/**
+ * @file job_queue.h
+ *
+ * @brief Interface of job_queue_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef JOB_QUEUE_H_
+#define JOB_QUEUE_H_
+
+typedef struct job_queue_t job_queue_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+
+/**
+ * @brief The job queue stores jobs, which will be processed by the thread_pool_t.
+ *
+ * Jobs are added from various sources, from the threads and
+ * from the event_queue_t.
+ * Although the job-queue is based on a linked_list_t
+ * all access functions are thread-save implemented.
+ *
+ * @b Constructors:
+ * - job_queue_create()
+ *
+ * @ingroup queues
+ */
+struct job_queue_t {
+
+ /**
+ * @brief Returns number of jobs in queue.
+ *
+ * @param job_queue_t calling object
+ * @returns number of items in queue
+ */
+ int (*get_count) (job_queue_t *job_queue);
+
+ /**
+ * @brief Get the next job from the queue.
+ *
+ * If the queue is empty, this function blocks until a job can be returned.
+ * After using, the returned job has to get destroyed by the caller.
+ *
+ * @param job_queue_t calling object
+ * @param[out] job pointer to a job pointer where to job is returned to
+ * @return next job
+ */
+ job_t *(*get) (job_queue_t *job_queue);
+
+ /**
+ * @brief Adds a job to the queue.
+ *
+ * This function is non blocking and adds a job_t to the list.
+ * The specific job object has to get destroyed by the thread which
+ * removes the job.
+ *
+ * @param job_queue_t calling object
+ * @param job job to add to the queue (job is not copied)
+ */
+ void (*add) (job_queue_t *job_queue, job_t *job);
+
+ /**
+ * @brief Destroys a job_queue object.
+ *
+ * @warning The caller of this function has to make sure
+ * that no thread is going to add or get a job from the job_queue
+ * after calling this function.
+ *
+ * @param job_queue_t calling object
+ */
+ void (*destroy) (job_queue_t *job_queue);
+};
+
+/**
+ * @brief Creates an empty job_queue.
+ *
+ * @return job_queue_t object
+ *
+ * @ingroup queues
+ */
+job_queue_t *job_queue_create(void);
+
+#endif /*JOB_QUEUE_H_*/
diff --git a/src/charon/queues/jobs/acquire_job.c b/src/charon/queues/jobs/acquire_job.c
new file mode 100644
index 000000000..b4ffb258d
--- /dev/null
+++ b/src/charon/queues/jobs/acquire_job.c
@@ -0,0 +1,98 @@
+/**
+ * @file acquire_job.c
+ *
+ * @brief Implementation of acquire_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "acquire_job.h"
+
+#include <daemon.h>
+
+
+typedef struct private_acquire_job_t private_acquire_job_t;
+
+/**
+ * Private data of an acquire_job_t object.
+ */
+struct private_acquire_job_t {
+ /**
+ * Public acquire_job_t interface.
+ */
+ acquire_job_t public;
+
+ /**
+ * reqid of the child to rekey
+ */
+ u_int32_t reqid;
+};
+
+/**
+ * Implementation of job_t.get_type.
+ */
+static job_type_t get_type(private_acquire_job_t *this)
+{
+ return ACQUIRE;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_acquire_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
+ this->reqid, TRUE);
+ if (ike_sa == NULL)
+ {
+ DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for acquiring",
+ this->reqid);
+ return DESTROY_ME;
+ }
+ ike_sa->acquire(ike_sa, this->reqid);
+
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+}
+
+/**
+ * Implementation of job_t.destroy.
+ */
+static void destroy(private_acquire_job_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+acquire_job_t *acquire_job_create(u_int32_t reqid)
+{
+ private_acquire_job_t *this = malloc_thing(private_acquire_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
+
+ /* private variables */
+ this->reqid = reqid;
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/acquire_job.h b/src/charon/queues/jobs/acquire_job.h
new file mode 100644
index 000000000..54f1b9b5b
--- /dev/null
+++ b/src/charon/queues/jobs/acquire_job.h
@@ -0,0 +1,60 @@
+/**
+ * @file acquire_job.h
+ *
+ * @brief Interface of acquire_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef ACQUIRE_JOB_H_
+#define ACQUIRE_JOB_H_
+
+typedef struct acquire_job_t acquire_job_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+
+/**
+ * @brief Class representing an ACQUIRE Job.
+ *
+ * This job initiates a CHILD SA on kernel request.
+ *
+ * @b Constructors:
+ * - acquire_job_create()
+ *
+ * @ingroup jobs
+ */
+struct acquire_job_t {
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type ACQUIRE.
+ *
+ * We use the reqid to find the routed CHILD_SA.
+ *
+ * @param reqid reqid of the CHILD_SA to acquire
+ * @return acquire_job_t object
+ *
+ * @ingroup jobs
+ */
+acquire_job_t *acquire_job_create(u_int32_t reqid);
+
+#endif /* REKEY_CHILD_SA_JOB_H_ */
diff --git a/src/charon/queues/jobs/delete_child_sa_job.c b/src/charon/queues/jobs/delete_child_sa_job.c
new file mode 100644
index 000000000..f694696b0
--- /dev/null
+++ b/src/charon/queues/jobs/delete_child_sa_job.c
@@ -0,0 +1,113 @@
+/**
+ * @file delete_child_sa_job.c
+ *
+ * @brief Implementation of delete_child_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "delete_child_sa_job.h"
+
+#include <daemon.h>
+
+
+typedef struct private_delete_child_sa_job_t private_delete_child_sa_job_t;
+
+/**
+ * Private data of an delete_child_sa_job_t object.
+ */
+struct private_delete_child_sa_job_t {
+ /**
+
+ * Public delete_child_sa_job_t interface.
+ */
+ delete_child_sa_job_t public;
+
+ /**
+ * reqid of the CHILD_SA
+ */
+ u_int32_t reqid;
+
+ /**
+ * protocol of the CHILD_SA (ESP/AH)
+ */
+ protocol_id_t protocol;
+
+ /**
+ * inbound SPI of the CHILD_SA
+ */
+ u_int32_t spi;
+};
+
+/**
+ * Implementation of job_t.get_type.
+ */
+static job_type_t get_type(private_delete_child_sa_job_t *this)
+{
+ return DELETE_CHILD_SA;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_delete_child_sa_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
+ this->reqid, TRUE);
+ if (ike_sa == NULL)
+ {
+ DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for delete",
+ this->reqid);
+ return DESTROY_ME;
+ }
+ ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi);
+
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+}
+
+/**
+ * Implementation of job_t.destroy.
+ */
+static void destroy(private_delete_child_sa_job_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
+ protocol_id_t protocol,
+ u_int32_t spi)
+{
+ private_delete_child_sa_job_t *this = malloc_thing(private_delete_child_sa_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
+
+ /* private variables */
+ this->reqid = reqid;
+ this->protocol = protocol;
+ this->spi = spi;
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/delete_child_sa_job.h b/src/charon/queues/jobs/delete_child_sa_job.h
new file mode 100644
index 000000000..9c2e4fa4d
--- /dev/null
+++ b/src/charon/queues/jobs/delete_child_sa_job.h
@@ -0,0 +1,68 @@
+/**
+ * @file delete_child_sa_job.h
+ *
+ * @brief Interface of delete_child_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef DELETE_CHILD_SA_JOB_H_
+#define DELETE_CHILD_SA_JOB_H_
+
+typedef struct delete_child_sa_job_t delete_child_sa_job_t;
+
+#include <library.h>
+#include <sa/ike_sa_id.h>
+#include <queues/jobs/job.h>
+#include <config/proposal.h>
+
+
+/**
+ * @brief Class representing an DELETE_CHILD_SA Job.
+ *
+ * This job initiates the delete of a CHILD SA.
+ *
+ * @b Constructors:
+ * - delete_child_sa_job_create()
+ *
+ * @ingroup jobs
+ */
+struct delete_child_sa_job_t {
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type DELETE_CHILD_SA.
+ *
+ * The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its
+ * inbound SPI.
+ *
+ * @param reqid reqid of the CHILD_SA, as used in kernel
+ * @param protocol protocol of the CHILD_SA
+ * @param spi security parameter index of the CHILD_SA
+ * @return delete_child_sa_job_t object
+ *
+ * @ingroup jobs
+ */
+delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
+ protocol_id_t protocol,
+ u_int32_t spi);
+
+#endif /* DELETE_CHILD_SA_JOB_H_ */
diff --git a/src/charon/queues/jobs/delete_ike_sa_job.c b/src/charon/queues/jobs/delete_ike_sa_job.c
new file mode 100644
index 000000000..706155aa6
--- /dev/null
+++ b/src/charon/queues/jobs/delete_ike_sa_job.c
@@ -0,0 +1,126 @@
+/**
+ * @file delete_ike_sa_job.c
+ *
+ * @brief Implementation of delete_ike_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "delete_ike_sa_job.h"
+
+#include <daemon.h>
+
+typedef struct private_delete_ike_sa_job_t private_delete_ike_sa_job_t;
+
+/**
+ * Private data of an delete_ike_sa_job_t Object
+ */
+struct private_delete_ike_sa_job_t {
+ /**
+ * public delete_ike_sa_job_t interface
+ */
+ delete_ike_sa_job_t public;
+
+ /**
+ * ID of the ike_sa to delete
+ */
+ ike_sa_id_t *ike_sa_id;
+
+ /**
+ * Should the IKE_SA be deleted if it is in ESTABLISHED state?
+ */
+ bool delete_if_established;
+};
+
+/**
+ * Implements job_t.get_type.
+ */
+static job_type_t get_type(private_delete_ike_sa_job_t *this)
+{
+ return DELETE_IKE_SA;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_delete_ike_sa_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa)
+ {
+ if (this->delete_if_established)
+ {
+ if (ike_sa->delete(ike_sa) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ else
+ {
+ /* destroy only if not ESTABLISHED */
+ if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ DBG1(DBG_JOB, "deleting half open IKE_SA after timeout");
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ }
+ }
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_delete_ike_sa_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id,
+ bool delete_if_established)
+{
+ private_delete_ike_sa_job_t *this = malloc_thing(private_delete_ike_sa_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*)(job_t *)) destroy;;
+
+ /* private variables */
+ this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
+ this->delete_if_established = delete_if_established;
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/delete_ike_sa_job.h b/src/charon/queues/jobs/delete_ike_sa_job.h
new file mode 100644
index 000000000..43701a354
--- /dev/null
+++ b/src/charon/queues/jobs/delete_ike_sa_job.h
@@ -0,0 +1,66 @@
+/**
+ * @file delete_ike_sa_job.h
+ *
+ * @brief Interface of delete_ike_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef DELETE_IKE_SA_JOB_H_
+#define DELETE_IKE_SA_JOB_H_
+
+typedef struct delete_ike_sa_job_t delete_ike_sa_job_t;
+
+#include <library.h>
+#include <sa/ike_sa_id.h>
+#include <queues/jobs/job.h>
+
+
+/**
+ * @brief Class representing an DELETE_IKE_SA Job.
+ *
+ * This job is responsible for deleting established or half open IKE_SAs.
+ * A half open IKE_SA is every IKE_SA which hasn't reache the SA_ESTABLISHED
+ * state.
+ *
+ * @b Constructors:
+ * - delete_ike_sa_job_create()
+ *
+ * @ingroup jobs
+ */
+struct delete_ike_sa_job_t {
+
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type DELETE_IKE_SA.
+ *
+ * @param ike_sa_id id of the IKE_SA to delete
+ * @param delete_if_established should the IKE_SA be deleted if it is established?
+ * @return created delete_ike_sa_job_t object
+ *
+ * @ingroup jobs
+ */
+delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id,
+ bool delete_if_established);
+
+#endif /* DELETE_IKE_SA_JOB_H_ */
diff --git a/src/charon/queues/jobs/initiate_job.c b/src/charon/queues/jobs/initiate_job.c
new file mode 100644
index 000000000..af50663d6
--- /dev/null
+++ b/src/charon/queues/jobs/initiate_job.c
@@ -0,0 +1,112 @@
+/**
+ * @file initiate_job.c
+ *
+ * @brief Implementation of initiate_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include <stdlib.h>
+
+#include "initiate_job.h"
+
+#include <daemon.h>
+
+typedef struct private_initiate_job_t private_initiate_job_t;
+
+/**
+ * Private data of an initiate_job_t Object
+ */
+struct private_initiate_job_t {
+ /**
+ * public initiate_job_t interface
+ */
+ initiate_job_t public;
+
+ /**
+ * associated connection to initiate
+ */
+ connection_t *connection;
+
+ /**
+ * associated policy to initiate
+ */
+ policy_t *policy;
+};
+
+/**
+ * Implements initiate_job_t.get_type.
+ */
+static job_type_t get_type(private_initiate_job_t *this)
+{
+ return INITIATE;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_initiate_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
+ this->connection->get_my_host(this->connection),
+ this->connection->get_other_host(this->connection),
+ this->policy->get_my_id(this->policy),
+ this->policy->get_other_id(this->policy));
+
+ if (ike_sa->initiate(ike_sa, this->connection, this->policy) != SUCCESS)
+ {
+ DBG1(DBG_JOB, "initiation failed, going to delete IKE_SA");
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+ }
+
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_initiate_job_t *this)
+{
+ this->connection->destroy(this->connection);
+ this->policy->destroy(this->policy);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy)
+{
+ private_initiate_job_t *this = malloc_thing(private_initiate_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
+
+ /* private variables */
+ this->connection = connection;
+ this->policy = policy;
+
+ return &this->public;
+}
diff --git a/src/charon/queues/jobs/initiate_job.h b/src/charon/queues/jobs/initiate_job.h
new file mode 100644
index 000000000..af1dd9ece
--- /dev/null
+++ b/src/charon/queues/jobs/initiate_job.h
@@ -0,0 +1,61 @@
+/**
+ * @file initiate_job.h
+ *
+ * @brief Interface of initiate_job_t.
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef INITIATE_IKE_SA_JOB_H_
+#define INITIATE_IKE_SA_JOB_H_
+
+typedef struct initiate_job_t initiate_job_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+#include <config/connections/connection.h>
+#include <config/policies/policy.h>
+
+/**
+ * @brief Class representing an INITIATE_IKE_SA Job.
+ *
+ * This job is created if an IKE_SA should be iniated.
+ *
+ * @b Constructors:
+ * - initiate_job_create()
+ *
+ * @ingroup jobs
+ */
+struct initiate_job_t {
+ /**
+ * implements job_t interface
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type INITIATE_IKE_SA.
+ *
+ * @param connection connection_t to initialize
+ * @param policy policy to set up
+ * @return initiate_job_t object
+ *
+ * @ingroup jobs
+ */
+initiate_job_t *initiate_job_create(connection_t *connection, policy_t *policy);
+
+#endif /*INITIATE_IKE_SA_JOB_H_*/
diff --git a/src/charon/queues/jobs/job.c b/src/charon/queues/jobs/job.c
new file mode 100644
index 000000000..d32d1bc61
--- /dev/null
+++ b/src/charon/queues/jobs/job.c
@@ -0,0 +1,39 @@
+/**
+ * @file job.c
+ *
+ * @brief Interface additions to job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include "job.h"
+
+ENUM(job_type_names, PROCESS_MESSAGE, SEND_DPD,
+ "PROCESS_MESSAGE",
+ "RETRANSMIT",
+ "INITIATE",
+ "ROUTE",
+ "ACQUIRE",
+ "DELETE_IKE_SA",
+ "DELETE_CHILD_SA",
+ "REKEY_CHILD_SA",
+ "REKEY_IKE_SA",
+ "SEND_KEEPALIVE",
+ "SEND_DPD",
+);
diff --git a/src/charon/queues/jobs/job.h b/src/charon/queues/jobs/job.h
new file mode 100644
index 000000000..28632672d
--- /dev/null
+++ b/src/charon/queues/jobs/job.h
@@ -0,0 +1,165 @@
+/**
+ * @file job.h
+ *
+ * @brief Interface job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef JOB_H_
+#define JOB_H_
+
+typedef enum job_type_t job_type_t;
+typedef struct job_t job_t;
+
+#include <library.h>
+
+/**
+ * @brief Definition of the various job types.
+ *
+ * @ingroup jobs
+ */
+enum job_type_t {
+ /**
+ * Process an incoming IKEv2-Message.
+ *
+ * Job is implemented in class process_message_job_t
+ */
+ PROCESS_MESSAGE,
+
+ /**
+ * Retransmit an IKEv2-Message.
+ *
+ * Job is implemented in class retransmit_job_t
+ */
+ RETRANSMIT,
+
+ /**
+ * Set up a CHILD_SA, optional with an IKE_SA.
+ *
+ * Job is implemented in class initiate_job_t
+ */
+ INITIATE,
+
+ /**
+ * Install SPD entries.
+ *
+ * Job is implemented in class route_job_t
+ */
+ ROUTE,
+
+ /**
+ * React on a acquire message from the kernel (e.g. setup CHILD_SA)
+ *
+ * Job is implemented in class acquire_job_t
+ */
+ ACQUIRE,
+
+ /**
+ * Delete an IKE_SA.
+ *
+ * Job is implemented in class delete_ike_sa_job_t
+ */
+ DELETE_IKE_SA,
+
+ /**
+ * Delete a CHILD_SA.
+ *
+ * Job is implemented in class delete_child_sa_job_t
+ */
+ DELETE_CHILD_SA,
+
+ /**
+ * Rekey a CHILD_SA.
+ *
+ * Job is implemented in class rekey_child_sa_job_t
+ */
+ REKEY_CHILD_SA,
+
+ /**
+ * Rekey an IKE_SA.
+ *
+ * Job is implemented in class rekey_ike_sa_job_t
+ */
+ REKEY_IKE_SA,
+
+ /**
+ * Send a keepalive packet.
+ *
+ * Job is implemented in class type send_keepalive_job_t
+ */
+ SEND_KEEPALIVE,
+
+ /**
+ * Send a DPD packet.
+ *
+ * Job is implemented in class type send_dpd_job_t
+ */
+ SEND_DPD
+};
+
+/**
+ * enum name for job_type_t
+ *
+ * @ingroup jobs
+ */
+extern enum_name_t *job_type_names;
+
+
+/**
+ * @brief Job-Interface as it is stored in the job queue.
+ *
+ * A job consists of a job-type and one or more assigned values.
+ *
+ * @b Constructors:
+ * - None, use specific implementation of the interface.
+ *
+ * @ingroup jobs
+ */
+struct job_t {
+
+ /**
+ * @brief get type of job.
+ *
+ * @param this calling object
+ * @return type of this job
+ */
+ job_type_t (*get_type) (job_t *this);
+
+ /**
+ * @brief Execute a job.
+ *
+ * Call the internall job routine to process the
+ * job. If this method returns DESTROY_ME, the job
+ * must be destroyed by the caller.
+ *
+ * @param this calling object
+ * @return status of job execution
+ */
+ status_t (*execute) (job_t *this);
+
+ /**
+ * @brief Destroys a job_t object
+ *
+ * @param job_t calling object
+ */
+ void (*destroy) (job_t *job);
+};
+
+
+#endif /* JOB_H_ */
diff --git a/src/charon/queues/jobs/process_message_job.c b/src/charon/queues/jobs/process_message_job.c
new file mode 100644
index 000000000..ee7484bbd
--- /dev/null
+++ b/src/charon/queues/jobs/process_message_job.c
@@ -0,0 +1,106 @@
+/**
+ * @file process_message_job.h
+ *
+ * @brief Implementation of process_message_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include "process_message_job.h"
+
+#include <daemon.h>
+
+typedef struct private_process_message_job_t private_process_message_job_t;
+
+/**
+ * Private data of an process_message_job_t Object
+ */
+struct private_process_message_job_t {
+ /**
+ * public process_message_job_t interface
+ */
+ process_message_job_t public;
+
+ /**
+ * Message associated with this job
+ */
+ message_t *message;
+};
+
+/**
+ * Implements job_t.get_type.
+ */
+static job_type_t get_type(private_process_message_job_t *this)
+{
+ return PROCESS_MESSAGE;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_process_message_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout_by_message(charon->ike_sa_manager,
+ this->message);
+ if (ike_sa)
+ {
+ DBG1(DBG_NET, "received packet: from %#H to %#H",
+ this->message->get_source(this->message),
+ this->message->get_destination(this->message));
+ if (ike_sa->process_message(ike_sa, this->message) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_process_message_job_t *this)
+{
+ this->message->destroy(this->message);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+process_message_job_t *process_message_job_create(message_t *message)
+{
+ private_process_message_job_t *this = malloc_thing(private_process_message_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void(*)(job_t*))destroy;
+
+ /* private variables */
+ this->message = message;
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/process_message_job.h b/src/charon/queues/jobs/process_message_job.h
new file mode 100644
index 000000000..2e60a298c
--- /dev/null
+++ b/src/charon/queues/jobs/process_message_job.h
@@ -0,0 +1,58 @@
+/**
+ * @file process_message_job.h
+ *
+ * @brief Interface of process_message_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef PROCESS_MESSAGE_JOB_H_
+#define PROCESS_MESSAGE_JOB_H_
+
+typedef struct process_message_job_t process_message_job_t;
+
+#include <library.h>
+#include <encoding/message.h>
+#include <queues/jobs/job.h>
+
+/**
+ * @brief Class representing an PROCESS_MESSAGE job.
+ *
+ * @b Constructors:
+ * - process_message_job_create()
+ *
+ * @ingroup jobs
+ */
+struct process_message_job_t {
+ /**
+ * implements job_t interface
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type PROCESS_MESSAGE.
+ *
+ * @param message message to process
+ * @return created process_message_job_t object
+ *
+ * @ingroup jobs
+ */
+process_message_job_t *process_message_job_create(message_t *message);
+
+#endif /*PROCESS_MESSAGE_JOB_H_*/
diff --git a/src/charon/queues/jobs/rekey_child_sa_job.c b/src/charon/queues/jobs/rekey_child_sa_job.c
new file mode 100644
index 000000000..3422b614d
--- /dev/null
+++ b/src/charon/queues/jobs/rekey_child_sa_job.c
@@ -0,0 +1,112 @@
+/**
+ * @file rekey_child_sa_job.c
+ *
+ * @brief Implementation of rekey_child_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "rekey_child_sa_job.h"
+
+#include <daemon.h>
+
+
+typedef struct private_rekey_child_sa_job_t private_rekey_child_sa_job_t;
+
+/**
+ * Private data of an rekey_child_sa_job_t object.
+ */
+struct private_rekey_child_sa_job_t {
+ /**
+ * Public rekey_child_sa_job_t interface.
+ */
+ rekey_child_sa_job_t public;
+
+ /**
+ * reqid of the child to rekey
+ */
+ u_int32_t reqid;
+
+ /**
+ * protocol of the CHILD_SA (ESP/AH)
+ */
+ protocol_id_t protocol;
+
+ /**
+ * inbound SPI of the CHILD_SA
+ */
+ u_int32_t spi;
+};
+
+/**
+ * Implementation of job_t.get_type.
+ */
+static job_type_t get_type(private_rekey_child_sa_job_t *this)
+{
+ return REKEY_CHILD_SA;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_rekey_child_sa_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
+ this->reqid, TRUE);
+ if (ike_sa == NULL)
+ {
+ DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
+ this->reqid);
+ return DESTROY_ME;
+ }
+ ike_sa->rekey_child_sa(ike_sa, this->protocol, this->spi);
+
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+}
+
+/**
+ * Implementation of job_t.destroy.
+ */
+static void destroy(private_rekey_child_sa_job_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
+ protocol_id_t protocol,
+ u_int32_t spi)
+{
+ private_rekey_child_sa_job_t *this = malloc_thing(private_rekey_child_sa_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
+
+ /* private variables */
+ this->reqid = reqid;
+ this->protocol = protocol;
+ this->spi = spi;
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/rekey_child_sa_job.h b/src/charon/queues/jobs/rekey_child_sa_job.h
new file mode 100644
index 000000000..19e1b5d32
--- /dev/null
+++ b/src/charon/queues/jobs/rekey_child_sa_job.h
@@ -0,0 +1,65 @@
+/**
+ * @file rekey_child_sa_job.h
+ *
+ * @brief Interface of rekey_child_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef REKEY_CHILD_SA_JOB_H_
+#define REKEY_CHILD_SA_JOB_H_
+
+typedef struct rekey_child_sa_job_t rekey_child_sa_job_t;
+
+#include <library.h>
+#include <sa/ike_sa_id.h>
+#include <queues/jobs/job.h>
+#include <config/proposal.h>
+
+/**
+ * @brief Class representing an REKEY_CHILD_SA Job.
+ *
+ * This job initiates the rekeying of a CHILD SA.
+ *
+ * @b Constructors:
+ * - rekey_child_sa_job_create()
+ *
+ * @ingroup jobs
+ */
+struct rekey_child_sa_job_t {
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type REKEY_CHILD_SA.
+ *
+ * The CHILD_SA is identified by its protocol (AH/ESP) and its
+ * inbound SPI.
+ *
+ * @param reqid reqid of the CHILD_SA to rekey
+ * @param protocol protocol of the CHILD_SA
+ * @param spi security parameter index of the CHILD_SA
+ * @return rekey_child_sa_job_t object
+ *
+ * @ingroup jobs
+ */
+rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, protocol_id_t protocol, u_int32_t spi);
+
+#endif /* REKEY_CHILD_SA_JOB_H_ */
diff --git a/src/charon/queues/jobs/rekey_ike_sa_job.c b/src/charon/queues/jobs/rekey_ike_sa_job.c
new file mode 100644
index 000000000..2539d997e
--- /dev/null
+++ b/src/charon/queues/jobs/rekey_ike_sa_job.c
@@ -0,0 +1,120 @@
+/**
+ * @file rekey_ike_sa_job.c
+ *
+ * @brief Implementation of rekey_ike_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "rekey_ike_sa_job.h"
+
+#include <daemon.h>
+
+
+typedef struct private_rekey_ike_sa_job_t private_rekey_ike_sa_job_t;
+
+/**
+ * Private data of an rekey_ike_sa_job_t object.
+ */
+struct private_rekey_ike_sa_job_t {
+ /**
+ * Public rekey_ike_sa_job_t interface.
+ */
+ rekey_ike_sa_job_t public;
+
+ /**
+ * ID of the IKE_SA to rekey
+ */
+ ike_sa_id_t *ike_sa_id;
+
+ /**
+ * force reauthentication of the peer (full IKE_SA setup)
+ */
+ bool reauth;
+};
+
+/**
+ * Implementation of job_t.get_type.
+ */
+static job_type_t get_type(private_rekey_ike_sa_job_t *this)
+{
+ return REKEY_IKE_SA;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_rekey_ike_sa_job_t *this)
+{
+ ike_sa_t *ike_sa;
+ status_t status = SUCCESS;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa == NULL)
+ {
+ DBG2(DBG_JOB, "IKE_SA %J to rekey not found", this->ike_sa_id);
+ return DESTROY_ME;
+ }
+
+ if (this->reauth)
+ {
+ ike_sa->reestablish(ike_sa);
+ }
+ else
+ {
+ status = ike_sa->rekey(ike_sa);
+ }
+
+ if (status == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ return DESTROY_ME;
+}
+
+/**
+ * Implementation of job_t.destroy.
+ */
+static void destroy(private_rekey_ike_sa_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth)
+{
+ private_rekey_ike_sa_job_t *this = malloc_thing(private_rekey_ike_sa_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
+
+ /* private variables */
+ this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
+ this->reauth = reauth;
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/rekey_ike_sa_job.h b/src/charon/queues/jobs/rekey_ike_sa_job.h
new file mode 100644
index 000000000..f3e336fb3
--- /dev/null
+++ b/src/charon/queues/jobs/rekey_ike_sa_job.h
@@ -0,0 +1,60 @@
+/**
+ * @file rekey_ike_sa_job.h
+ *
+ * @brief Interface of rekey_ike_sa_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef REKEY_IKE_SA_JOB_H_
+#define REKEY_IKE_SA_JOB_H_
+
+typedef struct rekey_ike_sa_job_t rekey_ike_sa_job_t;
+
+#include <library.h>
+#include <sa/ike_sa_id.h>
+#include <queues/jobs/job.h>
+
+/**
+ * @brief Class representing an REKEY_IKE_SA Job.
+ *
+ * This job initiates the rekeying of an IKE_SA.
+ *
+ * @b Constructors:
+ * - rekey_ike_sa_job_create()
+ *
+ * @ingroup jobs
+ */
+struct rekey_ike_sa_job_t {
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type REKEY_IKE_SA.
+ *
+ * @param ike_sa_id ID of the IKE_SA to rekey
+ * @param reauth TRUE to reauthenticate peer, FALSE for rekeying only
+ * @return rekey_ike_sa_job_t object
+ *
+ * @ingroup jobs
+ */
+rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth);
+
+#endif /* REKEY_IKE_SA_JOB_H_ */
diff --git a/src/charon/queues/jobs/retransmit_job.c b/src/charon/queues/jobs/retransmit_job.c
new file mode 100644
index 000000000..5bfa20dfd
--- /dev/null
+++ b/src/charon/queues/jobs/retransmit_job.c
@@ -0,0 +1,109 @@
+/**
+ * @file retransmit_job.c
+ *
+ * @brief Implementation of retransmit_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "retransmit_job.h"
+
+#include <daemon.h>
+
+typedef struct private_retransmit_job_t private_retransmit_job_t;
+
+/**
+ * Private data of an retransmit_job_t Object.
+ */
+struct private_retransmit_job_t {
+ /**
+ * Public retransmit_job_t interface.
+ */
+ retransmit_job_t public;
+
+ /**
+ * Message ID of the request to resend.
+ */
+ u_int32_t message_id;
+
+ /**
+ * ID of the IKE_SA which the message belongs to.
+ */
+ ike_sa_id_t *ike_sa_id;
+};
+
+/**
+ * Implements job_t.get_type.
+ */
+static job_type_t get_type(private_retransmit_job_t *this)
+{
+ return RETRANSMIT;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_retransmit_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa)
+ {
+ if (ike_sa->retransmit(ike_sa, this->message_id) == DESTROY_ME)
+ {
+ /* retransmitted to many times, giving up */
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_retransmit_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+retransmit_job_t *retransmit_job_create(u_int32_t message_id,ike_sa_id_t *ike_sa_id)
+{
+ private_retransmit_job_t *this = malloc_thing(private_retransmit_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
+
+ /* private variables */
+ this->message_id = message_id;
+ this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
+
+ return &this->public;
+}
diff --git a/src/charon/queues/jobs/retransmit_job.h b/src/charon/queues/jobs/retransmit_job.h
new file mode 100644
index 000000000..19e29b909
--- /dev/null
+++ b/src/charon/queues/jobs/retransmit_job.h
@@ -0,0 +1,64 @@
+/**
+ * @file retransmit_job.h
+ *
+ * @brief Interface of retransmit_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef RETRANSMIT_JOB_H_
+#define RETRANSMIT_JOB_H_
+
+typedef struct retransmit_job_t retransmit_job_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+#include <sa/ike_sa_id.h>
+
+/**
+ * @brief Class representing an retransmit Job.
+ *
+ * This job is scheduled every time a request is sent over the
+ * wire. If the response to the request is not received at schedule
+ * time, the retransmission will be initiated.
+ *
+ * @b Constructors:
+ * - retransmit_job_create()
+ *
+ * @ingroup jobs
+ */
+struct retransmit_job_t {
+ /**
+ * The job_t interface.
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type retransmit.
+ *
+ * @param message_id message_id of the request to resend
+ * @param ike_sa_id identification of the ike_sa as ike_sa_id_t
+ * @return retransmit_job_t object
+ *
+ * @ingroup jobs
+ */
+retransmit_job_t *retransmit_job_create(u_int32_t message_id,
+ ike_sa_id_t *ike_sa_id);
+
+#endif /* RETRANSMIT_JOB_H_ */
diff --git a/src/charon/queues/jobs/route_job.c b/src/charon/queues/jobs/route_job.c
new file mode 100644
index 000000000..bb6281dcc
--- /dev/null
+++ b/src/charon/queues/jobs/route_job.c
@@ -0,0 +1,125 @@
+/**
+ * @file route_job.c
+ *
+ * @brief Implementation of route_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include <stdlib.h>
+
+#include "route_job.h"
+
+#include <daemon.h>
+
+typedef struct private_route_job_t private_route_job_t;
+
+/**
+ * Private data of an route_job_t Object
+ */
+struct private_route_job_t {
+ /**
+ * public route_job_t interface
+ */
+ route_job_t public;
+
+ /**
+ * associated connection to route
+ */
+ connection_t *connection;
+
+ /**
+ * associated policy to route
+ */
+ policy_t *policy;
+
+ /**
+ * route or unroute?
+ */
+ bool route;
+};
+
+/**
+ * Implements route_job_t.get_type.
+ */
+static job_type_t get_type(private_route_job_t *this)
+{
+ return ROUTE;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_route_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
+ this->connection->get_my_host(this->connection),
+ this->connection->get_other_host(this->connection),
+ this->policy->get_my_id(this->policy),
+ this->policy->get_other_id(this->policy));
+ if (this->route)
+ {
+ if (ike_sa->route(ike_sa, this->connection, this->policy) != SUCCESS)
+ {
+ DBG1(DBG_JOB, "routing failed");
+ }
+ }
+ else
+ {
+ if (ike_sa->unroute(ike_sa, this->policy) == DESTROY_ME)
+ {
+ DBG1(DBG_JOB, "removing IKE_SA, as last routed CHILD_SA unrouted");
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+ }
+ }
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_route_job_t *this)
+{
+ this->connection->destroy(this->connection);
+ this->policy->destroy(this->policy);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+route_job_t *route_job_create(connection_t *connection, policy_t *policy, bool route)
+{
+ private_route_job_t *this = malloc_thing(private_route_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+ this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
+
+ /* private variables */
+ this->connection = connection;
+ this->policy = policy;
+ this->route = route;
+
+ return &this->public;
+}
diff --git a/src/charon/queues/jobs/route_job.h b/src/charon/queues/jobs/route_job.h
new file mode 100644
index 000000000..2743a70ab
--- /dev/null
+++ b/src/charon/queues/jobs/route_job.h
@@ -0,0 +1,59 @@
+/**
+ * @file route_job.h
+ *
+ * @brief Interface of route_job_t.
+ */
+
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef ROUTE_JOB_H_
+#define ROUTE_JOB_H_
+
+typedef struct route_job_t route_job_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+#include <config/policies/policy.h>
+#include <config/connections/connection.h>
+
+/**
+ * @brief Class representing an ROUTE Job.
+ *
+ * @b Constructors:
+ * - route_job_create()
+ *
+ * @ingroup jobs
+ */
+struct route_job_t {
+ /**
+ * implements job_t interface
+ */
+ job_t job_interface;
+};
+
+/**
+ * @brief Creates a job of type ROUTE.
+ *
+ * @param connection connection used for routing
+ * @param policy policy to set up
+ * @param route TRUE to route, FALSE to unroute
+ * @return route_job_t object
+ *
+ * @ingroup jobs
+ */
+route_job_t *route_job_create(connection_t *connection, policy_t *policy, bool route);
+
+#endif /*ROUTE_JOB_H_*/
diff --git a/src/charon/queues/jobs/send_dpd_job.c b/src/charon/queues/jobs/send_dpd_job.c
new file mode 100644
index 000000000..7294d78d5
--- /dev/null
+++ b/src/charon/queues/jobs/send_dpd_job.c
@@ -0,0 +1,110 @@
+/**
+ * @file send_dpd_job.c
+ *
+ * @brief Implementation of send_dpd_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include <stdlib.h>
+
+#include "send_dpd_job.h"
+
+#include <sa/ike_sa.h>
+#include <daemon.h>
+
+
+typedef struct private_send_dpd_job_t private_send_dpd_job_t;
+
+/**
+ * Private data of an send_dpd_job_t Object
+ */
+struct private_send_dpd_job_t {
+ /**
+ * public send_dpd_job_t interface
+ */
+ send_dpd_job_t public;
+
+ /**
+ * ID of the IKE_SA which the message belongs to.
+ */
+ ike_sa_id_t *ike_sa_id;
+};
+
+/**
+ * Implements send_dpd_job_t.get_type.
+ */
+static job_type_t get_type(private_send_dpd_job_t *this)
+{
+ return SEND_DPD;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_send_dpd_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa == NULL)
+ {
+ return DESTROY_ME;
+ }
+
+ if (ike_sa->send_dpd(ike_sa) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_send_dpd_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id)
+{
+ private_send_dpd_job_t *this = malloc_thing(private_send_dpd_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+
+ /* public functions */
+ this->public.destroy = (void (*)(send_dpd_job_t *)) destroy;
+
+ /* private variables */
+ this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/send_dpd_job.h b/src/charon/queues/jobs/send_dpd_job.h
new file mode 100644
index 000000000..f3900f9a2
--- /dev/null
+++ b/src/charon/queues/jobs/send_dpd_job.h
@@ -0,0 +1,68 @@
+/**
+ * @file send_dpd_job.h
+ *
+ * @brief Interface of send_dpd_job_t.
+ */
+
+/*
+ * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef SEND_DPD_JOB_H_
+#define SEND_DPD_JOB_H_
+
+typedef struct send_dpd_job_t send_dpd_job_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+#include <config/connections/connection.h>
+#include <sa/ike_sa_id.h>
+
+/**
+ * @brief Class representing a SEND_DPD Job.
+ *
+ * Job to periodically send a Dead Peer Detection (DPD) request,
+ * ie. an IKE request with no payloads other than the encrypted payload
+ * required by the syntax.
+ *
+ * @b Constructors:
+ * - send_dpd_job_create()
+ *
+ * @ingroup jobs
+ */
+struct send_dpd_job_t {
+ /**
+ * implements job_t interface
+ */
+ job_t job_interface;
+
+ /**
+ * @brief Destroys an send_dpd_job_t object.
+ *
+ * @param this send_dpd_job_t object to destroy
+ */
+ void (*destroy) (send_dpd_job_t *this);
+};
+
+/**
+ * @brief Creates a job of type SEND_DPD.
+ *
+ * @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned)
+ * @return initiate_ike_sa_job_t object
+ *
+ * @ingroup jobs
+ */
+send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id);
+
+#endif /*SEND_DPD_JOB_H_*/
diff --git a/src/charon/queues/jobs/send_keepalive_job.c b/src/charon/queues/jobs/send_keepalive_job.c
new file mode 100644
index 000000000..1c1cb288e
--- /dev/null
+++ b/src/charon/queues/jobs/send_keepalive_job.c
@@ -0,0 +1,103 @@
+/**
+ * @file send_keepalive_job.c
+ *
+ * @brief Implementation of send_keepalive_job_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+
+#include <stdlib.h>
+
+#include "send_keepalive_job.h"
+
+#include <sa/ike_sa.h>
+#include <daemon.h>
+
+
+typedef struct private_send_keepalive_job_t private_send_keepalive_job_t;
+
+/**
+ * Private data of an send_keepalive_job_t Object
+ */
+struct private_send_keepalive_job_t {
+ /**
+ * public send_keepalive_job_t interface
+ */
+ send_keepalive_job_t public;
+
+ /**
+ * ID of the IKE_SA which the message belongs to.
+ */
+ ike_sa_id_t *ike_sa_id;
+};
+
+/**
+ * Implements send_keepalive_job_t.get_type.
+ */
+static job_type_t get_type(private_send_keepalive_job_t *this)
+{
+ return SEND_KEEPALIVE;
+}
+
+/**
+ * Implementation of job_t.execute.
+ */
+static status_t execute(private_send_keepalive_job_t *this)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+ this->ike_sa_id);
+ if (ike_sa == NULL)
+ {
+ return DESTROY_ME;
+ }
+ ike_sa->send_keepalive(ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return DESTROY_ME;
+}
+
+/**
+ * Implements job_t.destroy.
+ */
+static void destroy(private_send_keepalive_job_t *this)
+{
+ this->ike_sa_id->destroy(this->ike_sa_id);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id)
+{
+ private_send_keepalive_job_t *this = malloc_thing(private_send_keepalive_job_t);
+
+ /* interface functions */
+ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
+ this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
+ this->public.job_interface.execute = (status_t (*) (job_t *)) execute;
+
+ /* public functions */
+ this->public.destroy = (void (*)(send_keepalive_job_t *)) destroy;
+
+ /* private variables */
+ this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
+
+ return &(this->public);
+}
diff --git a/src/charon/queues/jobs/send_keepalive_job.h b/src/charon/queues/jobs/send_keepalive_job.h
new file mode 100644
index 000000000..c7d05be65
--- /dev/null
+++ b/src/charon/queues/jobs/send_keepalive_job.h
@@ -0,0 +1,67 @@
+/**
+ * @file send_keepalive_job.h
+ *
+ * @brief Interface of send_keepalive_job_t.
+ */
+
+/*
+ * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef SEND_KEEPALIVE_JOB_H_
+#define SEND_KEEPALIVE_JOB_H_
+
+typedef struct send_keepalive_job_t send_keepalive_job_t;
+
+#include <library.h>
+#include <queues/jobs/job.h>
+#include <config/connections/connection.h>
+#include <sa/ike_sa_id.h>
+
+/**
+ * @brief Class representing a SEND_KEEPALIVE Job.
+ *
+ * This job will send a NAT keepalive packet if the IKE SA is still alive,
+ * and reinsert itself into the event queue.
+ *
+ * @b Constructors:
+ * - send_keepalive_job_create()
+ *
+ * @ingroup jobs
+ */
+struct send_keepalive_job_t {
+ /**
+ * implements job_t interface
+ */
+ job_t job_interface;
+
+ /**
+ * @brief Destroys an send_keepalive_job_t object.
+ *
+ * @param this send_keepalive_job_t object to destroy
+ */
+ void (*destroy) (send_keepalive_job_t *this);
+};
+
+/**
+ * @brief Creates a job of type SEND_KEEPALIVE.
+ *
+ * @param ike_sa_id identification of the ike_sa as ike_sa_id_t object (gets cloned)
+ * @return initiate_ike_sa_job_t object
+ *
+ * @ingroup jobs
+ */
+send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id);
+
+#endif /*SEND_KEEPALIVE_JOB_H_*/