blob: f89111381511a0f021622264e5e21a46bc1e23ab [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001
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
41void ares_free_data(void *dataptr)
42{
43 struct ares_data *ptr;
44
45 if (!dataptr)
46 return;
47
48#ifdef __INTEL_COMPILER
49# pragma warning(push)
50# pragma warning(disable:1684)
51 /* 1684: conversion from pointer to same-sized integral type */
52#endif
53
54 ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
55
56#ifdef __INTEL_COMPILER
57# pragma warning(pop)
58#endif
59
60 if (ptr->mark != ARES_DATATYPE_MARK)
61 return;
62
63 switch (ptr->type)
64 {
65 case ARES_DATATYPE_MX_REPLY:
66
67 if (ptr->data.mx_reply.next)
68 ares_free_data(ptr->data.mx_reply.next);
69 if (ptr->data.mx_reply.host)
70 ares_free(ptr->data.mx_reply.host);
71 break;
72
73 case ARES_DATATYPE_SRV_REPLY:
74
75 if (ptr->data.srv_reply.next)
76 ares_free_data(ptr->data.srv_reply.next);
77 if (ptr->data.srv_reply.host)
78 ares_free(ptr->data.srv_reply.host);
79 break;
80
81 case ARES_DATATYPE_TXT_REPLY:
82 case ARES_DATATYPE_TXT_EXT:
83
84 if (ptr->data.txt_reply.next)
85 ares_free_data(ptr->data.txt_reply.next);
86 if (ptr->data.txt_reply.txt)
87 ares_free(ptr->data.txt_reply.txt);
88 break;
89
90 case ARES_DATATYPE_ADDR_NODE:
91
92 if (ptr->data.addr_node.next)
93 ares_free_data(ptr->data.addr_node.next);
94 break;
95
96 case ARES_DATATYPE_ADDR_PORT_NODE:
97
98 if (ptr->data.addr_port_node.next)
99 ares_free_data(ptr->data.addr_port_node.next);
100 break;
101
102 case ARES_DATATYPE_NAPTR_REPLY:
103
104 if (ptr->data.naptr_reply.next)
105 ares_free_data(ptr->data.naptr_reply.next);
106 if (ptr->data.naptr_reply.flags)
107 ares_free(ptr->data.naptr_reply.flags);
108 if (ptr->data.naptr_reply.service)
109 ares_free(ptr->data.naptr_reply.service);
110 if (ptr->data.naptr_reply.regexp)
111 ares_free(ptr->data.naptr_reply.regexp);
112 if (ptr->data.naptr_reply.replacement)
113 ares_free(ptr->data.naptr_reply.replacement);
114 break;
115
116 case ARES_DATATYPE_SOA_REPLY:
117 if (ptr->data.soa_reply.nsname)
118 ares_free(ptr->data.soa_reply.nsname);
119 if (ptr->data.soa_reply.hostmaster)
120 ares_free(ptr->data.soa_reply.hostmaster);
121 break;
122
123 default:
124 return;
125 }
126
127 ares_free(ptr);
128}
129
130
131/*
132** ares_malloc_data() - c-ares internal helper function.
133**
134** This function allocates memory for a c-ares private ares_data struct
135** for the specified ares_datatype, initializes c-ares private fields
136** and zero initializes those which later might be used from the public
137** API. It returns an interior pointer which can be passed by c-ares
138** functions to the calling application, and that must be free'ed using
139** c-ares external API function ares_free_data().
140*/
141
142void *ares_malloc_data(ares_datatype type)
143{
144 struct ares_data *ptr;
145
146 ptr = ares_malloc(sizeof(struct ares_data));
147 if (!ptr)
148 return NULL;
149
150 switch (type)
151 {
152 case ARES_DATATYPE_MX_REPLY:
153 ptr->data.mx_reply.next = NULL;
154 ptr->data.mx_reply.host = NULL;
155 ptr->data.mx_reply.priority = 0;
156 break;
157
158 case ARES_DATATYPE_SRV_REPLY:
159 ptr->data.srv_reply.next = NULL;
160 ptr->data.srv_reply.host = NULL;
161 ptr->data.srv_reply.priority = 0;
162 ptr->data.srv_reply.weight = 0;
163 ptr->data.srv_reply.port = 0;
164 break;
165
166 case ARES_DATATYPE_TXT_EXT:
167 ptr->data.txt_ext.record_start = 0;
168 /* FALLTHROUGH */
169
170 case ARES_DATATYPE_TXT_REPLY:
171 ptr->data.txt_reply.next = NULL;
172 ptr->data.txt_reply.txt = NULL;
173 ptr->data.txt_reply.length = 0;
174 break;
175
176 case ARES_DATATYPE_ADDR_NODE:
177 ptr->data.addr_node.next = NULL;
178 ptr->data.addr_node.family = 0;
179 memset(&ptr->data.addr_node.addrV6, 0,
180 sizeof(ptr->data.addr_node.addrV6));
181 break;
182
183 case ARES_DATATYPE_ADDR_PORT_NODE:
184 ptr->data.addr_port_node.next = NULL;
185 ptr->data.addr_port_node.family = 0;
186 ptr->data.addr_port_node.udp_port = 0;
187 ptr->data.addr_port_node.tcp_port = 0;
188 memset(&ptr->data.addr_port_node.addrV6, 0,
189 sizeof(ptr->data.addr_port_node.addrV6));
190 break;
191
192 case ARES_DATATYPE_NAPTR_REPLY:
193 ptr->data.naptr_reply.next = NULL;
194 ptr->data.naptr_reply.flags = NULL;
195 ptr->data.naptr_reply.service = NULL;
196 ptr->data.naptr_reply.regexp = NULL;
197 ptr->data.naptr_reply.replacement = NULL;
198 ptr->data.naptr_reply.order = 0;
199 ptr->data.naptr_reply.preference = 0;
200 break;
201
202 case ARES_DATATYPE_SOA_REPLY:
203 ptr->data.soa_reply.nsname = NULL;
204 ptr->data.soa_reply.hostmaster = NULL;
205 ptr->data.soa_reply.serial = 0;
206 ptr->data.soa_reply.refresh = 0;
207 ptr->data.soa_reply.retry = 0;
208 ptr->data.soa_reply.expire = 0;
209 ptr->data.soa_reply.minttl = 0;
210 break;
211
212 default:
213 ares_free(ptr);
214 return NULL;
215 }
216
217 ptr->mark = ARES_DATATYPE_MARK;
218 ptr->type = type;
219
220 return &ptr->data;
221}