quickjs-tart

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

ares_dns_mapping.c (27396B)


      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 #include "ares_private.h"
     27 
     28 ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode)
     29 {
     30   switch (opcode) {
     31     case ARES_OPCODE_QUERY:
     32     case ARES_OPCODE_IQUERY:
     33     case ARES_OPCODE_STATUS:
     34     case ARES_OPCODE_NOTIFY:
     35     case ARES_OPCODE_UPDATE:
     36       return ARES_TRUE;
     37   }
     38   return ARES_FALSE;
     39 }
     40 
     41 ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode)
     42 {
     43   switch (rcode) {
     44     case ARES_RCODE_NOERROR:
     45     case ARES_RCODE_FORMERR:
     46     case ARES_RCODE_SERVFAIL:
     47     case ARES_RCODE_NXDOMAIN:
     48     case ARES_RCODE_NOTIMP:
     49     case ARES_RCODE_REFUSED:
     50     case ARES_RCODE_YXDOMAIN:
     51     case ARES_RCODE_YXRRSET:
     52     case ARES_RCODE_NXRRSET:
     53     case ARES_RCODE_NOTAUTH:
     54     case ARES_RCODE_NOTZONE:
     55     case ARES_RCODE_DSOTYPEI:
     56     case ARES_RCODE_BADSIG:
     57     case ARES_RCODE_BADKEY:
     58     case ARES_RCODE_BADTIME:
     59     case ARES_RCODE_BADMODE:
     60     case ARES_RCODE_BADNAME:
     61     case ARES_RCODE_BADALG:
     62     case ARES_RCODE_BADTRUNC:
     63     case ARES_RCODE_BADCOOKIE:
     64       return ARES_TRUE;
     65   }
     66   return ARES_FALSE;
     67 }
     68 
     69 ares_bool_t ares_dns_flags_arevalid(unsigned short flags)
     70 {
     71   unsigned short allflags = ARES_FLAG_QR | ARES_FLAG_AA | ARES_FLAG_TC |
     72                             ARES_FLAG_RD | ARES_FLAG_RA | ARES_FLAG_AD |
     73                             ARES_FLAG_CD;
     74 
     75   if (flags & ~allflags) {
     76     return ARES_FALSE;
     77   }
     78 
     79   return ARES_TRUE;
     80 }
     81 
     82 ares_bool_t ares_dns_rec_type_isvalid(ares_dns_rec_type_t type,
     83                                       ares_bool_t         is_query)
     84 {
     85   switch (type) {
     86     case ARES_REC_TYPE_A:
     87     case ARES_REC_TYPE_NS:
     88     case ARES_REC_TYPE_CNAME:
     89     case ARES_REC_TYPE_SOA:
     90     case ARES_REC_TYPE_PTR:
     91     case ARES_REC_TYPE_HINFO:
     92     case ARES_REC_TYPE_MX:
     93     case ARES_REC_TYPE_TXT:
     94     case ARES_REC_TYPE_SIG:
     95     case ARES_REC_TYPE_AAAA:
     96     case ARES_REC_TYPE_SRV:
     97     case ARES_REC_TYPE_NAPTR:
     98     case ARES_REC_TYPE_OPT:
     99     case ARES_REC_TYPE_TLSA:
    100     case ARES_REC_TYPE_SVCB:
    101     case ARES_REC_TYPE_HTTPS:
    102     case ARES_REC_TYPE_ANY:
    103     case ARES_REC_TYPE_URI:
    104     case ARES_REC_TYPE_CAA:
    105       return ARES_TRUE;
    106     case ARES_REC_TYPE_RAW_RR:
    107       return is_query ? ARES_FALSE : ARES_TRUE;
    108     default:
    109       break;
    110   }
    111   return is_query ? ARES_TRUE : ARES_FALSE;
    112 }
    113 
    114 ares_bool_t ares_dns_rec_allow_name_comp(ares_dns_rec_type_t type)
    115 {
    116   /* Only record types defined in RFC1035 allow name compression within the
    117    * RDATA.  Otherwise nameservers that don't understand an RR may not be
    118    * able to pass along the RR in a proper manner */
    119   switch (type) {
    120     case ARES_REC_TYPE_A:
    121     case ARES_REC_TYPE_NS:
    122     case ARES_REC_TYPE_CNAME:
    123     case ARES_REC_TYPE_SOA:
    124     case ARES_REC_TYPE_PTR:
    125     case ARES_REC_TYPE_HINFO:
    126     case ARES_REC_TYPE_MX:
    127     case ARES_REC_TYPE_TXT:
    128       return ARES_TRUE;
    129     default:
    130       break;
    131   }
    132   return ARES_FALSE;
    133 }
    134 
    135 ares_bool_t ares_dns_class_isvalid(ares_dns_class_t    qclass,
    136                                    ares_dns_rec_type_t type,
    137                                    ares_bool_t         is_query)
    138 {
    139   /* If we don't understand the record type, we shouldn't validate the class
    140    * as there are some instances like on RFC 2391 (SIG RR) the class is
    141    * meaningless, but since we didn't support that record type, we didn't
    142    * know it shouldn't be validated */
    143   if (type == ARES_REC_TYPE_RAW_RR) {
    144     return ARES_TRUE;
    145   }
    146 
    147   switch (qclass) {
    148     case ARES_CLASS_IN:
    149     case ARES_CLASS_CHAOS:
    150     case ARES_CLASS_HESOID:
    151     case ARES_CLASS_NONE:
    152       return ARES_TRUE;
    153     case ARES_CLASS_ANY:
    154       if (type == ARES_REC_TYPE_SIG) {
    155         return ARES_TRUE;
    156       }
    157       if (is_query) {
    158         return ARES_TRUE;
    159       }
    160       return ARES_FALSE;
    161   }
    162   return ARES_FALSE;
    163 }
    164 
    165 ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect)
    166 {
    167   switch (sect) {
    168     case ARES_SECTION_ANSWER:
    169     case ARES_SECTION_AUTHORITY:
    170     case ARES_SECTION_ADDITIONAL:
    171       return ARES_TRUE;
    172   }
    173   return ARES_FALSE;
    174 }
    175 
    176 ares_dns_rec_type_t ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key)
    177 {
    178   /* NOTE: due to the way we've numerated the keys, we can simply divide by
    179    *       100 to get the type rather than having to do a huge switch
    180    *       statement.  That said, we do then validate the type returned is
    181    *       valid in case something completely bogus is passed in */
    182   ares_dns_rec_type_t type = key / 100;
    183   if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) {
    184     return 0;
    185   }
    186   return type;
    187 }
    188 
    189 const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type)
    190 {
    191   switch (type) {
    192     case ARES_REC_TYPE_A:
    193       return "A";
    194     case ARES_REC_TYPE_NS:
    195       return "NS";
    196     case ARES_REC_TYPE_CNAME:
    197       return "CNAME";
    198     case ARES_REC_TYPE_SOA:
    199       return "SOA";
    200     case ARES_REC_TYPE_PTR:
    201       return "PTR";
    202     case ARES_REC_TYPE_HINFO:
    203       return "HINFO";
    204     case ARES_REC_TYPE_MX:
    205       return "MX";
    206     case ARES_REC_TYPE_TXT:
    207       return "TXT";
    208     case ARES_REC_TYPE_SIG:
    209       return "SIG";
    210     case ARES_REC_TYPE_AAAA:
    211       return "AAAA";
    212     case ARES_REC_TYPE_SRV:
    213       return "SRV";
    214     case ARES_REC_TYPE_NAPTR:
    215       return "NAPTR";
    216     case ARES_REC_TYPE_OPT:
    217       return "OPT";
    218     case ARES_REC_TYPE_TLSA:
    219       return "TLSA";
    220     case ARES_REC_TYPE_SVCB:
    221       return "SVCB";
    222     case ARES_REC_TYPE_HTTPS:
    223       return "HTTPS";
    224     case ARES_REC_TYPE_ANY:
    225       return "ANY";
    226     case ARES_REC_TYPE_URI:
    227       return "URI";
    228     case ARES_REC_TYPE_CAA:
    229       return "CAA";
    230     case ARES_REC_TYPE_RAW_RR:
    231       return "RAWRR";
    232   }
    233   return "UNKNOWN";
    234 }
    235 
    236 const char *ares_dns_class_tostr(ares_dns_class_t qclass)
    237 {
    238   switch (qclass) {
    239     case ARES_CLASS_IN:
    240       return "IN";
    241     case ARES_CLASS_CHAOS:
    242       return "CH";
    243     case ARES_CLASS_HESOID:
    244       return "HS";
    245     case ARES_CLASS_ANY:
    246       return "ANY";
    247     case ARES_CLASS_NONE:
    248       return "NONE";
    249   }
    250   return "UNKNOWN";
    251 }
    252 
    253 const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode)
    254 {
    255   switch (opcode) {
    256     case ARES_OPCODE_QUERY:
    257       return "QUERY";
    258     case ARES_OPCODE_IQUERY:
    259       return "IQUERY";
    260     case ARES_OPCODE_STATUS:
    261       return "STATUS";
    262     case ARES_OPCODE_NOTIFY:
    263       return "NOTIFY";
    264     case ARES_OPCODE_UPDATE:
    265       return "UPDATE";
    266   }
    267   return "UNKNOWN";
    268 }
    269 
    270 const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key)
    271 {
    272   switch (key) {
    273     case ARES_RR_A_ADDR:
    274       return "ADDR";
    275 
    276     case ARES_RR_NS_NSDNAME:
    277       return "NSDNAME";
    278 
    279     case ARES_RR_CNAME_CNAME:
    280       return "CNAME";
    281 
    282     case ARES_RR_SOA_MNAME:
    283       return "MNAME";
    284 
    285     case ARES_RR_SOA_RNAME:
    286       return "RNAME";
    287 
    288     case ARES_RR_SOA_SERIAL:
    289       return "SERIAL";
    290 
    291     case ARES_RR_SOA_REFRESH:
    292       return "REFRESH";
    293 
    294     case ARES_RR_SOA_RETRY:
    295       return "RETRY";
    296 
    297     case ARES_RR_SOA_EXPIRE:
    298       return "EXPIRE";
    299 
    300     case ARES_RR_SOA_MINIMUM:
    301       return "MINIMUM";
    302 
    303     case ARES_RR_PTR_DNAME:
    304       return "DNAME";
    305 
    306     case ARES_RR_AAAA_ADDR:
    307       return "ADDR";
    308 
    309     case ARES_RR_HINFO_CPU:
    310       return "CPU";
    311 
    312     case ARES_RR_HINFO_OS:
    313       return "OS";
    314 
    315     case ARES_RR_MX_PREFERENCE:
    316       return "PREFERENCE";
    317 
    318     case ARES_RR_MX_EXCHANGE:
    319       return "EXCHANGE";
    320 
    321     case ARES_RR_TXT_DATA:
    322       return "DATA";
    323 
    324     case ARES_RR_SIG_TYPE_COVERED:
    325       return "TYPE_COVERED";
    326 
    327     case ARES_RR_SIG_ALGORITHM:
    328       return "ALGORITHM";
    329 
    330     case ARES_RR_SIG_LABELS:
    331       return "LABELS";
    332 
    333     case ARES_RR_SIG_ORIGINAL_TTL:
    334       return "ORIGINAL_TTL";
    335 
    336     case ARES_RR_SIG_EXPIRATION:
    337       return "EXPIRATION";
    338 
    339     case ARES_RR_SIG_INCEPTION:
    340       return "INCEPTION";
    341 
    342     case ARES_RR_SIG_KEY_TAG:
    343       return "KEY_TAG";
    344 
    345     case ARES_RR_SIG_SIGNERS_NAME:
    346       return "SIGNERS_NAME";
    347 
    348     case ARES_RR_SIG_SIGNATURE:
    349       return "SIGNATURE";
    350 
    351     case ARES_RR_SRV_PRIORITY:
    352       return "PRIORITY";
    353 
    354     case ARES_RR_SRV_WEIGHT:
    355       return "WEIGHT";
    356 
    357     case ARES_RR_SRV_PORT:
    358       return "PORT";
    359 
    360     case ARES_RR_SRV_TARGET:
    361       return "TARGET";
    362 
    363     case ARES_RR_NAPTR_ORDER:
    364       return "ORDER";
    365 
    366     case ARES_RR_NAPTR_PREFERENCE:
    367       return "PREFERENCE";
    368 
    369     case ARES_RR_NAPTR_FLAGS:
    370       return "FLAGS";
    371 
    372     case ARES_RR_NAPTR_SERVICES:
    373       return "SERVICES";
    374 
    375     case ARES_RR_NAPTR_REGEXP:
    376       return "REGEXP";
    377 
    378     case ARES_RR_NAPTR_REPLACEMENT:
    379       return "REPLACEMENT";
    380 
    381     case ARES_RR_OPT_UDP_SIZE:
    382       return "UDP_SIZE";
    383 
    384     case ARES_RR_OPT_VERSION:
    385       return "VERSION";
    386 
    387     case ARES_RR_OPT_FLAGS:
    388       return "FLAGS";
    389 
    390     case ARES_RR_OPT_OPTIONS:
    391       return "OPTIONS";
    392 
    393     case ARES_RR_TLSA_CERT_USAGE:
    394       return "CERT_USAGE";
    395 
    396     case ARES_RR_TLSA_SELECTOR:
    397       return "SELECTOR";
    398 
    399     case ARES_RR_TLSA_MATCH:
    400       return "MATCH";
    401 
    402     case ARES_RR_TLSA_DATA:
    403       return "DATA";
    404 
    405     case ARES_RR_SVCB_PRIORITY:
    406       return "PRIORITY";
    407 
    408     case ARES_RR_SVCB_TARGET:
    409       return "TARGET";
    410 
    411     case ARES_RR_SVCB_PARAMS:
    412       return "PARAMS";
    413 
    414     case ARES_RR_HTTPS_PRIORITY:
    415       return "PRIORITY";
    416 
    417     case ARES_RR_HTTPS_TARGET:
    418       return "TARGET";
    419 
    420     case ARES_RR_HTTPS_PARAMS:
    421       return "PARAMS";
    422 
    423     case ARES_RR_URI_PRIORITY:
    424       return "PRIORITY";
    425 
    426     case ARES_RR_URI_WEIGHT:
    427       return "WEIGHT";
    428 
    429     case ARES_RR_URI_TARGET:
    430       return "TARGET";
    431 
    432     case ARES_RR_CAA_CRITICAL:
    433       return "CRITICAL";
    434 
    435     case ARES_RR_CAA_TAG:
    436       return "TAG";
    437 
    438     case ARES_RR_CAA_VALUE:
    439       return "VALUE";
    440 
    441     case ARES_RR_RAW_RR_TYPE:
    442       return "TYPE";
    443 
    444     case ARES_RR_RAW_RR_DATA:
    445       return "DATA";
    446   }
    447 
    448   return "UNKNOWN";
    449 }
    450 
    451 ares_dns_datatype_t ares_dns_rr_key_datatype(ares_dns_rr_key_t key)
    452 {
    453   switch (key) {
    454     case ARES_RR_A_ADDR:
    455       return ARES_DATATYPE_INADDR;
    456 
    457     case ARES_RR_AAAA_ADDR:
    458       return ARES_DATATYPE_INADDR6;
    459 
    460     case ARES_RR_NS_NSDNAME:
    461     case ARES_RR_CNAME_CNAME:
    462     case ARES_RR_SOA_MNAME:
    463     case ARES_RR_SOA_RNAME:
    464     case ARES_RR_PTR_DNAME:
    465     case ARES_RR_MX_EXCHANGE:
    466     case ARES_RR_SIG_SIGNERS_NAME:
    467     case ARES_RR_SRV_TARGET:
    468     case ARES_RR_SVCB_TARGET:
    469     case ARES_RR_HTTPS_TARGET:
    470     case ARES_RR_NAPTR_REPLACEMENT:
    471     case ARES_RR_URI_TARGET:
    472       return ARES_DATATYPE_NAME;
    473 
    474     case ARES_RR_HINFO_CPU:
    475     case ARES_RR_HINFO_OS:
    476     case ARES_RR_NAPTR_FLAGS:
    477     case ARES_RR_NAPTR_SERVICES:
    478     case ARES_RR_NAPTR_REGEXP:
    479     case ARES_RR_CAA_TAG:
    480       return ARES_DATATYPE_STR;
    481 
    482     case ARES_RR_SOA_SERIAL:
    483     case ARES_RR_SOA_REFRESH:
    484     case ARES_RR_SOA_RETRY:
    485     case ARES_RR_SOA_EXPIRE:
    486     case ARES_RR_SOA_MINIMUM:
    487     case ARES_RR_SIG_ORIGINAL_TTL:
    488     case ARES_RR_SIG_EXPIRATION:
    489     case ARES_RR_SIG_INCEPTION:
    490       return ARES_DATATYPE_U32;
    491 
    492     case ARES_RR_MX_PREFERENCE:
    493     case ARES_RR_SIG_TYPE_COVERED:
    494     case ARES_RR_SIG_KEY_TAG:
    495     case ARES_RR_SRV_PRIORITY:
    496     case ARES_RR_SRV_WEIGHT:
    497     case ARES_RR_SRV_PORT:
    498     case ARES_RR_NAPTR_ORDER:
    499     case ARES_RR_NAPTR_PREFERENCE:
    500     case ARES_RR_OPT_UDP_SIZE:
    501     case ARES_RR_OPT_FLAGS:
    502     case ARES_RR_SVCB_PRIORITY:
    503     case ARES_RR_HTTPS_PRIORITY:
    504     case ARES_RR_URI_PRIORITY:
    505     case ARES_RR_URI_WEIGHT:
    506     case ARES_RR_RAW_RR_TYPE:
    507       return ARES_DATATYPE_U16;
    508 
    509     case ARES_RR_SIG_ALGORITHM:
    510     case ARES_RR_SIG_LABELS:
    511     case ARES_RR_OPT_VERSION:
    512     case ARES_RR_TLSA_CERT_USAGE:
    513     case ARES_RR_TLSA_SELECTOR:
    514     case ARES_RR_TLSA_MATCH:
    515     case ARES_RR_CAA_CRITICAL:
    516       return ARES_DATATYPE_U8;
    517 
    518     case ARES_RR_CAA_VALUE:
    519       return ARES_DATATYPE_BINP;
    520 
    521     case ARES_RR_TXT_DATA:
    522       return ARES_DATATYPE_ABINP;
    523 
    524     case ARES_RR_SIG_SIGNATURE:
    525     case ARES_RR_TLSA_DATA:
    526     case ARES_RR_RAW_RR_DATA:
    527       return ARES_DATATYPE_BIN;
    528 
    529     case ARES_RR_OPT_OPTIONS:
    530     case ARES_RR_SVCB_PARAMS:
    531     case ARES_RR_HTTPS_PARAMS:
    532       return ARES_DATATYPE_OPT;
    533   }
    534 
    535   return 0;
    536 }
    537 
    538 static const ares_dns_rr_key_t rr_a_keys[]     = { ARES_RR_A_ADDR };
    539 static const ares_dns_rr_key_t rr_ns_keys[]    = { ARES_RR_NS_NSDNAME };
    540 static const ares_dns_rr_key_t rr_cname_keys[] = { ARES_RR_CNAME_CNAME };
    541 static const ares_dns_rr_key_t rr_soa_keys[]   = {
    542   ARES_RR_SOA_MNAME,   ARES_RR_SOA_RNAME, ARES_RR_SOA_SERIAL,
    543   ARES_RR_SOA_REFRESH, ARES_RR_SOA_RETRY, ARES_RR_SOA_EXPIRE,
    544   ARES_RR_SOA_MINIMUM
    545 };
    546 static const ares_dns_rr_key_t rr_ptr_keys[]   = { ARES_RR_PTR_DNAME };
    547 static const ares_dns_rr_key_t rr_hinfo_keys[] = { ARES_RR_HINFO_CPU,
    548                                                    ARES_RR_HINFO_OS };
    549 static const ares_dns_rr_key_t rr_mx_keys[]    = { ARES_RR_MX_PREFERENCE,
    550                                                    ARES_RR_MX_EXCHANGE };
    551 static const ares_dns_rr_key_t rr_sig_keys[]   = {
    552   ARES_RR_SIG_TYPE_COVERED, ARES_RR_SIG_ALGORITHM,    ARES_RR_SIG_LABELS,
    553   ARES_RR_SIG_ORIGINAL_TTL, ARES_RR_SIG_EXPIRATION,   ARES_RR_SIG_INCEPTION,
    554   ARES_RR_SIG_KEY_TAG,      ARES_RR_SIG_SIGNERS_NAME, ARES_RR_SIG_SIGNATURE
    555 };
    556 static const ares_dns_rr_key_t rr_txt_keys[]  = { ARES_RR_TXT_DATA };
    557 static const ares_dns_rr_key_t rr_aaaa_keys[] = { ARES_RR_AAAA_ADDR };
    558 static const ares_dns_rr_key_t rr_srv_keys[]  = {
    559   ARES_RR_SRV_PRIORITY, ARES_RR_SRV_WEIGHT, ARES_RR_SRV_PORT, ARES_RR_SRV_TARGET
    560 };
    561 static const ares_dns_rr_key_t rr_naptr_keys[] = {
    562   ARES_RR_NAPTR_ORDER,    ARES_RR_NAPTR_PREFERENCE, ARES_RR_NAPTR_FLAGS,
    563   ARES_RR_NAPTR_SERVICES, ARES_RR_NAPTR_REGEXP,     ARES_RR_NAPTR_REPLACEMENT
    564 };
    565 static const ares_dns_rr_key_t rr_opt_keys[]    = { ARES_RR_OPT_UDP_SIZE,
    566                                                     ARES_RR_OPT_VERSION,
    567                                                     ARES_RR_OPT_FLAGS,
    568                                                     ARES_RR_OPT_OPTIONS };
    569 static const ares_dns_rr_key_t rr_tlsa_keys[]   = { ARES_RR_TLSA_CERT_USAGE,
    570                                                     ARES_RR_TLSA_SELECTOR,
    571                                                     ARES_RR_TLSA_MATCH,
    572                                                     ARES_RR_TLSA_DATA };
    573 static const ares_dns_rr_key_t rr_svcb_keys[]   = { ARES_RR_SVCB_PRIORITY,
    574                                                     ARES_RR_SVCB_TARGET,
    575                                                     ARES_RR_SVCB_PARAMS };
    576 static const ares_dns_rr_key_t rr_https_keys[]  = { ARES_RR_HTTPS_PRIORITY,
    577                                                     ARES_RR_HTTPS_TARGET,
    578                                                     ARES_RR_HTTPS_PARAMS };
    579 static const ares_dns_rr_key_t rr_uri_keys[]    = { ARES_RR_URI_PRIORITY,
    580                                                     ARES_RR_URI_WEIGHT,
    581                                                     ARES_RR_URI_TARGET };
    582 static const ares_dns_rr_key_t rr_caa_keys[]    = { ARES_RR_CAA_CRITICAL,
    583                                                     ARES_RR_CAA_TAG,
    584                                                     ARES_RR_CAA_VALUE };
    585 static const ares_dns_rr_key_t rr_raw_rr_keys[] = { ARES_RR_RAW_RR_TYPE,
    586                                                     ARES_RR_RAW_RR_DATA };
    587 
    588 const ares_dns_rr_key_t       *ares_dns_rr_get_keys(ares_dns_rec_type_t type,
    589                                                     size_t             *cnt)
    590 {
    591   if (cnt == NULL) {
    592     return NULL;
    593   }
    594 
    595   *cnt = 0;
    596 
    597   switch (type) {
    598     case ARES_REC_TYPE_A:
    599       *cnt = sizeof(rr_a_keys) / sizeof(*rr_a_keys);
    600       return rr_a_keys;
    601     case ARES_REC_TYPE_NS:
    602       *cnt = sizeof(rr_ns_keys) / sizeof(*rr_ns_keys);
    603       return rr_ns_keys;
    604     case ARES_REC_TYPE_CNAME:
    605       *cnt = sizeof(rr_cname_keys) / sizeof(*rr_cname_keys);
    606       return rr_cname_keys;
    607     case ARES_REC_TYPE_SOA:
    608       *cnt = sizeof(rr_soa_keys) / sizeof(*rr_soa_keys);
    609       return rr_soa_keys;
    610     case ARES_REC_TYPE_PTR:
    611       *cnt = sizeof(rr_ptr_keys) / sizeof(*rr_ptr_keys);
    612       return rr_ptr_keys;
    613     case ARES_REC_TYPE_HINFO:
    614       *cnt = sizeof(rr_hinfo_keys) / sizeof(*rr_hinfo_keys);
    615       return rr_hinfo_keys;
    616     case ARES_REC_TYPE_MX:
    617       *cnt = sizeof(rr_mx_keys) / sizeof(*rr_mx_keys);
    618       return rr_mx_keys;
    619     case ARES_REC_TYPE_TXT:
    620       *cnt = sizeof(rr_txt_keys) / sizeof(*rr_txt_keys);
    621       return rr_txt_keys;
    622     case ARES_REC_TYPE_SIG:
    623       *cnt = sizeof(rr_sig_keys) / sizeof(*rr_sig_keys);
    624       return rr_sig_keys;
    625     case ARES_REC_TYPE_AAAA:
    626       *cnt = sizeof(rr_aaaa_keys) / sizeof(*rr_aaaa_keys);
    627       return rr_aaaa_keys;
    628     case ARES_REC_TYPE_SRV:
    629       *cnt = sizeof(rr_srv_keys) / sizeof(*rr_srv_keys);
    630       return rr_srv_keys;
    631     case ARES_REC_TYPE_NAPTR:
    632       *cnt = sizeof(rr_naptr_keys) / sizeof(*rr_naptr_keys);
    633       return rr_naptr_keys;
    634     case ARES_REC_TYPE_OPT:
    635       *cnt = sizeof(rr_opt_keys) / sizeof(*rr_opt_keys);
    636       return rr_opt_keys;
    637     case ARES_REC_TYPE_TLSA:
    638       *cnt = sizeof(rr_tlsa_keys) / sizeof(*rr_tlsa_keys);
    639       return rr_tlsa_keys;
    640     case ARES_REC_TYPE_SVCB:
    641       *cnt = sizeof(rr_svcb_keys) / sizeof(*rr_svcb_keys);
    642       return rr_svcb_keys;
    643     case ARES_REC_TYPE_HTTPS:
    644       *cnt = sizeof(rr_https_keys) / sizeof(*rr_https_keys);
    645       return rr_https_keys;
    646     case ARES_REC_TYPE_ANY:
    647       /* Not real */
    648       break;
    649     case ARES_REC_TYPE_URI:
    650       *cnt = sizeof(rr_uri_keys) / sizeof(*rr_uri_keys);
    651       return rr_uri_keys;
    652     case ARES_REC_TYPE_CAA:
    653       *cnt = sizeof(rr_caa_keys) / sizeof(*rr_caa_keys);
    654       return rr_caa_keys;
    655     case ARES_REC_TYPE_RAW_RR:
    656       *cnt = sizeof(rr_raw_rr_keys) / sizeof(*rr_raw_rr_keys);
    657       return rr_raw_rr_keys;
    658   }
    659 
    660   return NULL;
    661 }
    662 
    663 ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass, const char *str)
    664 {
    665   size_t i;
    666 
    667   static const struct {
    668     const char      *name;
    669     ares_dns_class_t qclass;
    670   } list[] = {
    671     { "IN",   ARES_CLASS_IN     },
    672     { "CH",   ARES_CLASS_CHAOS  },
    673     { "HS",   ARES_CLASS_HESOID },
    674     { "NONE", ARES_CLASS_NONE   },
    675     { "ANY",  ARES_CLASS_ANY    },
    676     { NULL,   0                 }
    677   };
    678 
    679   if (qclass == NULL || str == NULL) {
    680     return ARES_FALSE;
    681   }
    682 
    683   for (i = 0; list[i].name != NULL; i++) {
    684     if (ares_strcaseeq(list[i].name, str)) {
    685       *qclass = list[i].qclass;
    686       return ARES_TRUE;
    687     }
    688   }
    689   return ARES_FALSE;
    690 }
    691 
    692 ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype,
    693                                       const char          *str)
    694 {
    695   size_t i;
    696 
    697   static const struct {
    698     const char         *name;
    699     ares_dns_rec_type_t type;
    700   } list[] = {
    701     { "A",      ARES_REC_TYPE_A      },
    702     { "NS",     ARES_REC_TYPE_NS     },
    703     { "CNAME",  ARES_REC_TYPE_CNAME  },
    704     { "SOA",    ARES_REC_TYPE_SOA    },
    705     { "PTR",    ARES_REC_TYPE_PTR    },
    706     { "HINFO",  ARES_REC_TYPE_HINFO  },
    707     { "MX",     ARES_REC_TYPE_MX     },
    708     { "TXT",    ARES_REC_TYPE_TXT    },
    709     { "SIG",    ARES_REC_TYPE_SIG    },
    710     { "AAAA",   ARES_REC_TYPE_AAAA   },
    711     { "SRV",    ARES_REC_TYPE_SRV    },
    712     { "NAPTR",  ARES_REC_TYPE_NAPTR  },
    713     { "OPT",    ARES_REC_TYPE_OPT    },
    714     { "TLSA",   ARES_REC_TYPE_TLSA   },
    715     { "SVCB",   ARES_REC_TYPE_SVCB   },
    716     { "HTTPS",  ARES_REC_TYPE_HTTPS  },
    717     { "ANY",    ARES_REC_TYPE_ANY    },
    718     { "URI",    ARES_REC_TYPE_URI    },
    719     { "CAA",    ARES_REC_TYPE_CAA    },
    720     { "RAW_RR", ARES_REC_TYPE_RAW_RR },
    721     { NULL,     0                    }
    722   };
    723 
    724   if (qtype == NULL || str == NULL) {
    725     return ARES_FALSE;
    726   }
    727 
    728   for (i = 0; list[i].name != NULL; i++) {
    729     if (ares_strcaseeq(list[i].name, str)) {
    730       *qtype = list[i].type;
    731       return ARES_TRUE;
    732     }
    733   }
    734   return ARES_FALSE;
    735 }
    736 
    737 const char *ares_dns_section_tostr(ares_dns_section_t section)
    738 {
    739   switch (section) {
    740     case ARES_SECTION_ANSWER:
    741       return "ANSWER";
    742     case ARES_SECTION_AUTHORITY:
    743       return "AUTHORITY";
    744     case ARES_SECTION_ADDITIONAL:
    745       return "ADDITIONAL";
    746   }
    747   return "UNKNOWN";
    748 }
    749 
    750 static ares_dns_opt_datatype_t ares_dns_opt_get_type_opt(unsigned short opt)
    751 {
    752   ares_opt_param_t param = (ares_opt_param_t)opt;
    753   switch (param) {
    754     case ARES_OPT_PARAM_LLQ:
    755       /* Really it is u16 version, u16 opcode, u16 error, u64 id, u32 lease */
    756       return ARES_OPT_DATATYPE_BIN;
    757     case ARES_OPT_PARAM_UL:
    758       return ARES_OPT_DATATYPE_U32;
    759     case ARES_OPT_PARAM_NSID:
    760       return ARES_OPT_DATATYPE_BIN;
    761     case ARES_OPT_PARAM_DAU:
    762       return ARES_OPT_DATATYPE_U8_LIST;
    763     case ARES_OPT_PARAM_DHU:
    764       return ARES_OPT_DATATYPE_U8_LIST;
    765     case ARES_OPT_PARAM_N3U:
    766       return ARES_OPT_DATATYPE_U8_LIST;
    767     case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET:
    768       /* Really it is a u16 address family, u8 source prefix length,
    769        * u8 scope prefix length, address */
    770       return ARES_OPT_DATATYPE_BIN;
    771     case ARES_OPT_PARAM_EDNS_EXPIRE:
    772       return ARES_OPT_DATATYPE_U32;
    773     case ARES_OPT_PARAM_COOKIE:
    774       /* 8 bytes for client, 16-40 bytes for server */
    775       return ARES_OPT_DATATYPE_BIN;
    776     case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE:
    777       /* Timeout in 100ms intervals */
    778       return ARES_OPT_DATATYPE_U16;
    779     case ARES_OPT_PARAM_PADDING:
    780       /* Arbitrary padding */
    781       return ARES_OPT_DATATYPE_BIN;
    782     case ARES_OPT_PARAM_CHAIN:
    783       return ARES_OPT_DATATYPE_NAME;
    784     case ARES_OPT_PARAM_EDNS_KEY_TAG:
    785       return ARES_OPT_DATATYPE_U16_LIST;
    786     case ARES_OPT_PARAM_EXTENDED_DNS_ERROR:
    787       /* Really 16bit code followed by textual message */
    788       return ARES_OPT_DATATYPE_BIN;
    789   }
    790   return ARES_OPT_DATATYPE_BIN;
    791 }
    792 
    793 static ares_dns_opt_datatype_t ares_dns_opt_get_type_svcb(unsigned short opt)
    794 {
    795   ares_svcb_param_t param = (ares_svcb_param_t)opt;
    796   switch (param) {
    797     case ARES_SVCB_PARAM_NO_DEFAULT_ALPN:
    798       return ARES_OPT_DATATYPE_NONE;
    799     case ARES_SVCB_PARAM_ECH:
    800       return ARES_OPT_DATATYPE_BIN;
    801     case ARES_SVCB_PARAM_MANDATORY:
    802       return ARES_OPT_DATATYPE_U16_LIST;
    803     case ARES_SVCB_PARAM_ALPN:
    804       return ARES_OPT_DATATYPE_STR_LIST;
    805     case ARES_SVCB_PARAM_PORT:
    806       return ARES_OPT_DATATYPE_U16;
    807     case ARES_SVCB_PARAM_IPV4HINT:
    808       return ARES_OPT_DATATYPE_INADDR4_LIST;
    809     case ARES_SVCB_PARAM_IPV6HINT:
    810       return ARES_OPT_DATATYPE_INADDR6_LIST;
    811   }
    812   return ARES_OPT_DATATYPE_BIN;
    813 }
    814 
    815 ares_dns_opt_datatype_t ares_dns_opt_get_datatype(ares_dns_rr_key_t key,
    816                                                   unsigned short    opt)
    817 {
    818   switch (key) {
    819     case ARES_RR_OPT_OPTIONS:
    820       return ares_dns_opt_get_type_opt(opt);
    821     case ARES_RR_SVCB_PARAMS:
    822     case ARES_RR_HTTPS_PARAMS:
    823       return ares_dns_opt_get_type_svcb(opt);
    824     default:
    825       break;
    826   }
    827   return ARES_OPT_DATATYPE_BIN;
    828 }
    829 
    830 static const char *ares_dns_opt_get_name_opt(unsigned short opt)
    831 {
    832   ares_opt_param_t param = (ares_opt_param_t)opt;
    833   switch (param) {
    834     case ARES_OPT_PARAM_LLQ:
    835       return "LLQ";
    836     case ARES_OPT_PARAM_UL:
    837       return "UL";
    838     case ARES_OPT_PARAM_NSID:
    839       return "NSID";
    840     case ARES_OPT_PARAM_DAU:
    841       return "DAU";
    842     case ARES_OPT_PARAM_DHU:
    843       return "DHU";
    844     case ARES_OPT_PARAM_N3U:
    845       return "N3U";
    846     case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET:
    847       return "edns-client-subnet";
    848     case ARES_OPT_PARAM_EDNS_EXPIRE:
    849       return "edns-expire";
    850     case ARES_OPT_PARAM_COOKIE:
    851       return "COOKIE";
    852     case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE:
    853       return "edns-tcp-keepalive";
    854     case ARES_OPT_PARAM_PADDING:
    855       return "Padding";
    856     case ARES_OPT_PARAM_CHAIN:
    857       return "CHAIN";
    858     case ARES_OPT_PARAM_EDNS_KEY_TAG:
    859       return "edns-key-tag";
    860     case ARES_OPT_PARAM_EXTENDED_DNS_ERROR:
    861       return "extended-dns-error";
    862   }
    863   return NULL;
    864 }
    865 
    866 static const char *ares_dns_opt_get_name_svcb(unsigned short opt)
    867 {
    868   ares_svcb_param_t param = (ares_svcb_param_t)opt;
    869   switch (param) {
    870     case ARES_SVCB_PARAM_NO_DEFAULT_ALPN:
    871       return "no-default-alpn";
    872     case ARES_SVCB_PARAM_ECH:
    873       return "ech";
    874     case ARES_SVCB_PARAM_MANDATORY:
    875       return "mandatory";
    876     case ARES_SVCB_PARAM_ALPN:
    877       return "alpn";
    878     case ARES_SVCB_PARAM_PORT:
    879       return "port";
    880     case ARES_SVCB_PARAM_IPV4HINT:
    881       return "ipv4hint";
    882     case ARES_SVCB_PARAM_IPV6HINT:
    883       return "ipv6hint";
    884   }
    885   return NULL;
    886 }
    887 
    888 const char *ares_dns_opt_get_name(ares_dns_rr_key_t key, unsigned short opt)
    889 {
    890   switch (key) {
    891     case ARES_RR_OPT_OPTIONS:
    892       return ares_dns_opt_get_name_opt(opt);
    893     case ARES_RR_SVCB_PARAMS:
    894     case ARES_RR_HTTPS_PARAMS:
    895       return ares_dns_opt_get_name_svcb(opt);
    896     default:
    897       break;
    898   }
    899   return NULL;
    900 }
    901 
    902 const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode)
    903 {
    904   switch (rcode) {
    905     case ARES_RCODE_NOERROR:
    906       return "NOERROR";
    907     case ARES_RCODE_FORMERR:
    908       return "FORMERR";
    909     case ARES_RCODE_SERVFAIL:
    910       return "SERVFAIL";
    911     case ARES_RCODE_NXDOMAIN:
    912       return "NXDOMAIN";
    913     case ARES_RCODE_NOTIMP:
    914       return "NOTIMP";
    915     case ARES_RCODE_REFUSED:
    916       return "REFUSED";
    917     case ARES_RCODE_YXDOMAIN:
    918       return "YXDOMAIN";
    919     case ARES_RCODE_YXRRSET:
    920       return "YXRRSET";
    921     case ARES_RCODE_NXRRSET:
    922       return "NXRRSET";
    923     case ARES_RCODE_NOTAUTH:
    924       return "NOTAUTH";
    925     case ARES_RCODE_NOTZONE:
    926       return "NOTZONE";
    927     case ARES_RCODE_DSOTYPEI:
    928       return "DSOTYPEI";
    929     case ARES_RCODE_BADSIG:
    930       return "BADSIG";
    931     case ARES_RCODE_BADKEY:
    932       return "BADKEY";
    933     case ARES_RCODE_BADTIME:
    934       return "BADTIME";
    935     case ARES_RCODE_BADMODE:
    936       return "BADMODE";
    937     case ARES_RCODE_BADNAME:
    938       return "BADNAME";
    939     case ARES_RCODE_BADALG:
    940       return "BADALG";
    941     case ARES_RCODE_BADTRUNC:
    942       return "BADTRUNC";
    943     case ARES_RCODE_BADCOOKIE:
    944       return "BADCOOKIE";
    945   }
    946 
    947   return "UNKNOWN";
    948 }
    949 
    950 /* Convert an rcode and ancount from a query reply into an ares_status_t
    951  * value. Used internally by ares_search() and ares_query().
    952  */
    953 ares_status_t ares_dns_query_reply_tostatus(ares_dns_rcode_t rcode,
    954                                             size_t           ancount)
    955 {
    956   ares_status_t status = ARES_SUCCESS;
    957 
    958   switch (rcode) {
    959     case ARES_RCODE_NOERROR:
    960       status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA;
    961       break;
    962     case ARES_RCODE_FORMERR:
    963       status = ARES_EFORMERR;
    964       break;
    965     case ARES_RCODE_SERVFAIL:
    966       status = ARES_ESERVFAIL;
    967       break;
    968     case ARES_RCODE_NXDOMAIN:
    969       status = ARES_ENOTFOUND;
    970       break;
    971     case ARES_RCODE_NOTIMP:
    972       status = ARES_ENOTIMP;
    973       break;
    974     case ARES_RCODE_REFUSED:
    975       status = ARES_EREFUSED;
    976       break;
    977     default:
    978       break;
    979   }
    980 
    981   return status;
    982 }