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