xref: /src/contrib/unbound/pythonmod/interface.i (revision be771a7b7f4580a30d99e41a5bb1b93a385a119d)
1afb79913SDag-Erling Smørgrav /*
2afb79913SDag-Erling Smørgrav  * interface.i: unbound python module
3afb79913SDag-Erling Smørgrav  */
44713c21aSDag-Erling Smørgrav %begin %{
54713c21aSDag-Erling Smørgrav /* store state of warning output, restored at later pop */
64713c21aSDag-Erling Smørgrav #pragma GCC diagnostic push
7e2fe7268SCy Schubert /* ignore warnings for pragma below, where for older GCC it can produce a
8e2fe7268SCy Schubert    warning if the cast-function-type warning is absent. */
9e2fe7268SCy Schubert #pragma GCC diagnostic ignored "-Wpragmas"
104713c21aSDag-Erling Smørgrav /* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
114713c21aSDag-Erling Smørgrav #pragma GCC diagnostic ignored "-Wcast-function-type"
124713c21aSDag-Erling Smørgrav %}
13afb79913SDag-Erling Smørgrav %module unboundmodule
14afb79913SDag-Erling Smørgrav %{
154713c21aSDag-Erling Smørgrav /* restore state of warning output, remove the functioncast ignore */
164713c21aSDag-Erling Smørgrav #pragma GCC diagnostic pop
17afb79913SDag-Erling Smørgrav /**
18afb79913SDag-Erling Smørgrav  * \file
19afb79913SDag-Erling Smørgrav  * This is the interface between the unbound server and a python module
20afb79913SDag-Erling Smørgrav  * called to perform operations on queries.
21afb79913SDag-Erling Smørgrav  */
22afb79913SDag-Erling Smørgrav    #include <sys/types.h>
23d60fa10fSCy Schubert    #include <time.h>
244713c21aSDag-Erling Smørgrav    #ifdef HAVE_SYS_SOCKET_H
25afb79913SDag-Erling Smørgrav    #include <sys/socket.h>
264713c21aSDag-Erling Smørgrav    #endif
274713c21aSDag-Erling Smørgrav    #ifdef HAVE_NETINET_IN_H
28afb79913SDag-Erling Smørgrav    #include <netinet/in.h>
294713c21aSDag-Erling Smørgrav    #endif
304713c21aSDag-Erling Smørgrav    #ifdef HAVE_ARPA_INET_H
31afb79913SDag-Erling Smørgrav    #include <arpa/inet.h>
324713c21aSDag-Erling Smørgrav    #endif
334713c21aSDag-Erling Smørgrav    #ifdef HAVE_NETDB_H
349c9d011eSDag-Erling Smørgrav    #include <netdb.h>
354713c21aSDag-Erling Smørgrav    #endif
364713c21aSDag-Erling Smørgrav    #ifdef HAVE_SYS_UN_H
379c9d011eSDag-Erling Smørgrav    #include <sys/un.h>
384713c21aSDag-Erling Smørgrav    #endif
39afb79913SDag-Erling Smørgrav    #include <stdarg.h>
40afb79913SDag-Erling Smørgrav    #include "config.h"
41afb79913SDag-Erling Smørgrav    #include "util/log.h"
42afb79913SDag-Erling Smørgrav    #include "util/module.h"
43afb79913SDag-Erling Smørgrav    #include "util/netevent.h"
44afb79913SDag-Erling Smørgrav    #include "util/regional.h"
45afb79913SDag-Erling Smørgrav    #include "util/config_file.h"
46afb79913SDag-Erling Smørgrav    #include "util/data/msgreply.h"
47afb79913SDag-Erling Smørgrav    #include "util/data/packed_rrset.h"
48afb79913SDag-Erling Smørgrav    #include "util/data/dname.h"
49afb79913SDag-Erling Smørgrav    #include "util/storage/lruhash.h"
50afb79913SDag-Erling Smørgrav    #include "services/cache/dns.h"
51afb79913SDag-Erling Smørgrav    #include "services/mesh.h"
52d3348d43SDag-Erling Smørgrav    #include "iterator/iter_delegpt.h"
53d3348d43SDag-Erling Smørgrav    #include "iterator/iter_hints.h"
54d3348d43SDag-Erling Smørgrav    #include "iterator/iter_utils.h"
55af3dabbfSDag-Erling Smørgrav    #include "sldns/wire2str.h"
56af3dabbfSDag-Erling Smørgrav    #include "sldns/str2wire.h"
57af3dabbfSDag-Erling Smørgrav    #include "sldns/pkthdr.h"
58afb79913SDag-Erling Smørgrav %}
59afb79913SDag-Erling Smørgrav 
60bd51c208SDag-Erling Smørgrav %include "stdint.i"  /* uint_16_t can be known type now */
61afb79913SDag-Erling Smørgrav 
62afb79913SDag-Erling Smørgrav %inline %{
63bd51c208SDag-Erling Smørgrav    /* converts [len][data][len][data][0] string to a List of labels (PyBytes) */
GetNameAsLabelList(const char * name,int len)64afb79913SDag-Erling Smørgrav    PyObject* GetNameAsLabelList(const char* name, int len) {
65afb79913SDag-Erling Smørgrav      PyObject* list;
66afb79913SDag-Erling Smørgrav      int cnt=0, i;
67afb79913SDag-Erling Smørgrav 
68afb79913SDag-Erling Smørgrav      i = 0;
69afb79913SDag-Erling Smørgrav      while (i < len) {
709c9d011eSDag-Erling Smørgrav         i += ((unsigned int)name[i]) + 1;
71afb79913SDag-Erling Smørgrav         cnt++;
72afb79913SDag-Erling Smørgrav      }
73afb79913SDag-Erling Smørgrav 
74afb79913SDag-Erling Smørgrav      list = PyList_New(cnt);
75afb79913SDag-Erling Smørgrav      i = 0; cnt = 0;
76afb79913SDag-Erling Smørgrav      while (i < len) {
779c9d011eSDag-Erling Smørgrav         char buf[LDNS_MAX_LABELLEN+1];
789c9d011eSDag-Erling Smørgrav         if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) &&
799c9d011eSDag-Erling Smørgrav                 i+(int)((unsigned int)name[i]) < len) {
809c9d011eSDag-Erling Smørgrav                 memmove(buf, name + i + 1, (unsigned int)name[i]);
819c9d011eSDag-Erling Smørgrav                 buf[(unsigned int)name[i]] = 0;
829c9d011eSDag-Erling Smørgrav                 PyList_SetItem(list, cnt, PyString_FromString(buf));
839c9d011eSDag-Erling Smørgrav         }
849c9d011eSDag-Erling Smørgrav         i += ((unsigned int)name[i]) + 1;
85afb79913SDag-Erling Smørgrav         cnt++;
86afb79913SDag-Erling Smørgrav      }
87afb79913SDag-Erling Smørgrav      return list;
88afb79913SDag-Erling Smørgrav    }
8916fd0b24SCy Schubert 
9016fd0b24SCy Schubert    /* converts an array of strings (char**) to a List of strings */
CharArrayAsStringList(char ** array,int len)9116fd0b24SCy Schubert    PyObject* CharArrayAsStringList(char** array, int len) {
9216fd0b24SCy Schubert      PyObject* list;
9316fd0b24SCy Schubert      int i;
9416fd0b24SCy Schubert 
9516fd0b24SCy Schubert      if(!array||len==0) return PyList_New(0);
9616fd0b24SCy Schubert 
9716fd0b24SCy Schubert      list = PyList_New(len);
9816fd0b24SCy Schubert      for (i=0; i < len; i++) {
9916fd0b24SCy Schubert             PyList_SET_ITEM(list, i, PyString_FromString(array[i]));
10016fd0b24SCy Schubert      }
10116fd0b24SCy Schubert      return list;
10216fd0b24SCy Schubert    }
103afb79913SDag-Erling Smørgrav %}
104afb79913SDag-Erling Smørgrav 
105afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
106afb79913SDag-Erling Smørgrav    Structure query_info
107afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
108afb79913SDag-Erling Smørgrav /* Query info */
109afb79913SDag-Erling Smørgrav %ignore query_info::qname;
110afb79913SDag-Erling Smørgrav %ignore query_info::qname_len;
111afb79913SDag-Erling Smørgrav 
112afb79913SDag-Erling Smørgrav 
113afb79913SDag-Erling Smørgrav struct query_info {
114afb79913SDag-Erling Smørgrav    %immutable;
115afb79913SDag-Erling Smørgrav    char* qname;
116afb79913SDag-Erling Smørgrav    size_t qname_len;
117afb79913SDag-Erling Smørgrav    uint16_t qtype;
118afb79913SDag-Erling Smørgrav    uint16_t qclass;
119afb79913SDag-Erling Smørgrav    %mutable;
120afb79913SDag-Erling Smørgrav };
121afb79913SDag-Erling Smørgrav 
122afb79913SDag-Erling Smørgrav %inline %{
123afb79913SDag-Erling Smørgrav    enum enum_rr_class  {
124afb79913SDag-Erling Smørgrav       RR_CLASS_IN = 1,
125afb79913SDag-Erling Smørgrav       RR_CLASS_CH = 3,
126afb79913SDag-Erling Smørgrav       RR_CLASS_HS = 4,
127afb79913SDag-Erling Smørgrav       RR_CLASS_NONE = 254,
128afb79913SDag-Erling Smørgrav       RR_CLASS_ANY = 255,
129afb79913SDag-Erling Smørgrav    };
130afb79913SDag-Erling Smørgrav 
131afb79913SDag-Erling Smørgrav    enum enum_rr_type {
132afb79913SDag-Erling Smørgrav       RR_TYPE_A = 1,
133afb79913SDag-Erling Smørgrav       RR_TYPE_NS = 2,
134afb79913SDag-Erling Smørgrav       RR_TYPE_MD = 3,
135afb79913SDag-Erling Smørgrav       RR_TYPE_MF = 4,
136afb79913SDag-Erling Smørgrav       RR_TYPE_CNAME = 5,
137afb79913SDag-Erling Smørgrav       RR_TYPE_SOA = 6,
138afb79913SDag-Erling Smørgrav       RR_TYPE_MB = 7,
139afb79913SDag-Erling Smørgrav       RR_TYPE_MG = 8,
140afb79913SDag-Erling Smørgrav       RR_TYPE_MR = 9,
141afb79913SDag-Erling Smørgrav       RR_TYPE_NULL = 10,
142afb79913SDag-Erling Smørgrav       RR_TYPE_WKS = 11,
143afb79913SDag-Erling Smørgrav       RR_TYPE_PTR = 12,
144afb79913SDag-Erling Smørgrav       RR_TYPE_HINFO = 13,
145afb79913SDag-Erling Smørgrav       RR_TYPE_MINFO = 14,
146afb79913SDag-Erling Smørgrav       RR_TYPE_MX = 15,
147afb79913SDag-Erling Smørgrav       RR_TYPE_TXT = 16,
148afb79913SDag-Erling Smørgrav       RR_TYPE_RP = 17,
149afb79913SDag-Erling Smørgrav       RR_TYPE_AFSDB = 18,
150afb79913SDag-Erling Smørgrav       RR_TYPE_X25 = 19,
151afb79913SDag-Erling Smørgrav       RR_TYPE_ISDN = 20,
152afb79913SDag-Erling Smørgrav       RR_TYPE_RT = 21,
153afb79913SDag-Erling Smørgrav       RR_TYPE_NSAP = 22,
154afb79913SDag-Erling Smørgrav       RR_TYPE_NSAP_PTR = 23,
155afb79913SDag-Erling Smørgrav       RR_TYPE_SIG = 24,
156afb79913SDag-Erling Smørgrav       RR_TYPE_KEY = 25,
157afb79913SDag-Erling Smørgrav       RR_TYPE_PX = 26,
158afb79913SDag-Erling Smørgrav       RR_TYPE_GPOS = 27,
159afb79913SDag-Erling Smørgrav       RR_TYPE_AAAA = 28,
160afb79913SDag-Erling Smørgrav       RR_TYPE_LOC = 29,
161afb79913SDag-Erling Smørgrav       RR_TYPE_NXT = 30,
162afb79913SDag-Erling Smørgrav       RR_TYPE_EID = 31,
163afb79913SDag-Erling Smørgrav       RR_TYPE_NIMLOC = 32,
164afb79913SDag-Erling Smørgrav       RR_TYPE_SRV = 33,
165afb79913SDag-Erling Smørgrav       RR_TYPE_ATMA = 34,
166afb79913SDag-Erling Smørgrav       RR_TYPE_NAPTR = 35,
167afb79913SDag-Erling Smørgrav       RR_TYPE_KX = 36,
168afb79913SDag-Erling Smørgrav       RR_TYPE_CERT = 37,
169afb79913SDag-Erling Smørgrav       RR_TYPE_A6 = 38,
170afb79913SDag-Erling Smørgrav       RR_TYPE_DNAME = 39,
171afb79913SDag-Erling Smørgrav       RR_TYPE_SINK = 40,
172afb79913SDag-Erling Smørgrav       RR_TYPE_OPT = 41,
173afb79913SDag-Erling Smørgrav       RR_TYPE_APL = 42,
174afb79913SDag-Erling Smørgrav       RR_TYPE_DS = 43,
175afb79913SDag-Erling Smørgrav       RR_TYPE_SSHFP = 44,
176afb79913SDag-Erling Smørgrav       RR_TYPE_IPSECKEY = 45,
177afb79913SDag-Erling Smørgrav       RR_TYPE_RRSIG = 46,
178afb79913SDag-Erling Smørgrav       RR_TYPE_NSEC = 47,
179afb79913SDag-Erling Smørgrav       RR_TYPE_DNSKEY = 48,
180afb79913SDag-Erling Smørgrav       RR_TYPE_DHCID = 49,
181afb79913SDag-Erling Smørgrav       RR_TYPE_NSEC3 = 50,
182afb79913SDag-Erling Smørgrav       RR_TYPE_NSEC3PARAMS = 51,
183afb79913SDag-Erling Smørgrav       RR_TYPE_UINFO = 100,
184afb79913SDag-Erling Smørgrav       RR_TYPE_UID = 101,
185afb79913SDag-Erling Smørgrav       RR_TYPE_GID = 102,
186afb79913SDag-Erling Smørgrav       RR_TYPE_UNSPEC = 103,
187afb79913SDag-Erling Smørgrav       RR_TYPE_TSIG = 250,
188afb79913SDag-Erling Smørgrav       RR_TYPE_IXFR = 251,
189afb79913SDag-Erling Smørgrav       RR_TYPE_AXFR = 252,
190afb79913SDag-Erling Smørgrav       RR_TYPE_MAILB = 253,
191afb79913SDag-Erling Smørgrav       RR_TYPE_MAILA = 254,
192afb79913SDag-Erling Smørgrav       RR_TYPE_ANY = 255,
193afb79913SDag-Erling Smørgrav       RR_TYPE_DLV = 32769,
194afb79913SDag-Erling Smørgrav    };
195afb79913SDag-Erling Smørgrav 
_get_qname(struct query_info * q)196afb79913SDag-Erling Smørgrav    PyObject* _get_qname(struct query_info* q) {
197d433784aSDag-Erling Smørgrav       return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len);
198afb79913SDag-Erling Smørgrav    }
199afb79913SDag-Erling Smørgrav 
_get_qname_components(struct query_info * q)200afb79913SDag-Erling Smørgrav    PyObject* _get_qname_components(struct query_info* q) {
201afb79913SDag-Erling Smørgrav       return GetNameAsLabelList((const char*)q->qname, q->qname_len);
202afb79913SDag-Erling Smørgrav    }
203afb79913SDag-Erling Smørgrav %}
204afb79913SDag-Erling Smørgrav 
205afb79913SDag-Erling Smørgrav %inline %{
dnameAsStr(PyObject * dname)2069c9d011eSDag-Erling Smørgrav    PyObject* dnameAsStr(PyObject* dname) {
20744bab727SCy Schubert        char buf[LDNS_MAX_DOMAINLEN];
208afb79913SDag-Erling Smørgrav        buf[0] = '\0';
2099c9d011eSDag-Erling Smørgrav        dname_str((uint8_t*)PyBytes_AsString(dname), buf);
2109c9d011eSDag-Erling Smørgrav        return PyString_FromString(buf);
211afb79913SDag-Erling Smørgrav    }
212afb79913SDag-Erling Smørgrav %}
213afb79913SDag-Erling Smørgrav 
214afb79913SDag-Erling Smørgrav %extend query_info {
215afb79913SDag-Erling Smørgrav    %pythoncode %{
21679dd93c1SDag-Erling Smørgrav         def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
217366b94c4SDag-Erling Smørgrav         qtype_str = property(_get_qtype_str)
218afb79913SDag-Erling Smørgrav 
21979dd93c1SDag-Erling Smørgrav         def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
220366b94c4SDag-Erling Smørgrav         qclass_str = property(_get_qclass_str)
221afb79913SDag-Erling Smørgrav 
222366b94c4SDag-Erling Smørgrav         qname = property(_unboundmodule._get_qname)
223afb79913SDag-Erling Smørgrav 
224366b94c4SDag-Erling Smørgrav         qname_list = property(_unboundmodule._get_qname_components)
225afb79913SDag-Erling Smørgrav 
226afb79913SDag-Erling Smørgrav         def _get_qname_str(self): return dnameAsStr(self.qname)
227366b94c4SDag-Erling Smørgrav         qname_str = property(_get_qname_str)
228afb79913SDag-Erling Smørgrav    %}
229afb79913SDag-Erling Smørgrav }
230afb79913SDag-Erling Smørgrav 
231afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
232afb79913SDag-Erling Smørgrav    Structure packed_rrset_key
233afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
234afb79913SDag-Erling Smørgrav %ignore packed_rrset_key::dname;
235afb79913SDag-Erling Smørgrav %ignore packed_rrset_key::dname_len;
236afb79913SDag-Erling Smørgrav 
237afb79913SDag-Erling Smørgrav /* RRsets */
238afb79913SDag-Erling Smørgrav struct packed_rrset_key {
239afb79913SDag-Erling Smørgrav    %immutable;
240afb79913SDag-Erling Smørgrav    char*    dname;
241afb79913SDag-Erling Smørgrav    size_t   dname_len;
242afb79913SDag-Erling Smørgrav    uint32_t flags;
243bd51c208SDag-Erling Smørgrav    uint16_t type;  /* rrset type in network format */
244bd51c208SDag-Erling Smørgrav    uint16_t rrset_class;  /* rrset class in network format */
245afb79913SDag-Erling Smørgrav    %mutable;
246afb79913SDag-Erling Smørgrav };
247afb79913SDag-Erling Smørgrav 
248bd51c208SDag-Erling Smørgrav /**
249bd51c208SDag-Erling Smørgrav  * This subroutine converts values between the host and network byte order.
250bd51c208SDag-Erling Smørgrav  * Specifically, ntohs() converts 16-bit quantities from network byte order to
251bd51c208SDag-Erling Smørgrav  * host byte order.
252bd51c208SDag-Erling Smørgrav  */
253afb79913SDag-Erling Smørgrav uint16_t ntohs(uint16_t netshort);
254afb79913SDag-Erling Smørgrav 
255afb79913SDag-Erling Smørgrav %inline %{
256afb79913SDag-Erling Smørgrav    PyObject* _get_dname(struct packed_rrset_key* k) {
257d433784aSDag-Erling Smørgrav       return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len);
258afb79913SDag-Erling Smørgrav    }
259afb79913SDag-Erling Smørgrav    PyObject* _get_dname_components(struct packed_rrset_key* k) {
260afb79913SDag-Erling Smørgrav       return GetNameAsLabelList((char*)k->dname, k->dname_len);
261afb79913SDag-Erling Smørgrav    }
262afb79913SDag-Erling Smørgrav %}
263afb79913SDag-Erling Smørgrav 
264afb79913SDag-Erling Smørgrav %extend packed_rrset_key {
265afb79913SDag-Erling Smørgrav    %pythoncode %{
26679dd93c1SDag-Erling Smørgrav         def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
267366b94c4SDag-Erling Smørgrav         type_str = property(_get_type_str)
268afb79913SDag-Erling Smørgrav 
26979dd93c1SDag-Erling Smørgrav         def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
270366b94c4SDag-Erling Smørgrav         rrset_class_str = property(_get_class_str)
271afb79913SDag-Erling Smørgrav 
272366b94c4SDag-Erling Smørgrav         dname = property(_unboundmodule._get_dname)
273afb79913SDag-Erling Smørgrav 
274366b94c4SDag-Erling Smørgrav         dname_list = property(_unboundmodule._get_dname_components)
275afb79913SDag-Erling Smørgrav 
276afb79913SDag-Erling Smørgrav         def _get_dname_str(self): return dnameAsStr(self.dname)
277366b94c4SDag-Erling Smørgrav         dname_str = property(_get_dname_str)
278afb79913SDag-Erling Smørgrav    %}
279afb79913SDag-Erling Smørgrav }
280afb79913SDag-Erling Smørgrav 
281afb79913SDag-Erling Smørgrav #if defined(SWIGWORDSIZE64)
282fbdb9ac8SDag-Erling Smørgrav typedef long int                rrset_id_type;
283afb79913SDag-Erling Smørgrav #else
284fbdb9ac8SDag-Erling Smørgrav typedef long long int           rrset_id_type;
285afb79913SDag-Erling Smørgrav #endif
286afb79913SDag-Erling Smørgrav 
287afb79913SDag-Erling Smørgrav struct ub_packed_rrset_key {
288afb79913SDag-Erling Smørgrav    struct lruhash_entry entry;
289fbdb9ac8SDag-Erling Smørgrav    rrset_id_type id;
290afb79913SDag-Erling Smørgrav    struct packed_rrset_key rk;
291afb79913SDag-Erling Smørgrav };
292afb79913SDag-Erling Smørgrav 
293afb79913SDag-Erling Smørgrav struct lruhash_entry {
294fbdb9ac8SDag-Erling Smørgrav   lock_rw_type lock;
295afb79913SDag-Erling Smørgrav   struct lruhash_entry* overflow_next;
296afb79913SDag-Erling Smørgrav   struct lruhash_entry* lru_next;
297afb79913SDag-Erling Smørgrav   struct lruhash_entry* lru_prev;
298fbdb9ac8SDag-Erling Smørgrav   hashvalue_type hash;
299afb79913SDag-Erling Smørgrav   void* key;
300afb79913SDag-Erling Smørgrav   struct packed_rrset_data* data;
301afb79913SDag-Erling Smørgrav };
302afb79913SDag-Erling Smørgrav 
303afb79913SDag-Erling Smørgrav %ignore packed_rrset_data::rr_len;
304afb79913SDag-Erling Smørgrav %ignore packed_rrset_data::rr_ttl;
305afb79913SDag-Erling Smørgrav %ignore packed_rrset_data::rr_data;
306afb79913SDag-Erling Smørgrav 
307afb79913SDag-Erling Smørgrav struct packed_rrset_data {
308bd51c208SDag-Erling Smørgrav   /* TTL (in seconds like time()) */
309bd51c208SDag-Erling Smørgrav   uint32_t ttl;
310afb79913SDag-Erling Smørgrav 
311bd51c208SDag-Erling Smørgrav   /* number of rrs */
312bd51c208SDag-Erling Smørgrav   size_t count;
313bd51c208SDag-Erling Smørgrav   /* number of rrsigs */
314bd51c208SDag-Erling Smørgrav   size_t rrsig_count;
315afb79913SDag-Erling Smørgrav 
316afb79913SDag-Erling Smørgrav   enum rrset_trust trust;
317afb79913SDag-Erling Smørgrav   enum sec_status security;
318afb79913SDag-Erling Smørgrav 
319bd51c208SDag-Erling Smørgrav   /* length of every rr's rdata */
320bd51c208SDag-Erling Smørgrav   size_t* rr_len;
321bd51c208SDag-Erling Smørgrav   /* ttl of every rr */
322bd51c208SDag-Erling Smørgrav   uint32_t *rr_ttl;
323bd51c208SDag-Erling Smørgrav   /* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in
324bd51c208SDag-Erling Smørgrav    * uncompressed wireformat. */
325bd51c208SDag-Erling Smørgrav   uint8_t** rr_data;
326afb79913SDag-Erling Smørgrav };
327afb79913SDag-Erling Smørgrav 
328afb79913SDag-Erling Smørgrav %pythoncode %{
329afb79913SDag-Erling Smørgrav     class RRSetData_RRLen:
330afb79913SDag-Erling Smørgrav         def __init__(self, obj): self.obj = obj
331afb79913SDag-Erling Smørgrav         def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index)
3324cb89f2eSCy Schubert         def __len__(self): return self.obj.count + self.obj.rrsig_count
333afb79913SDag-Erling Smørgrav     class RRSetData_RRTTL:
334afb79913SDag-Erling Smørgrav         def __init__(self, obj): self.obj = obj
335afb79913SDag-Erling Smørgrav         def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index)
336afb79913SDag-Erling Smørgrav         def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value)
3374cb89f2eSCy Schubert         def __len__(self): return self.obj.count + self.obj.rrsig_count
338afb79913SDag-Erling Smørgrav     class RRSetData_RRData:
339afb79913SDag-Erling Smørgrav         def __init__(self, obj): self.obj = obj
340afb79913SDag-Erling Smørgrav         def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index)
3414cb89f2eSCy Schubert         def __len__(self): return self.obj.count + self.obj.rrsig_count
342afb79913SDag-Erling Smørgrav %}
343afb79913SDag-Erling Smørgrav 
344afb79913SDag-Erling Smørgrav %inline %{
345afb79913SDag-Erling Smørgrav    PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
346afb79913SDag-Erling Smørgrav      if ((d != NULL) && (idx >= 0) &&
347afb79913SDag-Erling Smørgrav              ((size_t)idx < (d->count+d->rrsig_count)))
348afb79913SDag-Erling Smørgrav         return PyInt_FromLong(d->rr_len[idx]);
349afb79913SDag-Erling Smørgrav      return Py_None;
350afb79913SDag-Erling Smørgrav    }
351afb79913SDag-Erling Smørgrav    void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
352afb79913SDag-Erling Smørgrav    {
353afb79913SDag-Erling Smørgrav      if ((d != NULL) && (idx >= 0) &&
354afb79913SDag-Erling Smørgrav              ((size_t)idx < (d->count+d->rrsig_count)))
355afb79913SDag-Erling Smørgrav         d->rr_ttl[idx] = ttl;
356afb79913SDag-Erling Smørgrav    }
357afb79913SDag-Erling Smørgrav    PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
358afb79913SDag-Erling Smørgrav      if ((d != NULL) && (idx >= 0) &&
359afb79913SDag-Erling Smørgrav              ((size_t)idx < (d->count+d->rrsig_count)))
360afb79913SDag-Erling Smørgrav         return PyInt_FromLong(d->rr_ttl[idx]);
361afb79913SDag-Erling Smørgrav      return Py_None;
362afb79913SDag-Erling Smørgrav    }
363afb79913SDag-Erling Smørgrav    PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
364afb79913SDag-Erling Smørgrav      if ((d != NULL) && (idx >= 0) &&
365afb79913SDag-Erling Smørgrav              ((size_t)idx < (d->count+d->rrsig_count)))
366d433784aSDag-Erling Smørgrav         return PyBytes_FromStringAndSize((char*)d->rr_data[idx],
367afb79913SDag-Erling Smørgrav                 d->rr_len[idx]);
368afb79913SDag-Erling Smørgrav      return Py_None;
369afb79913SDag-Erling Smørgrav    }
370afb79913SDag-Erling Smørgrav %}
371afb79913SDag-Erling Smørgrav 
372afb79913SDag-Erling Smørgrav %extend packed_rrset_data {
373afb79913SDag-Erling Smørgrav    %pythoncode %{
374afb79913SDag-Erling Smørgrav         def _get_data_rr_len(self): return RRSetData_RRLen(self)
375366b94c4SDag-Erling Smørgrav         rr_len = property(_get_data_rr_len)
376afb79913SDag-Erling Smørgrav         def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
377366b94c4SDag-Erling Smørgrav         rr_ttl = property(_get_data_rr_ttl)
378afb79913SDag-Erling Smørgrav         def _get_data_rr_data(self): return RRSetData_RRData(self)
379366b94c4SDag-Erling Smørgrav         rr_data = property(_get_data_rr_data)
380afb79913SDag-Erling Smørgrav    %}
381afb79913SDag-Erling Smørgrav }
382afb79913SDag-Erling Smørgrav 
383afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
384afb79913SDag-Erling Smørgrav    Structure reply_info
385afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
386afb79913SDag-Erling Smørgrav /* Messages */
387afb79913SDag-Erling Smørgrav %ignore reply_info::rrsets;
388afb79913SDag-Erling Smørgrav %ignore reply_info::ref;
389afb79913SDag-Erling Smørgrav 
390afb79913SDag-Erling Smørgrav struct reply_info {
391afb79913SDag-Erling Smørgrav    uint16_t flags;
392afb79913SDag-Erling Smørgrav    uint16_t qdcount;
393afb79913SDag-Erling Smørgrav    uint32_t ttl;
394afb79913SDag-Erling Smørgrav    uint32_t prefetch_ttl;
395afb79913SDag-Erling Smørgrav 
396afb79913SDag-Erling Smørgrav    uint16_t authoritative;
397afb79913SDag-Erling Smørgrav    enum sec_status security;
398afb79913SDag-Erling Smørgrav 
399afb79913SDag-Erling Smørgrav    size_t an_numrrsets;
400afb79913SDag-Erling Smørgrav    size_t ns_numrrsets;
401afb79913SDag-Erling Smørgrav    size_t ar_numrrsets;
402bd51c208SDag-Erling Smørgrav    size_t rrset_count;  /* an_numrrsets + ns_numrrsets + ar_numrrsets */
403afb79913SDag-Erling Smørgrav 
404afb79913SDag-Erling Smørgrav    struct ub_packed_rrset_key** rrsets;
405bd51c208SDag-Erling Smørgrav    struct rrset_ref ref[1];  /* ? */
406afb79913SDag-Erling Smørgrav };
407afb79913SDag-Erling Smørgrav 
408afb79913SDag-Erling Smørgrav struct rrset_ref {
409afb79913SDag-Erling Smørgrav    struct ub_packed_rrset_key* key;
410fbdb9ac8SDag-Erling Smørgrav    rrset_id_type id;
411afb79913SDag-Erling Smørgrav };
412afb79913SDag-Erling Smørgrav 
413afb79913SDag-Erling Smørgrav struct dns_msg {
414afb79913SDag-Erling Smørgrav    struct query_info qinfo;
415afb79913SDag-Erling Smørgrav    struct reply_info *rep;
416afb79913SDag-Erling Smørgrav };
417afb79913SDag-Erling Smørgrav 
418afb79913SDag-Erling Smørgrav %pythoncode %{
419afb79913SDag-Erling Smørgrav     class ReplyInfo_RRSet:
420afb79913SDag-Erling Smørgrav         def __init__(self, obj): self.obj = obj
421afb79913SDag-Erling Smørgrav         def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index)
4224cb89f2eSCy Schubert         def __len__(self): return self.obj.rrset_count
423afb79913SDag-Erling Smørgrav 
424afb79913SDag-Erling Smørgrav     class ReplyInfo_Ref:
425afb79913SDag-Erling Smørgrav         def __init__(self, obj): self.obj = obj
426afb79913SDag-Erling Smørgrav         def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index)
4274cb89f2eSCy Schubert         def __len__(self): return self.obj.rrset_count
428afb79913SDag-Erling Smørgrav %}
429afb79913SDag-Erling Smørgrav 
430afb79913SDag-Erling Smørgrav %inline %{
431afb79913SDag-Erling Smørgrav    struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) {
432afb79913SDag-Erling Smørgrav      if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count))
433afb79913SDag-Erling Smørgrav         return r->rrsets[idx];
434afb79913SDag-Erling Smørgrav      return NULL;
435afb79913SDag-Erling Smørgrav    }
436afb79913SDag-Erling Smørgrav 
437afb79913SDag-Erling Smørgrav    struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
438afb79913SDag-Erling Smørgrav      if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) {
439bd51c208SDag-Erling Smørgrav /* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */
440afb79913SDag-Erling Smørgrav              return &(r->ref[idx]);
441bd51c208SDag-Erling Smørgrav /*        return &(r->ref[idx]); */
442afb79913SDag-Erling Smørgrav      }
443bd51c208SDag-Erling Smørgrav /* printf("_rrset_ref_get: NULL\n"); */
444afb79913SDag-Erling Smørgrav      return NULL;
445afb79913SDag-Erling Smørgrav    }
446afb79913SDag-Erling Smørgrav %}
447afb79913SDag-Erling Smørgrav 
448afb79913SDag-Erling Smørgrav %extend reply_info {
449afb79913SDag-Erling Smørgrav    %pythoncode %{
450afb79913SDag-Erling Smørgrav         def _rrset_ref_get(self): return ReplyInfo_Ref(self)
451366b94c4SDag-Erling Smørgrav         ref = property(_rrset_ref_get)
452afb79913SDag-Erling Smørgrav 
453afb79913SDag-Erling Smørgrav         def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
454366b94c4SDag-Erling Smørgrav         rrsets = property(_rrset_rrsets_get)
455afb79913SDag-Erling Smørgrav    %}
456afb79913SDag-Erling Smørgrav }
457afb79913SDag-Erling Smørgrav 
458afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
4599c9d011eSDag-Erling Smørgrav    Structure sockaddr_storage
4609c9d011eSDag-Erling Smørgrav  * ************************************************************************************ */
4619c9d011eSDag-Erling Smørgrav 
4629c9d011eSDag-Erling Smørgrav struct sockaddr_storage {};
4639c9d011eSDag-Erling Smørgrav 
4649c9d011eSDag-Erling Smørgrav %inline %{
4659c9d011eSDag-Erling Smørgrav     static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) {
4669c9d011eSDag-Erling Smørgrav         if (ss == NULL) {
4679c9d011eSDag-Erling Smørgrav             return 0;
4689c9d011eSDag-Erling Smørgrav         }
4699c9d011eSDag-Erling Smørgrav 
4709c9d011eSDag-Erling Smørgrav         switch (ss->ss_family) {
4719c9d011eSDag-Erling Smørgrav         case AF_INET:  return sizeof(struct sockaddr_in);
4729c9d011eSDag-Erling Smørgrav         case AF_INET6: return sizeof(struct sockaddr_in6);
4734713c21aSDag-Erling Smørgrav #ifdef HAVE_SYS_UN_H
4749c9d011eSDag-Erling Smørgrav         case AF_UNIX:  return sizeof(struct sockaddr_un);
4754713c21aSDag-Erling Smørgrav #endif
4769c9d011eSDag-Erling Smørgrav         default:
4779c9d011eSDag-Erling Smørgrav             return 0;
4789c9d011eSDag-Erling Smørgrav         }
4799c9d011eSDag-Erling Smørgrav     }
4809c9d011eSDag-Erling Smørgrav 
4819c9d011eSDag-Erling Smørgrav     PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) {
4829c9d011eSDag-Erling Smørgrav         if (ss == NULL) {
4839c9d011eSDag-Erling Smørgrav             return Py_None;
4849c9d011eSDag-Erling Smørgrav         }
4859c9d011eSDag-Erling Smørgrav 
4869c9d011eSDag-Erling Smørgrav         switch (ss->ss_family) {
4879c9d011eSDag-Erling Smørgrav         case AF_INET:  return PyUnicode_FromString("ip4");
4889c9d011eSDag-Erling Smørgrav         case AF_INET6: return PyUnicode_FromString("ip6");
4899c9d011eSDag-Erling Smørgrav         case AF_UNIX:  return PyUnicode_FromString("unix");
4909c9d011eSDag-Erling Smørgrav         default:
4919c9d011eSDag-Erling Smørgrav             return Py_None;
4929c9d011eSDag-Erling Smørgrav         }
4939c9d011eSDag-Erling Smørgrav     }
4949c9d011eSDag-Erling Smørgrav 
4959c9d011eSDag-Erling Smørgrav     PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) {
4969c9d011eSDag-Erling Smørgrav         const struct sockaddr *sa;
4979c9d011eSDag-Erling Smørgrav         size_t sa_len;
4989c9d011eSDag-Erling Smørgrav         char name[NI_MAXHOST] = {0};
4999c9d011eSDag-Erling Smørgrav 
5009c9d011eSDag-Erling Smørgrav         if (ss == NULL) {
5019c9d011eSDag-Erling Smørgrav             return Py_None;
5029c9d011eSDag-Erling Smørgrav         }
5039c9d011eSDag-Erling Smørgrav 
5049c9d011eSDag-Erling Smørgrav         sa = (struct sockaddr *)ss;
5059c9d011eSDag-Erling Smørgrav         sa_len = _sockaddr_storage_len(ss);
5069c9d011eSDag-Erling Smørgrav         if (sa_len == 0) {
5079c9d011eSDag-Erling Smørgrav             return Py_None;
5089c9d011eSDag-Erling Smørgrav         }
5099c9d011eSDag-Erling Smørgrav 
5109c9d011eSDag-Erling Smørgrav         if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) {
5119c9d011eSDag-Erling Smørgrav             return Py_None;
5129c9d011eSDag-Erling Smørgrav         }
5139c9d011eSDag-Erling Smørgrav 
5149c9d011eSDag-Erling Smørgrav         return PyUnicode_FromString(name);
5159c9d011eSDag-Erling Smørgrav     }
5169c9d011eSDag-Erling Smørgrav 
5179c9d011eSDag-Erling Smørgrav     PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) {
5189c9d011eSDag-Erling Smørgrav         size_t sa_len;
5199c9d011eSDag-Erling Smørgrav 
5209c9d011eSDag-Erling Smørgrav         if (ss == NULL) {
5219c9d011eSDag-Erling Smørgrav             return Py_None;
5229c9d011eSDag-Erling Smørgrav         }
5239c9d011eSDag-Erling Smørgrav 
5249c9d011eSDag-Erling Smørgrav         sa_len = _sockaddr_storage_len(ss);
5259c9d011eSDag-Erling Smørgrav         if (sa_len == 0) {
5269c9d011eSDag-Erling Smørgrav             return Py_None;
5279c9d011eSDag-Erling Smørgrav         }
5289c9d011eSDag-Erling Smørgrav 
5299c9d011eSDag-Erling Smørgrav         if (ss->ss_family == AF_INET) {
5309c9d011eSDag-Erling Smørgrav             const struct sockaddr_in *sa = (struct sockaddr_in *)ss;
5319c9d011eSDag-Erling Smørgrav             const struct in_addr *raw = (struct in_addr *)&sa->sin_addr;
5329c9d011eSDag-Erling Smørgrav             return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
5339c9d011eSDag-Erling Smørgrav         }
5349c9d011eSDag-Erling Smørgrav 
5359c9d011eSDag-Erling Smørgrav         if (ss->ss_family == AF_INET6) {
5369c9d011eSDag-Erling Smørgrav             const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
5379c9d011eSDag-Erling Smørgrav             const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr;
5389c9d011eSDag-Erling Smørgrav             return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
5399c9d011eSDag-Erling Smørgrav         }
5409c9d011eSDag-Erling Smørgrav 
5414713c21aSDag-Erling Smørgrav #ifdef HAVE_SYS_UN_H
5429c9d011eSDag-Erling Smørgrav         if (ss->ss_family == AF_UNIX) {
5439c9d011eSDag-Erling Smørgrav             const struct sockaddr_un *sa = (struct sockaddr_un *)ss;
5449c9d011eSDag-Erling Smørgrav             return PyBytes_FromString(sa->sun_path);
5459c9d011eSDag-Erling Smørgrav         }
5464713c21aSDag-Erling Smørgrav #endif
5479c9d011eSDag-Erling Smørgrav 
5489c9d011eSDag-Erling Smørgrav         return Py_None;
5499c9d011eSDag-Erling Smørgrav     }
5509c9d011eSDag-Erling Smørgrav 
5519c9d011eSDag-Erling Smørgrav     PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
5529c9d011eSDag-Erling Smørgrav         if (ss == NULL) {
5539c9d011eSDag-Erling Smørgrav             return Py_None;
5549c9d011eSDag-Erling Smørgrav         }
5559c9d011eSDag-Erling Smørgrav 
5569c9d011eSDag-Erling Smørgrav         if (ss->ss_family == AF_INET) {
5579c9d011eSDag-Erling Smørgrav             const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
5589c9d011eSDag-Erling Smørgrav             return PyInt_FromLong(ntohs(sa4->sin_port));
5599c9d011eSDag-Erling Smørgrav         }
5609c9d011eSDag-Erling Smørgrav 
5619c9d011eSDag-Erling Smørgrav         if (ss->ss_family == AF_INET6) {
5629c9d011eSDag-Erling Smørgrav             const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
5639c9d011eSDag-Erling Smørgrav             return PyInt_FromLong(ntohs(sa6->sin6_port));
5649c9d011eSDag-Erling Smørgrav         }
5659c9d011eSDag-Erling Smørgrav 
5669c9d011eSDag-Erling Smørgrav         return Py_None;
5679c9d011eSDag-Erling Smørgrav     }
5689c9d011eSDag-Erling Smørgrav 
5699c9d011eSDag-Erling Smørgrav     PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
5709c9d011eSDag-Erling Smørgrav         const struct sockaddr_in6 *sa6;
5719c9d011eSDag-Erling Smørgrav 
5729c9d011eSDag-Erling Smørgrav         if (ss == NULL || ss->ss_family != AF_INET6) {
5739c9d011eSDag-Erling Smørgrav             return Py_None;
5749c9d011eSDag-Erling Smørgrav         }
5759c9d011eSDag-Erling Smørgrav 
5769c9d011eSDag-Erling Smørgrav         sa6 = (struct sockaddr_in6 *)ss;
5779c9d011eSDag-Erling Smørgrav         return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
5789c9d011eSDag-Erling Smørgrav     }
5799c9d011eSDag-Erling Smørgrav 
5809c9d011eSDag-Erling Smørgrav     PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
5819c9d011eSDag-Erling Smørgrav         const struct sockaddr_in6 *sa6;
5829c9d011eSDag-Erling Smørgrav 
5839c9d011eSDag-Erling Smørgrav         if (ss == NULL || ss->ss_family != AF_INET6) {
5849c9d011eSDag-Erling Smørgrav             return Py_None;
5859c9d011eSDag-Erling Smørgrav         }
5869c9d011eSDag-Erling Smørgrav 
5879c9d011eSDag-Erling Smørgrav         sa6 = (struct sockaddr_in6 *)ss;
5889c9d011eSDag-Erling Smørgrav         return PyInt_FromLong(ntohl(sa6->sin6_scope_id));
5899c9d011eSDag-Erling Smørgrav     }
5909c9d011eSDag-Erling Smørgrav %}
5919c9d011eSDag-Erling Smørgrav 
5929c9d011eSDag-Erling Smørgrav %extend sockaddr_storage {
5939c9d011eSDag-Erling Smørgrav    %pythoncode %{
5949c9d011eSDag-Erling Smørgrav         def _family_get(self): return _sockaddr_storage_family(self)
595366b94c4SDag-Erling Smørgrav         family = property(_family_get)
5969c9d011eSDag-Erling Smørgrav 
5979c9d011eSDag-Erling Smørgrav         def _addr_get(self): return _sockaddr_storage_addr(self)
598366b94c4SDag-Erling Smørgrav         addr = property(_addr_get)
5999c9d011eSDag-Erling Smørgrav 
6009c9d011eSDag-Erling Smørgrav         def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self)
601366b94c4SDag-Erling Smørgrav         raw_addr = property(_raw_addr_get)
6029c9d011eSDag-Erling Smørgrav 
6039c9d011eSDag-Erling Smørgrav         def _port_get(self): return _sockaddr_storage_port(self)
604366b94c4SDag-Erling Smørgrav         port = property(_port_get)
6059c9d011eSDag-Erling Smørgrav 
6069c9d011eSDag-Erling Smørgrav         def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self)
607366b94c4SDag-Erling Smørgrav         flowinfo = property(_flowinfo_get)
6089c9d011eSDag-Erling Smørgrav 
6099c9d011eSDag-Erling Smørgrav         def _scope_id_get(self): return _sockaddr_storage_scope_id(self)
610366b94c4SDag-Erling Smørgrav         scope_id = property(_scope_id_get)
6119c9d011eSDag-Erling Smørgrav    %}
6129c9d011eSDag-Erling Smørgrav }
6139c9d011eSDag-Erling Smørgrav 
6149c9d011eSDag-Erling Smørgrav /* ************************************************************************************ *
615afb79913SDag-Erling Smørgrav    Structure mesh_state
616afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
617afb79913SDag-Erling Smørgrav struct mesh_state {
618afb79913SDag-Erling Smørgrav    struct mesh_reply* reply_list;
619afb79913SDag-Erling Smørgrav };
620afb79913SDag-Erling Smørgrav 
621afb79913SDag-Erling Smørgrav struct mesh_reply {
622afb79913SDag-Erling Smørgrav    struct mesh_reply* next;
623afb79913SDag-Erling Smørgrav    struct comm_reply query_reply;
624afb79913SDag-Erling Smørgrav };
625afb79913SDag-Erling Smørgrav 
626643f9a05SCy Schubert %rename(_addr) comm_reply::client_addr;
627afb79913SDag-Erling Smørgrav struct comm_reply {
628643f9a05SCy Schubert    struct sockaddr_storage client_addr;
629afb79913SDag-Erling Smørgrav };
630afb79913SDag-Erling Smørgrav 
631afb79913SDag-Erling Smørgrav %extend comm_reply {
632afb79913SDag-Erling Smørgrav    %pythoncode %{
6339c9d011eSDag-Erling Smørgrav         def _addr_get(self): return _sockaddr_storage_addr(self._addr)
634366b94c4SDag-Erling Smørgrav         addr = property(_addr_get)
635afb79913SDag-Erling Smørgrav 
6369c9d011eSDag-Erling Smørgrav         def _port_get(self): return _sockaddr_storage_port(self._addr)
637366b94c4SDag-Erling Smørgrav         port = property(_port_get)
638afb79913SDag-Erling Smørgrav 
6399c9d011eSDag-Erling Smørgrav         def _family_get(self): return _sockaddr_storage_family(self._addr)
640366b94c4SDag-Erling Smørgrav         family = property(_family_get)
641afb79913SDag-Erling Smørgrav    %}
642afb79913SDag-Erling Smørgrav }
643bd51c208SDag-Erling Smørgrav 
644bd51c208SDag-Erling Smørgrav /* ************************************************************************************ *
645bd51c208SDag-Erling Smørgrav    Structure edns_option
646bd51c208SDag-Erling Smørgrav  * ************************************************************************************ */
647bd51c208SDag-Erling Smørgrav /* Rename the members to follow the python convention of marking them as
648bd51c208SDag-Erling Smørgrav  * private. Access to the opt_code and opt_data members is given by the later
649bd51c208SDag-Erling Smørgrav  * python defined code and data members respectively. */
650bd51c208SDag-Erling Smørgrav %rename(_next) edns_option::next;
651bd51c208SDag-Erling Smørgrav %rename(_opt_code) edns_option::opt_code;
652bd51c208SDag-Erling Smørgrav %rename(_opt_len) edns_option::opt_len;
653bd51c208SDag-Erling Smørgrav %rename(_opt_data) edns_option::opt_data;
654bd51c208SDag-Erling Smørgrav struct edns_option {
655bd51c208SDag-Erling Smørgrav     struct edns_option* next;
656bd51c208SDag-Erling Smørgrav     uint16_t opt_code;
657bd51c208SDag-Erling Smørgrav     size_t opt_len;
658bd51c208SDag-Erling Smørgrav     uint8_t* opt_data;
659bd51c208SDag-Erling Smørgrav };
660bd51c208SDag-Erling Smørgrav 
661bd51c208SDag-Erling Smørgrav %inline %{
662bd51c208SDag-Erling Smørgrav     PyObject* _edns_option_opt_code_get(struct edns_option* option) {
663bd51c208SDag-Erling Smørgrav         uint16_t opt_code = option->opt_code;
664bd51c208SDag-Erling Smørgrav         return PyInt_FromLong(opt_code);
665bd51c208SDag-Erling Smørgrav     }
666bd51c208SDag-Erling Smørgrav 
667bd51c208SDag-Erling Smørgrav     PyObject* _edns_option_opt_data_get(struct edns_option* option) {
668fbdb9ac8SDag-Erling Smørgrav         return PyByteArray_FromStringAndSize((void*)option->opt_data,
669bd51c208SDag-Erling Smørgrav             option->opt_len);
670bd51c208SDag-Erling Smørgrav     }
671bd51c208SDag-Erling Smørgrav %}
672bd51c208SDag-Erling Smørgrav %extend edns_option {
673bd51c208SDag-Erling Smørgrav     %pythoncode %{
674bd51c208SDag-Erling Smørgrav         def _opt_code_get(self): return _edns_option_opt_code_get(self)
675366b94c4SDag-Erling Smørgrav         code = property(_opt_code_get)
676bd51c208SDag-Erling Smørgrav 
677bd51c208SDag-Erling Smørgrav         def _opt_data_get(self): return _edns_option_opt_data_get(self)
678366b94c4SDag-Erling Smørgrav         data = property(_opt_data_get)
679bd51c208SDag-Erling Smørgrav     %}
680bd51c208SDag-Erling Smørgrav }
681bd51c208SDag-Erling Smørgrav 
682bd51c208SDag-Erling Smørgrav /* ************************************************************************************ *
683bd51c208SDag-Erling Smørgrav    Structure edns_data
684bd51c208SDag-Erling Smørgrav  * ************************************************************************************ */
685bd51c208SDag-Erling Smørgrav /* This is ignored because we will pass a double pointer of this to Python
686bd51c208SDag-Erling Smørgrav  * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
687bd51c208SDag-Erling Smørgrav  * pointers as None. */
688bd51c208SDag-Erling Smørgrav %ignore edns_data::opt_list;
689bd51c208SDag-Erling Smørgrav struct edns_data {
690bd51c208SDag-Erling Smørgrav     int edns_present;
691bd51c208SDag-Erling Smørgrav     uint8_t ext_rcode;
692bd51c208SDag-Erling Smørgrav     uint8_t edns_version;
693bd51c208SDag-Erling Smørgrav     uint16_t bits;
694bd51c208SDag-Erling Smørgrav     uint16_t udp_size;
69568965ba9SCy Schubert     struct edns_option* opt_list_in;
69668965ba9SCy Schubert     struct edns_option* opt_list_out;
69768965ba9SCy Schubert     struct edns_option* opt_list_inplace_cb_out;
69868965ba9SCy Schubert     uint16_t padding_block_size;
699bd51c208SDag-Erling Smørgrav };
700bd51c208SDag-Erling Smørgrav %inline %{
701bd51c208SDag-Erling Smørgrav     struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) {
70268965ba9SCy Schubert        return &edns->opt_list_in;
703bd51c208SDag-Erling Smørgrav     }
704bd51c208SDag-Erling Smørgrav %}
705bd51c208SDag-Erling Smørgrav %extend edns_data {
706bd51c208SDag-Erling Smørgrav     %pythoncode %{
707bd51c208SDag-Erling Smørgrav         def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
708366b94c4SDag-Erling Smørgrav         opt_list_iter = property(_opt_list_iter)
709bd51c208SDag-Erling Smørgrav         def _opt_list(self): return _edns_data_opt_list_get(self)
710366b94c4SDag-Erling Smørgrav         opt_list = property(_opt_list)
711bd51c208SDag-Erling Smørgrav     %}
712bd51c208SDag-Erling Smørgrav }
713bd51c208SDag-Erling Smørgrav 
714bd51c208SDag-Erling Smørgrav /* ************************************************************************************ *
715bd51c208SDag-Erling Smørgrav    Structure module_env
716bd51c208SDag-Erling Smørgrav  * ************************************************************************************ */
717d60fa10fSCy Schubert %rename(_now) module_env::now;
718d60fa10fSCy Schubert %rename(_now_tv) module_env::now_tv;
719bd51c208SDag-Erling Smørgrav struct module_env {
720bd51c208SDag-Erling Smørgrav     struct config_file* cfg;
721bd51c208SDag-Erling Smørgrav     struct slabhash* msg_cache;
722bd51c208SDag-Erling Smørgrav     struct rrset_cache* rrset_cache;
723bd51c208SDag-Erling Smørgrav     struct infra_cache* infra_cache;
724bd51c208SDag-Erling Smørgrav     struct key_cache* key_cache;
725bd51c208SDag-Erling Smørgrav 
726bd51c208SDag-Erling Smørgrav     /* --- services --- */
727bd51c208SDag-Erling Smørgrav     struct outbound_entry* (*send_query)(struct query_info* qinfo,
728bd51c208SDag-Erling Smørgrav         uint16_t flags, int dnssec, int want_dnssec, int nocaps,
7293574dc0bSCy Schubert         int check_ratelimit,
730bd51c208SDag-Erling Smørgrav         struct sockaddr_storage* addr, socklen_t addrlen,
73168965ba9SCy Schubert         uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream,
7323574dc0bSCy Schubert         char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
733bd51c208SDag-Erling Smørgrav     void (*detach_subs)(struct module_qstate* qstate);
734bd51c208SDag-Erling Smørgrav     int (*attach_sub)(struct module_qstate* qstate,
735bd51c208SDag-Erling Smørgrav         struct query_info* qinfo, uint16_t qflags, int prime,
736bd51c208SDag-Erling Smørgrav         int valrec, struct module_qstate** newq);
737bd51c208SDag-Erling Smørgrav     void (*kill_sub)(struct module_qstate* newq);
738bd51c208SDag-Erling Smørgrav     int (*detect_cycle)(struct module_qstate* qstate,
739bd51c208SDag-Erling Smørgrav         struct query_info* qinfo, uint16_t flags, int prime,
740bd51c208SDag-Erling Smørgrav         int valrec);
741bd51c208SDag-Erling Smørgrav 
742bd51c208SDag-Erling Smørgrav     struct regional* scratch;
743bd51c208SDag-Erling Smørgrav     struct sldns_buffer* scratch_buffer;
744bd51c208SDag-Erling Smørgrav     struct worker* worker;
745bd51c208SDag-Erling Smørgrav     struct mesh_area* mesh;
746bd51c208SDag-Erling Smørgrav     struct alloc_cache* alloc;
747bd51c208SDag-Erling Smørgrav     struct ub_randstate* rnd;
748bd51c208SDag-Erling Smørgrav     time_t* now;
749bd51c208SDag-Erling Smørgrav     struct timeval* now_tv;
750bd51c208SDag-Erling Smørgrav     int need_to_validate;
751bd51c208SDag-Erling Smørgrav     struct val_anchors* anchors;
752bd51c208SDag-Erling Smørgrav     struct val_neg_cache* neg_cache;
753bd51c208SDag-Erling Smørgrav     struct comm_timer* probe_timer;
754bd51c208SDag-Erling Smørgrav     struct iter_forwards* fwds;
755bd51c208SDag-Erling Smørgrav     struct iter_hints* hints;
756bd51c208SDag-Erling Smørgrav     void* modinfo[MAX_MODULE];
757bd51c208SDag-Erling Smørgrav 
758bd51c208SDag-Erling Smørgrav     void* inplace_cb_lists[inplace_cb_types_total];
759bd51c208SDag-Erling Smørgrav     struct edns_known_option* edns_known_options;
760bd51c208SDag-Erling Smørgrav     size_t edns_known_options_num;
761bd51c208SDag-Erling Smørgrav };
762bd51c208SDag-Erling Smørgrav 
763d60fa10fSCy Schubert %inline %{
764d60fa10fSCy Schubert     PyObject* _module_env_now_get(struct module_env* env) {
765d60fa10fSCy Schubert         double ts = env->now_tv->tv_sec + env->now_tv->tv_usec / 1e6;
766d60fa10fSCy Schubert         return PyFloat_FromDouble(ts);
767d60fa10fSCy Schubert     }
768d60fa10fSCy Schubert %}
769d60fa10fSCy Schubert %extend module_env {
770d60fa10fSCy Schubert     %pythoncode %{
771d60fa10fSCy Schubert         def _now_get(self): return _module_env_now_get(self)
772d60fa10fSCy Schubert         now = property(_now_get)
773d60fa10fSCy Schubert     %}
774d60fa10fSCy Schubert }
775d60fa10fSCy Schubert 
776afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
777afb79913SDag-Erling Smørgrav    Structure module_qstate
778afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
779afb79913SDag-Erling Smørgrav %ignore module_qstate::ext_state;
780afb79913SDag-Erling Smørgrav %ignore module_qstate::minfo;
781afb79913SDag-Erling Smørgrav 
782bd51c208SDag-Erling Smørgrav /* These are ignored because we will pass a double pointer of them to Python
783bd51c208SDag-Erling Smørgrav  * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
784bd51c208SDag-Erling Smørgrav  * pointers as None. */
785bd51c208SDag-Erling Smørgrav %ignore module_qstate::edns_opts_front_in;
786bd51c208SDag-Erling Smørgrav %ignore module_qstate::edns_opts_back_out;
787bd51c208SDag-Erling Smørgrav %ignore module_qstate::edns_opts_back_in;
788bd51c208SDag-Erling Smørgrav %ignore module_qstate::edns_opts_front_out;
789bd51c208SDag-Erling Smørgrav 
790afb79913SDag-Erling Smørgrav /* Query state */
791afb79913SDag-Erling Smørgrav struct module_qstate {
792afb79913SDag-Erling Smørgrav    struct query_info qinfo;
793bd51c208SDag-Erling Smørgrav    uint16_t query_flags;  /* See QF_BIT_xx constants */
794afb79913SDag-Erling Smørgrav    int is_priming;
795bd51c208SDag-Erling Smørgrav    int is_valrec;
796afb79913SDag-Erling Smørgrav 
797afb79913SDag-Erling Smørgrav    struct comm_reply* reply;
798afb79913SDag-Erling Smørgrav    struct dns_msg* return_msg;
799afb79913SDag-Erling Smørgrav    int return_rcode;
800afb79913SDag-Erling Smørgrav    struct regional* region; /* unwrapped */
801afb79913SDag-Erling Smørgrav 
802afb79913SDag-Erling Smørgrav    int curmod;
803afb79913SDag-Erling Smørgrav 
804afb79913SDag-Erling Smørgrav    enum module_ext_state ext_state[MAX_MODULE];
805afb79913SDag-Erling Smørgrav    void* minfo[MAX_MODULE];
806bd51c208SDag-Erling Smørgrav    time_t prefetch_leeway;
807afb79913SDag-Erling Smørgrav 
808afb79913SDag-Erling Smørgrav    struct module_env* env;         /* unwrapped */
809afb79913SDag-Erling Smørgrav    struct mesh_state* mesh_info;
810bd51c208SDag-Erling Smørgrav 
811bd51c208SDag-Erling Smørgrav    struct edns_option* edns_opts_front_in;
812bd51c208SDag-Erling Smørgrav    struct edns_option* edns_opts_back_out;
813bd51c208SDag-Erling Smørgrav    struct edns_option* edns_opts_back_in;
814bd51c208SDag-Erling Smørgrav    struct edns_option* edns_opts_front_out;
815bd51c208SDag-Erling Smørgrav    int no_cache_lookup;
816bd51c208SDag-Erling Smørgrav    int no_cache_store;
817afb79913SDag-Erling Smørgrav };
818afb79913SDag-Erling Smørgrav 
819afb79913SDag-Erling Smørgrav %constant int MODULE_COUNT = MAX_MODULE;
820afb79913SDag-Erling Smørgrav 
821afb79913SDag-Erling Smørgrav %constant int QF_BIT_CD = 0x0010;
822afb79913SDag-Erling Smørgrav %constant int QF_BIT_AD = 0x0020;
823afb79913SDag-Erling Smørgrav %constant int QF_BIT_Z  = 0x0040;
824afb79913SDag-Erling Smørgrav %constant int QF_BIT_RA = 0x0080;
825afb79913SDag-Erling Smørgrav %constant int QF_BIT_RD = 0x0100;
826afb79913SDag-Erling Smørgrav %constant int QF_BIT_TC = 0x0200;
827afb79913SDag-Erling Smørgrav %constant int QF_BIT_AA = 0x0400;
828afb79913SDag-Erling Smørgrav %constant int QF_BIT_QR = 0x8000;
829afb79913SDag-Erling Smørgrav 
830afb79913SDag-Erling Smørgrav %inline %{
831afb79913SDag-Erling Smørgrav  enum enum_return_rcode {
832afb79913SDag-Erling Smørgrav    RCODE_NOERROR = 0,
833afb79913SDag-Erling Smørgrav    RCODE_FORMERR = 1,
834afb79913SDag-Erling Smørgrav    RCODE_SERVFAIL = 2,
835afb79913SDag-Erling Smørgrav    RCODE_NXDOMAIN = 3,
836afb79913SDag-Erling Smørgrav    RCODE_NOTIMPL = 4,
837afb79913SDag-Erling Smørgrav    RCODE_REFUSED = 5,
838afb79913SDag-Erling Smørgrav    RCODE_YXDOMAIN = 6,
839afb79913SDag-Erling Smørgrav    RCODE_YXRRSET = 7,
840afb79913SDag-Erling Smørgrav    RCODE_NXRRSET = 8,
841afb79913SDag-Erling Smørgrav    RCODE_NOTAUTH = 9,
842afb79913SDag-Erling Smørgrav    RCODE_NOTZONE = 10
843afb79913SDag-Erling Smørgrav  };
844afb79913SDag-Erling Smørgrav %}
845afb79913SDag-Erling Smørgrav 
846afb79913SDag-Erling Smørgrav %pythoncode %{
847afb79913SDag-Erling Smørgrav     class ExtState:
848afb79913SDag-Erling Smørgrav         def __init__(self, obj): self.obj = obj
849afb79913SDag-Erling Smørgrav         def __str__(self):
850afb79913SDag-Erling Smørgrav             return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)])
851afb79913SDag-Erling Smørgrav         def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index)
852afb79913SDag-Erling Smørgrav         def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value)
853afb79913SDag-Erling Smørgrav         def __len__(self): return _unboundmodule.MODULE_COUNT
854bd51c208SDag-Erling Smørgrav 
855bd51c208SDag-Erling Smørgrav     class EdnsOptsListIter:
856bd51c208SDag-Erling Smørgrav         def __init__(self, obj):
857bd51c208SDag-Erling Smørgrav             self._current = obj
858bd51c208SDag-Erling Smørgrav             self._temp = None
859bd51c208SDag-Erling Smørgrav         def __iter__(self): return self
860bd51c208SDag-Erling Smørgrav         def __next__(self):
861bd51c208SDag-Erling Smørgrav             """Python 3 compatibility"""
862bd51c208SDag-Erling Smørgrav             return self._get_next()
863bd51c208SDag-Erling Smørgrav         def next(self):
864bd51c208SDag-Erling Smørgrav             """Python 2 compatibility"""
865bd51c208SDag-Erling Smørgrav             return self._get_next()
866bd51c208SDag-Erling Smørgrav         def _get_next(self):
867bd51c208SDag-Erling Smørgrav             if not edns_opt_list_is_empty(self._current):
868bd51c208SDag-Erling Smørgrav                 self._temp = self._current
869bd51c208SDag-Erling Smørgrav                 self._current = _p_p_edns_option_get_next(self._current)
870bd51c208SDag-Erling Smørgrav                 return _dereference_edns_option(self._temp)
871bd51c208SDag-Erling Smørgrav             else:
872bd51c208SDag-Erling Smørgrav                 raise StopIteration
873afb79913SDag-Erling Smørgrav %}
874afb79913SDag-Erling Smørgrav 
875afb79913SDag-Erling Smørgrav %inline %{
876afb79913SDag-Erling Smørgrav    enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
877afb79913SDag-Erling Smørgrav      if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
878afb79913SDag-Erling Smørgrav         return q->ext_state[idx];
879afb79913SDag-Erling Smørgrav      }
880afb79913SDag-Erling Smørgrav      return 0;
881afb79913SDag-Erling Smørgrav    }
882afb79913SDag-Erling Smørgrav 
883afb79913SDag-Erling Smørgrav    void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
884afb79913SDag-Erling Smørgrav      if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
885afb79913SDag-Erling Smørgrav         q->ext_state[idx] = state;
886afb79913SDag-Erling Smørgrav      }
887afb79913SDag-Erling Smørgrav    }
888bd51c208SDag-Erling Smørgrav 
889bd51c208SDag-Erling Smørgrav    int edns_opt_list_is_empty(struct edns_option** opt) {
890bd51c208SDag-Erling Smørgrav         if (!opt || !(*opt)) return 1;
891bd51c208SDag-Erling Smørgrav         return 0;
892bd51c208SDag-Erling Smørgrav    }
893bd51c208SDag-Erling Smørgrav 
894bd51c208SDag-Erling Smørgrav    struct edns_option* _dereference_edns_option(struct edns_option** opt) {
895bd51c208SDag-Erling Smørgrav         if (!opt) return NULL;
896bd51c208SDag-Erling Smørgrav         return *opt;
897bd51c208SDag-Erling Smørgrav    }
898bd51c208SDag-Erling Smørgrav 
899bd51c208SDag-Erling Smørgrav    struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) {
900bd51c208SDag-Erling Smørgrav         return &(*opt)->next;
901bd51c208SDag-Erling Smørgrav    }
902bd51c208SDag-Erling Smørgrav 
903bd51c208SDag-Erling Smørgrav    struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) {
904bd51c208SDag-Erling Smørgrav         return &q->edns_opts_front_in;
905bd51c208SDag-Erling Smørgrav    }
906bd51c208SDag-Erling Smørgrav 
907bd51c208SDag-Erling Smørgrav    struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) {
908bd51c208SDag-Erling Smørgrav         return &q->edns_opts_back_out;
909bd51c208SDag-Erling Smørgrav    }
910bd51c208SDag-Erling Smørgrav 
911bd51c208SDag-Erling Smørgrav    struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) {
912bd51c208SDag-Erling Smørgrav         return &q->edns_opts_back_in;
913bd51c208SDag-Erling Smørgrav    }
914bd51c208SDag-Erling Smørgrav 
915bd51c208SDag-Erling Smørgrav    struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) {
916bd51c208SDag-Erling Smørgrav         return &q->edns_opts_front_out;
917bd51c208SDag-Erling Smørgrav    }
918afb79913SDag-Erling Smørgrav %}
919afb79913SDag-Erling Smørgrav 
920afb79913SDag-Erling Smørgrav %extend module_qstate {
921afb79913SDag-Erling Smørgrav    %pythoncode %{
922afb79913SDag-Erling Smørgrav         def set_ext_state(self, id, state):
923afb79913SDag-Erling Smørgrav             """Sets the ext state"""
924afb79913SDag-Erling Smørgrav             _unboundmodule._ext_state_set(self, id, state)
925afb79913SDag-Erling Smørgrav 
926afb79913SDag-Erling Smørgrav         def __ext_state_get(self): return ExtState(self)
927366b94c4SDag-Erling Smørgrav         ext_state = property(__ext_state_get) #, __ext_state_set
928bd51c208SDag-Erling Smørgrav 
929bd51c208SDag-Erling Smørgrav         def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
930366b94c4SDag-Erling Smørgrav         edns_opts_front_in_iter = property(_edns_opts_front_in_iter)
931bd51c208SDag-Erling Smørgrav         def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
932366b94c4SDag-Erling Smørgrav         edns_opts_back_out_iter = property(_edns_opts_back_out_iter)
933bd51c208SDag-Erling Smørgrav         def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
934366b94c4SDag-Erling Smørgrav         edns_opts_back_in_iter = property(_edns_opts_back_in_iter)
935bd51c208SDag-Erling Smørgrav         def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
936366b94c4SDag-Erling Smørgrav         edns_opts_front_out_iter = property(_edns_opts_front_out_iter)
937bd51c208SDag-Erling Smørgrav 
938bd51c208SDag-Erling Smørgrav         def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
939366b94c4SDag-Erling Smørgrav         edns_opts_front_in = property(_edns_opts_front_in)
940bd51c208SDag-Erling Smørgrav         def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
941366b94c4SDag-Erling Smørgrav         edns_opts_back_out = property(_edns_opts_back_out)
942bd51c208SDag-Erling Smørgrav         def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
943366b94c4SDag-Erling Smørgrav         edns_opts_back_in = property(_edns_opts_back_in)
944bd51c208SDag-Erling Smørgrav         def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
945366b94c4SDag-Erling Smørgrav         edns_opts_front_out = property(_edns_opts_front_out)
946afb79913SDag-Erling Smørgrav    %}
947afb79913SDag-Erling Smørgrav }
948afb79913SDag-Erling Smørgrav 
949afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
950afb79913SDag-Erling Smørgrav    Structure config_strlist
951afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
952afb79913SDag-Erling Smørgrav struct config_strlist {
953afb79913SDag-Erling Smørgrav    struct config_strlist* next;
954afb79913SDag-Erling Smørgrav    char* str;
955afb79913SDag-Erling Smørgrav };
956afb79913SDag-Erling Smørgrav 
957afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
958afb79913SDag-Erling Smørgrav    Structure config_str2list
959afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
960afb79913SDag-Erling Smørgrav struct config_str2list {
961afb79913SDag-Erling Smørgrav    struct config_str2list* next;
962afb79913SDag-Erling Smørgrav    char* str;
963afb79913SDag-Erling Smørgrav    char* str2;
964afb79913SDag-Erling Smørgrav };
965afb79913SDag-Erling Smørgrav 
966afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
967afb79913SDag-Erling Smørgrav    Structure config_file
968afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
96916fd0b24SCy Schubert %ignore config_file::ifs;
97016fd0b24SCy Schubert %ignore config_file::out_ifs;
97116fd0b24SCy Schubert %ignore config_file::python_script;
972afb79913SDag-Erling Smørgrav struct config_file {
973afb79913SDag-Erling Smørgrav    int verbosity;
974afb79913SDag-Erling Smørgrav    int stat_interval;
975afb79913SDag-Erling Smørgrav    int stat_cumulative;
976afb79913SDag-Erling Smørgrav    int stat_extended;
977afb79913SDag-Erling Smørgrav    int num_threads;
978afb79913SDag-Erling Smørgrav    int port;
979afb79913SDag-Erling Smørgrav    int do_ip4;
980afb79913SDag-Erling Smørgrav    int do_ip6;
981afb79913SDag-Erling Smørgrav    int do_udp;
982afb79913SDag-Erling Smørgrav    int do_tcp;
983afb79913SDag-Erling Smørgrav    int outgoing_num_ports;
984afb79913SDag-Erling Smørgrav    size_t outgoing_num_tcp;
985afb79913SDag-Erling Smørgrav    size_t incoming_num_tcp;
986afb79913SDag-Erling Smørgrav    int* outgoing_avail_ports;
987afb79913SDag-Erling Smørgrav    size_t msg_buffer_size;
988afb79913SDag-Erling Smørgrav    size_t msg_cache_size;
989afb79913SDag-Erling Smørgrav    size_t msg_cache_slabs;
990afb79913SDag-Erling Smørgrav    size_t num_queries_per_thread;
991afb79913SDag-Erling Smørgrav    size_t jostle_time;
992afb79913SDag-Erling Smørgrav    size_t rrset_cache_size;
993afb79913SDag-Erling Smørgrav    size_t rrset_cache_slabs;
994afb79913SDag-Erling Smørgrav    int host_ttl;
995afb79913SDag-Erling Smørgrav    size_t infra_cache_slabs;
996afb79913SDag-Erling Smørgrav    size_t infra_cache_numhosts;
997afb79913SDag-Erling Smørgrav    char* target_fetch_policy;
998afb79913SDag-Erling Smørgrav    int if_automatic;
999afb79913SDag-Erling Smørgrav    int num_ifs;
1000afb79913SDag-Erling Smørgrav    char **ifs;
1001afb79913SDag-Erling Smørgrav    int num_out_ifs;
1002afb79913SDag-Erling Smørgrav    char **out_ifs;
1003afb79913SDag-Erling Smørgrav    struct config_strlist* root_hints;
1004afb79913SDag-Erling Smørgrav    struct config_stub* stubs;
1005afb79913SDag-Erling Smørgrav    struct config_stub* forwards;
1006afb79913SDag-Erling Smørgrav    struct config_strlist* donotqueryaddrs;
1007afb79913SDag-Erling Smørgrav    struct config_str2list* acls;
1008afb79913SDag-Erling Smørgrav    int donotquery_localhost;
1009afb79913SDag-Erling Smørgrav    int harden_short_bufsize;
1010afb79913SDag-Erling Smørgrav    int harden_large_queries;
1011afb79913SDag-Erling Smørgrav    int harden_glue;
10120a6d797cSCy Schubert    int harden_unverified_glue;
1013afb79913SDag-Erling Smørgrav    int harden_dnssec_stripped;
1014afb79913SDag-Erling Smørgrav    int harden_referral_path;
1015afb79913SDag-Erling Smørgrav    int use_caps_bits_for_id;
1016afb79913SDag-Erling Smørgrav    struct config_strlist* private_address;
1017afb79913SDag-Erling Smørgrav    struct config_strlist* private_domain;
1018afb79913SDag-Erling Smørgrav    size_t unwanted_threshold;
1019afb79913SDag-Erling Smørgrav    char* chrootdir;
1020afb79913SDag-Erling Smørgrav    char* username;
1021afb79913SDag-Erling Smørgrav    char* directory;
1022afb79913SDag-Erling Smørgrav    char* logfile;
1023afb79913SDag-Erling Smørgrav    char* pidfile;
1024afb79913SDag-Erling Smørgrav    int use_syslog;
1025afb79913SDag-Erling Smørgrav    int hide_identity;
1026afb79913SDag-Erling Smørgrav    int hide_version;
1027afb79913SDag-Erling Smørgrav    char* identity;
1028afb79913SDag-Erling Smørgrav    char* version;
1029afb79913SDag-Erling Smørgrav    char* module_conf;
1030afb79913SDag-Erling Smørgrav    struct config_strlist* trust_anchor_file_list;
1031afb79913SDag-Erling Smørgrav    struct config_strlist* trust_anchor_list;
1032afb79913SDag-Erling Smørgrav    struct config_strlist* trusted_keys_file_list;
1033afb79913SDag-Erling Smørgrav    int max_ttl;
1034afb79913SDag-Erling Smørgrav    int32_t val_date_override;
1035afb79913SDag-Erling Smørgrav    int bogus_ttl;
1036afb79913SDag-Erling Smørgrav    int val_clean_additional;
1037afb79913SDag-Erling Smørgrav    int val_permissive_mode;
1038afb79913SDag-Erling Smørgrav    char* val_nsec3_key_iterations;
1039afb79913SDag-Erling Smørgrav    size_t key_cache_size;
1040afb79913SDag-Erling Smørgrav    size_t key_cache_slabs;
1041afb79913SDag-Erling Smørgrav    size_t neg_cache_size;
1042afb79913SDag-Erling Smørgrav    struct config_str2list* local_zones;
1043afb79913SDag-Erling Smørgrav    struct config_strlist* local_zones_nodefault;
1044afb79913SDag-Erling Smørgrav    struct config_strlist* local_data;
1045afb79913SDag-Erling Smørgrav    int remote_control_enable;
10464aea2433SDag-Erling Smørgrav    struct config_strlist_head control_ifs;
1047afb79913SDag-Erling Smørgrav    int control_port;
1048afb79913SDag-Erling Smørgrav    char* server_key_file;
1049afb79913SDag-Erling Smørgrav    char* server_cert_file;
1050afb79913SDag-Erling Smørgrav    char* control_key_file;
1051afb79913SDag-Erling Smørgrav    char* control_cert_file;
1052afb79913SDag-Erling Smørgrav    int do_daemonize;
1053e2fe7268SCy Schubert    struct config_strlist* python_script;
1054afb79913SDag-Erling Smørgrav };
1055afb79913SDag-Erling Smørgrav 
105616fd0b24SCy Schubert %inline %{
105716fd0b24SCy Schubert    PyObject* _get_ifs_tuple(struct config_file* cfg) {
105816fd0b24SCy Schubert       return CharArrayAsStringList(cfg->ifs, cfg->num_ifs);
105916fd0b24SCy Schubert    }
106016fd0b24SCy Schubert    PyObject* _get_ifs_out_tuple(struct config_file* cfg) {
106116fd0b24SCy Schubert       return CharArrayAsStringList(cfg->out_ifs, cfg->num_out_ifs);
106216fd0b24SCy Schubert    }
106316fd0b24SCy Schubert %}
106416fd0b24SCy Schubert 
106516fd0b24SCy Schubert %extend config_file {
106616fd0b24SCy Schubert    %pythoncode %{
106716fd0b24SCy Schubert         ifs = property(_unboundmodule._get_ifs_tuple)
106816fd0b24SCy Schubert         out_ifs = property(_unboundmodule._get_ifs_out_tuple)
106916fd0b24SCy Schubert 
107016fd0b24SCy Schubert         def _deprecated_python_script(self): return "cfg.python_script is deprecated, you can use `mod_env['script']` instead."
107116fd0b24SCy Schubert         python_script = property(_deprecated_python_script)
107216fd0b24SCy Schubert    %}
107316fd0b24SCy Schubert }
107416fd0b24SCy Schubert 
1075afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
1076d3348d43SDag-Erling Smørgrav    ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation
1077d3348d43SDag-Erling Smørgrav  * ************************************************************************************ */
1078d3348d43SDag-Erling Smørgrav struct delegpt_ns {
1079d3348d43SDag-Erling Smørgrav     struct delegpt_ns* next;
1080d3348d43SDag-Erling Smørgrav     int resolved;
1081d3348d43SDag-Erling Smørgrav     uint8_t got4;
1082d3348d43SDag-Erling Smørgrav     uint8_t got6;
1083d3348d43SDag-Erling Smørgrav     uint8_t lame;
1084d3348d43SDag-Erling Smørgrav     uint8_t done_pside4;
1085d3348d43SDag-Erling Smørgrav     uint8_t done_pside6;
1086d3348d43SDag-Erling Smørgrav };
1087d3348d43SDag-Erling Smørgrav 
1088d3348d43SDag-Erling Smørgrav struct delegpt_addr {
1089d3348d43SDag-Erling Smørgrav     struct delegpt_addr* next_result;
1090d3348d43SDag-Erling Smørgrav     struct delegpt_addr* next_usable;
1091d3348d43SDag-Erling Smørgrav     struct delegpt_addr* next_target;
1092d3348d43SDag-Erling Smørgrav     int attempts;
1093d3348d43SDag-Erling Smørgrav     int sel_rtt;
1094d3348d43SDag-Erling Smørgrav     int bogus;
1095d3348d43SDag-Erling Smørgrav     int lame;
1096d3348d43SDag-Erling Smørgrav };
1097d3348d43SDag-Erling Smørgrav 
1098d3348d43SDag-Erling Smørgrav struct delegpt {
1099d3348d43SDag-Erling Smørgrav     int namelabs;
1100d3348d43SDag-Erling Smørgrav     struct delegpt_ns* nslist;
1101d3348d43SDag-Erling Smørgrav     struct delegpt_addr* target_list;
1102d3348d43SDag-Erling Smørgrav     struct delegpt_addr* usable_list;
1103d3348d43SDag-Erling Smørgrav     struct delegpt_addr* result_list;
1104d3348d43SDag-Erling Smørgrav     int bogus;
1105d3348d43SDag-Erling Smørgrav     uint8_t has_parent_side_NS;
1106d3348d43SDag-Erling Smørgrav     uint8_t dp_type_mlc;
1107d3348d43SDag-Erling Smørgrav };
1108d3348d43SDag-Erling Smørgrav 
1109d3348d43SDag-Erling Smørgrav 
1110d3348d43SDag-Erling Smørgrav %inline %{
1111d3348d43SDag-Erling Smørgrav    PyObject* _get_dp_dname(struct delegpt* dp) {
1112af3dabbfSDag-Erling Smørgrav       return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen);
1113d3348d43SDag-Erling Smørgrav    }
1114d3348d43SDag-Erling Smørgrav    PyObject* _get_dp_dname_components(struct delegpt* dp) {
1115d3348d43SDag-Erling Smørgrav       return GetNameAsLabelList((char*)dp->name, dp->namelen);
1116d3348d43SDag-Erling Smørgrav    }
1117d3348d43SDag-Erling Smørgrav    PyObject* _get_dpns_dname(struct delegpt_ns* dpns) {
1118af3dabbfSDag-Erling Smørgrav       return PyBytes_FromStringAndSize((char*)dpns->name, dpns->namelen);
1119d3348d43SDag-Erling Smørgrav    }
1120d3348d43SDag-Erling Smørgrav    PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) {
1121d3348d43SDag-Erling Smørgrav       return GetNameAsLabelList((char*)dpns->name, dpns->namelen);
1122d3348d43SDag-Erling Smørgrav    }
1123d3348d43SDag-Erling Smørgrav 
1124d3348d43SDag-Erling Smørgrav   PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) {
1125d3348d43SDag-Erling Smørgrav      char dest[64];
1126d3348d43SDag-Erling Smørgrav      delegpt_addr_addr2str(target, dest, 64);
1127d3348d43SDag-Erling Smørgrav      if (dest[0] == 0)
1128d3348d43SDag-Erling Smørgrav         return Py_None;
1129af3dabbfSDag-Erling Smørgrav      return PyBytes_FromString(dest);
1130d3348d43SDag-Erling Smørgrav   }
1131d3348d43SDag-Erling Smørgrav 
1132d3348d43SDag-Erling Smørgrav %}
1133d3348d43SDag-Erling Smørgrav 
1134d3348d43SDag-Erling Smørgrav %extend delegpt {
1135d3348d43SDag-Erling Smørgrav    %pythoncode %{
1136366b94c4SDag-Erling Smørgrav         dname = property(_unboundmodule._get_dp_dname)
1137d3348d43SDag-Erling Smørgrav 
1138366b94c4SDag-Erling Smørgrav         dname_list = property(_unboundmodule._get_dp_dname_components)
1139d3348d43SDag-Erling Smørgrav 
1140d3348d43SDag-Erling Smørgrav         def _get_dname_str(self): return dnameAsStr(self.dname)
1141366b94c4SDag-Erling Smørgrav         dname_str = property(_get_dname_str)
1142d3348d43SDag-Erling Smørgrav    %}
1143d3348d43SDag-Erling Smørgrav }
1144d3348d43SDag-Erling Smørgrav %extend delegpt_ns {
1145d3348d43SDag-Erling Smørgrav    %pythoncode %{
1146366b94c4SDag-Erling Smørgrav         dname = property(_unboundmodule._get_dpns_dname)
1147d3348d43SDag-Erling Smørgrav 
1148366b94c4SDag-Erling Smørgrav         dname_list = property(_unboundmodule._get_dpns_dname_components)
1149d3348d43SDag-Erling Smørgrav 
1150d3348d43SDag-Erling Smørgrav         def _get_dname_str(self): return dnameAsStr(self.dname)
1151366b94c4SDag-Erling Smørgrav         dname_str = property(_get_dname_str)
1152d3348d43SDag-Erling Smørgrav    %}
1153d3348d43SDag-Erling Smørgrav }
1154d3348d43SDag-Erling Smørgrav %extend delegpt_addr {
1155d3348d43SDag-Erling Smørgrav    %pythoncode %{
1156d3348d43SDag-Erling Smørgrav         def _addr_get(self): return _delegpt_addr_addr_get(self)
1157366b94c4SDag-Erling Smørgrav         addr = property(_addr_get)
1158d3348d43SDag-Erling Smørgrav    %}
1159d3348d43SDag-Erling Smørgrav }
1160d3348d43SDag-Erling Smørgrav 
1161d3348d43SDag-Erling Smørgrav /* ************************************************************************************ *
1162afb79913SDag-Erling Smørgrav    Enums
1163afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
1164afb79913SDag-Erling Smørgrav %rename ("MODULE_STATE_INITIAL") "module_state_initial";
1165afb79913SDag-Erling Smørgrav %rename ("MODULE_WAIT_REPLY") "module_wait_reply";
1166afb79913SDag-Erling Smørgrav %rename ("MODULE_WAIT_MODULE") "module_wait_module";
1167e2fe7268SCy Schubert %rename ("MODULE_RESTART_NEXT") "module_restart_next";
1168afb79913SDag-Erling Smørgrav %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
1169afb79913SDag-Erling Smørgrav %rename ("MODULE_ERROR") "module_error";
1170afb79913SDag-Erling Smørgrav %rename ("MODULE_FINISHED") "module_finished";
1171afb79913SDag-Erling Smørgrav 
1172afb79913SDag-Erling Smørgrav enum module_ext_state {
1173afb79913SDag-Erling Smørgrav    module_state_initial = 0,
1174afb79913SDag-Erling Smørgrav    module_wait_reply,
1175afb79913SDag-Erling Smørgrav    module_wait_module,
1176e2fe7268SCy Schubert    module_restart_next,
1177afb79913SDag-Erling Smørgrav    module_wait_subquery,
1178afb79913SDag-Erling Smørgrav    module_error,
1179afb79913SDag-Erling Smørgrav    module_finished
1180afb79913SDag-Erling Smørgrav };
1181afb79913SDag-Erling Smørgrav 
1182afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_NEW") "module_event_new";
1183afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_PASS") "module_event_pass";
1184afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_REPLY") "module_event_reply";
1185afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply";
1186afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail";
1187afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_MODDONE") "module_event_moddone";
1188afb79913SDag-Erling Smørgrav %rename ("MODULE_EVENT_ERROR") "module_event_error";
1189afb79913SDag-Erling Smørgrav 
1190afb79913SDag-Erling Smørgrav enum module_ev {
1191afb79913SDag-Erling Smørgrav    module_event_new = 0,
1192afb79913SDag-Erling Smørgrav    module_event_pass,
1193afb79913SDag-Erling Smørgrav    module_event_reply,
1194afb79913SDag-Erling Smørgrav    module_event_noreply,
1195afb79913SDag-Erling Smørgrav    module_event_capsfail,
1196afb79913SDag-Erling Smørgrav    module_event_moddone,
1197afb79913SDag-Erling Smørgrav    module_event_error
1198afb79913SDag-Erling Smørgrav };
1199afb79913SDag-Erling Smørgrav 
1200afb79913SDag-Erling Smørgrav enum sec_status {
1201afb79913SDag-Erling Smørgrav    sec_status_unchecked = 0,
1202afb79913SDag-Erling Smørgrav    sec_status_bogus,
1203afb79913SDag-Erling Smørgrav    sec_status_indeterminate,
1204afb79913SDag-Erling Smørgrav    sec_status_insecure,
1205afb79913SDag-Erling Smørgrav    sec_status_secure
1206afb79913SDag-Erling Smørgrav };
1207afb79913SDag-Erling Smørgrav 
1208afb79913SDag-Erling Smørgrav enum verbosity_value {
1209afb79913SDag-Erling Smørgrav    NO_VERBOSE = 0,
1210afb79913SDag-Erling Smørgrav    VERB_OPS,
1211afb79913SDag-Erling Smørgrav    VERB_DETAIL,
1212afb79913SDag-Erling Smørgrav    VERB_QUERY,
1213afb79913SDag-Erling Smørgrav    VERB_ALGO
1214afb79913SDag-Erling Smørgrav };
1215afb79913SDag-Erling Smørgrav 
12166cacf549SDag-Erling Smørgrav enum inplace_cb_list_type {
12176cacf549SDag-Erling Smørgrav     /* Inplace callbacks for when a resolved reply is ready to be sent to the
12186cacf549SDag-Erling Smørgrav      * front.*/
12196cacf549SDag-Erling Smørgrav     inplace_cb_reply = 0,
12206cacf549SDag-Erling Smørgrav     /* Inplace callbacks for when a reply is given from the cache. */
12216cacf549SDag-Erling Smørgrav     inplace_cb_reply_cache,
12226cacf549SDag-Erling Smørgrav     /* Inplace callbacks for when a reply is given with local data
12236cacf549SDag-Erling Smørgrav      * (or Chaos reply). */
12246cacf549SDag-Erling Smørgrav     inplace_cb_reply_local,
12256cacf549SDag-Erling Smørgrav     /* Inplace callbacks for when the reply is servfail. */
12266cacf549SDag-Erling Smørgrav     inplace_cb_reply_servfail,
12276cacf549SDag-Erling Smørgrav     /* Inplace callbacks for when a query is ready to be sent to the back.*/
12286cacf549SDag-Erling Smørgrav     inplace_cb_query,
12296cacf549SDag-Erling Smørgrav     /* Inplace callback for when a reply is received from the back. */
12306cacf549SDag-Erling Smørgrav     inplace_cb_edns_back_parsed,
12316cacf549SDag-Erling Smørgrav     /* Total number of types. Used for array initialization.
12326cacf549SDag-Erling Smørgrav      * Should always be last. */
12336cacf549SDag-Erling Smørgrav     inplace_cb_types_total
12346cacf549SDag-Erling Smørgrav };
12356cacf549SDag-Erling Smørgrav 
123679dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_QR = 1;      /* QueRy - query flag */
123779dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_AA = 2;      /* Authoritative Answer - server flag */
123879dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_TC = 4;      /* TrunCated - server flag */
123979dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_RD = 8;      /* Recursion Desired - query flag */
124079dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_CD = 16;     /* Checking Disabled - query flag */
124179dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_RA = 32;     /* Recursion Available - server flag */
124279dd93c1SDag-Erling Smørgrav %constant uint16_t PKT_AD = 64;     /* Authenticated Data - server flag */
124379dd93c1SDag-Erling Smørgrav 
1244afb79913SDag-Erling Smørgrav %{
1245afb79913SDag-Erling Smørgrav int checkList(PyObject *l)
1246afb79913SDag-Erling Smørgrav {
1247afb79913SDag-Erling Smørgrav     PyObject* item;
1248afb79913SDag-Erling Smørgrav     int i;
1249afb79913SDag-Erling Smørgrav 
1250afb79913SDag-Erling Smørgrav     if (l == Py_None)
1251afb79913SDag-Erling Smørgrav        return 1;
1252afb79913SDag-Erling Smørgrav 
1253afb79913SDag-Erling Smørgrav     if (PyList_Check(l))
1254afb79913SDag-Erling Smørgrav     {
1255afb79913SDag-Erling Smørgrav        for (i=0; i < PyList_Size(l); i++)
1256afb79913SDag-Erling Smørgrav        {
1257afb79913SDag-Erling Smørgrav            item = PyList_GetItem(l, i);
12589c9d011eSDag-Erling Smørgrav            if (!PyBytes_Check(item) && !PyUnicode_Check(item))
1259afb79913SDag-Erling Smørgrav               return 0;
1260afb79913SDag-Erling Smørgrav        }
1261afb79913SDag-Erling Smørgrav        return 1;
1262afb79913SDag-Erling Smørgrav     }
1263afb79913SDag-Erling Smørgrav 
1264afb79913SDag-Erling Smørgrav     return 0;
1265afb79913SDag-Erling Smørgrav }
1266afb79913SDag-Erling Smørgrav 
126779dd93c1SDag-Erling Smørgrav int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
126879dd93c1SDag-Erling Smørgrav         size_t count_offset)
1269afb79913SDag-Erling Smørgrav {
1270afb79913SDag-Erling Smørgrav     PyObject* item;
1271afb79913SDag-Erling Smørgrav     int i;
127279dd93c1SDag-Erling Smørgrav     size_t len;
12739c9d011eSDag-Erling Smørgrav     char* s;
12749c9d011eSDag-Erling Smørgrav     PyObject* ascstr;
1275afb79913SDag-Erling Smørgrav 
1276afb79913SDag-Erling Smørgrav     for (i=0; i < PyList_Size(l); i++)
1277afb79913SDag-Erling Smørgrav     {
12789c9d011eSDag-Erling Smørgrav         ascstr = NULL;
1279afb79913SDag-Erling Smørgrav         item = PyList_GetItem(l, i);
12809c9d011eSDag-Erling Smørgrav         if(PyObject_TypeCheck(item, &PyBytes_Type)) {
12819c9d011eSDag-Erling Smørgrav                 s = PyBytes_AsString(item);
12829c9d011eSDag-Erling Smørgrav         } else {
12839c9d011eSDag-Erling Smørgrav                 ascstr = PyUnicode_AsASCIIString(item);
12849c9d011eSDag-Erling Smørgrav                 s = PyBytes_AsString(ascstr);
12859c9d011eSDag-Erling Smørgrav         }
1286afb79913SDag-Erling Smørgrav 
128779dd93c1SDag-Erling Smørgrav         len = sldns_buffer_remaining(qb);
128879dd93c1SDag-Erling Smørgrav         if(qsec) {
12899c9d011eSDag-Erling Smørgrav                 if(sldns_str2wire_rr_question_buf(s,
129079dd93c1SDag-Erling Smørgrav                         sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
12919c9d011eSDag-Erling Smørgrav                         != 0) {
12929c9d011eSDag-Erling Smørgrav                         if(ascstr)
12939c9d011eSDag-Erling Smørgrav                             Py_DECREF(ascstr);
129479dd93c1SDag-Erling Smørgrav                         return 0;
1295afb79913SDag-Erling Smørgrav                 }
12969c9d011eSDag-Erling Smørgrav         } else {
12979c9d011eSDag-Erling Smørgrav                 if(sldns_str2wire_rr_buf(s,
12989c9d011eSDag-Erling Smørgrav                         sldns_buffer_current(qb), &len, NULL, default_ttl,
12999c9d011eSDag-Erling Smørgrav                         NULL, 0, NULL, 0) != 0) {
13009c9d011eSDag-Erling Smørgrav                         if(ascstr)
13019c9d011eSDag-Erling Smørgrav                             Py_DECREF(ascstr);
13029c9d011eSDag-Erling Smørgrav                         return 0;
13039c9d011eSDag-Erling Smørgrav                 }
13049c9d011eSDag-Erling Smørgrav         }
13059c9d011eSDag-Erling Smørgrav         if(ascstr)
13069c9d011eSDag-Erling Smørgrav             Py_DECREF(ascstr);
130779dd93c1SDag-Erling Smørgrav         sldns_buffer_skip(qb, len);
130879dd93c1SDag-Erling Smørgrav 
130979dd93c1SDag-Erling Smørgrav         sldns_buffer_write_u16_at(qb, count_offset,
131079dd93c1SDag-Erling Smørgrav                 sldns_buffer_read_u16_at(qb, count_offset)+1);
131179dd93c1SDag-Erling Smørgrav     }
131279dd93c1SDag-Erling Smørgrav     return 1;
1313afb79913SDag-Erling Smørgrav }
1314afb79913SDag-Erling Smørgrav 
1315afb79913SDag-Erling Smørgrav int set_return_msg(struct module_qstate* qstate,
131679dd93c1SDag-Erling Smørgrav                    const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
1317afb79913SDag-Erling Smørgrav                    PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
1318afb79913SDag-Erling Smørgrav {
131979dd93c1SDag-Erling Smørgrav      sldns_buffer *qb = 0;
1320afb79913SDag-Erling Smørgrav      int res = 1;
132179dd93c1SDag-Erling Smørgrav      size_t l;
132279dd93c1SDag-Erling Smørgrav      uint16_t PKT_QR = 1;
132379dd93c1SDag-Erling Smørgrav      uint16_t PKT_AA = 2;
132479dd93c1SDag-Erling Smørgrav      uint16_t PKT_TC = 4;
132579dd93c1SDag-Erling Smørgrav      uint16_t PKT_RD = 8;
132679dd93c1SDag-Erling Smørgrav      uint16_t PKT_CD = 16;
132779dd93c1SDag-Erling Smørgrav      uint16_t PKT_RA = 32;
132879dd93c1SDag-Erling Smørgrav      uint16_t PKT_AD = 64;
1329afb79913SDag-Erling Smørgrav 
1330afb79913SDag-Erling Smørgrav      if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
1331afb79913SDag-Erling Smørgrav         return 0;
133279dd93c1SDag-Erling Smørgrav      if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0;
1333afb79913SDag-Erling Smørgrav 
133479dd93c1SDag-Erling Smørgrav      /* write header */
133579dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, 0); /* ID */
133679dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, 0); /* flags */
133779dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, 1); /* qdcount */
133879dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, 0); /* ancount */
133979dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, 0); /* nscount */
134079dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, 0); /* arcount */
134179dd93c1SDag-Erling Smørgrav      if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb));
134279dd93c1SDag-Erling Smørgrav      if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb));
134379dd93c1SDag-Erling Smørgrav      if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb));
134479dd93c1SDag-Erling Smørgrav      if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb));
134579dd93c1SDag-Erling Smørgrav      if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb));
134679dd93c1SDag-Erling Smørgrav      if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb));
134779dd93c1SDag-Erling Smørgrav      if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb));
134879dd93c1SDag-Erling Smørgrav 
134979dd93c1SDag-Erling Smørgrav      /* write the query */
135079dd93c1SDag-Erling Smørgrav      l = sldns_buffer_remaining(qb);
135179dd93c1SDag-Erling Smørgrav      if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) {
135279dd93c1SDag-Erling Smørgrav              sldns_buffer_free(qb);
1353afb79913SDag-Erling Smørgrav              return 0;
135479dd93c1SDag-Erling Smørgrav      }
135579dd93c1SDag-Erling Smørgrav      sldns_buffer_skip(qb, l);
135679dd93c1SDag-Erling Smørgrav      if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; }
135779dd93c1SDag-Erling Smørgrav      if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; }
135879dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, rr_type);
135979dd93c1SDag-Erling Smørgrav      sldns_buffer_write_u16(qb, rr_class);
1360afb79913SDag-Erling Smørgrav 
136179dd93c1SDag-Erling Smørgrav      /* write RR sections */
136279dd93c1SDag-Erling Smørgrav      if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF))
136379dd93c1SDag-Erling Smørgrav              res = 0;
136479dd93c1SDag-Erling Smørgrav      if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF))
136579dd93c1SDag-Erling Smørgrav              res = 0;
136679dd93c1SDag-Erling Smørgrav      if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF))
136779dd93c1SDag-Erling Smørgrav              res = 0;
136879dd93c1SDag-Erling Smørgrav      if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF))
136979dd93c1SDag-Erling Smørgrav              res = 0;
1370afb79913SDag-Erling Smørgrav 
1371afb79913SDag-Erling Smørgrav      if (res) res = createResponse(qstate, qb);
1372afb79913SDag-Erling Smørgrav 
137379dd93c1SDag-Erling Smørgrav      if (qb) sldns_buffer_free(qb);
1374afb79913SDag-Erling Smørgrav      return res;
1375afb79913SDag-Erling Smørgrav }
1376afb79913SDag-Erling Smørgrav %}
1377afb79913SDag-Erling Smørgrav 
1378afb79913SDag-Erling Smørgrav int set_return_msg(struct module_qstate* qstate,
1379afb79913SDag-Erling Smørgrav                    const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
1380afb79913SDag-Erling Smørgrav                    PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
1381afb79913SDag-Erling Smørgrav 
1382afb79913SDag-Erling Smørgrav %pythoncode %{
1383afb79913SDag-Erling Smørgrav     class DNSMessage:
1384afb79913SDag-Erling Smørgrav         def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0):
138568965ba9SCy Schubert             """Query flags is a combination of PKT_xx constants"""
1386afb79913SDag-Erling Smørgrav             self.rr_name = rr_name
1387afb79913SDag-Erling Smørgrav             self.rr_type = rr_type
1388afb79913SDag-Erling Smørgrav             self.rr_class = rr_class
1389afb79913SDag-Erling Smørgrav             self.default_ttl = default_ttl
1390afb79913SDag-Erling Smørgrav             self.query_flags = query_flags
1391afb79913SDag-Erling Smørgrav             self.question = []
1392afb79913SDag-Erling Smørgrav             self.answer = []
1393afb79913SDag-Erling Smørgrav             self.authority = []
1394afb79913SDag-Erling Smørgrav             self.additional = []
1395afb79913SDag-Erling Smørgrav 
1396afb79913SDag-Erling Smørgrav         def set_return_msg(self, qstate):
1397afb79913SDag-Erling Smørgrav             """Returns 1 if OK"""
1398afb79913SDag-Erling Smørgrav             status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
1399afb79913SDag-Erling Smørgrav                                            self.query_flags, self.default_ttl,
1400afb79913SDag-Erling Smørgrav                                            self.question, self.answer, self.authority, self.additional)
1401afb79913SDag-Erling Smørgrav 
1402afb79913SDag-Erling Smørgrav             if (status) and (PKT_AA & self.query_flags):
1403afb79913SDag-Erling Smørgrav                 qstate.return_msg.rep.authoritative = 1
1404afb79913SDag-Erling Smørgrav 
1405afb79913SDag-Erling Smørgrav             return status
1406afb79913SDag-Erling Smørgrav 
1407afb79913SDag-Erling Smørgrav %}
1408afb79913SDag-Erling Smørgrav /* ************************************************************************************ *
1409d3348d43SDag-Erling Smørgrav    ASN: Delegation pointer related functions
1410d3348d43SDag-Erling Smørgrav  * ************************************************************************************ */
1411d3348d43SDag-Erling Smørgrav 
1412d3348d43SDag-Erling Smørgrav /* Functions which we will need to lookup delegations */
1413d3348d43SDag-Erling Smørgrav struct delegpt* dns_cache_find_delegation(struct module_env* env,
1414d3348d43SDag-Erling Smørgrav         uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
14159b76d32fSCy Schubert         struct regional* region, struct dns_msg** msg, uint32_t timenow,
14169b76d32fSCy Schubert         int noexpiredabove, uint8_t* expiretop, size_t expiretoplen);
1417d3348d43SDag-Erling Smørgrav int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
1418401770e0SCy Schubert         struct delegpt* dp, int supports_ipv4, int supports_ipv6, int use_nat64);
1419d3348d43SDag-Erling Smørgrav struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
1420c2a80056SCy Schubert         uint8_t* qname, uint16_t qclass, struct delegpt* dp, int nolock);
1421d3348d43SDag-Erling Smørgrav 
1422d3348d43SDag-Erling Smørgrav /* Custom function to perform logic similar to the one in daemon/cachedump.c */
1423d3348d43SDag-Erling Smørgrav struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen);
1424d3348d43SDag-Erling Smørgrav 
1425d3348d43SDag-Erling Smørgrav %{
1426d3348d43SDag-Erling Smørgrav #define BIT_RD 0x100
1427d3348d43SDag-Erling Smørgrav 
1428d3348d43SDag-Erling Smørgrav struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen)
1429d3348d43SDag-Erling Smørgrav {
1430d3348d43SDag-Erling Smørgrav     struct delegpt *dp;
1431d3348d43SDag-Erling Smørgrav     struct dns_msg *msg = NULL;
1432d3348d43SDag-Erling Smørgrav     struct regional* region = qstate->env->scratch;
1433d3348d43SDag-Erling Smørgrav     char b[260];
1434d3348d43SDag-Erling Smørgrav     struct query_info qinfo;
1435d3348d43SDag-Erling Smørgrav     struct iter_hints_stub* stub;
1436d3348d43SDag-Erling Smørgrav     uint32_t timenow = *qstate->env->now;
1437c2a80056SCy Schubert     int nolock = 0;
1438d3348d43SDag-Erling Smørgrav 
1439d3348d43SDag-Erling Smørgrav     regional_free_all(region);
1440d3348d43SDag-Erling Smørgrav     qinfo.qname = (uint8_t*)nm;
1441d3348d43SDag-Erling Smørgrav     qinfo.qname_len = nmlen;
1442d3348d43SDag-Erling Smørgrav     qinfo.qtype = LDNS_RR_TYPE_A;
1443d3348d43SDag-Erling Smørgrav     qinfo.qclass = LDNS_RR_CLASS_IN;
1444d3348d43SDag-Erling Smørgrav 
1445d3348d43SDag-Erling Smørgrav     while(1) {
14469b76d32fSCy Schubert         dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow, 0, NULL, 0);
1447d3348d43SDag-Erling Smørgrav         if(!dp)
1448d3348d43SDag-Erling Smørgrav             return NULL;
14495f9f8226SCy Schubert         if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
1450401770e0SCy Schubert                 qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6,
1451401770e0SCy Schubert                 qstate->env->cfg->do_nat64)) {
1452d3348d43SDag-Erling Smørgrav             if (dname_is_root((uint8_t*)nm))
1453d3348d43SDag-Erling Smørgrav                 return NULL;
1454d3348d43SDag-Erling Smørgrav             nm = (char*)dp->name;
1455d3348d43SDag-Erling Smørgrav             nmlen = dp->namelen;
1456d3348d43SDag-Erling Smørgrav             dname_remove_label((uint8_t**)&nm, &nmlen);
1457d3348d43SDag-Erling Smørgrav             dname_str((uint8_t*)nm, b);
1458d3348d43SDag-Erling Smørgrav             continue;
1459d3348d43SDag-Erling Smørgrav         }
1460c2a80056SCy Schubert         stub = hints_lookup_stub(qstate->env->hints, qinfo.qname,
1461c2a80056SCy Schubert             qinfo.qclass, dp, nolock);
1462d3348d43SDag-Erling Smørgrav         if (stub) {
1463c2a80056SCy Schubert             struct delegpt* stubdp = delegpt_copy(stub->dp, region);
1464c2a80056SCy Schubert             lock_rw_unlock(&qstate->env->hints->lock);
1465c2a80056SCy Schubert             return stubdp;
1466d3348d43SDag-Erling Smørgrav         } else {
1467d3348d43SDag-Erling Smørgrav             return dp;
1468d3348d43SDag-Erling Smørgrav         }
1469d3348d43SDag-Erling Smørgrav     }
1470d3348d43SDag-Erling Smørgrav     return NULL;
1471d3348d43SDag-Erling Smørgrav }
1472d3348d43SDag-Erling Smørgrav %}
1473d3348d43SDag-Erling Smørgrav 
1474d3348d43SDag-Erling Smørgrav /* ************************************************************************************ *
1475afb79913SDag-Erling Smørgrav    Functions
1476afb79913SDag-Erling Smørgrav  * ************************************************************************************ */
1477bd51c208SDag-Erling Smørgrav /******************************
14782bda7bdaSDag-Erling Smørgrav  * Various debugging functions *
1479bd51c208SDag-Erling Smørgrav  ******************************/
1480c1dbcbf2SCy Schubert 
1481c1dbcbf2SCy Schubert /* rename the variadic functions because python does the formatting already*/
1482c1dbcbf2SCy Schubert %rename (unbound_log_info) log_info;
1483c1dbcbf2SCy Schubert %rename (unbound_log_err) log_err;
1484c1dbcbf2SCy Schubert %rename (unbound_log_warn) log_warn;
1485c1dbcbf2SCy Schubert %rename (unbound_verbose) verbose;
1486c1dbcbf2SCy Schubert /* provide functions that take one string as argument, so python can cook
1487c1dbcbf2SCy Schubert the string */
1488c1dbcbf2SCy Schubert %rename (log_info) pymod_log_info;
1489c1dbcbf2SCy Schubert %rename (log_warn) pymod_log_warn;
1490c1dbcbf2SCy Schubert %rename (log_err) pymod_log_err;
1491c1dbcbf2SCy Schubert %rename (verbose) pymod_verbose;
1492c1dbcbf2SCy Schubert 
1493afb79913SDag-Erling Smørgrav void verbose(enum verbosity_value level, const char* format, ...);
1494afb79913SDag-Erling Smørgrav void log_info(const char* format, ...);
1495afb79913SDag-Erling Smørgrav void log_err(const char* format, ...);
1496afb79913SDag-Erling Smørgrav void log_warn(const char* format, ...);
1497afb79913SDag-Erling Smørgrav void log_hex(const char* msg, void* data, size_t length);
1498afb79913SDag-Erling Smørgrav void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep);
1499afb79913SDag-Erling Smørgrav void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
1500afb79913SDag-Erling Smørgrav void regional_log_stats(struct regional *r);
1501afb79913SDag-Erling Smørgrav 
1502c1dbcbf2SCy Schubert /* the one argument string log functions */
1503c1dbcbf2SCy Schubert void pymod_log_info(const char* str);
1504c1dbcbf2SCy Schubert void pymod_log_err(const char* str);
1505c1dbcbf2SCy Schubert void pymod_log_warn(const char* str);
1506c1dbcbf2SCy Schubert void pymod_verbose(enum verbosity_value level, const char* str);
1507c1dbcbf2SCy Schubert %{
1508c1dbcbf2SCy Schubert void pymod_log_info(const char* str) { log_info("%s", str); }
1509c1dbcbf2SCy Schubert void pymod_log_err(const char* str) { log_err("%s", str); }
1510c1dbcbf2SCy Schubert void pymod_log_warn(const char* str) { log_warn("%s", str); }
1511c1dbcbf2SCy Schubert void pymod_verbose(enum verbosity_value level, const char* str) {
1512c1dbcbf2SCy Schubert         verbose(level, "%s", str); }
1513c1dbcbf2SCy Schubert %}
1514c1dbcbf2SCy Schubert 
1515bd51c208SDag-Erling Smørgrav /***************************************************************************
1516bd51c208SDag-Erling Smørgrav  * Free allocated memory from marked sources returning corresponding types *
1517bd51c208SDag-Erling Smørgrav  ***************************************************************************/
1518afb79913SDag-Erling Smørgrav %typemap(newfree, noblock = 1) char * {
1519afb79913SDag-Erling Smørgrav   free($1);
1520afb79913SDag-Erling Smørgrav }
1521afb79913SDag-Erling Smørgrav 
1522bd51c208SDag-Erling Smørgrav /***************************************************
1523bd51c208SDag-Erling Smørgrav  * Mark as source returning newly allocated memory *
1524bd51c208SDag-Erling Smørgrav  ***************************************************/
152579dd93c1SDag-Erling Smørgrav %newobject sldns_wire2str_type;
152679dd93c1SDag-Erling Smørgrav %newobject sldns_wire2str_class;
1527afb79913SDag-Erling Smørgrav 
1528bd51c208SDag-Erling Smørgrav /******************
1529bd51c208SDag-Erling Smørgrav  * LDNS functions *
1530bd51c208SDag-Erling Smørgrav  ******************/
153179dd93c1SDag-Erling Smørgrav char *sldns_wire2str_type(const uint16_t atype);
153279dd93c1SDag-Erling Smørgrav char *sldns_wire2str_class(const uint16_t aclass);
1533afb79913SDag-Erling Smørgrav 
1534bd51c208SDag-Erling Smørgrav /**********************************
1535bd51c208SDag-Erling Smørgrav  * Functions from pythonmod_utils *
1536bd51c208SDag-Erling Smørgrav  **********************************/
1537afb79913SDag-Erling Smørgrav int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
1538afb79913SDag-Erling Smørgrav void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
1539afb79913SDag-Erling Smørgrav 
1540bd51c208SDag-Erling Smørgrav /*******************************
1541bd51c208SDag-Erling Smørgrav  * Module conversion functions *
1542bd51c208SDag-Erling Smørgrav  *******************************/
1543afb79913SDag-Erling Smørgrav const char* strextstate(enum module_ext_state s);
1544afb79913SDag-Erling Smørgrav const char* strmodulevent(enum module_ev e);
1545afb79913SDag-Erling Smørgrav 
1546bd51c208SDag-Erling Smørgrav /**************************
1547bd51c208SDag-Erling Smørgrav  * Edns related functions *
1548bd51c208SDag-Erling Smørgrav  **************************/
1549bd51c208SDag-Erling Smørgrav struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
1550bd51c208SDag-Erling Smørgrav int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
1551bd51c208SDag-Erling Smørgrav     int no_aggregation, struct module_env* env);
1552bd51c208SDag-Erling Smørgrav 
1553bd51c208SDag-Erling Smørgrav %pythoncode %{
1554bd51c208SDag-Erling Smørgrav     def register_edns_option(env, code, bypass_cache_stage=False,
1555bd51c208SDag-Erling Smørgrav                              no_aggregation=False):
1556bd51c208SDag-Erling Smørgrav         """Wrapper function to provide keyword attributes."""
1557bd51c208SDag-Erling Smørgrav         return edns_register_option(code, bypass_cache_stage,
1558bd51c208SDag-Erling Smørgrav                                     no_aggregation, env)
1559bd51c208SDag-Erling Smørgrav %}
1560bd51c208SDag-Erling Smørgrav 
1561bd51c208SDag-Erling Smørgrav /******************************
1562bd51c208SDag-Erling Smørgrav  * Callback related functions *
1563bd51c208SDag-Erling Smørgrav  ******************************/
1564bd51c208SDag-Erling Smørgrav /* typemap to check if argument is callable */
1565bd51c208SDag-Erling Smørgrav %typemap(in) PyObject *py_cb {
1566bd51c208SDag-Erling Smørgrav   if (!PyCallable_Check($input)) {
1567bd51c208SDag-Erling Smørgrav       SWIG_exception_fail(SWIG_TypeError, "Need a callable object!");
1568bd51c208SDag-Erling Smørgrav       return NULL;
1569bd51c208SDag-Erling Smørgrav   }
1570bd51c208SDag-Erling Smørgrav   $1 = $input;
1571bd51c208SDag-Erling Smørgrav }
1572bd51c208SDag-Erling Smørgrav /* typemap to get content/size from a bytearray  */
1573bd51c208SDag-Erling Smørgrav %typemap(in) (size_t len, uint8_t* py_bytearray_data) {
1574bd51c208SDag-Erling Smørgrav     if (!PyByteArray_CheckExact($input)) {
1575bd51c208SDag-Erling Smørgrav         SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!");
1576bd51c208SDag-Erling Smørgrav         return NULL;
1577bd51c208SDag-Erling Smørgrav     }
1578fbdb9ac8SDag-Erling Smørgrav     $2 = (void*)PyByteArray_AsString($input);
1579bd51c208SDag-Erling Smørgrav     $1 = PyByteArray_Size($input);
1580bd51c208SDag-Erling Smørgrav }
1581bd51c208SDag-Erling Smørgrav 
1582bd51c208SDag-Erling Smørgrav int edns_opt_list_remove(struct edns_option** list, uint16_t code);
1583bd51c208SDag-Erling Smørgrav int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
1584bd51c208SDag-Erling Smørgrav     uint8_t* py_bytearray_data, struct regional* region);
1585bd51c208SDag-Erling Smørgrav 
1586bd51c208SDag-Erling Smørgrav %{
1587bd51c208SDag-Erling Smørgrav     /* This function is called by unbound in order to call the python
1588bd51c208SDag-Erling Smørgrav      * callback function. */
1589bd51c208SDag-Erling Smørgrav     int python_inplace_cb_reply_generic(struct query_info* qinfo,
1590bd51c208SDag-Erling Smørgrav         struct module_qstate* qstate, struct reply_info* rep, int rcode,
1591bd51c208SDag-Erling Smørgrav         struct edns_data* edns, struct edns_option** opt_list_out,
1592d60fa10fSCy Schubert         struct comm_reply* repinfo, struct regional* region,
1593d60fa10fSCy Schubert         struct timeval* start_time, int id, void* python_callback)
1594bd51c208SDag-Erling Smørgrav     {
1595401770e0SCy Schubert         PyObject *func = NULL, *py_edns = NULL, *py_qstate = NULL;
1596401770e0SCy Schubert         PyObject *py_opt_list_out = NULL, *py_qinfo = NULL;
1597401770e0SCy Schubert         PyObject *py_rep = NULL, *py_repinfo = NULL, *py_region = NULL;
1598625f1c13SCy Schubert         PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL;
1599bd51c208SDag-Erling Smørgrav         int res = 0;
1600d60fa10fSCy Schubert         double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6;
1601bd51c208SDag-Erling Smørgrav 
1602bd51c208SDag-Erling Smørgrav         PyGILState_STATE gstate = PyGILState_Ensure();
1603401770e0SCy Schubert 
1604fbdb9ac8SDag-Erling Smørgrav         func = (PyObject *) python_callback;
1605bd51c208SDag-Erling Smørgrav         py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
1606bd51c208SDag-Erling Smørgrav         py_qstate = SWIG_NewPointerObj((void*) qstate,
1607bd51c208SDag-Erling Smørgrav             SWIGTYPE_p_module_qstate, 0);
1608bd51c208SDag-Erling Smørgrav         py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out,
1609bd51c208SDag-Erling Smørgrav             SWIGTYPE_p_p_edns_option, 0);
1610bd51c208SDag-Erling Smørgrav         py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1611bd51c208SDag-Erling Smørgrav         py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
1612dcaa814dSDag-Erling Smørgrav         py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0);
1613bd51c208SDag-Erling Smørgrav         py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1614401770e0SCy Schubert         if(!(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out
1615401770e0SCy Schubert                 && py_region && py_repinfo)) {
1616401770e0SCy Schubert                 log_err("pythonmod: swig pointer failure in python_inplace_cb_reply_generic");
1617401770e0SCy Schubert                 goto out;
1618401770e0SCy Schubert         }
1619dcaa814dSDag-Erling Smørgrav         py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
1620dcaa814dSDag-Erling Smørgrav                 rcode, py_edns, py_opt_list_out, py_region);
1621d60fa10fSCy Schubert         py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time",
1622d60fa10fSCy Schubert                 py_start_time);
1623401770e0SCy Schubert         if(!(py_args && py_kwargs)) {
1624401770e0SCy Schubert                 log_err("pythonmod: BuildValue failure in python_inplace_cb_reply_generic");
1625401770e0SCy Schubert                 goto out;
1626401770e0SCy Schubert         }
1627dcaa814dSDag-Erling Smørgrav         result = PyObject_Call(func, py_args, py_kwargs);
1628401770e0SCy Schubert         if (result) {
1629401770e0SCy Schubert             res = PyInt_AsLong(result);
1630625f1c13SCy Schubert         }
1631401770e0SCy Schubert out:
1632bd51c208SDag-Erling Smørgrav         Py_XDECREF(py_edns);
1633bd51c208SDag-Erling Smørgrav         Py_XDECREF(py_qstate);
1634bd51c208SDag-Erling Smørgrav         Py_XDECREF(py_opt_list_out);
1635bd51c208SDag-Erling Smørgrav         Py_XDECREF(py_qinfo);
1636bd51c208SDag-Erling Smørgrav         Py_XDECREF(py_rep);
1637dcaa814dSDag-Erling Smørgrav         Py_XDECREF(py_repinfo);
1638bd51c208SDag-Erling Smørgrav         Py_XDECREF(py_region);
1639dcaa814dSDag-Erling Smørgrav         Py_XDECREF(py_args);
1640dcaa814dSDag-Erling Smørgrav         Py_XDECREF(py_kwargs);
1641bd51c208SDag-Erling Smørgrav         Py_XDECREF(result);
1642bd51c208SDag-Erling Smørgrav         PyGILState_Release(gstate);
1643bd51c208SDag-Erling Smørgrav         return res;
1644bd51c208SDag-Erling Smørgrav     }
1645bd51c208SDag-Erling Smørgrav 
16466cacf549SDag-Erling Smørgrav     /* register a callback */
16476cacf549SDag-Erling Smørgrav     static int python_inplace_cb_register(enum inplace_cb_list_type type,
16486cacf549SDag-Erling Smørgrav         PyObject* py_cb, struct module_env* env, int id)
16496cacf549SDag-Erling Smørgrav     {
16506cacf549SDag-Erling Smørgrav         int ret = inplace_cb_register(python_inplace_cb_reply_generic,
16516cacf549SDag-Erling Smørgrav                 type, (void*) py_cb, env, id);
16526cacf549SDag-Erling Smørgrav         if (ret) Py_INCREF(py_cb);
16536cacf549SDag-Erling Smørgrav         return ret;
16546cacf549SDag-Erling Smørgrav     }
16556cacf549SDag-Erling Smørgrav 
1656bd51c208SDag-Erling Smørgrav     /* Swig implementations for Python */
1657bd51c208SDag-Erling Smørgrav     static int register_inplace_cb_reply(PyObject* py_cb,
16586cacf549SDag-Erling Smørgrav         struct module_env* env, int id)
1659bd51c208SDag-Erling Smørgrav     {
16606cacf549SDag-Erling Smørgrav         return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id);
1661bd51c208SDag-Erling Smørgrav     }
1662bd51c208SDag-Erling Smørgrav     static int register_inplace_cb_reply_cache(PyObject* py_cb,
16636cacf549SDag-Erling Smørgrav         struct module_env* env, int id)
1664bd51c208SDag-Erling Smørgrav     {
16656cacf549SDag-Erling Smørgrav         return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id);
1666bd51c208SDag-Erling Smørgrav     }
1667bd51c208SDag-Erling Smørgrav     static int register_inplace_cb_reply_local(PyObject* py_cb,
16686cacf549SDag-Erling Smørgrav         struct module_env* env, int id)
1669bd51c208SDag-Erling Smørgrav     {
16706cacf549SDag-Erling Smørgrav         return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id);
1671bd51c208SDag-Erling Smørgrav     }
1672bd51c208SDag-Erling Smørgrav     static int register_inplace_cb_reply_servfail(PyObject* py_cb,
16736cacf549SDag-Erling Smørgrav         struct module_env* env, int id)
1674bd51c208SDag-Erling Smørgrav     {
16756cacf549SDag-Erling Smørgrav         return python_inplace_cb_register(inplace_cb_reply_servfail,
16766cacf549SDag-Erling Smørgrav                 py_cb, env, id);
1677bd51c208SDag-Erling Smørgrav     }
16789c9d011eSDag-Erling Smørgrav 
16799c9d011eSDag-Erling Smørgrav     int python_inplace_cb_query_generic(
16809c9d011eSDag-Erling Smørgrav         struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
16819c9d011eSDag-Erling Smørgrav         struct sockaddr_storage* addr, socklen_t addrlen,
16829c9d011eSDag-Erling Smørgrav         uint8_t* zone, size_t zonelen, struct regional* region, int id,
16839c9d011eSDag-Erling Smørgrav         void* python_callback)
16849c9d011eSDag-Erling Smørgrav     {
16859c9d011eSDag-Erling Smørgrav         int res = 0;
16869c9d011eSDag-Erling Smørgrav         PyObject *func = python_callback;
1687625f1c13SCy Schubert         PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL;
1688401770e0SCy Schubert         PyObject *py_qinfo = NULL;
1689401770e0SCy Schubert         PyObject *py_qstate = NULL;
1690401770e0SCy Schubert         PyObject *py_addr = NULL;
1691401770e0SCy Schubert         PyObject *py_zone = NULL;
1692401770e0SCy Schubert         PyObject *py_region = NULL;
16939c9d011eSDag-Erling Smørgrav 
16949c9d011eSDag-Erling Smørgrav         PyGILState_STATE gstate = PyGILState_Ensure();
16959c9d011eSDag-Erling Smørgrav 
1696401770e0SCy Schubert         py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1697401770e0SCy Schubert         py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1698401770e0SCy Schubert         py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
1699401770e0SCy Schubert         py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
1700401770e0SCy Schubert         py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1701401770e0SCy Schubert         if(!(py_qinfo && py_qstate && py_addr && py_zone && py_region)) {
1702401770e0SCy Schubert                 log_err("pythonmod: swig pointer failure in python_inplace_cb_query_generic");
1703401770e0SCy Schubert                 goto out;
1704401770e0SCy Schubert         }
1705625f1c13SCy Schubert         py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
1706625f1c13SCy Schubert         py_kwargs = Py_BuildValue("{}");
1707401770e0SCy Schubert         if(!(py_args && py_kwargs)) {
1708401770e0SCy Schubert                 log_err("pythonmod: BuildValue failure in python_inplace_cb_query_generic");
1709401770e0SCy Schubert                 goto out;
1710401770e0SCy Schubert         }
1711625f1c13SCy Schubert         result = PyObject_Call(func, py_args, py_kwargs);
17129c9d011eSDag-Erling Smørgrav         if (result) {
17139c9d011eSDag-Erling Smørgrav             res = PyInt_AsLong(result);
17149c9d011eSDag-Erling Smørgrav         }
1715401770e0SCy Schubert out:
17169c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_qinfo);
17179c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_qstate);
17189c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_addr);
17199c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_zone);
17209c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_region);
17219c9d011eSDag-Erling Smørgrav 
17229c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_args);
17239c9d011eSDag-Erling Smørgrav         Py_XDECREF(py_kwargs);
17249c9d011eSDag-Erling Smørgrav         Py_XDECREF(result);
17259c9d011eSDag-Erling Smørgrav 
17269c9d011eSDag-Erling Smørgrav         PyGILState_Release(gstate);
17279c9d011eSDag-Erling Smørgrav 
17289c9d011eSDag-Erling Smørgrav         return res;
17299c9d011eSDag-Erling Smørgrav     }
17309c9d011eSDag-Erling Smørgrav 
17319c9d011eSDag-Erling Smørgrav     static int register_inplace_cb_query(PyObject* py_cb,
17329c9d011eSDag-Erling Smørgrav         struct module_env* env, int id)
17339c9d011eSDag-Erling Smørgrav     {
17349c9d011eSDag-Erling Smørgrav         int ret = inplace_cb_register(python_inplace_cb_query_generic,
17359c9d011eSDag-Erling Smørgrav                 inplace_cb_query, (void*) py_cb, env, id);
17369c9d011eSDag-Erling Smørgrav         if (ret) Py_INCREF(py_cb);
17379c9d011eSDag-Erling Smørgrav         return ret;
17389c9d011eSDag-Erling Smørgrav     }
1739401770e0SCy Schubert 
1740401770e0SCy Schubert     int python_inplace_cb_query_response(struct module_qstate* qstate,
1741401770e0SCy Schubert         struct dns_msg* response, int id, void* python_callback)
1742401770e0SCy Schubert     {
1743401770e0SCy Schubert         int res = 0;
1744401770e0SCy Schubert         PyObject *func = python_callback;
1745401770e0SCy Schubert         PyObject *py_qstate = NULL;
1746401770e0SCy Schubert         PyObject *py_response = NULL;
1747401770e0SCy Schubert         PyObject *py_args = NULL;
1748401770e0SCy Schubert         PyObject *py_kwargs = NULL;
1749401770e0SCy Schubert         PyObject *result = NULL;
1750401770e0SCy Schubert 
1751401770e0SCy Schubert         PyGILState_STATE gstate = PyGILState_Ensure();
1752401770e0SCy Schubert 
1753401770e0SCy Schubert         py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1754401770e0SCy Schubert         py_response = SWIG_NewPointerObj((void*) response, SWIGTYPE_p_dns_msg, 0);
1755401770e0SCy Schubert         if(!(py_qstate && py_response)) {
1756401770e0SCy Schubert                 log_err("pythonmod: swig pointer failure in python_inplace_cb_query_response");
1757401770e0SCy Schubert                 goto out;
1758401770e0SCy Schubert         }
1759401770e0SCy Schubert         py_args = Py_BuildValue("(OO)", py_qstate, py_response);
1760401770e0SCy Schubert         py_kwargs = Py_BuildValue("{}");
1761401770e0SCy Schubert         if(!(py_args && py_kwargs)) {
1762401770e0SCy Schubert                 log_err("pythonmod: BuildValue failure in python_inplace_cb_query_response");
1763401770e0SCy Schubert                 goto out;
1764401770e0SCy Schubert         }
1765401770e0SCy Schubert         result = PyObject_Call(func, py_args, py_kwargs);
1766401770e0SCy Schubert         if (result) {
1767401770e0SCy Schubert             res = PyInt_AsLong(result);
1768401770e0SCy Schubert         }
1769401770e0SCy Schubert out:
1770401770e0SCy Schubert         Py_XDECREF(py_qstate);
1771401770e0SCy Schubert         Py_XDECREF(py_response);
1772401770e0SCy Schubert 
1773401770e0SCy Schubert         Py_XDECREF(py_args);
1774401770e0SCy Schubert         Py_XDECREF(py_kwargs);
1775401770e0SCy Schubert         Py_XDECREF(result);
1776401770e0SCy Schubert 
1777401770e0SCy Schubert         PyGILState_Release(gstate);
1778401770e0SCy Schubert 
1779401770e0SCy Schubert         return res;
1780401770e0SCy Schubert     }
1781401770e0SCy Schubert 
1782401770e0SCy Schubert     static int register_inplace_cb_query_response(PyObject* py_cb,
1783401770e0SCy Schubert         struct module_env* env, int id)
1784401770e0SCy Schubert     {
1785401770e0SCy Schubert         int ret = inplace_cb_register(python_inplace_cb_query_response,
1786401770e0SCy Schubert             inplace_cb_query_response, (void*) py_cb, env, id);
1787401770e0SCy Schubert         if (ret) Py_INCREF(py_cb);
1788401770e0SCy Schubert         return ret;
1789401770e0SCy Schubert     }
1790401770e0SCy Schubert 
1791401770e0SCy Schubert     int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate,
1792401770e0SCy Schubert         int id, void* python_callback)
1793401770e0SCy Schubert     {
1794401770e0SCy Schubert         int res = 0;
1795401770e0SCy Schubert         PyObject *func = python_callback;
1796401770e0SCy Schubert         PyObject *py_qstate = NULL;
1797401770e0SCy Schubert         PyObject *py_args = NULL;
1798401770e0SCy Schubert         PyObject *py_kwargs = NULL;
1799401770e0SCy Schubert         PyObject *result = NULL;
1800401770e0SCy Schubert 
1801401770e0SCy Schubert         PyGILState_STATE gstate = PyGILState_Ensure();
1802401770e0SCy Schubert 
1803401770e0SCy Schubert         py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1804401770e0SCy Schubert         if(!py_qstate) {
1805401770e0SCy Schubert                 log_err("pythonmod: swig pointer failure in python_inplace_cb_edns_back_parsed_call");
1806401770e0SCy Schubert                 goto out;
1807401770e0SCy Schubert         }
1808401770e0SCy Schubert         py_args = Py_BuildValue("(O)", py_qstate);
1809401770e0SCy Schubert         py_kwargs = Py_BuildValue("{}");
1810401770e0SCy Schubert         if(!(py_args && py_kwargs)) {
1811401770e0SCy Schubert                 log_err("pythonmod: BuildValue failure in python_inplace_cb_edns_back_parsed_call");
1812401770e0SCy Schubert                 goto out;
1813401770e0SCy Schubert         }
1814401770e0SCy Schubert         result = PyObject_Call(func, py_args, py_kwargs);
1815401770e0SCy Schubert         if (result) {
1816401770e0SCy Schubert             res = PyInt_AsLong(result);
1817401770e0SCy Schubert         }
1818401770e0SCy Schubert out:
1819401770e0SCy Schubert         Py_XDECREF(py_qstate);
1820401770e0SCy Schubert 
1821401770e0SCy Schubert         Py_XDECREF(py_args);
1822401770e0SCy Schubert         Py_XDECREF(py_kwargs);
1823401770e0SCy Schubert         Py_XDECREF(result);
1824401770e0SCy Schubert 
1825401770e0SCy Schubert         PyGILState_Release(gstate);
1826401770e0SCy Schubert 
1827401770e0SCy Schubert         return res;
1828401770e0SCy Schubert     }
1829401770e0SCy Schubert 
1830401770e0SCy Schubert     static int register_inplace_cb_edns_back_parsed_call(PyObject* py_cb,
1831401770e0SCy Schubert         struct module_env* env, int id)
1832401770e0SCy Schubert     {
1833401770e0SCy Schubert         int ret = inplace_cb_register(python_inplace_cb_edns_back_parsed_call,
1834401770e0SCy Schubert             inplace_cb_edns_back_parsed, (void*) py_cb, env, id);
1835401770e0SCy Schubert         if (ret) Py_INCREF(py_cb);
1836401770e0SCy Schubert         return ret;
1837401770e0SCy Schubert     }
1838bd51c208SDag-Erling Smørgrav %}
1839bd51c208SDag-Erling Smørgrav /* C declarations */
18406cacf549SDag-Erling Smørgrav int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
18416cacf549SDag-Erling Smørgrav     struct module_env* env, int id);
1842bd51c208SDag-Erling Smørgrav 
1843bd51c208SDag-Erling Smørgrav /* Swig declarations */
1844bd51c208SDag-Erling Smørgrav static int register_inplace_cb_reply(PyObject* py_cb,
18456cacf549SDag-Erling Smørgrav     struct module_env* env, int id);
1846bd51c208SDag-Erling Smørgrav static int register_inplace_cb_reply_cache(PyObject* py_cb,
18476cacf549SDag-Erling Smørgrav     struct module_env* env, int id);
1848bd51c208SDag-Erling Smørgrav static int register_inplace_cb_reply_local(PyObject* py_cb,
18496cacf549SDag-Erling Smørgrav     struct module_env* env, int id);
1850bd51c208SDag-Erling Smørgrav static int register_inplace_cb_reply_servfail(PyObject* py_cb,
18516cacf549SDag-Erling Smørgrav     struct module_env* env, int id);
18529c9d011eSDag-Erling Smørgrav static int register_inplace_cb_query(PyObject *py_cb,
18539c9d011eSDag-Erling Smørgrav     struct module_env* env, int id);
1854401770e0SCy Schubert static int register_inplace_cb_query_response(PyObject *py_cb,
1855401770e0SCy Schubert     struct module_env* env, int id);
1856401770e0SCy Schubert static int register_inplace_cb_edns_back_parsed_call(PyObject *py_cb,
1857401770e0SCy Schubert     struct module_env* env, int id);
1858