1*be771a7bSCy Schubert /* 2*be771a7bSCy Schubert * interface.i: unbound python module 3*be771a7bSCy Schubert */ 4*be771a7bSCy Schubert %begin %{ 5*be771a7bSCy Schubert /* store state of warning output, restored at later pop */ 6*be771a7bSCy Schubert #pragma GCC diagnostic push 7*be771a7bSCy Schubert /* ignore warnings for pragma below, where for older GCC it can produce a 8*be771a7bSCy Schubert warning if the cast-function-type warning is absent. */ 9*be771a7bSCy Schubert #pragma GCC diagnostic ignored "-Wpragmas" 10*be771a7bSCy Schubert /* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */ 11*be771a7bSCy Schubert #pragma GCC diagnostic ignored "-Wcast-function-type" 12*be771a7bSCy Schubert %} 13*be771a7bSCy Schubert %module unboundmodule 14*be771a7bSCy Schubert %{ 15*be771a7bSCy Schubert /* restore state of warning output, remove the functioncast ignore */ 16*be771a7bSCy Schubert #pragma GCC diagnostic pop 17*be771a7bSCy Schubert /** 18*be771a7bSCy Schubert * \file 19*be771a7bSCy Schubert * This is the interface between the unbound server and a python module 20*be771a7bSCy Schubert * called to perform operations on queries. 21*be771a7bSCy Schubert */ 22*be771a7bSCy Schubert #include <sys/types.h> 23*be771a7bSCy Schubert #include <time.h> 24*be771a7bSCy Schubert #ifdef HAVE_SYS_SOCKET_H 25*be771a7bSCy Schubert #include <sys/socket.h> 26*be771a7bSCy Schubert #endif 27*be771a7bSCy Schubert #ifdef HAVE_NETINET_IN_H 28*be771a7bSCy Schubert #include <netinet/in.h> 29*be771a7bSCy Schubert #endif 30*be771a7bSCy Schubert #ifdef HAVE_ARPA_INET_H 31*be771a7bSCy Schubert #include <arpa/inet.h> 32*be771a7bSCy Schubert #endif 33*be771a7bSCy Schubert #ifdef HAVE_NETDB_H 34*be771a7bSCy Schubert #include <netdb.h> 35*be771a7bSCy Schubert #endif 36*be771a7bSCy Schubert #ifdef HAVE_SYS_UN_H 37*be771a7bSCy Schubert #include <sys/un.h> 38*be771a7bSCy Schubert #endif 39*be771a7bSCy Schubert #include <stdarg.h> 40*be771a7bSCy Schubert #include "config.h" 41*be771a7bSCy Schubert #include "util/log.h" 42*be771a7bSCy Schubert #include "util/module.h" 43*be771a7bSCy Schubert #include "util/netevent.h" 44*be771a7bSCy Schubert #include "util/regional.h" 45*be771a7bSCy Schubert #include "util/config_file.h" 46*be771a7bSCy Schubert #include "util/data/msgreply.h" 47*be771a7bSCy Schubert #include "util/data/packed_rrset.h" 48*be771a7bSCy Schubert #include "util/data/dname.h" 49*be771a7bSCy Schubert #include "util/storage/lruhash.h" 50*be771a7bSCy Schubert #include "services/cache/dns.h" 51*be771a7bSCy Schubert #include "services/mesh.h" 52*be771a7bSCy Schubert #include "iterator/iter_delegpt.h" 53*be771a7bSCy Schubert #include "iterator/iter_hints.h" 54*be771a7bSCy Schubert #include "iterator/iter_utils.h" 55*be771a7bSCy Schubert #include "sldns/wire2str.h" 56*be771a7bSCy Schubert #include "sldns/str2wire.h" 57*be771a7bSCy Schubert #include "sldns/pkthdr.h" 58*be771a7bSCy Schubert %} 59*be771a7bSCy Schubert 60*be771a7bSCy Schubert %include "stdint.i" /* uint_16_t can be known type now */ 61*be771a7bSCy Schubert 62*be771a7bSCy Schubert %inline %{ 63*be771a7bSCy Schubert /* converts [len][data][len][data][0] string to a List of labels (PyBytes) */ 64*be771a7bSCy Schubert PyObject* GetNameAsLabelList(const char* name, int len) { 65*be771a7bSCy Schubert PyObject* list; 66*be771a7bSCy Schubert int cnt=0, i; 67*be771a7bSCy Schubert 68*be771a7bSCy Schubert i = 0; 69*be771a7bSCy Schubert while (i < len) { 70*be771a7bSCy Schubert i += ((unsigned int)name[i]) + 1; 71*be771a7bSCy Schubert cnt++; 72*be771a7bSCy Schubert } 73*be771a7bSCy Schubert 74*be771a7bSCy Schubert list = PyList_New(cnt); 75*be771a7bSCy Schubert i = 0; cnt = 0; 76*be771a7bSCy Schubert while (i < len) { 77*be771a7bSCy Schubert char buf[LDNS_MAX_LABELLEN+1]; 78*be771a7bSCy Schubert if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) && 79*be771a7bSCy Schubert i+(int)((unsigned int)name[i]) < len) { 80*be771a7bSCy Schubert memmove(buf, name + i + 1, (unsigned int)name[i]); 81*be771a7bSCy Schubert buf[(unsigned int)name[i]] = 0; 82*be771a7bSCy Schubert PyList_SetItem(list, cnt, PyString_FromString(buf)); 83*be771a7bSCy Schubert } 84*be771a7bSCy Schubert i += ((unsigned int)name[i]) + 1; 85*be771a7bSCy Schubert cnt++; 86*be771a7bSCy Schubert } 87*be771a7bSCy Schubert return list; 88*be771a7bSCy Schubert } 89*be771a7bSCy Schubert 90*be771a7bSCy Schubert /* converts an array of strings (char**) to a List of strings */ 91*be771a7bSCy Schubert PyObject* CharArrayAsStringList(char** array, int len) { 92*be771a7bSCy Schubert PyObject* list; 93*be771a7bSCy Schubert int i; 94*be771a7bSCy Schubert 95*be771a7bSCy Schubert if(!array||len==0) return PyList_New(0); 96*be771a7bSCy Schubert 97*be771a7bSCy Schubert list = PyList_New(len); 98*be771a7bSCy Schubert for (i=0; i < len; i++) { 99*be771a7bSCy Schubert PyList_SET_ITEM(list, i, PyString_FromString(array[i])); 100*be771a7bSCy Schubert } 101*be771a7bSCy Schubert return list; 102*be771a7bSCy Schubert } 103*be771a7bSCy Schubert %} 104*be771a7bSCy Schubert 105*be771a7bSCy Schubert /* ************************************************************************************ * 106*be771a7bSCy Schubert Structure query_info 107*be771a7bSCy Schubert * ************************************************************************************ */ 108*be771a7bSCy Schubert /* Query info */ 109*be771a7bSCy Schubert %ignore query_info::qname; 110*be771a7bSCy Schubert %ignore query_info::qname_len; 111*be771a7bSCy Schubert 112*be771a7bSCy Schubert 113*be771a7bSCy Schubert struct query_info { 114*be771a7bSCy Schubert %immutable; 115*be771a7bSCy Schubert char* qname; 116*be771a7bSCy Schubert size_t qname_len; 117*be771a7bSCy Schubert uint16_t qtype; 118*be771a7bSCy Schubert uint16_t qclass; 119*be771a7bSCy Schubert %mutable; 120*be771a7bSCy Schubert }; 121*be771a7bSCy Schubert 122*be771a7bSCy Schubert %inline %{ 123*be771a7bSCy Schubert enum enum_rr_class { 124*be771a7bSCy Schubert RR_CLASS_IN = 1, 125*be771a7bSCy Schubert RR_CLASS_CH = 3, 126*be771a7bSCy Schubert RR_CLASS_HS = 4, 127*be771a7bSCy Schubert RR_CLASS_NONE = 254, 128*be771a7bSCy Schubert RR_CLASS_ANY = 255, 129*be771a7bSCy Schubert }; 130*be771a7bSCy Schubert 131*be771a7bSCy Schubert enum enum_rr_type { 132*be771a7bSCy Schubert RR_TYPE_A = 1, 133*be771a7bSCy Schubert RR_TYPE_NS = 2, 134*be771a7bSCy Schubert RR_TYPE_MD = 3, 135*be771a7bSCy Schubert RR_TYPE_MF = 4, 136*be771a7bSCy Schubert RR_TYPE_CNAME = 5, 137*be771a7bSCy Schubert RR_TYPE_SOA = 6, 138*be771a7bSCy Schubert RR_TYPE_MB = 7, 139*be771a7bSCy Schubert RR_TYPE_MG = 8, 140*be771a7bSCy Schubert RR_TYPE_MR = 9, 141*be771a7bSCy Schubert RR_TYPE_NULL = 10, 142*be771a7bSCy Schubert RR_TYPE_WKS = 11, 143*be771a7bSCy Schubert RR_TYPE_PTR = 12, 144*be771a7bSCy Schubert RR_TYPE_HINFO = 13, 145*be771a7bSCy Schubert RR_TYPE_MINFO = 14, 146*be771a7bSCy Schubert RR_TYPE_MX = 15, 147*be771a7bSCy Schubert RR_TYPE_TXT = 16, 148*be771a7bSCy Schubert RR_TYPE_RP = 17, 149*be771a7bSCy Schubert RR_TYPE_AFSDB = 18, 150*be771a7bSCy Schubert RR_TYPE_X25 = 19, 151*be771a7bSCy Schubert RR_TYPE_ISDN = 20, 152*be771a7bSCy Schubert RR_TYPE_RT = 21, 153*be771a7bSCy Schubert RR_TYPE_NSAP = 22, 154*be771a7bSCy Schubert RR_TYPE_NSAP_PTR = 23, 155*be771a7bSCy Schubert RR_TYPE_SIG = 24, 156*be771a7bSCy Schubert RR_TYPE_KEY = 25, 157*be771a7bSCy Schubert RR_TYPE_PX = 26, 158*be771a7bSCy Schubert RR_TYPE_GPOS = 27, 159*be771a7bSCy Schubert RR_TYPE_AAAA = 28, 160*be771a7bSCy Schubert RR_TYPE_LOC = 29, 161*be771a7bSCy Schubert RR_TYPE_NXT = 30, 162*be771a7bSCy Schubert RR_TYPE_EID = 31, 163*be771a7bSCy Schubert RR_TYPE_NIMLOC = 32, 164*be771a7bSCy Schubert RR_TYPE_SRV = 33, 165*be771a7bSCy Schubert RR_TYPE_ATMA = 34, 166*be771a7bSCy Schubert RR_TYPE_NAPTR = 35, 167*be771a7bSCy Schubert RR_TYPE_KX = 36, 168*be771a7bSCy Schubert RR_TYPE_CERT = 37, 169*be771a7bSCy Schubert RR_TYPE_A6 = 38, 170*be771a7bSCy Schubert RR_TYPE_DNAME = 39, 171*be771a7bSCy Schubert RR_TYPE_SINK = 40, 172*be771a7bSCy Schubert RR_TYPE_OPT = 41, 173*be771a7bSCy Schubert RR_TYPE_APL = 42, 174*be771a7bSCy Schubert RR_TYPE_DS = 43, 175*be771a7bSCy Schubert RR_TYPE_SSHFP = 44, 176*be771a7bSCy Schubert RR_TYPE_IPSECKEY = 45, 177*be771a7bSCy Schubert RR_TYPE_RRSIG = 46, 178*be771a7bSCy Schubert RR_TYPE_NSEC = 47, 179*be771a7bSCy Schubert RR_TYPE_DNSKEY = 48, 180*be771a7bSCy Schubert RR_TYPE_DHCID = 49, 181*be771a7bSCy Schubert RR_TYPE_NSEC3 = 50, 182*be771a7bSCy Schubert RR_TYPE_NSEC3PARAMS = 51, 183*be771a7bSCy Schubert RR_TYPE_UINFO = 100, 184*be771a7bSCy Schubert RR_TYPE_UID = 101, 185*be771a7bSCy Schubert RR_TYPE_GID = 102, 186*be771a7bSCy Schubert RR_TYPE_UNSPEC = 103, 187*be771a7bSCy Schubert RR_TYPE_TSIG = 250, 188*be771a7bSCy Schubert RR_TYPE_IXFR = 251, 189*be771a7bSCy Schubert RR_TYPE_AXFR = 252, 190*be771a7bSCy Schubert RR_TYPE_MAILB = 253, 191*be771a7bSCy Schubert RR_TYPE_MAILA = 254, 192*be771a7bSCy Schubert RR_TYPE_ANY = 255, 193*be771a7bSCy Schubert RR_TYPE_DLV = 32769, 194*be771a7bSCy Schubert }; 195*be771a7bSCy Schubert 196*be771a7bSCy Schubert PyObject* _get_qname(struct query_info* q) { 197*be771a7bSCy Schubert return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len); 198*be771a7bSCy Schubert } 199*be771a7bSCy Schubert 200*be771a7bSCy Schubert PyObject* _get_qname_components(struct query_info* q) { 201*be771a7bSCy Schubert return GetNameAsLabelList((const char*)q->qname, q->qname_len); 202*be771a7bSCy Schubert } 203*be771a7bSCy Schubert %} 204*be771a7bSCy Schubert 205*be771a7bSCy Schubert %inline %{ 206*be771a7bSCy Schubert PyObject* dnameAsStr(PyObject* dname) { 207*be771a7bSCy Schubert char buf[LDNS_MAX_DOMAINLEN]; 208*be771a7bSCy Schubert buf[0] = '\0'; 209*be771a7bSCy Schubert dname_str((uint8_t*)PyBytes_AsString(dname), buf); 210*be771a7bSCy Schubert return PyString_FromString(buf); 211*be771a7bSCy Schubert } 212*be771a7bSCy Schubert %} 213*be771a7bSCy Schubert 214*be771a7bSCy Schubert %extend query_info { 215*be771a7bSCy Schubert %pythoncode %{ 216*be771a7bSCy Schubert def _get_qtype_str(self): return sldns_wire2str_type(self.qtype) 217*be771a7bSCy Schubert qtype_str = property(_get_qtype_str) 218*be771a7bSCy Schubert 219*be771a7bSCy Schubert def _get_qclass_str(self): return sldns_wire2str_class(self.qclass) 220*be771a7bSCy Schubert qclass_str = property(_get_qclass_str) 221*be771a7bSCy Schubert 222*be771a7bSCy Schubert qname = property(_unboundmodule._get_qname) 223*be771a7bSCy Schubert 224*be771a7bSCy Schubert qname_list = property(_unboundmodule._get_qname_components) 225*be771a7bSCy Schubert 226*be771a7bSCy Schubert def _get_qname_str(self): return dnameAsStr(self.qname) 227*be771a7bSCy Schubert qname_str = property(_get_qname_str) 228*be771a7bSCy Schubert %} 229*be771a7bSCy Schubert } 230*be771a7bSCy Schubert 231*be771a7bSCy Schubert /* ************************************************************************************ * 232*be771a7bSCy Schubert Structure packed_rrset_key 233*be771a7bSCy Schubert * ************************************************************************************ */ 234*be771a7bSCy Schubert %ignore packed_rrset_key::dname; 235*be771a7bSCy Schubert %ignore packed_rrset_key::dname_len; 236*be771a7bSCy Schubert 237*be771a7bSCy Schubert /* RRsets */ 238*be771a7bSCy Schubert struct packed_rrset_key { 239*be771a7bSCy Schubert %immutable; 240*be771a7bSCy Schubert char* dname; 241*be771a7bSCy Schubert size_t dname_len; 242*be771a7bSCy Schubert uint32_t flags; 243*be771a7bSCy Schubert uint16_t type; /* rrset type in network format */ 244*be771a7bSCy Schubert uint16_t rrset_class; /* rrset class in network format */ 245*be771a7bSCy Schubert %mutable; 246*be771a7bSCy Schubert }; 247*be771a7bSCy Schubert 248*be771a7bSCy Schubert /** 249*be771a7bSCy Schubert * This subroutine converts values between the host and network byte order. 250*be771a7bSCy Schubert * Specifically, ntohs() converts 16-bit quantities from network byte order to 251*be771a7bSCy Schubert * host byte order. 252*be771a7bSCy Schubert */ 253*be771a7bSCy Schubert uint16_t ntohs(uint16_t netshort); 254*be771a7bSCy Schubert 255*be771a7bSCy Schubert %inline %{ 256*be771a7bSCy Schubert PyObject* _get_dname(struct packed_rrset_key* k) { 257*be771a7bSCy Schubert return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len); 258*be771a7bSCy Schubert } 259*be771a7bSCy Schubert PyObject* _get_dname_components(struct packed_rrset_key* k) { 260*be771a7bSCy Schubert return GetNameAsLabelList((char*)k->dname, k->dname_len); 261*be771a7bSCy Schubert } 262*be771a7bSCy Schubert %} 263*be771a7bSCy Schubert 264*be771a7bSCy Schubert %extend packed_rrset_key { 265*be771a7bSCy Schubert %pythoncode %{ 266*be771a7bSCy Schubert def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type)) 267*be771a7bSCy Schubert type_str = property(_get_type_str) 268*be771a7bSCy Schubert 269*be771a7bSCy Schubert def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class)) 270*be771a7bSCy Schubert rrset_class_str = property(_get_class_str) 271*be771a7bSCy Schubert 272*be771a7bSCy Schubert dname = property(_unboundmodule._get_dname) 273*be771a7bSCy Schubert 274*be771a7bSCy Schubert dname_list = property(_unboundmodule._get_dname_components) 275*be771a7bSCy Schubert 276*be771a7bSCy Schubert def _get_dname_str(self): return dnameAsStr(self.dname) 277*be771a7bSCy Schubert dname_str = property(_get_dname_str) 278*be771a7bSCy Schubert %} 279*be771a7bSCy Schubert } 280*be771a7bSCy Schubert 281*be771a7bSCy Schubert #if defined(SWIGWORDSIZE64) 282*be771a7bSCy Schubert typedef long int rrset_id_type; 283*be771a7bSCy Schubert #else 284*be771a7bSCy Schubert typedef long long int rrset_id_type; 285*be771a7bSCy Schubert #endif 286*be771a7bSCy Schubert 287*be771a7bSCy Schubert struct ub_packed_rrset_key { 288*be771a7bSCy Schubert struct lruhash_entry entry; 289*be771a7bSCy Schubert rrset_id_type id; 290*be771a7bSCy Schubert struct packed_rrset_key rk; 291*be771a7bSCy Schubert }; 292*be771a7bSCy Schubert 293*be771a7bSCy Schubert struct lruhash_entry { 294*be771a7bSCy Schubert lock_rw_type lock; 295*be771a7bSCy Schubert struct lruhash_entry* overflow_next; 296*be771a7bSCy Schubert struct lruhash_entry* lru_next; 297*be771a7bSCy Schubert struct lruhash_entry* lru_prev; 298*be771a7bSCy Schubert hashvalue_type hash; 299*be771a7bSCy Schubert void* key; 300*be771a7bSCy Schubert struct packed_rrset_data* data; 301*be771a7bSCy Schubert }; 302*be771a7bSCy Schubert 303*be771a7bSCy Schubert %ignore packed_rrset_data::rr_len; 304*be771a7bSCy Schubert %ignore packed_rrset_data::rr_ttl; 305*be771a7bSCy Schubert %ignore packed_rrset_data::rr_data; 306*be771a7bSCy Schubert 307*be771a7bSCy Schubert struct packed_rrset_data { 308*be771a7bSCy Schubert /* TTL (in seconds like time()) */ 309*be771a7bSCy Schubert uint32_t ttl; 310*be771a7bSCy Schubert 311*be771a7bSCy Schubert /* number of rrs */ 312*be771a7bSCy Schubert size_t count; 313*be771a7bSCy Schubert /* number of rrsigs */ 314*be771a7bSCy Schubert size_t rrsig_count; 315*be771a7bSCy Schubert 316*be771a7bSCy Schubert enum rrset_trust trust; 317*be771a7bSCy Schubert enum sec_status security; 318*be771a7bSCy Schubert 319*be771a7bSCy Schubert /* length of every rr's rdata */ 320*be771a7bSCy Schubert size_t* rr_len; 321*be771a7bSCy Schubert /* ttl of every rr */ 322*be771a7bSCy Schubert uint32_t *rr_ttl; 323*be771a7bSCy Schubert /* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in 324*be771a7bSCy Schubert * uncompressed wireformat. */ 325*be771a7bSCy Schubert uint8_t** rr_data; 326*be771a7bSCy Schubert }; 327*be771a7bSCy Schubert 328*be771a7bSCy Schubert %pythoncode %{ 329*be771a7bSCy Schubert class RRSetData_RRLen: 330*be771a7bSCy Schubert def __init__(self, obj): self.obj = obj 331*be771a7bSCy Schubert def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index) 332*be771a7bSCy Schubert def __len__(self): return self.obj.count + self.obj.rrsig_count 333*be771a7bSCy Schubert class RRSetData_RRTTL: 334*be771a7bSCy Schubert def __init__(self, obj): self.obj = obj 335*be771a7bSCy Schubert def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index) 336*be771a7bSCy Schubert def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value) 337*be771a7bSCy Schubert def __len__(self): return self.obj.count + self.obj.rrsig_count 338*be771a7bSCy Schubert class RRSetData_RRData: 339*be771a7bSCy Schubert def __init__(self, obj): self.obj = obj 340*be771a7bSCy Schubert def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index) 341*be771a7bSCy Schubert def __len__(self): return self.obj.count + self.obj.rrsig_count 342*be771a7bSCy Schubert %} 343*be771a7bSCy Schubert 344*be771a7bSCy Schubert %inline %{ 345*be771a7bSCy Schubert PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) { 346*be771a7bSCy Schubert if ((d != NULL) && (idx >= 0) && 347*be771a7bSCy Schubert ((size_t)idx < (d->count+d->rrsig_count))) 348*be771a7bSCy Schubert return PyInt_FromLong(d->rr_len[idx]); 349*be771a7bSCy Schubert return Py_None; 350*be771a7bSCy Schubert } 351*be771a7bSCy Schubert void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl) 352*be771a7bSCy Schubert { 353*be771a7bSCy Schubert if ((d != NULL) && (idx >= 0) && 354*be771a7bSCy Schubert ((size_t)idx < (d->count+d->rrsig_count))) 355*be771a7bSCy Schubert d->rr_ttl[idx] = ttl; 356*be771a7bSCy Schubert } 357*be771a7bSCy Schubert PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) { 358*be771a7bSCy Schubert if ((d != NULL) && (idx >= 0) && 359*be771a7bSCy Schubert ((size_t)idx < (d->count+d->rrsig_count))) 360*be771a7bSCy Schubert return PyInt_FromLong(d->rr_ttl[idx]); 361*be771a7bSCy Schubert return Py_None; 362*be771a7bSCy Schubert } 363*be771a7bSCy Schubert PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) { 364*be771a7bSCy Schubert if ((d != NULL) && (idx >= 0) && 365*be771a7bSCy Schubert ((size_t)idx < (d->count+d->rrsig_count))) 366*be771a7bSCy Schubert return PyBytes_FromStringAndSize((char*)d->rr_data[idx], 367*be771a7bSCy Schubert d->rr_len[idx]); 368*be771a7bSCy Schubert return Py_None; 369*be771a7bSCy Schubert } 370*be771a7bSCy Schubert %} 371*be771a7bSCy Schubert 372*be771a7bSCy Schubert %extend packed_rrset_data { 373*be771a7bSCy Schubert %pythoncode %{ 374*be771a7bSCy Schubert def _get_data_rr_len(self): return RRSetData_RRLen(self) 375*be771a7bSCy Schubert rr_len = property(_get_data_rr_len) 376*be771a7bSCy Schubert def _get_data_rr_ttl(self): return RRSetData_RRTTL(self) 377*be771a7bSCy Schubert rr_ttl = property(_get_data_rr_ttl) 378*be771a7bSCy Schubert def _get_data_rr_data(self): return RRSetData_RRData(self) 379*be771a7bSCy Schubert rr_data = property(_get_data_rr_data) 380*be771a7bSCy Schubert %} 381*be771a7bSCy Schubert } 382*be771a7bSCy Schubert 383*be771a7bSCy Schubert /* ************************************************************************************ * 384*be771a7bSCy Schubert Structure reply_info 385*be771a7bSCy Schubert * ************************************************************************************ */ 386*be771a7bSCy Schubert /* Messages */ 387*be771a7bSCy Schubert %ignore reply_info::rrsets; 388*be771a7bSCy Schubert %ignore reply_info::ref; 389*be771a7bSCy Schubert 390*be771a7bSCy Schubert struct reply_info { 391*be771a7bSCy Schubert uint16_t flags; 392*be771a7bSCy Schubert uint16_t qdcount; 393*be771a7bSCy Schubert uint32_t ttl; 394*be771a7bSCy Schubert uint32_t prefetch_ttl; 395*be771a7bSCy Schubert 396*be771a7bSCy Schubert uint16_t authoritative; 397*be771a7bSCy Schubert enum sec_status security; 398*be771a7bSCy Schubert 399*be771a7bSCy Schubert size_t an_numrrsets; 400*be771a7bSCy Schubert size_t ns_numrrsets; 401*be771a7bSCy Schubert size_t ar_numrrsets; 402*be771a7bSCy Schubert size_t rrset_count; /* an_numrrsets + ns_numrrsets + ar_numrrsets */ 403*be771a7bSCy Schubert 404*be771a7bSCy Schubert struct ub_packed_rrset_key** rrsets; 405*be771a7bSCy Schubert struct rrset_ref ref[1]; /* ? */ 406*be771a7bSCy Schubert }; 407*be771a7bSCy Schubert 408*be771a7bSCy Schubert struct rrset_ref { 409*be771a7bSCy Schubert struct ub_packed_rrset_key* key; 410*be771a7bSCy Schubert rrset_id_type id; 411*be771a7bSCy Schubert }; 412*be771a7bSCy Schubert 413*be771a7bSCy Schubert struct dns_msg { 414*be771a7bSCy Schubert struct query_info qinfo; 415*be771a7bSCy Schubert struct reply_info *rep; 416*be771a7bSCy Schubert }; 417*be771a7bSCy Schubert 418*be771a7bSCy Schubert %pythoncode %{ 419*be771a7bSCy Schubert class ReplyInfo_RRSet: 420*be771a7bSCy Schubert def __init__(self, obj): self.obj = obj 421*be771a7bSCy Schubert def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index) 422*be771a7bSCy Schubert def __len__(self): return self.obj.rrset_count 423*be771a7bSCy Schubert 424*be771a7bSCy Schubert class ReplyInfo_Ref: 425*be771a7bSCy Schubert def __init__(self, obj): self.obj = obj 426*be771a7bSCy Schubert def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index) 427*be771a7bSCy Schubert def __len__(self): return self.obj.rrset_count 428*be771a7bSCy Schubert %} 429*be771a7bSCy Schubert 430*be771a7bSCy Schubert %inline %{ 431*be771a7bSCy Schubert struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) { 432*be771a7bSCy Schubert if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) 433*be771a7bSCy Schubert return r->rrsets[idx]; 434*be771a7bSCy Schubert return NULL; 435*be771a7bSCy Schubert } 436*be771a7bSCy Schubert 437*be771a7bSCy Schubert struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) { 438*be771a7bSCy Schubert if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) { 439*be771a7bSCy Schubert /* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */ 440*be771a7bSCy Schubert return &(r->ref[idx]); 441*be771a7bSCy Schubert /* return &(r->ref[idx]); */ 442*be771a7bSCy Schubert } 443*be771a7bSCy Schubert /* printf("_rrset_ref_get: NULL\n"); */ 444*be771a7bSCy Schubert return NULL; 445*be771a7bSCy Schubert } 446*be771a7bSCy Schubert %} 447*be771a7bSCy Schubert 448*be771a7bSCy Schubert %extend reply_info { 449*be771a7bSCy Schubert %pythoncode %{ 450*be771a7bSCy Schubert def _rrset_ref_get(self): return ReplyInfo_Ref(self) 451*be771a7bSCy Schubert ref = property(_rrset_ref_get) 452*be771a7bSCy Schubert 453*be771a7bSCy Schubert def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self) 454*be771a7bSCy Schubert rrsets = property(_rrset_rrsets_get) 455*be771a7bSCy Schubert %} 456*be771a7bSCy Schubert } 457*be771a7bSCy Schubert 458*be771a7bSCy Schubert /* ************************************************************************************ * 459*be771a7bSCy Schubert Structure sockaddr_storage 460*be771a7bSCy Schubert * ************************************************************************************ */ 461*be771a7bSCy Schubert 462*be771a7bSCy Schubert struct sockaddr_storage {}; 463*be771a7bSCy Schubert 464*be771a7bSCy Schubert %inline %{ 465*be771a7bSCy Schubert static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) { 466*be771a7bSCy Schubert if (ss == NULL) { 467*be771a7bSCy Schubert return 0; 468*be771a7bSCy Schubert } 469*be771a7bSCy Schubert 470*be771a7bSCy Schubert switch (ss->ss_family) { 471*be771a7bSCy Schubert case AF_INET: return sizeof(struct sockaddr_in); 472*be771a7bSCy Schubert case AF_INET6: return sizeof(struct sockaddr_in6); 473*be771a7bSCy Schubert #ifdef HAVE_SYS_UN_H 474*be771a7bSCy Schubert case AF_UNIX: return sizeof(struct sockaddr_un); 475*be771a7bSCy Schubert #endif 476*be771a7bSCy Schubert default: 477*be771a7bSCy Schubert return 0; 478*be771a7bSCy Schubert } 479*be771a7bSCy Schubert } 480*be771a7bSCy Schubert 481*be771a7bSCy Schubert PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) { 482*be771a7bSCy Schubert if (ss == NULL) { 483*be771a7bSCy Schubert return Py_None; 484*be771a7bSCy Schubert } 485*be771a7bSCy Schubert 486*be771a7bSCy Schubert switch (ss->ss_family) { 487*be771a7bSCy Schubert case AF_INET: return PyUnicode_FromString("ip4"); 488*be771a7bSCy Schubert case AF_INET6: return PyUnicode_FromString("ip6"); 489*be771a7bSCy Schubert case AF_UNIX: return PyUnicode_FromString("unix"); 490*be771a7bSCy Schubert default: 491*be771a7bSCy Schubert return Py_None; 492*be771a7bSCy Schubert } 493*be771a7bSCy Schubert } 494*be771a7bSCy Schubert 495*be771a7bSCy Schubert PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) { 496*be771a7bSCy Schubert const struct sockaddr *sa; 497*be771a7bSCy Schubert size_t sa_len; 498*be771a7bSCy Schubert char name[NI_MAXHOST] = {0}; 499*be771a7bSCy Schubert 500*be771a7bSCy Schubert if (ss == NULL) { 501*be771a7bSCy Schubert return Py_None; 502*be771a7bSCy Schubert } 503*be771a7bSCy Schubert 504*be771a7bSCy Schubert sa = (struct sockaddr *)ss; 505*be771a7bSCy Schubert sa_len = _sockaddr_storage_len(ss); 506*be771a7bSCy Schubert if (sa_len == 0) { 507*be771a7bSCy Schubert return Py_None; 508*be771a7bSCy Schubert } 509*be771a7bSCy Schubert 510*be771a7bSCy Schubert if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) { 511*be771a7bSCy Schubert return Py_None; 512*be771a7bSCy Schubert } 513*be771a7bSCy Schubert 514*be771a7bSCy Schubert return PyUnicode_FromString(name); 515*be771a7bSCy Schubert } 516*be771a7bSCy Schubert 517*be771a7bSCy Schubert PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) { 518*be771a7bSCy Schubert size_t sa_len; 519*be771a7bSCy Schubert 520*be771a7bSCy Schubert if (ss == NULL) { 521*be771a7bSCy Schubert return Py_None; 522*be771a7bSCy Schubert } 523*be771a7bSCy Schubert 524*be771a7bSCy Schubert sa_len = _sockaddr_storage_len(ss); 525*be771a7bSCy Schubert if (sa_len == 0) { 526*be771a7bSCy Schubert return Py_None; 527*be771a7bSCy Schubert } 528*be771a7bSCy Schubert 529*be771a7bSCy Schubert if (ss->ss_family == AF_INET) { 530*be771a7bSCy Schubert const struct sockaddr_in *sa = (struct sockaddr_in *)ss; 531*be771a7bSCy Schubert const struct in_addr *raw = (struct in_addr *)&sa->sin_addr; 532*be771a7bSCy Schubert return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw)); 533*be771a7bSCy Schubert } 534*be771a7bSCy Schubert 535*be771a7bSCy Schubert if (ss->ss_family == AF_INET6) { 536*be771a7bSCy Schubert const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss; 537*be771a7bSCy Schubert const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr; 538*be771a7bSCy Schubert return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw)); 539*be771a7bSCy Schubert } 540*be771a7bSCy Schubert 541*be771a7bSCy Schubert #ifdef HAVE_SYS_UN_H 542*be771a7bSCy Schubert if (ss->ss_family == AF_UNIX) { 543*be771a7bSCy Schubert const struct sockaddr_un *sa = (struct sockaddr_un *)ss; 544*be771a7bSCy Schubert return PyBytes_FromString(sa->sun_path); 545*be771a7bSCy Schubert } 546*be771a7bSCy Schubert #endif 547*be771a7bSCy Schubert 548*be771a7bSCy Schubert return Py_None; 549*be771a7bSCy Schubert } 550*be771a7bSCy Schubert 551*be771a7bSCy Schubert PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) { 552*be771a7bSCy Schubert if (ss == NULL) { 553*be771a7bSCy Schubert return Py_None; 554*be771a7bSCy Schubert } 555*be771a7bSCy Schubert 556*be771a7bSCy Schubert if (ss->ss_family == AF_INET) { 557*be771a7bSCy Schubert const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss; 558*be771a7bSCy Schubert return PyInt_FromLong(ntohs(sa4->sin_port)); 559*be771a7bSCy Schubert } 560*be771a7bSCy Schubert 561*be771a7bSCy Schubert if (ss->ss_family == AF_INET6) { 562*be771a7bSCy Schubert const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss; 563*be771a7bSCy Schubert return PyInt_FromLong(ntohs(sa6->sin6_port)); 564*be771a7bSCy Schubert } 565*be771a7bSCy Schubert 566*be771a7bSCy Schubert return Py_None; 567*be771a7bSCy Schubert } 568*be771a7bSCy Schubert 569*be771a7bSCy Schubert PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) { 570*be771a7bSCy Schubert const struct sockaddr_in6 *sa6; 571*be771a7bSCy Schubert 572*be771a7bSCy Schubert if (ss == NULL || ss->ss_family != AF_INET6) { 573*be771a7bSCy Schubert return Py_None; 574*be771a7bSCy Schubert } 575*be771a7bSCy Schubert 576*be771a7bSCy Schubert sa6 = (struct sockaddr_in6 *)ss; 577*be771a7bSCy Schubert return PyInt_FromLong(ntohl(sa6->sin6_flowinfo)); 578*be771a7bSCy Schubert } 579*be771a7bSCy Schubert 580*be771a7bSCy Schubert PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) { 581*be771a7bSCy Schubert const struct sockaddr_in6 *sa6; 582*be771a7bSCy Schubert 583*be771a7bSCy Schubert if (ss == NULL || ss->ss_family != AF_INET6) { 584*be771a7bSCy Schubert return Py_None; 585*be771a7bSCy Schubert } 586*be771a7bSCy Schubert 587*be771a7bSCy Schubert sa6 = (struct sockaddr_in6 *)ss; 588*be771a7bSCy Schubert return PyInt_FromLong(ntohl(sa6->sin6_scope_id)); 589*be771a7bSCy Schubert } 590*be771a7bSCy Schubert %} 591*be771a7bSCy Schubert 592*be771a7bSCy Schubert %extend sockaddr_storage { 593*be771a7bSCy Schubert %pythoncode %{ 594*be771a7bSCy Schubert def _family_get(self): return _sockaddr_storage_family(self) 595*be771a7bSCy Schubert family = property(_family_get) 596*be771a7bSCy Schubert 597*be771a7bSCy Schubert def _addr_get(self): return _sockaddr_storage_addr(self) 598*be771a7bSCy Schubert addr = property(_addr_get) 599*be771a7bSCy Schubert 600*be771a7bSCy Schubert def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self) 601*be771a7bSCy Schubert raw_addr = property(_raw_addr_get) 602*be771a7bSCy Schubert 603*be771a7bSCy Schubert def _port_get(self): return _sockaddr_storage_port(self) 604*be771a7bSCy Schubert port = property(_port_get) 605*be771a7bSCy Schubert 606*be771a7bSCy Schubert def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self) 607*be771a7bSCy Schubert flowinfo = property(_flowinfo_get) 608*be771a7bSCy Schubert 609*be771a7bSCy Schubert def _scope_id_get(self): return _sockaddr_storage_scope_id(self) 610*be771a7bSCy Schubert scope_id = property(_scope_id_get) 611*be771a7bSCy Schubert %} 612*be771a7bSCy Schubert } 613*be771a7bSCy Schubert 614*be771a7bSCy Schubert /* ************************************************************************************ * 615*be771a7bSCy Schubert Structure mesh_state 616*be771a7bSCy Schubert * ************************************************************************************ */ 617*be771a7bSCy Schubert struct mesh_state { 618*be771a7bSCy Schubert struct mesh_reply* reply_list; 619*be771a7bSCy Schubert }; 620*be771a7bSCy Schubert 621*be771a7bSCy Schubert struct mesh_reply { 622*be771a7bSCy Schubert struct mesh_reply* next; 623*be771a7bSCy Schubert struct comm_reply query_reply; 624*be771a7bSCy Schubert }; 625*be771a7bSCy Schubert 626*be771a7bSCy Schubert %rename(_addr) comm_reply::client_addr; 627*be771a7bSCy Schubert struct comm_reply { 628*be771a7bSCy Schubert struct sockaddr_storage client_addr; 629*be771a7bSCy Schubert }; 630*be771a7bSCy Schubert 631*be771a7bSCy Schubert %extend comm_reply { 632*be771a7bSCy Schubert %pythoncode %{ 633*be771a7bSCy Schubert def _addr_get(self): return _sockaddr_storage_addr(self._addr) 634*be771a7bSCy Schubert addr = property(_addr_get) 635*be771a7bSCy Schubert 636*be771a7bSCy Schubert def _port_get(self): return _sockaddr_storage_port(self._addr) 637*be771a7bSCy Schubert port = property(_port_get) 638*be771a7bSCy Schubert 639*be771a7bSCy Schubert def _family_get(self): return _sockaddr_storage_family(self._addr) 640*be771a7bSCy Schubert family = property(_family_get) 641*be771a7bSCy Schubert %} 642*be771a7bSCy Schubert } 643*be771a7bSCy Schubert 644*be771a7bSCy Schubert /* ************************************************************************************ * 645*be771a7bSCy Schubert Structure edns_option 646*be771a7bSCy Schubert * ************************************************************************************ */ 647*be771a7bSCy Schubert /* Rename the members to follow the python convention of marking them as 648*be771a7bSCy Schubert * private. Access to the opt_code and opt_data members is given by the later 649*be771a7bSCy Schubert * python defined code and data members respectively. */ 650*be771a7bSCy Schubert %rename(_next) edns_option::next; 651*be771a7bSCy Schubert %rename(_opt_code) edns_option::opt_code; 652*be771a7bSCy Schubert %rename(_opt_len) edns_option::opt_len; 653*be771a7bSCy Schubert %rename(_opt_data) edns_option::opt_data; 654*be771a7bSCy Schubert struct edns_option { 655*be771a7bSCy Schubert struct edns_option* next; 656*be771a7bSCy Schubert uint16_t opt_code; 657*be771a7bSCy Schubert size_t opt_len; 658*be771a7bSCy Schubert uint8_t* opt_data; 659*be771a7bSCy Schubert }; 660*be771a7bSCy Schubert 661*be771a7bSCy Schubert %inline %{ 662*be771a7bSCy Schubert PyObject* _edns_option_opt_code_get(struct edns_option* option) { 663*be771a7bSCy Schubert uint16_t opt_code = option->opt_code; 664*be771a7bSCy Schubert return PyInt_FromLong(opt_code); 665*be771a7bSCy Schubert } 666*be771a7bSCy Schubert 667*be771a7bSCy Schubert PyObject* _edns_option_opt_data_get(struct edns_option* option) { 668*be771a7bSCy Schubert return PyByteArray_FromStringAndSize((void*)option->opt_data, 669*be771a7bSCy Schubert option->opt_len); 670*be771a7bSCy Schubert } 671*be771a7bSCy Schubert %} 672*be771a7bSCy Schubert %extend edns_option { 673*be771a7bSCy Schubert %pythoncode %{ 674*be771a7bSCy Schubert def _opt_code_get(self): return _edns_option_opt_code_get(self) 675*be771a7bSCy Schubert code = property(_opt_code_get) 676*be771a7bSCy Schubert 677*be771a7bSCy Schubert def _opt_data_get(self): return _edns_option_opt_data_get(self) 678*be771a7bSCy Schubert data = property(_opt_data_get) 679*be771a7bSCy Schubert %} 680*be771a7bSCy Schubert } 681*be771a7bSCy Schubert 682*be771a7bSCy Schubert /* ************************************************************************************ * 683*be771a7bSCy Schubert Structure edns_data 684*be771a7bSCy Schubert * ************************************************************************************ */ 685*be771a7bSCy Schubert /* This is ignored because we will pass a double pointer of this to Python 686*be771a7bSCy Schubert * with custom getmethods. This is done to bypass Swig's behavior to pass NULL 687*be771a7bSCy Schubert * pointers as None. */ 688*be771a7bSCy Schubert %ignore edns_data::opt_list; 689*be771a7bSCy Schubert struct edns_data { 690*be771a7bSCy Schubert int edns_present; 691*be771a7bSCy Schubert uint8_t ext_rcode; 692*be771a7bSCy Schubert uint8_t edns_version; 693*be771a7bSCy Schubert uint16_t bits; 694*be771a7bSCy Schubert uint16_t udp_size; 695*be771a7bSCy Schubert struct edns_option* opt_list_in; 696*be771a7bSCy Schubert struct edns_option* opt_list_out; 697*be771a7bSCy Schubert struct edns_option* opt_list_inplace_cb_out; 698*be771a7bSCy Schubert uint16_t padding_block_size; 699*be771a7bSCy Schubert }; 700*be771a7bSCy Schubert %inline %{ 701*be771a7bSCy Schubert struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) { 702*be771a7bSCy Schubert return &edns->opt_list_in; 703*be771a7bSCy Schubert } 704*be771a7bSCy Schubert %} 705*be771a7bSCy Schubert %extend edns_data { 706*be771a7bSCy Schubert %pythoncode %{ 707*be771a7bSCy Schubert def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list) 708*be771a7bSCy Schubert opt_list_iter = property(_opt_list_iter) 709*be771a7bSCy Schubert def _opt_list(self): return _edns_data_opt_list_get(self) 710*be771a7bSCy Schubert opt_list = property(_opt_list) 711*be771a7bSCy Schubert %} 712*be771a7bSCy Schubert } 713*be771a7bSCy Schubert 714*be771a7bSCy Schubert /* ************************************************************************************ * 715*be771a7bSCy Schubert Structure module_env 716*be771a7bSCy Schubert * ************************************************************************************ */ 717*be771a7bSCy Schubert %rename(_now) module_env::now; 718*be771a7bSCy Schubert %rename(_now_tv) module_env::now_tv; 719*be771a7bSCy Schubert struct module_env { 720*be771a7bSCy Schubert struct config_file* cfg; 721*be771a7bSCy Schubert struct slabhash* msg_cache; 722*be771a7bSCy Schubert struct rrset_cache* rrset_cache; 723*be771a7bSCy Schubert struct infra_cache* infra_cache; 724*be771a7bSCy Schubert struct key_cache* key_cache; 725*be771a7bSCy Schubert 726*be771a7bSCy Schubert /* --- services --- */ 727*be771a7bSCy Schubert struct outbound_entry* (*send_query)(struct query_info* qinfo, 728*be771a7bSCy Schubert uint16_t flags, int dnssec, int want_dnssec, int nocaps, 729*be771a7bSCy Schubert int check_ratelimit, 730*be771a7bSCy Schubert struct sockaddr_storage* addr, socklen_t addrlen, 731*be771a7bSCy Schubert uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, 732*be771a7bSCy Schubert char* tls_auth_name, struct module_qstate* q, int* was_ratelimited); 733*be771a7bSCy Schubert void (*detach_subs)(struct module_qstate* qstate); 734*be771a7bSCy Schubert int (*attach_sub)(struct module_qstate* qstate, 735*be771a7bSCy Schubert struct query_info* qinfo, uint16_t qflags, int prime, 736*be771a7bSCy Schubert int valrec, struct module_qstate** newq); 737*be771a7bSCy Schubert void (*kill_sub)(struct module_qstate* newq); 738*be771a7bSCy Schubert int (*detect_cycle)(struct module_qstate* qstate, 739*be771a7bSCy Schubert struct query_info* qinfo, uint16_t flags, int prime, 740*be771a7bSCy Schubert int valrec); 741*be771a7bSCy Schubert 742*be771a7bSCy Schubert struct regional* scratch; 743*be771a7bSCy Schubert struct sldns_buffer* scratch_buffer; 744*be771a7bSCy Schubert struct worker* worker; 745*be771a7bSCy Schubert struct mesh_area* mesh; 746*be771a7bSCy Schubert struct alloc_cache* alloc; 747*be771a7bSCy Schubert struct ub_randstate* rnd; 748*be771a7bSCy Schubert time_t* now; 749*be771a7bSCy Schubert struct timeval* now_tv; 750*be771a7bSCy Schubert int need_to_validate; 751*be771a7bSCy Schubert struct val_anchors* anchors; 752*be771a7bSCy Schubert struct val_neg_cache* neg_cache; 753*be771a7bSCy Schubert struct comm_timer* probe_timer; 754*be771a7bSCy Schubert struct iter_forwards* fwds; 755*be771a7bSCy Schubert struct iter_hints* hints; 756*be771a7bSCy Schubert void* modinfo[MAX_MODULE]; 757*be771a7bSCy Schubert 758*be771a7bSCy Schubert void* inplace_cb_lists[inplace_cb_types_total]; 759*be771a7bSCy Schubert struct edns_known_option* edns_known_options; 760*be771a7bSCy Schubert size_t edns_known_options_num; 761*be771a7bSCy Schubert }; 762*be771a7bSCy Schubert 763*be771a7bSCy Schubert %inline %{ 764*be771a7bSCy Schubert PyObject* _module_env_now_get(struct module_env* env) { 765*be771a7bSCy Schubert double ts = env->now_tv->tv_sec + env->now_tv->tv_usec / 1e6; 766*be771a7bSCy Schubert return PyFloat_FromDouble(ts); 767*be771a7bSCy Schubert } 768*be771a7bSCy Schubert %} 769*be771a7bSCy Schubert %extend module_env { 770*be771a7bSCy Schubert %pythoncode %{ 771*be771a7bSCy Schubert def _now_get(self): return _module_env_now_get(self) 772*be771a7bSCy Schubert now = property(_now_get) 773*be771a7bSCy Schubert %} 774*be771a7bSCy Schubert } 775*be771a7bSCy Schubert 776*be771a7bSCy Schubert /* ************************************************************************************ * 777*be771a7bSCy Schubert Structure module_qstate 778*be771a7bSCy Schubert * ************************************************************************************ */ 779*be771a7bSCy Schubert %ignore module_qstate::ext_state; 780*be771a7bSCy Schubert %ignore module_qstate::minfo; 781*be771a7bSCy Schubert 782*be771a7bSCy Schubert /* These are ignored because we will pass a double pointer of them to Python 783*be771a7bSCy Schubert * with custom getmethods. This is done to bypass Swig's behavior to pass NULL 784*be771a7bSCy Schubert * pointers as None. */ 785*be771a7bSCy Schubert %ignore module_qstate::edns_opts_front_in; 786*be771a7bSCy Schubert %ignore module_qstate::edns_opts_back_out; 787*be771a7bSCy Schubert %ignore module_qstate::edns_opts_back_in; 788*be771a7bSCy Schubert %ignore module_qstate::edns_opts_front_out; 789*be771a7bSCy Schubert 790*be771a7bSCy Schubert /* Query state */ 791*be771a7bSCy Schubert struct module_qstate { 792*be771a7bSCy Schubert struct query_info qinfo; 793*be771a7bSCy Schubert uint16_t query_flags; /* See QF_BIT_xx constants */ 794*be771a7bSCy Schubert int is_priming; 795*be771a7bSCy Schubert int is_valrec; 796*be771a7bSCy Schubert 797*be771a7bSCy Schubert struct comm_reply* reply; 798*be771a7bSCy Schubert struct dns_msg* return_msg; 799*be771a7bSCy Schubert int return_rcode; 800*be771a7bSCy Schubert struct regional* region; /* unwrapped */ 801*be771a7bSCy Schubert 802*be771a7bSCy Schubert int curmod; 803*be771a7bSCy Schubert 804*be771a7bSCy Schubert enum module_ext_state ext_state[MAX_MODULE]; 805*be771a7bSCy Schubert void* minfo[MAX_MODULE]; 806*be771a7bSCy Schubert time_t prefetch_leeway; 807*be771a7bSCy Schubert 808*be771a7bSCy Schubert struct module_env* env; /* unwrapped */ 809*be771a7bSCy Schubert struct mesh_state* mesh_info; 810*be771a7bSCy Schubert 811*be771a7bSCy Schubert struct edns_option* edns_opts_front_in; 812*be771a7bSCy Schubert struct edns_option* edns_opts_back_out; 813*be771a7bSCy Schubert struct edns_option* edns_opts_back_in; 814*be771a7bSCy Schubert struct edns_option* edns_opts_front_out; 815*be771a7bSCy Schubert int no_cache_lookup; 816*be771a7bSCy Schubert int no_cache_store; 817*be771a7bSCy Schubert }; 818*be771a7bSCy Schubert 819*be771a7bSCy Schubert %constant int MODULE_COUNT = MAX_MODULE; 820*be771a7bSCy Schubert 821*be771a7bSCy Schubert %constant int QF_BIT_CD = 0x0010; 822*be771a7bSCy Schubert %constant int QF_BIT_AD = 0x0020; 823*be771a7bSCy Schubert %constant int QF_BIT_Z = 0x0040; 824*be771a7bSCy Schubert %constant int QF_BIT_RA = 0x0080; 825*be771a7bSCy Schubert %constant int QF_BIT_RD = 0x0100; 826*be771a7bSCy Schubert %constant int QF_BIT_TC = 0x0200; 827*be771a7bSCy Schubert %constant int QF_BIT_AA = 0x0400; 828*be771a7bSCy Schubert %constant int QF_BIT_QR = 0x8000; 829*be771a7bSCy Schubert 830*be771a7bSCy Schubert %inline %{ 831*be771a7bSCy Schubert enum enum_return_rcode { 832*be771a7bSCy Schubert RCODE_NOERROR = 0, 833*be771a7bSCy Schubert RCODE_FORMERR = 1, 834*be771a7bSCy Schubert RCODE_SERVFAIL = 2, 835*be771a7bSCy Schubert RCODE_NXDOMAIN = 3, 836*be771a7bSCy Schubert RCODE_NOTIMPL = 4, 837*be771a7bSCy Schubert RCODE_REFUSED = 5, 838*be771a7bSCy Schubert RCODE_YXDOMAIN = 6, 839*be771a7bSCy Schubert RCODE_YXRRSET = 7, 840*be771a7bSCy Schubert RCODE_NXRRSET = 8, 841*be771a7bSCy Schubert RCODE_NOTAUTH = 9, 842*be771a7bSCy Schubert RCODE_NOTZONE = 10 843*be771a7bSCy Schubert }; 844*be771a7bSCy Schubert %} 845*be771a7bSCy Schubert 846*be771a7bSCy Schubert %pythoncode %{ 847*be771a7bSCy Schubert class ExtState: 848*be771a7bSCy Schubert def __init__(self, obj): self.obj = obj 849*be771a7bSCy Schubert def __str__(self): 850*be771a7bSCy Schubert return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)]) 851*be771a7bSCy Schubert def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index) 852*be771a7bSCy Schubert def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value) 853*be771a7bSCy Schubert def __len__(self): return _unboundmodule.MODULE_COUNT 854*be771a7bSCy Schubert 855*be771a7bSCy Schubert class EdnsOptsListIter: 856*be771a7bSCy Schubert def __init__(self, obj): 857*be771a7bSCy Schubert self._current = obj 858*be771a7bSCy Schubert self._temp = None 859*be771a7bSCy Schubert def __iter__(self): return self 860*be771a7bSCy Schubert def __next__(self): 861*be771a7bSCy Schubert """Python 3 compatibility""" 862*be771a7bSCy Schubert return self._get_next() 863*be771a7bSCy Schubert def next(self): 864*be771a7bSCy Schubert """Python 2 compatibility""" 865*be771a7bSCy Schubert return self._get_next() 866*be771a7bSCy Schubert def _get_next(self): 867*be771a7bSCy Schubert if not edns_opt_list_is_empty(self._current): 868*be771a7bSCy Schubert self._temp = self._current 869*be771a7bSCy Schubert self._current = _p_p_edns_option_get_next(self._current) 870*be771a7bSCy Schubert return _dereference_edns_option(self._temp) 871*be771a7bSCy Schubert else: 872*be771a7bSCy Schubert raise StopIteration 873*be771a7bSCy Schubert %} 874*be771a7bSCy Schubert 875*be771a7bSCy Schubert %inline %{ 876*be771a7bSCy Schubert enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) { 877*be771a7bSCy Schubert if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) { 878*be771a7bSCy Schubert return q->ext_state[idx]; 879*be771a7bSCy Schubert } 880*be771a7bSCy Schubert return 0; 881*be771a7bSCy Schubert } 882*be771a7bSCy Schubert 883*be771a7bSCy Schubert void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) { 884*be771a7bSCy Schubert if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) { 885*be771a7bSCy Schubert q->ext_state[idx] = state; 886*be771a7bSCy Schubert } 887*be771a7bSCy Schubert } 888*be771a7bSCy Schubert 889*be771a7bSCy Schubert int edns_opt_list_is_empty(struct edns_option** opt) { 890*be771a7bSCy Schubert if (!opt || !(*opt)) return 1; 891*be771a7bSCy Schubert return 0; 892*be771a7bSCy Schubert } 893*be771a7bSCy Schubert 894*be771a7bSCy Schubert struct edns_option* _dereference_edns_option(struct edns_option** opt) { 895*be771a7bSCy Schubert if (!opt) return NULL; 896*be771a7bSCy Schubert return *opt; 897*be771a7bSCy Schubert } 898*be771a7bSCy Schubert 899*be771a7bSCy Schubert struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) { 900*be771a7bSCy Schubert return &(*opt)->next; 901*be771a7bSCy Schubert } 902*be771a7bSCy Schubert 903*be771a7bSCy Schubert struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) { 904*be771a7bSCy Schubert return &q->edns_opts_front_in; 905*be771a7bSCy Schubert } 906*be771a7bSCy Schubert 907*be771a7bSCy Schubert struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) { 908*be771a7bSCy Schubert return &q->edns_opts_back_out; 909*be771a7bSCy Schubert } 910*be771a7bSCy Schubert 911*be771a7bSCy Schubert struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) { 912*be771a7bSCy Schubert return &q->edns_opts_back_in; 913*be771a7bSCy Schubert } 914*be771a7bSCy Schubert 915*be771a7bSCy Schubert struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) { 916*be771a7bSCy Schubert return &q->edns_opts_front_out; 917*be771a7bSCy Schubert } 918*be771a7bSCy Schubert %} 919*be771a7bSCy Schubert 920*be771a7bSCy Schubert %extend module_qstate { 921*be771a7bSCy Schubert %pythoncode %{ 922*be771a7bSCy Schubert def set_ext_state(self, id, state): 923*be771a7bSCy Schubert """Sets the ext state""" 924*be771a7bSCy Schubert _unboundmodule._ext_state_set(self, id, state) 925*be771a7bSCy Schubert 926*be771a7bSCy Schubert def __ext_state_get(self): return ExtState(self) 927*be771a7bSCy Schubert ext_state = property(__ext_state_get) #, __ext_state_set 928*be771a7bSCy Schubert 929*be771a7bSCy Schubert def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in) 930*be771a7bSCy Schubert edns_opts_front_in_iter = property(_edns_opts_front_in_iter) 931*be771a7bSCy Schubert def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out) 932*be771a7bSCy Schubert edns_opts_back_out_iter = property(_edns_opts_back_out_iter) 933*be771a7bSCy Schubert def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in) 934*be771a7bSCy Schubert edns_opts_back_in_iter = property(_edns_opts_back_in_iter) 935*be771a7bSCy Schubert def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out) 936*be771a7bSCy Schubert edns_opts_front_out_iter = property(_edns_opts_front_out_iter) 937*be771a7bSCy Schubert 938*be771a7bSCy Schubert def _edns_opts_front_in(self): return _edns_opts_front_in_get(self) 939*be771a7bSCy Schubert edns_opts_front_in = property(_edns_opts_front_in) 940*be771a7bSCy Schubert def _edns_opts_back_out(self): return _edns_opts_back_out_get(self) 941*be771a7bSCy Schubert edns_opts_back_out = property(_edns_opts_back_out) 942*be771a7bSCy Schubert def _edns_opts_back_in(self): return _edns_opts_back_in_get(self) 943*be771a7bSCy Schubert edns_opts_back_in = property(_edns_opts_back_in) 944*be771a7bSCy Schubert def _edns_opts_front_out(self): return _edns_opts_front_out_get(self) 945*be771a7bSCy Schubert edns_opts_front_out = property(_edns_opts_front_out) 946*be771a7bSCy Schubert %} 947*be771a7bSCy Schubert } 948*be771a7bSCy Schubert 949*be771a7bSCy Schubert /* ************************************************************************************ * 950*be771a7bSCy Schubert Structure config_strlist 951*be771a7bSCy Schubert * ************************************************************************************ */ 952*be771a7bSCy Schubert struct config_strlist { 953*be771a7bSCy Schubert struct config_strlist* next; 954*be771a7bSCy Schubert char* str; 955*be771a7bSCy Schubert }; 956*be771a7bSCy Schubert 957*be771a7bSCy Schubert /* ************************************************************************************ * 958*be771a7bSCy Schubert Structure config_str2list 959*be771a7bSCy Schubert * ************************************************************************************ */ 960*be771a7bSCy Schubert struct config_str2list { 961*be771a7bSCy Schubert struct config_str2list* next; 962*be771a7bSCy Schubert char* str; 963*be771a7bSCy Schubert char* str2; 964*be771a7bSCy Schubert }; 965*be771a7bSCy Schubert 966*be771a7bSCy Schubert /* ************************************************************************************ * 967*be771a7bSCy Schubert Structure config_file 968*be771a7bSCy Schubert * ************************************************************************************ */ 969*be771a7bSCy Schubert %ignore config_file::ifs; 970*be771a7bSCy Schubert %ignore config_file::out_ifs; 971*be771a7bSCy Schubert %ignore config_file::python_script; 972*be771a7bSCy Schubert struct config_file { 973*be771a7bSCy Schubert int verbosity; 974*be771a7bSCy Schubert int stat_interval; 975*be771a7bSCy Schubert int stat_cumulative; 976*be771a7bSCy Schubert int stat_extended; 977*be771a7bSCy Schubert int num_threads; 978*be771a7bSCy Schubert int port; 979*be771a7bSCy Schubert int do_ip4; 980*be771a7bSCy Schubert int do_ip6; 981*be771a7bSCy Schubert int do_udp; 982*be771a7bSCy Schubert int do_tcp; 983*be771a7bSCy Schubert int outgoing_num_ports; 984*be771a7bSCy Schubert size_t outgoing_num_tcp; 985*be771a7bSCy Schubert size_t incoming_num_tcp; 986*be771a7bSCy Schubert int* outgoing_avail_ports; 987*be771a7bSCy Schubert size_t msg_buffer_size; 988*be771a7bSCy Schubert size_t msg_cache_size; 989*be771a7bSCy Schubert size_t msg_cache_slabs; 990*be771a7bSCy Schubert size_t num_queries_per_thread; 991*be771a7bSCy Schubert size_t jostle_time; 992*be771a7bSCy Schubert size_t rrset_cache_size; 993*be771a7bSCy Schubert size_t rrset_cache_slabs; 994*be771a7bSCy Schubert int host_ttl; 995*be771a7bSCy Schubert size_t infra_cache_slabs; 996*be771a7bSCy Schubert size_t infra_cache_numhosts; 997*be771a7bSCy Schubert char* target_fetch_policy; 998*be771a7bSCy Schubert int if_automatic; 999*be771a7bSCy Schubert int num_ifs; 1000*be771a7bSCy Schubert char **ifs; 1001*be771a7bSCy Schubert int num_out_ifs; 1002*be771a7bSCy Schubert char **out_ifs; 1003*be771a7bSCy Schubert struct config_strlist* root_hints; 1004*be771a7bSCy Schubert struct config_stub* stubs; 1005*be771a7bSCy Schubert struct config_stub* forwards; 1006*be771a7bSCy Schubert struct config_strlist* donotqueryaddrs; 1007*be771a7bSCy Schubert struct config_str2list* acls; 1008*be771a7bSCy Schubert int donotquery_localhost; 1009*be771a7bSCy Schubert int harden_short_bufsize; 1010*be771a7bSCy Schubert int harden_large_queries; 1011*be771a7bSCy Schubert int harden_glue; 1012*be771a7bSCy Schubert int harden_unverified_glue; 1013*be771a7bSCy Schubert int harden_dnssec_stripped; 1014*be771a7bSCy Schubert int harden_referral_path; 1015*be771a7bSCy Schubert int use_caps_bits_for_id; 1016*be771a7bSCy Schubert struct config_strlist* private_address; 1017*be771a7bSCy Schubert struct config_strlist* private_domain; 1018*be771a7bSCy Schubert size_t unwanted_threshold; 1019*be771a7bSCy Schubert char* chrootdir; 1020*be771a7bSCy Schubert char* username; 1021*be771a7bSCy Schubert char* directory; 1022*be771a7bSCy Schubert char* logfile; 1023*be771a7bSCy Schubert char* pidfile; 1024*be771a7bSCy Schubert int use_syslog; 1025*be771a7bSCy Schubert int hide_identity; 1026*be771a7bSCy Schubert int hide_version; 1027*be771a7bSCy Schubert char* identity; 1028*be771a7bSCy Schubert char* version; 1029*be771a7bSCy Schubert char* module_conf; 1030*be771a7bSCy Schubert struct config_strlist* trust_anchor_file_list; 1031*be771a7bSCy Schubert struct config_strlist* trust_anchor_list; 1032*be771a7bSCy Schubert struct config_strlist* trusted_keys_file_list; 1033*be771a7bSCy Schubert int max_ttl; 1034*be771a7bSCy Schubert int32_t val_date_override; 1035*be771a7bSCy Schubert int bogus_ttl; 1036*be771a7bSCy Schubert int val_clean_additional; 1037*be771a7bSCy Schubert int val_permissive_mode; 1038*be771a7bSCy Schubert char* val_nsec3_key_iterations; 1039*be771a7bSCy Schubert size_t key_cache_size; 1040*be771a7bSCy Schubert size_t key_cache_slabs; 1041*be771a7bSCy Schubert size_t neg_cache_size; 1042*be771a7bSCy Schubert struct config_str2list* local_zones; 1043*be771a7bSCy Schubert struct config_strlist* local_zones_nodefault; 1044*be771a7bSCy Schubert struct config_strlist* local_data; 1045*be771a7bSCy Schubert int remote_control_enable; 1046*be771a7bSCy Schubert struct config_strlist_head control_ifs; 1047*be771a7bSCy Schubert int control_port; 1048*be771a7bSCy Schubert char* server_key_file; 1049*be771a7bSCy Schubert char* server_cert_file; 1050*be771a7bSCy Schubert char* control_key_file; 1051*be771a7bSCy Schubert char* control_cert_file; 1052*be771a7bSCy Schubert int do_daemonize; 1053*be771a7bSCy Schubert struct config_strlist* python_script; 1054*be771a7bSCy Schubert }; 1055*be771a7bSCy Schubert 1056*be771a7bSCy Schubert %inline %{ 1057*be771a7bSCy Schubert PyObject* _get_ifs_tuple(struct config_file* cfg) { 1058*be771a7bSCy Schubert return CharArrayAsStringList(cfg->ifs, cfg->num_ifs); 1059*be771a7bSCy Schubert } 1060*be771a7bSCy Schubert PyObject* _get_ifs_out_tuple(struct config_file* cfg) { 1061*be771a7bSCy Schubert return CharArrayAsStringList(cfg->out_ifs, cfg->num_out_ifs); 1062*be771a7bSCy Schubert } 1063*be771a7bSCy Schubert %} 1064*be771a7bSCy Schubert 1065*be771a7bSCy Schubert %extend config_file { 1066*be771a7bSCy Schubert %pythoncode %{ 1067*be771a7bSCy Schubert ifs = property(_unboundmodule._get_ifs_tuple) 1068*be771a7bSCy Schubert out_ifs = property(_unboundmodule._get_ifs_out_tuple) 1069*be771a7bSCy Schubert 1070*be771a7bSCy Schubert def _deprecated_python_script(self): return "cfg.python_script is deprecated, you can use `mod_env['script']` instead." 1071*be771a7bSCy Schubert python_script = property(_deprecated_python_script) 1072*be771a7bSCy Schubert %} 1073*be771a7bSCy Schubert } 1074*be771a7bSCy Schubert 1075*be771a7bSCy Schubert /* ************************************************************************************ * 1076*be771a7bSCy Schubert ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation 1077*be771a7bSCy Schubert * ************************************************************************************ */ 1078*be771a7bSCy Schubert struct delegpt_ns { 1079*be771a7bSCy Schubert struct delegpt_ns* next; 1080*be771a7bSCy Schubert int resolved; 1081*be771a7bSCy Schubert uint8_t got4; 1082*be771a7bSCy Schubert uint8_t got6; 1083*be771a7bSCy Schubert uint8_t lame; 1084*be771a7bSCy Schubert uint8_t done_pside4; 1085*be771a7bSCy Schubert uint8_t done_pside6; 1086*be771a7bSCy Schubert }; 1087*be771a7bSCy Schubert 1088*be771a7bSCy Schubert struct delegpt_addr { 1089*be771a7bSCy Schubert struct delegpt_addr* next_result; 1090*be771a7bSCy Schubert struct delegpt_addr* next_usable; 1091*be771a7bSCy Schubert struct delegpt_addr* next_target; 1092*be771a7bSCy Schubert int attempts; 1093*be771a7bSCy Schubert int sel_rtt; 1094*be771a7bSCy Schubert int bogus; 1095*be771a7bSCy Schubert int lame; 1096*be771a7bSCy Schubert }; 1097*be771a7bSCy Schubert 1098*be771a7bSCy Schubert struct delegpt { 1099*be771a7bSCy Schubert int namelabs; 1100*be771a7bSCy Schubert struct delegpt_ns* nslist; 1101*be771a7bSCy Schubert struct delegpt_addr* target_list; 1102*be771a7bSCy Schubert struct delegpt_addr* usable_list; 1103*be771a7bSCy Schubert struct delegpt_addr* result_list; 1104*be771a7bSCy Schubert int bogus; 1105*be771a7bSCy Schubert uint8_t has_parent_side_NS; 1106*be771a7bSCy Schubert uint8_t dp_type_mlc; 1107*be771a7bSCy Schubert }; 1108*be771a7bSCy Schubert 1109*be771a7bSCy Schubert 1110*be771a7bSCy Schubert %inline %{ 1111*be771a7bSCy Schubert PyObject* _get_dp_dname(struct delegpt* dp) { 1112*be771a7bSCy Schubert return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen); 1113*be771a7bSCy Schubert } 1114*be771a7bSCy Schubert PyObject* _get_dp_dname_components(struct delegpt* dp) { 1115*be771a7bSCy Schubert return GetNameAsLabelList((char*)dp->name, dp->namelen); 1116*be771a7bSCy Schubert } 1117*be771a7bSCy Schubert PyObject* _get_dpns_dname(struct delegpt_ns* dpns) { 1118*be771a7bSCy Schubert return PyBytes_FromStringAndSize((char*)dpns->name, dpns->namelen); 1119*be771a7bSCy Schubert } 1120*be771a7bSCy Schubert PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) { 1121*be771a7bSCy Schubert return GetNameAsLabelList((char*)dpns->name, dpns->namelen); 1122*be771a7bSCy Schubert } 1123*be771a7bSCy Schubert 1124*be771a7bSCy Schubert PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) { 1125*be771a7bSCy Schubert char dest[64]; 1126*be771a7bSCy Schubert delegpt_addr_addr2str(target, dest, 64); 1127*be771a7bSCy Schubert if (dest[0] == 0) 1128*be771a7bSCy Schubert return Py_None; 1129*be771a7bSCy Schubert return PyBytes_FromString(dest); 1130*be771a7bSCy Schubert } 1131*be771a7bSCy Schubert 1132*be771a7bSCy Schubert %} 1133*be771a7bSCy Schubert 1134*be771a7bSCy Schubert %extend delegpt { 1135*be771a7bSCy Schubert %pythoncode %{ 1136*be771a7bSCy Schubert dname = property(_unboundmodule._get_dp_dname) 1137*be771a7bSCy Schubert 1138*be771a7bSCy Schubert dname_list = property(_unboundmodule._get_dp_dname_components) 1139*be771a7bSCy Schubert 1140*be771a7bSCy Schubert def _get_dname_str(self): return dnameAsStr(self.dname) 1141*be771a7bSCy Schubert dname_str = property(_get_dname_str) 1142*be771a7bSCy Schubert %} 1143*be771a7bSCy Schubert } 1144*be771a7bSCy Schubert %extend delegpt_ns { 1145*be771a7bSCy Schubert %pythoncode %{ 1146*be771a7bSCy Schubert dname = property(_unboundmodule._get_dpns_dname) 1147*be771a7bSCy Schubert 1148*be771a7bSCy Schubert dname_list = property(_unboundmodule._get_dpns_dname_components) 1149*be771a7bSCy Schubert 1150*be771a7bSCy Schubert def _get_dname_str(self): return dnameAsStr(self.dname) 1151*be771a7bSCy Schubert dname_str = property(_get_dname_str) 1152*be771a7bSCy Schubert %} 1153*be771a7bSCy Schubert } 1154*be771a7bSCy Schubert %extend delegpt_addr { 1155*be771a7bSCy Schubert %pythoncode %{ 1156*be771a7bSCy Schubert def _addr_get(self): return _delegpt_addr_addr_get(self) 1157*be771a7bSCy Schubert addr = property(_addr_get) 1158*be771a7bSCy Schubert %} 1159*be771a7bSCy Schubert } 1160*be771a7bSCy Schubert 1161*be771a7bSCy Schubert /* ************************************************************************************ * 1162*be771a7bSCy Schubert Enums 1163*be771a7bSCy Schubert * ************************************************************************************ */ 1164*be771a7bSCy Schubert %rename ("MODULE_STATE_INITIAL") "module_state_initial"; 1165*be771a7bSCy Schubert %rename ("MODULE_WAIT_REPLY") "module_wait_reply"; 1166*be771a7bSCy Schubert %rename ("MODULE_WAIT_MODULE") "module_wait_module"; 1167*be771a7bSCy Schubert %rename ("MODULE_RESTART_NEXT") "module_restart_next"; 1168*be771a7bSCy Schubert %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery"; 1169*be771a7bSCy Schubert %rename ("MODULE_ERROR") "module_error"; 1170*be771a7bSCy Schubert %rename ("MODULE_FINISHED") "module_finished"; 1171*be771a7bSCy Schubert 1172*be771a7bSCy Schubert enum module_ext_state { 1173*be771a7bSCy Schubert module_state_initial = 0, 1174*be771a7bSCy Schubert module_wait_reply, 1175*be771a7bSCy Schubert module_wait_module, 1176*be771a7bSCy Schubert module_restart_next, 1177*be771a7bSCy Schubert module_wait_subquery, 1178*be771a7bSCy Schubert module_error, 1179*be771a7bSCy Schubert module_finished 1180*be771a7bSCy Schubert }; 1181*be771a7bSCy Schubert 1182*be771a7bSCy Schubert %rename ("MODULE_EVENT_NEW") "module_event_new"; 1183*be771a7bSCy Schubert %rename ("MODULE_EVENT_PASS") "module_event_pass"; 1184*be771a7bSCy Schubert %rename ("MODULE_EVENT_REPLY") "module_event_reply"; 1185*be771a7bSCy Schubert %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply"; 1186*be771a7bSCy Schubert %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail"; 1187*be771a7bSCy Schubert %rename ("MODULE_EVENT_MODDONE") "module_event_moddone"; 1188*be771a7bSCy Schubert %rename ("MODULE_EVENT_ERROR") "module_event_error"; 1189*be771a7bSCy Schubert 1190*be771a7bSCy Schubert enum module_ev { 1191*be771a7bSCy Schubert module_event_new = 0, 1192*be771a7bSCy Schubert module_event_pass, 1193*be771a7bSCy Schubert module_event_reply, 1194*be771a7bSCy Schubert module_event_noreply, 1195*be771a7bSCy Schubert module_event_capsfail, 1196*be771a7bSCy Schubert module_event_moddone, 1197*be771a7bSCy Schubert module_event_error 1198*be771a7bSCy Schubert }; 1199*be771a7bSCy Schubert 1200*be771a7bSCy Schubert enum sec_status { 1201*be771a7bSCy Schubert sec_status_unchecked = 0, 1202*be771a7bSCy Schubert sec_status_bogus, 1203*be771a7bSCy Schubert sec_status_indeterminate, 1204*be771a7bSCy Schubert sec_status_insecure, 1205*be771a7bSCy Schubert sec_status_secure 1206*be771a7bSCy Schubert }; 1207*be771a7bSCy Schubert 1208*be771a7bSCy Schubert enum verbosity_value { 1209*be771a7bSCy Schubert NO_VERBOSE = 0, 1210*be771a7bSCy Schubert VERB_OPS, 1211*be771a7bSCy Schubert VERB_DETAIL, 1212*be771a7bSCy Schubert VERB_QUERY, 1213*be771a7bSCy Schubert VERB_ALGO 1214*be771a7bSCy Schubert }; 1215*be771a7bSCy Schubert 1216*be771a7bSCy Schubert enum inplace_cb_list_type { 1217*be771a7bSCy Schubert /* Inplace callbacks for when a resolved reply is ready to be sent to the 1218*be771a7bSCy Schubert * front.*/ 1219*be771a7bSCy Schubert inplace_cb_reply = 0, 1220*be771a7bSCy Schubert /* Inplace callbacks for when a reply is given from the cache. */ 1221*be771a7bSCy Schubert inplace_cb_reply_cache, 1222*be771a7bSCy Schubert /* Inplace callbacks for when a reply is given with local data 1223*be771a7bSCy Schubert * (or Chaos reply). */ 1224*be771a7bSCy Schubert inplace_cb_reply_local, 1225*be771a7bSCy Schubert /* Inplace callbacks for when the reply is servfail. */ 1226*be771a7bSCy Schubert inplace_cb_reply_servfail, 1227*be771a7bSCy Schubert /* Inplace callbacks for when a query is ready to be sent to the back.*/ 1228*be771a7bSCy Schubert inplace_cb_query, 1229*be771a7bSCy Schubert /* Inplace callback for when a reply is received from the back. */ 1230*be771a7bSCy Schubert inplace_cb_edns_back_parsed, 1231*be771a7bSCy Schubert /* Total number of types. Used for array initialization. 1232*be771a7bSCy Schubert * Should always be last. */ 1233*be771a7bSCy Schubert inplace_cb_types_total 1234*be771a7bSCy Schubert }; 1235*be771a7bSCy Schubert 1236*be771a7bSCy Schubert %constant uint16_t PKT_QR = 1; /* QueRy - query flag */ 1237*be771a7bSCy Schubert %constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */ 1238*be771a7bSCy Schubert %constant uint16_t PKT_TC = 4; /* TrunCated - server flag */ 1239*be771a7bSCy Schubert %constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */ 1240*be771a7bSCy Schubert %constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */ 1241*be771a7bSCy Schubert %constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */ 1242*be771a7bSCy Schubert %constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */ 1243*be771a7bSCy Schubert 1244*be771a7bSCy Schubert %{ 1245*be771a7bSCy Schubert int checkList(PyObject *l) 1246*be771a7bSCy Schubert { 1247*be771a7bSCy Schubert PyObject* item; 1248*be771a7bSCy Schubert int i; 1249*be771a7bSCy Schubert 1250*be771a7bSCy Schubert if (l == Py_None) 1251*be771a7bSCy Schubert return 1; 1252*be771a7bSCy Schubert 1253*be771a7bSCy Schubert if (PyList_Check(l)) 1254*be771a7bSCy Schubert { 1255*be771a7bSCy Schubert for (i=0; i < PyList_Size(l); i++) 1256*be771a7bSCy Schubert { 1257*be771a7bSCy Schubert item = PyList_GetItem(l, i); 1258*be771a7bSCy Schubert if (!PyBytes_Check(item) && !PyUnicode_Check(item)) 1259*be771a7bSCy Schubert return 0; 1260*be771a7bSCy Schubert } 1261*be771a7bSCy Schubert return 1; 1262*be771a7bSCy Schubert } 1263*be771a7bSCy Schubert 1264*be771a7bSCy Schubert return 0; 1265*be771a7bSCy Schubert } 1266*be771a7bSCy Schubert 1267*be771a7bSCy Schubert int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec, 1268*be771a7bSCy Schubert size_t count_offset) 1269*be771a7bSCy Schubert { 1270*be771a7bSCy Schubert PyObject* item; 1271*be771a7bSCy Schubert int i; 1272*be771a7bSCy Schubert size_t len; 1273*be771a7bSCy Schubert char* s; 1274*be771a7bSCy Schubert PyObject* ascstr; 1275*be771a7bSCy Schubert 1276*be771a7bSCy Schubert for (i=0; i < PyList_Size(l); i++) 1277*be771a7bSCy Schubert { 1278*be771a7bSCy Schubert ascstr = NULL; 1279*be771a7bSCy Schubert item = PyList_GetItem(l, i); 1280*be771a7bSCy Schubert if(PyObject_TypeCheck(item, &PyBytes_Type)) { 1281*be771a7bSCy Schubert s = PyBytes_AsString(item); 1282*be771a7bSCy Schubert } else { 1283*be771a7bSCy Schubert ascstr = PyUnicode_AsASCIIString(item); 1284*be771a7bSCy Schubert s = PyBytes_AsString(ascstr); 1285*be771a7bSCy Schubert } 1286*be771a7bSCy Schubert 1287*be771a7bSCy Schubert len = sldns_buffer_remaining(qb); 1288*be771a7bSCy Schubert if(qsec) { 1289*be771a7bSCy Schubert if(sldns_str2wire_rr_question_buf(s, 1290*be771a7bSCy Schubert sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0) 1291*be771a7bSCy Schubert != 0) { 1292*be771a7bSCy Schubert if(ascstr) 1293*be771a7bSCy Schubert Py_DECREF(ascstr); 1294*be771a7bSCy Schubert return 0; 1295*be771a7bSCy Schubert } 1296*be771a7bSCy Schubert } else { 1297*be771a7bSCy Schubert if(sldns_str2wire_rr_buf(s, 1298*be771a7bSCy Schubert sldns_buffer_current(qb), &len, NULL, default_ttl, 1299*be771a7bSCy Schubert NULL, 0, NULL, 0) != 0) { 1300*be771a7bSCy Schubert if(ascstr) 1301*be771a7bSCy Schubert Py_DECREF(ascstr); 1302*be771a7bSCy Schubert return 0; 1303*be771a7bSCy Schubert } 1304*be771a7bSCy Schubert } 1305*be771a7bSCy Schubert if(ascstr) 1306*be771a7bSCy Schubert Py_DECREF(ascstr); 1307*be771a7bSCy Schubert sldns_buffer_skip(qb, len); 1308*be771a7bSCy Schubert 1309*be771a7bSCy Schubert sldns_buffer_write_u16_at(qb, count_offset, 1310*be771a7bSCy Schubert sldns_buffer_read_u16_at(qb, count_offset)+1); 1311*be771a7bSCy Schubert } 1312*be771a7bSCy Schubert return 1; 1313*be771a7bSCy Schubert } 1314*be771a7bSCy Schubert 1315*be771a7bSCy Schubert int set_return_msg(struct module_qstate* qstate, 1316*be771a7bSCy Schubert const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl, 1317*be771a7bSCy Schubert PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional) 1318*be771a7bSCy Schubert { 1319*be771a7bSCy Schubert sldns_buffer *qb = 0; 1320*be771a7bSCy Schubert int res = 1; 1321*be771a7bSCy Schubert size_t l; 1322*be771a7bSCy Schubert uint16_t PKT_QR = 1; 1323*be771a7bSCy Schubert uint16_t PKT_AA = 2; 1324*be771a7bSCy Schubert uint16_t PKT_TC = 4; 1325*be771a7bSCy Schubert uint16_t PKT_RD = 8; 1326*be771a7bSCy Schubert uint16_t PKT_CD = 16; 1327*be771a7bSCy Schubert uint16_t PKT_RA = 32; 1328*be771a7bSCy Schubert uint16_t PKT_AD = 64; 1329*be771a7bSCy Schubert 1330*be771a7bSCy Schubert if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional))) 1331*be771a7bSCy Schubert return 0; 1332*be771a7bSCy Schubert if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0; 1333*be771a7bSCy Schubert 1334*be771a7bSCy Schubert /* write header */ 1335*be771a7bSCy Schubert sldns_buffer_write_u16(qb, 0); /* ID */ 1336*be771a7bSCy Schubert sldns_buffer_write_u16(qb, 0); /* flags */ 1337*be771a7bSCy Schubert sldns_buffer_write_u16(qb, 1); /* qdcount */ 1338*be771a7bSCy Schubert sldns_buffer_write_u16(qb, 0); /* ancount */ 1339*be771a7bSCy Schubert sldns_buffer_write_u16(qb, 0); /* nscount */ 1340*be771a7bSCy Schubert sldns_buffer_write_u16(qb, 0); /* arcount */ 1341*be771a7bSCy Schubert if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb)); 1342*be771a7bSCy Schubert if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb)); 1343*be771a7bSCy Schubert if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb)); 1344*be771a7bSCy Schubert if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb)); 1345*be771a7bSCy Schubert if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb)); 1346*be771a7bSCy Schubert if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb)); 1347*be771a7bSCy Schubert if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb)); 1348*be771a7bSCy Schubert 1349*be771a7bSCy Schubert /* write the query */ 1350*be771a7bSCy Schubert l = sldns_buffer_remaining(qb); 1351*be771a7bSCy Schubert if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) { 1352*be771a7bSCy Schubert sldns_buffer_free(qb); 1353*be771a7bSCy Schubert return 0; 1354*be771a7bSCy Schubert } 1355*be771a7bSCy Schubert sldns_buffer_skip(qb, l); 1356*be771a7bSCy Schubert if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; } 1357*be771a7bSCy Schubert if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; } 1358*be771a7bSCy Schubert sldns_buffer_write_u16(qb, rr_type); 1359*be771a7bSCy Schubert sldns_buffer_write_u16(qb, rr_class); 1360*be771a7bSCy Schubert 1361*be771a7bSCy Schubert /* write RR sections */ 1362*be771a7bSCy Schubert if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF)) 1363*be771a7bSCy Schubert res = 0; 1364*be771a7bSCy Schubert if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF)) 1365*be771a7bSCy Schubert res = 0; 1366*be771a7bSCy Schubert if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF)) 1367*be771a7bSCy Schubert res = 0; 1368*be771a7bSCy Schubert if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF)) 1369*be771a7bSCy Schubert res = 0; 1370*be771a7bSCy Schubert 1371*be771a7bSCy Schubert if (res) res = createResponse(qstate, qb); 1372*be771a7bSCy Schubert 1373*be771a7bSCy Schubert if (qb) sldns_buffer_free(qb); 1374*be771a7bSCy Schubert return res; 1375*be771a7bSCy Schubert } 1376*be771a7bSCy Schubert %} 1377*be771a7bSCy Schubert 1378*be771a7bSCy Schubert int set_return_msg(struct module_qstate* qstate, 1379*be771a7bSCy Schubert const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl, 1380*be771a7bSCy Schubert PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional); 1381*be771a7bSCy Schubert 1382*be771a7bSCy Schubert %pythoncode %{ 1383*be771a7bSCy Schubert class DNSMessage: 1384*be771a7bSCy Schubert def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0): 1385*be771a7bSCy Schubert """Query flags is a combination of PKT_xx constants""" 1386*be771a7bSCy Schubert self.rr_name = rr_name 1387*be771a7bSCy Schubert self.rr_type = rr_type 1388*be771a7bSCy Schubert self.rr_class = rr_class 1389*be771a7bSCy Schubert self.default_ttl = default_ttl 1390*be771a7bSCy Schubert self.query_flags = query_flags 1391*be771a7bSCy Schubert self.question = [] 1392*be771a7bSCy Schubert self.answer = [] 1393*be771a7bSCy Schubert self.authority = [] 1394*be771a7bSCy Schubert self.additional = [] 1395*be771a7bSCy Schubert 1396*be771a7bSCy Schubert def set_return_msg(self, qstate): 1397*be771a7bSCy Schubert """Returns 1 if OK""" 1398*be771a7bSCy Schubert status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class, 1399*be771a7bSCy Schubert self.query_flags, self.default_ttl, 1400*be771a7bSCy Schubert self.question, self.answer, self.authority, self.additional) 1401*be771a7bSCy Schubert 1402*be771a7bSCy Schubert if (status) and (PKT_AA & self.query_flags): 1403*be771a7bSCy Schubert qstate.return_msg.rep.authoritative = 1 1404*be771a7bSCy Schubert 1405*be771a7bSCy Schubert return status 1406*be771a7bSCy Schubert 1407*be771a7bSCy Schubert %} 1408*be771a7bSCy Schubert /* ************************************************************************************ * 1409*be771a7bSCy Schubert ASN: Delegation pointer related functions 1410*be771a7bSCy Schubert * ************************************************************************************ */ 1411*be771a7bSCy Schubert 1412*be771a7bSCy Schubert /* Functions which we will need to lookup delegations */ 1413*be771a7bSCy Schubert struct delegpt* dns_cache_find_delegation(struct module_env* env, 1414*be771a7bSCy Schubert uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 1415*be771a7bSCy Schubert struct regional* region, struct dns_msg** msg, uint32_t timenow, 1416*be771a7bSCy Schubert int noexpiredabove, uint8_t* expiretop, size_t expiretoplen); 1417*be771a7bSCy Schubert int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, 1418*be771a7bSCy Schubert struct delegpt* dp, int supports_ipv4, int supports_ipv6, int use_nat64); 1419*be771a7bSCy Schubert struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints, 1420*be771a7bSCy Schubert uint8_t* qname, uint16_t qclass, struct delegpt* dp, int nolock); 1421*be771a7bSCy Schubert 1422*be771a7bSCy Schubert /* Custom function to perform logic similar to the one in daemon/cachedump.c */ 1423*be771a7bSCy Schubert struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen); 1424*be771a7bSCy Schubert 1425*be771a7bSCy Schubert %{ 1426*be771a7bSCy Schubert #define BIT_RD 0x100 1427*be771a7bSCy Schubert 1428*be771a7bSCy Schubert struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen) 1429*be771a7bSCy Schubert { 1430*be771a7bSCy Schubert struct delegpt *dp; 1431*be771a7bSCy Schubert struct dns_msg *msg = NULL; 1432*be771a7bSCy Schubert struct regional* region = qstate->env->scratch; 1433*be771a7bSCy Schubert char b[260]; 1434*be771a7bSCy Schubert struct query_info qinfo; 1435*be771a7bSCy Schubert struct iter_hints_stub* stub; 1436*be771a7bSCy Schubert uint32_t timenow = *qstate->env->now; 1437*be771a7bSCy Schubert int nolock = 0; 1438*be771a7bSCy Schubert 1439*be771a7bSCy Schubert regional_free_all(region); 1440*be771a7bSCy Schubert qinfo.qname = (uint8_t*)nm; 1441*be771a7bSCy Schubert qinfo.qname_len = nmlen; 1442*be771a7bSCy Schubert qinfo.qtype = LDNS_RR_TYPE_A; 1443*be771a7bSCy Schubert qinfo.qclass = LDNS_RR_CLASS_IN; 1444*be771a7bSCy Schubert 1445*be771a7bSCy Schubert while(1) { 1446*be771a7bSCy Schubert dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow, 0, NULL, 0); 1447*be771a7bSCy Schubert if(!dp) 1448*be771a7bSCy Schubert return NULL; 1449*be771a7bSCy Schubert if(iter_dp_is_useless(&qinfo, BIT_RD, dp, 1450*be771a7bSCy Schubert qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6, 1451*be771a7bSCy Schubert qstate->env->cfg->do_nat64)) { 1452*be771a7bSCy Schubert if (dname_is_root((uint8_t*)nm)) 1453*be771a7bSCy Schubert return NULL; 1454*be771a7bSCy Schubert nm = (char*)dp->name; 1455*be771a7bSCy Schubert nmlen = dp->namelen; 1456*be771a7bSCy Schubert dname_remove_label((uint8_t**)&nm, &nmlen); 1457*be771a7bSCy Schubert dname_str((uint8_t*)nm, b); 1458*be771a7bSCy Schubert continue; 1459*be771a7bSCy Schubert } 1460*be771a7bSCy Schubert stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, 1461*be771a7bSCy Schubert qinfo.qclass, dp, nolock); 1462*be771a7bSCy Schubert if (stub) { 1463*be771a7bSCy Schubert struct delegpt* stubdp = delegpt_copy(stub->dp, region); 1464*be771a7bSCy Schubert lock_rw_unlock(&qstate->env->hints->lock); 1465*be771a7bSCy Schubert return stubdp; 1466*be771a7bSCy Schubert } else { 1467*be771a7bSCy Schubert return dp; 1468*be771a7bSCy Schubert } 1469*be771a7bSCy Schubert } 1470*be771a7bSCy Schubert return NULL; 1471*be771a7bSCy Schubert } 1472*be771a7bSCy Schubert %} 1473*be771a7bSCy Schubert 1474*be771a7bSCy Schubert /* ************************************************************************************ * 1475*be771a7bSCy Schubert Functions 1476*be771a7bSCy Schubert * ************************************************************************************ */ 1477*be771a7bSCy Schubert /****************************** 1478*be771a7bSCy Schubert * Various debugging functions * 1479*be771a7bSCy Schubert ******************************/ 1480*be771a7bSCy Schubert 1481*be771a7bSCy Schubert /* rename the variadic functions because python does the formatting already*/ 1482*be771a7bSCy Schubert %rename (unbound_log_info) log_info; 1483*be771a7bSCy Schubert %rename (unbound_log_err) log_err; 1484*be771a7bSCy Schubert %rename (unbound_log_warn) log_warn; 1485*be771a7bSCy Schubert %rename (unbound_verbose) verbose; 1486*be771a7bSCy Schubert /* provide functions that take one string as argument, so python can cook 1487*be771a7bSCy Schubert the string */ 1488*be771a7bSCy Schubert %rename (log_info) pymod_log_info; 1489*be771a7bSCy Schubert %rename (log_warn) pymod_log_warn; 1490*be771a7bSCy Schubert %rename (log_err) pymod_log_err; 1491*be771a7bSCy Schubert %rename (verbose) pymod_verbose; 1492*be771a7bSCy Schubert 1493*be771a7bSCy Schubert void verbose(enum verbosity_value level, const char* format, ...); 1494*be771a7bSCy Schubert void log_info(const char* format, ...); 1495*be771a7bSCy Schubert void log_err(const char* format, ...); 1496*be771a7bSCy Schubert void log_warn(const char* format, ...); 1497*be771a7bSCy Schubert void log_hex(const char* msg, void* data, size_t length); 1498*be771a7bSCy Schubert void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep); 1499*be771a7bSCy Schubert void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf); 1500*be771a7bSCy Schubert void regional_log_stats(struct regional *r); 1501*be771a7bSCy Schubert 1502*be771a7bSCy Schubert /* the one argument string log functions */ 1503*be771a7bSCy Schubert void pymod_log_info(const char* str); 1504*be771a7bSCy Schubert void pymod_log_err(const char* str); 1505*be771a7bSCy Schubert void pymod_log_warn(const char* str); 1506*be771a7bSCy Schubert void pymod_verbose(enum verbosity_value level, const char* str); 1507*be771a7bSCy Schubert %{ 1508*be771a7bSCy Schubert void pymod_log_info(const char* str) { log_info("%s", str); } 1509*be771a7bSCy Schubert void pymod_log_err(const char* str) { log_err("%s", str); } 1510*be771a7bSCy Schubert void pymod_log_warn(const char* str) { log_warn("%s", str); } 1511*be771a7bSCy Schubert void pymod_verbose(enum verbosity_value level, const char* str) { 1512*be771a7bSCy Schubert verbose(level, "%s", str); } 1513*be771a7bSCy Schubert %} 1514*be771a7bSCy Schubert 1515*be771a7bSCy Schubert /*************************************************************************** 1516*be771a7bSCy Schubert * Free allocated memory from marked sources returning corresponding types * 1517*be771a7bSCy Schubert ***************************************************************************/ 1518*be771a7bSCy Schubert %typemap(newfree, noblock = 1) char * { 1519*be771a7bSCy Schubert free($1); 1520*be771a7bSCy Schubert } 1521*be771a7bSCy Schubert 1522*be771a7bSCy Schubert /*************************************************** 1523*be771a7bSCy Schubert * Mark as source returning newly allocated memory * 1524*be771a7bSCy Schubert ***************************************************/ 1525*be771a7bSCy Schubert %newobject sldns_wire2str_type; 1526*be771a7bSCy Schubert %newobject sldns_wire2str_class; 1527*be771a7bSCy Schubert 1528*be771a7bSCy Schubert /****************** 1529*be771a7bSCy Schubert * LDNS functions * 1530*be771a7bSCy Schubert ******************/ 1531*be771a7bSCy Schubert char *sldns_wire2str_type(const uint16_t atype); 1532*be771a7bSCy Schubert char *sldns_wire2str_class(const uint16_t aclass); 1533*be771a7bSCy Schubert 1534*be771a7bSCy Schubert /********************************** 1535*be771a7bSCy Schubert * Functions from pythonmod_utils * 1536*be771a7bSCy Schubert **********************************/ 1537*be771a7bSCy Schubert int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral); 1538*be771a7bSCy Schubert void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo); 1539*be771a7bSCy Schubert 1540*be771a7bSCy Schubert /******************************* 1541*be771a7bSCy Schubert * Module conversion functions * 1542*be771a7bSCy Schubert *******************************/ 1543*be771a7bSCy Schubert const char* strextstate(enum module_ext_state s); 1544*be771a7bSCy Schubert const char* strmodulevent(enum module_ev e); 1545*be771a7bSCy Schubert 1546*be771a7bSCy Schubert /************************** 1547*be771a7bSCy Schubert * Edns related functions * 1548*be771a7bSCy Schubert **************************/ 1549*be771a7bSCy Schubert struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code); 1550*be771a7bSCy Schubert int edns_register_option(uint16_t opt_code, int bypass_cache_stage, 1551*be771a7bSCy Schubert int no_aggregation, struct module_env* env); 1552*be771a7bSCy Schubert 1553*be771a7bSCy Schubert %pythoncode %{ 1554*be771a7bSCy Schubert def register_edns_option(env, code, bypass_cache_stage=False, 1555*be771a7bSCy Schubert no_aggregation=False): 1556*be771a7bSCy Schubert """Wrapper function to provide keyword attributes.""" 1557*be771a7bSCy Schubert return edns_register_option(code, bypass_cache_stage, 1558*be771a7bSCy Schubert no_aggregation, env) 1559*be771a7bSCy Schubert %} 1560*be771a7bSCy Schubert 1561*be771a7bSCy Schubert /****************************** 1562*be771a7bSCy Schubert * Callback related functions * 1563*be771a7bSCy Schubert ******************************/ 1564*be771a7bSCy Schubert /* typemap to check if argument is callable */ 1565*be771a7bSCy Schubert %typemap(in) PyObject *py_cb { 1566*be771a7bSCy Schubert if (!PyCallable_Check($input)) { 1567*be771a7bSCy Schubert SWIG_exception_fail(SWIG_TypeError, "Need a callable object!"); 1568*be771a7bSCy Schubert return NULL; 1569*be771a7bSCy Schubert } 1570*be771a7bSCy Schubert $1 = $input; 1571*be771a7bSCy Schubert } 1572*be771a7bSCy Schubert /* typemap to get content/size from a bytearray */ 1573*be771a7bSCy Schubert %typemap(in) (size_t len, uint8_t* py_bytearray_data) { 1574*be771a7bSCy Schubert if (!PyByteArray_CheckExact($input)) { 1575*be771a7bSCy Schubert SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!"); 1576*be771a7bSCy Schubert return NULL; 1577*be771a7bSCy Schubert } 1578*be771a7bSCy Schubert $2 = (void*)PyByteArray_AsString($input); 1579*be771a7bSCy Schubert $1 = PyByteArray_Size($input); 1580*be771a7bSCy Schubert } 1581*be771a7bSCy Schubert 1582*be771a7bSCy Schubert int edns_opt_list_remove(struct edns_option** list, uint16_t code); 1583*be771a7bSCy Schubert int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len, 1584*be771a7bSCy Schubert uint8_t* py_bytearray_data, struct regional* region); 1585*be771a7bSCy Schubert 1586*be771a7bSCy Schubert %{ 1587*be771a7bSCy Schubert /* This function is called by unbound in order to call the python 1588*be771a7bSCy Schubert * callback function. */ 1589*be771a7bSCy Schubert int python_inplace_cb_reply_generic(struct query_info* qinfo, 1590*be771a7bSCy Schubert struct module_qstate* qstate, struct reply_info* rep, int rcode, 1591*be771a7bSCy Schubert struct edns_data* edns, struct edns_option** opt_list_out, 1592*be771a7bSCy Schubert struct comm_reply* repinfo, struct regional* region, 1593*be771a7bSCy Schubert struct timeval* start_time, int id, void* python_callback) 1594*be771a7bSCy Schubert { 1595*be771a7bSCy Schubert PyObject *func = NULL, *py_edns = NULL, *py_qstate = NULL; 1596*be771a7bSCy Schubert PyObject *py_opt_list_out = NULL, *py_qinfo = NULL; 1597*be771a7bSCy Schubert PyObject *py_rep = NULL, *py_repinfo = NULL, *py_region = NULL; 1598*be771a7bSCy Schubert PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL; 1599*be771a7bSCy Schubert int res = 0; 1600*be771a7bSCy Schubert double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6; 1601*be771a7bSCy Schubert 1602*be771a7bSCy Schubert PyGILState_STATE gstate = PyGILState_Ensure(); 1603*be771a7bSCy Schubert 1604*be771a7bSCy Schubert func = (PyObject *) python_callback; 1605*be771a7bSCy Schubert py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0); 1606*be771a7bSCy Schubert py_qstate = SWIG_NewPointerObj((void*) qstate, 1607*be771a7bSCy Schubert SWIGTYPE_p_module_qstate, 0); 1608*be771a7bSCy Schubert py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out, 1609*be771a7bSCy Schubert SWIGTYPE_p_p_edns_option, 0); 1610*be771a7bSCy Schubert py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); 1611*be771a7bSCy Schubert py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0); 1612*be771a7bSCy Schubert py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0); 1613*be771a7bSCy Schubert py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); 1614*be771a7bSCy Schubert if(!(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out 1615*be771a7bSCy Schubert && py_region && py_repinfo)) { 1616*be771a7bSCy Schubert log_err("pythonmod: swig pointer failure in python_inplace_cb_reply_generic"); 1617*be771a7bSCy Schubert goto out; 1618*be771a7bSCy Schubert } 1619*be771a7bSCy Schubert py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep, 1620*be771a7bSCy Schubert rcode, py_edns, py_opt_list_out, py_region); 1621*be771a7bSCy Schubert py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time", 1622*be771a7bSCy Schubert py_start_time); 1623*be771a7bSCy Schubert if(!(py_args && py_kwargs)) { 1624*be771a7bSCy Schubert log_err("pythonmod: BuildValue failure in python_inplace_cb_reply_generic"); 1625*be771a7bSCy Schubert goto out; 1626*be771a7bSCy Schubert } 1627*be771a7bSCy Schubert result = PyObject_Call(func, py_args, py_kwargs); 1628*be771a7bSCy Schubert if (result) { 1629*be771a7bSCy Schubert res = PyInt_AsLong(result); 1630*be771a7bSCy Schubert } 1631*be771a7bSCy Schubert out: 1632*be771a7bSCy Schubert Py_XDECREF(py_edns); 1633*be771a7bSCy Schubert Py_XDECREF(py_qstate); 1634*be771a7bSCy Schubert Py_XDECREF(py_opt_list_out); 1635*be771a7bSCy Schubert Py_XDECREF(py_qinfo); 1636*be771a7bSCy Schubert Py_XDECREF(py_rep); 1637*be771a7bSCy Schubert Py_XDECREF(py_repinfo); 1638*be771a7bSCy Schubert Py_XDECREF(py_region); 1639*be771a7bSCy Schubert Py_XDECREF(py_args); 1640*be771a7bSCy Schubert Py_XDECREF(py_kwargs); 1641*be771a7bSCy Schubert Py_XDECREF(result); 1642*be771a7bSCy Schubert PyGILState_Release(gstate); 1643*be771a7bSCy Schubert return res; 1644*be771a7bSCy Schubert } 1645*be771a7bSCy Schubert 1646*be771a7bSCy Schubert /* register a callback */ 1647*be771a7bSCy Schubert static int python_inplace_cb_register(enum inplace_cb_list_type type, 1648*be771a7bSCy Schubert PyObject* py_cb, struct module_env* env, int id) 1649*be771a7bSCy Schubert { 1650*be771a7bSCy Schubert int ret = inplace_cb_register(python_inplace_cb_reply_generic, 1651*be771a7bSCy Schubert type, (void*) py_cb, env, id); 1652*be771a7bSCy Schubert if (ret) Py_INCREF(py_cb); 1653*be771a7bSCy Schubert return ret; 1654*be771a7bSCy Schubert } 1655*be771a7bSCy Schubert 1656*be771a7bSCy Schubert /* Swig implementations for Python */ 1657*be771a7bSCy Schubert static int register_inplace_cb_reply(PyObject* py_cb, 1658*be771a7bSCy Schubert struct module_env* env, int id) 1659*be771a7bSCy Schubert { 1660*be771a7bSCy Schubert return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id); 1661*be771a7bSCy Schubert } 1662*be771a7bSCy Schubert static int register_inplace_cb_reply_cache(PyObject* py_cb, 1663*be771a7bSCy Schubert struct module_env* env, int id) 1664*be771a7bSCy Schubert { 1665*be771a7bSCy Schubert return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id); 1666*be771a7bSCy Schubert } 1667*be771a7bSCy Schubert static int register_inplace_cb_reply_local(PyObject* py_cb, 1668*be771a7bSCy Schubert struct module_env* env, int id) 1669*be771a7bSCy Schubert { 1670*be771a7bSCy Schubert return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id); 1671*be771a7bSCy Schubert } 1672*be771a7bSCy Schubert static int register_inplace_cb_reply_servfail(PyObject* py_cb, 1673*be771a7bSCy Schubert struct module_env* env, int id) 1674*be771a7bSCy Schubert { 1675*be771a7bSCy Schubert return python_inplace_cb_register(inplace_cb_reply_servfail, 1676*be771a7bSCy Schubert py_cb, env, id); 1677*be771a7bSCy Schubert } 1678*be771a7bSCy Schubert 1679*be771a7bSCy Schubert int python_inplace_cb_query_generic( 1680*be771a7bSCy Schubert struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate, 1681*be771a7bSCy Schubert struct sockaddr_storage* addr, socklen_t addrlen, 1682*be771a7bSCy Schubert uint8_t* zone, size_t zonelen, struct regional* region, int id, 1683*be771a7bSCy Schubert void* python_callback) 1684*be771a7bSCy Schubert { 1685*be771a7bSCy Schubert int res = 0; 1686*be771a7bSCy Schubert PyObject *func = python_callback; 1687*be771a7bSCy Schubert PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL; 1688*be771a7bSCy Schubert PyObject *py_qinfo = NULL; 1689*be771a7bSCy Schubert PyObject *py_qstate = NULL; 1690*be771a7bSCy Schubert PyObject *py_addr = NULL; 1691*be771a7bSCy Schubert PyObject *py_zone = NULL; 1692*be771a7bSCy Schubert PyObject *py_region = NULL; 1693*be771a7bSCy Schubert 1694*be771a7bSCy Schubert PyGILState_STATE gstate = PyGILState_Ensure(); 1695*be771a7bSCy Schubert 1696*be771a7bSCy Schubert py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); 1697*be771a7bSCy Schubert py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); 1698*be771a7bSCy Schubert py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0); 1699*be771a7bSCy Schubert py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen); 1700*be771a7bSCy Schubert py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); 1701*be771a7bSCy Schubert if(!(py_qinfo && py_qstate && py_addr && py_zone && py_region)) { 1702*be771a7bSCy Schubert log_err("pythonmod: swig pointer failure in python_inplace_cb_query_generic"); 1703*be771a7bSCy Schubert goto out; 1704*be771a7bSCy Schubert } 1705*be771a7bSCy Schubert py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region); 1706*be771a7bSCy Schubert py_kwargs = Py_BuildValue("{}"); 1707*be771a7bSCy Schubert if(!(py_args && py_kwargs)) { 1708*be771a7bSCy Schubert log_err("pythonmod: BuildValue failure in python_inplace_cb_query_generic"); 1709*be771a7bSCy Schubert goto out; 1710*be771a7bSCy Schubert } 1711*be771a7bSCy Schubert result = PyObject_Call(func, py_args, py_kwargs); 1712*be771a7bSCy Schubert if (result) { 1713*be771a7bSCy Schubert res = PyInt_AsLong(result); 1714*be771a7bSCy Schubert } 1715*be771a7bSCy Schubert out: 1716*be771a7bSCy Schubert Py_XDECREF(py_qinfo); 1717*be771a7bSCy Schubert Py_XDECREF(py_qstate); 1718*be771a7bSCy Schubert Py_XDECREF(py_addr); 1719*be771a7bSCy Schubert Py_XDECREF(py_zone); 1720*be771a7bSCy Schubert Py_XDECREF(py_region); 1721*be771a7bSCy Schubert 1722*be771a7bSCy Schubert Py_XDECREF(py_args); 1723*be771a7bSCy Schubert Py_XDECREF(py_kwargs); 1724*be771a7bSCy Schubert Py_XDECREF(result); 1725*be771a7bSCy Schubert 1726*be771a7bSCy Schubert PyGILState_Release(gstate); 1727*be771a7bSCy Schubert 1728*be771a7bSCy Schubert return res; 1729*be771a7bSCy Schubert } 1730*be771a7bSCy Schubert 1731*be771a7bSCy Schubert static int register_inplace_cb_query(PyObject* py_cb, 1732*be771a7bSCy Schubert struct module_env* env, int id) 1733*be771a7bSCy Schubert { 1734*be771a7bSCy Schubert int ret = inplace_cb_register(python_inplace_cb_query_generic, 1735*be771a7bSCy Schubert inplace_cb_query, (void*) py_cb, env, id); 1736*be771a7bSCy Schubert if (ret) Py_INCREF(py_cb); 1737*be771a7bSCy Schubert return ret; 1738*be771a7bSCy Schubert } 1739*be771a7bSCy Schubert 1740*be771a7bSCy Schubert int python_inplace_cb_query_response(struct module_qstate* qstate, 1741*be771a7bSCy Schubert struct dns_msg* response, int id, void* python_callback) 1742*be771a7bSCy Schubert { 1743*be771a7bSCy Schubert int res = 0; 1744*be771a7bSCy Schubert PyObject *func = python_callback; 1745*be771a7bSCy Schubert PyObject *py_qstate = NULL; 1746*be771a7bSCy Schubert PyObject *py_response = NULL; 1747*be771a7bSCy Schubert PyObject *py_args = NULL; 1748*be771a7bSCy Schubert PyObject *py_kwargs = NULL; 1749*be771a7bSCy Schubert PyObject *result = NULL; 1750*be771a7bSCy Schubert 1751*be771a7bSCy Schubert PyGILState_STATE gstate = PyGILState_Ensure(); 1752*be771a7bSCy Schubert 1753*be771a7bSCy Schubert py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); 1754*be771a7bSCy Schubert py_response = SWIG_NewPointerObj((void*) response, SWIGTYPE_p_dns_msg, 0); 1755*be771a7bSCy Schubert if(!(py_qstate && py_response)) { 1756*be771a7bSCy Schubert log_err("pythonmod: swig pointer failure in python_inplace_cb_query_response"); 1757*be771a7bSCy Schubert goto out; 1758*be771a7bSCy Schubert } 1759*be771a7bSCy Schubert py_args = Py_BuildValue("(OO)", py_qstate, py_response); 1760*be771a7bSCy Schubert py_kwargs = Py_BuildValue("{}"); 1761*be771a7bSCy Schubert if(!(py_args && py_kwargs)) { 1762*be771a7bSCy Schubert log_err("pythonmod: BuildValue failure in python_inplace_cb_query_response"); 1763*be771a7bSCy Schubert goto out; 1764*be771a7bSCy Schubert } 1765*be771a7bSCy Schubert result = PyObject_Call(func, py_args, py_kwargs); 1766*be771a7bSCy Schubert if (result) { 1767*be771a7bSCy Schubert res = PyInt_AsLong(result); 1768*be771a7bSCy Schubert } 1769*be771a7bSCy Schubert out: 1770*be771a7bSCy Schubert Py_XDECREF(py_qstate); 1771*be771a7bSCy Schubert Py_XDECREF(py_response); 1772*be771a7bSCy Schubert 1773*be771a7bSCy Schubert Py_XDECREF(py_args); 1774*be771a7bSCy Schubert Py_XDECREF(py_kwargs); 1775*be771a7bSCy Schubert Py_XDECREF(result); 1776*be771a7bSCy Schubert 1777*be771a7bSCy Schubert PyGILState_Release(gstate); 1778*be771a7bSCy Schubert 1779*be771a7bSCy Schubert return res; 1780*be771a7bSCy Schubert } 1781*be771a7bSCy Schubert 1782*be771a7bSCy Schubert static int register_inplace_cb_query_response(PyObject* py_cb, 1783*be771a7bSCy Schubert struct module_env* env, int id) 1784*be771a7bSCy Schubert { 1785*be771a7bSCy Schubert int ret = inplace_cb_register(python_inplace_cb_query_response, 1786*be771a7bSCy Schubert inplace_cb_query_response, (void*) py_cb, env, id); 1787*be771a7bSCy Schubert if (ret) Py_INCREF(py_cb); 1788*be771a7bSCy Schubert return ret; 1789*be771a7bSCy Schubert } 1790*be771a7bSCy Schubert 1791*be771a7bSCy Schubert int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate, 1792*be771a7bSCy Schubert int id, void* python_callback) 1793*be771a7bSCy Schubert { 1794*be771a7bSCy Schubert int res = 0; 1795*be771a7bSCy Schubert PyObject *func = python_callback; 1796*be771a7bSCy Schubert PyObject *py_qstate = NULL; 1797*be771a7bSCy Schubert PyObject *py_args = NULL; 1798*be771a7bSCy Schubert PyObject *py_kwargs = NULL; 1799*be771a7bSCy Schubert PyObject *result = NULL; 1800*be771a7bSCy Schubert 1801*be771a7bSCy Schubert PyGILState_STATE gstate = PyGILState_Ensure(); 1802*be771a7bSCy Schubert 1803*be771a7bSCy Schubert py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); 1804*be771a7bSCy Schubert if(!py_qstate) { 1805*be771a7bSCy Schubert log_err("pythonmod: swig pointer failure in python_inplace_cb_edns_back_parsed_call"); 1806*be771a7bSCy Schubert goto out; 1807*be771a7bSCy Schubert } 1808*be771a7bSCy Schubert py_args = Py_BuildValue("(O)", py_qstate); 1809*be771a7bSCy Schubert py_kwargs = Py_BuildValue("{}"); 1810*be771a7bSCy Schubert if(!(py_args && py_kwargs)) { 1811*be771a7bSCy Schubert log_err("pythonmod: BuildValue failure in python_inplace_cb_edns_back_parsed_call"); 1812*be771a7bSCy Schubert goto out; 1813*be771a7bSCy Schubert } 1814*be771a7bSCy Schubert result = PyObject_Call(func, py_args, py_kwargs); 1815*be771a7bSCy Schubert if (result) { 1816*be771a7bSCy Schubert res = PyInt_AsLong(result); 1817*be771a7bSCy Schubert } 1818*be771a7bSCy Schubert out: 1819*be771a7bSCy Schubert Py_XDECREF(py_qstate); 1820*be771a7bSCy Schubert 1821*be771a7bSCy Schubert Py_XDECREF(py_args); 1822*be771a7bSCy Schubert Py_XDECREF(py_kwargs); 1823*be771a7bSCy Schubert Py_XDECREF(result); 1824*be771a7bSCy Schubert 1825*be771a7bSCy Schubert PyGILState_Release(gstate); 1826*be771a7bSCy Schubert 1827*be771a7bSCy Schubert return res; 1828*be771a7bSCy Schubert } 1829*be771a7bSCy Schubert 1830*be771a7bSCy Schubert static int register_inplace_cb_edns_back_parsed_call(PyObject* py_cb, 1831*be771a7bSCy Schubert struct module_env* env, int id) 1832*be771a7bSCy Schubert { 1833*be771a7bSCy Schubert int ret = inplace_cb_register(python_inplace_cb_edns_back_parsed_call, 1834*be771a7bSCy Schubert inplace_cb_edns_back_parsed, (void*) py_cb, env, id); 1835*be771a7bSCy Schubert if (ret) Py_INCREF(py_cb); 1836*be771a7bSCy Schubert return ret; 1837*be771a7bSCy Schubert } 1838*be771a7bSCy Schubert %} 1839*be771a7bSCy Schubert /* C declarations */ 1840*be771a7bSCy Schubert int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg, 1841*be771a7bSCy Schubert struct module_env* env, int id); 1842*be771a7bSCy Schubert 1843*be771a7bSCy Schubert /* Swig declarations */ 1844*be771a7bSCy Schubert static int register_inplace_cb_reply(PyObject* py_cb, 1845*be771a7bSCy Schubert struct module_env* env, int id); 1846*be771a7bSCy Schubert static int register_inplace_cb_reply_cache(PyObject* py_cb, 1847*be771a7bSCy Schubert struct module_env* env, int id); 1848*be771a7bSCy Schubert static int register_inplace_cb_reply_local(PyObject* py_cb, 1849*be771a7bSCy Schubert struct module_env* env, int id); 1850*be771a7bSCy Schubert static int register_inplace_cb_reply_servfail(PyObject* py_cb, 1851*be771a7bSCy Schubert struct module_env* env, int id); 1852*be771a7bSCy Schubert static int register_inplace_cb_query(PyObject *py_cb, 1853*be771a7bSCy Schubert struct module_env* env, int id); 1854*be771a7bSCy Schubert static int register_inplace_cb_query_response(PyObject *py_cb, 1855*be771a7bSCy Schubert struct module_env* env, int id); 1856*be771a7bSCy Schubert static int register_inplace_cb_edns_back_parsed_call(PyObject *py_cb, 1857*be771a7bSCy Schubert struct module_env* env, int id); 1858