quickjs-tart

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

ares_query.c (5128B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 1998 Massachusetts Institute of Technology
      4  * Copyright (c) The c-ares project and its contributors
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * SPDX-License-Identifier: MIT
     26  */
     27 
     28 #include "ares_private.h"
     29 
     30 #ifdef HAVE_NETINET_IN_H
     31 #  include <netinet/in.h>
     32 #endif
     33 
     34 typedef struct {
     35   ares_callback_dnsrec callback;
     36   void                *arg;
     37 } ares_query_dnsrec_arg_t;
     38 
     39 static void ares_query_dnsrec_cb(void *arg, ares_status_t status,
     40                                  size_t                   timeouts,
     41                                  const ares_dns_record_t *dnsrec)
     42 {
     43   ares_query_dnsrec_arg_t *qquery = arg;
     44 
     45   if (status != ARES_SUCCESS) {
     46     qquery->callback(qquery->arg, status, timeouts, dnsrec);
     47   } else {
     48     size_t           ancount;
     49     ares_dns_rcode_t rcode;
     50     /* Pull the response code and answer count from the packet and convert any
     51      * errors.
     52      */
     53     rcode   = ares_dns_record_get_rcode(dnsrec);
     54     ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER);
     55     status  = ares_dns_query_reply_tostatus(rcode, ancount);
     56     qquery->callback(qquery->arg, status, timeouts, dnsrec);
     57   }
     58   ares_free(qquery);
     59 }
     60 
     61 ares_status_t ares_query_nolock(ares_channel_t *channel, const char *name,
     62                                 ares_dns_class_t     dnsclass,
     63                                 ares_dns_rec_type_t  type,
     64                                 ares_callback_dnsrec callback, void *arg,
     65                                 unsigned short *qid)
     66 {
     67   ares_status_t            status;
     68   ares_dns_record_t       *dnsrec = NULL;
     69   ares_dns_flags_t         flags  = 0;
     70   ares_query_dnsrec_arg_t *qquery = NULL;
     71 
     72   if (channel == NULL || name == NULL || callback == NULL) {
     73     /* LCOV_EXCL_START: DefensiveCoding */
     74     status = ARES_EFORMERR;
     75     if (callback != NULL) {
     76       callback(arg, status, 0, NULL);
     77     }
     78     return status;
     79     /* LCOV_EXCL_STOP */
     80   }
     81 
     82   if (!(channel->flags & ARES_FLAG_NORECURSE)) {
     83     flags |= ARES_FLAG_RD;
     84   }
     85 
     86   status = ares_dns_record_create_query(
     87     &dnsrec, name, dnsclass, type, 0, flags,
     88     (size_t)(channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0);
     89   if (status != ARES_SUCCESS) {
     90     callback(arg, status, 0, NULL); /* LCOV_EXCL_LINE: OutOfMemory */
     91     return status;                  /* LCOV_EXCL_LINE: OutOfMemory */
     92   }
     93 
     94   qquery = ares_malloc(sizeof(*qquery));
     95   if (qquery == NULL) {
     96     /* LCOV_EXCL_START: OutOfMemory */
     97     status = ARES_ENOMEM;
     98     callback(arg, status, 0, NULL);
     99     ares_dns_record_destroy(dnsrec);
    100     return status;
    101     /* LCOV_EXCL_STOP */
    102   }
    103 
    104   qquery->callback = callback;
    105   qquery->arg      = arg;
    106 
    107   /* Send it off.  qcallback will be called when we get an answer. */
    108   status = ares_send_nolock(channel, NULL, 0, dnsrec, ares_query_dnsrec_cb,
    109                             qquery, qid);
    110 
    111   ares_dns_record_destroy(dnsrec);
    112   return status;
    113 }
    114 
    115 ares_status_t ares_query_dnsrec(ares_channel_t *channel, const char *name,
    116                                 ares_dns_class_t     dnsclass,
    117                                 ares_dns_rec_type_t  type,
    118                                 ares_callback_dnsrec callback, void *arg,
    119                                 unsigned short *qid)
    120 {
    121   ares_status_t status;
    122 
    123   if (channel == NULL) {
    124     return ARES_EFORMERR;
    125   }
    126 
    127   ares_channel_lock(channel);
    128   status = ares_query_nolock(channel, name, dnsclass, type, callback, arg, qid);
    129   ares_channel_unlock(channel);
    130   return status;
    131 }
    132 
    133 void ares_query(ares_channel_t *channel, const char *name, int dnsclass,
    134                 int type, ares_callback callback, void *arg)
    135 {
    136   void *carg = NULL;
    137 
    138   if (channel == NULL) {
    139     return;
    140   }
    141 
    142   carg = ares_dnsrec_convert_arg(callback, arg);
    143   if (carg == NULL) {
    144     callback(arg, ARES_ENOMEM, 0, NULL, 0); /* LCOV_EXCL_LINE: OutOfMemory */
    145     return;                                 /* LCOV_EXCL_LINE: OutOfMemory */
    146   }
    147 
    148   ares_query_dnsrec(channel, name, (ares_dns_class_t)dnsclass,
    149                     (ares_dns_rec_type_t)type, ares_dnsrec_convert_cb, carg,
    150                     NULL);
    151 }