PERFORCE change 99427 for review

Michael Bushkov bushman at FreeBSD.org
Sat Jun 17 14:34:52 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=99427

Change 99427 by bushman at bushman_nss_ldap_cached on 2006/06/17 14:34:21

	changes in the resolver-related parts that allow painless code migration from libc to nss-modules

Affected files ...

.. //depot/projects/soc2006/nss_ldap_cached/src/lib/libc/net/getaddrinfo.c#2 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/libc/net/gethostnamadr.c#3 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/libc/net/name6.c#2 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/lib/libc/net/netdb_private.h#3 edit

Differences ...

==== //depot/projects/soc2006/nss_ldap_cached/src/lib/libc/net/getaddrinfo.c#2 (text+ko) ====

@@ -93,11 +93,11 @@
 #include <stdio.h>
 #include <errno.h>
 
-#include "res_config.h"
+//#include "res_config.h"
 
-#ifdef DEBUG
-#include <syslog.h>
-#endif
+//#ifdef DEBUG
+//#include <syslog.h>
+//#endif
 
 #include <stdarg.h>
 #include <nsswitch.h>
@@ -127,14 +127,6 @@
 };
 #endif
 
-struct policyqueue {
-	TAILQ_ENTRY(policyqueue) pc_entry;
-#ifdef INET6
-	struct in6_addrpolicy pc_policy;
-#endif
-};
-TAILQ_HEAD(policyhead, policyqueue);
-
 static const struct afd {
 	int a_af;
 	int a_addrlen;
@@ -161,6 +153,14 @@
 	{0, 0, 0, 0, NULL, NULL, 0},
 };
 
+struct policyqueue {
+	TAILQ_ENTRY(policyqueue) pc_entry;
+#ifdef INET6
+	struct in6_addrpolicy pc_policy;
+#endif
+};
+TAILQ_HEAD(policyhead, policyqueue);
+
 struct explore {
 	int e_af;
 	int e_socktype;
@@ -219,22 +219,6 @@
 	{ 0 }
 };
 
-struct res_target {
-	struct res_target *next;
-	const char *name;	/* domain name */
-	int qclass, qtype;	/* class and type of query */
-	u_char *answer;		/* buffer to put answer */
-	int anslen;		/* size of answer buffer */
-	int n;			/* result length */
-};
-
-#define MAXPACKET	(64*1024)
-
-typedef union {
-	HEADER hdr;
-	u_char buf[MAXPACKET];
-} querybuf;
-
 static int str2number(const char *);
 static int explore_null(const struct addrinfo *,
 	const char *, struct addrinfo **);
@@ -267,7 +251,7 @@
 	struct policyhead *);
 static int matchlen(struct sockaddr *, struct sockaddr *);
 
-static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
+/*static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
 	const struct addrinfo *, res_state);
 #if defined(RESOLVSORT)
 static int addr4sort(struct addrinfo *, res_state);
@@ -281,17 +265,17 @@
 #ifdef YP
 static struct addrinfo *_yphostent(char *, const struct addrinfo *);
 static int _yp_getaddrinfo(void *, void *, va_list);
-#endif
+#endif*/
 #ifdef NS_CACHING
 static int addrinfo_id_func(char *, size_t *, va_list, void *);
 static int addrinfo_marshal_func(char *, size_t *, void *, va_list, void *);
 static int addrinfo_unmarshal_func(char *, size_t, void *, va_list, void *);
 #endif
 
-static int res_queryN(const char *, struct res_target *, res_state);
+/*static int res_queryN(const char *, struct res_target *, res_state);
 static int res_searchN(const char *, struct res_target *, res_state);
 static int res_querydomainN(const char *, const char *,
-	struct res_target *, res_state);
+	struct res_target *, res_state);*/
 
 /* XXX macros that make external reference is BAD. */
 
@@ -1730,9 +1714,6 @@
 		addrinfo_unmarshal_func);
 #endif
 	static const ns_dtab dtab[] = {
-		NS_FILES_CB(_files_getaddrinfo, NULL)
-		{ NSSRC_DNS, _dns_getaddrinfo, NULL },	/* force -DHESIOD */
-		NS_NIS_CB(_yp_getaddrinfo, NULL)
 #ifdef NS_CACHING
 		NS_CACHE_CB(&cache_info)
 #endif
@@ -1776,997 +1757,3 @@
 		freeaddrinfo(result);
 	return error;
 }
