diff options
Diffstat (limited to 'Source')
25 files changed, 504 insertions, 119 deletions
diff --git a/Source/charon/config/configuration_manager.c b/Source/charon/config/configuration_manager.c index 83f68eafc..c522ff67c 100644 --- a/Source/charon/config/configuration_manager.c +++ b/Source/charon/config/configuration_manager.c @@ -207,6 +207,11 @@ struct private_configuration_manager_t { * First retransmit timeout in ms. */ u_int32_t first_retransmit_timeout; + + /** + * Timeout in ms after that time a IKE_SA gets deleted. + */ + u_int32_t half_open_ike_sa_timeout; /** * Adds a new IKE_SA configuration. @@ -308,21 +313,24 @@ static void load_default_config (private_configuration_manager_t *this) sa_config1 = sa_config_create(ID_IPV4_ADDR, "152.96.193.130", ID_IPV4_ADDR, "152.96.193.131", - SHARED_KEY_MESSAGE_INTEGRITY_CODE); + SHARED_KEY_MESSAGE_INTEGRITY_CODE, + 30000); sa_config1->add_traffic_selector_initiator(sa_config1,ts); sa_config1->add_traffic_selector_responder(sa_config1,ts); sa_config2 = sa_config_create(ID_IPV4_ADDR, "152.96.193.131", ID_IPV4_ADDR, "152.96.193.130", - SHARED_KEY_MESSAGE_INTEGRITY_CODE); + SHARED_KEY_MESSAGE_INTEGRITY_CODE, + 30000); sa_config2->add_traffic_selector_initiator(sa_config2,ts); sa_config2->add_traffic_selector_responder(sa_config2,ts); sa_config3 = sa_config_create(ID_IPV4_ADDR, "127.0.0.1", ID_IPV4_ADDR, "127.0.0.1", - RSA_DIGITAL_SIGNATURE); + RSA_DIGITAL_SIGNATURE, + 30000); sa_config3->add_traffic_selector_initiator(sa_config3,ts); sa_config3->add_traffic_selector_responder(sa_config3,ts); @@ -715,7 +723,7 @@ static status_t get_rsa_private_key(private_configuration_manager_t *this, ident } /** - * Implementation of configuration_manager_t.destroy. + * Implementation of configuration_manager_t.get_retransmit_timeout. */ static status_t get_retransmit_timeout (private_configuration_manager_t *this, u_int32_t retransmit_count, u_int32_t *timeout) { @@ -733,6 +741,14 @@ static status_t get_retransmit_timeout (private_configuration_manager_t *this, u } /** + * Implementation of configuration_manager_t.get_half_open_ike_sa_timeout. + */ +static u_int32_t get_half_open_ike_sa_timeout (private_configuration_manager_t *this) +{ + return this->half_open_ike_sa_timeout; +} + +/** * Implementation of configuration_manager_t.destroy. */ static void destroy(private_configuration_manager_t *this) @@ -807,7 +823,7 @@ static void destroy(private_configuration_manager_t *this) /* * Described in header-file */ -configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit_timeout,u_int32_t max_retransmit_count) +configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit_timeout,u_int32_t max_retransmit_count, u_int32_t half_open_ike_sa_timeout) { private_configuration_manager_t *this = allocator_alloc_thing(private_configuration_manager_t); @@ -818,6 +834,7 @@ configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit this->public.get_sa_config_for_name =(status_t (*) (configuration_manager_t *, char *, sa_config_t **)) get_sa_config_for_name; this->public.get_sa_config_for_init_config_and_id =(status_t (*) (configuration_manager_t *, init_config_t *, identification_t *, identification_t *,sa_config_t **)) get_sa_config_for_init_config_and_id; this->public.get_retransmit_timeout = (status_t (*) (configuration_manager_t *, u_int32_t retransmit_count, u_int32_t *timeout))get_retransmit_timeout; + this->public.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_manager_t *)) get_half_open_ike_sa_timeout; this->public.get_shared_secret = (status_t (*) (configuration_manager_t *, identification_t *, chunk_t *))get_shared_secret; this->public.get_rsa_private_key = (status_t (*) (configuration_manager_t *, identification_t *, rsa_private_key_t**))get_rsa_private_key; this->public.get_rsa_public_key = (status_t (*) (configuration_manager_t *, identification_t *, rsa_public_key_t**))get_rsa_public_key; @@ -839,6 +856,7 @@ configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit this->rsa_public_keys = linked_list_create(); this->max_retransmit_count = max_retransmit_count; this->first_retransmit_timeout = first_retransmit_timeout; + this->half_open_ike_sa_timeout = half_open_ike_sa_timeout; this->load_default_config(this); diff --git a/Source/charon/config/configuration_manager.h b/Source/charon/config/configuration_manager.h index 6289bc48c..819367f05 100644 --- a/Source/charon/config/configuration_manager.h +++ b/Source/charon/config/configuration_manager.h @@ -130,6 +130,21 @@ struct configuration_manager_t { status_t (*get_retransmit_timeout) (configuration_manager_t *this, u_int32_t retransmit_count, u_int32_t *timeout); /** + * @brief Returns the timeout for an half open IKE_SA in ms. + * + * Half open means that the IKE_SA is still in one of the following states: + * - INITIATOR_INIT + * - RESPONDER_INIT + * - IKE_SA_INIT_REQUESTED + * - IKE_SA_INIT_RESPONDED + * - IKE_AUTH_REQUESTED + * + * @param this calling object + * @return timeout in milliseconds (ms) + */ + u_int32_t (*get_half_open_ike_sa_timeout) (configuration_manager_t *this); + + /** * @brief Returns the preshared secret of a specific ID. * * The returned preshared secret MUST NOT be destroyed cause it's managed by @@ -192,10 +207,11 @@ struct configuration_manager_t { * * @param first_retransmit_timeout first retransmit timeout in milliseconds * @param max_retransmit_count max number of tries to retransmitted a requests (0 for infinite) + * @param half_open_ike_sa_timeout timeout after that a half open IKE_SA gets deleted * @return * - pointer to created configuration_manager_t object * @ingroup config */ -configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit_timeout,u_int32_t max_retransmit_count); +configuration_manager_t *configuration_manager_create(u_int32_t first_retransmit_timeout,u_int32_t max_retransmit_count, u_int32_t half_open_ike_sa_timeout); #endif /*CONFIGURATION_MANAGER_H_*/ diff --git a/Source/charon/config/sa_config.c b/Source/charon/config/sa_config.c index 623f8be87..9f409ec6d 100644 --- a/Source/charon/config/sa_config.c +++ b/Source/charon/config/sa_config.c @@ -54,6 +54,11 @@ struct private_sa_config_t { auth_method_t auth_method; /** + * Lifetime of IKE_SA in milliseconds. + */ + u_int32_t ike_sa_lifetime; + + /** * list for all proposals */ linked_list_t *proposals; @@ -85,7 +90,7 @@ struct private_sa_config_t { }; /** - * implements sa_config_t.get_my_id + * Implementation of sa_config_t.get_my_id */ static identification_t *get_my_id(private_sa_config_t *this) { @@ -93,7 +98,7 @@ static identification_t *get_my_id(private_sa_config_t *this) } /** - * implements sa_config_t.get_other_id + * Implementation of sa_config_t.get_other_id */ static identification_t *get_other_id(private_sa_config_t *this) { @@ -101,16 +106,23 @@ static identification_t *get_other_id(private_sa_config_t *this) } /** - * implements sa_config_t.get_auth_method + * Implementation of sa_config_t.get_auth_method. */ static auth_method_t get_auth_method(private_sa_config_t *this) { return this->auth_method; } +/** + * Implementation of sa_config_t.get_ike_sa_lifetime. + */ +static u_int32_t get_ike_sa_lifetime (private_sa_config_t *this) +{ + return this->ike_sa_lifetime; +} /** - * implements sa_config_t.get_traffic_selectors_initiator + * Implementation of sa_config_t.get_traffic_selectors_initiator */ static size_t get_traffic_selectors_initiator(private_sa_config_t *this, traffic_selector_t **traffic_selectors[]) { @@ -118,7 +130,7 @@ static size_t get_traffic_selectors_initiator(private_sa_config_t *this, traffic } /** - * implements sa_config_t.get_traffic_selectors_responder + * Implementation of sa_config_t.get_traffic_selectors_responder */ static size_t get_traffic_selectors_responder(private_sa_config_t *this, traffic_selector_t **traffic_selectors[]) { @@ -126,7 +138,7 @@ static size_t get_traffic_selectors_responder(private_sa_config_t *this, traffic } /** - * implements private_sa_config_t.get_traffic_selectors + * Implementation of private_sa_config_t.get_traffic_selectors */ static size_t get_traffic_selectors(private_sa_config_t *this, linked_list_t *ts_list, traffic_selector_t **traffic_selectors[]) { @@ -148,7 +160,7 @@ static size_t get_traffic_selectors(private_sa_config_t *this, linked_list_t *ts } /** - * implements private_sa_config_t.select_traffic_selectors_initiator + * Implementation of private_sa_config_t.select_traffic_selectors_initiator */ static size_t select_traffic_selectors_initiator(private_sa_config_t *this,traffic_selector_t *supplied[], size_t count, traffic_selector_t **selected[]) { @@ -156,14 +168,14 @@ static size_t select_traffic_selectors_initiator(private_sa_config_t *this,traff } /** - * implements private_sa_config_t.select_traffic_selectors_responder + * Implementation of private_sa_config_t.select_traffic_selectors_responder */ static size_t select_traffic_selectors_responder(private_sa_config_t *this,traffic_selector_t *supplied[], size_t count, traffic_selector_t **selected[]) { return this->select_traffic_selectors(this, this->ts_responder, supplied, count, selected); } /** - * implements private_sa_config_t.select_traffic_selectors + * Implementation of private_sa_config_t.select_traffic_selectors */ static size_t select_traffic_selectors(private_sa_config_t *this, linked_list_t *ts_list, traffic_selector_t *supplied[], size_t count, traffic_selector_t **selected[]) { @@ -198,7 +210,7 @@ static size_t select_traffic_selectors(private_sa_config_t *this, linked_list_t } /** - * implements sa_config_t.get_proposals + * Implementation of sa_config_t.get_proposals */ static size_t get_proposals(private_sa_config_t *this, u_int8_t ah_spi[4], u_int8_t esp_spi[4], child_proposal_t **proposals) { @@ -223,7 +235,7 @@ static size_t get_proposals(private_sa_config_t *this, u_int8_t ah_spi[4], u_int } /** - * implements sa_config_t.select_proposal + * Implementation of sa_config_t.select_proposal */ static child_proposal_t *select_proposal(private_sa_config_t *this, u_int8_t ah_spi[4], u_int8_t esp_spi[4], child_proposal_t *supplied, size_t count) { @@ -256,7 +268,7 @@ static child_proposal_t *select_proposal(private_sa_config_t *this, u_int8_t ah_ /** - * implements private_sa_config_t.proposal_equals + * Implementation of private_sa_config_t.proposal_equals */ static bool proposal_equals(private_sa_config_t *this, child_proposal_t *first, child_proposal_t *second) { @@ -333,7 +345,7 @@ static bool proposal_equals(private_sa_config_t *this, child_proposal_t *first, } /** - * implements sa_config_t.add_traffic_selector_initiator + * Implementation of sa_config_t.add_traffic_selector_initiator */ static void add_traffic_selector_initiator(private_sa_config_t *this, traffic_selector_t *traffic_selector) { @@ -342,7 +354,7 @@ static void add_traffic_selector_initiator(private_sa_config_t *this, traffic_se } /** - * implements sa_config_t.add_traffic_selector_responder + * Implementation of sa_config_t.add_traffic_selector_responder */ static void add_traffic_selector_responder(private_sa_config_t *this, traffic_selector_t *traffic_selector) { @@ -351,7 +363,7 @@ static void add_traffic_selector_responder(private_sa_config_t *this, traffic_se } /** - * implements sa_config_t.add_proposal + * Implementation of sa_config_t.add_proposal */ static void add_proposal(private_sa_config_t *this, child_proposal_t *proposal) { @@ -405,7 +417,7 @@ static status_t destroy(private_sa_config_t *this) /* * Described in header-file */ -sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other_id_type, char *other_id, auth_method_t auth_method) +sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other_id_type, char *other_id, auth_method_t auth_method, u_int32_t ike_sa_lifetime) { private_sa_config_t *this = allocator_alloc_thing(private_sa_config_t); @@ -413,6 +425,7 @@ sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other this->public.get_my_id = (identification_t*(*)(sa_config_t*))get_my_id; this->public.get_other_id = (identification_t*(*)(sa_config_t*))get_other_id; this->public.get_auth_method = (auth_method_t(*)(sa_config_t*))get_auth_method; + this->public.get_ike_sa_lifetime = (u_int32_t(*)(sa_config_t*))get_ike_sa_lifetime; this->public.get_traffic_selectors_initiator = (size_t(*)(sa_config_t*,traffic_selector_t**[]))get_traffic_selectors_initiator; this->public.select_traffic_selectors_initiator = (size_t(*)(sa_config_t*,traffic_selector_t*[],size_t,traffic_selector_t**[]))select_traffic_selectors_initiator; this->public.get_traffic_selectors_responder = (size_t(*)(sa_config_t*,traffic_selector_t**[]))get_traffic_selectors_responder; @@ -448,6 +461,7 @@ sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other this->ts_initiator = linked_list_create(); this->ts_responder = linked_list_create(); this->auth_method = auth_method; + this->ike_sa_lifetime = ike_sa_lifetime; return (&this->public); } diff --git a/Source/charon/config/sa_config.h b/Source/charon/config/sa_config.h index 7468d8c5f..be95b4a9f 100644 --- a/Source/charon/config/sa_config.h +++ b/Source/charon/config/sa_config.h @@ -120,6 +120,13 @@ struct sa_config_t { auth_method_t (*get_auth_method) (sa_config_t *this); /** + * @brief Get lifetime of IKE_SA in milliseconds. + * + * @return IKE_SA lifetime in milliseconds. + */ + u_int32_t (*get_ike_sa_lifetime) (sa_config_t *this); + + /** * @brief Get configured traffic selectors for initiator site. * * Returns a pointer to an allocated array, in which @@ -256,10 +263,17 @@ struct sa_config_t { /** * @brief Create a configuration object for IKE_AUTH and later. * - * @return created sa_config_t + * @param my_id_type type of my identification + * @param my_id my identification as string + * @param other_id_type type of other identification + * @param other_id other identification as string + * @param auth_method Method of authentication + * @param ike_sa_lifetime lifetime of this IKE_SA in milliseconds. IKE_SA will be deleted + * after this lifetime! + * @return created sa_config_t * * @ingroup config */ -sa_config_t *sa_config_create(); +sa_config_t *sa_config_create(id_type_t my_id_type, char *my_id, id_type_t other_id_type, char *other_id, auth_method_t auth_method, u_int32_t ike_sa_lifetime); #endif //_SA_CONFIG_H_ diff --git a/Source/charon/daemon.c b/Source/charon/daemon.c index a58525356..560856863 100644 --- a/Source/charon/daemon.c +++ b/Source/charon/daemon.c @@ -158,7 +158,7 @@ static void build_test_jobs(private_daemon_t *this) for(i = 0; i<1; i++) { initiate_ike_sa_job_t *initiate_job; - initiate_job = initiate_ike_sa_job_create("pinflb30"); + initiate_job = initiate_ike_sa_job_create("localhost"); this->public.event_queue->add_relative(this->public.event_queue, (job_t*)initiate_job, i * 5000); } } @@ -173,7 +173,7 @@ static void initialize(private_daemon_t *this) this->public.job_queue = job_queue_create(); this->public.event_queue = event_queue_create(); this->public.send_queue = send_queue_create(); - this->public.configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT); + this->public.configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT, HALF_OPEN_IKE_SA_TIMEOUT); this->public.sender = sender_create(); this->public.receiver = receiver_create(); diff --git a/Source/charon/daemon.h b/Source/charon/daemon.h index 6173b6d08..406e78a27 100644 --- a/Source/charon/daemon.h +++ b/Source/charon/daemon.h @@ -63,6 +63,11 @@ #define RETRANSMIT_TIMEOUT 3000 /** + * Timeout in milliseconds after that a half open IKE_SA gets deleted. + */ +#define HALF_OPEN_IKE_SA_TIMEOUT 30000 + +/** * Max retransmit count. 0 for infinite. */ #define MAX_RETRANSMIT_COUNT 0 diff --git a/Source/charon/queues/jobs/Makefile.jobs b/Source/charon/queues/jobs/Makefile.jobs index d4cbf75cc..658dd1293 100644 --- a/Source/charon/queues/jobs/Makefile.jobs +++ b/Source/charon/queues/jobs/Makefile.jobs @@ -14,8 +14,12 @@ JOBS_DIR= $(QUEUES_DIR)jobs/ -OBJS+= $(BUILD_DIR)delete_ike_sa_job.o -$(BUILD_DIR)delete_ike_sa_job.o : $(JOBS_DIR)delete_ike_sa_job.c $(JOBS_DIR)delete_ike_sa_job.h +OBJS+= $(BUILD_DIR)delete_half_open_ike_sa_job.o +$(BUILD_DIR)delete_half_open_ike_sa_job.o : $(JOBS_DIR)delete_half_open_ike_sa_job.c $(JOBS_DIR)delete_half_open_ike_sa_job.h + $(CC) $(CFLAGS) -c -o $@ $< + +OBJS+= $(BUILD_DIR)delete_established_ike_sa_job.o +$(BUILD_DIR)delete_established_ike_sa_job.o : $(JOBS_DIR)delete_established_ike_sa_job.c $(JOBS_DIR)delete_established_ike_sa_job.h $(CC) $(CFLAGS) -c -o $@ $< OBJS+= $(BUILD_DIR)incoming_packet_job.o diff --git a/Source/charon/queues/jobs/delete_established_ike_sa_job.c b/Source/charon/queues/jobs/delete_established_ike_sa_job.c new file mode 100644 index 000000000..809980550 --- /dev/null +++ b/Source/charon/queues/jobs/delete_established_ike_sa_job.c @@ -0,0 +1,92 @@ +/** + * @file delete_established_ike_sa_job.c + * + * @brief Implementation of delete_established_ike_sa_job_t. + * + */ + +/* + * Copyright (C) 2005 Jan Hutter, 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_established_ike_sa_job.h" + +#include <utils/allocator.h> + + +typedef struct private_delete_established_ike_sa_job_t private_delete_established_ike_sa_job_t; + +/** + * Private data of an delete_established_ike_sa_job_t object. + */ +struct private_delete_established_ike_sa_job_t { + /** + * Public delete_established_ike_sa_job_t interface. + */ + delete_established_ike_sa_job_t public; + + /** + * ID of the ike_sa to delete. + */ + ike_sa_id_t *ike_sa_id; +}; + +/** + * Implementation of job_t.get_type. + */ +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 + */ +static ike_sa_id_t *get_ike_sa_id(private_delete_established_ike_sa_job_t *this) +{ + return this->ike_sa_id; +} + +/** + * Implementation of job_t.destroy. + */ +static void destroy(job_t *job) +{ + private_delete_established_ike_sa_job_t *this = (private_delete_established_ike_sa_job_t *) job; + this->ike_sa_id->destroy(this->ike_sa_id); + allocator_free(this); +} + +/* + * Described in header + */ +delete_established_ike_sa_job_t *delete_established_ike_sa_job_create(ike_sa_id_t *ike_sa_id) +{ + private_delete_established_ike_sa_job_t *this = allocator_alloc_thing(private_delete_established_ike_sa_job_t); + + /* 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.destroy = 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); + + return &(this->public); +} diff --git a/Source/charon/queues/jobs/delete_established_ike_sa_job.h b/Source/charon/queues/jobs/delete_established_ike_sa_job.h new file mode 100644 index 000000000..c2e1d8db1 --- /dev/null +++ b/Source/charon/queues/jobs/delete_established_ike_sa_job.h @@ -0,0 +1,75 @@ +/** + * @file delete_established_ike_sa_job.h + * + * @brief Interface of delete_established_ike_sa_job_t. + * + */ + +/* + * Copyright (C) 2005 Jan Hutter, 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_ESTABLISHED_IKE_SA_JOB_H_ +#define DELETE_ESTABLISHED_IKE_SA_JOB_H_ + +#include <types.h> +#include <sa/ike_sa_id.h> +#include <queues/jobs/job.h> + + +typedef struct delete_established_ike_sa_job_t delete_established_ike_sa_job_t; + +/** + * @brief Class representing an DELETE_ESTABLISHED_IKE_SA Job. + * + * @b Constructors: + * - delete_established_ike_sa_job_create() + * + * @ingroup jobs + */ +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); +}; + +/** + * @brief Creates a job of type DELETE_ESTABLISHED_IKE_SA. + * + * @param ike_sa_id id of the IKE_SA to delete + * @return created delete_established_ike_sa_job_t object + * + * @ingroup jobs + */ +delete_established_ike_sa_job_t *delete_established_ike_sa_job_create(ike_sa_id_t *ike_sa_id); + +#endif /*DELETE_ESTABLISHED_IKE_SA_JOB_H_*/ diff --git a/Source/charon/queues/jobs/delete_established_ike_sa_job.o b/Source/charon/queues/jobs/delete_established_ike_sa_job.o Binary files differnew file mode 100644 index 000000000..bfd0c9d98 --- /dev/null +++ b/Source/charon/queues/jobs/delete_established_ike_sa_job.o diff --git a/Source/charon/queues/jobs/delete_ike_sa_job.c b/Source/charon/queues/jobs/delete_half_open_ike_sa_job.c index ee0118674..d37cb98c4 100644 --- a/Source/charon/queues/jobs/delete_ike_sa_job.c +++ b/Source/charon/queues/jobs/delete_half_open_ike_sa_job.c @@ -1,7 +1,7 @@ /** - * @file delete_ike_sa_job.h + * @file delete_half_open_ike_sa_job.c * - * @brief Implementation of delete_ike_sa_job_t. + * @brief Implementation of delete_half_open_ike_sa_job_t. * */ @@ -20,21 +20,21 @@ * for more details. */ -#include "delete_ike_sa_job.h" +#include "delete_half_open_ike_sa_job.h" #include <utils/allocator.h> -typedef struct private_delete_ike_sa_job_t private_delete_ike_sa_job_t; +typedef struct private_delete_half_open_ike_sa_job_t private_delete_half_open_ike_sa_job_t; /** - * Private data of an delete_ike_sa_job_t Object + * Private data of an delete_half_open_ike_sa_job_t Object */ -struct private_delete_ike_sa_job_t { +struct private_delete_half_open_ike_sa_job_t { /** - * public delete_ike_sa_job_t interface + * public delete_half_open_ike_sa_job_t interface */ - delete_ike_sa_job_t public; + delete_half_open_ike_sa_job_t public; /** * ID of the ike_sa to delete @@ -45,15 +45,15 @@ struct private_delete_ike_sa_job_t { /** * Implements job_t.get_type. */ -static job_type_t get_type(private_delete_ike_sa_job_t *this) +static job_type_t get_type(private_delete_half_open_ike_sa_job_t *this) { - return DELETE_IKE_SA; + return DELETE_HALF_OPEN_IKE_SA; } /** * Implements elete_ike_sa_job_t.get_ike_sa_id */ -static ike_sa_id_t *get_ike_sa_id(private_delete_ike_sa_job_t *this) +static ike_sa_id_t *get_ike_sa_id(private_delete_half_open_ike_sa_job_t *this) { return this->ike_sa_id; } @@ -63,7 +63,7 @@ static ike_sa_id_t *get_ike_sa_id(private_delete_ike_sa_job_t *this) */ static void destroy(job_t *job) { - private_delete_ike_sa_job_t *this = (private_delete_ike_sa_job_t *) job; + private_delete_half_open_ike_sa_job_t *this = (private_delete_half_open_ike_sa_job_t *) job; this->ike_sa_id->destroy(this->ike_sa_id); allocator_free(this); } @@ -71,9 +71,9 @@ static void destroy(job_t *job) /* * Described in header */ -delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id) +delete_half_open_ike_sa_job_t *delete_half_open_ike_sa_job_create(ike_sa_id_t *ike_sa_id) { - private_delete_ike_sa_job_t *this = allocator_alloc_thing(private_delete_ike_sa_job_t); + private_delete_half_open_ike_sa_job_t *this = allocator_alloc_thing(private_delete_half_open_ike_sa_job_t); /* interface functions */ this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; @@ -82,8 +82,8 @@ delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id) this->public.job_interface.destroy = destroy; /* public functions */ - this->public.get_ike_sa_id = (ike_sa_id_t * (*)(delete_ike_sa_job_t *)) get_ike_sa_id; - this->public.destroy = (void (*)(delete_ike_sa_job_t *)) destroy; + 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); diff --git a/Source/charon/queues/jobs/delete_ike_sa_job.h b/Source/charon/queues/jobs/delete_half_open_ike_sa_job.h index e4e254370..39b75183a 100644 --- a/Source/charon/queues/jobs/delete_ike_sa_job.h +++ b/Source/charon/queues/jobs/delete_half_open_ike_sa_job.h @@ -1,7 +1,7 @@ /** - * @file delete_ike_sa_job.h + * @file delete_half_open_ike_sa_job.h * - * @brief Interface of delete_ike_sa_job_t. + * @brief Interface of delete_half_open_ike_sa_job_t. * */ @@ -20,24 +20,27 @@ * for more details. */ -#ifndef DELETE_IKE_SA_JOB_H_ -#define DELETE_IKE_SA_JOB_H_ +#ifndef DELETE_HALF_OPEN_IKE_SA_JOB_H_ +#define DELETE_HALF_OPEN_IKE_SA_JOB_H_ #include <types.h> #include <sa/ike_sa_id.h> #include <queues/jobs/job.h> -typedef struct delete_ike_sa_job_t delete_ike_sa_job_t; +typedef struct delete_half_open_ike_sa_job_t delete_half_open_ike_sa_job_t; /** - * @brief Class representing an DELETE_IKE_SA Job. + * @brief Class representing an DELETE_HALF_OPEN_IKE_SA Job. + * + * @b Constructors: + * - delete_half_open_ike_sa_job_create() * * @ingroup jobs */ -struct delete_ike_sa_job_t { +struct delete_half_open_ike_sa_job_t { /** - * implements job_t interface + * The job_t interface. */ job_t job_interface; @@ -46,27 +49,27 @@ struct delete_ike_sa_job_t { * * @warning Returned object is not copied. * - * @param this calling delete_ike_sa_job_t object + * @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_ike_sa_job_t *this); + ike_sa_id_t * (*get_ike_sa_id) (delete_half_open_ike_sa_job_t *this); /** - * @brief Destroys an delete_ike_sa_job_t object (including assigned data). + * @brief Destroys an delete_half_open_ike_sa_job_t object (including assigned data). * - * @param this delete_ike_sa_job_t object to destroy + * @param this delete_half_open_ike_sa_job_t object to destroy */ - void (*destroy) (delete_ike_sa_job_t *this); + void (*destroy) (delete_half_open_ike_sa_job_t *this); }; /** - * @brief Creates a job of type DELETE_IKE_SA. + * @brief Creates a job of type DELETE_HALF_OPEN_IKE_SA. * * @param ike_sa_id id of the IKE_SA to delete - * @return created delete_ike_sa_job_t object + * @return created delete_half_open_ike_sa_job_t object * * @ingroup jobs */ -delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id); +delete_half_open_ike_sa_job_t *delete_half_open_ike_sa_job_create(ike_sa_id_t *ike_sa_id); -#endif /*DELETE_IKE_SA_JOB_H_*/ +#endif /*DELETE_HALF_OPEN_IKE_SA_JOB_H_*/ diff --git a/Source/charon/queues/jobs/job.c b/Source/charon/queues/jobs/job.c index 6cd7cbdd0..df739f9e5 100644 --- a/Source/charon/queues/jobs/job.c +++ b/Source/charon/queues/jobs/job.c @@ -28,6 +28,7 @@ mapping_t job_type_m[] = { {INCOMING_PACKET, "INCOMING_PACKET"}, {RETRANSMIT_REQUEST, "RETRANSMIT_REQUEST"}, {INITIATE_IKE_SA, "INITIATE_IKE_SA"}, - {DELETE_IKE_SA, "DELETE_IKE_SA"}, + {DELETE_HALF_OPEN_IKE_SA, "DELETE_HALF_OPEN_IKE_SA"}, + {DELETE_ESTABLISHED_IKE_SA, "DELETE_ESTABLISHED_IKE_SA"}, {MAPPING_END, NULL} }; diff --git a/Source/charon/queues/jobs/job.h b/Source/charon/queues/jobs/job.h index 753bea358..89e9c5b60 100644 --- a/Source/charon/queues/jobs/job.h +++ b/Source/charon/queues/jobs/job.h @@ -36,30 +36,37 @@ typedef enum job_type_t job_type_t; */ enum job_type_t { /** - * Process an incoming IKEv2-Message + * Process an incoming IKEv2-Message. * * Job is implemented in class type incoming_packet_job_t */ INCOMING_PACKET, /** - * Retransmit an IKEv2-Message + * Retransmit an IKEv2-Message. */ RETRANSMIT_REQUEST, /** - * Establish an ike sa as initiator + * Establish an ike sa as initiator. * * Job is implemented in class type initiate_ike_sa_job_t */ INITIATE_IKE_SA, /** - * Delete an ike sa + * Delete an ike sa which is still not established. * - * Job is implemented in class type delete_ike_sa_job_t + * Job is implemented in class type delete_half_open_ike_sa_job_t */ - DELETE_IKE_SA + DELETE_HALF_OPEN_IKE_SA, + + /** + * Delete an ike sa which is established. + * + * Job is implemented in class type delete_established_ike_sa_job_t + */ + DELETE_ESTABLISHED_IKE_SA /* more job types have to be inserted here */ diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index 84fb65107..113c0e94b 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -39,8 +39,8 @@ #include <encoding/payloads/transform_attribute.h> #include <sa/states/initiator_init.h> #include <sa/states/responder_init.h> -#include <queues/jobs/delete_ike_sa_job.h> #include <queues/jobs/retransmit_request_job.h> +#include <queues/jobs/delete_established_ike_sa_job.h> @@ -58,13 +58,6 @@ struct private_ike_sa_t { protected_ike_sa_t protected; /** - * Creates a job to delete the given IKE_SA. - * - * @param this calling object - */ - status_t (*create_delete_job) (private_ike_sa_t *this); - - /** * Resends the last sent reply. * * @param this calling object @@ -518,22 +511,6 @@ status_t retransmit_request (private_ike_sa_t *this, u_int32_t message_id) return SUCCESS; } - -/** - * Implementation of private_ike_sa_t.resend_last_reply. - */ -static status_t create_delete_job(private_ike_sa_t *this) -{ - job_t *delete_job; - - this->logger->log(this->logger, CONTROL | MORE, "Going to create job to delete this IKE_SA"); - - delete_job = (job_t *) delete_ike_sa_job_create(this->ike_sa_id); - charon->job_queue->add(charon->job_queue,delete_job); - - return SUCCESS; -} - /** * Implementation of protected_ike_sa_t.set_new_state. */ @@ -867,6 +844,11 @@ static message_t * get_last_requested_message (private_ike_sa_t *this) return this->last_requested_message; } +static ike_sa_state_t get_state (private_ike_sa_t *this) +{ + return this->current_state->get_state(this->current_state); +} + /** * Implementation of protected_ike_sa_t.reset_message_buffers. */ @@ -892,6 +874,16 @@ static void reset_message_buffers (private_ike_sa_t *this) this->last_replied_message_id = -1; } +static void create_delete_established_ike_sa_job (private_ike_sa_t *this,u_int32_t timeout) +{ + job_t *delete_job; + + this->logger->log(this->logger, CONTROL | MORE, "Going to create job to delete established IKE_SA in %d ms", timeout); + + delete_job = (job_t *) delete_established_ike_sa_job_create(this->ike_sa_id); + charon->event_queue->add_relative(charon->event_queue,delete_job, timeout); +} + /** * Implementation of protected_ike_sa_t.destroy. */ @@ -1005,6 +997,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->protected.public.initialize_connection = (status_t(*)(ike_sa_t*, char*)) initialize_connection; this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id; this->protected.public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request; + this->protected.public.get_state = (ike_sa_state_t (*) (ike_sa_t *this)) get_state; this->protected.public.destroy = (void(*)(ike_sa_t*))destroy; /* protected functions */ @@ -1034,12 +1027,12 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t *)) reset_message_buffers; this->protected.get_last_responded_message = (message_t * (*) (protected_ike_sa_t *this)) get_last_responded_message; this->protected.get_last_requested_message = (message_t * (*) (protected_ike_sa_t *this)) get_last_requested_message; + this->protected.create_delete_established_ike_sa_job = (void (*) (protected_ike_sa_t *this,u_int32_t)) create_delete_established_ike_sa_job; this->protected.set_last_replied_message_id = (void (*) (protected_ike_sa_t *,u_int32_t)) set_last_replied_message_id; /* private functions */ this->resend_last_reply = resend_last_reply; - this->create_delete_job = create_delete_job; /* initialize private fields */ this->logger = charon->logger_manager->create_logger(charon->logger_manager, IKE_SA, NULL); diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index ffc9bd2f4..af3be504f 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -88,6 +88,14 @@ struct ike_sa_t { * @return ike_sa's ike_sa_id_t */ ike_sa_id_t* (*get_id) (ike_sa_t *this); + + /** + * @brief Get the state of type of associated state object. + * + * @param this ike_sa_t object object + * @return state of IKE_SA + */ + ike_sa_state_t (*get_state) (ike_sa_t *this); /** * @brief Destroys a ike_sa_t object. @@ -375,7 +383,16 @@ struct protected_ike_sa_t { * @param this calling object */ void (*reset_message_buffers) (protected_ike_sa_t *this); - + + /** + * Creates a job of type DELETE_ESTABLISHED_IKE_SA for the current IKE_SA. + * + * + * @param this calling object + * @param timeout timeout after the IKE_SA gets deleted + * + */ + void (*create_delete_established_ike_sa_job) (protected_ike_sa_t *this,u_int32_t timeout); }; diff --git a/Source/charon/sa/ike_sa_manager.c b/Source/charon/sa/ike_sa_manager.c index c2bc365f7..82a54dafb 100644 --- a/Source/charon/sa/ike_sa_manager.c +++ b/Source/charon/sa/ike_sa_manager.c @@ -466,7 +466,7 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, new_ike_sa_entry->checked_out = TRUE; *ike_sa = new_ike_sa_entry->ike_sa; - retval = SUCCESS; + retval = CREATED; } else { diff --git a/Source/charon/sa/ike_sa_manager.h b/Source/charon/sa/ike_sa_manager.h index e86cfe83c..c001afb14 100644 --- a/Source/charon/sa/ike_sa_manager.h +++ b/Source/charon/sa/ike_sa_manager.h @@ -59,6 +59,7 @@ struct ike_sa_manager_t { * @returns * - SUCCESS if checkout successful * - NOT_FOUND when no such SA is available + * - CREATED if a new IKE_SA got created */ status_t (*checkout) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *sa_id, ike_sa_t **ike_sa); diff --git a/Source/charon/sa/states/ike_auth_requested.c b/Source/charon/sa/states/ike_auth_requested.c index 69ccd0bd2..cbd5555eb 100644 --- a/Source/charon/sa/states/ike_auth_requested.c +++ b/Source/charon/sa/states/ike_auth_requested.c @@ -317,6 +317,7 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i /* create new state */ this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa)); + this->ike_sa->create_delete_established_ike_sa_job(this->ike_sa,this->sa_config->get_ike_sa_lifetime(this->sa_config)); this->public.state_interface.destroy(&(this->public.state_interface)); return SUCCESS; diff --git a/Source/charon/sa/states/ike_sa_init_responded.c b/Source/charon/sa/states/ike_sa_init_responded.c index 60068382a..109a1f10a 100644 --- a/Source/charon/sa/states/ike_sa_init_responded.c +++ b/Source/charon/sa/states/ike_sa_init_responded.c @@ -339,6 +339,7 @@ static status_t process_message(private_ike_sa_init_responded_t *this, message_t /* create new state */ this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa)); + this->ike_sa->create_delete_established_ike_sa_job(this->ike_sa,this->sa_config->get_ike_sa_lifetime(this->sa_config)); this->public.state_interface.destroy(&(this->public.state_interface)); diff --git a/Source/charon/testcases/sa_config_test.c b/Source/charon/testcases/sa_config_test.c index 10808c119..1529b3ccf 100644 --- a/Source/charon/testcases/sa_config_test.c +++ b/Source/charon/testcases/sa_config_test.c @@ -49,7 +49,8 @@ void test_sa_config(tester_t *tester) sa_config = sa_config_create(ID_IPV4_ADDR, "152.96.193.130", ID_IPV4_ADDR, "152.96.193.131", - RSA_DIGITAL_SIGNATURE); + RSA_DIGITAL_SIGNATURE, + 30000); tester->assert_true(tester, (sa_config != NULL), "sa_config construction"); diff --git a/Source/charon/testcases/testcases.c b/Source/charon/testcases/testcases.c index 666287c51..c412cfc89 100644 --- a/Source/charon/testcases/testcases.c +++ b/Source/charon/testcases/testcases.c @@ -162,7 +162,7 @@ daemon_t *daemon_create() charon->event_queue = event_queue_create(); charon->send_queue = send_queue_create(); charon->prime_pool = prime_pool_create(0); - charon->configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT); + charon->configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT,HALF_OPEN_IKE_SA_TIMEOUT); charon->sender = NULL; charon->receiver = NULL; charon->scheduler = NULL; diff --git a/Source/charon/threads/thread_pool.c b/Source/charon/threads/thread_pool.c index cce510f36..8a689a4df 100644 --- a/Source/charon/threads/thread_pool.c +++ b/Source/charon/threads/thread_pool.c @@ -29,7 +29,8 @@ #include <daemon.h> #include <queues/job_queue.h> -#include <queues/jobs/delete_ike_sa_job.h> +#include <queues/jobs/delete_half_open_ike_sa_job.h> +#include <queues/jobs/delete_established_ike_sa_job.h> #include <queues/jobs/incoming_packet_job.h> #include <queues/jobs/initiate_ike_sa_job.h> #include <queues/jobs/retransmit_request_job.h> @@ -75,14 +76,22 @@ struct private_thread_pool_t { void (*process_initiate_ike_sa_job) (private_thread_pool_t *this, initiate_ike_sa_job_t *job); /** - * @brief Process a DELETE_IKE_SA job. + * @brief Process a DELETE_HALF_OPEN_IKE_SA job. * * @param this private_thread_pool_t object - * @param job delete_ike_sa_job_t object + * @param job delete__half_open_ike_sa_job_t object */ - void (*process_delete_ike_sa_job) (private_thread_pool_t *this, delete_ike_sa_job_t *job); + void (*process_delete_half_open_ike_sa_job) (private_thread_pool_t *this, delete_half_open_ike_sa_job_t *job); /** + * @brief Process a DELETE_ESTABLISHED_IKE_SA job. + * + * @param this private_thread_pool_t object + * @param job delete_established_ike_sa_job_t object + */ + void (*process_delete_established_ike_sa_job) (private_thread_pool_t *this, delete_established_ike_sa_job_t *job); + + /** * @brief Process a RETRANSMIT_REQUEST job. * * @param this private_thread_pool_t object @@ -91,6 +100,17 @@ struct private_thread_pool_t { void (*process_retransmit_request_job) (private_thread_pool_t *this, retransmit_request_job_t *job); /** + * Creates a job of type DELETE_HALF_OPEN_IKE_SA. + * + * This job is used to delete IKE_SA's which are still in state INITIATOR_INIT, + * RESPONDER_INIT, IKE_AUTH_REQUESTED, IKE_INIT_REQUESTED or IKE_INIT_RESPONDED. + * + * @param ike_sa_id ID of IKE_SA to delete + * @param delay Delay in ms after a half open IKE_SA gets deleted! + */ + void (*create_delete_half_open_ike_sa_job) (private_thread_pool_t *this,ike_sa_id_t *ike_sa_id, u_int32_t delay); + + /** * number of running threads */ size_t pool_size; @@ -147,9 +167,15 @@ static void process_jobs(private_thread_pool_t *this) job->destroy(job); break; } - case DELETE_IKE_SA: + case DELETE_HALF_OPEN_IKE_SA: { - this->process_delete_ike_sa_job(this, (delete_ike_sa_job_t*)job); + this->process_delete_half_open_ike_sa_job(this, (delete_half_open_ike_sa_job_t*)job); + job->destroy(job); + break; + } + case DELETE_ESTABLISHED_IKE_SA: + { + this->process_delete_established_ike_sa_job(this, (delete_established_ike_sa_job_t*)job); job->destroy(job); break; } @@ -255,19 +281,25 @@ static void process_incoming_packet_job(private_thread_pool_t *this, incoming_pa 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) + if ((status != SUCCESS) && (status != CREATED)) { this->worker_logger->log(this->worker_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 + * TODO send notify reply of type INVALID_IKE_SPI if SPI could not be found ? */ return; } - + + if (status == CREATED) + { + this->worker_logger->log(this->worker_logger, CONTROL|MOST, "Create Job to delete half open IKE_SA."); + this->create_delete_half_open_ike_sa_job(this,ike_sa_id,charon->configuration_manager->get_half_open_ike_sa_timeout(charon->configuration_manager)); + } + status = ike_sa->process_message(ike_sa, message); if ((status != SUCCESS) && (status != DELETE_ME)) { @@ -326,6 +358,9 @@ static void process_initiate_ike_sa_job(private_thread_pool_t *this, initiate_ik charon->ike_sa_manager->checkin_and_delete(charon->ike_sa_manager, ike_sa); return; } + + this->worker_logger->log(this->worker_logger, CONTROL|MOST, "Create Job to delete half open IKE_SA."); + this->create_delete_half_open_ike_sa_job(this,ike_sa->get_id(ike_sa),charon->configuration_manager->get_half_open_ike_sa_timeout(charon->configuration_manager)); this->worker_logger->log(this->worker_logger, CONTROL|MOST, "checking in IKE SA"); status = charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); @@ -339,24 +374,90 @@ static void process_initiate_ike_sa_job(private_thread_pool_t *this, initiate_ik /** * Implementation of private_thread_pool_t.process_delete_ike_sa_job. */ -static void process_delete_ike_sa_job(private_thread_pool_t *this, delete_ike_sa_job_t *job) +static void process_delete_half_open_ike_sa_job(private_thread_pool_t *this, delete_half_open_ike_sa_job_t *job) { - status_t status; ike_sa_id_t *ike_sa_id = job->get_ike_sa_id(job); - - this->worker_logger->log(this->worker_logger, CONTROL|MOST, "deleting 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"); + ike_sa_t *ike_sa; + status_t status; + status = charon->ike_sa_manager->checkout(charon->ike_sa_manager,ike_sa_id, &ike_sa); + if ((status != SUCCESS) && (status != CREATED)) + { + this->worker_logger->log(this->worker_logger, CONTROL | ALL, "IKE SA seems to be allready deleted and so doesn't have to be deleted"); + return; + } - status = charon->ike_sa_manager->delete(charon->ike_sa_manager, ike_sa_id); + + 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: + { + /* IKE_SA is half open and gets deleted! */ + status = charon->ike_sa_manager->checkin_and_delete(charon->ike_sa_manager, ike_sa); + if (status != SUCCESS) + { + this->worker_logger->log(this->worker_logger, ERROR, "Could not checkin and delete checked out IKE_SA!"); + } + break; + } + 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->worker_logger->log(this->worker_logger, ERROR, "Could not checkin a checked out IKE_SA!"); + } + break; + } + } +} + +/** + * Implementation of private_thread_pool_t.process_delete_established_ike_sa_job. + */ +static void process_delete_established_ike_sa_job(private_thread_pool_t *this, delete_established_ike_sa_job_t *job) +{ + ike_sa_id_t *ike_sa_id = job->get_ike_sa_id(job); + ike_sa_t *ike_sa; + status_t status; + status = charon->ike_sa_manager->checkout(charon->ike_sa_manager,ike_sa_id, &ike_sa); + if ((status != SUCCESS) && (status != CREATED)) + { + this->worker_logger->log(this->worker_logger, CONTROL | ALL, "IKE SA seems to be allready deleted and so doesn't have to be deleted"); + return; + } + + 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: + { + break; + } + default: + { + /* + * TODO Send delete notify + */ + break; + } + } + + status = charon->ike_sa_manager->checkin_and_delete(charon->ike_sa_manager, ike_sa); if (status != SUCCESS) { - this->worker_logger->log(this->worker_logger, ERROR, "could not delete IKE_SA (%s)", - mapping_find(status_m, status)); - } + this->worker_logger->log(this->worker_logger, ERROR, "Could not checkin and delete checked out IKE_SA!"); + } } + /** * Implementation of private_thread_pool_t.process_retransmit_request_job. */ @@ -376,7 +477,7 @@ static void process_retransmit_request_job(private_thread_pool_t *this, retransm 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) + if ((status != SUCCESS) && (status != CREATED)) { job->destroy(job); this->worker_logger->log(this->worker_logger, ERROR, "IKE SA could not be checked out. Allready deleted?"); @@ -422,6 +523,22 @@ static void process_retransmit_request_job(private_thread_pool_t *this, retransm charon->event_queue->add_relative(charon->event_queue,(job_t *) job,timeout); } + + +/** + * Implementation of private_thread_pool_t.create_delete_half_open_ike_sa_job. + */ +static void create_delete_half_open_ike_sa_job(private_thread_pool_t *this,ike_sa_id_t *ike_sa_id, u_int32_t delay) +{ + job_t *delete_job; + + this->worker_logger->log(this->worker_logger, CONTROL | MORE, "Going to create job to delete half open IKE_SA in %d ms", delay); + + delete_job = (job_t *) delete_half_open_ike_sa_job_create(ike_sa_id); + charon->event_queue->add_relative(charon->event_queue,delete_job, delay); +} + + /** * Implementation of thread_pool_t.get_pool_size. */ @@ -470,9 +587,12 @@ thread_pool_t *thread_pool_create(size_t pool_size) this->process_jobs = process_jobs; this->process_initiate_ike_sa_job = process_initiate_ike_sa_job; - this->process_delete_ike_sa_job = process_delete_ike_sa_job; + this->process_delete_half_open_ike_sa_job = process_delete_half_open_ike_sa_job; + this->process_delete_established_ike_sa_job = process_delete_established_ike_sa_job; this->process_incoming_packet_job = process_incoming_packet_job; this->process_retransmit_request_job = process_retransmit_request_job; + this->create_delete_half_open_ike_sa_job = create_delete_half_open_ike_sa_job; + this->pool_size = pool_size; this->threads = allocator_alloc(sizeof(pthread_t) * pool_size); diff --git a/Source/charon/types.c b/Source/charon/types.c index 9af849893..ca4aaff0c 100644 --- a/Source/charon/types.c +++ b/Source/charon/types.c @@ -36,6 +36,7 @@ mapping_t status_m[] = { {VERIFY_ERROR, "VERIFY_ERROR"}, {INVALID_STATE, "INVALID_STATE"}, {DELETE_ME, "DELETE_ME"}, + {CREATED, "CREATED"}, {MAPPING_END, NULL} }; diff --git a/Source/charon/types.h b/Source/charon/types.h index 521741f72..09a669cf4 100644 --- a/Source/charon/types.h +++ b/Source/charon/types.h @@ -47,6 +47,7 @@ enum status_t { VERIFY_ERROR, INVALID_STATE, DELETE_ME, + CREATED, }; extern mapping_t status_m[]; |