implemented a simple IP blocking filter in receiver thread
This commit is contained in:
+109
-11
@@ -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,¤t_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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user