• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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