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