diff options
Diffstat (limited to 'contrib/unbound/pythonmod/interface.i')
| -rw-r--r-- | contrib/unbound/pythonmod/interface.i | 1857 |
1 files changed, 0 insertions, 1857 deletions
diff --git a/contrib/unbound/pythonmod/interface.i b/contrib/unbound/pythonmod/interface.i deleted file mode 100644 index 2040fb9e8adf..000000000000 --- a/contrib/unbound/pythonmod/interface.i +++ /dev/null @@ -1,1857 +0,0 @@ -/* - * interface.i: unbound python module - */ -%begin %{ -/* store state of warning output, restored at later pop */ -#pragma GCC diagnostic push -/* ignore warnings for pragma below, where for older GCC it can produce a - warning if the cast-function-type warning is absent. */ -#pragma GCC diagnostic ignored "-Wpragmas" -/* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */ -#pragma GCC diagnostic ignored "-Wcast-function-type" -%} -%module unboundmodule -%{ -/* restore state of warning output, remove the functioncast ignore */ -#pragma GCC diagnostic pop -/** - * \file - * This is the interface between the unbound server and a python module - * called to perform operations on queries. - */ - #include <sys/types.h> - #include <time.h> - #ifdef HAVE_SYS_SOCKET_H - #include <sys/socket.h> - #endif - #ifdef HAVE_NETINET_IN_H - #include <netinet/in.h> - #endif - #ifdef HAVE_ARPA_INET_H - #include <arpa/inet.h> - #endif - #ifdef HAVE_NETDB_H - #include <netdb.h> - #endif - #ifdef HAVE_SYS_UN_H - #include <sys/un.h> - #endif - #include <stdarg.h> - #include "config.h" - #include "util/log.h" - #include "util/module.h" - #include "util/netevent.h" - #include "util/regional.h" - #include "util/config_file.h" - #include "util/data/msgreply.h" - #include "util/data/packed_rrset.h" - #include "util/data/dname.h" - #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 "iterator/iter_utils.h" - #include "sldns/wire2str.h" - #include "sldns/str2wire.h" - #include "sldns/pkthdr.h" -%} - -%include "stdint.i" /* uint_16_t can be known type now */ - -%inline %{ - /* converts [len][data][len][data][0] string to a List of labels (PyBytes) */ - PyObject* GetNameAsLabelList(const char* name, int len) { - PyObject* list; - int cnt=0, i; - - i = 0; - while (i < len) { - i += ((unsigned int)name[i]) + 1; - cnt++; - } - - list = PyList_New(cnt); - i = 0; cnt = 0; - while (i < len) { - char buf[LDNS_MAX_LABELLEN+1]; - if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) && - i+(int)((unsigned int)name[i]) < len) { - 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++; - } - return list; - } - - /* converts an array of strings (char**) to a List of strings */ - PyObject* CharArrayAsStringList(char** array, int len) { - PyObject* list; - int i; - - if(!array||len==0) return PyList_New(0); - - list = PyList_New(len); - for (i=0; i < len; i++) { - PyList_SET_ITEM(list, i, PyString_FromString(array[i])); - } - return list; - } -%} - -/* ************************************************************************************ * - Structure query_info - * ************************************************************************************ */ -/* Query info */ -%ignore query_info::qname; -%ignore query_info::qname_len; - - -struct query_info { - %immutable; - char* qname; - size_t qname_len; - uint16_t qtype; - uint16_t qclass; - %mutable; -}; - -%inline %{ - enum enum_rr_class { - RR_CLASS_IN = 1, - RR_CLASS_CH = 3, - RR_CLASS_HS = 4, - RR_CLASS_NONE = 254, - RR_CLASS_ANY = 255, - }; - - enum enum_rr_type { - RR_TYPE_A = 1, - RR_TYPE_NS = 2, - RR_TYPE_MD = 3, - RR_TYPE_MF = 4, - RR_TYPE_CNAME = 5, - RR_TYPE_SOA = 6, - RR_TYPE_MB = 7, - RR_TYPE_MG = 8, - RR_TYPE_MR = 9, - RR_TYPE_NULL = 10, - RR_TYPE_WKS = 11, - RR_TYPE_PTR = 12, - RR_TYPE_HINFO = 13, - RR_TYPE_MINFO = 14, - RR_TYPE_MX = 15, - RR_TYPE_TXT = 16, - RR_TYPE_RP = 17, - RR_TYPE_AFSDB = 18, - RR_TYPE_X25 = 19, - RR_TYPE_ISDN = 20, - RR_TYPE_RT = 21, - RR_TYPE_NSAP = 22, - RR_TYPE_NSAP_PTR = 23, - RR_TYPE_SIG = 24, - RR_TYPE_KEY = 25, - RR_TYPE_PX = 26, - RR_TYPE_GPOS = 27, - RR_TYPE_AAAA = 28, - RR_TYPE_LOC = 29, - RR_TYPE_NXT = 30, - RR_TYPE_EID = 31, - RR_TYPE_NIMLOC = 32, - RR_TYPE_SRV = 33, - RR_TYPE_ATMA = 34, - RR_TYPE_NAPTR = 35, - RR_TYPE_KX = 36, - RR_TYPE_CERT = 37, - RR_TYPE_A6 = 38, - RR_TYPE_DNAME = 39, - RR_TYPE_SINK = 40, - RR_TYPE_OPT = 41, - RR_TYPE_APL = 42, - RR_TYPE_DS = 43, - RR_TYPE_SSHFP = 44, - RR_TYPE_IPSECKEY = 45, - RR_TYPE_RRSIG = 46, - RR_TYPE_NSEC = 47, - RR_TYPE_DNSKEY = 48, - RR_TYPE_DHCID = 49, - RR_TYPE_NSEC3 = 50, - RR_TYPE_NSEC3PARAMS = 51, - RR_TYPE_UINFO = 100, - RR_TYPE_UID = 101, - RR_TYPE_GID = 102, - RR_TYPE_UNSPEC = 103, - RR_TYPE_TSIG = 250, - RR_TYPE_IXFR = 251, - RR_TYPE_AXFR = 252, - RR_TYPE_MAILB = 253, - RR_TYPE_MAILA = 254, - RR_TYPE_ANY = 255, - RR_TYPE_DLV = 32769, - }; - - PyObject* _get_qname(struct query_info* q) { - return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len); - } - - PyObject* _get_qname_components(struct query_info* q) { - return GetNameAsLabelList((const char*)q->qname, q->qname_len); - } -%} - -%inline %{ - PyObject* dnameAsStr(PyObject* dname) { - char buf[LDNS_MAX_DOMAINLEN]; - buf[0] = '\0'; - dname_str((uint8_t*)PyBytes_AsString(dname), buf); - return PyString_FromString(buf); - } -%} - -%extend query_info { - %pythoncode %{ - def _get_qtype_str(self): return sldns_wire2str_type(self.qtype) - qtype_str = property(_get_qtype_str) - - def _get_qclass_str(self): return sldns_wire2str_class(self.qclass) - qclass_str = property(_get_qclass_str) - - qname = property(_unboundmodule._get_qname) - - qname_list = property(_unboundmodule._get_qname_components) - - def _get_qname_str(self): return dnameAsStr(self.qname) - qname_str = property(_get_qname_str) - %} -} - -/* ************************************************************************************ * - Structure packed_rrset_key - * ************************************************************************************ */ -%ignore packed_rrset_key::dname; -%ignore packed_rrset_key::dname_len; - -/* RRsets */ -struct packed_rrset_key { - %immutable; - char* dname; - size_t dname_len; - uint32_t flags; - uint16_t type; /* rrset type in network format */ - uint16_t rrset_class; /* rrset class in network format */ - %mutable; -}; - -/** - * This subroutine converts values between the host and network byte order. - * Specifically, ntohs() converts 16-bit quantities from network byte order to - * host byte order. - */ -uint16_t ntohs(uint16_t netshort); - -%inline %{ - PyObject* _get_dname(struct packed_rrset_key* k) { - return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len); - } - PyObject* _get_dname_components(struct packed_rrset_key* k) { - return GetNameAsLabelList((char*)k->dname, k->dname_len); - } -%} - -%extend packed_rrset_key { - %pythoncode %{ - def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type)) - type_str = property(_get_type_str) - - def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class)) - rrset_class_str = property(_get_class_str) - - dname = property(_unboundmodule._get_dname) - - dname_list = property(_unboundmodule._get_dname_components) - - def _get_dname_str(self): return dnameAsStr(self.dname) - dname_str = property(_get_dname_str) - %} -} - -#if defined(SWIGWORDSIZE64) -typedef long int rrset_id_type; -#else -typedef long long int rrset_id_type; -#endif - -struct ub_packed_rrset_key { - struct lruhash_entry entry; - rrset_id_type id; - struct packed_rrset_key rk; -}; - -struct lruhash_entry { - lock_rw_type lock; - struct lruhash_entry* overflow_next; - struct lruhash_entry* lru_next; - struct lruhash_entry* lru_prev; - hashvalue_type hash; - void* key; - struct packed_rrset_data* data; -}; - -%ignore packed_rrset_data::rr_len; -%ignore packed_rrset_data::rr_ttl; -%ignore packed_rrset_data::rr_data; - -struct packed_rrset_data { - /* TTL (in seconds like time()) */ - uint32_t ttl; - - /* number of rrs */ - size_t count; - /* number of rrsigs */ - size_t rrsig_count; - - enum rrset_trust trust; - enum sec_status security; - - /* length of every rr's rdata */ - size_t* rr_len; - /* ttl of every rr */ - uint32_t *rr_ttl; - /* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in - * uncompressed wireformat. */ - uint8_t** rr_data; -}; - -%pythoncode %{ - class RRSetData_RRLen: - def __init__(self, obj): self.obj = obj - def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index) - def __len__(self): return self.obj.count + self.obj.rrsig_count - class RRSetData_RRTTL: - def __init__(self, obj): self.obj = obj - def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index) - def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value) - def __len__(self): return self.obj.count + self.obj.rrsig_count - class RRSetData_RRData: - def __init__(self, obj): self.obj = obj - def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index) - def __len__(self): return self.obj.count + self.obj.rrsig_count -%} - -%inline %{ - PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) { - if ((d != NULL) && (idx >= 0) && - ((size_t)idx < (d->count+d->rrsig_count))) - return PyInt_FromLong(d->rr_len[idx]); - return Py_None; - } - void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl) - { - if ((d != NULL) && (idx >= 0) && - ((size_t)idx < (d->count+d->rrsig_count))) - d->rr_ttl[idx] = ttl; - } - PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) { - if ((d != NULL) && (idx >= 0) && - ((size_t)idx < (d->count+d->rrsig_count))) - return PyInt_FromLong(d->rr_ttl[idx]); - return Py_None; - } - PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) { - if ((d != NULL) && (idx >= 0) && - ((size_t)idx < (d->count+d->rrsig_count))) - return PyBytes_FromStringAndSize((char*)d->rr_data[idx], - d->rr_len[idx]); - return Py_None; - } -%} - -%extend packed_rrset_data { - %pythoncode %{ - def _get_data_rr_len(self): return RRSetData_RRLen(self) - rr_len = property(_get_data_rr_len) - def _get_data_rr_ttl(self): return RRSetData_RRTTL(self) - rr_ttl = property(_get_data_rr_ttl) - def _get_data_rr_data(self): return RRSetData_RRData(self) - rr_data = property(_get_data_rr_data) - %} -} - -/* ************************************************************************************ * - Structure reply_info - * ************************************************************************************ */ -/* Messages */ -%ignore reply_info::rrsets; -%ignore reply_info::ref; - -struct reply_info { - uint16_t flags; - uint16_t qdcount; - uint32_t ttl; - uint32_t prefetch_ttl; - - uint16_t authoritative; - enum sec_status security; - - size_t an_numrrsets; - size_t ns_numrrsets; - size_t ar_numrrsets; - size_t rrset_count; /* an_numrrsets + ns_numrrsets + ar_numrrsets */ - - struct ub_packed_rrset_key** rrsets; - struct rrset_ref ref[1]; /* ? */ -}; - -struct rrset_ref { - struct ub_packed_rrset_key* key; - rrset_id_type id; -}; - -struct dns_msg { - struct query_info qinfo; - struct reply_info *rep; -}; - -%pythoncode %{ - class ReplyInfo_RRSet: - def __init__(self, obj): self.obj = obj - def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index) - def __len__(self): return self.obj.rrset_count - - class ReplyInfo_Ref: - def __init__(self, obj): self.obj = obj - def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index) - def __len__(self): return self.obj.rrset_count -%} - -%inline %{ - struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) { - if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) - return r->rrsets[idx]; - return NULL; - } - - struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) { - if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) { -/* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */ - return &(r->ref[idx]); -/* return &(r->ref[idx]); */ - } -/* printf("_rrset_ref_get: NULL\n"); */ - return NULL; - } -%} - -%extend reply_info { - %pythoncode %{ - def _rrset_ref_get(self): return ReplyInfo_Ref(self) - ref = property(_rrset_ref_get) - - def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self) - rrsets = property(_rrset_rrsets_get) - %} -} - -/* ************************************************************************************ * - Structure sockaddr_storage - * ************************************************************************************ */ - -struct sockaddr_storage {}; - -%inline %{ - static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) { - if (ss == NULL) { - return 0; - } - - switch (ss->ss_family) { - case AF_INET: return sizeof(struct sockaddr_in); - case AF_INET6: return sizeof(struct sockaddr_in6); -#ifdef HAVE_SYS_UN_H - case AF_UNIX: return sizeof(struct sockaddr_un); -#endif - default: - return 0; - } - } - - PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) { - if (ss == NULL) { - return Py_None; - } - - switch (ss->ss_family) { - case AF_INET: return PyUnicode_FromString("ip4"); - case AF_INET6: return PyUnicode_FromString("ip6"); - case AF_UNIX: return PyUnicode_FromString("unix"); - default: - return Py_None; - } - } - - PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) { - const struct sockaddr *sa; - size_t sa_len; - char name[NI_MAXHOST] = {0}; - - if (ss == NULL) { - return Py_None; - } - - sa = (struct sockaddr *)ss; - sa_len = _sockaddr_storage_len(ss); - if (sa_len == 0) { - return Py_None; - } - - if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) { - return Py_None; - } - - return PyUnicode_FromString(name); - } - - PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) { - size_t sa_len; - - if (ss == NULL) { - return Py_None; - } - - sa_len = _sockaddr_storage_len(ss); - if (sa_len == 0) { - return Py_None; - } - - if (ss->ss_family == AF_INET) { - const struct sockaddr_in *sa = (struct sockaddr_in *)ss; - const struct in_addr *raw = (struct in_addr *)&sa->sin_addr; - return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw)); - } - - if (ss->ss_family == AF_INET6) { - const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss; - const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr; - return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw)); - } - -#ifdef HAVE_SYS_UN_H - if (ss->ss_family == AF_UNIX) { - const struct sockaddr_un *sa = (struct sockaddr_un *)ss; - return PyBytes_FromString(sa->sun_path); - } -#endif - - return Py_None; - } - - PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) { - if (ss == NULL) { - return Py_None; - } - - if (ss->ss_family == AF_INET) { - const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss; - return PyInt_FromLong(ntohs(sa4->sin_port)); - } - - if (ss->ss_family == AF_INET6) { - const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss; - return PyInt_FromLong(ntohs(sa6->sin6_port)); - } - - return Py_None; - } - - PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) { - const struct sockaddr_in6 *sa6; - - if (ss == NULL || ss->ss_family != AF_INET6) { - return Py_None; - } - - sa6 = (struct sockaddr_in6 *)ss; - return PyInt_FromLong(ntohl(sa6->sin6_flowinfo)); - } - - PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) { - const struct sockaddr_in6 *sa6; - - if (ss == NULL || ss->ss_family != AF_INET6) { - return Py_None; - } - - sa6 = (struct sockaddr_in6 *)ss; - return PyInt_FromLong(ntohl(sa6->sin6_scope_id)); - } -%} - -%extend sockaddr_storage { - %pythoncode %{ - def _family_get(self): return _sockaddr_storage_family(self) - family = property(_family_get) - - def _addr_get(self): return _sockaddr_storage_addr(self) - addr = property(_addr_get) - - def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self) - raw_addr = property(_raw_addr_get) - - def _port_get(self): return _sockaddr_storage_port(self) - port = property(_port_get) - - def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self) - flowinfo = property(_flowinfo_get) - - def _scope_id_get(self): return _sockaddr_storage_scope_id(self) - scope_id = property(_scope_id_get) - %} -} - -/* ************************************************************************************ * - Structure mesh_state - * ************************************************************************************ */ -struct mesh_state { - struct mesh_reply* reply_list; -}; - -struct mesh_reply { - struct mesh_reply* next; - struct comm_reply query_reply; -}; - -%rename(_addr) comm_reply::client_addr; -struct comm_reply { - struct sockaddr_storage client_addr; -}; - -%extend comm_reply { - %pythoncode %{ - def _addr_get(self): return _sockaddr_storage_addr(self._addr) - addr = property(_addr_get) - - def _port_get(self): return _sockaddr_storage_port(self._addr) - port = property(_port_get) - - def _family_get(self): return _sockaddr_storage_family(self._addr) - family = property(_family_get) - %} -} - -/* ************************************************************************************ * - Structure edns_option - * ************************************************************************************ */ -/* Rename the members to follow the python convention of marking them as - * private. Access to the opt_code and opt_data members is given by the later - * python defined code and data members respectively. */ -%rename(_next) edns_option::next; -%rename(_opt_code) edns_option::opt_code; -%rename(_opt_len) edns_option::opt_len; -%rename(_opt_data) edns_option::opt_data; -struct edns_option { - struct edns_option* next; - uint16_t opt_code; - size_t opt_len; - uint8_t* opt_data; -}; - -%inline %{ - PyObject* _edns_option_opt_code_get(struct edns_option* option) { - uint16_t opt_code = option->opt_code; - return PyInt_FromLong(opt_code); - } - - PyObject* _edns_option_opt_data_get(struct edns_option* option) { - return PyByteArray_FromStringAndSize((void*)option->opt_data, - option->opt_len); - } -%} -%extend edns_option { - %pythoncode %{ - def _opt_code_get(self): return _edns_option_opt_code_get(self) - code = property(_opt_code_get) - - def _opt_data_get(self): return _edns_option_opt_data_get(self) - data = property(_opt_data_get) - %} -} - -/* ************************************************************************************ * - Structure edns_data - * ************************************************************************************ */ -/* This is ignored because we will pass a double pointer of this to Python - * with custom getmethods. This is done to bypass Swig's behavior to pass NULL - * pointers as None. */ -%ignore edns_data::opt_list; -struct edns_data { - int edns_present; - uint8_t ext_rcode; - uint8_t edns_version; - uint16_t bits; - uint16_t udp_size; - struct edns_option* opt_list_in; - struct edns_option* opt_list_out; - struct edns_option* opt_list_inplace_cb_out; - uint16_t padding_block_size; -}; -%inline %{ - struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) { - return &edns->opt_list_in; - } -%} -%extend edns_data { - %pythoncode %{ - def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list) - opt_list_iter = property(_opt_list_iter) - def _opt_list(self): return _edns_data_opt_list_get(self) - opt_list = property(_opt_list) - %} -} - -/* ************************************************************************************ * - Structure module_env - * ************************************************************************************ */ -%rename(_now) module_env::now; -%rename(_now_tv) module_env::now_tv; -struct module_env { - struct config_file* cfg; - struct slabhash* msg_cache; - struct rrset_cache* rrset_cache; - struct infra_cache* infra_cache; - struct key_cache* key_cache; - - /* --- services --- */ - struct outbound_entry* (*send_query)(struct query_info* qinfo, - uint16_t flags, int dnssec, int want_dnssec, int nocaps, - int check_ratelimit, - struct sockaddr_storage* addr, socklen_t addrlen, - uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, - char* tls_auth_name, struct module_qstate* q, int* was_ratelimited); - void (*detach_subs)(struct module_qstate* qstate); - int (*attach_sub)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t qflags, int prime, - int valrec, struct module_qstate** newq); - void (*kill_sub)(struct module_qstate* newq); - int (*detect_cycle)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t flags, int prime, - int valrec); - - struct regional* scratch; - struct sldns_buffer* scratch_buffer; - struct worker* worker; - struct mesh_area* mesh; - struct alloc_cache* alloc; - struct ub_randstate* rnd; - time_t* now; - struct timeval* now_tv; - int need_to_validate; - struct val_anchors* anchors; - struct val_neg_cache* neg_cache; - struct comm_timer* probe_timer; - struct iter_forwards* fwds; - struct iter_hints* hints; - void* modinfo[MAX_MODULE]; - - void* inplace_cb_lists[inplace_cb_types_total]; - struct edns_known_option* edns_known_options; - size_t edns_known_options_num; -}; - -%inline %{ - PyObject* _module_env_now_get(struct module_env* env) { - double ts = env->now_tv->tv_sec + env->now_tv->tv_usec / 1e6; - return PyFloat_FromDouble(ts); - } -%} -%extend module_env { - %pythoncode %{ - def _now_get(self): return _module_env_now_get(self) - now = property(_now_get) - %} -} - -/* ************************************************************************************ * - Structure module_qstate - * ************************************************************************************ */ -%ignore module_qstate::ext_state; -%ignore module_qstate::minfo; - -/* These are ignored because we will pass a double pointer of them to Python - * with custom getmethods. This is done to bypass Swig's behavior to pass NULL - * pointers as None. */ -%ignore module_qstate::edns_opts_front_in; -%ignore module_qstate::edns_opts_back_out; -%ignore module_qstate::edns_opts_back_in; -%ignore module_qstate::edns_opts_front_out; - -/* Query state */ -struct module_qstate { - struct query_info qinfo; - uint16_t query_flags; /* See QF_BIT_xx constants */ - int is_priming; - int is_valrec; - - struct comm_reply* reply; - struct dns_msg* return_msg; - int return_rcode; - struct regional* region; /* unwrapped */ - - int curmod; - - enum module_ext_state ext_state[MAX_MODULE]; - void* minfo[MAX_MODULE]; - time_t prefetch_leeway; - - struct module_env* env; /* unwrapped */ - struct mesh_state* mesh_info; - - struct edns_option* edns_opts_front_in; - struct edns_option* edns_opts_back_out; - struct edns_option* edns_opts_back_in; - struct edns_option* edns_opts_front_out; - int no_cache_lookup; - int no_cache_store; -}; - -%constant int MODULE_COUNT = MAX_MODULE; - -%constant int QF_BIT_CD = 0x0010; -%constant int QF_BIT_AD = 0x0020; -%constant int QF_BIT_Z = 0x0040; -%constant int QF_BIT_RA = 0x0080; -%constant int QF_BIT_RD = 0x0100; -%constant int QF_BIT_TC = 0x0200; -%constant int QF_BIT_AA = 0x0400; -%constant int QF_BIT_QR = 0x8000; - -%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 - }; -%} - -%pythoncode %{ - class ExtState: - def __init__(self, obj): self.obj = obj - def __str__(self): - return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)]) - def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index) - def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value) - def __len__(self): return _unboundmodule.MODULE_COUNT - - class EdnsOptsListIter: - def __init__(self, obj): - self._current = obj - self._temp = None - def __iter__(self): return self - def __next__(self): - """Python 3 compatibility""" - return self._get_next() - def next(self): - """Python 2 compatibility""" - return self._get_next() - def _get_next(self): - if not edns_opt_list_is_empty(self._current): - self._temp = self._current - self._current = _p_p_edns_option_get_next(self._current) - return _dereference_edns_option(self._temp) - else: - raise StopIteration -%} - -%inline %{ - enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) { - if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) { - return q->ext_state[idx]; - } - return 0; - } - - void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) { - if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) { - q->ext_state[idx] = state; - } - } - - int edns_opt_list_is_empty(struct edns_option** opt) { - if (!opt || !(*opt)) return 1; - return 0; - } - - struct edns_option* _dereference_edns_option(struct edns_option** opt) { - if (!opt) return NULL; - return *opt; - } - - struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) { - return &(*opt)->next; - } - - struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) { - return &q->edns_opts_front_in; - } - - struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) { - return &q->edns_opts_back_out; - } - - struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) { - return &q->edns_opts_back_in; - } - - struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) { - return &q->edns_opts_front_out; - } -%} - -%extend module_qstate { - %pythoncode %{ - def set_ext_state(self, id, state): - """Sets the ext state""" - _unboundmodule._ext_state_set(self, id, state) - - def __ext_state_get(self): return ExtState(self) - ext_state = property(__ext_state_get) #, __ext_state_set - - def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in) - edns_opts_front_in_iter = property(_edns_opts_front_in_iter) - def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out) - edns_opts_back_out_iter = property(_edns_opts_back_out_iter) - def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in) - edns_opts_back_in_iter = property(_edns_opts_back_in_iter) - def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out) - edns_opts_front_out_iter = property(_edns_opts_front_out_iter) - - def _edns_opts_front_in(self): return _edns_opts_front_in_get(self) - edns_opts_front_in = property(_edns_opts_front_in) - def _edns_opts_back_out(self): return _edns_opts_back_out_get(self) - edns_opts_back_out = property(_edns_opts_back_out) - def _edns_opts_back_in(self): return _edns_opts_back_in_get(self) - edns_opts_back_in = property(_edns_opts_back_in) - def _edns_opts_front_out(self): return _edns_opts_front_out_get(self) - edns_opts_front_out = property(_edns_opts_front_out) - %} -} - -/* ************************************************************************************ * - Structure config_strlist - * ************************************************************************************ */ -struct config_strlist { - struct config_strlist* next; - char* str; -}; - -/* ************************************************************************************ * - Structure config_str2list - * ************************************************************************************ */ -struct config_str2list { - struct config_str2list* next; - char* str; - char* str2; -}; - -/* ************************************************************************************ * - Structure config_file - * ************************************************************************************ */ -%ignore config_file::ifs; -%ignore config_file::out_ifs; -%ignore config_file::python_script; -struct config_file { - int verbosity; - int stat_interval; - int stat_cumulative; - int stat_extended; - int num_threads; - int port; - int do_ip4; - int do_ip6; - int do_udp; - int do_tcp; - int outgoing_num_ports; - size_t outgoing_num_tcp; - size_t incoming_num_tcp; - int* outgoing_avail_ports; - size_t msg_buffer_size; - size_t msg_cache_size; - size_t msg_cache_slabs; - size_t num_queries_per_thread; - size_t jostle_time; - size_t rrset_cache_size; - size_t rrset_cache_slabs; - int host_ttl; - size_t infra_cache_slabs; - size_t infra_cache_numhosts; - char* target_fetch_policy; - int if_automatic; - int num_ifs; - char **ifs; - int num_out_ifs; - char **out_ifs; - struct config_strlist* root_hints; - struct config_stub* stubs; - struct config_stub* forwards; - struct config_strlist* donotqueryaddrs; - struct config_str2list* acls; - int donotquery_localhost; - int harden_short_bufsize; - int harden_large_queries; - int harden_glue; - int harden_unverified_glue; - int harden_dnssec_stripped; - int harden_referral_path; - int use_caps_bits_for_id; - struct config_strlist* private_address; - struct config_strlist* private_domain; - size_t unwanted_threshold; - char* chrootdir; - char* username; - char* directory; - char* logfile; - char* pidfile; - int use_syslog; - int hide_identity; - int hide_version; - char* identity; - char* version; - char* module_conf; - struct config_strlist* trust_anchor_file_list; - struct config_strlist* trust_anchor_list; - struct config_strlist* trusted_keys_file_list; - int max_ttl; - int32_t val_date_override; - int bogus_ttl; - int val_clean_additional; - int val_permissive_mode; - char* val_nsec3_key_iterations; - size_t key_cache_size; - size_t key_cache_slabs; - size_t neg_cache_size; - struct config_str2list* local_zones; - struct config_strlist* local_zones_nodefault; - struct config_strlist* local_data; - int remote_control_enable; - struct config_strlist_head control_ifs; - int control_port; - char* server_key_file; - char* server_cert_file; - char* control_key_file; - char* control_cert_file; - int do_daemonize; - struct config_strlist* python_script; -}; - -%inline %{ - PyObject* _get_ifs_tuple(struct config_file* cfg) { - return CharArrayAsStringList(cfg->ifs, cfg->num_ifs); - } - PyObject* _get_ifs_out_tuple(struct config_file* cfg) { - return CharArrayAsStringList(cfg->out_ifs, cfg->num_out_ifs); - } -%} - -%extend config_file { - %pythoncode %{ - ifs = property(_unboundmodule._get_ifs_tuple) - out_ifs = property(_unboundmodule._get_ifs_out_tuple) - - def _deprecated_python_script(self): return "cfg.python_script is deprecated, you can use `mod_env['script']` instead." - python_script = property(_deprecated_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 PyBytes_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 PyBytes_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 PyBytes_FromString(dest); - } - -%} - -%extend delegpt { - %pythoncode %{ - dname = property(_unboundmodule._get_dp_dname) - - dname_list = property(_unboundmodule._get_dp_dname_components) - - def _get_dname_str(self): return dnameAsStr(self.dname) - dname_str = property(_get_dname_str) - %} -} -%extend delegpt_ns { - %pythoncode %{ - dname = property(_unboundmodule._get_dpns_dname) - - dname_list = property(_unboundmodule._get_dpns_dname_components) - - def _get_dname_str(self): return dnameAsStr(self.dname) - dname_str = property(_get_dname_str) - %} -} -%extend delegpt_addr { - %pythoncode %{ - def _addr_get(self): return _delegpt_addr_addr_get(self) - addr = property(_addr_get) - %} -} - -/* ************************************************************************************ * - Enums - * ************************************************************************************ */ -%rename ("MODULE_STATE_INITIAL") "module_state_initial"; -%rename ("MODULE_WAIT_REPLY") "module_wait_reply"; -%rename ("MODULE_WAIT_MODULE") "module_wait_module"; -%rename ("MODULE_RESTART_NEXT") "module_restart_next"; -%rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery"; -%rename ("MODULE_ERROR") "module_error"; -%rename ("MODULE_FINISHED") "module_finished"; - -enum module_ext_state { - module_state_initial = 0, - module_wait_reply, - module_wait_module, - module_restart_next, - module_wait_subquery, - module_error, - module_finished -}; - -%rename ("MODULE_EVENT_NEW") "module_event_new"; -%rename ("MODULE_EVENT_PASS") "module_event_pass"; -%rename ("MODULE_EVENT_REPLY") "module_event_reply"; -%rename ("MODULE_EVENT_NOREPLY") "module_event_noreply"; -%rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail"; -%rename ("MODULE_EVENT_MODDONE") "module_event_moddone"; -%rename ("MODULE_EVENT_ERROR") "module_event_error"; - -enum module_ev { - module_event_new = 0, - module_event_pass, - module_event_reply, - module_event_noreply, - module_event_capsfail, - module_event_moddone, - module_event_error -}; - -enum sec_status { - sec_status_unchecked = 0, - sec_status_bogus, - sec_status_indeterminate, - sec_status_insecure, - sec_status_secure -}; - -enum verbosity_value { - NO_VERBOSE = 0, - VERB_OPS, - VERB_DETAIL, - VERB_QUERY, - VERB_ALGO -}; - -enum inplace_cb_list_type { - /* Inplace callbacks for when a resolved reply is ready to be sent to the - * front.*/ - inplace_cb_reply = 0, - /* Inplace callbacks for when a reply is given from the cache. */ - inplace_cb_reply_cache, - /* Inplace callbacks for when a reply is given with local data - * (or Chaos reply). */ - inplace_cb_reply_local, - /* Inplace callbacks for when the reply is servfail. */ - inplace_cb_reply_servfail, - /* Inplace callbacks for when a query is ready to be sent to the back.*/ - inplace_cb_query, - /* Inplace callback for when a reply is received from the back. */ - inplace_cb_edns_back_parsed, - /* Total number of types. Used for array initialization. - * Should always be last. */ - inplace_cb_types_total -}; - -%constant uint16_t PKT_QR = 1; /* QueRy - query flag */ -%constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */ -%constant uint16_t PKT_TC = 4; /* TrunCated - server flag */ -%constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */ -%constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */ -%constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */ -%constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */ - -%{ -int checkList(PyObject *l) -{ - PyObject* item; - int i; - - if (l == Py_None) - return 1; - - if (PyList_Check(l)) - { - for (i=0; i < PyList_Size(l); i++) - { - item = PyList_GetItem(l, i); - if (!PyBytes_Check(item) && !PyUnicode_Check(item)) - return 0; - } - return 1; - } - - return 0; -} - -int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec, - size_t count_offset) -{ - PyObject* item; - int i; - size_t len; - char* s; - PyObject* ascstr; - - for (i=0; i < PyList_Size(l); i++) - { - ascstr = NULL; - 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); - if(qsec) { - if(sldns_str2wire_rr_question_buf(s, - sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0) - != 0) { - if(ascstr) - Py_DECREF(ascstr); - return 0; - } - } else { - if(sldns_str2wire_rr_buf(s, - sldns_buffer_current(qb), &len, NULL, default_ttl, - NULL, 0, NULL, 0) != 0) { - if(ascstr) - Py_DECREF(ascstr); - return 0; - } - } - if(ascstr) - Py_DECREF(ascstr); - sldns_buffer_skip(qb, len); - - sldns_buffer_write_u16_at(qb, count_offset, - sldns_buffer_read_u16_at(qb, count_offset)+1); - } - return 1; -} - -int set_return_msg(struct module_qstate* qstate, - const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl, - PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional) -{ - sldns_buffer *qb = 0; - int res = 1; - size_t l; - uint16_t PKT_QR = 1; - uint16_t PKT_AA = 2; - uint16_t PKT_TC = 4; - uint16_t PKT_RD = 8; - uint16_t PKT_CD = 16; - uint16_t PKT_RA = 32; - uint16_t PKT_AD = 64; - - if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional))) - return 0; - if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0; - - /* write header */ - sldns_buffer_write_u16(qb, 0); /* ID */ - sldns_buffer_write_u16(qb, 0); /* flags */ - sldns_buffer_write_u16(qb, 1); /* qdcount */ - sldns_buffer_write_u16(qb, 0); /* ancount */ - sldns_buffer_write_u16(qb, 0); /* nscount */ - sldns_buffer_write_u16(qb, 0); /* arcount */ - if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb)); - if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb)); - if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb)); - if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb)); - if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb)); - if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb)); - if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb)); - - /* write the query */ - l = sldns_buffer_remaining(qb); - if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) { - sldns_buffer_free(qb); - return 0; - } - sldns_buffer_skip(qb, l); - if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; } - if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; } - sldns_buffer_write_u16(qb, rr_type); - sldns_buffer_write_u16(qb, rr_class); - - /* write RR sections */ - if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF)) - res = 0; - if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF)) - res = 0; - if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF)) - res = 0; - if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF)) - res = 0; - - if (res) res = createResponse(qstate, qb); - - if (qb) sldns_buffer_free(qb); - return res; -} -%} - -int set_return_msg(struct module_qstate* qstate, - const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl, - PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional); - -%pythoncode %{ - class DNSMessage: - def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0): - """Query flags is a combination of PKT_xx constants""" - self.rr_name = rr_name - self.rr_type = rr_type - self.rr_class = rr_class - self.default_ttl = default_ttl - self.query_flags = query_flags - self.question = [] - self.answer = [] - self.authority = [] - self.additional = [] - - def set_return_msg(self, qstate): - """Returns 1 if OK""" - status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class, - self.query_flags, self.default_ttl, - self.question, self.answer, self.authority, self.additional) - - if (status) and (PKT_AA & self.query_flags): - qstate.return_msg.rep.authoritative = 1 - - 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, - uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - struct regional* region, struct dns_msg** msg, uint32_t timenow, - int noexpiredabove, uint8_t* expiretop, size_t expiretoplen); -int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, - struct delegpt* dp, int supports_ipv4, int supports_ipv6, int use_nat64); -struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints, - uint8_t* qname, uint16_t qclass, struct delegpt* dp, int nolock); - -/* 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; - int nolock = 0; - - regional_free_all(region); - qinfo.qname = (uint8_t*)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, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow, 0, NULL, 0); - if(!dp) - return NULL; - if(iter_dp_is_useless(&qinfo, BIT_RD, dp, - qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6, - qstate->env->cfg->do_nat64)) { - if (dname_is_root((uint8_t*)nm)) - return NULL; - nm = (char*)dp->name; - nmlen = dp->namelen; - dname_remove_label((uint8_t**)&nm, &nmlen); - dname_str((uint8_t*)nm, b); - continue; - } - stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, - qinfo.qclass, dp, nolock); - if (stub) { - struct delegpt* stubdp = delegpt_copy(stub->dp, region); - lock_rw_unlock(&qstate->env->hints->lock); - return stubdp; - } else { - return dp; - } - } - return NULL; -} -%} - -/* ************************************************************************************ * - Functions - * ************************************************************************************ */ -/****************************** - * Various debugging functions * - ******************************/ - -/* rename the variadic functions because python does the formatting already*/ -%rename (unbound_log_info) log_info; -%rename (unbound_log_err) log_err; -%rename (unbound_log_warn) log_warn; -%rename (unbound_verbose) verbose; -/* provide functions that take one string as argument, so python can cook -the string */ -%rename (log_info) pymod_log_info; -%rename (log_warn) pymod_log_warn; -%rename (log_err) pymod_log_err; -%rename (verbose) pymod_verbose; - -void verbose(enum verbosity_value level, const char* format, ...); -void log_info(const char* format, ...); -void log_err(const char* format, ...); -void log_warn(const char* format, ...); -void log_hex(const char* msg, void* data, size_t length); -void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep); -void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf); -void regional_log_stats(struct regional *r); - -/* the one argument string log functions */ -void pymod_log_info(const char* str); -void pymod_log_err(const char* str); -void pymod_log_warn(const char* str); -void pymod_verbose(enum verbosity_value level, const char* str); -%{ -void pymod_log_info(const char* str) { log_info("%s", str); } -void pymod_log_err(const char* str) { log_err("%s", str); } -void pymod_log_warn(const char* str) { log_warn("%s", str); } -void pymod_verbose(enum verbosity_value level, const char* str) { - verbose(level, "%s", str); } -%} - -/*************************************************************************** - * Free allocated memory from marked sources returning corresponding types * - ***************************************************************************/ -%typemap(newfree, noblock = 1) char * { - free($1); -} - -/*************************************************** - * Mark as source returning newly allocated memory * - ***************************************************/ -%newobject sldns_wire2str_type; -%newobject sldns_wire2str_class; - -/****************** - * LDNS functions * - ******************/ -char *sldns_wire2str_type(const uint16_t atype); -char *sldns_wire2str_class(const uint16_t aclass); - -/********************************** - * Functions from pythonmod_utils * - **********************************/ -int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral); -void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo); - -/******************************* - * Module conversion functions * - *******************************/ -const char* strextstate(enum module_ext_state s); -const char* strmodulevent(enum module_ev e); - -/************************** - * Edns related functions * - **************************/ -struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code); -int edns_register_option(uint16_t opt_code, int bypass_cache_stage, - int no_aggregation, struct module_env* env); - -%pythoncode %{ - def register_edns_option(env, code, bypass_cache_stage=False, - no_aggregation=False): - """Wrapper function to provide keyword attributes.""" - return edns_register_option(code, bypass_cache_stage, - no_aggregation, env) -%} - -/****************************** - * Callback related functions * - ******************************/ -/* typemap to check if argument is callable */ -%typemap(in) PyObject *py_cb { - if (!PyCallable_Check($input)) { - SWIG_exception_fail(SWIG_TypeError, "Need a callable object!"); - return NULL; - } - $1 = $input; -} -/* typemap to get content/size from a bytearray */ -%typemap(in) (size_t len, uint8_t* py_bytearray_data) { - if (!PyByteArray_CheckExact($input)) { - SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!"); - return NULL; - } - $2 = (void*)PyByteArray_AsString($input); - $1 = PyByteArray_Size($input); -} - -int edns_opt_list_remove(struct edns_option** list, uint16_t code); -int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len, - uint8_t* py_bytearray_data, struct regional* region); - -%{ - /* This function is called by unbound in order to call the python - * callback function. */ - int python_inplace_cb_reply_generic(struct query_info* qinfo, - struct module_qstate* qstate, struct reply_info* rep, int rcode, - struct edns_data* edns, struct edns_option** opt_list_out, - struct comm_reply* repinfo, struct regional* region, - struct timeval* start_time, int id, void* python_callback) - { - PyObject *func = NULL, *py_edns = NULL, *py_qstate = NULL; - PyObject *py_opt_list_out = NULL, *py_qinfo = NULL; - PyObject *py_rep = NULL, *py_repinfo = NULL, *py_region = NULL; - PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL; - int res = 0; - double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6; - - PyGILState_STATE gstate = PyGILState_Ensure(); - - func = (PyObject *) python_callback; - py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0); - py_qstate = SWIG_NewPointerObj((void*) qstate, - SWIGTYPE_p_module_qstate, 0); - py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out, - SWIGTYPE_p_p_edns_option, 0); - py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); - py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0); - py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0); - py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); - if(!(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out - && py_region && py_repinfo)) { - log_err("pythonmod: swig pointer failure in python_inplace_cb_reply_generic"); - goto out; - } - py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep, - rcode, py_edns, py_opt_list_out, py_region); - py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time", - py_start_time); - if(!(py_args && py_kwargs)) { - log_err("pythonmod: BuildValue failure in python_inplace_cb_reply_generic"); - goto out; - } - result = PyObject_Call(func, py_args, py_kwargs); - if (result) { - res = PyInt_AsLong(result); - } -out: - Py_XDECREF(py_edns); - Py_XDECREF(py_qstate); - Py_XDECREF(py_opt_list_out); - Py_XDECREF(py_qinfo); - Py_XDECREF(py_rep); - Py_XDECREF(py_repinfo); - Py_XDECREF(py_region); - Py_XDECREF(py_args); - Py_XDECREF(py_kwargs); - Py_XDECREF(result); - PyGILState_Release(gstate); - return res; - } - - /* register a callback */ - static int python_inplace_cb_register(enum inplace_cb_list_type type, - PyObject* py_cb, struct module_env* env, int id) - { - int ret = inplace_cb_register(python_inplace_cb_reply_generic, - type, (void*) py_cb, env, id); - if (ret) Py_INCREF(py_cb); - return ret; - } - - /* Swig implementations for Python */ - static int register_inplace_cb_reply(PyObject* py_cb, - struct module_env* env, int id) - { - return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id); - } - static int register_inplace_cb_reply_cache(PyObject* py_cb, - struct module_env* env, int id) - { - return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id); - } - static int register_inplace_cb_reply_local(PyObject* py_cb, - struct module_env* env, int id) - { - return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id); - } - static int register_inplace_cb_reply_servfail(PyObject* py_cb, - struct module_env* env, int id) - { - return python_inplace_cb_register(inplace_cb_reply_servfail, - py_cb, env, id); - } - - int python_inplace_cb_query_generic( - struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate, - struct sockaddr_storage* addr, socklen_t addrlen, - uint8_t* zone, size_t zonelen, struct regional* region, int id, - void* python_callback) - { - int res = 0; - PyObject *func = python_callback; - PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL; - PyObject *py_qinfo = NULL; - PyObject *py_qstate = NULL; - PyObject *py_addr = NULL; - PyObject *py_zone = NULL; - PyObject *py_region = NULL; - - PyGILState_STATE gstate = PyGILState_Ensure(); - - py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); - py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); - py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0); - py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen); - py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); - if(!(py_qinfo && py_qstate && py_addr && py_zone && py_region)) { - log_err("pythonmod: swig pointer failure in python_inplace_cb_query_generic"); - goto out; - } - py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region); - py_kwargs = Py_BuildValue("{}"); - if(!(py_args && py_kwargs)) { - log_err("pythonmod: BuildValue failure in python_inplace_cb_query_generic"); - goto out; - } - result = PyObject_Call(func, py_args, py_kwargs); - if (result) { - res = PyInt_AsLong(result); - } -out: - Py_XDECREF(py_qinfo); - Py_XDECREF(py_qstate); - Py_XDECREF(py_addr); - Py_XDECREF(py_zone); - Py_XDECREF(py_region); - - Py_XDECREF(py_args); - Py_XDECREF(py_kwargs); - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return res; - } - - static int register_inplace_cb_query(PyObject* py_cb, - struct module_env* env, int id) - { - int ret = inplace_cb_register(python_inplace_cb_query_generic, - inplace_cb_query, (void*) py_cb, env, id); - if (ret) Py_INCREF(py_cb); - return ret; - } - - int python_inplace_cb_query_response(struct module_qstate* qstate, - struct dns_msg* response, int id, void* python_callback) - { - int res = 0; - PyObject *func = python_callback; - PyObject *py_qstate = NULL; - PyObject *py_response = NULL; - PyObject *py_args = NULL; - PyObject *py_kwargs = NULL; - PyObject *result = NULL; - - PyGILState_STATE gstate = PyGILState_Ensure(); - - py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); - py_response = SWIG_NewPointerObj((void*) response, SWIGTYPE_p_dns_msg, 0); - if(!(py_qstate && py_response)) { - log_err("pythonmod: swig pointer failure in python_inplace_cb_query_response"); - goto out; - } - py_args = Py_BuildValue("(OO)", py_qstate, py_response); - py_kwargs = Py_BuildValue("{}"); - if(!(py_args && py_kwargs)) { - log_err("pythonmod: BuildValue failure in python_inplace_cb_query_response"); - goto out; - } - result = PyObject_Call(func, py_args, py_kwargs); - if (result) { - res = PyInt_AsLong(result); - } -out: - Py_XDECREF(py_qstate); - Py_XDECREF(py_response); - - Py_XDECREF(py_args); - Py_XDECREF(py_kwargs); - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return res; - } - - static int register_inplace_cb_query_response(PyObject* py_cb, - struct module_env* env, int id) - { - int ret = inplace_cb_register(python_inplace_cb_query_response, - inplace_cb_query_response, (void*) py_cb, env, id); - if (ret) Py_INCREF(py_cb); - return ret; - } - - int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate, - int id, void* python_callback) - { - int res = 0; - PyObject *func = python_callback; - PyObject *py_qstate = NULL; - PyObject *py_args = NULL; - PyObject *py_kwargs = NULL; - PyObject *result = NULL; - - PyGILState_STATE gstate = PyGILState_Ensure(); - - py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); - if(!py_qstate) { - log_err("pythonmod: swig pointer failure in python_inplace_cb_edns_back_parsed_call"); - goto out; - } - py_args = Py_BuildValue("(O)", py_qstate); - py_kwargs = Py_BuildValue("{}"); - if(!(py_args && py_kwargs)) { - log_err("pythonmod: BuildValue failure in python_inplace_cb_edns_back_parsed_call"); - goto out; - } - result = PyObject_Call(func, py_args, py_kwargs); - if (result) { - res = PyInt_AsLong(result); - } -out: - Py_XDECREF(py_qstate); - - Py_XDECREF(py_args); - Py_XDECREF(py_kwargs); - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return res; - } - - static int register_inplace_cb_edns_back_parsed_call(PyObject* py_cb, - struct module_env* env, int id) - { - int ret = inplace_cb_register(python_inplace_cb_edns_back_parsed_call, - inplace_cb_edns_back_parsed, (void*) py_cb, env, id); - if (ret) Py_INCREF(py_cb); - return ret; - } -%} -/* C declarations */ -int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg, - struct module_env* env, int id); - -/* Swig declarations */ -static int register_inplace_cb_reply(PyObject* py_cb, - struct module_env* env, int id); -static int register_inplace_cb_reply_cache(PyObject* py_cb, - struct module_env* env, int id); -static int register_inplace_cb_reply_local(PyObject* py_cb, - struct module_env* env, int id); -static int register_inplace_cb_reply_servfail(PyObject* py_cb, - struct module_env* env, int id); -static int register_inplace_cb_query(PyObject *py_cb, - struct module_env* env, int id); -static int register_inplace_cb_query_response(PyObject *py_cb, - struct module_env* env, int id); -static int register_inplace_cb_edns_back_parsed_call(PyObject *py_cb, - struct module_env* env, int id); |
