Add dynamic library support

This commit is contained in:
PMunch 2019-10-17 15:10:33 +02:00
parent eb2283332b
commit 1762437121
13 changed files with 490 additions and 5 deletions

View File

@ -25,6 +25,7 @@ DNSTAP_SRC=@DNSTAP_SRC@
DNSTAP_OBJ=@DNSTAP_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
WITH_PYUNBOUND=@WITH_PYUNBOUND@
PY_MAJOR_VERSION=@PY_MAJOR_VERSION@
@ -87,6 +88,12 @@ LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=i
INSTALL=$(SHELL) $(srcdir)/install-sh
DYNLIBMOD_SRC=dynlibmod/dynlibmod.c
DYNLIBMOD_OBJ=@DYNLIBMOD_OBJ@
DYNLIBMOD_HEADER=@DYNLIBMOD_HEADER@
DYNLIBMOD_EXTRALIBS=@DYNLIBMOD_EXTRALIBS@
#pythonmod.c is not here, it is mentioned by itself in its own rules,
#makedepend fails on missing interface.h otherwise.
PYTHONMOD_SRC=pythonmod/pythonmod_utils.c
@ -139,7 +146,7 @@ autotrust.lo val_anchor.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@ -326,7 +333,7 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS)
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
@ -453,6 +460,7 @@ clean:
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
rm -f $(ALL_SRC:.c=.lint)
rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
rm -f libunbound.a
rm -rf autom4te.cache .libs build doc/html doc/xml
realclean: clean
@ -622,6 +630,7 @@ depend:
-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
-e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
-e 's?$$(srcdir)/dynlibmod/dynlibmod.h?$$(DYNLIBMOD_HEADER)?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP)
cp $(DEPEND_TARGET) $(DEPEND_TMP2)
@ -783,7 +792,7 @@ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/service
$(srcdir)/services/view.h $(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h \
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
$(srcdir)/ipset/ipset.h
$(srcdir)/ipset/ipset.h $(srcdir)/dynlibmod/dynlibmod.h
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
@ -865,7 +874,8 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
$(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/respip/respip.h $(PYTHONMOD_HEADER) \
$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h \
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h \
$(srcdir)/dynlibmod/dynlibmod.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h
@ -1072,6 +1082,14 @@ dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.
dnstap/dnstap.pb-c.h
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h \
dynlibmod.lo dynlibmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h\
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/wire2str.h
ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h $(srcdir)/ipsecmod/ipsecmod.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \

View File

@ -836,6 +836,9 @@
/* Define if you want Python module. */
#undef WITH_PYTHONMODULE
/* Define if you want dynamic library module. */
#undef WITH_DYNLIBMODULE
/* Define if you want PyUnbound. */
#undef WITH_PYUNBOUND

35
configure vendored
View File

@ -697,6 +697,10 @@ PYTHON_LDFLAGS
PYTHON_CPPFLAGS
PYTHON
PYTHON_VERSION
DYNLIBMOD_EXTRALIBS
DYNLIBMOD_HEADER
DYNLIBMOD_OBJ
WITH_DYNLIBMODULE
PTHREAD_CFLAGS_ONLY
PTHREAD_CFLAGS
PTHREAD_LIBS
@ -851,6 +855,7 @@ enable_alloc_nonregional
with_pthreads
with_solaris_threads
with_syslog_facility
with_dynlibmodule
with_pyunbound
with_pythonmodule
enable_swig_version_check
@ -1607,6 +1612,8 @@ Optional Packages:
--with-solaris-threads use solaris native thread library.
--with-syslog-facility=LOCAL0 - LOCAL7
set SYSLOG_FACILITY, default DAEMON
--with-dynlibmodule build dynamic library module, or
--without-dynlibmodule to disable it. (default=no)
--with-pyunbound build PyUnbound, or --without-pyunbound to skip it.
(default=no)
--with-pythonmodule build Python module, or --without-pythonmodule to
@ -17123,6 +17130,34 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
# Check for dynamic library module
# Check whether --with-dynlibmodule was given.
if test "${with_dynlibmodule+set}" = set; then :
withval=$with_dynlibmodule;
else
withval="no"
fi
if test x_$withval != x_no; then
$as_echo "#define WITH_DYNLIBMODULE 1" >>confdefs.h
WITH_DYNLIBMODULE=yes
DYNLIBMOD_OBJ="dynlibmod.lo"
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
if test $on_mingw = "no"; then
DYNLIBMOD_EXTRALIBS="-ldl -export-dynamic"
else
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.a"
fi
fi
# Check for PyUnbound
# Check whether --with-pyunbound was given.

View File

@ -616,6 +616,28 @@ case "${UNBOUND_SYSLOG_FACILITY}" in
esac
AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
# Check for dynamic library module
AC_ARG_WITH(dynlibmodule,
AC_HELP_STRING([--with-dynlibmodule],
[build dynamic library module, or --without-dynlibmodule to disable it. (default=no)]),
[], [ withval="no" ])
if test x_$withval != x_no; then
AC_DEFINE(WITH_DYNLIBMODULE, 1, [Define if you want dynlib module.])
WITH_DYNLIBMODULE=yes
AC_SUBST(WITH_DYNLIBMODULE)
DYNLIBMOD_OBJ="dynlibmod.lo"
AC_SUBST(DYNLIBMOD_OBJ)
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
AC_SUBST(DYNLIBMOD_HEADER)
if test $on_mingw = "no"; then
DYNLIBMOD_EXTRALIBS="-ldl -export-dynamic"
else
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.a"
fi
AC_SUBST(DYNLIBMOD_EXTRALIBS)
fi
# Check for PyUnbound
AC_ARG_WITH(pyunbound,
AC_HELP_STRING([--with-pyunbound],

236
dynlibmod/dynlibmod.c Normal file
View File

@ -0,0 +1,236 @@
#include "config.h"
#include "util/module.h"
#include "util/config_file.h"
#include "dynlibmod/dynlibmod.h"
#if HAVE_WINDOWS_H
#include <windows.h>
#define __DYNSYM FARPROC
#define __LOADSYM GetProcAddress
void log_dlerror() {
DWORD dwLastError = GetLastError();
LPSTR MessageBuffer;
DWORD dwBufferLength;
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM ;
if(dwBufferLength = FormatMessageA(
dwFormatFlags,
NULL, // module to get message from (NULL == system)
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten;
//
// Output message string on stderr.
//
log_info("dynlibmod: %s (%ld)", MessageBuffer, dwLastError);
//WriteFile(
// GetStdHandle(STD_ERROR_HANDLE),
// MessageBuffer,
// dwBufferLength,
// &dwBytesWritten,
// NULL
// );
//
// Free the buffer allocated by the system.
//
LocalFree(MessageBuffer);
}
}
#else
#include <dlfcn.h>
#define __DYNSYM void*
#define __LOADSYM dlsym
void log_dlerror() {
log_err("dynlibmod: %s", dlerror());
}
#endif
/**
* Global state for the module.
*/
typedef int (*func_init_t)(int, struct config_file*);
typedef int (*func_deinit_t)(int);
typedef int (*func_operate_t)(int, enum module_ev event, struct module_qstate* qstate, void*);
typedef int (*func_inform_t)(int, struct module_qstate* qstate, struct module_qstate* super, void*);
struct dynlibmod_env {
/** Dynamic library filename. */
const char* fname;
/** Module init function */
func_init_t func_init;
/** Module deinit function */
func_deinit_t func_deinit;
/** Module operate function */
func_operate_t func_operate;
/** Module super_inform function */
func_inform_t func_inform;
/** Module qstate. */
struct module_qstate* qstate;
};
struct dynlibmod_qstate {
/** Module per query data. */
void* data;
};
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id) {
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
if (!de)
{
log_err("dynlibmod: malloc failure");
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.");
return 0;
}
log_info("Trying to load library %s", de->fname);
#ifndef HAVE_WINDOWS_H
void* dynamic_library = dlopen(de->fname, RTLD_LAZY | RTLD_GLOBAL);
#else
HMODULE dynamic_library = LoadLibrary(de->fname);
#endif
if (dynamic_library == NULL) {
log_dlerror();
log_err("dynlibmod: unable to load dynamic library.");
return 0;
} else {
__DYNSYM initializer = __LOADSYM(dynamic_library,"init");
if (initializer == NULL) {
log_err("dynlibmod: unable to load init procedure from dynamic library.");
#ifndef HAVE_WINDOWS_H
log_err("dynlibmod: %s", dlerror());
#endif
return 0;
} else {
de->func_init = (func_init_t) initializer;
}
__DYNSYM deinitializer = __LOADSYM(dynamic_library,"deinit");
if (deinitializer == NULL) {
log_err("dynlibmod: unable to load deinit procedure from dynamic library.");
#ifndef HAVE_WINDOWS_H
log_err("dynlibmod: %s", dlerror());
#endif
return 0;
} else {
de->func_deinit = (func_deinit_t) deinitializer;
}
__DYNSYM operate = __LOADSYM(dynamic_library,"operate");
if (operate == NULL) {
log_err("dynlibmod: unable to load operate procedure from dynamic library.");
#ifndef HAVE_WINDOWS_H
log_err("dynlibmod: %s", dlerror());
#endif
return 0;
} else {
de->func_operate = (func_operate_t) operate;
}
__DYNSYM inform = __LOADSYM(dynamic_library,"inform_super");
if (inform == NULL) {
log_err("dynlibmod: unable to load inform_super procedure from dynamic library.");
#ifndef HAVE_WINDOWS_H
log_err("dynlibmod: %s", dlerror());
#endif
return 0;
} else {
de->func_inform = (func_inform_t) inform;
}
}
de->func_init(id, env->cfg);
return 1;
}
/** dynlib module deinit */
void dynlibmod_deinit(struct module_env* env, int id) {
struct dynlibmod_env* de = env->modinfo[id];
if(de == NULL)
return;
de->func_deinit(id);
de->fname = NULL;
free(de);
}
/** dynlib module operate on a query */
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
struct dynlibmod_qstate* dq = (struct dynlibmod_qstate*)qstate->minfo[id];
void * data = dq == NULL ? NULL : dq->data;
int ret = de->func_operate(id, event, qstate, data);
if (ret != 1) {
log_err("dynlibmod: dynamic library returned bad code from operate %d.", ret);
qstate->ext_state[id] = module_error;
}
}
/** dynlib module */
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
struct dynlibmod_qstate* dq = (struct dynlibmod_qstate*)qstate->minfo[id];
void * data = dq == NULL ? NULL : dq->data;
int ret = de->func_inform(id, qstate, super, data);
if (ret != 1) {
log_err("dynlibmod: dynamic library returned bad code from inform_super %d.", ret);
qstate->ext_state[id] = module_error;
}
}
/** dynlib module cleanup query state */
void dynlibmod_clear(struct module_qstate* qstate, int id) {
struct dynlibmod_qstate* dq;
if (qstate == NULL)
return;
dq = (struct dynlibmod_qstate*)qstate->minfo[id];
verbose(VERB_ALGO, "dynlibmod: clear, id: %d, dq:%p", id, dq);
if(dq != NULL) {
/* Free qstate */
free(dq);
}
qstate->minfo[id] = NULL;
}
/** dynlib module alloc size routine */
size_t dynlibmod_get_mem(struct module_env* env, int id) {
struct dynlibmod_env* de = (struct dynlibmod_env*)env->modinfo[id];
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
if(!de)
return 0;
return sizeof(*de);
}
/**
* The module function block
*/
static struct module_func_block dynlibmod_block = {
"dynlib",
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
&dynlibmod_clear, &dynlibmod_get_mem
};
struct module_func_block* dynlibmod_get_funcblock(void)
{
return &dynlibmod_block;
}

71
dynlibmod/dynlibmod.h Normal file
View File

@ -0,0 +1,71 @@
/*
* dynlibmod.h: module header file
*
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the organization nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Dynamic loading module for unbound. Loads dynamic library.
*/
#ifndef DYNLIBMOD_H
#define DYNLIBMOD_H
#include "util/module.h"
#include "services/outbound_list.h"
/**
* Get the module function block.
* @return: function block with function pointers to module methods.
*/
struct module_func_block* dynlibmod_get_funcblock(void);
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id);
/** dynlib module deinit */
void dynlibmod_deinit(struct module_env* env, int id);
/** dynlib module operate on a query */
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** dynlib module */
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** dynlib module cleanup query state */
void dynlibmod_clear(struct module_qstate* qstate, int id);
/** dynlib module alloc size routine */
size_t dynlibmod_get_mem(struct module_env* env, int id);
#endif /* DYNLIBMOD_H */

View File

@ -0,0 +1,45 @@
/*
* This is an example to show how dynamic libraries can be made to work with
* unbound. To build a .so file simply run:
* gcc -I../.. -shared -Wall -Werror -fpic -o helloworld.so helloworld.c
* And to build for windows, first make unbound with the --with-dynlibmod
* switch, then use this command:
* x86_64-w64-mingw32-gcc -m64 -I../.. -shared -Wall -Werror -fpic -o helloworld.dll helloworld.c -L../.. -l:libunbound.a
* to cross-compile a 64-bit Windows DLL.
*/
#include "../../config.h"
#include "../../util/module.h"
#ifdef HAVE_WINDOWS_H
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
EXPORT int init(int id, struct config_file* cfg) {
log_info("Hello world from init");
return 1;
}
EXPORT int deinit(int id) {
log_info("Hello world from deinit");
return 1;
}
EXPORT int operate(int id, enum module_ev event, struct module_qstate* qstate, void* data) {
log_info("Hello world from operate");
if (event == module_event_new || event == module_event_pass) {
qstate->ext_state[id] = module_wait_module;
} else if (event == module_event_moddone) {
qstate->ext_state[id] = module_finished;
} else {
qstate->ext_state[id] = module_error;
}
return 1;
}
EXPORT int inform_super(int id, struct module_qstate* qstate, struct module_qstate* super, void* data) {
log_info("Hello world from inform_super");
return 1;
}

View File

@ -51,6 +51,9 @@
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif
#ifdef WITH_DYNLIBMODULE
#include "dynlibmod/dynlibmod.h"
#endif
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
@ -140,6 +143,9 @@ module_list_avail(void)
#ifdef WITH_PYTHONMODULE
"python",
#endif
#ifdef WITH_DYNLIBMODULE
"dynlib",
#endif
#ifdef USE_CACHEDB
"cachedb",
#endif
@ -171,6 +177,9 @@ module_funcs_avail(void)
#ifdef WITH_PYTHONMODULE
&pythonmod_get_funcblock,
#endif
#ifdef WITH_DYNLIBMODULE
&dynlibmod_get_funcblock,
#endif
#ifdef USE_CACHEDB
&cachedb_get_funcblock,
#endif

View File

@ -264,6 +264,7 @@ config_create(void)
cfg->unblock_lan_zones = 0;
cfg->insecure_lan_zones = 0;
cfg->python_script = NULL;
cfg->dynlib_file = NULL;
cfg->remote_control_enable = 0;
cfg->control_ifs.first = NULL;
cfg->control_ifs.last = NULL;
@ -610,6 +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("module-config:", module_conf)
else S_STRLIST("python-script:", python_script)
else S_STR("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
@ -1062,6 +1064,7 @@ config_get_option(struct config_file* cfg, const char* opt,
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_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check)
else O_DEC(opt, "ip-ratelimit", ip_ratelimit)
else O_DEC(opt, "ratelimit", ratelimit)
@ -1398,6 +1401,7 @@ config_delete(struct config_file* cfg)
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);

View File

@ -439,6 +439,9 @@ struct config_file {
/** Python script file */
struct config_strlist* python_script;
/** Dynamic library file */
char* dynlib_file;
/** Use systemd socket activation. */
int use_systemd;

View File

@ -404,6 +404,8 @@ control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) }
control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_FILE) }
python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) }
python{COLON} { YDVAR(0, VAR_PYTHON) }
dynlib-file{COLON} { YDVAR(1, VAR_DYNLIB_FILE) }
dynlib{COLON} { YDVAR(0, VAR_DYNLIB) }
domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) }
minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) }
rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) }

