diff options
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.c | 62 | ||||
-rw-r--r-- | src/libstrongswan/plugins/plugin_loader.h | 10 |
3 files changed, 87 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac index 56738bdf3..07df3a672 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # -# Copyright (C) 2007-2015 Tobias Brunner +# Copyright (C) 2007-2017 Tobias Brunner # Copyright (C) 2006-2016 Andreas Steffen # Copyright (C) 2006-2014 Martin Willi # HSR Hochschule fuer Technik Rapperswil @@ -1303,6 +1303,19 @@ AM_CONDITIONAL(PYTHON_EGGS_INSTALL, [test "x$python_eggs_install" = xtrue]) AM_CONDITIONAL(PERL_CPAN_INSTALL, [test "x$perl_cpan_install" = xtrue]) +AC_CACHE_CHECK( + [if plugin constructors should be resolved statically], + [ss_cv_static_plugin_constructors], + [if test x$monolithic = xtrue -a x$enable_static = xyes; then + ss_cv_static_plugin_constructors=yes + else + ss_cv_static_plugin_constructors="no (enabled for static, monolithic builds)" + fi] +) +if test "x$ss_cv_static_plugin_constructors" = xyes; then + static_plugin_constructors=true +fi + # =============================================== # collect plugin list for strongSwan components # =============================================== @@ -1678,6 +1691,7 @@ AM_CONDITIONAL(USE_IMCV, test x$imcv = xtrue) AM_CONDITIONAL(USE_TROUSERS, test x$tss_trousers = xtrue) AM_CONDITIONAL(USE_TSS2, test x$tss_tss2 = xtrue) AM_CONDITIONAL(MONOLITHIC, test x$monolithic = xtrue) +AM_CONDITIONAL(STATIC_PLUGIN_CONSTRUCTORS, test x$static_plugin_constructors = xtrue) AM_CONDITIONAL(USE_SILENT_RULES, test x$enable_silent_rules = xyes) AM_CONDITIONAL(COVERAGE, test x$coverage = xtrue) AM_CONDITIONAL(USE_DBGHELP, test x$dbghelp_backtraces = xtrue) @@ -1709,6 +1723,9 @@ fi if test x$monolithic = xtrue; then AC_DEFINE([MONOLITHIC], [], [monolithic build embedding plugins]) fi +if test x$static_plugin_constructors = xtrue; then + AC_DEFINE([STATIC_PLUGIN_CONSTRUCTORS], [], [static plugin constructors]) +fi if test x$ikev1 = xtrue; then AC_DEFINE([USE_IKEV1], [], [support for IKEv1 protocol]) fi diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index e4698fac0..e78762b2c 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -40,6 +40,13 @@ typedef struct registered_feature_t registered_feature_t; typedef struct provided_feature_t provided_feature_t; typedef struct plugin_entry_t plugin_entry_t; +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/** + * Statically registered constructors + */ +static hashtable_t *plugin_constructors = NULL; +#endif + /** * private data of plugin_loader */ @@ -298,6 +305,46 @@ static plugin_t *static_features_create(const char *name, return &this->public; } +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/* + * Described in header. + */ +void plugin_constructor_register(char *name, void *constructor) +{ + bool old = FALSE; + + if (lib && lib->leak_detective) + { + old = lib->leak_detective->set_state(lib->leak_detective, FALSE); + } + + if (!plugin_constructors) + { + chunk_hash_seed(); + plugin_constructors = hashtable_create(hashtable_hash_str, + hashtable_equals_str, 32); + } + if (constructor) + { + plugin_constructors->put(plugin_constructors, name, constructor); + } + else + { + plugin_constructors->remove(plugin_constructors, name); + if (!plugin_constructors->get_count(plugin_constructors)) + { + plugin_constructors->destroy(plugin_constructors); + plugin_constructors = NULL; + } + } + + if (lib && lib->leak_detective) + { + lib->leak_detective->set_state(lib->leak_detective, old); + } +} +#endif + /** * create a plugin * returns: NOT_FOUND, if the constructor was not found @@ -309,7 +356,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, { char create[128]; plugin_t *plugin; - plugin_constructor_t constructor; + plugin_constructor_t constructor = NULL; if (snprintf(create, sizeof(create), "%s_plugin_create", name) >= sizeof(create)) @@ -317,8 +364,17 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, return FAILED; } translate(create, "-", "_"); - constructor = dlsym(handle, create); - if (constructor == NULL) +#ifdef STATIC_PLUGIN_CONSTRUCTORS + if (plugin_constructors) + { + constructor = plugin_constructors->get(plugin_constructors, name); + } + if (!constructor) +#endif + { + constructor = dlsym(handle, create); + } + if (!constructor) { return NOT_FOUND; } diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h index 6be6a909c..92a860615 100644 --- a/src/libstrongswan/plugins/plugin_loader.h +++ b/src/libstrongswan/plugins/plugin_loader.h @@ -168,4 +168,14 @@ plugin_loader_t *plugin_loader_create(); */ void plugin_loader_add_plugindirs(char *basedir, char *plugins); +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/** + * Register a plugin constructor in case of static builds. + * + * @param name name of the plugin + * @param constructor constructor to register (set to NULL to unregister) + */ +void plugin_constructor_register(char *name, void *constructor); +#endif + #endif /** PLUGIN_LOADER_H_ @}*/ |