From: Wouter Wijngaards Date: Thu, 26 Mar 2009 15:47:45 +0000 (+0000) Subject: python work X-Git-Tag: release-1.3.0~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7dcca025f481279368a20ab33378fedca40f4628;p=thirdparty%2Funbound.git python work git-svn-id: file:///svn/unbound/trunk@1561 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/Makefile.in b/Makefile.in index 23535aa17..33cc5d2ad 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65,7 +65,7 @@ BUILD=build/ 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 diff --git a/daemon/unbound.c b/daemon/unbound.c index 9703b4f6f..e82f1014a 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -87,6 +87,7 @@ void* unbound_start_brk = 0; /** 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"); @@ -103,6 +104,10 @@ static void usage() 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); } diff --git a/doc/Changelog b/doc/Changelog index d70f92658..e283b4288 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,7 @@ - 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 diff --git a/doc/example.conf.in b/doc/example.conf.in index 52386ddd1..d7ece167d 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -386,10 +386,13 @@ server: # 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: diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index a0d62f1c3..6c071d52e 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -823,6 +823,18 @@ Name of server to forward to. Is itself resolved before it is used. .B forward\-addr: \fI 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\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 diff --git a/pythonmod/interface.i b/pythonmod/interface.i index e8eabaf9a..8684042dc 100644 --- a/pythonmod/interface.i +++ b/pythonmod/interface.i @@ -242,13 +242,13 @@ struct ub_packed_rrset_key { }; 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; @@ -256,17 +256,17 @@ struct lruhash_entry { %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 %{ @@ -442,17 +442,17 @@ struct module_qstate { %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 }; %} @@ -805,3 +805,4 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin // Module conversion functions const char* strextstate(enum module_ext_state s); const char* strmodulevent(enum module_ev e); + diff --git a/pythonmod/pythonmod.c b/pythonmod/pythonmod.c index 361b8998a..1b8fc3942 100644 --- a/pythonmod/pythonmod.c +++ b/pythonmod/pythonmod.c @@ -47,7 +47,9 @@ #include /* Generated */ +#ifndef S_SPLINT_S #include "pythonmod/interface.h" +#endif int pythonmod_init(struct module_env* env, int id) { @@ -62,15 +64,10 @@ 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; } @@ -89,7 +86,14 @@ int pythonmod_init(struct module_env* env, int id) /* 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"); @@ -271,7 +275,8 @@ void pythonmod_clear(struct module_qstate* qstate, int id) 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); @@ -285,7 +290,8 @@ void pythonmod_clear(struct module_qstate* qstate, int id) 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); diff --git a/pythonmod/ubmodule-msg.py b/pythonmod/ubmodule-msg.py index d234d609f..648368080 100644 --- a/pythonmod/ubmodule-msg.py +++ b/pythonmod/ubmodule-msg.py @@ -146,7 +146,7 @@ def operate(id, event, qstate, qdata): 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") diff --git a/pythonmod/ubmodule-tst.py b/pythonmod/ubmodule-tst.py index d0d4cd442..0b9b5a9d2 100644 --- a/pythonmod/ubmodule-tst.py +++ b/pythonmod/ubmodule-tst.py @@ -139,7 +139,7 @@ def operate(id, event, qstate, qdata): 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") diff --git a/services/modstack.c b/services/modstack.c index b9252ce7e..fdadca9f9 100644 --- a/services/modstack.c +++ b/services/modstack.c @@ -109,24 +109,42 @@ modstack_config(struct module_stack* stack, const char* module_conf) 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]) { diff --git a/services/modstack.h b/services/modstack.h index b9605758b..869b593ad 100644 --- a/services/modstack.h +++ b/services/modstack.h @@ -76,6 +76,12 @@ int modstack_config(struct module_stack* stack, const char* module_conf); */ 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. diff --git a/smallapp/unbound-checkconf.c b/smallapp/unbound-checkconf.c index 99949396e..a0c7f76a5 100644 --- a/smallapp/unbound-checkconf.c +++ b/smallapp/unbound-checkconf.c @@ -496,7 +496,10 @@ morechecks(struct config_file* cfg, const char* fname) 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); } diff --git a/util/config_file.c b/util/config_file.c index 59f54b0fc..bb52ceefb 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -156,9 +156,7 @@ config_create() 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;