1
2 /* Copyright (C) 2009-2013 by Daniel Stenberg
3 *
4 * Permission to use, copy, modify, and distribute this
5 * software and its documentation for any purpose and without
6 * fee is hereby granted, provided that the above copyright
7 * notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting
9 * documentation, and that the name of M.I.T. not be used in
10 * advertising or publicity pertaining to distribution of the
11 * software without specific, written prior permission.
12 * M.I.T. makes no representations about the suitability of
13 * this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
15 */
16
17
18 #include "ares_setup.h"
19
20 #include <stddef.h>
21
22 #include "ares.h"
23 #include "ares_data.h"
24 #include "ares_private.h"
25
26
27 /*
28 ** ares_free_data() - c-ares external API function.
29 **
30 ** This function must be used by the application to free data memory that
31 ** has been internally allocated by some c-ares function and for which a
32 ** pointer has already been returned to the calling application. The list
33 ** of c-ares functions returning pointers that must be free'ed using this
34 ** function is:
35 **
36 ** ares_get_servers()
37 ** ares_parse_srv_reply()
38 ** ares_parse_txt_reply()
39 */
40
ares_free_data(void * dataptr)41 void ares_free_data(void *dataptr)
42 {
43 while (dataptr != NULL) {
44 struct ares_data *ptr;
45 void *next_data = NULL;
46
47 #ifdef __INTEL_COMPILER
48 # pragma warning(push)
49 # pragma warning(disable:1684)
50 /* 1684: conversion from pointer to same-sized integral type */
51 #endif
52
53 ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
54
55 #ifdef __INTEL_COMPILER
56 # pragma warning(pop)
57 #endif
58
59 if (ptr->mark != ARES_DATATYPE_MARK)
60 return;
61
62 switch (ptr->type)
63 {
64 case ARES_DATATYPE_MX_REPLY:
65
66 if (ptr->data.mx_reply.next)
67 next_data = ptr->data.mx_reply.next;
68 if (ptr->data.mx_reply.host)
69 ares_free(ptr->data.mx_reply.host);
70 break;
71
72 case ARES_DATATYPE_SRV_REPLY:
73
74 if (ptr->data.srv_reply.next)
75 next_data = ptr->data.srv_reply.next;
76 if (ptr->data.srv_reply.host)
77 ares_free(ptr->data.srv_reply.host);
78 break;
79
80 case ARES_DATATYPE_URI_REPLY:
81
82 if (ptr->data.uri_reply.next)
83 next_data = ptr->data.uri_reply.next;
84 if (ptr->data.uri_reply.uri)
85 ares_free(ptr->data.uri_reply.uri);
86 break;
87
88 case ARES_DATATYPE_TXT_REPLY:
89 case ARES_DATATYPE_TXT_EXT:
90
91 if (ptr->data.txt_reply.next)
92 next_data = ptr->data.txt_reply.next;
93 if (ptr->data.txt_reply.txt)
94 ares_free(ptr->data.txt_reply.txt);
95 break;
96
97 case ARES_DATATYPE_ADDR_NODE:
98
99 if (ptr->data.addr_node.next)
100 next_data = ptr->data.addr_node.next;
101 break;
102
103 case ARES_DATATYPE_ADDR_PORT_NODE:
104
105 if (ptr->data.addr_port_node.next)
106 next_data = ptr->data.addr_port_node.next;
107 break;
108
109 case ARES_DATATYPE_NAPTR_REPLY:
110
111 if (ptr->data.naptr_reply.next)
112 next_data = ptr->data.naptr_reply.next;
113 if (ptr->data.naptr_reply.flags)
114 ares_free(ptr->data.naptr_reply.flags);
115 if (ptr->data.naptr_reply.service)
116 ares_free(ptr->data.naptr_reply.service);
117 if (ptr->data.naptr_reply.regexp)
118 ares_free(ptr->data.naptr_reply.regexp);
119 if (ptr->data.naptr_reply.replacement)
120 ares_free(ptr->data.naptr_reply.replacement);
121 break;
122
123 case ARES_DATATYPE_SOA_REPLY:
124 if (ptr->data.soa_reply.nsname)
125 ares_free(ptr->data.soa_reply.nsname);
126 if (ptr->data.soa_reply.hostmaster)
127 ares_free(ptr->data.soa_reply.hostmaster);
128 break;
129
130 case ARES_DATATYPE_CAA_REPLY:
131
132 if (ptr->data.caa_reply.next)
133 next_data = ptr->data.caa_reply.next;
134 if (ptr->data.caa_reply.property)
135 ares_free(ptr->data.caa_reply.property);
136 if (ptr->data.caa_reply.value)
137 ares_free(ptr->data.caa_reply.value);
138 break;
139
140 default:
141 return;
142 }
143
144 ares_free(ptr);
145 dataptr = next_data;
146 }
147 }
148
149
150 /*
151 ** ares_malloc_data() - c-ares internal helper function.
152 **
153 ** This function allocates memory for a c-ares private ares_data struct
154 ** for the specified ares_datatype, initializes c-ares private fields
155 ** and zero initializes those which later might be used from the public
156 ** API. It returns an interior pointer which can be passed by c-ares
157 ** functions to the calling application, and that must be free'ed using
158 ** c-ares external API function ares_free_data().
159 */
160
ares_malloc_data(ares_datatype type)161 void *ares_malloc_data(ares_datatype type)
162 {
163 struct ares_data *ptr;
164
165 ptr = ares_malloc(sizeof(struct ares_data));
166 if (!ptr)
167 return NULL;
168
169 switch (type)
170 {
171 case ARES_DATATYPE_MX_REPLY:
172 ptr->data.mx_reply.next = NULL;
173 ptr->data.mx_reply.host = NULL;
174 ptr->data.mx_reply.priority = 0;
175 break;
176
177 case ARES_DATATYPE_SRV_REPLY:
178 ptr->data.srv_reply.next = NULL;
179 ptr->data.srv_reply.host = NULL;
180 ptr->data.srv_reply.priority = 0;
181 ptr->data.srv_reply.weight = 0;
182 ptr->data.srv_reply.port = 0;
183 break;
184
185 case ARES_DATATYPE_URI_REPLY:
186 ptr->data.uri_reply.next = NULL;
187 ptr->data.uri_reply.priority = 0;
188 ptr->data.uri_reply.weight = 0;
189 ptr->data.uri_reply.uri = NULL;
190 ptr->data.uri_reply.ttl = 0;
191 break;
192
193 case ARES_DATATYPE_TXT_EXT:
194 ptr->data.txt_ext.record_start = 0;
195 /* FALLTHROUGH */
196
197 case ARES_DATATYPE_TXT_REPLY:
198 ptr->data.txt_reply.next = NULL;
199 ptr->data.txt_reply.txt = NULL;
200 ptr->data.txt_reply.length = 0;
201 break;
202
203 case ARES_DATATYPE_CAA_REPLY:
204 ptr->data.caa_reply.next = NULL;
205 ptr->data.caa_reply.plength = 0;
206 ptr->data.caa_reply.property = NULL;
207 ptr->data.caa_reply.length = 0;
208 ptr->data.caa_reply.value = NULL;
209 break;
210
211 case ARES_DATATYPE_ADDR_NODE:
212 ptr->data.addr_node.next = NULL;
213 ptr->data.addr_node.family = 0;
214 memset(&ptr->data.addr_node.addrV6, 0,
215 sizeof(ptr->data.addr_node.addrV6));
216 break;
217
218 case ARES_DATATYPE_ADDR_PORT_NODE:
219 ptr->data.addr_port_node.next = NULL;
220 ptr->data.addr_port_node.family = 0;
221 ptr->data.addr_port_node.udp_port = 0;
222 ptr->data.addr_port_node.tcp_port = 0;
223 memset(&ptr->data.addr_port_node.addrV6, 0,
224 sizeof(ptr->data.addr_port_node.addrV6));
225 break;
226
227 case ARES_DATATYPE_NAPTR_REPLY:
228 ptr->data.naptr_reply.next = NULL;
229 ptr->data.naptr_reply.flags = NULL;
230 ptr->data.naptr_reply.service = NULL;
231 ptr->data.naptr_reply.regexp = NULL;
232 ptr->data.naptr_reply.replacement = NULL;
233 ptr->data.naptr_reply.order = 0;
234 ptr->data.naptr_reply.preference = 0;
235 break;
236
237 case ARES_DATATYPE_SOA_REPLY:
238 ptr->data.soa_reply.nsname = NULL;
239 ptr->data.soa_reply.hostmaster = NULL;
240 ptr->data.soa_reply.serial = 0;
241 ptr->data.soa_reply.refresh = 0;
242 ptr->data.soa_reply.retry = 0;
243 ptr->data.soa_reply.expire = 0;
244 ptr->data.soa_reply.minttl = 0;
245 break;
246
247 default:
248 ares_free(ptr);
249 return NULL;
250 }
251
252 ptr->mark = ARES_DATATYPE_MARK;
253 ptr->type = type;
254
255 return &ptr->data;
256 }
257