crypt: Remove manul entry for --enable-crypt
[glibc.git] / resolv / res_query.c
blob1b148a2a05b8641c96a33f2b4d161bb2aaf41e20
1 /*
2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
31 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
33 * Permission to use, copy, modify, and distribute this software for any
34 * purpose with or without fee is hereby granted, provided that the above
35 * copyright notice and this permission notice appear in all copies, and that
36 * the name of Digital Equipment Corporation not be used in advertising or
37 * publicity pertaining to distribution of the document or software without
38 * specific, written prior permission.
40 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
41 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
42 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
43 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
44 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
45 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
46 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47 * SOFTWARE.
51 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
53 * Permission to use, copy, modify, and distribute this software for any
54 * purpose with or without fee is hereby granted, provided that the above
55 * copyright notice and this permission notice appear in all copies.
57 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
58 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
59 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
60 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
61 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
62 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
63 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
64 * SOFTWARE.
67 #include <assert.h>
68 #include <sys/types.h>
69 #include <sys/param.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
72 #include <arpa/nameser.h>
73 #include <ctype.h>
74 #include <errno.h>
75 #include <netdb.h>
76 #include <resolv.h>
77 #include <resolv/resolv-internal.h>
78 #include <resolv/resolv_context.h>
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <shlib-compat.h>
83 #include <scratch_buffer.h>
85 #if PACKETSZ > 65536
86 #define MAXPACKET PACKETSZ
87 #else
88 #define MAXPACKET 65536
89 #endif
91 #define QUERYSIZE (HFIXEDSZ + QFIXEDSZ + MAXCDNAME + 1)
93 static int
94 __res_context_querydomain (struct resolv_context *,
95 const char *name, const char *domain,
96 int class, int type, unsigned char *answer, int anslen,
97 unsigned char **answerp, unsigned char **answerp2, int *nanswerp2,
98 int *resplen2, int *answerp2_malloced);
100 /* Formulate a normal query, send, and await answer. Returned answer
101 is placed in supplied buffer ANSWER. Perform preliminary check of
102 answer, returning success only if no error is indicated and the
103 answer count is nonzero. Return the size of the response on
104 success, -1 on error. Error number is left in h_errno.
106 Caller must parse answer and determine whether it answers the
107 question. */
109 __res_context_query (struct resolv_context *ctx, const char *name,
110 int class, int type,
111 unsigned char *answer, int anslen,
112 unsigned char **answerp, unsigned char **answerp2,
113 int *nanswerp2, int *resplen2, int *answerp2_malloced)
115 struct __res_state *statp = ctx->resp;
116 UHEADER *hp = (UHEADER *) answer;
117 UHEADER *hp2;
118 int n;
120 /* It requires 2 times QUERYSIZE for type == T_QUERY_A_AND_AAAA. */
121 struct scratch_buffer buf;
122 scratch_buffer_init (&buf);
123 _Static_assert (2 * QUERYSIZE <= sizeof (buf.__space.__c),
124 "scratch_buffer too small");
125 u_char *query1 = buf.data;
126 int nquery1 = -1;
127 u_char *query2 = NULL;
128 int nquery2 = 0;
130 again:
131 hp->rcode = NOERROR; /* default */
133 if (type == T_QUERY_A_AND_AAAA)
135 n = __res_context_mkquery (ctx, QUERY, name, class, T_A, NULL,
136 query1, buf.length);
137 if (n > 0)
139 if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
141 /* Use RESOLV_EDNS_BUFFER_SIZE because the receive
142 buffer can be reallocated. */
143 n = __res_nopt (ctx, n, query1, buf.length,
144 RESOLV_EDNS_BUFFER_SIZE);
145 if (n < 0)
146 goto unspec_nomem;
149 nquery1 = n;
150 query2 = buf.data + n;
151 n = __res_context_mkquery (ctx, QUERY, name, class, T_AAAA,
152 NULL, query2, buf.length - n);
153 if (n > 0
154 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
155 /* Use RESOLV_EDNS_BUFFER_SIZE because the receive
156 buffer can be reallocated. */
157 n = __res_nopt (ctx, n, query2, buf.length,
158 RESOLV_EDNS_BUFFER_SIZE);
159 nquery2 = n;
162 unspec_nomem:;
164 else
166 n = __res_context_mkquery (ctx, QUERY, name, class, type, NULL,
167 query1, buf.length);
169 if (n > 0
170 && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
172 /* Use RESOLV_EDNS_BUFFER_SIZE if the receive buffer
173 can be reallocated. */
174 size_t advertise;
175 if (answerp == NULL)
176 advertise = anslen;
177 else
178 advertise = RESOLV_EDNS_BUFFER_SIZE;
179 n = __res_nopt (ctx, n, query1, buf.length, advertise);
182 nquery1 = n;
185 if (__glibc_unlikely (n <= 0)) {
186 /* Retry just in case res_nmkquery failed because of too
187 short buffer. Shouldn't happen. */
188 if (scratch_buffer_set_array_size (&buf,
189 T_QUERY_A_AND_AAAA ? 2 : 1,
190 MAXPACKET)) {
191 query1 = buf.data;
192 goto again;
195 if (__glibc_unlikely (n <= 0)) {
196 RES_SET_H_ERRNO(statp, NO_RECOVERY);
197 scratch_buffer_free (&buf);
198 return (n);
201 /* Suppress AAAA lookups if required. __res_handle_no_aaaa
202 checks RES_NOAAAA first, so avoids parsing the
203 just-generated query packet in most cases. nss_dns avoids
204 using T_QUERY_A_AND_AAAA in RES_NOAAAA mode, so there is no
205 need to handle it here. */
206 if (type == T_AAAA && __res_handle_no_aaaa (ctx, query1, nquery1,
207 answer, anslen, &n))
208 /* There must be no second query for AAAA queries. The code
209 below is still needed to translate NODATA responses. */
210 assert (query2 == NULL);
211 else
213 assert (answerp == NULL || (void *) *answerp == (void *) answer);
214 n = __res_context_send (ctx, query1, nquery1, query2, nquery2,
215 answer, anslen,
216 answerp, answerp2, nanswerp2, resplen2,
217 answerp2_malloced);
220 scratch_buffer_free (&buf);
221 if (n < 0) {
222 RES_SET_H_ERRNO(statp, TRY_AGAIN);
223 return (n);
226 if (answerp != NULL)
227 /* __res_context_send might have reallocated the buffer. */
228 hp = (UHEADER *) *answerp;
230 /* We simplify the following tests by assigning HP to HP2 or
231 vice versa. It is easy to verify that this is the same as
232 ignoring all tests of HP or HP2. */
233 if (answerp2 == NULL || *resplen2 < (int) sizeof (HEADER))
235 hp2 = hp;
237 else
239 hp2 = (UHEADER *) *answerp2;
240 if (n < (int) sizeof (HEADER))
242 hp = hp2;
246 /* Make sure both hp and hp2 are defined */
247 assert((hp != NULL) && (hp2 != NULL));
249 if ((hp->rcode != NOERROR || ntohs(hp->ancount) == 0)
250 && (hp2->rcode != NOERROR || ntohs(hp2->ancount) == 0)) {
251 switch (hp->rcode == NOERROR ? hp2->rcode : hp->rcode) {
252 case NXDOMAIN:
253 if ((hp->rcode == NOERROR && ntohs (hp->ancount) != 0)
254 || (hp2->rcode == NOERROR
255 && ntohs (hp2->ancount) != 0))
256 goto success;
257 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
258 break;
259 case SERVFAIL:
260 RES_SET_H_ERRNO(statp, TRY_AGAIN);
261 break;
262 case NOERROR:
263 if (ntohs (hp->ancount) != 0
264 || ntohs (hp2->ancount) != 0)
265 goto success;
266 RES_SET_H_ERRNO(statp, NO_DATA);
267 break;
268 case FORMERR:
269 case NOTIMP:
270 /* Servers must not reply to AAAA queries with
271 NOTIMP etc but some of them do. */
272 if ((hp->rcode == NOERROR && ntohs (hp->ancount) != 0)
273 || (hp2->rcode == NOERROR
274 && ntohs (hp2->ancount) != 0))
275 goto success;
276 /* FALLTHROUGH */
277 case REFUSED:
278 default:
279 RES_SET_H_ERRNO(statp, NO_RECOVERY);
280 break;
282 return (-1);
284 success:
285 return (n);
287 libc_hidden_def (__res_context_query)
289 /* Common part of res_nquery and res_query. */
290 static int
291 context_query_common (struct resolv_context *ctx,
292 const char *name, int class, int type,
293 unsigned char *answer, int anslen)
295 if (ctx == NULL)
297 RES_SET_H_ERRNO (&_res, NETDB_INTERNAL);
298 return -1;
300 int result = __res_context_query (ctx, name, class, type, answer, anslen,
301 NULL, NULL, NULL, NULL, NULL);
302 __resolv_context_put (ctx);
303 return result;
307 ___res_nquery (res_state statp,
308 const char *name, /* Domain name. */
309 int class, int type, /* Class and type of query. */
310 unsigned char *answer, /* Buffer to put answer. */
311 int anslen) /* Size of answer buffer. */
313 return context_query_common
314 (__resolv_context_get_override (statp), name, class, type, answer, anslen);
316 versioned_symbol (libc, ___res_nquery, res_nquery, GLIBC_2_34);
317 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_2, GLIBC_2_34)
318 compat_symbol (libresolv, ___res_nquery, __res_nquery, GLIBC_2_2);
319 #endif
322 ___res_query (const char *name, int class, int type,
323 unsigned char *answer, int anslen)
325 return context_query_common
326 (__resolv_context_get (), name, class, type, answer, anslen);
328 versioned_symbol (libc, ___res_query, res_query, GLIBC_2_34);
329 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2)
330 compat_symbol (libresolv, ___res_query, res_query, GLIBC_2_0);
331 #endif
332 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_2, GLIBC_2_34)
333 compat_symbol (libresolv, ___res_query, __res_query, GLIBC_2_2);
334 #endif
336 /* Formulate a normal query, send, and retrieve answer in supplied
337 buffer. Return the size of the response on success, -1 on error.
338 If enabled, implement search rules until answer or unrecoverable
339 failure is detected. Error code, if any, is left in h_errno. */
341 __res_context_search (struct resolv_context *ctx,
342 const char *name, int class, int type,
343 unsigned char *answer, int anslen,
344 unsigned char **answerp, unsigned char **answerp2,
345 int *nanswerp2, int *resplen2, int *answerp2_malloced)
347 struct __res_state *statp = ctx->resp;
348 const char *cp;
349 UHEADER *hp = (UHEADER *) answer;
350 char tmp[NS_MAXDNAME];
351 u_int dots;
352 int trailing_dot, ret, saved_herrno;
353 int got_nodata = 0, got_servfail = 0, root_on_list = 0;
354 int tried_as_is = 0;
355 int searched = 0;
357 __set_errno (0);
358 RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /* True if we never query. */
360 dots = 0;
361 for (cp = name; *cp != '\0'; cp++)
362 dots += (*cp == '.');
363 trailing_dot = 0;
364 if (cp > name && *--cp == '.')
365 trailing_dot++;
367 /* If there aren't any dots, it could be a user-level alias. */
368 if (!dots && (cp = __res_context_hostalias
369 (ctx, name, tmp, sizeof tmp))!= NULL)
370 return __res_context_query (ctx, cp, class, type, answer,
371 anslen, answerp, answerp2,
372 nanswerp2, resplen2, answerp2_malloced);
375 * If there are enough dots in the name, let's just give it a
376 * try 'as is'. The threshold can be set with the "ndots" option.
377 * Also, query 'as is', if there is a trailing dot in the name.
379 saved_herrno = -1;
380 if (dots >= statp->ndots || trailing_dot) {
381 ret = __res_context_querydomain (ctx, name, NULL, class, type,
382 answer, anslen, answerp,
383 answerp2, nanswerp2, resplen2,
384 answerp2_malloced);
385 if (ret > 0 || trailing_dot
386 /* If the second response is valid then we use that. */
387 || (ret == 0 && resplen2 != NULL && *resplen2 > 0))
388 return (ret);
389 saved_herrno = h_errno;
390 tried_as_is++;
391 if (answerp && *answerp != answer) {
392 answer = *answerp;
393 anslen = MAXPACKET;
395 if (answerp2 && *answerp2_malloced)
397 free (*answerp2);
398 *answerp2 = NULL;
399 *nanswerp2 = 0;
400 *answerp2_malloced = 0;
405 * We do at least one level of search if
406 * - there is no dot and RES_DEFNAME is set, or
407 * - there is at least one dot, there is no trailing dot,
408 * and RES_DNSRCH is set.
410 if ((!dots && (statp->options & RES_DEFNAMES) != 0) ||
411 (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0)) {
412 int done = 0;
414 for (size_t domain_index = 0; !done; ++domain_index) {
415 const char *dname = __resolv_context_search_list
416 (ctx, domain_index);
417 if (dname == NULL)
418 break;
419 searched = 1;
421 /* __res_context_querydoman concatenates name
422 with dname with a "." in between. If we
423 pass it in dname the "." we got from the
424 configured default search path, we'll end
425 up with "name..", which won't resolve.
426 OTOH, passing it "" will result in "name.",
427 which has the intended effect for both
428 possible representations of the root
429 domain. */
430 if (dname[0] == '.')
431 dname++;
432 if (dname[0] == '\0')
433 root_on_list++;
435 ret = __res_context_querydomain
436 (ctx, name, dname, class, type,
437 answer, anslen, answerp, answerp2, nanswerp2,
438 resplen2, answerp2_malloced);
439 if (ret > 0 || (ret == 0 && resplen2 != NULL
440 && *resplen2 > 0))
441 return (ret);
443 if (answerp && *answerp != answer) {
444 answer = *answerp;
445 anslen = MAXPACKET;
447 if (answerp2 && *answerp2_malloced)
449 free (*answerp2);
450 *answerp2 = NULL;
451 *nanswerp2 = 0;
452 *answerp2_malloced = 0;
456 * If no server present, give up.
457 * If name isn't found in this domain,
458 * keep trying higher domains in the search list
459 * (if that's enabled).
460 * On a NO_DATA error, keep trying, otherwise
461 * a wildcard entry of another type could keep us
462 * from finding this entry higher in the domain.
463 * If we get some other error (negative answer or
464 * server failure), then stop searching up,
465 * but try the input name below in case it's
466 * fully-qualified.
468 if (errno == ECONNREFUSED) {
469 RES_SET_H_ERRNO(statp, TRY_AGAIN);
470 return (-1);
473 switch (statp->res_h_errno) {
474 case NO_DATA:
475 got_nodata++;
476 /* FALLTHROUGH */
477 case HOST_NOT_FOUND:
478 /* keep trying */
479 break;
480 case TRY_AGAIN:
481 if (hp->rcode == SERVFAIL) {
482 /* try next search element, if any */
483 got_servfail++;
484 break;
486 /* FALLTHROUGH */
487 default:
488 /* anything else implies that we're done */
489 done++;
492 /* if we got here for some reason other than DNSRCH,
493 * we only wanted one iteration of the loop, so stop.
495 if ((statp->options & RES_DNSRCH) == 0)
496 done++;
501 * If the query has not already been tried as is then try it
502 * unless RES_NOTLDQUERY is set and there were no dots.
504 if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0)
505 && !(tried_as_is || root_on_list)) {
506 ret = __res_context_querydomain
507 (ctx, name, NULL, class, type,
508 answer, anslen, answerp, answerp2, nanswerp2,
509 resplen2, answerp2_malloced);
510 if (ret > 0 || (ret == 0 && resplen2 != NULL
511 && *resplen2 > 0))
512 return (ret);
515 /* if we got here, we didn't satisfy the search.
516 * if we did an initial full query, return that query's H_ERRNO
517 * (note that we wouldn't be here if that query had succeeded).
518 * else if we ever got a nodata, send that back as the reason.
519 * else send back meaningless H_ERRNO, that being the one from
520 * the last DNSRCH we did.
522 if (answerp2 && *answerp2_malloced)
524 free (*answerp2);
525 *answerp2 = NULL;
526 *nanswerp2 = 0;
527 *answerp2_malloced = 0;
529 if (saved_herrno != -1)
530 RES_SET_H_ERRNO(statp, saved_herrno);
531 else if (got_nodata)
532 RES_SET_H_ERRNO(statp, NO_DATA);
533 else if (got_servfail)
534 RES_SET_H_ERRNO(statp, TRY_AGAIN);
535 return (-1);
537 libc_hidden_def (__res_context_search)
539 /* Common part of res_nsearch and res_search. */
540 static int
541 context_search_common (struct resolv_context *ctx,
542 const char *name, int class, int type,
543 unsigned char *answer, int anslen)
545 if (ctx == NULL)
547 RES_SET_H_ERRNO (&_res, NETDB_INTERNAL);
548 return -1;
550 int result = __res_context_search (ctx, name, class, type, answer, anslen,
551 NULL, NULL, NULL, NULL, NULL);
552 __resolv_context_put (ctx);
553 return result;
557 ___res_nsearch (res_state statp,
558 const char *name, /* Domain name. */
559 int class, int type, /* Class and type of query. */
560 unsigned char *answer, /* Buffer to put answer. */
561 int anslen) /* Size of answer. */
563 return context_search_common
564 (__resolv_context_get_override (statp), name, class, type, answer, anslen);
566 versioned_symbol (libc, ___res_nsearch, res_nsearch, GLIBC_2_34);
567 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_2, GLIBC_2_34)
568 compat_symbol (libresolv, ___res_nsearch, __res_nsearch, GLIBC_2_2);
569 #endif
572 ___res_search (const char *name, int class, int type,
573 unsigned char *answer, int anslen)
575 return context_search_common
576 (__resolv_context_get (), name, class, type, answer, anslen);
578 versioned_symbol (libc, ___res_search, res_search, GLIBC_2_34);
579 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2)
580 compat_symbol (libresolv, ___res_search, res_search, GLIBC_2_0);
581 #endif
582 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_2, GLIBC_2_34)
583 compat_symbol (libresolv, ___res_search, __res_search, GLIBC_2_2);
584 #endif
586 /* Perform a call on res_query on the concatenation of name and
587 domain. */
588 static int
589 __res_context_querydomain (struct resolv_context *ctx,
590 const char *name, const char *domain,
591 int class, int type,
592 unsigned char *answer, int anslen,
593 unsigned char **answerp, unsigned char **answerp2,
594 int *nanswerp2, int *resplen2,
595 int *answerp2_malloced)
597 struct __res_state *statp = ctx->resp;
598 char nbuf[MAXDNAME];
599 const char *longname = nbuf;
600 size_t n, d;
602 if (domain == NULL) {
603 n = strlen(name);
605 /* Decrement N prior to checking it against MAXDNAME
606 so that we detect a wrap to SIZE_MAX and return
607 a reasonable error. */
608 n--;
609 if (n >= MAXDNAME - 1) {
610 RES_SET_H_ERRNO(statp, NO_RECOVERY);
611 return (-1);
613 longname = name;
614 } else {
615 n = strlen(name);
616 d = strlen(domain);
617 if (n + d + 1 >= MAXDNAME) {
618 RES_SET_H_ERRNO(statp, NO_RECOVERY);
619 return (-1);
621 char *p = __stpcpy (nbuf, name);
622 *p++ = '.';
623 strcpy (p, domain);
625 return __res_context_query (ctx, longname, class, type, answer,
626 anslen, answerp, answerp2, nanswerp2,
627 resplen2, answerp2_malloced);
630 /* Common part of res_nquerydomain and res_querydomain. */
631 static int
632 context_querydomain_common (struct resolv_context *ctx,
633 const char *name, const char *domain,
634 int class, int type,
635 unsigned char *answer, int anslen)
637 if (ctx == NULL)
639 RES_SET_H_ERRNO (&_res, NETDB_INTERNAL);
640 return -1;
642 int result = __res_context_querydomain (ctx, name, domain, class, type,
643 answer, anslen,
644 NULL, NULL, NULL, NULL, NULL);
645 __resolv_context_put (ctx);
646 return result;
650 ___res_nquerydomain (res_state statp,
651 const char *name,
652 const char *domain,
653 int class, int type, /* Class and type of query. */
654 unsigned char *answer, /* Buffer to put answer. */
655 int anslen) /* Size of answer. */
657 return context_querydomain_common
658 (__resolv_context_get_override (statp),
659 name, domain, class, type, answer, anslen);
661 versioned_symbol (libc, ___res_nquerydomain, res_nquerydomain, GLIBC_2_34);
662 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_2, GLIBC_2_34)
663 compat_symbol (libresolv, ___res_nquerydomain, __res_nquerydomain, GLIBC_2_2);
664 #endif
667 ___res_querydomain (const char *name, const char *domain, int class, int type,
668 unsigned char *answer, int anslen)
670 return context_querydomain_common
671 (__resolv_context_get (), name, domain, class, type, answer, anslen);
673 versioned_symbol (libc, ___res_querydomain, res_querydomain, GLIBC_2_34);
674 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2)
675 compat_symbol (libresolv, ___res_querydomain, res_querydomain, GLIBC_2_0);
676 #endif
677 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_2, GLIBC_2_34)
678 compat_symbol (libresolv, ___res_querydomain, __res_querydomain, GLIBC_2_2);
679 #endif