- With ./configure --with-pyunbound --with-pythonmodule

PYTHON_VERSION=3.6 or with 2.7 unbound can compile and unit tests
  succeed for the python module.
- pythonmod logs the python error and traceback on failure.


git-svn-id: file:///svn/unbound/trunk@4966 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2018-11-22 13:01:29 +00:00
parent 022d5131b3
commit 5853f90076
9 changed files with 323 additions and 65 deletions

View file

@ -482,9 +482,9 @@ doc:
if test -n "$(doxygen)"; then \ if test -n "$(doxygen)"; then \
$(doxygen) $(srcdir)/doc/unbound.doxygen; fi $(doxygen) $(srcdir)/doc/unbound.doxygen; fi
if test "$(WITH_PYUNBOUND)" = "yes" -o "$(WITH_PYTHONMODULE)" = "yes"; \ if test "$(WITH_PYUNBOUND)" = "yes" -o "$(WITH_PYTHONMODULE)" = "yes"; \
then if test -x "`which sphinx-build 2>&1`"; then \ then if test -x "`which sphinx-build-$(PY_MAJOR_VERSION) 2>&1`"; then \
sphinx-build -b html pythonmod/doc doc/html/pythonmod; \ sphinx-build-$(PY_MAJOR_VERSION) -b html pythonmod/doc doc/html/pythonmod; \
sphinx-build -b html libunbound/python/doc doc/html/pyunbound;\ sphinx-build-$(PY_MAJOR_VERSION) -b html libunbound/python/doc doc/html/pyunbound;\
fi ;\ fi ;\
fi fi

View file

@ -1,3 +1,9 @@
22 November 2018: Wouter
- With ./configure --with-pyunbound --with-pythonmodule
PYTHON_VERSION=3.6 or with 2.7 unbound can compile and unit tests
succeed for the python module.
- pythonmod logs the python error and traceback on failure.
21 November 2018: Wouter 21 November 2018: Wouter
- Scrub NS records from NODATA responses as well. - Scrub NS records from NODATA responses as well.

View file

@ -612,17 +612,21 @@ RECURSIVE = YES
EXCLUDE = ./build \ EXCLUDE = ./build \
./compat \ ./compat \
./contrib \
util/configparser.c \ util/configparser.c \
util/configparser.h \ util/configparser.h \
util/configlexer.c \ util/configlexer.c \
util/locks.h \ util/locks.h \
pythonmod/doc \
pythonmod/examples \
pythonmod/unboundmodule.py \ pythonmod/unboundmodule.py \
pythonmod/interface.h \ pythonmod/interface.h \
pythonmod/examples/resgen.py \ pythonmod/ubmodule-msg.py \
pythonmod/examples/resmod.py \ pythonmod/ubmodule-tst.py \
pythonmod/examples/resip.py \
libunbound/python/unbound.py \ libunbound/python/unbound.py \
libunbound/python/libunbound_wrap.c \ libunbound/python/libunbound_wrap.c \
libunbound/python/doc \
libunbound/python/examples \
./ldns-src \ ./ldns-src \
doc/control_proto_spec.txt \ doc/control_proto_spec.txt \
doc/requirements.txt doc/requirements.txt

View file

