diff options
Diffstat (limited to 'src/lib/ares_getsock.c')
-rw-r--r-- | src/lib/ares_getsock.c | 106 |
1 files changed, 61 insertions, 45 deletions
diff --git a/src/lib/ares_getsock.c b/src/lib/ares_getsock.c index 22d3446..2cdfdb7 100644 --- a/src/lib/ares_getsock.c +++ b/src/lib/ares_getsock.c @@ -1,15 +1,27 @@ - -/* Copyright (C) 2005 - 2010, Daniel Stenberg +/* MIT License + * + * Copyright (c) 2005 Daniel Stenberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of M.I.T. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. M.I.T. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * SPDX-License-Identifier: MIT */ #include "ares_setup.h" @@ -17,50 +29,54 @@ #include "ares.h" #include "ares_private.h" -int ares_getsock(ares_channel channel, - ares_socket_t *socks, +int ares_getsock(ares_channel channel, ares_socket_t *socks, int numsocks) /* size of the 'socks' array */ { struct server_state *server; - int i; - int sockindex=0; - int bitmap = 0; - unsigned int setbits = 0xffffffff; + size_t i; + size_t sockindex = 0; + unsigned int bitmap = 0; + unsigned int setbits = 0xffffffff; /* Are there any active queries? */ - int active_queries = !ares__is_list_empty(&(channel->all_queries)); + size_t active_queries = ares__llist_len(channel->all_queries); + + if (numsocks <= 0) { + return 0; + } + + for (i = 0; i < channel->nservers; i++) { + ares__llist_node_t *node; + server = &channel->servers[i]; + + for (node = ares__llist_node_first(server->connections); node != NULL; + node = ares__llist_node_next(node)) { + const struct server_connection *conn = ares__llist_node_val(node); + + if (sockindex >= (size_t)numsocks || sockindex >= ARES_GETSOCK_MAXNUM) { + break; + } - for (i = 0; i < channel->nservers; i++) - { - server = &channel->servers[i]; /* We only need to register interest in UDP sockets if we have * outstanding queries. */ - if (active_queries && server->udp_socket != ARES_SOCKET_BAD) - { - if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM) - break; - socks[sockindex] = server->udp_socket; - bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); - sockindex++; - } - /* We always register for TCP events, because we want to know - * when the other side closes the connection, so we don't waste - * time trying to use a broken connection. - */ - if (server->tcp_socket != ARES_SOCKET_BAD) - { - if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM) - break; - socks[sockindex] = server->tcp_socket; - bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); + if (!active_queries && !conn->is_tcp) { + continue; + } + + socks[sockindex] = conn->fd; + + if (active_queries || conn->is_tcp) { + bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); + } - if (server->qhead && active_queries) - /* then the tcp socket is also writable! */ - bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); + if (conn->is_tcp && ares__buf_len(server->tcp_send)) { + /* then the tcp socket is also writable! */ + bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); + } - sockindex++; - } + sockindex++; } - return bitmap; + } + return (int)bitmap; } |