1/*	$NetBSD: getaddrinfo.c,v 1.82 2006/03/25 12:09:40 rpaulo Exp $	*/
2/*	$KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $	*/
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Issues to be discussed:
35 * - Thread safe-ness must be checked.
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 * - IPv4 classful (shortened) form.  RFC2553 is silent about it.  XNET 5.2
40 *   says to use inet_aton() to convert IPv4 numeric to binary (alows
41 *   classful form as a result).
42 *   current code - disallow classful form for IPv4 (due to use of inet_pton).
43 * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
44 *   invalid.
45 *   current code - SEGV on freeaddrinfo(NULL)
46 * Note:
47 * - We use getipnodebyname() just for thread-safeness.  There's no intent
48 *   to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
49 *   getipnodebyname().
50 * - The code filters out AFs that are not supported by the kernel,
51 *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
52 *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
53 *   in ai_flags?
54 * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
55 *   (1) what should we do against numeric hostname (2) what should we do
56 *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
57 *   non-loopback address configured?  global address configured?
58 * - To avoid search order issue, we have a big amount of code duplicate
59 *   from gethnamaddr.c and some other places.  The issues that there's no
60 *   lower layer function to lookup "IPv4 or IPv6" record.  Calling
61 *   gethostbyname2 from getaddrinfo will end up in wrong search order, as
62 *   follows:
63 *	- The code makes use of following calls when asked to resolver with
64 *	  ai_family  = PF_UNSPEC:
65 *		getipnodebyname(host, AF_INET6);
66 *		getipnodebyname(host, AF_INET);
67 *	  This will result in the following queries if the node is configure to
68 *	  prefer /etc/hosts than DNS:
69 *		lookup /etc/hosts for IPv6 address
70 *		lookup DNS for IPv6 address
71 *		lookup /etc/hosts for IPv4 address
72 *		lookup DNS for IPv4 address
73 *	  which may not meet people's requirement.
74 *	  The right thing to happen is to have underlying layer which does
75 *	  PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
76 *	  This would result in a bit of code duplicate with _dns_ghbyname() and
77 *	  friends.
78 */
79
80#include <fcntl.h>
81#include <sys/cdefs.h>
82#include <sys/types.h>
83#include <sys/stat.h>
84#include <sys/param.h>
85#include <sys/socket.h>
86#include <sys/un.h>
87#include <net/if.h>
88#include <netinet/in.h>
89#include <arpa/inet.h>
90#include <arpa/nameser.h>
91#include <assert.h>
92#include <ctype.h>
93#include <errno.h>
94#include <netdb.h>
95#include "NetdClientDispatch.h"
96#include "resolv_cache.h"
97#include "resolv_netid.h"
98#include "resolv_private.h"
99#include <stdbool.h>
100#include <stddef.h>
101#include <stdio.h>
102#include <stdlib.h>
103#include <string.h>
104#include <strings.h>
105#include <unistd.h>
106
107#include <syslog.h>
108#include <stdarg.h>
109#include "nsswitch.h"
110
111#ifdef ANDROID_CHANGES
112#include <sys/system_properties.h>
113#endif /* ANDROID_CHANGES */
114
115typedef union sockaddr_union {
116    struct sockaddr     generic;
117    struct sockaddr_in  in;
118    struct sockaddr_in6 in6;
119} sockaddr_union;
120
121#define SUCCESS 0
122#define ANY 0
123#define YES 1
124#define NO  0
125
126static const char in_addrany[] = { 0, 0, 0, 0 };
127static const char in_loopback[] = { 127, 0, 0, 1 };
128#ifdef INET6
129static const char in6_addrany[] = {
130	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
131};
132static const char in6_loopback[] = {
133	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
134};
135#endif
136
137// This should be synchronized to ResponseCode.h
138static const int DnsProxyQueryResult = 222;
139
140static const struct afd {
141	int a_af;
142	int a_addrlen;
143	int a_socklen;
144	int a_off;
145	const char *a_addrany;
146	const char *a_loopback;
147	int a_scoped;
148} afdl [] = {
149#ifdef INET6
150	{PF_INET6, sizeof(struct in6_addr),
151	 sizeof(struct sockaddr_in6),
152	 offsetof(struct sockaddr_in6, sin6_addr),
153	 in6_addrany, in6_loopback, 1},
154#endif
155	{PF_INET, sizeof(struct in_addr),
156	 sizeof(struct sockaddr_in),
157	 offsetof(struct sockaddr_in, sin_addr),
158	 in_addrany, in_loopback, 0},
159	{0, 0, 0, 0, NULL, NULL, 0},
160};
161
162struct explore {
163	int e_af;
164	int e_socktype;
165	int e_protocol;
166	const char *e_protostr;
167	int e_wild;
168#define WILD_AF(ex)		((ex)->e_wild & 0x01)
169#define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
170#define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
171};
172
173static const struct explore explore[] = {
174#if 0
175	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
176#endif
177#ifdef INET6
178	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
179	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
180	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
181#endif
182	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
183	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
184	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
185	{ PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
186	{ PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
187	{ PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
188	{ -1, 0, 0, NULL, 0 },
189};
190
191#ifdef INET6
192#define PTON_MAX	16
193#else
194#define PTON_MAX	4
195#endif
196
197static const ns_src default_dns_files[] = {
198	{ NSSRC_FILES, 	NS_SUCCESS },
199	{ NSSRC_DNS, 	NS_SUCCESS },
200	{ 0, 0 }
201};
202
203#define MAXPACKET	(64*1024)
204
205typedef union {
206	HEADER hdr;
207	u_char buf[MAXPACKET];
208} querybuf;
209
210struct res_target {
211	struct res_target *next;
212	const char *name;	/* domain name */
213	int qclass, qtype;	/* class and type of query */
214	u_char *answer;		/* buffer to put answer */
215	int anslen;		/* size of answer buffer */
216	int n;			/* result length */
217};
218
219static int str2number(const char *);
220static int explore_fqdn(const struct addrinfo *, const char *,
221	const char *, struct addrinfo **, unsigned netid, unsigned mark);
222static int explore_null(const struct addrinfo *,
223	const char *, struct addrinfo **);
224static int explore_numeric(const struct addrinfo *, const char *,
225	const char *, struct addrinfo **, const char *);
226static int explore_numeric_scope(const struct addrinfo *, const char *,
227	const char *, struct addrinfo **);
228static int get_canonname(const struct addrinfo *,
229	struct addrinfo *, const char *);
230static struct addrinfo *get_ai(const struct addrinfo *,
231	const struct afd *, const char *);
232static int get_portmatch(const struct addrinfo *, const char *);
233static int get_port(const struct addrinfo *, const char *, int);
234static const struct afd *find_afd(int);
235#ifdef INET6
236static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
237#endif
238
239static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
240	const struct addrinfo *);
241static int _dns_getaddrinfo(void *, void *, va_list);
242static void _sethtent(FILE **);
243static void _endhtent(FILE **);
244static struct addrinfo *_gethtent(FILE **, const char *,
245    const struct addrinfo *);
246static int _files_getaddrinfo(void *, void *, va_list);
247
248static int res_queryN(const char *, struct res_target *, res_state);
249static int res_searchN(const char *, struct res_target *, res_state);
250static int res_querydomainN(const char *, const char *,
251	struct res_target *, res_state);
252
253static const char * const ai_errlist[] = {
254	"Success",
255	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
256	"Temporary failure in name resolution",		/* EAI_AGAIN      */
257	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
258	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
259	"ai_family not supported",			/* EAI_FAMILY     */
260	"Memory allocation failure", 			/* EAI_MEMORY     */
261	"No address associated with hostname", 		/* EAI_NODATA     */
262	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
263	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
264	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
265	"System error returned in errno", 		/* EAI_SYSTEM     */
266	"Invalid value for hints",			/* EAI_BADHINTS	  */
267	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
268	"Argument buffer overflow",			/* EAI_OVERFLOW   */
269	"Unknown error", 				/* EAI_MAX        */
270};
271
272/* XXX macros that make external reference is BAD. */
273
274#define GET_AI(ai, afd, addr) 					\
275do { 								\
276	/* external reference: pai, error, and label free */ 	\
277	(ai) = get_ai(pai, (afd), (addr)); 			\
278	if ((ai) == NULL) { 					\
279		error = EAI_MEMORY; 				\
280		goto free; 					\
281	} 							\
282} while (/*CONSTCOND*/0)
283
284#define GET_PORT(ai, serv) 					\
285do { 								\
286	/* external reference: error and label free */ 		\
287	error = get_port((ai), (serv), 0); 			\
288	if (error != 0) 					\
289		goto free; 					\
290} while (/*CONSTCOND*/0)
291
292#define GET_CANONNAME(ai, str) 					\
293do { 								\
294	/* external reference: pai, error and label free */ 	\
295	error = get_canonname(pai, (ai), (str)); 		\
296	if (error != 0) 					\
297		goto free; 					\
298} while (/*CONSTCOND*/0)
299
300#define ERR(err) 						\
301do { 								\
302	/* external reference: error, and label bad */ 		\
303	error = (err); 						\
304	goto bad; 						\
305	/*NOTREACHED*/ 						\
306} while (/*CONSTCOND*/0)
307
308#define MATCH_FAMILY(x, y, w) 						\
309	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || 	\
310	    (y) == PF_UNSPEC)))
311#define MATCH(x, y, w) 							\
312	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
313
314const char *
315gai_strerror(int ecode)
316{
317	if (ecode < 0 || ecode > EAI_MAX)
318		ecode = EAI_MAX;
319	return ai_errlist[ecode];
320}
321
322void
323freeaddrinfo(struct addrinfo *ai)
324{
325	struct addrinfo *next;
326
327	assert(ai != NULL);
328
329	do {
330		next = ai->ai_next;
331		if (ai->ai_canonname)
332			free(ai->ai_canonname);
333		/* no need to free(ai->ai_addr) */
334		free(ai);
335		ai = next;
336	} while (ai);
337}
338
339static int
340str2number(const char *p)
341{
342	char *ep;
343	unsigned long v;
344
345	assert(p != NULL);
346
347	if (*p == '\0')
348		return -1;
349	ep = NULL;
350	errno = 0;
351	v = strtoul(p, &ep, 10);
352	if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX)
353		return v;
354	else
355		return -1;
356}
357
358/*
359 * Connect a UDP socket to a given unicast address. This will cause no network
360 * traffic, but will fail fast if the system has no or limited reachability to
361 * the destination (e.g., no IPv4 address, no IPv6 default route, ...).
362 */
363static int
364_test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
365	int s = socket(pf, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
366	if (s < 0)
367		return 0;
368	if (mark != MARK_UNSET && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
369		return 0;
370	int ret;
371	do {
372		ret = __connect(s, addr, addrlen);
373	} while (ret < 0 && errno == EINTR);
374	int success = (ret == 0);
375	do {
376		ret = close(s);
377	} while (ret < 0 && errno == EINTR);
378	return success;
379}
380
381/*
382 * The following functions determine whether IPv4 or IPv6 connectivity is
383 * available in order to implement AI_ADDRCONFIG.
384 *
385 * Strictly speaking, AI_ADDRCONFIG should not look at whether connectivity is
386 * available, but whether addresses of the specified family are "configured
387 * on the local system". However, bionic doesn't currently support getifaddrs,
388 * so checking for connectivity is the next best thing.
389 */
390static int
391_have_ipv6(unsigned mark) {
392	static const struct sockaddr_in6 sin6_test = {
393		.sin6_family = AF_INET6,
394		.sin6_addr.s6_addr = {  // 2000::
395			0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
396		};
397	sockaddr_union addr = { .in6 = sin6_test };
398	return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6), mark);
399}
400
401static int
402_have_ipv4(unsigned mark) {
403	static const struct sockaddr_in sin_test = {
404		.sin_family = AF_INET,
405		.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
406	};
407	sockaddr_union addr = { .in = sin_test };
408	return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
409}
410
411// Returns 0 on success, else returns on error.
412static int
413android_getaddrinfo_proxy(
414    const char *hostname, const char *servname,
415    const struct addrinfo *hints, struct addrinfo **res, unsigned netid)
416{
417	int sock;
418	const int one = 1;
419	struct sockaddr_un proxy_addr;
420	FILE* proxy = NULL;
421	int success = 0;
422
423	// Clear this at start, as we use its non-NULLness later (in the
424	// error path) to decide if we have to free up any memory we
425	// allocated in the process (before failing).
426	*res = NULL;
427
428	// Bogus things we can't serialize.  Don't use the proxy.  These will fail - let them.
429	if ((hostname != NULL &&
430	     strcspn(hostname, " \n\r\t^'\"") != strlen(hostname)) ||
431	    (servname != NULL &&
432	     strcspn(servname, " \n\r\t^'\"") != strlen(servname))) {
433		return EAI_NODATA;
434	}
435
436	sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
437	if (sock < 0) {
438		return EAI_NODATA;
439	}
440
441	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
442	memset(&proxy_addr, 0, sizeof(proxy_addr));
443	proxy_addr.sun_family = AF_UNIX;
444	strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
445		sizeof(proxy_addr.sun_path));
446	if (TEMP_FAILURE_RETRY(connect(sock,
447				       (const struct sockaddr*) &proxy_addr,
448				       sizeof(proxy_addr))) != 0) {
449		close(sock);
450		return EAI_NODATA;
451	}
452
453	netid = __netdClientDispatch.netIdForResolv(netid);
454
455	// Send the request.
456	proxy = fdopen(sock, "r+");
457	if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d %u",
458		    hostname == NULL ? "^" : hostname,
459		    servname == NULL ? "^" : servname,
460		    hints == NULL ? -1 : hints->ai_flags,
461		    hints == NULL ? -1 : hints->ai_family,
462		    hints == NULL ? -1 : hints->ai_socktype,
463		    hints == NULL ? -1 : hints->ai_protocol,
464		    netid) < 0) {
465		goto exit;
466	}
467	// literal NULL byte at end, required by FrameworkListener
468	if (fputc(0, proxy) == EOF ||
469	    fflush(proxy) != 0) {
470		goto exit;
471	}
472
473	char buf[4];
474	// read result code for gethostbyaddr
475	if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) {
476		goto exit;
477	}
478
479	int result_code = (int)strtol(buf, NULL, 10);
480	// verify the code itself
481	if (result_code != DnsProxyQueryResult ) {
482		fread(buf, 1, sizeof(buf), proxy);
483		goto exit;
484	}
485
486	struct addrinfo* ai = NULL;
487	struct addrinfo** nextres = res;
488	while (1) {
489		uint32_t addrinfo_len;
490		if (fread(&addrinfo_len, sizeof(addrinfo_len),
491			  1, proxy) != 1) {
492			break;
493		}
494		addrinfo_len = ntohl(addrinfo_len);
495		if (addrinfo_len == 0) {
496			success = 1;
497			break;
498		}
499
500		if (addrinfo_len < sizeof(struct addrinfo)) {
501			break;
502		}
503		struct addrinfo* ai = calloc(1, addrinfo_len +
504					     sizeof(struct sockaddr_storage));
505		if (ai == NULL) {
506			break;
507		}
508
509		if (fread(ai, addrinfo_len, 1, proxy) != 1) {
510			// Error; fall through.
511			break;
512		}
513
514		// Zero out the pointer fields we copied which aren't
515		// valid in this address space.
516		ai->ai_addr = NULL;
517		ai->ai_canonname = NULL;
518		ai->ai_next = NULL;
519
520		// struct sockaddr
521		uint32_t addr_len;
522		if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
523			break;
524		}
525		addr_len = ntohl(addr_len);
526		if (addr_len != 0) {
527			if (addr_len > sizeof(struct sockaddr_storage)) {
528				// Bogus; too big.
529				break;
530			}
531			struct sockaddr* addr = (struct sockaddr*)(ai + 1);
532			if (fread(addr, addr_len, 1, proxy) != 1) {
533				break;
534			}
535			ai->ai_addr = addr;
536		}
537
538		// cannonname
539		uint32_t name_len;
540		if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
541			break;
542		}
543		name_len = ntohl(name_len);
544		if (name_len != 0) {
545			ai->ai_canonname = (char*) malloc(name_len);
546			if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
547				break;
548			}
549			if (ai->ai_canonname[name_len - 1] != '\0') {
550				// The proxy should be returning this
551				// NULL-terminated.
552				break;
553			}
554		}
555
556		*nextres = ai;
557		nextres = &ai->ai_next;
558		ai = NULL;
559	}
560
561	if (ai != NULL) {
562		// Clean up partially-built addrinfo that we never ended up
563		// attaching to the response.
564		freeaddrinfo(ai);
565	}
566exit:
567	if (proxy != NULL) {
568		fclose(proxy);
569	}
570
571	if (success) {
572		return 0;
573	}
574
575	// Proxy failed;
576	// clean up memory we might've allocated.
577	if (*res) {
578		freeaddrinfo(*res);
579		*res = NULL;
580	}
581	return EAI_NODATA;
582}
583
584int
585getaddrinfo(const char *hostname, const char *servname,
586    const struct addrinfo *hints, struct addrinfo **res)
587{
588	return android_getaddrinfofornet(hostname, servname, hints, NETID_UNSET, MARK_UNSET, res);
589}
590
591int
592android_getaddrinfofornet(const char *hostname, const char *servname,
593    const struct addrinfo *hints, unsigned netid, unsigned mark, struct addrinfo **res)
594{
595	struct addrinfo sentinel;
596	struct addrinfo *cur;
597	int error = 0;
598	struct addrinfo ai;
599	struct addrinfo ai0;
600	struct addrinfo *pai;
601	const struct explore *ex;
602	const char* cache_mode = getenv("ANDROID_DNS_MODE");
603
604	/* hostname is allowed to be NULL */
605	/* servname is allowed to be NULL */
606	/* hints is allowed to be NULL */
607	assert(res != NULL);
608	memset(&sentinel, 0, sizeof(sentinel));
609	cur = &sentinel;
610	pai = &ai;
611	pai->ai_flags = 0;
612	pai->ai_family = PF_UNSPEC;
613	pai->ai_socktype = ANY;
614	pai->ai_protocol = ANY;
615	pai->ai_addrlen = 0;
616	pai->ai_canonname = NULL;
617	pai->ai_addr = NULL;
618	pai->ai_next = NULL;
619
620	if (hostname == NULL && servname == NULL)
621		return EAI_NONAME;
622	if (hints) {
623		/* error check for hints */
624		if (hints->ai_addrlen || hints->ai_canonname ||
625		    hints->ai_addr || hints->ai_next)
626			ERR(EAI_BADHINTS); /* xxx */
627		if (hints->ai_flags & ~AI_MASK)
628			ERR(EAI_BADFLAGS);
629		switch (hints->ai_family) {
630		case PF_UNSPEC:
631		case PF_INET:
632#ifdef INET6
633		case PF_INET6:
634#endif
635			break;
636		default:
637			ERR(EAI_FAMILY);
638		}
639		memcpy(pai, hints, sizeof(*pai));
640
641		/*
642		 * if both socktype/protocol are specified, check if they
643		 * are meaningful combination.
644		 */
645		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
646			for (ex = explore; ex->e_af >= 0; ex++) {
647				if (pai->ai_family != ex->e_af)
648					continue;
649				if (ex->e_socktype == ANY)
650					continue;
651				if (ex->e_protocol == ANY)
652					continue;
653				if (pai->ai_socktype == ex->e_socktype
654				 && pai->ai_protocol != ex->e_protocol) {
655					ERR(EAI_BADHINTS);
656				}
657			}
658		}
659	}
660
661	/*
662	 * check for special cases.  (1) numeric servname is disallowed if
663	 * socktype/protocol are left unspecified. (2) servname is disallowed
664	 * for raw and other inet{,6} sockets.
665	 */
666	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
667#ifdef PF_INET6
668	 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
669#endif
670	    ) {
671		ai0 = *pai;	/* backup *pai */
672
673		if (pai->ai_family == PF_UNSPEC) {
674#ifdef PF_INET6
675			pai->ai_family = PF_INET6;
676#else
677			pai->ai_family = PF_INET;
678#endif
679		}
680		error = get_portmatch(pai, servname);
681		if (error)
682			ERR(error);
683
684		*pai = ai0;
685	}
686
687	ai0 = *pai;
688
689	/* NULL hostname, or numeric hostname */
690	for (ex = explore; ex->e_af >= 0; ex++) {
691		*pai = ai0;
692
693		/* PF_UNSPEC entries are prepared for DNS queries only */
694		if (ex->e_af == PF_UNSPEC)
695			continue;
696
697		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
698			continue;
699		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
700			continue;
701		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
702			continue;
703
704		if (pai->ai_family == PF_UNSPEC)
705			pai->ai_family = ex->e_af;
706		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
707			pai->ai_socktype = ex->e_socktype;
708		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
709			pai->ai_protocol = ex->e_protocol;
710
711		if (hostname == NULL)
712			error = explore_null(pai, servname, &cur->ai_next);
713		else
714			error = explore_numeric_scope(pai, hostname, servname,
715			    &cur->ai_next);
716
717		if (error)
718			goto free;
719
720		while (cur->ai_next)
721			cur = cur->ai_next;
722	}
723
724	/*
725	 * XXX
726	 * If numeric representation of AF1 can be interpreted as FQDN
727	 * representation of AF2, we need to think again about the code below.
728	 */
729	if (sentinel.ai_next)
730		goto good;
731
732	if (hostname == NULL)
733		ERR(EAI_NODATA);
734	if (pai->ai_flags & AI_NUMERICHOST)
735		ERR(EAI_NONAME);
736
737        /*
738         * BEGIN ANDROID CHANGES; proxying to the cache
739         */
740	if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
741		// we're not the proxy - pass the request to them
742		return android_getaddrinfo_proxy(hostname, servname, hints, res, netid);
743	}
744
745	/*
746	 * hostname as alphabetical name.
747	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
748	 * outer loop by AFs.
749	 */
750	for (ex = explore; ex->e_af >= 0; ex++) {
751		*pai = ai0;
752
753		/* require exact match for family field */
754		if (pai->ai_family != ex->e_af)
755			continue;
756
757		if (!MATCH(pai->ai_socktype, ex->e_socktype,
758				WILD_SOCKTYPE(ex))) {
759			continue;
760		}
761		if (!MATCH(pai->ai_protocol, ex->e_protocol,
762				WILD_PROTOCOL(ex))) {
763			continue;
764		}
765
766		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
767			pai->ai_socktype = ex->e_socktype;
768		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
769			pai->ai_protocol = ex->e_protocol;
770
771		error = explore_fqdn(pai, hostname, servname,
772			&cur->ai_next, netid, mark);
773
774		while (cur && cur->ai_next)
775			cur = cur->ai_next;
776	}
777
778	/* XXX */
779	if (sentinel.ai_next)
780		error = 0;
781
782	if (error)
783		goto free;
784	if (error == 0) {
785		if (sentinel.ai_next) {
786 good:
787			*res = sentinel.ai_next;
788			return SUCCESS;
789		} else
790			error = EAI_FAIL;
791	}
792 free:
793 bad:
794	if (sentinel.ai_next)
795		freeaddrinfo(sentinel.ai_next);
796	*res = NULL;
797	return error;
798}
799
800/*
801 * FQDN hostname, DNS lookup
802 */
803static int
804explore_fqdn(const struct addrinfo *pai, const char *hostname,
805    const char *servname, struct addrinfo **res, unsigned netid, unsigned mark)
806{
807	struct addrinfo *result;
808	struct addrinfo *cur;
809	int error = 0;
810	static const ns_dtab dtab[] = {
811		NS_FILES_CB(_files_getaddrinfo, NULL)
812		{ NSSRC_DNS, _dns_getaddrinfo, NULL },	/* force -DHESIOD */
813		NS_NIS_CB(_yp_getaddrinfo, NULL)
814		{ 0, 0, 0 }
815	};
816
817	assert(pai != NULL);
818	/* hostname may be NULL */
819	/* servname may be NULL */
820	assert(res != NULL);
821
822	result = NULL;
823
824	/*
825	 * if the servname does not match socktype/protocol, ignore it.
826	 */
827	if (get_portmatch(pai, servname) != 0)
828		return 0;
829
830	switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
831			default_dns_files, hostname, pai, netid, mark)) {
832	case NS_TRYAGAIN:
833		error = EAI_AGAIN;
834		goto free;
835	case NS_UNAVAIL:
836		error = EAI_FAIL;
837		goto free;
838	case NS_NOTFOUND:
839		error = EAI_NODATA;
840		goto free;
841	case NS_SUCCESS:
842		error = 0;
843		for (cur = result; cur; cur = cur->ai_next) {
844			GET_PORT(cur, servname);
845			/* canonname should be filled already */
846		}
847		break;
848	}
849
850	*res = result;
851
852	return 0;
853
854free:
855	if (result)
856		freeaddrinfo(result);
857	return error;
858}
859
860/*
861 * hostname == NULL.
862 * passive socket -> anyaddr (0.0.0.0 or ::)
863 * non-passive socket -> localhost (127.0.0.1 or ::1)
864 */
865static int
866explore_null(const struct addrinfo *pai, const char *servname,
867    struct addrinfo **res)
868{
869	int s;
870	const struct afd *afd;
871	struct addrinfo *cur;
872	struct addrinfo sentinel;
873	int error;
874
875	assert(pai != NULL);
876	/* servname may be NULL */
877	assert(res != NULL);
878
879	*res = NULL;
880	sentinel.ai_next = NULL;
881	cur = &sentinel;
882
883	/*
884	 * filter out AFs that are not supported by the kernel
885	 * XXX errno?
886	 */
887	s = socket(pai->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
888	if (s < 0) {
889		if (errno != EMFILE)
890			return 0;
891	} else
892		close(s);
893
894	/*
895	 * if the servname does not match socktype/protocol, ignore it.
896	 */
897	if (get_portmatch(pai, servname) != 0)
898		return 0;
899
900	afd = find_afd(pai->ai_family);
901	if (afd == NULL)
902		return 0;
903
904	if (pai->ai_flags & AI_PASSIVE) {
905		GET_AI(cur->ai_next, afd, afd->a_addrany);
906		/* xxx meaningless?
907		 * GET_CANONNAME(cur->ai_next, "anyaddr");
908		 */
909		GET_PORT(cur->ai_next, servname);
910	} else {
911		GET_AI(cur->ai_next, afd, afd->a_loopback);
912		/* xxx meaningless?
913		 * GET_CANONNAME(cur->ai_next, "localhost");
914		 */
915		GET_PORT(cur->ai_next, servname);
916	}
917	cur = cur->ai_next;
918
919	*res = sentinel.ai_next;
920	return 0;
921
922free:
923	if (sentinel.ai_next)
924		freeaddrinfo(sentinel.ai_next);
925	return error;
926}
927
928/*
929 * numeric hostname
930 */
931static int
932explore_numeric(const struct addrinfo *pai, const char *hostname,
933    const char *servname, struct addrinfo **res, const char *canonname)
934{
935	const struct afd *afd;
936	struct addrinfo *cur;
937	struct addrinfo sentinel;
938	int error;
939	char pton[PTON_MAX];
940
941	assert(pai != NULL);
942	/* hostname may be NULL */
943	/* servname may be NULL */
944	assert(res != NULL);
945
946	*res = NULL;
947	sentinel.ai_next = NULL;
948	cur = &sentinel;
949
950	/*
951	 * if the servname does not match socktype/protocol, ignore it.
952	 */
953	if (get_portmatch(pai, servname) != 0)
954		return 0;
955
956	afd = find_afd(pai->ai_family);
957	if (afd == NULL)
958		return 0;
959
960	switch (afd->a_af) {
961#if 0 /*X/Open spec*/
962	case AF_INET:
963		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
964			if (pai->ai_family == afd->a_af ||
965			    pai->ai_family == PF_UNSPEC /*?*/) {
966				GET_AI(cur->ai_next, afd, pton);
967				GET_PORT(cur->ai_next, servname);
968				if ((pai->ai_flags & AI_CANONNAME)) {
969					/*
970					 * Set the numeric address itself as
971					 * the canonical name, based on a
972					 * clarification in rfc2553bis-03.
973					 */
974					GET_CANONNAME(cur->ai_next, canonname);
975				}
976				while (cur && cur->ai_next)
977					cur = cur->ai_next;
978			} else
979				ERR(EAI_FAMILY);	/*xxx*/
980		}
981		break;
982#endif
983	default:
984		if (inet_pton(afd->a_af, hostname, pton) == 1) {
985			if (pai->ai_family == afd->a_af ||
986			    pai->ai_family == PF_UNSPEC /*?*/) {
987				GET_AI(cur->ai_next, afd, pton);
988				GET_PORT(cur->ai_next, servname);
989				if ((pai->ai_flags & AI_CANONNAME)) {
990					/*
991					 * Set the numeric address itself as
992					 * the canonical name, based on a
993					 * clarification in rfc2553bis-03.
994					 */
995					GET_CANONNAME(cur->ai_next, canonname);
996				}
997				while (cur->ai_next)
998					cur = cur->ai_next;
999			} else
1000				ERR(EAI_FAMILY);	/*xxx*/
1001		}
1002		break;
1003	}
1004
1005	*res = sentinel.ai_next;
1006	return 0;
1007
1008free:
1009bad:
1010	if (sentinel.ai_next)
1011		freeaddrinfo(sentinel.ai_next);
1012	return error;
1013}
1014
1015/*
1016 * numeric hostname with scope
1017 */
1018static int
1019explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
1020    const char *servname, struct addrinfo **res)
1021{
1022#if !defined(SCOPE_DELIMITER) || !defined(INET6)
1023	return explore_numeric(pai, hostname, servname, res, hostname);
1024#else
1025	const struct afd *afd;
1026	struct addrinfo *cur;
1027	int error;
1028	char *cp, *hostname2 = NULL, *scope, *addr;
1029	struct sockaddr_in6 *sin6;
1030
1031	assert(pai != NULL);
1032	/* hostname may be NULL */
1033	/* servname may be NULL */
1034	assert(res != NULL);
1035
1036	/*
1037	 * if the servname does not match socktype/protocol, ignore it.
1038	 */
1039	if (get_portmatch(pai, servname) != 0)
1040		return 0;
1041
1042	afd = find_afd(pai->ai_family);
1043	if (afd == NULL)
1044		return 0;
1045
1046	if (!afd->a_scoped)
1047		return explore_numeric(pai, hostname, servname, res, hostname);
1048
1049	cp = strchr(hostname, SCOPE_DELIMITER);
1050	if (cp == NULL)
1051		return explore_numeric(pai, hostname, servname, res, hostname);
1052
1053	/*
1054	 * Handle special case of <scoped_address><delimiter><scope id>
1055	 */
1056	hostname2 = strdup(hostname);
1057	if (hostname2 == NULL)
1058		return EAI_MEMORY;
1059	/* terminate at the delimiter */
1060	hostname2[cp - hostname] = '\0';
1061	addr = hostname2;
1062	scope = cp + 1;
1063
1064	error = explore_numeric(pai, addr, servname, res, hostname);
1065	if (error == 0) {
1066		u_int32_t scopeid;
1067
1068		for (cur = *res; cur; cur = cur->ai_next) {
1069			if (cur->ai_family != AF_INET6)
1070				continue;
1071			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
1072			if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
1073				free(hostname2);
1074				return(EAI_NODATA); /* XXX: is return OK? */
1075			}
1076			sin6->sin6_scope_id = scopeid;
1077		}
1078	}
1079
1080	free(hostname2);
1081
1082	return error;
1083#endif
1084}
1085
1086static int
1087get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
1088{
1089
1090	assert(pai != NULL);
1091	assert(ai != NULL);
1092	assert(str != NULL);
1093
1094	if ((pai->ai_flags & AI_CANONNAME) != 0) {
1095		ai->ai_canonname = strdup(str);
1096		if (ai->ai_canonname == NULL)
1097			return EAI_MEMORY;
1098	}
1099	return 0;
1100}
1101
1102static struct addrinfo *
1103get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
1104{
1105	char *p;
1106	struct addrinfo *ai;
1107
1108	assert(pai != NULL);
1109	assert(afd != NULL);
1110	assert(addr != NULL);
1111
1112	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
1113		+ (afd->a_socklen));
1114	if (ai == NULL)
1115		return NULL;
1116
1117	memcpy(ai, pai, sizeof(struct addrinfo));
1118	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
1119	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
1120
1121#ifdef HAVE_SA_LEN
1122	ai->ai_addr->sa_len = afd->a_socklen;
1123#endif
1124
1125	ai->ai_addrlen = afd->a_socklen;
1126#if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || defined(__sparc64__)
1127	ai->__ai_pad0 = 0;
1128#endif
1129	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
1130	p = (char *)(void *)(ai->ai_addr);
1131	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
1132	return ai;
1133}
1134
1135static int
1136get_portmatch(const struct addrinfo *ai, const char *servname)
1137{
1138
1139	assert(ai != NULL);
1140	/* servname may be NULL */
1141
1142	return get_port(ai, servname, 1);
1143}
1144
1145static int
1146get_port(const struct addrinfo *ai, const char *servname, int matchonly)
1147{
1148	const char *proto;
1149	struct servent *sp;
1150	int port;
1151	int allownumeric;
1152
1153	assert(ai != NULL);
1154	/* servname may be NULL */
1155
1156	if (servname == NULL)
1157		return 0;
1158	switch (ai->ai_family) {
1159	case AF_INET:
1160#ifdef AF_INET6
1161	case AF_INET6:
1162#endif
1163		break;
1164	default:
1165		return 0;
1166	}
1167
1168	switch (ai->ai_socktype) {
1169	case SOCK_RAW:
1170		return EAI_SERVICE;
1171	case SOCK_DGRAM:
1172	case SOCK_STREAM:
1173		allownumeric = 1;
1174		break;
1175	case ANY:
1176#if 1  /* ANDROID-SPECIFIC CHANGE TO MATCH GLIBC */
1177		allownumeric = 1;
1178#else
1179		allownumeric = 0;
1180#endif
1181		break;
1182	default:
1183		return EAI_SOCKTYPE;
1184	}
1185
1186	port = str2number(servname);
1187	if (port >= 0) {
1188		if (!allownumeric)
1189			return EAI_SERVICE;
1190		if (port < 0 || port > 65535)
1191			return EAI_SERVICE;
1192		port = htons(port);
1193	} else {
1194		if (ai->ai_flags & AI_NUMERICSERV)
1195			return EAI_NONAME;
1196
1197		switch (ai->ai_socktype) {
1198		case SOCK_DGRAM:
1199			proto = "udp";
1200			break;
1201		case SOCK_STREAM:
1202			proto = "tcp";
1203			break;
1204		default:
1205			proto = NULL;
1206			break;
1207		}
1208
1209		if ((sp = getservbyname(servname, proto)) == NULL)
1210			return EAI_SERVICE;
1211		port = sp->s_port;
1212	}
1213
1214	if (!matchonly) {
1215		switch (ai->ai_family) {
1216		case AF_INET:
1217			((struct sockaddr_in *)(void *)
1218			    ai->ai_addr)->sin_port = port;
1219			break;
1220#ifdef INET6
1221		case AF_INET6:
1222			((struct sockaddr_in6 *)(void *)
1223			    ai->ai_addr)->sin6_port = port;
1224			break;
1225#endif
1226		}
1227	}
1228
1229	return 0;
1230}
1231
1232static const struct afd *
1233find_afd(int af)
1234{
1235	const struct afd *afd;
1236
1237	if (af == PF_UNSPEC)
1238		return NULL;
1239	for (afd = afdl; afd->a_af; afd++) {
1240		if (afd->a_af == af)
1241			return afd;
1242	}
1243	return NULL;
1244}
1245
1246#ifdef INET6
1247/* convert a string to a scope identifier. XXX: IPv6 specific */
1248static int
1249ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
1250{
1251	u_long lscopeid;
1252	struct in6_addr *a6;
1253	char *ep;
1254
1255	assert(scope != NULL);
1256	assert(sin6 != NULL);
1257	assert(scopeid != NULL);
1258
1259	a6 = &sin6->sin6_addr;
1260
1261	/* empty scopeid portion is invalid */
1262	if (*scope == '\0')
1263		return -1;
1264
1265	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
1266		/*
1267		 * We currently assume a one-to-one mapping between links
1268		 * and interfaces, so we simply use interface indices for
1269		 * like-local scopes.
1270		 */
1271		*scopeid = if_nametoindex(scope);
1272		if (*scopeid == 0)
1273			goto trynumeric;
1274		return 0;
1275	}
1276
1277	/* still unclear about literal, allow numeric only - placeholder */
1278	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1279		goto trynumeric;
1280	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1281		goto trynumeric;
1282	else
1283		goto trynumeric;	/* global */
1284
1285	/* try to convert to a numeric id as a last resort */
1286  trynumeric:
1287	errno = 0;
1288	lscopeid = strtoul(scope, &ep, 10);
1289	*scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1290	if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1291		return 0;
1292	else
1293		return -1;
1294}
1295#endif
1296
1297/* code duplicate with gethnamaddr.c */
1298
1299static const char AskedForGot[] =
1300	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1301
1302static struct addrinfo *
1303getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
1304    const struct addrinfo *pai)
1305{
1306	struct addrinfo sentinel, *cur;
1307	struct addrinfo ai;
1308	const struct afd *afd;
1309	char *canonname;
1310	const HEADER *hp;
1311	const u_char *cp;
1312	int n;
1313	const u_char *eom;
1314	char *bp, *ep;
1315	int type, class, ancount, qdcount;
1316	int haveanswer, had_error;
1317	char tbuf[MAXDNAME];
1318	int (*name_ok) (const char *);
1319	char hostbuf[8*1024];
1320
1321	assert(answer != NULL);
1322	assert(qname != NULL);
1323	assert(pai != NULL);
1324
1325	memset(&sentinel, 0, sizeof(sentinel));
1326	cur = &sentinel;
1327
1328	canonname = NULL;
1329	eom = answer->buf + anslen;
1330	switch (qtype) {
1331	case T_A:
1332	case T_AAAA:
1333	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
1334		name_ok = res_hnok;
1335		break;
1336	default:
1337		return NULL;	/* XXX should be abort(); */
1338	}
1339	/*
1340	 * find first satisfactory answer
1341	 */
1342	hp = &answer->hdr;
1343	ancount = ntohs(hp->ancount);
1344	qdcount = ntohs(hp->qdcount);
1345	bp = hostbuf;
1346	ep = hostbuf + sizeof hostbuf;
1347	cp = answer->buf + HFIXEDSZ;
1348	if (qdcount != 1) {
1349		h_errno = NO_RECOVERY;
1350		return (NULL);
1351	}
1352	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1353	if ((n < 0) || !(*name_ok)(bp)) {
1354		h_errno = NO_RECOVERY;
1355		return (NULL);
1356	}
1357	cp += n + QFIXEDSZ;
1358	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1359		/* res_send() has already verified that the query name is the
1360		 * same as the one we sent; this just gets the expanded name
1361		 * (i.e., with the succeeding search-domain tacked on).
1362		 */
1363		n = strlen(bp) + 1;		/* for the \0 */
1364		if (n >= MAXHOSTNAMELEN) {
1365			h_errno = NO_RECOVERY;
1366			return (NULL);
1367		}
1368		canonname = bp;
1369		bp += n;
1370		/* The qname can be abbreviated, but h_name is now absolute. */
1371		qname = canonname;
1372	}
1373	haveanswer = 0;
1374	had_error = 0;
1375	while (ancount-- > 0 && cp < eom && !had_error) {
1376		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1377		if ((n < 0) || !(*name_ok)(bp)) {
1378			had_error++;
1379			continue;
1380		}
1381		cp += n;			/* name */
1382		type = _getshort(cp);
1383 		cp += INT16SZ;			/* type */
1384		class = _getshort(cp);
1385 		cp += INT16SZ + INT32SZ;	/* class, TTL */
1386		n = _getshort(cp);
1387		cp += INT16SZ;			/* len */
1388		if (class != C_IN) {
1389			/* XXX - debug? syslog? */
1390			cp += n;
1391			continue;		/* XXX - had_error++ ? */
1392		}
1393		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1394		    type == T_CNAME) {
1395			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1396			if ((n < 0) || !(*name_ok)(tbuf)) {
1397				had_error++;
1398				continue;
1399			}
1400			cp += n;
1401			/* Get canonical name. */
1402			n = strlen(tbuf) + 1;	/* for the \0 */
1403			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1404				had_error++;
1405				continue;
1406			}
1407			strlcpy(bp, tbuf, (size_t)(ep - bp));
1408			canonname = bp;
1409			bp += n;
1410			continue;
1411		}
1412		if (qtype == T_ANY) {
1413			if (!(type == T_A || type == T_AAAA)) {
1414				cp += n;
1415				continue;
1416			}
1417		} else if (type != qtype) {
1418			if (type != T_KEY && type != T_SIG)
1419				syslog(LOG_NOTICE|LOG_AUTH,
1420	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1421				       qname, p_class(C_IN), p_type(qtype),
1422				       p_type(type));
1423			cp += n;
1424			continue;		/* XXX - had_error++ ? */
1425		}
1426		switch (type) {
1427		case T_A:
1428		case T_AAAA:
1429			if (strcasecmp(canonname, bp) != 0) {
1430				syslog(LOG_NOTICE|LOG_AUTH,
1431				       AskedForGot, canonname, bp);
1432				cp += n;
1433				continue;	/* XXX - had_error++ ? */
1434			}
1435			if (type == T_A && n != INADDRSZ) {
1436				cp += n;
1437				continue;
1438			}
1439			if (type == T_AAAA && n != IN6ADDRSZ) {
1440				cp += n;
1441				continue;
1442			}
1443			if (type == T_AAAA) {
1444				struct in6_addr in6;
1445				memcpy(&in6, cp, IN6ADDRSZ);
1446				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1447					cp += n;
1448					continue;
1449				}
1450			}
1451			if (!haveanswer) {
1452				int nn;
1453
1454				canonname = bp;
1455				nn = strlen(bp) + 1;	/* for the \0 */
1456				bp += nn;
1457			}
1458
1459			/* don't overwrite pai */
1460			ai = *pai;
1461			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1462			afd = find_afd(ai.ai_family);
1463			if (afd == NULL) {
1464				cp += n;
1465				continue;
1466			}
1467			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1468			if (cur->ai_next == NULL)
1469				had_error++;
1470			while (cur && cur->ai_next)
1471				cur = cur->ai_next;
1472			cp += n;
1473			break;
1474		default:
1475			abort();
1476		}
1477		if (!had_error)
1478			haveanswer++;
1479	}
1480	if (haveanswer) {
1481		if (!canonname)
1482			(void)get_canonname(pai, sentinel.ai_next, qname);
1483		else
1484			(void)get_canonname(pai, sentinel.ai_next, canonname);
1485		h_errno = NETDB_SUCCESS;
1486		return sentinel.ai_next;
1487	}
1488
1489	h_errno = NO_RECOVERY;
1490	return NULL;
1491}
1492
1493struct addrinfo_sort_elem {
1494	struct addrinfo *ai;
1495	int has_src_addr;
1496	sockaddr_union src_addr;
1497	int original_order;
1498};
1499
1500/*ARGSUSED*/
1501static int
1502_get_scope(const struct sockaddr *addr)
1503{
1504	if (addr->sa_family == AF_INET6) {
1505		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
1506		if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) {
1507			return IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
1508		} else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
1509			   IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) {
1510			/*
1511			 * RFC 4291 section 2.5.3 says loopback is to be treated as having
1512			 * link-local scope.
1513			 */
1514			return IPV6_ADDR_SCOPE_LINKLOCAL;
1515		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
1516			return IPV6_ADDR_SCOPE_SITELOCAL;
1517		} else {
1518			return IPV6_ADDR_SCOPE_GLOBAL;
1519		}
1520	} else if (addr->sa_family == AF_INET) {
1521		const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr;
1522		unsigned long int na = ntohl(addr4->sin_addr.s_addr);
1523
1524		if (IN_LOOPBACK(na) ||                          /* 127.0.0.0/8 */
1525		    (na & 0xffff0000) == 0xa9fe0000) {          /* 169.254.0.0/16 */
1526			return IPV6_ADDR_SCOPE_LINKLOCAL;
1527		} else {
1528			/*
1529			 * RFC 6724 section 3.2. Other IPv4 addresses, including private addresses
1530			 * and shared addresses (100.64.0.0/10), are assigned global scope.
1531			 */
1532			return IPV6_ADDR_SCOPE_GLOBAL;
1533		}
1534	} else {
1535		/*
1536		 * This should never happen.
1537		 * Return a scope with low priority as a last resort.
1538		 */
1539		return IPV6_ADDR_SCOPE_NODELOCAL;
1540	}
1541}
1542
1543/* These macros are modelled after the ones in <netinet/in6.h>. */
1544
1545/* RFC 4380, section 2.6 */
1546#define IN6_IS_ADDR_TEREDO(a)	 \
1547	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
1548
1549/* RFC 3056, section 2. */
1550#define IN6_IS_ADDR_6TO4(a)	 \
1551	(((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
1552
1553/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
1554#define IN6_IS_ADDR_6BONE(a)      \
1555	(((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
1556
1557/*
1558 * Get the label for a given IPv4/IPv6 address.
1559 * RFC 6724, section 2.1.
1560 */
1561
1562/*ARGSUSED*/
1563static int
1564_get_label(const struct sockaddr *addr)
1565{
1566	if (addr->sa_family == AF_INET) {
1567		return 4;
1568	} else if (addr->sa_family == AF_INET6) {
1569		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
1570		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
1571			return 0;
1572		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
1573			return 4;
1574		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
1575			return 2;
1576		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
1577			return 5;
1578		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
1579			return 13;
1580		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
1581			return 3;
1582		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
1583			return 11;
1584		} else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
1585			return 12;
1586		} else {
1587			/* All other IPv6 addresses, including global unicast addresses. */
1588			return 1;
1589		}
1590	} else {
1591		/*
1592		 * This should never happen.
1593		 * Return a semi-random label as a last resort.
1594		 */
1595		return 1;
1596	}
1597}
1598
1599/*
1600 * Get the precedence for a given IPv4/IPv6 address.
1601 * RFC 6724, section 2.1.
1602 */
1603
1604/*ARGSUSED*/
1605static int
1606_get_precedence(const struct sockaddr *addr)
1607{
1608	if (addr->sa_family == AF_INET) {
1609		return 35;
1610	} else if (addr->sa_family == AF_INET6) {
1611		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
1612		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
1613			return 50;
1614		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
1615			return 35;
1616		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
1617			return 30;
1618		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
1619			return 5;
1620		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
1621			return 3;
1622		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
1623		           IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
1624		           IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
1625			return 1;
1626		} else {
1627			/* All other IPv6 addresses, including global unicast addresses. */
1628			return 40;
1629		}
1630	} else {
1631		return 1;
1632	}
1633}
1634
1635/*
1636 * Find number of matching initial bits between the two addresses a1 and a2.
1637 */
1638
1639/*ARGSUSED*/
1640static int
1641_common_prefix_len(const struct in6_addr *a1, const struct in6_addr *a2)
1642{
1643	const char *p1 = (const char *)a1;
1644	const char *p2 = (const char *)a2;
1645	unsigned i;
1646
1647	for (i = 0; i < sizeof(*a1); ++i) {
1648		int x, j;
1649
1650		if (p1[i] == p2[i]) {
1651			continue;
1652		}
1653		x = p1[i] ^ p2[i];
1654		for (j = 0; j < CHAR_BIT; ++j) {
1655			if (x & (1 << (CHAR_BIT - 1))) {
1656				return i * CHAR_BIT + j;
1657			}
1658			x <<= 1;
1659		}
1660	}
1661	return sizeof(*a1) * CHAR_BIT;
1662}
1663
1664/*
1665 * Compare two source/destination address pairs.
1666 * RFC 6724, section 6.
1667 */
1668
1669/*ARGSUSED*/
1670static int
1671_rfc6724_compare(const void *ptr1, const void* ptr2)
1672{
1673	const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
1674	const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
1675	int scope_src1, scope_dst1, scope_match1;
1676	int scope_src2, scope_dst2, scope_match2;
1677	int label_src1, label_dst1, label_match1;
1678	int label_src2, label_dst2, label_match2;
1679	int precedence1, precedence2;
1680	int prefixlen1, prefixlen2;
1681
1682	/* Rule 1: Avoid unusable destinations. */
1683	if (a1->has_src_addr != a2->has_src_addr) {
1684		return a2->has_src_addr - a1->has_src_addr;
1685	}
1686
1687	/* Rule 2: Prefer matching scope. */
1688	scope_src1 = _get_scope(&a1->src_addr.generic);
1689	scope_dst1 = _get_scope(a1->ai->ai_addr);
1690	scope_match1 = (scope_src1 == scope_dst1);
1691
1692	scope_src2 = _get_scope(&a2->src_addr.generic);
1693	scope_dst2 = _get_scope(a2->ai->ai_addr);
1694	scope_match2 = (scope_src2 == scope_dst2);
1695
1696	if (scope_match1 != scope_match2) {
1697		return scope_match2 - scope_match1;
1698	}
1699
1700	/*
1701	 * Rule 3: Avoid deprecated addresses.
1702	 * TODO(sesse): We don't currently have a good way of finding this.
1703	 */
1704
1705	/*
1706	 * Rule 4: Prefer home addresses.
1707	 * TODO(sesse): We don't currently have a good way of finding this.
1708	 */
1709
1710	/* Rule 5: Prefer matching label. */
1711	label_src1 = _get_label(&a1->src_addr.generic);
1712	label_dst1 = _get_label(a1->ai->ai_addr);
1713	label_match1 = (label_src1 == label_dst1);
1714
1715	label_src2 = _get_label(&a2->src_addr.generic);
1716	label_dst2 = _get_label(a2->ai->ai_addr);
1717	label_match2 = (label_src2 == label_dst2);
1718
1719	if (label_match1 != label_match2) {
1720		return label_match2 - label_match1;
1721	}
1722
1723	/* Rule 6: Prefer higher precedence. */
1724	precedence1 = _get_precedence(a1->ai->ai_addr);
1725	precedence2 = _get_precedence(a2->ai->ai_addr);
1726	if (precedence1 != precedence2) {
1727		return precedence2 - precedence1;
1728	}
1729
1730	/*
1731	 * Rule 7: Prefer native transport.
1732	 * TODO(sesse): We don't currently have a good way of finding this.
1733	 */
1734
1735	/* Rule 8: Prefer smaller scope. */
1736	if (scope_dst1 != scope_dst2) {
1737		return scope_dst1 - scope_dst2;
1738	}
1739
1740	/*
1741	 * Rule 9: Use longest matching prefix.
1742         * We implement this for IPv6 only, as the rules in RFC 6724 don't seem
1743         * to work very well directly applied to IPv4. (glibc uses information from
1744         * the routing table for a custom IPv4 implementation here.)
1745	 */
1746	if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
1747	    a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) {
1748		const struct sockaddr_in6 *a1_src = &a1->src_addr.in6;
1749		const struct sockaddr_in6 *a1_dst = (const struct sockaddr_in6 *)a1->ai->ai_addr;
1750		const struct sockaddr_in6 *a2_src = &a2->src_addr.in6;
1751		const struct sockaddr_in6 *a2_dst = (const struct sockaddr_in6 *)a2->ai->ai_addr;
1752		prefixlen1 = _common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
1753		prefixlen2 = _common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
1754		if (prefixlen1 != prefixlen2) {
1755			return prefixlen2 - prefixlen1;
1756		}
1757	}
1758
1759	/*
1760	 * Rule 10: Leave the order unchanged.
1761	 * We need this since qsort() is not necessarily stable.
1762	 */
1763	return a1->original_order - a2->original_order;
1764}
1765
1766/*
1767 * Find the source address that will be used if trying to connect to the given
1768 * address. src_addr must be large enough to hold a struct sockaddr_in6.
1769 *
1770 * Returns 1 if a source address was found, 0 if the address is unreachable,
1771 * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
1772 * undefined.
1773 */
1774
1775/*ARGSUSED*/
1776static int
1777_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned mark)
1778{
1779	int sock;
1780	int ret;
1781	socklen_t len;
1782
1783	switch (addr->sa_family) {
1784	case AF_INET:
1785		len = sizeof(struct sockaddr_in);
1786		break;
1787	case AF_INET6:
1788		len = sizeof(struct sockaddr_in6);
1789		break;
1790	default:
1791		/* No known usable source address for non-INET families. */
1792		return 0;
1793	}
1794
1795	sock = socket(addr->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
1796	if (sock == -1) {
1797		if (errno == EAFNOSUPPORT) {
1798			return 0;
1799		} else {
1800			return -1;
1801		}
1802	}
1803	if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
1804		return 0;
1805	do {
1806		ret = __connect(sock, addr, len);
1807	} while (ret == -1 && errno == EINTR);
1808
1809	if (ret == -1) {
1810		close(sock);
1811		return 0;
1812	}
1813
1814	if (getsockname(sock, src_addr, &len) == -1) {
1815		close(sock);
1816		return -1;
1817	}
1818	close(sock);
1819	return 1;
1820}
1821
1822/*
1823 * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
1824 * Will leave the list unchanged if an error occurs.
1825 */
1826
1827/*ARGSUSED*/
1828static void
1829_rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark)
1830{
1831	struct addrinfo *cur;
1832	int nelem = 0, i;
1833	struct addrinfo_sort_elem *elems;
1834
1835	cur = list_sentinel->ai_next;
1836	while (cur) {
1837		++nelem;
1838		cur = cur->ai_next;
1839	}
1840
1841	elems = (struct addrinfo_sort_elem *)malloc(nelem * sizeof(struct addrinfo_sort_elem));
1842	if (elems == NULL) {
1843		goto error;
1844	}
1845
1846	/*
1847	 * Convert the linked list to an array that also contains the candidate
1848	 * source address for each destination address.
1849	 */
1850	for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next) {
1851		int has_src_addr;
1852		assert(cur != NULL);
1853		elems[i].ai = cur;
1854		elems[i].original_order = i;
1855
1856		has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic, mark);
1857		if (has_src_addr == -1) {
1858			goto error;
1859		}
1860		elems[i].has_src_addr = has_src_addr;
1861	}
1862
1863	/* Sort the addresses, and rearrange the linked list so it matches the sorted order. */
1864	qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc6724_compare);
1865
1866	list_sentinel->ai_next = elems[0].ai;
1867	for (i = 0; i < nelem - 1; ++i) {
1868		elems[i].ai->ai_next = elems[i + 1].ai;
1869	}
1870	elems[nelem - 1].ai->ai_next = NULL;
1871
1872error:
1873	free(elems);
1874}
1875
1876/*ARGSUSED*/
1877static int
1878_dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
1879{
1880	struct addrinfo *ai;
1881	querybuf *buf, *buf2;
1882	const char *name;
1883	const struct addrinfo *pai;
1884	struct addrinfo sentinel, *cur;
1885	struct res_target q, q2;
1886	res_state res;
1887	unsigned netid, mark;
1888
1889	name = va_arg(ap, char *);
1890	pai = va_arg(ap, const struct addrinfo *);
1891	netid = va_arg(ap, unsigned);
1892	mark = va_arg(ap, unsigned);
1893	//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
1894
1895	memset(&q, 0, sizeof(q));
1896	memset(&q2, 0, sizeof(q2));
1897	memset(&sentinel, 0, sizeof(sentinel));
1898	cur = &sentinel;
1899
1900	buf = malloc(sizeof(*buf));
1901	if (buf == NULL) {
1902		h_errno = NETDB_INTERNAL;
1903		return NS_NOTFOUND;
1904	}
1905	buf2 = malloc(sizeof(*buf2));
1906	if (buf2 == NULL) {
1907		free(buf);
1908		h_errno = NETDB_INTERNAL;
1909		return NS_NOTFOUND;
1910	}
1911
1912	switch (pai->ai_family) {
1913	case AF_UNSPEC:
1914		/* prefer IPv6 */
1915		q.name = name;
1916		q.qclass = C_IN;
1917		q.answer = buf->buf;
1918		q.anslen = sizeof(buf->buf);
1919		int query_ipv6 = 1, query_ipv4 = 1;
1920		if (pai->ai_flags & AI_ADDRCONFIG) {
1921			query_ipv6 = _have_ipv6(mark);
1922			query_ipv4 = _have_ipv4(mark);
1923		}
1924		if (query_ipv6) {
1925			q.qtype = T_AAAA;
1926			if (query_ipv4) {
1927				q.next = &q2;
1928				q2.name = name;
1929				q2.qclass = C_IN;
1930				q2.qtype = T_A;
1931				q2.answer = buf2->buf;
1932				q2.anslen = sizeof(buf2->buf);
1933			}
1934		} else if (query_ipv4) {
1935			q.qtype = T_A;
1936		} else {
1937			free(buf);
1938			free(buf2);
1939			return NS_NOTFOUND;
1940		}
1941		break;
1942	case AF_INET:
1943		q.name = name;
1944		q.qclass = C_IN;
1945		q.qtype = T_A;
1946		q.answer = buf->buf;
1947		q.anslen = sizeof(buf->buf);
1948		break;
1949	case AF_INET6:
1950		q.name = name;
1951		q.qclass = C_IN;
1952		q.qtype = T_AAAA;
1953		q.answer = buf->buf;
1954		q.anslen = sizeof(buf->buf);
1955		break;
1956	default:
1957		free(buf);
1958		free(buf2);
1959		return NS_UNAVAIL;
1960	}
1961
1962	res = __res_get_state();
1963	if (res == NULL) {
1964		free(buf);
1965		free(buf2);
1966		return NS_NOTFOUND;
1967	}
1968
1969	/* this just sets our netid val in the thread private data so we don't have to
1970	 * modify the api's all the way down to res_send.c's res_nsend.  We could
1971	 * fully populate the thread private data here, but if we get down there
1972	 * and have a cache hit that would be wasted, so we do the rest there on miss
1973	 */
1974	res_setnetid(res, netid);
1975	res_setmark(res, mark);
1976	if (res_searchN(name, &q, res) < 0) {
1977		__res_put_state(res);
1978		free(buf);
1979		free(buf2);
1980		return NS_NOTFOUND;
1981	}
1982	ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1983	if (ai) {
1984		cur->ai_next = ai;
1985		while (cur && cur->ai_next)
1986			cur = cur->ai_next;
1987	}
1988	if (q.next) {
1989		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1990		if (ai)
1991			cur->ai_next = ai;
1992	}
1993	free(buf);
1994	free(buf2);
1995	if (sentinel.ai_next == NULL) {
1996		__res_put_state(res);
1997		switch (h_errno) {
1998		case HOST_NOT_FOUND:
1999			return NS_NOTFOUND;
2000		case TRY_AGAIN:
2001			return NS_TRYAGAIN;
2002		default:
2003			return NS_UNAVAIL;
2004		}
2005	}
2006
2007	_rfc6724_sort(&sentinel, netid);
2008
2009	__res_put_state(res);
2010
2011	*((struct addrinfo **)rv) = sentinel.ai_next;
2012	return NS_SUCCESS;
2013}
2014
2015static void
2016_sethtent(FILE **hostf)
2017{
2018
2019	if (!*hostf)
2020		*hostf = fopen(_PATH_HOSTS, "r" );
2021	else
2022		rewind(*hostf);
2023}
2024
2025static void
2026_endhtent(FILE **hostf)
2027{
2028
2029	if (*hostf) {
2030		(void) fclose(*hostf);
2031		*hostf = NULL;
2032	}
2033}
2034
2035static struct addrinfo *
2036_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
2037{
2038	char *p;
2039	char *cp, *tname, *cname;
2040	struct addrinfo hints, *res0, *res;
2041	int error;
2042	const char *addr;
2043	char hostbuf[8*1024];
2044
2045//	fprintf(stderr, "_gethtent() name = '%s'\n", name);
2046	assert(name != NULL);
2047	assert(pai != NULL);
2048
2049	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r" )))
2050		return (NULL);
2051 again:
2052	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
2053		return (NULL);
2054	if (*p == '#')
2055		goto again;
2056	if (!(cp = strpbrk(p, "#\n")))
2057		goto again;
2058	*cp = '\0';
2059	if (!(cp = strpbrk(p, " \t")))
2060		goto again;
2061	*cp++ = '\0';
2062	addr = p;
2063	/* if this is not something we're looking for, skip it. */
2064	cname = NULL;
2065	while (cp && *cp) {
2066		if (*cp == ' ' || *cp == '\t') {
2067			cp++;
2068			continue;
2069		}
2070		if (!cname)
2071			cname = cp;
2072		tname = cp;
2073		if ((cp = strpbrk(cp, " \t")) != NULL)
2074			*cp++ = '\0';
2075//		fprintf(stderr, "\ttname = '%s'", tname);
2076		if (strcasecmp(name, tname) == 0)
2077			goto found;
2078	}
2079	goto again;
2080
2081found:
2082	hints = *pai;
2083	hints.ai_flags = AI_NUMERICHOST;
2084	error = getaddrinfo(addr, NULL, &hints, &res0);
2085	if (error)
2086		goto again;
2087	for (res = res0; res; res = res->ai_next) {
2088		/* cover it up */
2089		res->ai_flags = pai->ai_flags;
2090
2091		if (pai->ai_flags & AI_CANONNAME) {
2092			if (get_canonname(pai, res, cname) != 0) {
2093				freeaddrinfo(res0);
2094				goto again;
2095			}
2096		}
2097	}
2098	return res0;
2099}
2100
2101/*ARGSUSED*/
2102static int
2103_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
2104{
2105	const char *name;
2106	const struct addrinfo *pai;
2107	struct addrinfo sentinel, *cur;
2108	struct addrinfo *p;
2109	FILE *hostf = NULL;
2110
2111	name = va_arg(ap, char *);
2112	pai = va_arg(ap, struct addrinfo *);
2113
2114//	fprintf(stderr, "_files_getaddrinfo() name = '%s'\n", name);
2115	memset(&sentinel, 0, sizeof(sentinel));
2116	cur = &sentinel;
2117
2118	_sethtent(&hostf);
2119	while ((p = _gethtent(&hostf, name, pai)) != NULL) {
2120		cur->ai_next = p;
2121		while (cur && cur->ai_next)
2122			cur = cur->ai_next;
2123	}
2124	_endhtent(&hostf);
2125
2126	*((struct addrinfo **)rv) = sentinel.ai_next;
2127	if (sentinel.ai_next == NULL)
2128		return NS_NOTFOUND;
2129	return NS_SUCCESS;
2130}
2131
2132/* resolver logic */
2133
2134/*
2135 * Formulate a normal query, send, and await answer.
2136 * Returned answer is placed in supplied buffer "answer".
2137 * Perform preliminary check of answer, returning success only
2138 * if no error is indicated and the answer count is nonzero.
2139 * Return the size of the response on success, -1 on error.
2140 * Error number is left in h_errno.
2141 *
2142 * Caller must parse answer and determine whether it answers the question.
2143 */
2144static int
2145res_queryN(const char *name, /* domain name */ struct res_target *target,
2146    res_state res)
2147{
2148	u_char buf[MAXPACKET];
2149	HEADER *hp;
2150	int n;
2151	struct res_target *t;
2152	int rcode;
2153	int ancount;
2154
2155	assert(name != NULL);
2156	/* XXX: target may be NULL??? */
2157
2158	rcode = NOERROR;
2159	ancount = 0;
2160
2161	for (t = target; t; t = t->next) {
2162		int class, type;
2163		u_char *answer;
2164		int anslen;
2165
2166		hp = (HEADER *)(void *)t->answer;
2167		hp->rcode = NOERROR;	/* default */
2168
2169		/* make it easier... */
2170		class = t->qclass;
2171		type = t->qtype;
2172		answer = t->answer;
2173		anslen = t->anslen;
2174#ifdef DEBUG
2175		if (res->options & RES_DEBUG)
2176			printf(";; res_nquery(%s, %d, %d)\n", name, class, type);
2177#endif
2178
2179		n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL,
2180		    buf, sizeof(buf));
2181#ifdef RES_USE_EDNS0
2182		if (n > 0 && (res->options & RES_USE_EDNS0) != 0)
2183			n = res_nopt(res, n, buf, sizeof(buf), anslen);
2184#endif
2185		if (n <= 0) {
2186#ifdef DEBUG
2187			if (res->options & RES_DEBUG)
2188				printf(";; res_nquery: mkquery failed\n");
2189#endif
2190			h_errno = NO_RECOVERY;
2191			return n;
2192		}
2193		n = res_nsend(res, buf, n, answer, anslen);
2194#if 0
2195		if (n < 0) {
2196#ifdef DEBUG
2197			if (res->options & RES_DEBUG)
2198				printf(";; res_query: send error\n");
2199#endif
2200			h_errno = TRY_AGAIN;
2201			return n;
2202		}
2203#endif
2204
2205		if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
2206			rcode = hp->rcode;	/* record most recent error */
2207#ifdef DEBUG
2208			if (res->options & RES_DEBUG)
2209				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
2210				    ntohs(hp->ancount));
2211#endif
2212			continue;
2213		}
2214
2215		ancount += ntohs(hp->ancount);
2216
2217		t->n = n;
2218	}
2219
2220	if (ancount == 0) {
2221		switch (rcode) {
2222		case NXDOMAIN:
2223			h_errno = HOST_NOT_FOUND;
2224			break;
2225		case SERVFAIL:
2226			h_errno = TRY_AGAIN;
2227			break;
2228		case NOERROR:
2229			h_errno = NO_DATA;
2230			break;
2231		case FORMERR:
2232		case NOTIMP:
2233		case REFUSED:
2234		default:
2235			h_errno = NO_RECOVERY;
2236			break;
2237		}
2238		return -1;
2239	}
2240	return ancount;
2241}
2242
2243/*
2244 * Formulate a normal query, send, and retrieve answer in supplied buffer.
2245 * Return the size of the response on success, -1 on error.
2246 * If enabled, implement search rules until answer or unrecoverable failure
2247 * is detected.  Error code, if any, is left in h_errno.
2248 */
2249static int
2250res_searchN(const char *name, struct res_target *target, res_state res)
2251{
2252	const char *cp, * const *domain;
2253	HEADER *hp;
2254	u_int dots;
2255	int trailing_dot, ret, saved_herrno;
2256	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
2257
2258	assert(name != NULL);
2259	assert(target != NULL);
2260
2261	hp = (HEADER *)(void *)target->answer;	/*XXX*/
2262
2263	errno = 0;
2264	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
2265	dots = 0;
2266	for (cp = name; *cp; cp++)
2267		dots += (*cp == '.');
2268	trailing_dot = 0;
2269	if (cp > name && *--cp == '.')
2270		trailing_dot++;
2271
2272
2273        //fprintf(stderr, "res_searchN() name = '%s'\n", name);
2274
2275	/*
2276	 * if there aren't any dots, it could be a user-level alias
2277	 */
2278	if (!dots && (cp = __hostalias(name)) != NULL) {
2279		ret = res_queryN(cp, target, res);
2280		return ret;
2281	}
2282
2283	/*
2284	 * If there are dots in the name already, let's just give it a try
2285	 * 'as is'.  The threshold can be set with the "ndots" option.
2286	 */
2287	saved_herrno = -1;
2288	if (dots >= res->ndots) {
2289		ret = res_querydomainN(name, NULL, target, res);
2290		if (ret > 0)
2291			return (ret);
2292		saved_herrno = h_errno;
2293		tried_as_is++;
2294	}
2295
2296	/*
2297	 * We do at least one level of search if
2298	 *	- there is no dot and RES_DEFNAME is set, or
2299	 *	- there is at least one dot, there is no trailing dot,
2300	 *	  and RES_DNSRCH is set.
2301	 */
2302	if ((!dots && (res->options & RES_DEFNAMES)) ||
2303	    (dots && !trailing_dot && (res->options & RES_DNSRCH))) {
2304		int done = 0;
2305
2306		/* Unfortunately we need to set stuff up before
2307		 * the domain stuff is tried.  Will have a better
2308		 * fix after thread pools are used.
2309		 */
2310		_resolv_populate_res_for_net(res);
2311
2312		for (domain = (const char * const *)res->dnsrch;
2313		   *domain && !done;
2314		   domain++) {
2315
2316			ret = res_querydomainN(name, *domain, target, res);
2317			if (ret > 0)
2318				return ret;
2319
2320			/*
2321			 * If no server present, give up.
2322			 * If name isn't found in this domain,
2323			 * keep trying higher domains in the search list
2324			 * (if that's enabled).
2325			 * On a NO_DATA error, keep trying, otherwise
2326			 * a wildcard entry of another type could keep us
2327			 * from finding this entry higher in the domain.
2328			 * If we get some other error (negative answer or
2329			 * server failure), then stop searching up,
2330			 * but try the input name below in case it's
2331			 * fully-qualified.
2332			 */
2333			if (errno == ECONNREFUSED) {
2334				h_errno = TRY_AGAIN;
2335				return -1;
2336			}
2337
2338			switch (h_errno) {
2339			case NO_DATA:
2340				got_nodata++;
2341				/* FALLTHROUGH */
2342			case HOST_NOT_FOUND:
2343				/* keep trying */
2344				break;
2345			case TRY_AGAIN:
2346				if (hp->rcode == SERVFAIL) {
2347					/* try next search element, if any */
2348					got_servfail++;
2349					break;
2350				}
2351				/* FALLTHROUGH */
2352			default:
2353				/* anything else implies that we're done */
2354				done++;
2355			}
2356			/*
2357			 * if we got here for some reason other than DNSRCH,
2358			 * we only wanted one iteration of the loop, so stop.
2359			 */
2360			if (!(res->options & RES_DNSRCH))
2361			        done++;
2362		}
2363	}
2364
2365	/*
2366	 * if we have not already tried the name "as is", do that now.
2367	 * note that we do this regardless of how many dots were in the
2368	 * name or whether it ends with a dot.
2369	 */
2370	if (!tried_as_is) {
2371		ret = res_querydomainN(name, NULL, target, res);
2372		if (ret > 0)
2373			return ret;
2374	}
2375
2376	/*
2377	 * if we got here, we didn't satisfy the search.
2378	 * if we did an initial full query, return that query's h_errno
2379	 * (note that we wouldn't be here if that query had succeeded).
2380	 * else if we ever got a nodata, send that back as the reason.
2381	 * else send back meaningless h_errno, that being the one from
2382	 * the last DNSRCH we did.
2383	 */
2384	if (saved_herrno != -1)
2385		h_errno = saved_herrno;
2386	else if (got_nodata)
2387		h_errno = NO_DATA;
2388	else if (got_servfail)
2389		h_errno = TRY_AGAIN;
2390	return -1;
2391}
2392
2393/*
2394 * Perform a call on res_query on the concatenation of name and domain,
2395 * removing a trailing dot from name if domain is NULL.
2396 */
2397static int
2398res_querydomainN(const char *name, const char *domain,
2399    struct res_target *target, res_state res)
2400{
2401	char nbuf[MAXDNAME];
2402	const char *longname = nbuf;
2403	size_t n, d;
2404
2405	assert(name != NULL);
2406	/* XXX: target may be NULL??? */
2407
2408#ifdef DEBUG
2409	if (res->options & RES_DEBUG)
2410		printf(";; res_querydomain(%s, %s)\n",
2411			name, domain?domain:"<Nil>");
2412#endif
2413	if (domain == NULL) {
2414		/*
2415		 * Check for trailing '.';
2416		 * copy without '.' if present.
2417		 */
2418		n = strlen(name);
2419		if (n + 1 > sizeof(nbuf)) {
2420			h_errno = NO_RECOVERY;
2421			return -1;
2422		}
2423		if (n > 0 && name[--n] == '.') {
2424			strncpy(nbuf, name, n);
2425			nbuf[n] = '\0';
2426		} else
2427			longname = name;
2428	} else {
2429		n = strlen(name);
2430		d = strlen(domain);
2431		if (n + 1 + d + 1 > sizeof(nbuf)) {
2432			h_errno = NO_RECOVERY;
2433			return -1;
2434		}
2435		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
2436	}
2437	return res_queryN(longname, target, res);
2438}
2439