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) */ GetNameAsLabelList(const char * name,int len)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 */ CharArrayAsStringList(char ** array,int len)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 _get_qname(struct query_info * q)196 PyObject* _get_qname(struct query_info* q) { 197 return PyBytes_FromStringAndSize((char*)q->qname, q->qname_len); 198 } 199 _get_qname_components(struct query_info * q)200 PyObject* _get_qname_components(struct query_info* q) { 201 return GetNameAsLabelList((const char*)q->qname, q->qname_len); 202 } 203 %} 204 205 %inline %{ dnameAsStr(PyObject * dname)206 PyObject* dnameAsStr(PyObject* dname) { 207 char buf[LDNS_MAX_DOMAINLEN+1]; 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_dnssec_stripped; 1013 int harden_referral_path; 1014 int use_caps_bits_for_id; 1015 struct config_strlist* private_address; 1016 struct config_strlist* private_domain; 1017 size_t unwanted_threshold; 1018 char* chrootdir; 1019 char* username; 1020 char* directory; 1021 char* logfile; 1022 char* pidfile; 1023 int use_syslog; 1024 int hide_identity; 1025 int hide_version; 1026 char* identity; 1027 char* version; 1028 char* module_conf; 1029 struct config_strlist* trust_anchor_file_list; 1030 struct config_strlist* trust_anchor_list; 1031 struct config_strlist* trusted_keys_file_list; 1032 int max_ttl; 1033 int32_t val_date_override; 1034 int bogus_ttl; 1035 int val_clean_additional; 1036 int val_permissive_mode; 1037 char* val_nsec3_key_iterations; 1038 size_t key_cache_size; 1039 size_t key_cache_slabs; 1040 size_t neg_cache_size; 1041 struct config_str2list* local_zones; 1042 struct config_strlist* local_zones_nodefault; 1043 struct config_strlist* local_data; 1044 int remote_control_enable; 1045 struct config_strlist_head control_ifs; 1046 int control_port; 1047 char* server_key_file; 1048 char* server_cert_file; 1049 char* control_key_file; 1050 char* control_cert_file; 1051 int do_daemonize; 1052 struct config_strlist* python_script; 1053 }; 1054 1055 %inline %{ 1056 PyObject* _get_ifs_tuple(struct config_file* cfg) { 1057 return CharArrayAsStringList(cfg->ifs, cfg->num_ifs); 1058 } 1059 PyObject* _get_ifs_out_tuple(struct config_file* cfg) { 1060 return CharArrayAsStringList(cfg->out_ifs, cfg->num_out_ifs); 1061 } 1062 %} 1063 1064 %extend config_file { 1065 %pythoncode %{ 1066 ifs = property(_unboundmodule._get_ifs_tuple) 1067 out_ifs = property(_unboundmodule._get_ifs_out_tuple) 1068 1069 def _deprecated_python_script(self): return "cfg.python_script is deprecated, you can use `mod_env['script']` instead." 1070 python_script = property(_deprecated_python_script) 1071 %} 1072 } 1073 1074 /* ************************************************************************************ * 1075 ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation 1076 * ************************************************************************************ */ 1077 struct delegpt_ns { 1078 struct delegpt_ns* next; 1079 int resolved; 1080 uint8_t got4; 1081 uint8_t got6; 1082 uint8_t lame; 1083 uint8_t done_pside4; 1084 uint8_t done_pside6; 1085 }; 1086 1087 struct delegpt_addr { 1088 struct delegpt_addr* next_result; 1089 struct delegpt_addr* next_usable; 1090 struct delegpt_addr* next_target; 1091 int attempts; 1092 int sel_rtt; 1093 int bogus; 1094 int lame; 1095 }; 1096 1097 struct delegpt { 1098 int namelabs; 1099 struct delegpt_ns* nslist; 1100 struct delegpt_addr* target_list; 1101 struct delegpt_addr* usable_list; 1102 struct delegpt_addr* result_list; 1103 int bogus; 1104 uint8_t has_parent_side_NS; 1105 uint8_t dp_type_mlc; 1106 }; 1107 1108 1109 %inline %{ 1110 PyObject* _get_dp_dname(struct delegpt* dp) { 1111 return PyBytes_FromStringAndSize((char*)dp->name, dp->namelen); 1112 } 1113 PyObject* _get_dp_dname_components(struct delegpt* dp) { 1114 return GetNameAsLabelList((char*)dp->name, dp->namelen); 1115 } 1116 PyObject* _get_dpns_dname(struct delegpt_ns* dpns) { 1117 return PyBytes_FromStringAndSize((char*)dpns->name, dpns->namelen); 1118 } 1119 PyObject* _get_dpns_dname_components(struct delegpt_ns* dpns) { 1120 return GetNameAsLabelList((char*)dpns->name, dpns->namelen); 1121 } 1122 1123 PyObject* _delegpt_addr_addr_get(struct delegpt_addr* target) { 1124 char dest[64]; 1125 delegpt_addr_addr2str(target, dest, 64); 1126 if (dest[0] == 0) 1127 return Py_None; 1128 return PyBytes_FromString(dest); 1129 } 1130 1131 %} 1132 1133 %extend delegpt { 1134 %pythoncode %{ 1135 dname = property(_unboundmodule._get_dp_dname) 1136 1137 dname_list = property(_unboundmodule._get_dp_dname_components) 1138 1139 def _get_dname_str(self): return dnameAsStr(self.dname) 1140 dname_str = property(_get_dname_str) 1141 %} 1142 } 1143 %extend delegpt_ns { 1144 %pythoncode %{ 1145 dname = property(_unboundmodule._get_dpns_dname) 1146 1147 dname_list = property(_unboundmodule._get_dpns_dname_components) 1148 1149 def _get_dname_str(self): return dnameAsStr(self.dname) 1150 dname_str = property(_get_dname_str) 1151 %} 1152 } 1153 %extend delegpt_addr { 1154 %pythoncode %{ 1155 def _addr_get(self): return _delegpt_addr_addr_get(self) 1156 addr = property(_addr_get) 1157 %} 1158 } 1159 1160 /* ************************************************************************************ * 1161 Enums 1162 * ************************************************************************************ */ 1163 %rename ("MODULE_STATE_INITIAL") "module_state_initial"; 1164 %rename ("MODULE_WAIT_REPLY") "module_wait_reply"; 1165 %rename ("MODULE_WAIT_MODULE") "module_wait_module"; 1166 %rename ("MODULE_RESTART_NEXT") "module_restart_next"; 1167 %rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery"; 1168 %rename ("MODULE_ERROR") "module_error"; 1169 %rename ("MODULE_FINISHED") "module_finished"; 1170 1171 enum module_ext_state { 1172 module_state_initial = 0, 1173 module_wait_reply, 1174 module_wait_module, 1175 module_restart_next, 1176 module_wait_subquery, 1177 module_error, 1178 module_finished 1179 }; 1180 1181 %rename ("MODULE_EVENT_NEW") "module_event_new"; 1182 %rename ("MODULE_EVENT_PASS") "module_event_pass"; 1183 %rename ("MODULE_EVENT_REPLY") "module_event_reply"; 1184 %rename ("MODULE_EVENT_NOREPLY") "module_event_noreply"; 1185 %rename ("MODULE_EVENT_CAPSFAIL") "module_event_capsfail"; 1186 %rename ("MODULE_EVENT_MODDONE") "module_event_moddone"; 1187 %rename ("MODULE_EVENT_ERROR") "module_event_error"; 1188 1189 enum module_ev { 1190 module_event_new = 0, 1191 module_event_pass, 1192 module_event_reply, 1193 module_event_noreply, 1194 module_event_capsfail, 1195 module_event_moddone, 1196 module_event_error 1197 }; 1198 1199 enum sec_status { 1200 sec_status_unchecked = 0, 1201 sec_status_bogus, 1202 sec_status_indeterminate, 1203 sec_status_insecure, 1204 sec_status_secure 1205 }; 1206 1207 enum verbosity_value { 1208 NO_VERBOSE = 0, 1209 VERB_OPS, 1210 VERB_DETAIL, 1211 VERB_QUERY, 1212 VERB_ALGO 1213 }; 1214 1215 enum inplace_cb_list_type { 1216 /* Inplace callbacks for when a resolved reply is ready to be sent to the 1217 * front.*/ 1218 inplace_cb_reply = 0, 1219 /* Inplace callbacks for when a reply is given from the cache. */ 1220 inplace_cb_reply_cache, 1221 /* Inplace callbacks for when a reply is given with local data 1222 * (or Chaos reply). */ 1223 inplace_cb_reply_local, 1224 /* Inplace callbacks for when the reply is servfail. */ 1225 inplace_cb_reply_servfail, 1226 /* Inplace callbacks for when a query is ready to be sent to the back.*/ 1227 inplace_cb_query, 1228 /* Inplace callback for when a reply is received from the back. */ 1229 inplace_cb_edns_back_parsed, 1230 /* Total number of types. Used for array initialization. 1231 * Should always be last. */ 1232 inplace_cb_types_total 1233 }; 1234 1235 %constant uint16_t PKT_QR = 1; /* QueRy - query flag */ 1236 %constant uint16_t PKT_AA = 2; /* Authoritative Answer - server flag */ 1237 %constant uint16_t PKT_TC = 4; /* TrunCated - server flag */ 1238 %constant uint16_t PKT_RD = 8; /* Recursion Desired - query flag */ 1239 %constant uint16_t PKT_CD = 16; /* Checking Disabled - query flag */ 1240 %constant uint16_t PKT_RA = 32; /* Recursion Available - server flag */ 1241 %constant uint16_t PKT_AD = 64; /* Authenticated Data - server flag */ 1242 1243 %{ 1244 int checkList(PyObject *l) 1245 { 1246 PyObject* item; 1247 int i; 1248 1249 if (l == Py_None) 1250 return 1; 1251 1252 if (PyList_Check(l)) 1253 { 1254 for (i=0; i < PyList_Size(l); i++) 1255 { 1256 item = PyList_GetItem(l, i); 1257 if (!PyBytes_Check(item) && !PyUnicode_Check(item)) 1258 return 0; 1259 } 1260 return 1; 1261 } 1262 1263 return 0; 1264 } 1265 1266 int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec, 1267 size_t count_offset) 1268 { 1269 PyObject* item; 1270 int i; 1271 size_t len; 1272 char* s; 1273 PyObject* ascstr; 1274 1275 for (i=0; i < PyList_Size(l); i++) 1276 { 1277 ascstr = NULL; 1278 item = PyList_GetItem(l, i); 1279 if(PyObject_TypeCheck(item, &PyBytes_Type)) { 1280 s = PyBytes_AsString(item); 1281 } else { 1282 ascstr = PyUnicode_AsASCIIString(item); 1283 s = PyBytes_AsString(ascstr); 1284 } 1285 1286 len = sldns_buffer_remaining(qb); 1287 if(qsec) { 1288 if(sldns_str2wire_rr_question_buf(s, 1289 sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0) 1290 != 0) { 1291 if(ascstr) 1292 Py_DECREF(ascstr); 1293 return 0; 1294 } 1295 } else { 1296 if(sldns_str2wire_rr_buf(s, 1297 sldns_buffer_current(qb), &len, NULL, default_ttl, 1298 NULL, 0, NULL, 0) != 0) { 1299 if(ascstr) 1300 Py_DECREF(ascstr); 1301 return 0; 1302 } 1303 } 1304 if(ascstr) 1305 Py_DECREF(ascstr); 1306 sldns_buffer_skip(qb, len); 1307 1308 sldns_buffer_write_u16_at(qb, count_offset, 1309 sldns_buffer_read_u16_at(qb, count_offset)+1); 1310 } 1311 return 1; 1312 } 1313 1314 int set_return_msg(struct module_qstate* qstate, 1315 const char* rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class , uint16_t flags, uint32_t default_ttl, 1316 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional) 1317 { 1318 sldns_buffer *qb = 0; 1319 int res = 1; 1320 size_t l; 1321 uint16_t PKT_QR = 1; 1322 uint16_t PKT_AA = 2; 1323 uint16_t PKT_TC = 4; 1324 uint16_t PKT_RD = 8; 1325 uint16_t PKT_CD = 16; 1326 uint16_t PKT_RA = 32; 1327 uint16_t PKT_AD = 64; 1328 1329 if ((!checkList(question)) || (!checkList(answer)) || (!checkList(authority)) || (!checkList(additional))) 1330 return 0; 1331 if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == 0) return 0; 1332 1333 /* write header */ 1334 sldns_buffer_write_u16(qb, 0); /* ID */ 1335 sldns_buffer_write_u16(qb, 0); /* flags */ 1336 sldns_buffer_write_u16(qb, 1); /* qdcount */ 1337 sldns_buffer_write_u16(qb, 0); /* ancount */ 1338 sldns_buffer_write_u16(qb, 0); /* nscount */ 1339 sldns_buffer_write_u16(qb, 0); /* arcount */ 1340 if ((flags&PKT_QR)) LDNS_QR_SET(sldns_buffer_begin(qb)); 1341 if ((flags&PKT_AA)) LDNS_AA_SET(sldns_buffer_begin(qb)); 1342 if ((flags&PKT_TC)) LDNS_TC_SET(sldns_buffer_begin(qb)); 1343 if ((flags&PKT_RD)) LDNS_RD_SET(sldns_buffer_begin(qb)); 1344 if ((flags&PKT_CD)) LDNS_CD_SET(sldns_buffer_begin(qb)); 1345 if ((flags&PKT_RA)) LDNS_RA_SET(sldns_buffer_begin(qb)); 1346 if ((flags&PKT_AD)) LDNS_AD_SET(sldns_buffer_begin(qb)); 1347 1348 /* write the query */ 1349 l = sldns_buffer_remaining(qb); 1350 if(sldns_str2wire_dname_buf(rr_name, sldns_buffer_current(qb), &l) != 0) { 1351 sldns_buffer_free(qb); 1352 return 0; 1353 } 1354 sldns_buffer_skip(qb, l); 1355 if (rr_type == 0) { rr_type = LDNS_RR_TYPE_A; } 1356 if (rr_class == 0) { rr_class = LDNS_RR_CLASS_IN; } 1357 sldns_buffer_write_u16(qb, rr_type); 1358 sldns_buffer_write_u16(qb, rr_class); 1359 1360 /* write RR sections */ 1361 if(res && !pushRRList(qb, question, default_ttl, 1, LDNS_QDCOUNT_OFF)) 1362 res = 0; 1363 if(res && !pushRRList(qb, answer, default_ttl, 0, LDNS_ANCOUNT_OFF)) 1364 res = 0; 1365 if(res && !pushRRList(qb, authority, default_ttl, 0, LDNS_NSCOUNT_OFF)) 1366 res = 0; 1367 if(res && !pushRRList(qb, additional, default_ttl, 0, LDNS_ARCOUNT_OFF)) 1368 res = 0; 1369 1370 if (res) res = createResponse(qstate, qb); 1371 1372 if (qb) sldns_buffer_free(qb); 1373 return res; 1374 } 1375 %} 1376 1377 int set_return_msg(struct module_qstate* qstate, 1378 const char* rr_name, int rr_type, int rr_class , uint16_t flags, uint32_t default_ttl, 1379 PyObject* question, PyObject* answer, PyObject* authority, PyObject* additional); 1380 1381 %pythoncode %{ 1382 class DNSMessage: 1383 def __init__(self, rr_name, rr_type, rr_class = RR_CLASS_IN, query_flags = 0, default_ttl = 0): 1384 """Query flags is a combination of PKT_xx constants""" 1385 self.rr_name = rr_name 1386 self.rr_type = rr_type 1387 self.rr_class = rr_class 1388 self.default_ttl = default_ttl 1389 self.query_flags = query_flags 1390 self.question = [] 1391 self.answer = [] 1392 self.authority = [] 1393 self.additional = [] 1394 1395 def set_return_msg(self, qstate): 1396 """Returns 1 if OK""" 1397 status = _unboundmodule.set_return_msg(qstate, self.rr_name, self.rr_type, self.rr_class, 1398 self.query_flags, self.default_ttl, 1399 self.question, self.answer, self.authority, self.additional) 1400 1401 if (status) and (PKT_AA & self.query_flags): 1402 qstate.return_msg.rep.authoritative = 1 1403 1404 return status 1405 1406 %} 1407 /* ************************************************************************************ * 1408 ASN: Delegation pointer related functions 1409 * ************************************************************************************ */ 1410 1411 /* Functions which we will need to lookup delegations */ 1412 struct delegpt* dns_cache_find_delegation(struct module_env* env, 1413 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 1414 struct regional* region, struct dns_msg** msg, uint32_t timenow, 1415 int noexpiredabove, uint8_t* expiretop, size_t expiretoplen); 1416 int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, 1417 struct delegpt* dp, int supports_ipv4, int supports_ipv6, int use_nat64); 1418 struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints, 1419 uint8_t* qname, uint16_t qclass, struct delegpt* dp); 1420 1421 /* Custom function to perform logic similar to the one in daemon/cachedump.c */ 1422 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen); 1423 1424 %{ 1425 #define BIT_RD 0x100 1426 1427 struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen) 1428 { 1429 struct delegpt *dp; 1430 struct dns_msg *msg = NULL; 1431 struct regional* region = qstate->env->scratch; 1432 char b[260]; 1433 struct query_info qinfo; 1434 struct iter_hints_stub* stub; 1435 uint32_t timenow = *qstate->env->now; 1436 1437 regional_free_all(region); 1438 qinfo.qname = (uint8_t*)nm; 1439 qinfo.qname_len = nmlen; 1440 qinfo.qtype = LDNS_RR_TYPE_A; 1441 qinfo.qclass = LDNS_RR_CLASS_IN; 1442 1443 while(1) { 1444 dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow, 0, NULL, 0); 1445 if(!dp) 1446 return NULL; 1447 if(iter_dp_is_useless(&qinfo, BIT_RD, dp, 1448 qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6, 1449 qstate->env->cfg->do_nat64)) { 1450 if (dname_is_root((uint8_t*)nm)) 1451 return NULL; 1452 nm = (char*)dp->name; 1453 nmlen = dp->namelen; 1454 dname_remove_label((uint8_t**)&nm, &nmlen); 1455 dname_str((uint8_t*)nm, b); 1456 continue; 1457 } 1458 stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, qinfo.qclass, dp); 1459 if (stub) { 1460 return stub->dp; 1461 } else { 1462 return dp; 1463 } 1464 } 1465 return NULL; 1466 } 1467 %} 1468 1469 /* ************************************************************************************ * 1470 Functions 1471 * ************************************************************************************ */ 1472 /****************************** 1473 * Various debugging functions * 1474 ******************************/ 1475 1476 /* rename the variadic functions because python does the formatting already*/ 1477 %rename (unbound_log_info) log_info; 1478 %rename (unbound_log_err) log_err; 1479 %rename (unbound_log_warn) log_warn; 1480 %rename (unbound_verbose) verbose; 1481 /* provide functions that take one string as argument, so python can cook 1482 the string */ 1483 %rename (log_info) pymod_log_info; 1484 %rename (log_warn) pymod_log_warn; 1485 %rename (log_err) pymod_log_err; 1486 %rename (verbose) pymod_verbose; 1487 1488 void verbose(enum verbosity_value level, const char* format, ...); 1489 void log_info(const char* format, ...); 1490 void log_err(const char* format, ...); 1491 void log_warn(const char* format, ...); 1492 void log_hex(const char* msg, void* data, size_t length); 1493 void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep); 1494 void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf); 1495 void regional_log_stats(struct regional *r); 1496 1497 /* the one argument string log functions */ 1498 void pymod_log_info(const char* str); 1499 void pymod_log_err(const char* str); 1500 void pymod_log_warn(const char* str); 1501 void pymod_verbose(enum verbosity_value level, const char* str); 1502 %{ 1503 void pymod_log_info(const char* str) { log_info("%s", str); } 1504 void pymod_log_err(const char* str) { log_err("%s", str); } 1505 void pymod_log_warn(const char* str) { log_warn("%s", str); } 1506 void pymod_verbose(enum verbosity_value level, const char* str) { 1507 verbose(level, "%s", str); } 1508 %} 1509 1510 /*************************************************************************** 1511 * Free allocated memory from marked sources returning corresponding types * 1512 ***************************************************************************/ 1513 %typemap(newfree, noblock = 1) char * { 1514 free($1); 1515 } 1516 1517 /*************************************************** 1518 * Mark as source returning newly allocated memory * 1519 ***************************************************/ 1520 %newobject sldns_wire2str_type; 1521 %newobject sldns_wire2str_class; 1522 1523 /****************** 1524 * LDNS functions * 1525 ******************/ 1526 char *sldns_wire2str_type(const uint16_t atype); 1527 char *sldns_wire2str_class(const uint16_t aclass); 1528 1529 /********************************** 1530 * Functions from pythonmod_utils * 1531 **********************************/ 1532 int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral); 1533 void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo); 1534 1535 /******************************* 1536 * Module conversion functions * 1537 *******************************/ 1538 const char* strextstate(enum module_ext_state s); 1539 const char* strmodulevent(enum module_ev e); 1540 1541 /************************** 1542 * Edns related functions * 1543 **************************/ 1544 struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code); 1545 int edns_register_option(uint16_t opt_code, int bypass_cache_stage, 1546 int no_aggregation, struct module_env* env); 1547 1548 %pythoncode %{ 1549 def register_edns_option(env, code, bypass_cache_stage=False, 1550 no_aggregation=False): 1551 """Wrapper function to provide keyword attributes.""" 1552 return edns_register_option(code, bypass_cache_stage, 1553 no_aggregation, env) 1554 %} 1555 1556 /****************************** 1557 * Callback related functions * 1558 ******************************/ 1559 /* typemap to check if argument is callable */ 1560 %typemap(in) PyObject *py_cb { 1561 if (!PyCallable_Check($input)) { 1562 SWIG_exception_fail(SWIG_TypeError, "Need a callable object!"); 1563 return NULL; 1564 } 1565 $1 = $input; 1566 } 1567 /* typemap to get content/size from a bytearray */ 1568 %typemap(in) (size_t len, uint8_t* py_bytearray_data) { 1569 if (!PyByteArray_CheckExact($input)) { 1570 SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!"); 1571 return NULL; 1572 } 1573 $2 = (void*)PyByteArray_AsString($input); 1574 $1 = PyByteArray_Size($input); 1575 } 1576 1577 int edns_opt_list_remove(struct edns_option** list, uint16_t code); 1578 int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len, 1579 uint8_t* py_bytearray_data, struct regional* region); 1580 1581 %{ 1582 /* This function is called by unbound in order to call the python 1583 * callback function. */ 1584 int python_inplace_cb_reply_generic(struct query_info* qinfo, 1585 struct module_qstate* qstate, struct reply_info* rep, int rcode, 1586 struct edns_data* edns, struct edns_option** opt_list_out, 1587 struct comm_reply* repinfo, struct regional* region, 1588 struct timeval* start_time, int id, void* python_callback) 1589 { 1590 PyObject *func = NULL, *py_edns = NULL, *py_qstate = NULL; 1591 PyObject *py_opt_list_out = NULL, *py_qinfo = NULL; 1592 PyObject *py_rep = NULL, *py_repinfo = NULL, *py_region = NULL; 1593 PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL; 1594 int res = 0; 1595 double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6; 1596 1597 PyGILState_STATE gstate = PyGILState_Ensure(); 1598 1599 func = (PyObject *) python_callback; 1600 py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0); 1601 py_qstate = SWIG_NewPointerObj((void*) qstate, 1602 SWIGTYPE_p_module_qstate, 0); 1603 py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out, 1604 SWIGTYPE_p_p_edns_option, 0); 1605 py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); 1606 py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0); 1607 py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0); 1608 py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); 1609 if(!(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out 1610 && py_region && py_repinfo)) { 1611 log_err("pythonmod: swig pointer failure in python_inplace_cb_reply_generic"); 1612 goto out; 1613 } 1614 py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep, 1615 rcode, py_edns, py_opt_list_out, py_region); 1616 py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time", 1617 py_start_time); 1618 if(!(py_args && py_kwargs)) { 1619 log_err("pythonmod: BuildValue failure in python_inplace_cb_reply_generic"); 1620 goto out; 1621 } 1622 result = PyObject_Call(func, py_args, py_kwargs); 1623 if (result) { 1624 res = PyInt_AsLong(result); 1625 } 1626 out: 1627 Py_XDECREF(py_edns); 1628 Py_XDECREF(py_qstate); 1629 Py_XDECREF(py_opt_list_out); 1630 Py_XDECREF(py_qinfo); 1631 Py_XDECREF(py_rep); 1632 Py_XDECREF(py_repinfo); 1633 Py_XDECREF(py_region); 1634 Py_XDECREF(py_args); 1635 Py_XDECREF(py_kwargs); 1636 Py_XDECREF(result); 1637 PyGILState_Release(gstate); 1638 return res; 1639 } 1640 1641 /* register a callback */ 1642 static int python_inplace_cb_register(enum inplace_cb_list_type type, 1643 PyObject* py_cb, struct module_env* env, int id) 1644 { 1645 int ret = inplace_cb_register(python_inplace_cb_reply_generic, 1646 type, (void*) py_cb, env, id); 1647 if (ret) Py_INCREF(py_cb); 1648 return ret; 1649 } 1650 1651 /* Swig implementations for Python */ 1652 static int register_inplace_cb_reply(PyObject* py_cb, 1653 struct module_env* env, int id) 1654 { 1655 return python_inplace_cb_register(inplace_cb_reply, py_cb, env, id); 1656 } 1657 static int register_inplace_cb_reply_cache(PyObject* py_cb, 1658 struct module_env* env, int id) 1659 { 1660 return python_inplace_cb_register(inplace_cb_reply_cache, py_cb, env, id); 1661 } 1662 static int register_inplace_cb_reply_local(PyObject* py_cb, 1663 struct module_env* env, int id) 1664 { 1665 return python_inplace_cb_register(inplace_cb_reply_local, py_cb, env, id); 1666 } 1667 static int register_inplace_cb_reply_servfail(PyObject* py_cb, 1668 struct module_env* env, int id) 1669 { 1670 return python_inplace_cb_register(inplace_cb_reply_servfail, 1671 py_cb, env, id); 1672 } 1673 1674 int python_inplace_cb_query_generic( 1675 struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate, 1676 struct sockaddr_storage* addr, socklen_t addrlen, 1677 uint8_t* zone, size_t zonelen, struct regional* region, int id, 1678 void* python_callback) 1679 { 1680 int res = 0; 1681 PyObject *func = python_callback; 1682 PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL; 1683 PyObject *py_qinfo = NULL; 1684 PyObject *py_qstate = NULL; 1685 PyObject *py_addr = NULL; 1686 PyObject *py_zone = NULL; 1687 PyObject *py_region = NULL; 1688 1689 PyGILState_STATE gstate = PyGILState_Ensure(); 1690 1691 py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); 1692 py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); 1693 py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0); 1694 py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen); 1695 py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); 1696 if(!(py_qinfo && py_qstate && py_addr && py_zone && py_region)) { 1697 log_err("pythonmod: swig pointer failure in python_inplace_cb_query_generic"); 1698 goto out; 1699 } 1700 py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region); 1701 py_kwargs = Py_BuildValue("{}"); 1702 if(!(py_args && py_kwargs)) { 1703 log_err("pythonmod: BuildValue failure in python_inplace_cb_query_generic"); 1704 goto out; 1705 } 1706 result = PyObject_Call(func, py_args, py_kwargs); 1707 if (result) { 1708 res = PyInt_AsLong(result); 1709 } 1710 out: 1711 Py_XDECREF(py_qinfo); 1712 Py_XDECREF(py_qstate); 1713 Py_XDECREF(py_addr); 1714 Py_XDECREF(py_zone); 1715 Py_XDECREF(py_region); 1716 1717 Py_XDECREF(py_args); 1718 Py_XDECREF(py_kwargs); 1719 Py_XDECREF(result); 1720 1721 PyGILState_Release(gstate); 1722 1723 return res; 1724 } 1725 1726 static int register_inplace_cb_query(PyObject* py_cb, 1727 struct module_env* env, int id) 1728 { 1729 int ret = inplace_cb_register(python_inplace_cb_query_generic, 1730 inplace_cb_query, (void*) py_cb, env, id); 1731 if (ret) Py_INCREF(py_cb); 1732 return ret; 1733 } 1734 1735 int python_inplace_cb_query_response(struct module_qstate* qstate, 1736 struct dns_msg* response, int id, void* python_callback) 1737 { 1738 int res = 0; 1739 PyObject *func = python_callback; 1740 PyObject *py_qstate = NULL; 1741 PyObject *py_response = NULL; 1742 PyObject *py_args = NULL; 1743 PyObject *py_kwargs = NULL; 1744 PyObject *result = NULL; 1745 1746 PyGILState_STATE gstate = PyGILState_Ensure(); 1747 1748 py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); 1749 py_response = SWIG_NewPointerObj((void*) response, SWIGTYPE_p_dns_msg, 0); 1750 if(!(py_qstate && py_response)) { 1751 log_err("pythonmod: swig pointer failure in python_inplace_cb_query_response"); 1752 goto out; 1753 } 1754 py_args = Py_BuildValue("(OO)", py_qstate, py_response); 1755 py_kwargs = Py_BuildValue("{}"); 1756 if(!(py_args && py_kwargs)) { 1757 log_err("pythonmod: BuildValue failure in python_inplace_cb_query_response"); 1758 goto out; 1759 } 1760 result = PyObject_Call(func, py_args, py_kwargs); 1761 if (result) { 1762 res = PyInt_AsLong(result); 1763 } 1764 out: 1765 Py_XDECREF(py_qstate); 1766 Py_XDECREF(py_response); 1767 1768 Py_XDECREF(py_args); 1769 Py_XDECREF(py_kwargs); 1770 Py_XDECREF(result); 1771 1772 PyGILState_Release(gstate); 1773 1774 return res; 1775 } 1776 1777 static int register_inplace_cb_query_response(PyObject* py_cb, 1778 struct module_env* env, int id) 1779 { 1780 int ret = inplace_cb_register(python_inplace_cb_query_response, 1781 inplace_cb_query_response, (void*) py_cb, env, id); 1782 if (ret) Py_INCREF(py_cb); 1783 return ret; 1784 } 1785 1786 int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate, 1787 int id, void* python_callback) 1788 { 1789 int res = 0; 1790 PyObject *func = python_callback; 1791 PyObject *py_qstate = NULL; 1792 PyObject *py_args = NULL; 1793 PyObject *py_kwargs = NULL; 1794 PyObject *result = NULL; 1795 1796 PyGILState_STATE gstate = PyGILState_Ensure(); 1797 1798 py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0); 1799 if(!py_qstate) { 1800 log_err("pythonmod: swig pointer failure in python_inplace_cb_edns_back_parsed_call"); 1801 goto out; 1802 } 1803 py_args = Py_BuildValue("(O)", py_qstate); 1804 py_kwargs = Py_BuildValue("{}"); 1805 if(!(py_args && py_kwargs)) { 1806 log_err("pythonmod: BuildValue failure in python_inplace_cb_edns_back_parsed_call"); 1807 goto out; 1808 } 1809 result = PyObject_Call(func, py_args, py_kwargs); 1810 if (result) { 1811 res = PyInt_AsLong(result); 1812 } 1813 out: 1814 Py_XDECREF(py_qstate); 1815 1816 Py_XDECREF(py_args); 1817 Py_XDECREF(py_kwargs); 1818 Py_XDECREF(result); 1819 1820 PyGILState_Release(gstate); 1821 1822 return res; 1823 } 1824 1825 static int register_inplace_cb_edns_back_parsed_call(PyObject* py_cb, 1826 struct module_env* env, int id) 1827 { 1828 int ret = inplace_cb_register(python_inplace_cb_edns_back_parsed_call, 1829 inplace_cb_edns_back_parsed, (void*) py_cb, env, id); 1830 if (ret) Py_INCREF(py_cb); 1831 return ret; 1832 } 1833 %} 1834 /* C declarations */ 1835 int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg, 1836 struct module_env* env, int id); 1837 1838 /* Swig declarations */ 1839 static int register_inplace_cb_reply(PyObject* py_cb, 1840 struct module_env* env, int id); 1841 static int register_inplace_cb_reply_cache(PyObject* py_cb, 1842 struct module_env* env, int id); 1843 static int register_inplace_cb_reply_local(PyObject* py_cb, 1844 struct module_env* env, int id); 1845 static int register_inplace_cb_reply_servfail(PyObject* py_cb, 1846 struct module_env* env, int id); 1847 static int register_inplace_cb_query(PyObject *py_cb, 1848 struct module_env* env, int id); 1849 static int register_inplace_cb_query_response(PyObject *py_cb, 1850 struct module_env* env, int id); 1851 static int register_inplace_cb_edns_back_parsed_call(PyObject *py_cb, 1852 struct module_env* env, int id); 1853