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