• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 2023 Brad House
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * SPDX-License-Identifier: MIT
25  */
26 #ifndef __ARES_DNS_RECORD_H
27 #define __ARES_DNS_RECORD_H
28 
29 /* Include ares.h, not this file directly */
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /*! \addtogroup ares_dns_record DNS Record Handling
36  *
37  * This is a set of functions to create and manipulate DNS records.
38  *
39  * @{
40  */
41 
42 /*! DNS Record types handled by c-ares.  Some record types may only be valid
43  *  on requests (e.g. ARES_REC_TYPE_ANY), and some may only be valid on
44  *  responses */
45 typedef enum {
46   ARES_REC_TYPE_A     = 1,     /*!< Host address. */
47   ARES_REC_TYPE_NS    = 2,     /*!< Authoritative server. */
48   ARES_REC_TYPE_CNAME = 5,     /*!< Canonical name. */
49   ARES_REC_TYPE_SOA   = 6,     /*!< Start of authority zone. */
50   ARES_REC_TYPE_PTR   = 12,    /*!< Domain name pointer. */
51   ARES_REC_TYPE_HINFO = 13,    /*!< Host information. */
52   ARES_REC_TYPE_MX    = 15,    /*!< Mail routing information. */
53   ARES_REC_TYPE_TXT   = 16,    /*!< Text strings. */
54   ARES_REC_TYPE_AAAA  = 28,    /*!< RFC 3596. Ip6 Address. */
55   ARES_REC_TYPE_SRV   = 33,    /*!< RFC 2782. Server Selection. */
56   ARES_REC_TYPE_NAPTR = 35,    /*!< RFC 3403. Naming Authority Pointer */
57   ARES_REC_TYPE_OPT   = 41,    /*!< RFC 6891. EDNS0 option (meta-RR) */
58 
59   ARES_REC_TYPE_TLSA = 52,     /*!< RFC 6698. DNS-Based Authentication of Named
60                                 *   Entities (DANE) Transport Layer Security
61                                 *   (TLS) Protocol: TLSA */
62   ARES_REC_TYPE_SVCB  = 64,    /*!< RFC 9460. General Purpose Service Binding */
63   ARES_REC_TYPE_HTTPS = 65,    /*!< RFC 9460. Service Binding type for use with
64                                 *   HTTPS */
65   ARES_REC_TYPE_ANY = 255,     /*!< Wildcard match.  Not response RR. */
66   ARES_REC_TYPE_URI = 256,     /*!< RFC 7553. Uniform Resource Identifier */
67   ARES_REC_TYPE_CAA = 257,     /*!< RFC 6844. Certification Authority
68                                 *   Authorization. */
69   ARES_REC_TYPE_RAW_RR = 65536 /*!< Used as an indicator that the RR record
70                                 *   is not parsed, but provided in wire
71                                 *   format */
72 } ares_dns_rec_type_t;
73 
74 /*! DNS Classes for requests and responses.  */
75 typedef enum {
76   ARES_CLASS_IN     = 1,   /*!< Internet */
77   ARES_CLASS_CHAOS  = 3,   /*!< CHAOS */
78   ARES_CLASS_HESOID = 4,   /*!< Hesoid [Dyer 87] */
79   ARES_CLASS_NONE   = 254, /*!< RFC 2136 */
80   ARES_CLASS_ANY    = 255  /*!< Any class (requests only) */
81 } ares_dns_class_t;
82 
83 /*! DNS RR Section type */
84 typedef enum {
85   ARES_SECTION_ANSWER     = 1, /*!< Answer section */
86   ARES_SECTION_AUTHORITY  = 2, /*!< Authority section */
87   ARES_SECTION_ADDITIONAL = 3  /*!< Additional information section */
88 } ares_dns_section_t;
89 
90 /*! DNS Header opcodes */
91 typedef enum {
92   ARES_OPCODE_QUERY  = 0, /*!< Standard query */
93   ARES_OPCODE_IQUERY = 1, /*!< Inverse query. Obsolete. */
94   ARES_OPCODE_STATUS = 2, /*!< Name server status query */
95   ARES_OPCODE_NOTIFY = 4, /*!< Zone change notification (RFC 1996) */
96   ARES_OPCODE_UPDATE = 5, /*!< Zone update message (RFC2136) */
97 } ares_dns_opcode_t;
98 
99 /*! DNS Header flags */
100 typedef enum {
101   ARES_FLAG_QR = 1 << 0, /*!< QR. If set, is a response */
102   ARES_FLAG_AA = 1 << 1, /*!< Authoritative Answer. If set, is authoritative */
103   ARES_FLAG_TC = 1 << 2, /*!< Truncation. If set, is truncated response */
104   ARES_FLAG_RD = 1 << 3, /*!< Recursion Desired. If set, recursion is desired */
105   ARES_FLAG_RA = 1 << 4, /*!< Recursion Available. If set, server supports
106                           *   recursion */
107   ARES_FLAG_AD = 1 << 5, /*!< RFC 2065. Authentic Data bit indicates in a
108                           * response that the data included has been verified by
109                           * the server providing it */
110   ARES_FLAG_CD = 1 << 6, /*!< RFC 2065. Checking Disabled bit indicates in a
111                           * query that non-verified data is acceptable to the
112                           * resolver sending the query. */
113 } ares_dns_flags_t;
114 
115 /*! DNS Response Codes from server */
116 typedef enum {
117   ARES_RCODE_NOERROR = 0,    /*!< Success */
118   ARES_RCODE_FORMERR = 1,    /*!< Format error. The name server was unable
119                               *   to interpret the query. */
120   ARES_RCODE_SERVFAIL = 2,   /*!< Server Failure. The name server was
121                               *   unable to process this query due to a
122                               *   problem with the nameserver */
123   ARES_RCODE_NXDOMAIN = 3,   /*!< Name Error.  Meaningful only for
124                               *   responses from an authoritative name
125                               *   server, this code signifies that the
126                               *   domain name referenced in the query does
127                               *   not exist. */
128   ARES_RCODE_NOTIMP = 4,     /*!< Not implemented.  The name server does
129                               *   not support the requested kind of
130                               *   query */
131   ARES_RCODE_REFUSED = 5,    /*!< Refused. The name server refuses to
132                               *   perform the specified operation for
133                               *   policy reasons. */
134   ARES_RCODE_YXDOMAIN = 6,   /*!< RFC 2136. Some name that ought not to
135                               *   exist, does exist. */
136   ARES_RCODE_YXRRSET = 7,    /*!< RFC 2136. Some RRset that ought to not
137                               *   exist, does exist. */
138   ARES_RCODE_NXRRSET = 8,    /*!< RFC 2136. Some RRset that ought to exist,
139                               *   does not exist. */
140   ARES_RCODE_NOTAUTH = 9,    /*!< RFC 2136. The server is not authoritative
141                               *   for the zone named in the Zone section.
142                               */
143   ARES_RCODE_NOTZONE = 10,   /*!< RFC 2136. A name used in the Prerequisite
144                               *   or Update Section is not within the zone
145                               *   denoted by the Zone Section. */
146   ARES_RCODE_DSOTYPEI  = 11, /*!< RFC 8409. DSO-TYPE Not implemented */
147   ARES_RCODE_BADSIG    = 16, /*!< RFC 8945. TSIG Signature Failure */
148   ARES_RCODE_BADKEY    = 17, /*!< RFC 8945. Key not recognized. */
149   ARES_RCODE_BADTIME   = 18, /*!< RFC 8945. Signature out of time window. */
150   ARES_RCODE_BADMODE   = 19, /*!< RFC 2930. Bad TKEY Mode */
151   ARES_RCODE_BADNAME   = 20, /*!< RFC 2930. Duplicate Key Name */
152   ARES_RCODE_BADALG    = 21, /*!< RFC 2930. Algorithm not supported */
153   ARES_RCODE_BADTRUNC  = 22, /*!< RFC 8945. Bad Truncation */
154   ARES_RCODE_BADCOOKIE = 23, /*!< RVC 7973. Bad/missing Server Cookie */
155 } ares_dns_rcode_t;
156 
157 /*! Data types used */
158 typedef enum {
159   ARES_DATATYPE_INADDR  = 1, /*!< struct in_addr * type */
160   ARES_DATATYPE_INADDR6 = 2, /*!< struct ares_in6_addr * type */
161   ARES_DATATYPE_U8      = 3, /*!< 8bit unsigned integer */
162   ARES_DATATYPE_U16     = 4, /*!< 16bit unsigned integer */
163   ARES_DATATYPE_U32     = 5, /*!< 32bit unsigned integer */
164   ARES_DATATYPE_NAME    = 6, /*!< Null-terminated string of a domain name */
165   ARES_DATATYPE_STR     = 7, /*!< Null-terminated string */
166   ARES_DATATYPE_BIN     = 8, /*!< Binary data */
167   ARES_DATATYPE_BINP    = 9, /*!< Officially defined as binary data, but likely
168                               *   printable. Guaranteed to have a NULL
169                               *   terminator for convenience (not included in
170                               *   length) */
171   ARES_DATATYPE_OPT = 10,    /*!< Array of options.  16bit identifier, BIN
172                               *   data. */
173 } ares_dns_datatype_t;
174 
175 /*! Keys used for all RR Types.  We take the record type and multiply by 100
176  *  to ensure we have a proper offset between keys so we can keep these sorted
177  */
178 typedef enum {
179   /*! A Record. Address. Datatype: INADDR */
180   ARES_RR_A_ADDR = (ARES_REC_TYPE_A * 100) + 1,
181   /*! NS Record. Name. Datatype: NAME */
182   ARES_RR_NS_NSDNAME = (ARES_REC_TYPE_NS * 100) + 1,
183   /*! CNAME Record. CName. Datatype: NAME */
184   ARES_RR_CNAME_CNAME = (ARES_REC_TYPE_CNAME * 100) + 1,
185   /*! SOA Record. MNAME, Primary Source of Data. Datatype: NAME */
186   ARES_RR_SOA_MNAME = (ARES_REC_TYPE_SOA * 100) + 1,
187   /*! SOA Record. RNAME, Mailbox of person responsible. Datatype: NAME */
188   ARES_RR_SOA_RNAME = (ARES_REC_TYPE_SOA * 100) + 2,
189   /*! SOA Record. Serial, version. Datatype: U32 */
190   ARES_RR_SOA_SERIAL = (ARES_REC_TYPE_SOA * 100) + 3,
191   /*! SOA Record. Refresh, zone refersh interval. Datatype: U32 */
192   ARES_RR_SOA_REFRESH = (ARES_REC_TYPE_SOA * 100) + 4,
193   /*! SOA Record. Retry, failed refresh retry interval. Datatype: U32 */
194   ARES_RR_SOA_RETRY = (ARES_REC_TYPE_SOA * 100) + 5,
195   /*! SOA Record. Expire, upper limit on authority. Datatype: U32 */
196   ARES_RR_SOA_EXPIRE = (ARES_REC_TYPE_SOA * 100) + 6,
197   /*! SOA Record. Minimum, RR TTL. Datatype: U32 */
198   ARES_RR_SOA_MINIMUM = (ARES_REC_TYPE_SOA * 100) + 7,
199   /*! PTR Record. DNAME, pointer domain. Datatype: NAME */
200   ARES_RR_PTR_DNAME = (ARES_REC_TYPE_PTR * 100) + 1,
201   /*! HINFO Record. CPU. Datatype: STR */
202   ARES_RR_HINFO_CPU = (ARES_REC_TYPE_HINFO * 100) + 1,
203   /*! HINFO Record. OS. Datatype: STR */
204   ARES_RR_HINFO_OS = (ARES_REC_TYPE_HINFO * 100) + 2,
205   /*! MX Record. Preference. Datatype: U16 */
206   ARES_RR_MX_PREFERENCE = (ARES_REC_TYPE_MX * 100) + 1,
207   /*! MX Record. Exchange, domain. Datatype: NAME */
208   ARES_RR_MX_EXCHANGE = (ARES_REC_TYPE_MX * 100) + 2,
209   /*! TXT Record. Data. Datatype: BINP */
210   ARES_RR_TXT_DATA = (ARES_REC_TYPE_TXT * 100) + 1,
211   /*! AAAA Record. Address. Datatype: INADDR6 */
212   ARES_RR_AAAA_ADDR = (ARES_REC_TYPE_AAAA * 100) + 1,
213   /*! SRV Record. Priority. Datatype: U16 */
214   ARES_RR_SRV_PRIORITY = (ARES_REC_TYPE_SRV * 100) + 2,
215   /*! SRV Record. Weight. Datatype: U16 */
216   ARES_RR_SRV_WEIGHT = (ARES_REC_TYPE_SRV * 100) + 3,
217   /*! SRV Record. Port. Datatype: U16 */
218   ARES_RR_SRV_PORT = (ARES_REC_TYPE_SRV * 100) + 4,
219   /*! SRV Record. Target domain. Datatype: NAME */
220   ARES_RR_SRV_TARGET = (ARES_REC_TYPE_SRV * 100) + 5,
221   /*! NAPTR Record. Order. Datatype: U16 */
222   ARES_RR_NAPTR_ORDER = (ARES_REC_TYPE_NAPTR * 100) + 1,
223   /*! NAPTR Record. Preference. Datatype: U16 */
224   ARES_RR_NAPTR_PREFERENCE = (ARES_REC_TYPE_NAPTR * 100) + 2,
225   /*! NAPTR Record. Flags. Datatype: STR */
226   ARES_RR_NAPTR_FLAGS = (ARES_REC_TYPE_NAPTR * 100) + 3,
227   /*! NAPTR Record. Services. Datatype: STR */
228   ARES_RR_NAPTR_SERVICES = (ARES_REC_TYPE_NAPTR * 100) + 4,
229   /*! NAPTR Record. Regexp. Datatype: STR */
230   ARES_RR_NAPTR_REGEXP = (ARES_REC_TYPE_NAPTR * 100) + 5,
231   /*! NAPTR Record. Replacement. Datatype: NAME */
232   ARES_RR_NAPTR_REPLACEMENT = (ARES_REC_TYPE_NAPTR * 100) + 6,
233   /*! OPT Record. UDP Size. Datatype: U16 */
234   ARES_RR_OPT_UDP_SIZE = (ARES_REC_TYPE_OPT * 100) + 1,
235   /*! OPT Record. Version. Datatype: U8 */
236   ARES_RR_OPT_VERSION = (ARES_REC_TYPE_OPT * 100) + 3,
237   /*! OPT Record. Flags. Datatype: U16 */
238   ARES_RR_OPT_FLAGS = (ARES_REC_TYPE_OPT * 100) + 4,
239   /*! OPT Record. Options. Datatype: OPT */
240   ARES_RR_OPT_OPTIONS = (ARES_REC_TYPE_OPT * 100) + 5,
241   /*! TLSA Record. Certificate Usage. Datatype: U8 */
242   ARES_RR_TLSA_CERT_USAGE = (ARES_REC_TYPE_TLSA * 100) + 1,
243   /*! TLSA Record. Selector. Datatype: U8 */
244   ARES_RR_TLSA_SELECTOR = (ARES_REC_TYPE_TLSA * 100) + 2,
245   /*! TLSA Record. Matching Type. Datatype: U8 */
246   ARES_RR_TLSA_MATCH = (ARES_REC_TYPE_TLSA * 100) + 3,
247   /*! TLSA Record. Certificate Association Data. Datatype: BIN */
248   ARES_RR_TLSA_DATA = (ARES_REC_TYPE_TLSA * 100) + 4,
249   /*! SVCB Record. SvcPriority. Datatype: U16 */
250   ARES_RR_SVCB_PRIORITY = (ARES_REC_TYPE_SVCB * 100) + 1,
251   /*! SVCB Record. TargetName. Datatype: NAME */
252   ARES_RR_SVCB_TARGET = (ARES_REC_TYPE_SVCB * 100) + 2,
253   /*! SVCB Record. SvcParams. Datatype: OPT */
254   ARES_RR_SVCB_PARAMS = (ARES_REC_TYPE_SVCB * 100) + 3,
255   /*! HTTPS Record. SvcPriority. Datatype: U16 */
256   ARES_RR_HTTPS_PRIORITY = (ARES_REC_TYPE_HTTPS * 100) + 1,
257   /*! HTTPS Record. TargetName. Datatype: NAME */
258   ARES_RR_HTTPS_TARGET = (ARES_REC_TYPE_HTTPS * 100) + 2,
259   /*! HTTPS Record. SvcParams. Datatype: OPT */
260   ARES_RR_HTTPS_PARAMS = (ARES_REC_TYPE_HTTPS * 100) + 3,
261   /*! URI Record. Priority. Datatype: U16 */
262   ARES_RR_URI_PRIORITY = (ARES_REC_TYPE_URI * 100) + 1,
263   /*! URI Record. Weight. Datatype: U16 */
264   ARES_RR_URI_WEIGHT = (ARES_REC_TYPE_URI * 100) + 2,
265   /*! URI Record. Target domain. Datatype: NAME */
266   ARES_RR_URI_TARGET = (ARES_REC_TYPE_URI * 100) + 3,
267   /*! CAA Record. Critical flag. Datatype: U8 */
268   ARES_RR_CAA_CRITICAL = (ARES_REC_TYPE_CAA * 100) + 1,
269   /*! CAA Record. Tag/Property. Datatype: STR */
270   ARES_RR_CAA_TAG = (ARES_REC_TYPE_CAA * 100) + 2,
271   /*! CAA Record. Value. Datatype: BINP */
272   ARES_RR_CAA_VALUE = (ARES_REC_TYPE_CAA * 100) + 3,
273   /*! RAW Record. RR Type. Datatype: U16 */
274   ARES_RR_RAW_RR_TYPE = (ARES_REC_TYPE_RAW_RR * 100) + 1,
275   /*! RAW Record. RR Data. Datatype: BIN */
276   ARES_RR_RAW_RR_DATA = (ARES_REC_TYPE_RAW_RR * 100) + 2,
277 } ares_dns_rr_key_t;
278 
279 /*! TLSA Record ARES_RR_TLSA_CERT_USAGE known values */
280 typedef enum {
281   /*! Certificate Usage 0. CA Constraint. */
282   ARES_TLSA_USAGE_CA = 0,
283   /*! Certificate Usage 1. Service Certificate Constraint. */
284   ARES_TLSA_USAGE_SERVICE = 1,
285   /*! Certificate Usage 2. Trust Anchor Assertion. */
286   ARES_TLSA_USAGE_TRUSTANCHOR = 2,
287   /*! Certificate Usage 3. Domain-issued certificate. */
288   ARES_TLSA_USAGE_DOMAIN = 3
289 } ares_tlsa_usage_t;
290 
291 /*! TLSA Record ARES_RR_TLSA_SELECTOR known values */
292 typedef enum {
293   /*! Full Certificate */
294   ARES_TLSA_SELECTOR_FULL = 0,
295   /*! DER-encoded SubjectPublicKeyInfo */
296   ARES_TLSA_SELECTOR_SUBJPUBKEYINFO = 1
297 } ares_tlsa_selector_t;
298 
299 /*! TLSA Record ARES_RR_TLSA_MATCH known values */
300 typedef enum {
301   /*! Exact match */
302   ARES_TLSA_MATCH_EXACT = 0,
303   /*! Sha256 match */
304   ARES_TLSA_MATCH_SHA256 = 1,
305   /*! Sha512 match */
306   ARES_TLSA_MATCH_SHA512 = 2
307 } ares_tlsa_match_t;
308 
309 /*! SVCB (and HTTPS) RR known parameters */
310 typedef enum {
311   /*! Mandatory keys in this RR (RFC 9460 Section 8) */
312   ARES_SVCB_PARAM_MANDATORY = 0,
313   /*! Additional supported protocols (RFC 9460 Section 7.1) */
314   ARES_SVCB_PARAM_ALPN = 1,
315   /*! No support for default protocol (RFC 9460 Section 7.1) */
316   ARES_SVCB_PARAM_NO_DEFAULT_ALPN = 2,
317   /*! Port for alternative endpoint (RFC 9460 Section 7.2) */
318   ARES_SVCB_PARAM_PORT = 3,
319   /*! IPv4 address hints (RFC 9460 Section 7.3) */
320   ARES_SVCB_PARAM_IPV4HINT = 4,
321   /*! RESERVED (held for Encrypted ClientHello) */
322   ARES_SVCB_PARAM_ECH = 5,
323   /*! IPv6 address hints (RFC 9460 Section 7.3) */
324   ARES_SVCB_PARAM_IPV6HINT = 6
325 } ares_svcb_param_t;
326 
327 /*! OPT RR known parameters */
328 typedef enum {
329   /*! RFC 8764. Apple's DNS Long-Lived Queries Protocol */
330   ARES_OPT_PARAM_LLQ = 1,
331   /*! http://files.dns-sd.org/draft-sekar-dns-ul.txt: Update Lease */
332   ARES_OPT_PARAM_UL = 2,
333   /*! RFC 5001. Name Server Identification */
334   ARES_OPT_PARAM_NSID = 3,
335   /*! RFC 6975. DNSSEC Algorithm Understood */
336   ARES_OPT_PARAM_DAU = 5,
337   /*! RFC 6975. DS Hash Understood */
338   ARES_OPT_PARAM_DHU = 6,
339   /*! RFC 6975. NSEC3 Hash Understood */
340   ARES_OPT_PARAM_N3U = 7,
341   /*! RFC 7871. Client Subnet */
342   ARES_OPT_PARAM_EDNS_CLIENT_SUBNET = 8,
343   /*! RFC 7314. Expire Timer */
344   ARES_OPT_PARAM_EDNS_EXPIRE = 9,
345   /*! RFC 7873. Client and Server Cookies */
346   ARES_OPT_PARAM_COOKIE = 10,
347   /*! RFC 7828. TCP Keepalive timeout */
348   ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE = 11,
349   /*! RFC 7830. Padding */
350   ARES_OPT_PARAM_PADDING = 12,
351   /*! RFC 7901. Chain query requests */
352   ARES_OPT_PARAM_CHAIN = 13,
353   /*! RFC 8145. Signaling Trust Anchor Knowledge in DNSSEC */
354   ARES_OPT_PARAM_EDNS_KEY_TAG = 14,
355   /*! RFC 8914. Extended ERROR code and message */
356   ARES_OPT_PARAM_EXTENDED_DNS_ERROR = 15,
357 } ares_opt_param_t;
358 
359 /*! Data type for option records for keys like ARES_RR_OPT_OPTIONS and
360  *  ARES_RR_HTTPS_PARAMS returned by ares_dns_opt_get_datatype() */
361 typedef enum {
362   /*! No value allowed for this option */
363   ARES_OPT_DATATYPE_NONE = 1,
364   /*! List of strings, each prefixed with a single octet representing the length
365    */
366   ARES_OPT_DATATYPE_STR_LIST = 2,
367   /*! List of 8bit integers, concatenated */
368   ARES_OPT_DATATYPE_U8_LIST = 3,
369   /*! 16bit integer in network byte order */
370   ARES_OPT_DATATYPE_U16 = 4,
371   /*! list of 16bit integer in network byte order, concatenated. */
372   ARES_OPT_DATATYPE_U16_LIST = 5,
373   /*! 32bit integer in network byte order */
374   ARES_OPT_DATATYPE_U32 = 6,
375   /*! list 32bit integer in network byte order, concatenated */
376   ARES_OPT_DATATYPE_U32_LIST = 7,
377   /*! List of ipv4 addresses in network byte order, concatenated */
378   ARES_OPT_DATATYPE_INADDR4_LIST = 8,
379   /*! List of ipv6 addresses in network byte order, concatenated */
380   ARES_OPT_DATATYPE_INADDR6_LIST = 9,
381   /*! Binary Data */
382   ARES_OPT_DATATYPE_BIN = 10,
383   /*! DNS Domain Name Format */
384   ARES_OPT_DATATYPE_NAME = 11
385 } ares_dns_opt_datatype_t;
386 
387 /*! Data type for flags to ares_dns_parse() */
388 typedef enum {
389   /*! Parse Answers from RFC 1035 that allow name compression as RAW */
390   ARES_DNS_PARSE_AN_BASE_RAW = 1 << 0,
391   /*! Parse Authority from RFC 1035 that allow name compression as RAW */
392   ARES_DNS_PARSE_NS_BASE_RAW = 1 << 1,
393   /*! Parse Additional from RFC 1035 that allow name compression as RAW */
394   ARES_DNS_PARSE_AR_BASE_RAW = 1 << 2,
395   /*! Parse Answers from later RFCs (no name compression) RAW */
396   ARES_DNS_PARSE_AN_EXT_RAW  = 1 << 3,
397   /*! Parse Authority from later RFCs (no name compression) as RAW */
398   ARES_DNS_PARSE_NS_EXT_RAW  = 1 << 4,
399   /*< Parse Additional from later RFCs (no name compression) as RAW */
400   ARES_DNS_PARSE_AR_EXT_RAW  = 1 << 5
401 } ares_dns_parse_flags_t;
402 
403 /*! String representation of DNS Record Type
404  *
405  *  \param[in] type  DNS Record Type
406  *  \return string
407  */
408 CARES_EXTERN const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type);
409 
410 /*! String representation of DNS Class
411  *
412  *  \param[in] qclass  DNS Class
413  *  \return string
414  */
415 CARES_EXTERN const char *ares_dns_class_tostr(ares_dns_class_t qclass);
416 
417 /*! String representation of DNS OpCode
418  *
419  *  \param[in] opcode  DNS OpCode
420  *  \return string
421  */
422 CARES_EXTERN const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode);
423 
424 /*! String representation of DNS Resource Record Parameter
425  *
426  *  \param[in] key  DNS Resource Record parameter
427  *  \return string
428  */
429 CARES_EXTERN const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key);
430 
431 /*! String representation of DNS Resource Record section
432  *
433  * \param[in] section  Section
434  * \return string
435  */
436 CARES_EXTERN const char *ares_dns_section_tostr(ares_dns_section_t section);
437 
438 /*! Convert DNS class name as string to ares_dns_class_t
439  *
440  *  \param[out] qclass  Pointer passed by reference to write class
441  *  \param[in]  str     String to convert
442  *  \return ARES_TRUE on success
443  */
444 CARES_EXTERN ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass,
445                                                 const char       *str);
446 
447 /*! Convert DNS record type as string to ares_dns_rec_type_t
448  *
449  *  \param[out] qtype   Pointer passed by reference to write record type
450  *  \param[in]  str     String to convert
451  *  \return ARES_TRUE on success
452  */
453 CARES_EXTERN ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype,
454                                                    const char          *str);
455 
456 
457 /*! Convert DNS response code as string to from ares_dns_rcode_t
458  *
459  *  \param[in] rcode  Response code to convert
460  *  \return ARES_TRUE on success
461  */
462 CARES_EXTERN const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode);
463 
464 /*! Convert any valid ip address (ipv4 or ipv6) into struct ares_addr and
465  *  return the starting pointer of the network byte order address and the
466  *  length of the address (4 or 16).
467  *
468  *  \param[in]     ipaddr  ASCII string form of the ip address
469  *  \param[in,out] addr    Must set "family" member to one of AF_UNSPEC,
470  *                         AF_INET, AF_INET6 on input.
471  *  \param[out]    ptr_len Length of binary form address
472  *  \return Pointer to start of binary address or NULL on error.
473  */
474 CARES_EXTERN const void *ares_dns_pton(const char       *ipaddr,
475                                        struct ares_addr *addr, size_t *out_len);
476 
477 /*! Convert an ip address into the PTR format for in-addr.arpa or in6.arpa
478  *
479  *  \param[in]  addr  properly filled address structure
480  *  \return  String representing PTR, use ares_free_string() to free
481  */
482 CARES_EXTERN char       *ares_dns_addr_to_ptr(const struct ares_addr *addr);
483 
484 
485 /*! The options/parameters extensions to some RRs can be somewhat opaque, this
486  *  is a helper to return the best match for a datatype for interpreting the
487  *  option record.
488  *
489  *  \param[in] key  Key associated with options/parameters
490  *  \param[in] opt  Option Key/Parameter
491  *  \return Datatype
492  */
493 CARES_EXTERN ares_dns_opt_datatype_t
494   ares_dns_opt_get_datatype(ares_dns_rr_key_t key, unsigned short opt);
495 
496 /*! The options/parameters extensions to some RRs can be somewhat opaque, this
497  *  is a helper to return the name if the option is known.
498  *
499  *  \param[in] key  Key associated with options/parameters
500  *  \param[in] opt  Option Key/Parameter
501  *  \return name, or NULL if not known.
502  */
503 CARES_EXTERN const char *ares_dns_opt_get_name(ares_dns_rr_key_t key,
504                                                unsigned short    opt);
505 
506 
507 /*! Retrieve a list of Resource Record keys that can be set or retrieved for
508  *  the Resource record type.
509  *
510  *  \param[in]  type  Record Type
511  *  \param[out] cnt   Number of keys returned
512  *  \return array of keys associated with Resource Record
513  */
514 CARES_EXTERN const ares_dns_rr_key_t *
515   ares_dns_rr_get_keys(ares_dns_rec_type_t type, size_t *cnt);
516 
517 /*! Retrieve the datatype associated with a Resource Record key.
518  *
519  *  \param[in] key   Resource Record Key
520  *  \return datatype
521  */
522 CARES_EXTERN ares_dns_datatype_t
523   ares_dns_rr_key_datatype(ares_dns_rr_key_t key);
524 
525 /*! Retrieve the DNS Resource Record type associated with a Resource Record key.
526  *
527  *  \param[in] key   Resource Record Key
528  *  \return DNS Resource Record Type
529  */
530 CARES_EXTERN ares_dns_rec_type_t
531   ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key);
532 
533 /*! Opaque data type representing a DNS RR (Resource Record) */
534 struct ares_dns_rr;
535 
536 /*! Typedef for opaque data type representing a DNS RR (Resource Record) */
537 typedef struct ares_dns_rr ares_dns_rr_t;
538 
539 /*! Opaque data type representing a DNS Query Data QD Packet */
540 struct ares_dns_qd;
541 
542 /*! Typedef for opaque data type representing a DNS Query Data QD Packet */
543 typedef struct ares_dns_qd ares_dns_qd_t;
544 
545 /*! Opaque data type representing a DNS Packet */
546 struct ares_dns_record;
547 
548 /*! Typedef for opaque data type representing a DNS Packet */
549 typedef struct ares_dns_record ares_dns_record_t;
550 
551 
552 /*! Create a new DNS record object
553  *
554  *  \param[out] dnsrec  Pointer passed by reference for a newly allocated
555  *                      record object.  Must be ares_dns_record_destroy()'d by
556  *                      caller.
557  *  \param[in]  id      DNS Query ID.  If structuring a new query to be sent
558  *                      with ares_send(), this value should be zero.
559  *  \param[in]  flags   DNS Flags from \ares_dns_flags_t
560  *  \param[in]  opcode  DNS OpCode (typically ARES_OPCODE_QUERY)
561  *  \param[in]  rcode   DNS RCode
562  *  \return ARES_SUCCESS on success
563  */
564 CARES_EXTERN ares_status_t ares_dns_record_create(ares_dns_record_t **dnsrec,
565                                                   unsigned short      id,
566                                                   unsigned short      flags,
567                                                   ares_dns_opcode_t   opcode,
568                                                   ares_dns_rcode_t    rcode);
569 
570 /*! Destroy a DNS record object
571  *
572  *  \param[in] dnsrec  Initialized record object
573  */
574 CARES_EXTERN void          ares_dns_record_destroy(ares_dns_record_t *dnsrec);
575 
576 /*! Get the DNS Query ID
577  *
578  *  \param[in] dnsrec  Initialized record object
579  *  \return DNS query id
580  */
581 CARES_EXTERN unsigned short
582   ares_dns_record_get_id(const ares_dns_record_t *dnsrec);
583 
584 /*! Get the DNS Record Flags
585  *
586  *  \param[in] dnsrec  Initialized record object
587  *  \return One or more \ares_dns_flags_t
588  */
589 CARES_EXTERN unsigned short
590   ares_dns_record_get_flags(const ares_dns_record_t *dnsrec);
591 
592 /*! Get the DNS Record OpCode
593  *
594  *  \param[in] dnsrec  Initialized record object
595  *  \return opcode
596  */
597 CARES_EXTERN ares_dns_opcode_t
598   ares_dns_record_get_opcode(const ares_dns_record_t *dnsrec);
599 
600 /*! Get the DNS Record RCode
601  *
602  *  \param[in] dnsrec  Initialized record object
603  *  \return rcode
604  */
605 CARES_EXTERN ares_dns_rcode_t
606   ares_dns_record_get_rcode(const ares_dns_record_t *dnsrec);
607 
608 /*! Add a query to the DNS Record.  Typically a record will have only 1
609  *  query. Most DNS servers will reject queries with more than 1 question.
610  *
611  * \param[in] dnsrec  Initialized record object
612  * \param[in] name    Name/Hostname of request
613  * \param[in] qtype   Type of query
614  * \param[in] qclass  Class of query (typically ARES_CLASS_IN)
615  * \return ARES_SUCCESS on success
616  */
617 CARES_EXTERN ares_status_t ares_dns_record_query_add(ares_dns_record_t  *dnsrec,
618                                                      const char         *name,
619                                                      ares_dns_rec_type_t qtype,
620                                                      ares_dns_class_t qclass);
621 
622 /*! Get the count of queries in the DNS Record
623  *
624  * \param[in] dnsrec  Initialized record object
625  * \return count of queries
626  */
627 CARES_EXTERN size_t ares_dns_record_query_cnt(const ares_dns_record_t *dnsrec);
628 
629 /*! Get the data about the query at the provided index.
630  *
631  * \param[in]  dnsrec  Initialized record object
632  * \param[in]  idx     Index of query
633  * \param[out] name    Optional.  Returns name, may pass NULL if not desired.
634  * \param[out] qtype   Optional.  Returns record type, may pass NULL.
635  * \param[out] qclass  Optional.  Returns class, may pass NULL.
636  * \return ARES_SUCCESS on success
637  */
638 CARES_EXTERN ares_status_t ares_dns_record_query_get(
639   const ares_dns_record_t *dnsrec, size_t idx, const char **name,
640   ares_dns_rec_type_t *qtype, ares_dns_class_t *qclass);
641 
642 /*! Get the count of Resource Records in the provided section
643  *
644  * \param[in] dnsrec  Initialized record object
645  * \param[in] sect    Section.  ARES_SECTION_ANSWER is most used.
646  * \return count of resource records.
647  */
648 CARES_EXTERN size_t ares_dns_record_rr_cnt(const ares_dns_record_t *dnsrec,
649                                            ares_dns_section_t       sect);
650 
651 
652 /*! Add a Resource Record to the DNS Record.
653  *
654  *  \param[out] rr_out   Pointer to created resource record.  This pointer
655  *                       is owned by the DNS record itself, this is just made
656  *                       available to facilitate adding RR-specific fields.
657  *  \param[in]  dnsrec   Initialized record object
658  *  \param[in]  sect     Section to add resource record to
659  *  \param[in]  name     Resource Record name/hostname
660  *  \param[in]  type     Record Type
661  *  \param[in]  rclass   Class
662  *  \param[in]  ttl      TTL
663  *  \return ARES_SUCCESS on success
664  */
665 CARES_EXTERN ares_status_t ares_dns_record_rr_add(
666   ares_dns_rr_t **rr_out, ares_dns_record_t *dnsrec, ares_dns_section_t sect,
667   const char *name, ares_dns_rec_type_t type, ares_dns_class_t rclass,
668   unsigned int ttl);
669 
670 /*! Fetch a resource record based on the section and index.
671  *
672  *  \param[in]  dnsrec   Initialized record object
673  *  \param[in]  sect     Section for resource record
674  *  \param[in]  idx      Index of resource record in section
675  *  \return NULL on misuse, otherwise a pointer to the resource record
676  */
677 CARES_EXTERN ares_dns_rr_t *ares_dns_record_rr_get(ares_dns_record_t *dnsrec,
678                                                    ares_dns_section_t sect,
679                                                    size_t             idx);
680 
681 
682 /*! Remove the resource record based on the section and index
683  *
684  *  \param[in]  dnsrec   Initialized record object
685  *  \param[in]  sect     Section for resource record
686  *  \param[in]  idx      Index of resource record in section
687  *  \return ARES_SUCCESS on success, otherwise an error code.
688  */
689 CARES_EXTERN ares_status_t  ares_dns_record_rr_del(ares_dns_record_t *dnsrec,
690                                                    ares_dns_section_t sect,
691                                                    size_t             idx);
692 
693 
694 /*! Retrieve the resource record Name/Hostname
695  *
696  *  \param[in] rr  Pointer to resource record
697  *  \return Name
698  */
699 CARES_EXTERN const char    *ares_dns_rr_get_name(const ares_dns_rr_t *rr);
700 
701 /*! Retrieve the resource record type
702  *
703  *  \param[in] rr  Pointer to resource record
704  *  \return type
705  */
706 CARES_EXTERN ares_dns_rec_type_t ares_dns_rr_get_type(const ares_dns_rr_t *rr);
707 
708 /*! Retrieve the resource record class
709  *
710  *  \param[in] rr  Pointer to resource record
711  *  \return class
712  */
713 CARES_EXTERN ares_dns_class_t    ares_dns_rr_get_class(const ares_dns_rr_t *rr);
714 
715 /*! Retrieve the resource record TTL
716  *
717  *  \param[in] rr  Pointer to resource record
718  *  \return TTL
719  */
720 CARES_EXTERN unsigned int        ares_dns_rr_get_ttl(const ares_dns_rr_t *rr);
721 
722 /*! Set ipv4 address data type for specified resource record and key.  Can
723  *  only be used on keys with datatype ARES_DATATYPE_INADDR
724  *
725  *  \param[in] dns_rr Pointer to resource record
726  *  \param[in] key    DNS Resource Record Key
727  *  \param[in] addr   Pointer to ipv4 address to use.
728  *  \return ARES_SUCCESS on success
729  */
730 CARES_EXTERN ares_status_t       ares_dns_rr_set_addr(ares_dns_rr_t        *dns_rr,
731                                                       ares_dns_rr_key_t     key,
732                                                       const struct in_addr *addr);
733 
734 /*! Set ipv6 address data type for specified resource record and key.  Can
735  *  only be used on keys with datatype ARES_DATATYPE_INADDR6
736  *
737  *  \param[in] dns_rr Pointer to resource record
738  *  \param[in] key    DNS Resource Record Key
739  *  \param[in] addr   Pointer to ipv6 address to use.
740  *  \return ARES_SUCCESS on success
741  */
742 CARES_EXTERN ares_status_t
743   ares_dns_rr_set_addr6(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key,
744                         const struct ares_in6_addr *addr);
745 
746 /*! Set string data for specified resource record and key.  Can
747  *  only be used on keys with datatype ARES_DATATYPE_STR or ARES_DATATYPE_NAME.
748  *
749  *  \param[in] dns_rr Pointer to resource record
750  *  \param[in] key    DNS Resource Record Key
751  *  \param[in] val    Pointer to string to set.
752  *  \return ARES_SUCCESS on success
753  */
754 CARES_EXTERN ares_status_t ares_dns_rr_set_str(ares_dns_rr_t    *dns_rr,
755                                                ares_dns_rr_key_t key,
756                                                const char       *val);
757 
758 /*! Set 8bit unsigned integer for specified resource record and key.  Can
759  *  only be used on keys with datatype ARES_DATATYPE_U8
760  *
761  *  \param[in] dns_rr Pointer to resource record
762  *  \param[in] key    DNS Resource Record Key
763  *  \param[in] val    8bit unsigned integer
764  *  \return ARES_SUCCESS on success
765  */
766 CARES_EXTERN ares_status_t ares_dns_rr_set_u8(ares_dns_rr_t    *dns_rr,
767                                               ares_dns_rr_key_t key,
768                                               unsigned char     val);
769 
770 /*! Set 16bit unsigned integer for specified resource record and key.  Can
771  *  only be used on keys with datatype ARES_DATATYPE_U16
772  *
773  *  \param[in] dns_rr Pointer to resource record
774  *  \param[in] key    DNS Resource Record Key
775  *  \param[in] val    16bit unsigned integer
776  *  \return ARES_SUCCESS on success
777  */
778 CARES_EXTERN ares_status_t ares_dns_rr_set_u16(ares_dns_rr_t    *dns_rr,
779                                                ares_dns_rr_key_t key,
780                                                unsigned short    val);
781 
782 /*! Set 32bit unsigned integer for specified resource record and key.  Can
783  *  only be used on keys with datatype ARES_DATATYPE_U32
784  *
785  *  \param[in] dns_rr Pointer to resource record
786  *  \param[in] key    DNS Resource Record Key
787  *  \param[in] val    32bit unsigned integer
788  *  \return ARES_SUCCESS on success
789  */
790 CARES_EXTERN ares_status_t ares_dns_rr_set_u32(ares_dns_rr_t    *dns_rr,
791                                                ares_dns_rr_key_t key,
792                                                unsigned int      val);
793 
794 /*! Set binary (BIN or BINP) data for specified resource record and key.  Can
795  *  only be used on keys with datatype ARES_DATATYPE_BIN or ARES_DATATYPE_BINP.
796  *
797  *  \param[in] dns_rr Pointer to resource record
798  *  \param[in] key    DNS Resource Record Key
799  *  \param[in] val    Pointer to binary data.
800  *  \param[in] len    Length of binary data
801  *  \return ARES_SUCCESS on success
802  */
803 CARES_EXTERN ares_status_t ares_dns_rr_set_bin(ares_dns_rr_t       *dns_rr,
804                                                ares_dns_rr_key_t    key,
805                                                const unsigned char *val,
806                                                size_t               len);
807 
808 /*! Set the option for the RR
809  *
810  *  \param[in]  dns_rr   Pointer to resource record
811  *  \param[in]  key      DNS Resource Record Key
812  *  \param[in]  opt      Option record key id.
813  *  \param[out] val      Optional. Value to associate with option.
814  *  \param[out] val_len  Length of value passed.
815  *  \return ARES_SUCCESS on success
816  */
817 CARES_EXTERN ares_status_t ares_dns_rr_set_opt(ares_dns_rr_t       *dns_rr,
818                                                ares_dns_rr_key_t    key,
819                                                unsigned short       opt,
820                                                const unsigned char *val,
821                                                size_t               val_len);
822 
823 /*! Retrieve a pointer to the ipv4 address.  Can only be used on keys with
824  *  datatype ARES_DATATYPE_INADDR.
825  *
826  *  \param[in] dns_rr Pointer to resource record
827  *  \param[in] key    DNS Resource Record Key
828  *  \return pointer to ipv4 address or NULL on error
829  */
830 CARES_EXTERN const struct in_addr *
831   ares_dns_rr_get_addr(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key);
832 
833 /*! Retrieve a pointer to the ipv6 address.  Can only be used on keys with
834  *  datatype ARES_DATATYPE_INADDR6.
835  *
836  *  \param[in] dns_rr Pointer to resource record
837  *  \param[in] key    DNS Resource Record Key
838  *  \return pointer to ipv6 address or NULL on error
839  */
840 CARES_EXTERN const struct ares_in6_addr *
841   ares_dns_rr_get_addr6(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key);
842 
843 /*! Retrieve a pointer to the string.  Can only be used on keys with
844  *  datatype ARES_DATATYPE_STR and ARES_DATATYPE_NAME.
845  *
846  *  \param[in] dns_rr Pointer to resource record
847  *  \param[in] key    DNS Resource Record Key
848  *  \return pointer string or NULL on error
849  */
850 CARES_EXTERN const char    *ares_dns_rr_get_str(const ares_dns_rr_t *dns_rr,
851                                                 ares_dns_rr_key_t    key);
852 
853 /*! Retrieve an 8bit unsigned integer.  Can only be used on keys with
854  *  datatype ARES_DATATYPE_U8.
855  *
856  *  \param[in] dns_rr Pointer to resource record
857  *  \param[in] key    DNS Resource Record Key
858  *  \return 8bit unsigned integer
859  */
860 CARES_EXTERN unsigned char  ares_dns_rr_get_u8(const ares_dns_rr_t *dns_rr,
861                                                ares_dns_rr_key_t    key);
862 
863 /*! Retrieve an 16bit unsigned integer.  Can only be used on keys with
864  *  datatype ARES_DATATYPE_U16.
865  *
866  *  \param[in] dns_rr Pointer to resource record
867  *  \param[in] key    DNS Resource Record Key
868  *  \return 16bit unsigned integer
869  */
870 CARES_EXTERN unsigned short ares_dns_rr_get_u16(const ares_dns_rr_t *dns_rr,
871                                                 ares_dns_rr_key_t    key);
872 
873 /*! Retrieve an 32bit unsigned integer.  Can only be used on keys with
874  *  datatype ARES_DATATYPE_U32.
875  *
876  *  \param[in] dns_rr Pointer to resource record
877  *  \param[in] key    DNS Resource Record Key
878  *  \return 32bit unsigned integer
879  */
880 CARES_EXTERN unsigned int   ares_dns_rr_get_u32(const ares_dns_rr_t *dns_rr,
881                                                 ares_dns_rr_key_t    key);
882 
883 /*! Retrieve a pointer to the binary data.  Can only be used on keys with
884  *  datatype ARES_DATATYPE_BIN or ARES_DATATYPE_BINP.  If BINP, the data is
885  *  guaranteed to have a NULL terminator which is NOT included in the length.
886  *
887  *  \param[in]  dns_rr Pointer to resource record
888  *  \param[in]  key    DNS Resource Record Key
889  *  \param[out] len    Length of binary data returned
890  *  \return pointer binary data or NULL on error
891  */
892 CARES_EXTERN const unsigned char *
893   ares_dns_rr_get_bin(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key,
894                       size_t *len);
895 
896 /*! Retrieve the number of options stored for the RR.
897  *
898  *  \param[in] dns_rr Pointer to resource record
899  *  \param[in] key    DNS Resource Record Key
900  *  \return count, or 0 if none.
901  */
902 CARES_EXTERN size_t ares_dns_rr_get_opt_cnt(const ares_dns_rr_t *dns_rr,
903                                             ares_dns_rr_key_t    key);
904 
905 /*! Retrieve the option for the RR by index.
906  *
907  *  \param[in]  dns_rr  Pointer to resource record
908  *  \param[in]  key     DNS Resource Record Key
909  *  \param[in]  idx     Index of option record
910  *  \param[out] val     Optional. Pointer passed by reference to hold value.
911  *                      Options may not have values.  Value if returned is
912  *                      guaranteed to be NULL terminated, however in most
913  *                      cases it is not printable.
914  *  \param[out] val_len Optional. Pointer passed by reference to hold value
915  *                      length.
916  *  \return option key/id on success, 65535 on misuse.
917  */
918 CARES_EXTERN unsigned short
919   ares_dns_rr_get_opt(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key,
920                       size_t idx, const unsigned char **val, size_t *val_len);
921 
922 /*! Retrieve the option for the RR by the option key/id.
923  *
924  *  \param[in]  dns_rr  Pointer to resource record
925  *  \param[in]  key     DNS Resource Record Key
926  *  \param[in]  opt     Option record key id (this is not the index).
927  *  \param[out] val     Optional. Pointer passed by reference to hold value.
928  *                      Options may not have values. Value if returned is
929  *                      guaranteed to be NULL terminated, however in most cases
930  *                      it is not printable.
931  *  \param[out] val_len Optional. Pointer passed by reference to hold value
932  *                      length.
933  *  \return ARES_TRUE on success, ARES_FALSE on misuse.
934  */
935 CARES_EXTERN ares_bool_t   ares_dns_rr_get_opt_byid(const ares_dns_rr_t  *dns_rr,
936                                                     ares_dns_rr_key_t     key,
937                                                     unsigned short        opt,
938                                                     const unsigned char **val,
939                                                     size_t *val_len);
940 
941 /*! Parse a complete DNS message.
942  *
943  *  \param[in]  buf      pointer to bytes to be parsed
944  *  \param[in]  buf_len  Length of buf provided
945  *  \param[in]  flags    Flags dictating how the message should be parsed.
946  *  \param[out] dnsrec   Pointer passed by reference for a new DNS record object
947  *                       that must be ares_dns_record_destroy()'d by caller.
948  *  \return ARES_SUCCESS on success
949  */
950 CARES_EXTERN ares_status_t ares_dns_parse(const unsigned char *buf,
951                                           size_t buf_len, unsigned int flags,
952                                           ares_dns_record_t **dnsrec);
953 
954 /*! Write a complete DNS message
955  *
956  *  \param[in]  dnsrec   Pointer to initialized and filled DNS record object.
957  *  \param[out] buf      Pointer passed by reference to be filled in with with
958  *                       DNS message.  Must be ares_free()'d by caller.
959  *  \param[out] buf_len  Length of returned buffer containing DNS message.
960  *  \return ARES_SUCCESS on success
961  */
962 CARES_EXTERN ares_status_t ares_dns_write(ares_dns_record_t *dnsrec,
963                                           unsigned char **buf, size_t *buf_len);
964 /*! @} */
965 
966 #ifdef __cplusplus
967 }
968 #endif
969 
970 #endif /* __ARES_DNS_RECORD_H */
971