quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_dns_record.h (47691B)


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