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