summaryrefslogtreecommitdiffstats
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 2016ffe3..973e480b 100644
--- a/openbsd-compat/getrrsetbyname.c
+++ b/openbsd-compat/getrrsetbyname.c
@@ -1,6 +1,6 @@
/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */
-/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */
+/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */
/*
* Copyright (c) 2001 Jakob Schlyter. All rights reserved.
@@ -51,48 +51,18 @@
#include "getrrsetbyname.h"
-#define ANSWER_BUFFER_SIZE 1024*64
-
#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO
extern int h_errno;
#endif
-struct dns_query {
- char *name;
- u_int16_t type;
- u_int16_t class;
- struct dns_query *next;
-};
-
-struct dns_rr {
- char *name;
- u_int16_t type;
- u_int16_t class;
- u_int16_t ttl;
- u_int16_t size;
- void *rdata;
- struct dns_rr *next;
-};
-
-struct dns_response {
- HEADER header;
- struct dns_query *query;
- struct dns_rr *answer;
- struct dns_rr *authority;
- struct dns_rr *additional;
-};
-
-static struct dns_response *parse_dns_response(const u_char *, int);
-static struct dns_query *parse_dns_qsection(const u_char *, int,
- const u_char **, int);
-static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
- int);
-
-static void free_dns_query(struct dns_query *);
-static void free_dns_rr(struct dns_rr *);
-static void free_dns_response(struct dns_response *);
+/* We don't need multithread support here */
+#ifdef _THREAD_PRIVATE
+# undef _THREAD_PRIVATE
+#endif
+#define _THREAD_PRIVATE(a,b,c) (c)
+struct __res_state _res;
-static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
+/* Necessary functions and macros */
/*
* Inline versions of get/put short/long. Pointer is advanced.
@@ -162,14 +132,56 @@ _getlong(msgp)
u_int32_t _getlong(register const u_char *);
#endif
+/* ************** */
+
+#define ANSWER_BUFFER_SIZE 1024*64
+
+struct dns_query {
+ char *name;
+ u_int16_t type;
+ u_int16_t class;
+ struct dns_query *next;
+};
+
+struct dns_rr {
+ char *name;
+ u_int16_t type;
+ u_int16_t class;
+ u_int16_t ttl;
+ u_int16_t size;
+ void *rdata;
+ struct dns_rr *next;
+};
+
+struct dns_response {
+ HEADER header;
+ struct dns_query *query;
+ struct dns_rr *answer;
+ struct dns_rr *authority;
+ struct dns_rr *additional;
+};
+
+static struct dns_response *parse_dns_response(const u_char *, int);
+static struct dns_query *parse_dns_qsection(const u_char *, int,
+ const u_char **, int);
+static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
+ int);
+
+static void free_dns_query(struct dns_query *);
+static void free_dns_rr(struct dns_rr *);
+static void free_dns_response(struct dns_response *);
+
+static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
+
int
getrrsetbyname(const char *hostname, unsigned int rdclass,
unsigned int rdtype, unsigned int flags,
struct rrsetinfo **res)
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int result;
struct rrsetinfo *rrset = NULL;
- struct dns_response *response;
+ struct dns_response *response = NULL;
struct dns_rr *rr;
struct rdatainfo *rdata;
int length;
@@ -195,19 +207,19 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
}
/* initialize resolver */
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
result = ERRSET_FAIL;
goto fail;
}
#ifdef DEBUG
- _res.options |= RES_DEBUG;
+ _resp->options |= RES_DEBUG;
#endif /* DEBUG */
#ifdef RES_USE_DNSSEC
/* turn on DNSSEC if EDNS0 is configured */
- if (_res.options & RES_USE_EDNS0)
- _res.options |= RES_USE_DNSSEC;
+ if (_resp->options & RES_USE_EDNS0)
+ _resp->options |= RES_USE_DNSSEC;
#endif /* RES_USE_DNSEC */
/* make query */
@@ -250,20 +262,16 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
rrset->rri_ttl = response->answer->ttl;
rrset->rri_nrdatas = response->header.ancount;
-#ifdef HAVE_HEADER_AD
/* check for authenticated data */
if (response->header.ad == 1)
rrset->rri_flags |= RRSET_VALIDATED;
-#endif
/* copy name from answer section */
- length = strlen(response->answer->name);
- rrset->rri_name = malloc(length + 1);
+ rrset->rri_name = strdup(response->answer->name);
if (rrset->rri_name == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
- strlcpy(rrset->rri_name, response->answer->name, length + 1);
/* count answers */
rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
@@ -281,7 +289,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
/* allocate memory for signatures */
rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
- if (rrset->rri_nsigs > 0 && rrset->rri_sigs == NULL) {
+ if (rrset->rri_sigs == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
@@ -311,6 +319,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
memcpy(rdata->rdi_data, rr->rdata, rr->size);
}
}
+ free_dns_response(response);
*res = rrset;
return (ERRSET_SUCCESS);
@@ -318,6 +327,8 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
fail:
if (rrset != NULL)
freerrset(rrset);
+ if (response != NULL)
+ free_dns_response(response);
return (result);
}
@@ -467,7 +478,8 @@ parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
}
static struct dns_rr *
-parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count)
+parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
+ int count)
{
struct dns_rr *head, *curr, *prev;
int i, length;