removed send_queue, handled internally in sender_t know
do header parsing in receiver, ready for cookie integration
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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_*/
|
||||
@@ -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",
|
||||
|
||||
@@ -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_*/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user