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/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;
@@ -49,6 +75,16 @@ struct private_receiver_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)
{
packet_t * current_packet;
job_t *current_job;
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)
{
while (charon->socket->receive(charon->socket,&current_packet) == SUCCESS)
if (charon->socket->receive(charon->socket, &packet) != SUCCESS)
{
DBG2(DBG_NET, "creating job from packet");
current_job = (job_t *) incoming_packet_job_create(current_packet);
charon->job_queue->add(charon->job_queue,current_job);
DBG1(DBG_NET, "receiving from socket failed!");
continue;
}
/* 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.
*/
@@ -86,16 +179,18 @@ static void destroy(private_receiver_t *this)
{
pthread_cancel(this->assigned_thread);
pthread_join(this->assigned_thread, NULL);
this->blocks->destroy_function(this->blocks, (void*)block_destroy);
free(this);
}
/*
* Described in header.
*/
receiver_t * receiver_create()
receiver_t *receiver_create()
{
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;
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");
}
pthread_mutex_init(&this->mutex, NULL);
this->blocks = linked_list_create();
return &(this->public);
}
+11 -1
View File
@@ -27,12 +27,13 @@
typedef struct receiver_t receiver_t;
#include <library.h>
#include <utils/host.h>
/**
* @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
* data is available, a packet_t object is created, wrapped
* in an incoming_packet_job_t and added to the job queue.
*
* @b Constructors:
@@ -42,6 +43,15 @@ typedef struct receiver_t 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.
*