summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/resolv/res_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/lib/resolv/res_init.c')
-rw-r--r--contrib/bind/lib/resolv/res_init.c237
1 files changed, 222 insertions, 15 deletions
diff --git a/contrib/bind/lib/resolv/res_init.c b/contrib/bind/lib/resolv/res_init.c
index 8c63351..8dc72f4 100644
--- a/contrib/bind/lib/resolv/res_init.c
+++ b/contrib/bind/lib/resolv/res_init.c
@@ -70,7 +70,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: res_init.c,v 8.19 2001/03/08 03:57:16 marka Exp $";
+static const char rcsid[] = "$Id: res_init.c,v 8.28 2002/01/30 01:07:35 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -85,14 +85,19 @@ static const char rcsid[] = "$Id: res_init.c,v 8.19 2001/03/08 03:57:16 marka Ex
#include <arpa/nameser.h>
#include <ctype.h>
-#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <netdb.h>
#include "port_after.h"
+/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
+#include <resolv.h>
+
+#include "res_private.h"
+
/* Options. Should all be left alone. */
#define RESOLVSORT
#define DEBUG
@@ -164,6 +169,9 @@ __res_vinit(res_state statp, int preinit) {
statp->id = res_randomid();
}
+ if ((statp->options & RES_INIT) != 0)
+ res_ndestroy(statp);
+
#ifdef USELOOPBACK
statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
@@ -171,6 +179,9 @@ __res_vinit(res_state statp, int preinit) {
#endif
statp->nsaddr.sin_family = AF_INET;
statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
+#ifdef HAVE_SA_LEN
+ statp->nsaddr.sin_len = sizeof(struct sockaddr_in);
+#endif
statp->nscount = 1;
statp->ndots = 1;
statp->pfcode = 0;
@@ -179,6 +190,13 @@ __res_vinit(res_state statp, int preinit) {
statp->qhook = NULL;
statp->rhook = NULL;
statp->_u._ext.nscount = 0;
+ statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
+ if (statp->_u._ext.ext != NULL) {
+ memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
+ statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
+ strcpy(statp->_u._ext.ext->nsuffix, "ip6.int");
+ strcpy(statp->_u._ext.ext->bsuffix, "ip6.arpa");
+ }
#ifdef RESOLVSORT
statp->nsort = 0;
#endif
@@ -284,17 +302,36 @@ __res_vinit(res_state statp, int preinit) {
}
/* read nameservers to query */
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
- struct in_addr a;
+ struct addrinfo hints, *ai;
+ char sbuf[NI_MAXSERV];
+ const size_t minsiz =
+ sizeof(statp->_u._ext.ext->nsaddrs[0]);
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
- if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
- statp->nsaddr_list[nserv].sin_addr = a;
- statp->nsaddr_list[nserv].sin_family = AF_INET;
- statp->nsaddr_list[nserv].sin_port =
- htons(NAMESERVER_PORT);
- nserv++;
+ cp[strcspn(cp, ";# \t\n")] = '\0';
+ if ((*cp != '\0') && (*cp != '\n')) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ sprintf(sbuf, "%u", NAMESERVER_PORT);
+ if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
+ ai->ai_addrlen <= minsiz) {
+ if (statp->_u._ext.ext != NULL) {
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ ai->ai_addr, ai->ai_addrlen);
+ }
+ if (ai->ai_addrlen <=
+ sizeof(statp->nsaddr_list[nserv])) {
+ memcpy(&statp->nsaddr_list[nserv],
+ ai->ai_addr, ai->ai_addrlen);
+ } else
+ statp->nsaddr_list[nserv].sin_family = 0;
+ freeaddrinfo(ai);
+ nserv++;
+ }
}
continue;
}
@@ -310,7 +347,7 @@ __res_vinit(res_state statp, int preinit) {
break;
net = cp;
while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
+ isascii(*cp) && !isspace((unsigned char)*cp))
cp++;
n = *cp;
*cp = 0;
@@ -320,7 +357,8 @@ __res_vinit(res_state statp, int preinit) {
*cp++ = n;
net = cp;
while (*cp && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
+ isascii(*cp) &&
+ !isspace((unsigned char)*cp))
cp++;
n = *cp;
*cp = 0;
@@ -346,8 +384,7 @@ __res_vinit(res_state statp, int preinit) {
continue;
}
}
-
- if (nserv > 1)
+ if (nserv > 1)
statp->nscount = nserv;
#ifdef RESOLVSORT
statp->nsort = nsort;
@@ -404,9 +441,11 @@ __res_vinit(res_state statp, int preinit) {
}
static void
-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;
+ struct __res_state_ext *ext = statp->_u._ext.ext;
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -449,6 +488,11 @@ res_setoptions(res_state statp, const char *options, const char *source) {
}
printf(";;\tdebug\n");
#endif
+ } else if (!strncmp(cp, "no_tld_query",
+ sizeof("no_tld_query") - 1) ||
+ !strncmp(cp, "no-tld-query",
+ sizeof("no-tld-query") - 1)) {
+ statp->options |= RES_NOTLDQUERY;
} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
statp->options |= RES_USE_INET6;
} else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
@@ -456,9 +500,52 @@ res_setoptions(res_state statp, const char *options, const char *source) {
} else if (!strncmp(cp, "no-check-names",
sizeof("no-check-names") - 1)) {
statp->options |= RES_NOCHECKNAME;
- } else {
+ }
+#ifdef RES_USE_EDNS0
+ else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
+ statp->options |= RES_USE_EDNS0;
+ }
+#endif
+ else if (!strncmp(cp, "a6", sizeof("a6") - 1)) {
+ statp->options |= RES_USE_A6;
+ }
+ else if (!strncmp(cp, "dname", sizeof("dname") - 1)) {
+ statp->options |= RES_USE_DNAME;
+ }
+ else if (!strncmp(cp, "nibble:", sizeof("nibble:") - 1)) {
+ if (ext == NULL)
+ goto skip;
+ cp += sizeof("nibble:") - 1;
+ i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
+ strncpy(ext->nsuffix, cp, i);
+ ext->nsuffix[i] = '\0';
+ }
+ else if (!strncmp(cp, "bitstring:", sizeof("bitstring:") - 1)) {
+ if (ext == NULL)
+ goto skip;
+ cp += sizeof("bitstring:") - 1;
+ i = MIN(strcspn(cp, " \t"), sizeof(ext->bsuffix) - 1);
+ strncpy(ext->bsuffix, cp, i);
+ ext->bsuffix[i] = '\0';
+ }
+ else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) {
+ cp += sizeof("v6revmode:") - 1;
+ if (!strncmp(cp, "nibble", sizeof("nibble") - 1)) {
+ statp->options &= ~RES_NO_NIBBLE;
+ statp->options |= RES_NO_BITSTRING;
+ } else if (!strncmp(cp, "bitstring",
+ sizeof("bitstring") - 1)) {
+ statp->options |= RES_NO_NIBBLE;
+ statp->options &= ~RES_NO_BITSTRING;
+ } else if (!strncmp(cp, "both", sizeof("both") - 1)) {
+ statp->options &=
+ ~(RES_NO_NIBBLE|RES_NO_BITSTRING);
+ }
+ }
+ else {
/* XXX - print a warning here? */
}
+ skip:
/* skip to next run of spaces */
while (*cp && *cp != ' ' && *cp != '\t')
cp++;
@@ -512,3 +599,123 @@ res_nclose(res_state statp) {
}
}
}
+
+void
+res_ndestroy(res_state statp) {
+ res_nclose(statp);
+ if (statp->_u._ext.ext != NULL)
+ free(statp->_u._ext.ext);
+ statp->options &= ~RES_INIT;
+ statp->_u._ext.ext = NULL;
+}
+
+const char *
+res_get_nibblesuffix(res_state statp) {
+ if (statp->_u._ext.ext)
+ return (statp->_u._ext.ext->nsuffix);
+ return ("ip6.int");
+}
+
+const char *
+res_get_bitstringsuffix(res_state statp) {
+ if (statp->_u._ext.ext)
+ return (statp->_u._ext.ext->bsuffix);
+ return ("ip6.arpa");
+}
+
+void
+res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) {
+ int i, nserv;
+ size_t size;
+
+ /* close open servers */
+ res_nclose(statp);
+
+ /* cause rtt times to be forgotten */
+ statp->_u._ext.nscount = 0;
+
+ nserv = 0;
+ for (i = 0; i < cnt && nserv < MAXNS; i++) {
+ switch (set->sin.sin_family) {
+ case AF_INET:
+ size = sizeof(set->sin);
+ if (statp->_u._ext.ext)
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ &set->sin, size);
+ if (size <= sizeof(statp->nsaddr_list[nserv]))
+ memcpy(&statp->nsaddr_list[nserv],
+ &set->sin, size);
+ else
+ statp->nsaddr_list[nserv].sin_family = 0;
+ nserv++;
+ break;
+
+#ifdef HAS_INET6_STRUCTS
+ case AF_INET6:
+ size = sizeof(set->sin6);
+ if (statp->_u._ext.ext)
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ &set->sin6, size);
+ if (size <= sizeof(statp->nsaddr_list[nserv]))
+ memcpy(&statp->nsaddr_list[nserv],
+ &set->sin6, size);
+ else
+ statp->nsaddr_list[nserv].sin_family = 0;
+ nserv++;
+ break;
+#endif
+
+ default:
+ break;
+ }
+ set++;
+ }
+ statp->nscount = nserv;
+
+}
+
+int
+res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) {
+ int i;
+ size_t size;
+ u_int16_t family;
+
+ for (i = 0; i < statp->nscount && i < cnt; i++) {
+ if (statp->_u._ext.ext)
+ family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family;
+ else
+ family = statp->nsaddr_list[i].sin_family;
+
+ switch (family) {
+ case AF_INET:
+ size = sizeof(set->sin);
+ if (statp->_u._ext.ext)
+ memcpy(&set->sin,
+ &statp->_u._ext.ext->nsaddrs[i],
+ size);
+ else
+ memcpy(&set->sin, &statp->nsaddr_list[i],
+ size);
+ break;
+
+#ifdef HAS_INET6_STRUCTS
+ case AF_INET6:
+ size = sizeof(set->sin6);
+ if (statp->_u._ext.ext)
+ memcpy(&set->sin6,
+ &statp->_u._ext.ext->nsaddrs[i],
+ size);
+ else
+ memcpy(&set->sin6, &statp->nsaddr_list[i],
+ size);
+ break;
+#endif
+
+ default:
+ set->sin.sin_family = 0;
+ break;
+ }
+ set++;
+ }
+ return (statp->nscount);
+}
OpenPOWER on IntegriCloud