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 "ares.h"
31#include "ares_private.h"
32
33/* library-private global and unique instance vars */
34
35#if defined(ANDROID) || defined(__ANDROID__)
36#  include "ares_android.h"
37#endif
38
39/* library-private global vars with source visibility restricted to this file */
40
41static unsigned int ares_initialized;
42static int          ares_init_flags;
43
44/* library-private global vars with visibility across the whole library */
45
46/* Some systems may return either NULL or a valid pointer on malloc(0).  c-ares
47 * should never call malloc(0) so lets return NULL so we're more likely to find
48 * an issue if it were to occur. */
49
50static void        *default_malloc(size_t size)
51{
52  if (size == 0) {
53    return NULL;
54  }
55  return malloc(size);
56}
57
58#if defined(WIN32)
59/* We need indirections to handle Windows DLL rules. */
60static void *default_realloc(void *p, size_t size)
61{
62  return realloc(p, size);
63}
64
65static void default_free(void *p)
66{
67  free(p);
68}
69#else
70#  define default_realloc realloc
71#  define default_free    free
72#endif
73void *(*ares_malloc)(size_t size)             = default_malloc;
74void *(*ares_realloc)(void *ptr, size_t size) = default_realloc;
75void  (*ares_free)(void *ptr)                 = default_free;
76
77void *ares_malloc_zero(size_t size)
78{
79  void *ptr = ares_malloc(size);
80  if (ptr != NULL) {
81    memset(ptr, 0, size);
82  }
83
84  return ptr;
85}
86
87void *ares_realloc_zero(void *ptr, size_t orig_size, size_t new_size)
88{
89  void *p = ares_realloc(ptr, new_size);
90  if (p == NULL) {
91    return NULL;
92  }
93
94  if (new_size > orig_size) {
95    memset((unsigned char *)p + orig_size, 0, new_size - orig_size);
96  }
97
98  return p;
99}
100
101int ares_library_init(int flags)
102{
103  if (ares_initialized) {
104    ares_initialized++;
105    return ARES_SUCCESS;
106  }
107  ares_initialized++;
108
109  /* NOTE: ARES_LIB_INIT_WIN32 flag no longer used */
110
111  ares_init_flags = flags;
112
113  return ARES_SUCCESS;
114}
115
116int ares_library_init_mem(int flags, void *(*amalloc)(size_t size),
117                          void  (*afree)(void *ptr),
118                          void *(*arealloc)(void *ptr, size_t size))
119{
120  if (amalloc) {
121    ares_malloc = amalloc;
122  }
123  if (arealloc) {
124    ares_realloc = arealloc;
125  }
126  if (afree) {
127    ares_free = afree;
128  }
129  return ares_library_init(flags);
130}
131
132void ares_library_cleanup(void)
133{
134  if (!ares_initialized) {
135    return;
136  }
137  ares_initialized--;
138  if (ares_initialized) {
139    return;
140  }
141
142  /* NOTE: ARES_LIB_INIT_WIN32 flag no longer used */
143
144#if defined(ANDROID) || defined(__ANDROID__)
145  ares_library_cleanup_android();
146#endif
147
148  ares_init_flags = ARES_LIB_INIT_NONE;
149  ares_malloc     = malloc;
150  ares_realloc    = realloc;
151  ares_free       = free;
152}
153
154int ares_library_initialized(void)
155{
156#ifdef USE_WINSOCK
157  if (!ares_initialized) {
158    return ARES_ENOTINITIALIZED;
159  }
160#endif
161  return ARES_SUCCESS;
162}
163