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