diff options
| author | David Sommerseth <dazo@users.sourceforge.net> | 2008-08-20 00:08:12 +0200 |
|---|---|---|
| committer | David Sommerseth <dazo@users.sourceforge.net> | 2008-08-20 00:08:12 +0200 |
| commit | c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd (patch) | |
| tree | 46bcdc38a2a6405ccdaae07892a4a34ab6f322d1 | |
| parent | 084ffe9fb93691104a2ac8bdf1ab85fddb30062c (diff) | |
| download | eurephia-c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd.tar.gz eurephia-c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd.tar.xz eurephia-c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd.zip | |
Added framework for putting a firewall module into its own thread
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | eurephia.c | 4 | ||||
| -rw-r--r-- | eurephia_struct.h | 35 | ||||
| -rw-r--r-- | eurephiafw.c | 101 | ||||
| -rw-r--r-- | eurephiafw.h | 5 | ||||
| -rw-r--r-- | eurephiafw_intf.h | 2 |
6 files changed, 144 insertions, 4 deletions
@@ -9,6 +9,7 @@ objs = eurephiadb.o eurephia_log.o eurephia_values.o eurephiadb_session.o sha1.o testprog_obj = eurephiadb-testprog.o eurephiadb.o eurephia_log.o sha1.o eurephiadb_session.o CFLAGS += -I. +LDFLAGS += -lpthread -lrt -lgcc_s ifeq (${EUREPHIAMW},enabled) objs += memwatch.o @@ -149,6 +149,7 @@ eurephiaCTX *eurephiaInit(const char **argv) if( fwintf != NULL ) { if( eFW_load(ctx, fwintf) ) { eurephia_log(ctx, LOG_INFO, 0, "Loaded firewall interface: %s", fwintf); + eFW_StartFirewall(ctx); } else { eurephia_log(ctx, LOG_INFO, 0, "Loading of firewall interface failed (%s)", fwintf); ctx->eurephia_fw_intf = NULL; @@ -169,6 +170,9 @@ int eurephiaShutdown(eurephiaCTX *ctx) } if( ctx->eurephia_fw_intf != NULL ) { + if( ctx->fwcfg != NULL ) { + eFW_StopFirewall(ctx); + } eFW_unload(ctx); } diff --git a/eurephia_struct.h b/eurephia_struct.h index 8cc9838..b1dac41 100644 --- a/eurephia_struct.h +++ b/eurephia_struct.h @@ -21,6 +21,8 @@ /*** Structures used by the eurphia module ***/ +#include <mqueue.h> +#include <semaphore.h> #ifndef EUREPHIASTRUCT_H_ #define EUREPHIASTRUCT_H_ @@ -38,6 +40,10 @@ typedef struct __eurephiaVALUES { struct __eurephiaVALUES *next; } eurephiaVALUES; + +// +// Struct which contains session unique data +// typedef struct { char *sessionkey; int sessionstatus; @@ -45,6 +51,10 @@ typedef struct { } eurephiaSESSION; + +// +// Struct containing connection to the database we are using +// typedef struct { void *dbhandle; char *dbname; @@ -52,13 +62,32 @@ typedef struct { } eDBconn; -/* - * Our plugin context, where we keep our state. - */ + +// +// structs used by the firewall interface +// +typedef struct { + mqd_t msgq; + sem_t semp_module; + sem_t semp_driver; +} efw_threaddata; + +typedef struct { + pthread_t fw_thread; + pthread_attr_t fw_threadattr; + efw_threaddata thrdata; +} eurephiaFWINTF; + + +// +// main structure for the eurephia module context +// - the same context structure is used for all OpenVPN sessions +// typedef struct { void *eurephia_driver; void *eurephia_fw_intf; eDBconn *dbc; + eurephiaFWINTF *fwcfg; FILE *log; int loglevel; int fatal_error; diff --git a/eurephiafw.c b/eurephiafw.c index ebdcbe3..47324f7 100644 --- a/eurephiafw.c +++ b/eurephiafw.c @@ -19,14 +19,23 @@ */ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <dlfcn.h> +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <pthread.h> #include "eurephia_struct.h" #include "eurephia_log.h" #include "eurephiafw.h" #include "eurephiafw_intf.h" #include "eurephia_getsym.h" +#include "eurephia_nullsafe.h" +#include "eurephiafw_intf.h" + +#define MQUEUE_NAME "eurephiaFW" int eFW_unload(eurephiaCTX *ctx) { @@ -88,3 +97,95 @@ int eFW_load(eurephiaCTX *ctx, const char *intf) { return 1; } +void eFW_StartFirewall(eurephiaCTX *ctx) { + struct mq_attr mqattr; + + ctx->fwcfg = (eurephiaFWINTF *) malloc(sizeof(eurephiaFWINTF)+2); + memset(ctx->fwcfg, 0, sizeof(eurephiaFWINTF)+2); + + + // Initialise driver semaphore + if( sem_init(&(*ctx->fwcfg).thrdata.semp_driver, 0, 0) != 0 ) { + eurephia_log(ctx, LOG_FATAL, 0, "Could not setup semaphore for FW driver: %s", strerror(errno)); + free_nullsafe(ctx->fwcfg); + return; + } + + // Start a new thread (with root permissions) - which will do the firewall work + pthread_attr_init(&(*ctx->fwcfg).fw_threadattr); + pthread_attr_setdetachstate(&(*ctx->fwcfg).fw_threadattr, PTHREAD_CREATE_JOINABLE); + if( pthread_create(&(*ctx->fwcfg).fw_thread, &(*ctx->fwcfg).fw_threadattr, + eFW_RunFirewall, (void *) &(*ctx->fwcfg).thrdata) ) { + eurephia_log(ctx, LOG_FATAL, 0, "Could not start firewall thread: %s", strerror(errno)); + free_nullsafe(ctx->fwcfg); + return; + } + + // Prepare a POSIX Message Queue + mqattr.mq_maxmsg = 10; + mqattr.mq_msgsize = 1024; + mqattr.mq_flags = 0; + (*ctx->fwcfg).thrdata.msgq = mq_open(MQUEUE_NAME, O_RDWR | O_CREAT, 0600, &mqattr); + if( (*ctx->fwcfg).thrdata.msgq < 0 ) { + pthread_kill((*ctx->fwcfg).fw_thread, SIGABRT); + eurephia_log(ctx, LOG_FATAL, 0, "Could not open message queue: %s", strerror(errno)); + free_nullsafe(ctx->fwcfg); + return; + } + + // Let child have time to settle and create a semaphore for us + sleep(1); + + // Indicate for the FW module that we are ready + sem_post(&(*ctx->fwcfg).thrdata.semp_driver); + + // Waiting for the FW module to get ready + eurephia_log(ctx, LOG_DEBUG, 20, "eFW interface ready, waiting for the eFW module to get ready"); + sem_wait(&(*ctx->fwcfg).thrdata.semp_module); + eurephia_log(ctx, LOG_INFO, 2, "eFW interface initialised."); +} + +void eFW_StopFirewall(eurephiaCTX *ctx) { + char buf[50]; + void *status = NULL; + + if( ctx->fwcfg == NULL ) { + return; + } + + + // Send shutdown message to the firewall module thread + snprintf(buf, 48, "FWSHUTDOWN%c", 0); + if( mq_send((*ctx->fwcfg).thrdata.msgq, buf, 11, 1) == -1 ) { + eurephia_log(ctx, LOG_FATAL, 0, "Could not initiate shutdown on eFW module: %s", strerror(errno)); + pthread_kill((*ctx->fwcfg).fw_thread, SIGABRT); + } + + // Wait for the firewall module thread to finish + pthread_attr_destroy(&(*ctx->fwcfg).fw_threadattr); + if( pthread_join((*ctx->fwcfg).fw_thread, &status) ) { + eurephia_log(ctx, LOG_FATAL, 0, "Could not do thread join on eFW module thread: %s", + strerror(errno)); + pthread_kill((*ctx->fwcfg).fw_thread, SIGABRT); + } + + // Close and remove the message queue used + if( mq_close((*ctx->fwcfg).thrdata.msgq) != 0 ) { + eurephia_log(ctx, LOG_WARNING, 0, "Could not do close the message queue used for eFW: %s", + strerror(errno)); + } + + if( mq_unlink(MQUEUE_NAME) != 0 ) { + eurephia_log(ctx, LOG_WARNING, 0, "Could not do close the message queue used for eFW: %s", + strerror(errno)); + } + + // Take down the semaphore we used + if( sem_destroy(&ctx->fwcfg->thrdata.semp_driver) != 0 ) { + eurephia_log(ctx, LOG_WARNING, 0, "Could not do destroy the driver semaphore for eFW: %s", + strerror(errno)); + } + + free_nullsafe(ctx->fwcfg); +} + diff --git a/eurephiafw.h b/eurephiafw.h index 48b8c57..636312f 100644 --- a/eurephiafw.h +++ b/eurephiafw.h @@ -22,7 +22,10 @@ #define EUREPHIAFW_H_ int eFW_load(eurephiaCTX *ctx, const char *intf); - +void eFW_InitInterface(eurephiaCTX *ctx); int eFW_unload(eurephiaCTX *ctx); +void eFW_StartFirewall(eurephiaCTX *ctx); +void eFW_StopFirewall(eurephiaCTX *ctx); + #endif /* !EUREPHIAFW_H_ */ diff --git a/eurephiafw_intf.h b/eurephiafw_intf.h index 1397fdc..d756372 100644 --- a/eurephiafw_intf.h +++ b/eurephiafw_intf.h @@ -25,4 +25,6 @@ const char *(*eFWinterfaceVersion) (void); int (*eFWinterfaceAPIversion) (void); +void *(*eFW_RunFirewall) (void *); + #endif /* !EUREPHIAFW_INTF_H_ */ |
