initialize libstrongswan in dynamic stand-alone libimcv-based libraries
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 1 Jun 2011 18:59:25 +0000 (20:59 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 1 Jun 2011 18:59:25 +0000 (20:59 +0200)
src/libimcv/Makefile.am
src/libimcv/imc/imc_agent.c
src/libimcv/imcv.c [new file with mode: 0644]
src/libimcv/imcv.h [new file with mode: 0644]
src/libimcv/imv/imv_agent.c
src/libimcv/plugins/imc_test/imc_test.c
src/libimcv/plugins/imv_test/imv_test.c

index ffce14a..1f0b028 100644 (file)
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES = libimcv.la
 libimcv_la_LIBADD = $(top_builddir)/src/libtncif/libtncif.la
 
 libimcv_la_SOURCES = \
+       imcv.h imcv.c \
        imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
        imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
        ietf/ietf_attr.h \
index 8edd59a..68799c8 100644 (file)
@@ -12,6 +12,7 @@
  * for more details.
  */
 
+#include "imcv.h"
 #include "imc_agent.h"
 
 #include <debug.h>
@@ -277,6 +278,9 @@ METHOD(imc_agent_t, destroy, void,
        this->connections->destroy_function(this->connections, free);
        this->connection_lock->destroy(this->connection_lock);
        free(this);
+
+       /* decrease the reference count or terminate */
+       libimcv_deinit();
 }
 
 /**
@@ -288,6 +292,12 @@ imc_agent_t *imc_agent_create(const char *name,
 {
        private_imc_agent_t *this;
 
+       /* initialize  or increase the reference count */
+       if (!libimcv_init())
+       {
+               return NULL;
+       }
+
        INIT(this,
                .public = {
                        .bind_functions = _bind_functions,
diff --git a/src/libimcv/imcv.c b/src/libimcv/imcv.c
new file mode 100644 (file)
index 0000000..4d86b0b
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "imcv.h"
+
+#include "utils.h"
+#include <debug.h>
+
+#include <syslog.h>
+
+/**
+ * Reference count for IMC/IMV instances
+ */
+refcount_t ref = 0;
+
+/**
+ * Global configuration of libimcv dbg function
+ */
+static int debug_level = 3;
+static bool stderr_quiet = FALSE;
+
+/**
+ * libimvc dbg function
+ */
+static void libimcv_dbg(debug_t group, level_t level, char *fmt, ...)
+{
+       int priority = LOG_INFO;
+       char buffer[8192];
+       char *current = buffer, *next;
+       va_list args;
+
+       if (level <= debug_level)
+       {
+               if (!stderr_quiet)
+               {
+                       va_start(args, fmt);
+                       vfprintf(stderr, fmt, args);
+                       fprintf(stderr, "\n");
+                       va_end(args);
+               }
+
+               /* write in memory buffer first */
+               va_start(args, fmt);
+               vsnprintf(buffer, sizeof(buffer), fmt, args);
+               va_end(args);
+
+               /* do a syslog with every line */
+               while (current)
+               {
+                       next = strchr(current, '\n');
+                       if (next)
+                       {
+                               *(next++) = '\0';
+                       }
+                       syslog(priority, "%s\n", current);
+                       current = next;
+               }
+       }
+}
+
+/**
+ * Described in header.
+ */
+bool libimcv_init(void)
+{
+       /* initialize libstrongswan library only once */
+       if (lib)
+       {
+               /* did main program initialize libstrongswan? */
+               if (ref == 0)
+               {
+                       ref_get(&ref);
+               }
+       }
+       else
+       {
+               /* we are the first to initialize libstrongswan */
+               if (!library_init(NULL))
+               {
+                       return FALSE;
+               }
+
+               if (!lib->plugins->load(lib->plugins, NULL, "random"))
+               {
+                       library_deinit();
+                       return FALSE;
+               }
+
+               /* enable libimcv debugging hook */
+               dbg = libimcv_dbg;
+               openlog("imcv", 0, LOG_DAEMON);
+
+               DBG1(DBG_LIB, "libimcv initialized");
+       }
+       ref_get(&ref);
+
+       return TRUE;
+}
+
+/**
+ * Described in header.
+ */
+void libimcv_deinit(void)
+{
+       if (ref_put(&ref))
+       {
+               DBG1(DBG_LIB, "libimcv terminated");
+               library_deinit();               
+       }
+}
+
+
diff --git a/src/libimcv/imcv.h b/src/libimcv/imcv.h
new file mode 100644 (file)
index 0000000..85c3350
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup libimcv libimcv
+ *
+ * @defgroup iplugins plugins
+ * @ingroup libimcv
+ *
+ * @addtogroup libimcv
+ * @{
+ */
+
+#ifndef IMCV_H_
+#define IMCV_H_
+
+#include <library.h>
+
+/**
+ * Initialize libimcv.
+ *
+ * @return                             FALSE if initialization failed
+ */
+bool libimcv_init(void);
+
+/**
+ * Deinitialize libimcv.
+ */
+void libimcv_deinit(void);
+
+#endif /** IMCV_H_ @}*/
index 1309cfe..cca3ed4 100644 (file)
@@ -12,8 +12,8 @@
  * for more details.
  */
 
+#include "imcv.h"
 #include "imv_agent.h"
-#include "imv_state.h"
 
 #include <debug.h>
 #include <utils/linked_list.h>
@@ -345,6 +345,9 @@ METHOD(imv_agent_t, destroy, void,
                                                                          offsetof(imv_state_t, destroy));
        this->connection_lock->destroy(this->connection_lock);
        free(this);
+
+       /* decrease the reference count or terminate */
+       libimcv_deinit();
 }
 
 /**
@@ -356,6 +359,12 @@ imv_agent_t *imv_agent_create(const char *name,
 {
        private_imv_agent_t *this;
 
+       /* initialize  or increase the reference count */
+       if (!libimcv_init())
+       {
+               return NULL;
+       }
+
        INIT(this,
                .public = {
                        .bind_functions = _bind_functions,
@@ -374,7 +383,7 @@ imv_agent_t *imv_agent_create(const char *name,
                .connections = linked_list_create(),
                .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        );
-       
+
        *actual_version = TNC_IFIMV_VERSION_1;
        DBG1(DBG_IMV, "IMV %u \"%s\" initialized", this->id, this->name);
 
index 752a66e..8971427 100644 (file)
@@ -44,13 +44,17 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
                DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
                return TNC_RESULT_ALREADY_INITIALIZED;
        }
+       imc_test = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
+                                                               imc_id, actual_version);
+       if (!imc_test)
+       {
+               return TNC_RESULT_FATAL;
+       }
        if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
        {
                DBG1(DBG_IMC, "no common IF-IMC version");
                return TNC_RESULT_NO_COMMON_VERSION;
        }
-       imc_test = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
-                                                               imc_id, actual_version);
        return TNC_RESULT_SUCCESS;
 }
 
index a6540c1..9324ebe 100644 (file)
@@ -44,13 +44,17 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
                DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name);
                return TNC_RESULT_ALREADY_INITIALIZED;
        }
+       imv_test = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE,
+                                                               imv_id, actual_version);
+       if (!imv_test)
+       {
+               return TNC_RESULT_FATAL;
+       }
        if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1)
        {
                DBG1(DBG_IMV, "no common IF-IMV version");
                return TNC_RESULT_NO_COMMON_VERSION;
        }
-       imv_test = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE,
-                                                               imv_id, actual_version);
        return TNC_RESULT_SUCCESS;
 }