removed send_queue, handled internally in sender_t know

do header parsing in receiver, ready for cookie integration
This commit is contained in:
Martin Willi
2007-03-28 13:34:02 +00:00
parent 077a6fff95
commit 4deb89485c
20 changed files with 419 additions and 653 deletions
+3 -3
View File
@@ -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
-3
View File
@@ -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;
+3 -15
View File
@@ -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.
@@ -308,11 +301,6 @@ struct daemon_t {
*/
socket_t *socket;
/**
* A send_queue_t instance.
*/
send_queue_t *send_queue;
/**
* A job_queue_t instance.
*/
@@ -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);
}
@@ -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_*/
+2 -2
View File
@@ -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",
+2 -2
View File
@@ -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.
@@ -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);
}
@@ -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_*/
-144
View File
@@ -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);
}
-100
View File
@@ -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_*/
@@ -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);
+2 -2
View File
@@ -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);
}
+39
View File
@@ -729,6 +729,44 @@ static status_t checkin_and_destroy(private_ike_sa_manager_t *this, ike_sa_t *ik
return retval;
}
/**
* 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.
*/
@@ -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();
+16
View File
@@ -166,6 +166,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.
*
+5 -6
View File
@@ -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
{
+95 -70
View File
@@ -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;
@@ -87,75 +87,6 @@ struct private_receiver_t {
pthread_mutex_t mutex;
};
/**
* Implementation of receiver_t.receive_packets.
*/
static void receive_packets(private_receiver_t * this)
{
packet_t *packet;
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());
while (TRUE)
{
if (charon->socket->receive(charon->socket, &packet) != SUCCESS)
{
DBG1(DBG_NET, "receiving from socket failed!");
continue;
}
if (this->blocks->get_count(this->blocks))
{
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;
}
}
DBG2(DBG_NET, "creating job from packet");
job = (job_t *) incoming_packet_job_create(packet);
charon->job_queue->add(charon->job_queue, job);
}
}
/**
* Implementation of receiver_t.block
*/
@@ -172,6 +103,100 @@ static void block(private_receiver_t *this, host_t *ip, u_int32_t seconds)
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;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
DBG1(DBG_NET, "receiver thread running, thread_ID: %06u",
(int)pthread_self());
while (TRUE)
{
if (charon->socket->receive(charon->socket, &packet) != SUCCESS)
{
DBG1(DBG_NET, "receiving from socket failed!");
continue;
}
if (is_blocked(this, packet->get_source(packet)))
{
packet->destroy(packet);
continue;
}
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.destroy.
*/
+2 -3
View File
@@ -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()
+58 -15
View File
@@ -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");
}
+19 -9
View File
@@ -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
*/