diff options
Diffstat (limited to 'src/charon/queues')
-rw-r--r-- | src/charon/queues/event_queue.c | 2 | ||||
-rw-r--r-- | src/charon/queues/job_queue.c | 2 | ||||
-rw-r--r-- | src/charon/queues/jobs/delete_child_sa_job.c | 104 | ||||
-rw-r--r-- | src/charon/queues/jobs/delete_child_sa_job.h | 63 | ||||
-rw-r--r-- | src/charon/queues/jobs/delete_established_ike_sa_job.c | 31 | ||||
-rw-r--r-- | src/charon/queues/jobs/delete_established_ike_sa_job.h | 17 | ||||
-rw-r--r-- | src/charon/queues/jobs/delete_half_open_ike_sa_job.c | 58 | ||||
-rw-r--r-- | src/charon/queues/jobs/delete_half_open_ike_sa_job.h | 17 | ||||
-rw-r--r-- | src/charon/queues/jobs/incoming_packet_job.c | 141 | ||||
-rw-r--r-- | src/charon/queues/jobs/incoming_packet_job.h | 17 | ||||
-rw-r--r-- | src/charon/queues/jobs/initiate_ike_sa_job.c | 64 | ||||
-rw-r--r-- | src/charon/queues/jobs/initiate_ike_sa_job.h | 15 | ||||
-rw-r--r-- | src/charon/queues/jobs/job.h | 41 | ||||
-rw-r--r-- | src/charon/queues/jobs/rekey_child_sa_job.c | 105 | ||||
-rw-r--r-- | src/charon/queues/jobs/rekey_child_sa_job.h | 63 | ||||
-rw-r--r-- | src/charon/queues/jobs/retransmit_request_job.c | 102 | ||||
-rw-r--r-- | src/charon/queues/jobs/retransmit_request_job.h | 45 |
17 files changed, 673 insertions, 214 deletions
diff --git a/src/charon/queues/event_queue.c b/src/charon/queues/event_queue.c index 39681928c..eb58ca894 100644 --- a/src/charon/queues/event_queue.c +++ b/src/charon/queues/event_queue.c @@ -306,7 +306,7 @@ static void event_queue_destroy(private_event_queue_t *this) this->list->destroy(this->list); break; } - event->job->destroy_all(event->job); + event->job->destroy(event->job); event->destroy(event); } this->list->destroy(this->list); diff --git a/src/charon/queues/job_queue.c b/src/charon/queues/job_queue.c index 12a781c67..91b992bf0 100644 --- a/src/charon/queues/job_queue.c +++ b/src/charon/queues/job_queue.c @@ -121,7 +121,7 @@ static void job_queue_destroy (private_job_queue_t *this) this->list->destroy(this->list); break; } - job->destroy_all(job); + job->destroy(job); } this->list->destroy(this->list); diff --git a/src/charon/queues/jobs/delete_child_sa_job.c b/src/charon/queues/jobs/delete_child_sa_job.c new file mode 100644 index 000000000..ccad9103a --- /dev/null +++ b/src/charon/queues/jobs/delete_child_sa_job.c @@ -0,0 +1,104 @@ +/** + * @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 sa to delete. + */ + u_int32_t reqid; + + /** + * Logger ref + */ + logger_t *logger; +}; + +/** + * 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; + status_t status; + + status = charon->ike_sa_manager->checkout_by_reqid(charon->ike_sa_manager, this->reqid, &ike_sa); + if (status != SUCCESS) + { + this->logger->log(this->logger, CONTROL, "CHILD SA didn't exist anymore"); + return DESTROY_ME; + } + + /* TODO */ + + status = 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) +{ + 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->logger = logger_manager->get_logger(logger_manager, WORKER); + + return &(this->public); +} diff --git a/src/charon/queues/jobs/delete_child_sa_job.h b/src/charon/queues/jobs/delete_child_sa_job.h new file mode 100644 index 000000000..29802403e --- /dev/null +++ b/src/charon/queues/jobs/delete_child_sa_job.h @@ -0,0 +1,63 @@ +/** + * @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_ + +#include <types.h> +#include <sa/ike_sa_id.h> +#include <queues/jobs/job.h> + + +typedef struct delete_child_sa_job_t delete_child_sa_job_t; + +/** + * @brief Class representing an DELETE_CHILD_SA Job. + * + * This job initiates the deletion of an CHILD_SA. The SA + * to delete is specified via the unique reqid used in kernel. + * + * @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. + * + * To find the targeted CHILD_SA, the uniqe reqid used in + * the kernel is used. + * + * @param reqid reqid CHILD_SA to rekey + * + * @ingroup jobs + */ +delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid); + +#endif /* DELETE_CHILD_SA_JOB_H_ */ diff --git a/src/charon/queues/jobs/delete_established_ike_sa_job.c b/src/charon/queues/jobs/delete_established_ike_sa_job.c index 7251e2ca4..78f5c9ed1 100644 --- a/src/charon/queues/jobs/delete_established_ike_sa_job.c +++ b/src/charon/queues/jobs/delete_established_ike_sa_job.c @@ -22,6 +22,7 @@ #include "delete_established_ike_sa_job.h" +#include <daemon.h> typedef struct private_delete_established_ike_sa_job_t private_delete_established_ike_sa_job_t; @@ -39,6 +40,11 @@ struct private_delete_established_ike_sa_job_t { * ID of the ike_sa to delete. */ ike_sa_id_t *ike_sa_id; + + /** + * Logger ref + */ + logger_t *logger; }; /** @@ -49,12 +55,21 @@ static job_type_t get_type(private_delete_established_ike_sa_job_t *this) return DELETE_ESTABLISHED_IKE_SA; } + /** - * Implementation of delete_established_ike_sa_job_t.get_ike_sa_id + * Implementation of job_t.execute. */ -static ike_sa_id_t *get_ike_sa_id(private_delete_established_ike_sa_job_t *this) +static status_t execute(private_delete_established_ike_sa_job_t *this) { - return this->ike_sa_id; + ike_sa_t *ike_sa; + status_t status; + + status = charon->ike_sa_manager->delete(charon->ike_sa_manager, this->ike_sa_id); + if (status != SUCCESS) + { + this->logger->log(this->logger, CONTROL, "IKE SA didn't exist anymore"); + } + return DESTROY_ME; } /** @@ -75,16 +90,12 @@ delete_established_ike_sa_job_t *delete_established_ike_sa_job_create(ike_sa_id_ /* interface functions */ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; - /* same as destroy */ - this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy; + this->public.job_interface.execute = (status_t (*) (job_t *)) execute; this->public.job_interface.destroy = (void (*)(job_t*)) destroy; - - /* public functions */ - this->public.get_ike_sa_id = (ike_sa_id_t * (*)(delete_established_ike_sa_job_t *)) get_ike_sa_id; - this->public.destroy = (void (*)(delete_established_ike_sa_job_t *)) destroy; - + /* private variables */ this->ike_sa_id = ike_sa_id->clone(ike_sa_id); + this->logger = logger_manager->get_logger(logger_manager, WORKER); return &(this->public); } diff --git a/src/charon/queues/jobs/delete_established_ike_sa_job.h b/src/charon/queues/jobs/delete_established_ike_sa_job.h index 762dceae6..030e1aefe 100644 --- a/src/charon/queues/jobs/delete_established_ike_sa_job.h +++ b/src/charon/queues/jobs/delete_established_ike_sa_job.h @@ -46,23 +46,6 @@ struct delete_established_ike_sa_job_t { * The job_t interface. */ job_t job_interface; - - /** - * @brief Returns the currently set ike_sa_id. - * - * @warning Returned object is not copied. - * - * @param this calling delete_established_ike_sa_job_t object - * @return ike_sa_id_t object - */ - ike_sa_id_t * (*get_ike_sa_id) (delete_established_ike_sa_job_t *this); - - /** - * @brief Destroys an delete_established_ike_sa_job_t object (including assigned data). - * - * @param this delete_established_ike_sa_job_t object to destroy - */ - void (*destroy) (delete_established_ike_sa_job_t *this); }; /** diff --git a/src/charon/queues/jobs/delete_half_open_ike_sa_job.c b/src/charon/queues/jobs/delete_half_open_ike_sa_job.c index 610285e20..5de3cb222 100644 --- a/src/charon/queues/jobs/delete_half_open_ike_sa_job.c +++ b/src/charon/queues/jobs/delete_half_open_ike_sa_job.c @@ -22,7 +22,7 @@ #include "delete_half_open_ike_sa_job.h" - +#include <daemon.h> typedef struct private_delete_half_open_ike_sa_job_t private_delete_half_open_ike_sa_job_t; @@ -39,6 +39,11 @@ struct private_delete_half_open_ike_sa_job_t { * ID of the ike_sa to delete */ ike_sa_id_t *ike_sa_id; + + /** + * logger ref + */ + logger_t *logger; }; /** @@ -50,11 +55,48 @@ static job_type_t get_type(private_delete_half_open_ike_sa_job_t *this) } /** - * Implements elete_ike_sa_job_t.get_ike_sa_id + * Implementation of job_t.execute. */ -static ike_sa_id_t *get_ike_sa_id(private_delete_half_open_ike_sa_job_t *this) +static status_t execute(private_delete_half_open_ike_sa_job_t *this) { - return this->ike_sa_id; + ike_sa_t *ike_sa; + status_t status; + + status = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id, &ike_sa); + if ((status != SUCCESS) && (status != CREATED)) + { + this->logger->log(this->logger, CONTROL | LEVEL3, "IKE SA seems to be already deleted"); + return DESTROY_ME; + } + + switch (ike_sa->get_state(ike_sa)) + { + case INITIATOR_INIT: + case RESPONDER_INIT: + case IKE_SA_INIT_REQUESTED: + case IKE_SA_INIT_RESPONDED: + case IKE_AUTH_REQUESTED: + case DELETE_REQUESTED: + { + /* IKE_SA is half open and gets deleted! */ + status = charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not checkin and delete checked out IKE_SA!"); + } + return DESTROY_ME; + } + default: + { + /* IKE_SA is established and so is not getting deleted! */ + status = charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not checkin a checked out IKE_SA!"); + } + return DESTROY_ME; + } + } } /** @@ -75,16 +117,12 @@ delete_half_open_ike_sa_job_t *delete_half_open_ike_sa_job_create(ike_sa_id_t *i /* interface functions */ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; - /* same as destroy */ - this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy; + this->public.job_interface.execute = (status_t (*) (job_t *)) execute; this->public.job_interface.destroy = (void (*)(job_t *)) destroy;; - /* public functions */ - this->public.get_ike_sa_id = (ike_sa_id_t * (*)(delete_half_open_ike_sa_job_t *)) get_ike_sa_id; - this->public.destroy = (void (*)(delete_half_open_ike_sa_job_t *)) destroy; - /* private variables */ this->ike_sa_id = ike_sa_id->clone(ike_sa_id); + this->logger = logger_manager->get_logger(logger_manager, WORKER); return &(this->public); } diff --git a/src/charon/queues/jobs/delete_half_open_ike_sa_job.h b/src/charon/queues/jobs/delete_half_open_ike_sa_job.h index ea42be8f2..b26750cc1 100644 --- a/src/charon/queues/jobs/delete_half_open_ike_sa_job.h +++ b/src/charon/queues/jobs/delete_half_open_ike_sa_job.h @@ -47,23 +47,6 @@ struct delete_half_open_ike_sa_job_t { * The job_t interface. */ job_t job_interface; - - /** - * @brief Returns the currently set ike_sa_id. - * - * @warning Returned object is not copied. - * - * @param this calling delete_half_open_ike_sa_job_t object - * @return ike_sa_id_t object - */ - ike_sa_id_t * (*get_ike_sa_id) (delete_half_open_ike_sa_job_t *this); - - /** - * @brief Destroys an delete_half_open_ike_sa_job_t object (including assigned data). - * - * @param this delete_half_open_ike_sa_job_t object to destroy - */ - void (*destroy) (delete_half_open_ike_sa_job_t *this); }; /** diff --git a/src/charon/queues/jobs/incoming_packet_job.c b/src/charon/queues/jobs/incoming_packet_job.c index fc71f63ea..834b14bb2 100644 --- a/src/charon/queues/jobs/incoming_packet_job.c +++ b/src/charon/queues/jobs/incoming_packet_job.c @@ -23,7 +23,7 @@ #include "incoming_packet_job.h" - +#include <daemon.h> typedef struct private_incoming_packet_job_t private_incoming_packet_job_t; @@ -40,6 +40,11 @@ struct private_incoming_packet_job_t { * Assigned packet */ packet_t *packet; + + /** + * logger + */ + logger_t *logger; }; /** @@ -51,31 +56,132 @@ static job_type_t get_type(private_incoming_packet_job_t *this) } /** - * Implements incoming_packet_job_t.get_packet. + * Implementation of job_t.execute. */ -static packet_t *get_packet(private_incoming_packet_job_t *this) +static status_t execute(private_incoming_packet_job_t *this) { - return this->packet; + message_t *message; + ike_sa_t *ike_sa; + ike_sa_id_t *ike_sa_id; + status_t status; + packet_t *packet; + + message = message_create_from_packet(this->packet->clone(this->packet)); + status = message->parse_header(message); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Message header could not be verified!"); + message->destroy(message); + return DESTROY_ME; + } + + this->logger->log(this->logger, CONTROL|LEVEL2, "Message is a %s %s", + mapping_find(exchange_type_m, message->get_exchange_type(message)), + message->get_request(message) ? "request" : "reply"); + + if ((message->get_major_version(message) != IKE_MAJOR_VERSION) || + (message->get_minor_version(message) != IKE_MINOR_VERSION)) + { + this->logger->log(this->logger, ERROR | LEVEL2, + "IKE version %d.%d not supported", + message->get_major_version(message), + message->get_minor_version(message)); + if ((message->get_exchange_type(message) == IKE_SA_INIT) && (message->get_request(message))) + { + message_t *response; + message->get_ike_sa_id(message, &ike_sa_id); + ike_sa_id->switch_initiator(ike_sa_id); + response = message_create_notify_reply(message->get_destination(message), + message->get_source(message), + IKE_SA_INIT, FALSE, ike_sa_id, + INVALID_MAJOR_VERSION); + message->destroy(message); + ike_sa_id->destroy(ike_sa_id); + status = response->generate(response, NULL, NULL, &packet); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not generate packet from message"); + response->destroy(response); + return DESTROY_ME; + } + this->logger->log(this->logger, ERROR, "Send notify reply of type INVALID_MAJOR_VERSION"); + charon->send_queue->add(charon->send_queue, packet); + response->destroy(response); + return DESTROY_ME; + } + message->destroy(message); + return DESTROY_ME; + } + + message->get_ike_sa_id(message, &ike_sa_id); + ike_sa_id->switch_initiator(ike_sa_id); + this->logger->log(this->logger, CONTROL|LEVEL3, "Checking out IKE SA %lld:%lld, role %s", + ike_sa_id->get_initiator_spi(ike_sa_id), + ike_sa_id->get_responder_spi(ike_sa_id), + ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder"); + + status = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id, &ike_sa); + if ((status != SUCCESS) && (status != CREATED)) + { + this->logger->log(this->logger, ERROR, "IKE SA could not be checked out"); + ike_sa_id->destroy(ike_sa_id); + message->destroy(message); + + /* TODO: send notify reply of type INVALID_IKE_SPI if SPI could not be found ? */ + return DESTROY_ME; + } + + if (status == CREATED) + { + job_t *delete_job; + this->logger->log(this->logger, CONTROL|LEVEL3, + "Create Job to delete half open IKE_SA."); + + delete_job = (job_t *) delete_half_open_ike_sa_job_create(ike_sa_id); + charon->event_queue->add_relative(charon->event_queue, delete_job, + charon->configuration->get_half_open_ike_sa_timeout(charon->configuration)); + } + + status = ike_sa->process_message(ike_sa, message); + + this->logger->log(this->logger, CONTROL|LEVEL3, "%s IKE SA %lld:%lld, role %s", + status == DESTROY_ME ? "Checkin and delete" : "Checkin", + ike_sa_id->get_initiator_spi(ike_sa_id), + ike_sa_id->get_responder_spi(ike_sa_id), + ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder"); + ike_sa_id->destroy(ike_sa_id); + + if (status == DESTROY_ME) + { + status = charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); + } + else + { + status = charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + } + + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Checkin of IKE SA failed!"); + } + message->destroy(message); + return DESTROY_ME; } /** - * Implements job_t.destroy_all. + * Implements incoming_packet_job_t.get_packet. */ -static void destroy_all(private_incoming_packet_job_t *this) +static packet_t* get_packet(private_incoming_packet_job_t *this) { - if (this->packet != NULL) - { - this->packet->destroy(this->packet); - } - free(this); + return this->packet; } /** * Implements job_t.destroy. */ -static void destroy(job_t *job) +static void destroy(private_incoming_packet_job_t *this) { - private_incoming_packet_job_t *this = (private_incoming_packet_job_t *) job; + this->packet->destroy(this->packet); free(this); } @@ -88,15 +194,14 @@ incoming_packet_job_t *incoming_packet_job_create(packet_t *packet) /* interface functions */ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; - this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy_all; - this->public.job_interface.destroy = destroy; + this->public.job_interface.execute = (status_t (*) (job_t *)) execute; + this->public.job_interface.destroy = (void(*)(job_t*))destroy; - /* public functions */ - this->public.get_packet = (packet_t * (*)(incoming_packet_job_t *)) get_packet; - this->public.destroy = (void (*)(incoming_packet_job_t *)) destroy; + this->public.get_packet = (packet_t*(*)(incoming_packet_job_t*)) get_packet; /* private variables */ this->packet = packet; + this->logger = logger_manager->get_logger(logger_manager, WORKER); return &(this->public); } diff --git a/src/charon/queues/jobs/incoming_packet_job.h b/src/charon/queues/jobs/incoming_packet_job.h index e3fb5797e..93d8febc9 100644 --- a/src/charon/queues/jobs/incoming_packet_job.h +++ b/src/charon/queues/jobs/incoming_packet_job.h @@ -48,21 +48,12 @@ struct incoming_packet_job_t { job_t job_interface; /** - * @brief Returns the assigned packet_t object - * - * @warning Returned packet is not cloned and has to get destroyed by the caller. + * @brief Get associated packet. * - * @param this calling incoming_packet_job_t object - * @return assigned packet + * @param this calling object + * @return associated packet */ - packet_t *(*get_packet) (incoming_packet_job_t *this); - - /** - * @brief Destroys an incoming_packet_job_t object. - * - * @param this incoming_packet_job_t object to destroy - */ - void (*destroy) (incoming_packet_job_t *this); + packet_t *(*get_packet)(incoming_packet_job_t *this); }; /** diff --git a/src/charon/queues/jobs/initiate_ike_sa_job.c b/src/charon/queues/jobs/initiate_ike_sa_job.c index ac9ace36c..fa8513659 100644 --- a/src/charon/queues/jobs/initiate_ike_sa_job.c +++ b/src/charon/queues/jobs/initiate_ike_sa_job.c @@ -25,7 +25,7 @@ #include "initiate_ike_sa_job.h" - +#include <daemon.h> typedef struct private_initiate_ike_sa_job_t private_initiate_ike_sa_job_t; @@ -42,9 +42,13 @@ struct private_initiate_ike_sa_job_t { * associated connection object to initiate */ connection_t *connection; + + /** + * logger + */ + logger_t *logger; }; - /** * Implements initiate_ike_sa_job_t.get_type. */ @@ -54,20 +58,46 @@ static job_type_t get_type(private_initiate_ike_sa_job_t *this) } /** - * Implements initiate_ike_sa_job_t.get_configuration_name. + * Implementation of job_t.execute. */ -static connection_t *get_connection(private_initiate_ike_sa_job_t *this) +static status_t execute(private_initiate_ike_sa_job_t *this) { - return this->connection; -} + /* + * Initiatie an IKE_SA: + * - is defined by a name of a configuration + * - create an empty IKE_SA via manager + * - call initiate_connection on this sa + */ + ike_sa_t *ike_sa; + status_t status; + job_t *delete_job; + + this->logger->log(this->logger, CONTROL|LEVEL2, "Creating and checking out IKE SA"); + charon->ike_sa_manager->create_and_checkout(charon->ike_sa_manager, &ike_sa); + + status = ike_sa->initiate_connection(ike_sa, this->connection->clone(this->connection)); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Initiation returned %s, going to delete IKE_SA.", + mapping_find(status_m, status)); + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); + return DESTROY_ME; + } + + this->logger->log(this->logger, CONTROL|LEVEL3, "Create Job to delete half open IKE_SA."); + + delete_job = (job_t *) delete_half_open_ike_sa_job_create(ike_sa->get_id(ike_sa)); + charon->event_queue->add_relative(charon->event_queue, delete_job, + charon->configuration->get_half_open_ike_sa_timeout(charon->configuration)); -/** - * Implements job_t.destroy. - */ -static void destroy_all(private_initiate_ike_sa_job_t *this) -{ - this->connection->destroy(this->connection); - free(this); + this->logger->log(this->logger, CONTROL|LEVEL2, "Checking in IKE SA"); + status = charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Could not checkin IKE_SA (%s)", + mapping_find(status_m, status)); + } + return DESTROY_ME; } /** @@ -75,6 +105,7 @@ static void destroy_all(private_initiate_ike_sa_job_t *this) */ static void destroy(private_initiate_ike_sa_job_t *this) { + this->connection->destroy(this->connection); free(this); } @@ -87,15 +118,12 @@ initiate_ike_sa_job_t *initiate_ike_sa_job_create(connection_t *connection) /* interface functions */ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; - this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy_all; + this->public.job_interface.execute = (status_t (*) (job_t *)) execute; this->public.job_interface.destroy = (void (*) (job_t *)) destroy; - /* public functions */ - this->public.get_connection = (connection_t* (*)(initiate_ike_sa_job_t *)) get_connection; - this->public.destroy = (void (*)(initiate_ike_sa_job_t *)) destroy; - /* private variables */ this->connection = connection; + this->logger = logger_manager->get_logger(logger_manager, WORKER); return &(this->public); } diff --git a/src/charon/queues/jobs/initiate_ike_sa_job.h b/src/charon/queues/jobs/initiate_ike_sa_job.h index cee31f07b..24f4a89a7 100644 --- a/src/charon/queues/jobs/initiate_ike_sa_job.h +++ b/src/charon/queues/jobs/initiate_ike_sa_job.h @@ -45,21 +45,6 @@ struct initiate_ike_sa_job_t { * implements job_t interface */ job_t job_interface; - - /** - * @brief Returns the connection_t to initialize - * - * @param this calling initiate_ike_sa_job_t object - * @return connection_t - */ - connection_t *(*get_connection) (initiate_ike_sa_job_t *this); - - /** - * @brief Destroys an initiate_ike_sa_job_t object. - * - * @param this initiate_ike_sa_job_t object to destroy - */ - void (*destroy) (initiate_ike_sa_job_t *this); }; /** diff --git a/src/charon/queues/jobs/job.h b/src/charon/queues/jobs/job.h index eea4da09e..d7531531d 100644 --- a/src/charon/queues/jobs/job.h +++ b/src/charon/queues/jobs/job.h @@ -32,43 +32,57 @@ typedef enum job_type_t job_type_t; /** * @brief Definition of the various job types. * - * @todo add more jobs, such as rekeying. - * * @ingroup jobs */ enum job_type_t { /** * Process an incoming IKEv2-Message. * - * Job is implemented in class type incoming_packet_job_t + * Job is implemented in class incoming_packet_job_t */ INCOMING_PACKET, /** * Retransmit an IKEv2-Message. + * + * Job is implemented in class retransmit_request_job_t */ RETRANSMIT_REQUEST, /** * Establish an ike sa as initiator. * - * Job is implemented in class type initiate_ike_sa_job_t + * Job is implemented in class initiate_ike_sa_job_t */ INITIATE_IKE_SA, /** * Delete an ike sa which is still not established. * - * Job is implemented in class type delete_half_open_ike_sa_job_t + * Job is implemented in class delete_half_open_ike_sa_job_t */ DELETE_HALF_OPEN_IKE_SA, /** * Delete an ike sa which is established. * - * Job is implemented in class type delete_established_ike_sa_job_t + * Job is implemented in class delete_established_ike_sa_job_t */ - DELETE_ESTABLISHED_IKE_SA + DELETE_ESTABLISHED_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, }; /** @@ -102,11 +116,16 @@ struct job_t { job_type_t (*get_type) (job_t *this); /** - * @brief Destroys a job_t object and all assigned data! + * @brief Execute a job. * - * @param job_t calling object + * 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 */ - void (*destroy_all) (job_t *job); + status_t (*execute) (job_t *this); /** * @brief Destroys a job_t object @@ -117,4 +136,4 @@ struct job_t { }; -#endif /*JOB_H_*/ +#endif /* JOB_H_ */ diff --git a/src/charon/queues/jobs/rekey_child_sa_job.c b/src/charon/queues/jobs/rekey_child_sa_job.c new file mode 100644 index 000000000..69b1342a5 --- /dev/null +++ b/src/charon/queues/jobs/rekey_child_sa_job.c @@ -0,0 +1,105 @@ +/** + * @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 sa, as used in the kernel + */ + u_int32_t reqid; + + /** + * Logger ref + */ + logger_t *logger; +}; + +/** + * 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; + status_t status; + + status = charon->ike_sa_manager->checkout_by_reqid(charon->ike_sa_manager, this->reqid, &ike_sa); + if (status != SUCCESS) + { + this->logger->log(this->logger, CONTROL, "CHILD SA didn't exist anymore"); + return DESTROY_ME; + } + + /* TODO */ + + status = 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) +{ + 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->logger = logger_manager->get_logger(logger_manager, WORKER); + + return &(this->public); +} diff --git a/src/charon/queues/jobs/rekey_child_sa_job.h b/src/charon/queues/jobs/rekey_child_sa_job.h new file mode 100644 index 000000000..2492b2b46 --- /dev/null +++ b/src/charon/queues/jobs/rekey_child_sa_job.h @@ -0,0 +1,63 @@ +/** + * @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_ + +#include <types.h> +#include <sa/ike_sa_id.h> +#include <queues/jobs/job.h> + + +typedef struct rekey_child_sa_job_t rekey_child_sa_job_t; + +/** + * @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. + * + * To find the targeted CHILD_SA, the uniqe reqid used in + * the kernel is used. + * + * @param reqid reqid CHILD_SA to rekey + * @return rekey_child_sa_job_t object + * + * @ingroup jobs + */ +rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid); + +#endif /* REKEY_CHILD_SA_JOB_H_ */ diff --git a/src/charon/queues/jobs/retransmit_request_job.c b/src/charon/queues/jobs/retransmit_request_job.c index e171df5bd..f89d2adaf 100644 --- a/src/charon/queues/jobs/retransmit_request_job.c +++ b/src/charon/queues/jobs/retransmit_request_job.c @@ -22,8 +22,7 @@ #include "retransmit_request_job.h" - - +#include <daemon.h> typedef struct private_retransmit_request_job_t private_retransmit_request_job_t; @@ -50,9 +49,13 @@ struct private_retransmit_request_job_t { * Number of times a request was retransmitted */ u_int32_t retransmit_count; + + /** + * Logger reference + */ + logger_t *logger; }; - /** * Implements job_t.get_type. */ @@ -62,39 +65,65 @@ static job_type_t get_type(private_retransmit_request_job_t *this) } /** - * Implements retransmit_request_job_t.get_ike_sa_id. - */ -static ike_sa_id_t *get_ike_sa_id(private_retransmit_request_job_t *this) -{ - return this->ike_sa_id; -} - -/** - * Implements retransmit_request_job_t.get_retransmit_count. - */ -static u_int32_t get_retransmit_count(private_retransmit_request_job_t *this) -{ - return this->retransmit_count; -} - -/** - * Implements retransmit_request_job_t.increase_retransmit_count. + * Implementation of job_t.execute. */ -static void increase_retransmit_count(private_retransmit_request_job_t *this) +static status_t execute(private_retransmit_request_job_t *this) { + bool stop_retransmitting = FALSE; + u_int32_t timeout; + ike_sa_t *ike_sa; + status_t status; + + this->logger->log(this->logger, CONTROL|LEVEL2, "Checking out IKE SA %lld:%lld, role %s", + this->ike_sa_id->get_initiator_spi(this->ike_sa_id), + this->ike_sa_id->get_responder_spi(this->ike_sa_id), + this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder"); + + status = charon->ike_sa_manager->checkout(charon->ike_sa_manager, this->ike_sa_id, &ike_sa); + if ((status != SUCCESS) && (status != CREATED)) + { + this->logger->log(this->logger, ERROR|LEVEL1, + "IKE SA could not be checked out. Already deleted?"); + return DESTROY_ME; + } + + status = ike_sa->retransmit_request(ike_sa, this->message_id); + if (status != SUCCESS) + { + this->logger->log(this->logger, CONTROL|LEVEL3, + "Message doesn't have to be retransmitted"); + stop_retransmitting = TRUE; + } + + this->logger->log(this->logger, CONTROL|LEVEL2, "Checkin IKE SA %lld:%lld, role %s", + this->ike_sa_id->get_initiator_spi(this->ike_sa_id), + this->ike_sa_id->get_responder_spi(this->ike_sa_id), + this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder"); + + status = charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + if (status != SUCCESS) + { + this->logger->log(this->logger, ERROR, "Checkin of IKE SA failed!"); + } + + if (stop_retransmitting) + { + return DESTROY_ME; + } + this->retransmit_count++; + status = charon->configuration->get_retransmit_timeout(charon->configuration, + this->retransmit_count, &timeout); + if (status != SUCCESS) + { + this->logger->log(this->logger, CONTROL|LEVEL2, "Message will not be retransmitted anymore"); + return DESTROY_ME; + } + charon->event_queue->add_relative(charon->event_queue, (job_t *)this, timeout); + return SUCCESS; } /** - * Implements retransmit_request_job_t.get_message_id. - */ -static u_int32_t get_message_id(private_retransmit_request_job_t *this) -{ - return this->message_id; -} - - -/** * Implements job_t.destroy. */ static void destroy(private_retransmit_request_job_t *this) @@ -112,21 +141,14 @@ retransmit_request_job_t *retransmit_request_job_create(u_int32_t message_id,ike /* interface functions */ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; - /* same as destroy */ - this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy; + this->public.job_interface.execute = (status_t (*) (job_t *)) execute; this->public.job_interface.destroy = (void (*) (job_t *)) destroy; - - /* public functions */ - this->public.get_ike_sa_id = (ike_sa_id_t * (*)(retransmit_request_job_t *)) get_ike_sa_id; - this->public.get_message_id = (u_int32_t (*)(retransmit_request_job_t *)) get_message_id; - this->public.destroy = (void (*)(retransmit_request_job_t *)) destroy; - this->public.get_retransmit_count = (u_int32_t (*)(retransmit_request_job_t *)) get_retransmit_count; - this->public.increase_retransmit_count = (void (*)(retransmit_request_job_t *)) increase_retransmit_count; - + /* private variables */ this->message_id = message_id; this->retransmit_count = 0; this->ike_sa_id = ike_sa_id->clone(ike_sa_id); + this->logger = logger_manager->get_logger(logger_manager, WORKER); return &(this->public); } diff --git a/src/charon/queues/jobs/retransmit_request_job.h b/src/charon/queues/jobs/retransmit_request_job.h index 2349d3f5e..c34484b99 100644 --- a/src/charon/queues/jobs/retransmit_request_job.h +++ b/src/charon/queues/jobs/retransmit_request_job.h @@ -47,48 +47,6 @@ struct retransmit_request_job_t { * The job_t interface. */ job_t job_interface; - - /** - * @brief Returns the retransmit count for a specific request. - * - * @param this calling retransmit_request_job_t object - * @return retransmit count of request - */ - u_int32_t (*get_retransmit_count) (retransmit_request_job_t *this); - - /** - * @brief Increases number of retransmitt attemps. - * - * @param this calling retransmit_request_job_t object - */ - void (*increase_retransmit_count) (retransmit_request_job_t *this); - - /** - * @brief Returns the message_id of the request to be resent - * - * @param this calling retransmit_request_job_t object - * @return message id of the request to resend - */ - u_int32_t (*get_message_id) (retransmit_request_job_t *this); - - /** - * @brief Returns the ike_sa_id_t object of the IKE_SA - * which the request belongs to - * - * @warning returned ike_sa_id_t object is getting destroyed in - * retransmit_request_job_t.destroy. - * - * @param this calling retransmit_request_job_t object - * @return ike_sa_id_t object to identify IKE_SA (gets NOT cloned) - */ - ike_sa_id_t *(*get_ike_sa_id) (retransmit_request_job_t *this); - - /** - * @brief Destroys an retransmit_request_job_t object. - * - * @param this retransmit_request_job_t object to destroy - */ - void (*destroy) (retransmit_request_job_t *this); }; /** @@ -100,6 +58,7 @@ struct retransmit_request_job_t { * * @ingroup jobs */ -retransmit_request_job_t *retransmit_request_job_create(u_int32_t message_id,ike_sa_id_t *ike_sa_id); +retransmit_request_job_t *retransmit_request_job_create(u_int32_t message_id, + ike_sa_id_t *ike_sa_id); #endif /* RESEND_MESSAGE_JOB_H_ */ |