11cb0ef41Sopenharmony_ci/* MIT License 21cb0ef41Sopenharmony_ci * 31cb0ef41Sopenharmony_ci * Copyright (c) 1998 Massachusetts Institute of Technology 41cb0ef41Sopenharmony_ci * Copyright (c) The c-ares project and its contributors 51cb0ef41Sopenharmony_ci * 61cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 71cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 81cb0ef41Sopenharmony_ci * in the Software without restriction, including without limitation the rights 91cb0ef41Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 101cb0ef41Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 111cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions: 121cb0ef41Sopenharmony_ci * 131cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice (including the next 141cb0ef41Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 151cb0ef41Sopenharmony_ci * Software. 161cb0ef41Sopenharmony_ci * 171cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 181cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 191cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 201cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 211cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 221cb0ef41Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 231cb0ef41Sopenharmony_ci * SOFTWARE. 241cb0ef41Sopenharmony_ci * 251cb0ef41Sopenharmony_ci * SPDX-License-Identifier: MIT 261cb0ef41Sopenharmony_ci */ 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci#include "ares_setup.h" 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci#include "ares.h" 311cb0ef41Sopenharmony_ci#include "ares_private.h" 321cb0ef41Sopenharmony_ci#include <assert.h> 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_cistatic void ares__requeue_queries(struct server_connection *conn) 351cb0ef41Sopenharmony_ci{ 361cb0ef41Sopenharmony_ci struct query *query; 371cb0ef41Sopenharmony_ci struct timeval now = ares__tvnow(); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci while ((query = ares__llist_first_val(conn->queries_to_conn)) != NULL) { 401cb0ef41Sopenharmony_ci ares__requeue_query(query, &now); 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_civoid ares__close_connection(struct server_connection *conn) 451cb0ef41Sopenharmony_ci{ 461cb0ef41Sopenharmony_ci struct server_state *server = conn->server; 471cb0ef41Sopenharmony_ci ares_channel_t *channel = server->channel; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci /* Unlink */ 501cb0ef41Sopenharmony_ci ares__llist_node_claim( 511cb0ef41Sopenharmony_ci ares__htable_asvp_get_direct(channel->connnode_by_socket, conn->fd)); 521cb0ef41Sopenharmony_ci ares__htable_asvp_remove(channel->connnode_by_socket, conn->fd); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci if (conn->is_tcp) { 551cb0ef41Sopenharmony_ci /* Reset any existing input and output buffer. */ 561cb0ef41Sopenharmony_ci ares__buf_consume(server->tcp_parser, ares__buf_len(server->tcp_parser)); 571cb0ef41Sopenharmony_ci ares__buf_consume(server->tcp_send, ares__buf_len(server->tcp_send)); 581cb0ef41Sopenharmony_ci server->tcp_conn = NULL; 591cb0ef41Sopenharmony_ci } 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci /* Requeue queries to other connections */ 621cb0ef41Sopenharmony_ci ares__requeue_queries(conn); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci ares__llist_destroy(conn->queries_to_conn); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci SOCK_STATE_CALLBACK(channel, conn->fd, 0, 0); 671cb0ef41Sopenharmony_ci ares__close_socket(channel, conn->fd); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci ares_free(conn); 701cb0ef41Sopenharmony_ci} 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_civoid ares__close_sockets(struct server_state *server) 731cb0ef41Sopenharmony_ci{ 741cb0ef41Sopenharmony_ci ares__llist_node_t *node; 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci while ((node = ares__llist_node_first(server->connections)) != NULL) { 771cb0ef41Sopenharmony_ci struct server_connection *conn = ares__llist_node_val(node); 781cb0ef41Sopenharmony_ci ares__close_connection(conn); 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci} 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_civoid ares__check_cleanup_conn(const ares_channel_t *channel, 831cb0ef41Sopenharmony_ci struct server_connection *conn) 841cb0ef41Sopenharmony_ci{ 851cb0ef41Sopenharmony_ci ares_bool_t do_cleanup = ARES_FALSE; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci if (channel == NULL || conn == NULL) { 881cb0ef41Sopenharmony_ci return; 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci if (ares__llist_len(conn->queries_to_conn)) { 921cb0ef41Sopenharmony_ci return; 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci /* If we are configured not to stay open, close it out */ 961cb0ef41Sopenharmony_ci if (!(channel->flags & ARES_FLAG_STAYOPEN)) { 971cb0ef41Sopenharmony_ci do_cleanup = ARES_TRUE; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci /* If the udp connection hit its max queries, always close it */ 1011cb0ef41Sopenharmony_ci if (!conn->is_tcp && channel->udp_max_queries > 0 && 1021cb0ef41Sopenharmony_ci conn->total_queries >= channel->udp_max_queries) { 1031cb0ef41Sopenharmony_ci do_cleanup = ARES_TRUE; 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci if (!do_cleanup) { 1071cb0ef41Sopenharmony_ci return; 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci ares__close_connection(conn); 1111cb0ef41Sopenharmony_ci} 112