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 /eurephiafw.c | |
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
Diffstat (limited to 'eurephiafw.c')
-rw-r--r-- | eurephiafw.c | 101 |
1 files changed, 101 insertions, 0 deletions
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); +} + |