View File

@ -168,6 +168,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
%token VAR_TLS_SESSION_TICKET_KEYS
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
%token VAR_DYNLIB VAR_DYNLIB_FILE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -175,7 +176,7 @@ toplevelvar: serverstart contents_server | stubstart contents_stub |
forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb |
ipsetstart contents_ipset | authstart contents_auth
ipsetstart contents_ipset | authstart contents_auth | dynlibstart contents_dl
;
/* server: declaration */
@ -2741,6 +2742,21 @@ py_script: VAR_PYTHON_SCRIPT STRING_ARG
if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2))
yyerror("out of memory");
}
dynlibstart: VAR_DYNLIB
{
OUTYY(("\nP(dynlib:)\n"));
}
;
contents_dl: contents_dl content_dl
| ;
content_dl: dl_file
;
dl_file: VAR_DYNLIB_FILE STRING_ARG
{
OUTYY(("P(dynlib-file:%s)\n", $2));
free(cfg_parser->cfg->dynlib_file);
cfg_parser->cfg->dynlib_file = $2;
}
server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
{
OUTYY(("P(disable_dnssec_lame_check:%s)\n", $2));

View File

@ -81,6 +81,9 @@
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif
#ifdef WITH_DYNLIBMODULE
#include "dynlibmod/dynlibmod.h"
#endif
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
@ -379,6 +382,9 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_init) return 1;
#endif
#ifdef WITH_DYNLIBMODULE
else if(fptr == &dynlibmod_init) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_init) return 1;
#endif
@ -404,6 +410,9 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_deinit) return 1;
#endif
#ifdef WITH_DYNLIBMODULE
else if(fptr == &dynlibmod_deinit) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_deinit) return 1;
#endif
@ -430,6 +439,9 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_operate) return 1;
#endif
#ifdef WITH_DYNLIBMODULE
else if(fptr == &dynlibmod_operate) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_operate) return 1;
#endif
@ -456,6 +468,9 @@ fptr_whitelist_mod_inform_super(void (*fptr)(
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_inform_super) return 1;
#endif
#ifdef WITH_DYNLIBMODULE
else if(fptr == &dynlibmod_inform_super) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_inform_super) return 1;
#endif
@ -482,6 +497,9 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_clear) return 1;
#endif
#ifdef WITH_DYNLIBMODULE
else if(fptr == &dynlibmod_clear) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_clear) return 1;
#endif
@ -507,6 +525,9 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_get_mem) return 1;
#endif
#ifdef WITH_DYNLIBMODULE
else if(fptr == &dynlibmod_get_mem) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_get_mem) return 1;
#endif