implemented a simple IP blocking filter in receiver thread

This commit is contained in:
Martin Willi
2007-03-28 09:23:03 +00:00
parent 9179ac9667
commit 077a6fff95
2 changed files with 120 additions and 12 deletions
+109 -11
View File
@@ -33,6 +33,32 @@
#include <queues/jobs/job.h> #include <queues/jobs/job.h>
#include <queues/jobs/incoming_packet_job.h> #include <queues/jobs/incoming_packet_job.h>
typedef struct block_t block_t;
/**
* entry for a blocked IP
*/
struct block_t {
/**
* IP address to block
*/
host_t *ip;
/**
* lifetime for this block
*/
u_int32_t timeout;
};
/**
* destroy a block_t
*/
static void block_destroy(block_t *block)
{
block->ip->destroy(block->ip);
free(block);
}
typedef struct private_receiver_t private_receiver_t; typedef struct private_receiver_t private_receiver_t;
@@ -49,6 +75,16 @@ struct private_receiver_t {
* Assigned thread. * Assigned thread.
*/ */
pthread_t assigned_thread; pthread_t assigned_thread;
/**
* List of blocked IPs
*/
linked_list_t *blocks;
/**
* mutex to exclusively access block list
*/
pthread_mutex_t mutex;
}; };
/** /**
@@ -56,29 +92,86 @@ struct private_receiver_t {
*/ */
static void receive_packets(private_receiver_t * this) static void receive_packets(private_receiver_t * this)
{ {
packet_t * current_packet; packet_t *packet;
job_t *current_job; job_t *job;
/* cancellation disabled by default */ /* cancellation disabled by default */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
DBG1(DBG_NET, "receiver thread running, thread_ID: %06u", DBG1(DBG_NET, "receiver thread running, thread_ID: %06u",
(int)pthread_self()); (int)pthread_self());
while (TRUE) while (TRUE)
{ {
while (charon->socket->receive(charon->socket,&current_packet) == SUCCESS) if (charon->socket->receive(charon->socket, &packet) != SUCCESS)
{ {
DBG2(DBG_NET, "creating job from packet"); DBG1(DBG_NET, "receiving from socket failed!");
current_job = (job_t *) incoming_packet_job_create(current_packet); continue;
charon->job_queue->add(charon->job_queue,current_job);
} }
/* bad bad, TODO: rebuild the socket ? */
DBG1(DBG_NET, "receiving from socket failed!"); 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
*/
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. * Implementation of receiver_t.destroy.
*/ */
@@ -86,16 +179,18 @@ static void destroy(private_receiver_t *this)
{ {
pthread_cancel(this->assigned_thread); pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL); pthread_join(this->assigned_thread, NULL);
this->blocks->destroy_function(this->blocks, (void*)block_destroy);
free(this); free(this);
} }
/* /*
* Described in header. * Described in header.
*/ */
receiver_t * receiver_create() receiver_t *receiver_create()
{ {
private_receiver_t *this = malloc_thing(private_receiver_t); private_receiver_t *this = malloc_thing(private_receiver_t);
this->public.block = (void(*)(receiver_t*,host_t*,u_int32_t)) block;
this->public.destroy = (void(*)(receiver_t*)) destroy; this->public.destroy = (void(*)(receiver_t*)) destroy;
if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))receive_packets, this) != 0) if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))receive_packets, this) != 0)
@@ -104,5 +199,8 @@ receiver_t * receiver_create()
charon->kill(charon, "unable to create receiver thread"); charon->kill(charon, "unable to create receiver thread");
} }
pthread_mutex_init(&this->mutex, NULL);
this->blocks = linked_list_create();
return &(this->public); return &(this->public);
} }
+11 -1
View File
@@ -27,12 +27,13 @@
typedef struct receiver_t receiver_t; typedef struct receiver_t receiver_t;
#include <library.h> #include <library.h>
#include <utils/host.h>
/** /**
* @brief Receives packets from the socket and adds them to the job queue. * @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 * The receiver starts a thread, wich reads on the blocking socket. If
* data is available, a packet_t object is created , wrapped * data is available, a packet_t object is created, wrapped
* in an incoming_packet_job_t and added to the job queue. * in an incoming_packet_job_t and added to the job queue.
* *
* @b Constructors: * @b Constructors:
@@ -42,6 +43,15 @@ typedef struct receiver_t receiver_t;
*/ */
struct receiver_t { struct receiver_t {
/**
* @brief Block packets coming from a specific address.
*
* @param receiver receiver object
* @param ip IP address to block
* @param seconds for how long to block ip
*/
void (*block) (receiver_t *receiver, host_t *ip, u_int32_t seconds);
/** /**
* @brief Destroys a receiver_t object. * @brief Destroys a receiver_t object.
* *