• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 1998 Massachusetts Institute of Technology
4  * Copyright (c) 2004 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_setup.h"
29 
30 #include <assert.h>
31 
32 #include "ares.h"
33 #include "ares_private.h"
34 
ares_destroy(ares_channel_t * channel)35 void ares_destroy(ares_channel_t *channel)
36 {
37   size_t              i;
38   ares__llist_node_t *node = NULL;
39 
40   if (channel == NULL) {
41     return;
42   }
43 
44   /* Lock because callbacks will be triggered */
45   ares__channel_lock(channel);
46 
47   /* Destroy all queries */
48   node = ares__llist_node_first(channel->all_queries);
49   while (node != NULL) {
50     ares__llist_node_t *next  = ares__llist_node_next(node);
51     struct query       *query = ares__llist_node_claim(node);
52 
53     query->node_all_queries = NULL;
54     query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0);
55     ares__free_query(query);
56 
57     node = next;
58   }
59 
60   ares_queue_notify_empty(channel);
61 
62 #ifndef NDEBUG
63   /* Freeing the query should remove it from all the lists in which it sits,
64    * so all query lists should be empty now.
65    */
66   assert(ares__llist_len(channel->all_queries) == 0);
67   assert(ares__htable_szvp_num_keys(channel->queries_by_qid) == 0);
68   assert(ares__slist_len(channel->queries_by_timeout) == 0);
69 #endif
70 
71   ares__destroy_servers_state(channel);
72 
73 #ifndef NDEBUG
74   assert(ares__htable_asvp_num_keys(channel->connnode_by_socket) == 0);
75 #endif
76 
77   /* No more callbacks will be triggered after this point, unlock */
78   ares__channel_unlock(channel);
79 
80   /* Shut down the event thread */
81   if (channel->optmask & ARES_OPT_EVENT_THREAD) {
82     ares_event_thread_destroy(channel);
83   }
84 
85   if (channel->domains) {
86     for (i = 0; i < channel->ndomains; i++) {
87       ares_free(channel->domains[i]);
88     }
89     ares_free(channel->domains);
90   }
91 
92   ares__llist_destroy(channel->all_queries);
93   ares__slist_destroy(channel->queries_by_timeout);
94   ares__htable_szvp_destroy(channel->queries_by_qid);
95   ares__htable_asvp_destroy(channel->connnode_by_socket);
96 
97   ares_free(channel->sortlist);
98   ares_free(channel->lookups);
99   ares_free(channel->resolvconf_path);
100   ares_free(channel->hosts_path);
101   ares__destroy_rand_state(channel->rand_state);
102 
103   ares__hosts_file_destroy(channel->hf);
104 
105   ares__qcache_destroy(channel->qcache);
106 
107   ares__channel_threading_destroy(channel);
108 
109   ares_free(channel);
110 }
111 
ares__destroy_server(struct server_state * server)112 void ares__destroy_server(struct server_state *server)
113 {
114   if (server == NULL) {
115     return;
116   }
117 
118   ares__close_sockets(server);
119   ares__llist_destroy(server->connections);
120   ares__buf_destroy(server->tcp_parser);
121   ares__buf_destroy(server->tcp_send);
122   ares_free(server);
123 }
124 
ares__destroy_servers_state(ares_channel_t * channel)125 void ares__destroy_servers_state(ares_channel_t *channel)
126 {
127   ares__slist_node_t *node;
128 
129   while ((node = ares__slist_node_first(channel->servers)) != NULL) {
130     struct server_state *server = ares__slist_node_claim(node);
131     ares__destroy_server(server);
132   }
133 
134   ares__slist_destroy(channel->servers);
135   channel->servers = NULL;
136 }
137