Skip to content

Commit

Permalink
- For PR #93: dynlibmod can handle reloads and deinit and inits again,
Browse files Browse the repository at this point in the history
  with dlclose and dlopen of the library again.  Also for multiple
  modules.  Fix memory leak by not closing dlopened content.  Fix
  to allow one dynlibmod instance by unbound-checkconf.
  • Loading branch information
wcawijngaards committed May 18, 2020
1 parent 510e79a commit 01db6c3
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 1 deletion.
6 changes: 6 additions & 0 deletions doc/Changelog
@@ -1,3 +1,9 @@
18 May 2020: Wouter
- For PR #93: dynlibmod can handle reloads and deinit and inits again,
with dlclose and dlopen of the library again. Also for multiple
modules. Fix memory leak by not closing dlopened content. Fix
to allow one dynlibmod instance by unbound-checkconf.

15 May 2020: Wouter
- Merge PR #93: Add dynamic library support.
- Fixed conflicts for PR #93 and make configure, yacc, lex.
Expand Down
19 changes: 18 additions & 1 deletion dynlibmod/dynlibmod.c
Expand Up @@ -34,6 +34,11 @@ void log_dlerror() {
HMODULE open_library(const char* fname) {
return LoadLibrary(fname);
}

void close_library(const char* fname, __DYNMOD handle) {
(void)fname;
(void)handle;
}
#else
#include <dlfcn.h>
#define __DYNMOD void*
Expand All @@ -46,11 +51,20 @@ void log_dlerror() {
void* open_library(const char* fname) {
return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
}

void close_library(const char* fname, __DYNMOD handle) {
if(!handle) return;
if(dlclose(handle) != 0) {
log_err("dlclose %s: %s", fname, strerror(errno));
}
}
#endif

/** module counter for multiple dynlib modules */
static int dynlib_mod_count = 0;

/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id) {
static int dynlib_mod_count;
int dynlib_mod_idx = dynlib_mod_count++;
struct config_strlist* cfg_item = env->cfg->dynlib_file;
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
Expand All @@ -76,6 +90,7 @@ int dynlibmod_init(struct module_env* env, int id) {
}
verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
dynamic_library = open_library(de->fname);
de->dynamic_library = (void*)dynamic_library;
if (dynamic_library == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
Expand Down Expand Up @@ -147,6 +162,8 @@ void dynlibmod_deinit(struct module_env* env, int id) {
if(de == NULL)
return;
de->func_deinit(env, id);
close_library(de->fname, (__DYNMOD)de->dynamic_library);
dynlib_mod_count--;
de->fname = NULL;
free(de);
}
Expand Down
2 changes: 2 additions & 0 deletions dynlibmod/dynlibmod.h
Expand Up @@ -114,6 +114,8 @@ typedef int (*inplace_cb_register_wrapped_t)(void*, enum inplace_cb_list_type, v
struct dynlibmod_env {
/** Dynamic library filename. */
const char* fname;
/** dynamic library handle */
void* dynamic_library;
/** Module init function */
func_init_t func_init;
/** Module deinit function */
Expand Down
48 changes: 48 additions & 0 deletions smallapp/unbound-checkconf.c
Expand Up @@ -569,6 +569,54 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "python dns64 iterator") != 0
&& strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
#endif
#ifdef WITH_DYNLIBMODULE
&& strcmp(cfg->module_conf, "dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip iterator") != 0
&& strcmp(cfg->module_conf, "dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip validator iterator") != 0
&& strcmp(cfg->module_conf, "validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "validator cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip validator cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "validator dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod respip validator dynlib iterator") != 0
#endif
#ifdef USE_CACHEDB
&& strcmp(cfg->module_conf, "validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0
Expand Down

0 comments on commit 01db6c3

Please sign in to comment.