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