a very small wrapper that allows dynamic modules to be loaded on runtime
instead of being compiled into the application. To enable the dynlib module it
has to be compiled into the daemon, and the word "dynlib" has to be put in the
-\fBmodule\-config:\fR option.
+\fBmodule\-config:\fR option. Multiple instances of dynamic libraries are
+supported by adding the word "dynlib" more than once.
.LP
The \fBdynlib\-file:\fR path should be specified as an absolute path relative
to the new path set by \fBchroot:\fR option, or as a relative path to the
working directory.
.TP
.B dynlib\-file: \fI<dynlib file>\fR
-The dynamic library file to load.
+The dynamic library file to load. Repeat this option for every dynlib module
+instance added to the \fBmodule\-config:\fR option.
.SS "DNS64 Module Options"
.LP
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
struct module_qstate* qstate;
};
+/**
+ * counter for dynamic library module instances
+ * incremeted by dynlibmod_init
+ */
+int dynlib_mod_count = 0;
+
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id) {
+ 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));
__DYNMOD dynamic_library;
if (!de)
{
- log_err("dynlibmod: malloc failure");
+ log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
return 0;
}
env->modinfo[id] = (void*) de;
- de->fname = env->cfg->dynlib_file;
- if (de->fname == NULL || de->fname[0] == 0) {
- log_err("dynlibmod: no dynamic library given.");
+ de->fname = NULL;
+ for(int i = dynlib_mod_idx;
+ i != 0 && cfg_item != NULL;
+ i--, cfg_item = cfg_item->next) {}
+
+ if (cfg_item == NULL || cfg_item->str == NULL || cfg_item->str[0] == 0) {
+ log_err("dynlibmod[%d]: no dynamic library given.", dynlib_mod_idx);
return 0;
+ } else {
+ de->fname = cfg_item->str;
}
- verbose(VERB_ALGO, "dynlibmod: Trying to load library %s", de->fname);
+ verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
dynamic_library = open_library(de->fname);
if (dynamic_library == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
__DYNSYM initializer = __LOADSYM(dynamic_library,"init");
if (initializer == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load init procedure from dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load init procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_init = (func_init_t) initializer;
__DYNSYM deinitializer = __LOADSYM(dynamic_library,"deinit");
if (deinitializer == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load deinit procedure from dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load deinit procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_deinit = (func_deinit_t) deinitializer;
__DYNSYM operate = __LOADSYM(dynamic_library,"operate");
if (operate == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load operate procedure from dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load operate procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_operate = (func_operate_t) operate;
__DYNSYM inform = __LOADSYM(dynamic_library,"inform_super");
if (inform == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load inform_super procedure from dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load inform_super procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_inform = (func_inform_t) inform;
__DYNSYM clear = __LOADSYM(dynamic_library,"clear");
if (clear == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load clear procedure from dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load clear procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_clear = (func_clear_t) clear;
__DYNSYM get_mem = __LOADSYM(dynamic_library,"get_mem");
if (get_mem == NULL) {
log_dlerror();
- log_err("dynlibmod: unable to load get_mem procedure from dynamic library \"%s\".", de->fname);
+ log_err("dynlibmod[%d]: unable to load get_mem procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_get_mem = (func_get_mem_t) get_mem;
else S_STR("control-cert-file:", control_cert_file)
else S_STR("module-config:", module_conf)
else S_STRLIST("python-script:", python_script)
- else S_STR("dynlib-file:", dynlib_file)
+ else S_STRLIST("dynlib-file:", dynlib_file)
else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check)
#ifdef CLIENT_SUBNET
/* Can't set max subnet prefix here, since that value is used when
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
else O_DEC(opt, "max-udp-size", max_udp_size)
else O_LST(opt, "python-script", python_script)
- else O_STR(opt, "dynlib-file", dynlib_file)
+ else O_LST(opt, "dynlib-file", dynlib_file)
else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
else O_DEC(opt, "ratelimit", ratelimit)
free(cfg->version);
free(cfg->module_conf);
free(cfg->outgoing_avail_ports);
- free(cfg->dynlib_file);
config_delstrlist(cfg->caps_whitelist);
config_delstrlist(cfg->private_address);
config_delstrlist(cfg->private_domain);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script);
+ config_delstrlist(cfg->dynlib_file);
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);