2 * interface.i: unbound python module
5 /* store state of warning output, restored at later pop */
6 #pragma GCC diagnostic push
7 /* ignore warnings for pragma below, where for older GCC it can produce a
8 warning if the cast-function-type warning is absent. */
9 #pragma GCC diagnostic ignored "-Wpragmas"
10 /* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
11 #pragma GCC diagnostic ignored "-Wcast-function-type"
15 /* restore state of warning output, remove the functioncast ignore */
16 #pragma GCC diagnostic pop
19 * This is the interface between the unbound server and a python module
20 * called to perform operations on queries.
22 #include <sys/types.h>
24 #ifdef HAVE_SYS_SOCKET_H
25 #include <sys/socket.h>
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
42 #include "util/module.h"
43 #include "util/netevent.h"
44 #include "util/regional.h"
45 #include "util/config_file.h"
46 #include "util/data/msgreply.h"
47 #include "util/data/packed_rrset.h"
48 #include "util/data/dname.h"
49 #include "util/storage/lruhash.h"
50 #include "services/cache/dns.h"
51 #include "services/mesh.h"
52 #include "iterator/iter_delegpt.h"
53 #include "iterator/iter_hints.h"
54 #include "iterator/iter_utils.h"
55 #include "sldns/wire2str.h"
56 #include "sldns/str2wire.h"
57 #include "sldns/pkthdr.h"
60 %include "stdint.i" /* uint_16_t can be known type now */
63 /* converts [len][data][len][data][0] string to a List of labels (PyBytes) */
64 PyObject* GetNameAsLabelList(const char* name, int len) {
70 i += ((unsigned int)name[i]) + 1;
74 list = PyList_New(cnt);
77 char buf[LDNS_MAX_LABELLEN+1];
78 if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) &&
79 i+(int)((unsigned int)name[i]) < len) {
80 memmove(buf, name + i + 1, (unsigned int)name[i]);
81 buf[(unsigned int)name[i]] = 0;
82 PyList_SetItem(list, cnt, PyString_FromString(buf));
84 i += ((unsigned int)name[i]) + 1;
90 /* converts an array of strings (char**) to a List of strings */
91 PyObject* CharArrayAsStringList(char** array, int len) {
95 if(!array||len==0) return PyList_New(0);
97 list = PyList_New(len);
98 for (i=0; i < len; i++) {
99 PyList_SET_ITEM(list, i, PyString_FromString(array[i]));
105 /* ************************************************************************************ *
107 * ************************************************************************************ */
109 %ignore query_info::qname;
110 %ignore query_info::qname_len;
154 RR_TYPE_NSAP_PTR = 23,
176 RR_TYPE_IPSECKEY = 45,
182 RR_TYPE_NSEC3PARAMS = 51,
186 RR_TYPE_UNSPEC = 103,
196 PyObject* _get_qname(struct query_info* q) {
197 return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len);
200 PyObject* _get_qname_components(struct query_info* q) {
201 return GetNameAsLabelList((const char*)q->qname, q->qname_len);
206 PyObject* dnameAsStr(PyObject* dname) {
207 char buf[LDNS_MAX_DOMAINLEN+1];
209 dname_str((uint8_t*)PyBytes_AsString(dname), buf);
210 return PyString_FromString(buf);
216 def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
217 qtype_str = property(_get_qtype_str)
219 def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
220 qclass_str = property(_get_qclass_str)
222 qname = property(_unboundmodule._get_qname)
224 qname_list = property(_unboundmodule._get_qname_components)
226 def _get_qname_str(self): return dnameAsStr(self.qname)
227 qname_str = property(_get_qname_str)
231 /* ************************************************************************************ *
232 Structure packed_rrset_key
233 * ************************************************************************************ */
234 %ignore packed_rrset_key::dname;
235 %ignore packed_rrset_key::dname_len;
238 struct packed_rrset_key {
243 uint16_t type; /* rrset type in network format */
244 uint16_t rrset_class; /* rrset class in network format */
249 * This subroutine converts values between the host and network byte order.
250 * Specifically, ntohs() converts 16-bit quantities from network byte order to
253 uint16_t ntohs(uint16_t netshort);
256 PyObject* _get_dname(struct packed_rrset_key* k) {
257 return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len);
259 PyObject* _get_dname_components(struct packed_rrset_key* k) {
260 return GetNameAsLabelList((char*)k->dname, k->dname_len);
264 %extend packed_rrset_key {
266 def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
267 type_str = property(_get_type_str)
269 def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
270 rrset_class_str = property(_get_class_str)
272 dname = property(_unboundmodule._get_dname)
274 dname_list = property(_unboundmodule._get_dname_components)
276 def _get_dname_str(self): return dnameAsStr(self.dname)
277 dname_str = property(_get_dname_str)
281 #if defined(SWIGWORDSIZE64)
282 typedef long int rrset_id_type;
284 typedef long long int rrset_id_type;
287 struct ub_packed_rrset_key {
288 struct lruhash_entry entry;
290 struct packed_rrset_key rk;
293 struct lruhash_entry {
295 struct lruhash_entry* overflow_next;
296 struct lruhash_entry* lru_next;
297 struct lruhash_entry* lru_prev;
300 struct packed_rrset_data* data;
303 %ignore packed_rrset_data::rr_len;
304 %ignore packed_rrset_data::rr_ttl;
305 %ignore packed_rrset_data::rr_data;
307 struct packed_rrset_data {
308 /* TTL (in seconds like time()) */
313 /* number of rrsigs */
316 enum rrset_trust trust;
317 enum sec_status security;
319 /* length of every rr's rdata */
321 /* ttl of every rr */
323 /* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in
324 * uncompressed wireformat. */
329 class RRSetData_RRLen:
330 def __init__(self, obj): self.obj = obj
331 def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index)
332 def __len__(self): return self.obj.count + self.obj.rrsig_count
333 class RRSetData_RRTTL:
334 def __init__(self, obj): self.obj = obj
335 def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index)
336 def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value)
337 def __len__(self): return self.obj.count + self.obj.rrsig_count
338 class RRSetData_RRData:
339 def __init__(self, obj): self.obj = obj
340 def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index)
341 def __len__(self): return self.obj.count + self.obj.rrsig_count
345 PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
346 if ((d != NULL) && (idx >= 0) &&
347 ((size_t)idx < (d->count+d->rrsig_count)))
348 return PyInt_FromLong(d->rr_len[idx]);
351 void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
353 if ((d != NULL) && (idx >= 0) &&
354 ((size_t)idx < (d->count+d->rrsig_count)))
355 d->rr_ttl[idx] = ttl;
357 PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
358 if ((d != NULL) && (idx >= 0) &&
359 ((size_t)idx < (d->count+d->rrsig_count)))
360 return PyInt_FromLong(d->rr_ttl[idx]);
363 PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
364 if ((d != NULL) && (idx >= 0) &&
365 ((size_t)idx < (d->count+d->rrsig_count)))
366 return PyBytes_FromStringAndSize((char*)d->rr_data[idx],
372 %extend packed_rrset_data {
374 def _get_data_rr_len(self): return RRSetData_RRLen(self)
375 rr_len = property(_get_data_rr_len)
376 def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
377 rr_ttl = property(_get_data_rr_ttl)
378 def _get_data_rr_data(self): return RRSetData_RRData(self)
379 rr_data = property(_get_data_rr_data)
383 /* ************************************************************************************ *
385 * ************************************************************************************ */
387 %ignore reply_info::rrsets;
388 %ignore reply_info::ref;
394 uint32_t prefetch_ttl;
396 uint16_t authoritative;
397 enum sec_status security;
402 size_t rrset_count; /* an_numrrsets + ns_numrrsets + ar_numrrsets */
404 struct ub_packed_rrset_key** rrsets;
405 struct rrset_ref ref[1]; /* ? */
409 struct ub_packed_rrset_key* key;
414 struct query_info qinfo;
415 struct reply_info *rep;
419 class ReplyInfo_RRSet:
420 def __init__(self, obj): self.obj = obj
421 def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index)
422 def __len__(self): return self.obj.rrset_count
425 def __init__(self, obj): self.obj = obj
426 def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index)
427 def __len__(self): return self.obj.rrset_count
431 struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) {
432 if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count))
433 return r->rrsets[idx];
437 struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
438 if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) {
439 /* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */
440 return &(r->ref[idx]);
441 /* return &(r->ref[idx]); */
443 /* printf("_rrset_ref_get: NULL\n"); */
450 def _rrset_ref_get(self): return ReplyInfo_Ref(self)
451 ref = property(_rrset_ref_get)
453 def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
454 rrsets = property(_rrset_rrsets_get)
458 /* ************************************************************************************ *
459 Structure sockaddr_storage
460 * ************************************************************************************ */
462 struct sockaddr_storage {};
465 static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) {
470 switch (ss->ss_family) {
471 case AF_INET: return sizeof(struct sockaddr_in);
472 case AF_INET6: return sizeof(struct sockaddr_in6);
474 case AF_UNIX: return sizeof(struct sockaddr_un);
481 PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) {
486 switch (ss->ss_family) {
487 case AF_INET: return PyUnicode_FromString("ip4");
488 case AF_INET6: return PyUnicode_FromString("ip6");
489 case AF_UNIX: return PyUnicode_FromString("unix");
495 PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) {
496 const struct sockaddr *sa;
498 char name[NI_MAXHOST] = {0};
504 sa = (struct sockaddr *)ss;
505 sa_len = _sockaddr_storage_len(ss);
510 if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) {
514 return PyUnicode_FromString(name);
517 PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) {
524 sa_len = _sockaddr_storage_len(ss);
529 if (ss->ss_family == AF_INET) {
530 const struct sockaddr_in *sa = (struct sockaddr_in *)ss;
531 const struct in_addr *raw = (struct in_addr *)&sa->sin_addr;
532 return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
535 if (ss->ss_family == AF_INET6) {
536 const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
537 const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr;
538 return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
542 if (ss->ss_family == AF_UNIX) {
543 const struct sockaddr_un *sa = (struct sockaddr_un *)ss;
544 return PyBytes_FromString(sa->sun_path);
551 PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
556 if (ss->ss_family == AF_INET) {
557 const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
558 return PyInt_FromLong(ntohs(sa4->sin_port));
561 if (ss->ss_family == AF_INET6) {
562 const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
563 return PyInt_FromLong(ntohs(sa6->sin6_port));
569 PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
570 const struct sockaddr_in6 *sa6;
572 if (ss == NULL || ss->ss_family != AF_INET6) {
576 sa6 = (struct sockaddr_in6 *)ss;
577 return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
580 PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
581 const struct sockaddr_in6 *sa6;
583 if (ss == NULL || ss->ss_family != AF_INET6) {
587 sa6 = (struct sockaddr_in6 *)ss;
588 return PyInt_FromLong(ntohl(sa6->sin6_scope_id));
592 %extend sockaddr_storage {
594 def _family_get(self): return _sockaddr_storage_family(self)
595 family = property(_family_get)
597 def _addr_get(self): return _sockaddr_storage_addr(self)
598 addr = property(_addr_get)
600 def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self)
601 raw_addr = property(_raw_addr_get)
603 def _port_get(self): return _sockaddr_storage_port(self)
604 port = property(_port_get)
606 def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self)
607 flowinfo = property(_flowinfo_get)
609 def _scope_id_get(self): return _sockaddr_storage_scope_id(self)
610 scope_id = property(_scope_id_get)
614 /* ************************************************************************************ *
616 * ************************************************************************************ */
618 struct mesh_reply* reply_list;
622 struct mesh_reply* next;
623 struct comm_reply query_reply;
626 %rename(_addr) comm_reply::client_addr;
628 struct sockaddr_storage client_addr;
633 def _addr_get(self): return _sockaddr_storage_addr(self._addr)
634 addr = property(_addr_get)
636 def _port_get(self): return _sockaddr_storage_port(self._addr)
637 port = property(_port_get)
639 def _family_get(self): return _sockaddr_storage_family(self._addr)
640 family = property(_family_get)
644 /* ************************************************************************************ *
645 Structure edns_option
646 * ************************************************************************************ */
647 /* Rename the members to follow the python convention of marking them as
648 * private. Access to the opt_code and opt_data members is given by the later
649 * python defined code and data members respectively. */
650 %rename(_next) edns_option::next;
651 %rename(_opt_code) edns_option::opt_code;
652 %rename(_opt_len) edns_option::opt_len;
653 %rename(_opt_data) edns_option::opt_data;
655 struct edns_option* next;
662 PyObject* _edns_option_opt_code_get(struct edns_option* option) {
663 uint16_t opt_code = option->opt_code;
664 return PyInt_FromLong(opt_code);
667 PyObject* _edns_option_opt_data_get(struct edns_option* option) {
668 return PyByteArray_FromStringAndSize((void*)option->opt_data,
672 %extend edns_option {
674 def _opt_code_get(self): return _edns_option_opt_code_get(self)
675 code = property(_opt_code_get)
677 def _opt_data_get(self): return _edns_option_opt_data_get(self)
678 data = property(_opt_data_get)
682 /* ************************************************************************************ *
684 * ************************************************************************************ */
685 /* This is ignored because we will pass a double pointer of this to Python
686 * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
687 * pointers as None. */
688 %ignore edns_data::opt_list;
692 uint8_t edns_version;
695 struct edns_option* opt_list_in;
696 struct edns_option* opt_list_out;
697 struct edns_option* opt_list_inplace_cb_out;
698 uint16_t padding_block_size;
701 struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) {
702 return &edns->opt_list_in;
707 def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
708 opt_list_iter = property(_opt_list_iter)
709 def _opt_list(self): return _edns_data_opt_list_get(self)
710 opt_list = property(_opt_list)
714 /* ************************************************************************************ *
716 * ************************************************************************************ */
717 %rename(_now) module_env::now;
718 %rename(_now_tv) module_env::now_tv;
720 struct config_file* cfg;
721 struct slabhash* msg_cache;
722 struct rrset_cache* rrset_cache;
723 struct infra_cache* infra_cache;
724 struct key_cache* key_cache;
726 /* --- services --- */
727 struct outbound_entry* (*send_query)(struct query_info* qinfo,
728 uint16_t flags, int dnssec, int want_dnssec, int nocaps,
730 struct sockaddr_storage* addr, socklen_t addrlen,
731 uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream,
732 char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
733 void (*detach_subs)(struct module_qstate* qstate);
734 int (*attach_sub)(struct module_qstate* qstate,
735 struct query_info* qinfo, uint16_t qflags, int prime,
736 int valrec, struct module_qstate** newq);
737 void (*kill_sub)(struct module_qstate* newq);
738 int (*detect_cycle)(struct module_qstate* qstate,
739 struct query_info* qinfo, uint16_t flags, int prime,
742 struct regional* scratch;
743 struct sldns_buffer* scratch_buffer;
744 struct worker* worker;
745 struct mesh_area* mesh;
746 struct alloc_cache* alloc;
747 struct ub_randstate* rnd;
749 struct timeval* now_tv;
750 int need_to_validate;
751 struct val_anchors* anchors;
752 struct val_neg_cache* neg_cache;
753 struct comm_timer* probe_timer;
754 struct iter_forwards* fwds;
755 struct iter_hints* hints;
756 void* modinfo[MAX_MODULE];
758 void* inplace_cb_lists[inplace_cb_types_total];
759 struct edns_known_option* edns_known_options;
760 size_t edns_known_options_num;
764 PyObject* _module_env_now_get(struct module_env* env) {
765 double ts = env->now_tv->tv_sec + env->now_tv->tv_usec / 1e6;
766 return PyFloat_FromDouble(ts);
771 def _now_get(self): return _module_env_now_get(self)
772 now = property(_now_get)
776 /* ************************************************************************************ *
777 Structure module_qstate
778 * ************************************************************************************ */
779 %ignore module_qstate::ext_state;
780 %ignore module_qstate::minfo;
782 /* These are ignored because we will pass a double pointer of them to Python
783 * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
784 * pointers as None. */
785 %ignore module_qstate::edns_opts_front_in;
786 %ignore module_qstate::edns_opts_back_out;
787 %ignore module_qstate::edns_opts_back_in;
788 %ignore module_qstate::edns_opts_front_out;
791 struct module_qstate {
792 struct query_info qinfo;
793 uint16_t query_flags; /* See QF_BIT_xx constants */
797 struct comm_reply* reply;
798 struct dns_msg* return_msg;
800 struct regional* region; /* unwrapped */
804 enum module_ext_state ext_state[MAX_MODULE];
805 void* minfo[MAX_MODULE];
806 time_t prefetch_leeway;
808 struct module_env* env; /* unwrapped */
809 struct mesh_state* mesh_info;
811 struct edns_option* edns_opts_front_in;
812 struct edns_option* edns_opts_back_out;
813 struct edns_option* edns_opts_back_in;
814 struct edns_option* edns_opts_front_out;
819 %constant int MODULE_COUNT = MAX_MODULE;
821 %constant int QF_BIT_CD = 0x0010;
822 %constant int QF_BIT_AD = 0x0020;
823 %constant int QF_BIT_Z = 0x0040;
824 %constant int QF_BIT_RA = 0x0080;
825 %constant int QF_BIT_RD = 0x0100;
826 %constant int QF_BIT_TC = 0x0200;
827 %constant int QF_BIT_AA = 0x0400;
828 %constant int QF_BIT_QR = 0x8000;
831 enum enum_return_rcode {
848 def __init__(self, obj): self.obj = obj
850 return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)])
851 def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index)
852 def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value)
853 def __len__(self): return _unboundmodule.MODULE_COUNT
855 class EdnsOptsListIter:
856 def __init__(self, obj):
859 def __iter__(self): return self
861 """Python 3 compatibility"""
862 return self._get_next()
864 """Python 2 compatibility"""
865 return self._get_next()
867 if not edns_opt_list_is_empty(self._current):
868 self._temp = self._current
869 self._current = _p_p_edns_option_get_next(self._current)
870 return _dereference_edns_option(self._temp)
876 enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
877 if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
878 return q->ext_state[idx];
883 void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
884 if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
885 q->ext_state[idx] = state;
889 int edns_opt_list_is_empty(struct edns_option** opt) {
890 if (!opt || !(*opt)) return 1;
894 struct edns_option* _dereference_edns_option(struct edns_option** opt) {
895 if (!opt) return NULL;
899 struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) {
900 return &(*opt)->next;
903 struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) {
904 return &q->edns_opts_front_in;
907 struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) {
908 return &q->edns_opts_back_out;
911 struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) {
912 return &q->edns_opts_back_in;
915 struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) {
916 return &q->edns_opts_front_out;
920 %extend module_qstate {
922 def set_ext_state(self, id, state):
923 """Sets the ext state"""
924 _unboundmodule._ext_state_set(self, id, state)
926 def __ext_state_get(self): return ExtState(self)
927 ext_state = property(__ext_state_get) #, __ext_state_set
929 def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
930 edns_opts_front_in_iter = property(_edns_opts_front_in_iter)
931 def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
932 edns_opts_back_out_iter = property(_edns_opts_back_out_iter)
933 def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
934 edns_opts_back_in_iter = property(_edns_opts_back_in_iter)
935 def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
936 edns_opts_front_out_iter = property(_edns_opts_front_out_iter)
938 def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
939 edns_opts_front_in = property(_edns_opts_front_in)
940 def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
941 edns_opts_back_out = property(_edns_opts_back_out)
942 def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
943 edns_opts_back_in = property(_edns_opts_back_in)
944 def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
945 edns_opts_front_out = property(_edns_opts_front_out)
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 * ************************************************************************************ */
969 %ignore config_file::ifs;
970 %ignore config_file::out_ifs;
971 %ignore config_file::python_script;
983 int outgoing_num_ports;
984 size_t outgoing_num_tcp;
985 size_t incoming_num_tcp;
986 int* outgoing_avail_ports;
987 size_t msg_buffer_size;
988 size_t msg_cache_size;
989 size_t msg_cache_slabs;
990 size_t num_queries_per_thread;
992 size_t rrset_cache_size;
993 size_t rrset_cache_slabs;
995 size_t infra_cache_slabs;
996 size_t infra_cache_numhosts;
997 char* target_fetch_policy;
1003 struct config_strlist* root_hints;
1004 struct config_stub* stubs;
1005 struct config_stub* forwards;
1006 struct config_strlist* donotqueryaddrs;
1007 struct config_str2list* acls;
1008 int donotquery_localhost;
1009 int harden_short_bufsize;
1010 int harden_large_queries;
1012 int harden_dnssec_stripped;
1013 int harden_referral_path;
1014 int use_caps_bits_for_id;
1015 struct config_strlist* private_address;
1016 struct config_strlist* private_domain;
1017 size_t unwanted_threshold;
1029 struct config_strlist* trust_anchor_file_list;
1030 struct config_strlist* trust_anchor_list;
1031 struct config_strlist* trusted_keys_file_list;
1033 int32_t val_date_override;
1035 int val_clean_additional;
1036 int val_permissive_mode;
1037 char* val_nsec3_key_iterations;
1038 size_t key_cache_size;
1039 size_t key_cache_slabs;
1040 size_t neg_cache_size;
1041 struct config_str2list* local_zones;
1042 struct config_strlist* local_zones_nodefault;
1043 struct config_strlist* local_data;
1044 int remote_control_enable;
1045 struct config_strlist_head control_ifs;
1047 char* server_key_file;
1048 char* server_cert_file;
1049 char* control_key_file;
1050 char* control_cert_file;
1052 struct config_strlist* python_script;
1056 PyObject* _get_ifs_tuple(struct config_file* cfg) {
1057 return CharArrayAsStringList(cfg->ifs, cfg->num_ifs);
1059 PyObject* _get_ifs_out_tuple(struct config_file* cfg) {
1060 return CharArrayAsStringList(cfg->out_ifs, cfg->num_out_ifs);
1064 %extend config_file {
1066 ifs = property(_unboundmodule._get_ifs_tuple)
1067 out_ifs = property(_unboundmodule._get_ifs_out_tuple)
1069 def _deprecated_python_script(self): return "cfg.python_script is deprecated, you can use `mod_env['script']` instead."
1070 python_script = property(_deprecated_python_script)
1074 /* ************************************************************************************ *
1075 ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation
1076 * ************************************************************************************ */
1078 struct delegpt_ns* next;
1083 uint8_t done_pside4;
1084 uint8_t done_pside6;
1087 struct delegpt_addr {
1088 struct delegpt_addr* next_result;
1089 struct delegpt_addr* next_usable;
1090 struct delegpt_addr* next_target;
1099 struct delegpt_ns* nslist;
1100 struct delegpt_addr* target_list;
1101 struct delegpt_addr* usable_list;
1102 struct delegpt_addr* result_list;
1104 uint8_t has_parent_side_NS;
1105 uint8_t dp_type_mlc;
1110 PyObject* _get_dp_dname(struct delegpt* dp) {
1111 return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen);
1113 PyObject* _get_dp_dname_components(struct delegpt* dp) {
1114 return GetNameAsLabelList((char*)dp->name, dp->namelen);
1116 PyObject* _get_dpns_dname(struct delegpt_ns* dpns) {
1117 return PyBytes_FromStringAndSize((char*)dpns->name, dpns->namelen);
1119 PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) {
1120 return GetNameAsLabelList((char*)dpns->name, dpns->namelen);
1123 PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) {
1125 delegpt_addr_addr2str(target, dest, 64);
1128 return PyBytes_FromString(dest);
1135 dname = property(_unboundmodule._get_dp_dname)
1137 dname_list = property(_unboundmodule._get_dp_dname_components)
1139 def _get_dname_str(self): return dnameAsStr(self.dname)
1140 dname_str = property(_get_dname_str)
1143 %extend delegpt_ns {
1145 dname = property(_unboundmodule._get_dpns_dname)
1147 dname_list = property(_unboundmodule._get_dpns_dname_components)
1149 def _get_dname_str(self): return dnameAsStr(self.dname)
1150 dname_str = property(_get_dname_str)
1153 %extend delegpt_addr {
1155 def _addr_get(self): return _delegpt_addr_addr_get(self)
1156 addr = property(_addr_get)
1160 /* ************************************************************************************ *
1162 * ************************************************************************************ */
1163 %rename ("MODULE_STATE_INITIAL") "module_state_initial";
1164 %rename ("MODULE_WAIT_REPLY") "module_wait_reply";
1165 %rename ("MODULE_WAIT_MODULE") "module_wait_module";
1166 %rename ("MODULE_RESTART_NEXT") "module_restart_next";
1167 %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
1168 %rename ("MODULE_ERROR") "module_error";
1169 %rename ("MODULE_FINISHED") "module_finished";
1171 enum module_ext_state {
1172 module_state_initial = 0,
1175 module_restart_next,
1176 module_wait_subquery,
1181 %rename ("MODULE_EVENT_NEW") "module_event_new";
1182 %rename ("MODULE_EVENT_PASS") "module_event_pass";
1183 %rename ("MODULE_EVENT_REPLY") "module_event_reply";
1184 %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply";
1185 %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail";
1186 %rename ("MODULE_EVENT_MODDONE") "module_event_moddone";
1187 %rename ("MODULE_EVENT_ERROR") "module_event_error";
1190 module_event_new = 0,
1193 module_event_noreply,
1194 module_event_capsfail,
1195 module_event_moddone,
1200 sec_status_unchecked = 0,
1202 sec_status_indeterminate,
1203 sec_status_insecure,
1207 enum verbosity_value {
1215 enum inplace_cb_list_type {
1216 /* Inplace callbacks for when a resolved reply is ready to be sent to the
1218 inplace_cb_reply = 0,
1219 /* Inplace callbacks for when a reply is given from the cache. */
1220 inplace_cb_reply_cache,
1221 /* Inplace callbacks for when a reply is given with local data
1222 * (or Chaos reply). */
1223 inplace_cb_reply_local,
1224 /* Inplace callbacks for when the reply is servfail. */
1225 inplace_cb_reply_servfail,
1226 /* Inplace callbacks for when a query is ready to be sent to the back.*/
1228 /* Inplace callback for when a reply is received from the back. */
1229 inplace_cb_edns_back_parsed,
1230 /* Total number of types. Used for array initialization.
1231 * Should always be last. */
1232 inplace_cb_types_total
1235 %constant uint16_t PKT_QR = 1; /* QueRy - query flag */
1236 %constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */
1237 %constant uint16_t PKT_TC = 4; /* TrunCated - server flag */
1238 %constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */
1239 %constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */
1240 %constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */
1241 %constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */
1244 int checkList(PyObject *l)
1252 if (PyList_Check(l))
1254 for (i=0; i < PyList_Size(l); i++)
1256 item = PyList_GetItem(l, i);
1257 if (!PyBytes_Check(item) && !PyUnicode_Check(item))
1266 int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
1267 size_t count_offset)
1275 for (i=0; i < PyList_Size(l); i++)
1278 item = PyList_GetItem(l, i);
1279 if(PyObject_TypeCheck(item, &PyBytes_Type)) {
1280 s = PyBytes_AsString(item);
1282 ascstr = PyUnicode_AsASCIIString(item);
1283 s = PyBytes_AsString(ascstr);
1286 len = sldns_buffer_remaining(qb);
1288 if(sldns_str2wire_rr_question_buf(s,
1289 sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
1296 if(sldns_str2wire_rr_buf(s,
1297 sldns_buffer_current(qb), &len, NULL, default_ttl,
1298 NULL, 0, NULL, 0) != 0) {
1306 sldns_buffer_skip(qb, len);
1308 sldns_buffer_write_u16_at(qb, count_offset,
1309 sldns_buffer_read_u16_at(qb, count_offset)+1);
1314 int set_return_msg(struct module_qstate* qstate,
1315 const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
1316 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
1318 sldns_buffer *qb = 0;
1321 uint16_t PKT_QR = 1;
1322 uint16_t PKT_AA = 2;
1323 uint16_t PKT_TC = 4;
1324 uint16_t PKT_RD = 8;
1325 uint16_t PKT_CD = 16;
1326 uint16_t PKT_RA = 32;
1327 uint16_t PKT_AD = 64;
1329 if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
1331 if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0;
1334 sldns_buffer_write_u16(qb, 0); /* ID */
1335 sldns_buffer_write_u16(qb, 0); /* flags */
1336 sldns_buffer_write_u16(qb, 1); /* qdcount */
1337 sldns_buffer_write_u16(qb, 0); /* ancount */
1338 sldns_buffer_write_u16(qb, 0); /* nscount */
1339 sldns_buffer_write_u16(qb, 0); /* arcount */
1340 if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb));
1341 if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb));
1342 if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb));
1343 if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb));
1344 if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb));
1345 if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb));
1346 if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb));
1348 /* write the query */
1349 l = sldns_buffer_remaining(qb);
1350 if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) {
1351 sldns_buffer_free(qb);
1354 sldns_buffer_skip(qb, l);
1355 if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; }
1356 if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; }
1357 sldns_buffer_write_u16(qb, rr_type);
1358 sldns_buffer_write_u16(qb, rr_class);
1360 /* write RR sections */
1361 if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF))
1363 if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF))
1365 if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF))
1367 if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF))
1370 if (res) res = createResponse(qstate, qb);
1372 if (qb) sldns_buffer_free(qb);
1377 int set_return_msg(struct module_qstate* qstate,
1378 const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
1379 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
1383 def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0):
1384 """Query flags is a combination of PKT_xx constants"""
1385 self.rr_name = rr_name
1386 self.rr_type = rr_type
1387 self.rr_class = rr_class
1388 self.default_ttl = default_ttl
1389 self.query_flags = query_flags
1393 self.additional = []
1395 def set_return_msg(self, qstate):
1396 """Returns 1 if OK"""
1397 status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
1398 self.query_flags, self.default_ttl,
1399 self.question, self.answer, self.authority, self.additional)
1401 if (status) and (PKT_AA & self.query_flags):
1402 qstate.return_msg.rep.authoritative = 1
1407 /* ************************************************************************************ *
1408 ASN: Delegation pointer related functions
1409 * ************************************************************************************ */
1411 /* Functions which we will need to lookup delegations */
1412 struct delegpt* dns_cache_find_delegation(struct module_env* env,
1413 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
1414 struct regional* region, struct dns_msg** msg, uint32_t timenow,
1415 int noexpiredabove, uint8_t* expiretop, size_t expiretoplen);
1416 int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
1417 struct delegpt* dp, int supports_ipv4, int supports_ipv6, int use_nat64);
1418 struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
1419 uint8_t* qname, uint16_t qclass, struct delegpt* dp);
1421 /* Custom function to perform logic similar to the one in daemon/cachedump.c */
1422 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen);
1425 #define BIT_RD 0x100
1427 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen)
1430 struct dns_msg *msg = NULL;
1431 struct regional* region = qstate->env->scratch;
1433 struct query_info qinfo;
1434 struct iter_hints_stub* stub;
1435 uint32_t timenow = *qstate->env->now;
1437 regional_free_all(region);
1438 qinfo.qname = (uint8_t*)nm;
1439 qinfo.qname_len = nmlen;
1440 qinfo.qtype = LDNS_RR_TYPE_A;
1441 qinfo.qclass = LDNS_RR_CLASS_IN;
1444 dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow, 0, NULL, 0);
1447 if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
1448 qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6,
1449 qstate->env->cfg->do_nat64)) {
1450 if (dname_is_root((uint8_t*)nm))
1452 nm = (char*)dp->name;
1453 nmlen = dp->namelen;
1454 dname_remove_label((uint8_t**)&nm, &nmlen);
1455 dname_str((uint8_t*)nm, b);
1458 stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, qinfo.qclass, dp);
1469 /* ************************************************************************************ *
1471 * ************************************************************************************ */
1472 /******************************
1473 * Various debugging functions *
1474 ******************************/
1476 /* rename the variadic functions because python does the formatting already*/
1477 %rename (unbound_log_info) log_info;
1478 %rename (unbound_log_err) log_err;
1479 %rename (unbound_log_warn) log_warn;
1480 %rename (unbound_verbose) verbose;
1481 /* provide functions that take one string as argument, so python can cook
1483 %rename (log_info) pymod_log_info;
1484 %rename (log_warn) pymod_log_warn;
1485 %rename (log_err) pymod_log_err;
1486 %rename (verbose) pymod_verbose;
1488 void verbose(enum verbosity_value level, const char* format, ...);
1489 void log_info(const char* format, ...);
1490 void log_err(const char* format, ...);
1491 void log_warn(const char* format, ...);
1492 void log_hex(const char* msg, void* data, size_t length);
1493 void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep);
1494 void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
1495 void regional_log_stats(struct regional *r);
1497 /* the one argument string log functions */
1498 void pymod_log_info(const char* str);
1499 void pymod_log_err(const char* str);
1500 void pymod_log_warn(const char* str);
1501 void pymod_verbose(enum verbosity_value level, const char* str);
1503 void pymod_log_info(const char* str) { log_info("%s", str); }
1504 void pymod_log_err(const char* str) { log_err("%s", str); }
1505 void pymod_log_warn(const char* str) { log_warn("%s", str); }
1506 void pymod_verbose(enum verbosity_value level, const char* str) {
1507 verbose(level, "%s", str); }
1510 /***************************************************************************
1511 * Free allocated memory from marked sources returning corresponding types *
1512 ***************************************************************************/
1513 %typemap(newfree, noblock = 1) char * {
1517 /***************************************************
1518 * Mark as source returning newly allocated memory *
1519 ***************************************************/
1520 %newobject sldns_wire2str_type;
1521 %newobject sldns_wire2str_class;
1526 char *sldns_wire2str_type(const uint16_t atype);
1527 char *sldns_wire2str_class(const uint16_t aclass);
1529 /**********************************
1530 * Functions from pythonmod_utils *
1531 **********************************/
1532 int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
1533 void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
1535 /*******************************
1536 * Module conversion functions *
1537 *******************************/
1538 const char* strextstate(enum module_ext_state s);
1539 const char* strmodulevent(enum module_ev e);
1541 /**************************
1542 * Edns related functions *
1543 **************************/
1544 struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
1545 int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
1546 int no_aggregation, struct module_env* env);
1549 def register_edns_option(env, code, bypass_cache_stage=False,
1550 no_aggregation=False):
1551 """Wrapper function to provide keyword attributes."""
1552 return edns_register_option(code, bypass_cache_stage,
1553 no_aggregation, env)
1556 /******************************
1557 * Callback related functions *
1558 ******************************/
1559 /* typemap to check if argument is callable */
1560 %typemap(in) PyObject *py_cb {
1561 if (!PyCallable_Check($input)) {
1562 SWIG_exception_fail(SWIG_TypeError, "Need a callable object!");
1567 /* typemap to get content/size from a bytearray */
1568 %typemap(in) (size_t len, uint8_t* py_bytearray_data) {
1569 if (!PyByteArray_CheckExact($input)) {
1570 SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!");
1573 $2 = (void*)PyByteArray_AsString($input);
1574 $1 = PyByteArray_Size($input);
1577 int edns_opt_list_remove(struct edns_option** list, uint16_t code);
1578 int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
1579 uint8_t* py_bytearray_data, struct regional* region);
1582 /* This function is called by unbound in order to call the python
1583 * callback function. */
1584 int python_inplace_cb_reply_generic(struct query_info* qinfo,
1585 struct module_qstate* qstate, struct reply_info* rep, int rcode,
1586 struct edns_data* edns, struct edns_option** opt_list_out,
1587 struct comm_reply* repinfo, struct regional* region,
1588 struct timeval* start_time, int id, void* python_callback)
1590 PyObject *func = NULL, *py_edns = NULL, *py_qstate = NULL;
1591 PyObject *py_opt_list_out = NULL, *py_qinfo = NULL;
1592 PyObject *py_rep = NULL, *py_repinfo = NULL, *py_region = NULL;
1593 PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL;
1595 double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6;
1597 PyGILState_STATE gstate = PyGILState_Ensure();
1599 func = (PyObject *) python_callback;
1600 py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
1601 py_qstate = SWIG_NewPointerObj((void*) qstate,
1602 SWIGTYPE_p_module_qstate, 0);
1603 py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out,
1604 SWIGTYPE_p_p_edns_option, 0);
1605 py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1606 py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
1607 py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0);
1608 py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1609 if(!(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out
1610 && py_region && py_repinfo)) {
1611 log_err("pythonmod: swig pointer failure in python_inplace_cb_reply_generic");
1614 py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
1615 rcode, py_edns, py_opt_list_out, py_region);
1616 py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time",
1618 if(!(py_args && py_kwargs)) {
1619 log_err("pythonmod: BuildValue failure in python_inplace_cb_reply_generic");
1622 result = PyObject_Call(func, py_args, py_kwargs);
1624 res = PyInt_AsLong(result);
1627 Py_XDECREF(py_edns);
1628 Py_XDECREF(py_qstate);
1629 Py_XDECREF(py_opt_list_out);
1630 Py_XDECREF(py_qinfo);
1632 Py_XDECREF(py_repinfo);
1633 Py_XDECREF(py_region);
1634 Py_XDECREF(py_args);
1635 Py_XDECREF(py_kwargs);
1637 PyGILState_Release(gstate);
1641 /* register a callback */
1642 static int python_inplace_cb_register(enum inplace_cb_list_type type,
1643 PyObject* py_cb, struct module_env* env, int id)
1645 int ret = inplace_cb_register(python_inplace_cb_reply_generic,
1646 type, (void*) py_cb, env, id);
1647 if (ret) Py_INCREF(py_cb);
1651 /* Swig implementations for Python */
1652 static int register_inplace_cb_reply(PyObject* py_cb,
1653 struct module_env* env, int id)
1655 return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id);
1657 static int register_inplace_cb_reply_cache(PyObject* py_cb,
1658 struct module_env* env, int id)
1660 return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id);
1662 static int register_inplace_cb_reply_local(PyObject* py_cb,
1663 struct module_env* env, int id)
1665 return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id);
1667 static int register_inplace_cb_reply_servfail(PyObject* py_cb,
1668 struct module_env* env, int id)
1670 return python_inplace_cb_register(inplace_cb_reply_servfail,
1674 int python_inplace_cb_query_generic(
1675 struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
1676 struct sockaddr_storage* addr, socklen_t addrlen,
1677 uint8_t* zone, size_t zonelen, struct regional* region, int id,
1678 void* python_callback)
1681 PyObject *func = python_callback;
1682 PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL;
1683 PyObject *py_qinfo = NULL;
1684 PyObject *py_qstate = NULL;
1685 PyObject *py_addr = NULL;
1686 PyObject *py_zone = NULL;
1687 PyObject *py_region = NULL;
1689 PyGILState_STATE gstate = PyGILState_Ensure();
1691 py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1692 py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1693 py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
1694 py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
1695 py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1696 if(!(py_qinfo && py_qstate && py_addr && py_zone && py_region)) {
1697 log_err("pythonmod: swig pointer failure in python_inplace_cb_query_generic");
1700 py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
1701 py_kwargs = Py_BuildValue("{}");
1702 if(!(py_args && py_kwargs)) {
1703 log_err("pythonmod: BuildValue failure in python_inplace_cb_query_generic");
1706 result = PyObject_Call(func, py_args, py_kwargs);
1708 res = PyInt_AsLong(result);
1711 Py_XDECREF(py_qinfo);
1712 Py_XDECREF(py_qstate);
1713 Py_XDECREF(py_addr);
1714 Py_XDECREF(py_zone);
1715 Py_XDECREF(py_region);
1717 Py_XDECREF(py_args);
1718 Py_XDECREF(py_kwargs);
1721 PyGILState_Release(gstate);
1726 static int register_inplace_cb_query(PyObject* py_cb,
1727 struct module_env* env, int id)
1729 int ret = inplace_cb_register(python_inplace_cb_query_generic,
1730 inplace_cb_query, (void*) py_cb, env, id);
1731 if (ret) Py_INCREF(py_cb);
1735 int python_inplace_cb_query_response(struct module_qstate* qstate,
1736 struct dns_msg* response, int id, void* python_callback)
1739 PyObject *func = python_callback;
1740 PyObject *py_qstate = NULL;
1741 PyObject *py_response = NULL;
1742 PyObject *py_args = NULL;
1743 PyObject *py_kwargs = NULL;
1744 PyObject *result = NULL;
1746 PyGILState_STATE gstate = PyGILState_Ensure();
1748 py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1749 py_response = SWIG_NewPointerObj((void*) response, SWIGTYPE_p_dns_msg, 0);
1750 if(!(py_qstate && py_response)) {
1751 log_err("pythonmod: swig pointer failure in python_inplace_cb_query_response");
1754 py_args = Py_BuildValue("(OO)", py_qstate, py_response);
1755 py_kwargs = Py_BuildValue("{}");
1756 if(!(py_args && py_kwargs)) {
1757 log_err("pythonmod: BuildValue failure in python_inplace_cb_query_response");
1760 result = PyObject_Call(func, py_args, py_kwargs);
1762 res = PyInt_AsLong(result);
1765 Py_XDECREF(py_qstate);
1766 Py_XDECREF(py_response);
1768 Py_XDECREF(py_args);
1769 Py_XDECREF(py_kwargs);
1772 PyGILState_Release(gstate);
1777 static int register_inplace_cb_query_response(PyObject* py_cb,
1778 struct module_env* env, int id)
1780 int ret = inplace_cb_register(python_inplace_cb_query_response,
1781 inplace_cb_query_response, (void*) py_cb, env, id);
1782 if (ret) Py_INCREF(py_cb);
1786 int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate,
1787 int id, void* python_callback)
1790 PyObject *func = python_callback;
1791 PyObject *py_qstate = NULL;
1792 PyObject *py_args = NULL;
1793 PyObject *py_kwargs = NULL;
1794 PyObject *result = NULL;
1796 PyGILState_STATE gstate = PyGILState_Ensure();
1798 py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
1800 log_err("pythonmod: swig pointer failure in python_inplace_cb_edns_back_parsed_call");
1803 py_args = Py_BuildValue("(O)", py_qstate);
1804 py_kwargs = Py_BuildValue("{}");
1805 if(!(py_args && py_kwargs)) {
1806 log_err("pythonmod: BuildValue failure in python_inplace_cb_edns_back_parsed_call");
1809 result = PyObject_Call(func, py_args, py_kwargs);
1811 res = PyInt_AsLong(result);
1814 Py_XDECREF(py_qstate);
1816 Py_XDECREF(py_args);
1817 Py_XDECREF(py_kwargs);
1820 PyGILState_Release(gstate);
1825 static int register_inplace_cb_edns_back_parsed_call(PyObject* py_cb,
1826 struct module_env* env, int id)
1828 int ret = inplace_cb_register(python_inplace_cb_edns_back_parsed_call,
1829 inplace_cb_edns_back_parsed, (void*) py_cb, env, id);
1830 if (ret) Py_INCREF(py_cb);
1834 /* C declarations */
1835 int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
1836 struct module_env* env, int id);
1838 /* Swig declarations */
1839 static int register_inplace_cb_reply(PyObject* py_cb,
1840 struct module_env* env, int id);
1841 static int register_inplace_cb_reply_cache(PyObject* py_cb,
1842 struct module_env* env, int id);
1843 static int register_inplace_cb_reply_local(PyObject* py_cb,
1844 struct module_env* env, int id);
1845 static int register_inplace_cb_reply_servfail(PyObject* py_cb,
1846 struct module_env* env, int id);
1847 static int register_inplace_cb_query(PyObject *py_cb,
1848 struct module_env* env, int id);
1849 static int register_inplace_cb_query_response(PyObject *py_cb,
1850 struct module_env* env, int id);
1851 static int register_inplace_cb_edns_back_parsed_call(PyObject *py_cb,
1852 struct module_env* env, int id);