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