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