restructured file layout

new configuration structure:
  peer_cfg: configuration related to a peer (authenitcation, ...=
  ike_cfg: config to use for IKE setup (proposals)
  child_Cfg: config for CHILD_SA (proposals, traffic selectors)
  a peer_cfg has one ike_cfg and multiple child_cfg's
stroke now uses fixed count of threads
This commit is contained in:
Martin Willi
2007-04-10 06:01:03 +00:00
parent 1628cd6bda
commit e0fe765152
104 changed files with 3466 additions and 3470 deletions
+290
View File
@@ -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);
}
+118
View File
@@ -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 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_*/
+139
View File
@@ -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);
}
+100
View File
@@ -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 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_*/
+98
View File
@@ -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);
}
+60
View File
@@ -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_ */
@@ -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);
}
@@ -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_ */
@@ -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);
}
@@ -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_ */
+118
View File
@@ -0,0 +1,118 @@
/**
* @file initiate_job.c
*
* @brief Implementation of initiate_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 <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 peer config to use for IKE_SA setup
*/
peer_cfg_t *peer_cfg;
/**
* child config to use for CHILD_SA
*/
child_cfg_t *child_cfg;
};
/**
* 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_cfg_t *ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
ike_cfg->get_my_host(ike_cfg),
ike_cfg->get_other_host(ike_cfg),
this->peer_cfg->get_my_id(this->peer_cfg),
this->peer_cfg->get_other_id(this->peer_cfg));
if (ike_sa->get_peer_cfg(ike_sa) == NULL)
{
ike_sa->set_peer_cfg(ike_sa, this->peer_cfg);
}
if (ike_sa->initiate(ike_sa, this->child_cfg) != 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->peer_cfg->destroy(this->peer_cfg);
this->child_cfg->destroy(this->child_cfg);
free(this);
}
/*
* Described in header
*/
initiate_job_t *initiate_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg)
{
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->peer_cfg = peer_cfg;
this->child_cfg = child_cfg;
return &this->public;
}
+61
View File
@@ -0,0 +1,61 @@
/**
* @file initiate_job.h
*
* @brief Interface of initiate_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 INITIATE_JOB_H_
#define INITIATE_JOB_H_
typedef struct initiate_job_t initiate_job_t;
#include <library.h>
#include <processing/jobs/job.h>
#include <config/peer_cfg.h>
#include <config/child_cfg.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.
*
* @param peer_cfg peer configuration to use (if not yet established)
* @param child_cfg config to create a CHILD from
* @return initiate_job_t object
*
* @ingroup jobs
*/
initiate_job_t *initiate_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg);
#endif /*INITIATE_JOB_H_*/
+39
View File
@@ -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",
);
+165
View File
@@ -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_ */
@@ -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);
}
@@ -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_*/
@@ -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);
}
@@ -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_ */
@@ -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);
}
@@ -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_ */
+109
View File
@@ -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;
}
@@ -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_ */
+133
View File
@@ -0,0 +1,133 @@
/**
* @file route_job.c
*
* @brief Implementation of route_job_t.
*
*/
/*
* Copyright (C) 2005-2007 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;
/**
* peer config for route
*/
peer_cfg_t *peer_cfg;
/**
* child config to route
*/
child_cfg_t *child_cfg;
/**
* 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_cfg_t *ike_cfg = this->peer_cfg->get_ike_cfg(this->peer_cfg);
ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
ike_cfg->get_my_host(ike_cfg),
ike_cfg->get_other_host(ike_cfg),
this->peer_cfg->get_my_id(this->peer_cfg),
this->peer_cfg->get_other_id(this->peer_cfg));
if (ike_sa->get_peer_cfg(ike_sa) == NULL)
{
ike_sa->set_peer_cfg(ike_sa, this->peer_cfg);
}
if (this->route)
{
if (ike_sa->route(ike_sa, this->child_cfg) != SUCCESS)
{
DBG1(DBG_JOB, "routing failed");
}
}
else
{
if (ike_sa->unroute(ike_sa, this->child_cfg) == 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->peer_cfg->destroy(this->peer_cfg);
this->child_cfg->destroy(this->child_cfg);
free(this);
}
/*
* Described in header
*/
route_job_t *route_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
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->peer_cfg = peer_cfg;
this->child_cfg = child_cfg;
this->route = route;
return &this->public;
}
+59
View File
@@ -0,0 +1,59 @@
/**
* @file route_job.h
*
* @brief Interface of route_job_t.
*/
/*
* Copyright (C) 2005-2007 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 <processing/jobs/job.h>
#include <config/peer_cfg.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 peer_cfg peer config to use for acquire
* @param child_cfg route to install
* @param route TRUE to route, FALSE to unroute
* @return route_job_t object
*
* @ingroup jobs
*/
route_job_t *route_job_create(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
bool route);
#endif /*ROUTE_JOB_H_*/
+110
View File
@@ -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);
}
+67
View File
@@ -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_*/
@@ -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);
}
@@ -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_*/
+102
View File
@@ -0,0 +1,102 @@
/**
* @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());
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);
}
+68
View File
@@ -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 threads
*/
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 threads
*/
scheduler_t * scheduler_create(void);
#endif /*SCHEDULER_H_*/
+181
View File
@@ -0,0 +1,181 @@
/**
* @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());
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;
}
+87
View File
@@ -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 threads
*/
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 threads
*/
thread_pool_t *thread_pool_create(size_t pool_size);
#endif /*THREAD_POOL_H_*/