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