summaryrefslogtreecommitdiff
path: root/src/charon/processing
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2007-06-03 17:36:35 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2007-06-03 17:36:35 +0000
commit08ee5250bd9c43fda5f24d10b791ca2c4c17fcee (patch)
treed4e2fc7144e288d624555a38955593e1ee066531 /src/charon/processing
parentb0d8ed94fe9e74afb49fdf5f11e4add29879c65c (diff)
downloadvyos-strongswan-08ee5250bd9c43fda5f24d10b791ca2c4c17fcee.tar.gz
vyos-strongswan-08ee5250bd9c43fda5f24d10b791ca2c4c17fcee.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.1.3)
Diffstat (limited to 'src/charon/processing')
-rw-r--r--src/charon/processing/event_queue.c290
-rw-r--r--src/charon/processing/event_queue.h118
-rw-r--r--src/charon/processing/job_queue.c139
-rw-r--r--src/charon/processing/job_queue.h100
-rw-r--r--src/charon/processing/jobs/acquire_job.c98
-rw-r--r--src/charon/processing/jobs/acquire_job.h60
-rw-r--r--src/charon/processing/jobs/delete_child_sa_job.c113
-rw-r--r--src/charon/processing/jobs/delete_child_sa_job.h68
-rw-r--r--src/charon/processing/jobs/delete_ike_sa_job.c126
-rw-r--r--src/charon/processing/jobs/delete_ike_sa_job.h66
-rw-r--r--src/charon/processing/jobs/job.c39
-rw-r--r--src/charon/processing/jobs/job.h165
-rw-r--r--src/charon/processing/jobs/process_message_job.c106
-rw-r--r--src/charon/processing/jobs/process_message_job.h58
-rw-r--r--src/charon/processing/jobs/rekey_child_sa_job.c112
-rw-r--r--src/charon/processing/jobs/rekey_child_sa_job.h65
-rw-r--r--src/charon/processing/jobs/rekey_ike_sa_job.c120
-rw-r--r--src/charon/processing/jobs/rekey_ike_sa_job.h60
-rw-r--r--src/charon/processing/jobs/retransmit_job.c109
-rw-r--r--src/charon/processing/jobs/retransmit_job.h64
-rw-r--r--src/charon/processing/jobs/send_dpd_job.c110
-rw-r--r--src/charon/processing/jobs/send_dpd_job.h67
-rw-r--r--src/charon/processing/jobs/send_keepalive_job.c103
-rw-r--r--src/charon/processing/jobs/send_keepalive_job.h66
-rw-r--r--src/charon/processing/scheduler.c104
-rw-r--r--src/charon/processing/scheduler.h68
-rw-r--r--src/charon/processing/thread_pool.c183
-rw-r--r--src/charon/processing/thread_pool.h87
28 files changed, 2864 insertions, 0 deletions
diff --git a/src/charon/processing/event_queue.c b/src/charon/processing/event_queue.c
new file mode 100644
index 000000000..40bcb1ed8
--- /dev/null
+++ b/src/charon/processing/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/processing/event_queue.h b/src/charon/processing/event_queue.h
new file mode 100644
index 000000000..c85286bf2
--- /dev/null
+++ b/src/charon/processing/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 <processing/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 processing
+ */
+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 processing
+ */
+event_queue_t *event_queue_create(void);
+
+#endif /*EVENT_QUEUE_H_*/
diff --git a/src/charon/processing/job_queue.c b/src/charon/processing/job_queue.c
new file mode 100644
index 000000000..2310ca6ff
--- /dev/null
+++ b/src/charon/processing/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/processing/job_queue.h b/src/charon/processing/job_queue.h
new file mode 100644
index 000000000..9b58588ae
--- /dev/null
+++ b/src/charon/processing/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 <processing/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 processing
+ */
+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 processing
+ */
+job_queue_t *job_queue_create(void);
+
+#endif /*JOB_QUEUE_H_*/
diff --git a/src/charon/processing/jobs/acquire_job.c b/src/charon/processing/jobs/acquire_job.c
new file mode 100644
index 000000000..b4ffb258d
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/acquire_job.h b/src/charon/processing/jobs/acquire_job.h
new file mode 100644
index 000000000..226966215
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/delete_child_sa_job.c b/src/charon/processing/jobs/delete_child_sa_job.c
new file mode 100644
index 000000000..f694696b0
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/delete_child_sa_job.h b/src/charon/processing/jobs/delete_child_sa_job.h
new file mode 100644
index 000000000..0b90e008d
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/delete_ike_sa_job.c b/src/charon/processing/jobs/delete_ike_sa_job.c
new file mode 100644
index 000000000..706155aa6
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/delete_ike_sa_job.h b/src/charon/processing/jobs/delete_ike_sa_job.h
new file mode 100644
index 000000000..11bb46e73
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/job.c b/src/charon/processing/jobs/job.c
new file mode 100644
index 000000000..d32d1bc61
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/job.h b/src/charon/processing/jobs/job.h
new file mode 100644
index 000000000..28632672d
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/process_message_job.c b/src/charon/processing/jobs/process_message_job.c
new file mode 100644
index 000000000..ee7484bbd
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/process_message_job.h b/src/charon/processing/jobs/process_message_job.h
new file mode 100644
index 000000000..5bb18155a
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/rekey_child_sa_job.c b/src/charon/processing/jobs/rekey_child_sa_job.c
new file mode 100644
index 000000000..3422b614d
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/rekey_child_sa_job.h b/src/charon/processing/jobs/rekey_child_sa_job.h
new file mode 100644
index 000000000..df86070bc
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/rekey_ike_sa_job.c b/src/charon/processing/jobs/rekey_ike_sa_job.c
new file mode 100644
index 000000000..f6c058634
--- /dev/null
+++ b/src/charon/processing/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 to rekey not found");
+ 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/processing/jobs/rekey_ike_sa_job.h b/src/charon/processing/jobs/rekey_ike_sa_job.h
new file mode 100644
index 000000000..4031b3813
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/retransmit_job.c b/src/charon/processing/jobs/retransmit_job.c
new file mode 100644
index 000000000..5bfa20dfd
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/retransmit_job.h b/src/charon/processing/jobs/retransmit_job.h
new file mode 100644
index 000000000..93bb548e7
--- /dev/null
+++ b/src/charon/processing/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 <processing/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/processing/jobs/send_dpd_job.c b/src/charon/processing/jobs/send_dpd_job.c
new file mode 100644
index 000000000..7294d78d5
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/send_dpd_job.h b/src/charon/processing/jobs/send_dpd_job.h
new file mode 100644
index 000000000..26c9e2e81
--- /dev/null
+++ b/src/charon/processing/jobs/send_dpd_job.h
@@ -0,0 +1,67 @@
+/**
+ * @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 <processing/jobs/job.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/processing/jobs/send_keepalive_job.c b/src/charon/processing/jobs/send_keepalive_job.c
new file mode 100644
index 000000000..1c1cb288e
--- /dev/null
+++ b/src/charon/processing/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/processing/jobs/send_keepalive_job.h b/src/charon/processing/jobs/send_keepalive_job.h
new file mode 100644
index 000000000..f7b38337e
--- /dev/null
+++ b/src/charon/processing/jobs/send_keepalive_job.h
@@ -0,0 +1,66 @@
+/**
+ * @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 <processing/jobs/job.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_*/
diff --git a/src/charon/processing/scheduler.c b/src/charon/processing/scheduler.c
new file mode 100644
index 000000000..7249e43e6
--- /dev/null
+++ b/src/charon/processing/scheduler.c
@@ -0,0 +1,104 @@
+/**
+ * @file scheduler.c
+ *
+ * @brief Implementation of scheduler_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 "scheduler.h"
+
+#include <daemon.h>
+#include <processing/job_queue.h>
+
+
+typedef struct private_scheduler_t private_scheduler_t;
+
+/**
+ * Private data of a scheduler_t object.
+ */
+struct private_scheduler_t {
+ /**
+ * Public part of a scheduler_t object.
+ */
+ scheduler_t public;
+
+ /**
+ * Assigned thread.
+ */
+ pthread_t assigned_thread;
+};
+
+/**
+ * Implementation of private_scheduler_t.get_events.
+ */
+static void get_events(private_scheduler_t * this)
+{
+ job_t *current_job;
+
+ /* cancellation disabled by default */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ DBG1(DBG_JOB, "scheduler thread running, thread_ID: %06u",
+ (int)pthread_self());
+
+ charon->drop_capabilities(charon, TRUE);
+
+ while (TRUE)
+ {
+ DBG2(DBG_JOB, "waiting for next event...");
+ /* get a job, this block until one is available */
+ current_job = charon->event_queue->get(charon->event_queue);
+ /* queue the job in the job queue, workers will eat them */
+ DBG2(DBG_JOB, "got event, adding job %N to job-queue",
+ job_type_names, current_job->get_type(current_job));
+ charon->job_queue->add(charon->job_queue, current_job);
+ }
+}
+
+/**
+ * Implementation of scheduler_t.destroy.
+ */
+static void destroy(private_scheduler_t *this)
+{
+ pthread_cancel(this->assigned_thread);
+ pthread_join(this->assigned_thread, NULL);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+scheduler_t * scheduler_create()
+{
+ private_scheduler_t *this = malloc_thing(private_scheduler_t);
+
+ this->public.destroy = (void(*)(scheduler_t*)) destroy;
+
+ if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))get_events, this) != 0)
+ {
+ /* thread could not be created */
+ free(this);
+ charon->kill(charon, "unable to create scheduler thread");
+ }
+
+ return &(this->public);
+}
diff --git a/src/charon/processing/scheduler.h b/src/charon/processing/scheduler.h
new file mode 100644
index 000000000..bea93e7c9
--- /dev/null
+++ b/src/charon/processing/scheduler.h
@@ -0,0 +1,68 @@
+/**
+ * @file scheduler.h
+ *
+ * @brief Interface of scheduler_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 SCHEDULER_H_
+#define SCHEDULER_H_
+
+typedef struct scheduler_t scheduler_t;
+
+#include <library.h>
+
+/**
+ * @brief The scheduler thread is responsible for timed events.
+ *
+ * The scheduler thread takes out jobs from the event-queue and adds them
+ * to the job-queue.
+ *
+ * Starts a thread which does the work, since event-queue is blocking.
+ *
+ * @b Constructors:
+ * - scheduler_create()
+ *
+ * @ingroup processing
+ */
+struct scheduler_t {
+
+ /**
+ * @brief Destroys a scheduler object.
+ *
+ * @param scheduler calling object
+ */
+ void (*destroy) (scheduler_t *scheduler);
+};
+
+/**
+ * @brief Create a scheduler with its associated thread.
+ *
+ * The thread will start to get jobs form the event queue
+ * and adds them to the job queue.
+ *
+ * @return
+ * - scheduler_t object
+ * - NULL if thread could not be started
+ *
+ * @ingroup processing
+ */
+scheduler_t * scheduler_create(void);
+
+#endif /*SCHEDULER_H_*/
diff --git a/src/charon/processing/thread_pool.c b/src/charon/processing/thread_pool.c
new file mode 100644
index 000000000..a9891da15
--- /dev/null
+++ b/src/charon/processing/thread_pool.c
@@ -0,0 +1,183 @@
+/**
+ * @file thread_pool.c
+ *
+ * @brief Implementation of thread_pool_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 <string.h>
+#include <errno.h>
+
+#include "thread_pool.h"
+
+#include <daemon.h>
+#include <processing/job_queue.h>
+
+
+typedef struct private_thread_pool_t private_thread_pool_t;
+
+/**
+ * @brief Private data of thread_pool_t class.
+ */
+struct private_thread_pool_t {
+ /**
+ * Public thread_pool_t interface.
+ */
+ thread_pool_t public;
+
+ /**
+ * Number of running threads.
+ */
+ u_int pool_size;
+
+ /**
+ * Number of threads waiting for work
+ */
+ u_int idle_threads;
+
+ /**
+ * Array of thread ids.
+ */
+ pthread_t *threads;
+};
+
+/**
+ * Implementation of private_thread_pool_t.process_jobs.
+ */
+static void process_jobs(private_thread_pool_t *this)
+{
+ job_t *job;
+ status_t status;
+
+ /* cancellation disabled by default */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ DBG1(DBG_JOB, "worker thread running, thread_ID: %06u",
+ (int)pthread_self());
+
+ charon->drop_capabilities(charon, TRUE);
+
+ while (TRUE)
+ {
+ /* TODO: should be atomic, but is not mission critical */
+ this->idle_threads++;
+ job = charon->job_queue->get(charon->job_queue);
+ this->idle_threads--;
+
+ status = job->execute(job);
+
+ if (status == DESTROY_ME)
+ {
+ job->destroy(job);
+ }
+ }
+}
+
+/**
+ * Implementation of thread_pool_t.get_pool_size.
+ */
+static u_int get_pool_size(private_thread_pool_t *this)
+{
+ return this->pool_size;
+}
+
+/**
+ * Implementation of thread_pool_t.get_idle_threads.
+ */
+static u_int get_idle_threads(private_thread_pool_t *this)
+{
+ return this->idle_threads;
+}
+
+/**
+ * Implementation of thread_pool_t.destroy.
+ */
+static void destroy(private_thread_pool_t *this)
+{
+ int current;
+ /* flag thread for termination */
+ for (current = 0; current < this->pool_size; current++)
+ {
+ DBG1(DBG_JOB, "cancelling worker thread #%d", current+1);
+ pthread_cancel(this->threads[current]);
+ }
+
+ /* wait for all threads */
+ for (current = 0; current < this->pool_size; current++) {
+ if (pthread_join(this->threads[current], NULL) == 0)
+ {
+ DBG1(DBG_JOB, "worker thread #%d terminated", current+1);
+ }
+ else
+ {
+ DBG1(DBG_JOB, "could not terminate worker thread #%d", current+1);
+ }
+ }
+
+ /* free mem */
+ free(this->threads);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+thread_pool_t *thread_pool_create(size_t pool_size)
+{
+ int current;
+ private_thread_pool_t *this = malloc_thing(private_thread_pool_t);
+
+ /* fill in public fields */
+ this->public.destroy = (void(*)(thread_pool_t*))destroy;
+ this->public.get_pool_size = (u_int(*)(thread_pool_t*))get_pool_size;
+ this->public.get_idle_threads = (u_int(*)(thread_pool_t*))get_idle_threads;
+
+ /* initialize member */
+ this->pool_size = pool_size;
+ this->idle_threads = 0;
+ this->threads = malloc(sizeof(pthread_t) * pool_size);
+
+ /* try to create as many threads as possible, up to pool_size */
+ for (current = 0; current < pool_size; current++)
+ {
+ if (pthread_create(&(this->threads[current]), NULL,
+ (void*(*)(void*))process_jobs, this) == 0)
+ {
+ DBG1(DBG_JOB, "created worker thread #%d", current+1);
+ }
+ else
+ {
+ /* creation failed, is it the first one? */
+ if (current == 0)
+ {
+ free(this->threads);
+ free(this);
+ charon->kill(charon, "could not create any worker threads");
+ }
+ /* not all threads could be created, but at least one :-/ */
+ DBG1(DBG_JOB, "could only create %d from requested %d threads!",
+ current, pool_size);
+ this->pool_size = current;
+ break;
+ }
+ }
+ return (thread_pool_t*)this;
+}
diff --git a/src/charon/processing/thread_pool.h b/src/charon/processing/thread_pool.h
new file mode 100644
index 000000000..09a6312a8
--- /dev/null
+++ b/src/charon/processing/thread_pool.h
@@ -0,0 +1,87 @@
+/**
+ * @file thread_pool.h
+ *
+ * @brief Interface of thread_pool_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 THREAD_POOL_H_
+#define THREAD_POOL_H_
+
+typedef struct thread_pool_t thread_pool_t;
+
+#include <stdlib.h>
+
+#include <library.h>
+
+/**
+ * @brief A thread_pool consists of a pool of threads processing jobs from the job queue.
+ *
+ * Current implementation uses as many threads as specified in constructor.
+ * A more improved version would dynamically increase thread count if necessary.
+ *
+ * @b Constructors:
+ * - thread_pool_create()
+ *
+ * @todo Add support for dynamic thread handling
+ *
+ * @ingroup processing
+ */
+struct thread_pool_t {
+
+ /**
+ * @brief Return currently instanciated thread count.
+ *
+ * @param thread_pool calling object
+ * @return size of thread pool
+ */
+ u_int (*get_pool_size) (thread_pool_t *thread_pool);
+
+ /**
+ * @brief Get the number of threads currently waiting for work.
+ *
+ * @param thread_pool calling object
+ * @return number of idle threads
+ */
+ u_int (*get_idle_threads) (thread_pool_t *thread_pool);
+
+ /**
+ * @brief Destroy a thread_pool_t object.
+ *
+ * Sends cancellation request to all threads and AWAITS their termination.
+ *
+ * @param thread_pool calling object
+ */
+ void (*destroy) (thread_pool_t *thread_pool);
+};
+
+/**
+ * @brief Create the thread pool using using pool_size of threads.
+ *
+ * @param pool_size desired pool size
+ * @return
+ * - thread_pool_t object if one ore more threads could be started, or
+ * - NULL if no threads could be created
+ *
+ * @ingroup processing
+ */
+thread_pool_t *thread_pool_create(size_t pool_size);
+
+
+#endif /*THREAD_POOL_H_*/