quickjs-tart

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

ares_process.c (45132B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 1998 Massachusetts Institute of Technology
      4  * Copyright (c) 2010 Daniel Stenberg
      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_STRINGS_H
     31 #  include <strings.h>
     32 #endif
     33 #ifdef HAVE_SYS_IOCTL_H
     34 #  include <sys/ioctl.h>
     35 #endif
     36 #ifdef NETWARE
     37 #  include <sys/filio.h>
     38 #endif
     39 #ifdef HAVE_STDINT_H
     40 #  include <stdint.h>
     41 #endif
     42 
     43 #include <assert.h>
     44 #include <fcntl.h>
     45 #include <limits.h>
     46 
     47 
     48 static void          timeadd(ares_timeval_t *now, size_t millisecs);
     49 static ares_status_t process_write(ares_channel_t *channel,
     50                                    ares_socket_t   write_fd);
     51 static ares_status_t process_read(ares_channel_t       *channel,
     52                                   ares_socket_t         read_fd,
     53                                   const ares_timeval_t *now);
     54 static ares_status_t process_timeouts(ares_channel_t       *channel,
     55                                       const ares_timeval_t *now);
     56 static ares_status_t process_answer(ares_channel_t      *channel,
     57                                     const unsigned char *abuf, size_t alen,
     58                                     ares_conn_t          *conn,
     59                                     const ares_timeval_t *now,
     60                                     ares_array_t        **requeue);
     61 static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure,
     62                               ares_status_t failure_status);
     63 static ares_bool_t same_questions(const ares_query_t      *query,
     64                                   const ares_dns_record_t *arec);
     65 static void        end_query(ares_channel_t *channel, ares_server_t *server,
     66                              ares_query_t *query, ares_status_t status,
     67                              const ares_dns_record_t *dnsrec);
     68 
     69 static void        ares_query_remove_from_conn(ares_query_t *query)
     70 {
     71   /* If its not part of a connection, it can't be tracked for timeouts either */
     72   ares_slist_node_destroy(query->node_queries_by_timeout);
     73   ares_llist_node_destroy(query->node_queries_to_conn);
     74   query->node_queries_by_timeout = NULL;
     75   query->node_queries_to_conn    = NULL;
     76   query->conn                    = NULL;
     77 }
     78 
     79 /* Invoke the server state callback after a success or failure */
     80 static void invoke_server_state_cb(const ares_server_t *server,
     81                                    ares_bool_t success, int flags)
     82 {
     83   const ares_channel_t *channel = server->channel;
     84   ares_buf_t           *buf;
     85   ares_status_t         status;
     86   char                 *server_string;
     87 
     88   if (channel->server_state_cb == NULL) {
     89     return;
     90   }
     91 
     92   buf = ares_buf_create();
     93   if (buf == NULL) {
     94     return; /* LCOV_EXCL_LINE: OutOfMemory */
     95   }
     96 
     97   status = ares_get_server_addr(server, buf);
     98   if (status != ARES_SUCCESS) {
     99     ares_buf_destroy(buf); /* LCOV_EXCL_LINE: OutOfMemory */
    100     return;                /* LCOV_EXCL_LINE: OutOfMemory */
    101   }
    102 
    103   server_string = ares_buf_finish_str(buf, NULL);
    104   buf           = NULL;
    105   if (server_string == NULL) {
    106     return; /* LCOV_EXCL_LINE: OutOfMemory */
    107   }
    108 
    109   channel->server_state_cb(server_string, success, flags,
    110                            channel->server_state_cb_data);
    111   ares_free(server_string);
    112 }
    113 
    114 static void server_increment_failures(ares_server_t *server,
    115                                       ares_bool_t    used_tcp)
    116 {
    117   ares_slist_node_t    *node;
    118   const ares_channel_t *channel = server->channel;
    119   ares_timeval_t        next_retry_time;
    120 
    121   node = ares_slist_node_find(channel->servers, server);
    122   if (node == NULL) {
    123     return; /* LCOV_EXCL_LINE: DefensiveCoding */
    124   }
    125 
    126   server->consec_failures++;
    127   ares_slist_node_reinsert(node);
    128 
    129   ares_tvnow(&next_retry_time);
    130   timeadd(&next_retry_time, channel->server_retry_delay);
    131   server->next_retry_time = next_retry_time;
    132 
    133   invoke_server_state_cb(server, ARES_FALSE,
    134                          used_tcp == ARES_TRUE ? ARES_SERV_STATE_TCP
    135                                                : ARES_SERV_STATE_UDP);
    136 }
    137 
    138 static void server_set_good(ares_server_t *server, ares_bool_t used_tcp)
    139 {
    140   ares_slist_node_t    *node;
    141   const ares_channel_t *channel = server->channel;
    142 
    143   node = ares_slist_node_find(channel->servers, server);
    144   if (node == NULL) {
    145     return; /* LCOV_EXCL_LINE: DefensiveCoding */
    146   }
    147 
    148   if (server->consec_failures > 0) {
    149     server->consec_failures = 0;
    150     ares_slist_node_reinsert(node);
    151   }
    152 
    153   server->next_retry_time.sec  = 0;
    154   server->next_retry_time.usec = 0;
    155 
    156   invoke_server_state_cb(server, ARES_TRUE,
    157                          used_tcp == ARES_TRUE ? ARES_SERV_STATE_TCP
    158                                                : ARES_SERV_STATE_UDP);
    159 }
    160 
    161 /* return true if now is exactly check time or later */
    162 ares_bool_t ares_timedout(const ares_timeval_t *now,
    163                           const ares_timeval_t *check)
    164 {
    165   ares_int64_t secs = (now->sec - check->sec);
    166 
    167   if (secs > 0) {
    168     return ARES_TRUE; /* yes, timed out */
    169   }
    170   if (secs < 0) {
    171     return ARES_FALSE; /* nope, not timed out */
    172   }
    173 
    174   /* if the full seconds were identical, check the sub second parts */
    175   return ((ares_int64_t)now->usec - (ares_int64_t)check->usec) >= 0
    176            ? ARES_TRUE
    177            : ARES_FALSE;
    178 }
    179 
    180 /* add the specific number of milliseconds to the time in the first argument */
    181 static void timeadd(ares_timeval_t *now, size_t millisecs)
    182 {
    183   now->sec  += (ares_int64_t)millisecs / 1000;
    184   now->usec += (unsigned int)((millisecs % 1000) * 1000);
    185 
    186   if (now->usec >= 1000000) {
    187     now->sec  += now->usec / 1000000;
    188     now->usec %= 1000000;
    189   }
    190 }
    191 
    192 static ares_status_t ares_process_fds_nolock(ares_channel_t         *channel,
    193                                              const ares_fd_events_t *events,
    194                                              size_t nevents, unsigned int flags)
    195 {
    196   ares_timeval_t now;
    197   size_t         i;
    198   ares_status_t  status = ARES_SUCCESS;
    199 
    200   if (channel == NULL || (events == NULL && nevents != 0)) {
    201     return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */
    202   }
    203 
    204   ares_tvnow(&now);
    205 
    206   /* Process write events */
    207   for (i = 0; i < nevents; i++) {
    208     if (events[i].fd == ARES_SOCKET_BAD ||
    209         !(events[i].events & ARES_FD_EVENT_WRITE)) {
    210       continue;
    211     }
    212     status = process_write(channel, events[i].fd);
    213     /* We only care about ENOMEM, anything else is handled via connection
    214      * retries, etc */
    215     if (status == ARES_ENOMEM) {
    216       goto done;
    217     }
    218   }
    219 
    220   /* Process read events */
    221   for (i = 0; i < nevents; i++) {
    222     if (events[i].fd == ARES_SOCKET_BAD ||
    223         !(events[i].events & ARES_FD_EVENT_READ)) {
    224       continue;
    225     }
    226     status = process_read(channel, events[i].fd, &now);
    227     if (status == ARES_ENOMEM) {
    228       goto done;
    229     }
    230   }
    231 
    232   if (!(flags & ARES_PROCESS_FLAG_SKIP_NON_FD)) {
    233     ares_check_cleanup_conns(channel);
    234     status = process_timeouts(channel, &now);
    235     if (status == ARES_ENOMEM) {
    236       goto done;
    237     }
    238   }
    239 
    240 done:
    241   if (status == ARES_ENOMEM) {
    242     return ARES_ENOMEM;
    243   }
    244   return ARES_SUCCESS;
    245 }
    246 
    247 ares_status_t ares_process_fds(ares_channel_t         *channel,
    248                                const ares_fd_events_t *events, size_t nevents,
    249                                unsigned int flags)
    250 {
    251   ares_status_t status;
    252 
    253   if (channel == NULL) {
    254     return ARES_EFORMERR;
    255   }
    256 
    257   ares_channel_lock(channel);
    258   status = ares_process_fds_nolock(channel, events, nevents, flags);
    259   ares_channel_unlock(channel);
    260   return status;
    261 }
    262 
    263 void ares_process_fd(ares_channel_t *channel, ares_socket_t read_fd,
    264                      ares_socket_t write_fd)
    265 {
    266   ares_fd_events_t events[2];
    267   size_t           nevents = 0;
    268 
    269   memset(events, 0, sizeof(events));
    270 
    271   if (read_fd != ARES_SOCKET_BAD) {
    272     nevents++;
    273     events[nevents - 1].fd      = read_fd;
    274     events[nevents - 1].events |= ARES_FD_EVENT_READ;
    275   }
    276 
    277   if (write_fd != ARES_SOCKET_BAD) {
    278     if (write_fd != read_fd) {
    279       nevents++;
    280     }
    281     events[nevents - 1].fd      = write_fd;
    282     events[nevents - 1].events |= ARES_FD_EVENT_WRITE;
    283   }
    284 
    285   ares_process_fds(channel, events, nevents, ARES_PROCESS_FLAG_NONE);
    286 }
    287 
    288 static ares_socket_t *channel_socket_list(const ares_channel_t *channel,
    289                                           size_t               *num)
    290 {
    291   ares_slist_node_t *snode;
    292   ares_array_t      *arr = ares_array_create(sizeof(ares_socket_t), NULL);
    293 
    294   *num = 0;
    295 
    296   if (arr == NULL) {
    297     return NULL; /* LCOV_EXCL_LINE: OutOfMemory */
    298   }
    299 
    300   for (snode = ares_slist_node_first(channel->servers); snode != NULL;
    301        snode = ares_slist_node_next(snode)) {
    302     ares_server_t     *server = ares_slist_node_val(snode);
    303     ares_llist_node_t *node;
    304 
    305     for (node = ares_llist_node_first(server->connections); node != NULL;
    306          node = ares_llist_node_next(node)) {
    307       const ares_conn_t *conn = ares_llist_node_val(node);
    308       ares_socket_t     *sptr;
    309       ares_status_t      status;
    310 
    311       if (conn->fd == ARES_SOCKET_BAD) {
    312         continue;
    313       }
    314 
    315       status = ares_array_insert_last((void **)&sptr, arr);
    316       if (status != ARES_SUCCESS) {
    317         ares_array_destroy(arr); /* LCOV_EXCL_LINE: OutOfMemory */
    318         return NULL;             /* LCOV_EXCL_LINE: OutOfMemory */
    319       }
    320       *sptr = conn->fd;
    321     }
    322   }
    323 
    324   return ares_array_finish(arr, num);
    325 }
    326 
    327 /* Something interesting happened on the wire, or there was a timeout.
    328  * See what's up and respond accordingly.
    329  */
    330 void ares_process(ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds)
    331 {
    332   size_t            i;
    333   size_t            num_sockets;
    334   ares_socket_t    *socketlist;
    335   ares_fd_events_t *events  = NULL;
    336   size_t            nevents = 0;
    337 
    338   if (channel == NULL) {
    339     return;
    340   }
    341 
    342   ares_channel_lock(channel);
    343 
    344   /* There is no good way to iterate across an fd_set, instead we must pull a
    345    * list of all known fds, and iterate across that checking against the fd_set.
    346    */
    347   socketlist = channel_socket_list(channel, &num_sockets);
    348 
    349   /* Lets create an events array, maximum number is the number of sockets in
    350    * the list, so we'll use that and just track entries with nevents */
    351   if (num_sockets) {
    352     events = ares_malloc_zero(sizeof(*events) * num_sockets);
    353     if (events == NULL) {
    354       goto done;
    355     }
    356   }
    357 
    358   for (i = 0; i < num_sockets; i++) {
    359     ares_bool_t had_read = ARES_FALSE;
    360     if (read_fds && FD_ISSET(socketlist[i], read_fds)) {
    361       nevents++;
    362       events[nevents - 1].fd      = socketlist[i];
    363       events[nevents - 1].events |= ARES_FD_EVENT_READ;
    364       had_read                    = ARES_TRUE;
    365     }
    366     if (write_fds && FD_ISSET(socketlist[i], write_fds)) {
    367       if (!had_read) {
    368         nevents++;
    369       }
    370       events[nevents - 1].fd      = socketlist[i];
    371       events[nevents - 1].events |= ARES_FD_EVENT_WRITE;
    372     }
    373   }
    374 
    375 done:
    376   ares_process_fds_nolock(channel, events, nevents, ARES_PROCESS_FLAG_NONE);
    377   ares_free(events);
    378   ares_free(socketlist);
    379   ares_channel_unlock(channel);
    380 }
    381 
    382 static ares_status_t process_write(ares_channel_t *channel,
    383                                    ares_socket_t   write_fd)
    384 {
    385   ares_conn_t  *conn = ares_conn_from_fd(channel, write_fd);
    386   ares_status_t status;
    387 
    388   if (conn == NULL) {
    389     return ARES_SUCCESS;
    390   }
    391 
    392   /* Mark as connected if we got here and TFO Initial not set */
    393   if (!(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) {
    394     conn->state_flags |= ARES_CONN_STATE_CONNECTED;
    395   }
    396 
    397   status = ares_conn_flush(conn);
    398   if (status != ARES_SUCCESS) {
    399     handle_conn_error(conn, ARES_TRUE, status);
    400   }
    401   return status;
    402 }
    403 
    404 void ares_process_pending_write(ares_channel_t *channel)
    405 {
    406   ares_slist_node_t *node;
    407 
    408   if (channel == NULL) {
    409     return;
    410   }
    411 
    412   ares_channel_lock(channel);
    413   if (!channel->notify_pending_write) {
    414     ares_channel_unlock(channel);
    415     return;
    416   }
    417 
    418   /* Set as untriggerd before calling into ares_conn_flush(), this is
    419    * because its possible ares_conn_flush() might cause additional data to
    420    * be enqueued if there is some form of exception so it will need to recurse.
    421    */
    422   channel->notify_pending_write = ARES_FALSE;
    423 
    424   for (node = ares_slist_node_first(channel->servers); node != NULL;
    425        node = ares_slist_node_next(node)) {
    426     ares_server_t *server = ares_slist_node_val(node);
    427     ares_conn_t   *conn   = server->tcp_conn;
    428     ares_status_t  status;
    429 
    430     if (conn == NULL) {
    431       continue;
    432     }
    433 
    434     /* Enqueue any pending data if there is any */
    435     status = ares_conn_flush(conn);
    436     if (status != ARES_SUCCESS) {
    437       handle_conn_error(conn, ARES_TRUE, status);
    438     }
    439   }
    440 
    441   ares_channel_unlock(channel);
    442 }
    443 
    444 static ares_status_t read_conn_packets(ares_conn_t *conn)
    445 {
    446   ares_bool_t           read_again;
    447   ares_conn_err_t       err;
    448   const ares_channel_t *channel = conn->server->channel;
    449 
    450   do {
    451     size_t         count;
    452     size_t         len = 65535;
    453     unsigned char *ptr;
    454     size_t         start_len = ares_buf_len(conn->in_buf);
    455 
    456     /* If UDP, lets write out a placeholder for the length indicator */
    457     if (!(conn->flags & ARES_CONN_FLAG_TCP) &&
    458         ares_buf_append_be16(conn->in_buf, 0) != ARES_SUCCESS) {
    459       handle_conn_error(conn, ARES_FALSE /* not critical to connection */,
    460                         ARES_SUCCESS);
    461       return ARES_ENOMEM;
    462     }
    463 
    464     /* Get a buffer of sufficient size */
    465     ptr = ares_buf_append_start(conn->in_buf, &len);
    466 
    467     if (ptr == NULL) {
    468       handle_conn_error(conn, ARES_FALSE /* not critical to connection */,
    469                         ARES_SUCCESS);
    470       return ARES_ENOMEM;
    471     }
    472 
    473     /* Read from socket */
    474     err = ares_conn_read(conn, ptr, len, &count);
    475 
    476     if (err != ARES_CONN_ERR_SUCCESS) {
    477       ares_buf_append_finish(conn->in_buf, 0);
    478       if (!(conn->flags & ARES_CONN_FLAG_TCP)) {
    479         ares_buf_set_length(conn->in_buf, start_len);
    480       }
    481       break;
    482     }
    483 
    484     /* Record amount of data read */
    485     ares_buf_append_finish(conn->in_buf, count);
    486 
    487     /* Only loop if sockets support non-blocking operation, and are using UDP
    488      * or are using TCP and read the maximum buffer size */
    489     read_again = ARES_FALSE;
    490     if (channel->sock_funcs.flags & ARES_SOCKFUNC_FLAG_NONBLOCKING &&
    491         (!(conn->flags & ARES_CONN_FLAG_TCP) || count == len)) {
    492       read_again = ARES_TRUE;
    493     }
    494 
    495     /* If UDP, overwrite length */
    496     if (!(conn->flags & ARES_CONN_FLAG_TCP)) {
    497       len = ares_buf_len(conn->in_buf);
    498       ares_buf_set_length(conn->in_buf, start_len);
    499       ares_buf_append_be16(conn->in_buf, (unsigned short)count);
    500       ares_buf_set_length(conn->in_buf, len);
    501     }
    502     /* Try to read again only if *we* set up the socket, otherwise it may be
    503      * a blocking socket and would cause recvfrom to hang. */
    504   } while (read_again);
    505 
    506   if (err != ARES_CONN_ERR_SUCCESS && err != ARES_CONN_ERR_WOULDBLOCK) {
    507     handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED);
    508     return ARES_ECONNREFUSED;
    509   }
    510 
    511   return ARES_SUCCESS;
    512 }
    513 
    514 /* Simple data structure to store a query that needs to be requeued with
    515  * optional server */
    516 typedef struct {
    517   unsigned short qid;
    518   ares_server_t *server; /* optional */
    519 } ares_requeue_t;
    520 
    521 static ares_status_t ares_append_requeue(ares_array_t **requeue,
    522                                          ares_query_t *query,
    523                                          ares_server_t *server)
    524 {
    525   ares_requeue_t entry;
    526 
    527   if (*requeue == NULL) {
    528     *requeue = ares_array_create(sizeof(ares_requeue_t), NULL);
    529     if (*requeue == NULL) {
    530       return ARES_ENOMEM;
    531     }
    532   }
    533 
    534   ares_query_remove_from_conn(query);
    535 
    536   entry.qid    = query->qid;
    537   entry.server = server;
    538   return ares_array_insertdata_last(*requeue, &entry);
    539 }
    540 
    541 static ares_status_t read_answers(ares_conn_t *conn, const ares_timeval_t *now)
    542 {
    543   ares_status_t   status;
    544   ares_channel_t *channel = conn->server->channel;
    545   ares_array_t   *requeue = NULL;
    546 
    547   /* Process all queued answers */
    548   while (1) {
    549     unsigned short       dns_len  = 0;
    550     const unsigned char *data     = NULL;
    551     size_t               data_len = 0;
    552 
    553     /* Tag so we can roll back */
    554     ares_buf_tag(conn->in_buf);
    555 
    556     /* Read length indicator */
    557     status = ares_buf_fetch_be16(conn->in_buf, &dns_len);
    558     if (status != ARES_SUCCESS) {
    559       ares_buf_tag_rollback(conn->in_buf);
    560       break;
    561     }
    562 
    563     /* Not enough data for a full response yet */
    564     status = ares_buf_consume(conn->in_buf, dns_len);
    565     if (status != ARES_SUCCESS) {
    566       ares_buf_tag_rollback(conn->in_buf);
    567       break;
    568     }
    569 
    570     /* Can't fail except for misuse */
    571     data = ares_buf_tag_fetch(conn->in_buf, &data_len);
    572     if (data == NULL || data_len < 2) {
    573       ares_buf_tag_clear(conn->in_buf);
    574       break;
    575     }
    576 
    577     /* Strip off 2 bytes length */
    578     data     += 2;
    579     data_len -= 2;
    580 
    581     /* We finished reading this answer; process it */
    582     status = process_answer(channel, data, data_len, conn, now, &requeue);
    583     if (status != ARES_SUCCESS) {
    584       handle_conn_error(conn, ARES_TRUE, status);
    585       goto cleanup;
    586     }
    587 
    588     /* Since we processed the answer, clear the tag so space can be reclaimed */
    589     ares_buf_tag_clear(conn->in_buf);
    590   }
    591 
    592 cleanup:
    593 
    594   /* Flush requeue */
    595   while (ares_array_len(requeue) > 0) {
    596     ares_query_t  *query;
    597     ares_requeue_t entry;
    598     ares_status_t  internal_status;
    599 
    600     internal_status = ares_array_claim_at(&entry, sizeof(entry), requeue, 0);
    601     if (internal_status != ARES_SUCCESS) {
    602       break;
    603     }
    604 
    605     /* Query disappeared */
    606     query = ares_htable_szvp_get_direct(channel->queries_by_qid, entry.qid);
    607     if (query == NULL) {
    608       continue;
    609     }
    610 
    611     internal_status = ares_send_query(entry.server, query, now);
    612     /* We only care about ARES_ENOMEM */
    613     if (internal_status == ARES_ENOMEM) {
    614       status = ARES_ENOMEM;
    615     }
    616   }
    617   ares_array_destroy(requeue);
    618 
    619   return status;
    620 }
    621 
    622 static ares_status_t process_read(ares_channel_t       *channel,
    623                                   ares_socket_t         read_fd,
    624                                   const ares_timeval_t *now)
    625 {
    626   ares_conn_t  *conn = ares_conn_from_fd(channel, read_fd);
    627   ares_status_t status;
    628 
    629   if (conn == NULL) {
    630     return ARES_SUCCESS;
    631   }
    632 
    633   /* TODO: There might be a potential issue here where there was a read that
    634    *       read some data, then looped and read again and got a disconnect.
    635    *       Right now, that would cause a resend instead of processing the data
    636    *       we have.  This is fairly unlikely to occur due to only looping if
    637    *       a full buffer of 65535 bytes was read. */
    638   status = read_conn_packets(conn);
    639 
    640   if (status != ARES_SUCCESS) {
    641     return status;
    642   }
    643 
    644   return read_answers(conn, now);
    645 }
    646 
    647 /* If any queries have timed out, note the timeout and move them on. */
    648 static ares_status_t process_timeouts(ares_channel_t       *channel,
    649                                       const ares_timeval_t *now)
    650 {
    651   ares_slist_node_t *node;
    652   ares_status_t      status = ARES_SUCCESS;
    653 
    654   /* Just keep popping off the first as this list will re-sort as things come
    655    * and go.  We don't want to try to rely on 'next' as some operation might
    656    * cause a cleanup of that pointer and would become invalid */
    657   while ((node = ares_slist_node_first(channel->queries_by_timeout)) != NULL) {
    658     ares_query_t *query = ares_slist_node_val(node);
    659     ares_conn_t  *conn;
    660 
    661     /* Since this is sorted, as soon as we hit a query that isn't timed out,
    662      * break */
    663     if (!ares_timedout(now, &query->timeout)) {
    664       break;
    665     }
    666 
    667     query->timeouts++;
    668 
    669     conn = query->conn;
    670     server_increment_failures(conn->server, query->using_tcp);
    671     status = ares_requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE, NULL,
    672                                 NULL);
    673     if (status == ARES_ENOMEM) {
    674       goto done;
    675     }
    676   }
    677 done:
    678   if (status == ARES_ENOMEM) {
    679     return ARES_ENOMEM;
    680   }
    681   return ARES_SUCCESS;
    682 }
    683 
    684 static ares_status_t rewrite_without_edns(ares_query_t *query)
    685 {
    686   ares_status_t status = ARES_SUCCESS;
    687   size_t        i;
    688   ares_bool_t   found_opt_rr = ARES_FALSE;
    689 
    690   /* Find and remove the OPT RR record */
    691   for (i = 0; i < ares_dns_record_rr_cnt(query->query, ARES_SECTION_ADDITIONAL);
    692        i++) {
    693     const ares_dns_rr_t *rr;
    694     rr = ares_dns_record_rr_get(query->query, ARES_SECTION_ADDITIONAL, i);
    695     if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_OPT) {
    696       ares_dns_record_rr_del(query->query, ARES_SECTION_ADDITIONAL, i);
    697       found_opt_rr = ARES_TRUE;
    698       break;
    699     }
    700   }
    701 
    702   if (!found_opt_rr) {
    703     status = ARES_EFORMERR;
    704     goto done;
    705   }
    706 
    707 done:
    708   return status;
    709 }
    710 
    711 static ares_bool_t issue_might_be_edns(const ares_dns_record_t *req,
    712                                        const ares_dns_record_t *rsp)
    713 {
    714   const ares_dns_rr_t *rr;
    715 
    716   /* If we use EDNS and server answers with FORMERR without an OPT RR, the
    717    * protocol extension is not understood by the responder. We must retry the
    718    * query without EDNS enabled. */
    719   if (ares_dns_record_get_rcode(rsp) != ARES_RCODE_FORMERR) {
    720     return ARES_FALSE;
    721   }
    722 
    723   rr = ares_dns_get_opt_rr_const(req);
    724   if (rr == NULL) {
    725     /* We didn't send EDNS */
    726     return ARES_FALSE;
    727   }
    728 
    729   if (ares_dns_get_opt_rr_const(rsp) == NULL) {
    730     /* Spec says EDNS won't be echo'd back on non-supporting servers, so
    731      * retry without EDNS */
    732     return ARES_TRUE;
    733   }
    734 
    735   /* As per issue #911 some non-compliant servers that do indeed support EDNS
    736    * but don't support unrecognized option codes exist.  At this point we
    737    * expect them to have also returned an EDNS opt record, but we may remove
    738    * that check in the future. Lets detect this situation if we're sending
    739    * option codes */
    740   if (ares_dns_rr_get_opt_cnt(rr, ARES_RR_OPT_OPTIONS) == 0) {
    741     /* We didn't send any option codes */
    742     return ARES_FALSE;
    743   }
    744 
    745   if (ares_dns_get_opt_rr_const(rsp) != NULL) {
    746     /* At this time we're requiring the server to respond with EDNS opt
    747      * records since that's what has been observed in the field.  We might
    748      * find in the future we have to remove this, who knows. Lets go
    749      * ahead and force a retry without EDNS*/
    750     return ARES_TRUE;
    751   }
    752 
    753   return ARES_FALSE;
    754 }
    755 
    756 /* Handle an answer from a server. This must NEVER cleanup the
    757  * server connection! Return something other than ARES_SUCCESS to cause
    758  * the connection to be terminated after this call. */
    759 static ares_status_t process_answer(ares_channel_t      *channel,
    760                                     const unsigned char *abuf, size_t alen,
    761                                     ares_conn_t          *conn,
    762                                     const ares_timeval_t *now,
    763                                     ares_array_t        **requeue)
    764 {
    765   ares_query_t      *query;
    766   /* Cache these as once ares_send_query() gets called, it may end up
    767    * invalidating the connection all-together */
    768   ares_server_t     *server  = conn->server;
    769   ares_dns_record_t *rdnsrec = NULL;
    770   ares_status_t      status;
    771   ares_bool_t        is_cached = ARES_FALSE;
    772 
    773   /* UDP can have 0-byte messages, drop them to the ground */
    774   if (alen == 0) {
    775     return ARES_SUCCESS;
    776   }
    777 
    778   /* Parse the response */
    779   status = ares_dns_parse(abuf, alen, 0, &rdnsrec);
    780   if (status != ARES_SUCCESS) {
    781     /* Malformations are never accepted */
    782     status = ARES_EBADRESP;
    783     goto cleanup;
    784   }
    785 
    786   /* Find the query corresponding to this packet. The queries are
    787    * hashed/bucketed by query id, so this lookup should be quick.
    788    */
    789   query = ares_htable_szvp_get_direct(channel->queries_by_qid,
    790                                       ares_dns_record_get_id(rdnsrec));
    791   if (!query) {
    792     /* We may have stopped listening for this query, that's ok */
    793     status = ARES_SUCCESS;
    794     goto cleanup;
    795   }
    796 
    797   /* Both the query id and the questions must be the same. We will drop any
    798    * replies that aren't for the same query as this is considered invalid. */
    799   if (!same_questions(query, rdnsrec)) {
    800     /* Possible qid conflict due to delayed response, that's ok */
    801     status = ARES_SUCCESS;
    802     goto cleanup;
    803   }
    804 
    805   /* Validate DNS cookie in response. This function may need to requeue the
    806    * query. */
    807   if (ares_cookie_validate(query, rdnsrec, conn, now, requeue)
    808       != ARES_SUCCESS) {
    809     /* Drop response and return */
    810     status = ARES_SUCCESS;
    811     goto cleanup;
    812   }
    813 
    814   /* At this point we know we've received an answer for this query, so we should
    815    * remove it from the connection's queue so we can possibly invalidate the
    816    * connection. Delay cleaning up the connection though as we may enqueue
    817    * something new.  */
    818   ares_llist_node_destroy(query->node_queries_to_conn);
    819   query->node_queries_to_conn = NULL;
    820 
    821   /* There are old servers that don't understand EDNS at all, then some servers
    822    * that have non-compliant implementations.  Lets try to detect this sort
    823    * of thing. */
    824   if (issue_might_be_edns(query->query, rdnsrec)) {
    825     status = rewrite_without_edns(query);
    826     if (status != ARES_SUCCESS) {
    827       end_query(channel, server, query, status, NULL);
    828       goto cleanup;
    829     }
    830 
    831     /* Requeue to same server */
    832     status = ares_append_requeue(requeue, query, server);
    833     goto cleanup;
    834   }
    835 
    836   /* If we got a truncated UDP packet and are not ignoring truncation,
    837    * don't accept the packet, and switch the query to TCP if we hadn't
    838    * done so already.
    839    */
    840   if (ares_dns_record_get_flags(rdnsrec) & ARES_FLAG_TC &&
    841       !(conn->flags & ARES_CONN_FLAG_TCP) &&
    842       !(channel->flags & ARES_FLAG_IGNTC)) {
    843     query->using_tcp = ARES_TRUE;
    844     status = ares_append_requeue(requeue, query, NULL);
    845     /* Status will reflect success except on memory error, which is good since
    846      * requeuing to TCP is ok */
    847     goto cleanup;
    848   }
    849 
    850   /* If we aren't passing through all error packets, discard packets
    851    * with SERVFAIL, NOTIMP, or REFUSED response codes.
    852    */
    853   if (!(channel->flags & ARES_FLAG_NOCHECKRESP)) {
    854     ares_dns_rcode_t rcode = ares_dns_record_get_rcode(rdnsrec);
    855     if (rcode == ARES_RCODE_SERVFAIL || rcode == ARES_RCODE_NOTIMP ||
    856         rcode == ARES_RCODE_REFUSED) {
    857       switch (rcode) {
    858         case ARES_RCODE_SERVFAIL:
    859           status = ARES_ESERVFAIL;
    860           break;
    861         case ARES_RCODE_NOTIMP:
    862           status = ARES_ENOTIMP;
    863           break;
    864         case ARES_RCODE_REFUSED:
    865           status = ARES_EREFUSED;
    866           break;
    867         default:
    868           break;
    869       }
    870 
    871       server_increment_failures(server, query->using_tcp);
    872       status = ares_requeue_query(query, now, status, ARES_TRUE, rdnsrec, requeue);
    873 
    874       if (status != ARES_ENOMEM) {
    875         /* Should any of these cause a connection termination?
    876          * Maybe SERVER_FAILURE? */
    877         status = ARES_SUCCESS;
    878       }
    879       goto cleanup;
    880     }
    881   }
    882 
    883   /* If cache insertion was successful, it took ownership.  We ignore
    884    * other cache insertion failures. */
    885   if (ares_qcache_insert(channel, now, query, rdnsrec) == ARES_SUCCESS) {
    886     is_cached = ARES_TRUE;
    887   }
    888 
    889   server_set_good(server, query->using_tcp);
    890   end_query(channel, server, query, ARES_SUCCESS, rdnsrec);
    891 
    892   status = ARES_SUCCESS;
    893 
    894 cleanup:
    895   /* Don't cleanup the cached pointer to the dns response */
    896   if (!is_cached) {
    897     ares_dns_record_destroy(rdnsrec);
    898   }
    899 
    900   return status;
    901 }
    902 
    903 static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure,
    904                               ares_status_t failure_status)
    905 {
    906   ares_server_t *server = conn->server;
    907 
    908   /* Increment failures first before requeue so it is unlikely to requeue
    909    * to the same server */
    910   if (critical_failure) {
    911     server_increment_failures(
    912       server, (conn->flags & ARES_CONN_FLAG_TCP) ? ARES_TRUE : ARES_FALSE);
    913   }
    914 
    915   /* This will requeue any connections automatically */
    916   ares_close_connection(conn, failure_status);
    917 }
    918 
    919 /* Requeue query will normally call ares_send_query() but in some circumstances
    920  * this needs to be delayed, so if requeue is not NULL, it will add the query
    921  * to the queue instead */
    922 ares_status_t ares_requeue_query(ares_query_t *query, const ares_timeval_t *now,
    923                                  ares_status_t            status,
    924                                  ares_bool_t              inc_try_count,
    925                                  const ares_dns_record_t *dnsrec,
    926                                  ares_array_t           **requeue)
    927 {
    928   ares_channel_t *channel   = query->channel;
    929   size_t          max_tries = ares_slist_len(channel->servers) * channel->tries;
    930 
    931   ares_query_remove_from_conn(query);
    932 
    933   if (status != ARES_SUCCESS) {
    934     query->error_status = status;
    935   }
    936 
    937   if (inc_try_count) {
    938     query->try_count++;
    939   }
    940 
    941   if (query->try_count < max_tries && !query->no_retries) {
    942     if (requeue != NULL) {
    943       return ares_append_requeue(requeue, query, NULL);
    944     }
    945     return ares_send_query(NULL, query, now);
    946   }
    947 
    948   /* If we are here, all attempts to perform query failed. */
    949   if (query->error_status == ARES_SUCCESS) {
    950     query->error_status = ARES_ETIMEOUT;
    951   }
    952 
    953   end_query(channel, NULL, query, query->error_status, dnsrec);
    954   return ARES_ETIMEOUT;
    955 }
    956 
    957 /*! Count the number of servers that share the same highest priority (lowest
    958  *  consecutive failures).  Since they are sorted in priority order, we just
    959  *  stop when the consecutive failure count changes. Used for random selection
    960  *  of good servers. */
    961 static size_t count_highest_prio_servers(const ares_channel_t *channel)
    962 {
    963   ares_slist_node_t *node;
    964   size_t             cnt                  = 0;
    965   size_t             last_consec_failures = SIZE_MAX;
    966 
    967   for (node = ares_slist_node_first(channel->servers); node != NULL;
    968        node = ares_slist_node_next(node)) {
    969     const ares_server_t *server = ares_slist_node_val(node);
    970 
    971     if (last_consec_failures != SIZE_MAX &&
    972         last_consec_failures < server->consec_failures) {
    973       break;
    974     }
    975 
    976     last_consec_failures = server->consec_failures;
    977     cnt++;
    978   }
    979 
    980   return cnt;
    981 }
    982 
    983 /* Pick a random *best* server from the list, we first get a random number in
    984  * the range of the number of *best* servers, then scan until we find that
    985  * server in the list */
    986 static ares_server_t *ares_random_server(ares_channel_t *channel)
    987 {
    988   unsigned char      c;
    989   size_t             cnt;
    990   size_t             idx;
    991   ares_slist_node_t *node;
    992   size_t             num_servers = count_highest_prio_servers(channel);
    993 
    994   /* Silence coverity, not possible */
    995   if (num_servers == 0) {
    996     return NULL;
    997   }
    998 
    999   ares_rand_bytes(channel->rand_state, &c, 1);
   1000 
   1001   cnt = c;
   1002   idx = cnt % num_servers;
   1003 
   1004   cnt = 0;
   1005   for (node = ares_slist_node_first(channel->servers); node != NULL;
   1006        node = ares_slist_node_next(node)) {
   1007     if (cnt == idx) {
   1008       return ares_slist_node_val(node);
   1009     }
   1010 
   1011     cnt++;
   1012   }
   1013 
   1014   return NULL;
   1015 }
   1016 
   1017 static void server_probe_cb(void *arg, ares_status_t status, size_t timeouts,
   1018                             const ares_dns_record_t *dnsrec)
   1019 {
   1020   (void)arg;
   1021   (void)status;
   1022   (void)timeouts;
   1023   (void)dnsrec;
   1024   /* Nothing to do, the logic internally will handle success/fail of this */
   1025 }
   1026 
   1027 /* Determine if we should probe a downed server */
   1028 static void ares_probe_failed_server(ares_channel_t      *channel,
   1029                                      const ares_server_t *server,
   1030                                      const ares_query_t  *query)
   1031 {
   1032   const ares_server_t *last_server = ares_slist_last_val(channel->servers);
   1033   unsigned short       r;
   1034   ares_timeval_t       now;
   1035   ares_slist_node_t   *node;
   1036   ares_server_t       *probe_server = NULL;
   1037 
   1038   /* If no servers have failures, or we're not configured with a server retry
   1039    * chance, then nothing to probe */
   1040   if ((last_server != NULL && last_server->consec_failures == 0) ||
   1041       channel->server_retry_chance == 0) {
   1042     return;
   1043   }
   1044 
   1045   /* Generate a random value to decide whether to retry a failed server. The
   1046    * probability to use is 1/channel->server_retry_chance, rounded up to a
   1047    * precision of 1/2^B where B is the number of bits in the random value.
   1048    * We use an unsigned short for the random value for increased precision.
   1049    */
   1050   ares_rand_bytes(channel->rand_state, (unsigned char *)&r, sizeof(r));
   1051   if (r % channel->server_retry_chance != 0) {
   1052     return;
   1053   }
   1054 
   1055   /* Select the first server with failures to retry that has passed the retry
   1056    * timeout and doesn't already have a pending probe */
   1057   ares_tvnow(&now);
   1058   for (node = ares_slist_node_first(channel->servers); node != NULL;
   1059        node = ares_slist_node_next(node)) {
   1060     ares_server_t *node_val = ares_slist_node_val(node);
   1061     if (node_val != NULL && node_val->consec_failures > 0 &&
   1062         !node_val->probe_pending &&
   1063         ares_timedout(&now, &node_val->next_retry_time)) {
   1064       probe_server = node_val;
   1065       break;
   1066     }
   1067   }
   1068 
   1069   /* Either nothing to probe or the query was enqueud to the same server
   1070    * we were going to probe. Do nothing. */
   1071   if (probe_server == NULL || server == probe_server) {
   1072     return;
   1073   }
   1074 
   1075   /* Enqueue an identical query onto the specified server without honoring
   1076    * the cache or allowing retries.  We want to make sure it only attempts to
   1077    * use the server in question */
   1078   probe_server->probe_pending = ARES_TRUE;
   1079   ares_send_nolock(channel, probe_server,
   1080                    ARES_SEND_FLAG_NOCACHE | ARES_SEND_FLAG_NORETRY,
   1081                    query->query, server_probe_cb, NULL, NULL);
   1082 }
   1083 
   1084 static size_t ares_calc_query_timeout(const ares_query_t   *query,
   1085                                       const ares_server_t  *server,
   1086                                       const ares_timeval_t *now)
   1087 {
   1088   const ares_channel_t *channel  = query->channel;
   1089   size_t                timeout  = ares_metrics_server_timeout(server, now);
   1090   size_t                timeplus = timeout;
   1091   size_t                rounds;
   1092   size_t                num_servers = ares_slist_len(channel->servers);
   1093 
   1094   if (num_servers == 0) {
   1095     return 0; /* LCOV_EXCL_LINE: DefensiveCoding */
   1096   }
   1097 
   1098   /* For each trip through the entire server list, we want to double the
   1099    * retry from the last retry */
   1100   rounds = (query->try_count / num_servers);
   1101   if (rounds > 0) {
   1102     timeplus <<= rounds;
   1103   }
   1104 
   1105   if (channel->maxtimeout && timeplus > channel->maxtimeout) {
   1106     timeplus = channel->maxtimeout;
   1107   }
   1108 
   1109   /* Add some jitter to the retry timeout.
   1110    *
   1111    * Jitter is needed in situation when resolve requests are performed
   1112    * simultaneously from multiple hosts and DNS server throttle these requests.
   1113    * Adding randomness allows to avoid synchronisation of retries.
   1114    *
   1115    * Value of timeplus adjusted randomly to the range [0.5 * timeplus,
   1116    * timeplus].
   1117    */
   1118   if (rounds > 0) {
   1119     unsigned short r;
   1120     float          delta_multiplier;
   1121 
   1122     ares_rand_bytes(channel->rand_state, (unsigned char *)&r, sizeof(r));
   1123     delta_multiplier  = ((float)r / USHRT_MAX) * 0.5f;
   1124     timeplus         -= (size_t)((float)timeplus * delta_multiplier);
   1125   }
   1126 
   1127   /* We want explicitly guarantee that timeplus is greater or equal to timeout
   1128    * specified in channel options. */
   1129   if (timeplus < timeout) {
   1130     timeplus = timeout;
   1131   }
   1132 
   1133   return timeplus;
   1134 }
   1135 
   1136 static ares_conn_t *ares_fetch_connection(const ares_channel_t *channel,
   1137                                           ares_server_t        *server,
   1138                                           const ares_query_t   *query)
   1139 {
   1140   ares_llist_node_t *node;
   1141   ares_conn_t       *conn;
   1142 
   1143   if (query->using_tcp) {
   1144     return server->tcp_conn;
   1145   }
   1146 
   1147   /* Fetch existing UDP connection */
   1148   node = ares_llist_node_first(server->connections);
   1149   if (node == NULL) {
   1150     return NULL;
   1151   }
   1152 
   1153   conn = ares_llist_node_val(node);
   1154   /* Not UDP, skip */
   1155   if (conn->flags & ARES_CONN_FLAG_TCP) {
   1156     return NULL;
   1157   }
   1158 
   1159   /* Used too many times */
   1160   if (channel->udp_max_queries > 0 &&
   1161       conn->total_queries >= channel->udp_max_queries) {
   1162     return NULL;
   1163   }
   1164 
   1165   return conn;
   1166 }
   1167 
   1168 static ares_status_t ares_conn_query_write(ares_conn_t          *conn,
   1169                                            ares_query_t         *query,
   1170                                            const ares_timeval_t *now)
   1171 {
   1172   ares_server_t  *server  = conn->server;
   1173   ares_channel_t *channel = server->channel;
   1174   ares_status_t   status;
   1175 
   1176   status = ares_cookie_apply(query->query, conn, now);
   1177   if (status != ARES_SUCCESS) {
   1178     return status;
   1179   }
   1180 
   1181   /* We write using the TCP format even for UDP, we just strip the length
   1182    * before putting on the wire */
   1183   status = ares_dns_write_buf_tcp(query->query, conn->out_buf);
   1184   if (status != ARES_SUCCESS) {
   1185     return status;
   1186   }
   1187 
   1188   /* Not pending a TFO write and not connected, so we can't even try to
   1189    * write until we get a signal */
   1190   if (conn->flags & ARES_CONN_FLAG_TCP &&
   1191       !(conn->state_flags & ARES_CONN_STATE_CONNECTED) &&
   1192       !(conn->flags & ARES_CONN_FLAG_TFO_INITIAL)) {
   1193     return ARES_SUCCESS;
   1194   }
   1195 
   1196   /* Delay actual write if possible (TCP only, and only if callback
   1197    * configured) */
   1198   if (channel->notify_pending_write_cb && !channel->notify_pending_write &&
   1199       conn->flags & ARES_CONN_FLAG_TCP) {
   1200     channel->notify_pending_write = ARES_TRUE;
   1201     channel->notify_pending_write_cb(channel->notify_pending_write_cb_data);
   1202     return ARES_SUCCESS;
   1203   }
   1204 
   1205   /* Unfortunately we need to write right away and can't aggregate multiple
   1206    * queries into a single write. */
   1207   return ares_conn_flush(conn);
   1208 }
   1209 
   1210 ares_status_t ares_send_query(ares_server_t *requested_server,
   1211                               ares_query_t *query, const ares_timeval_t *now)
   1212 {
   1213   ares_channel_t *channel = query->channel;
   1214   ares_server_t  *server;
   1215   ares_conn_t    *conn;
   1216   size_t          timeplus;
   1217   ares_status_t   status;
   1218   ares_bool_t     probe_downed_server = ARES_TRUE;
   1219 
   1220 
   1221   /* Choose the server to send the query to */
   1222   if (requested_server != NULL) {
   1223     server = requested_server;
   1224   } else {
   1225     /* If rotate is turned on, do a random selection */
   1226     if (channel->rotate) {
   1227       server = ares_random_server(channel);
   1228     } else {
   1229       /* First server in list */
   1230       server = ares_slist_first_val(channel->servers);
   1231     }
   1232   }
   1233 
   1234   if (server == NULL) {
   1235     end_query(channel, server, query, ARES_ENOSERVER /* ? */, NULL);
   1236     return ARES_ENOSERVER;
   1237   }
   1238 
   1239   /* If a query is directed to a specific query, or the server chosen has
   1240    * failures, or the query is being retried, don't probe for downed servers */
   1241   if (requested_server != NULL || server->consec_failures > 0 ||
   1242       query->try_count != 0) {
   1243     probe_downed_server = ARES_FALSE;
   1244   }
   1245 
   1246   conn = ares_fetch_connection(channel, server, query);
   1247   if (conn == NULL) {
   1248     status = ares_open_connection(&conn, channel, server, query->using_tcp);
   1249     switch (status) {
   1250       /* Good result, continue on */
   1251       case ARES_SUCCESS:
   1252         break;
   1253 
   1254       /* These conditions are retryable as they are server-specific
   1255        * error codes */
   1256       case ARES_ECONNREFUSED:
   1257       case ARES_EBADFAMILY:
   1258         server_increment_failures(server, query->using_tcp);
   1259         return ares_requeue_query(query, now, status, ARES_TRUE, NULL, NULL);
   1260 
   1261       /* Anything else is not retryable, likely ENOMEM */
   1262       default:
   1263         end_query(channel, server, query, status, NULL);
   1264         return status;
   1265     }
   1266   }
   1267 
   1268   /* Write the query */
   1269   status = ares_conn_query_write(conn, query, now);
   1270   switch (status) {
   1271     /* Good result, continue on */
   1272     case ARES_SUCCESS:
   1273       break;
   1274 
   1275     case ARES_ENOMEM:
   1276       /* Not retryable */
   1277       end_query(channel, server, query, status, NULL);
   1278       return status;
   1279 
   1280     /* These conditions are retryable as they are server-specific
   1281      * error codes */
   1282     case ARES_ECONNREFUSED:
   1283     case ARES_EBADFAMILY:
   1284       handle_conn_error(conn, ARES_TRUE, status);
   1285       status = ares_requeue_query(query, now, status, ARES_TRUE, NULL, NULL);
   1286       if (status == ARES_ETIMEOUT) {
   1287         status = ARES_ECONNREFUSED;
   1288       }
   1289       return status;
   1290 
   1291     default:
   1292       server_increment_failures(server, query->using_tcp);
   1293       status = ares_requeue_query(query, now, status, ARES_TRUE, NULL, NULL);
   1294       return status;
   1295   }
   1296 
   1297   timeplus = ares_calc_query_timeout(query, server, now);
   1298   /* Keep track of queries bucketed by timeout, so we can process
   1299    * timeout events quickly.
   1300    */
   1301   ares_slist_node_destroy(query->node_queries_by_timeout);
   1302   query->ts      = *now;
   1303   query->timeout = *now;
   1304   timeadd(&query->timeout, timeplus);
   1305   query->node_queries_by_timeout =
   1306     ares_slist_insert(channel->queries_by_timeout, query);
   1307   if (!query->node_queries_by_timeout) {
   1308     /* LCOV_EXCL_START: OutOfMemory */
   1309     end_query(channel, server, query, ARES_ENOMEM, NULL);
   1310     return ARES_ENOMEM;
   1311     /* LCOV_EXCL_STOP */
   1312   }
   1313 
   1314   /* Keep track of queries bucketed by connection, so we can process errors
   1315    * quickly. */
   1316   ares_llist_node_destroy(query->node_queries_to_conn);
   1317   query->node_queries_to_conn =
   1318     ares_llist_insert_last(conn->queries_to_conn, query);
   1319 
   1320   if (query->node_queries_to_conn == NULL) {
   1321     /* LCOV_EXCL_START: OutOfMemory */
   1322     end_query(channel, server, query, ARES_ENOMEM, NULL);
   1323     return ARES_ENOMEM;
   1324     /* LCOV_EXCL_STOP */
   1325   }
   1326 
   1327   query->conn = conn;
   1328   conn->total_queries++;
   1329 
   1330   /* We just successfully enqueud a query, see if we should probe downed
   1331    * servers. */
   1332   if (probe_downed_server) {
   1333     ares_probe_failed_server(channel, server, query);
   1334   }
   1335 
   1336   return ARES_SUCCESS;
   1337 }
   1338 
   1339 static ares_bool_t same_questions(const ares_query_t      *query,
   1340                                   const ares_dns_record_t *arec)
   1341 {
   1342   size_t                   i;
   1343   ares_bool_t              rv      = ARES_FALSE;
   1344   const ares_dns_record_t *qrec    = query->query;
   1345   const ares_channel_t    *channel = query->channel;
   1346 
   1347 
   1348   if (ares_dns_record_query_cnt(qrec) != ares_dns_record_query_cnt(arec)) {
   1349     goto done;
   1350   }
   1351 
   1352   for (i = 0; i < ares_dns_record_query_cnt(qrec); i++) {
   1353     const char         *qname = NULL;
   1354     const char         *aname = NULL;
   1355     ares_dns_rec_type_t qtype;
   1356     ares_dns_rec_type_t atype;
   1357     ares_dns_class_t    qclass;
   1358     ares_dns_class_t    aclass;
   1359 
   1360     if (ares_dns_record_query_get(qrec, i, &qname, &qtype, &qclass) !=
   1361           ARES_SUCCESS ||
   1362         qname == NULL) {
   1363       goto done;
   1364     }
   1365 
   1366     if (ares_dns_record_query_get(arec, i, &aname, &atype, &aclass) !=
   1367           ARES_SUCCESS ||
   1368         aname == NULL) {
   1369       goto done;
   1370     }
   1371 
   1372     if (qtype != atype || qclass != aclass) {
   1373       goto done;
   1374     }
   1375 
   1376     if (channel->flags & ARES_FLAG_DNS0x20 && !query->using_tcp) {
   1377       /* NOTE: for DNS 0x20, part of the protection is to use a case-sensitive
   1378        *       comparison of the DNS query name.  This expects the upstream DNS
   1379        *       server to preserve the case of the name in the response packet.
   1380        *       https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00
   1381        */
   1382       if (!ares_streq(qname, aname)) {
   1383         goto done;
   1384       }
   1385     } else {
   1386       /* without DNS0x20 use case-insensitive matching */
   1387       if (!ares_strcaseeq(qname, aname)) {
   1388         goto done;
   1389       }
   1390     }
   1391   }
   1392 
   1393   rv = ARES_TRUE;
   1394 
   1395 done:
   1396   return rv;
   1397 }
   1398 
   1399 static void ares_detach_query(ares_query_t *query)
   1400 {
   1401   /* Remove the query from all the lists in which it is linked */
   1402   ares_query_remove_from_conn(query);
   1403   ares_htable_szvp_remove(query->channel->queries_by_qid, query->qid);
   1404   ares_llist_node_destroy(query->node_all_queries);
   1405   query->node_all_queries = NULL;
   1406 }
   1407 
   1408 static void end_query(ares_channel_t *channel, ares_server_t *server,
   1409                       ares_query_t *query, ares_status_t status,
   1410                       const ares_dns_record_t *dnsrec)
   1411 {
   1412   /* If we were probing for the server to come back online, lets mark it as
   1413    * no longer being probed */
   1414   if (server != NULL) {
   1415     server->probe_pending = ARES_FALSE;
   1416   }
   1417 
   1418   ares_metrics_record(query, server, status, dnsrec);
   1419 
   1420   /* Invoke the callback. */
   1421   query->callback(query->arg, status, query->timeouts, dnsrec);
   1422   ares_free_query(query);
   1423 
   1424   /* Check and notify if no other queries are enqueued on the channel.  This
   1425    * must come after the callback and freeing the query for 2 reasons.
   1426    *  1) The callback itself may enqueue a new query
   1427    *  2) Technically the current query isn't detached until it is free()'d.
   1428    */
   1429   ares_queue_notify_empty(channel);
   1430 }
   1431 
   1432 void ares_free_query(ares_query_t *query)
   1433 {
   1434   ares_detach_query(query);
   1435   /* Zero out some important stuff, to help catch bugs */
   1436   query->callback = NULL;
   1437   query->arg      = NULL;
   1438   /* Deallocate the memory associated with the query */
   1439   ares_dns_record_destroy(query->query);
   1440 
   1441   ares_free(query);
   1442 }