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/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,¤t_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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user