diff options
Diffstat (limited to 'lib')
38 files changed, 901 insertions, 123 deletions
diff --git a/lib/libc/include/port_after.h b/lib/libc/include/port_after.h new file mode 100644 index 000000000000..762795f5d63d --- /dev/null +++ b/lib/libc/include/port_after.h @@ -0,0 +1,10 @@ +/* $FreeBSD$ */ + +#ifndef _PORT_AFTER_H_ +#define _PORT_AFTER_H_ + +#define HAVE_SA_LEN 1 +#define HAS_INET6_STRUCTS 1 +#define HAVE_SIN6_SCOPE_ID 1 + +#endif /* _PORT_AFTER_H_ */ diff --git a/lib/libc/include/port_before.h b/lib/libc/include/port_before.h new file mode 100644 index 000000000000..beef71d02607 --- /dev/null +++ b/lib/libc/include/port_before.h @@ -0,0 +1,22 @@ +/* $FreeBSD$ */ + +#ifndef _PORT_BEFORE_H_ +#define _PORT_BEFORE_H_ + +#define _LIBC 1 +#define DO_PTHREADS 1 +#define USE_KQUEUE 1 + +#define ISC_SOCKLEN_T socklen_t +#define ISC_FORMAT_PRINTF(fmt, args) \ + __attribute__((__format__(__printf__, fmt, args))) +#define DE_CONST(konst, var) \ + do { \ + union { const void *k; void *v; } _u; \ + _u.k = konst; \ + var = _u.v; \ + } while (0) + +#define UNUSED(x) (x) = (x) + +#endif /* _PORT_BEFORE_H_ */ diff --git a/lib/libc/inet/Makefile.inc b/lib/libc/inet/Makefile.inc new file mode 100644 index 000000000000..27ff992e4fb9 --- /dev/null +++ b/lib/libc/inet/Makefile.inc @@ -0,0 +1,9 @@ +# $FreeBSD$ + +# inet sources +.PATH: ${.CURDIR}/inet + +SRCS+= inet_addr.c inet_cidr_ntop.c inet_cidr_pton.c inet_lnaof.c \ + inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \ + inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ + inet_pton.c nsap_addr.c diff --git a/lib/libc/inet/Symbol.map b/lib/libc/inet/Symbol.map new file mode 100644 index 000000000000..03cacc7aed1c --- /dev/null +++ b/lib/libc/inet/Symbol.map @@ -0,0 +1,34 @@ +# $FreeBSD$ + +FBSD_1.0 { + __inet_addr; + __inet_aton; + inet_addr; + inet_aton; + __inet_cidr_ntop; + __inet_cidr_pton; + __inet_lnaof; + inet_lnaof; + __inet_makeaddr; + inet_makeaddr; + __inet_net_ntop; + inet_net_ntop; + __inet_net_pton; + inet_net_pton; + __inet_neta; + inet_neta; + __inet_netof; + inet_netof; + __inet_network; + inet_network; + __inet_ntoa; + inet_ntoa; + __inet_ntop; + inet_ntop; + __inet_pton; + inet_pton; + __inet_nsap_addr; + __inet_nsap_ntoa; + inet_nsap_addr; + inet_nsap_ntoa; +}; diff --git a/lib/libc/inet/inet_addr.c b/lib/libc/inet/inet_addr.c index b967dc22039c..aa6504a30e77 100644 --- a/lib/libc/inet/inet_addr.c +++ b/lib/libc/inet/inet_addr.c @@ -72,6 +72,8 @@ static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; static const char rcsid[] = "$Id: inet_addr.c,v 1.2.206.2 2004/03/17 00:29:45 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -89,7 +91,7 @@ static const char rcsid[] = "$Id: inet_addr.c,v 1.2.206.2 2004/03/17 00:29:45 ma * Ascii internet address interpretation routine. * The value returned is in network order. */ -u_long +in_addr_t /* XXX should be struct in_addr :( */ inet_addr(const char *cp) { struct in_addr val; @@ -204,3 +206,12 @@ inet_aton(const char *cp, struct in_addr *addr) { addr->s_addr = htonl(val); return (1); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_addr +__weak_reference(__inet_addr, inet_addr); +#undef inet_aton +__weak_reference(__inet_aton, inet_aton); diff --git a/lib/libc/inet/inet_cidr_pton.c b/lib/libc/inet/inet_cidr_pton.c index 5bfef71ba721..3089eb95dafc 100644 --- a/lib/libc/inet/inet_cidr_pton.c +++ b/lib/libc/inet/inet_cidr_pton.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.2.2.1.8.2 2004/03/17 00:29:46 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -27,7 +29,7 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.2.2.1.8.2 2004/03/17 00:2 #include <arpa/nameser.h> #include <arpa/inet.h> -#include <isc/assertions.h> +#include <assert.h> #include <ctype.h> #include <errno.h> #include <stdio.h> @@ -92,7 +94,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits, int ipv6) { tmp = 0; do { n = strchr(digits, ch) - digits; - INSIST(n >= 0 && n <= 9); + assert(n >= 0 && n <= 9); tmp *= 10; tmp += n; if (tmp > 255) diff --git a/lib/libc/inet/inet_lnaof.c b/lib/libc/inet/inet_lnaof.c index 97b80cffdb5b..678e02cb5b92 100644 --- a/lib/libc/inet/inet_lnaof.c +++ b/lib/libc/inet/inet_lnaof.c @@ -34,6 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -48,11 +50,11 @@ static const char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; * internet address; handles class a/b/c network * number formats. */ -u_long +in_addr_t inet_lnaof(in) struct in_addr in; { - register u_long i = ntohl(in.s_addr); + in_addr_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return ((i)&IN_CLASSA_HOST); @@ -61,3 +63,10 @@ inet_lnaof(in) else return ((i)&IN_CLASSC_HOST); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_lnaof +__weak_reference(__inet_lnaof, inet_lnaof); diff --git a/lib/libc/inet/inet_makeaddr.c b/lib/libc/inet/inet_makeaddr.c index 6e4ecc37ccab..fa6cffef39bb 100644 --- a/lib/libc/inet/inet_makeaddr.c +++ b/lib/libc/inet/inet_makeaddr.c @@ -34,6 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -49,7 +51,7 @@ static const char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; */ struct in_addr inet_makeaddr(net, host) - u_long net, host; + in_addr_t net, host; { struct in_addr a; @@ -64,3 +66,10 @@ inet_makeaddr(net, host) a.s_addr = htonl(a.s_addr); return (a); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_makeaddr +__weak_reference(__inet_makeaddr, inet_makeaddr); diff --git a/lib/libc/inet/inet_net_ntop.c b/lib/libc/inet/inet_net_ntop.c index f508629d617a..e221d21b7352 100644 --- a/lib/libc/inet/inet_net_ntop.c +++ b/lib/libc/inet/inet_net_ntop.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.1.2.1.8.1 2004/03/09 08:33:32 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -39,10 +41,10 @@ static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.1.2.1.8.1 2004/03/09 08:33 # define SPRINTF(x) ((size_t)sprintf x) #endif -static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits, - char *dst, size_t size)); -static char * inet_net_ntop_ipv6 __P((const u_char *src, int bits, - char *dst, size_t size)); +static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, + size_t size); +static char * inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, + size_t size); /* * char * @@ -159,7 +161,7 @@ inet_net_ntop_ipv4(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: * Vadim Kogan (UCB), June 2001 * Original version (IPv4) by Paul Vixie (ISC), July 1996 @@ -191,7 +193,7 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { *cp++ = ':'; *cp = '\0'; } else { - /* Copy src to private buffer. Zero host part. */ + /* Copy src to private buffer. Zero host part. */ p = (bits + 7) / 8; memcpy(inbuf, src, p); memset(inbuf + p, 0, 16 - p); @@ -207,7 +209,7 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { words = (bits + 15) / 16; if (words == 1) words = 2; - + /* Find the longest substring of zero's */ zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; for (i = 0; i < (words * 2); i += 2) { @@ -268,10 +270,17 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { if (strlen(outbuf) + 1 > size) goto emsgsize; strcpy(dst, outbuf); - + return (dst); emsgsize: errno = EMSGSIZE; return (NULL); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_net_ntop +__weak_reference(__inet_net_ntop, inet_net_ntop); diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c index abecfc79cd2c..3d9650c9fbcc 100644 --- a/lib/libc/inet/inet_net_pton.c +++ b/lib/libc/inet/inet_net_pton.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: inet_net_pton.c,v 1.4.2.1.8.2 2004/03/17 00:29:47 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -27,7 +29,7 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.4.2.1.8.2 2004/03/17 00:29 #include <arpa/nameser.h> #include <arpa/inet.h> -#include <isc/assertions.h> +#include <assert.h> #include <ctype.h> #include <errno.h> #include <stdio.h> @@ -78,7 +80,7 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { if (isupper(ch)) ch = tolower(ch); n = strchr(xdigits, ch) - xdigits; - INSIST(n >= 0 && n <= 15); + assert(n >= 0 && n <= 15); if (dirty == 0) tmp = n; else @@ -101,7 +103,7 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { tmp = 0; do { n = strchr(digits, ch) - digits; - INSIST(n >= 0 && n <= 9); + assert(n >= 0 && n <= 9); tmp *= 10; tmp += n; if (tmp > 255) @@ -130,7 +132,7 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { bits = 0; do { n = strchr(digits, ch) - digits; - INSIST(n >= 0 && n <= 9); + assert(n >= 0 && n <= 9); bits *= 10; bits += n; } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); @@ -403,3 +405,10 @@ inet_net_pton(int af, const char *src, void *dst, size_t size) { return (-1); } } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_net_pton +__weak_reference(__inet_net_pton, inet_net_pton); diff --git a/lib/libc/inet/inet_neta.c b/lib/libc/inet/inet_neta.c index 325b7ce814e3..872ad485a671 100644 --- a/lib/libc/inet/inet_neta.c +++ b/lib/libc/inet/inet_neta.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: inet_neta.c,v 1.1.206.1 2004/03/09 08:33:33 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -41,7 +43,7 @@ static const char rcsid[] = "$Id: inet_neta.c,v 1.1.206.1 2004/03/09 08:33:33 ma /* * char * * inet_neta(src, dst, size) - * format a u_long network number into presentation format. + * format an in_addr_t network number into presentation format. * return: * pointer to dst, or NULL if an error occurred (check errno). * note: @@ -51,7 +53,7 @@ static const char rcsid[] = "$Id: inet_neta.c,v 1.1.206.1 2004/03/09 08:33:33 ma */ char * inet_neta(src, dst, size) - u_long src; + in_addr_t src; char *dst; size_t size; { @@ -85,3 +87,10 @@ inet_neta(src, dst, size) errno = EMSGSIZE; return (NULL); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_neta +__weak_reference(__inet_neta, inet_neta); diff --git a/lib/libc/inet/inet_netof.c b/lib/libc/inet/inet_netof.c index e887530088a1..e99345961fbd 100644 --- a/lib/libc/inet/inet_netof.c +++ b/lib/libc/inet/inet_netof.c @@ -34,6 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -47,11 +49,11 @@ static const char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; * Return the network number from an internet * address; handles class a/b/c network #'s. */ -u_long +in_addr_t inet_netof(in) struct in_addr in; { - register u_long i = ntohl(in.s_addr); + in_addr_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); @@ -60,3 +62,10 @@ inet_netof(in) else return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_netof +__weak_reference(__inet_netof, inet_netof); diff --git a/lib/libc/inet/inet_network.c b/lib/libc/inet/inet_network.c index aaa50c831578..9d417ac2db91 100644 --- a/lib/libc/inet/inet_network.c +++ b/lib/libc/inet/inet_network.c @@ -34,6 +34,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -49,14 +51,14 @@ static const char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; * The library routines call this routine to interpret * network numbers. */ -u_long +in_addr_t inet_network(cp) - register const char *cp; + const char *cp; { - register u_long val, base, n, i; - register char c; - u_long parts[4], *pp = parts; - int digit; + in_addr_t val, base, n; + char c; + in_addr_t parts[4], *pp = parts; + int i, digit; again: val = 0; base = 10; digit = 0; @@ -102,3 +104,10 @@ again: } return (val); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_network +__weak_reference(__inet_network, inet_network); diff --git a/lib/libc/inet/inet_ntoa.c b/lib/libc/inet/inet_ntoa.c index 7fad4b8902a4..f1fe1a9c3145 100644 --- a/lib/libc/inet/inet_ntoa.c +++ b/lib/libc/inet/inet_ntoa.c @@ -35,6 +35,8 @@ static const char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: inet_ntoa.c,v 1.1 2001/03/29 06:31:38 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -60,3 +62,10 @@ inet_ntoa(struct in_addr in) { (void) inet_ntop(AF_INET, &in, ret, sizeof ret); return (ret); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_ntoa +__weak_reference(__inet_ntoa, inet_ntoa); diff --git a/lib/libc/inet/inet_ntop.c b/lib/libc/inet/inet_ntop.c index cd502ab75862..48c2efee270f 100644 --- a/lib/libc/inet/inet_ntop.c +++ b/lib/libc/inet/inet_ntop.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: inet_ntop.c,v 1.1.2.1.8.2 2005/11/03 23:08:40 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -35,19 +37,13 @@ static const char rcsid[] = "$Id: inet_ntop.c,v 1.1.2.1.8.2 2005/11/03 23:08:40 #include "port_after.h" -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif - /* * WARNING: Don't even consider trying to compile this on a system where * 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, size_t size)); -static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); +static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size); +static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size); /* char * * inet_ntop(af, src, dst, size) @@ -58,11 +54,8 @@ static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); * Paul Vixie, 1996. */ const char * -inet_ntop(af, src, dst, size) - int af; - const void *src; - char *dst; - size_t size; +inet_ntop(int af, const void * __restrict src, char * __restrict dst, + socklen_t size) { switch (af) { case AF_INET: @@ -88,19 +81,18 @@ inet_ntop(af, src, dst, size) * Paul Vixie, 1996. */ static const char * -inet_ntop4(src, dst, size) - const u_char *src; - char *dst; - size_t size; +inet_ntop4(const u_char *src, char *dst, socklen_t size) { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; + int l; - if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) { + l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); + if (l <= 0 || (socklen_t) l >= size) { errno = ENOSPC; return (NULL); } - strcpy(dst, tmp); + strlcpy(dst, tmp, size); return (dst); } @@ -111,10 +103,7 @@ inet_ntop4(src, dst, size) * Paul Vixie, 1996. */ static const char * -inet_ntop6(src, dst, size) - const u_char *src; - char *dst; - size_t size; +inet_ntop6(const u_char *src, char *dst, socklen_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough @@ -185,7 +174,7 @@ inet_ntop6(src, dst, size) tp += strlen(tp); break; } - tp += SPRINTF((tp, "%x", words[i])); + tp += sprintf(tp, "%x", words[i]); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == @@ -196,10 +185,17 @@ inet_ntop6(src, dst, size) /* * Check for overflow, copy, and we're done. */ - if ((size_t)(tp - tmp) > size) { + if ((socklen_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_ntop +__weak_reference(__inet_ntop, inet_ntop); diff --git a/lib/libc/inet/inet_pton.c b/lib/libc/inet/inet_pton.c index f18a7b64fde2..44d9c61f7e5b 100644 --- a/lib/libc/inet/inet_pton.c +++ b/lib/libc/inet/inet_pton.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: inet_pton.c,v 1.2.206.2 2005/07/28 07:43:18 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" #include <sys/param.h> @@ -35,8 +37,8 @@ static const char rcsid[] = "$Id: inet_pton.c,v 1.2.206.2 2005/07/28 07:43:18 ma * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -static int inet_pton4 __P((const char *src, u_char *dst)); -static int inet_pton6 __P((const char *src, u_char *dst)); +static int inet_pton4(const char *src, u_char *dst); +static int inet_pton6(const char *src, u_char *dst); /* int * inet_pton(af, src, dst) @@ -50,10 +52,7 @@ static int inet_pton6 __P((const char *src, u_char *dst)); * Paul Vixie, 1996. */ int -inet_pton(af, src, dst) - int af; - const char *src; - void *dst; +inet_pton(int af, const char * __restrict src, void * __restrict dst) { switch (af) { case AF_INET: @@ -78,9 +77,7 @@ inet_pton(af, src, dst) * Paul Vixie, 1996. */ static int -inet_pton4(src, dst) - const char *src; - u_char *dst; +inet_pton4(const char *src, u_char *dst) { static const char digits[] = "0123456789"; int saw_digit, octets, ch; @@ -133,9 +130,7 @@ inet_pton4(src, dst) * Paul Vixie, 1996. */ static int -inet_pton6(src, dst) - const char *src; - u_char *dst; +inet_pton6(const char *src, u_char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; @@ -219,3 +214,10 @@ inet_pton6(src, dst) memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_pton +__weak_reference(__inet_pton, inet_pton); diff --git a/lib/libc/inet/nsap_addr.c b/lib/libc/inet/nsap_addr.c index a4b98e7c4a09..27d44ba31798 100644 --- a/lib/libc/inet/nsap_addr.c +++ b/lib/libc/inet/nsap_addr.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: nsap_addr.c,v 1.2.206.2 2005/07/28 07:43:18 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -107,3 +109,12 @@ inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) { *ascii = '\0'; return (start); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <arpa/inet.h>. + */ +#undef inet_nsap_addr +__weak_reference(__inet_nsap_addr, inet_nsap_addr); +#undef inet_nsap_ntoa +__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa); diff --git a/lib/libc/isc/Makefile.inc b/lib/libc/isc/Makefile.inc new file mode 100644 index 000000000000..48c90f7f66e6 --- /dev/null +++ b/lib/libc/isc/Makefile.inc @@ -0,0 +1,6 @@ +# $FreeBSD$ + +# isc sources +.PATH: ${.CURDIR}/isc + +SRCS+= ev_streams.c ev_timers.c diff --git a/lib/libc/isc/ev_streams.c b/lib/libc/isc/ev_streams.c index 64e88b0c00d6..4ad82cf7f35a 100644 --- a/lib/libc/isc/ev_streams.c +++ b/lib/libc/isc/ev_streams.c @@ -22,9 +22,13 @@ #if !defined(LINT) && !defined(CODECENTER) static const char rcsid[] = "$Id: ev_streams.c,v 1.2.206.2 2004/03/17 00:29:51 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" +#ifndef _LIBC #include "fd_setsize.h" +#endif #include <sys/types.h> #include <sys/uio.h> @@ -32,16 +36,20 @@ static const char rcsid[] = "$Id: ev_streams.c,v 1.2.206.2 2004/03/17 00:29:51 m #include <errno.h> #include <isc/eventlib.h> +#ifndef _LIBC #include <isc/assertions.h> +#endif #include "eventlib_p.h" #include "port_after.h" +#ifndef _LIBC static int copyvec(evStream *str, const struct iovec *iov, int iocnt); static void consume(evStream *str, size_t bytes); static void done(evContext opaqueCtx, evStream *str); static void writable(evContext opaqueCtx, void *uap, int fd, int evmask); static void readable(evContext opaqueCtx, void *uap, int fd, int evmask); +#endif struct iovec evConsIovec(void *buf, size_t cnt) { @@ -53,6 +61,7 @@ evConsIovec(void *buf, size_t cnt) { return (ret); } +#ifndef _LIBC int evWrite(evContext opaqueCtx, int fd, const struct iovec *iov, int iocnt, evStreamFunc func, void *uap, evStreamID *id) @@ -304,3 +313,4 @@ readable(evContext opaqueCtx, void *uap, int fd, int evmask) { if (str->ioDone <= 0 || str->ioDone == str->ioTotal) done(opaqueCtx, str); } +#endif diff --git a/lib/libc/isc/ev_timers.c b/lib/libc/isc/ev_timers.c index 11433fbffa2f..47c3dcf7166d 100644 --- a/lib/libc/isc/ev_timers.c +++ b/lib/libc/isc/ev_timers.c @@ -22,15 +22,21 @@ #if !defined(LINT) && !defined(CODECENTER) static const char rcsid[] = "$Id: ev_timers.c,v 1.2.2.1.4.5 2004/03/17 02:39:13 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); /* Import. */ #include "port_before.h" +#ifndef _LIBC #include "fd_setsize.h" +#endif #include <errno.h> +#ifndef _LIBC #include <isc/assertions.h> +#endif #include <isc/eventlib.h> #include "eventlib_p.h" @@ -43,6 +49,9 @@ static const char rcsid[] = "$Id: ev_timers.c,v 1.2.2.1.4.5 2004/03/17 02:39:13 /* Forward. */ +#ifdef _LIBC +static int __evOptMonoTime; +#else static int due_sooner(void *, void *); static void set_index(void *, int); static void free_timer(void *, void *); @@ -58,6 +67,7 @@ typedef struct { struct timespec max_idle; evTimer * timer; } idle_timer; +#endif /* Public. */ @@ -138,12 +148,14 @@ evUTCTime() { return (evTimeSpec(now)); } +#ifndef _LIBC struct timespec evLastEventTime(evContext opaqueCtx) { evContext_p *ctx = opaqueCtx.opaque; return (ctx->lastEventTime); } +#endif struct timespec evTimeSpec(struct timeval tv) { @@ -154,6 +166,7 @@ evTimeSpec(struct timeval tv) { return (ts); } +#if !defined(USE_KQUEUE) || !defined(_LIBC) struct timeval evTimeVal(struct timespec ts) { struct timeval tv; @@ -162,7 +175,9 @@ evTimeVal(struct timespec ts) { tv.tv_usec = ts.tv_nsec / 1000; return (tv); } +#endif +#ifndef _LIBC int evSetTimer(evContext opaqueCtx, evTimerFunc func, @@ -495,3 +510,4 @@ idle_timeout(evContext opaqueCtx, this->timer->inter = evSubTime(this->max_idle, idle); } } +#endif diff --git a/lib/libc/isc/eventlib_p.h b/lib/libc/isc/eventlib_p.h index b95741d7aff3..38b1852e431c 100644 --- a/lib/libc/isc/eventlib_p.h +++ b/lib/libc/isc/eventlib_p.h @@ -19,6 +19,7 @@ * vix 09sep95 [initial] * * $Id: eventlib_p.h,v 1.3.2.1.4.3 2005/07/28 07:43:20 marka Exp $ + * $FreeBSD$ */ #ifndef _EVENTLIB_P_H @@ -38,9 +39,11 @@ #include <stdlib.h> #include <string.h> -#include <isc/heap.h> +#ifndef _LIBC #include <isc/list.h> +#include <isc/heap.h> #include <isc/memcluster.h> +#endif #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) #define EV_ERR(e) return (errno = (e), -1) @@ -83,6 +86,7 @@ typedef struct evConn { struct evConn * next; } evConn; +#ifndef _LIBC typedef struct evAccept { int fd; union { @@ -172,6 +176,7 @@ typedef struct evEvent_p { struct { const void *placeholder; } null; } u; } evEvent_p; +#endif #ifdef USE_POLL typedef struct { @@ -207,6 +212,7 @@ extern void __fd_set(int fd, __evEmulMask *maskp); #endif /* USE_POLL */ +#ifndef _LIBC typedef struct { /* Global. */ const evEvent_p *cur; @@ -271,6 +277,7 @@ void evDestroyTimers(const evContext_p *); /* ev_waits.c */ #define evFreeWait __evFreeWait evWait *evFreeWait(evContext_p *ctx, evWait *old); +#endif /* Global options */ extern int __evOptMonoTime; diff --git a/lib/libc/nameser/Makefile.inc b/lib/libc/nameser/Makefile.inc new file mode 100644 index 000000000000..2bbb12f79628 --- /dev/null +++ b/lib/libc/nameser/Makefile.inc @@ -0,0 +1,6 @@ +# $FreeBSD$ + +# nameser sources +.PATH: ${.CURDIR}/nameser + +SRCS+= ns_name.c ns_netint.c ns_parse.c ns_print.c ns_samedomain.c ns_ttl.c diff --git a/lib/libc/nameser/Symbol.map b/lib/libc/nameser/Symbol.map new file mode 100644 index 000000000000..82d0f4382774 --- /dev/null +++ b/lib/libc/nameser/Symbol.map @@ -0,0 +1,28 @@ +# $FreeBSD$ + +FBSD_1.0 { + __ns_makecanon; + __ns_msg_getflag; + __ns_name_ntol; + __ns_name_ntop; + __ns_name_pton; + __ns_name_unpack; + __ns_name_pack; + __ns_name_uncompress; + __ns_name_compress; + __ns_name_rollback; + __ns_name_skip; + __ns_get16; + __ns_get32; + __ns_put16; + __ns_put32; + __ns_initparse; + __ns_parserr; + _ns_flagdata; + __ns_samename; + __ns_skiprr; + __ns_sprintrr; + __ns_sprintrrf; + __ns_format_ttl; + __ns_parse_ttl; +}; diff --git a/lib/libc/nameser/ns_print.c b/lib/libc/nameser/ns_print.c index cb61cb1add30..ca595a78e1fc 100644 --- a/lib/libc/nameser/ns_print.c +++ b/lib/libc/nameser/ns_print.c @@ -18,6 +18,8 @@ #ifndef lint static const char rcsid[] = "$Id: ns_print.c,v 1.3.2.1.4.7 2004/09/16 07:01:12 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); /* Import. */ @@ -30,8 +32,13 @@ static const char rcsid[] = "$Id: ns_print.c,v 1.3.2.1.4.7 2004/09/16 07:01:12 m #include <arpa/nameser.h> #include <arpa/inet.h> +#ifdef _LIBC +#include <assert.h> +#define INSIST(cond) assert(cond) +#else #include <isc/assertions.h> #include <isc/dst.h> +#endif #include <errno.h> #include <resolv.h> #include <string.h> @@ -457,7 +464,11 @@ ns_sprintrrf(const u_char *msg, size_t msglen, goto formerr; /* Key flags, Protocol, Algorithm. */ +#ifndef _LIBC key_id = dst_s_dns_key_id(rdata, edata-rdata); +#else + key_id = 0; +#endif keyflags = ns_get16(rdata); rdata += NS_INT16SZ; protocol = *rdata++; algorithm = *rdata++; diff --git a/lib/libc/nameser/ns_samedomain.c b/lib/libc/nameser/ns_samedomain.c index d4ca550a7ae3..21117d82ceee 100644 --- a/lib/libc/nameser/ns_samedomain.c +++ b/lib/libc/nameser/ns_samedomain.c @@ -18,6 +18,8 @@ #ifndef lint static const char rcsid[] = "$Id: ns_samedomain.c,v 1.1.2.2.4.2 2004/03/16 12:34:17 marka Exp $"; #endif +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -28,6 +30,7 @@ static const char rcsid[] = "$Id: ns_samedomain.c,v 1.1.2.2.4.2 2004/03/16 12:34 #include "port_after.h" +#ifndef _LIBC /* * int * ns_samedomain(a, b) @@ -149,6 +152,7 @@ int ns_subdomain(const char *a, const char *b) { return (ns_samename(a, b) != 1 && ns_samedomain(a, b)); } +#endif /* * int diff --git a/lib/libc/resolv/Makefile.inc b/lib/libc/resolv/Makefile.inc new file mode 100644 index 000000000000..8e4366c751cd --- /dev/null +++ b/lib/libc/resolv/Makefile.inc @@ -0,0 +1,7 @@ +# $FreeBSD$ + +# resolv sources +.PATH: ${.CURDIR}/resolv + +SRCS+= herror.c h_errno.c mtctxres.c res_comp.c res_data.c res_debug.c \ + res_init.c res_mkquery.c res_query.c res_send.c res_state.c diff --git a/lib/libc/resolv/Symbol.map b/lib/libc/resolv/Symbol.map new file mode 100644 index 000000000000..3239a2031f1e --- /dev/null +++ b/lib/libc/resolv/Symbol.map @@ -0,0 +1,102 @@ +# $FreeBSD$ + +FBSD_1.0 { + #h_nerr; # Why is this not staticized in net/herror.c? + h_errlist; + herror; + hstrerror; + __dn_expand; + __dn_comp; + __dn_skipname; + __res_hnok; + __res_ownok; + __res_mailok; + __res_dnok; + __putlong; + __putshort; + _getlong; + _getshort; + dn_comp; + dn_expand; + __fp_resstat; + __p_query; + __fp_query; + __fp_nquery; + __p_cdnname; + __p_cdname; + __p_fqnname; + __p_fqname; + __p_cert_syms; + __p_class_syms; + __p_key_syms; + __p_type_syms; + __sym_ston; + __sym_ntos; + __sym_ntop; + __p_rcode; + __p_sockun; + __p_type; + __p_section; + __p_class; + __p_option; + __p_time; + __loc_aton; + __loc_ntoa; + __dn_count_labels; + __p_secstodate; + fp_resstat; + p_query; + p_fqnname; + sym_ston; + sym_ntos; + sym_ntop; + dn_count_labels; + p_secstodate; + __res_init; + __res_randomid; + ___res; + ___res_ext; + __h_errno; + __h_errno_set; + __h_error; + h_errno; + res_init; + __res_mkquery; + res_mkquery; + __res_opt; + __res_freeupdrec; + #__res_get_nibblesuffix; # Excluded + #__res_get_nibblesuffix2; # Excluded + __res_getservers; + __res_hostalias; + __res_nametoclass; + __res_nametotype; + __res_nclose; + __res_ndestroy; + __res_ninit; + __res_nmkquery; + __res_nopt; + __res_nquery; + __res_nquerydomain; + __res_nsearch; + __res_nsend; + __res_ourserver_p; + __res_pquery; + __res_query; + __res_search; + __res_querydomain; + __res_setservers; + __res_state; + __res_vinit; + __hostalias; + res_query; + res_search; + res_querydomain; + __res_isourserver; + __res_nameinquery; + __res_queriesmatch; + __res_send; + __res_close; + _res_close; + res_send; +}; diff --git a/lib/libc/resolv/h_errno.c b/lib/libc/resolv/h_errno.c new file mode 100644 index 000000000000..4d471b49cbc4 --- /dev/null +++ b/lib/libc/resolv/h_errno.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2006 The FreeBSD Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * 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. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> + +#undef h_errno +extern int h_errno; + +int * +__h_errno(void) +{ + return (&__res_state()->res_h_errno); +} + +void +__h_errno_set(res_state res, int err) +{ + h_errno = res->res_h_errno = err; +} + +/* binary backward compatibility for FreeBSD 5.x and 6.x */ +__weak_reference(__h_errno, __h_error); diff --git a/lib/libc/resolv/herror.c b/lib/libc/resolv/herror.c index 58807e9678e0..be4b43ec1d9c 100644 --- a/lib/libc/resolv/herror.c +++ b/lib/libc/resolv/herror.c @@ -52,9 +52,12 @@ static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: herror.c,v 1.2.206.1 2004/03/09 08:33:54 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" +#include "namespace.h" #include <sys/types.h> #include <sys/param.h> #include <sys/uio.h> @@ -66,7 +69,7 @@ static const char rcsid[] = "$Id: herror.c,v 1.2.206.1 2004/03/09 08:33:54 marka #include <resolv.h> #include <string.h> #include <unistd.h> -#include <irs.h> +#include "un-namespace.h" #include "port_after.h" @@ -77,12 +80,10 @@ const char *h_errlist[] = { "Unknown server error", /* 3 NO_RECOVERY */ "No address associated with name", /* 4 NO_ADDRESS */ }; -int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; +const int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; -#if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) #undef h_errno int h_errno; -#endif /* * herror -- @@ -110,7 +111,7 @@ herror(const char *s) { DE_CONST("\n", t); v->iov_base = t; v->iov_len = 1; - writev(STDERR_FILENO, iov, (v - iov) + 1); + _writev(STDERR_FILENO, iov, (v - iov) + 1); } /* diff --git a/lib/libc/resolv/mtctxres.c b/lib/libc/resolv/mtctxres.c index f33cf11e3f42..86b5a79600f0 100644 --- a/lib/libc/resolv/mtctxres.c +++ b/lib/libc/resolv/mtctxres.c @@ -1,13 +1,18 @@ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <port_before.h> #ifdef DO_PTHREADS #include <pthread.h> +#ifdef _LIBC +#include <pthread_np.h> +#endif #endif #include <errno.h> #include <netdb.h> #include <stdlib.h> #include <string.h> #include <resolv_mt.h> -#include <irs.h> #include <port_after.h> #ifdef DO_PTHREADS @@ -40,6 +45,7 @@ _mtctxres_init(void) { } #endif +#ifndef _LIBC /* * To support binaries that used the private MT-safe interface in * Solaris 8, we still need to provide the __res_enable_mt() @@ -54,6 +60,7 @@ int __res_disable_mt(void) { return (0); } +#endif #ifdef DO_PTHREADS static int @@ -99,6 +106,11 @@ ___mtctxres(void) { #ifdef DO_PTHREADS mtctxres_t *mt; +#ifdef _LIBC + if (pthread_main_np() != 0) + return (&sharedctx); +#endif + /* * This if clause should only be executed if we are linking * statically. When linked dynamically _mtctxres_init() should diff --git a/lib/libc/resolv/res_comp.c b/lib/libc/resolv/res_comp.c index 8cc99a762884..cf45f0758450 100644 --- a/lib/libc/resolv/res_comp.c +++ b/lib/libc/resolv/res_comp.c @@ -72,6 +72,8 @@ static const char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: res_comp.c,v 1.1.2.1.4.2 2005/07/28 07:43:22 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" #include <sys/types.h> @@ -261,3 +263,12 @@ 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*/ + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <resolv.h>. + */ +#undef dn_comp +__weak_reference(__dn_comp, dn_comp); +#undef dn_expand +__weak_reference(__dn_expand, dn_expand); diff --git a/lib/libc/resolv/res_data.c b/lib/libc/resolv/res_data.c index 204e03d685f4..a864b6079655 100644 --- a/lib/libc/resolv/res_data.c +++ b/lib/libc/resolv/res_data.c @@ -18,6 +18,8 @@ #if defined(LIBC_SCCS) && !defined(lint) static const char rcsid[] = "$Id: res_data.c,v 1.1.206.2 2004/03/16 12:34:18 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -33,14 +35,15 @@ static const char rcsid[] = "$Id: res_data.c,v 1.1.206.2 2004/03/16 12:34:18 mar #include <ctype.h> #include <netdb.h> #include <resolv.h> +#ifndef _LIBC #include <res_update.h> +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "port_after.h" -#undef _res const char *_res_opcodes[] = { "QUERY", @@ -71,11 +74,6 @@ const char *_res_sectioncodes[] = { #endif #ifndef __BIND_NOSTATIC -struct __res_state _res -# if defined(__BIND_RES_TEXT) - = { RES_TIMEOUT, } /* Motorola, et al. */ -# endif - ; /* Proto. */ @@ -107,7 +105,7 @@ res_init(void) { if (!_res.retrans) _res.retrans = RES_TIMEOUT; if (!_res.retry) - _res.retry = 4; + _res.retry = RES_DFLRETRY; if (!(_res.options & RES_INIT)) _res.options = RES_DEFAULT; @@ -158,6 +156,7 @@ res_mkquery(int op, /* opcode of query */ newrr_in, buf, buflen)); } +#ifndef _LIBC int res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { if ((_res.options & RES_INIT) == 0U && res_init() == -1) { @@ -167,6 +166,7 @@ res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { return (res_nmkupdate(&_res, rrecp_in, buf, buflen)); } +#endif int res_query(const char *name, /* domain name */ @@ -181,6 +181,7 @@ res_query(const char *name, /* domain name */ return (res_nquery(&_res, name, class, type, answer, anslen)); } +#ifndef _LIBC void res_send_setqhook(res_send_qhook hook) { _res.qhook = hook; @@ -190,6 +191,7 @@ void res_send_setrhook(res_send_rhook hook) { _res.rhook = hook; } +#endif int res_isourserver(const struct sockaddr_in *inp) { @@ -206,6 +208,7 @@ res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { return (res_nsend(&_res, buf, buflen, ans, anssiz)); } +#ifndef _LIBC int res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, u_char *ans, int anssiz) @@ -217,12 +220,14 @@ res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz)); } +#endif void res_close(void) { res_nclose(&_res); } +#ifndef _LIBC int res_update(ns_updrec *rrecp_in) { if ((_res.options & RES_INIT) == 0U && res_init() == -1) { @@ -232,6 +237,7 @@ res_update(ns_updrec *rrecp_in) { return (res_nupdate(&_res, rrecp_in, NULL)); } +#endif int res_search(const char *name, /* domain name */ @@ -264,6 +270,12 @@ res_querydomain(const char *name, answer, anslen)); } +int +res_opt(int n0, u_char *buf, int buflen, int anslen) +{ + return (res_nopt(&_res, n0, buf, buflen, anslen)); +} + const char * hostalias(const char *name) { static char abuf[MAXDNAME]; @@ -288,4 +300,25 @@ local_hostname_length(const char *hostname) { } #endif /*ultrix*/ +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <resolv.h>. + */ +#undef res_init +__weak_reference(__res_init, res_init); +#undef p_query +__weak_reference(__p_query, p_query); +#undef res_mkquery +__weak_reference(__res_mkquery, res_mkquery); +#undef res_query +__weak_reference(__res_query, res_query); +#undef res_send +__weak_reference(__res_send, res_send); +#undef res_close +__weak_reference(__res_close, _res_close); +#undef res_search +__weak_reference(__res_search, res_search); +#undef res_querydomain +__weak_reference(__res_querydomain, res_querydomain); + #endif diff --git a/lib/libc/resolv/res_debug.c b/lib/libc/resolv/res_debug.c index 8dda12c5e81c..29c6ef42f8ce 100644 --- a/lib/libc/resolv/res_debug.c +++ b/lib/libc/resolv/res_debug.c @@ -97,6 +97,8 @@ static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: res_debug.c,v 1.3.2.5.4.6 2005/07/28 07:43:22 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -375,7 +377,7 @@ const struct res_sym __p_class_syms[] = { /* * Names of message sections. */ -const struct res_sym __p_default_section_syms[] = { +static const struct res_sym __p_default_section_syms[] = { {ns_s_qd, "QUERY", (char *)0}, {ns_s_an, "ANSWER", (char *)0}, {ns_s_ns, "AUTHORITY", (char *)0}, @@ -383,7 +385,7 @@ const struct res_sym __p_default_section_syms[] = { {0, (char *)0, (char *)0} }; -const struct res_sym __p_update_section_syms[] = { +static const struct res_sym __p_update_section_syms[] = { {S_ZONE, "ZONE", (char *)0}, {S_PREREQ, "PREREQUISITE", (char *)0}, {S_UPDATE, "UPDATE", (char *)0}, @@ -470,7 +472,7 @@ const struct res_sym __p_type_syms[] = { /* * Names of DNS rcodes. */ -const struct res_sym __p_rcode_syms[] = { +static const struct res_sym __p_rcode_syms[] = { {ns_r_noerror, "NOERROR", "no error"}, {ns_r_formerr, "FORMERR", "format error"}, {ns_r_servfail, "SERVFAIL", "server failed"}, @@ -1161,3 +1163,22 @@ res_nametotype(const char *buf, int *successp) { *successp = success; return (result); } + +/* + * Weak aliases for applications that use certain private entry points, + * and fail to include <resolv.h>. + */ +#undef fp_resstat +__weak_reference(__fp_resstat, fp_resstat); +#undef p_fqnname +__weak_reference(__p_fqnname, p_fqnname); +#undef sym_ston +__weak_reference(__sym_ston, sym_ston); +#undef sym_ntos +__weak_reference(__sym_ntos, sym_ntos); +#undef sym_ntop +__weak_reference(__sym_ntop, sym_ntop); +#undef dn_count_labels +__weak_reference(__dn_count_labels, dn_count_labels); +#undef p_secstodate +__weak_reference(__p_secstodate, p_secstodate); diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c index 28a3ebd088e9..30ff9dc42fe2 100644 --- a/lib/libc/resolv/res_init.c +++ b/lib/libc/resolv/res_init.c @@ -72,6 +72,8 @@ static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; static const char rcsid[] = "$Id: res_init.c,v 1.9.2.5.4.5 2005/11/03 00:00:52 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" @@ -106,12 +108,12 @@ static const char rcsid[] = "$Id: res_init.c,v 1.9.2.5.4.5 2005/11/03 00:00:52 m #include <sys/systeminfo.h> #endif -static void res_setoptions __P((res_state, const char *, const char *)); +static void res_setoptions(res_state, const char *, const char *); #ifdef RESOLVSORT static const char sort_mask[] = "/&"; #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) -static u_int32_t net_mask __P((struct in_addr)); +static u_int32_t net_mask(struct in_addr); #endif #if !defined(isascii) /* XXX - could be a function */ @@ -153,9 +155,9 @@ res_ninit(res_state statp) { /* This function has to be reachable by res_data.c but not publically. */ int __res_vinit(res_state statp, int preinit) { - register FILE *fp; - register char *cp, **pp; - register int n; + FILE *fp; + char *cp, **pp; + int n; char buf[BUFSIZ]; int nserv = 0; /* number of nameserver records read from file */ int haveenv = 0; @@ -253,7 +255,7 @@ __res_vinit(res_state statp, int preinit) { #endif /* SOLARIS2 */ /* Allow user to override the local domain definition */ - if ((cp = getenv("LOCALDOMAIN")) != NULL) { + if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) { (void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); statp->defdname[sizeof(statp->defdname) - 1] = '\0'; haveenv++; @@ -390,6 +392,10 @@ __res_vinit(res_state statp, int preinit) { #ifdef RESOLVSORT if (MATCH(buf, "sortlist")) { struct in_addr a; + struct in6_addr a6; + int m, i; + u_char *u; + struct __res_state_ext *ext = statp->_u._ext.ext; cp = buf + sizeof("sortlist") - 1; while (nsort < MAXRESOLVSORT) { @@ -424,6 +430,57 @@ __res_vinit(res_state statp, int preinit) { statp->sort_list[nsort].mask = net_mask(statp->sort_list[nsort].addr); } + ext->sort_list[nsort].af = AF_INET; + ext->sort_list[nsort].addr.ina = + statp->sort_list[nsort].addr; + ext->sort_list[nsort].mask.ina.s_addr = + statp->sort_list[nsort].mask; + nsort++; + } + else if (inet_pton(AF_INET6, net, &a6) == 1) { + + ext->sort_list[nsort].af = AF_INET6; + ext->sort_list[nsort].addr.in6a = a6; + u = (u_char *)&ext->sort_list[nsort].mask.in6a; + *cp++ = n; + net = cp; + while (*cp && *cp != ';' && + isascii(*cp) && !isspace(*cp)) + cp++; + m = n; + n = *cp; + *cp = 0; + switch (m) { + case '/': + m = atoi(net); + break; + case '&': + if (inet_pton(AF_INET6, net, u) == 1) { + m = -1; + break; + } + /*FALLTHROUGH*/ + default: + m = sizeof(struct in6_addr) * CHAR_BIT; + break; + } + if (m >= 0) { + for (i = 0; i < sizeof(struct in6_addr); i++) { + if (m <= 0) { + *u = 0; + } else { + m -= CHAR_BIT; + *u = (u_char)~0; + if (m < 0) + *u <<= -m; + } + u++; + } + } + statp->sort_list[nsort].addr.s_addr = + (u_int32_t)0xffffffff; + statp->sort_list[nsort].mask = + (u_int32_t)0xffffffff; nsort++; } *cp = n; @@ -486,7 +543,9 @@ __res_vinit(res_state statp, int preinit) { #endif } - if ((cp = getenv("RES_OPTIONS")) != NULL) + if (issetugid()) + statp->options |= RES_NOALIASES; + else if ((cp = getenv("RES_OPTIONS")) != NULL) res_setoptions(statp, cp, "env"); statp->options |= RES_INIT; return (0); @@ -506,7 +565,9 @@ res_setoptions(res_state statp, const char *options, const char *source) { const char *cp = options; int i; +#ifndef _LIBC struct __res_state_ext *ext = statp->_u._ext.ext; +#endif #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -580,6 +641,10 @@ res_setoptions(res_state statp, const char *options, const char *source) statp->options |= RES_NOTLDQUERY; } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { statp->options |= RES_USE_INET6; + } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) { + statp->options |= RES_INSECURE1; + } else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) { + statp->options |= RES_INSECURE2; } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) { statp->options |= RES_ROTATE; } else if (!strncmp(cp, "no-check-names", @@ -591,6 +656,7 @@ res_setoptions(res_state statp, const char *options, const char *source) statp->options |= RES_USE_EDNS0; } #endif +#ifndef _LIBC else if (!strncmp(cp, "dname", sizeof("dname") - 1)) { statp->options |= RES_USE_DNAME; } @@ -620,10 +686,13 @@ res_setoptions(res_state statp, const char *options, const char *source) ~RES_NO_NIBBLE2; } } +#endif else { /* XXX - print a warning here? */ } +#ifndef _LIBC skip: +#endif /* skip to next run of spaces */ while (*cp && *cp != ' ' && *cp != '\t') cp++; @@ -636,7 +705,7 @@ static u_int32_t net_mask(in) /* XXX - should really use system's version of this */ struct in_addr in; { - register u_int32_t i = ntohl(in.s_addr); + u_int32_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return (htonl(IN_CLASSA_NET)); @@ -687,6 +756,7 @@ res_ndestroy(res_state statp) { statp->_u._ext.ext = NULL; } +#ifndef _LIBC const char * res_get_nibblesuffix(res_state statp) { if (statp->_u._ext.ext) @@ -700,6 +770,7 @@ res_get_nibblesuffix2(res_state statp) { return (statp->_u._ext.ext->nsuffix2); return ("ip6.int"); } +#endif void res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) { diff --git a/lib/libc/resolv/res_mkquery.c b/lib/libc/resolv/res_mkquery.c index 89000edf6ad4..60f1efc19e3f 100644 --- a/lib/libc/resolv/res_mkquery.c +++ b/lib/libc/resolv/res_mkquery.c @@ -72,6 +72,8 @@ static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: res_mkquery.c,v 1.1.2.2.4.2 2004/03/16 12:34:18 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" #include <sys/types.h> @@ -104,9 +106,9 @@ res_nmkquery(res_state statp, u_char *buf, /* buffer to put query */ int buflen) /* size of buffer */ { - register HEADER *hp; - register u_char *cp, *ep; - register int n; + HEADER *hp; + u_char *cp, *ep; + int n; u_char *dnptrs[20], **dpp, **lastdnptr; UNUSED(newrr_in); @@ -214,8 +216,8 @@ res_nopt(res_state statp, int buflen, /* size of buffer */ int anslen) /* UDP answer buffer size */ { - register HEADER *hp; - register u_char *cp, *ep; + HEADER *hp; + u_char *cp, *ep; u_int16_t flags = 0; #ifdef DEBUG @@ -234,6 +236,8 @@ res_nopt(res_state statp, ns_put16(T_OPT, cp); /* TYPE */ cp += INT16SZ; + if (anslen > 0xffff) + anslen = 0xffff; /* limit to 16bit value */ ns_put16(anslen & 0xffff, cp); /* CLASS = UDP payload size */ cp += INT16SZ; *cp++ = NOERROR; /* extended RCODE */ diff --git a/lib/libc/resolv/res_query.c b/lib/libc/resolv/res_query.c index 5156ce84c086..cb21ac6d3fc5 100644 --- a/lib/libc/resolv/res_query.c +++ b/lib/libc/resolv/res_query.c @@ -72,6 +72,8 @@ static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: res_query.c,v 1.2.2.3.4.2 2004/03/16 12:34:19 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include "port_before.h" #include <sys/types.h> @@ -86,6 +88,7 @@ static const char rcsid[] = "$Id: res_query.c,v 1.2.2.3.4.2 2004/03/16 12:34:19 #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "port_after.h" /* Options. Leave them on. */ @@ -209,7 +212,6 @@ res_nsearch(res_state statp, int anslen) /* size of answer */ { const char *cp, * const *domain; - HEADER *hp = (HEADER *) answer; char tmp[NS_MAXDNAME]; u_int dots; int trailing_dot, ret, saved_herrno; @@ -242,6 +244,17 @@ res_nsearch(res_state statp, answer, anslen); if (ret > 0 || trailing_dot) return (ret); + if (errno == ECONNREFUSED) { + RES_SET_H_ERRNO(statp, TRY_AGAIN); + return (-1); + } + switch (statp->res_h_errno) { + case NO_DATA: + case HOST_NOT_FOUND: + break; + default: + return (-1); + } saved_herrno = statp->res_h_errno; tried_as_is++; } @@ -265,6 +278,9 @@ res_nsearch(res_state statp, (domain[0][0] == '.' && domain[0][1] == '\0')) root_on_list++; + if (root_on_list && tried_as_is) + continue; + ret = res_nquerydomain(statp, name, *domain, class, type, answer, anslen); @@ -297,11 +313,24 @@ res_nsearch(res_state statp, /* keep trying */ break; case TRY_AGAIN: - if (hp->rcode == SERVFAIL) { - /* try next search element, if any */ - got_servfail++; - break; - } + /* + * This can occur due to a server failure + * (that is, all listed servers have failed), + * or all listed servers have timed out. + * ((HEADER *)answer)->rcode may not be set + * to SERVFAIL in the case of a timeout. + * + * Either way we must terminate the search + * and return TRY_AGAIN in order to avoid + * non-deterministic return codes. For + * example, loaded name servers or races + * against network startup/validation (dhcp, + * ppp, etc) can cause the search to timeout + * on one search element, e.g. 'fu.bar.com', + * and return a definitive failure on the + * next search element, e.g. 'fu.'. + */ + got_servfail++; /* FALLTHROUGH */ default: /* anything else implies that we're done */ @@ -316,6 +345,14 @@ res_nsearch(res_state statp, } } + switch (statp->res_h_errno) { + case NO_DATA: + case HOST_NOT_FOUND: + break; + default: + goto giveup; + } + /* * If the query has not already been tried as is then try it * unless RES_NOTLDQUERY is set and there were no dots. @@ -335,6 +372,7 @@ res_nsearch(res_state statp, * else send back meaningless H_ERRNO, that being the one from * the last DNSRCH we did. */ +giveup: if (saved_herrno != -1) RES_SET_H_ERRNO(statp, saved_herrno); else if (got_nodata) @@ -401,6 +439,8 @@ res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { if (statp->options & RES_NOALIASES) return (NULL); + if (issetugid()) + return (NULL); file = getenv("HOSTALIASES"); if (file == NULL || (fp = fopen(file, "r")) == NULL) return (NULL); diff --git a/lib/libc/resolv/res_send.c b/lib/libc/resolv/res_send.c index 5be248932596..f31abf1327eb 100644 --- a/lib/libc/resolv/res_send.c +++ b/lib/libc/resolv/res_send.c @@ -72,14 +72,19 @@ static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: res_send.c,v 1.5.2.2.4.7 2005/08/15 02:04:41 marka Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); /* * Send query to name server and wait for reply. */ #include "port_before.h" +#ifndef USE_KQUEUE #include "fd_setsize.h" +#endif +#include "namespace.h" #include <sys/types.h> #include <sys/param.h> #include <sys/time.h> @@ -103,12 +108,18 @@ static const char rcsid[] = "$Id: res_send.c,v 1.5.2.2.4.7 2005/08/15 02:04:41 m #include "port_after.h" +#ifdef USE_KQUEUE +#include <sys/event.h> +#else #ifdef USE_POLL #ifdef HAVE_STROPTS_H #include <stropts.h> #endif #include <poll.h> #endif /* USE_POLL */ +#endif + +#include "un-namespace.h" /* Options. Leave them on. */ #define DEBUG @@ -125,18 +136,22 @@ static int highestFD = 0; /* Forward. */ -static int get_salen __P((const struct sockaddr *)); -static struct sockaddr * get_nsaddr __P((res_state, size_t)); +static int get_salen(const struct sockaddr *); +static struct sockaddr * get_nsaddr(res_state, size_t); 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, +static int send_dg(res_state, +#ifdef USE_KQUEUE + int kq, +#endif + const u_char *, int, u_char *, int, int *, int, int *, int *); static void Aerror(const res_state, FILE *, const char *, int, const struct sockaddr *, int); static void Perror(const res_state, FILE *, const char *, int); static int sock_eq(struct sockaddr *, struct sockaddr *); -#if defined(NEED_PSELECT) && !defined(USE_POLL) +#if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE) static int pselect(int, void *, void *, void *, struct timespec *, const sigset_t *); @@ -289,6 +304,9 @@ res_nsend(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz) { int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; +#ifdef USE_KQUEUE + int kq; +#endif char abuf[NI_MAXHOST]; #ifdef USE_POLL @@ -309,6 +327,13 @@ res_nsend(res_state statp, gotsomewhere = 0; terrno = ETIMEDOUT; +#ifdef USE_KQUEUE + if ((kq = kqueue()) < 0) { + Perror(statp, stderr, "kqueue", errno); + return (-1); + } +#endif + /* * If the ns_addr_list in the resolver context has changed, then * invalidate our cached copy and the associated timing data. @@ -332,7 +357,7 @@ res_nsend(res_state statp, if (EXT(statp).nssocks[ns] == -1) continue; peerlen = sizeof(peer); - if (getsockname(EXT(statp).nssocks[ns], + if (_getsockname(EXT(statp).nssocks[ns], (struct sockaddr *)&peer, &peerlen) < 0) { needclose++; break; @@ -424,6 +449,9 @@ res_nsend(res_state statp, res_nclose(statp); goto next_ns; case res_done: +#ifdef USE_KQUEUE + _close(kq); +#endif return (resplen); case res_modified: /* give the hook another try */ @@ -457,7 +485,11 @@ res_nsend(res_state statp, resplen = n; } else { /* Use datagrams. */ - n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, + n = send_dg(statp, +#ifdef USE_KQUEUE + kq, +#endif + buf, buflen, ans, anssiz, &terrno, ns, &v_circuit, &gotsomewhere); if (n < 0) goto fail; @@ -516,11 +548,17 @@ res_nsend(res_state statp, } while (!done); } +#ifdef USE_KQUEUE + _close(kq); +#endif return (resplen); next_ns: ; } /*foreach ns*/ } /*foreach retry*/ res_nclose(statp); +#ifdef USE_KQUEUE + _close(kq); +#endif if (!v_circuit) { if (!gotsomewhere) errno = ECONNREFUSED; /* no nameservers found */ @@ -531,6 +569,9 @@ res_nsend(res_state statp, return (-1); fail: res_nclose(statp); +#ifdef USE_KQUEUE + _close(kq); +#endif return (-1); } @@ -608,7 +649,7 @@ send_vc(res_state statp, struct sockaddr_storage peer; ISC_SOCKLEN_T size = sizeof peer; - if (getpeername(statp->_vcsock, + if (_getpeername(statp->_vcsock, (struct sockaddr *)&peer, &size) < 0 || !sock_eq((struct sockaddr *)&peer, nsap)) { res_nclose(statp); @@ -620,7 +661,7 @@ send_vc(res_state statp, if (statp->_vcsock >= 0) res_nclose(statp); - statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); + statp->_vcsock = _socket(nsap->sa_family, SOCK_STREAM, 0); if (statp->_vcsock > highestFD) { res_nclose(statp); errno = ENOTSOCK; @@ -641,7 +682,7 @@ send_vc(res_state statp, } } errno = 0; - if (connect(statp->_vcsock, nsap, nsaplen) < 0) { + if (_connect(statp->_vcsock, nsap, nsaplen) < 0) { *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, nsap, nsaplen); @@ -658,7 +699,7 @@ send_vc(res_state statp, iov[0] = evConsIovec(&len, INT16SZ); DE_CONST(buf, tmp); iov[1] = evConsIovec(tmp, buflen); - if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { + if (_writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); res_nclose(statp); @@ -670,7 +711,7 @@ send_vc(res_state statp, read_len: cp = ans; len = INT16SZ; - while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) { + while ((n = _read(statp->_vcsock, (char *)cp, (int)len)) > 0) { cp += n; if ((len -= n) == 0) break; @@ -716,7 +757,8 @@ send_vc(res_state statp, return (0); } cp = ans; - while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){ + while (len != 0 && + (n = _read(statp->_vcsock, (char *)cp, (int)len)) > 0) { cp += n; len -= n; } @@ -735,8 +777,8 @@ send_vc(res_state statp, while (len != 0) { char junk[PACKETSZ]; - n = read(statp->_vcsock, junk, - (len > sizeof junk) ? sizeof junk : len); + n = _read(statp->_vcsock, junk, + (len > sizeof junk) ? sizeof junk : len); if (n > 0) len -= n; else @@ -767,6 +809,9 @@ send_vc(res_state statp, static int send_dg(res_state statp, +#ifdef USE_KQUEUE + int kq, +#endif const u_char *buf, int buflen, u_char *ans, int anssiz, int *terrno, int ns, int *v_circuit, int *gotsomewhere) { @@ -778,17 +823,22 @@ send_dg(res_state statp, struct sockaddr_storage from; ISC_SOCKLEN_T fromlen; int resplen, seconds, n, s; +#ifdef USE_KQUEUE + struct kevent kv; +#else #ifdef USE_POLL int polltimeout; struct pollfd pollfd; #else fd_set dsmask; #endif +#endif nsap = get_nsaddr(statp, ns); nsaplen = get_salen(nsap); if (EXT(statp).nssocks[ns] == -1) { - EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); + EXT(statp).nssocks[ns] = _socket(nsap->sa_family, + SOCK_DGRAM, 0); if (EXT(statp).nssocks[ns] > highestFD) { res_nclose(statp); errno = ENOTSOCK; @@ -819,8 +869,16 @@ send_dg(res_state statp, * socket operation, and select returns if the * error message is received. We can thus detect * the absence of a nameserver without timing out. + * + * When the option "insecure1" is specified, we'd + * rather expect to see responses from an "unknown" + * address. In order to let the kernel accept such + * responses, do not connect the socket here. + * XXX: or do we need an explicit option to disable + * connecting? */ - if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) { + if (!(statp->options & RES_INSECURE1) && + _connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) { Aerror(statp, stderr, "connect(dg)", errno, nsap, nsaplen); res_nclose(statp); @@ -832,13 +890,20 @@ send_dg(res_state statp, } s = EXT(statp).nssocks[ns]; #ifndef CANNOT_CONNECT_DGRAM - if (send(s, (const char*)buf, buflen, 0) != buflen) { + if (statp->options & RES_INSECURE1) { + if (_sendto(s, + (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) { + Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); + res_nclose(statp); + return (0); + } + } else if (send(s, (const char*)buf, buflen, 0) != buflen) { Perror(statp, stderr, "send", errno); res_nclose(statp); return (0); } #else /* !CANNOT_CONNECT_DGRAM */ - if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) + if (_sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) { Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); res_nclose(statp); @@ -862,13 +927,18 @@ send_dg(res_state statp, now = evNowTime(); nonow: #ifndef USE_POLL - FD_ZERO(&dsmask); - FD_SET(s, &dsmask); if (evCmpTime(finish, now) > 0) timeout = evSubTime(finish, now); else timeout = evConsTime(0, 0); +#ifdef USE_KQUEUE + EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0); + n = _kevent(kq, &kv, 1, &kv, 1, &timeout); +#else + FD_ZERO(&dsmask); + FD_SET(s, &dsmask); n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL); +#endif #else timeout = evSubTime(finish, now); if (timeout.tv_sec < 0) @@ -888,17 +958,21 @@ send_dg(res_state statp, if (n < 0) { if (errno == EINTR) goto wait; +#ifdef USE_KQUEUE + Perror(statp, stderr, "kevent", errno); +#else #ifndef USE_POLL Perror(statp, stderr, "select", errno); #else Perror(statp, stderr, "poll", errno); #endif /* USE_POLL */ +#endif res_nclose(statp); return (0); } errno = 0; fromlen = sizeof(from); - resplen = recvfrom(s, (char*)ans, anssiz,0, + resplen = _recvfrom(s, (char*)ans, anssiz,0, (struct sockaddr *)&from, &fromlen); if (resplen <= 0) { Perror(statp, stderr, "recvfrom", errno); @@ -1061,7 +1135,7 @@ sock_eq(struct sockaddr *a, struct sockaddr *b) { } } -#if defined(NEED_PSELECT) && !defined(USE_POLL) +#if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE) /* XXX needs to move to the porting library. */ static int pselect(int nfds, void *rfds, void *wfds, void *efds, diff --git a/lib/libc/resolv/res_state.c b/lib/libc/resolv/res_state.c new file mode 100644 index 000000000000..542dba824055 --- /dev/null +++ b/lib/libc/resolv/res_state.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2006 The FreeBSD Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * 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. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <stdlib.h> + +#include "namespace.h" +#include "reentrant.h" +#include "un-namespace.h" + +#undef _res + +struct __res_state _res; + +static thread_key_t res_key; +static once_t res_init_once = ONCE_INITIALIZER; +static int res_thr_keycreated = 0; + +static void +free_res(void *ptr) +{ + res_state statp = ptr; + + if (statp->options & RES_INIT) + res_ndestroy(statp); + free(statp); +} + +static void +res_keycreate(void) +{ + res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0; +} + +res_state +__res_state(void) +{ + res_state statp; + + if (thr_main() != 0) + return (&_res); + + if (thr_once(&res_init_once, res_keycreate) != 0 || + !res_thr_keycreated) + return (&_res); + + statp = thr_getspecific(res_key); + if (statp != NULL) + return (statp); + statp = calloc(1, sizeof(*statp)); + if (statp == NULL) + return (&_res); +#ifdef __BIND_RES_TEXT + statp->options = RES_TIMEOUT; /* Motorola, et al. */ +#endif + if (thr_setspecific(res_key, statp) == 0) + return (statp); + free(statp); + return (&_res); +} + +/* binary backward compatibility for FreeBSD 5.x and 6.x */ +struct __res_state_ext * +___res_ext(void) +{ + return (__res_state()->_u._ext.ext); +} + +__weak_reference(__res_state, ___res); |