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