mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Improve dynlib module and add documentation
Dynamic library module is now only a thin wrapper that loads dynamic libraries and forwards all function calls directly to the loaded module. This meant adding get_mem and clear, and get_mem calls have been added in the expected places. Documentation has also been added to the example.conf and the unbound.conf manpage.
This commit is contained in:
parent
1762437121
commit
8eeb910e3d
9 changed files with 119 additions and 88 deletions
|
|
@ -803,6 +803,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
|
||||||
size_t dnscrypt_shared_secret = 0;
|
size_t dnscrypt_shared_secret = 0;
|
||||||
size_t dnscrypt_nonce = 0;
|
size_t dnscrypt_nonce = 0;
|
||||||
#endif /* USE_DNSCRYPT */
|
#endif /* USE_DNSCRYPT */
|
||||||
|
#ifdef WITH_DYNLIBMODULE
|
||||||
|
size_t dynlib = 0;
|
||||||
|
#endif /* WITH_DYNLIBMODULE */
|
||||||
msg = slabhash_get_mem(daemon->env->msg_cache);
|
msg = slabhash_get_mem(daemon->env->msg_cache);
|
||||||
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
|
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
|
||||||
val = mod_get_mem(&worker->env, "validator");
|
val = mod_get_mem(&worker->env, "validator");
|
||||||
|
|
@ -821,6 +824,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
|
||||||
dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
|
dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
|
||||||
}
|
}
|
||||||
#endif /* USE_DNSCRYPT */
|
#endif /* USE_DNSCRYPT */
|
||||||
|
#ifdef WITH_DYNLIBMODULE
|
||||||
|
dynlib = mod_get_mem(&worker->env, "dynlib");
|
||||||
|
#endif /* WITH_DYNLIBMODULE */
|
||||||
|
|
||||||
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
|
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -848,6 +854,10 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
|
||||||
dnscrypt_nonce))
|
dnscrypt_nonce))
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* USE_DNSCRYPT */
|
#endif /* USE_DNSCRYPT */
|
||||||
|
#ifdef WITH_DYNLIBMODULE
|
||||||
|
if(!print_longnum(ssl, "mem.mod.dynlibmod"SQ, dynlib))
|
||||||
|
return 0;
|
||||||
|
#endif /* WITH_DYNLIBMODULE */
|
||||||
if(!print_longnum(ssl, "mem.streamwait"SQ,
|
if(!print_longnum(ssl, "mem.streamwait"SQ,
|
||||||
(size_t)s->svr.mem_stream_wait))
|
(size_t)s->svr.mem_stream_wait))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -837,6 +837,16 @@ python:
|
||||||
# Script file to load
|
# Script file to load
|
||||||
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
|
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
|
||||||
|
|
||||||
|
# Dynamic library config section. To enable:
|
||||||
|
# o use --with-dynlibmodule to configure before compiling.
|
||||||
|
# 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
|
||||||
|
# to load modules dynamically.
|
||||||
|
# o and give a dynlib-file to run.
|
||||||
|
dynlib:
|
||||||
|
# Script file to load
|
||||||
|
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
|
||||||
|
|
||||||
# Remote control config section.
|
# Remote control config section.
|
||||||
remote-control:
|
remote-control:
|
||||||
# Enable remote control with unbound-control(8) here.
|
# Enable remote control with unbound-control(8) here.
|
||||||
|
|
|
||||||
|
|
@ -940,7 +940,9 @@ EDNS client subnet support the default is "subnetcache validator iterator".
|
||||||
Most modules that need to be listed here have to be listed at the beginning
|
Most modules that need to be listed here have to be listed at the beginning
|
||||||
of the line. The cachedb module has to be listed just before the iterator.
|
of the line. The cachedb module has to be listed just before the iterator.
|
||||||
The python module can be listed in different places, it then processes the
|
The python module can be listed in different places, it then processes the
|
||||||
output of the module it is just before.
|
output of the module it is just before. The dynlib module can be listed pretty
|
||||||
|
much anywhere, it is only a very thin wrapper that allows dynamic libraries to
|
||||||
|
run in its place.
|
||||||
.TP
|
.TP
|
||||||
.B trust\-anchor\-file: \fI<filename>
|
.B trust\-anchor\-file: \fI<filename>
|
||||||
File with trusted keys for validation. Both DS and DNSKEY entries can appear
|
File with trusted keys for validation. Both DS and DNSKEY entries can appear
|
||||||
|
|
@ -1782,6 +1784,22 @@ directory.
|
||||||
.B python\-script: \fI<python file>\fR
|
.B python\-script: \fI<python file>\fR
|
||||||
The script file to load. Repeat this option for every python module instance
|
The script file to load. Repeat this option for every python module instance
|
||||||
added to the \fBmodule\-config:\fR option.
|
added to the \fBmodule\-config:\fR option.
|
||||||
|
.SS "Dynamic Library Module Options"
|
||||||
|
.LP
|
||||||
|
The
|
||||||
|
.B dynlib:
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
.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.
|
||||||
.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
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#if HAVE_WINDOWS_H
|
#if HAVE_WINDOWS_H
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#define __DYNMOD HMODULE
|
||||||
#define __DYNSYM FARPROC
|
#define __DYNSYM FARPROC
|
||||||
#define __LOADSYM GetProcAddress
|
#define __LOADSYM GetProcAddress
|
||||||
void log_dlerror() {
|
void log_dlerror() {
|
||||||
|
|
@ -25,43 +26,39 @@ void log_dlerror() {
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
DWORD dwBytesWritten;
|
DWORD dwBytesWritten;
|
||||||
|
log_err("dynlibmod: %s (%ld)", MessageBuffer, dwLastError);
|
||||||
//
|
|
||||||
// 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);
|
LocalFree(MessageBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
HMODULE open_library(const char* fname) {
|
||||||
|
return LoadLibrary(fname);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#define __DYNMOD void*
|
||||||
#define __DYNSYM void*
|
#define __DYNSYM void*
|
||||||
#define __LOADSYM dlsym
|
#define __LOADSYM dlsym
|
||||||
void log_dlerror() {
|
void log_dlerror() {
|
||||||
log_err("dynlibmod: %s", dlerror());
|
log_err("dynlibmod: %s", dlerror());
|
||||||
}
|
}
|
||||||
|
void* open_library(const char* fname) {
|
||||||
|
return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global state for the module.
|
* Global state for the module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int (*func_init_t)(int, struct config_file*);
|
typedef void (*func_init_t)(struct module_env*, int);
|
||||||
typedef int (*func_deinit_t)(int);
|
typedef void (*func_deinit_t)(struct module_env*, int);
|
||||||
typedef int (*func_operate_t)(int, enum module_ev event, struct module_qstate* qstate, void*);
|
typedef void (*func_operate_t)(struct module_qstate*, enum module_ev, int, struct outbound_entry*);
|
||||||
typedef int (*func_inform_t)(int, struct module_qstate* qstate, struct module_qstate* super, void*);
|
typedef void (*func_inform_t)(struct module_qstate*, int, struct module_qstate*);
|
||||||
|
typedef void (*func_clear_t)(struct module_qstate*, int);
|
||||||
|
typedef size_t (*func_get_mem_t)(struct module_env*, int);
|
||||||
|
|
||||||
struct dynlibmod_env {
|
struct dynlibmod_env {
|
||||||
|
|
||||||
/** Dynamic library filename. */
|
/** Dynamic library filename. */
|
||||||
|
|
@ -75,20 +72,19 @@ struct dynlibmod_env {
|
||||||
func_operate_t func_operate;
|
func_operate_t func_operate;
|
||||||
/** Module super_inform function */
|
/** Module super_inform function */
|
||||||
func_inform_t func_inform;
|
func_inform_t func_inform;
|
||||||
|
/** Module clear function */
|
||||||
|
func_clear_t func_clear;
|
||||||
|
/** Module get_mem function */
|
||||||
|
func_get_mem_t func_get_mem;
|
||||||
|
|
||||||
/** Module qstate. */
|
/** Module qstate. */
|
||||||
struct module_qstate* qstate;
|
struct module_qstate* qstate;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynlibmod_qstate {
|
|
||||||
|
|
||||||
/** Module per query data. */
|
|
||||||
void* data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** dynlib module init */
|
/** dynlib module init */
|
||||||
int dynlibmod_init(struct module_env* env, int id) {
|
int dynlibmod_init(struct module_env* env, int id) {
|
||||||
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;
|
||||||
if (!de)
|
if (!de)
|
||||||
{
|
{
|
||||||
log_err("dynlibmod: malloc failure");
|
log_err("dynlibmod: malloc failure");
|
||||||
|
|
@ -102,59 +98,63 @@ int dynlibmod_init(struct module_env* env, int id) {
|
||||||
log_err("dynlibmod: no dynamic library given.");
|
log_err("dynlibmod: no dynamic library given.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
log_info("Trying to load library %s", de->fname);
|
verbose(VERB_ALGO, "dynlibmod: Trying to load library %s", de->fname);
|
||||||
#ifndef HAVE_WINDOWS_H
|
dynamic_library = open_library(de->fname);
|
||||||
void* dynamic_library = dlopen(de->fname, RTLD_LAZY | RTLD_GLOBAL);
|
|
||||||
#else
|
|
||||||
HMODULE dynamic_library = LoadLibrary(de->fname);
|
|
||||||
#endif
|
|
||||||
if (dynamic_library == NULL) {
|
if (dynamic_library == NULL) {
|
||||||
log_dlerror();
|
log_dlerror();
|
||||||
log_err("dynlibmod: unable to load dynamic library.");
|
log_err("dynlibmod: unable to load dynamic library \"%s\".", 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_err("dynlibmod: unable to load init procedure from dynamic library.");
|
log_dlerror();
|
||||||
#ifndef HAVE_WINDOWS_H
|
log_err("dynlibmod: unable to load init procedure from dynamic library \"%s\".", de->fname);
|
||||||
log_err("dynlibmod: %s", dlerror());
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_init = (func_init_t) initializer;
|
de->func_init = (func_init_t) initializer;
|
||||||
}
|
}
|
||||||
__DYNSYM deinitializer = __LOADSYM(dynamic_library,"deinit");
|
__DYNSYM deinitializer = __LOADSYM(dynamic_library,"deinit");
|
||||||
if (deinitializer == NULL) {
|
if (deinitializer == NULL) {
|
||||||
log_err("dynlibmod: unable to load deinit procedure from dynamic library.");
|
log_dlerror();
|
||||||
#ifndef HAVE_WINDOWS_H
|
log_err("dynlibmod: unable to load deinit procedure from dynamic library \"%s\".", de->fname);
|
||||||
log_err("dynlibmod: %s", dlerror());
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_deinit = (func_deinit_t) deinitializer;
|
de->func_deinit = (func_deinit_t) deinitializer;
|
||||||
}
|
}
|
||||||
__DYNSYM operate = __LOADSYM(dynamic_library,"operate");
|
__DYNSYM operate = __LOADSYM(dynamic_library,"operate");
|
||||||
if (operate == NULL) {
|
if (operate == NULL) {
|
||||||
log_err("dynlibmod: unable to load operate procedure from dynamic library.");
|
log_dlerror();
|
||||||
#ifndef HAVE_WINDOWS_H
|
log_err("dynlibmod: unable to load operate procedure from dynamic library \"%s\".", de->fname);
|
||||||
log_err("dynlibmod: %s", dlerror());
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_operate = (func_operate_t) operate;
|
de->func_operate = (func_operate_t) operate;
|
||||||
}
|
}
|
||||||
__DYNSYM inform = __LOADSYM(dynamic_library,"inform_super");
|
__DYNSYM inform = __LOADSYM(dynamic_library,"inform_super");
|
||||||
if (inform == NULL) {
|
if (inform == NULL) {
|
||||||
log_err("dynlibmod: unable to load inform_super procedure from dynamic library.");
|
log_dlerror();
|
||||||
#ifndef HAVE_WINDOWS_H
|
log_err("dynlibmod: unable to load inform_super procedure from dynamic library \"%s\".", de->fname);
|
||||||
log_err("dynlibmod: %s", dlerror());
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
de->func_inform = (func_inform_t) inform;
|
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);
|
||||||
|
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);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
de->func_get_mem = (func_get_mem_t) get_mem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
de->func_init(id, env->cfg);
|
de->func_init(env, id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@ void dynlibmod_deinit(struct module_env* env, int id) {
|
||||||
struct dynlibmod_env* de = env->modinfo[id];
|
struct dynlibmod_env* de = env->modinfo[id];
|
||||||
if(de == NULL)
|
if(de == NULL)
|
||||||
return;
|
return;
|
||||||
de->func_deinit(id);
|
de->func_deinit(env, id);
|
||||||
de->fname = NULL;
|
de->fname = NULL;
|
||||||
free(de);
|
free(de);
|
||||||
}
|
}
|
||||||
|
|
@ -172,44 +172,23 @@ void dynlibmod_deinit(struct module_env* env, int id) {
|
||||||
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
|
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||||
int id, struct outbound_entry* outbound) {
|
int id, struct outbound_entry* outbound) {
|
||||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
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;
|
de->func_operate(qstate, event, id, outbound);
|
||||||
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 */
|
/** dynlib module */
|
||||||
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
|
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
|
||||||
struct module_qstate* super) {
|
struct module_qstate* super) {
|
||||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
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;
|
de->func_inform(qstate, id, super);
|
||||||
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 */
|
/** dynlib module cleanup query state */
|
||||||
void dynlibmod_clear(struct module_qstate* qstate, int id) {
|
void dynlibmod_clear(struct module_qstate* qstate, int id) {
|
||||||
struct dynlibmod_qstate* dq;
|
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||||
if (qstate == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dq = (struct dynlibmod_qstate*)qstate->minfo[id];
|
de->func_clear(qstate, 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 */
|
/** dynlib module alloc size routine */
|
||||||
|
|
@ -218,7 +197,9 @@ size_t dynlibmod_get_mem(struct module_env* env, int id) {
|
||||||
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
|
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
|
||||||
if(!de)
|
if(!de)
|
||||||
return 0;
|
return 0;
|
||||||
return sizeof(*de);
|
|
||||||
|
size_t size = de->func_get_mem(env, id);
|
||||||
|
return size + sizeof(*de);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* dynlibmod.h: module header file
|
* dynlibmod.h: module header file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
* Copyright (c) 2019, Peter Munch-Ellingsen (peterme AT peterme.net)
|
||||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
|
||||||
*
|
*
|
||||||
* This software is open source.
|
* This software is open source.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,15 @@
|
||||||
#define EXPORT
|
#define EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPORT int init(int id, struct config_file* cfg) {
|
EXPORT void init(struct module_env* env, int id) {
|
||||||
log_info("Hello world from init");
|
log_info("Hello world from init");
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int deinit(int id) {
|
EXPORT void deinit(struct module_env* env, int id) {
|
||||||
log_info("Hello world from deinit");
|
log_info("Hello world from deinit");
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int operate(int id, enum module_ev event, struct module_qstate* qstate, void* data) {
|
EXPORT void operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* entry) {
|
||||||
log_info("Hello world from operate");
|
log_info("Hello world from operate");
|
||||||
if (event == module_event_new || event == module_event_pass) {
|
if (event == module_event_new || event == module_event_pass) {
|
||||||
qstate->ext_state[id] = module_wait_module;
|
qstate->ext_state[id] = module_wait_module;
|
||||||
|
|
@ -36,10 +34,17 @@ EXPORT int operate(int id, enum module_ev event, struct module_qstate* qstate, v
|
||||||
} else {
|
} else {
|
||||||
qstate->ext_state[id] = module_error;
|
qstate->ext_state[id] = module_error;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int inform_super(int id, struct module_qstate* qstate, struct module_qstate* super, void* data) {
|
EXPORT void inform_super(struct module_qstate* qstate, int id, struct module_qstate* super) {
|
||||||
log_info("Hello world from inform_super");
|
log_info("Hello world from inform_super");
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
EXPORT void clear(struct module_qstate* qstate, int id) {
|
||||||
|
log_info("Hello world from clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT size_t get_mem(struct module_env* env, int id) {
|
||||||
|
log_info("Hello world from get_mem");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -641,6 +641,7 @@ struct ub_shm_stat_info {
|
||||||
long long respip;
|
long long respip;
|
||||||
long long dnscrypt_shared_secret;
|
long long dnscrypt_shared_secret;
|
||||||
long long dnscrypt_nonce;
|
long long dnscrypt_nonce;
|
||||||
|
long long dynlib;
|
||||||
} mem;
|
} mem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,9 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
|
||||||
#ifdef USE_IPSECMOD
|
#ifdef USE_IPSECMOD
|
||||||
PR_LL("mem.mod.ipsecmod", shm_stat->mem.ipsecmod);
|
PR_LL("mem.mod.ipsecmod", shm_stat->mem.ipsecmod);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WITH_DYNLIBMODULE
|
||||||
|
PR_LL("mem.mod.dynlib", shm_stat->mem.dynlib);
|
||||||
|
#endif
|
||||||
#ifdef USE_DNSCRYPT
|
#ifdef USE_DNSCRYPT
|
||||||
PR_LL("mem.cache.dnscrypt_shared_secret",
|
PR_LL("mem.cache.dnscrypt_shared_secret",
|
||||||
shm_stat->mem.dnscrypt_shared_secret);
|
shm_stat->mem.dnscrypt_shared_secret);
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,10 @@ void shm_main_run(struct worker *worker)
|
||||||
#ifdef USE_IPSECMOD
|
#ifdef USE_IPSECMOD
|
||||||
shm_stat->mem.ipsecmod = (long long)mod_get_mem(&worker->env,
|
shm_stat->mem.ipsecmod = (long long)mod_get_mem(&worker->env,
|
||||||
"ipsecmod");
|
"ipsecmod");
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_DYNLIBMODULE
|
||||||
|
shm_stat->mem.dynlib = (long long)mod_get_mem(&worker->env,
|
||||||
|
"dynlib");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue