diff options
Diffstat (limited to 'openbsd-compat')
-rw-r--r-- | openbsd-compat/getrrsetbyname.c | 112 |
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 |
57 | extern int h_errno; | 55 | extern int h_errno; |
58 | #endif | 56 | #endif |
59 | 57 | ||
60 | struct 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 | }; | 63 | struct __res_state _res; |
66 | |||
67 | struct 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 | |||
77 | struct 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 | |||
85 | static struct dns_response *parse_dns_response(const u_char *, int); | ||
86 | static struct dns_query *parse_dns_qsection(const u_char *, int, | ||
87 | const u_char **, int); | ||
88 | static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, | ||
89 | int); | ||
90 | |||
91 | static void free_dns_query(struct dns_query *); | ||
92 | static void free_dns_rr(struct dns_rr *); | ||
93 | static void free_dns_response(struct dns_response *); | ||
94 | 64 | ||
95 | static 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) | |||
162 | u_int32_t _getlong(register const u_char *); | 132 | u_int32_t _getlong(register const u_char *); |
163 | #endif | 133 | #endif |
164 | 134 | ||
135 | /* ************** */ | ||
136 | |||
137 | #define ANSWER_BUFFER_SIZE 1024*64 | ||
138 | |||
139 | struct dns_query { | ||
140 | char *name; | ||
141 | u_int16_t type; | ||
142 | u_int16_t class; | ||
143 | struct dns_query *next; | ||
144 | }; | ||
145 | |||
146 | struct 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 | |||
156 | struct 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 | |||
164 | static struct dns_response *parse_dns_response(const u_char *, int); | ||
165 | static struct dns_query *parse_dns_qsection(const u_char *, int, | ||
166 | const u_char **, int); | ||
167 | static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, | ||
168 | int); | ||
169 | |||
170 | static void free_dns_query(struct dns_query *); | ||
171 | static void free_dns_rr(struct dns_rr *); | ||
172 | static void free_dns_response(struct dns_response *); | ||
173 | |||
174 | static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); | ||
175 | |||
165 | int | 176 | int |
166 | getrrsetbyname(const char *hostname, unsigned int rdclass, | 177 | getrrsetbyname(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, | |||
318 | fail: | 327 | fail: |
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 | ||
469 | static struct dns_rr * | 480 | static struct dns_rr * |
470 | parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) | 481 | parse_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; |