• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 2005 Daniel Stenberg
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * SPDX-License-Identifier: MIT
25  */
26 
27 #include "ares_private.h"
28 
ares_getsock(const ares_channel_t * channel,ares_socket_t * socks,int numsocks)29 int ares_getsock(const ares_channel_t *channel, ares_socket_t *socks,
30                  int numsocks) /* size of the 'socks' array */
31 {
32   ares_slist_node_t *snode;
33   size_t             sockindex = 0;
34   unsigned int       bitmap    = 0;
35   unsigned int       setbits   = 0xffffffff;
36 
37   /* Are there any active queries? */
38   size_t             active_queries;
39 
40   if (channel == NULL || numsocks <= 0) {
41     return 0;
42   }
43 
44   ares_channel_lock(channel);
45 
46   active_queries = ares_llist_len(channel->all_queries);
47 
48   for (snode = ares_slist_node_first(channel->servers); snode != NULL;
49        snode = ares_slist_node_next(snode)) {
50     ares_server_t     *server = ares_slist_node_val(snode);
51     ares_llist_node_t *node;
52 
53     for (node = ares_llist_node_first(server->connections); node != NULL;
54          node = ares_llist_node_next(node)) {
55       const ares_conn_t *conn = ares_llist_node_val(node);
56 
57       if (sockindex >= (size_t)numsocks || sockindex >= ARES_GETSOCK_MAXNUM) {
58         break;
59       }
60 
61       /* We only need to register interest in UDP sockets if we have
62        * outstanding queries.
63        */
64       if (!active_queries && !(conn->flags & ARES_CONN_FLAG_TCP)) {
65         continue;
66       }
67 
68       socks[sockindex] = conn->fd;
69 
70       if (active_queries || conn->flags & ARES_CONN_FLAG_TCP) {
71         bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
72       }
73 
74       if (conn->state_flags & ARES_CONN_STATE_WRITE) {
75         /* then the tcp socket is also writable! */
76         bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex);
77       }
78 
79       sockindex++;
80     }
81   }
82 
83   ares_channel_unlock(channel);
84   return (int)bitmap;
85 }
86