summaryrefslogtreecommitdiff
path: root/usr/src/lib/libresolv2/common/resolv/res_init.c
diff options
context:
space:
mode:
authorRao Shoaib <Rao.Shoaib@Sun.COM>2009-11-11 08:45:41 -0800
committerRao Shoaib <Rao.Shoaib@Sun.COM>2009-11-11 08:45:41 -0800
commit9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829 (patch)
treedf51891a276edf456c1481f49653a76cdfedee53 /usr/src/lib/libresolv2/common/resolv/res_init.c
parent0324f02a004039d6377111191fdd7134452d7817 (diff)
downloadillumos-joyent-9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829.tar.gz
6289479 libresolv2 clean up and alignment with libbind.6.0
Diffstat (limited to 'usr/src/lib/libresolv2/common/resolv/res_init.c')
-rw-r--r--usr/src/lib/libresolv2/common/resolv/res_init.c220
1 files changed, 143 insertions, 77 deletions
diff --git a/usr/src/lib/libresolv2/common/resolv/res_init.c b/usr/src/lib/libresolv2/common/resolv/res_init.c
index 33ccc9ece7..e839323a79 100644
--- a/usr/src/lib/libresolv2/common/resolv/res_init.c
+++ b/usr/src/lib/libresolv2/common/resolv/res_init.c
@@ -1,8 +1,9 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+
/*
* Copyright (c) 1985, 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -57,27 +58,25 @@
*/
/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static const char rcsid[] = "$Id: res_init.c,v 8.32 2003/04/03 06:31:10 marka Exp $";
+static const char rcsid[] = "$Id: res_init.c,v 1.26 2008/12/11 09:59:00 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -98,14 +97,30 @@ static const char rcsid[] = "$Id: res_init.c,v 8.32 2003/04/03 06:31:10 marka Ex
#include <unistd.h>
#include <netdb.h>
+#ifndef HAVE_MD5
+# include "../dst/md5.h"
+#else
+# ifdef SOLARIS2
+# include <sys/md5.h>
+# endif
+#endif
+#ifndef _MD5_H_
+# define _MD5_H_ 1 /*%< make sure we do not include rsaref md5.h file */
+#endif
+
+
#include "port_after.h"
/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
#include <resolv.h>
+/* ISC purposely put port_after.h before <resolv.h> to force in6 stuff
+ * (above) so we explicitly include port_resolv.h here */
+#include "port_resolv.h"
+
#include "res_private.h"
-/* Options. Should all be left alone. */
+/*% Options. Should all be left alone. */
#define RESOLVSORT
#define DEBUG
@@ -116,15 +131,9 @@ static const char rcsid[] = "$Id: res_init.c,v 8.32 2003/04/03 06:31:10 marka Ex
#define MAXIFS 8192
#endif /* SUNW_INITCHKIF */
-#ifdef SUNW_DOMAINFROMNIS
+#ifdef SOLARIS2
#include <sys/systeminfo.h>
-#include <string.h>
-#endif /* SUNW_DOMAINFROMNIS */
-
-#ifdef ORIGINAL_ISC_CODE
-#else
-#pragma weak __res_randomid = res_randomid
-#endif /* ORIGINAL_ISC_CODE */
+#endif
static void res_setoptions __P((res_state, const char *, const char *));
@@ -134,7 +143,7 @@ static const char sort_mask[] = "/&";
static u_int32_t net_mask __P((struct in_addr));
#endif
-#if !defined(isascii) /* XXX - could be a function */
+#if !defined(isascii) /*%< XXX - could be a function */
# define isascii(c) (!(c & 0200))
#endif
@@ -142,7 +151,7 @@ static u_int32_t net_mask __P((struct in_addr));
* Resolver state default settings.
*/
-/*
+/*%
* Set up default settings. If the configuration file exist, the values
* there will have precedence. Otherwise, the server address is set to
* INADDR_ANY and the default domain name comes from the gethostname().
@@ -166,18 +175,17 @@ static u_int32_t net_mask __P((struct in_addr));
int
res_ninit(res_state statp) {
extern int __res_vinit(res_state, int);
-
return (__res_vinit(statp, 0));
}
-/* This function has to be reachable by res_data.c but not publically. */
+/*% 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;
char buf[BUFSIZ];
- int nserv = 0; /* number of nameserver records read from file */
+ int nserv = 0; /*%< number of nameserver records read from file */
int haveenv = 0;
int havesearch = 0;
#ifdef RESOLVSORT
@@ -186,7 +194,9 @@ __res_vinit(res_state statp, int preinit) {
#endif
int dots;
union res_sockaddr_union u[2];
+ int maxns = MAXNS;
+ RES_SET_H_ERRNO(statp, 0);
if (statp->_u._ext.ext != NULL)
res_ndestroy(statp);
@@ -194,7 +204,8 @@ __res_vinit(res_state statp, int preinit) {
statp->retrans = RES_TIMEOUT;
statp->retry = RES_DFLRETRY;
statp->options = RES_DEFAULT;
- statp->id = res_randomid();
+ res_rndinit(statp);
+ statp->id = res_nrandomid(statp);
}
memset(u, 0, sizeof(u));
@@ -236,8 +247,22 @@ __res_vinit(res_state statp, int preinit) {
statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
- } else
- return (-1);
+ } else {
+ /*
+ * Historically res_init() rarely, if at all, failed.
+ * Examples and applications exist which do not check
+ * our return code. Furthermore several applications
+ * simply call us to get the systems domainname. So
+ * rather then immediately fail here we store the
+ * failure, which is returned later, in h_errno. And
+ * prevent the collection of 'nameserver' information
+ * by setting maxns to 0. Thus applications that fail
+ * to check our return code wont be able to make
+ * queries anyhow.
+ */
+ RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
+ maxns = 0;
+ }
#ifdef RESOLVSORT
statp->nsort = 0;
#endif
@@ -328,25 +353,27 @@ __res_vinit(res_state statp, int preinit) {
}
#endif /* SUNW_INITCHKIF */
-#ifdef SUNW_DOMAINFROMNIS
-/*
- * The old (4.8.3) libresolv derived the default domainname from NIS/NIS+.
- */
- {
- char buf[sizeof(statp->defdname)], *cp;
- int ret;
- if ((ret = sysinfo(SI_SRPC_DOMAIN, buf, sizeof(buf))) > 0 &&
- ret <= sizeof(buf)) {
- if (buf[0] == '+')
- buf[0] = '.';
- cp = strchr(buf, '.');
- if (cp == 0)
- strcpy(statp->defdname, buf);
- else
- strcpy(statp->defdname, cp+1);
- }
- }
-#endif /* SUNW_DOMAINFROMNIS */
+#ifdef SOLARIS2
+ /*
+ * The old libresolv derived the defaultdomain from NIS/NIS+.
+ * We want to keep this behaviour
+ */
+ {
+ char buf[sizeof(statp->defdname)], *cp;
+ int ret;
+
+ if ((ret = sysinfo(SI_SRPC_DOMAIN, buf, sizeof(buf))) > 0 &&
+ (unsigned int)ret <= sizeof(buf)) {
+ if (buf[0] == '+')
+ buf[0] = '.';
+ cp = strchr(buf, '.');
+ cp = (cp == NULL) ? buf : (cp + 1);
+ strncpy(statp->defdname, cp,
+ sizeof(statp->defdname) - 1);
+ statp->defdname[sizeof(statp->defdname) - 1] = '\0';
+ }
+ }
+#endif /* SOLARIS2 */
/* Allow user to override the local domain definition */
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
@@ -365,7 +392,7 @@ __res_vinit(res_state statp, int preinit) {
pp = statp->dnsrch;
*pp++ = cp;
for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
- if (*cp == '\n') /* silly backwards compat */
+ if (*cp == '\n') /*%< silly backwards compat */
break;
else if (*cp == ' ' || *cp == '\t') {
*cp = 0;
@@ -389,12 +416,7 @@ __res_vinit(res_state statp, int preinit) {
line[sizeof(name) - 1] == '\t'))
nserv = 0;
-
-#ifdef SUNW_AVOIDSTDIO_FDLIMIT
- if ((fp = fopen(_PATH_RESCONF, "rF")) != NULL) {
-#else
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
-#endif
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
@@ -402,7 +424,7 @@ __res_vinit(res_state statp, int preinit) {
continue;
/* read default domain name */
if (MATCH(buf, "domain")) {
- if (haveenv) /* skip if have from environ */
+ if (haveenv) /*%< skip if have from environ */
continue;
cp = buf + sizeof("domain") - 1;
while (*cp == ' ' || *cp == '\t')
@@ -418,7 +440,7 @@ __res_vinit(res_state statp, int preinit) {
}
/* set search list */
if (MATCH(buf, "search")) {
- if (haveenv) /* skip if have from environ */
+ if (haveenv) /*%< skip if have from environ */
continue;
cp = buf + sizeof("search") - 1;
while (*cp == ' ' || *cp == '\t')
@@ -454,7 +476,7 @@ __res_vinit(res_state statp, int preinit) {
continue;
}
/* read nameservers to query */
- if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+ if (MATCH(buf, "nameserver") && nserv < maxns) {
struct addrinfo hints, *ai;
char sbuf[NI_MAXSERV];
const size_t minsiz =
@@ -542,7 +564,7 @@ __res_vinit(res_state statp, int preinit) {
#ifdef RESOLVSORT
statp->nsort = nsort;
#endif
- (void) fclose(fp);
+ (void) fclose(fp);
}
/*
* Last chance to get a nameserver. This should not normally
@@ -572,7 +594,7 @@ __res_vinit(res_state statp, int preinit) {
while (pp < statp->dnsrch + MAXDFLSRCH) {
if (dots < LOCALDOMAINPARTS)
break;
- cp = strchr(cp, '.') + 1; /* we know there is one */
+ cp = strchr(cp, '.') + 1; /*%< we know there is one */
*pp++ = cp;
dots--;
}
@@ -590,7 +612,7 @@ __res_vinit(res_state statp, int preinit) {
if ((cp = getenv("RES_OPTIONS")) != NULL)
res_setoptions(statp, cp, "env");
statp->options |= RES_INIT;
- return (0);
+ return (statp->res_h_errno);
#ifdef SUNW_INITCHKIF
freedata:
if (statp->_u._ext.ext != NULL) {
@@ -599,6 +621,7 @@ freedata:
}
return (-1);
#endif /* SUNW_INITCHKIF */
+
}
static void
@@ -634,20 +657,17 @@ res_setoptions(res_state statp, const char *options, const char *source)
statp->retrans = i;
else
statp->retrans = RES_MAXRETRANS;
- } else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
- i = atoi(cp + sizeof("attempts:") - 1);
- if (i <= RES_MAXRETRY)
- statp->retry = i;
- else
- statp->retry = RES_MAXRETRY;
-#ifdef ORIGINAL_ISC_CODE
-#else
+#ifdef DEBUG
+ if (statp->options & RES_DEBUG)
+ printf(";;\ttimeout=%d\n", statp->retrans);
+#endif
+#ifdef SOLARIS2
} else if (!strncmp(cp, "retrans:", sizeof("retrans:") - 1)) {
/*
- * For backward compatibility, 'retrans' is
- * supported as an alias for 'timeout', though
- * without an imposed maximum.
- */
+ * For backward compatibility, 'retrans' is
+ * supported as an alias for 'timeout', though
+ * without an imposed maximum.
+ */
statp->retrans = atoi(cp + sizeof("retrans:") - 1);
} else if (!strncmp(cp, "retry:", sizeof("retry:") - 1)){
/*
@@ -656,7 +676,17 @@ res_setoptions(res_state statp, const char *options, const char *source)
* without an imposed maximum.
*/
statp->retry = atoi(cp + sizeof("retry:") - 1);
-#endif /* ORIGINAL_ISC_CODE */
+#endif /* SOLARIS2 */
+ } else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
+ i = atoi(cp + sizeof("attempts:") - 1);
+ if (i <= RES_MAXRETRY)
+ statp->retry = i;
+ else
+ statp->retry = RES_MAXRETRY;
+#ifdef DEBUG
+ if (statp->options & RES_DEBUG)
+ printf(";;\tattempts=%d\n", statp->retry);
+#endif
} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
#ifdef DEBUG
if (!(statp->options & RES_DEBUG)) {
@@ -726,7 +756,7 @@ res_setoptions(res_state statp, const char *options, const char *source)
#ifdef RESOLVSORT
/* XXX - should really support CIDR which means explicit masks always. */
static u_int32_t
-net_mask(in) /* XXX - should really use system's version of this */
+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);
@@ -739,15 +769,49 @@ net_mask(in) /* XXX - should really use system's version of this */
}
#endif
+void
+res_rndinit(res_state statp)
+{
+ struct timeval now;
+ u_int32_t u32;
+ u_int16_t u16;
+
+ gettimeofday(&now, NULL);
+ u32 = now.tv_sec;
+ memcpy(statp->_u._ext._rnd, &u32, 4);
+ u32 = now.tv_usec;
+ memcpy(statp->_u._ext._rnd + 4, &u32, 4);
+ u32 += now.tv_sec;
+ memcpy(statp->_u._ext._rnd + 8, &u32, 4);
+ u16 = getpid();
+ memcpy(statp->_u._ext._rnd + 12, &u16, 2);
+
+}
+
u_int
-res_randomid(void) {
+res_nrandomid(res_state statp) {
struct timeval now;
+ u_int16_t u16;
+ MD5_CTX ctx;
gettimeofday(&now, NULL);
- return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+ u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec);
+
+ memcpy(statp->_u._ext._rnd + 14, &u16, 2);
+#ifndef HAVE_MD5
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, statp->_u._ext._rnd, 16);
+ MD5_Final(statp->_u._ext._rnd, &ctx);
+#else
+ MD5Init(&ctx);
+ MD5Update(&ctx, statp->_u._ext._rnd, 16);
+ MD5Final(statp->_u._ext._rnd, &ctx);
+#endif
+ memcpy(&u16, statp->_u._ext._rnd + 14, 2);
+ return ((u_int) u16);
}
-/*
+/*%
* 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.
@@ -890,3 +954,5 @@ res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) {
}
return (statp->nscount);
}
+
+/*! \file */