@ -45,15 +45,20 @@
i = 0; i = 0;
while (i < len) { while (i < len) {
i += name[i] + 1; i += ((unsigned int)name[i]) + 1;
cnt++; cnt++;
} }
list = PyList_New(cnt); list = PyList_New(cnt);
i = 0; cnt = 0; i = 0; cnt = 0;
while (i < len) { while (i < len) {
PyList_SetItem(list, cnt, PyBytes_FromStringAndSize(name + i + 1, name[i])); char buf[LDNS_MAX_LABELLEN+1];
i += name[i] + 1; if(((unsigned int)name[i])+1 <= (int)sizeof(buf)) {
memmove(buf, name + i + 1, (unsigned int)name[i]);
buf[(unsigned int)name[i]] = 0;
PyList_SetItem(list, cnt, PyString_FromString(buf));
}
i += ((unsigned int)name[i]) + 1;
cnt++; cnt++;
} }
return list; return list;
@ -161,11 +166,11 @@ struct query_info {
%} %}
%inline %{ %inline %{
PyObject* dnameAsStr(const char* dname) { PyObject* dnameAsStr(PyObject* dname) {
char buf[LDNS_MAX_DOMAINLEN+1]; char buf[LDNS_MAX_DOMAINLEN+1];
buf[0] = '\0'; buf[0] = '\0';
dname_str((uint8_t*)dname, buf); dname_str((uint8_t*)PyBytes_AsString(dname), buf);
return PyBytes_FromString(buf); return PyString_FromString(buf);
} }
%} %}
@ -1211,7 +1216,7 @@ int checkList(PyObject *l)
for (i=0; i < PyList_Size(l); i++) for (i=0; i < PyList_Size(l); i++)
{ {
item = PyList_GetItem(l, i); item = PyList_GetItem(l, i);
if (!PyBytes_Check(item)) if (!PyBytes_Check(item) && !PyUnicode_Check(item))
return 0; return 0;
} }
return 1; return 1;
@ -1226,23 +1231,40 @@ int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
PyObject* item; PyObject* item;
int i; int i;
size_t len; size_t len;
char* s;
PyObject* ascstr;
for (i=0; i < PyList_Size(l); i++) for (i=0; i < PyList_Size(l); i++)
{ {
ascstr = NULL;
item = PyList_GetItem(l, i); item = PyList_GetItem(l, i);
if(PyObject_TypeCheck(item, &PyBytes_Type)) {
s = PyBytes_AsString(item);
} else {
ascstr = PyUnicode_AsASCIIString(item);
s = PyBytes_AsString(ascstr);
}
len = sldns_buffer_remaining(qb); len = sldns_buffer_remaining(qb);
if(qsec) { if(qsec) {
if(sldns_str2wire_rr_question_buf(PyBytes_AsString(item), if(sldns_str2wire_rr_question_buf(s,
sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0) sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
!= 0) != 0) {
if(ascstr)
Py_DECREF(ascstr);
return 0; return 0;
}
} else { } else {
if(sldns_str2wire_rr_buf(PyBytes_AsString(item), if(sldns_str2wire_rr_buf(s,
sldns_buffer_current(qb), &len, NULL, default_ttl, sldns_buffer_current(qb), &len, NULL, default_ttl,
NULL, 0, NULL, 0) != 0) NULL, 0, NULL, 0) != 0) {
if(ascstr)
Py_DECREF(ascstr);
return 0; return 0;
}
} }
if(ascstr)
Py_DECREF(ascstr);
sldns_buffer_skip(qb, len); sldns_buffer_skip(qb, len);
sldns_buffer_write_u16_at(qb, count_offset, sldns_buffer_write_u16_at(qb, count_offset,

View file

@ -110,6 +110,128 @@ struct pythonmod_qstate {
#include "pythonmod/interface.h" #include "pythonmod/interface.h"
#endif #endif
/** log python error */
static void
log_py_err(void)
{
char *result = NULL;
PyObject *modStringIO = NULL;
PyObject *modTB = NULL;
PyObject *obFuncStringIO = NULL;
PyObject *obStringIO = NULL;
PyObject *obFuncTB = NULL;
PyObject *argsTB = NULL;
PyObject *obResult = NULL;
PyObject *ascstr = NULL;
PyObject *exc_typ, *exc_val, *exc_tb;
/* Fetch the error state now before we cruch it */
/* exc val contains the error message
* exc tb contains stack traceback and other info. */
PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
PyErr_NormalizeException(&exc_typ, &exc_val, &exc_tb);
/* Import the modules we need - cStringIO and traceback */
modStringIO = PyImport_ImportModule("cStringIO");
if (modStringIO==NULL) /* python 1.4 and before */
modStringIO = PyImport_ImportModule("StringIO");
if (modStringIO==NULL) /* python 3 */
modStringIO = PyImport_ImportModule("io");
if (modStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot ImportModule cStringIO or StringIO");
goto cleanup;
}
modTB = PyImport_ImportModule("traceback");
if (modTB==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot ImportModule traceback");
goto cleanup;
}
/* Construct a cStringIO object */
obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
if (obFuncStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot GetAttrString cStringIO.StringIO");
goto cleanup;
}
obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
if (obStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot cStringIO.StringIO()");
goto cleanup;
}
/* Get the traceback.print_exception function, and call it. */
obFuncTB = PyObject_GetAttrString(modTB, "print_exception");
if (obFuncTB==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot GetAttrString traceback.print_exception");
goto cleanup;
}
argsTB = Py_BuildValue("OOOOO", (exc_typ ? exc_typ : Py_None),
(exc_val ? exc_val : Py_None), (exc_tb ? exc_tb : Py_None),
Py_None, obStringIO);
if (argsTB==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot BuildValue for print_exception");
goto cleanup;
}
obResult = PyObject_CallObject(obFuncTB, argsTB);
if (obResult==NULL) {
PyErr_Print();
log_err("pythonmod: cannot print exception, "
"call traceback.print_exception() failed");
goto cleanup;
}
/* Now call the getvalue() method in the StringIO instance */
Py_DECREF(obFuncStringIO);
obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue");
if (obFuncStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot GetAttrString cStringIO.getvalue");
goto cleanup;
}
Py_DECREF(obResult);
obResult = PyObject_CallObject(obFuncStringIO, NULL);
if (obResult==NULL) {
log_err("pythonmod: cannot print exception, "
"call cStringIO.getvalue() failed");
goto cleanup;
}
/* And it should be a string all ready to go - duplicate it. */
if (!PyString_Check(obResult) && !PyUnicode_Check(obResult)) {
log_err("pythonmod: cannot print exception, "
"cStringIO.getvalue() result did not String_Check");
goto cleanup;
}
if(PyString_Check(obResult)) {
result = PyString_AsString(obResult);
} else {
ascstr = PyUnicode_AsASCIIString(obResult);
result = PyBytes_AsString(ascstr);
}
log_err("pythonmod: python error: %s", result);
cleanup:
Py_XDECREF(modStringIO);
Py_XDECREF(modTB);
Py_XDECREF(obFuncStringIO);
Py_XDECREF(obStringIO);
Py_XDECREF(obFuncTB);
Py_XDECREF(argsTB);
Py_XDECREF(obResult);
Py_XDECREF(ascstr);
/* clear the exception, by not restoring it */
/* Restore the exception state */
/* PyErr_Restore(exc_typ, exc_val, exc_tb); */
}
int pythonmod_init(struct module_env* env, int id) int pythonmod_init(struct module_env* env, int id)
{ {
/* Initialize module */ /* Initialize module */
@ -193,13 +315,26 @@ int pythonmod_init(struct module_env* env, int id)
/* TODO: deallocation of pe->... if an error occurs */ /* TODO: deallocation of pe->... if an error occurs */
if (PyRun_SimpleFile(script_py, pe->fname) < 0) if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
{
log_err("pythonmod: can't parse Python script %s", pe->fname); log_err("pythonmod: can't parse Python script %s", pe->fname);
/* print the error to logs too, run it again */
fseek(script_py, 0, SEEK_SET);
/* we don't run the file, like this, because then side-effects
* s = PyRun_File(script_py, pe->fname, Py_file_input,
* PyModule_GetDict(PyImport_AddModule("__main__")), pe->dict);
* could happen (again). Instead we parse the file again to get
* the error string in the logs, for when the daemon has stderr
* removed. SimpleFile run already printed to stderr, for then
* this is called from unbound-checkconf or unbound -dd the user
* has a nice formatted error.
*/
/* ignore the NULL return of _node, it is NULL due to the parse failure
* that we are expecting */
(void)PyParser_SimpleParseFile(script_py, pe->fname, Py_file_input);
log_py_err();
PyGILState_Release(gil); PyGILState_Release(gil);
return 0; return 0;
} }
fclose(script_py); fclose(script_py);
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL) if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL)
@ -244,7 +379,7 @@ int pythonmod_init(struct module_env* env, int id)
if (PyErr_Occurred()) if (PyErr_Occurred())
{ {
log_err("pythonmod: Exception occurred in function init"); log_err("pythonmod: Exception occurred in function init");
PyErr_Print(); log_py_err();
Py_XDECREF(res); Py_XDECREF(res);
Py_XDECREF(py_init_arg); Py_XDECREF(py_init_arg);
PyGILState_Release(gil); PyGILState_Release(gil);
@ -274,7 +409,7 @@ void pythonmod_deinit(struct module_env* env, int id)
res = PyObject_CallFunction(pe->func_deinit, "i", id); res = PyObject_CallFunction(pe->func_deinit, "i", id);
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
log_err("pythonmod: Exception occurred in function deinit"); log_err("pythonmod: Exception occurred in function deinit");
PyErr_Print(); log_py_err();
} }
/* Free result if any */ /* Free result if any */
Py_XDECREF(res); Py_XDECREF(res);
@ -312,7 +447,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_
if (PyErr_Occurred()) if (PyErr_Occurred())
{ {
log_err("pythonmod: Exception occurred in function inform_super"); log_err("pythonmod: Exception occurred in function inform_super");
PyErr_Print(); log_py_err();
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
} }
else if ((res == NULL) || (!PyObject_IsTrue(res))) else if ((res == NULL) || (!PyObject_IsTrue(res)))
@ -353,7 +488,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
if (PyErr_Occurred()) if (PyErr_Occurred())
{ {
log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event)); log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event));
PyErr_Print(); log_py_err();
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
} }
else if ((res == NULL) || (!PyObject_IsTrue(res))) else if ((res == NULL) || (!PyObject_IsTrue(res)))

View file

@ -19,9 +19,13 @@ fi
#echo export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:../../.libs:." #echo export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:../../.libs:."
#export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:../../.libs:." #export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:../../.libs:."
if grep "PY_MAJOR_VERSION=3" $PRE/Makefile; then
PYTHON="python3"; else PYTHON="python2"; fi
if test ! -x `which $PYTHON` 2>&1; then PYTHON="python"; fi
# do the test # do the test
echo "> pylib.lookup.py www.example.com." echo "> pylib.lookup.py www.example.com."
./pylib.lookup.py www.example.com. | tee outfile $PYTHON pylib.lookup.py www.example.com. | tee outfile
echo "> cat logfiles" echo "> cat logfiles"
cat fwd.log cat fwd.log

View file

@ -59,12 +59,15 @@ def setTTL(qstate, ttl):
def dataHex(data, prefix=""): def dataHex(data, prefix=""):
res = "" res = ""
for i in range(0, (len(data)+15)/16): for i in range(0, int((len(data)+15)/16)):
res += "%s0x%02X | " % (prefix, i*16) res += "%s0x%02X | " % (prefix, i*16)
d = map(lambda x:ord(x), data[i*16:i*16+17]) if type(data[0]) == type(1):
d = map(lambda x:int(x), data[i*16:i*16+17])
else:
d = map(lambda x:ord(x), data[i*16:i*16+17])
for ch in d: for ch in d:
res += "%02X " % ch res += "%02X " % ch
for i in range(0,17-len(d)): for i in range(0,17-len(data[i*16:i*16+17])):
res += " " res += " "
res += "| " res += "| "
for ch in d: for ch in d:
@ -76,35 +79,35 @@ def dataHex(data, prefix=""):
return res return res
def printReturnMsg(qstate): def printReturnMsg(qstate):
print "Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl) print ("Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount, qstate.return_msg.rep.security, qstate.return_msg.rep.ttl))
print " qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str print (" qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str)
if (qstate.return_msg.rep): if (qstate.return_msg.rep):
print "RRSets:",qstate.return_msg.rep.rrset_count print ("RRSets:",qstate.return_msg.rep.rrset_count)
prevkey = None prevkey = None
for i in range(0,qstate.return_msg.rep.rrset_count): for i in range(0,qstate.return_msg.rep.rrset_count):
r = qstate.return_msg.rep.rrsets[i] r = qstate.return_msg.rep.rrsets[i]
rk = r.rk rk = r.rk
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags, print (i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags)
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class) print ("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
d = r.entry.data d = r.entry.data
print " RRDatas:",d.count+d.rrsig_count print (" RRDatas:",d.count+d.rrsig_count)
for j in range(0,d.count+d.rrsig_count): for j in range(0,d.count+d.rrsig_count):
print " ",j,":","TTL=",d.rr_ttl[j],"RR data:" print (" ",j,":","TTL=",d.rr_ttl[j],"RR data:")
print dataHex(d.rr_data[j]," ") print (dataHex(d.rr_data[j]," "))
def operate(id, event, qstate, qdata): def operate(id, event, qstate, qdata):
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event))) log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
#print "pythonmod: per query data", qdata #print ("pythonmod: per query data", qdata)
print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list, qstate.qinfo.qname_str, print ("Query:", qstate.qinfo.qname, qstate.qinfo.qname_list, qstate.qinfo.qname_str)
print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype, print ("Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype)
print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass print ("Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass)
print print ()
if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("www2.example.com.")): if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("www2.example.com.")):
print qstate.qinfo.qname_str print (qstate.qinfo.qname_str)
qstate.ext_state[id] = MODULE_FINISHED qstate.ext_state[id] = MODULE_FINISHED
@ -121,6 +124,7 @@ def operate(id, event, qstate, qdata):
if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY): if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str) msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str)
print(msg.answer)
if not msg.set_return_msg(qstate): if not msg.set_return_msg(qstate):
qstate.ext_state[id] = MODULE_ERROR qstate.ext_state[id] = MODULE_ERROR
return True return True

