2 * interface.i: unbound python module
8 * This is the interface between the unbound server and a python module
9 * called to perform operations on queries.
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
18 #include "util/module.h"
19 #include "util/netevent.h"
20 #include "util/regional.h"
21 #include "util/config_file.h"
22 #include "util/data/msgreply.h"
23 #include "util/data/packed_rrset.h"
24 #include "util/data/dname.h"
25 #include "util/storage/lruhash.h"
26 #include "services/cache/dns.h"
27 #include "services/mesh.h"
28 #include "iterator/iter_delegpt.h"
29 #include "iterator/iter_hints.h"
30 #include "iterator/iter_utils.h"
31 #include "sldns/wire2str.h"
32 #include "sldns/str2wire.h"
33 #include "sldns/pkthdr.h"
36 %include "stdint.i" /* uint_16_t can be known type now */
39 /* converts [len][data][len][data][0] string to a List of labels (PyBytes) */
40 PyObject* GetNameAsLabelList(const char* name, int len) {
50 list = PyList_New(cnt);
53 PyList_SetItem(list, cnt, PyBytes_FromStringAndSize(name + i + 1, name[i]));
61 /* ************************************************************************************ *
63 * ************************************************************************************ */
65 %ignore query_info::qname;
66 %ignore query_info::qname_len;
110 RR_TYPE_NSAP_PTR = 23,
132 RR_TYPE_IPSECKEY = 45,
138 RR_TYPE_NSEC3PARAMS = 51,
142 RR_TYPE_UNSPEC = 103,
152 PyObject* _get_qname(struct query_info* q) {
153 return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len);
156 PyObject* _get_qname_components(struct query_info* q) {
157 return GetNameAsLabelList((const char*)q->qname, q->qname_len);
162 PyObject* dnameAsStr(const char* dname) {
163 char buf[LDNS_MAX_DOMAINLEN+1];
165 dname_str((uint8_t*)dname, buf);
166 return PyBytes_FromString(buf);
172 def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
173 __swig_getmethods__["qtype_str"] = _get_qtype_str
174 if _newclass:qtype_str = _swig_property(_get_qtype_str)
176 def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
177 __swig_getmethods__["qclass_str"] = _get_qclass_str
178 if _newclass:qclass_str = _swig_property(_get_qclass_str)
180 __swig_getmethods__["qname"] = _unboundmodule._get_qname
181 if _newclass:qname = _swig_property(_unboundmodule._get_qname)
183 __swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components
184 if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components)
186 def _get_qname_str(self): return dnameAsStr(self.qname)
187 __swig_getmethods__["qname_str"] = _get_qname_str
188 if _newclass:qname_str = _swig_property(_get_qname_str)
192 /* ************************************************************************************ *
193 Structure packed_rrset_key
194 * ************************************************************************************ */
195 %ignore packed_rrset_key::dname;
196 %ignore packed_rrset_key::dname_len;
199 struct packed_rrset_key {
204 uint16_t type; /* rrset type in network format */
205 uint16_t rrset_class; /* rrset class in network format */
210 * This subroutine converts values between the host and network byte order.
211 * Specifically, ntohs() converts 16-bit quantities from network byte order to
214 uint16_t ntohs(uint16_t netshort);
217 PyObject* _get_dname(struct packed_rrset_key* k) {
218 return PyBytes_FromStringAndSize((char*)k->dname, k->dname_len);
220 PyObject* _get_dname_components(struct packed_rrset_key* k) {
221 return GetNameAsLabelList((char*)k->dname, k->dname_len);
225 %extend packed_rrset_key {
227 def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
228 __swig_getmethods__["type_str"] = _get_type_str
229 if _newclass:type_str = _swig_property(_get_type_str)
231 def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
232 __swig_getmethods__["rrset_class_str"] = _get_class_str
233 if _newclass:rrset_class_str = _swig_property(_get_class_str)
235 __swig_getmethods__["dname"] = _unboundmodule._get_dname
236 if _newclass:dname = _swig_property(_unboundmodule._get_dname)
238 __swig_getmethods__["dname_list"] = _unboundmodule._get_dname_components
239 if _newclass:dname_list = _swig_property(_unboundmodule._get_dname_components)
241 def _get_dname_str(self): return dnameAsStr(self.dname)
242 __swig_getmethods__["dname_str"] = _get_dname_str
243 if _newclass:dname_str = _swig_property(_get_dname_str)
247 #if defined(SWIGWORDSIZE64)
248 typedef long int rrset_id_type;
250 typedef long long int rrset_id_type;
253 struct ub_packed_rrset_key {
254 struct lruhash_entry entry;
256 struct packed_rrset_key rk;
259 struct lruhash_entry {
261 struct lruhash_entry* overflow_next;
262 struct lruhash_entry* lru_next;
263 struct lruhash_entry* lru_prev;
266 struct packed_rrset_data* data;
269 %ignore packed_rrset_data::rr_len;
270 %ignore packed_rrset_data::rr_ttl;
271 %ignore packed_rrset_data::rr_data;
273 struct packed_rrset_data {
274 /* TTL (in seconds like time()) */
279 /* number of rrsigs */
282 enum rrset_trust trust;
283 enum sec_status security;
285 /* length of every rr's rdata */
287 /* ttl of every rr */
289 /* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in
290 * uncompressed wireformat. */
295 class RRSetData_RRLen:
296 def __init__(self, obj): self.obj = obj
297 def __getitem__(self, index): return _unboundmodule._get_data_rr_len(self.obj, index)
298 def __len__(self): return obj.count + obj.rrsig_count
299 class RRSetData_RRTTL:
300 def __init__(self, obj): self.obj = obj
301 def __getitem__(self, index): return _unboundmodule._get_data_rr_ttl(self.obj, index)
302 def __setitem__(self, index, value): _unboundmodule._set_data_rr_ttl(self.obj, index, value)
303 def __len__(self): return obj.count + obj.rrsig_count
304 class RRSetData_RRData:
305 def __init__(self, obj): self.obj = obj
306 def __getitem__(self, index): return _unboundmodule._get_data_rr_data(self.obj, index)
307 def __len__(self): return obj.count + obj.rrsig_count
311 PyObject* _get_data_rr_len(struct packed_rrset_data* d, int idx) {
312 if ((d != NULL) && (idx >= 0) &&
313 ((size_t)idx < (d->count+d->rrsig_count)))
314 return PyInt_FromLong(d->rr_len[idx]);
317 void _set_data_rr_ttl(struct packed_rrset_data* d, int idx, uint32_t ttl)
319 if ((d != NULL) && (idx >= 0) &&
320 ((size_t)idx < (d->count+d->rrsig_count)))
321 d->rr_ttl[idx] = ttl;
323 PyObject* _get_data_rr_ttl(struct packed_rrset_data* d, int idx) {
324 if ((d != NULL) && (idx >= 0) &&
325 ((size_t)idx < (d->count+d->rrsig_count)))
326 return PyInt_FromLong(d->rr_ttl[idx]);
329 PyObject* _get_data_rr_data(struct packed_rrset_data* d, int idx) {
330 if ((d != NULL) && (idx >= 0) &&
331 ((size_t)idx < (d->count+d->rrsig_count)))
332 return PyBytes_FromStringAndSize((char*)d->rr_data[idx],
338 %extend packed_rrset_data {
340 def _get_data_rr_len(self): return RRSetData_RRLen(self)
341 __swig_getmethods__["rr_len"] = _get_data_rr_len
342 if _newclass:rr_len = _swig_property(_get_data_rr_len)
343 def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
344 __swig_getmethods__["rr_ttl"] =_get_data_rr_ttl
345 if _newclass:rr_len = _swig_property(_get_data_rr_ttl)
346 def _get_data_rr_data(self): return RRSetData_RRData(self)
347 __swig_getmethods__["rr_data"] = _get_data_rr_data
348 if _newclass:rr_len = _swig_property(_get_data_rr_data)
352 /* ************************************************************************************ *
354 * ************************************************************************************ */
356 %ignore reply_info::rrsets;
357 %ignore reply_info::ref;
363 uint32_t prefetch_ttl;
365 uint16_t authoritative;
366 enum sec_status security;
371 size_t rrset_count; /* an_numrrsets + ns_numrrsets + ar_numrrsets */
373 struct ub_packed_rrset_key** rrsets;
374 struct rrset_ref ref[1]; /* ? */
378 struct ub_packed_rrset_key* key;
383 struct query_info qinfo;
384 struct reply_info *rep;
388 class ReplyInfo_RRSet:
389 def __init__(self, obj): self.obj = obj
390 def __getitem__(self, index): return _unboundmodule._rrset_rrsets_get(self.obj, index)
391 def __len__(self): return obj.rrset_count
394 def __init__(self, obj): self.obj = obj
395 def __getitem__(self, index): return _unboundmodule._rrset_ref_get(self.obj, index)
396 def __len__(self): return obj.rrset_count
400 struct ub_packed_rrset_key* _rrset_rrsets_get(struct reply_info* r, int idx) {
401 if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count))
402 return r->rrsets[idx];
406 struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
407 if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) {
408 /* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */
409 return &(r->ref[idx]);
410 /* return &(r->ref[idx]); */
412 /* printf("_rrset_ref_get: NULL\n"); */
419 def _rrset_ref_get(self): return ReplyInfo_Ref(self)
420 __swig_getmethods__["ref"] = _rrset_ref_get
421 if _newclass:ref = _swig_property(_rrset_ref_get)
423 def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
424 __swig_getmethods__["rrsets"] = _rrset_rrsets_get
425 if _newclass:rrsets = _swig_property(_rrset_rrsets_get)
429 /* ************************************************************************************ *
431 * ************************************************************************************ */
433 struct mesh_reply* reply_list;
437 struct mesh_reply* next;
438 struct comm_reply query_reply;
447 PyObject* _comm_reply_addr_get(struct comm_reply* reply) {
449 reply_addr2str(reply, dest, 64);
452 return PyBytes_FromString(dest);
455 PyObject* _comm_reply_family_get(struct comm_reply* reply) {
457 int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
460 case AF_INET: return PyBytes_FromString("ip4");
461 case AF_INET6: return PyBytes_FromString("ip6");
462 case AF_UNIX: return PyBytes_FromString("unix");
468 PyObject* _comm_reply_port_get(struct comm_reply* reply) {
470 port = ntohs(((struct sockaddr_in*)&(reply->addr))->sin_port);
471 return PyInt_FromLong(port);
478 def _addr_get(self): return _comm_reply_addr_get(self)
479 __swig_getmethods__["addr"] = _addr_get
480 if _newclass:addr = _swig_property(_addr_get)
482 def _port_get(self): return _comm_reply_port_get(self)
483 __swig_getmethods__["port"] = _port_get
484 if _newclass:port = _swig_property(_port_get)
486 def _family_get(self): return _comm_reply_family_get(self)
487 __swig_getmethods__["family"] = _family_get
488 if _newclass:family = _swig_property(_family_get)
492 /* ************************************************************************************ *
493 Structure edns_option
494 * ************************************************************************************ */
495 /* Rename the members to follow the python convention of marking them as
496 * private. Access to the opt_code and opt_data members is given by the later
497 * python defined code and data members respectively. */
498 %rename(_next) edns_option::next;
499 %rename(_opt_code) edns_option::opt_code;
500 %rename(_opt_len) edns_option::opt_len;
501 %rename(_opt_data) edns_option::opt_data;
503 struct edns_option* next;
510 PyObject* _edns_option_opt_code_get(struct edns_option* option) {
511 uint16_t opt_code = option->opt_code;
512 return PyInt_FromLong(opt_code);
515 PyObject* _edns_option_opt_data_get(struct edns_option* option) {
516 return PyByteArray_FromStringAndSize((void*)option->opt_data,
520 %extend edns_option {
522 def _opt_code_get(self): return _edns_option_opt_code_get(self)
523 __swig_getmethods__["code"] = _opt_code_get
524 if _newclass: opt_code = _swig_property(_opt_code_get)
526 def _opt_data_get(self): return _edns_option_opt_data_get(self)
527 __swig_getmethods__["data"] = _opt_data_get
528 if _newclass: opt_data = _swig_property(_opt_data_get)
532 /* ************************************************************************************ *
534 * ************************************************************************************ */
535 /* This is ignored because we will pass a double pointer of this to Python
536 * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
537 * pointers as None. */
538 %ignore edns_data::opt_list;
542 uint8_t edns_version;
545 struct edns_option* opt_list;
548 struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) {
549 return &edns->opt_list;
554 def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
555 __swig_getmethods__["opt_list_iter"] = _opt_list_iter
556 if _newclass:opt_list_iter = _swig_property(_opt_list_iter)
557 def _opt_list(self): return _edns_data_opt_list_get(self)
558 __swig_getmethods__["opt_list"] = _opt_list
559 if _newclass:opt_list = _swig_property(_opt_list)
563 /* ************************************************************************************ *
565 * ************************************************************************************ */
567 struct config_file* cfg;
568 struct slabhash* msg_cache;
569 struct rrset_cache* rrset_cache;
570 struct infra_cache* infra_cache;
571 struct key_cache* key_cache;
573 /* --- services --- */
574 struct outbound_entry* (*send_query)(struct query_info* qinfo,
575 uint16_t flags, int dnssec, int want_dnssec, int nocaps,
576 struct sockaddr_storage* addr, socklen_t addrlen,
577 uint8_t* zone, size_t zonelen, int ssl_upstream,
578 struct module_qstate* q);
579 void (*detach_subs)(struct module_qstate* qstate);
580 int (*attach_sub)(struct module_qstate* qstate,
581 struct query_info* qinfo, uint16_t qflags, int prime,
582 int valrec, struct module_qstate** newq);
583 void (*kill_sub)(struct module_qstate* newq);
584 int (*detect_cycle)(struct module_qstate* qstate,
585 struct query_info* qinfo, uint16_t flags, int prime,
588 struct regional* scratch;
589 struct sldns_buffer* scratch_buffer;
590 struct worker* worker;
591 struct mesh_area* mesh;
592 struct alloc_cache* alloc;
593 struct ub_randstate* rnd;
595 struct timeval* now_tv;
596 int need_to_validate;
597 struct val_anchors* anchors;
598 struct val_neg_cache* neg_cache;
599 struct comm_timer* probe_timer;
600 struct iter_forwards* fwds;
601 struct iter_hints* hints;
602 void* modinfo[MAX_MODULE];
604 void* inplace_cb_lists[inplace_cb_types_total];
605 struct edns_known_option* edns_known_options;
606 size_t edns_known_options_num;
609 /* ************************************************************************************ *
610 Structure module_qstate
611 * ************************************************************************************ */
612 %ignore module_qstate::ext_state;
613 %ignore module_qstate::minfo;
615 /* These are ignored because we will pass a double pointer of them to Python
616 * with custom getmethods. This is done to bypass Swig's behavior to pass NULL
617 * pointers as None. */
618 %ignore module_qstate::edns_opts_front_in;
619 %ignore module_qstate::edns_opts_back_out;
620 %ignore module_qstate::edns_opts_back_in;
621 %ignore module_qstate::edns_opts_front_out;
624 struct module_qstate {
625 struct query_info qinfo;
626 uint16_t query_flags; /* See QF_BIT_xx constants */
630 struct comm_reply* reply;
631 struct dns_msg* return_msg;
633 struct regional* region; /* unwrapped */
637 enum module_ext_state ext_state[MAX_MODULE];
638 void* minfo[MAX_MODULE];
639 time_t prefetch_leeway;
641 struct module_env* env; /* unwrapped */
642 struct mesh_state* mesh_info;
644 struct edns_option* edns_opts_front_in;
645 struct edns_option* edns_opts_back_out;
646 struct edns_option* edns_opts_back_in;
647 struct edns_option* edns_opts_front_out;
652 %constant int MODULE_COUNT = MAX_MODULE;
654 %constant int QF_BIT_CD = 0x0010;
655 %constant int QF_BIT_AD = 0x0020;
656 %constant int QF_BIT_Z = 0x0040;
657 %constant int QF_BIT_RA = 0x0080;
658 %constant int QF_BIT_RD = 0x0100;
659 %constant int QF_BIT_TC = 0x0200;
660 %constant int QF_BIT_AA = 0x0400;
661 %constant int QF_BIT_QR = 0x8000;
664 enum enum_return_rcode {
681 def __init__(self, obj): self.obj = obj
683 return ", ".join([_unboundmodule.strextstate(_unboundmodule._ext_state_get(self.obj,a)) for a in range(0, _unboundmodule.MODULE_COUNT)])
684 def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index)
685 def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value)
686 def __len__(self): return _unboundmodule.MODULE_COUNT
688 class EdnsOptsListIter:
689 def __init__(self, obj):
692 def __iter__(self): return self
694 """Python 3 compatibility"""
695 return self._get_next()
697 """Python 2 compatibility"""
698 return self._get_next()
700 if not edns_opt_list_is_empty(self._current):
701 self._temp = self._current
702 self._current = _p_p_edns_option_get_next(self._current)
703 return _dereference_edns_option(self._temp)
709 enum module_ext_state _ext_state_get(struct module_qstate* q, int idx) {
710 if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
711 return q->ext_state[idx];
716 void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
717 if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
718 q->ext_state[idx] = state;
722 int edns_opt_list_is_empty(struct edns_option** opt) {
723 if (!opt || !(*opt)) return 1;
727 struct edns_option* _dereference_edns_option(struct edns_option** opt) {
728 if (!opt) return NULL;
732 struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) {
733 return &(*opt)->next;
736 struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) {
737 return &q->edns_opts_front_in;
740 struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) {
741 return &q->edns_opts_back_out;
744 struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) {
745 return &q->edns_opts_back_in;
748 struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) {
749 return &q->edns_opts_front_out;
753 %extend module_qstate {
755 def set_ext_state(self, id, state):
756 """Sets the ext state"""
757 _unboundmodule._ext_state_set(self, id, state)
759 def __ext_state_get(self): return ExtState(self)
760 __swig_getmethods__["ext_state"] = __ext_state_get
761 if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
763 def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
764 __swig_getmethods__["edns_opts_front_in_iter"] = _edns_opts_front_in_iter
765 if _newclass:edns_opts_front_in_iter = _swig_property(_edns_opts_front_in_iter)
766 def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
767 __swig_getmethods__["edns_opts_back_out_iter"] = _edns_opts_back_out_iter
768 if _newclass:edns_opts_back_out_iter = _swig_property(_edns_opts_back_out_iter)
769 def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
770 __swig_getmethods__["edns_opts_back_in_iter"] = _edns_opts_back_in_iter
771 if _newclass:edns_opts_back_in_iter = _swig_property(_edns_opts_back_in_iter)
772 def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
773 __swig_getmethods__["edns_opts_front_out_iter"] = _edns_opts_front_out_iter
774 if _newclass:edns_opts_front_out_iter = _swig_property(_edns_opts_front_out_iter)
776 def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
777 __swig_getmethods__["edns_opts_front_in"] = _edns_opts_front_in
778 if _newclass:edns_opts_front_in = _swig_property(_edns_opts_front_in)
779 def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
780 __swig_getmethods__["edns_opts_back_out"] = _edns_opts_back_out
781 if _newclass:edns_opts_back_out = _swig_property(_edns_opts_back_out)
782 def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
783 __swig_getmethods__["edns_opts_back_in"] = _edns_opts_back_in
784 if _newclass:edns_opts_back_in = _swig_property(_edns_opts_back_in)
785 def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
786 __swig_getmethods__["edns_opts_front_out"] = _edns_opts_front_out
787 if _newclass:edns_opts_front_out = _swig_property(_edns_opts_front_out)
791 /* ************************************************************************************ *
792 Structure config_strlist
793 * ************************************************************************************ */
794 struct config_strlist {
795 struct config_strlist* next;
799 /* ************************************************************************************ *
800 Structure config_str2list
801 * ************************************************************************************ */
802 struct config_str2list {
803 struct config_str2list* next;
808 /* ************************************************************************************ *
809 Structure config_file
810 * ************************************************************************************ */
822 int outgoing_num_ports;
823 size_t outgoing_num_tcp;
824 size_t incoming_num_tcp;
825 int* outgoing_avail_ports;
826 size_t msg_buffer_size;
827 size_t msg_cache_size;
828 size_t msg_cache_slabs;
829 size_t num_queries_per_thread;
831 size_t rrset_cache_size;
832 size_t rrset_cache_slabs;
834 size_t infra_cache_slabs;
835 size_t infra_cache_numhosts;
836 char* target_fetch_policy;
842 struct config_strlist* root_hints;
843 struct config_stub* stubs;
844 struct config_stub* forwards;
845 struct config_strlist* donotqueryaddrs;
846 struct config_str2list* acls;
847 int donotquery_localhost;
848 int harden_short_bufsize;
849 int harden_large_queries;
851 int harden_dnssec_stripped;
852 int harden_referral_path;
853 int use_caps_bits_for_id;
854 struct config_strlist* private_address;
855 struct config_strlist* private_domain;
856 size_t unwanted_threshold;
868 struct config_strlist* trust_anchor_file_list;
869 struct config_strlist* trust_anchor_list;
870 struct config_strlist* trusted_keys_file_list;
871 char* dlv_anchor_file;
872 struct config_strlist* dlv_anchor_list;
874 int32_t val_date_override;
876 int val_clean_additional;
877 int val_permissive_mode;
878 char* val_nsec3_key_iterations;
879 size_t key_cache_size;
880 size_t key_cache_slabs;
881 size_t neg_cache_size;
882 struct config_str2list* local_zones;
883 struct config_strlist* local_zones_nodefault;
884 struct config_strlist* local_data;
885 int remote_control_enable;
886 struct config_strlist* control_ifs;
888 char* server_key_file;
889 char* server_cert_file;
890 char* control_key_file;
891 char* control_cert_file;
896 /* ************************************************************************************ *
897 ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation
898 * ************************************************************************************ */
900 struct delegpt_ns* next;
909 struct delegpt_addr {
910 struct delegpt_addr* next_result;
911 struct delegpt_addr* next_usable;
912 struct delegpt_addr* next_target;
921 struct delegpt_ns* nslist;
922 struct delegpt_addr* target_list;
923 struct delegpt_addr* usable_list;
924 struct delegpt_addr* result_list;
926 uint8_t has_parent_side_NS;
932 PyObject* _get_dp_dname(struct delegpt* dp) {
933 return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen);
935 PyObject* _get_dp_dname_components(struct delegpt* dp) {
936 return GetNameAsLabelList((char*)dp->name, dp->namelen);
938 PyObject* _get_dpns_dname(struct delegpt_ns* dpns) {
939 return PyBytes_FromStringAndSize((char*)dpns->name, dpns->namelen);
941 PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) {
942 return GetNameAsLabelList((char*)dpns->name, dpns->namelen);
945 PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) {
947 delegpt_addr_addr2str(target, dest, 64);
950 return PyBytes_FromString(dest);
957 __swig_getmethods__["dname"] = _unboundmodule._get_dp_dname
958 if _newclass:dname = _swig_property(_unboundmodule._get_dp_dname)
960 __swig_getmethods__["dname_list"] = _unboundmodule._get_dp_dname_components
961 if _newclass:dname_list = _swig_property(_unboundmodule._get_dp_dname_components)
963 def _get_dname_str(self): return dnameAsStr(self.dname)
964 __swig_getmethods__["dname_str"] = _get_dname_str
965 if _newclass:dname_str = _swig_property(_get_dname_str)
970 __swig_getmethods__["dname"] = _unboundmodule._get_dpns_dname
971 if _newclass:dname = _swig_property(_unboundmodule._get_dpns_dname)
973 __swig_getmethods__["dname_list"] = _unboundmodule._get_dpns_dname_components
974 if _newclass:dname_list = _swig_property(_unboundmodule._get_dpns_dname_components)
976 def _get_dname_str(self): return dnameAsStr(self.dname)
977 __swig_getmethods__["dname_str"] = _get_dname_str
978 if _newclass:dname_str = _swig_property(_get_dname_str)
981 %extend delegpt_addr {
983 def _addr_get(self): return _delegpt_addr_addr_get(self)
984 __swig_getmethods__["addr"] = _addr_get
985 if _newclass:addr = _swig_property(_addr_get)
989 /* ************************************************************************************ *
991 * ************************************************************************************ */
992 %rename ("MODULE_STATE_INITIAL") "module_state_initial";
993 %rename ("MODULE_WAIT_REPLY") "module_wait_reply";
994 %rename ("MODULE_WAIT_MODULE") "module_wait_module";
995 %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
996 %rename ("MODULE_ERROR") "module_error";
997 %rename ("MODULE_FINISHED") "module_finished";
999 enum module_ext_state {
1000 module_state_initial = 0,
1003 module_wait_subquery,
1008 %rename ("MODULE_EVENT_NEW") "module_event_new";
1009 %rename ("MODULE_EVENT_PASS") "module_event_pass";
1010 %rename ("MODULE_EVENT_REPLY") "module_event_reply";
1011 %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply";
1012 %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail";
1013 %rename ("MODULE_EVENT_MODDONE") "module_event_moddone";
1014 %rename ("MODULE_EVENT_ERROR") "module_event_error";
1017 module_event_new = 0,
1020 module_event_noreply,
1021 module_event_capsfail,
1022 module_event_moddone,
1027 sec_status_unchecked = 0,
1029 sec_status_indeterminate,
1030 sec_status_insecure,
1034 enum verbosity_value {
1042 enum inplace_cb_list_type {
1043 /* Inplace callbacks for when a resolved reply is ready to be sent to the
1045 inplace_cb_reply = 0,
1046 /* Inplace callbacks for when a reply is given from the cache. */
1047 inplace_cb_reply_cache,
1048 /* Inplace callbacks for when a reply is given with local data
1049 * (or Chaos reply). */
1050 inplace_cb_reply_local,
1051 /* Inplace callbacks for when the reply is servfail. */
1052 inplace_cb_reply_servfail,
1053 /* Inplace callbacks for when a query is ready to be sent to the back.*/
1055 /* Inplace callback for when a reply is received from the back. */
1056 inplace_cb_edns_back_parsed,
1057 /* Total number of types. Used for array initialization.
1058 * Should always be last. */
1059 inplace_cb_types_total
1062 %constant uint16_t PKT_QR = 1; /* QueRy - query flag */
1063 %constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */
1064 %constant uint16_t PKT_TC = 4; /* TrunCated - server flag */
1065 %constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */
1066 %constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */
1067 %constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */
1068 %constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */
1071 int checkList(PyObject *l)
1079 if (PyList_Check(l))
1081 for (i=0; i < PyList_Size(l); i++)
1083 item = PyList_GetItem(l, i);
1084 if (!PyBytes_Check(item))
1093 int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
1094 size_t count_offset)
1100 for (i=0; i < PyList_Size(l); i++)
1102 item = PyList_GetItem(l, i);
1104 len = sldns_buffer_remaining(qb);
1106 if(sldns_str2wire_rr_question_buf(PyBytes_AsString(item),
1107 sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
1111 if(sldns_str2wire_rr_buf(PyBytes_AsString(item),
1112 sldns_buffer_current(qb), &len, NULL, default_ttl,
1113 NULL, 0, NULL, 0) != 0)
1116 sldns_buffer_skip(qb, len);
1118 sldns_buffer_write_u16_at(qb, count_offset,
1119 sldns_buffer_read_u16_at(qb, count_offset)+1);
1124 int set_return_msg(struct module_qstate* qstate,
1125 const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl,
1126 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional)
1128 sldns_buffer *qb = 0;
1131 uint16_t PKT_QR = 1;
1132 uint16_t PKT_AA = 2;
1133 uint16_t PKT_TC = 4;
1134 uint16_t PKT_RD = 8;
1135 uint16_t PKT_CD = 16;
1136 uint16_t PKT_RA = 32;
1137 uint16_t PKT_AD = 64;
1139 if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional)))
1141 if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0;
1144 sldns_buffer_write_u16(qb, 0); /* ID */
1145 sldns_buffer_write_u16(qb, 0); /* flags */
1146 sldns_buffer_write_u16(qb, 1); /* qdcount */
1147 sldns_buffer_write_u16(qb, 0); /* ancount */
1148 sldns_buffer_write_u16(qb, 0); /* nscount */
1149 sldns_buffer_write_u16(qb, 0); /* arcount */
1150 if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb));
1151 if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb));
1152 if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb));
1153 if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb));
1154 if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb));
1155 if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb));
1156 if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb));
1158 /* write the query */
1159 l = sldns_buffer_remaining(qb);
1160 if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) {
1161 sldns_buffer_free(qb);
1164 sldns_buffer_skip(qb, l);
1165 if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; }
1166 if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; }
1167 sldns_buffer_write_u16(qb, rr_type);
1168 sldns_buffer_write_u16(qb, rr_class);
1170 /* write RR sections */
1171 if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF))
1173 if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF))
1175 if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF))
1177 if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF))
1180 if (res) res = createResponse(qstate, qb);
1182 if (qb) sldns_buffer_free(qb);
1187 int set_return_msg(struct module_qstate* qstate,
1188 const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl,
1189 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional);
1193 def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0):
1194 """Query flags is a combination of PKT_xx contants"""
1195 self.rr_name = rr_name
1196 self.rr_type = rr_type
1197 self.rr_class = rr_class
1198 self.default_ttl = default_ttl
1199 self.query_flags = query_flags
1203 self.additional = []
1205 def set_return_msg(self, qstate):
1206 """Returns 1 if OK"""
1207 status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class,
1208 self.query_flags, self.default_ttl,
1209 self.question, self.answer, self.authority, self.additional)
1211 if (status) and (PKT_AA & self.query_flags):
1212 qstate.return_msg.rep.authoritative = 1
1217 /* ************************************************************************************ *
1218 ASN: Delegation pointer related functions
1219 * ************************************************************************************ */
1221 /* Functions which we will need to lookup delegations */
1222 struct delegpt* dns_cache_find_delegation(struct module_env* env,
1223 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
1224 struct regional* region, struct dns_msg** msg, uint32_t timenow);
1225 int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
1226 struct delegpt* dp);
1227 struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
1228 uint8_t* qname, uint16_t qclass, struct delegpt* dp);
1230 /* Custom function to perform logic similar to the one in daemon/cachedump.c */
1231 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen);
1234 #define BIT_RD 0x100
1236 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen)
1239 struct dns_msg *msg = NULL;
1240 struct regional* region = qstate->env->scratch;
1242 struct query_info qinfo;
1243 struct iter_hints_stub* stub;
1244 uint32_t timenow = *qstate->env->now;
1246 regional_free_all(region);
1247 qinfo.qname = (uint8_t*)nm;
1248 qinfo.qname_len = nmlen;
1249 qinfo.qtype = LDNS_RR_TYPE_A;
1250 qinfo.qclass = LDNS_RR_CLASS_IN;
1253 dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow);
1256 if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
1257 if (dname_is_root((uint8_t*)nm))
1259 nm = (char*)dp->name;
1260 nmlen = dp->namelen;
1261 dname_remove_label((uint8_t**)&nm, &nmlen);
1262 dname_str((uint8_t*)nm, b);
1265 stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, qinfo.qclass, dp);
1276 /* ************************************************************************************ *
1278 * ************************************************************************************ */
1279 /******************************
1280 * Various debuging functions *
1281 ******************************/
1282 void verbose(enum verbosity_value level, const char* format, ...);
1283 void log_info(const char* format, ...);
1284 void log_err(const char* format, ...);
1285 void log_warn(const char* format, ...);
1286 void log_hex(const char* msg, void* data, size_t length);
1287 void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep);
1288 void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
1289 void regional_log_stats(struct regional *r);
1291 /***************************************************************************
1292 * Free allocated memory from marked sources returning corresponding types *
1293 ***************************************************************************/
1294 %typemap(newfree, noblock = 1) char * {
1298 /***************************************************
1299 * Mark as source returning newly allocated memory *
1300 ***************************************************/
1301 %newobject sldns_wire2str_type;
1302 %newobject sldns_wire2str_class;
1307 char *sldns_wire2str_type(const uint16_t atype);
1308 char *sldns_wire2str_class(const uint16_t aclass);
1310 /**********************************
1311 * Functions from pythonmod_utils *
1312 **********************************/
1313 int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
1314 void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
1316 /*******************************
1317 * Module conversion functions *
1318 *******************************/
1319 const char* strextstate(enum module_ext_state s);
1320 const char* strmodulevent(enum module_ev e);
1322 /**************************
1323 * Edns related functions *
1324 **************************/
1325 struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
1326 int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
1327 int no_aggregation, struct module_env* env);
1330 def register_edns_option(env, code, bypass_cache_stage=False,
1331 no_aggregation=False):
1332 """Wrapper function to provide keyword attributes."""
1333 return edns_register_option(code, bypass_cache_stage,
1334 no_aggregation, env)
1337 /******************************
1338 * Callback related functions *
1339 ******************************/
1340 /* typemap to check if argument is callable */
1341 %typemap(in) PyObject *py_cb {
1342 if (!PyCallable_Check($input)) {
1343 SWIG_exception_fail(SWIG_TypeError, "Need a callable object!");
1348 /* typemap to get content/size from a bytearray */
1349 %typemap(in) (size_t len, uint8_t* py_bytearray_data) {
1350 if (!PyByteArray_CheckExact($input)) {
1351 SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!");
1354 $2 = (void*)PyByteArray_AsString($input);
1355 $1 = PyByteArray_Size($input);
1358 int edns_opt_list_remove(struct edns_option** list, uint16_t code);
1359 int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
1360 uint8_t* py_bytearray_data, struct regional* region);
1363 /* This function is called by unbound in order to call the python
1364 * callback function. */
1365 int python_inplace_cb_reply_generic(struct query_info* qinfo,
1366 struct module_qstate* qstate, struct reply_info* rep, int rcode,
1367 struct edns_data* edns, struct edns_option** opt_list_out,
1368 struct regional* region, int id, void* python_callback)
1370 PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
1371 PyObject *py_rep, *py_region;
1375 PyGILState_STATE gstate = PyGILState_Ensure();
1376 func = (PyObject *) python_callback;
1377 py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
1378 py_qstate = SWIG_NewPointerObj((void*) qstate,
1379 SWIGTYPE_p_module_qstate, 0);
1380 py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out,
1381 SWIGTYPE_p_p_edns_option, 0);
1382 py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
1383 py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
1384 py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
1385 result = PyObject_CallFunction(func, "OOOiOOO", py_qinfo, py_qstate,
1386 py_rep, rcode, py_edns, py_opt_list_out, py_region);
1387 Py_XDECREF(py_edns);
1388 Py_XDECREF(py_qstate);
1389 Py_XDECREF(py_opt_list_out);
1390 Py_XDECREF(py_qinfo);
1392 Py_XDECREF(py_region);
1394 res = PyInt_AsLong(result);
1397 PyGILState_Release(gstate);
1401 /* register a callback */
1402 static int python_inplace_cb_register(enum inplace_cb_list_type type,
1403 PyObject* py_cb, struct module_env* env, int id)
1405 int ret = inplace_cb_register(python_inplace_cb_reply_generic,
1406 type, (void*) py_cb, env, id);
1407 if (ret) Py_INCREF(py_cb);
1411 /* Swig implementations for Python */
1412 static int register_inplace_cb_reply(PyObject* py_cb,
1413 struct module_env* env, int id)
1415 return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id);
1417 static int register_inplace_cb_reply_cache(PyObject* py_cb,
1418 struct module_env* env, int id)
1420 return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id);
1422 static int register_inplace_cb_reply_local(PyObject* py_cb,
1423 struct module_env* env, int id)
1425 return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id);
1427 static int register_inplace_cb_reply_servfail(PyObject* py_cb,
1428 struct module_env* env, int id)
1430 return python_inplace_cb_register(inplace_cb_reply_servfail,
1434 /* C declarations */
1435 int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
1436 struct module_env* env, int id);
1438 /* Swig declarations */
1439 static int register_inplace_cb_reply(PyObject* py_cb,
1440 struct module_env* env, int id);
1441 static int register_inplace_cb_reply_cache(PyObject* py_cb,
1442 struct module_env* env, int id);
1443 static int register_inplace_cb_reply_local(PyObject* py_cb,
1444 struct module_env* env, int id);
1445 static int register_inplace_cb_reply_servfail(PyObject* py_cb,
1446 struct module_env* env, int id);