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