• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ares_query_remove_from_conn(ares_query_t * query)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 */
invoke_server_state_cb(const ares_server_t * server,ares_bool_t success,int flags)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 
server_increment_failures(ares_server_t * server,ares_bool_t used_tcp)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 
server_set_good(ares_server_t * server,ares_bool_t used_tcp)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 */
ares_timedout(const ares_timeval_t * now,const ares_timeval_t * check)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 */
timeadd(ares_timeval_t * now,size_t millisecs)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 
ares_process_fds_nolock(ares_channel_t * channel,const ares_fd_events_t * events,size_t nevents,unsigned int flags)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 
ares_process_fds(ares_channel_t * channel,const ares_fd_events_t * events,size_t nevents,unsigned int flags)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 
ares_process_fd(ares_channel_t * channel,ares_socket_t read_fd,ares_socket_t write_fd)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 
channel_socket_list(const ares_channel_t * channel,size_t * num)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  */
ares_process(ares_channel_t * channel,fd_set * read_fds,fd_set * write_fds)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 
process_write(ares_channel_t * channel,ares_socket_t write_fd)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 
ares_process_pending_write(ares_channel_t * channel)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 
read_conn_packets(ares_conn_t * conn)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 
ares_append_requeue(ares_array_t ** requeue,ares_query_t * query,ares_server_t * server)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 
read_answers(ares_conn_t * conn,const ares_timeval_t * now)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 
process_read(ares_channel_t * channel,ares_socket_t read_fd,const ares_timeval_t * now)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. */
process_timeouts(ares_channel_t * channel,const ares_timeval_t * now)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 
rewrite_without_edns(ares_query_t * query)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 
issue_might_be_edns(const ares_dns_record_t * req,const ares_dns_record_t * rsp)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. */
process_answer(ares_channel_t * channel,const unsigned char * abuf,size_t alen,ares_conn_t * conn,const ares_timeval_t * now,ares_array_t ** requeue)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 
handle_conn_error(ares_conn_t * conn,ares_bool_t critical_failure,ares_status_t failure_status)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 */
ares_requeue_query(ares_query_t * query,const ares_timeval_t * now,ares_status_t status,ares_bool_t inc_try_count,const ares_dns_record_t * dnsrec,ares_array_t ** requeue)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. */
count_highest_prio_servers(const ares_channel_t * channel)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 */
ares_random_server(ares_channel_t * channel)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 
server_probe_cb(void * arg,ares_status_t status,size_t timeouts,const ares_dns_record_t * dnsrec)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 */
ares_probe_failed_server(ares_channel_t * channel,const ares_server_t * server,const ares_query_t * query)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 
ares_calc_query_timeout(const ares_query_t * query,const ares_server_t * server,const ares_timeval_t * now)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 
ares_fetch_connection(const ares_channel_t * channel,ares_server_t * server,const ares_query_t * query)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 
ares_conn_query_write(ares_conn_t * conn,ares_query_t * query,const ares_timeval_t * now)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 
ares_send_query(ares_server_t * requested_server,ares_query_t * query,const ares_timeval_t * now)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 #if OHOS_DNS_PROXY_BY_NETSYS
1299   timeplus = channel->timeout;
1300 #endif
1301   /* Keep track of queries bucketed by timeout, so we can process
1302    * timeout events quickly.
1303    */
1304   ares_slist_node_destroy(query->node_queries_by_timeout);
1305   query->ts      = *now;
1306   query->timeout = *now;
1307   timeadd(&query->timeout, timeplus);
1308   query->node_queries_by_timeout =
1309     ares_slist_insert(channel->queries_by_timeout, query);
1310   if (!query->node_queries_by_timeout) {
1311     /* LCOV_EXCL_START: OutOfMemory */
1312     end_query(channel, server, query, ARES_ENOMEM, NULL);
1313     return ARES_ENOMEM;
1314     /* LCOV_EXCL_STOP */
1315   }
1316 
1317   /* Keep track of queries bucketed by connection, so we can process errors
1318    * quickly. */
1319   ares_llist_node_destroy(query->node_queries_to_conn);
1320   query->node_queries_to_conn =
1321     ares_llist_insert_last(conn->queries_to_conn, query);
1322 
1323   if (query->node_queries_to_conn == NULL) {
1324     /* LCOV_EXCL_START: OutOfMemory */
1325     end_query(channel, server, query, ARES_ENOMEM, NULL);
1326     return ARES_ENOMEM;
1327     /* LCOV_EXCL_STOP */
1328   }
1329 
1330   query->conn = conn;
1331   conn->total_queries++;
1332 
1333   /* We just successfully enqueud a query, see if we should probe downed
1334    * servers. */
1335   if (probe_downed_server) {
1336     ares_probe_failed_server(channel, server, query);
1337   }
1338 
1339   return ARES_SUCCESS;
1340 }
1341 
same_questions(const ares_query_t * query,const ares_dns_record_t * arec)1342 static ares_bool_t same_questions(const ares_query_t      *query,
1343                                   const ares_dns_record_t *arec)
1344 {
1345   size_t                   i;
1346   ares_bool_t              rv      = ARES_FALSE;
1347   const ares_dns_record_t *qrec    = query->query;
1348   const ares_channel_t    *channel = query->channel;
1349 
1350 
1351   if (ares_dns_record_query_cnt(qrec) != ares_dns_record_query_cnt(arec)) {
1352     goto done;
1353   }
1354 
1355   for (i = 0; i < ares_dns_record_query_cnt(qrec); i++) {
1356     const char         *qname = NULL;
1357     const char         *aname = NULL;
1358     ares_dns_rec_type_t qtype;
1359     ares_dns_rec_type_t atype;
1360     ares_dns_class_t    qclass;
1361     ares_dns_class_t    aclass;
1362 
1363     if (ares_dns_record_query_get(qrec, i, &qname, &qtype, &qclass) !=
1364           ARES_SUCCESS ||
1365         qname == NULL) {
1366       goto done;
1367     }
1368 
1369     if (ares_dns_record_query_get(arec, i, &aname, &atype, &aclass) !=
1370           ARES_SUCCESS ||
1371         aname == NULL) {
1372       goto done;
1373     }
1374 
1375     if (qtype != atype || qclass != aclass) {
1376       goto done;
1377     }
1378 
1379     if (channel->flags & ARES_FLAG_DNS0x20 && !query->using_tcp) {
1380       /* NOTE: for DNS 0x20, part of the protection is to use a case-sensitive
1381        *       comparison of the DNS query name.  This expects the upstream DNS
1382        *       server to preserve the case of the name in the response packet.
1383        *       https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00
1384        */
1385       if (!ares_streq(qname, aname)) {
1386         goto done;
1387       }
1388     } else {
1389       /* without DNS0x20 use case-insensitive matching */
1390       if (!ares_strcaseeq(qname, aname)) {
1391         goto done;
1392       }
1393     }
1394   }
1395 
1396   rv = ARES_TRUE;
1397 
1398 done:
1399   return rv;
1400 }
1401 
ares_detach_query(ares_query_t * query)1402 static void ares_detach_query(ares_query_t *query)
1403 {
1404   /* Remove the query from all the lists in which it is linked */
1405   ares_query_remove_from_conn(query);
1406   ares_htable_szvp_remove(query->channel->queries_by_qid, query->qid);
1407   ares_llist_node_destroy(query->node_all_queries);
1408   query->node_all_queries = NULL;
1409 }
1410 
end_query(ares_channel_t * channel,ares_server_t * server,ares_query_t * query,ares_status_t status,const ares_dns_record_t * dnsrec)1411 static void end_query(ares_channel_t *channel, ares_server_t *server,
1412                       ares_query_t *query, ares_status_t status,
1413                       const ares_dns_record_t *dnsrec)
1414 {
1415   /* If we were probing for the server to come back online, lets mark it as
1416    * no longer being probed */
1417   if (server != NULL) {
1418     server->probe_pending = ARES_FALSE;
1419   }
1420 
1421   ares_metrics_record(query, server, status, dnsrec);
1422 
1423   /* Invoke the callback. */
1424   query->callback(query->arg, status, query->timeouts, dnsrec);
1425   ares_free_query(query);
1426 
1427   /* Check and notify if no other queries are enqueued on the channel.  This
1428    * must come after the callback and freeing the query for 2 reasons.
1429    *  1) The callback itself may enqueue a new query
1430    *  2) Technically the current query isn't detached until it is free()'d.
1431    */
1432   ares_queue_notify_empty(channel);
1433 }
1434 
ares_free_query(ares_query_t * query)1435 void ares_free_query(ares_query_t *query)
1436 {
1437   ares_detach_query(query);
1438   /* Zero out some important stuff, to help catch bugs */
1439   query->callback = NULL;
1440   query->arg      = NULL;
1441   /* Deallocate the memory associated with the query */
1442   ares_dns_record_destroy(query->query);
1443 
1444   ares_free(query);
1445 }
1446