1 /* ========================================================================== 2 * dns.h - Recursive, Reentrant DNS Resolver. 3 * -------------------------------------------------------------------------- 4 * Copyright (c) 2009, 2010, 2012, 2013, 2014, 2015 William Ahern 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to permit 11 * persons to whom the Software is furnished to do so, subject to the 12 * following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 20 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 23 * USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * ========================================================================== 25 */ 26 #ifndef DNS_H 27 #define DNS_H 28 29 #include <stddef.h> /* size_t offsetof() */ 30 #include <stdio.h> /* FILE */ 31 32 #include <string.h> /* strlen(3) */ 33 34 #include <time.h> /* time_t */ 35 36 #if _WIN32 37 #include <winsock2.h> 38 #include <ws2tcpip.h> 39 #else 40 #include <sys/param.h> /* BYTE_ORDER BIG_ENDIAN _BIG_ENDIAN */ 41 #include <sys/types.h> /* socklen_t */ 42 #include <sys/socket.h> /* struct socket */ 43 44 #include <poll.h> /* POLLIN POLLOUT */ 45 46 #include <netinet/in.h> /* struct in_addr struct in6_addr */ 47 48 #include <netdb.h> /* struct addrinfo */ 49 #endif 50 51 52 /* 53 * V E R S I O N 54 * 55 * Vendor: Entity for which versions numbers are relevant. (If forking 56 * change DNS_VENDOR to avoid confusion.) 57 * 58 * Three versions: 59 * 60 * REL Official "release"--bug fixes, new features, etc. 61 * ABI Changes to existing object sizes or parameter types. 62 * API Changes that might effect application source. 63 * 64 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 65 66 #define DNS_VENDOR "william@25thandClement.com" 67 68 #define DNS_V_REL 0x20150630 69 #define DNS_V_ABI 0x20150612 70 #define DNS_V_API 0x20150612 71 72 73 const char *dns_vendor(void); 74 75 int dns_v_rel(void); 76 int dns_v_abi(void); 77 int dns_v_api(void); 78 79 80 /* 81 * E R R O R S 82 * 83 * Errors and exceptions are always returned through an int. This should 84 * hopefully make integration easier in the majority of circumstances, and 85 * also cut down on useless compiler warnings. 86 * 87 * System and library errors are returned together. POSIX guarantees that 88 * all system errors are positive integers. Library errors are always 89 * negative integers in the range DNS_EBASE to DNS_ELAST, with the high bits 90 * set to the three magic ASCII characters "dns". 91 * 92 * dns_strerror() returns static English string descriptions of all known 93 * errors, and punts the remainder to strerror(3). 94 * 95 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 96 97 #define DNS_EBASE -(('d' << 24) | ('n' << 16) | ('s' << 8) | 64) 98 99 #define dns_error_t int /* for documentation only */ 100 101 enum dns_errno { 102 DNS_ENOBUFS = DNS_EBASE, 103 DNS_EILLEGAL, 104 DNS_EORDER, 105 DNS_ESECTION, 106 DNS_EUNKNOWN, 107 DNS_EADDRESS, 108 DNS_ENOQUERY, 109 DNS_ENOANSWER, 110 DNS_EFETCHED, 111 DNS_ESERVICE, /* EAI_SERVICE */ 112 DNS_ENONAME, /* EAI_NONAME */ 113 DNS_EFAIL, /* EAI_FAIL */ 114 DNS_ELAST, 115 }; /* dns_errno */ 116 117 const char *dns_strerror(dns_error_t); 118 119 extern int dns_debug; 120 121 122 /* 123 * C O M P I L E R A N N O T A T I O N S 124 * 125 * GCC with -Wextra, and clang by default, complain about overrides in 126 * initializer lists. Overriding previous member initializers is well 127 * defined behavior in C. dns.c relies on this behavior to define default, 128 * overrideable member values when instantiating configuration objects. 129 * 130 * dns_quietinit() guards a compound literal expression with pragmas to 131 * silence these shrill warnings. This alleviates the burden of requiring 132 * third-party projects to adjust their compiler flags. 133 * 134 * NOTE: If you take the address of the compound literal, take the address 135 * of the transformed expression, otherwise the compound literal lifetime is 136 * tied to the scope of the GCC statement expression. 137 * 138 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 139 140 #if defined __clang__ 141 #define DNS_PRAGMA_PUSH _Pragma("clang diagnostic push") 142 #define DNS_PRAGMA_QUIET _Pragma("clang diagnostic ignored \"-Winitializer-overrides\"") 143 #define DNS_PRAGMA_POP _Pragma("clang diagnostic pop") 144 145 #define dns_quietinit(...) \ 146 DNS_PRAGMA_PUSH DNS_PRAGMA_QUIET __VA_ARGS__ DNS_PRAGMA_POP 147 #elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4 148 #define DNS_PRAGMA_PUSH _Pragma("GCC diagnostic push") 149 #define DNS_PRAGMA_QUIET _Pragma("GCC diagnostic ignored \"-Woverride-init\"") 150 #define DNS_PRAGMA_POP _Pragma("GCC diagnostic pop") 151 152 /* GCC parses the _Pragma operator less elegantly than clang. */ 153 #define dns_quietinit(...) \ 154 __extension__ ({ DNS_PRAGMA_PUSH DNS_PRAGMA_QUIET __VA_ARGS__; DNS_PRAGMA_POP }) 155 #else 156 #define DNS_PRAGMA_PUSH 157 #define DNS_PRAGMA_QUIET 158 #define DNS_PRAGMA_POP 159 #define dns_quietinit(...) __VA_ARGS__ 160 #endif 161 162 #if defined __GNUC__ 163 #define DNS_PRAGMA_EXTENSION __extension__ 164 #else 165 #define DNS_PRAGMA_EXTENSION 166 #endif 167 168 169 /* 170 * E V E N T S I N T E R F A C E S 171 * 172 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 173 174 #if defined(POLLIN) 175 #define DNS_POLLIN POLLIN 176 #else 177 #define DNS_POLLIN 1 178 #endif 179 180 #if defined(POLLOUT) 181 #define DNS_POLLOUT POLLOUT 182 #else 183 #define DNS_POLLOUT 2 184 #endif 185 186 187 /* 188 * See Application Interface below for configuring libevent bitmasks instead 189 * of poll(2) bitmasks. 190 */ 191 #define DNS_EVREAD 2 192 #define DNS_EVWRITE 4 193 194 195 #define DNS_POLL2EV(set) \ 196 (((set) & DNS_POLLIN)? DNS_EVREAD : 0) | (((set) & DNS_POLLOUT)? DNS_EVWRITE : 0) 197 198 #define DNS_EV2POLL(set) \ 199 (((set) & DNS_EVREAD)? DNS_POLLIN : 0) | (((set) & DNS_EVWRITE)? DNS_POLLOUT : 0) 200 201 202 /* 203 * E N U M E R A T I O N I N T E R F A C E S 204 * 205 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 206 207 enum dns_section { 208 DNS_S_QD = 0x01, 209 #define DNS_S_QUESTION DNS_S_QD 210 211 DNS_S_AN = 0x02, 212 #define DNS_S_ANSWER DNS_S_AN 213 214 DNS_S_NS = 0x04, 215 #define DNS_S_AUTHORITY DNS_S_NS 216 217 DNS_S_AR = 0x08, 218 #define DNS_S_ADDITIONAL DNS_S_AR 219 220 DNS_S_ALL = 0x0f 221 }; /* enum dns_section */ 222 223 224 enum dns_class { 225 DNS_C_IN = 1, 226 227 DNS_C_ANY = 255 228 }; /* enum dns_class */ 229 230 231 enum dns_type { 232 DNS_T_A = 1, 233 DNS_T_NS = 2, 234 DNS_T_CNAME = 5, 235 DNS_T_SOA = 6, 236 DNS_T_PTR = 12, 237 DNS_T_MX = 15, 238 DNS_T_TXT = 16, 239 DNS_T_AAAA = 28, 240 DNS_T_SRV = 33, 241 DNS_T_OPT = 41, 242 DNS_T_SSHFP = 44, 243 DNS_T_SPF = 99, 244 245 DNS_T_ALL = 255 246 }; /* enum dns_type */ 247 248 249 enum dns_opcode { 250 DNS_OP_QUERY = 0, 251 DNS_OP_IQUERY = 1, 252 DNS_OP_STATUS = 2, 253 DNS_OP_NOTIFY = 4, 254 DNS_OP_UPDATE = 5, 255 }; /* dns_opcode */ 256 257 258 enum dns_rcode { 259 DNS_RC_NOERROR = 0, 260 DNS_RC_FORMERR = 1, 261 DNS_RC_SERVFAIL = 2, 262 DNS_RC_NXDOMAIN = 3, 263 DNS_RC_NOTIMP = 4, 264 DNS_RC_REFUSED = 5, 265 DNS_RC_YXDOMAIN = 6, 266 DNS_RC_YXRRSET = 7, 267 DNS_RC_NXRRSET = 8, 268 DNS_RC_NOTAUTH = 9, 269 DNS_RC_NOTZONE = 10, 270 }; /* dns_rcode */ 271 272 273 /* 274 * NOTE: These string functions need a small buffer in case the literal 275 * integer value needs to be printed and returned. UNLESS this buffer is 276 * SPECIFIED, the returned string has ONLY BLOCK SCOPE. 277 */ 278 #define DNS_STRMAXLEN 47 /* "QUESTION|ANSWER|AUTHORITY|ADDITIONAL" */ 279 280 const char *dns_strsection(enum dns_section, void *, size_t); 281 #define dns_strsection3(a, b, c) \ 282 dns_strsection((a), (b), (c)) 283 #define dns_strsection1(a) dns_strsection((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) 284 #define dns_strsection(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strsection, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) 285 286 enum dns_section dns_isection(const char *); 287 288 const char *dns_strclass(enum dns_class, void *, size_t); 289 #define dns_strclass3(a, b, c) dns_strclass((a), (b), (c)) 290 #define dns_strclass1(a) dns_strclass((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) 291 #define dns_strclass(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strclass, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) 292 293 enum dns_class dns_iclass(const char *); 294 295 const char *dns_strtype(enum dns_type, void *, size_t); 296 #define dns_strtype3(a, b, c) dns_strtype((a), (b), (c)) 297 #define dns_strtype1(a) dns_strtype((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) 298 #define dns_strtype(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strtype, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) 299 300 enum dns_type dns_itype(const char *); 301 302 const char *dns_stropcode(enum dns_opcode); 303 304 enum dns_opcode dns_iopcode(const char *); 305 306 const char *dns_strrcode(enum dns_rcode); 307 308 enum dns_rcode dns_ircode(const char *); 309 310 311 /* 312 * A T O M I C I N T E R F A C E S 313 * 314 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 315 316 typedef unsigned long dns_atomic_t; 317 318 typedef unsigned long dns_refcount_t; /* must be same value type as dns_atomic_t */ 319 320 321 /* 322 * C R Y P T O I N T E R F A C E S 323 * 324 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 325 326 extern unsigned (*dns_random)(void); 327 328 329 /* 330 * P A C K E T I N T E R F A C E 331 * 332 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 333 334 struct dns_header { 335 unsigned qid:16; 336 337 #if (defined BYTE_ORDER && BYTE_ORDER == BIG_ENDIAN) || (defined __sun && defined _BIG_ENDIAN) 338 unsigned qr:1; 339 unsigned opcode:4; 340 unsigned aa:1; 341 unsigned tc:1; 342 unsigned rd:1; 343 344 unsigned ra:1; 345 unsigned unused:3; 346 unsigned rcode:4; 347 #else 348 unsigned rd:1; 349 unsigned tc:1; 350 unsigned aa:1; 351 unsigned opcode:4; 352 unsigned qr:1; 353 354 unsigned rcode:4; 355 unsigned unused:3; 356 unsigned ra:1; 357 #endif 358 359 unsigned qdcount:16; 360 unsigned ancount:16; 361 unsigned nscount:16; 362 unsigned arcount:16; 363 }; /* struct dns_header */ 364 365 #define dns_header(p) (&(p)->header) 366 367 368 #ifndef DNS_P_QBUFSIZ 369 #define DNS_P_QBUFSIZ dns_p_calcsize(256 + 4) 370 #endif 371 372 #ifndef DNS_P_DICTSIZE 373 #define DNS_P_DICTSIZE 16 374 #endif 375 376 struct dns_packet { 377 unsigned short dict[DNS_P_DICTSIZE]; 378 379 struct dns_s_memo { 380 unsigned short base, end; 381 } qd, an, ns, ar; 382 383 struct { struct dns_packet *cqe_next, *cqe_prev; } cqe; 384 385 size_t size, end; 386 387 int:16; /* tcp padding */ 388 389 DNS_PRAGMA_EXTENSION union { 390 struct dns_header header; 391 unsigned char data[1]; 392 }; 393 }; /* struct dns_packet */ 394 395 #define dns_p_calcsize(n) (offsetof(struct dns_packet, data) + DNS_PP_MAX(12, (n))) 396 397 #define dns_p_sizeof(P) dns_p_calcsize((P)->end) 398 399 /** takes size of maximum desired payload */ 400 #define dns_p_new(n) (dns_p_init((struct dns_packet *)&(union { unsigned char b[dns_p_calcsize((n))]; struct dns_packet p; }){ { 0 } }, dns_p_calcsize((n)))) 401 402 /** takes size of entire packet structure as allocated */ 403 struct dns_packet *dns_p_init(struct dns_packet *, size_t); 404 405 /** takes size of maximum desired payload */ 406 struct dns_packet *dns_p_make(size_t, int *); 407 408 int dns_p_grow(struct dns_packet **); 409 410 struct dns_packet *dns_p_copy(struct dns_packet *, const struct dns_packet *); 411 412 #define dns_p_opcode(P) (dns_header(P)->opcode) 413 414 #define dns_p_rcode(P) (dns_header(P)->rcode) 415 416 unsigned dns_p_count(struct dns_packet *, enum dns_section); 417 418 int dns_p_push(struct dns_packet *, enum dns_section, const void *, size_t, enum dns_type, enum dns_class, unsigned, const void *); 419 420 void dns_p_dictadd(struct dns_packet *, unsigned short); 421 422 struct dns_packet *dns_p_merge(struct dns_packet *, enum dns_section, struct dns_packet *, enum dns_section, int *); 423 424 void dns_p_dump(struct dns_packet *, FILE *); 425 426 int dns_p_study(struct dns_packet *); 427 428 429 /* 430 * D O M A I N N A M E I N T E R F A C E S 431 * 432 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 433 434 #define DNS_D_MAXLABEL 63 /* + 1 '\0' */ 435 #define DNS_D_MAXNAME 255 /* + 1 '\0' */ 436 437 #define DNS_D_ANCHOR 1 /* anchor domain w/ root "." */ 438 #define DNS_D_CLEAVE 2 /* cleave sub-domain */ 439 #define DNS_D_TRIM 4 /* remove superfluous dots */ 440 441 #define dns_d_new3(a, b, f) dns_d_init(&(char[DNS_D_MAXNAME + 1]){ 0 }, DNS_D_MAXNAME + 1, (a), (b), (f)) 442 #define dns_d_new2(a, f) dns_d_new3((a), strlen((a)), (f)) 443 #define dns_d_new1(a) dns_d_new3((a), strlen((a)), DNS_D_ANCHOR) 444 #define dns_d_new(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_d_new, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) 445 446 char *dns_d_init(void *, size_t, const void *, size_t, int); 447 448 size_t dns_d_anchor(void *, size_t, const void *, size_t); 449 450 size_t dns_d_cleave(void *, size_t, const void *, size_t); 451 452 size_t dns_d_comp(void *, size_t, const void *, size_t, struct dns_packet *, int *); 453 454 size_t dns_d_expand(void *, size_t, unsigned short, struct dns_packet *, int *); 455 456 unsigned short dns_d_skip(unsigned short, struct dns_packet *); 457 458 int dns_d_push(struct dns_packet *, const void *, size_t); 459 460 size_t dns_d_cname(void *, size_t, const void *, size_t, struct dns_packet *, int *error); 461 462 463 /* 464 * R E S O U R C E R E C O R D I N T E R F A C E S 465 * 466 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 467 468 struct dns_rr { 469 enum dns_section section; 470 471 struct { 472 unsigned short p; 473 unsigned short len; 474 } dn; 475 476 enum dns_type type; 477 enum dns_class class; 478 unsigned ttl; 479 480 struct { 481 unsigned short p; 482 unsigned short len; 483 } rd; 484 }; /* struct dns_rr */ 485 486 487 int dns_rr_copy(struct dns_packet *, struct dns_rr *, struct dns_packet *); 488 489 int dns_rr_parse(struct dns_rr *, unsigned short, struct dns_packet *); 490 491 unsigned short dns_rr_skip(unsigned short, struct dns_packet *); 492 493 int dns_rr_cmp(struct dns_rr *, struct dns_packet *, struct dns_rr *, struct dns_packet *); 494 495 size_t dns_rr_print(void *, size_t, struct dns_rr *, struct dns_packet *, int *); 496 497 498 #define dns_rr_i_new(P, ...) \ 499 dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P)) 500 501 struct dns_rr_i { 502 enum dns_section section; 503 const void *name; 504 enum dns_type type; 505 enum dns_class class; 506 const void *data; 507 508 int follow; 509 510 int (*sort)(); 511 unsigned args[2]; 512 513 struct { 514 unsigned short next; 515 unsigned short count; 516 517 unsigned exec; 518 unsigned regs[2]; 519 } state, saved; 520 }; /* struct dns_rr_i */ 521 522 int dns_rr_i_packet(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); 523 524 int dns_rr_i_order(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); 525 526 int dns_rr_i_shuffle(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); 527 528 struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *, struct dns_packet *); 529 530 #define dns_rr_i_save(i) ((i)->saved = (i)->state) 531 #define dns_rr_i_rewind(i) ((i)->state = (i)->saved) 532 #define dns_rr_i_count(i) ((i)->state.count) 533 534 unsigned dns_rr_grep(struct dns_rr *, unsigned, struct dns_rr_i *, struct dns_packet *, int *); 535 536 #define dns_rr_foreach_(rr, P, ...) \ 537 for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); ) 538 539 #define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__) 540 541 542 /* 543 * A R E S O U R C E R E C O R D 544 */ 545 546 struct dns_a { 547 struct in_addr addr; 548 }; /* struct dns_a */ 549 550 int dns_a_parse(struct dns_a *, struct dns_rr *, struct dns_packet *); 551 552 int dns_a_push(struct dns_packet *, struct dns_a *); 553 554 int dns_a_cmp(const struct dns_a *, const struct dns_a *); 555 556 size_t dns_a_print(void *, size_t, struct dns_a *); 557 558 559 /* 560 * AAAA R E S O U R C E R E C O R D 561 */ 562 563 struct dns_aaaa { 564 struct in6_addr addr; 565 }; /* struct dns_aaaa */ 566 567 int dns_aaaa_parse(struct dns_aaaa *, struct dns_rr *, struct dns_packet *); 568 569 int dns_aaaa_push(struct dns_packet *, struct dns_aaaa *); 570 571 int dns_aaaa_cmp(const struct dns_aaaa *, const struct dns_aaaa *); 572 573 size_t dns_aaaa_print(void *, size_t, struct dns_aaaa *); 574 575 576 /* 577 * MX R E S O U R C E R E C O R D 578 */ 579 580 struct dns_mx { 581 unsigned short preference; 582 char host[DNS_D_MAXNAME + 1]; 583 }; /* struct dns_mx */ 584 585 int dns_mx_parse(struct dns_mx *, struct dns_rr *, struct dns_packet *); 586 587 int dns_mx_push(struct dns_packet *, struct dns_mx *); 588 589 int dns_mx_cmp(const struct dns_mx *, const struct dns_mx *); 590 591 size_t dns_mx_print(void *, size_t, struct dns_mx *); 592 593 size_t dns_mx_cname(void *, size_t, struct dns_mx *); 594 595 596 /* 597 * NS R E S O U R C E R E C O R D 598 */ 599 600 struct dns_ns { 601 char host[DNS_D_MAXNAME + 1]; 602 }; /* struct dns_ns */ 603 604 int dns_ns_parse(struct dns_ns *, struct dns_rr *, struct dns_packet *); 605 606 int dns_ns_push(struct dns_packet *, struct dns_ns *); 607 608 int dns_ns_cmp(const struct dns_ns *, const struct dns_ns *); 609 610 size_t dns_ns_print(void *, size_t, struct dns_ns *); 611 612 size_t dns_ns_cname(void *, size_t, struct dns_ns *); 613 614 615 /* 616 * CNAME R E S O U R C E R E C O R D 617 */ 618 619 struct dns_cname { 620 char host[DNS_D_MAXNAME + 1]; 621 }; /* struct dns_cname */ 622 623 int dns_cname_parse(struct dns_cname *, struct dns_rr *, struct dns_packet *); 624 625 int dns_cname_push(struct dns_packet *, struct dns_cname *); 626 627 int dns_cname_cmp(const struct dns_cname *, const struct dns_cname *); 628 629 size_t dns_cname_print(void *, size_t, struct dns_cname *); 630 631 size_t dns_cname_cname(void *, size_t, struct dns_cname *); 632 633 634 /* 635 * SOA R E S O U R C E R E C O R D 636 */ 637 638 struct dns_soa { 639 char mname[DNS_D_MAXNAME + 1]; 640 char rname[DNS_D_MAXNAME + 1]; 641 unsigned serial, refresh, retry, expire, minimum; 642 }; /* struct dns_soa */ 643 644 int dns_soa_parse(struct dns_soa *, struct dns_rr *, struct dns_packet *); 645 646 int dns_soa_push(struct dns_packet *, struct dns_soa *); 647 648 int dns_soa_cmp(const struct dns_soa *, const struct dns_soa *); 649 650 size_t dns_soa_print(void *, size_t, struct dns_soa *); 651 652 653 /* 654 * PTR R E S O U R C E R E C O R D 655 */ 656 657 struct dns_ptr { 658 char host[DNS_D_MAXNAME + 1]; 659 }; /* struct dns_ptr */ 660 661 int dns_ptr_parse(struct dns_ptr *, struct dns_rr *, struct dns_packet *); 662 663 int dns_ptr_push(struct dns_packet *, struct dns_ptr *); 664 665 int dns_ptr_cmp(const struct dns_ptr *, const struct dns_ptr *); 666 667 size_t dns_ptr_print(void *, size_t, struct dns_ptr *); 668 669 size_t dns_ptr_cname(void *, size_t, struct dns_ptr *); 670 671 672 /* 673 * SRV R E S O U R C E R E C O R D 674 */ 675 676 struct dns_srv { 677 unsigned short priority; 678 unsigned short weight; 679 unsigned short port; 680 char target[DNS_D_MAXNAME + 1]; 681 }; /* struct dns_srv */ 682 683 int dns_srv_parse(struct dns_srv *, struct dns_rr *, struct dns_packet *); 684 685 int dns_srv_push(struct dns_packet *, struct dns_srv *); 686 687 int dns_srv_cmp(const struct dns_srv *, const struct dns_srv *); 688 689 size_t dns_srv_print(void *, size_t, struct dns_srv *); 690 691 size_t dns_srv_cname(void *, size_t, struct dns_srv *); 692 693 694 /* 695 * OPT R E S O U R C E R E C O R D 696 */ 697 698 #define DNS_OPT_MINDATA 512 699 700 #define DNS_OPT_BADVERS 16 701 702 struct dns_opt { 703 size_t size, len; 704 705 unsigned char rcode, version; 706 unsigned short maxsize; 707 708 unsigned char data[DNS_OPT_MINDATA]; 709 }; /* struct dns_opt */ 710 711 unsigned int dns_opt_ttl(const struct dns_opt *); 712 713 unsigned short dns_opt_class(const struct dns_opt *); 714 715 struct dns_opt *dns_opt_init(struct dns_opt *, size_t); 716 717 int dns_opt_parse(struct dns_opt *, struct dns_rr *, struct dns_packet *); 718 719 int dns_opt_push(struct dns_packet *, struct dns_opt *); 720 721 int dns_opt_cmp(const struct dns_opt *, const struct dns_opt *); 722 723 size_t dns_opt_print(void *, size_t, struct dns_opt *); 724 725 726 /* 727 * SSHFP R E S O U R C E R E C O R D 728 */ 729 730 struct dns_sshfp { 731 enum dns_sshfp_key { 732 DNS_SSHFP_RSA = 1, 733 DNS_SSHFP_DSA = 2, 734 } algo; 735 736 enum dns_sshfp_digest { 737 DNS_SSHFP_SHA1 = 1, 738 } type; 739 740 union { 741 unsigned char sha1[20]; 742 } digest; 743 }; /* struct dns_sshfp */ 744 745 int dns_sshfp_parse(struct dns_sshfp *, struct dns_rr *, struct dns_packet *); 746 747 int dns_sshfp_push(struct dns_packet *, struct dns_sshfp *); 748 749 int dns_sshfp_cmp(const struct dns_sshfp *, const struct dns_sshfp *); 750 751 size_t dns_sshfp_print(void *, size_t, struct dns_sshfp *); 752 753 754 /* 755 * TXT R E S O U R C E R E C O R D 756 */ 757 758 #ifndef DNS_TXT_MINDATA 759 #define DNS_TXT_MINDATA 1024 760 #endif 761 762 struct dns_txt { 763 size_t size, len; 764 unsigned char data[DNS_TXT_MINDATA]; 765 }; /* struct dns_txt */ 766 767 struct dns_txt *dns_txt_init(struct dns_txt *, size_t); 768 769 int dns_txt_parse(struct dns_txt *, struct dns_rr *, struct dns_packet *); 770 771 int dns_txt_push(struct dns_packet *, struct dns_txt *); 772 773 int dns_txt_cmp(const struct dns_txt *, const struct dns_txt *); 774 775 size_t dns_txt_print(void *, size_t, struct dns_txt *); 776 777 778 /* 779 * ANY R E S O U R C E R E C O R D 780 */ 781 782 union dns_any { 783 struct dns_a a; 784 struct dns_aaaa aaaa; 785 struct dns_mx mx; 786 struct dns_ns ns; 787 struct dns_cname cname; 788 struct dns_soa soa; 789 struct dns_ptr ptr; 790 struct dns_srv srv; 791 struct dns_opt opt; 792 struct dns_sshfp sshfp; 793 struct dns_txt txt, spf, rdata; 794 }; /* union dns_any */ 795 796 #define DNS_ANY_INIT(any) { .rdata = { .size = sizeof *(any) } } 797 798 union dns_any *dns_any_init(union dns_any *, size_t); 799 800 int dns_any_parse(union dns_any *, struct dns_rr *, struct dns_packet *); 801 802 int dns_any_push(struct dns_packet *, union dns_any *, enum dns_type); 803 804 int dns_any_cmp(const union dns_any *, enum dns_type, const union dns_any *, enum dns_type); 805 806 size_t dns_any_print(void *, size_t, union dns_any *, enum dns_type); 807 808 size_t dns_any_cname(void *, size_t, union dns_any *, enum dns_type); 809 810 811 /* 812 * H O S T S I N T E R F A C E 813 * 814 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 815 816 struct dns_hosts; 817 818 struct dns_hosts *dns_hosts_open(int *); 819 820 void dns_hosts_close(struct dns_hosts *); 821 822 dns_refcount_t dns_hosts_acquire(struct dns_hosts *); 823 824 dns_refcount_t dns_hosts_release(struct dns_hosts *); 825 826 struct dns_hosts *dns_hosts_mortal(struct dns_hosts *); 827 828 struct dns_hosts *dns_hosts_local(int *); 829 830 int dns_hosts_loadfile(struct dns_hosts *, FILE *); 831 832 int dns_hosts_loadpath(struct dns_hosts *, const char *); 833 834 int dns_hosts_dump(struct dns_hosts *, FILE *); 835 836 int dns_hosts_insert(struct dns_hosts *, int, const void *, const void *, _Bool); 837 838 struct dns_packet *dns_hosts_query(struct dns_hosts *, struct dns_packet *, int *); 839 840 841 /* 842 * R E S O L V . C O N F I N T E R F A C E 843 * 844 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 845 846 struct dns_resolv_conf { 847 struct sockaddr_storage nameserver[3]; 848 849 char search[4][DNS_D_MAXNAME + 1]; 850 851 /* (f)ile, (b)ind, (c)ache */ 852 char lookup[4 * (1 + (4 * 2))]; 853 854 struct { 855 _Bool edns0; 856 857 unsigned ndots; 858 859 unsigned timeout; 860 861 unsigned attempts; 862 863 _Bool rotate; 864 865 _Bool recurse; 866 867 _Bool smart; 868 869 enum { 870 DNS_RESCONF_TCP_ENABLE, 871 DNS_RESCONF_TCP_ONLY, 872 DNS_RESCONF_TCP_DISABLE, 873 } tcp; 874 } options; 875 876 struct sockaddr_storage iface; 877 878 struct { /* PRIVATE */ 879 dns_atomic_t refcount; 880 } _; 881 }; /* struct dns_resolv_conf */ 882 883 struct dns_resolv_conf *dns_resconf_open(int *); 884 885 void dns_resconf_close(struct dns_resolv_conf *); 886 887 dns_refcount_t dns_resconf_acquire(struct dns_resolv_conf *); 888 889 dns_refcount_t dns_resconf_release(struct dns_resolv_conf *); 890 891 struct dns_resolv_conf *dns_resconf_mortal(struct dns_resolv_conf *); 892 893 struct dns_resolv_conf *dns_resconf_local(int *); 894 895 struct dns_resolv_conf *dns_resconf_root(int *); 896 897 int dns_resconf_pton(struct sockaddr_storage *, const char *); 898 899 int dns_resconf_loadfile(struct dns_resolv_conf *, FILE *); 900 901 int dns_resconf_loadpath(struct dns_resolv_conf *, const char *); 902 903 int dns_nssconf_loadfile(struct dns_resolv_conf *, FILE *); 904 905 int dns_nssconf_loadpath(struct dns_resolv_conf *, const char *); 906 907 int dns_resconf_dump(struct dns_resolv_conf *, FILE *); 908 909 int dns_nssconf_dump(struct dns_resolv_conf *, FILE *); 910 911 int dns_resconf_setiface(struct dns_resolv_conf *, const char *, unsigned short); 912 913 typedef unsigned long dns_resconf_i_t; 914 915 size_t dns_resconf_search(void *, size_t, const void *, size_t, struct dns_resolv_conf *, dns_resconf_i_t *); 916 917 918 /* 919 * H I N T S E R V E R I N T E R F A C E 920 * 921 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 922 923 struct dns_hints; 924 925 struct dns_hints *dns_hints_open(struct dns_resolv_conf *, int *); 926 927 void dns_hints_close(struct dns_hints *); 928 929 dns_refcount_t dns_hints_acquire(struct dns_hints *); 930 931 dns_refcount_t dns_hints_release(struct dns_hints *); 932 933 struct dns_hints *dns_hints_mortal(struct dns_hints *); 934 935 int dns_hints_insert(struct dns_hints *, const char *, const struct sockaddr *, unsigned); 936 937 unsigned dns_hints_insert_resconf(struct dns_hints *, const char *, const struct dns_resolv_conf *, int *); 938 939 struct dns_hints *dns_hints_local(struct dns_resolv_conf *, int *); 940 941 struct dns_hints *dns_hints_root(struct dns_resolv_conf *, int *); 942 943 int dns_hints_dump(struct dns_hints *, FILE *); 944 945 946 struct dns_hints_i { 947 const char *zone; 948 949 struct { 950 unsigned next; 951 unsigned seed; 952 } state; 953 }; /* struct dns_hints_i */ 954 955 #define dns_hints_i_new(...) (&(struct dns_hints_i){ __VA_ARGS__ }) 956 957 unsigned dns_hints_grep(struct sockaddr **, socklen_t *, unsigned, struct dns_hints_i *, struct dns_hints *); 958 959 960 /* 961 * C A C H E I N T E R F A C E 962 * 963 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 964 965 struct dns_cache { 966 void *state; 967 968 dns_refcount_t (*acquire)(struct dns_cache *); 969 dns_refcount_t (*release)(struct dns_cache *); 970 971 struct dns_packet *(*query)(struct dns_packet *, struct dns_cache *, int *); 972 973 int (*submit)(struct dns_packet *, struct dns_cache *); 974 int (*check)(struct dns_cache *); 975 struct dns_packet *(*fetch)(struct dns_cache *, int *); 976 977 int (*pollfd)(struct dns_cache *); 978 short (*events)(struct dns_cache *); 979 void (*clear)(struct dns_cache *); 980 981 union { 982 long i; 983 void *p; 984 } arg[3]; 985 986 struct { /* PRIVATE */ 987 dns_atomic_t refcount; 988 } _; 989 }; /* struct dns_cache */ 990 991 992 struct dns_cache *dns_cache_init(struct dns_cache *); 993 994 void dns_cache_close(struct dns_cache *); 995 996 997 /* 998 * A P P L I C A T I O N I N T E R F A C E 999 * 1000 * Options to change the behavior of the API. Applies across all the 1001 * different components. 1002 * 1003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1004 1005 #define DNS_OPTS_INITIALIZER_ { 0, 0 }, 0 1006 #define DNS_OPTS_INITIALIZER { DNS_OPTS_INITIALIZER_ } 1007 #define DNS_OPTS_INIT(...) { DNS_OPTS_INITIALIZER_, __VA_ARGS__ } 1008 1009 #define dns_opts(...) (&dns_quietinit((struct dns_options)DNS_OPTS_INIT(__VA_ARGS__))) 1010 1011 struct dns_options { 1012 /* 1013 * If the callback closes *fd, it must set it to -1. Otherwise, the 1014 * descriptor is queued and lazily closed at object destruction or 1015 * by an explicit call to _clear(). This allows safe use of 1016 * kqueue(2), epoll(2), et al -style persistent events. 1017 */ 1018 struct { 1019 void *arg; 1020 int (*cb)(int *fd, void *arg); 1021 } closefd; 1022 1023 /* bitmask for _events() routines */ 1024 enum dns_events { 1025 DNS_SYSPOLL, 1026 DNS_LIBEVENT, 1027 } events; 1028 }; /* struct dns_options */ 1029 1030 1031 /* 1032 * S T A T S I N T E R F A C E S 1033 * 1034 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1035 1036 struct dns_stat { 1037 size_t queries; 1038 1039 struct { 1040 struct { 1041 size_t count, bytes; 1042 } sent, rcvd; 1043 } udp, tcp; 1044 }; /* struct dns_stat */ 1045 1046 1047 /* 1048 * S O C K E T I N T E R F A C E 1049 * 1050 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1051 1052 struct dns_socket; 1053 1054 struct dns_socket *dns_so_open(const struct sockaddr *, int, const struct dns_options *, int *error); 1055 1056 void dns_so_close(struct dns_socket *); 1057 1058 void dns_so_reset(struct dns_socket *); 1059 1060 unsigned short dns_so_mkqid(struct dns_socket *so); 1061 1062 struct dns_packet *dns_so_query(struct dns_socket *, struct dns_packet *, struct sockaddr *, int *); 1063 1064 int dns_so_submit(struct dns_socket *, struct dns_packet *, struct sockaddr *); 1065 1066 int dns_so_check(struct dns_socket *); 1067 1068 struct dns_packet *dns_so_fetch(struct dns_socket *, int *); 1069 1070 time_t dns_so_elapsed(struct dns_socket *); 1071 1072 void dns_so_clear(struct dns_socket *); 1073 1074 int dns_so_events(struct dns_socket *); 1075 1076 int dns_so_pollfd(struct dns_socket *); 1077 1078 int dns_so_poll(struct dns_socket *, int); 1079 1080 const struct dns_stat *dns_so_stat(struct dns_socket *); 1081 1082 1083 /* 1084 * R E S O L V E R I N T E R F A C E 1085 * 1086 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1087 1088 struct dns_resolver; 1089 1090 struct dns_resolver *dns_res_open(struct dns_resolv_conf *, struct dns_hosts *hosts, struct dns_hints *, struct dns_cache *, const struct dns_options *, int *); 1091 1092 struct dns_resolver *dns_res_stub(const struct dns_options *, int *); 1093 1094 void dns_res_reset(struct dns_resolver *); 1095 1096 void dns_res_close(struct dns_resolver *); 1097 1098 dns_refcount_t dns_res_acquire(struct dns_resolver *); 1099 1100 dns_refcount_t dns_res_release(struct dns_resolver *); 1101 1102 struct dns_resolver *dns_res_mortal(struct dns_resolver *); 1103 1104 int dns_res_submit(struct dns_resolver *, const char *, enum dns_type, enum dns_class); 1105 1106 int dns_res_submit2(struct dns_resolver *, const char *, size_t, enum dns_type, enum dns_class); 1107 1108 int dns_res_check(struct dns_resolver *); 1109 1110 struct dns_packet *dns_res_fetch(struct dns_resolver *, int *); 1111 1112 time_t dns_res_elapsed(struct dns_resolver *); 1113 1114 void dns_res_clear(struct dns_resolver *); 1115 1116 int dns_res_events(struct dns_resolver *); 1117 1118 int dns_res_pollfd(struct dns_resolver *); 1119 1120 time_t dns_res_timeout(struct dns_resolver *); 1121 1122 int dns_res_poll(struct dns_resolver *, int); 1123 1124 struct dns_packet *dns_res_query(struct dns_resolver *, const char *, enum dns_type, enum dns_class, int, int *); 1125 1126 const struct dns_stat *dns_res_stat(struct dns_resolver *); 1127 1128 void dns_res_sethints(struct dns_resolver *, struct dns_hints *); 1129 1130 1131 /* 1132 * A D D R I N F O I N T E R F A C E 1133 * 1134 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1135 1136 struct dns_addrinfo; 1137 1138 struct dns_addrinfo *dns_ai_open(const char *, const char *, enum dns_type, const struct addrinfo *, struct dns_resolver *, int *); 1139 1140 void dns_ai_close(struct dns_addrinfo *); 1141 1142 int dns_ai_nextent(struct addrinfo **, struct dns_addrinfo *); 1143 1144 size_t dns_ai_print(void *, size_t, struct addrinfo *, struct dns_addrinfo *); 1145 1146 time_t dns_ai_elapsed(struct dns_addrinfo *); 1147 1148 void dns_ai_clear(struct dns_addrinfo *); 1149 1150 int dns_ai_events(struct dns_addrinfo *); 1151 1152 int dns_ai_pollfd(struct dns_addrinfo *); 1153 1154 time_t dns_ai_timeout(struct dns_addrinfo *); 1155 1156 int dns_ai_poll(struct dns_addrinfo *, int); 1157 1158 const struct dns_stat *dns_ai_stat(struct dns_addrinfo *); 1159 1160 1161 /* 1162 * U T I L I T Y I N T E R F A C E S 1163 * 1164 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1165 1166 size_t dns_strlcpy(char *, const char *, size_t); 1167 1168 size_t dns_strlcat(char *, const char *, size_t); 1169 1170 1171 /* 1172 * M A C R O M A G I C S 1173 * 1174 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1175 1176 #define DNS_PP_MIN(a, b) (((a) < (b))? (a) : (b)) 1177 #define DNS_PP_MAX(a, b) (((a) > (b))? (a) : (b)) 1178 #define DNS_PP_NARG_(a, b, c, d, e, f, g, h, i, j, k, N,...) N 1179 #define DNS_PP_NARG(...) DNS_PP_NARG_(__VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 1180 #define DNS_PP_CALL(F, ...) F(__VA_ARGS__) 1181 #define DNS_PP_PASTE(x, y) x##y 1182 #define DNS_PP_XPASTE(x, y) DNS_PP_PASTE(x, y) 1183 #define DNS_PP_STRINGIFY_(s) #s 1184 #define DNS_PP_STRINGIFY(s) DNS_PP_STRINGIFY_(s) 1185 #define DNS_PP_D1 0 1186 #define DNS_PP_D2 1 1187 #define DNS_PP_D3 2 1188 #define DNS_PP_D4 3 1189 #define DNS_PP_D5 4 1190 #define DNS_PP_D6 5 1191 #define DNS_PP_D7 6 1192 #define DNS_PP_D8 7 1193 #define DNS_PP_D9 8 1194 #define DNS_PP_D10 9 1195 #define DNS_PP_D11 10 1196 #define DNS_PP_DEC(N) DNS_PP_XPASTE(DNS_PP_D, N) 1197 1198 #endif /* DNS_H */ 1199