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