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@
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
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
$(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)
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
-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)
$(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 \
$(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
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 \
/* 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
PYTHON_CPPFLAGS
PYTHON
PYTHON_VERSION
+DYNLIBMOD_EXTRALIBS
+DYNLIBMOD_HEADER
+DYNLIBMOD_OBJ
+WITH_DYNLIBMODULE
PTHREAD_CFLAGS_ONLY
PTHREAD_CFLAGS
PTHREAD_LIBS
with_pthreads
with_solaris_threads
with_syslog_facility
+with_dynlibmodule
with_pyunbound
with_pythonmodule
enable_swig_version_check
--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
_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.
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],
--- /dev/null
+#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;
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif
+#ifdef WITH_DYNLIBMODULE
+#include "dynlibmod/dynlibmod.h"
+#endif
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
#ifdef WITH_PYTHONMODULE
"python",
#endif
+#ifdef WITH_DYNLIBMODULE
+ "dynlib",
+#endif
#ifdef USE_CACHEDB
"cachedb",
#endif
#ifdef WITH_PYTHONMODULE
&pythonmod_get_funcblock,
#endif
+#ifdef WITH_DYNLIBMODULE
+ &dynlibmod_get_funcblock,
+#endif
#ifdef USE_CACHEDB
&cachedb_get_funcblock,
#endif
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;
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
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)
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);
/** Python script file */
struct config_strlist* python_script;
+ /** Dynamic library file */
+ char* dynlib_file;
+
/** Use systemd socket activation. */
int use_systemd;
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) }
%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 ;
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 */
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));
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif
+#ifdef WITH_DYNLIBMODULE
+#include "dynlibmod/dynlibmod.h"
+#endif
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
#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
#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
#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
#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
#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
#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