]> git.mxchange.org Git - simgear.git/blob - 3rdparty/udns/udns.h
Initial commit for a DNS service resolver
[simgear.git] / 3rdparty / udns / udns.h
1 /* udns.h
2    header file for the UDNS library.
3
4    Copyright (C) 2005  Michael Tokarev <mjt@corpit.ru>
5    This file is part of UDNS library, an async DNS stub resolver.
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this library, in file named COPYING.LGPL; if not,
19    write to the Free Software Foundation, Inc., 59 Temple Place,
20    Suite 330, Boston, MA  02111-1307  USA
21
22  */
23
24 #ifndef UDNS_VERSION    /* include guard */
25
26 #define UDNS_VERSION "0.4"
27
28 #ifdef WINDOWS
29 # ifdef UDNS_DYNAMIC_LIBRARY
30 #  ifdef DNS_LIBRARY_BUILD
31 #   define UDNS_API __declspec(dllexport)
32 #   define UDNS_DATA_API __declspec(dllexport)
33 #  else
34 #   define UDNS_API __declspec(dllimport)
35 #   define UDNS_DATA_API __declspec(dllimport)
36 #  endif
37 # endif
38 #endif
39
40 #ifndef UDNS_API
41 # define UDNS_API
42 #endif
43 #ifndef UDNS_DATA_API
44 # define UDNS_DATA_API
45 #endif
46
47 #include <sys/types.h>          /* for time_t */
48
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52
53 /* forward declarations if sockets stuff isn't #include'd */
54 struct in_addr;
55 struct in6_addr;
56 struct sockaddr;
57
58 /**************************************************************************/
59 /**************** Common definitions **************************************/
60
61 UDNS_API const char *
62 dns_version(void);
63
64 struct dns_ctx;
65 struct dns_query;
66
67 /* shorthand for [const] unsigned char */
68 typedef unsigned char dnsc_t;
69 typedef const unsigned char dnscc_t;
70
71 #define DNS_MAXDN       255     /* max DN length */
72 #define DNS_DNPAD       1       /* padding for DN buffers */
73 #define DNS_MAXLABEL    63      /* max DN label length */
74 #define DNS_MAXNAME     1024    /* max asciiz domain name length */
75 #define DNS_HSIZE       12      /* DNS packet header size */
76 #define DNS_PORT        53      /* default domain port */
77 #define DNS_MAXSERV     6       /* max servers to consult */
78 #define DNS_MAXPACKET   512     /* max traditional-DNS UDP packet size */
79 #define DNS_EDNS0PACKET 4096    /* EDNS0 packet size to use */
80
81 enum dns_class {        /* DNS RR Classes */
82   DNS_C_INVALID = 0,    /* invalid class */
83   DNS_C_IN      = 1,    /* Internet */
84   DNS_C_CH      = 3,    /* CHAOS */
85   DNS_C_HS      = 4,    /* HESIOD */
86   DNS_C_ANY     = 255   /* wildcard */
87 };
88
89 enum dns_type {         /* DNS RR Types */
90   DNS_T_INVALID         = 0,    /* Cookie. */
91   DNS_T_A               = 1,    /* Host address. */
92   DNS_T_NS              = 2,    /* Authoritative server. */
93   DNS_T_MD              = 3,    /* Mail destination. */
94   DNS_T_MF              = 4,    /* Mail forwarder. */
95   DNS_T_CNAME           = 5,    /* Canonical name. */
96   DNS_T_SOA             = 6,    /* Start of authority zone. */
97   DNS_T_MB              = 7,    /* Mailbox domain name. */
98   DNS_T_MG              = 8,    /* Mail group member. */
99   DNS_T_MR              = 9,    /* Mail rename name. */
100   DNS_T_NULL            = 10,   /* Null resource record. */
101   DNS_T_WKS             = 11,   /* Well known service. */
102   DNS_T_PTR             = 12,   /* Domain name pointer. */
103   DNS_T_HINFO           = 13,   /* Host information. */
104   DNS_T_MINFO           = 14,   /* Mailbox information. */
105   DNS_T_MX              = 15,   /* Mail routing information. */
106   DNS_T_TXT             = 16,   /* Text strings. */
107   DNS_T_RP              = 17,   /* Responsible person. */
108   DNS_T_AFSDB           = 18,   /* AFS cell database. */
109   DNS_T_X25             = 19,   /* X_25 calling address. */
110   DNS_T_ISDN            = 20,   /* ISDN calling address. */
111   DNS_T_RT              = 21,   /* Router. */
112   DNS_T_NSAP            = 22,   /* NSAP address. */
113   DNS_T_NSAP_PTR        = 23,   /* Reverse NSAP lookup (deprecated). */
114   DNS_T_SIG             = 24,   /* Security signature. */
115   DNS_T_KEY             = 25,   /* Security key. */
116   DNS_T_PX              = 26,   /* X.400 mail mapping. */
117   DNS_T_GPOS            = 27,   /* Geographical position (withdrawn). */
118   DNS_T_AAAA            = 28,   /* Ip6 Address. */
119   DNS_T_LOC             = 29,   /* Location Information. */
120   DNS_T_NXT             = 30,   /* Next domain (security). */
121   DNS_T_EID             = 31,   /* Endpoint identifier. */
122   DNS_T_NIMLOC          = 32,   /* Nimrod Locator. */
123   DNS_T_SRV             = 33,   /* Server Selection. */
124   DNS_T_ATMA            = 34,   /* ATM Address */
125   DNS_T_NAPTR           = 35,   /* Naming Authority PoinTeR */
126   DNS_T_KX              = 36,   /* Key Exchange */
127   DNS_T_CERT            = 37,   /* Certification record */
128   DNS_T_A6              = 38,   /* IPv6 address (deprecates AAAA) */
129   DNS_T_DNAME           = 39,   /* Non-terminal DNAME (for IPv6) */
130   DNS_T_SINK            = 40,   /* Kitchen sink (experimentatl) */
131   DNS_T_OPT             = 41,   /* EDNS0 option (meta-RR) */
132   DNS_T_DS              = 43,   /* DNSSEC */
133   DNS_T_SSHFP           = 44,
134   DNS_T_IPSECKEY        = 45,
135   DNS_T_RRSIG           = 46,   /* DNSSEC */
136   DNS_T_NSEC            = 47,   /* DNSSEC */
137   DNS_T_DNSKEY          = 48,
138   DNS_T_DHCID           = 49,
139   DNS_T_NSEC3           = 50,
140   DNS_T_NSEC3PARAMS     = 51,
141   DNS_T_TALINK          = 58, /* draft-ietf-dnsop-trust-history */
142   DNS_T_SPF             = 99,
143   DNS_T_UINFO           = 100,
144   DNS_T_UID             = 101,
145   DNS_T_GID             = 102,
146   DNS_T_UNSPEC          = 103,
147   DNS_T_TSIG            = 250,  /* Transaction signature. */
148   DNS_T_IXFR            = 251,  /* Incremental zone transfer. */
149   DNS_T_AXFR            = 252,  /* Transfer zone of authority. */
150   DNS_T_MAILB           = 253,  /* Transfer mailbox records. */
151   DNS_T_MAILA           = 254,  /* Transfer mail agent records. */
152   DNS_T_ANY             = 255,  /* Wildcard match. */
153   DNS_T_ZXFR            = 256,  /* BIND-specific, nonstandard. */
154   DNS_T_DLV             = 32769, /* RFC 4431, 5074, DNSSEC Lookaside Validation */
155   DNS_T_MAX             = 65536
156 };
157
158 /**************************************************************************/
159 /**************** Domain Names (DNs) **************************************/
160
161 /* return length of the DN */
162 UDNS_API unsigned
163 dns_dnlen(dnscc_t *dn);
164
165 /* return #of labels in a DN */
166 UDNS_API unsigned
167 dns_dnlabels(dnscc_t *dn);
168
169 /* lower- and uppercase single DN char */
170 #define DNS_DNLC(c) ((c) >= 'A' && (c) <= 'Z' ? (c) - 'A' + 'a' : (c))
171 #define DNS_DNUC(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
172
173 /* compare the DNs, return dnlen of equal or 0 if not */
174 UDNS_API unsigned
175 dns_dnequal(dnscc_t *dn1, dnscc_t *dn2);
176
177 /* copy one DN to another, size checking */
178 UDNS_API unsigned
179 dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz);
180
181 /* convert asciiz string of length namelen (0 to use strlen) to DN */
182 UDNS_API int
183 dns_ptodn(const char *name, unsigned namelen,
184           dnsc_t *dn, unsigned dnsiz, int *isabs);
185
186 /* simpler form of dns_ptodn() */
187 #define dns_sptodn(name,dn,dnsiz) dns_ptodn((name),0,(dn),(dnsiz),0)
188
189 UDNS_DATA_API extern dnscc_t dns_inaddr_arpa_dn[14];
190 #define DNS_A4RSIZE     30
191 UDNS_API int
192 dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
193            dnsc_t *dn, unsigned dnsiz);
194 UDNS_API int
195 dns_a4ptodn(const struct in_addr *addr, const char *tname,
196             dnsc_t *dn, unsigned dnsiz);
197 UDNS_API dnsc_t *
198 dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne);
199
200 UDNS_DATA_API extern dnscc_t dns_ip6_arpa_dn[10];
201 #define DNS_A6RSIZE     74
202 UDNS_API int
203 dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
204            dnsc_t *dn, unsigned dnsiz);
205 UDNS_API int
206 dns_a6ptodn(const struct in6_addr *addr, const char *tname,
207             dnsc_t *dn, unsigned dnsiz);
208 UDNS_API dnsc_t *
209 dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne);
210
211 /* convert DN into asciiz string */
212 UDNS_API int
213 dns_dntop(dnscc_t *dn, char *name, unsigned namesiz);
214
215 /* convert DN into asciiz string, using static buffer (NOT thread-safe!) */
216 UDNS_API const char *
217 dns_dntosp(dnscc_t *dn);
218
219 /* return buffer size (incl. null byte) required for asciiz form of a DN */
220 UDNS_API unsigned
221 dns_dntop_size(dnscc_t *dn);
222
223 /* either wrappers or reimplementations for inet_ntop() and inet_pton() */
224 UDNS_API const char *dns_ntop(int af, const void *src, char *dst, int size);
225 UDNS_API int dns_pton(int af, const char *src, void *dst);
226
227 /**************************************************************************/
228 /**************** DNS raw packet layout ***********************************/
229
230 enum dns_rcode {        /* reply codes */
231   DNS_R_NOERROR         = 0,    /* ok, no error */
232   DNS_R_FORMERR         = 1,    /* format error */
233   DNS_R_SERVFAIL        = 2,    /* server failed */
234   DNS_R_NXDOMAIN        = 3,    /* domain does not exists */
235   DNS_R_NOTIMPL         = 4,    /* not implemented */
236   DNS_R_REFUSED         = 5,    /* query refused */
237   /* these are for BIND_UPDATE */
238   DNS_R_YXDOMAIN        = 6,    /* Name exists */
239   DNS_R_YXRRSET         = 7,    /* RRset exists */
240   DNS_R_NXRRSET         = 8,    /* RRset does not exist */
241   DNS_R_NOTAUTH         = 9,    /* Not authoritative for zone */
242   DNS_R_NOTZONE         = 10,   /* Zone of record different from zone section */
243   /*ns_r_max = 11,*/
244   /* The following are TSIG extended errors */
245   DNS_R_BADSIG          = 16,
246   DNS_R_BADKEY          = 17,
247   DNS_R_BADTIME         = 18
248 };
249
250 static __inline unsigned dns_get16(dnscc_t *s) {
251   return ((unsigned)s[0]<<8) | s[1];
252 }
253 static __inline unsigned dns_get32(dnscc_t *s) {
254   return ((unsigned)s[0]<<24) | ((unsigned)s[1]<<16)
255         | ((unsigned)s[2]<<8) | s[3];
256 }
257 static __inline dnsc_t *dns_put16(dnsc_t *d, unsigned n) {
258   *d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); return d;
259 }
260 static __inline dnsc_t *dns_put32(dnsc_t *d, unsigned n) {
261   *d++ = (dnsc_t)((n >> 24) & 255); *d++ = (dnsc_t)((n >> 16) & 255);
262   *d++ = (dnsc_t)((n >>  8) & 255); *d++ = (dnsc_t)(n & 255);
263   return d;
264 }
265
266 /* DNS Header layout */
267 enum {
268  /* bytes 0:1 - query ID */
269   DNS_H_QID1    = 0,
270   DNS_H_QID2    = 1,
271   DNS_H_QID     = DNS_H_QID1,
272 #define dns_qid(pkt)    dns_get16((pkt)+DNS_H_QID)
273  /* byte 2: flags1 */
274   DNS_H_F1      = 2,
275   DNS_HF1_QR    = 0x80, /* query response flag */
276 #define dns_qr(pkt)     ((pkt)[DNS_H_F1]&DNS_HF1_QR)
277   DNS_HF1_OPCODE = 0x78, /* opcode, 0 = query */
278 #define dns_opcode(pkt) (((pkt)[DNS_H_F1]&DNS_HF1_OPCODE)>>3)
279   DNS_HF1_AA    = 0x04, /* auth answer */
280 #define dns_aa(pkt)     ((pkt)[DNS_H_F1]&DNS_HF1_AA)
281   DNS_HF1_TC    = 0x02, /* truncation flag */
282 #define dns_tc(pkt)     ((pkt)[DNS_H_F1]&DNS_HF1_TC)
283   DNS_HF1_RD    = 0x01, /* recursion desired (may be set in query) */
284 #define dns_rd(pkt)     ((pkt)[DNS_H_F1]&DNS_HF1_RD)
285  /* byte 3: flags2 */
286   DNS_H_F2      = 3,
287   DNS_HF2_RA    = 0x80, /* recursion available */
288 #define dns_ra(pkt)     ((pkt)[DNS_H_F2]&DNS_HF2_RA)
289   DNS_HF2_Z     = 0x40, /* reserved */
290   DNS_HF2_AD    = 0x20, /* DNSSEC: authentic data */
291 #define dns_ad(pkt)     ((pkt)[DNS_H_F2]&DNS_HF2_AD)
292   DNS_HF2_CD    = 0x10, /* DNSSEC: checking disabled */
293 #define dns_cd(pkt)     ((pkt)[DNS_H_F2]&DNS_HF2_CD)
294   DNS_HF2_RCODE = 0x0f, /* response code, DNS_R_XXX above */
295 #define dns_rcode(pkt)  ((pkt)[DNS_H_F2]&DNS_HF2_RCODE)
296  /* bytes 4:5: qdcount, numqueries */
297   DNS_H_QDCNT1  = 4,
298   DNS_H_QDCNT2  = 5,
299   DNS_H_QDCNT   = DNS_H_QDCNT1,
300 #define dns_numqd(pkt)  dns_get16((pkt)+4)
301  /* bytes 6:7: ancount, numanswers */
302   DNS_H_ANCNT1  = 6,
303   DNS_H_ANCNT2  = 7,
304   DNS_H_ANCNT   = DNS_H_ANCNT1,
305 #define dns_numan(pkt)  dns_get16((pkt)+6)
306  /* bytes 8:9: nscount, numauthority */
307   DNS_H_NSCNT1  = 8,
308   DNS_H_NSCNT2  = 9,
309   DNS_H_NSCNT   = DNS_H_NSCNT1,
310 #define dns_numns(pkt)  dns_get16((pkt)+8)
311  /* bytes 10:11: arcount, numadditional */
312   DNS_H_ARCNT1  = 10,
313   DNS_H_ARCNT2  = 11,
314   DNS_H_ARCNT   = DNS_H_ARCNT1,
315 #define dns_numar(pkt)  dns_get16((pkt)+10)
316 #define dns_payload(pkt) ((pkt)+DNS_HSIZE)
317   /* EDNS0 (OPT RR) flags (Ext. Flags) */
318   DNS_EF1_DO    = 0x80, /* DNSSEC OK */
319 };
320
321 /* packet buffer: start at pkt, end before pkte, current pos *curp.
322  * extract a DN and set *curp to the next byte after DN in packet.
323  * return -1 on error, 0 if dnsiz is too small, or dnlen on ok.
324  */
325 UDNS_API int
326 dns_getdn(dnscc_t *pkt, dnscc_t **curp, dnscc_t *end,
327           dnsc_t *dn, unsigned dnsiz);
328
329 /* skip the DN at position cur in packet ending before pkte,
330  * return pointer to the next byte after the DN or NULL on error */
331 UDNS_API dnscc_t *
332 dns_skipdn(dnscc_t *end, dnscc_t *cur);
333
334 struct dns_rr {         /* DNS Resource Record */
335   dnsc_t dnsrr_dn[DNS_MAXDN];   /* the DN of the RR */
336   enum dns_class dnsrr_cls;     /* Class */
337   enum dns_type  dnsrr_typ;     /* Type */
338   unsigned dnsrr_ttl;           /* Time-To-Live (TTL) */
339   unsigned dnsrr_dsz;           /* data size */
340   dnscc_t *dnsrr_dptr;          /* pointer to start of data */
341   dnscc_t *dnsrr_dend;          /* past end of data */
342 };
343
344 struct dns_parse {      /* RR/packet parsing state */
345   dnscc_t *dnsp_pkt;            /* start of the packet */
346   dnscc_t *dnsp_end;            /* end of the packet */
347   dnscc_t *dnsp_cur;            /* current packet position */
348   dnscc_t *dnsp_ans;            /* start of answer section */
349   int dnsp_rrl;                 /* number of RRs left to go */
350   int dnsp_nrr;                 /* RR count so far */
351   unsigned dnsp_ttl;            /* TTL value so far */
352   dnscc_t *dnsp_qdn;            /* the RR DN we're looking for */
353   enum dns_class dnsp_qcls;     /* RR class we're looking for or 0 */
354   enum dns_type  dnsp_qtyp;     /* RR type we're looking for or 0 */
355   dnsc_t dnsp_dnbuf[DNS_MAXDN]; /* domain buffer */
356 };
357
358 /* initialize the parse structure */
359 UDNS_API void
360 dns_initparse(struct dns_parse *p, dnscc_t *qdn,
361               dnscc_t *pkt, dnscc_t *cur, dnscc_t *end);
362
363 /* search next RR, <0=error, 0=no more RRs, >0 = found. */
364 UDNS_API int
365 dns_nextrr(struct dns_parse *p, struct dns_rr *rr);
366
367 UDNS_API void
368 dns_rewind(struct dns_parse *p, dnscc_t *qdn);
369
370
371 /**************************************************************************/
372 /**************** Resolver Context ****************************************/
373
374 /* default resolver context */
375 UDNS_DATA_API extern struct dns_ctx dns_defctx;
376
377 /* reset resolver context to default state, close it if open, drop queries */
378 UDNS_API void
379 dns_reset(struct dns_ctx *ctx);
380
381 /* reset resolver context and read in system configuration */
382 UDNS_API int
383 dns_init(struct dns_ctx *ctx, int do_open);
384
385 /* return new resolver context with the same settings as copy */
386 UDNS_API struct dns_ctx *
387 dns_new(const struct dns_ctx *copy);
388
389 /* free resolver context returned by dns_new(); all queries are dropped */
390 UDNS_API void
391 dns_free(struct dns_ctx *ctx);
392
393 /* add nameserver for a resolver context (or reset nslist if serv==NULL) */
394 UDNS_API int
395 dns_add_serv(struct dns_ctx *ctx, const char *serv);
396
397 /* add nameserver using struct sockaddr structure (with ports) */
398 UDNS_API int
399 dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa);
400
401 /* add search list element for a resolver context (or reset it if srch==NULL) */
402 UDNS_API int
403 dns_add_srch(struct dns_ctx *ctx, const char *srch);
404
405 /* set options for a resolver context */
406 UDNS_API int
407 dns_set_opts(struct dns_ctx *ctx, const char *opts);
408
409 enum dns_opt {          /* options */
410   DNS_OPT_FLAGS,        /* flags, DNS_F_XXX */
411   DNS_OPT_TIMEOUT,      /* timeout in secounds */
412   DNS_OPT_NTRIES,       /* number of retries */
413   DNS_OPT_NDOTS,        /* ndots */
414   DNS_OPT_UDPSIZE,      /* EDNS0 UDP size */
415   DNS_OPT_PORT,         /* port to use */
416 };
417
418 /* set or get (if val<0) an option */
419 UDNS_API int
420 dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val);
421
422 enum dns_flags {
423   DNS_NOSRCH    = 0x00010000,   /* do not perform search */
424   DNS_NORD      = 0x00020000,   /* request no recursion */
425   DNS_AAONLY    = 0x00040000,   /* set AA flag in queries */
426   DNS_SET_DO    = 0x00080000,   /* set EDNS0 "DO" bit (DNSSEC OK) */
427   DNS_SET_CD    = 0x00100000,   /* set CD bit (DNSSEC: checking disabled) */
428 };
429
430 /* set the debug function pointer */
431 typedef void
432 (dns_dbgfn)(int code, const struct sockaddr *sa, unsigned salen,
433             dnscc_t *pkt, int plen,
434             const struct dns_query *q, void *data);
435 UDNS_API void
436 dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn);
437
438 /* open and return UDP socket */
439 UDNS_API int
440 dns_open(struct dns_ctx *ctx);
441
442 /* return UDP socket or -1 if not open */
443 UDNS_API int
444 dns_sock(const struct dns_ctx *ctx);
445
446 /* close the UDP socket */
447 UDNS_API void
448 dns_close(struct dns_ctx *ctx);
449
450 /* return number of requests queued */
451 UDNS_API int
452 dns_active(const struct dns_ctx *ctx);
453
454 /* return status of the last operation */
455 UDNS_API int
456 dns_status(const struct dns_ctx *ctx);
457 UDNS_API void
458 dns_setstatus(struct dns_ctx *ctx, int status);
459
460 /* handle I/O event on UDP socket */
461 UDNS_API void
462 dns_ioevent(struct dns_ctx *ctx, time_t now);
463
464 /* process any timeouts, return time in secounds to the
465  * next timeout (or -1 if none) but not greather than maxwait */
466 UDNS_API int
467 dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now);
468
469 /* define timer requesting routine to use */
470 typedef void dns_utm_fn(struct dns_ctx *ctx, int timeout, void *data);
471 UDNS_API void
472 dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data);
473
474 /**************************************************************************/
475 /**************** Making Queries ******************************************/
476
477 /* query callback routine */
478 typedef void dns_query_fn(struct dns_ctx *ctx, void *result, void *data);
479
480 /* query parse routine: raw DNS => application structure */
481 typedef int
482 dns_parse_fn(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
483              void **res);
484
485 enum dns_status {
486   DNS_E_NOERROR         = 0,    /* ok, not an error */
487   DNS_E_TEMPFAIL        = -1,   /* timeout, SERVFAIL or similar */
488   DNS_E_PROTOCOL        = -2,   /* got garbled reply */
489   DNS_E_NXDOMAIN        = -3,   /* domain does not exists */
490   DNS_E_NODATA          = -4,   /* domain exists but no data of reqd type */
491   DNS_E_NOMEM           = -5,   /* out of memory while processing */
492   DNS_E_BADQUERY        = -6    /* the query is malformed */
493 };
494
495 /* submit generic DN query */
496 UDNS_API struct dns_query *
497 dns_submit_dn(struct dns_ctx *ctx,
498               dnscc_t *dn, int qcls, int qtyp, int flags,
499               dns_parse_fn *parse, dns_query_fn *cbck, void *data);
500 /* submit generic name query */
501 UDNS_API struct dns_query *
502 dns_submit_p(struct dns_ctx *ctx,
503              const char *name, int qcls, int qtyp, int flags,
504              dns_parse_fn *parse, dns_query_fn *cbck, void *data);
505
506 /* cancel the given async query in progress */
507 UDNS_API int
508 dns_cancel(struct dns_ctx *ctx, struct dns_query *q);
509
510 /* resolve a generic query, return the answer */
511 UDNS_API void *
512 dns_resolve_dn(struct dns_ctx *ctx,
513                dnscc_t *qdn, int qcls, int qtyp, int flags,
514                dns_parse_fn *parse);
515 UDNS_API void *
516 dns_resolve_p(struct dns_ctx *ctx,
517               const char *qname, int qcls, int qtyp, int flags,
518               dns_parse_fn *parse);
519 UDNS_API void *
520 dns_resolve(struct dns_ctx *ctx, struct dns_query *q);
521
522
523 /* Specific RR handlers */
524
525 #define dns_rr_common(prefix)                                           \
526   char *prefix##_cname;         /* canonical name */                    \
527   char *prefix##_qname;         /* original query name */               \
528   unsigned prefix##_ttl;        /* TTL value */                         \
529   int prefix##_nrr              /* number of records */
530
531 struct dns_rr_null {            /* NULL RRset, aka RRset template */
532   dns_rr_common(dnsn);
533 };
534
535 UDNS_API int
536 dns_stdrr_size(const struct dns_parse *p);
537 UDNS_API void *
538 dns_stdrr_finish(struct dns_rr_null *ret, char *cp, const struct dns_parse *p);
539
540 struct dns_rr_a4 {              /* the A RRset */
541   dns_rr_common(dnsa4);
542   struct in_addr *dnsa4_addr;   /* array of addresses, naddr elements */
543 };
544
545 UDNS_API dns_parse_fn dns_parse_a4;     /* A RR parsing routine */
546 typedef void                            /* A query callback routine */
547 dns_query_a4_fn(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data);
548
549 /* submit A IN query */
550 UDNS_API struct dns_query *
551 dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
552               dns_query_a4_fn *cbck, void *data);
553
554 /* resolve A IN query */
555 UDNS_API struct dns_rr_a4 *
556 dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags);
557
558
559 struct dns_rr_a6 {              /* the AAAA RRset */
560   dns_rr_common(dnsa6);
561   struct in6_addr *dnsa6_addr;  /* array of addresses, naddr elements */
562 };
563
564 UDNS_API dns_parse_fn dns_parse_a6;     /* A RR parsing routine */
565 typedef void                            /* A query callback routine */
566 dns_query_a6_fn(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data);
567
568 /* submit AAAA IN query */
569 UDNS_API struct dns_query *
570 dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
571               dns_query_a6_fn *cbck, void *data);
572
573 /* resolve AAAA IN query */
574 UDNS_API struct dns_rr_a6 *
575 dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags);
576
577
578 struct dns_rr_ptr {             /* the PTR RRset */
579   dns_rr_common(dnsptr);
580   char **dnsptr_ptr;            /* array of PTRs */
581 };
582
583 UDNS_API dns_parse_fn dns_parse_ptr;    /* PTR RR parsing routine */
584 typedef void                            /* PTR query callback */
585 dns_query_ptr_fn(struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data);
586 /* submit PTR IN in-addr.arpa query */
587 UDNS_API struct dns_query *
588 dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
589                  dns_query_ptr_fn *cbck, void *data);
590 /* resolve PTR IN in-addr.arpa query */
591 UDNS_API struct dns_rr_ptr *
592 dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr);
593
594 /* the same as above, but for ip6.arpa */
595 UDNS_API struct dns_query *
596 dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
597                  dns_query_ptr_fn *cbck, void *data);
598 UDNS_API struct dns_rr_ptr *
599 dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr);
600
601
602 struct dns_mx {         /* single MX RR */
603   int priority;         /* MX priority */
604   char *name;           /* MX name */
605 };
606 struct dns_rr_mx {              /* the MX RRset */
607   dns_rr_common(dnsmx);
608   struct dns_mx *dnsmx_mx;      /* array of MXes */
609 };
610 UDNS_API dns_parse_fn dns_parse_mx;     /* MX RR parsing routine */
611 typedef void                            /* MX RR callback */
612 dns_query_mx_fn(struct dns_ctx *ctx, struct dns_rr_mx *result, void *data);
613 /* submit MX IN query */
614 UDNS_API struct dns_query *
615 dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
616               dns_query_mx_fn *cbck, void *data);
617 /* resolve MX IN query */
618 UDNS_API struct dns_rr_mx *
619 dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags);
620
621
622 struct dns_txt {        /* single TXT record */
623   int len;              /* length of the text */
624   dnsc_t *txt;  /* pointer to text buffer. May contain nulls. */
625 };
626 struct dns_rr_txt {             /* the TXT RRset */
627   dns_rr_common(dnstxt);
628   struct dns_txt *dnstxt_txt;   /* array of TXT records */
629 };
630 UDNS_API dns_parse_fn dns_parse_txt;    /* TXT RR parsing routine */
631 typedef void                            /* TXT RR callback */
632 dns_query_txt_fn(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data);
633 /* submit TXT query */
634 UDNS_API struct dns_query *
635 dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
636                dns_query_txt_fn *cbck, void *data);
637 /* resolve TXT query */
638 UDNS_API struct dns_rr_txt *
639 dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags);
640
641
642 struct dns_srv {        /* single SRV RR */
643   int priority;         /* SRV priority */
644   int weight;           /* SRV weight */
645   int port;             /* SRV port */
646   char *name;           /* SRV name */
647 };
648 struct dns_rr_srv {             /* the SRV RRset */
649   dns_rr_common(dnssrv);
650   struct dns_srv *dnssrv_srv;   /* array of SRVes */
651 };
652 UDNS_API dns_parse_fn dns_parse_srv;    /* SRV RR parsing routine */
653 typedef void                            /* SRV RR callback */
654 dns_query_srv_fn(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data);
655 /* submit SRV IN query */
656 UDNS_API struct dns_query *
657 dns_submit_srv(struct dns_ctx *ctx,
658                const char *name, const char *srv, const char *proto,
659                int flags, dns_query_srv_fn *cbck, void *data);
660 /* resolve SRV IN query */
661 UDNS_API struct dns_rr_srv *
662 dns_resolve_srv(struct dns_ctx *ctx,
663                 const char *name, const char *srv, const char *proto,
664                 int flags);
665
666 /* NAPTR (RFC3403) RR type */
667 struct dns_naptr {      /* single NAPTR RR */
668   int order;            /* NAPTR order */
669   int preference;       /* NAPTR preference */
670   char *flags;          /* NAPTR flags */
671   char *service;        /* NAPTR service */
672   char *regexp;         /* NAPTR regexp */
673   char *replacement;    /* NAPTR replacement */
674 };
675
676 struct dns_rr_naptr {           /* the NAPTR RRset */
677   dns_rr_common(dnsnaptr);
678   struct dns_naptr *dnsnaptr_naptr;     /* array of NAPTRes */
679 };
680 UDNS_API dns_parse_fn dns_parse_naptr;  /* NAPTR RR parsing routine */
681 typedef void                            /* NAPTR RR callback */
682 dns_query_naptr_fn(struct dns_ctx *ctx,
683                    struct dns_rr_naptr *result, void *data);
684 /* submit NAPTR IN query */
685 UDNS_API struct dns_query *
686 dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
687                  dns_query_naptr_fn *cbck, void *data);
688 /* resolve NAPTR IN query */
689 UDNS_API struct dns_rr_naptr *
690 dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags);
691
692
693 UDNS_API struct dns_query *
694 dns_submit_a4dnsbl(struct dns_ctx *ctx,
695                    const struct in_addr *addr, const char *dnsbl,
696                    dns_query_a4_fn *cbck, void *data);
697 UDNS_API struct dns_query *
698 dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
699                        const struct in_addr *addr, const char *dnsbl,
700                        dns_query_txt_fn *cbck, void *data);
701 UDNS_API struct dns_rr_a4 *
702 dns_resolve_a4dnsbl(struct dns_ctx *ctx,
703                     const struct in_addr *addr, const char *dnsbl);
704 UDNS_API struct dns_rr_txt *
705 dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
706                         const struct in_addr *addr, const char *dnsbl);
707
708 UDNS_API struct dns_query *
709 dns_submit_a6dnsbl(struct dns_ctx *ctx,
710                    const struct in6_addr *addr, const char *dnsbl,
711                    dns_query_a4_fn *cbck, void *data);
712 UDNS_API struct dns_query *
713 dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
714                        const struct in6_addr *addr, const char *dnsbl,
715                        dns_query_txt_fn *cbck, void *data);
716 UDNS_API struct dns_rr_a4 *
717 dns_resolve_a6dnsbl(struct dns_ctx *ctx,
718                     const struct in6_addr *addr, const char *dnsbl);
719 UDNS_API struct dns_rr_txt *
720 dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
721                         const struct in6_addr *addr, const char *dnsbl);
722
723 UDNS_API struct dns_query *
724 dns_submit_rhsbl(struct dns_ctx *ctx,
725                  const char *name, const char *rhsbl,
726                  dns_query_a4_fn *cbck, void *data);
727 UDNS_API struct dns_query *
728 dns_submit_rhsbl_txt(struct dns_ctx *ctx,
729                      const char *name, const char *rhsbl,
730                      dns_query_txt_fn *cbck, void *data);
731 UDNS_API struct dns_rr_a4 *
732 dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl);
733 UDNS_API struct dns_rr_txt *
734 dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl);
735
736 /**************************************************************************/
737 /**************** Names, Names ********************************************/
738
739 struct dns_nameval {
740   int val;
741   const char *name;
742 };
743
744 UDNS_DATA_API extern const struct dns_nameval dns_classtab[];
745 UDNS_DATA_API extern const struct dns_nameval dns_typetab[];
746 UDNS_DATA_API extern const struct dns_nameval dns_rcodetab[];
747 UDNS_API int
748 dns_findname(const struct dns_nameval *nv, const char *name);
749 #define dns_findclassname(cls) dns_findname(dns_classtab, (cls))
750 #define dns_findtypename(type) dns_findname(dns_typetab, (type))
751 #define dns_findrcodename(rcode) dns_findname(dns_rcodetab, (rcode))
752
753 UDNS_API const char *dns_classname(enum dns_class cls);
754 UDNS_API const char *dns_typename(enum dns_type type);
755 UDNS_API const char *dns_rcodename(enum dns_rcode rcode);
756 const char *_dns_format_code(char *buf, const char *prefix, int code);
757
758 UDNS_API const char *dns_strerror(int errnum);
759
760 /* simple pseudo-random number generator, code by Bob Jenkins */
761
762 struct udns_jranctx {   /* the context */
763   unsigned a, b, c, d;
764 };
765
766 /* initialize the RNG with a given seed */
767 UDNS_API void
768 udns_jraninit(struct udns_jranctx *x, unsigned seed);
769
770 /* return next random number.  32bits on most platforms so far. */
771 UDNS_API unsigned
772 udns_jranval(struct udns_jranctx *x);
773
774 #ifdef __cplusplus
775 } /* extern "C" */
776 #endif
777
778 #endif  /* include guard */