quickjs-tart

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

ares_parse_naptr_reply.c (4625B)


      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 #include "ares_data.h"
     28 
     29 int ares_parse_naptr_reply(const unsigned char *abuf, int alen_int,
     30                            struct ares_naptr_reply **naptr_out)
     31 {
     32   ares_status_t            status;
     33   size_t                   alen;
     34   struct ares_naptr_reply *naptr_head = NULL;
     35   struct ares_naptr_reply *naptr_last = NULL;
     36   struct ares_naptr_reply *naptr_curr;
     37   ares_dns_record_t       *dnsrec = NULL;
     38   size_t                   i;
     39 
     40   *naptr_out = NULL;
     41 
     42   if (alen_int < 0) {
     43     return ARES_EBADRESP;
     44   }
     45 
     46   alen = (size_t)alen_int;
     47 
     48   status = ares_dns_parse(abuf, alen, 0, &dnsrec);
     49   if (status != ARES_SUCCESS) {
     50     goto done;
     51   }
     52 
     53   if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) {
     54     status = ARES_ENODATA;
     55     goto done;
     56   }
     57 
     58   for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) {
     59     const ares_dns_rr_t *rr =
     60       ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i);
     61 
     62     if (rr == NULL) {
     63       /* Shouldn't be possible */
     64       status = ARES_EBADRESP; /* LCOV_EXCL_LINE: DefensiveCoding */
     65       goto done;              /* LCOV_EXCL_LINE: DefensiveCoding */
     66     }
     67 
     68     if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN ||
     69         ares_dns_rr_get_type(rr) != ARES_REC_TYPE_NAPTR) {
     70       continue;
     71     }
     72 
     73     /* Allocate storage for this NAPTR answer appending it to the list */
     74     naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY);
     75     if (naptr_curr == NULL) {
     76       status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
     77       goto done;            /* LCOV_EXCL_LINE: OutOfMemory */
     78     }
     79 
     80     /* Link in the record */
     81     if (naptr_last) {
     82       naptr_last->next = naptr_curr;
     83     } else {
     84       naptr_head = naptr_curr;
     85     }
     86     naptr_last = naptr_curr;
     87 
     88     naptr_curr->order      = ares_dns_rr_get_u16(rr, ARES_RR_NAPTR_ORDER);
     89     naptr_curr->preference = ares_dns_rr_get_u16(rr, ARES_RR_NAPTR_PREFERENCE);
     90 
     91     /* XXX: Why is this unsigned char * ? */
     92     naptr_curr->flags = (unsigned char *)ares_strdup(
     93       ares_dns_rr_get_str(rr, ARES_RR_NAPTR_FLAGS));
     94     if (naptr_curr->flags == NULL) {
     95       status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
     96       goto done;            /* LCOV_EXCL_LINE: OutOfMemory */
     97     }
     98     /* XXX: Why is this unsigned char * ? */
     99     naptr_curr->service = (unsigned char *)ares_strdup(
    100       ares_dns_rr_get_str(rr, ARES_RR_NAPTR_SERVICES));
    101     if (naptr_curr->service == NULL) {
    102       status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
    103       goto done;            /* LCOV_EXCL_LINE: OutOfMemory */
    104     }
    105     /* XXX: Why is this unsigned char * ? */
    106     naptr_curr->regexp = (unsigned char *)ares_strdup(
    107       ares_dns_rr_get_str(rr, ARES_RR_NAPTR_REGEXP));
    108     if (naptr_curr->regexp == NULL) {
    109       status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
    110       goto done;            /* LCOV_EXCL_LINE: OutOfMemory */
    111     }
    112     naptr_curr->replacement =
    113       ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_NAPTR_REPLACEMENT));
    114     if (naptr_curr->replacement == NULL) {
    115       status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */
    116       goto done;            /* LCOV_EXCL_LINE: OutOfMemory */
    117     }
    118   }
    119 
    120 done:
    121   /* clean up on error */
    122   if (status != ARES_SUCCESS) {
    123     if (naptr_head) {
    124       ares_free_data(naptr_head);
    125     }
    126   } else {
    127     /* everything looks fine, return the data */
    128     *naptr_out = naptr_head;
    129   }
    130   ares_dns_record_destroy(dnsrec);
    131   return (int)status;
    132 }