summaryrefslogtreecommitdiff
path: root/openbsd-compat/getrrsetbyname.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-11-05 16:56:52 +1100
committerDamien Miller <djm@mindrot.org>2005-11-05 16:56:52 +1100
commit9b59ada7ca95a7ab42c49ae7b7cd6ff713b1bea0 (patch)
tree35b4ce12da414bbcf88edf3ad820503f1c8ec334 /openbsd-compat/getrrsetbyname.c
parent3a38c5a856073672228b8033599e96fe749cb116 (diff)
- (djm) [openbsd-compat/getrrsetbyname.c] Sync to latest OpenBSD version,
resolving memory leak bz#1111 reported by kremenek AT cs.stanford.edu; ok dtucker@
Diffstat (limited to 'openbsd-compat/getrrsetbyname.c')
-rw-r--r--openbsd-compat/getrrsetbyname.c112
1 files changed, 62 insertions, 50 deletions
diff --git a/openbsd-compat/getrrsetbyname.c b/openbsd-compat/getrrsetbyname.c
index 2016ffe31..973e480b4 100644
--- a/openbsd-compat/getrrsetbyname.c
+++ b/openbsd-compat/getrrsetbyname.c
@@ -1,6 +1,6 @@
1/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ 1/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */
2 2
3/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */ 3/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */
4 4
5/* 5/*
6 * Copyright (c) 2001 Jakob Schlyter. All rights reserved. 6 * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
@@ -51,48 +51,18 @@
51 51
52#include "getrrsetbyname.h" 52#include "getrrsetbyname.h"
53 53
54#define ANSWER_BUFFER_SIZE 1024*64
55
56#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO 54#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO
57extern int h_errno; 55extern int h_errno;
58#endif 56#endif
59 57
60struct dns_query { 58/* We don't need multithread support here */
61 char *name; 59#ifdef _THREAD_PRIVATE
62 u_int16_t type; 60# undef _THREAD_PRIVATE
63 u_int16_t class; 61#endif
64 struct dns_query *next; 62#define _THREAD_PRIVATE(a,b,c) (c)
65}; 63struct __res_state _res;
66
67struct dns_rr {
68 char *name;
69 u_int16_t type;
70 u_int16_t class;
71 u_int16_t ttl;
72 u_int16_t size;
73 void *rdata;
74 struct dns_rr *next;
75};
76
77struct dns_response {
78 HEADER header;
79 struct dns_query *query;
80 struct dns_rr *answer;
81 struct dns_rr *authority;
82 struct dns_rr *additional;
83};
84
85static struct dns_response *parse_dns_response(const u_char *, int);
86static struct dns_query *parse_dns_qsection(const u_char *, int,
87 const u_char **, int);
88static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
89 int);
90
91static void free_dns_query(struct dns_query *);
92static void free_dns_rr(struct dns_rr *);
93static void free_dns_response(struct dns_response *);
94 64
95static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); 65/* Necessary functions and macros */
96 66
97/* 67/*
98 * Inline versions of get/put short/long. Pointer is advanced. 68 * Inline versions of get/put short/long. Pointer is advanced.
@@ -162,14 +132,56 @@ _getlong(msgp)
162u_int32_t _getlong(register const u_char *); 132u_int32_t _getlong(register const u_char *);
163#endif 133#endif
164 134
135/* ************** */
136
137#define ANSWER_BUFFER_SIZE 1024*64
138
139struct dns_query {
140 char *name;
141 u_int16_t type;
142 u_int16_t class;
143 struct dns_query *next;
144};
145
146struct dns_rr {
147 char *name;
148 u_int16_t type;
149 u_int16_t class;
150 u_int16_t ttl;
151 u_int16_t size;
152 void *rdata;
153 struct dns_rr *next;
154};
155
156struct dns_response {
157 HEADER header;
158 struct dns_query *query;
159 struct dns_rr *answer;
160 struct dns_rr *authority;
161 struct dns_rr *additional;
162};
163
164static struct dns_response *parse_dns_response(const u_char *, int);
165static struct dns_query *parse_dns_qsection(const u_char *, int,
166 const u_char **, int);
167static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
168 int);
169
170static void free_dns_query(struct dns_query *);
171static void free_dns_rr(struct dns_rr *);
172static void free_dns_response(struct dns_response *);
173
174static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
175
165int 176int
166getrrsetbyname(const char *hostname, unsigned int rdclass, 177getrrsetbyname(const char *hostname, unsigned int rdclass,
167 unsigned int rdtype, unsigned int flags, 178 unsigned int rdtype, unsigned int flags,
168 struct rrsetinfo **res) 179 struct rrsetinfo **res)
169{ 180{
181 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
170 int result; 182 int result;
171 struct rrsetinfo *rrset = NULL; 183 struct rrsetinfo *rrset = NULL;
172 struct dns_response *response; 184 struct dns_response *response = NULL;
173 struct dns_rr *rr; 185 struct dns_rr *rr;
174 struct rdatainfo *rdata; 186 struct rdatainfo *rdata;
175 int length; 187 int length;
@@ -195,19 +207,19 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
195 } 207 }
196 208
197 /* initialize resolver */ 209 /* initialize resolver */
198 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 210 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
199 result = ERRSET_FAIL; 211 result = ERRSET_FAIL;
200 goto fail; 212 goto fail;
201 } 213 }
202 214
203#ifdef DEBUG 215#ifdef DEBUG
204 _res.options |= RES_DEBUG; 216 _resp->options |= RES_DEBUG;
205#endif /* DEBUG */ 217#endif /* DEBUG */
206 218
207#ifdef RES_USE_DNSSEC 219#ifdef RES_USE_DNSSEC
208 /* turn on DNSSEC if EDNS0 is configured */ 220 /* turn on DNSSEC if EDNS0 is configured */
209 if (_res.options & RES_USE_EDNS0) 221 if (_resp->options & RES_USE_EDNS0)
210 _res.options |= RES_USE_DNSSEC; 222 _resp->options |= RES_USE_DNSSEC;
211#endif /* RES_USE_DNSEC */ 223#endif /* RES_USE_DNSEC */
212 224
213 /* make query */ 225 /* make query */
@@ -250,20 +262,16 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
250 rrset->rri_ttl = response->answer->ttl; 262 rrset->rri_ttl = response->answer->ttl;
251 rrset->rri_nrdatas = response->header.ancount; 263 rrset->rri_nrdatas = response->header.ancount;
252 264
253#ifdef HAVE_HEADER_AD
254 /* check for authenticated data */ 265 /* check for authenticated data */
255 if (response->header.ad == 1) 266 if (response->header.ad == 1)
256 rrset->rri_flags |= RRSET_VALIDATED; 267 rrset->rri_flags |= RRSET_VALIDATED;
257#endif
258 268
259 /* copy name from answer section */ 269 /* copy name from answer section */
260 length = strlen(response->answer->name); 270 rrset->rri_name = strdup(response->answer->name);
261 rrset->rri_name = malloc(length + 1);
262 if (rrset->rri_name == NULL) { 271 if (rrset->rri_name == NULL) {
263 result = ERRSET_NOMEMORY; 272 result = ERRSET_NOMEMORY;
264 goto fail; 273 goto fail;
265 } 274 }
266 strlcpy(rrset->rri_name, response->answer->name, length + 1);
267 275
268 /* count answers */ 276 /* count answers */
269 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, 277 rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
@@ -281,7 +289,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
281 289
282 /* allocate memory for signatures */ 290 /* allocate memory for signatures */
283 rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); 291 rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
284 if (rrset->rri_nsigs > 0 && rrset->rri_sigs == NULL) { 292 if (rrset->rri_sigs == NULL) {
285 result = ERRSET_NOMEMORY; 293 result = ERRSET_NOMEMORY;
286 goto fail; 294 goto fail;
287 } 295 }
@@ -311,6 +319,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
311 memcpy(rdata->rdi_data, rr->rdata, rr->size); 319 memcpy(rdata->rdi_data, rr->rdata, rr->size);
312 } 320 }
313 } 321 }
322 free_dns_response(response);
314 323
315 *res = rrset; 324 *res = rrset;
316 return (ERRSET_SUCCESS); 325 return (ERRSET_SUCCESS);
@@ -318,6 +327,8 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
318fail: 327fail:
319 if (rrset != NULL) 328 if (rrset != NULL)
320 freerrset(rrset); 329 freerrset(rrset);
330 if (response != NULL)
331 free_dns_response(response);
321 return (result); 332 return (result);
322} 333}
323 334
@@ -467,7 +478,8 @@ parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
467} 478}
468 479
469static struct dns_rr * 480static struct dns_rr *
470parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) 481parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
482 int count)
471{ 483{
472 struct dns_rr *head, *curr, *prev; 484 struct dns_rr *head, *curr, *prev;
473 int i, length; 485 int i, length;