1/*	$KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $	*/
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
34 *
35 * Issues to be discussed:
36 * - Return values.  There are nonstandard return values defined and used
37 *   in the source code.  This is because RFC2553 is silent about which error
38 *   code must be returned for which situation.
39 * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
40 *   invalid.  current code - SEGV on freeaddrinfo(NULL)
41 *
42 * Note:
43 * - The code filters out AFs that are not supported by the kernel,
44 *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
45 *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
46 *   in ai_flags?
47 * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
48 *   (1) what should we do against numeric hostname (2) what should we do
49 *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
50 *   non-loopback address configured?  global address configured?
51 *
52 * OS specific notes for freebsd4:
53 * - FreeBSD supported $GAI.  The code does not.
54 */
55
56#include <sys/cdefs.h>
57__FBSDID("$FreeBSD: stable/10/lib/libc/net/getaddrinfo.c 327238 2017-12-27 14:50:07Z ume $");
58
59#include "namespace.h"
60#include <sys/types.h>
61#include <sys/param.h>
62#include <sys/socket.h>
63#include <net/if.h>
64#include <netinet/in.h>
65#include <net/if_types.h>
66#include <ifaddrs.h>
67#include <sys/queue.h>
68#ifdef INET6
69#include <net/if_var.h>
70#include <sys/sysctl.h>
71#include <sys/ioctl.h>
72#include <netinet6/in6_var.h>
73#include <netinet6/nd6.h>
74#endif
75#include <arpa/inet.h>
76#include <arpa/nameser.h>
77#include <rpc/rpc.h>
78#include <rpcsvc/yp_prot.h>
79#include <rpcsvc/ypclnt.h>
80#include <netdb.h>
81#include <resolv.h>
82#include <string.h>
83#include <stdlib.h>
84#include <stddef.h>
85#include <ctype.h>
86#include <unistd.h>
87#include <stdio.h>
88#include <errno.h>
89
90#include "res_config.h"
91
92#ifdef DEBUG
93#include <syslog.h>
94#endif
95
96#include <stdarg.h>
97#include <nsswitch.h>
98#include "un-namespace.h"
99#include "netdb_private.h"
100#include "libc_private.h"
101#ifdef NS_CACHING
102#include "nscache.h"
103#endif
104
105#if defined(__KAME__) && defined(INET6)
106# define FAITH
107#endif
108
109#define ANY 0
110#define YES 1
111#define NO  0
112
113static const char in_addrany[] = { 0, 0, 0, 0 };
114static const char in_loopback[] = { 127, 0, 0, 1 };
115#ifdef INET6
116static const char in6_addrany[] = {
117	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
118};
119static const char in6_loopback[] = {
120	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
121};
122#endif
123
124struct policyqueue {
125	TAILQ_ENTRY(policyqueue) pc_entry;
126#ifdef INET6
127	struct in6_addrpolicy pc_policy;
128#endif
129};
130TAILQ_HEAD(policyhead, policyqueue);
131
132static const struct afd {
133	int a_af;
134	int a_addrlen;
135	socklen_t a_socklen;
136	int a_off;
137	const char *a_addrany;
138	const char *a_loopback;
139	int a_scoped;
140} afdl [] = {
141#ifdef INET6
142#define	N_INET6 0
143	{PF_INET6, sizeof(struct in6_addr),
144	 sizeof(struct sockaddr_in6),
145	 offsetof(struct sockaddr_in6, sin6_addr),
146	 in6_addrany, in6_loopback, 1},
147#define	N_INET 1
148#else
149#define	N_INET 0
150#endif
151	{PF_INET, sizeof(struct in_addr),
152	 sizeof(struct sockaddr_in),
153	 offsetof(struct sockaddr_in, sin_addr),
154	 in_addrany, in_loopback, 0},
155	{0, 0, 0, 0, NULL, NULL, 0},
156};
157
158struct explore {
159	int e_af;
160	int e_socktype;
161	int e_protocol;
162	int e_wild;
163#define WILD_AF(ex)		((ex)->e_wild & 0x01)
164#define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
165#define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
166};
167
168static const struct explore explore[] = {
169#if 0
170	{ PF_LOCAL, ANY, ANY, 0x01 },
171#endif
172#ifdef INET6
173	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0x07 },
174	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07 },
175	{ PF_INET6, SOCK_STREAM, IPPROTO_SCTP, 0x03 },
176	{ PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 },
177	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 },
178	{ PF_INET6, SOCK_RAW, ANY, 0x05 },
179#endif
180	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, 0x07 },
181	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, 0x07 },
182	{ PF_INET, SOCK_STREAM, IPPROTO_SCTP, 0x03 },
183	{ PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, 0x07 },
184	{ PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE, 0x03 },
185	{ PF_INET, SOCK_RAW, ANY, 0x05 },
186	{ -1, 0, 0, 0 },
187};
188
189#ifdef INET6
190#define PTON_MAX	16
191#else
192#define PTON_MAX	4
193#endif
194
195#define AIO_SRCFLAG_DEPRECATED	0x1
196
197struct ai_order {
198	union {
199		struct sockaddr_storage aiou_ss;
200		struct sockaddr aiou_sa;
201	} aio_src_un;
202#define aio_srcsa aio_src_un.aiou_sa
203	u_int32_t aio_srcflag;
204	int aio_srcscope;
205	int aio_dstscope;
206	struct policyqueue *aio_srcpolicy;
207	struct policyqueue *aio_dstpolicy;
208	struct addrinfo *aio_ai;
209	int aio_matchlen;
210	int aio_initial_sequence;
211};
212
213static const ns_src default_dns_files[] = {
214	{ NSSRC_FILES, 	NS_SUCCESS },
215	{ NSSRC_DNS, 	NS_SUCCESS },
216	{ 0 }
217};
218
219struct res_target {
220	struct res_target *next;
221	const char *name;	/* domain name */
222	int qclass, qtype;	/* class and type of query */
223	u_char *answer;		/* buffer to put answer */
224	int anslen;		/* size of answer buffer */
225	int n;			/* result length */
226};
227
228#define MAXPACKET	(64*1024)
229
230typedef union {
231	HEADER hdr;
232	u_char buf[MAXPACKET];
233} querybuf;
234
235static int str2number(const char *, int *);
236static int explore_copy(const struct addrinfo *, const struct addrinfo *,
237	struct addrinfo **);
238static int explore_null(const struct addrinfo *,
239	const char *, struct addrinfo **);
240static int explore_numeric(const struct addrinfo *, const char *,
241	const char *, struct addrinfo **, const char *);
242static int explore_numeric_scope(const struct addrinfo *, const char *,
243	const char *, struct addrinfo **);
244static int get_canonname(const struct addrinfo *,
245	struct addrinfo *, const char *);
246static struct addrinfo *get_ai(const struct addrinfo *,
247	const struct afd *, const char *);
248static struct addrinfo *copy_ai(const struct addrinfo *);
249static int get_portmatch(const struct addrinfo *, const char *);
250static int get_port(struct addrinfo *, const char *, int);
251static const struct afd *find_afd(int);
252static int addrconfig(struct addrinfo *);
253#ifdef INET6
254static int is_ifdisabled(char *);
255#endif
256static void set_source(struct ai_order *, struct policyhead *);
257static int comp_dst(const void *, const void *);
258#ifdef INET6
259static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
260#endif
261static int gai_addr2scopetype(struct sockaddr *);
262
263static int explore_fqdn(const struct addrinfo *, const char *,
264	const char *, struct addrinfo **);
265
266static int reorder(struct addrinfo *);
267static int get_addrselectpolicy(struct policyhead *);
268static void free_addrselectpolicy(struct policyhead *);
269static struct policyqueue *match_addrselectpolicy(struct sockaddr *,
270	struct policyhead *);
271static int matchlen(struct sockaddr *, struct sockaddr *);
272
273static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
274	const struct addrinfo *, res_state);
275#if defined(RESOLVSORT)
276static int addr4sort(struct addrinfo *, res_state);
277#endif
278static int _dns_getaddrinfo(void *, void *, va_list);
279static void _sethtent(FILE **);
280static void _endhtent(FILE **);
281static struct addrinfo *_gethtent(FILE **, const char *,
282	const struct addrinfo *);
283static int _files_getaddrinfo(void *, void *, va_list);
284#ifdef YP
285static struct addrinfo *_yphostent(char *, const struct addrinfo *);
286static int _yp_getaddrinfo(void *, void *, va_list);
287#endif
288#ifdef NS_CACHING
289static int addrinfo_id_func(char *, size_t *, va_list, void *);
290static int addrinfo_marshal_func(char *, size_t *, void *, va_list, void *);
291static int addrinfo_unmarshal_func(char *, size_t, void *, va_list, void *);
292#endif
293
294static int res_queryN(const char *, struct res_target *, res_state);
295static int res_searchN(const char *, struct res_target *, res_state);
296static int res_querydomainN(const char *, const char *,
297	struct res_target *, res_state);
298
299/* XXX macros that make external reference is BAD. */
300
301#define GET_AI(ai, afd, addr) \
302do { \
303	/* external reference: pai, error, and label free */ \
304	(ai) = get_ai(pai, (afd), (addr)); \
305	if ((ai) == NULL) { \
306		error = EAI_MEMORY; \
307		goto free; \
308	} \
309} while (/*CONSTCOND*/0)
310
311#define GET_PORT(ai, serv) \
312do { \
313	/* external reference: error and label free */ \
314	error = get_port((ai), (serv), 0); \
315	if (error != 0) \
316		goto free; \
317} while (/*CONSTCOND*/0)
318
319#define GET_CANONNAME(ai, str) \
320do { \
321	/* external reference: pai, error and label free */ \
322	error = get_canonname(pai, (ai), (str)); \
323	if (error != 0) \
324		goto free; \
325} while (/*CONSTCOND*/0)
326
327#define ERR(err) \
328do { \
329	/* external reference: error, and label bad */ \
330	error = (err); \
331	goto bad; \
332	/*NOTREACHED*/ \
333} while (/*CONSTCOND*/0)
334
335#define MATCH_FAMILY(x, y, w) \
336	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
337#define MATCH(x, y, w) \
338	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
339
340void
341freeaddrinfo(struct addrinfo *ai)
342{
343	struct addrinfo *next;
344
345	do {
346		next = ai->ai_next;
347		if (ai->ai_canonname)
348			free(ai->ai_canonname);
349		/* no need to free(ai->ai_addr) */
350		free(ai);
351		ai = next;
352	} while (ai);
353}
354
355static int
356str2number(const char *p, int *portp)
357{
358	char *ep;
359	unsigned long v;
360
361	if (*p == '\0')
362		return -1;
363	ep = NULL;
364	errno = 0;
365	v = strtoul(p, &ep, 10);
366	if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX) {
367		*portp = v;
368		return 0;
369	} else
370		return -1;
371}
372
373int
374getaddrinfo(const char *hostname, const char *servname,
375    const struct addrinfo *hints, struct addrinfo **res)
376{
377	struct addrinfo sentinel;
378	struct addrinfo *cur;
379	int error = 0;
380	struct addrinfo ai, ai0, *afai;
381	struct addrinfo *pai;
382	const struct afd *afd;
383	const struct explore *ex;
384	struct addrinfo *afailist[sizeof(afdl)/sizeof(afdl[0])];
385	struct addrinfo *afai_unspec;
386	int found;
387	int numeric = 0;
388
389	/* ensure we return NULL on errors */
390	*res = NULL;
391
392	memset(&ai, 0, sizeof(ai));
393
394	memset(afailist, 0, sizeof(afailist));
395	afai_unspec = NULL;
396
397	memset(&sentinel, 0, sizeof(sentinel));
398	cur = &sentinel;
399	pai = &ai;
400	pai->ai_flags = 0;
401	pai->ai_family = PF_UNSPEC;
402	pai->ai_socktype = ANY;
403	pai->ai_protocol = ANY;
404	pai->ai_addrlen = 0;
405	pai->ai_canonname = NULL;
406	pai->ai_addr = NULL;
407	pai->ai_next = NULL;
408
409	if (hostname == NULL && servname == NULL)
410		return EAI_NONAME;
411	if (hints) {
412		/* error check for hints */
413		if (hints->ai_addrlen || hints->ai_canonname ||
414		    hints->ai_addr || hints->ai_next)
415			ERR(EAI_BADHINTS); /* xxx */
416		if (hints->ai_flags & ~AI_MASK)
417			ERR(EAI_BADFLAGS);
418		switch (hints->ai_family) {
419		case PF_UNSPEC:
420		case PF_INET:
421#ifdef INET6
422		case PF_INET6:
423#endif
424			break;
425		default:
426			ERR(EAI_FAMILY);
427		}
428		memcpy(pai, hints, sizeof(*pai));
429
430		/*
431		 * if both socktype/protocol are specified, check if they
432		 * are meaningful combination.
433		 */
434		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
435			for (ex = explore; ex->e_af >= 0; ex++) {
436				if (!MATCH_FAMILY(pai->ai_family, ex->e_af,
437				    WILD_AF(ex)))
438					continue;
439				if (!MATCH(pai->ai_socktype, ex->e_socktype,
440				    WILD_SOCKTYPE(ex)))
441					continue;
442				if (!MATCH(pai->ai_protocol, ex->e_protocol,
443				    WILD_PROTOCOL(ex)))
444					continue;
445
446				/* matched */
447				break;
448			}
449
450			if (ex->e_af < 0)
451				ERR(EAI_BADHINTS);
452		}
453	}
454
455	/*
456	 * RFC 3493: AI_ALL and AI_V4MAPPED are effective only against
457	 * AF_INET6 query.  They need to be ignored if specified in other
458	 * occassions.
459	 */
460	switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
461	case AI_V4MAPPED:
462	case AI_ALL | AI_V4MAPPED:
463#ifdef INET6
464		if (pai->ai_family != AF_INET6)
465			pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
466		break;
467#endif
468	case AI_ALL:
469		pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
470		break;
471	}
472
473	/*
474	 * check for special cases.  (1) numeric servname is disallowed if
475	 * socktype/protocol are left unspecified. (2) servname is disallowed
476	 * for raw and other inet{,6} sockets.
477	 */
478	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
479#ifdef PF_INET6
480	    || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
481#endif
482	    ) {
483		ai0 = *pai;	/* backup *pai */
484
485		if (pai->ai_family == PF_UNSPEC) {
486#ifdef PF_INET6
487			pai->ai_family = PF_INET6;
488#else
489			pai->ai_family = PF_INET;
490#endif
491		}
492		error = get_portmatch(pai, servname);
493		if (error)
494			goto bad;
495
496		*pai = ai0;
497	}
498
499	ai0 = *pai;
500
501	/*
502	 * NULL hostname, or numeric hostname.
503	 * If numeric representation of AF1 can be interpreted as FQDN
504	 * representation of AF2, we need to think again about the code below.
505	 */
506	found = 0;
507	for (afd = afdl; afd->a_af; afd++) {
508		*pai = ai0;
509
510		if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1))
511			continue;
512
513		if (pai->ai_family == PF_UNSPEC)
514			pai->ai_family = afd->a_af;
515
516		if (hostname == NULL) {
517			error = explore_null(pai, servname,
518			    &afailist[afd - afdl]);
519
520			/*
521			 * Errors from explore_null should be unexpected and
522			 * be caught to avoid returning an incomplete result.
523			 */
524			if (error != 0)
525				goto bad;
526		} else {
527			error = explore_numeric_scope(pai, hostname, servname,
528			    &afailist[afd - afdl]);
529
530			/*
531			 * explore_numeric_scope returns an error for address
532			 * families that do not match that of hostname.
533			 * Thus we should not catch the error at this moment.
534			 */
535		}
536
537		if (!error && afailist[afd - afdl])
538			found++;
539	}
540	if (found) {
541		numeric = 1;
542		goto globcopy;
543	}
544
545	if (hostname == NULL)
546		ERR(EAI_NONAME);	/* used to be EAI_NODATA */
547	if (pai->ai_flags & AI_NUMERICHOST)
548		ERR(EAI_NONAME);
549
550	if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0))
551		ERR(EAI_FAIL);
552
553	/*
554	 * hostname as alphabetical name.
555	 */
556	*pai = ai0;
557	error = explore_fqdn(pai, hostname, servname, &afai_unspec);
558
559globcopy:
560	for (ex = explore; ex->e_af >= 0; ex++) {
561		*pai = ai0;
562
563		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
564			continue;
565		if (!MATCH(pai->ai_socktype, ex->e_socktype,
566		    WILD_SOCKTYPE(ex)))
567			continue;
568		if (!MATCH(pai->ai_protocol, ex->e_protocol,
569		    WILD_PROTOCOL(ex)))
570			continue;
571
572		if (pai->ai_family == PF_UNSPEC)
573			pai->ai_family = ex->e_af;
574		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
575			pai->ai_socktype = ex->e_socktype;
576		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
577			pai->ai_protocol = ex->e_protocol;
578
579		/*
580		 * if the servname does not match socktype/protocol, ignore it.
581		 */
582		if (get_portmatch(pai, servname) != 0)
583			continue;
584
585		if (afai_unspec)
586			afai = afai_unspec;
587		else {
588			if ((afd = find_afd(pai->ai_family)) == NULL)
589				continue;
590			/* XXX assumes that afd points inside afdl[] */
591			afai = afailist[afd - afdl];
592		}
593		if (!afai)
594			continue;
595
596		error = explore_copy(pai, afai, &cur->ai_next);
597		if (error != 0)
598			goto bad;
599
600		while (cur && cur->ai_next)
601			cur = cur->ai_next;
602	}
603
604	/*
605	 * ensure we return either:
606	 * - error == 0, non-NULL *res
607	 * - error != 0, NULL *res
608	 */
609	if (error == 0) {
610		if (sentinel.ai_next) {
611			/*
612			 * If the returned entry is for an active connection,
613			 * and the given name is not numeric, reorder the
614			 * list, so that the application would try the list
615			 * in the most efficient order.  Since the head entry
616			 * of the original list may contain ai_canonname and
617			 * that entry may be moved elsewhere in the new list,
618			 * we keep the pointer and will  restore it in the new
619			 * head entry.  (Note that RFC3493 requires the head
620			 * entry store it when requested by the caller).
621			 */
622			if (hints == NULL || !(hints->ai_flags & AI_PASSIVE)) {
623				if (!numeric) {
624					char *canonname;
625
626					canonname =
627					    sentinel.ai_next->ai_canonname;
628					sentinel.ai_next->ai_canonname = NULL;
629					(void)reorder(&sentinel);
630					if (sentinel.ai_next->ai_canonname ==
631					    NULL) {
632						sentinel.ai_next->ai_canonname
633						    = canonname;
634					} else if (canonname != NULL)
635						free(canonname);
636				}
637			}
638			*res = sentinel.ai_next;
639		} else
640			error = EAI_FAIL;
641	}
642
643bad:
644	if (afai_unspec)
645		freeaddrinfo(afai_unspec);
646	for (afd = afdl; afd->a_af; afd++) {
647		if (afailist[afd - afdl])
648			freeaddrinfo(afailist[afd - afdl]);
649	}
650	if (!*res)
651		if (sentinel.ai_next)
652			freeaddrinfo(sentinel.ai_next);
653
654	return (error);
655}
656
657static int
658reorder(struct addrinfo *sentinel)
659{
660	struct addrinfo *ai, **aip;
661	struct ai_order *aio;
662	int i, n;
663	struct policyhead policyhead;
664
665	/* count the number of addrinfo elements for sorting. */
666	for (n = 0, ai = sentinel->ai_next; ai != NULL; ai = ai->ai_next, n++)
667		;
668
669	/*
670	 * If the number is small enough, we can skip the reordering process.
671	 */
672	if (n <= 1)
673		return(n);
674
675	/* allocate a temporary array for sort and initialization of it. */
676	if ((aio = calloc(n, sizeof(*aio))) == NULL)
677		return(n);	/* give up reordering */
678
679	/* retrieve address selection policy from the kernel */
680	TAILQ_INIT(&policyhead);
681	if (!get_addrselectpolicy(&policyhead)) {
682		/* no policy is installed into kernel, we don't sort. */
683		free(aio);
684		return (n);
685	}
686
687	for (i = 0, ai = sentinel->ai_next; i < n; ai = ai->ai_next, i++) {
688		aio[i].aio_ai = ai;
689		aio[i].aio_dstscope = gai_addr2scopetype(ai->ai_addr);
690		aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr,
691							      &policyhead);
692		set_source(&aio[i], &policyhead);
693		aio[i].aio_initial_sequence = i;
694	}
695
696	/* perform sorting. */
697	qsort(aio, n, sizeof(*aio), comp_dst);
698
699	/* reorder the addrinfo chain. */
700	for (i = 0, aip = &sentinel->ai_next; i < n; i++) {
701		*aip = aio[i].aio_ai;
702		aip = &aio[i].aio_ai->ai_next;
703	}
704	*aip = NULL;
705
706	/* cleanup and return */
707	free(aio);
708	free_addrselectpolicy(&policyhead);
709	return(n);
710}
711
712static int
713get_addrselectpolicy(struct policyhead *head)
714{
715#ifdef INET6
716	int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_ADDRCTLPOLICY };
717	size_t l;
718	char *buf;
719	struct in6_addrpolicy *pol, *ep;
720
721	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0)
722		return (0);
723	if (l == 0)
724		return (0);
725	if ((buf = malloc(l)) == NULL)
726		return (0);
727	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) {
728		free(buf);
729		return (0);
730	}
731
732	ep = (struct in6_addrpolicy *)(buf + l);
733	for (pol = (struct in6_addrpolicy *)buf; pol + 1 <= ep; pol++) {
734		struct policyqueue *new;
735
736		if ((new = malloc(sizeof(*new))) == NULL) {
737			free_addrselectpolicy(head); /* make the list empty */
738			break;
739		}
740		new->pc_policy = *pol;
741		TAILQ_INSERT_TAIL(head, new, pc_entry);
742	}
743
744	free(buf);
745	return (1);
746#else
747	return (0);
748#endif
749}
750
751static void
752free_addrselectpolicy(struct policyhead *head)
753{
754	struct policyqueue *ent, *nent;
755
756	for (ent = TAILQ_FIRST(head); ent; ent = nent) {
757		nent = TAILQ_NEXT(ent, pc_entry);
758		TAILQ_REMOVE(head, ent, pc_entry);
759		free(ent);
760	}
761}
762
763static struct policyqueue *
764match_addrselectpolicy(struct sockaddr *addr, struct policyhead *head)
765{
766#ifdef INET6
767	struct policyqueue *ent, *bestent = NULL;
768	struct in6_addrpolicy *pol;
769	int matchlen, bestmatchlen = -1;
770	u_char *mp, *ep, *k, *p, m;
771	struct sockaddr_in6 key;
772
773	switch(addr->sa_family) {
774	case AF_INET6:
775		key = *(struct sockaddr_in6 *)addr;
776		break;
777	case AF_INET:
778		/* convert the address into IPv4-mapped IPv6 address. */
779		memset(&key, 0, sizeof(key));
780		key.sin6_family = AF_INET6;
781		key.sin6_len = sizeof(key);
782		_map_v4v6_address(
783		    (char *)&((struct sockaddr_in *)addr)->sin_addr,
784		    (char *)&key.sin6_addr);
785		break;
786	default:
787		return(NULL);
788	}
789
790	for (ent = TAILQ_FIRST(head); ent; ent = TAILQ_NEXT(ent, pc_entry)) {
791		pol = &ent->pc_policy;
792		matchlen = 0;
793
794		mp = (u_char *)&pol->addrmask.sin6_addr;
795		ep = mp + 16;	/* XXX: scope field? */
796		k = (u_char *)&key.sin6_addr;
797		p = (u_char *)&pol->addr.sin6_addr;
798		for (; mp < ep && *mp; mp++, k++, p++) {
799			m = *mp;
800			if ((*k & m) != *p)
801				goto next; /* not match */
802			if (m == 0xff) /* short cut for a typical case */
803				matchlen += 8;
804			else {
805				while (m >= 0x80) {
806					matchlen++;
807					m <<= 1;
808				}
809			}
810		}
811
812		/* matched.  check if this is better than the current best. */
813		if (matchlen > bestmatchlen) {
814			bestent = ent;
815			bestmatchlen = matchlen;
816		}
817
818	  next:
819		continue;
820	}
821
822	return(bestent);
823#else
824	return(NULL);
825#endif
826
827}
828
829static void
830set_source(struct ai_order *aio, struct policyhead *ph)
831{
832	struct addrinfo ai = *aio->aio_ai;
833	struct sockaddr_storage ss;
834	socklen_t srclen;
835	int s;
836
837	/* set unspec ("no source is available"), just in case */
838	aio->aio_srcsa.sa_family = AF_UNSPEC;
839	aio->aio_srcscope = -1;
840
841	switch(ai.ai_family) {
842	case AF_INET:
843#ifdef INET6
844	case AF_INET6:
845#endif
846		break;
847	default:		/* ignore unsupported AFs explicitly */
848		return;
849	}
850
851	/* XXX: make a dummy addrinfo to call connect() */
852	ai.ai_socktype = SOCK_DGRAM;
853	ai.ai_protocol = IPPROTO_UDP; /* is UDP too specific? */
854	ai.ai_next = NULL;
855	memset(&ss, 0, sizeof(ss));
856	memcpy(&ss, ai.ai_addr, ai.ai_addrlen);
857	ai.ai_addr = (struct sockaddr *)&ss;
858	get_port(&ai, "1", 0);
859
860	/* open a socket to get the source address for the given dst */
861	if ((s = _socket(ai.ai_family, ai.ai_socktype | SOCK_CLOEXEC,
862	    ai.ai_protocol)) < 0)
863		return;		/* give up */
864#ifdef INET6
865	if (ai.ai_family == AF_INET6) {
866		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai.ai_addr;
867		int off = 0;
868
869		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
870			(void)_setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
871			    (char *)&off, sizeof(off));
872	}
873#endif
874	if (_connect(s, ai.ai_addr, ai.ai_addrlen) < 0)
875		goto cleanup;
876	srclen = ai.ai_addrlen;
877	if (_getsockname(s, &aio->aio_srcsa, &srclen) < 0) {
878		aio->aio_srcsa.sa_family = AF_UNSPEC;
879		goto cleanup;
880	}
881	aio->aio_srcscope = gai_addr2scopetype(&aio->aio_srcsa);
882	aio->aio_srcpolicy = match_addrselectpolicy(&aio->aio_srcsa, ph);
883	aio->aio_matchlen = matchlen(&aio->aio_srcsa, aio->aio_ai->ai_addr);
884#ifdef INET6
885	if (ai.ai_family == AF_INET6) {
886		struct in6_ifreq ifr6;
887		u_int32_t flags6;
888
889		memset(&ifr6, 0, sizeof(ifr6));
890		memcpy(&ifr6.ifr_addr, ai.ai_addr, ai.ai_addrlen);
891		if (_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == 0) {
892			flags6 = ifr6.ifr_ifru.ifru_flags6;
893			if ((flags6 & IN6_IFF_DEPRECATED))
894				aio->aio_srcflag |= AIO_SRCFLAG_DEPRECATED;
895		}
896	}
897#endif
898
899  cleanup:
900	_close(s);
901	return;
902}
903
904static int
905matchlen(struct sockaddr *src, struct sockaddr *dst)
906{
907	int match = 0;
908	u_char *s, *d;
909	u_char *lim, r;
910	int addrlen;
911
912	switch (src->sa_family) {
913#ifdef INET6
914	case AF_INET6:
915		s = (u_char *)&((struct sockaddr_in6 *)src)->sin6_addr;
916		d = (u_char *)&((struct sockaddr_in6 *)dst)->sin6_addr;
917		addrlen = sizeof(struct in6_addr);
918		lim = s + addrlen;
919		break;
920#endif
921	case AF_INET:
922		s = (u_char *)&((struct sockaddr_in *)src)->sin_addr;
923		d = (u_char *)&((struct sockaddr_in *)dst)->sin_addr;
924		addrlen = sizeof(struct in_addr);
925		lim = s + addrlen;
926		break;
927	default:
928		return(0);
929	}
930
931	while (s < lim)
932		if ((r = (*d++ ^ *s++)) != 0) {
933			while ((r & 0x80) == 0) {
934				match++;
935				r <<= 1;
936			}
937			break;
938		} else
939			match += 8;
940	return(match);
941}
942
943static int
944comp_dst(const void *arg1, const void *arg2)
945{
946	const struct ai_order *dst1 = arg1, *dst2 = arg2;
947
948	/*
949	 * Rule 1: Avoid unusable destinations.
950	 * XXX: we currently do not consider if an appropriate route exists.
951	 */
952	if (dst1->aio_srcsa.sa_family != AF_UNSPEC &&
953	    dst2->aio_srcsa.sa_family == AF_UNSPEC) {
954		return(-1);
955	}
956	if (dst1->aio_srcsa.sa_family == AF_UNSPEC &&
957	    dst2->aio_srcsa.sa_family != AF_UNSPEC) {
958		return(1);
959	}
960
961	/* Rule 2: Prefer matching scope. */
962	if (dst1->aio_dstscope == dst1->aio_srcscope &&
963	    dst2->aio_dstscope != dst2->aio_srcscope) {
964		return(-1);
965	}
966	if (dst1->aio_dstscope != dst1->aio_srcscope &&
967	    dst2->aio_dstscope == dst2->aio_srcscope) {
968		return(1);
969	}
970
971	/* Rule 3: Avoid deprecated addresses. */
972	if (dst1->aio_srcsa.sa_family != AF_UNSPEC &&
973	    dst2->aio_srcsa.sa_family != AF_UNSPEC) {
974		if (!(dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) &&
975		    (dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) {
976			return(-1);
977		}
978		if ((dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) &&
979		    !(dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) {
980			return(1);
981		}
982	}
983
984	/* Rule 4: Prefer home addresses. */
985	/* XXX: not implemented yet */
986
987	/* Rule 5: Prefer matching label. */
988#ifdef INET6
989	if (dst1->aio_srcpolicy && dst1->aio_dstpolicy &&
990	    dst1->aio_srcpolicy->pc_policy.label ==
991	    dst1->aio_dstpolicy->pc_policy.label &&
992	    (dst2->aio_srcpolicy == NULL || dst2->aio_dstpolicy == NULL ||
993	     dst2->aio_srcpolicy->pc_policy.label !=
994	     dst2->aio_dstpolicy->pc_policy.label)) {
995		return(-1);
996	}
997	if (dst2->aio_srcpolicy && dst2->aio_dstpolicy &&
998	    dst2->aio_srcpolicy->pc_policy.label ==
999	    dst2->aio_dstpolicy->pc_policy.label &&
1000	    (dst1->aio_srcpolicy == NULL || dst1->aio_dstpolicy == NULL ||
1001	     dst1->aio_srcpolicy->pc_policy.label !=
1002	     dst1->aio_dstpolicy->pc_policy.label)) {
1003		return(1);
1004	}
1005#endif
1006
1007	/* Rule 6: Prefer higher precedence. */
1008#ifdef INET6
1009	if (dst1->aio_dstpolicy &&
1010	    (dst2->aio_dstpolicy == NULL ||
1011	     dst1->aio_dstpolicy->pc_policy.preced >
1012	     dst2->aio_dstpolicy->pc_policy.preced)) {
1013		return(-1);
1014	}
1015	if (dst2->aio_dstpolicy &&
1016	    (dst1->aio_dstpolicy == NULL ||
1017	     dst2->aio_dstpolicy->pc_policy.preced >
1018	     dst1->aio_dstpolicy->pc_policy.preced)) {
1019		return(1);
1020	}
1021#endif
1022
1023	/* Rule 7: Prefer native transport. */
1024	/* XXX: not implemented yet */
1025
1026	/* Rule 8: Prefer smaller scope. */
1027	if (dst1->aio_dstscope >= 0 &&
1028	    dst1->aio_dstscope < dst2->aio_dstscope) {
1029		return(-1);
1030	}
1031	if (dst2->aio_dstscope >= 0 &&
1032	    dst2->aio_dstscope < dst1->aio_dstscope) {
1033		return(1);
1034	}
1035
1036	/*
1037	 * Rule 9: Use longest matching prefix.
1038	 * We compare the match length in a same AF only.
1039	 */
1040	if (dst1->aio_ai->ai_addr->sa_family ==
1041	    dst2->aio_ai->ai_addr->sa_family &&
1042	    dst1->aio_ai->ai_addr->sa_family != AF_INET) {
1043		if (dst1->aio_matchlen > dst2->aio_matchlen) {
1044			return(-1);
1045		}
1046		if (dst1->aio_matchlen < dst2->aio_matchlen) {
1047			return(1);
1048		}
1049	}
1050
1051	/* Rule 10: Otherwise, leave the order unchanged. */
1052
1053	/*
1054	 * Note that qsort is unstable; so, we can't return zero and
1055	 * expect the order to be unchanged.
1056	 * That also means we can't depend on the current position of
1057	 * dst2 being after dst1.  We must enforce the initial order
1058	 * with an explicit compare on the original position.
1059	 * The qsort specification requires that "When the same objects
1060	 * (consisting of width bytes, irrespective of their current
1061	 * positions in the array) are passed more than once to the
1062	 * comparison function, the results shall be consistent with one
1063	 * another."
1064	 * In other words, If A < B, then we must also return B > A.
1065	 */
1066	if (dst2->aio_initial_sequence < dst1->aio_initial_sequence)
1067		return(1);
1068
1069	return(-1);
1070}
1071
1072/*
1073 * Copy from scope.c.
1074 * XXX: we should standardize the functions and link them as standard
1075 * library.
1076 */
1077static int
1078gai_addr2scopetype(struct sockaddr *sa)
1079{
1080#ifdef INET6
1081	struct sockaddr_in6 *sa6;
1082#endif
1083	struct sockaddr_in *sa4;
1084
1085	switch(sa->sa_family) {
1086#ifdef INET6
1087	case AF_INET6:
1088		sa6 = (struct sockaddr_in6 *)sa;
1089		if (IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) {
1090			/* just use the scope field of the multicast address */
1091			return(sa6->sin6_addr.s6_addr[2] & 0x0f);
1092		}
1093		/*
1094		 * Unicast addresses: map scope type to corresponding scope
1095		 * value defined for multcast addresses.
1096		 * XXX: hardcoded scope type values are bad...
1097		 */
1098		if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
1099			return(1); /* node local scope */
1100		if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr))
1101			return(2); /* link-local scope */
1102		if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr))
1103			return(5); /* site-local scope */
1104		return(14);	/* global scope */
1105		break;
1106#endif
1107	case AF_INET:
1108		/*
1109		 * IPv4 pseudo scoping according to RFC 3484.
1110		 */
1111		sa4 = (struct sockaddr_in *)sa;
1112		/* IPv4 autoconfiguration addresses have link-local scope. */
1113		if (((u_char *)&sa4->sin_addr)[0] == 169 &&
1114		    ((u_char *)&sa4->sin_addr)[1] == 254)
1115			return(2);
1116		/* Private addresses have site-local scope. */
1117		if (((u_char *)&sa4->sin_addr)[0] == 10 ||
1118		    (((u_char *)&sa4->sin_addr)[0] == 172 &&
1119		     (((u_char *)&sa4->sin_addr)[1] & 0xf0) == 16) ||
1120		    (((u_char *)&sa4->sin_addr)[0] == 192 &&
1121		     ((u_char *)&sa4->sin_addr)[1] == 168))
1122			return(14);	/* XXX: It should be 5 unless NAT */
1123		/* Loopback addresses have link-local scope. */
1124		if (((u_char *)&sa4->sin_addr)[0] == 127)
1125			return(2);
1126		return(14);
1127		break;
1128	default:
1129		errno = EAFNOSUPPORT; /* is this a good error? */
1130		return(-1);
1131	}
1132}
1133
1134static int
1135explore_copy(const struct addrinfo *pai, const struct addrinfo *src0,
1136    struct addrinfo **res)
1137{
1138	int error;
1139	struct addrinfo sentinel, *cur;
1140	const struct addrinfo *src;
1141
1142	error = 0;
1143	sentinel.ai_next = NULL;
1144	cur = &sentinel;
1145
1146	for (src = src0; src != NULL; src = src->ai_next) {
1147		if (src->ai_family != pai->ai_family)
1148			continue;
1149
1150		cur->ai_next = copy_ai(src);
1151		if (!cur->ai_next) {
1152			error = EAI_MEMORY;
1153			goto fail;
1154		}
1155
1156		cur->ai_next->ai_socktype = pai->ai_socktype;
1157		cur->ai_next->ai_protocol = pai->ai_protocol;
1158		cur = cur->ai_next;
1159	}
1160
1161	*res = sentinel.ai_next;
1162	return 0;
1163
1164fail:
1165	freeaddrinfo(sentinel.ai_next);
1166	return error;
1167}
1168
1169/*
1170 * hostname == NULL.
1171 * passive socket -> anyaddr (0.0.0.0 or ::)
1172 * non-passive socket -> localhost (127.0.0.1 or ::1)
1173 */
1174static int
1175explore_null(const struct addrinfo *pai, const char *servname,
1176    struct addrinfo **res)
1177{
1178	int s;
1179	const struct afd *afd;
1180	struct addrinfo *ai;
1181	int error;
1182
1183	*res = NULL;
1184	ai = NULL;
1185
1186	/*
1187	 * filter out AFs that are not supported by the kernel
1188	 * XXX errno?
1189	 */
1190	s = _socket(pai->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1191	if (s < 0) {
1192		if (errno != EMFILE)
1193			return 0;
1194	} else
1195		_close(s);
1196
1197	afd = find_afd(pai->ai_family);
1198	if (afd == NULL)
1199		return 0;
1200
1201	if (pai->ai_flags & AI_PASSIVE) {
1202		GET_AI(ai, afd, afd->a_addrany);
1203		GET_PORT(ai, servname);
1204	} else {
1205		GET_AI(ai, afd, afd->a_loopback);
1206		GET_PORT(ai, servname);
1207	}
1208
1209	*res = ai;
1210	return 0;
1211
1212free:
1213	if (ai != NULL)
1214		freeaddrinfo(ai);
1215	return error;
1216}
1217
1218/*
1219 * numeric hostname
1220 */
1221static int
1222explore_numeric(const struct addrinfo *pai, const char *hostname,
1223    const char *servname, struct addrinfo **res, const char *canonname)
1224{
1225	const struct afd *afd;
1226	struct addrinfo *ai, ai0;
1227	int error;
1228	char pton[PTON_MAX];
1229
1230	*res = NULL;
1231	ai = NULL;
1232
1233	afd = find_afd(pai->ai_family);
1234	if (afd == NULL)
1235		return 0;
1236
1237	switch (afd->a_af) {
1238	case AF_INET:
1239		/*
1240		 * RFC3493 requires getaddrinfo() to accept AF_INET formats
1241		 * that are accepted by inet_addr() and its family.  The
1242		 * accepted forms includes the "classful" one, which inet_pton
1243		 * does not accept.  So we need to separate the case for
1244		 * AF_INET.
1245		 */
1246		if (inet_aton(hostname, (struct in_addr *)pton) != 1 ||
1247		    hostname[strspn(hostname, "0123456789.xabcdefXABCDEF")] != '\0')
1248			return 0;
1249		break;
1250	default:
1251		if (inet_pton(afd->a_af, hostname, pton) != 1) {
1252			if (pai->ai_family != AF_INET6 ||
1253			    (pai->ai_flags & AI_V4MAPPED) != AI_V4MAPPED)
1254				return 0;
1255			if (inet_aton(hostname, (struct in_addr *)pton) != 1)
1256				return 0;
1257			afd = &afdl[N_INET];
1258			ai0 = *pai;
1259			ai0.ai_family = AF_INET;
1260			pai = &ai0;
1261		}
1262		break;
1263	}
1264
1265	if (pai->ai_family == afd->a_af) {
1266		GET_AI(ai, afd, pton);
1267		GET_PORT(ai, servname);
1268		if ((pai->ai_flags & AI_CANONNAME)) {
1269			/*
1270			 * Set the numeric address itself as the canonical
1271			 * name, based on a clarification in RFC3493.
1272			 */
1273			GET_CANONNAME(ai, canonname);
1274		}
1275	} else {
1276		/*
1277		 * XXX: This should not happen since we already matched the AF
1278		 * by find_afd.
1279		 */
1280		ERR(EAI_FAMILY);
1281	}
1282
1283	*res = ai;
1284	return 0;
1285
1286free:
1287bad:
1288	if (ai != NULL)
1289		freeaddrinfo(ai);
1290	return error;
1291}
1292
1293/*
1294 * numeric hostname with scope
1295 */
1296static int
1297explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
1298    const char *servname, struct addrinfo **res)
1299{
1300#if !defined(SCOPE_DELIMITER) || !defined(INET6)
1301	return explore_numeric(pai, hostname, servname, res, hostname);
1302#else
1303	const struct afd *afd;
1304	struct addrinfo *cur;
1305	int error;
1306	char *cp, *hostname2 = NULL, *scope, *addr;
1307	struct sockaddr_in6 *sin6;
1308
1309	afd = find_afd(pai->ai_family);
1310	if (afd == NULL)
1311		return 0;
1312
1313	if (!afd->a_scoped)
1314		return explore_numeric(pai, hostname, servname, res, hostname);
1315
1316	cp = strchr(hostname, SCOPE_DELIMITER);
1317	if (cp == NULL)
1318		return explore_numeric(pai, hostname, servname, res, hostname);
1319
1320	/*
1321	 * Handle special case of <scoped_address><delimiter><scope id>
1322	 */
1323	hostname2 = strdup(hostname);
1324	if (hostname2 == NULL)
1325		return EAI_MEMORY;
1326	/* terminate at the delimiter */
1327	hostname2[cp - hostname] = '\0';
1328	addr = hostname2;
1329	scope = cp + 1;
1330
1331	error = explore_numeric(pai, addr, servname, res, hostname);
1332	if (error == 0) {
1333		u_int32_t scopeid;
1334
1335		for (cur = *res; cur; cur = cur->ai_next) {
1336			if (cur->ai_family != AF_INET6)
1337				continue;
1338			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
1339			if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
1340				free(hostname2);
1341				freeaddrinfo(*res);
1342				*res = NULL;
1343				return(EAI_NONAME); /* XXX: is return OK? */
1344			}
1345			sin6->sin6_scope_id = scopeid;
1346		}
1347	}
1348
1349	free(hostname2);
1350
1351	if (error && *res) {
1352		freeaddrinfo(*res);
1353		*res = NULL;
1354	}
1355	return error;
1356#endif
1357}
1358
1359static int
1360get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
1361{
1362	if ((pai->ai_flags & AI_CANONNAME) != 0) {
1363		ai->ai_canonname = strdup(str);
1364		if (ai->ai_canonname == NULL)
1365			return EAI_MEMORY;
1366	}
1367	return 0;
1368}
1369
1370static struct addrinfo *
1371get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
1372{
1373	char *p;
1374	struct addrinfo *ai;
1375#ifdef FAITH
1376	struct in6_addr faith_prefix;
1377	char *fp_str;
1378	int translate = 0;
1379#endif
1380#ifdef INET6
1381	struct in6_addr mapaddr;
1382#endif
1383
1384#ifdef FAITH
1385	/*
1386	 * Transfrom an IPv4 addr into a special IPv6 addr format for
1387	 * IPv6->IPv4 translation gateway. (only TCP is supported now)
1388	 *
1389	 * +-----------------------------------+------------+
1390	 * | faith prefix part (12 bytes)      | embedded   |
1391	 * |                                   | IPv4 addr part (4 bytes)
1392	 * +-----------------------------------+------------+
1393	 *
1394	 * faith prefix part is specified as ascii IPv6 addr format
1395	 * in environmental variable GAI.
1396	 * For FAITH to work correctly, routing to faith prefix must be
1397	 * setup toward a machine where a FAITH daemon operates.
1398	 * Also, the machine must enable some mechanizm
1399	 * (e.g. faith interface hack) to divert those packet with
1400	 * faith prefixed destination addr to user-land FAITH daemon.
1401	 */
1402	fp_str = getenv("GAI");
1403	if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 &&
1404	    afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) {
1405		u_int32_t v4a;
1406		u_int8_t v4a_top;
1407
1408		memcpy(&v4a, addr, sizeof v4a);
1409		v4a_top = v4a >> IN_CLASSA_NSHIFT;
1410		if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) &&
1411		    v4a_top != 0 && v4a != IN_LOOPBACKNET) {
1412			afd = &afdl[N_INET6];
1413			memcpy(&faith_prefix.s6_addr[12], addr,
1414			       sizeof(struct in_addr));
1415			translate = 1;
1416		}
1417	}
1418#endif
1419
1420#ifdef INET6
1421	if (afd->a_af == AF_INET && (pai->ai_flags & AI_V4MAPPED) != 0) {
1422		afd = &afdl[N_INET6];
1423		_map_v4v6_address(addr, (char *)&mapaddr);
1424		addr = (char *)&mapaddr;
1425	}
1426#endif
1427
1428	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
1429		+ (afd->a_socklen));
1430	if (ai == NULL)
1431		return NULL;
1432
1433	memcpy(ai, pai, sizeof(struct addrinfo));
1434	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
1435	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
1436	ai->ai_addr->sa_len = afd->a_socklen;
1437	ai->ai_addrlen = afd->a_socklen;
1438	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
1439	p = (char *)(void *)(ai->ai_addr);
1440#ifdef FAITH
1441	if (translate == 1)
1442		memcpy(p + afd->a_off, &faith_prefix, (size_t)afd->a_addrlen);
1443	else
1444#endif
1445	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
1446	return ai;
1447}
1448
1449/* XXX need to malloc() the same way we do from other functions! */
1450static struct addrinfo *
1451copy_ai(const struct addrinfo *pai)
1452{
1453	struct addrinfo *ai;
1454	size_t l;
1455
1456	l = sizeof(*ai) + pai->ai_addrlen;
1457	if ((ai = calloc(1, l)) == NULL)
1458		return NULL;
1459	memcpy(ai, pai, sizeof(*ai));
1460	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
1461	memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen);
1462
1463	if (pai->ai_canonname) {
1464		l = strlen(pai->ai_canonname) + 1;
1465		if ((ai->ai_canonname = malloc(l)) == NULL) {
1466			free(ai);
1467			return NULL;
1468		}
1469		strlcpy(ai->ai_canonname, pai->ai_canonname, l);
1470	} else {
1471		/* just to make sure */
1472		ai->ai_canonname = NULL;
1473	}
1474
1475	ai->ai_next = NULL;
1476
1477	return ai;
1478}
1479
1480static int
1481get_portmatch(const struct addrinfo *ai, const char *servname)
1482{
1483
1484	/* get_port does not touch first argument when matchonly == 1. */
1485	/* LINTED const cast */
1486	return get_port((struct addrinfo *)ai, servname, 1);
1487}
1488
1489static int
1490get_port(struct addrinfo *ai, const char *servname, int matchonly)
1491{
1492	const char *proto;
1493	struct servent *sp;
1494	int port, error;
1495	int allownumeric;
1496
1497	if (servname == NULL)
1498		return 0;
1499	switch (ai->ai_family) {
1500	case AF_INET:
1501#ifdef AF_INET6
1502	case AF_INET6:
1503#endif
1504		break;
1505	default:
1506		return 0;
1507	}
1508
1509	switch (ai->ai_socktype) {
1510	case SOCK_RAW:
1511		return EAI_SERVICE;
1512	case SOCK_DGRAM:
1513	case SOCK_STREAM:
1514	case SOCK_SEQPACKET:
1515		allownumeric = 1;
1516		break;
1517	case ANY:
1518		switch (ai->ai_family) {
1519		case AF_INET:
1520#ifdef AF_INET6
1521		case AF_INET6:
1522#endif
1523			allownumeric = 1;
1524			break;
1525		default:
1526			allownumeric = 0;
1527			break;
1528		}
1529		break;
1530	default:
1531		return EAI_SOCKTYPE;
1532	}
1533
1534	error = str2number(servname, &port);
1535	if (error == 0) {
1536		if (!allownumeric)
1537			return EAI_SERVICE;
1538		if (port < 0 || port > 65535)
1539			return EAI_SERVICE;
1540		port = htons(port);
1541	} else {
1542		if (ai->ai_flags & AI_NUMERICSERV)
1543			return EAI_NONAME;
1544
1545		switch (ai->ai_protocol) {
1546		case IPPROTO_UDP:
1547			proto = "udp";
1548			break;
1549		case IPPROTO_TCP:
1550			proto = "tcp";
1551			break;
1552		case IPPROTO_SCTP:
1553			proto = "sctp";
1554			break;
1555		case IPPROTO_UDPLITE:
1556			proto = "udplite";
1557			break;
1558		default:
1559			proto = NULL;
1560			break;
1561		}
1562
1563		if ((sp = getservbyname(servname, proto)) == NULL)
1564			return EAI_SERVICE;
1565		port = sp->s_port;
1566	}
1567
1568	if (!matchonly) {
1569		switch (ai->ai_family) {
1570		case AF_INET:
1571			((struct sockaddr_in *)(void *)
1572			    ai->ai_addr)->sin_port = port;
1573			break;
1574#ifdef INET6
1575		case AF_INET6:
1576			((struct sockaddr_in6 *)(void *)
1577			    ai->ai_addr)->sin6_port = port;
1578			break;
1579#endif
1580		}
1581	}
1582
1583	return 0;
1584}
1585
1586static const struct afd *
1587find_afd(int af)
1588{
1589	const struct afd *afd;
1590
1591	if (af == PF_UNSPEC)
1592		return NULL;
1593	for (afd = afdl; afd->a_af; afd++) {
1594		if (afd->a_af == af)
1595			return afd;
1596	}
1597	return NULL;
1598}
1599
1600/*
1601 * RFC 3493: AI_ADDRCONFIG check.  Determines which address families are
1602 * configured on the local system and correlates with pai->ai_family value.
1603 * If an address family is not configured on the system, it will not be
1604 * queried for.  For this purpose, loopback addresses are not considered
1605 * configured addresses.
1606 *
1607 * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with
1608 * _dns_getaddrinfo.
1609 */
1610static int
1611addrconfig(struct addrinfo *pai)
1612{
1613	struct ifaddrs *ifaddrs, *ifa;
1614	struct sockaddr_in *sin;
1615#ifdef INET6
1616	struct sockaddr_in6 *sin6;
1617#endif
1618	int seen_inet = 0, seen_inet6 = 0;
1619
1620	if (getifaddrs(&ifaddrs) != 0)
1621		return (0);
1622
1623	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
1624		if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_UP) == 0)
1625			continue;
1626		switch (ifa->ifa_addr->sa_family) {
1627		case AF_INET:
1628			if (seen_inet)
1629				continue;
1630			sin = (struct sockaddr_in *)(ifa->ifa_addr);
1631			if (htonl(sin->sin_addr.s_addr) == INADDR_LOOPBACK)
1632				continue;
1633			seen_inet = 1;
1634			break;
1635#ifdef INET6
1636		case AF_INET6:
1637			if (seen_inet6)
1638				continue;
1639			sin6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
1640			if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
1641				continue;
1642			if ((ifa->ifa_flags & IFT_LOOP) != 0 &&
1643			    IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
1644				continue;
1645			if (is_ifdisabled(ifa->ifa_name))
1646				continue;
1647			seen_inet6 = 1;
1648			break;
1649#endif
1650		}
1651	}
1652	freeifaddrs(ifaddrs);
1653
1654	switch(pai->ai_family) {
1655	case AF_INET6:
1656		return (seen_inet6);
1657	case AF_INET:
1658		return (seen_inet);
1659	case AF_UNSPEC:
1660		if (seen_inet == seen_inet6)
1661			return (seen_inet);
1662		pai->ai_family = seen_inet ? AF_INET : AF_INET6;
1663		return (1);
1664	}
1665	return (1);
1666}
1667
1668#ifdef INET6
1669static int
1670is_ifdisabled(char *name)
1671{
1672	struct in6_ndireq nd;
1673	int fd;
1674
1675	if ((fd = _socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0)
1676		return (-1);
1677	memset(&nd, 0, sizeof(nd));
1678	strlcpy(nd.ifname, name, sizeof(nd.ifname));
1679	if (_ioctl(fd, SIOCGIFINFO_IN6, &nd) < 0) {
1680		_close(fd);
1681		return (-1);
1682	}
1683	_close(fd);
1684	return ((nd.ndi.flags & ND6_IFF_IFDISABLED) != 0);
1685}
1686
1687/* convert a string to a scope identifier. XXX: IPv6 specific */
1688static int
1689ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
1690{
1691	u_long lscopeid;
1692	struct in6_addr *a6;
1693	char *ep;
1694
1695	a6 = &sin6->sin6_addr;
1696
1697	/* empty scopeid portion is invalid */
1698	if (*scope == '\0')
1699		return -1;
1700
1701	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
1702	    IN6_IS_ADDR_MC_NODELOCAL(a6)) {
1703		/*
1704		 * We currently assume a one-to-one mapping between links
1705		 * and interfaces, so we simply use interface indices for
1706		 * like-local scopes.
1707		 */
1708		*scopeid = if_nametoindex(scope);
1709		if (*scopeid == 0)
1710			goto trynumeric;
1711		return 0;
1712	}
1713
1714	/* still unclear about literal, allow numeric only - placeholder */
1715	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1716		goto trynumeric;
1717	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1718		goto trynumeric;
1719	else
1720		goto trynumeric;	/* global */
1721
1722	/* try to convert to a numeric id as a last resort */
1723  trynumeric:
1724	errno = 0;
1725	lscopeid = strtoul(scope, &ep, 10);
1726	*scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1727	if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1728		return 0;
1729	else
1730		return -1;
1731}
1732#endif
1733
1734
1735#ifdef NS_CACHING
1736static int
1737addrinfo_id_func(char *buffer, size_t *buffer_size, va_list ap,
1738    void *cache_mdata)
1739{
1740	res_state statp;
1741	u_long res_options;
1742
1743	const int op_id = 0;	/* identifies the getaddrinfo for the cache */
1744	char *hostname;
1745	struct addrinfo *hints;
1746
1747	char *p;
1748	int ai_flags, ai_family, ai_socktype, ai_protocol;
1749	size_t desired_size, size;
1750
1751	statp = __res_state();
1752	res_options = statp->options & (RES_RECURSE | RES_DEFNAMES |
1753	    RES_DNSRCH | RES_NOALIASES | RES_USE_INET6);
1754
1755	hostname = va_arg(ap, char *);
1756	hints = va_arg(ap, struct addrinfo *);
1757
1758	desired_size = sizeof(res_options) + sizeof(int) + sizeof(int) * 4;
1759	if (hostname != NULL) {
1760		size = strlen(hostname);
1761		desired_size += size + 1;
1762	} else
1763		size = 0;
1764
1765	if (desired_size > *buffer_size) {
1766		*buffer_size = desired_size;
1767		return (NS_RETURN);
1768	}
1769
1770	if (hints == NULL)
1771		ai_flags = ai_family = ai_socktype = ai_protocol = 0;
1772	else {
1773		ai_flags = hints->ai_flags;
1774		ai_family = hints->ai_family;
1775		ai_socktype = hints->ai_socktype;
1776		ai_protocol = hints->ai_protocol;
1777	}
1778
1779	p = buffer;
1780	memcpy(p, &res_options, sizeof(res_options));
1781	p += sizeof(res_options);
1782
1783	memcpy(p, &op_id, sizeof(int));
1784	p += sizeof(int);
1785
1786	memcpy(p, &ai_flags, sizeof(int));
1787	p += sizeof(int);
1788
1789	memcpy(p, &ai_family, sizeof(int));
1790	p += sizeof(int);
1791
1792	memcpy(p, &ai_socktype, sizeof(int));
1793	p += sizeof(int);
1794
1795	memcpy(p, &ai_protocol, sizeof(int));
1796	p += sizeof(int);
1797
1798	if (hostname != NULL)
1799		memcpy(p, hostname, size);
1800
1801	*buffer_size = desired_size;
1802	return (NS_SUCCESS);
1803}
1804
1805static int
1806addrinfo_marshal_func(char *buffer, size_t *buffer_size, void *retval,
1807    va_list ap, void *cache_mdata)
1808{
1809	struct addrinfo	*ai, *cai;
1810	char *p;
1811	size_t desired_size, size, ai_size;
1812
1813	ai = *((struct addrinfo **)retval);
1814
1815	desired_size = sizeof(size_t);
1816	ai_size = 0;
1817	for (cai = ai; cai != NULL; cai = cai->ai_next) {
1818		desired_size += sizeof(struct addrinfo) + cai->ai_addrlen;
1819		if (cai->ai_canonname != NULL)
1820			desired_size += sizeof(size_t) +
1821			    strlen(cai->ai_canonname);
1822		++ai_size;
1823	}
1824
1825	if (desired_size > *buffer_size) {
1826		/* this assignment is here for future use */
1827		errno = ERANGE;
1828		*buffer_size = desired_size;
1829		return (NS_RETURN);
1830	}
1831
1832	memset(buffer, 0, desired_size);
1833	p = buffer;
1834
1835	memcpy(p, &ai_size, sizeof(size_t));
1836	p += sizeof(size_t);
1837	for (cai = ai; cai != NULL; cai = cai->ai_next) {
1838		memcpy(p, cai, sizeof(struct addrinfo));
1839		p += sizeof(struct addrinfo);
1840
1841		memcpy(p, cai->ai_addr, cai->ai_addrlen);
1842		p += cai->ai_addrlen;
1843
1844		if (cai->ai_canonname != NULL) {
1845			size = strlen(cai->ai_canonname);
1846			memcpy(p, &size, sizeof(size_t));
1847			p += sizeof(size_t);
1848
1849			memcpy(p, cai->ai_canonname, size);
1850			p += size;
1851		}
1852	}
1853
1854	return (NS_SUCCESS);
1855}
1856
1857static int
1858addrinfo_unmarshal_func(char *buffer, size_t buffer_size, void *retval,
1859    va_list ap, void *cache_mdata)
1860{
1861	struct addrinfo	new_ai, *result, *sentinel, *lasts;
1862
1863	char *p;
1864	size_t ai_size, ai_i, size;
1865
1866	p = buffer;
1867	memcpy(&ai_size, p, sizeof(size_t));
1868	p += sizeof(size_t);
1869
1870	result = NULL;
1871	lasts = NULL;
1872	for (ai_i = 0; ai_i < ai_size; ++ai_i) {
1873		memcpy(&new_ai, p, sizeof(struct addrinfo));
1874		p += sizeof(struct addrinfo);
1875		size = new_ai.ai_addrlen + sizeof(struct addrinfo) +
1876			_ALIGNBYTES;
1877
1878		sentinel = calloc(1, size);
1879
1880		memcpy(sentinel, &new_ai, sizeof(struct addrinfo));
1881		sentinel->ai_addr = (struct sockaddr *)_ALIGN((char *)sentinel +
1882		    sizeof(struct addrinfo));
1883
1884		memcpy(sentinel->ai_addr, p, new_ai.ai_addrlen);
1885		p += new_ai.ai_addrlen;
1886
1887		if (new_ai.ai_canonname != NULL) {
1888			memcpy(&size, p, sizeof(size_t));
1889			p += sizeof(size_t);
1890
1891			sentinel->ai_canonname = calloc(1, size + 1);
1892
1893			memcpy(sentinel->ai_canonname, p, size);
1894			p += size;
1895		}
1896
1897		if (result == NULL) {
1898			result = sentinel;
1899			lasts = sentinel;
1900		} else {
1901			lasts->ai_next = sentinel;
1902			lasts = sentinel;
1903		}
1904	}
1905
1906	*((struct addrinfo **)retval) = result;
1907	return (NS_SUCCESS);
1908}
1909#endif /* NS_CACHING */
1910
1911/*
1912 * FQDN hostname, DNS lookup
1913 */
1914static int
1915explore_fqdn(const struct addrinfo *pai, const char *hostname,
1916    const char *servname, struct addrinfo **res)
1917{
1918	struct addrinfo *result;
1919	struct addrinfo *cur;
1920	int error = 0;
1921
1922#ifdef NS_CACHING
1923	static const nss_cache_info cache_info =
1924	NS_COMMON_CACHE_INFO_INITIALIZER(
1925		hosts, NULL, addrinfo_id_func, addrinfo_marshal_func,
1926		addrinfo_unmarshal_func);
1927#endif
1928	static const ns_dtab dtab[] = {
1929		NS_FILES_CB(_files_getaddrinfo, NULL)
1930		{ NSSRC_DNS, _dns_getaddrinfo, NULL },	/* force -DHESIOD */
1931		NS_NIS_CB(_yp_getaddrinfo, NULL)
1932#ifdef NS_CACHING
1933		NS_CACHE_CB(&cache_info)
1934#endif
1935		{ 0 }
1936	};
1937
1938	result = NULL;
1939
1940	/*
1941	 * if the servname does not match socktype/protocol, ignore it.
1942	 */
1943	if (get_portmatch(pai, servname) != 0)
1944		return 0;
1945
1946	switch (_nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
1947			default_dns_files, hostname, pai)) {
1948	case NS_TRYAGAIN:
1949		error = EAI_AGAIN;
1950		goto free;
1951	case NS_UNAVAIL:
1952		error = EAI_FAIL;
1953		goto free;
1954	case NS_NOTFOUND:
1955		error = EAI_NONAME;
1956		goto free;
1957	case NS_SUCCESS:
1958		error = 0;
1959		for (cur = result; cur; cur = cur->ai_next) {
1960			GET_PORT(cur, servname);
1961			/* canonname should be filled already */
1962		}
1963		break;
1964	}
1965
1966	*res = result;
1967
1968	return 0;
1969
1970free:
1971	if (result)
1972		freeaddrinfo(result);
1973	return error;
1974}
1975
1976#ifdef DEBUG
1977static const char AskedForGot[] =
1978	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1979#endif
1980
1981static struct addrinfo *
1982getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
1983    const struct addrinfo *pai, res_state res)
1984{
1985	struct addrinfo sentinel, *cur;
1986	struct addrinfo ai;
1987	const struct afd *afd;
1988	char *canonname;
1989	const HEADER *hp;
1990	const u_char *cp;
1991	int n;
1992	const u_char *eom;
1993	char *bp, *ep;
1994	int type, class, ancount, qdcount;
1995	int haveanswer, had_error;
1996	char tbuf[MAXDNAME];
1997	int (*name_ok)(const char *);
1998	char hostbuf[8*1024];
1999
2000	memset(&sentinel, 0, sizeof(sentinel));
2001	cur = &sentinel;
2002
2003	canonname = NULL;
2004	eom = answer->buf + anslen;
2005	switch (qtype) {
2006	case T_A:
2007	case T_AAAA:
2008	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
2009		name_ok = res_hnok;
2010		break;
2011	default:
2012		return (NULL);	/* XXX should be abort(); */
2013	}
2014	/*
2015	 * find first satisfactory answer
2016	 */
2017	hp = &answer->hdr;
2018	ancount = ntohs(hp->ancount);
2019	qdcount = ntohs(hp->qdcount);
2020	bp = hostbuf;
2021	ep = hostbuf + sizeof hostbuf;
2022	cp = answer->buf + HFIXEDSZ;
2023	if (qdcount != 1) {
2024		RES_SET_H_ERRNO(res, NO_RECOVERY);
2025		return (NULL);
2026	}
2027	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
2028	if ((n < 0) || !(*name_ok)(bp)) {
2029		RES_SET_H_ERRNO(res, NO_RECOVERY);
2030		return (NULL);
2031	}
2032	cp += n + QFIXEDSZ;
2033	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
2034		/* res_send() has already verified that the query name is the
2035		 * same as the one we sent; this just gets the expanded name
2036		 * (i.e., with the succeeding search-domain tacked on).
2037		 */
2038		n = strlen(bp) + 1;		/* for the \0 */
2039		if (n >= MAXHOSTNAMELEN) {
2040			RES_SET_H_ERRNO(res, NO_RECOVERY);
2041			return (NULL);
2042		}
2043		canonname = bp;
2044		bp += n;
2045		/* The qname can be abbreviated, but h_name is now absolute. */
2046		qname = canonname;
2047	}
2048	haveanswer = 0;
2049	had_error = 0;
2050	while (ancount-- > 0 && cp < eom && !had_error) {
2051		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
2052		if ((n < 0) || !(*name_ok)(bp)) {
2053			had_error++;
2054			continue;
2055		}
2056		cp += n;			/* name */
2057		type = _getshort(cp);
2058 		cp += INT16SZ;			/* type */
2059		class = _getshort(cp);
2060 		cp += INT16SZ + INT32SZ;	/* class, TTL */
2061		n = _getshort(cp);
2062		cp += INT16SZ;			/* len */
2063		if (class != C_IN) {
2064			/* XXX - debug? syslog? */
2065			cp += n;
2066			continue;		/* XXX - had_error++ ? */
2067		}
2068		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
2069		    type == T_CNAME) {
2070			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
2071			if ((n < 0) || !(*name_ok)(tbuf)) {
2072				had_error++;
2073				continue;
2074			}
2075			cp += n;
2076			/* Get canonical name. */
2077			n = strlen(tbuf) + 1;	/* for the \0 */
2078			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
2079				had_error++;
2080				continue;
2081			}
2082			strlcpy(bp, tbuf, ep - bp);
2083			canonname = bp;
2084			bp += n;
2085			continue;
2086		}
2087		if (qtype == T_ANY) {
2088			if (!(type == T_A || type == T_AAAA)) {
2089				cp += n;
2090				continue;
2091			}
2092		} else if (type != qtype) {
2093#ifdef DEBUG
2094			if (type != T_KEY && type != T_SIG &&
2095			    type != ns_t_dname)
2096				syslog(LOG_NOTICE|LOG_AUTH,
2097	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
2098				       qname, p_class(C_IN), p_type(qtype),
2099				       p_type(type));
2100#endif
2101			cp += n;
2102			continue;		/* XXX - had_error++ ? */
2103		}
2104		switch (type) {
2105		case T_A:
2106		case T_AAAA:
2107			if (strcasecmp(canonname, bp) != 0) {
2108#ifdef DEBUG
2109				syslog(LOG_NOTICE|LOG_AUTH,
2110				       AskedForGot, canonname, bp);
2111#endif
2112				cp += n;
2113				continue;	/* XXX - had_error++ ? */
2114			}
2115			if (type == T_A && n != INADDRSZ) {
2116				cp += n;
2117				continue;
2118			}
2119			if (type == T_AAAA && n != IN6ADDRSZ) {
2120				cp += n;
2121				continue;
2122			}
2123#ifdef FILTER_V4MAPPED
2124			if (type == T_AAAA) {
2125				struct in6_addr in6;
2126				memcpy(&in6, cp, sizeof(in6));
2127				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
2128					cp += n;
2129					continue;
2130				}
2131			}
2132#endif
2133			if (!haveanswer) {
2134				int nn;
2135
2136				canonname = bp;
2137				nn = strlen(bp) + 1;	/* for the \0 */
2138				bp += nn;
2139			}
2140
2141			/* don't overwrite pai */
2142			ai = *pai;
2143			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
2144			afd = find_afd(ai.ai_family);
2145			if (afd == NULL) {
2146				cp += n;
2147				continue;
2148			}
2149			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
2150			if (cur->ai_next == NULL)
2151				had_error++;
2152			while (cur && cur->ai_next)
2153				cur = cur->ai_next;
2154			cp += n;
2155			break;
2156		default:
2157			abort();
2158		}
2159		if (!had_error)
2160			haveanswer++;
2161	}
2162	if (haveanswer) {
2163#if defined(RESOLVSORT)
2164		/*
2165		 * We support only IPv4 address for backward
2166		 * compatibility against gethostbyname(3).
2167		 */
2168		if (res->nsort && qtype == T_A) {
2169			if (addr4sort(&sentinel, res) < 0) {
2170				freeaddrinfo(sentinel.ai_next);
2171				RES_SET_H_ERRNO(res, NO_RECOVERY);
2172				return NULL;
2173			}
2174		}
2175#endif /*RESOLVSORT*/
2176		if (!canonname)
2177			(void)get_canonname(pai, sentinel.ai_next, qname);
2178		else
2179			(void)get_canonname(pai, sentinel.ai_next, canonname);
2180		RES_SET_H_ERRNO(res, NETDB_SUCCESS);
2181		return sentinel.ai_next;
2182	}
2183
2184	/*
2185	 * We could have walked a CNAME chain, but the ultimate target
2186	 * may not have what we looked for.
2187	 */
2188	RES_SET_H_ERRNO(res, ntohs(hp->ancount) > 0 ? NO_DATA : NO_RECOVERY);
2189	return NULL;
2190}
2191
2192#ifdef RESOLVSORT
2193struct addr_ptr {
2194	struct addrinfo *ai;
2195	int aval;
2196};
2197
2198static int
2199addr4sort(struct addrinfo *sentinel, res_state res)
2200{
2201	struct addrinfo *ai;
2202	struct addr_ptr *addrs, addr;
2203	struct sockaddr_in *sin;
2204	int naddrs, i, j;
2205	int needsort = 0;
2206
2207	if (!sentinel)
2208		return -1;
2209	naddrs = 0;
2210	for (ai = sentinel->ai_next; ai; ai = ai->ai_next)
2211		naddrs++;
2212	if (naddrs < 2)
2213		return 0;		/* We don't need sorting. */
2214	if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL)
2215		return -1;
2216	i = 0;
2217	for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
2218		sin = (struct sockaddr_in *)ai->ai_addr;
2219		for (j = 0; (unsigned)j < res->nsort; j++) {
2220			if (res->sort_list[j].addr.s_addr ==
2221			    (sin->sin_addr.s_addr & res->sort_list[j].mask))
2222				break;
2223		}
2224		addrs[i].ai = ai;
2225		addrs[i].aval = j;
2226		if (needsort == 0 && i > 0 && j < addrs[i - 1].aval)
2227			needsort = i;
2228		i++;
2229	}
2230	if (!needsort) {
2231		free(addrs);
2232		return 0;
2233	}
2234
2235	while (needsort < naddrs) {
2236		for (j = needsort - 1; j >= 0; j--) {
2237			if (addrs[j].aval > addrs[j+1].aval) {
2238				addr = addrs[j];
2239				addrs[j] = addrs[j + 1];
2240				addrs[j + 1] = addr;
2241			} else
2242				break;
2243		}
2244		needsort++;
2245	}
2246
2247	ai = sentinel;
2248	for (i = 0; i < naddrs; ++i) {
2249		ai->ai_next = addrs[i].ai;
2250		ai = ai->ai_next;
2251	}
2252	ai->ai_next = NULL;
2253	free(addrs);
2254	return 0;
2255}
2256#endif /*RESOLVSORT*/
2257
2258/*ARGSUSED*/
2259static int
2260_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
2261{
2262	struct addrinfo *ai, ai0;
2263	querybuf *buf, *buf2;
2264	const char *hostname;
2265	const struct addrinfo *pai;
2266	struct addrinfo sentinel, *cur;
2267	struct res_target q, q2;
2268	res_state res;
2269
2270	ai = NULL;
2271
2272	hostname = va_arg(ap, char *);
2273	pai = va_arg(ap, const struct addrinfo *);
2274
2275	memset(&q, 0, sizeof(q));
2276	memset(&q2, 0, sizeof(q2));
2277	memset(&sentinel, 0, sizeof(sentinel));
2278	cur = &sentinel;
2279
2280	res = __res_state();
2281
2282	buf = malloc(sizeof(*buf));
2283	if (!buf) {
2284		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
2285		return NS_NOTFOUND;
2286	}
2287	buf2 = malloc(sizeof(*buf2));
2288	if (!buf2) {
2289		free(buf);
2290		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
2291		return NS_NOTFOUND;
2292	}
2293
2294	if (pai->ai_family == AF_INET6 &&
2295	    (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) {
2296		ai0 = *pai;
2297		ai0.ai_family = AF_UNSPEC;
2298		pai = &ai0;
2299	}
2300
2301	switch (pai->ai_family) {
2302	case AF_UNSPEC:
2303		q.name = hostname;
2304		q.qclass = C_IN;
2305		q.qtype = T_A;
2306		q.answer = buf->buf;
2307		q.anslen = sizeof(buf->buf);
2308		q.next = &q2;
2309		q2.name = hostname;
2310		q2.qclass = C_IN;
2311		q2.qtype = T_AAAA;
2312		q2.answer = buf2->buf;
2313		q2.anslen = sizeof(buf2->buf);
2314		break;
2315	case AF_INET:
2316		q.name = hostname;
2317		q.qclass = C_IN;
2318		q.qtype = T_A;
2319		q.answer = buf->buf;
2320		q.anslen = sizeof(buf->buf);
2321		break;
2322	case AF_INET6:
2323		q.name = hostname;
2324		q.qclass = C_IN;
2325		q.qtype = T_AAAA;
2326		q.answer = buf->buf;
2327		q.anslen = sizeof(buf->buf);
2328		break;
2329	default:
2330		free(buf);
2331		free(buf2);
2332		return NS_UNAVAIL;
2333	}
2334
2335	if ((res->options & RES_INIT) == 0 && res_ninit(res) == -1) {
2336		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
2337		free(buf);
2338		free(buf2);
2339		return NS_NOTFOUND;
2340	}
2341
2342	if (res_searchN(hostname, &q, res) < 0) {
2343		free(buf);
2344		free(buf2);
2345		return NS_NOTFOUND;
2346	}
2347	/* prefer IPv6 */
2348	if (q.next) {
2349		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, res);
2350		if (ai != NULL) {
2351			cur->ai_next = ai;
2352			while (cur && cur->ai_next)
2353				cur = cur->ai_next;
2354		}
2355	}
2356	if (ai == NULL || pai->ai_family != AF_UNSPEC ||
2357	    (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) != AI_V4MAPPED) {
2358		ai = getanswer(buf, q.n, q.name, q.qtype, pai, res);
2359		if (ai != NULL)
2360			cur->ai_next = ai;
2361	}
2362	free(buf);
2363	free(buf2);
2364	if (sentinel.ai_next == NULL)
2365		switch (res->res_h_errno) {
2366		case HOST_NOT_FOUND:
2367		case NO_DATA:
2368			return NS_NOTFOUND;
2369		case TRY_AGAIN:
2370			return NS_TRYAGAIN;
2371		default:
2372			return NS_UNAVAIL;
2373		}
2374	*((struct addrinfo **)rv) = sentinel.ai_next;
2375	return NS_SUCCESS;
2376}
2377
2378static void
2379_sethtent(FILE **hostf)
2380{
2381	if (!*hostf)
2382		*hostf = fopen(_PATH_HOSTS, "re");
2383	else
2384		rewind(*hostf);
2385}
2386
2387static void
2388_endhtent(FILE **hostf)
2389{
2390	if (*hostf) {
2391		(void) fclose(*hostf);
2392		*hostf = NULL;
2393	}
2394}
2395
2396static struct addrinfo *
2397_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
2398{
2399	char *p;
2400	char *cp, *tname, *cname;
2401	struct addrinfo hints, *res0, *res;
2402	int error;
2403	const char *addr;
2404	char hostbuf[8*1024];
2405
2406	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "re")))
2407		return (NULL);
2408again:
2409	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
2410		return (NULL);
2411	if (*p == '#')
2412		goto again;
2413	cp = strpbrk(p, "#\n");
2414	if (cp != NULL)
2415		*cp = '\0';
2416	if (!(cp = strpbrk(p, " \t")))
2417		goto again;
2418	*cp++ = '\0';
2419	addr = p;
2420	cname = NULL;
2421	/* if this is not something we're looking for, skip it. */
2422	while (cp && *cp) {
2423		if (*cp == ' ' || *cp == '\t') {
2424			cp++;
2425			continue;
2426		}
2427		tname = cp;
2428		if (cname == NULL)
2429			cname = cp;
2430		if ((cp = strpbrk(cp, " \t")) != NULL)
2431			*cp++ = '\0';
2432		if (strcasecmp(name, tname) == 0)
2433			goto found;
2434	}
2435	goto again;
2436
2437found:
2438	/* we should not glob socktype/protocol here */
2439	memset(&hints, 0, sizeof(hints));
2440	hints.ai_family = pai->ai_family;
2441	hints.ai_socktype = SOCK_DGRAM;
2442	hints.ai_protocol = 0;
2443	hints.ai_flags = AI_NUMERICHOST;
2444	if (pai->ai_family == AF_INET6 &&
2445	    (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
2446		hints.ai_flags |= AI_V4MAPPED;
2447	error = getaddrinfo(addr, "0", &hints, &res0);
2448	if (error)
2449		goto again;
2450#ifdef FILTER_V4MAPPED
2451	/* XXX should check all items in the chain */
2452	if (res0->ai_family == AF_INET6 &&
2453	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) {
2454		freeaddrinfo(res0);
2455		goto again;
2456	}
2457#endif
2458	for (res = res0; res; res = res->ai_next) {
2459		/* cover it up */
2460		res->ai_flags = pai->ai_flags;
2461		res->ai_socktype = pai->ai_socktype;
2462		res->ai_protocol = pai->ai_protocol;
2463
2464		if (pai->ai_flags & AI_CANONNAME) {
2465			if (get_canonname(pai, res, cname) != 0) {
2466				freeaddrinfo(res0);
2467				goto again;
2468			}
2469		}
2470	}
2471	return res0;
2472}
2473
2474static struct addrinfo *
2475_getht(FILE **hostf, const char *name, const struct addrinfo *pai,
2476     struct addrinfo *cur)
2477{
2478	struct addrinfo *p;
2479
2480	while ((p = _gethtent(hostf, name, pai)) != NULL) {
2481		cur->ai_next = p;
2482		while (cur && cur->ai_next)
2483			cur = cur->ai_next;
2484	}
2485	return (cur);
2486}
2487
2488/*ARGSUSED*/
2489static int
2490_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
2491{
2492	const char *name;
2493	const struct addrinfo *pai;
2494	struct addrinfo sentinel, *cur;
2495	FILE *hostf = NULL;
2496
2497	name = va_arg(ap, char *);
2498	pai = va_arg(ap, struct addrinfo *);
2499
2500	memset(&sentinel, 0, sizeof(sentinel));
2501	cur = &sentinel;
2502
2503	_sethtent(&hostf);
2504	if (pai->ai_family == AF_INET6 &&
2505	    (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) == AI_V4MAPPED) {
2506		struct addrinfo ai0 = *pai;
2507
2508		ai0.ai_flags &= ~AI_V4MAPPED;
2509		cur = _getht(&hostf, name, &ai0, cur);
2510		if (sentinel.ai_next == NULL) {
2511			_sethtent(&hostf);
2512			ai0.ai_flags |= AI_V4MAPPED;
2513			cur = _getht(&hostf, name, &ai0, cur);
2514		}
2515	} else
2516		cur = _getht(&hostf, name, pai, cur);
2517	_endhtent(&hostf);
2518
2519	*((struct addrinfo **)rv) = sentinel.ai_next;
2520	if (sentinel.ai_next == NULL)
2521		return NS_NOTFOUND;
2522	return NS_SUCCESS;
2523}
2524
2525#ifdef YP
2526/*ARGSUSED*/
2527static struct addrinfo *
2528_yphostent(char *line, const struct addrinfo *pai)
2529{
2530	struct addrinfo sentinel, *cur;
2531	struct addrinfo hints, *res, *res0;
2532	int error;
2533	char *p = line;
2534	const char *addr, *canonname;
2535	char *nextline;
2536	char *cp;
2537
2538	addr = canonname = NULL;
2539
2540	memset(&sentinel, 0, sizeof(sentinel));
2541	cur = &sentinel;
2542
2543nextline:
2544	/* terminate line */
2545	cp = strchr(p, '\n');
2546	if (cp) {
2547		*cp++ = '\0';
2548		nextline = cp;
2549	} else
2550		nextline = NULL;
2551
2552	cp = strpbrk(p, " \t");
2553	if (cp == NULL) {
2554		if (canonname == NULL)
2555			return (NULL);
2556		else
2557			goto done;
2558	}
2559	*cp++ = '\0';
2560
2561	addr = p;
2562
2563	while (cp && *cp) {
2564		if (*cp == ' ' || *cp == '\t') {
2565			cp++;
2566			continue;
2567		}
2568		if (!canonname)
2569			canonname = cp;
2570		if ((cp = strpbrk(cp, " \t")) != NULL)
2571			*cp++ = '\0';
2572	}
2573
2574	hints = *pai;
2575	hints.ai_flags = AI_NUMERICHOST;
2576	if (pai->ai_family == AF_INET6 &&
2577	    (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED)
2578		hints.ai_flags |= AI_V4MAPPED;
2579	error = getaddrinfo(addr, NULL, &hints, &res0);
2580	if (error == 0) {
2581		for (res = res0; res; res = res->ai_next) {
2582			/* cover it up */
2583			res->ai_flags = pai->ai_flags;
2584
2585			if (pai->ai_flags & AI_CANONNAME)
2586				(void)get_canonname(pai, res, canonname);
2587		}
2588	} else
2589		res0 = NULL;
2590	if (res0) {
2591		cur->ai_next = res0;
2592		while (cur && cur->ai_next)
2593			cur = cur->ai_next;
2594	}
2595
2596	if (nextline) {
2597		p = nextline;
2598		goto nextline;
2599	}
2600
2601done:
2602	return sentinel.ai_next;
2603}
2604
2605/*ARGSUSED*/
2606static int
2607_yp_getaddrinfo(void *rv, void *cb_data, va_list ap)
2608{
2609	struct addrinfo sentinel, *cur;
2610	struct addrinfo *ai = NULL;
2611	char *ypbuf;
2612	int ypbuflen, r;
2613	const char *name;
2614	const struct addrinfo *pai;
2615	char *ypdomain;
2616
2617	if (_yp_check(&ypdomain) == 0)
2618		return NS_UNAVAIL;
2619
2620	name = va_arg(ap, char *);
2621	pai = va_arg(ap, const struct addrinfo *);
2622
2623	memset(&sentinel, 0, sizeof(sentinel));
2624	cur = &sentinel;
2625
2626	/* ipnodes.byname can hold both IPv4/v6 */
2627	r = yp_match(ypdomain, "ipnodes.byname", name,
2628		(int)strlen(name), &ypbuf, &ypbuflen);
2629	if (r == 0) {
2630		ai = _yphostent(ypbuf, pai);
2631		if (ai) {
2632			cur->ai_next = ai;
2633			while (cur && cur->ai_next)
2634				cur = cur->ai_next;
2635		}
2636		free(ypbuf);
2637	}
2638
2639	if (ai != NULL) {
2640		struct sockaddr_in6 *sin6;
2641
2642		switch (ai->ai_family) {
2643		case AF_INET:
2644			goto done;
2645		case AF_INET6:
2646			sin6 = (struct sockaddr_in6 *)ai->ai_addr;
2647			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
2648				goto done;
2649			break;
2650		}
2651	}
2652
2653	/* hosts.byname is only for IPv4 (Solaris8) */
2654	if (pai->ai_family == AF_UNSPEC || pai->ai_family == AF_INET ||
2655	    ((pai->ai_family == AF_INET6 &&
2656	     (pai->ai_flags & AI_V4MAPPED) == AI_V4MAPPED) &&
2657	      (ai == NULL || (pai->ai_flags & AI_ALL) == AI_ALL))) {
2658		r = yp_match(ypdomain, "hosts.byname", name,
2659			(int)strlen(name), &ypbuf, &ypbuflen);
2660		if (r == 0) {
2661			struct addrinfo ai4;
2662
2663			ai4 = *pai;
2664			if (pai->ai_family == AF_UNSPEC)
2665				ai4.ai_family = AF_INET;
2666			ai = _yphostent(ypbuf, &ai4);
2667			if (ai) {
2668				cur->ai_next = ai;
2669				while (cur && cur->ai_next)
2670					cur = cur->ai_next;
2671			}
2672			free(ypbuf);
2673		}
2674	}
2675
2676done:
2677	if (sentinel.ai_next == NULL) {
2678		RES_SET_H_ERRNO(__res_state(), HOST_NOT_FOUND);
2679		return NS_NOTFOUND;
2680	}
2681	*((struct addrinfo **)rv) = sentinel.ai_next;
2682	return NS_SUCCESS;
2683}
2684#endif
2685
2686/* resolver logic */
2687
2688/*
2689 * Formulate a normal query, send, and await answer.
2690 * Returned answer is placed in supplied buffer "answer".
2691 * Perform preliminary check of answer, returning success only
2692 * if no error is indicated and the answer count is nonzero.
2693 * Return the size of the response on success, -1 on error.
2694 * Error number is left in h_errno.
2695 *
2696 * Caller must parse answer and determine whether it answers the question.
2697 */
2698static int
2699res_queryN(const char *name, struct res_target *target, res_state res)
2700{
2701	u_char *buf;
2702	HEADER *hp;
2703	int n;
2704	u_int oflags;
2705	struct res_target *t;
2706	int rcode;
2707	int ancount;
2708
2709	rcode = NOERROR;
2710	ancount = 0;
2711
2712	buf = malloc(MAXPACKET);
2713	if (!buf) {
2714		RES_SET_H_ERRNO(res, NETDB_INTERNAL);
2715		return -1;
2716	}
2717
2718	for (t = target; t; t = t->next) {
2719		int class, type;
2720		u_char *answer;
2721		int anslen;
2722
2723		hp = (HEADER *)(void *)t->answer;
2724
2725		/* make it easier... */
2726		class = t->qclass;
2727		type = t->qtype;
2728		answer = t->answer;
2729		anslen = t->anslen;
2730
2731		oflags = res->_flags;
2732
2733again:
2734		hp->rcode = NOERROR;	/* default */
2735
2736#ifdef DEBUG
2737		if (res->options & RES_DEBUG)
2738			printf(";; res_query(%s, %d, %d)\n", name, class, type);
2739#endif
2740
2741		n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL,
2742		    buf, MAXPACKET);
2743		if (n > 0 && (res->_flags & RES_F_EDNS0ERR) == 0 &&
2744		    (res->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U)
2745			n = res_nopt(res, n, buf, MAXPACKET, anslen);
2746		if (n <= 0) {
2747#ifdef DEBUG
2748			if (res->options & RES_DEBUG)
2749				printf(";; res_query: mkquery failed\n");
2750#endif
2751			free(buf);
2752			RES_SET_H_ERRNO(res, NO_RECOVERY);
2753			return (n);
2754		}
2755		n = res_nsend(res, buf, n, answer, anslen);
2756		if (n < 0) {
2757			/*
2758			 * if the query choked with EDNS0, retry
2759			 * without EDNS0
2760			 */
2761			if ((res->options & (RES_USE_EDNS0|RES_USE_DNSSEC))
2762			    != 0U &&
2763			    ((oflags ^ res->_flags) & RES_F_EDNS0ERR) != 0) {
2764				res->_flags |= RES_F_EDNS0ERR;
2765				if (res->options & RES_DEBUG)
2766					printf(";; res_nquery: retry without EDNS0\n");
2767				goto again;
2768			}
2769			rcode = hp->rcode;	/* record most recent error */
2770#ifdef DEBUG
2771			if (res->options & RES_DEBUG)
2772				printf(";; res_query: send error\n");
2773#endif
2774			continue;
2775		}
2776
2777		if (n > anslen)
2778			hp->rcode = FORMERR; /* XXX not very informative */
2779		if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
2780			rcode = hp->rcode;	/* record most recent error */
2781#ifdef DEBUG
2782			if (res->options & RES_DEBUG)
2783				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
2784				    ntohs(hp->ancount));
2785#endif
2786			continue;
2787		}
2788
2789		ancount += ntohs(hp->ancount);
2790
2791		t->n = n;
2792	}
2793
2794	free(buf);
2795
2796	if (ancount == 0) {
2797		switch (rcode) {
2798		case NXDOMAIN:
2799			RES_SET_H_ERRNO(res, HOST_NOT_FOUND);
2800			break;
2801		case SERVFAIL:
2802			RES_SET_H_ERRNO(res, TRY_AGAIN);
2803			break;
2804		case NOERROR:
2805			RES_SET_H_ERRNO(res, NO_DATA);
2806			break;
2807		case FORMERR:
2808		case NOTIMP:
2809		case REFUSED:
2810		default:
2811			RES_SET_H_ERRNO(res, NO_RECOVERY);
2812			break;
2813		}
2814		return (-1);
2815	}
2816	return (ancount);
2817}
2818
2819/*
2820 * Formulate a normal query, send, and retrieve answer in supplied buffer.
2821 * Return the size of the response on success, -1 on error.
2822 * If enabled, implement search rules until answer or unrecoverable failure
2823 * is detected.  Error code, if any, is left in h_errno.
2824 */
2825static int
2826res_searchN(const char *name, struct res_target *target, res_state res)
2827{
2828	const char *cp, * const *domain;
2829	HEADER *hp = (HEADER *)(void *)target->answer;	/*XXX*/
2830	u_int dots;
2831	int trailing_dot, ret, saved_herrno;
2832	int got_nodata = 0, got_servfail = 0, root_on_list = 0;
2833	int tried_as_is = 0;
2834	int searched = 0;
2835	char abuf[MAXDNAME];
2836
2837	errno = 0;
2838	RES_SET_H_ERRNO(res, HOST_NOT_FOUND); /* default, if we never query */
2839	dots = 0;
2840	for (cp = name; *cp; cp++)
2841		dots += (*cp == '.');
2842	trailing_dot = 0;
2843	if (cp > name && *--cp == '.')
2844		trailing_dot++;
2845
2846	/*
2847	 * if there aren't any dots, it could be a user-level alias
2848	 */
2849	if (!dots &&
2850	    (cp = res_hostalias(res, name, abuf, sizeof(abuf))) != NULL)
2851		return (res_queryN(cp, target, res));
2852
2853	/*
2854	 * If there are enough dots in the name, let's just give it a
2855	 * try 'as is'. The threshold can be set with the "ndots" option.
2856	 * Also, query 'as is', if there is a trailing dot in the name.
2857	 */
2858	saved_herrno = -1;
2859	if (dots >= res->ndots || trailing_dot) {
2860		ret = res_querydomainN(name, NULL, target, res);
2861		if (ret > 0 || trailing_dot)
2862			return (ret);
2863		if (errno == ECONNREFUSED) {
2864			RES_SET_H_ERRNO(res, TRY_AGAIN);
2865			return (-1);
2866		}
2867		switch (res->res_h_errno) {
2868		case NO_DATA:
2869		case HOST_NOT_FOUND:
2870			break;
2871		case TRY_AGAIN:
2872			if (hp->rcode == SERVFAIL)
2873				break;
2874			/* FALLTHROUGH */
2875		default:
2876			return (-1);
2877		}
2878		saved_herrno = res->res_h_errno;
2879		tried_as_is++;
2880	}
2881
2882	/*
2883	 * We do at least one level of search if
2884	 *	- there is no dot and RES_DEFNAME is set, or
2885	 *	- there is at least one dot, there is no trailing dot,
2886	 *	  and RES_DNSRCH is set.
2887	 */
2888	if ((!dots && (res->options & RES_DEFNAMES)) ||
2889	    (dots && !trailing_dot && (res->options & RES_DNSRCH))) {
2890		int done = 0;
2891
2892		for (domain = (const char * const *)res->dnsrch;
2893		   *domain && !done;
2894		   domain++) {
2895			searched = 1;
2896
2897			if (domain[0][0] == '\0' ||
2898			    (domain[0][0] == '.' && domain[0][1] == '\0'))
2899				root_on_list++;
2900
2901			if (root_on_list && tried_as_is)
2902				continue;
2903
2904			ret = res_querydomainN(name, *domain, target, res);
2905			if (ret > 0)
2906				return (ret);
2907
2908			/*
2909			 * If no server present, give up.
2910			 * If name isn't found in this domain,
2911			 * keep trying higher domains in the search list
2912			 * (if that's enabled).
2913			 * On a NO_DATA error, keep trying, otherwise
2914			 * a wildcard entry of another type could keep us
2915			 * from finding this entry higher in the domain.
2916			 * If we get some other error (negative answer or
2917			 * server failure), then stop searching up,
2918			 * but try the input name below in case it's
2919			 * fully-qualified.
2920			 */
2921			if (errno == ECONNREFUSED) {
2922				RES_SET_H_ERRNO(res, TRY_AGAIN);
2923				return (-1);
2924			}
2925
2926			switch (res->res_h_errno) {
2927			case NO_DATA:
2928				got_nodata++;
2929				/* FALLTHROUGH */
2930			case HOST_NOT_FOUND:
2931				/* keep trying */
2932				break;
2933			case TRY_AGAIN:
2934				got_servfail++;
2935				if (hp->rcode == SERVFAIL) {
2936					/* try next search element, if any */
2937					break;
2938				}
2939				/* FALLTHROUGH */
2940			default:
2941				/* anything else implies that we're done */
2942				done++;
2943			}
2944			/*
2945			 * if we got here for some reason other than DNSRCH,
2946			 * we only wanted one iteration of the loop, so stop.
2947			 */
2948			if (!(res->options & RES_DNSRCH))
2949			        done++;
2950		}
2951	}
2952
2953	switch (res->res_h_errno) {
2954	case NO_DATA:
2955	case HOST_NOT_FOUND:
2956		break;
2957	case TRY_AGAIN:
2958		if (hp->rcode == SERVFAIL)
2959			break;
2960		/* FALLTHROUGH */
2961	default:
2962		goto giveup;
2963	}
2964
2965	/*
2966	 * If the query has not already been tried as is then try it
2967	 * unless RES_NOTLDQUERY is set and there were no dots.
2968	 */
2969	if ((dots || !searched || !(res->options & RES_NOTLDQUERY)) &&
2970	    !(tried_as_is || root_on_list)) {
2971		ret = res_querydomainN(name, NULL, target, res);
2972		if (ret > 0)
2973			return (ret);
2974	}
2975
2976	/*
2977	 * if we got here, we didn't satisfy the search.
2978	 * if we did an initial full query, return that query's h_errno
2979	 * (note that we wouldn't be here if that query had succeeded).
2980	 * else if we ever got a nodata, send that back as the reason.
2981	 * else send back meaningless h_errno, that being the one from
2982	 * the last DNSRCH we did.
2983	 */
2984giveup:
2985	if (saved_herrno != -1)
2986		RES_SET_H_ERRNO(res, saved_herrno);
2987	else if (got_nodata)
2988		RES_SET_H_ERRNO(res, NO_DATA);
2989	else if (got_servfail)
2990		RES_SET_H_ERRNO(res, TRY_AGAIN);
2991	return (-1);
2992}
2993
2994/*
2995 * Perform a call on res_query on the concatenation of name and domain,
2996 * removing a trailing dot from name if domain is NULL.
2997 */
2998static int
2999res_querydomainN(const char *name, const char *domain,
3000    struct res_target *target, res_state res)
3001{
3002	char nbuf[MAXDNAME];
3003	const char *longname = nbuf;
3004	size_t n, d;
3005
3006#ifdef DEBUG
3007	if (res->options & RES_DEBUG)
3008		printf(";; res_querydomain(%s, %s)\n",
3009			name, domain?domain:"<Nil>");
3010#endif
3011	if (domain == NULL) {
3012		/*
3013		 * Check for trailing '.';
3014		 * copy without '.' if present.
3015		 */
3016		n = strlen(name);
3017		if (n >= MAXDNAME) {
3018			RES_SET_H_ERRNO(res, NO_RECOVERY);
3019			return (-1);
3020		}
3021		if (n > 0 && name[--n] == '.') {
3022			strncpy(nbuf, name, n);
3023			nbuf[n] = '\0';
3024		} else
3025			longname = name;
3026	} else {
3027		n = strlen(name);
3028		d = strlen(domain);
3029		if (n + d + 1 >= MAXDNAME) {
3030			RES_SET_H_ERRNO(res, NO_RECOVERY);
3031			return (-1);
3032		}
3033		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
3034	}
3035	return (res_queryN(longname, target, res));
3036}
3037