diff options
author | Martin Willi <martin@strongswan.org> | 2007-03-28 13:34:02 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2007-03-28 13:34:02 +0000 |
commit | 4deb89485c1f2ad64eb1e9f834d792191138a266 (patch) | |
tree | 47ca968ab2a9259ec0d61ac4702e43265157028b | |
parent | 077a6fff9584dc6b321ac267b4f8b1afc5d9a5bf (diff) | |
download | strongswan-4deb89485c1f2ad64eb1e9f834d792191138a266.tar.bz2 strongswan-4deb89485c1f2ad64eb1e9f834d792191138a266.tar.xz |
removed send_queue, handled internally in sender_t know
do header parsing in receiver, ready for cookie integration
-rw-r--r-- | src/charon/Makefile.am | 6 | ||||
-rw-r--r-- | src/charon/daemon.c | 3 | ||||
-rw-r--r-- | src/charon/daemon.h | 18 | ||||
-rw-r--r-- | src/charon/queues/jobs/incoming_packet_job.c | 209 | ||||
-rw-r--r-- | src/charon/queues/jobs/incoming_packet_job.h | 69 | ||||
-rw-r--r-- | src/charon/queues/jobs/job.c | 4 | ||||
-rw-r--r-- | src/charon/queues/jobs/job.h | 4 | ||||
-rw-r--r-- | src/charon/queues/jobs/process_message_job.c | 115 | ||||
-rw-r--r-- | src/charon/queues/jobs/process_message_job.h | 58 | ||||
-rw-r--r-- | src/charon/queues/send_queue.c | 144 | ||||
-rw-r--r-- | src/charon/queues/send_queue.h | 100 | ||||
-rw-r--r-- | src/charon/sa/authenticators/eap_authenticator.c | 1 | ||||
-rw-r--r-- | src/charon/sa/ike_sa.c | 4 | ||||
-rw-r--r-- | src/charon/sa/ike_sa_manager.c | 39 | ||||
-rw-r--r-- | src/charon/sa/ike_sa_manager.h | 16 | ||||
-rw-r--r-- | src/charon/sa/task_manager.c | 11 | ||||
-rw-r--r-- | src/charon/threads/receiver.c | 141 | ||||
-rw-r--r-- | src/charon/threads/receiver.h | 5 | ||||
-rw-r--r-- | src/charon/threads/sender.c | 73 | ||||
-rw-r--r-- | src/charon/threads/sender.h | 28 |
20 files changed, 407 insertions, 641 deletions
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index c422939f0..9522b6e6d 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -65,15 +65,15 @@ encoding/parser.h encoding/message.c encoding/generator.c encoding/message.h enc encoding/parser.c daemon.c daemon.h network/packet.c \ network/socket.c network/packet.h network/socket.h queues/jobs/job.h queues/jobs/job.c \ queues/jobs/retransmit_job.h queues/jobs/initiate_job.h \ -queues/jobs/incoming_packet_job.h queues/jobs/incoming_packet_job.c \ +queues/jobs/process_message_job.h queues/jobs/process_message_job.c \ queues/jobs/delete_ike_sa_job.c queues/jobs/delete_ike_sa_job.h \ queues/jobs/retransmit_job.c queues/jobs/initiate_job.c \ queues/jobs/send_keepalive_job.c queues/jobs/send_keepalive_job.h \ queues/jobs/rekey_child_sa_job.c queues/jobs/rekey_child_sa_job.h queues/jobs/delete_child_sa_job.c queues/jobs/delete_child_sa_job.h \ queues/jobs/send_dpd_job.c queues/jobs/send_dpd_job.h queues/jobs/route_job.c queues/jobs/route_job.h \ queues/jobs/acquire_job.c queues/jobs/acquire_job.h queues/jobs/rekey_ike_sa_job.c queues/jobs/rekey_ike_sa_job.h \ -queues/job_queue.c queues/event_queue.c queues/send_queue.h queues/job_queue.h queues/event_queue.h \ -queues/send_queue.c threads/kernel_interface.c threads/thread_pool.c threads/scheduler.c threads/sender.c \ +queues/job_queue.c queues/event_queue.c queues/job_queue.h queues/event_queue.h \ +threads/kernel_interface.c threads/thread_pool.c threads/scheduler.c threads/sender.c \ threads/sender.h threads/kernel_interface.h threads/scheduler.h threads/receiver.c threads/stroke_interface.c \ threads/thread_pool.h threads/receiver.h threads/stroke_interface.h diff --git a/src/charon/daemon.c b/src/charon/daemon.c index 05acd36bf..b3adf3e89 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -184,7 +184,6 @@ static void destroy(private_daemon_t *this) /* we hope the sender could send the outstanding deletes, but * we shut down here at any cost */ DESTROY_IF(this->public.sender); - DESTROY_IF(this->public.send_queue); DESTROY_IF(this->public.socket); /* before destroying bus with its listeners, rehook library logs */ dbg = dbg_stderr; @@ -264,7 +263,6 @@ static void initialize(private_daemon_t *this, bool strict, bool syslog, this->public.ike_sa_manager = ike_sa_manager_create(); this->public.job_queue = job_queue_create(); this->public.event_queue = event_queue_create(); - this->public.send_queue = send_queue_create(); this->public.connections = (connection_store_t*)local_connection_store_create(); this->public.policies = (policy_store_t*)local_policy_store_create(); this->public.credentials = (credential_store_t*)local_credential_store_create(strict); @@ -334,7 +332,6 @@ private_daemon_t *daemon_create(void) this->public.ike_sa_manager = NULL; this->public.job_queue = NULL; this->public.event_queue = NULL; - this->public.send_queue = NULL; this->public.configuration = NULL; this->public.credentials = NULL; this->public.connections = NULL; diff --git a/src/charon/daemon.h b/src/charon/daemon.h index b0b191b6c..420262474 100644 --- a/src/charon/daemon.h +++ b/src/charon/daemon.h @@ -40,7 +40,6 @@ typedef struct daemon_t daemon_t; #include <bus/listeners/file_logger.h> #include <bus/listeners/sys_logger.h> #include <sa/ike_sa_manager.h> -#include <queues/send_queue.h> #include <queues/job_queue.h> #include <queues/event_queue.h> #include <config/configuration.h> @@ -75,14 +74,8 @@ typedef struct daemon_t daemon_t; | | - u | | Pool | | | +----+-------+ | e |------| |---| | | sender | +------+ +------------+ +------+ - +----+-------+ - | +------+ - | | S Q | - | | e u | - | | n e | - +------------| d u | - | - e | - +--+---+ + +------------+ + @endverbatim * The thread-pool is the heart of the architecture. It processes jobs from a * (fully synchronized) job-queue. Mostly, a job is associated with a specific @@ -94,7 +87,7 @@ typedef struct daemon_t daemon_t; * (fully synchronized) event-queue is ready for processing and pushes the event * down to the job-queue. A thread form the pool will pick it up as quick as * possible. Every thread can queue events or jobs. Furter, an event can place a - * packet in the send-queue. The sender thread waits for those packets and sends + * packet in the sender. The sender thread waits for those packets and sends * them over the wire, via the socket. The receiver does exactly the opposite of * the sender. It waits on the socket, reads in packets an places them on the * job-queue for further processing by a thread from the pool. @@ -309,11 +302,6 @@ struct daemon_t { socket_t *socket; /** - * A send_queue_t instance. - */ - send_queue_t *send_queue; - - /** * A job_queue_t instance. */ job_queue_t *job_queue; diff --git a/src/charon/queues/jobs/incoming_packet_job.c b/src/charon/queues/jobs/incoming_packet_job.c deleted file mode 100644 index c4f211a04..000000000 --- a/src/charon/queues/jobs/incoming_packet_job.c +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file incoming_packet_job.h - * - * @brief Implementation of incoming_packet_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 "incoming_packet_job.h" - -#include <daemon.h> - -typedef struct private_incoming_packet_job_t private_incoming_packet_job_t; - -/** - * Private data of an incoming_packet_job_t Object - */ -struct private_incoming_packet_job_t { - /** - * public incoming_packet_job_t interface - */ - incoming_packet_job_t public; - - /** - * Assigned packet - */ - packet_t *packet; -}; - -/** - * Implements job_t.get_type. - */ -static job_type_t get_type(private_incoming_packet_job_t *this) -{ - return INCOMING_PACKET; -} - -/** - * send a notify back to the sender - */ -static void send_notify_response(private_incoming_packet_job_t *this, - message_t *request, - notify_type_t type) -{ - notify_payload_t *notify; - message_t *response; - host_t *src, *dst; - packet_t *packet; - ike_sa_id_t *ike_sa_id; - - if (request->get_exchange_type(request) != IKE_SA_INIT) - { - /* TODO: Use transforms implementing the "NULL" algorithm, - we are unable to generate message otherwise */ - return; - } - - ike_sa_id = request->get_ike_sa_id(request); - ike_sa_id = ike_sa_id->clone(ike_sa_id); - ike_sa_id->switch_initiator(ike_sa_id); - - response = message_create(); - dst = request->get_source(request); - src = request->get_destination(request); - response->set_source(response, src->clone(src)); - response->set_destination(response, dst->clone(dst)); - response->set_exchange_type(response, request->get_exchange_type(request)); - response->set_request(response, FALSE); - response->set_message_id(response, 0); - response->set_ike_sa_id(response, ike_sa_id); - ike_sa_id->destroy(ike_sa_id); - notify = notify_payload_create_from_protocol_and_type(PROTO_NONE, type); - response->add_payload(response, (payload_t *)notify); - if (response->generate(response, NULL, NULL, &packet) != SUCCESS) - { - response->destroy(response); - return; - } - DBG1(DBG_NET, "sending %N notify", notify_type_names, type); - charon->send_queue->add(charon->send_queue, packet); - response->destroy(response); - return; -} - -/** - * Implementation of job_t.execute. - */ -static status_t execute(private_incoming_packet_job_t *this) -{ - message_t *message; - ike_sa_t *ike_sa; - ike_sa_id_t *ike_sa_id; - status_t status; - host_t *src, *dst; - - message = message_create_from_packet(this->packet->clone(this->packet)); - src = message->get_source(message); - dst = message->get_destination(message); - - status = message->parse_header(message); - if (status != SUCCESS) - { - DBG1(DBG_NET, "received message from %H with invalid IKE header, " - "ignored", src); - message->destroy(message); - return DESTROY_ME; - } - - if ((message->get_major_version(message) != IKE_MAJOR_VERSION) || - (message->get_minor_version(message) != IKE_MINOR_VERSION)) - { - DBG1(DBG_NET, "received message from %H with unsupported IKE " - "version %d.%d, ignored", src, message->get_major_version(message), - message->get_minor_version(message)); - - if (message->get_exchange_type(message) == IKE_SA_INIT && - message->get_request(message)) - { - send_notify_response(this, message, INVALID_MAJOR_VERSION); - } - message->destroy(message); - return DESTROY_ME; - } - - ike_sa_id = message->get_ike_sa_id(message); - ike_sa_id = ike_sa_id->clone(ike_sa_id); - ike_sa_id->switch_initiator(ike_sa_id); - ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id); - if (ike_sa == NULL) - { - DBG1(DBG_NET, "received packet from %#H for IKE_SA: %J, but no such " - "IKE_SA", src, ike_sa_id); - if (message->get_request(message)) - { - send_notify_response(this, message, INVALID_IKE_SPI); - } - ike_sa_id->destroy(ike_sa_id); - message->destroy(message); - return DESTROY_ME; - } - - DBG1(DBG_NET, "received packet: from %#H to %#H", src, dst); - - status = ike_sa->process_message(ike_sa, message); - 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); - } - ike_sa_id->destroy(ike_sa_id); - message->destroy(message); - return DESTROY_ME; -} - -/** - * Implements incoming_packet_job_t.get_packet. - */ -static packet_t* get_packet(private_incoming_packet_job_t *this) -{ - return this->packet; -} - -/** - * Implements job_t.destroy. - */ -static void destroy(private_incoming_packet_job_t *this) -{ - this->packet->destroy(this->packet); - free(this); -} - -/* - * Described in header - */ -incoming_packet_job_t *incoming_packet_job_create(packet_t *packet) -{ - private_incoming_packet_job_t *this = malloc_thing(private_incoming_packet_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; - - this->public.get_packet = (packet_t*(*)(incoming_packet_job_t*)) get_packet; - - /* private variables */ - this->packet = packet; - - return &(this->public); -} diff --git a/src/charon/queues/jobs/incoming_packet_job.h b/src/charon/queues/jobs/incoming_packet_job.h deleted file mode 100644 index 5ce0750f7..000000000 --- a/src/charon/queues/jobs/incoming_packet_job.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file incoming_packet_job.h - * - * @brief Interface of incoming_packet_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 INCOMING_PACKET_JOB_H_ -#define INCOMING_PACKET_JOB_H_ - -typedef struct incoming_packet_job_t incoming_packet_job_t; - -#include <library.h> -#include <network/packet.h> -#include <queues/jobs/job.h> - -/** - * @brief Class representing an INCOMING_PACKET Job. - * - * An incoming pack job is created from the receiver, which has - * read a packet to process from the socket. - * - * @b Constructors: - * - incoming_packet_job_create() - * - * @ingroup jobs - */ -struct incoming_packet_job_t { - /** - * implements job_t interface - */ - job_t job_interface; - - /** - * @brief Get associated packet. - * - * @param this calling object - * @return associated packet - */ - packet_t *(*get_packet)(incoming_packet_job_t *this); -}; - -/** - * @brief Creates a job of type INCOMING_PACKET - * - * @param[in] packet packet to assign with this job - * @return created incoming_packet_job_t object - * - * @ingroup jobs - */ -incoming_packet_job_t *incoming_packet_job_create(packet_t *packet); - -#endif /*INCOMING_PACKET_JOB_H_*/ diff --git a/src/charon/queues/jobs/job.c b/src/charon/queues/jobs/job.c index 337558c2d..d32d1bc61 100644 --- a/src/charon/queues/jobs/job.c +++ b/src/charon/queues/jobs/job.c @@ -24,8 +24,8 @@ #include "job.h" -ENUM(job_type_names, INCOMING_PACKET, SEND_DPD, - "INCOMING_PACKET", +ENUM(job_type_names, PROCESS_MESSAGE, SEND_DPD, + "PROCESS_MESSAGE", "RETRANSMIT", "INITIATE", "ROUTE", diff --git a/src/charon/queues/jobs/job.h b/src/charon/queues/jobs/job.h index ae67a2bdc..28632672d 100644 --- a/src/charon/queues/jobs/job.h +++ b/src/charon/queues/jobs/job.h @@ -38,9 +38,9 @@ enum job_type_t { /** * Process an incoming IKEv2-Message. * - * Job is implemented in class incoming_packet_job_t + * Job is implemented in class process_message_job_t */ - INCOMING_PACKET, + PROCESS_MESSAGE, /** * Retransmit an IKEv2-Message. diff --git a/src/charon/queues/jobs/process_message_job.c b/src/charon/queues/jobs/process_message_job.c new file mode 100644 index 000000000..8d2a97ecf --- /dev/null +++ b/src/charon/queues/jobs/process_message_job.c @@ -0,0 +1,115 @@ +/** + * @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_id_t *ike_sa_id; + + ike_sa_id = this->message->get_ike_sa_id(this->message); + ike_sa_id = ike_sa_id->clone(ike_sa_id); + ike_sa_id->switch_initiator(ike_sa_id); + ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, ike_sa_id); + 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); + } + } + else + { + DBG1(DBG_NET, "received packet from %#H for IKE_SA: %J, but no such " + "IKE_SA", this->message->get_source(this->message), ike_sa_id); + } + ike_sa_id->destroy(ike_sa_id); + return DESTROY_ME; +} + +/** + * Implements job_t.destroy. + */ +static void destroy(private_process_message_job_t *this) +{ + this->message->destroy(this->message); + free(this); +} + +/* + * Described in header + */ +process_message_job_t *process_message_job_create(message_t *message) +{ + private_process_message_job_t *this = malloc_thing(private_process_message_job_t); + + /* interface functions */ + this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type; + this->public.job_interface.execute = (status_t (*) (job_t *)) execute; + this->public.job_interface.destroy = (void(*)(job_t*))destroy; + + /* private variables */ + this->message = message; + + return &(this->public); +} diff --git a/src/charon/queues/jobs/process_message_job.h b/src/charon/queues/jobs/process_message_job.h new file mode 100644 index 000000000..2e60a298c --- /dev/null +++ b/src/charon/queues/jobs/process_message_job.h @@ -0,0 +1,58 @@ +/** + * @file process_message_job.h + * + * @brief Interface of process_message_job_t. + * + */ + +/* + * Copyright (C) 2005-2007 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef PROCESS_MESSAGE_JOB_H_ +#define PROCESS_MESSAGE_JOB_H_ + +typedef struct process_message_job_t process_message_job_t; + +#include <library.h> +#include <encoding/message.h> +#include <queues/jobs/job.h> + +/** + * @brief Class representing an PROCESS_MESSAGE job. + * + * @b Constructors: + * - process_message_job_create() + * + * @ingroup jobs + */ +struct process_message_job_t { + /** + * implements job_t interface + */ + job_t job_interface; +}; + +/** + * @brief Creates a job of type PROCESS_MESSAGE. + * + * @param message message to process + * @return created process_message_job_t object + * + * @ingroup jobs + */ +process_message_job_t *process_message_job_create(message_t *message); + +#endif /*PROCESS_MESSAGE_JOB_H_*/ diff --git a/src/charon/queues/send_queue.c b/src/charon/queues/send_queue.c deleted file mode 100644 index a9666947b..000000000 --- a/src/charon/queues/send_queue.c +++ /dev/null @@ -1,144 +0,0 @@ -/** - * @file send_queue.c - * - * @brief Implementation of send_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 "send_queue.h" - -#include <utils/linked_list.h> -#include <bus/bus.h> -#include <daemon.h> - - -typedef struct private_send_queue_t private_send_queue_t; - -/** - * @brief Private Variables and Functions of send_queue class - * - */ -struct private_send_queue_t { - /** - * Public part of the send_queue_t object - */ - send_queue_t public; - - /** - * The packets 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 send_queue_t.get_count - */ -static int get_count(private_send_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 send_queue_t.get - */ -static packet_t *get(private_send_queue_t *this) -{ - int oldstate; - packet_t *packet; - - pthread_mutex_lock(&this->mutex); - - /* go to wait while no packets 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**)&packet); - pthread_mutex_unlock(&this->mutex); - return packet; -} - -/** - * implements send_queue_t.add - */ -static void add(private_send_queue_t *this, packet_t *packet) -{ - host_t *src, *dst; - - src = packet->get_source(packet); - dst = packet->get_destination(packet); - DBG1(DBG_NET, "sending packet: from %#H to %#H", src, dst); - - pthread_mutex_lock(&this->mutex); - this->list->insert_last(this->list, packet); - pthread_cond_signal(&this->condvar); - pthread_mutex_unlock(&this->mutex); -} - -/** - * implements send_queue_t.destroy - */ -static void destroy (private_send_queue_t *this) -{ - this->list->destroy_offset(this->list, offsetof(packet_t, destroy)); - free(this); -} - -/* - * Documented in header - */ -send_queue_t *send_queue_create(void) -{ - private_send_queue_t *this = malloc_thing(private_send_queue_t); - - this->public.get_count = (int(*)(send_queue_t*)) get_count; - this->public.get = (packet_t*(*)(send_queue_t*)) get; - this->public.add = (void(*)(send_queue_t*, packet_t*)) add; - this->public.destroy = (void(*)(send_queue_t*)) destroy; - - this->list = linked_list_create(); - pthread_mutex_init(&this->mutex, NULL); - pthread_cond_init(&this->condvar, NULL); - - return (&this->public); -} diff --git a/src/charon/queues/send_queue.h b/src/charon/queues/send_queue.h deleted file mode 100644 index b69499cc1..000000000 --- a/src/charon/queues/send_queue.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file send_queue.h - * - * @brief Interface of send_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 SEND_QUEUE_H_ -#define SEND_QUEUE_H_ - -typedef struct send_queue_t send_queue_t; - -#include <library.h> -#include <network/packet.h> - -/** - * @brief The send queue stores packet for the sender_t instance. - * - * The sender_t will send them consequently over the wire. - * Although the send-queue is based on a linked_list_t - * all access functions are thread-save implemented. - * - * @b Constructors: - * - send_queue_create() - * - * @ingroup queues - */ -struct send_queue_t { - - /** - * @brief returns number of packets in queue - * - * @param send_queue_t calling object - * @param[out] count integer pointer to store the count in - * @returns number of items in queue - */ - int (*get_count) (send_queue_t *send_queue); - - /** - * @brief get the next packet from the queue. - * - * If the queue is empty, this function blocks until a packet can be returned. - * - * After using, the returned packet has to get destroyed by the caller. - * - * @param send_queue_t calling object - * @return next packet from the queue - */ - packet_t *(*get) (send_queue_t *send_queue); - - /** - * @brief adds a packet to the queue. - * - * This function is non blocking and adds a packet_t to the list. - * The specific packet object has to get destroyed by the thread which - * removes the packet. - * - * @param send_queue_t calling object - * @param packet packet_t to add to the queue (packet is not copied) - */ - void (*add) (send_queue_t *send_queue, packet_t *packet); - - /** - * @brief destroys a send_queue object. - * - * @warning The caller of this function has to make sure - * that no thread is going to add or get a packet from the send_queue - * after calling this function. - * - * @param send_queue_t calling object - */ - void (*destroy) (send_queue_t *send_queue); -}; - -/** - * @brief Creates an empty send_queue_t. - * - * @return send_queue_t object - * - * @ingroup queues - */ -send_queue_t *send_queue_create(void); - -#endif /*SEND_QUEUE_H_*/ diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c index db4a79f16..6c8ca8d8f 100644 --- a/src/charon/sa/authenticators/eap_authenticator.c +++ b/src/charon/sa/authenticators/eap_authenticator.c @@ -100,7 +100,6 @@ static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init, { chunk_t auth_data; identification_t *my_id = this->ike_sa->get_my_id(this->ike_sa); - prf_t *prf = this->ike_sa->get_auth_build(this->ike_sa); DBG1(DBG_IKE, "authentication of '%D' (myself) with %N", my_id, auth_method_names, AUTH_EAP); diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index e4e603e28..39a28c189 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -422,7 +422,7 @@ static void send_keepalive(private_ike_sa_t *this) data.ptr[0] = 0xFF; data.len = 1; packet->set_data(packet, data); - charon->send_queue->add(charon->send_queue, packet); + charon->sender->send(charon->sender, packet); DBG1(DBG_IKE, "sending keep alive"); diff = 0; } @@ -625,7 +625,7 @@ static void send_notify_response(private_ike_sa_t *this, message_t *request, } if (generate_message(this, response, &packet) == SUCCESS) { - charon->send_queue->add(charon->send_queue, packet); + charon->sender->send(charon->sender, packet); } response->destroy(response); } diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c index 6e9d867fd..b4a7324c5 100644 --- a/src/charon/sa/ike_sa_manager.c +++ b/src/charon/sa/ike_sa_manager.c @@ -730,6 +730,44 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik } /** + * Implementation of ike_sa_manager_t.get_half_open_count. + */ +static int get_half_open_count(private_ike_sa_manager_t *this, host_t *ip) +{ + iterator_t *iterator; + entry_t *entry; + int count = 0; + + pthread_mutex_lock(&(this->mutex)); + iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE); + while (iterator->iterate(iterator, (void**)&entry)) + { + /* we check if we have a responder CONNECTING IKE_SA without checkout */ + if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) && + entry->ike_sa->get_state(entry->ike_sa) == IKE_CONNECTING) + { + /* if we have a host, we have wait until no other uses the IKE_SA */ + if (ip) + { + if (wait_for_entry(this, entry) && ip->ip_equals(ip, + entry->ike_sa->get_other_host(entry->ike_sa))) + { + count++; + } + } + else + { + count++; + } + } + } + iterator->destroy(iterator); + + pthread_mutex_unlock(&(this->mutex)); + return count; +} + +/** * Implementation of ike_sa_manager_t.destroy. */ static void destroy(private_ike_sa_manager_t *this) @@ -798,6 +836,7 @@ ike_sa_manager_t *ike_sa_manager_create() this->public.create_iterator = (iterator_t*(*)(ike_sa_manager_t*))create_iterator; this->public.checkin = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin; this->public.checkin_and_destroy = (status_t(*)(ike_sa_manager_t*,ike_sa_t*))checkin_and_destroy; + this->public.get_half_open_count = (int(*)(ike_sa_manager_t*,host_t*))get_half_open_count; /* initialize private variables */ this->ike_sa_list = linked_list_create(); diff --git a/src/charon/sa/ike_sa_manager.h b/src/charon/sa/ike_sa_manager.h index ecd3db156..5fcead45d 100644 --- a/src/charon/sa/ike_sa_manager.h +++ b/src/charon/sa/ike_sa_manager.h @@ -167,6 +167,22 @@ struct ike_sa_manager_t { status_t (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa); /** + * @brief Get the number of IKE_SAs which are in the connecting state. + * + * To prevent the server from resource exhaustion, cookies and other + * mechanisms are used. The number of half open IKE_SAs is a good + * indicator to see if a peer is flooding the server. + * If a host is supplied, only the number of half open IKE_SAs initiated + * from this IP are counted. + * Only SAs for which we are the responder are counted. + * + * @param this the manager object + * @param ip NULL for all, IP for half open IKE_SAs with IP + * @return number of half open IKE_SAs + */ + int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip); + + /** * @brief Destroys the manager with all associated SAs. * * Threads will be driven out, so all SAs can be deleted cleanly. diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c index 5bfc04840..b129f12df 100644 --- a/src/charon/sa/task_manager.c +++ b/src/charon/sa/task_manager.c @@ -226,7 +226,7 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id) } this->initiating.retransmitted++; - charon->send_queue->add(charon->send_queue, + charon->sender->send(charon->sender, this->initiating.packet->clone(this->initiating.packet)); job = (job_t*)retransmit_job_create(this->initiating.mid, this->ike_sa->get_id(this->ike_sa)); @@ -541,8 +541,8 @@ static status_t build_response(private_task_manager_t *this, return DESTROY_ME; } - charon->send_queue->add(charon->send_queue, - this->responding.packet->clone(this->responding.packet)); + charon->sender->send(charon->sender, + this->responding.packet->clone(this->responding.packet)); if (delete) { return DESTROY_ME; @@ -711,9 +711,8 @@ static status_t process_message(private_task_manager_t *this, message_t *msg) { DBG1(DBG_IKE, "received retransmit of request with ID %d, " "retransmitting response", mid); - charon->send_queue->add(charon->send_queue, - this->responding.packet->clone( - this->responding.packet)); + charon->sender->send(charon->sender, + this->responding.packet->clone(this->responding.packet)); } else { diff --git a/src/charon/threads/receiver.c b/src/charon/threads/receiver.c index a97476621..ffcbf5db6 100644 --- a/src/charon/threads/receiver.c +++ b/src/charon/threads/receiver.c @@ -31,7 +31,7 @@ #include <network/packet.h> #include <queues/job_queue.h> #include <queues/jobs/job.h> -#include <queues/jobs/incoming_packet_job.h> +#include <queues/jobs/process_message_job.h> typedef struct block_t block_t; @@ -88,14 +88,72 @@ struct private_receiver_t { }; /** + * Implementation of receiver_t.block + */ +static void block(private_receiver_t *this, host_t *ip, u_int32_t seconds) +{ + block_t *blocked = malloc_thing(block_t); + + blocked->ip = ip->clone(ip); + blocked->timeout = time(NULL) + seconds; + DBG1(DBG_NET, "blocking %H for %ds", ip, seconds); + + pthread_mutex_lock(&this->mutex); + this->blocks->insert_last(this->blocks, blocked); + pthread_mutex_unlock(&this->mutex); +} + +/** + * check if an IP is blocked + */ +static bool is_blocked(private_receiver_t *this, host_t *ip) +{ + bool found = FALSE; + + if (this->blocks->get_count(this->blocks)) + { + iterator_t *iterator; + block_t *blocked; + u_int32_t now = time(NULL); + + pthread_mutex_lock(&this->mutex); + iterator = this->blocks->create_iterator(this->blocks, TRUE); + while (iterator->iterate(iterator, (void**)&blocked)) + { + if (now > blocked->timeout) + { + /* blocking expired, remove */ + iterator->remove(iterator); + block_destroy(blocked); + continue; + } + + if (!ip->ip_equals(ip, blocked->ip)) + { + /* no match, get next */ + continue; + } + + /* blocked */ + DBG2(DBG_NET, "received packet source address %H blocked", ip); + found = TRUE; + break; + } + iterator->destroy(iterator); + pthread_mutex_unlock(&this->mutex); + } + return found; +} + +/** * Implementation of receiver_t.receive_packets. */ static void receive_packets(private_receiver_t * this) { packet_t *packet; + message_t *message; job_t *job; - /* cancellation disabled by default */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); DBG1(DBG_NET, "receiver thread running, thread_ID: %06u", (int)pthread_self()); @@ -108,69 +166,36 @@ static void receive_packets(private_receiver_t * this) continue; } - if (this->blocks->get_count(this->blocks)) + if (is_blocked(this, packet->get_source(packet))) { - iterator_t *iterator; - block_t *blocked; - bool found = FALSE; - u_int32_t now = time(NULL); - - pthread_mutex_lock(&this->mutex); - iterator = this->blocks->create_iterator(this->blocks, TRUE); - while (iterator->iterate(iterator, (void**)&blocked)) - { - if (now > blocked->timeout) - { - /* block expired, remove */ - iterator->remove(iterator); - block_destroy(blocked); - continue; - } - - if (!blocked->ip->ip_equals(blocked->ip, - packet->get_source(packet))) - { - /* no match, get next */ - continue; - } - - /* IP is blocked */ - DBG2(DBG_NET, "received packets source address %H blocked", - blocked->ip); - packet->destroy(packet); - found = TRUE; - break; - } - iterator->destroy(iterator); - pthread_mutex_unlock(&this->mutex); - if (found) - { - /* get next packet */ - continue; - } + packet->destroy(packet); + continue; } - DBG2(DBG_NET, "creating job from packet"); - job = (job_t *) incoming_packet_job_create(packet); + message = message_create_from_packet(packet); + if (message->parse_header(message) != SUCCESS) + { + DBG1(DBG_NET, "received invalid IKE header from %H, ignored", + packet->get_source(packet)); + message->destroy(message); + continue; + } + + if (message->get_major_version(message) != IKE_MAJOR_VERSION) + { + DBG1(DBG_NET, "received unsupported IKE version %d.%d from %H, " + "ignored", message->get_major_version(message), + message->get_minor_version(message), packet->get_source(packet)); + message->destroy(message); + continue; + } + + + job = (job_t *)process_message_job_create(message); charon->job_queue->add(charon->job_queue, job); } } -/** - * Implementation of receiver_t.block - */ -static void block(private_receiver_t *this, host_t *ip, u_int32_t seconds) -{ - block_t *blocked = malloc_thing(block_t); - - blocked->ip = ip->clone(ip); - blocked->timeout = time(NULL) + seconds; - DBG1(DBG_NET, "blocking %H for %ds", ip, seconds); - - pthread_mutex_lock(&this->mutex); - this->blocks->insert_last(this->blocks, blocked); - pthread_mutex_unlock(&this->mutex); -} /** * Implementation of receiver_t.destroy. diff --git a/src/charon/threads/receiver.h b/src/charon/threads/receiver.h index 3be40e901..c39511bf7 100644 --- a/src/charon/threads/receiver.h +++ b/src/charon/threads/receiver.h @@ -32,9 +32,8 @@ typedef struct receiver_t receiver_t; /** * @brief Receives packets from the socket and adds them to the job queue. * - * The receiver starts a thread, wich reads on the blocking socket. If - * data is available, a packet_t object is created, wrapped - * in an incoming_packet_job_t and added to the job queue. + * The receiver starts a thread, wich reads on the blocking socket. A received + * packet is preparsed a process_message_job is queued in the job queue. * * @b Constructors: * - receiver_create() diff --git a/src/charon/threads/sender.c b/src/charon/threads/sender.c index 548fd33aa..c1cd0a68c 100644 --- a/src/charon/threads/sender.c +++ b/src/charon/threads/sender.c @@ -28,8 +28,6 @@ #include <daemon.h> #include <network/socket.h> -#include <network/packet.h> -#include <queues/send_queue.h> typedef struct private_sender_t private_sender_t; @@ -47,33 +45,72 @@ struct private_sender_t { * Assigned thread. */ pthread_t assigned_thread; + + /** + * The packets are stored in a linked list + */ + linked_list_t *list; + + /** + * mutex to synchronize access to list + */ + pthread_mutex_t mutex; + /** + * condvar to signal for packets in list + */ + pthread_cond_t condvar; }; /** + * implements sender_t.send + */ +static void send_(private_sender_t *this, packet_t *packet) +{ + host_t *src, *dst; + + src = packet->get_source(packet); + dst = packet->get_destination(packet); + DBG1(DBG_NET, "sending packet: from %#H to %#H", src, dst); + + pthread_mutex_lock(&this->mutex); + this->list->insert_last(this->list, packet); + pthread_mutex_unlock(&this->mutex); + pthread_cond_signal(&this->condvar); +} + +/** * Implementation of private_sender_t.send_packets. */ static void send_packets(private_sender_t * this) { - packet_t *current_packet; - status_t status; /* cancellation disabled by default */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - - DBG1(DBG_NET, "sender thread running, thread_ID: %06u", - (int)pthread_self()); + DBG1(DBG_NET, "sender thread running, thread_ID: %06u", (int)pthread_self()); while (TRUE) { - current_packet = charon->send_queue->get(charon->send_queue); - DBG2(DBG_NET, "got a packet, sending it"); - status = charon->socket->send(charon->socket, current_packet); - if (status != SUCCESS) + packet_t *packet; + int oldstate; + + pthread_mutex_lock(&this->mutex); + /* go to wait while no packets available */ + while (this->list->get_count(this->list) == 0) { - DBG1(DBG_NET, "sending packet failed"); + /* add cleanup handler, wait for packet, remove cleanup handler */ + pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&this->mutex); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + pthread_cond_wait(&this->condvar, &this->mutex); + + pthread_setcancelstate(oldstate, NULL); + pthread_cleanup_pop(0); } - current_packet->destroy(current_packet); + this->list->remove_first(this->list, (void**)&packet); + pthread_mutex_unlock(&this->mutex); + + charon->socket->send(charon->socket, packet); + packet->destroy(packet); } } @@ -84,6 +121,7 @@ static void destroy(private_sender_t *this) { pthread_cancel(this->assigned_thread); pthread_join(this->assigned_thread, NULL); + this->list->destroy_offset(this->list, offsetof(packet_t, destroy)); free(this); } @@ -94,11 +132,16 @@ sender_t * sender_create() { private_sender_t *this = malloc_thing(private_sender_t); + this->public.send = (void(*)(sender_t*,packet_t*))send_; this->public.destroy = (void(*)(sender_t*)) destroy; - if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))send_packets, this) != 0) + this->list = linked_list_create(); + pthread_mutex_init(&this->mutex, NULL); + pthread_cond_init(&this->condvar, NULL); + + if (pthread_create(&this->assigned_thread, NULL, + (void*)send_packets, this) != 0) { - free(this); charon->kill(charon, "unable to create sender thread"); } diff --git a/src/charon/threads/sender.h b/src/charon/threads/sender.h index bc2a1eab1..4f42f6f9e 100644 --- a/src/charon/threads/sender.h +++ b/src/charon/threads/sender.h @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -27,6 +27,7 @@ typedef struct sender_t sender_t; #include <library.h> +#include <network/packet.h> /** * @brief Thread responsible for sending packets over the socket. @@ -37,25 +38,34 @@ typedef struct sender_t sender_t; * @ingroup threads */ struct sender_t { - + + /** + * @brief Send a packet over the network. + * + * This function is non blocking and adds the packet to a queue. + * Whenever the sender thread things it's good to send the packet, + * it'll do so. + * + * @param this calling object + * @param packet packet to send + */ + void (*send) (sender_t *this, packet_t *packet); + /** * @brief Destroys a sender object. * - * @param sender calling object + * @param this calling object */ - void (*destroy) (sender_t *sender); + void (*destroy) (sender_t *this); }; - /** * @brief Create the sender thread. * * The thread will start to work, getting packets - * from the send queue and sends them out. + * from its queue and sends them out. * - * @return - * - sender_t object - * - NULL of thread could not be started + * @return created sender object * * @ingroup threads */ |