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