ares_parse_naptr_reply: check sufficient data
[platform/upstream/c-ares.git] / ares_library_init.c
1
2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3  * Copyright (C) 2004-2009 by Daniel Stenberg
4  *
5  * Permission to use, copy, modify, and distribute this
6  * software and its documentation for any purpose and without
7  * fee is hereby granted, provided that the above copyright
8  * notice appear in all copies and that both that copyright
9  * notice and this permission notice appear in supporting
10  * documentation, and that the name of M.I.T. not be used in
11  * advertising or publicity pertaining to distribution of the
12  * software without specific, written prior permission.
13  * M.I.T. makes no representations about the suitability of
14  * this software for any purpose.  It is provided "as is"
15  * without express or implied warranty.
16  */
17
18 #include "ares_setup.h"
19
20 #include "ares.h"
21 #include "ares_library_init.h"
22 #include "ares_private.h"
23
24 /* library-private global and unique instance vars */
25
26 #ifdef USE_WINSOCK
27 fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
28 fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
29 fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
30 #endif
31
32 /* library-private global vars with source visibility restricted to this file */
33
34 static unsigned int ares_initialized;
35 static int          ares_init_flags;
36
37 /* library-private global vars with visibility across the whole library */
38 void *(*ares_malloc)(size_t size) = malloc;
39 void *(*ares_realloc)(void *ptr, size_t size) = realloc;
40 void (*ares_free)(void *ptr) = free;
41
42 #ifdef USE_WINSOCK
43 static HMODULE hnd_iphlpapi;
44 static HMODULE hnd_advapi32;
45 #endif
46
47
48 static int ares_win32_init(void)
49 {
50 #ifdef USE_WINSOCK
51
52   hnd_iphlpapi = 0;
53   hnd_iphlpapi = LoadLibraryW(L"iphlpapi.dll");
54   if (!hnd_iphlpapi)
55     return ARES_ELOADIPHLPAPI;
56
57   ares_fpGetNetworkParams = (fpGetNetworkParams_t)
58     GetProcAddress(hnd_iphlpapi, "GetNetworkParams");
59   if (!ares_fpGetNetworkParams)
60     {
61       FreeLibrary(hnd_iphlpapi);
62       return ARES_EADDRGETNETWORKPARAMS;
63     }
64
65   ares_fpGetAdaptersAddresses = (fpGetAdaptersAddresses_t)
66     GetProcAddress(hnd_iphlpapi, "GetAdaptersAddresses");
67   if (!ares_fpGetAdaptersAddresses)
68     {
69       /* This can happen on clients before WinXP, I don't
70          think it should be an error, unless we don't want to
71          support Windows 2000 anymore */
72     }
73
74   /*
75    * When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
76    * also known as RtlGenRandom, which is the case for Windows versions prior
77    * to WinXP then c-ares uses portable rand() function. Then don't error here.
78    */
79
80   hnd_advapi32 = 0;
81   hnd_advapi32 = LoadLibraryW(L"advapi32.dll");
82   if (hnd_advapi32)
83     {
84       ares_fpSystemFunction036 = (fpSystemFunction036_t)
85         GetProcAddress(hnd_advapi32, "SystemFunction036");
86     }
87
88 #endif
89   return ARES_SUCCESS;
90 }
91
92
93 static void ares_win32_cleanup(void)
94 {
95 #ifdef USE_WINSOCK
96   if (hnd_advapi32)
97     FreeLibrary(hnd_advapi32);
98   if (hnd_iphlpapi)
99     FreeLibrary(hnd_iphlpapi);
100 #endif
101 }
102
103
104 int ares_library_init(int flags)
105 {
106   int res;
107
108   if (ares_initialized)
109     {
110       ares_initialized++;
111       return ARES_SUCCESS;
112     }
113   ares_initialized++;
114
115   if (flags & ARES_LIB_INIT_WIN32)
116     {
117       res = ares_win32_init();
118       if (res != ARES_SUCCESS)
119         return res;  /* LCOV_EXCL_LINE: can't test Win32 init failure */
120     }
121
122   ares_init_flags = flags;
123
124   return ARES_SUCCESS;
125 }
126
127 int ares_library_init_mem(int flags,
128                           void *(*amalloc)(size_t size),
129                           void (*afree)(void *ptr),
130                           void *(*arealloc)(void *ptr, size_t size))
131 {
132   if (amalloc)
133     ares_malloc = amalloc;
134   if (arealloc)
135     ares_realloc = arealloc;
136   if (afree)
137     ares_free = afree;
138   return ares_library_init(flags);
139 }
140
141
142 void ares_library_cleanup(void)
143 {
144   if (!ares_initialized)
145     return;
146   ares_initialized--;
147   if (ares_initialized)
148     return;
149
150   if (ares_init_flags & ARES_LIB_INIT_WIN32)
151     ares_win32_cleanup();
152
153   ares_init_flags = ARES_LIB_INIT_NONE;
154   ares_malloc = malloc;
155   ares_realloc = realloc;
156   ares_free = free;
157 }
158
159
160 int ares_library_initialized(void)
161 {
162 #ifdef USE_WINSOCK
163   if (!ares_initialized)
164     return ARES_ENOTINITIALIZED;
165 #endif
166   return ARES_SUCCESS;
167 }