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_setup.h" 28 29#include "ares.h" 30#include "ares_private.h" 31 32int ares_getsock(ares_channel_t *channel, ares_socket_t *socks, 33 int numsocks) /* size of the 'socks' array */ 34{ 35 ares__slist_node_t *snode; 36 size_t sockindex = 0; 37 unsigned int bitmap = 0; 38 unsigned int setbits = 0xffffffff; 39 40 /* Are there any active queries? */ 41 size_t active_queries; 42 43 if (channel == NULL || numsocks <= 0) { 44 return 0; 45 } 46 47 ares__channel_lock(channel); 48 49 active_queries = ares__llist_len(channel->all_queries); 50 51 for (snode = ares__slist_node_first(channel->servers); snode != NULL; 52 snode = ares__slist_node_next(snode)) { 53 struct server_state *server = ares__slist_node_val(snode); 54 ares__llist_node_t *node; 55 56 for (node = ares__llist_node_first(server->connections); node != NULL; 57 node = ares__llist_node_next(node)) { 58 const struct server_connection *conn = ares__llist_node_val(node); 59 60 if (sockindex >= (size_t)numsocks || sockindex >= ARES_GETSOCK_MAXNUM) { 61 break; 62 } 63 64 /* We only need to register interest in UDP sockets if we have 65 * outstanding queries. 66 */ 67 if (!active_queries && !conn->is_tcp) { 68 continue; 69 } 70 71 socks[sockindex] = conn->fd; 72 73 if (active_queries || conn->is_tcp) { 74 bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); 75 } 76 77 if (conn->is_tcp && ares__buf_len(server->tcp_send)) { 78 /* then the tcp socket is also writable! */ 79 bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); 80 } 81 82 sockindex++; 83 } 84 } 85 86 ares__channel_unlock(channel); 87 return (int)bitmap; 88} 89