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