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