mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Add support for multiple dynamic modules
Allows the use of multiple dynamic modules. Simply add more "dynlib" entries to the "modules-config" and the same amount of "dynlib-file" entries in the dynlib configuration block.
This commit is contained in:
parent
8eeb910e3d
commit
f177dc974c
6 changed files with 38 additions and 21 deletions
|
|
@ -842,7 +842,8 @@ python:
|
||||||
# o list dynlib in the module-config string (above) to enable.
|
# o list dynlib in the module-config string (above) to enable.
|
||||||
# It can be placed anywhere, the dynlib module is only a very thin wrapper
|
# It can be placed anywhere, the dynlib module is only a very thin wrapper
|
||||||
# to load modules dynamically.
|
# to load modules dynamically.
|
||||||
# o and give a dynlib-file to run.
|
# o and give a dynlib-file to run. If more than one dynlib entry is listed in
|
||||||
|
# the module-config then you need one dynlib-file per instance.
|
||||||
dynlib:
|
dynlib:
|
||||||
# Script file to load
|
# Script file to load
|
||||||
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
|
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
|
||||||
|
|
|
||||||
|
|
@ -1792,14 +1792,16 @@ clause gives the settings for the \fIdynlib\fR(1) module. This module is only
|
||||||
a very small wrapper that allows dynamic modules to be loaded on runtime
|
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
|
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
|
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
|
.LP
|
||||||
The \fBdynlib\-file:\fR path should be specified as an absolute path relative
|
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
|
to the new path set by \fBchroot:\fR option, or as a relative path to the
|
||||||
working directory.
|
working directory.
|
||||||
.TP
|
.TP
|
||||||
.B dynlib\-file: \fI<dynlib file>\fR
|
.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"
|
.SS "DNS64 Module Options"
|
||||||
.LP
|
.LP
|
||||||
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
|
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
|
||||||
|
|
|
||||||
|
|
@ -81,34 +81,48 @@ struct dynlibmod_env {
|
||||||
struct module_qstate* qstate;
|
struct module_qstate* qstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* counter for dynamic library module instances
|
||||||
|
* incremeted by dynlibmod_init
|
||||||
|
*/
|
||||||
|
int dynlib_mod_count = 0;
|
||||||
|
|
||||||
/** dynlib module init */
|
/** dynlib module init */
|
||||||
int dynlibmod_init(struct module_env* env, int id) {
|
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));
|
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
|
||||||
__DYNMOD dynamic_library;
|
__DYNMOD dynamic_library;
|
||||||
if (!de)
|
if (!de)
|
||||||
{
|
{
|
||||||
log_err("dynlibmod: malloc failure");
|
log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
env->modinfo[id] = (void*) de;
|
env->modinfo[id] = (void*) de;
|
||||||
|
|
||||||
de->fname = env->cfg->dynlib_file;
|
de->fname = NULL;
|
||||||
if (de->fname == NULL || de->fname[0] == 0) {
|
for(int i = dynlib_mod_idx;
|
||||||
log_err("dynlibmod: no dynamic library given.");
|
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;
|
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);
|
dynamic_library = open_library(de->fname);
|
||||||
if (dynamic_library == NULL) {
|
if (dynamic_library == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
__DYNSYM initializer = __LOADSYM(dynamic_library,"init");
|
__DYNSYM initializer = __LOADSYM(dynamic_library,"init");
|
||||||
if (initializer == NULL) {
|
if (initializer == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_init = (func_init_t) initializer;
|
de->func_init = (func_init_t) initializer;
|
||||||
|
|
@ -116,7 +130,7 @@ int dynlibmod_init(struct module_env* env, int id) {
|
||||||
__DYNSYM deinitializer = __LOADSYM(dynamic_library,"deinit");
|
__DYNSYM deinitializer = __LOADSYM(dynamic_library,"deinit");
|
||||||
if (deinitializer == NULL) {
|
if (deinitializer == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_deinit = (func_deinit_t) deinitializer;
|
de->func_deinit = (func_deinit_t) deinitializer;
|
||||||
|
|
@ -124,7 +138,7 @@ int dynlibmod_init(struct module_env* env, int id) {
|
||||||
__DYNSYM operate = __LOADSYM(dynamic_library,"operate");
|
__DYNSYM operate = __LOADSYM(dynamic_library,"operate");
|
||||||
if (operate == NULL) {
|
if (operate == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_operate = (func_operate_t) operate;
|
de->func_operate = (func_operate_t) operate;
|
||||||
|
|
@ -132,7 +146,7 @@ int dynlibmod_init(struct module_env* env, int id) {
|
||||||
__DYNSYM inform = __LOADSYM(dynamic_library,"inform_super");
|
__DYNSYM inform = __LOADSYM(dynamic_library,"inform_super");
|
||||||
if (inform == NULL) {
|
if (inform == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_inform = (func_inform_t) inform;
|
de->func_inform = (func_inform_t) inform;
|
||||||
|
|
@ -140,7 +154,7 @@ int dynlibmod_init(struct module_env* env, int id) {
|
||||||
__DYNSYM clear = __LOADSYM(dynamic_library,"clear");
|
__DYNSYM clear = __LOADSYM(dynamic_library,"clear");
|
||||||
if (clear == NULL) {
|
if (clear == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_clear = (func_clear_t) clear;
|
de->func_clear = (func_clear_t) clear;
|
||||||
|
|
@ -148,7 +162,7 @@ int dynlibmod_init(struct module_env* env, int id) {
|
||||||
__DYNSYM get_mem = __LOADSYM(dynamic_library,"get_mem");
|
__DYNSYM get_mem = __LOADSYM(dynamic_library,"get_mem");
|
||||||
if (get_mem == NULL) {
|
if (get_mem == NULL) {
|
||||||
log_dlerror();
|
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;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_get_mem = (func_get_mem_t) get_mem;
|
de->func_get_mem = (func_get_mem_t) get_mem;
|
||||||
|
|
|
||||||
|
|
@ -611,7 +611,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
else S_STR("control-cert-file:", control_cert_file)
|
else S_STR("control-cert-file:", control_cert_file)
|
||||||
else S_STR("module-config:", module_conf)
|
else S_STR("module-config:", module_conf)
|
||||||
else S_STRLIST("python-script:", python_script)
|
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)
|
else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check)
|
||||||
#ifdef CLIENT_SUBNET
|
#ifdef CLIENT_SUBNET
|
||||||
/* Can't set max subnet prefix here, since that value is used when
|
/* Can't set max subnet prefix here, since that value is used when
|
||||||
|
|
@ -1064,7 +1064,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||||
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
|
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
|
||||||
else O_DEC(opt, "max-udp-size", max_udp_size)
|
else O_DEC(opt, "max-udp-size", max_udp_size)
|
||||||
else O_LST(opt, "python-script", python_script)
|
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_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
|
||||||
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
|
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
|
||||||
else O_DEC(opt, "ratelimit", ratelimit)
|
else O_DEC(opt, "ratelimit", ratelimit)
|
||||||
|
|
@ -1401,7 +1401,6 @@ config_delete(struct config_file* cfg)
|
||||||
free(cfg->version);
|
free(cfg->version);
|
||||||
free(cfg->module_conf);
|
free(cfg->module_conf);
|
||||||
free(cfg->outgoing_avail_ports);
|
free(cfg->outgoing_avail_ports);
|
||||||
free(cfg->dynlib_file);
|
|
||||||
config_delstrlist(cfg->caps_whitelist);
|
config_delstrlist(cfg->caps_whitelist);
|
||||||
config_delstrlist(cfg->private_address);
|
config_delstrlist(cfg->private_address);
|
||||||
config_delstrlist(cfg->private_domain);
|
config_delstrlist(cfg->private_domain);
|
||||||
|
|
@ -1441,6 +1440,7 @@ config_delete(struct config_file* cfg)
|
||||||
config_deldblstrlist(cfg->ratelimit_for_domain);
|
config_deldblstrlist(cfg->ratelimit_for_domain);
|
||||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||||
config_delstrlist(cfg->python_script);
|
config_delstrlist(cfg->python_script);
|
||||||
|
config_delstrlist(cfg->dynlib_file);
|
||||||
#ifdef USE_IPSECMOD
|
#ifdef USE_IPSECMOD
|
||||||
free(cfg->ipsecmod_hook);
|
free(cfg->ipsecmod_hook);
|
||||||
config_delstrlist(cfg->ipsecmod_whitelist);
|
config_delstrlist(cfg->ipsecmod_whitelist);
|
||||||
|
|
|
||||||
|
|
@ -440,7 +440,7 @@ struct config_file {
|
||||||
struct config_strlist* python_script;
|
struct config_strlist* python_script;
|
||||||
|
|
||||||
/** Dynamic library file */
|
/** Dynamic library file */
|
||||||
char* dynlib_file;
|
struct config_strlist* dynlib_file;
|
||||||
|
|
||||||
/** Use systemd socket activation. */
|
/** Use systemd socket activation. */
|
||||||
int use_systemd;
|
int use_systemd;
|
||||||
|
|
|
||||||
|
|
@ -2754,8 +2754,8 @@ content_dl: dl_file
|
||||||
dl_file: VAR_DYNLIB_FILE STRING_ARG
|
dl_file: VAR_DYNLIB_FILE STRING_ARG
|
||||||
{
|
{
|
||||||
OUTYY(("P(dynlib-file:%s)\n", $2));
|
OUTYY(("P(dynlib-file:%s)\n", $2));
|
||||||
free(cfg_parser->cfg->dynlib_file);
|
if(!cfg_strlist_append_ex(&cfg_parser->cfg->dynlib_file, $2))
|
||||||
cfg_parser->cfg->dynlib_file = $2;
|
yyerror("out of memory");
|
||||||
}
|
}
|
||||||
server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
|
server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue