python work

git-svn-id: file:///svn/unbound/trunk@1561 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-03-26 15:47:45 +00:00
parent e0cd16b38c
commit 7dcca025f4
13 changed files with 101 additions and 48 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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:

View file

@ -823,6 +823,18 @@ Name of server to forward to. Is itself resolved before it is used.
.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

View file

@ -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);

View file

@ -47,7 +47,9 @@
#include <Python.h>
/* 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);

View file

@ -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")

View file

@ -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")

View file

@ -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]) {

View file

@ -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.

View file

@ -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);
}

View file

@ -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;