From: Wouter Wijngaards Date: Mon, 5 Jan 2015 10:16:36 +0000 (+0000) Subject: - patch from Stephane Lapie that adds to the python API, that X-Git-Tag: release-1.5.2rc1~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bcec3cc4f1ed2463c565ccea5989c65a9d85f017;p=thirdparty%2Funbound.git - patch from Stephane Lapie that adds to the python API, that exposes struct delegpt, and adds the find_delegation function. git-svn-id: file:///svn/unbound/trunk@3295 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 90f8db9e2..4427ce976 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,8 @@ 5 January 2015: Wouter - getauxval test for ppc64 linux compatibility. - make strip works for unbound-host and unbound-anchor. + - patch from Stephane Lapie that adds to the python API, that + exposes struct delegpt, and adds the find_delegation function. 9 December 2014: Wouter - svn trunk has 1.5.2 in development. diff --git a/pythonmod/interface.i b/pythonmod/interface.i index 4f1a25f21..19ded4b33 100644 --- a/pythonmod/interface.i +++ b/pythonmod/interface.i @@ -26,6 +26,8 @@ #include "util/storage/lruhash.h" #include "services/cache/dns.h" #include "services/mesh.h" + #include "iterator/iter_delegpt.h" + #include "iterator/iter_hints.h" #include "ldns/wire2str.h" #include "ldns/str2wire.h" #include "ldns/pkthdr.h" @@ -671,6 +673,99 @@ struct config_file { char* python_script; }; +/* ************************************************************************************ * + ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation + * ************************************************************************************ */ +struct delegpt_ns { + struct delegpt_ns* next; + int resolved; + uint8_t got4; + uint8_t got6; + uint8_t lame; + uint8_t done_pside4; + uint8_t done_pside6; +}; + +struct delegpt_addr { + struct delegpt_addr* next_result; + struct delegpt_addr* next_usable; + struct delegpt_addr* next_target; + int attempts; + int sel_rtt; + int bogus; + int lame; +}; + +struct delegpt { + int namelabs; + struct delegpt_ns* nslist; + struct delegpt_addr* target_list; + struct delegpt_addr* usable_list; + struct delegpt_addr* result_list; + int bogus; + uint8_t has_parent_side_NS; + uint8_t dp_type_mlc; +}; + + +%inline %{ + PyObject* _get_dp_dname(struct delegpt* dp) { + return PyString_FromStringAndSize((char*)dp->name, dp->namelen); + } + PyObject* _get_dp_dname_components(struct delegpt* dp) { + return GetNameAsLabelList((char*)dp->name, dp->namelen); + } + PyObject* _get_dpns_dname(struct delegpt_ns* dpns) { + return PyString_FromStringAndSize((char*)dpns->name, dpns->namelen); + } + PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) { + return GetNameAsLabelList((char*)dpns->name, dpns->namelen); + } + + PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) { + char dest[64]; + delegpt_addr_addr2str(target, dest, 64); + if (dest[0] == 0) + return Py_None; + return PyString_FromString(dest); + } + +%} + +%extend delegpt { + %pythoncode %{ + __swig_getmethods__["dname"] = _unboundmodule._get_dp_dname + if _newclass:dname = _swig_property(_unboundmodule._get_dp_dname) + + __swig_getmethods__["dname_list"] = _unboundmodule._get_dp_dname_components + if _newclass:dname_list = _swig_property(_unboundmodule._get_dp_dname_components) + + def _get_dname_str(self): return dnameAsStr(self.dname) + __swig_getmethods__["dname_str"] = _get_dname_str + if _newclass:dname_str = _swig_property(_get_dname_str) + %} +} +%extend delegpt_ns { + %pythoncode %{ + __swig_getmethods__["dname"] = _unboundmodule._get_dpns_dname + if _newclass:dname = _swig_property(_unboundmodule._get_dpns_dname) + + __swig_getmethods__["dname_list"] = _unboundmodule._get_dpns_dname_components + if _newclass:dname_list = _swig_property(_unboundmodule._get_dpns_dname_components) + + def _get_dname_str(self): return dnameAsStr(self.dname) + __swig_getmethods__["dname_str"] = _get_dname_str + if _newclass:dname_str = _swig_property(_get_dname_str) + %} +} +%extend delegpt_addr { + %pythoncode %{ + def _addr_get(self): return _delegpt_addr_addr_get(self) + __swig_getmethods__["addr"] = _addr_get + if _newclass:addr = _swig_property(_addr_get) + %} +} + /* ************************************************************************************ * Enums * ************************************************************************************ */ @@ -879,6 +974,65 @@ int set_return_msg(struct module_qstate* qstate, return status %} +/* ************************************************************************************ * + ASN: Delegation pointer related functions + * ************************************************************************************ */ + +/* Functions which we will need to lookup delegations */ +struct delegpt* dns_cache_find_delegation(struct module_env* env, + char* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, + struct regional* region, struct dns_msg** msg, uint32_t timenow); +int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, + struct delegpt* dp); +struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints, + uint8_t* qname, uint16_t qclass, struct delegpt* dp); + +/* Custom function to perform logic similar to the one in daemon/cachedump.c */ +struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen); + +%{ +#define BIT_RD 0x100 + +struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen) +{ + struct delegpt *dp; + struct dns_msg *msg = NULL; + struct regional* region = qstate->env->scratch; + char b[260]; + struct query_info qinfo; + struct iter_hints_stub* stub; + uint32_t timenow = *qstate->env->now; + + regional_free_all(region); + qinfo.qname = nm; + qinfo.qname_len = nmlen; + qinfo.qtype = LDNS_RR_TYPE_A; + qinfo.qclass = LDNS_RR_CLASS_IN; + + while(1) { + dp = dns_cache_find_delegation(qstate->env, nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow); + if(!dp) + return NULL; + if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) { + if (dname_is_root(nm)) + return NULL; + nm = dp->name; + nmlen = dp->namelen; + dname_remove_label((uint8_t**)&nm, &nmlen); + dname_str(nm, b); + continue; + } + stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, qinfo.qclass, dp); + if (stub) { + return stub->dp; + } else { + return dp; + } + } + return NULL; +} +%} + /* ************************************************************************************ * Functions * ************************************************************************************ */ diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c index 1091dcf10..05914b88a 100644 --- a/pythonmod/pythonmod_utils.c +++ b/pythonmod/pythonmod_utils.c @@ -48,6 +48,7 @@ #include "util/data/msgreply.h" #include "util/storage/slabhash.h" #include "util/regional.h" +#include "iterator/iter_delegpt.h" #include "ldns/sbuffer.h" #undef _POSIX_C_SOURCE @@ -176,3 +177,17 @@ void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen) return; dest[maxlen-1] = 0; } + +/* Convert target->addr to string */ +void delegpt_addr_addr2str(struct delegpt_addr* target, char *dest, int maxlen) +{ + int af = (int)((struct sockaddr_in*) &(target->addr))->sin_family; + void* sinaddr = &((struct sockaddr_in*) &(target->addr))->sin_addr; + + if(af == AF_INET6) + sinaddr = &((struct sockaddr_in6*)&(target->addr))->sin6_addr; + dest[0] = 0; + if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0) + return; + dest[maxlen-1] = 0; +}