WINDRES=windres
LINT=splint
-LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list
+LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list -Dglob64=glob -Dglobfree64=globfree
# compat with openssl linux edition.
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned
/** print usage. */
static void usage()
{
+ const char** m;
printf("usage: unbound [options]\n");
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help\n");
printf("libevent %s, libldns %s, %s\n",
event_get_version(), ldns_version(),
SSLeay_version(SSLEAY_VERSION));
+ printf("modules:");
+ for(m = module_list_avail(); *m; m++)
+ printf(" %s", *m);
+ printf("\n");
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
}
- remove duplicate example.conf text from python example configs.
- outofdir compile fix for python.
- pyunbound works.
+ - print modules compiled in on -h. manpage.
25 March 2009: Wouter
- initial import of the python contribution from Zdenek Vasicek and
# you need to do the reverse notation yourself.
# local-data-ptr: "192.0.2.3 www.example.com"
-# Python config section, list python in the module-config string to enable.
+# Python config section. To enable:
+# o use --with-pythonmodule to configure before compiling.
+# o list python in the module-config string (above) to enable.
+# o and give a python-script to run.
python:
# Script file to load
- python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
+ # python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
# Remote control config section.
remote-control:
.B forward\-addr: \fI<IP address>
IP address of server to forward to. Can be IP 4 or IP 6.
To use a nondefault port for DNS communication append '@' with the port number.
+.SS "Python Module Options"
+.LP
+The
+.B python:
+clause gives the settings for the \fIpython\fR(1) script module. This module
+acts like the iterator and validator modules do, on queries and answers.
+To enable the script module it has to be compiled into the daemon,
+and the word "python" has to be put in the \fBmodule\-conf:\fR option
+(usually first, or between the validator and iterator).
+.TP
+.B python\-script: \fI<python file>\fR
+The script file to load.
.SH "MEMORY CONTROL EXAMPLE"
In the example config settings below memory usage is reduced. Some service
levels are lower, notable very large data and a high TCP load are no longer
};
struct lruhash_entry {
- lock_rw_t lock;
- struct lruhash_entry* overflow_next;
- struct lruhash_entry* lru_next;
- struct lruhash_entry* lru_prev;
- hashvalue_t hash;
- void* key;
- struct packed_rrset_data* data;
+ lock_rw_t lock;
+ struct lruhash_entry* overflow_next;
+ struct lruhash_entry* lru_next;
+ struct lruhash_entry* lru_prev;
+ hashvalue_t hash;
+ void* key;
+ struct packed_rrset_data* data;
};
%ignore packed_rrset_data::rr_len;
%ignore packed_rrset_data::rr_data;
struct packed_rrset_data {
- uint32_t ttl; //TTL (in seconds like time())
+ uint32_t ttl; //TTL (in seconds like time())
- size_t count; //number of rrs
- size_t rrsig_count; //number of rrsigs
+ size_t count; //number of rrs
+ size_t rrsig_count; //number of rrsigs
- enum rrset_trust trust;
- enum sec_status security;
+ enum rrset_trust trust;
+ enum sec_status security;
- size_t* rr_len; //length of every rr's rdata
- uint32_t *rr_ttl; //ttl of every rr
- uint8_t** rr_data; //array of pointers to every rr's rdata; The rr_data[i] rdata is stored in uncompressed wireformat.
+ size_t* rr_len; //length of every rr's rdata
+ uint32_t *rr_ttl; //ttl of every rr
+ uint8_t** rr_data; //array of pointers to every rr's rdata; The rr_data[i] rdata is stored in uncompressed wireformat.
};
%pythoncode %{
%inline %{
enum enum_return_rcode {
- RCODE_NOERROR = 0,
- RCODE_FORMERR = 1,
- RCODE_SERVFAIL = 2,
- RCODE_NXDOMAIN = 3,
- RCODE_NOTIMPL = 4,
- RCODE_REFUSED = 5,
- RCODE_YXDOMAIN = 6,
- RCODE_YXRRSET = 7,
- RCODE_NXRRSET = 8,
- RCODE_NOTAUTH = 9,
- RCODE_NOTZONE = 10
+ RCODE_NOERROR = 0,
+ RCODE_FORMERR = 1,
+ RCODE_SERVFAIL = 2,
+ RCODE_NXDOMAIN = 3,
+ RCODE_NOTIMPL = 4,
+ RCODE_REFUSED = 5,
+ RCODE_YXDOMAIN = 6,
+ RCODE_YXRRSET = 7,
+ RCODE_NXRRSET = 8,
+ RCODE_NOTAUTH = 9,
+ RCODE_NOTZONE = 10
};
%}
// Module conversion functions
const char* strextstate(enum module_ext_state s);
const char* strmodulevent(enum module_ev e);
+
#include <Python.h>
/* Generated */
+#ifndef S_SPLINT_S
#include "pythonmod/interface.h"
+#endif
int pythonmod_init(struct module_env* env, int id)
{
}
env->modinfo[id] = (void*) pe;
- pe->fname = NULL;
- pe->module = NULL;
- pe->dict = NULL;
- pe->data = NULL;
- pe->qstate = NULL;
/* Initialize module */
- if ((pe->fname = env->cfg->python_script) == NULL)
- {
+ pe->fname = env->cfg->python_script;
+ if(pe->fname==NULL || pe->fname[0]==0) {
log_err("pythonmod: no script given.");
return 0;
}
/* Initialize Python */
PyRun_SimpleString("import sys \n");
PyRun_SimpleString("sys.path.append('.') \n");
+ if(env->cfg->directory && env->cfg->directory[0]) {
+ char wdir[1524];
+ snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
+ env->cfg->directory);
+ PyRun_SimpleString(wdir);
+ }
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
+ PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
if (PyRun_SimpleString("from Unbound import *\n") < 0)
{
log_err("pythonmod: cannot initialize core module: Unbound.py");
return;
pq = (struct pythonmod_qstate*)qstate->minfo[id];
- log_info("pythonmod: clear, id: %d, pq:%lX", id, (unsigned long int)pq);
+ verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id,
+ (unsigned long int)pq);
if(pq != NULL)
{
Py_DECREF(pq->data);
size_t pythonmod_get_mem(struct module_env* env, int id)
{
struct pythonmod_env* pe = (struct pythonmod_env*)env->modinfo[id];
- log_info("pythonmod: get_mem, id: %d, pe:%lX", id, (unsigned long int)pe);
+ verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id,
+ (unsigned long int)pe);
if(!pe)
return 0;
return sizeof(*pe);
if event == MODULE_EVENT_PASS:
log_info("pythonmod: event_pass")
- qstate.ext_state[id] = MODULE_ERROR
+ qstate.ext_state[id] = MODULE_WAIT_MODULE
return True
log_err("pythonmod: BAD event")
if event == MODULE_EVENT_PASS:
log_info("pythonmod: event_pass")
- qstate.ext_state[id] = MODULE_ERROR
+ qstate.ext_state[id] = MODULE_WAIT_MODULE
return True
log_err("pythonmod: BAD event")
return 1;
}
-struct
-module_func_block* module_factory(const char** str)
+/** The list of module names */
+const char**
+module_list_avail(void)
{
/* these are the modules available */
- const char* names[] = {"iterator", "validator",
+ static const char* names[] = {"iterator", "validator",
#ifdef WITH_PYTHONMODULE
"python",
#endif
NULL};
- struct module_func_block* (*fb[])(void) =
+ return names;
+}
+
+/** func block get function type */
+typedef struct module_func_block* (*fbgetfunctype)(void);
+
+/** The list of module func blocks */
+static fbgetfunctype*
+module_funcs_avail(void)
+{
+ static struct module_func_block* (*fb[])(void) =
{&iter_get_funcblock, &val_get_funcblock,
#ifdef WITH_PYTHONMODULE
&pythonmod_get_funcblock,
#endif
NULL};
+ return fb;
+}
+struct
+module_func_block* module_factory(const char** str)
+{
int i = 0;
const char* s = *str;
+ const char** names = module_list_avail();
+ fbgetfunctype* fb = module_funcs_avail();
while(*s && isspace((int)*s))
s++;
while(names[i]) {
*/
struct module_func_block* module_factory(const char** str);
+/**
+ * Get list of modules available.
+ * @return list of modules available. Static strings, ends with NULL.
+ */
+const char** module_list_avail(void);
+
/**
* Setup modules. Assigns ids and calls module_init.
* @param stack: if not empty beforehand, it will be desetup()ed.
cfg->chrootdir = NULL;
if(strcmp(cfg->module_conf, "iterator") != 0 &&
- strcmp(cfg->module_conf, "validator iterator") != 0) {
+ strcmp(cfg->module_conf, "validator iterator") != 0 &&
+ strcmp(cfg->module_conf, "python iterator") != 0 &&
+ strcmp(cfg->module_conf, "python validator iterator") != 0 &&
+ strcmp(cfg->module_conf, "validator python iterator") != 0) {
fatal_exit("module conf '%s' is not known to work",
cfg->module_conf);
}
cfg->local_zones = NULL;
cfg->local_zones_nodefault = NULL;
cfg->local_data = NULL;
-
- if(!(cfg->python_script = strdup(SHARE_DIR"/ubmodule.py")))
- goto error_exit;
+ cfg->python_script = NULL;
cfg->remote_control_enable = 0;
cfg->control_ifs = NULL;
cfg->control_port = 953;