summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2008-08-20 00:08:12 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2008-08-20 00:08:12 +0200
commitc0da96e53cd8b5bac09975fe4bd7701bbb36f5bd (patch)
tree46bcdc38a2a6405ccdaae07892a4a34ab6f322d1
parent084ffe9fb93691104a2ac8bdf1ab85fddb30062c (diff)
downloadeurephia-c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd.tar.gz
eurephia-c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd.tar.xz
eurephia-c0da96e53cd8b5bac09975fe4bd7701bbb36f5bd.zip
Added framework for putting a firewall module into its own thread
-rw-r--r--Makefile1
-rw-r--r--eurephia.c4
-rw-r--r--eurephia_struct.h35
-rw-r--r--eurephiafw.c101
-rw-r--r--eurephiafw.h5
-rw-r--r--eurephiafw_intf.h2
6 files changed, 144 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index b2b5264..6f87fc0 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/eurephia.c b/eurephia.c
index e2d7ebc..0102465 100644
--- a/eurephia.c
+++ b/eurephia.c
@@ -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_ */