-
-#ifdef DEBUG
-static const char AskedForGot[] =
-	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
-#endif
-
-static struct addrinfo *
-getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
-    const struct addrinfo *pai, res_state res)
-{
-	struct addrinfo sentinel, *cur;
-	struct addrinfo ai;
-	const struct afd *afd;
-	char *canonname;
-	const HEADER *hp;
-	const u_char *cp;
-	int n;
-	const u_char *eom;
-	char *bp, *ep;
-	int type, class, ancount, qdcount;
-	int haveanswer, had_error;
-	char tbuf[MAXDNAME];
-	int (*name_ok)(const char *);
-	char hostbuf[8*1024];
-
-	memset(&sentinel, 0, sizeof(sentinel));
-	cur = &sentinel;
-
-	canonname = NULL;
-	eom = answer->buf + anslen;
-	switch (qtype) {
-	case T_A:
-	case T_AAAA:
-	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
-		name_ok = res_hnok;
-		break;
-	default:
-		return (NULL);	/* XXX should be abort(); */
-	}
-	/*
-	 * find first satisfactory answer
-	 */
-	hp = &answer->hdr;
-	ancount = ntohs(hp->ancount);
-	qdcount = ntohs(hp->qdcount);
-	bp = hostbuf;
-	ep = hostbuf + sizeof hostbuf;
-	cp = answer->buf + HFIXEDSZ;
-	if (qdcount != 1) {
-		RES_SET_H_ERRNO(res, NO_RECOVERY);
-		return (NULL);
-	}
-	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
-	if ((n < 0) || !(*name_ok)(bp)) {
-		RES_SET_H_ERRNO(res, NO_RECOVERY);
-		return (NULL);
-	}
-	cp += n + QFIXEDSZ;
-	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
-		/* res_send() has already verified that the query name is the
-		 * same as the one we sent; this just gets the expanded name
-		 * (i.e., with the succeeding search-domain tacked on).
-		 */
-		n = strlen(bp) + 1;		/* for the \0 */
-		if (n >= MAXHOSTNAMELEN) {
-			RES_SET_H_ERRNO(res, NO_RECOVERY);
-			return (NULL);
-		}
-		canonname = bp;
-		bp += n;
-		/* The qname can be abbreviated, but h_name is now absolute. */
-		qname = canonname;
-	}
-	haveanswer = 0;
-	had_error = 0;
-	while (ancount-- > 0 && cp < eom && !had_error) {
-		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
-		if ((n < 0) || !(*name_ok)(bp)) {
-			had_error++;
-			continue;
-		}
-		cp += n;			/* name */
-		type = _getshort(cp);
- 		cp += INT16SZ;			/* type */
-		class = _getshort(cp);
- 		cp += INT16SZ + INT32SZ;	/* class, TTL */
-		n = _getshort(cp);
-		cp += INT16SZ;			/* len */
-		if (class != C_IN) {
-			/* XXX - debug? syslog? */
-			cp += n;
-			continue;		/* XXX - had_error++ ? */
-		}
-		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
-		    type == T_CNAME) {
-			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
-			if ((n < 0) || !(*name_ok)(tbuf)) {
-				had_error++;
-				continue;
-			}
-			cp += n;
-			/* Get canonical name. */
-			n = strlen(tbuf) + 1;	/* for the \0 */
-			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
-				had_error++;
-				continue;
-			}
-			strlcpy(bp, tbuf, ep - bp);
-			canonname = bp;
-			bp += n;
-			continue;
-		}
-		if (qtype == T_ANY) {
-			if (!(type == T_A || type == T_AAAA)) {
-				cp += n;
-				continue;
-			}
-		} else if (type != qtype) {
-#ifdef DEBUG
-			if (type != T_KEY && type != T_SIG)
-				syslog(LOG_NOTICE|LOG_AUTH,
-	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
-				       qname, p_class(C_IN), p_type(qtype),
-				       p_type(type));
-#endif
-			cp += n;
-			continue;		/* XXX - had_error++ ? */
-		}
-		switch (type) {
-		case T_A:
-		case T_AAAA:
-			if (strcasecmp(canonname, bp) != 0) {
-#ifdef DEBUG
-				syslog(LOG_NOTICE|LOG_AUTH,
-				       AskedForGot, canonname, bp);
-#endif
-				cp += n;
-				continue;	/* XXX - had_error++ ? */
-			}
-			if (type == T_A && n != INADDRSZ) {
-				cp += n;
-				continue;
-			}
-			if (type == T_AAAA && n != IN6ADDRSZ) {
-				cp += n;
-				continue;
-			}
-#ifdef FILTER_V4MAPPED
-			if (type == T_AAAA) {
-				struct in6_addr in6;
-				memcpy(&in6, cp, sizeof(in6));
-				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
-					cp += n;
-					continue;
-				}
-			}
-#endif
-			if (!haveanswer) {
-				int nn;
-
-				canonname = bp;
-				nn = strlen(bp) + 1;	/* for the \0 */
-				bp += nn;
-			}
-
-			/* don't overwrite pai */
-			ai = *pai;
-			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
-			afd = find_afd(ai.ai_family);
-			if (afd == NULL) {
-				cp += n;
-				continue;
-			}
-			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
-			if (cur->ai_next == NULL)
-				had_error++;
-			while (cur && cur->ai_next)
-				cur = cur->ai_next;
-			cp += n;
-			break;
-		default:
-			abort();
-		}
-		if (!had_error)
-			haveanswer++;
-	}
-	if (haveanswer) {
-#if defined(RESOLVSORT)
-		/*
-		 * We support only IPv4 address for backward
-		 * compatibility against gethostbyname(3).
-		 */
-		if (res->nsort && qtype == T_A) {
-			if (addr4sort(&sentinel, res) < 0) {
-				freeaddrinfo(sentinel.ai_next);
-				RES_SET_H_ERRNO(res, NO_RECOVERY);
-				return NULL;
-			}
-		}
-#endif /*RESOLVSORT*/
-		if (!canonname)
-			(void)get_canonname(pai, sentinel.ai_next, qname);
-		else
-			(void)get_canonname(pai, sentinel.ai_next, canonname);
-		RES_SET_H_ERRNO(res, NETDB_SUCCESS);
-		return sentinel.ai_next;
-	}
-
-	RES_SET_H_ERRNO(res, NO_RECOVERY);
-	return NULL;
-}
-
-#ifdef RESOLVSORT
-struct addr_ptr {
-	struct addrinfo *ai;
-	int aval;
-};
-
-static int
-addr4sort(struct addrinfo *sentinel, res_state res)
-{
-	struct addrinfo *ai;
-	struct addr_ptr *addrs, addr;
-	struct sockaddr_in *sin;
-	int naddrs, i, j;
-	int needsort = 0;
-
-	if (!sentinel)
-		return -1;
-	naddrs = 0;
-	for (ai = sentinel->ai_next; ai; ai = ai->ai_next)
-		naddrs++;
-	if (naddrs < 2)
-		return 0;		/* We don't need sorting. */
-	if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL)
-		return -1;
-	i = 0;
-	for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
-		sin = (struct sockaddr_in *)ai->ai_addr;
-		for (j = 0; (unsigned)j < res->nsort; j++) {
-			if (res->sort_list[j].addr.s_addr ==
-			    (sin->sin_addr.s_addr & res->sort_list[j].mask))
-				break;
-		}
-		addrs[i].ai = ai;
-		addrs[i].aval = j;
-		if (needsort == 0 && i > 0 && j < addrs[i - 1].aval)
-			needsort = i;
-		i++;
-	}
-	if (!needsort) {
-		free(addrs);
-		return 0;
-	}
-
-	while (needsort < naddrs) {
-		for (j = needsort - 1; j >= 0; j--) {
-			if (addrs[j].aval > addrs[j+1].aval) {
-				addr = addrs[j];
-				addrs[j] = addrs[j + 1];
-				addrs[j + 1] = addr;
-			} else
-				break;
-		}
-		needsort++;
-	}
-
-	ai = sentinel;
-	for (i = 0; i < naddrs; ++i) {
-		ai->ai_next = addrs[i].ai;
-		ai = ai->ai_next;
-	}
-	ai->ai_next = NULL;
-	free(addrs);
-	return 0;
-}
-#endif /*RESOLVSORT*/
-
-/*ARGSUSED*/
-static int
-_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
-{
-	struct addrinfo *ai;
-	querybuf *buf, *buf2;
-	const char *hostname;
-	const struct addrinfo *pai;
-	struct addrinfo sentinel, *cur;
-	struct res_target q, q2;
-	res_state res;
-
-	hostname = va_arg(ap, char *);
-	pai = va_arg(ap, const struct addrinfo *);
-
-	memset(&q, 0, sizeof(q));
-	memset(&q2, 0, sizeof(q2));
-	memset(&sentinel, 0, sizeof(sentinel));
-	cur = &sentinel;
-
-	buf = malloc(sizeof(*buf));
-	if (!buf) {
-		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
-		return NS_NOTFOUND;
-	}
-	buf2 = malloc(sizeof(*buf2));
-	if (!buf2) {
-		free(buf);
-		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
-		return NS_NOTFOUND;
-	}
-
-	switch (pai->ai_family) {
-	case AF_UNSPEC:
-		q.name = hostname;
-		q.qclass = C_IN;
-		q.qtype = T_A;
-		q.answer = buf->buf;
-		q.anslen = sizeof(buf->buf);
-		q.next = &q2;
-		q2.name = hostname;
-		q2.qclass = C_IN;
-		q2.qtype = T_AAAA;
-		q2.answer = buf2->buf;
-		q2.anslen = sizeof(buf2->buf);
-		break;
-	case AF_INET:
-		q.name = hostname;
-		q.qclass = C_IN;
-		q.qtype = T_A;
-		q.answer = buf->buf;
-		q.anslen = sizeof(buf->buf);
-		break;
-	case AF_INET6:
-		q.name = hostname;
-		q.qclass = C_IN;
-		q.qtype = T_AAAA;
-		q.answer = buf->buf;
-		q.anslen = sizeof(buf->buf);
-		break;
-	default:
-		free(buf);
-		free(buf2);
-		return NS_UNAVAIL;
-	}
-
-	res = __res_state();
-	if ((res->options & RES_INIT) == 0 && res_ninit(res) == -1) {
-		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
-		free(buf);
-		free(buf2);
-		return NS_NOTFOUND;
-	}
-
-	if (res_searchN(hostname, &q, res) < 0) {
-		free(buf);
-		free(buf2);
-		return NS_NOTFOUND;
-	}
-	/* prefer IPv6 */
-	if (q.next) {
-		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, res);
-		if (ai) {
-			cur->ai_next = ai;
-			while (cur && cur->ai_next)
-				cur = cur->ai_next;
-		}
-	}
-	ai = getanswer(buf, q.n, q.name, q.qtype, pai, res);
-	if (ai)
-		cur->ai_next = ai;
-	free(buf);
-	free(buf2);
-	if (sentinel.ai_next == NULL)
-		switch (res->res_h_errno) {
-		case HOST_NOT_FOUND:
-			return NS_NOTFOUND;
-		case TRY_AGAIN:
-			return NS_TRYAGAIN;
-		default:
-			return NS_UNAVAIL;
-		}
-	*((struct addrinfo **)rv) = sentinel.ai_next;
-	return NS_SUCCESS;
-}
-
-static void
-_sethtent(FILE **hostf)
-{
-	if (!*hostf)
-		*hostf = fopen(_PATH_HOSTS, "r");
-	else
-		rewind(*hostf);
-}
-
-static void
-_endhtent(FILE **hostf)
-{
-	if (*hostf) {
-		(void) fclose(*hostf);
-		*hostf = NULL;
-	}
-}
-
-static struct addrinfo *
-_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
-{
-	char *p;
-	char *cp, *tname, *cname;
-	struct addrinfo hints, *res0, *res;
-	int error;
-	const char *addr;
-	char hostbuf[8*1024];
-
-	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r")))
-		return (NULL);
-again:
-	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
-		return (NULL);
-	if (*p == '#')
-		goto again;
-	cp = strpbrk(p, "#\n");
-	if (cp != NULL)
-		*cp = '\0';
-	if (!(cp = strpbrk(p, " \t")))
-		goto again;
-	*cp++ = '\0';
-	addr = p;
-	cname = NULL;
-	/* if this is not something we're looking for, skip it. */
-	while (cp && *cp) {
-		if (*cp == ' ' || *cp == '\t') {
-			cp++;
-			continue;
-		}
-		tname = cp;
-		if (cname == NULL)
-			cname = cp;
-		if ((cp = strpbrk(cp, " \t")) != NULL)
-			*cp++ = '\0';
-		if (strcasecmp(name, tname) == 0)
-			goto found;
-	}
-	goto again;
-
-found:
-	/* we should not glob socktype/protocol here */
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = pai->ai_family;
-	hints.ai_socktype = SOCK_DGRAM;
-	hints.ai_protocol = 0;
-	hints.ai_flags = AI_NUMERICHOST;
-	error = getaddrinfo(addr, "0", &hints, &res0);
-	if (error)
-		goto again;
-#ifdef FILTER_V4MAPPED
-	/* XXX should check all items in the chain */
-	if (res0->ai_family == AF_INET6 &&
-	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) {
-		freeaddrinfo(res0);
-		goto again;
-	}
-#endif
-	for (res = res0; res; res = res->ai_next) {
-		/* cover it up */
-		res->ai_flags = pai->ai_flags;
-		res->ai_socktype = pai->ai_socktype;
-		res->ai_protocol = pai->ai_protocol;
-
-		if (pai->ai_flags & AI_CANONNAME) {
-			if (get_canonname(pai, res, cname) != 0) {
-				freeaddrinfo(res0);
-				goto again;
-			}
-		}
-	}
-	return res0;
-}
-
-/*ARGSUSED*/
-static int
-_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
-{
-	const char *name;
-	const struct addrinfo *pai;
-	struct addrinfo sentinel, *cur;
-	struct addrinfo *p;
-	FILE *hostf = NULL;
-
-	name = va_arg(ap, char *);
-	pai = va_arg(ap, struct addrinfo *);
-
-	memset(&sentinel, 0, sizeof(sentinel));
-	cur = &sentinel;
-
-	_sethtent(&hostf);
-	while ((p = _gethtent(&hostf, name, pai)) != NULL) {
-		cur->ai_next = p;
-		while (cur && cur->ai_next)
-			cur = cur->ai_next;
-	}
-	_endhtent(&hostf);
-
-	*((struct addrinfo **)rv) = sentinel.ai_next;
-	if (sentinel.ai_next == NULL)
-		return NS_NOTFOUND;
-	return NS_SUCCESS;
-}
-
-#ifdef YP
-/*ARGSUSED*/
-static struct addrinfo *
-_yphostent(char *line, const struct addrinfo *pai)
-{
-	struct addrinfo sentinel, *cur;
-	struct addrinfo hints, *res, *res0;
-	int error;
-	char *p = line;
-	const char *addr, *canonname;
-	char *nextline;
-	char *cp;
-
-	addr = canonname = NULL;
-
-	memset(&sentinel, 0, sizeof(sentinel));
-	cur = &sentinel;
-
-nextline:
-	/* terminate line */
-	cp = strchr(p, '\n');
-	if (cp) {
-		*cp++ = '\0';
-		nextline = cp;
-	} else
-		nextline = NULL;
-
-	cp = strpbrk(p, " \t");
-	if (cp == NULL) {
-		if (canonname == NULL)
-			return (NULL);
-		else
-			goto done;
-	}
-	*cp++ = '\0';
-
-	addr = p;
-
-	while (cp && *cp) {
-		if (*cp == ' ' || *cp == '\t') {
-			cp++;
-			continue;
-		}
-		if (!canonname)
-			canonname = cp;
-		if ((cp = strpbrk(cp, " \t")) != NULL)
-			*cp++ = '\0';
-	}
-
-	hints = *pai;
-	hints.ai_flags = AI_NUMERICHOST;
-	error = getaddrinfo(addr, NULL, &hints, &res0);
-	if (error == 0) {
-		for (res = res0; res; res = res->ai_next) {
-			/* cover it up */
-			res->ai_flags = pai->ai_flags;
-
-			if (pai->ai_flags & AI_CANONNAME)
-				(void)get_canonname(pai, res, canonname);
-		}
-	} else
-		res0 = NULL;
-	if (res0) {
-		cur->ai_next = res0;
-		while (cur && cur->ai_next)
-			cur = cur->ai_next;
-	}
-
-	if (nextline) {
-		p = nextline;
-		goto nextline;
-	}
-
-done:
-	return sentinel.ai_next;
-}
-
-/*ARGSUSED*/
-static int
-_yp_getaddrinfo(void *rv, void *cb_data, va_list ap)
-{
-	struct addrinfo sentinel, *cur;
-	struct addrinfo *ai = NULL;
-	char *ypbuf;
-	int ypbuflen, r;
-	const char *name;
-	const struct addrinfo *pai;
-	char *ypdomain;
-
-	if (_yp_check(&ypdomain) == 0)
-		return NS_UNAVAIL;
-
-	name = va_arg(ap, char *);
-	pai = va_arg(ap, const struct addrinfo *);
-
-	memset(&sentinel, 0, sizeof(sentinel));
-	cur = &sentinel;
-
-	/* hosts.byname is only for IPv4 (Solaris8) */
-	if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
-		r = yp_match(ypdomain, "hosts.byname", name,
-			(int)strlen(name), &ypbuf, &ypbuflen);
-		if (r == 0) {
-			struct addrinfo ai4;
-
-			ai4 = *pai;
-			ai4.ai_family = AF_INET;
-			ai = _yphostent(ypbuf, &ai4);
-			if (ai) {
-				cur->ai_next = ai;
-				while (cur && cur->ai_next)
-					cur = cur->ai_next;
-			}
-			free(ypbuf);
-		}
-	}
-
-	/* ipnodes.byname can hold both IPv4/v6 */
-	r = yp_match(ypdomain, "ipnodes.byname", name,
-		(int)strlen(name), &ypbuf, &ypbuflen);
-	if (r == 0) {
-		ai = _yphostent(ypbuf, pai);
-		if (ai)
-			cur->ai_next = ai;
-		free(ypbuf);
-	}
-
-	if (sentinel.ai_next == NULL) {
-		RES_SET_H_ERRNO(__res_state(), HOST_NOT_FOUND);
-		return NS_NOTFOUND;
-	}
-	*((struct addrinfo **)rv) = sentinel.ai_next;
-	return NS_SUCCESS;
-}
-#endif
-
-/* resolver logic */
-
-/*
- * Formulate a normal query, send, and await answer.
- * Returned answer is placed in supplied buffer "answer".
- * Perform preliminary check of answer, returning success only
- * if no error is indicated and the answer count is nonzero.
- * Return the size of the response on success, -1 on error.
- * Error number is left in h_errno.
- *
- * Caller must parse answer and determine whether it answers the question.
- */
-static int
-res_queryN(const char *name, struct res_target *target, res_state res)
-{
-	u_char *buf;
-	HEADER *hp;
-	int n;
-	u_int oflags;
-	struct res_target *t;
-	int rcode;
-	int ancount;
-
-	rcode = NOERROR;
-	ancount = 0;
-
-	buf = malloc(MAXPACKET);
-	if (!buf) {
-		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
-		return -1;
-	}
-
-	for (t = target; t; t = t->next) {
-		int class, type;
-		u_char *answer;
-		int anslen;
-
-		hp = (HEADER *)(void *)t->answer;
-
-		/* make it easier... */
-		class = t->qclass;
-		type = t->qtype;
-		answer = t->answer;
-		anslen = t->anslen;
-
-		oflags = res->_flags;
-
-again:
-		hp->rcode = NOERROR;	/* default */
-
-#ifdef DEBUG
-		if (res->options & RES_DEBUG)
-			printf(";; res_query(%s, %d, %d)\n", name, class, type);
-#endif
-
-		n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL,
-		    buf, MAXPACKET);
-		if (n > 0 && (res->_flags & RES_F_EDNS0ERR) == 0 &&
-		    (res->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U)
-			n = res_nopt(res, n, buf, MAXPACKET, anslen);
-		if (n <= 0) {
-#ifdef DEBUG
-			if (res->options & RES_DEBUG)
-				printf(";; res_query: mkquery failed\n");
-#endif
-			free(buf);
-			RES_SET_H_ERRNO(res, NO_RECOVERY);
-			return (n);
-		}
-		n = res_nsend(res, buf, n, answer, anslen);
-		if (n < 0) {
-			/*
-			 * if the query choked with EDNS0, retry
-			 * without EDNS0
-			 */
-			if ((res->options & (RES_USE_EDNS0|RES_USE_DNSSEC))
-			    != 0U &&
-			    ((oflags ^ res->_flags) & RES_F_EDNS0ERR) != 0) {
-				res->_flags |= RES_F_EDNS0ERR;
-				if (res->options & RES_DEBUG)
-					printf(";; res_nquery: retry without EDNS0\n");
-				goto again;
-			}
-			rcode = hp->rcode;	/* record most recent error */
-#ifdef DEBUG
-			if (res->options & RES_DEBUG)
-				printf(";; res_query: send error\n");
-#endif
-			continue;
-		}
-
-		if (n > anslen)
-			hp->rcode = FORMERR; /* XXX not very informative */
-		if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
-			rcode = hp->rcode;	/* record most recent error */
-#ifdef DEBUG
-			if (res->options & RES_DEBUG)
-				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
-				    ntohs(hp->ancount));
-#endif
-			continue;
-		}
-
-		ancount += ntohs(hp->ancount);
-
-		t->n = n;
-	}
-
-	free(buf);
-
-	if (ancount == 0) {
-		switch (rcode) {
-		case NXDOMAIN:
-			RES_SET_H_ERRNO(res, HOST_NOT_FOUND);
-			break;
-		case SERVFAIL:
-			RES_SET_H_ERRNO(res, TRY_AGAIN);
-			break;
-		case NOERROR:
-			RES_SET_H_ERRNO(res, NO_DATA);
-			break;
-		case FORMERR:
-		case NOTIMP:
-		case REFUSED:
-		default:
-			RES_SET_H_ERRNO(res, NO_RECOVERY);
-			break;
-		}
-		return (-1);
-	}
-	return (ancount);
-}
-
-/*
- * Formulate a normal query, send, and retrieve answer in supplied buffer.
- * Return the size of the response on success, -1 on error.
- * If enabled, implement search rules until answer or unrecoverable failure
- * is detected.  Error code, if any, is left in h_errno.
- */
-static int
-res_searchN(const char *name, struct res_target *target, res_state res)
-{
-	const char *cp, * const *domain;
-	HEADER *hp = (HEADER *)(void *)target->answer;	/*XXX*/
-	u_int dots;
-	int trailing_dot, ret, saved_herrno;
-	int got_nodata = 0, got_servfail = 0, root_on_list = 0;
-	int tried_as_is = 0;
-	int searched = 0;
-	char abuf[MAXDNAME];
-
-	errno = 0;
-	RES_SET_H_ERRNO(res, HOST_NOT_FOUND); /* default, if we never query */
-	dots = 0;
-	for (cp = name; *cp; cp++)
-		dots += (*cp == '.');
-	trailing_dot = 0;
-	if (cp > name && *--cp == '.')
-		trailing_dot++;
-
-	/*
-	 * if there aren't any dots, it could be a user-level alias
-	 */
-	if (!dots &&
-	    (cp = res_hostalias(res, name, abuf, sizeof(abuf))) != NULL)
-		return (res_queryN(cp, target, res));
-
-	/*
-	 * 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.
-	 */
-	saved_herrno = -1;
-	if (dots >= res->ndots || trailing_dot) {
-		ret = res_querydomainN(name, NULL, target, res);
-		if (ret > 0 || trailing_dot)
-			return (ret);
-		if (errno == ECONNREFUSED) {
-			RES_SET_H_ERRNO(res, TRY_AGAIN);
-			return (-1);
-		}
-		switch (res->res_h_errno) {
-		case NO_DATA:
-		case HOST_NOT_FOUND:
-			break;
-		case TRY_AGAIN:
-			if (hp->rcode == SERVFAIL)
-				break;
-			/* FALLTHROUGH */
-		default:
-			return (-1);
-		}
-		saved_herrno = res->res_h_errno;
-		tried_as_is++;
-	}
-
-	/*
-	 * We do at least one level of search if
-	 *	- there is no dot and RES_DEFNAME is set, or
-	 *	- there is at least one dot, there is no trailing dot,
-	 *	  and RES_DNSRCH is set.
-	 */
-	if ((!dots && (res->options & RES_DEFNAMES)) ||
-	    (dots && !trailing_dot && (res->options & RES_DNSRCH))) {
-		int done = 0;
-
-		for (domain = (const char * const *)res->dnsrch;
-		   *domain && !done;
-		   domain++) {
-			searched = 1;
-
-			if (domain[0][0] == '\0' ||
-			    (domain[0][0] == '.' && domain[0][1] == '\0'))
-				root_on_list++;
-
-			if (root_on_list && tried_as_is)
-				continue;
-
-			ret = res_querydomainN(name, *domain, target, res);
-			if (ret > 0)
-				return (ret);
-
-			/*
-			 * If no server present, give up.
-			 * If name isn't found in this domain,
-			 * keep trying higher domains in the search list
-			 * (if that's enabled).
-			 * On a NO_DATA error, keep trying, otherwise
-			 * a wildcard entry of another type could keep us

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list