View file

@ -59,12 +59,15 @@ def setTTL(qstate, ttl):
def dataHex(data, prefix=""): def dataHex(data, prefix=""):
res = "" res = ""
for i in range(0, (len(data)+15)/16): for i in range(0, int((len(data)+15)/16)):
res += "%s0x%02X | " % (prefix, i*16) res += "%s0x%02X | " % (prefix, i*16)
d = map(lambda x:ord(x), data[i*16:i*16+17]) if type(data[0]) == type(1):
d = map(lambda x:int(x), data[i*16:i*16+17])
else:
d = map(lambda x:ord(x), data[i*16:i*16+17])
for ch in d: for ch in d:
res += "%02X " % ch res += "%02X " % int(ch)
for i in range(0,17-len(d)): for i in range(0,17-len(data[i*16:i*16+17])):
res += " " res += " "
res += "| " res += "| "
for ch in d: for ch in d:
@ -76,43 +79,43 @@ def dataHex(data, prefix=""):
return res return res
def printReturnMsg(qstate): def printReturnMsg(qstate):
print "Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl) print ("Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount, qstate.return_msg.rep.security, qstate.return_msg.rep.ttl))
print " qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str print (" qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str)
if (qstate.return_msg.rep): if (qstate.return_msg.rep):
print "RRSets:",qstate.return_msg.rep.rrset_count print ("RRSets:",qstate.return_msg.rep.rrset_count)
prevkey = None prevkey = None
for i in range(0,qstate.return_msg.rep.rrset_count): for i in range(0,qstate.return_msg.rep.rrset_count):
r = qstate.return_msg.rep.rrsets[i] r = qstate.return_msg.rep.rrsets[i]
rk = r.rk rk = r.rk
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags, print (i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags)
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class) print ("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
d = r.entry.data d = r.entry.data
print " RRDatas:",d.count+d.rrsig_count print (" RRDatas:",d.count+d.rrsig_count)
for j in range(0,d.count+d.rrsig_count): for j in range(0,d.count+d.rrsig_count):
print " ",j,":","TTL=",d.rr_ttl[j],"RR data:" print (" ",j,":","TTL=",d.rr_ttl[j],"RR data:")
print dataHex(d.rr_data[j]," ") print (dataHex(d.rr_data[j]," "))
def operate(id, event, qstate, qdata): def operate(id, event, qstate, qdata):
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event))) log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
#print "pythonmod: per query data", qdata #print ("pythonmod: per query data", qdata)
print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list, qstate.qinfo.qname_str, print ("Query:", qstate.qinfo.qname, qstate.qinfo.qname_list, qstate.qinfo.qname_str)
print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype, print ("Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype)
print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass print ("Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass)
print print ()
if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("example.com.")): if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("example.com.")):
print qstate.qinfo.qname_str print (qstate.qinfo.qname_str)
qstate.ext_state[id] = MODULE_FINISHED qstate.ext_state[id] = MODULE_FINISHED
# eat time # eat time
y = 20 y = 20
for z in range(2, 10000): for z in range(2, 10000):
y = y*2 - z/2 y = y*2 - z/2
y = y/2 + z y = y/2 + z
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300) msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300)
#msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1") #msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1")

