2 * interface.i: unbound python module
5 /* store state of warning output, restored at later pop */
6 #pragma GCC diagnostic push
7 /* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
8 #pragma GCC diagnostic ignored "-Wcast-function-type"
12 /* restore state of warning output, remove the functioncast ignore */
13 #pragma GCC diagnostic pop
16 * This is the interface between the unbound server and a python module
17 * called to perform operations on queries.
19 #include <sys/types.h>
20 #ifdef HAVE_SYS_SOCKET_H
21 #include <sys/socket.h>
23 #ifdef HAVE_NETINET_IN_H
24 #include <netinet/in.h>
26 #ifdef HAVE_ARPA_INET_H
27 #include <arpa/inet.h>
38 #include "util/module.h"
39 #include "util/netevent.h"
40 #include "util/regional.h"
41 #include "util/config_file.h"
42 #include "util/data/msgreply.h"
43 #include "util/data/packed_rrset.h"
44 #include "util/data/dname.h"
45 #include "util/storage/lruhash.h"
46 #include "services/cache/dns.h"
47 #include "services/mesh.h"
48 #include "iterator/iter_delegpt.h"
49 #include "iterator/iter_hints.h"
50 #include "iterator/iter_utils.h"
51 #include "sldns/wire2str.h"
52 #include "sldns/str2wire.h"
53 #include "sldns/pkthdr.h"
56 %include "stdint.i" /* uint_16_t can be known type now */
59 /* converts [len][data][len][data][0] string to a List of labels (PyBytes) */
60 PyObject* GetNameAsLabelList(const char* name, int len) {
66 i += ((unsigned int)name[i]) + 1;
70 list = PyList_New(cnt);
73 char buf[LDNS_MAX_LABELLEN+1];
74 if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) &&
75 i+(int)((unsigned int)name[i]) < len) {
76 memmove(buf, name + i + 1, (unsigned int)name[i]);
77 buf[(unsigned int)name[i]] = 0;
78 PyList_SetItem(list, cnt, PyString_FromString(buf));
80 i += ((unsigned int)name[i]) + 1;
87 /* ************************************************************************************ *
89 * ************************************************************************************ */
91 %ignore query_info::qname;
92 %ignore query_info::qname_len;
136 RR_TYPE_NSAP_PTR = 23,
158 RR_TYPE_IPSECKEY = 45,
164 RR_TYPE_NSEC3PARAMS = 51,
168 RR_TYPE_UNSPEC = 103,
178 PyObject* _get_qname(struct query_info* q) {
179 return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len);
182 PyObject* _get_qname_components(struct query_info* q) {
183 return GetNameAsLabelList((const char*)q->qname, q->qname_len);
188 PyObject* dnameAsStr(PyObject* dname) {
189 char buf[LDNS_MAX_DOMAINLEN+1];
191 dname_str((uint8_t*)PyBytes_AsString(dname), buf);
192 return PyString_FromString(buf);
198 def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
199 __swig_getmethods__["qtype_str"] = _get_qtype_str
200 if _newclass:qtype_str = _swig_property(_get_qtype_str)
202 def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
203 __swig_getmethods__["qclass_str"] = _get_qclass_str
204 if _newclass:qclass_str = _swig_property(_get_qclass_str)
206 __swig_getmethods__["qname"] = _unboundmodule._get_qname
207 if _newclass:qname = _swig_property(_unboundmodule._get_qname)
209 __swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components
210 if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components)
212 def _get_qname_str(self): return dnameAsStr(self.qname)
213 __swig_getmethods__["qname_str"] = _get_qname_str
214 if _newclass:qname_str = _swig_property(_get_qname_str)
218 /* ************************************************************************************ *
219 Structure packed_rrset_key
220 * ************************************************************************************ */
221 %ignore packed_rrset_key::dname;
222 %ignore packed_rrset_key::dname_len;
225 struct packed_rrset_key {
230 uint16_t type; /* rrset type in network format */
231 uint16_t rrset_class; /* rrset class in network format */
236 * This subroutine converts values between the host and network byte order.
237 * Specifically, ntohs() converts 16-bit quantities from network byte order to
240 uint16_t ntohs(uint16_t netshort);
243 PyObject* _get_dname(struct packed_rrset_key* k) {
244 return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len);
246 PyObject* _get_dname_components(struct packed_rrset_key* k) {
247 return GetNameAsLabelList((char*)k->dname, k->dname_len);
251 %extend packed_rrset_key {
253 def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
254 __swig_getmethods__["type_str"] = _get_type_str
255 if _newclass:type_str = _swig_property(_get_type_str)
257 def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
258 __swig_getmethods__["rrset_class_str"] = _get_class_str
259 if _newclass:rrset_class_str = _swig_property(_get_class_str)
261 __swig_getmethods__["dname"] = _unboundmodule._get_dname
262 if _newclass:dname = _swig_property(_unboundmodule._get_dname)
264 __swig_getmethods__["dname_list"] = _unboundmodule._get_dname_components
265 if _newclass:dname_list = _swig_property(_unboundmodule._get_dname_components)
267 def _get_dname_str(self): return dnameAsStr(self.dname)
268 __swig_getmethods__["dname_str"] = _get_dname_str
269 if _newclass:dname_str = _swig_property(_get_dname_str)
273 #if defined(SWIGWORDSIZE64)
274 typedef long int rrset_id_type;
276 typedef long long int rrset_id_type;
279 struct ub_packed_rrset_key {
280 struct lruhash_entry entry;
282 struct packed_rrset_key rk;
285 struct lruhash_entry {
287 struct lruhash_entry* overflow_next;
288 struct lruhash_entry* lru_next;
289 struct lruhash_entry* lru_prev;
292 struct packed_rrset_data* data;
295 %ignore packed_rrset_data::rr_len;
296 %ignore packed_rrset_data::rr_ttl;
297 %ignore packed_rrset_data::rr_data;
299 struct packed_rrset_data {
300 /* TTL (in seconds like time()) */
305 /* number of rrsigs */
308 enum rrset_trust trust;
309 enum sec_status security;
311 /* length of every rr's rdata */
313 /* ttl of every rr */
315 /* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in
316 * uncompressed wireformat. */
321 class RRSetData_RRLen:
322 def __init__(self, obj): self.obj = obj
323 def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index)
324 def __len__(self): return obj.count + obj.rrsig_count
325 class RRSetData_RRTTL:
326 def __init__(self, obj): self.obj = obj
327 def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index)
328 def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value)
329 def __len__(self): return obj.count + obj.rrsig_count
330 class RRSetData_RRData:
331 def __init__(self, obj): self.obj = obj
332 def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index)
333 def __len__(self): return obj.count + obj.rrsig_count
337 PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
338 if ((d != NULL) && (idx >= 0) &&
339 ((size_t)idx < (d->count+d->rrsig_count)))
340 return PyInt_FromLong(d->rr_len[idx]);
343 void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
345 if ((d != NULL) && (idx >= 0) &&
346 ((size_t)idx < (d->count+d->rrsig_count)))
347 d->rr_ttl[idx] = ttl;
349 PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
350 if ((d != NULL) && (idx >= 0) &&
351 ((size_t)idx < (d->count+d->rrsig_count)))
352 return PyInt_FromLong(d->rr_ttl[idx]);
355 PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
356 if ((d != NULL) && (idx >= 0) &&
357 ((size_t)idx < (d->count+d->rrsig_count)))
358 return PyBytes_FromStringAndSize((char*)d->rr_data[idx],
364 %extend packed_rrset_data {
366 def _get_data_rr_len(self): return RRSetData_RRLen(self)
367 __swig_getmethods__["rr_len"] = _get_data_rr_len
368 if _newclass:rr_len = _swig_property(_get_data_rr_len)
369 def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
370 __swig_getmethods__["rr_ttl"] =_get_data_rr_ttl
371 if _newclass:rr_len = _swig_property(_get_data_rr_ttl)
372 def _get_data_rr_data(self): return RRSetData_RRData(self)
373 __swig_getmethods__["rr_data"] = _get_data_rr_data
374 if _newclass:rr_len = _swig_property(_get_data_rr_data)
378 /* ************************************************************************************ *
380 * ************************************************************************************ */
382 %ignore reply_info::rrsets;
383 %ignore reply_info::ref;
389 uint32_t prefetch_ttl;
391 uint16_t authoritative;
392 enum sec_status security;
397 size_t rrset_count; /* an_numrrsets + ns_numrrsets + ar_numrrsets */
399 struct ub_packed_rrset_key** rrsets;
400 struct rrset_ref ref[1]; /* ? */
404 struct ub_packed_rrset_key* key;
409 struct query_info qinfo;
410 struct reply_info *rep;
414 class ReplyInfo_RRSet:
415 def __init__(self, obj): self.obj = obj
416 def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index)
417 def __len__(self): return obj.rrset_count
420 def __init__(self, obj): self.obj = obj
421 def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index)
422 def __len__(self): return obj.rrset_count
426 struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) {
427 if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count))
428 return r->rrsets[idx];
432 struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
433 if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) {
434 /* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */
435 return &(r->ref[idx]);
436 /* return &(r->ref[idx]); */
438 /* printf("_rrset_ref_get: NULL\n"); */
445 def _rrset_ref_get(self): return ReplyInfo_Ref(self)
446 __swig_getmethods__["ref"] = _rrset_ref_get
447 if _newclass:ref = _swig_property(_rrset_ref_get)
449 def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
450 __swig_getmethods__["rrsets"] = _rrset_rrsets_get
451 if _newclass:rrsets = _swig_property(_rrset_rrsets_get)
455 /* ************************************************************************************ *
456 Structure sockaddr_storage
457 * ************************************************************************************ */
459 struct sockaddr_storage {};
462 static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) {
467 switch (ss->ss_family) {
468 case AF_INET: return sizeof(struct sockaddr_in);
469 case AF_INET6: return sizeof(struct sockaddr_in6);
471 case AF_UNIX: return sizeof(struct sockaddr_un);
478 PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) {
483 switch (ss->ss_family) {
484 case AF_INET: return PyUnicode_FromString("ip4");
485 case AF_INET6: return PyUnicode_FromString("ip6");
486 case AF_UNIX: return PyUnicode_FromString("unix");
492 PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) {
493 const struct sockaddr *sa;
495 char name[NI_MAXHOST] = {0};
501 sa = (struct sockaddr *)ss;
502 sa_len = _sockaddr_storage_len(ss);
507 if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) {
511 return PyUnicode_FromString(name);
514 PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) {
521 sa_len = _sockaddr_storage_len(ss);
526 if (ss->ss_family == AF_INET) {
527 const struct sockaddr_in *sa = (struct sockaddr_in *)ss;
528 const struct in_addr *raw = (struct in_addr *)&sa->sin_addr;
529 return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
532 if (ss->ss_family == AF_INET6) {
533 const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
534 const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr;
535 return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
539 if (ss->ss_family == AF_UNIX) {
540 const struct sockaddr_un *sa = (struct sockaddr_un *)ss;
541 return PyBytes_FromString(sa->sun_path);
548 PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
553 if (ss->ss_family == AF_INET) {
554 const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
555 return PyInt_FromLong(ntohs(sa4->sin_port));
558 if (ss->ss_family == AF_INET6) {
559 const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
560 return PyInt_FromLong(ntohs(sa6->sin6_port));
566 PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
567 const struct sockaddr_in6 *sa6;
569 if (ss == NULL || ss->ss_family != AF_INET6) {
573 sa6 = (struct sockaddr_in6 *)ss;
574 return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
577 PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
578 const struct sockaddr_in6 *sa6;
580 if (ss == NULL || ss->ss_family != AF_INET6) {
584 sa6 = (struct sockaddr_in6 *)ss;
585 return PyInt_FromLong(ntohl(sa6->sin6_scope_id));
589 %extend sockaddr_storage {
591 def _family_get(self): return _sockaddr_storage_family(self)
592 __swig_getmethods__["family"] = _family_get
593 if _newclass: family = _swig_property(_family_get)
595 def _addr_get(self): return _sockaddr_storage_addr(self)
596 __swig_getmethods__["addr"] = _addr_get
597 if _newclass: addr = _swig_property(_addr_get)
599 def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self)
600 __swig_getmethods__["raw_addr"] = _raw_addr_get
601 if _newclass: raw_addr = _swig_property(_raw_addr_get)
603 def _port_get(self): return _sockaddr_storage_port(self)
604 __swig_getmethods__["port"] = _port_get
605 if _newclass: port = _swig_property(_port_get)
607 def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self)
608 __swig_getmethods__["flowinfo"] = _flowinfo_get
609 if _newclass: flowinfo = _swig_property(_flowinfo_get)
611 def _scope_id_get(self): return _sockaddr_storage_scope_id(self)
612 __swig_getmethods__["scope_id"] = _scope_id_get
613 if _newclass: scope_id = _swig_property(_scope_id_get)
617 /* ************************************************************************************ *
619 * ************************************************************************************ */
621 struct mesh_reply* reply_list;
625 struct mesh_reply* next;
626 struct comm_reply query_reply;
629 %rename(_addr) comm_reply::addr;
631 struct sockaddr_storage addr;
636 def _addr_get(self): return _sockaddr_storage_addr(self._addr)
637 __swig_getmethods__["addr"] = _addr_get
638 if _newclass:addr = _swig_property(_addr_get)
640 def _port_get(self): return _sockaddr_storage_port(self._addr)
641 __swig_getmethods__["port"] = _port_get
642 if _newclass:port = _swig_property(_port_get)
644 def _family_get(self): return _sockaddr_storage_family(self._addr)
645 __swig_getmethods__["family"] = _family_get
646 if _newclass:family = _swig_property(_family_get)
650 /* ************************************************************************************ *
651 Structure edns_option
652 * ************************************************************************************ */
653 /* Rename the members to follow the python convention of marking them as
654 * private. Access to the opt_code and opt_data members is given by the later
655 * python defined code and data members respectively. */
656 %rename(_next) edns_option::next;
657 %rename(_opt_code) edns_option::opt_code;
658 %rename(_opt_len) edns_option::opt_len;
659 %rename(_opt_data) edns_option::opt_data;
661 struct edns_option* next;
668 PyObject* _edns_option_opt_code_get(struct edns_option* option) {
669 uint16_t opt_code = option->opt_code;
670 return PyInt_FromLong(opt_code);
673 PyObject* _edns_option_opt_data_get(struct edns_option* option) {
674 return PyByteArray_FromStringAndSize((void*)option->opt_data,
678 %extend edns_option {
680 def _opt_code_get(self): return _edns_option_opt_code_get(self)
681 __swig_getmethods__["code"] = _opt_code_get
682 if _newclass: opt_code = _swig_property(_opt_code_get)
684 def _opt_data_get(self): return _edns_option_opt_data_get(self)
685 __swig_getmethods__["data"] = _opt_data_get
686 if _newclass: opt_data = _swig_property(_opt_data_get)
690 /* ************************************************************************************ *
692 * ************************************************************************************ */
693 /* This is ignored because we will pass a double pointer of this to Python
694 * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
695 * pointers as None. */
696 %ignore edns_data::opt_list;
700 uint8_t edns_version;
703 struct edns_option* opt_list;
706 struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) {
707 return &edns->opt_list;
712 def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
713 __swig_getmethods__["opt_list_iter"] = _opt_list_iter
714 if _newclass:opt_list_iter = _swig_property(_opt_list_iter)
715 def _opt_list(self): return _edns_data_opt_list_get(self)
716 __swig_getmethods__["opt_list"] = _opt_list
717 if _newclass:opt_list = _swig_property(_opt_list)
721 /* ************************************************************************************ *
723 * ************************************************************************************ */
725 struct config_file* cfg;
726 struct slabhash* msg_cache;
727 struct rrset_cache* rrset_cache;
728 struct infra_cache* infra_cache;
729 struct key_cache* key_cache;
731 /* --- services --- */
732 struct outbound_entry* (*send_query)(struct query_info* qinfo,
733 uint16_t flags, int dnssec, int want_dnssec, int nocaps,
734 struct sockaddr_storage* addr, socklen_t addrlen,
735 uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
736 struct module_qstate* q);
737 void (*detach_subs)(struct module_qstate* qstate);
738 int (*attach_sub)(struct module_qstate* qstate,
739 struct query_info* qinfo, uint16_t qflags, int prime,
740 int valrec, struct module_qstate** newq);
741 void (*kill_sub)(struct module_qstate* newq);
742 int (*detect_cycle)(struct module_qstate* qstate,
743 struct query_info* qinfo, uint16_t flags, int prime,
746 struct regional* scratch;
747 struct sldns_buffer* scratch_buffer;
748 struct worker* worker;
749 struct mesh_area* mesh;
750 struct alloc_cache* alloc;
751 struct ub_randstate* rnd;
753 struct timeval* now_tv;
754 int need_to_validate;
755 struct val_anchors* anchors;
756 struct val_neg_cache* neg_cache;
757 struct comm_timer* probe_timer;
758 struct iter_forwards* fwds;
759 struct iter_hints* hints;
760 void* modinfo[MAX_MODULE];
762 void* inplace_cb_lists[inplace_cb_types_total];
763 struct edns_known_option* edns_known_options;
764 size_t edns_known_options_num;
767 /* ************************************************************************************ *
768 Structure module_qstate
769 * ************************************************************************************ */
770 %ignore module_qstate::ext_state;
771 %ignore module_qstate::minfo;
773 /* These are ignored because we will pass a double pointer of them to Python
774 * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
775 * pointers as None. */
776 %ignore module_qstate::edns_opts_front_in;
777 %ignore module_qstate::edns_opts_back_out;
778 %ignore module_qstate::edns_opts_back_in;
779 %ignore module_qstate::edns_opts_front_out;
782 struct module_qstate {
783 struct query_info qinfo;
784 uint16_t query_flags; /* See QF_BIT_xx constants */
788 struct comm_reply* reply;
789 struct dns_msg* return_msg;
791 struct regional* region; /* unwrapped */
795 enum module_ext_state ext_state[MAX_MODULE];
796 void* minfo[MAX_MODULE];
797 time_t prefetch_leeway;
799 struct module_env* env; /* unwrapped */
800 struct mesh_state* mesh_info;
802 struct edns_option* edns_opts_front_in;
803 struct edns_option* edns_opts_back_out;
804 struct edns_option* edns_opts_back_in;
805 struct edns_option* edns_opts_front_out;
810 %constant int MODULE_COUNT = MAX_MODULE;
812 %constant int QF_BIT_CD = 0x0010;
813 %constant int QF_BIT_AD = 0x0020;
814 %constant int QF_BIT_Z = 0x0040;
815 %constant int QF_BIT_RA = 0x0080;
816 %constant int QF_BIT_RD = 0x0100;
817 %constant int QF_BIT_TC = 0x0200;
818 %constant int QF_BIT_AA = 0x0400;
819 %constant int QF_BIT_QR = 0x8000;
822 enum enum_return_rcode {
839 def __init__(self, obj): self.obj = obj
841 return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)])
842 def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index)
843 def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value)
844 def __len__(self): return _unboundmodule.MODULE_COUNT
846 class EdnsOptsListIter:
847 def __init__(self, obj):
850 def __iter__(self): return self
852 """Python 3 compatibility"""
853 return self._get_next()
855 """Python 2 compatibility"""
856 return self._get_next()
858 if not edns_opt_list_is_empty(self._current):
859 self._temp = self._current
860 self._current = _p_p_edns_option_get_next(self._current)
861 return _dereference_edns_option(self._temp)
867 enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
868 if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
869 return q->ext_state[idx];
874 void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
875 if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
876 q->ext_state[idx] = state;
880 int edns_opt_list_is_empty(struct edns_option** opt) {
881 if (!opt || !(*opt)) return 1;
885 struct edns_option* _dereference_edns_option(struct edns_option** opt) {
886 if (!opt) return NULL;
890 struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) {
891 return &(*opt)->next;
894 struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) {
895 return &q->edns_opts_front_in;
898 struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) {
899 return &q->edns_opts_back_out;
902 struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) {
903 return &q->edns_opts_back_in;
906 struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) {
907 return &q->edns_opts_front_out;
911 %extend module_qstate {
913 def set_ext_state(self, id, state):
914 """Sets the ext state"""
915 _unboundmodule._ext_state_set(self, id, state)
917 def __ext_state_get(self): return ExtState(self)
918 __swig_getmethods__["ext_state"] = __ext_state_get
919 if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
921 def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
922 __swig_getmethods__["edns_opts_front_in_iter"] = _edns_opts_front_in_iter
923 if _newclass:edns_opts_front_in_iter = _swig_property(_edns_opts_front_in_iter)
924 def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
925 __swig_getmethods__["edns_opts_back_out_iter"] = _edns_opts_back_out_iter
926 if _newclass:edns_opts_back_out_iter = _swig_property(_edns_opts_back_out_iter)
927 def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
928 __swig_getmethods__["edns_opts_back_in_iter"] = _edns_opts_back_in_iter
929 if _newclass:edns_opts_back_in_iter = _swig_property(_edns_opts_back_in_iter)
930 def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
931 __swig_getmethods__["edns_opts_front_out_iter"] = _edns_opts_front_out_iter
932 if _newclass:edns_opts_front_out_iter = _swig_property(_edns_opts_front_out_iter)
934 def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
935 __swig_getmethods__["edns_opts_front_in"] = _edns_opts_front_in
936 if _newclass:edns_opts_front_in = _swig_property(_edns_opts_front_in)
937 def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
938 __swig_getmethods__["edns_opts_back_out"] = _edns_opts_back_out
939 if _newclass:edns_opts_back_out = _swig_property(_edns_opts_back_out)
940 def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
941 __swig_getmethods__["edns_opts_back_in"] = _edns_opts_back_in
942 if _newclass:edns_opts_back_in = _swig_property(_edns_opts_back_in)
943 def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
944 __swig_getmethods__["edns_opts_front_out"] = _edns_opts_front_out
945 if _newclass:edns_opts_front_out = _swig_property(_edns_opts_front_out)
949 /* ************************************************************************************ *
950 Structure config_strlist
951 * ************************************************************************************ */
952 struct config_strlist {
953 struct config_strlist* next;
957 /* ************************************************************************************ *
958 Structure config_str2list
959 * ************************************************************************************ */
960 struct config_str2list {
961 struct config_str2list* next;
966 /* ************************************************************************************ *
967 Structure config_file
968 * ************************************************************************************ */
980 int outgoing_num_ports;
981 size_t outgoing_num_tcp;
982 size_t incoming_num_tcp;
983 int* outgoing_avail_ports;
984 size_t msg_buffer_size;
985 size_t msg_cache_size;
986 size_t msg_cache_slabs;
987 size_t num_queries_per_thread;
989 size_t rrset_cache_size;
990 size_t rrset_cache_slabs;
992 size_t infra_cache_slabs;
993 size_t infra_cache_numhosts;
994 char* target_fetch_policy;
1000 struct config_strlist* root_hints;
1001 struct config_stub* stubs;
1002 struct config_stub* forwards;
1003 struct config_strlist* donotqueryaddrs;
1004 struct config_str2list* acls;
1005 int donotquery_localhost;
1006 int harden_short_bufsize;
1007 int harden_large_queries;
1009 int harden_dnssec_stripped;
1010 int harden_referral_path;
1011 int use_caps_bits_for_id;
1012 struct config_strlist* private_address;
1013 struct config_strlist* private_domain;
1014 size_t unwanted_threshold;
1026 struct config_strlist* trust_anchor_file_list;
1027 struct config_strlist* trust_anchor_list;
1028 struct config_strlist* trusted_keys_file_list;
1029 char* dlv_anchor_file;
1030 struct config_strlist* dlv_anchor_list;
1032 int32_t val_date_override;
1034 int val_clean_additional;
1035 int val_permissive_mode;
1036 char* val_nsec3_key_iterations;
1037 size_t key_cache_size;
1038 size_t key_cache_slabs;
1039 size_t neg_cache_size;
1040 struct config_str2list* local_zones;
1041 struct config_strlist* local_zones_nodefault;
1042 struct config_strlist* local_data;
1043 int remote_control_enable;
1044 struct config_strlist_head control_ifs;
1046 char* server_key_file;
1047 char* server_cert_file;
1048 char* control_key_file;
1049 char* control_cert_file;
1051 char* python_script;
1054 /* ************************************************************************************ *
1055 ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation
1056 * ************************************************************************************ */
1058 struct delegpt_ns* next;
1063 uint8_t done_pside4;
1064 uint8_t done_pside6;
1067 struct delegpt_addr {
1068 struct delegpt_addr* next_result;
1069 struct delegpt_addr* next_usable;
1070 struct delegpt_addr* next_target;
1079 struct delegpt_ns* nslist;
1080 struct delegpt_addr* target_list;
1081 struct delegpt_addr* usable_list;
1082 struct delegpt_addr* result_list;
1084 uint8_t has_parent_side_NS;
1085 uint8_t dp_type_mlc;
1090 PyObject* _get_dp_dname(struct delegpt* dp) {
1091 return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen);
1093 PyObject* _get_dp_dname_components(struct delegpt* dp) {
1094 return GetNameAsLabelList((char*)dp->name, dp->namelen);
1096 PyObject* _get_dpns_dname(struct delegpt_ns* dpns) {
1097 return PyBytes_FromStringAndSize((char*)dpns->name, dpns->namelen);
1099 PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) {
1100 return GetNameAsLabelList((char*)dpns->name, dpns->namelen);
1103 PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) {
1105 delegpt_addr_addr2str(target, dest, 64);
1108 return PyBytes_FromString(dest);
1115 __swig_getmethods__["dname"] = _unboundmodule._get_dp_dname
1116 if _newclass:dname = _swig_property(_unboundmodule._get_dp_dname)
1118 __swig_getmethods__["dname_list"] = _unboundmodule._get_dp_dname_components
1119 if _newclass:dname_list = _swig_property(_unboundmodule._get_dp_dname_components)
1121 def _get_dname_str(self): return dnameAsStr(self.dname)
1122 __swig_getmethods__["dname_str"] = _get_dname_str
1123 if _newclass:dname_str = _swig_property(_get_dname_str)
1126 %extend delegpt_ns {
1128 __swig_getmethods__["dname"] = _unboundmodule._get_dpns_dname
1129 if _newclass:dname = _swig_property(_unboundmodule._get_dpns_dname)
1131 __swig_getmethods__["dname_list"] = _unboundmodule._get_dpns_dname_components
1132 if _newclass:dname_list = _swig_property(_unboundmodule._get_dpns_dname_components)
1134 def _get_dname_str(self): return dnameAsStr(self.dname)
1135 __swig_getmethods__["dname_str"] = _get_dname_str
1136 if _newclass:dname_str = _swig_property(_get_dname_str)
1139 %extend delegpt_addr {
1141 def _addr_get(self): return _delegpt_addr_addr_get(self)
1142 __swig_getmethods__["addr"] = _addr_get
1143 if _newclass:addr = _swig_property(_addr_get)
1147 /* ************************************************************************************ *
1149 * ************************************************************************************ */
1150 %rename ("MODULE_STATE_INITIAL") "module_state_initial";
1151 %rename ("MODULE_WAIT_REPLY") "module_wait_reply";
1152 %rename ("MODULE_WAIT_MODULE") "module_wait_module";
1153 %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
1154 %rename ("MODULE_ERROR") "module_error";
1155 %rename ("MODULE_FINISHED") "module_finished";
1157 enum module_ext_state {
1158 module_state_initial = 0,
1161 module_wait_subquery,
1166 %rename ("MODULE_EVENT_NEW") "module_event_new";
1167 %rename ("MODULE_EVENT_PASS") "module_event_pass";
1168 %rename ("MODULE_EVENT_REPLY") "module_event_reply";
1169 %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply";
1170 %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail";
1171 %rename ("MODULE_EVENT_MODDONE") "module_event_moddone";
1172 %rename ("MODULE_EVENT_ERROR") "module_event_error";
1175 module_event_new = 0,
1178 module_event_noreply,
1179 module_event_capsfail,
1180 module_event_moddone,
1185 sec_status_unchecked = 0,
1187 sec_status_indeterminate,
1188 sec_status_insecure,
1192 enum verbosity_value {
1200 enum inplace_cb_list_type {
1201 /* Inplace callbacks for when a resolved reply is ready to be sent to the
1203 inplace_cb_reply = 0,
1204 /* Inplace callbacks for when a reply is given from the cache. */
1205 inplace_cb_reply_cache,
1206 /* Inplace callbacks for when a reply is given with local data
1207 * (or Chaos reply). */
1208 inplace_cb_reply_local,
1209 /* Inplace callbacks for when the reply is servfail. */
1210 inplace_cb_reply_servfail,
1211 /* Inplace callbacks for when a query is ready to be sent to the back.*/
1213 /* Inplace callback for when a reply is received from the back. */
1214 inplace_cb_edns_back_parsed,
1215 /* Total number of types. Used for array initialization.
1216 * Should always be last. */
1217 inplace_cb_types_total
1220 %constant uint16_t PKT_QR = 1; /* QueRy - query flag */
1221 %constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */
1222 %constant uint16_t PKT_TC = 4; /* TrunCated - server flag */
1223 %constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */
1224 %constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */
1225 %constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */
1226 %constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */
1229 int checkList(PyObject *l)
1237 if (PyList_Check(l))
1239 for (i=0; i < PyList_Size(l); i++)
1241 item = PyList_GetItem(l, i);
1242 if (!PyBytes_Check(item) && !PyUnicode_Check(item))
1251 int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
1252 size_t count_offset)
1260 for (i=0; i < PyList_Size(l); i++)
1263 item = PyList_GetItem(l, i);
1264 if(PyObject_TypeCheck(item, &PyBytes_Type)) {
1265 s = PyBytes_AsString(item);
1267 ascstr = PyUnicode_AsASCIIString(item);
1268 s = PyBytes_AsString(ascstr);
1271 len = sldns_buffer_remaining(qb);
1273 if(sldns_str2wire_rr_question_buf(s,
1274 sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
1281 if(sldns_str2wire_rr_buf(s,
1282 sldns_buffer_current(qb), &len, NULL, default_ttl,
1283 NULL, 0, NULL, 0) != 0) {
1291 sldns_buffer_skip(qb, len);
1293 sldns_buffer_write_u16_at(qb, count_offset,
1294 sldns_buffer_read_u16_at(qb, count_offset)+1);
1299 int set_return_msg(struct module_qstate* qstate,
1300 const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
1301 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
1303 sldns_buffer *qb = 0;
1306 uint16_t PKT_QR = 1;
1307 uint16_t PKT_AA = 2;
1308 uint16_t PKT_TC = 4;
1309 uint16_t PKT_RD = 8;
1310 uint16_t PKT_CD = 16;
1311 uint16_t PKT_RA = 32;
1312 uint16_t PKT_AD = 64;
1314 if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
1316 if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0;
1319 sldns_buffer_write_u16(qb, 0); /* ID */
1320 sldns_buffer_write_u16(qb, 0); /* flags */
1321 sldns_buffer_write_u16(qb, 1); /* qdcount */
1322 sldns_buffer_write_u16(qb, 0); /* ancount */
1323 sldns_buffer_write_u16(qb, 0); /* nscount */
1324 sldns_buffer_write_u16(qb, 0); /* arcount */
1325 if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb));
1326 if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb));
1327 if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb));
1328 if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb));
1329 if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb));
1330 if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb));
1331 if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb));
1333 /* write the query */
1334 l = sldns_buffer_remaining(qb);
1335 if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) {
1336 sldns_buffer_free(qb);
1339 sldns_buffer_skip(qb, l);
1340 if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; }
1341 if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; }
1342 sldns_buffer_write_u16(qb, rr_type);
1343 sldns_buffer_write_u16(qb, rr_class);
1345 /* write RR sections */
1346 if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF))
1348 if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF))
1350 if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF))
1352 if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF))
1355 if (res) res = createResponse(qstate, qb);
1357 if (qb) sldns_buffer_free(qb);
1362 int set_return_msg(struct module_qstate* qstate,
1363 const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
1364 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
1368 def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0):
1369 """Query flags is a combination of PKT_xx contants"""
1370 self.rr_name = rr_name
1371 self.rr_type = rr_type
1372 self.rr_class = rr_class
1373 self.default_ttl = default_ttl
1374 self.query_flags = query_flags
1378 self.additional = []
1380 def set_return_msg(self, qstate):
1381 """Returns 1 if OK"""
1382 status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
1383 self.query_flags, self.default_ttl,
1384 self.question, self.answer, self.authority, self.additional)
1386 if (status) and (PKT_AA & self.query_flags):
1387 qstate.return_msg.rep.authoritative = 1
1392 /* ************************************************************************************ *
1393 ASN: Delegation pointer related functions
1394 * ************************************************************************************ */
1396 /* Functions which we will need to lookup delegations */
1397 struct delegpt* dns_cache_find_delegation(struct module_env* env,
1398 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
1399 struct regional* region, struct dns_msg** msg, uint32_t timenow);
1400 int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
1401 struct delegpt* dp);
1402 struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
1403 uint8_t* qname, uint16_t qclass, struct delegpt* dp);
1405 /* Custom function to perform logic similar to the one in daemon/cachedump.c */
1406 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen);
1409 #define BIT_RD 0x100
1411 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen)
1414 struct dns_msg *msg = NULL;
1415 struct regional* region = qstate->env->scratch;
1417 struct query_info qinfo;
1418 struct iter_hints_stub* stub;
1419 uint32_t timenow = *qstate->env->now;
1421 regional_free_all(region);
1422 qinfo.qname = (uint8_t*)nm;
1423 qinfo.qname_len = nmlen;
1424 qinfo.qtype = LDNS_RR_TYPE_A;
1425 qinfo.qclass = LDNS_RR_CLASS_IN;
1428 dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow);
1431 if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
1432 if (dname_is_root((uint8_t*)nm))
1434 nm = (char*)dp->name;
1435 nmlen = dp->namelen;
1436 dname_remove_label((uint8_t**)&nm, &nmlen);
1437 dname_str((uint8_t*)nm, b);
1440 stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, qinfo.qclass, dp);
1451 /* ************************************************************************************ *
1453 * ************************************************************************************ */
1454 /******************************
1455 * Various debugging functions *
1456 ******************************/
1457 void verbose(enum verbosity_value level, const char* format, ...);
1458 void log_info(const char* format, ...);
1459 void log_err(const char* format, ...);
1460 void log_warn(const char* format, ...);
1461 void log_hex(const char* msg, void* data, size_t length);
1462 void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep);
1463 void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
1464 void regional_log_stats(struct regional *r);
1466 /***************************************************************************
1467 * Free allocated memory from marked sources returning corresponding types *
1468 ***************************************************************************/
1469 %typemap(newfree, noblock = 1) char * {
1473 /***************************************************
1474 * Mark as source returning newly allocated memory *
1475 ***************************************************/
1476 %newobject sldns_wire2str_type;
1477 %newobject sldns_wire2str_class;
1482 char *sldns_wire2str_type(const uint16_t atype);
1483 char *sldns_wire2str_class(const uint16_t aclass);
1485 /**********************************
1486 * Functions from pythonmod_utils *
1487 **********************************/
1488 int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
1489 void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
1491 /*******************************
1492 * Module conversion functions *
1493 *******************************/
1494 const char* strextstate(enum module_ext_state s);
1495 const char* strmodulevent(enum module_ev e);
1497 /**************************
1498 * Edns related functions *
1499 **************************/
1500 struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
1501 int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
1502 int no_aggregation, struct module_env* env);
1505 def register_edns_option(env, code, bypass_cache_stage=False,
1506 no_aggregation=False):
1507 """Wrapper function to provide keyword attributes."""
1508 return edns_register_option(code, bypass_cache_stage,
1509 no_aggregation, env)
1512 /******************************
1513 * Callback related functions *
1514 ******************************/
1515 /* typemap to check if argument is callable */
1516 %typemap(in) PyObject *py_cb {
1517 if (!PyCallable_Check($input)) {
1518 SWIG_exception_fail(SWIG_TypeError, "Need a callable object!");
1523 /* typemap to get content/size from a bytearray */
1524 %typemap(in) (size_t len, uint8_t* py_bytearray_data) {
1525 if (!PyByteArray_CheckExact($input)) {
1526 SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!");
1529 $2 = (void*)PyByteArray_AsString($input);
1530 $1 = PyByteArray_Size($input);
1533 int edns_opt_list_remove(struct edns_option** list, uint16_t code);
1534 int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
1535 uint8_t* py_bytearray_data, struct regional* region);
1538 /* This function is called by unbound in order to call the python
1539 * callback function. */
1540 int python_inplace_cb_reply_generic(struct query_info* qinfo,
1541 struct module_qstate* qstate, struct reply_info* rep, int rcode,
1542 struct edns_data* edns, struct edns_option** opt_list_out,
1543 struct comm_reply* repinfo, struct regional* region, int id,
1544 void* python_callback)
1546 PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
1547 PyObject *py_rep, *py_repinfo, *py_region;
1548 PyObject *py_args, *py_kwargs, *result;
1551 PyGILState_STATE gstate = PyGILState_Ensure();
1552 func = (PyObject *) python_callback;
1553 py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
1554 py_qstate = SWIG_NewPointerObj((void*) qstate,
1555 SWIGTYPE_p_module_qstate, 0);
1556 py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out,
1557 SWIGTYPE_p_p_edns_option, 0);
1558 py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1559 py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
1560 py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0);
1561 py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1562 py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
1563 rcode, py_edns, py_opt_list_out, py_region);
1564 py_kwargs = Py_BuildValue("{s:O}", "repinfo", py_repinfo);
1565 result = PyObject_Call(func, py_args, py_kwargs);
1566 Py_XDECREF(py_edns);
1567 Py_XDECREF(py_qstate);
1568 Py_XDECREF(py_opt_list_out);
1569 Py_XDECREF(py_qinfo);
1571 Py_XDECREF(py_repinfo);
1572 Py_XDECREF(py_region);
1573 Py_XDECREF(py_args);
1574 Py_XDECREF(py_kwargs);
1576 res = PyInt_AsLong(result);
1579 PyGILState_Release(gstate);
1583 /* register a callback */
1584 static int python_inplace_cb_register(enum inplace_cb_list_type type,
1585 PyObject* py_cb, struct module_env* env, int id)
1587 int ret = inplace_cb_register(python_inplace_cb_reply_generic,
1588 type, (void*) py_cb, env, id);
1589 if (ret) Py_INCREF(py_cb);
1593 /* Swig implementations for Python */
1594 static int register_inplace_cb_reply(PyObject* py_cb,
1595 struct module_env* env, int id)
1597 return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id);
1599 static int register_inplace_cb_reply_cache(PyObject* py_cb,
1600 struct module_env* env, int id)
1602 return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id);
1604 static int register_inplace_cb_reply_local(PyObject* py_cb,
1605 struct module_env* env, int id)
1607 return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id);
1609 static int register_inplace_cb_reply_servfail(PyObject* py_cb,
1610 struct module_env* env, int id)
1612 return python_inplace_cb_register(inplace_cb_reply_servfail,
1616 int python_inplace_cb_query_generic(
1617 struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
1618 struct sockaddr_storage* addr, socklen_t addrlen,
1619 uint8_t* zone, size_t zonelen, struct regional* region, int id,
1620 void* python_callback)
1623 PyObject *func = python_callback;
1625 PyGILState_STATE gstate = PyGILState_Ensure();
1627 PyObject *py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1628 PyObject *py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1629 PyObject *py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
1630 PyObject *py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
1631 PyObject *py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1633 PyObject *py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
1634 PyObject *py_kwargs = Py_BuildValue("{}");
1635 PyObject *result = PyObject_Call(func, py_args, py_kwargs);
1637 res = PyInt_AsLong(result);
1640 Py_XDECREF(py_qinfo);
1641 Py_XDECREF(py_qstate);
1642 Py_XDECREF(py_addr);
1643 Py_XDECREF(py_zone);
1644 Py_XDECREF(py_region);
1646 Py_XDECREF(py_args);
1647 Py_XDECREF(py_kwargs);
1650 PyGILState_Release(gstate);
1655 static int register_inplace_cb_query(PyObject* py_cb,
1656 struct module_env* env, int id)
1658 int ret = inplace_cb_register(python_inplace_cb_query_generic,
1659 inplace_cb_query, (void*) py_cb, env, id);
1660 if (ret) Py_INCREF(py_cb);
1664 /* C declarations */
1665 int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
1666 struct module_env* env, int id);
1668 /* Swig declarations */
1669 static int register_inplace_cb_reply(PyObject* py_cb,
1670 struct module_env* env, int id);
1671 static int register_inplace_cb_reply_cache(PyObject* py_cb,
1672 struct module_env* env, int id);
1673 static int register_inplace_cb_reply_local(PyObject* py_cb,
1674 struct module_env* env, int id);
1675 static int register_inplace_cb_reply_servfail(PyObject* py_cb,
1676 struct module_env* env, int id);
1677 static int register_inplace_cb_query(PyObject *py_cb,
1678 struct module_env* env, int id);