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