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
/* 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;
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);
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;
#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>
| | - 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
* (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.
socket_t *socket;
/**
- * A send_queue_t instance.
- */
- send_queue_t *send_queue;
-
- /**
* A job_queue_t instance.
*/
job_queue_t *job_queue;
+++ /dev/null
-/**
- * @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);
-}
+++ /dev/null
-/**
- * @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_*/
#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",
/**
* 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.
--- /dev/null
+/**
+ * @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);
+}
--- /dev/null
+/**
+ * @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_*/
+++ /dev/null
-/**
- * @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);
-}
+++ /dev/null
-/**
- * @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_*/
{
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);
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;
}
}
if (generate_message(this, response, &packet) == SUCCESS)
{
- charon->send_queue->add(charon->send_queue, packet);
+ charon->sender->send(charon->sender, packet);
}
response->destroy(response);
}
}
/**
+ * 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)
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();
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.
}
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));
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;
{
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
{
#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;
};
/**
+ * 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());
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.
/**
* @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()
#include <daemon.h>
#include <network/socket.h>
-#include <network/packet.h>
-#include <queues/send_queue.h>
typedef struct private_sender_t 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);
}
}
{
pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL);
+ this->list->destroy_offset(this->list, offsetof(packet_t, destroy));
free(this);
}
{
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");
}
*/
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
typedef struct sender_t sender_t;
#include <library.h>
+#include <network/packet.h>
/**
* @brief Thread responsible for sending packets over the socket.
* @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
*/