diff options
Diffstat (limited to 'resolv')
-rw-r--r-- | resolv/Banner | 2 | ||||
-rw-r--r-- | resolv/Versions | 9 | ||||
-rw-r--r-- | resolv/arpa/nameser.h | 13 | ||||
-rw-r--r-- | resolv/arpa/nameser_compat.h | 3 | ||||
-rw-r--r-- | resolv/base64.c | 56 | ||||
-rw-r--r-- | resolv/herror.c | 69 | ||||
-rw-r--r-- | resolv/inet_addr.c | 79 | ||||
-rw-r--r-- | resolv/inet_net_ntop.c | 8 | ||||
-rw-r--r-- | resolv/inet_net_pton.c | 16 | ||||
-rw-r--r-- | resolv/inet_neta.c | 4 | ||||
-rw-r--r-- | resolv/inet_ntop.c | 27 | ||||
-rw-r--r-- | resolv/inet_pton.c | 31 | ||||
-rw-r--r-- | resolv/ns_name.c | 92 | ||||
-rw-r--r-- | resolv/ns_netint.c | 4 | ||||
-rw-r--r-- | resolv/ns_parse.c | 4 | ||||
-rw-r--r-- | resolv/ns_print.c | 37 | ||||
-rw-r--r-- | resolv/ns_samedomain.c | 4 | ||||
-rw-r--r-- | resolv/ns_ttl.c | 5 | ||||
-rw-r--r-- | resolv/nsap_addr.c | 8 | ||||
-rw-r--r-- | resolv/res_comp.c | 30 | ||||
-rw-r--r-- | resolv/res_data.c | 35 | ||||
-rw-r--r-- | resolv/res_debug.c | 54 | ||||
-rw-r--r-- | resolv/res_init.c | 47 | ||||
-rw-r--r-- | resolv/res_libc.c | 56 | ||||
-rw-r--r-- | resolv/res_mkquery.c | 10 | ||||
-rw-r--r-- | resolv/res_query.c | 41 | ||||
-rw-r--r-- | resolv/res_send.c | 1069 | ||||
-rw-r--r-- | resolv/resolv.h | 273 |
28 files changed, 1077 insertions, 1009 deletions
diff --git a/resolv/Banner b/resolv/Banner index d05a4e3..e585ed8 100644 --- a/resolv/Banner +++ b/resolv/Banner @@ -1 +1 @@ -BIND-8.2.2-5 +BIND-8.2.3-T5B diff --git a/resolv/Versions b/resolv/Versions index 98fa762..0f9255d 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -20,7 +20,7 @@ libc { } GLIBC_2.2 { # r* - __res_state; __res_ninit; + __res_state; __res_init; __res_nclose; __res_ninit; } } @@ -51,8 +51,11 @@ libresolv { __ns_name_unpack; __ns_name_ntop; } GLIBC_2.2 { - __res_nmkquery; __res_nquery; __res_nquerydomain; __res_nsearch; - __ns_get16; __res_hostalias; + __dn_expand; + __ns_get16; __ns_samename; + __res_hostalias; __res_mkquery; __res_nmkquery; __res_nquery; + __res_nquerydomain; __res_nsearch; __res_nsend; __res_query; + __res_querydomain; __res_search; } libnss_dns { diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h index 6655f3b..6ae1bc6 100644 --- a/resolv/arpa/nameser.h +++ b/resolv/arpa/nameser.h @@ -45,7 +45,7 @@ */ /* - * $Id$ + * $BINDId: nameser.h,v 8.37 2000/03/30 21:16:49 vixie Exp $ */ #ifndef _ARPA_NAMESER_H_ @@ -53,9 +53,13 @@ #define BIND_4_COMPAT -#include <features.h> #include <sys/param.h> -#include <sys/types.h> +#if (!defined(BSD)) || (BSD < 199306) +# include <sys/bitypes.h> +#else +# include <sys/types.h> +#endif +#include <sys/cdefs.h> /* * Revision information. This is the release date in YYYYMMDD format. @@ -481,6 +485,7 @@ typedef enum __ns_cert_types { #define ns_name_compress __ns_name_compress #define ns_name_uncompress __ns_name_uncompress #define ns_name_skip __ns_name_skip +#define ns_name_rollback __ns_name_rollback #define ns_sign __ns_sign #define ns_sign_tcp __ns_sign_tcp #define ns_sign_tcp_init __ns_sign_tcp_init @@ -522,6 +527,8 @@ int ns_name_uncompress __P((const u_char *, const u_char *, int ns_name_compress __P((const char *, u_char *, size_t, const u_char **, const u_char **)); int ns_name_skip __P((const u_char **, const u_char *)); +void ns_name_rollback __P((const u_char *, const u_char **, + const u_char **)); int ns_sign __P((u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t)); int ns_sign_tcp __P((u_char *, int *, int, int, diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h index f67f5b3..43bcd3a 100644 --- a/resolv/arpa/nameser_compat.h +++ b/resolv/arpa/nameser_compat.h @@ -28,7 +28,7 @@ /* * from nameser.h 8.1 (Berkeley) 6/2/93 - * $Id$ + * $BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $ */ #ifndef _ARPA_NAMESER_COMPAT_ @@ -36,7 +36,6 @@ #define __BIND 19950621 /* (DEAD) interface version stamp. */ -/* glibc always has byte order info in <endian.h> */ #include <endian.h> /* diff --git a/resolv/base64.c b/resolv/base64.c index 4e7e2a0..b7c7d1c 100644 --- a/resolv/base64.c +++ b/resolv/base64.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -40,9 +40,14 @@ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ +#if !defined(LINT) && !defined(CODECENTER) +static const char rcsid[] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $"; +#endif /* not lint */ + #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> + #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/nameser.h> @@ -50,13 +55,8 @@ #include <ctype.h> #include <resolv.h> #include <stdio.h> - -#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) -# include <stdlib.h> -# include <string.h> -#else -# include "../conf/portability.h" -#endif +#include <stdlib.h> +#include <string.h> #define Assert(Cond) if (!(Cond)) abort() @@ -112,9 +112,9 @@ static const char Pad64 = '='; end of the data is performed using the '=' character. Since all base64 input is an integral number of octets, only the - ------------------------------------------------- + ------------------------------------------------- following cases can arise: - + (1) the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters @@ -128,12 +128,7 @@ static const char Pad64 = '='; */ int -b64_ntop(src, srclength, target, targsize) - u_char const *src; - size_t srclength; - char *target; - size_t targsize; -{ +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) { size_t datalength = 0; u_char input[3]; u_char output[4]; @@ -161,14 +156,14 @@ b64_ntop(src, srclength, target, targsize) target[datalength++] = Base64[output[2]]; target[datalength++] = Base64[output[3]]; } - + /* Now we worry about padding. */ if (0 != srclength) { /* Get what's left. */ input[0] = input[1] = input[2] = '\0'; for (i = 0; i < srclength; i++) input[i] = *src++; - + output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); @@ -204,8 +199,7 @@ b64_pton(src, target, targsize) u_char *target; size_t targsize; { - size_t tarindex; - int state, ch; + int tarindex, state, ch; char *pos; state = 0; @@ -225,7 +219,7 @@ b64_pton(src, target, targsize) switch (state) { case 0: if (target) { - if (tarindex >= targsize) + if ((size_t)tarindex >= targsize) return (-1); target[tarindex] = (pos - Base64) << 2; } @@ -233,7 +227,7 @@ b64_pton(src, target, targsize) break; case 1: if (target) { - if (tarindex + 1 >= targsize) + if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= (pos - Base64) >> 4; target[tarindex+1] = ((pos - Base64) & 0x0f) @@ -244,7 +238,7 @@ b64_pton(src, target, targsize) break; case 2: if (target) { - if (tarindex + 1 >= targsize) + if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= (pos - Base64) >> 2; target[tarindex+1] = ((pos - Base64) & 0x03) @@ -255,7 +249,7 @@ b64_pton(src, target, targsize) break; case 3: if (target) { - if (tarindex >= targsize) + if ((size_t)tarindex >= targsize) return (-1); target[tarindex] |= (pos - Base64); } @@ -281,12 +275,7 @@ b64_pton(src, target, targsize) case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ -#ifdef _LIBC - /* To avoid warnings. */ - for ( ; ch != '\0'; ch = *src++) -#else - for (NULL; ch != '\0'; ch = *src++) -#endif + for ((void)NULL; ch != '\0'; ch = *src++) if (!isspace(ch)) break; /* Make sure there is another trailing = sign. */ @@ -301,12 +290,7 @@ b64_pton(src, target, targsize) * We know this char is an =. Is there anything but * whitespace after it? */ -#ifdef _LIBC - /* To avoid warnings. */ - for ( ; ch != '\0'; ch = *src++) -#else - for (NULL; ch != '\0'; ch = *src++) -#endif + for ((void)NULL; ch != '\0'; ch = *src++) if (!isspace(ch)) return (-1); diff --git a/resolv/herror.c b/resolv/herror.c index 8ba0ebe..d53a0b5 100644 --- a/resolv/herror.c +++ b/resolv/herror.c @@ -1,9 +1,7 @@ /* - * ++Copyright++ 1987, 1993 - * - * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -27,44 +25,43 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. + */ + +/* + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. + * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. - * - - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id$"; +static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; +static const char rcsid[] = "$BINDId: herror.c,v 8.11 1999/10/13 16:39:39 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <sys/param.h> #include <sys/uio.h> + +#include <netinet/in.h> +#include <arpa/nameser.h> + #include <netdb.h> +#include <resolv.h> +#include <string.h> +#include <unistd.h> + #include <libintl.h> -#if defined(BSD) && (BSD >= 199103) -# include <unistd.h> -# include <string.h> -#else -# include "../conf/portability.h" -#endif const char *h_errlist[] = { N_("Resolver Error 0 (no error)"), @@ -75,23 +72,17 @@ const char *h_errlist[] = { }; int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; -#ifndef h_errno -extern int h_errno; -#endif - /* * herror -- * print the error indicated by the h_errno value. */ void -herror(s) - const char *s; -{ - struct iovec iov[4]; - register struct iovec *v = iov; +herror(const char *s) { + struct iovec iov[4], *v = iov; + extern int * __h_errno(); - if (s && *s) { - v->iov_base = (char *)s; + if (s != NULL && *s != '\0') { + v->iov_base = (/*noconst*/ char *)s; v->iov_len = strlen(s); v++; v->iov_base = ": "; @@ -106,10 +97,12 @@ herror(s) __writev(STDERR_FILENO, iov, (v - iov) + 1); } +/* + * hstrerror -- + * return the string associated with a given "host" errno value. + */ const char * -hstrerror(err) - int err; -{ +hstrerror(int err) { if (err < 0) return _("Resolver internal error"); else if (err < h_nerr) diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c index 48373b2..59e160e 100644 --- a/resolv/inet_addr.c +++ b/resolv/inet_addr.c @@ -1,9 +1,7 @@ /* - * ++Copyright++ 1983, 1990, 1993 - * - * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -27,16 +25,18 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - + */ + +/* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -45,20 +45,38 @@ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. - * - - * --Copyright-- + */ + +/* + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static char rcsid[] = "$Id$"; +static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static const char rcsid[] = "$BINDId: inet_addr.c,v 8.11 1999/10/13 16:39:25 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <sys/param.h> + #include <netinet/in.h> #include <arpa/inet.h> + #include <ctype.h> + #ifdef _LIBC # include <endian.h> # include <stdint.h> @@ -66,18 +84,13 @@ static char rcsid[] = "$Id$"; # include <limits.h> # include <errno.h> #endif -#include "../conf/portability.h" - -/* these are compatibility routines, not needed on recent BSD releases */ /* * Ascii internet address interpretation routine. * The value returned is in network order. */ in_addr_t -inet_addr(cp) - register const char *cp; -{ +inet_addr(const char *cp) { struct in_addr val; if (__inet_aton(cp, &val)) @@ -85,7 +98,7 @@ inet_addr(cp) return (INADDR_NONE); } -/* +/* * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. @@ -93,21 +106,18 @@ inet_addr(cp) * cannot distinguish between failure and a local broadcast address. */ in_addr_t -__inet_aton(cp, addr) - const char *cp; - struct in_addr *addr; -{ +__inet_aton(const char *cp, struct in_addr *addr) { static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; - register in_addr_t val; + in_addr_t val; #ifndef _LIBC - register int base; + int base; #endif - register char c; + char c; union iaddr { uint8_t bytes[4]; uint32_t word; } res; - register uint8_t *pp = res.bytes; + uint8_t *pp = res.bytes; int digit; #ifdef _LIBC @@ -140,23 +150,28 @@ __inet_aton(cp, addr) } c = *cp; #else - base = 10; + val = 0; base = 10; digit = 0; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') base = 16, c = *++cp; - else + else { base = 8; + digit = 1 ; + } } - val = 0; for (;;) { if (isascii(c) && isdigit(c)) { + if (base == 8 && (c == '8' || c == '9')) + return (0); val = (val * base) + (c - '0'); c = *++cp; + digit = 1; } else if (base == 16 && isascii(c) && isxdigit(c)) { val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; + digit = 1; } else break; } @@ -168,8 +183,7 @@ __inet_aton(cp, addr) * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ - if (pp > res.bytes + 3 - || val > 0xff) + if (pp > res.bytes + 3 || val > 0xff) goto ret_0; *pp++ = val; c = *++cp; @@ -181,7 +195,6 @@ __inet_aton(cp, addr) */ if (c != '\0' && (!isascii(c) || !isspace(c))) goto ret_0; - /* * Did we get a valid digit? */ @@ -193,7 +206,7 @@ __inet_aton(cp, addr) if (val > max[pp - res.bytes]) goto ret_0; - if (addr) + if (addr != NULL) addr->s_addr = res.word | htonl (val); #ifdef _LIBC diff --git a/resolv/inet_net_ntop.c b/resolv/inet_net_ntop.c index d012c53..ac71605 100644 --- a/resolv/inet_net_ntop.c +++ b/resolv/inet_net_ntop.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: inet_net_ntop.c,v 1.6 1999/01/08 19:23:42 vixie Exp $"; #endif #include <sys/types.h> @@ -74,7 +74,7 @@ inet_net_ntop(af, src, bits, dst, size) * pointer to dst, or NULL if an error occurred (check errno). * note: * network byte order assumed. this means 192.5.5.240/28 has - * 0x11110000 in its fourth octet. + * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), July 1996 */ @@ -98,7 +98,7 @@ inet_net_ntop_ipv4(src, bits, dst, size) if (size < sizeof "0") goto emsgsize; *dst++ = '0'; - --size; + size--; *dst = '\0'; } diff --git a/resolv/inet_net_pton.c b/resolv/inet_net_pton.c index 50ab9f8..a7e597a 100644 --- a/resolv/inet_net_pton.c +++ b/resolv/inet_net_pton.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp $"; #endif #include <sys/types.h> @@ -81,7 +81,7 @@ inet_net_pton(af, src, dst, size) * not an IPv4 network specification. * note: * network byte order assumed. this means 192.5.5.240/28 has - * 0x11110000 in its fourth octet. + * 0b11110000 in its fourth octet. * author: * Paul Vixie (ISC), June 1996 */ @@ -101,7 +101,7 @@ inet_net_pton_ipv4(src, dst, size) /* Hexadecimal: Eat nybble string. */ if (size <= 0) goto emsgsize; - *dst = 0, dirty = 0; + dirty = 0; tmp = 0; /* To calm down gcc. */ src++; /* skip x or X. */ while (isxdigit((ch = *src++))) { @@ -109,9 +109,9 @@ inet_net_pton_ipv4(src, dst, size) n = (const char *) __rawmemchr(xdigits, ch) - xdigits; assert(n >= 0 && n <= 15); if (dirty == 0) - tmp = n << 4; + tmp = n; else - tmp |= n; + tmp = (tmp << 4) | n; if (++dirty == 2) { if (size-- <= 0) goto emsgsize; @@ -119,10 +119,10 @@ inet_net_pton_ipv4(src, dst, size) dirty = 0; } } - if (dirty) { + if (dirty) { /* Odd trailing nybble? */ if (size-- <= 0) goto emsgsize; - *dst = (u_char) tmp; + *dst++ = (u_char) (tmp << 4); } } else if (isascii(ch) && isdigit(ch)) { /* Decimal: eat dotted digit string. */ diff --git a/resolv/inet_neta.c b/resolv/inet_neta.c index 5633ed1..349e6bd 100644 --- a/resolv/inet_neta.c +++ b/resolv/inet_neta.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: inet_neta.c,v 1.6 1999/01/08 19:23:45 vixie Exp $"; #endif #include <sys/types.h> diff --git a/resolv/inet_ntop.c b/resolv/inet_ntop.c index a95f684..f99a69b 100644 --- a/resolv/inet_ntop.c +++ b/resolv/inet_ntop.c @@ -1,4 +1,5 @@ -/* Copyright (c) 1996 by Internet Software Consortium. +/* + * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,19 +16,20 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: inet_ntop.c,v 1.8 1999/10/13 16:39:28 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> + #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/nameser.h> -#include <string.h> + #include <errno.h> #include <stdio.h> -#include "../conf/portability.h" +#include <string.h> #ifdef SPRINTF_CHAR # define SPRINTF(x) strlen(sprintf/**/x) @@ -40,9 +42,9 @@ static char rcsid[] = "$Id$"; * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -static const char *inet_ntop4 __P((const u_char *src, char *dst, socklen_t size)) +static const char *inet_ntop4 (const u_char *src, char *dst, socklen_t size) internal_function; -static const char *inet_ntop6 __P((const u_char *src, char *dst, socklen_t size)) +static const char *inet_ntop6 (const u_char *src, char *dst, socklen_t size) internal_function; /* char * @@ -74,7 +76,7 @@ inet_ntop(af, src, dst, size) /* const char * * inet_ntop4(src, dst, size) - * format an IPv4 address, more or less like inet_ntoa() + * format an IPv4 address * return: * `dst' (as a const) * notes: @@ -122,7 +124,7 @@ inet_ntop6(src, dst, size) */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; struct { int base, len; } best, cur; - u_int words[IN6ADDRSZ / INT16SZ]; + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; /* @@ -131,11 +133,11 @@ inet_ntop6(src, dst, size) * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); - for (i = 0; i < IN6ADDRSZ; i += 2) + for (i = 0; i < NS_IN6ADDRSZ; i += 2) words[i / 2] = (src[i] << 8) | src[i + 1]; best.base = -1; cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; @@ -160,7 +162,7 @@ inet_ntop6(src, dst, size) * Format the result. */ tp = tmp; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { @@ -182,7 +184,8 @@ inet_ntop6(src, dst, size) tp += SPRINTF((tp, "%x", words[i])); } /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c index 4dcbad9..264278b 100644 --- a/resolv/inet_pton.c +++ b/resolv/inet_pton.c @@ -1,4 +1,5 @@ -/* Copyright (c) 1996 by Internet Software Consortium. +/* + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: inet_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -27,7 +28,6 @@ static char rcsid[] = "$Id$"; #include <ctype.h> #include <string.h> #include <errno.h> -#include <conf/portability.h> /* * WARNING: Don't even consider trying to compile this on a system where @@ -83,7 +83,7 @@ inet_pton4(src, dst) u_char *dst; { int saw_digit, octets, ch; - u_char tmp[INADDRSZ], *tp; + u_char tmp[NS_INADDRSZ], *tp; saw_digit = 0; octets = 0; @@ -111,8 +111,7 @@ inet_pton4(src, dst) } if (octets < 4) return (0); - - memcpy(dst, tmp, INADDRSZ); + memcpy(dst, tmp, NS_INADDRSZ); return (1); } @@ -136,13 +135,13 @@ inet_pton6(src, dst) u_char *dst; { static const char xdigits[] = "0123456789abcdef"; - u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *curtok; int ch, saw_xdigit; u_int val; - tp = memset(tmp, '\0', IN6ADDRSZ); - endp = tp + IN6ADDRSZ; + tp = memset(tmp, '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') @@ -170,8 +169,10 @@ inet_pton6(src, dst) return (0); colonp = tp; continue; + } else if (*src == '\0') { + return (0); } - if (tp + INT16SZ > endp) + if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; @@ -179,16 +180,16 @@ inet_pton6(src, dst) val = 0; continue; } - if (ch == '.' && ((tp + INADDRSZ) <= endp) && + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; + tp += NS_INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { - if (tp + INT16SZ > endp) + if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; @@ -201,6 +202,8 @@ inet_pton6(src, dst) const int n = tp - colonp; int i; + if (tp == endp) + return (0); for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; @@ -209,6 +212,6 @@ inet_pton6(src, dst) } if (tp != endp) return (0); - memcpy(dst, tmp, IN6ADDRSZ); + memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } diff --git a/resolv/ns_name.c b/resolv/ns_name.c index b75f731..cb63935 100644 --- a/resolv/ns_name.c +++ b/resolv/ns_name.c @@ -15,8 +15,8 @@ * SOFTWARE. */ -#ifndef lint -static const char rcsid[] = "$Id$"; +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp $"; #endif #include <sys/types.h> @@ -375,7 +375,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, u_char *dstp; const u_char **cpp, **lpp, *eob, *msg; const u_char *srcp; - int n, l; + int n, l, first = 1; srcp = src; dstp = dst; @@ -424,9 +424,10 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, } /* Not found, save it. */ if (lastdnptr != NULL && cpp < lastdnptr - 1 && - (dstp - msg) < 0x4000) { + (dstp - msg) < 0x4000 && first) { *cpp++ = dstp; *cpp = NULL; + first = 0; } } /* copy label to buffer */ @@ -499,6 +500,23 @@ ns_name_compress(const char *src, u_char *dst, size_t dstsiz, } /* + * Reset dnptrs so that there are no active references to pointers at or + * after src. + */ +void +ns_name_rollback(const u_char *src, const u_char **dnptrs, + const u_char **lastdnptr) +{ + while (dnptrs < lastdnptr && *dnptrs != NULL) { + if (*dnptrs >= src) { + *dnptrs = NULL; + break; + } + dnptrs++; + } +} + +/* * ns_name_skip(ptrptr, eom) * Advance *ptrptr to skip over the compressed name it points at. * return: @@ -600,36 +618,48 @@ dn_find(const u_char *domain, const u_char *msg, u_int n; for (cpp = dnptrs; cpp < lastdnptr; cpp++) { - dn = domain; - sp = cp = *cpp; - while ((n = *cp++) != 0) { - /* - * check for indirection - */ - switch (n & NS_CMPRSFLGS) { - case 0: /* normal case, n == len */ - if (n != *dn++) - goto next; - for ((void)NULL; n > 0; n--) - if (mklower(*dn++) != mklower(*cp++)) + sp = *cpp; + /* + * terminate search on: + * root label + * compression pointer + * unusable offset + */ + while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 && + (sp - msg) < 0x4000) { + dn = domain; + cp = sp; + while ((n = *cp++) != 0) { + /* + * check for indirection + */ + switch (n & NS_CMPRSFLGS) { + case 0: /* normal case, n == len */ + if (n != *dn++) goto next; - /* Is next root for both ? */ - if (*dn == '\0' && *cp == '\0') - return (sp - msg); - if (*dn) - continue; - goto next; - - case NS_CMPRSFLGS: /* indirection */ - cp = msg + (((n & 0x3f) << 8) | *cp); - break; - - default: /* illegal type */ - __set_errno (EMSGSIZE); - return (-1); + for ((void)NULL; n > 0; n--) + if (mklower(*dn++) != + mklower(*cp++)) + goto next; + /* Is next root for both ? */ + if (*dn == '\0' && *cp == '\0') + return (sp - msg); + if (*dn) + continue; + goto next; + + case NS_CMPRSFLGS: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + break; + + default: /* illegal type */ + __set_errno (EMSGSIZE); + return (-1); + } } + next: + sp += *sp + 1; } - next: ; } __set_errno (ENOENT); return (-1); diff --git a/resolv/ns_netint.c b/resolv/ns_netint.c index 9dcf91c..ff24128 100644 --- a/resolv/ns_netint.c +++ b/resolv/ns_netint.c @@ -15,8 +15,8 @@ * SOFTWARE. */ -#ifndef lint -static const char rcsid[] = "$Id$"; +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$BINDId: ns_netint.c,v 8.4 1999/10/13 16:39:35 vixie Exp $"; #endif /* Import. */ diff --git a/resolv/ns_parse.c b/resolv/ns_parse.c index 7bbdc41..d305eae 100644 --- a/resolv/ns_parse.c +++ b/resolv/ns_parse.c @@ -15,8 +15,8 @@ * SOFTWARE. */ -#ifndef lint -static const char rcsid[] = "$Id$"; +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$BINDId: ns_parse.c,v 8.13 1999/10/13 16:39:35 vixie Exp $"; #endif /* Import. */ diff --git a/resolv/ns_print.c b/resolv/ns_print.c index cce3fb6..7a2ef70 100644 --- a/resolv/ns_print.c +++ b/resolv/ns_print.c @@ -15,11 +15,12 @@ * SOFTWARE. */ -#ifndef lint -static const char rcsid[] = "$Id$"; +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $"; #endif /* Import. */ + #include <sys/types.h> #include <sys/socket.h> @@ -27,6 +28,7 @@ static const char rcsid[] = "$Id$"; #include <arpa/nameser.h> #include <arpa/inet.h> +#include <assert.h> #include <errno.h> #include <resolv.h> #include <string.h> @@ -53,6 +55,7 @@ static int addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen); /* Proto. */ + #ifndef _LIBC u_int16_t dst_s_dns_key_id(const u_char *, const int); #endif @@ -122,9 +125,10 @@ ns_sprintrrf(const u_char *msg, size_t msglen, T(addstr("@\t\t\t", 4, &buf, &buflen)); } else { T(addstr(name, len, &buf, &buflen)); - /* Origin not used and no trailing dot? */ - if ((!origin || !origin[0] || name[len] == '\0') && - name[len - 1] != '.') { + /* Origin not used or not root, and no trailing dot? */ + if (((origin == NULL || origin[0] == '\0') || + (origin[0] != '.' && origin[1] != '\0' && + name[len] == '\0')) && name[len - 1] != '.') { T(addstr(".", 1, &buf, &buflen)); len++; } @@ -480,6 +484,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen, n = SPRINTF((tmp, " ; key_tag= %u", key_id)); T(addstr(tmp, n, &buf, &buflen)); #endif /* !_LIBC */ + break; } @@ -749,20 +754,22 @@ addname(const u_char *msg, size_t msglen, if (n < 0) goto enospc; /* Guess. */ newlen = prune_origin(*buf, origin); - if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') && - (newlen == 0 || (*buf)[newlen - 1] != '.')) { - /* No trailing dot. */ - if (newlen + 2 > *buflen) - goto enospc; /* No room for ".\0". */ - (*buf)[newlen++] = '.'; - (*buf)[newlen] = '\0'; - } if (newlen == 0) { /* Use "@" instead of name. */ if (newlen + 2 > *buflen) goto enospc; /* No room for "@\0". */ (*buf)[newlen++] = '@'; (*buf)[newlen] = '\0'; + } else { + if (((origin == NULL || origin[0] == '\0') || + (origin[0] != '.' && origin[1] != '\0' && + (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') { + /* No trailing dot. */ + if (newlen + 2 > *buflen) + goto enospc; /* No room for ".\0". */ + (*buf)[newlen++] = '.'; + (*buf)[newlen] = '\0'; + } } *pp += n; addlen(newlen, buf, buflen); @@ -777,9 +784,7 @@ addname(const u_char *msg, size_t msglen, static void addlen(size_t len, char **buf, size_t *buflen) { -#if 0 - INSIST(len <= *buflen); -#endif + assert(len <= *buflen); *buf += len; *buflen -= len; } diff --git a/resolv/ns_samedomain.c b/resolv/ns_samedomain.c index bac5a63..1fb1c55 100644 --- a/resolv/ns_samedomain.c +++ b/resolv/ns_samedomain.c @@ -15,8 +15,8 @@ * SOFTWARE. */ -#ifndef lint -static const char rcsid[] = "$Id$"; +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$BINDId: ns_samedomain.c,v 8.9 1999/10/15 21:06:51 vixie Exp $"; #endif #include <sys/types.h> diff --git a/resolv/ns_ttl.c b/resolv/ns_ttl.c index 6be2b0d..c5d5af2 100644 --- a/resolv/ns_ttl.c +++ b/resolv/ns_ttl.c @@ -15,11 +15,12 @@ * SOFTWARE. */ -#ifndef lint -static const char rcsid[] = "$Id$"; +#if !defined(_LIBC) && !defined(lint) +static const char rcsid[] = "$BINDId: ns_ttl.c,v 8.8 1999/10/13 16:39:36 vixie Exp $"; #endif /* Import. */ + #include <arpa/nameser.h> #include <ctype.h> diff --git a/resolv/nsap_addr.c b/resolv/nsap_addr.c index c1c9a61..b3f2f77 100644 --- a/resolv/nsap_addr.c +++ b/resolv/nsap_addr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 by Internet Software Consortium. + * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,15 +16,17 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: nsap_addr.c,v 8.10 1999/10/13 16:39:28 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> + #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/nameser.h> + #include <ctype.h> #include <resolv.h> @@ -38,7 +40,7 @@ inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) { u_char c, nib; u_int len = 0; - while ((c = *ascii++) != '\0' && (int) len < maxlen) { + while ((c = *ascii++) != '\0' && len < (u_int)maxlen) { if (c == '.' || c == '+' || c == '/') continue; if (!isascii(c)) diff --git a/resolv/res_comp.c b/resolv/res_comp.c index e6f54ce..f227c4d 100644 --- a/resolv/res_comp.c +++ b/resolv/res_comp.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -25,16 +25,18 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - + */ + +/* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -64,23 +66,19 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_comp.c,v 8.15 1999/10/13 16:39:39 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <sys/param.h> #include <netinet/in.h> #include <arpa/nameser.h> - #include <ctype.h> -#include <errno.h> #include <resolv.h> #include <stdio.h> - #include <string.h> #include <unistd.h> - /* * Expand compressed domain name 'comp_dn' to full domain name. * 'msg' is a pointer to the begining of the message, @@ -157,7 +155,7 @@ res_hnok(const char *dn) { int nch = *dn++; if (periodchar(ch)) { - /* NULL */; + (void)NULL; } else if (periodchar(pch)) { if (!borderchar(ch)) return (0); @@ -198,7 +196,7 @@ res_mailok(const char *dn) { /* "." is a valid missing representation */ if (*dn == '\0') - return(1); + return (1); /* otherwise <label>.<hostname> */ while ((ch = *dn++) != '\0') { @@ -246,3 +244,11 @@ u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); } u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); } #endif /*__ultrix__*/ #endif /*BIND_4_COMPAT*/ + + +#include <shlib-compat.h> + +#if SHLIB_COMPAT(libresolv, GLIBC_2_0, GLIBC_2_2) +# undef dn_expand +weak_alias (__dn_expand, dn_expand); +#endif diff --git a/resolv/res_data.c b/resolv/res_data.c index a9f5a2a..c8aa5c5 100644 --- a/resolv/res_data.c +++ b/resolv/res_data.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_data.c,v 8.17 1999/10/13 17:11:31 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -31,6 +31,9 @@ static const char rcsid[] = "$Id$"; #include <ctype.h> #include <netdb.h> #include <resolv.h> +#ifdef BIND_UPDATE +#include <res_update.h> +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -67,11 +70,10 @@ const char *_res_sectioncodes[] = { #endif #ifndef __BIND_NOSTATIC - #ifdef _LIBC extern struct __res_state _res; #else -/* The declaration has been moved to res_libc.c. */ +/* The definition has been moved to res_libc.c. */ struct __res_state _res # if defined(__BIND_RES_TEXT) = { RES_TIMEOUT, } /* Motorola, et al. */ @@ -85,7 +87,7 @@ int res_ourserver_p(const res_state, const struct sockaddr_in *); void res_pquery(const res_state, const u_char *, int, FILE *); #ifndef _LIBC -/* Moved to res_libc.c since res_init should go into libc.so but the +/* Moved to res_libc.c since res_init() should go into libc.so but the rest of this file not. */ int res_init(void) { @@ -231,6 +233,17 @@ res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, void res_close(void) { +#ifdef _LIBC + /* + * Some stupid programs out there call res_close() before res_init(). + * Since _res._vcsock isn't explicitly initialized, these means that + * we could do a close(0), which might lead to some security problems. + * Therefore we check if res_init() was called before by looking at + * the RES_INIT bit in _res.options. If it hasn't been set we bail out + * early. */ + if ((_res.options & RES_INIT) == 0) + return; +#endif res_nclose(&_res); } @@ -302,3 +315,17 @@ local_hostname_length(const char *hostname) { #endif /*ultrix*/ #endif + + +#include <shlib-compat.h> + +#if SHLIB_COMPAT(libresolv, GLIBC_2_0, GLIBC_2_2) +# undef res_mkquery +# undef res_query +# undef res_querydomain +# undef res_search +weak_alias (__res_mkquery, res_mkquery); +weak_alias (__res_query, res_query); +weak_alias (__res_querydomain, res_querydomain); +weak_alias (__res_search, res_search); +#endif diff --git a/resolv/res_debug.c b/resolv/res_debug.c index 2df1c5b..f4e9169 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1985 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,14 +29,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -91,7 +91,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -141,7 +141,8 @@ do_section(const res_state statp, int pflag, FILE *file) { int n, sflag, rrnum; - char buf[2048]; /* XXX need to malloc */ + static int buflen = 2048; + char *buf; ns_opcode opcode; ns_rr rr; @@ -152,6 +153,12 @@ do_section(const res_state statp, if (statp->pfcode && !sflag) return; + buf = malloc(buflen); + if (buf == NULL) { + fprintf(file, ";; memory allocation failure\n"); + return; + } + opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode); rrnum = 0; for (;;) { @@ -162,7 +169,7 @@ do_section(const res_state statp, else if (rrnum > 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) putc('\n', file); - return; + goto cleanup; } if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) fprintf(file, ";; %s SECTION:\n", @@ -174,17 +181,32 @@ do_section(const res_state statp, p_class(ns_rr_class(rr))); else { n = ns_sprintrr(handle, &rr, NULL, NULL, - buf, sizeof buf); + buf, buflen); if (n < 0) { + if (errno == ENOSPC) { + free(buf); + buf = NULL; + if (buflen < 131072) + buf = malloc(buflen += 1024); + if (buf == NULL) { + fprintf(file, + ";; memory allocation failure\n"); + return; + } + continue; + } fprintf(file, ";; ns_sprintrr: %s\n", strerror(errno)); - return; + goto cleanup; } fputs(buf, file); fputc('\n', file); } rrnum++; } + cleanup: + if (buf != NULL) + free(buf); } /* @@ -465,13 +487,8 @@ const char * sym_ntos(const struct res_sym *syms, int number, int *success) { static char unname[20]; -#ifdef _LIBC - /* Changed to prevent warning. --drepper@gnu */ - for (; syms->name != 0; syms++) { -#else for ((void)NULL; syms->name != 0; syms++) { -#endif - if (number == syms->number) { + if (number == syms->number) { if (success) *success = 1; return (syms->name); @@ -488,12 +505,7 @@ const char * sym_ntop(const struct res_sym *syms, int number, int *success) { static char unname[20]; -#ifdef _LIBC - /* Changed to prevent warning. --drepper@gnu */ - for (; syms->name != 0; syms++) { -#else for ((void)NULL; syms->name != 0; syms++) { -#endif if (number == syms->number) { if (success) *success = 1; @@ -1012,7 +1024,7 @@ p_secstodate (u_long secs) { struct tm *time; #ifdef HAVE_TIME_R - struct time timebuf; + struct tm timebuf; time = gmtime_r(&clock, &timebuf); #else diff --git a/resolv/res_init.c b/resolv/res_init.c index bf6cf7f..c483645 100644 --- a/resolv/res_init.c +++ b/resolv/res_init.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,14 +29,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -88,13 +88,11 @@ static const char rcsid[] = "$Id$"; /* Options. Should all be left alone. */ #define RESOLVSORT #define RFC1535 -#undef DEBUG +/* #undef DEBUG */ -static void -res_setoptions (res_state statp, const char *options, const char *source) +static void res_setoptions (res_state, const char *, const char *) internal_function; - #ifdef RESOLVSORT static const char sort_mask[] = "/&"; #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) @@ -172,10 +170,11 @@ __res_vinit(res_state statp, int preinit) { statp->nscount = 1; statp->ndots = 1; statp->pfcode = 0; - statp->_sock = -1; + statp->_vcsock = -1; statp->_flags = 0; statp->qhook = NULL; statp->rhook = NULL; + statp->_u._ext.nscount = 0; /* Allow user to override the local domain definition */ if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) { @@ -391,8 +390,7 @@ __res_vinit(res_state statp, int preinit) { static void internal_function -res_setoptions(res_state statp, const char *options, const char *source) -{ +res_setoptions(res_state statp, const char *options, const char *source) { const char *cp = options; int i; @@ -476,3 +474,28 @@ res_randomid(void) { __gettimeofday(&now, NULL); return (0xffff & (now.tv_sec ^ now.tv_usec ^ __getpid())); } + +/* + * This routine is for closing the socket if a virtual circuit is used and + * the program wants to close it. This provides support for endhostent() + * which expects to close the socket. + * + * This routine is not expected to be user visible. + */ +void +res_nclose(res_state statp) { + int ns; + + if (statp->_vcsock >= 0) { + (void) close(statp->_vcsock); + statp->_vcsock = -1; + statp->_flags &= ~(RES_F_VC | RES_F_CONN); + } + for (ns = 0; ns < statp->_u._ext.nscount; ns++) { + if (statp->_u._ext.nssocks[ns] != -1) { + (void) close(statp->_u._ext.nssocks[ns]); + statp->_u._ext.nssocks[ns] = -1; + } + } + statp->_u._ext.nscount = 0; +} diff --git a/resolv/res_libc.c b/resolv/res_libc.c index fc5cc69..fde5f5c 100644 --- a/resolv/res_libc.c +++ b/resolv/res_libc.c @@ -15,34 +15,29 @@ * SOFTWARE. */ -/* Define some functions that go int libc.so. */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id$"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/time.h> - #include <netinet/in.h> -#include <arpa/inet.h> #include <arpa/nameser.h> - -#include <ctype.h> -#include <netdb.h> #include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> +#undef _res + +/* The resolver state for use by single-threaded programs. */ +struct __res_state _res; -/* This is the old res_init function. It has been moved from - res_data.c to this file since res_init should go into libc.so but - the rest of res_data not. */ +/* This function is used to access the resolver state in + single-threaded programs. */ +struct __res_state * +weak_const_function +__res_state (void) +{ + return &_res; +} + +/* The following bit is copied from res_data.c (where it is #ifdef'ed + out) since res_init() should go into libc.so but the rest of that + file should not. */ int res_init(void) { @@ -83,18 +78,11 @@ res_init(void) { return (__res_vinit(&_res, 1)); } + -/* We need a resolver context - in unthreaded apps, this weak function - provides it. */ - -#undef _res - -struct __res_state _res = { _sock : -1 }; - +#include <shlib-compat.h> -struct __res_state * -weak_const_function -__res_state(void) -{ - return &_res; -} +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2) +# undef res_init +weak_alias (__res_init, res_init); +#endif diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index dba2c80..05b94bd 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,14 +29,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_mkquery.c,v 8.12 1999/10/13 16:39:40 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> diff --git a/resolv/res_query.c b/resolv/res_query.c index deebf4c..00a5e3e 100644 --- a/resolv/res_query.c +++ b/resolv/res_query.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,14 +29,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -184,8 +184,9 @@ res_nsearch(res_state statp, HEADER *hp = (HEADER *) answer; char tmp[NS_MAXDNAME]; u_int dots; - int trailing_dot, ret; + int trailing_dot, ret, saved_herrno; int got_nodata = 0, got_servfail = 0, root_on_list = 0; + int tried_as_is = 0; __set_errno (0); RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /* True if we never query. */ @@ -202,12 +203,19 @@ res_nsearch(res_state statp, return (res_nquery(statp, cp, class, type, answer, anslen)); /* - * If there are enough dots in the name, do no searching. - * (The threshold can be set with the "ndots" option.) + * If there are enough dots in the name, let's just give it a + * try 'as is'. The threshold can be set with the "ndots" option. + * Also, query 'as is', if there is a trailing dot in the name. */ - if (dots >= statp->ndots || trailing_dot) - return (res_nquerydomain(statp, name, NULL, class, type, - answer, anslen)); + saved_herrno = -1; + if (dots >= statp->ndots || trailing_dot) { + ret = res_nquerydomain(statp, name, NULL, class, type, + answer, anslen); + if (ret > 0 || trailing_dot) + return (ret); + saved_herrno = h_errno; + tried_as_is++; + } /* * We do at least one level of search if @@ -279,10 +287,11 @@ res_nsearch(res_state statp, } /* - * If the name has any dots at all, and "." is not on the search - * list, then try an as-is query now. + * If the name has any dots at all, and no earlier 'as-is' query + * for the name, and "." is not on the search list, then try an as-is + * query now. */ - if (statp->ndots) { + if (statp->ndots && !(tried_as_is || root_on_list)) { ret = res_nquerydomain(statp, name, NULL, class, type, answer, anslen); if (ret > 0) @@ -296,7 +305,9 @@ res_nsearch(res_state statp, * else send back meaningless H_ERRNO, that being the one from * the last DNSRCH we did. */ - if (got_nodata) + if (saved_herrno != -1) + RES_SET_H_ERRNO(statp, saved_herrno); + else if (got_nodata) RES_SET_H_ERRNO(statp, NO_DATA); else if (got_servfail) RES_SET_H_ERRNO(statp, TRY_AGAIN); diff --git a/resolv/res_send.c b/resolv/res_send.c index d3dc2ba..bf500b1 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -13,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -29,14 +29,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -66,7 +66,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static const char rcsid[] = "$Id$"; +static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -78,6 +78,9 @@ static const char rcsid[] = "$Id$"; #include <sys/time.h> #include <sys/socket.h> #include <sys/uio.h> +#ifdef _LIBC +#include <sys/poll.h> +#endif #include <netinet/in.h> #include <arpa/nameser.h> @@ -92,32 +95,36 @@ static const char rcsid[] = "$Id$"; #include <string.h> #include <unistd.h> -#include <sys/poll.h> +#ifndef _LIBC +#include <isc/eventlib.h> +#else -/* Options. Leave them on. */ -/* #undef DEBUG */ -#include "res_debug.h" +/* From ev_streams.c. */ + +static inline struct iovec +evConsIovec(void *buf, size_t cnt) { + struct iovec ret; -#ifdef NEED_PSELECT -static int pselect(int, void *, void *, void *, - struct timespec *, - const sigset_t *); -#endif + memset(&ret, 0xf5, sizeof ret); + ret.iov_base = buf; + ret.iov_len = cnt; + return (ret); +} -#define CHECK_SRVR_ADDR +/* From ev_timers.c. */ -/* From bind lib/isc/ev_timers.c: */ #define BILLION 1000000000 -static struct timespec + +static inline struct timespec evTimeSpec(struct timeval tv) { - struct timespec ts; + struct timespec ts; - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - return (ts); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + return (ts); } -static struct timespec +static inline struct timespec evConsTime(time_t sec, long nsec) { struct timespec x; @@ -126,7 +133,7 @@ evConsTime(time_t sec, long nsec) { return (x); } -static struct timespec +static inline struct timespec evAddTime(struct timespec addend1, struct timespec addend2) { struct timespec x; @@ -139,7 +146,7 @@ evAddTime(struct timespec addend1, struct timespec addend2) { return (x); } -static struct timespec +static inline struct timespec evSubTime(struct timespec minuend, struct timespec subtrahend) { struct timespec x; @@ -153,7 +160,7 @@ evSubTime(struct timespec minuend, struct timespec subtrahend) { return (x); } -static int +static inline int evCmpTime(struct timespec a, struct timespec b) { long x = a.tv_sec - b.tv_sec; @@ -162,7 +169,7 @@ evCmpTime(struct timespec a, struct timespec b) { return (x < 0L ? (-1) : x > 0L ? (1) : (0)); } -static struct timespec +static inline struct timespec evNowTime() { struct timeval now; @@ -170,41 +177,44 @@ evNowTime() { return (evConsTime(0, 0)); return (evTimeSpec(now)); } -/* End of code from bind lib/isc/ev_timers.c. */ -#ifdef DEBUG - static void - Aerror(const res_state statp, FILE *file, const char *string, int error, - struct sockaddr_in address) - { - int save = errno; +#endif - if ((statp->options & RES_DEBUG) != 0) { - char tmp[sizeof "255.255.255.255"]; +/* Options. Leave them on. */ +/* #undef DEBUG */ +#include "res_debug.h" - fprintf(file, "res_send: %s ([%s].%u): %s\n", - string, - inet_ntop(address.sin_family, &address.sin_addr, - tmp, sizeof tmp), - ntohs(address.sin_port), - strerror(error)); - } - __set_errno (save); - } - static void - Perror(const res_state statp, FILE *file, const char *string, int error) { - int save = errno; +#define EXT(res) ((res)->_u._ext) - if ((statp->options & RES_DEBUG) != 0) - fprintf(file, "res_send: %s: %s\n", - string, strerror(error)); - __set_errno (save); - } +#ifndef _LIBC +static const int highestFD = FD_SETSIZE - 1; #endif -static int cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2); +/* Forward. */ + +static int send_vc(res_state, const u_char *, int, + u_char *, int, int *, int); +static int send_dg(res_state, const u_char *, int, + u_char *, int, int *, int, + int *, int *); +#ifdef DEBUG +static void Aerror(const res_state, FILE *, const char *, int, + struct sockaddr_in); +static void Perror(const res_state, FILE *, const char *, int); +#endif +static int sock_eq(struct sockaddr_in *, struct sockaddr_in *); +#ifdef NEED_PSELECT +static int pselect(int, void *, void *, void *, + struct timespec *, + const sigset_t *); +#endif + +/* Reachover. */ + void res_pquery(const res_state, const u_char *, int, FILE *); +/* Public. */ + /* int * res_isourserver(ina) * looks up "ina" in _res.ns_addr_list[] @@ -220,7 +230,7 @@ res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) { int ns; ina = *inp; - for (ns = 0; ns < statp->nscount; ns++) { + for (ns = 0; ns < statp->nscount; ns++) { const struct sockaddr_in *srv = &statp->nsaddr_list[ns]; if (srv->sin_family == ina.sin_family && @@ -295,8 +305,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, * Only header section present in replies to * dynamic update packets. */ - if ( (((HEADER *)buf1)->opcode == ns_o_update) && - (((HEADER *)buf2)->opcode == ns_o_update) ) + if ((((HEADER *)buf1)->opcode == ns_o_update) && + (((HEADER *)buf2)->opcode == ns_o_update)) return (1); if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) @@ -323,12 +333,12 @@ int res_nsend(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz) { - HEADER *hp = (HEADER *) buf; - HEADER *anhp = (HEADER *) ans; - int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n; - u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */ - static int highestFD = FD_SETSIZE - 1; + int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; + if (statp->nscount == 0) { + __set_errno (ESRCH); + return (-1); + } if (anssiz < HFIXEDSZ) { __set_errno (EINVAL); return (-1); @@ -337,14 +347,46 @@ res_nsend(res_state statp, (stdout, ";; res_send()\n"), buf, buflen); v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; gotsomewhere = 0; - connreset = 0; terrno = ETIMEDOUT; - badns = 0; /* - * Some callers want to even out the load on their resolver list. + * If the ns_addr_list in the resolver context has changed, then + * invalidate our cached copy and the associated timing data. */ - if (statp->nscount > 0 && (statp->options & RES_ROTATE) != 0) { + if (EXT(statp).nscount != 0) { + int needclose = 0; + + if (EXT(statp).nscount != statp->nscount) + needclose++; + else + for (ns = 0; ns < statp->nscount; ns++) + if (!sock_eq(&statp->nsaddr_list[ns], + &EXT(statp).nsaddrs[ns])) { + needclose++; + break; + } + if (needclose) + res_nclose(statp); + } + + /* + * Maybe initialize our private copy of the ns_addr_list. + */ + if (EXT(statp).nscount == 0) { + for (ns = 0; ns < statp->nscount; ns++) { + EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns]; + EXT(statp).nstimes[ns] = RES_MAXTIME; + EXT(statp).nssocks[ns] = -1; + } + EXT(statp).nscount = statp->nscount; + } + + /* + * Some resolvers want to even out the load on their nameservers. + * Note that RES_BLAST overrides RES_ROTATE. + */ + if ((statp->options & RES_ROTATE) != 0 && + (statp->options & RES_BLAST) == 0) { struct sockaddr_in ina; int lastns = statp->nscount - 1; @@ -355,17 +397,12 @@ res_nsend(res_state statp, } /* - * Send request, RETRY times, or until successful + * Send request, RETRY times, or until successful. */ for (try = 0; try < statp->retry; try++) { for (ns = 0; ns < statp->nscount; ns++) { struct sockaddr_in *nsap = &statp->nsaddr_list[ns]; same_ns: - if (badns & (1 << ns)) { - res_nclose(statp); - goto next_ns; - } - if (statp->qhook) { int done = 0, loops = 0; @@ -401,474 +438,45 @@ res_nsend(res_state statp, ns + 1, inet_ntoa(nsap->sin_addr))); if (v_circuit) { - int truncated; - struct iovec iov[2]; - u_short len; - u_char *cp; - /* Use VC; at most one attempt per server. */ try = statp->retry; - truncated = 0; - - /* Are we still talking to whom we want to talk to? */ - if (statp->_sock >= 0 && - (statp->_flags & RES_F_VC) != 0) { - struct sockaddr_in peer; - int size = sizeof(peer); - - if (getpeername(statp->_sock, - (struct sockaddr *)&peer, - &size) < 0) { - res_nclose(statp); - statp->_flags &= ~RES_F_VC; - } else if (!cmpsock(&peer, nsap)) { - res_nclose(statp); - statp->_flags &= ~RES_F_VC; - } - } - - if (statp->_sock < 0 || - (statp->_flags & RES_F_VC) == 0) { - if (statp->_sock >= 0) - res_nclose(statp); - - statp->_sock = socket(PF_INET, - SOCK_STREAM, 0); - if (statp->_sock < 0 || - statp->_sock > highestFD) { - terrno = errno; - Perror(statp, stderr, - "socket(vc)", errno); - return (-1); - } - __set_errno (0); - if (connect(statp->_sock, - (struct sockaddr *)nsap, - sizeof *nsap) < 0) { - terrno = errno; - Aerror(statp, stderr, "connect/vc", - errno, *nsap); - badns |= (1 << ns); - res_nclose(statp); - goto next_ns; - } - statp->_flags |= RES_F_VC; - } - /* - * Send length & message - */ - putshort((u_short)buflen, (u_char*)&len); - iov[0].iov_base = (caddr_t)&len; - iov[0].iov_len = INT16SZ; - iov[1].iov_base = (caddr_t)buf; - iov[1].iov_len = buflen; - if (writev(statp->_sock, iov, 2) != - (INT16SZ + buflen)) { - terrno = errno; - Perror(statp, stderr, "write failed", errno); - badns |= (1 << ns); - res_nclose(statp); + n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, + ns); + if (n < 0) + return (-1); + if (n == 0) goto next_ns; - } - /* - * Receive length & response - */ - read_len: - cp = ans; - len = INT16SZ; - while ((n = read(statp->_sock, - (char *)cp, (int)len)) > 0) { - cp += n; - if ((len -= n) <= 0) - break; - } - if (n <= 0) { - terrno = errno; - Perror(statp, stderr, "read failed", errno); - res_nclose(statp); - /* - * A long running process might get its TCP - * connection reset if the remote server was - * restarted. Requery the server instead of - * trying a new one. When there is only one - * server, this means that a query might work - * instead of failing. We only allow one reset - * per query to prevent looping. - */ - if (terrno == ECONNRESET && !connreset) { - connreset = 1; - res_nclose(statp); - goto same_ns; - } - res_nclose(statp); - goto next_ns; - } - resplen = ns_get16(ans); - if (resplen > anssiz) { - Dprint(statp->options & RES_DEBUG, - (stdout, ";; response truncated\n") - ); - truncated = 1; - len = anssiz; - } else - len = resplen; - if (len < HFIXEDSZ) { - /* - * Undersized message. - */ - Dprint(statp->options & RES_DEBUG, - (stdout, ";; undersized: %d\n", len)); - terrno = EMSGSIZE; - badns |= (1 << ns); - res_nclose(statp); - goto next_ns; - } - cp = ans; - while (len != 0 && - (n = read(statp->_sock, (char *)cp, (int)len)) - > 0) { - cp += n; - len -= n; - } - if (n <= 0) { - terrno = errno; - Perror(statp, stderr, "read(vc)", errno); - res_nclose(statp); - goto next_ns; - } - if (truncated) { - /* - * Flush rest of answer - * so connection stays in synch. - */ - anhp->tc = 1; - len = resplen - anssiz; - while (len != 0) { - char junk[PACKETSZ]; - - n = ((size_t)len > sizeof(junk) - ? sizeof(junk) - : len); - n = read(statp->_sock, junk, n); - if (n > 0) - len -= n; - else - break; - } - } - /* - * The calling applicating has bailed out of - * a previous call and failed to arrange to have - * the circuit closed or the server has got - * itself confused. Anyway drop the packet and - * wait for the correct one. - */ - if (hp->id != anhp->id) { - DprintQ((statp->options & RES_DEBUG) || - (statp->pfcode & RES_PRF_REPLY), - (stdout, ";; old answer (unexpected):\n"), - ans, (resplen>anssiz)?anssiz:resplen); - goto read_len; - } + resplen = n; } else { - /* - * Use datagrams. - */ - struct timespec start, timeout, finish; -#ifdef _LIBC - struct pollfd pfd[1]; - int ptimeout; -#else - fd_set dsmask; -#endif - struct sockaddr_in from; - int fromlen, seconds; - - if (statp->_sock < 0 || - (statp->_flags & RES_F_VC) != 0) { - if ((statp->_flags & RES_F_VC) != 0) - res_nclose(statp); - statp->_sock = socket(PF_INET, SOCK_DGRAM, 0); - if (statp->_sock < 0 || - statp->_sock > highestFD) { -#ifndef CAN_RECONNECT - bad_dg_sock: -#endif - terrno = errno; - Perror(statp, stderr, - "socket(dg)", errno); - return (-1); - } - statp->_flags &= ~RES_F_CONN; - } -#ifndef CANNOT_CONNECT_DGRAM - /* - * On a 4.3BSD+ machine (client and server, - * actually), sending to a nameserver datagram - * port with no nameserver will cause an - * ICMP port unreachable message to be returned. - * If our datagram socket is "connected" to the - * server, we get an ECONNREFUSED error on the next - * socket operation, and select returns if the - * error message is received. We can thus detect - * the absence of a nameserver without timing out. - * If we have sent queries to at least two servers, - * however, we don't want to remain connected, - * as we wish to receive answers from the first - * server to respond. - */ - if (statp->nscount == 1 || (try == 0 && ns == 0)) { - /* - * Connect only if we are sure we won't - * receive a response from another server. - */ - if ((statp->_flags & RES_F_CONN) == 0) { - if (connect(statp->_sock, - (struct sockaddr *)nsap, - sizeof *nsap) < 0) { - Aerror(statp, stderr, - "connect(dg)", - errno, *nsap); - badns |= (1 << ns); - res_nclose(statp); - goto next_ns; - } - statp->_flags |= RES_F_CONN; - } - if (send(statp->_sock, (char*)buf, buflen, 0) - != buflen) { - Perror(statp, stderr, "send", errno); - badns |= (1 << ns); - res_nclose(statp); - goto next_ns; - } - } else { - /* - * Disconnect if we want to listen - * for responses from more than one server. - */ - if ((statp->_flags & RES_F_CONN) != 0) { -#ifdef CAN_RECONNECT - struct sockaddr_in no_addr; - - no_addr.sin_family = AF_INET; - no_addr.sin_addr.s_addr = INADDR_ANY; - no_addr.sin_port = 0; - (void) connect(statp->_sock, - (struct sockaddr *) - &no_addr, - sizeof no_addr); -#else - struct sockaddr_in local_addr; - int len, result, s1; - - len = sizeof(local_addr); - s1 = socket(PF_INET, SOCK_DGRAM, 0); - result = getsockname(statp->_sock, - (struct sockaddr *)&local_addr, - &len); - if (s1 < 0) - goto bad_dg_sock; - (void) dup2(s1, statp->_sock); - (void) close(s1); - if (result == 0) { - /* - * Attempt to rebind to old - * port. Note connected socket - * has an sin_addr set. - */ - local_addr.sin_addr.s_addr = - htonl(0); - (void)bind(statp->_sock, - (struct sockaddr *) - &local_addr, len); - } - Dprint(statp->options & RES_DEBUG, - (stdout, ";; new DG socket\n")) -#endif /* CAN_RECONNECT */ - statp->_flags &= ~RES_F_CONN; - __set_errno (0); - } -#endif /* !CANNOT_CONNECT_DGRAM */ - if (sendto(statp->_sock, - (char*)buf, buflen, 0, - (struct sockaddr *)nsap, - sizeof *nsap) - != buflen) { - Aerror(statp, stderr, "sendto", errno, *nsap); - badns |= (1 << ns); - res_nclose(statp); - goto next_ns; - } -#ifndef CANNOT_CONNECT_DGRAM - } -#endif /* !CANNOT_CONNECT_DGRAM */ - - if (statp->_sock < 0 || statp->_sock > highestFD) { - Perror(statp, stderr, - "fd out-of-bounds", EMFILE); - res_nclose(statp); + /* Use datagrams. */ + n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, + ns, &v_circuit, &gotsomewhere); + if (n < 0) + return (-1); + if (n == 0) goto next_ns; - } - - /* - * Wait for reply - */ - seconds = (statp->retrans << try); - if (try > 0) - seconds /= statp->nscount; - if (seconds <= 0) - seconds = 1; - - start = evNowTime(); - timeout = evConsTime(seconds, 0); - finish = evAddTime(start, timeout); - wait: -#ifdef _LIBC - /* Convert struct timespec in milliseconds. */ - ptimeout = timeout.tv_sec * 1000 - + timeout.tv_nsec / 1000000; - - pfd[0].fd = statp->_sock; - pfd[0].events = POLLIN; - n = __poll (pfd, 1, ptimeout); -#else - FD_ZERO(&dsmask); - FD_SET(statp->_sock, &dsmask); - n = pselect(statp->_sock + 1, - &dsmask, NULL, NULL, - &timeout, NULL); -#endif - if (n == 0) { - Dprint(statp->options & RES_DEBUG, - (stdout, ";; timeout\n")); - gotsomewhere = 1; - goto next_ns; - } - if (n < 0) { - if (errno == EINTR) { - struct timespec now; - - now = evNowTime(); - if (evCmpTime(finish, now) >= 0) { - timeout = evSubTime(finish, - now); - goto wait; - } - } -#ifdef _LIBC - Perror(statp, stderr, "poll", errno); -#else - Perror(statp, stderr, "select", errno); -#endif - res_nclose(statp); - goto next_ns; - } - __set_errno (0); - fromlen = sizeof(struct sockaddr_in); - resplen = recvfrom(statp->_sock, (char*)ans, anssiz,0, - (struct sockaddr *)&from, &fromlen); - if (resplen <= 0) { - Perror(statp, stderr, "recvfrom", errno); - res_nclose(statp); - goto next_ns; - } - gotsomewhere = 1; - if (resplen < HFIXEDSZ) { - /* - * Undersized message. - */ - Dprint(statp->options & RES_DEBUG, - (stdout, ";; undersized: %d\n", - resplen)); - terrno = EMSGSIZE; - badns |= (1 << ns); - res_nclose(statp); - goto next_ns; - } - if (hp->id != anhp->id) { - /* - * response from old query, ignore it. - * XXX - potential security hazard could - * be detected here. - */ - DprintQ((statp->options & RES_DEBUG) || - (statp->pfcode & RES_PRF_REPLY), - (stdout, ";; old answer:\n"), - ans, (resplen>anssiz)?anssiz:resplen); - goto wait; - } -#ifdef CHECK_SRVR_ADDR - if (!(statp->options & RES_INSECURE1) && - !res_ourserver_p(statp, &from)) { - /* - * response from wrong server? ignore it. - * XXX - potential security hazard could - * be detected here. - */ - DprintQ((statp->options & RES_DEBUG) || - (statp->pfcode & RES_PRF_REPLY), - (stdout, ";; not our server:\n"), - ans, (resplen>anssiz)?anssiz:resplen); - goto wait; - } -#endif - if (!(statp->options & RES_INSECURE2) && - !res_queriesmatch(buf, buf + buflen, - ans, ans + anssiz)) { - /* - * response contains wrong query? ignore it. - * XXX - potential security hazard could - * be detected here. - */ - DprintQ((statp->options & RES_DEBUG) || - (statp->pfcode & RES_PRF_REPLY), - (stdout, ";; wrong query name:\n"), - ans, (resplen>anssiz)?anssiz:resplen); - goto wait; - } - if (anhp->rcode == SERVFAIL || - anhp->rcode == NOTIMP || - anhp->rcode == REFUSED) { - DprintQ(statp->options & RES_DEBUG, - (stdout, "server rejected query:\n"), - ans, (resplen>anssiz)?anssiz:resplen); - badns |= (1 << ns); - res_nclose(statp); - /* don't retry if called from dig */ - if (!statp->pfcode) - goto next_ns; - } - if (!(statp->options & RES_IGNTC) && anhp->tc) { - /* - * get rest of answer; - * use TCP with same server. - */ - Dprint(statp->options & RES_DEBUG, - (stdout, ";; truncated answer\n")); - v_circuit = 1; - res_nclose(statp); + if (v_circuit) goto same_ns; - } - } /*if vc/dg*/ + resplen = n; + } + Dprint((statp->options & RES_DEBUG) || ((statp->pfcode & RES_PRF_REPLY) && (statp->pfcode & RES_PRF_HEAD1)), (stdout, ";; got answer:\n")); + DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, ""), - ans, (resplen>anssiz)?anssiz:resplen); + ans, (resplen > anssiz) ? anssiz : resplen); + /* - * If using virtual circuits, we assume that the first server - * is preferred over the rest (i.e. it is on the local - * machine) and only keep that one open. * If we have temporarily opened a virtual circuit, * or if we haven't been asked to keep a socket open, * close the socket. */ - if ((v_circuit && (!(statp->options & RES_USEVC) || ns != 0)) || - !(statp->options & RES_STAYOPEN)) { + if ((v_circuit && (statp->options & RES_USEVC) == 0) || + (statp->options & RES_STAYOPEN) == 0) { res_nclose(statp); } if (statp->rhook) { @@ -915,25 +523,411 @@ res_nsend(res_state statp, return (-1); } -/* - * This routine is for closing the socket if a virtual circuit is used and - * the program wants to close it. This provides support for endhostent() - * which expects to close the socket. - * - * This routine is not expected to be user visible. - */ -void -res_nclose(res_state statp) { - if (statp->_sock >= 0) { - (void) close(statp->_sock); - statp->_sock = -1; - statp->_flags &= ~(RES_F_VC | RES_F_CONN); +/* Private */ + +static int +send_vc(res_state statp, + const u_char *buf, int buflen, u_char *ans, int anssiz, + int *terrno, int ns) +{ + const HEADER *hp = (HEADER *) buf; + HEADER *anhp = (HEADER *) ans; + struct sockaddr_in *nsap = &statp->nsaddr_list[ns]; + int truncating, connreset, resplen, n; + struct iovec iov[2]; + u_short len; + u_char *cp; + + connreset = 0; + same_ns: + truncating = 0; + + /* Are we still talking to whom we want to talk to? */ + if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { + struct sockaddr_in peer; + int size = sizeof peer; + + if (getpeername(statp->_vcsock, + (struct sockaddr *)&peer, &size) < 0 || + !sock_eq(&peer, nsap)) { + res_nclose(statp); + statp->_flags &= ~RES_F_VC; + } + } + + if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { + if (statp->_vcsock >= 0) + res_nclose(statp); + + statp->_vcsock = socket(PF_INET, SOCK_STREAM, 0); +#ifndef _LIBC + if (statp->_vcsock > highestFD) { + res_nclose(statp); + __set_errno (ENOTSOCK); + } +#endif + if (statp->_vcsock < 0) { + *terrno = errno; + Perror(statp, stderr, "socket(vc)", errno); + return (-1); + } + __set_errno (0); + if (connect(statp->_vcsock, (struct sockaddr *)nsap, + sizeof *nsap) < 0) { + *terrno = errno; + Aerror(statp, stderr, "connect/vc", errno, *nsap); + res_nclose(statp); + return (0); + } + statp->_flags |= RES_F_VC; } + + /* + * Send length & message + */ + putshort((u_short)buflen, (u_char*)&len); + iov[0] = evConsIovec(&len, INT16SZ); + iov[1] = evConsIovec((void*)buf, buflen); + if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { + *terrno = errno; + Perror(statp, stderr, "write failed", errno); + res_nclose(statp); + return (0); + } + /* + * Receive length & response + */ + read_len: + cp = ans; + len = INT16SZ; + while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) { + cp += n; + if ((len -= n) <= 0) + break; + } + if (n <= 0) { + *terrno = errno; + Perror(statp, stderr, "read failed", errno); + res_nclose(statp); + /* + * A long running process might get its TCP + * connection reset if the remote server was + * restarted. Requery the server instead of + * trying a new one. When there is only one + * server, this means that a query might work + * instead of failing. We only allow one reset + * per query to prevent looping. + */ + if (*terrno == ECONNRESET && !connreset) { + connreset = 1; + res_nclose(statp); + goto same_ns; + } + res_nclose(statp); + return (0); + } + resplen = ns_get16(ans); + if (resplen > anssiz) { + Dprint(statp->options & RES_DEBUG, + (stdout, ";; response truncated\n") + ); + truncating = 1; + len = anssiz; + } else + len = resplen; + if (len < HFIXEDSZ) { + /* + * Undersized message. + */ + Dprint(statp->options & RES_DEBUG, + (stdout, ";; undersized: %d\n", len)); + *terrno = EMSGSIZE; + res_nclose(statp); + return (0); + } + cp = ans; + while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){ + cp += n; + len -= n; + } + if (n <= 0) { + *terrno = errno; + Perror(statp, stderr, "read(vc)", errno); + res_nclose(statp); + return (0); + } + if (truncating) { + /* + * Flush rest of answer so connection stays in synch. + */ + anhp->tc = 1; + len = resplen - anssiz; + while (len != 0) { + char junk[PACKETSZ]; + + n = read(statp->_vcsock, junk, + (len > sizeof junk) ? sizeof junk : len); + if (n > 0) + len -= n; + else + break; + } + } + /* + * If the calling applicating has bailed out of + * a previous call and failed to arrange to have + * the circuit closed or the server has got + * itself confused, then drop the packet and + * wait for the correct one. + */ + if (hp->id != anhp->id) { + DprintQ((statp->options & RES_DEBUG) || + (statp->pfcode & RES_PRF_REPLY), + (stdout, ";; old answer (unexpected):\n"), + ans, (resplen > anssiz) ? anssiz: resplen); + goto read_len; + } + + /* + * All is well, or the error is fatal. Signal that the + * next nameserver ought not be tried. + */ + return (resplen); } -/* Private */ static int -cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2) { +send_dg(res_state statp, + const u_char *buf, int buflen, u_char *ans, int anssiz, + int *terrno, int ns, int *v_circuit, int *gotsomewhere) +{ + const HEADER *hp = (HEADER *) buf; + HEADER *anhp = (HEADER *) ans; + const struct sockaddr_in *nsap = &statp->nsaddr_list[ns]; + struct timespec now, timeout, finish; +#ifdef _LIBC + struct pollfd pfd[1]; + int ptimeout; +#else + fd_set dsmask; +#endif + struct sockaddr_in from; + int fromlen, resplen, seconds, n, s; + + if (EXT(statp).nssocks[ns] == -1) { + EXT(statp).nssocks[ns] = socket(PF_INET, SOCK_DGRAM, 0); +#ifndef _LIBC + if (EXT(statp).nssocks[ns] > highestFD) { + res_nclose(statp); + __set_errno (ENOTSOCK); + } +#endif + if (EXT(statp).nssocks[ns] < 0) { + *terrno = errno; + Perror(statp, stderr, "socket(dg)", errno); + return (-1); + } +#ifndef CANNOT_CONNECT_DGRAM + /* + * On a 4.3BSD+ machine (client and server, + * actually), sending to a nameserver datagram + * port with no nameserver will cause an + * ICMP port unreachable message to be returned. + * If our datagram socket is "connected" to the + * server, we get an ECONNREFUSED error on the next + * socket operation, and select returns if the + * error message is received. We can thus detect + * the absence of a nameserver without timing out. + */ + if (connect(EXT(statp).nssocks[ns], (struct sockaddr *)nsap, + sizeof *nsap) < 0) { + Aerror(statp, stderr, "connect(dg)", errno, *nsap); + res_nclose(statp); + return (0); + } +#endif /* !CANNOT_CONNECT_DGRAM */ + Dprint(statp->options & RES_DEBUG, + (stdout, ";; new DG socket\n")) + } + s = EXT(statp).nssocks[ns]; +#ifndef CANNOT_CONNECT_DGRAM + if (send(s, (char*)buf, buflen, 0) != buflen) { + Perror(statp, stderr, "send", errno); + res_nclose(statp); + return (0); + } +#else /* !CANNOT_CONNECT_DGRAM */ + if (sendto(s, (char*)buf, buflen, 0, + (struct sockaddr *)nsap, sizeof *nsap) != buflen) + { + Aerror(statp, stderr, "sendto", errno, *nsap); + res_nclose(statp); + return (0); + } +#endif /* !CANNOT_CONNECT_DGRAM */ + + /* + * Wait for reply. + */ + seconds = (statp->retrans << ns); + if (ns > 0) + seconds /= statp->nscount; + if (seconds <= 0) + seconds = 1; + now = evNowTime(); + timeout = evConsTime(seconds, 0); + finish = evAddTime(now, timeout); + wait: +#ifdef _LIBC + /* Convert struct timespec in milliseconds. */ + ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000; + + pfd[0].fd = s; + pfd[0].events = POLLIN; + n = __poll (pfd, 1, ptimeout); +#else + FD_ZERO(&dsmask); + FD_SET(s, &dsmask); + n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL); +#endif + if (n == 0) { + Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); + *gotsomewhere = 1; + return (0); + } + if (n < 0) { + if (errno == EINTR) { + now = evNowTime(); + if (evCmpTime(finish, now) > 0) { + timeout = evSubTime(finish, now); + goto wait; + } + } + Perror(statp, stderr, "select", errno); + res_nclose(statp); + return (0); + } + __set_errno (0); + fromlen = sizeof(struct sockaddr_in); + resplen = recvfrom(s, (char*)ans, anssiz,0, + (struct sockaddr *)&from, &fromlen); + if (resplen <= 0) { + Perror(statp, stderr, "recvfrom", errno); + res_nclose(statp); + return (0); + } + *gotsomewhere = 1; + if (resplen < HFIXEDSZ) { + /* + * Undersized message. + */ + Dprint(statp->options & RES_DEBUG, + (stdout, ";; undersized: %d\n", + resplen)); + *terrno = EMSGSIZE; + res_nclose(statp); + return (0); + } + if (hp->id != anhp->id) { + /* + * response from old query, ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((statp->options & RES_DEBUG) || + (statp->pfcode & RES_PRF_REPLY), + (stdout, ";; old answer:\n"), + ans, (resplen > anssiz) ? anssiz : resplen); + goto wait; + } + if (!(statp->options & RES_INSECURE1) && + !res_ourserver_p(statp, &from)) { + /* + * response from wrong server? ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((statp->options & RES_DEBUG) || + (statp->pfcode & RES_PRF_REPLY), + (stdout, ";; not our server:\n"), + ans, (resplen > anssiz) ? anssiz : resplen); + goto wait; + } + if (!(statp->options & RES_INSECURE2) && + !res_queriesmatch(buf, buf + buflen, + ans, ans + anssiz)) { + /* + * response contains wrong query? ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((statp->options & RES_DEBUG) || + (statp->pfcode & RES_PRF_REPLY), + (stdout, ";; wrong query name:\n"), + ans, (resplen > anssiz) ? anssiz : resplen); + goto wait; + } + if (anhp->rcode == SERVFAIL || + anhp->rcode == NOTIMP || + anhp->rcode == REFUSED) { + DprintQ(statp->options & RES_DEBUG, + (stdout, "server rejected query:\n"), + ans, (resplen > anssiz) ? anssiz : resplen); + res_nclose(statp); + /* don't retry if called from dig */ + if (!statp->pfcode) + return (0); + } + if (!(statp->options & RES_IGNTC) && anhp->tc) { + /* + * To get the rest of answer, + * use TCP with same server. + */ + Dprint(statp->options & RES_DEBUG, + (stdout, ";; truncated answer\n")); + *v_circuit = 1; + res_nclose(statp); + return (1); + } + /* + * All is well, or the error is fatal. Signal that the + * next nameserver ought not be tried. + */ + return (resplen); +} + +#ifdef DEBUG +static void +Aerror(const res_state statp, FILE *file, const char *string, int error, + struct sockaddr_in address) +{ + int save = errno; + + if ((statp->options & RES_DEBUG) != 0) { + char tmp[sizeof "255.255.255.255"]; + + fprintf(file, "res_send: %s ([%s].%u): %s\n", + string, + inet_ntop(address.sin_family, &address.sin_addr, + tmp, sizeof tmp), + ntohs(address.sin_port), + strerror(error)); + } + __set_errno (save); +} + +static void +Perror(const res_state statp, FILE *file, const char *string, int error) { + int save = errno; + + if ((statp->options & RES_DEBUG) != 0) + fprintf(file, "res_send: %s: %s\n", + string, strerror(error)); + __set_errno (save); +} +#endif + +static int +sock_eq(struct sockaddr_in *a1, struct sockaddr_in *a2) { return ((a1->sin_family == a2->sin_family) && (a1->sin_port == a2->sin_port) && (a1->sin_addr.s_addr == a2->sin_addr.s_addr)); @@ -943,8 +937,7 @@ cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2) { /* XXX needs to move to the porting library. */ static int pselect(int nfds, void *rfds, void *wfds, void *efds, - struct timespec *tsp, - const sigset_t *sigmask) + struct timespec *tsp, const sigset_t *sigmask) { struct timeval tv, *tvp; sigset_t sigs; diff --git a/resolv/resolv.h b/resolv/resolv.h index 426ac7a..058c631 100644 --- a/resolv/resolv.h +++ b/resolv/resolv.h @@ -1,9 +1,7 @@ /* - * ++Copyright++ 1983, 1987, 1989, 1993 - * - - * Copyright (c) 1983, 1987, 1989, 1993 + * Copyright (c) 1983, 1987, 1989 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,7 +13,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -27,26 +25,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- */ /* @@ -68,13 +46,11 @@ /* * @(#)resolv.h 8.1 (Berkeley) 6/2/93 - * $Id$ + * $BINDId: resolv.h,v 8.31 2000/03/30 20:16:50 vixie Exp $ */ -#ifndef _RESOLV_H -#define _RESOLV_H 1 - -#include <features.h> +#ifndef _RESOLV_H_ +#define _RESOLV_H_ #include <sys/param.h> #if (!defined(BSD)) || (BSD < 199306) @@ -82,8 +58,11 @@ #else # include <sys/types.h> #endif +#include <sys/cdefs.h> #include <stdio.h> + #include <netinet/in.h> +#include <arpa/nameser.h> /* * Revision information. This is the release date in YYYYMMDD format. @@ -96,37 +75,9 @@ #define __RES 19991006 /* - * This used to be defined in res_query.c, now it's in herror.c. - * [XXX no it's not. It's in irs/irs_data.c] - * It was - * never extern'd by any *.h file before it was placed here. For thread - * aware programs, the last h_errno value set is stored in res->h_errno. - * - * XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO - * (and __h_errno_set) to the public via <resolv.h>. - * XXX: __h_errno_set is really part of IRS, not part of the resolver. - * If somebody wants to build and use a resolver that doesn't use IRS, - * what do they do? Perhaps something like - * #ifdef WANT_IRS - * # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) - * #else - * # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x)) - * #endif - */ -#define RES_SET_H_ERRNO(r,x) \ - do \ - { \ - (r)->res_h_errno = x; \ - __set_h_errno(x); \ - } \ - while (0) - -struct __res_state; /* forward */ - -/* * Resolver configuration file. * Normally not present, but may contain the address of the - * initial name server(s) to query and the domain search list. + * inital name server(s) to query and the domain search list. */ #ifndef _PATH_RESCONF @@ -136,19 +87,19 @@ struct __res_state; /* forward */ typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } res_sendhookact; -typedef res_sendhookact (*res_send_qhook) (struct sockaddr_in * const *ns, - const u_char **query, - int *querylen, - u_char *ans, - int anssiz, - int *resplen); +typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns, + const u_char **query, + int *querylen, + u_char *ans, + int anssiz, + int *resplen)); -typedef res_sendhookact (*res_send_rhook) (const struct sockaddr_in *ns, - const u_char *query, - int querylen, - u_char *ans, - int anssiz, - int *resplen); +typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns, + const u_char *query, + int querylen, + u_char *ans, + int anssiz, + int *resplen)); struct res_sym { int number; /* Identifying number, like T_MX */ @@ -170,9 +121,10 @@ struct res_sym { #define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */ #define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */ #define RES_DFLRETRY 2 /* Default #/tries. */ +#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */ struct __res_state { - int retrans; /* retransmission time interval */ + int retrans; /* retransmition time interval */ int retry; /* number of times to retransmit */ u_long options; /* option flags - see below. */ int nscount; /* number of name servers */ @@ -193,9 +145,17 @@ struct __res_state { res_send_qhook qhook; /* query hook */ res_send_rhook rhook; /* response hook */ int res_h_errno; /* last one set for this context */ - int _sock; /* PRIVATE: for res_send i/o */ + int _vcsock; /* PRIVATE: for res_send VC i/o */ u_int _flags; /* PRIVATE: see below */ - char pad[52]; /* On an i386 this means 512b total. */ + union { + char pad[52]; /* On an i386 this means 512b total. */ + struct { + u_int16_t nscount; + u_int16_t nstimes[MAXNS]; /* ms. */ + int nssocks[MAXNS]; + struct sockaddr_in nsaddrs[MAXNS]; + } _ext; + } _u; }; typedef struct __res_state *res_state; @@ -229,6 +189,7 @@ typedef struct __res_state *res_state; #define RES_ROTATE 0x00004000 /* rotate ns list after each query */ #define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */ #define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */ +#define RES_BLAST 0x00020000 /* blast all recursive servers */ #define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) @@ -237,7 +198,7 @@ typedef struct __res_state *res_state; */ #define RES_PRF_STATS 0x00000001 #define RES_PRF_UPDATE 0x00000002 -#define RES_PRF_CLASS 0x00000004 +#define RES_PRF_CLASS 0x00000004 #define RES_PRF_CMD 0x00000008 #define RES_PRF_QUES 0x00000010 #define RES_PRF_ANS 0x00000020 @@ -253,46 +214,51 @@ typedef struct __res_state *res_state; /* 0x00008000 */ /* Things involving an internal (static) resolver context. */ -#if defined _REENTRANT || defined _LIBC_REENTRANT +#if !defined _LIBC || defined _LIBC_REENTRANT extern struct __res_state *__res_state(void) __attribute__ ((__const__)); -# if defined __RES_PTHREAD_INTERNAL -extern struct __res_state _res; -# else -# define _res (*__res_state()) -# endif +#define _res (*__res_state()) #else +#ifndef __BIND_NOSTATIC extern struct __res_state _res; #endif +#endif +#ifndef __BIND_NOSTATIC #define fp_nquery __fp_nquery #define fp_query __fp_query #define hostalias __hostalias #define p_query __p_query #define res_close __res_close +#define res_init __res_init #define res_isourserver __res_isourserver +#define res_mkquery __res_mkquery +#define res_query __res_query +#define res_querydomain __res_querydomain +#define res_search __res_search #define res_send __res_send __BEGIN_DECLS -void fp_nquery (const u_char *, int, FILE *) __THROW; -void fp_query (const u_char *, FILE *) __THROW; -const char * hostalias (const char *) __THROW; -void p_query (const u_char *) __THROW; -void res_close (void) __THROW; -int res_init (void) __THROW; -int res_isourserver (const struct sockaddr_in *) __THROW; -int res_mkquery (int, const char *, int, int, const u_char *, - int, const u_char *, u_char *, int) __THROW; -int res_query (const char *, int, int, u_char *, int) __THROW; -int res_querydomain (const char *, const char *, int, int, - u_char *, int) __THROW; -int res_search (const char *, int, int, u_char *, int) __THROW; -int res_send (const u_char *, int, u_char *, int) __THROW; +void fp_nquery __P((const u_char *, int, FILE *)); +void fp_query __P((const u_char *, FILE *)); +const char * hostalias __P((const char *)); +void p_query __P((const u_char *)); +void res_close __P((void)); +int res_init __P((void)); +int res_isourserver __P((const struct sockaddr_in *)); +int res_mkquery __P((int, const char *, int, int, const u_char *, + int, const u_char *, u_char *, int)); +int res_query __P((const char *, int, int, u_char *, int)); +int res_querydomain __P((const char *, const char *, int, int, + u_char *, int)); +int res_search __P((const char *, int, int, u_char *, int)); +int res_send __P((const u_char *, int, u_char *, int)); __END_DECLS +#endif -#if !defined(SHARED_LIBBIND) || defined(_LIBC) +#if !defined(SHARED_LIBBIND) || defined(LIB) /* * If libbind is a shared object (well, DLL anyway) - * these externs break the linker when resolv.h is + * these externs break the linker when resolv.h is * included by a lib client (like named) * Make them go away if a client is including this * @@ -308,6 +274,7 @@ extern const struct res_sym __p_rcode_syms[]; #define b64_pton __b64_pton #define dn_comp __dn_comp #define dn_count_labels __dn_count_labels +#define dn_expand __dn_expand #define dn_skipname __dn_skipname #define fp_resstat __fp_resstat #define loc_aton __loc_aton @@ -326,7 +293,6 @@ extern const struct res_sym __p_rcode_syms[]; #define putlong __putlong #define putshort __putshort #define res_dnok __res_dnok -#define res_findzonecut __res_findzonecut #define res_hnok __res_hnok #define res_hostalias __res_hostalias #define res_mailok __res_mailok @@ -347,63 +313,62 @@ extern const struct res_sym __p_rcode_syms[]; #define sym_ntos __sym_ntos #define sym_ston __sym_ston __BEGIN_DECLS -int res_hnok (const char *) __THROW; -int res_ownok (const char *) __THROW; -int res_mailok (const char *) __THROW; -int res_dnok (const char *) __THROW; -int sym_ston (const struct res_sym *, const char *, int *) __THROW; -const char * sym_ntos (const struct res_sym *, int, int *) __THROW; -const char * sym_ntop (const struct res_sym *, int, int *) __THROW; -int b64_ntop (u_char const *, size_t, char *, size_t) __THROW; -int b64_pton (char const *, u_char *, size_t) __THROW; -int loc_aton (const char *__ascii, u_char *__binary) __THROW; -const char * loc_ntoa (const u_char *__binary, char *__ascii) __THROW; -int dn_skipname (const u_char *, const u_char *) __THROW; -void putlong (u_int32_t, u_char *) __THROW; -void putshort (u_int16_t, u_char *) __THROW; -const char * p_class (int) __THROW; -const char * p_time (u_int32_t) __THROW; -const char * p_type (int) __THROW; -const char * p_rcode (int) __THROW; -const u_char * p_cdnname (const u_char *, const u_char *, int, FILE *) - __THROW; -const u_char * p_cdname (const u_char *, const u_char *, FILE *) __THROW; -const u_char * p_fqnname (const u_char *cp, const u_char *msg, - int, char *, int) __THROW; -const u_char * p_fqname (const u_char *, const u_char *, FILE *) __THROW; -const char * p_option (u_long option) __THROW; -char * p_secstodate (u_long) __THROW; -int dn_count_labels (const char *) __THROW; -int dn_comp (const char *, u_char *, int, - u_char **, u_char **) __THROW; -int dn_expand (const u_char *, const u_char *, const u_char *, - char *, int) __THROW; -u_int res_randomid (void) __THROW; -int res_nameinquery (const char *, int, int, - const u_char *, const u_char *) __THROW; -int res_queriesmatch (const u_char *, const u_char *, - const u_char *, const u_char *) __THROW; -const char * p_section (int section, int opcode) __THROW; +int res_hnok __P((const char *)); +int res_ownok __P((const char *)); +int res_mailok __P((const char *)); +int res_dnok __P((const char *)); +int sym_ston __P((const struct res_sym *, const char *, int *)); +const char * sym_ntos __P((const struct res_sym *, int, int *)); +const char * sym_ntop __P((const struct res_sym *, int, int *)); +int b64_ntop __P((u_char const *, size_t, char *, size_t)); +int b64_pton __P((char const *, u_char *, size_t)); +int loc_aton __P((const char *ascii, u_char *binary)); +const char * loc_ntoa __P((const u_char *binary, char *ascii)); +int dn_skipname __P((const u_char *, const u_char *)); +void putlong __P((u_int32_t, u_char *)); +void putshort __P((u_int16_t, u_char *)); +const char * p_class __P((int)); +const char * p_time __P((u_int32_t)); +const char * p_type __P((int)); +const char * p_rcode __P((int)); +const u_char * p_cdnname __P((const u_char *, const u_char *, int, FILE *)); +const u_char * p_cdname __P((const u_char *, const u_char *, FILE *)); +const u_char * p_fqnname __P((const u_char *cp, const u_char *msg, + int, char *, int)); +const u_char * p_fqname __P((const u_char *, const u_char *, FILE *)); +const char * p_option __P((u_long option)); +char * p_secstodate __P((u_long)); +int dn_count_labels __P((const char *)); +int dn_comp __P((const char *, u_char *, int, + u_char **, u_char **)); +int dn_expand __P((const u_char *, const u_char *, const u_char *, + char *, int)); +u_int res_randomid __P((void)); +int res_nameinquery __P((const char *, int, int, + const u_char *, const u_char *)); +int res_queriesmatch __P((const u_char *, const u_char *, + const u_char *, const u_char *)); +const char * p_section __P((int section, int opcode)); /* Things involving a resolver context. */ -int res_ninit (res_state) __THROW; -int res_nisourserver (const res_state, - const struct sockaddr_in *) __THROW; -void fp_resstat (const res_state, FILE *) __THROW; -void res_npquery (const res_state, const u_char *, int, FILE *) __THROW; -const char * res_hostalias (const res_state, const char *, - char *, size_t) __THROW; -int res_nquery (res_state, - const char *, int, int, u_char *, int) __THROW; -int res_nsearch (res_state, const char *, int, - int, u_char *, int) __THROW; -int res_nquerydomain (res_state, - const char *, const char *, int, int, - u_char *, int) __THROW; -int res_nmkquery (res_state, - int, const char *, int, int, const u_char *, - int, const u_char *, u_char *, int) __THROW; -int res_nsend (res_state, const u_char *, int, u_char *, int) __THROW; -void res_nclose (res_state) __THROW; +int res_ninit __P((res_state)); +int res_nisourserver __P((const res_state, + const struct sockaddr_in *)); +void fp_resstat __P((const res_state, FILE *)); +void res_npquery __P((const res_state, const u_char *, int, FILE *)); +const char * res_hostalias __P((const res_state, const char *, + char *, size_t)); +int res_nquery __P((res_state, + const char *, int, int, u_char *, int)); +int res_nsearch __P((res_state, const char *, int, + int, u_char *, int)); +int res_nquerydomain __P((res_state, + const char *, const char *, int, int, + u_char *, int)); +int res_nmkquery __P((res_state, + int, const char *, int, int, const u_char *, + int, const u_char *, u_char *, int)); +int res_nsend __P((res_state, const u_char *, int, u_char *, int)); +void res_nclose __P((res_state)); __END_DECLS #endif /* !_RESOLV_H_ */ |