View file

@ -22,3 +22,83 @@ SECTION ANSWER
www2 IN A 10.20.30.40 www2 IN A 10.20.30.40
ENTRY_END ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www3 IN A
SECTION ANSWER
www3 IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www4 IN A
SECTION ANSWER
www4 IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www5 IN A
SECTION ANSWER
www5 IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NXDOMAIN
ADJUST copy_id
SECTION QUESTION
www6 IN A
SECTION AUTHORITY
example.com. 3600 IN SOA a. b. 2018100719 7200 3600 1209600 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NXDOMAIN
ADJUST copy_id
SECTION QUESTION
www7 IN A
SECTION AUTHORITY
example.com. 3600 IN SOA a. b. 2018100719 7200 3600 1209600 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NXDOMAIN
ADJUST copy_id
SECTION QUESTION
www8 IN A
SECTION AUTHORITY
example.com. 3600 IN SOA a. b. 2018100719 7200 3600 1209600 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NXDOMAIN
ADJUST copy_id
SECTION QUESTION
www9 IN A
SECTION AUTHORITY
example.com. 3600 IN SOA a. b. 2018100719 7200 3600 1209600 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NXDOMAIN
ADJUST copy_id
SECTION QUESTION
www10 IN A
SECTION AUTHORITY
example.com. 3600 IN SOA a. b. 2018100719 7200 3600 1209600 3600
ENTRY_END