getaddrinfo.c revision ea9bf6788144b83cc51c454b2bfe6b980d6e947c
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_cache.h"
96#include "resolv_netid.h"
97#include "resolv_private.h"
98#include <stdbool.h>
99#include <stddef.h>
100#include <stdio.h>
101#include <stdlib.h>
102#include <string.h>
103#include <strings.h>
104#include <unistd.h>
105
106#include <syslog.h>
107#include <stdarg.h>
108#include "nsswitch.h"
109
110#ifdef ANDROID_CHANGES
111#include <sys/system_properties.h>
112#endif /* ANDROID_CHANGES */
113
114typedef union sockaddr_union {
115    struct sockaddr     generic;
116    struct sockaddr_in  in;
117    struct sockaddr_in6 in6;
118} sockaddr_union;
119
120#define SUCCESS 0
121#define ANY 0
122#define YES 1
123#define NO  0
124
125static const char in_addrany[] = { 0, 0, 0, 0 };
126static const char in_loopback[] = { 127, 0, 0, 1 };
127#ifdef INET6
128static const char in6_addrany[] = {
129	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
130};
131static const char in6_loopback[] = {
132	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
133};
134#endif
135
136// This should be synchronized to ResponseCode.h
137static const int DnsProxyQueryResult = 222;
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	(64*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 **, unsigned netid, unsigned mark);
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);
246
247static int res_queryN(const char *, struct res_target *, res_state);
248static int res_searchN(const char *, struct res_target *, res_state);
249static int res_querydomainN(const char *, const char *,
250	struct res_target *, res_state);
251
252static const char * const ai_errlist[] = {
253	"Success",
254	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
255	"Temporary failure in name resolution",		/* EAI_AGAIN      */
256	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
257	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
258	"ai_family not supported",			/* EAI_FAMILY     */
259	"Memory allocation failure", 			/* EAI_MEMORY     */
260	"No address associated with hostname", 		/* EAI_NODATA     */
261	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
262	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
263	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
264	"System error returned in errno", 		/* EAI_SYSTEM     */
265	"Invalid value for hints",			/* EAI_BADHINTS	  */
266	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
267	"Argument buffer overflow",			/* EAI_OVERFLOW   */
268	"Unknown error", 				/* EAI_MAX        */
269};
270
271/* XXX macros that make external reference is BAD. */
272
273#define GET_AI(ai, afd, addr) 					\
274do { 								\
275	/* external reference: pai, error, and label free */ 	\
276	(ai) = get_ai(pai, (afd), (addr)); 			\
277	if ((ai) == NULL) { 					\
278		error = EAI_MEMORY; 				\
279		goto free; 					\
280	} 							\
281} while (/*CONSTCOND*/0)
282
283#define GET_PORT(ai, serv) 					\
284do { 								\
285	/* external reference: error and label free */ 		\
286	error = get_port((ai), (serv), 0); 			\
287	if (error != 0) 					\
288		goto free; 					\
289} while (/*CONSTCOND*/0)
290
291#define GET_CANONNAME(ai, str) 					\
292do { 								\
293	/* external reference: pai, error and label free */ 	\
294	error = get_canonname(pai, (ai), (str)); 		\
295	if (error != 0) 					\
296		goto free; 					\
297} while (/*CONSTCOND*/0)
298
299#define ERR(err) 						\
300do { 								\
301	/* external reference: error, and label bad */ 		\
302	error = (err); 						\
303	goto bad; 						\
304	/*NOTREACHED*/ 						\
305} while (/*CONSTCOND*/0)
306
307#define MATCH_FAMILY(x, y, w) 						\
308	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || 	\
309	    (y) == PF_UNSPEC)))
310#define MATCH(x, y, w) 							\
311	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
312
313const char *
314gai_strerror(int ecode)
315{
316	if (ecode < 0 || ecode > EAI_MAX)
317		ecode = EAI_MAX;
318	return ai_errlist[ecode];
319}
320
321void
322freeaddrinfo(struct addrinfo *ai)
323{
324	struct addrinfo *next;
325
326	assert(ai != NULL);
327
328	do {
329		next = ai->ai_next;
330		if (ai->ai_canonname)
331			free(ai->ai_canonname);
332		/* no need to free(ai->ai_addr) */
333		free(ai);
334		ai = next;
335	} while (ai);
336}
337
338static int
339str2number(const char *p)
340{
341	char *ep;
342	unsigned long v;
343
344	assert(p != NULL);
345
346	if (*p == '\0')
347		return -1;
348	ep = NULL;
349	errno = 0;
350	v = strtoul(p, &ep, 10);
351	if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX)
352		return v;
353	else
354		return -1;
355}
356
357/*
358 * Connect a UDP socket to a given unicast address. This will cause no network
359 * traffic, but will fail fast if the system has no or limited reachability to
360 * the destination (e.g., no IPv4 address, no IPv6 default route, ...).
361 */
362static int
363_test_connect(int pf, struct sockaddr *addr, size_t addrlen, unsigned mark) {
364	int s = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
365	if (s < 0)
366		return 0;
367	if (mark != MARK_UNSET && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
368		return 0;
369	int ret;
370	do {
371		ret = connect(s, addr, addrlen);
372	} while (ret < 0 && errno == EINTR);
373	int success = (ret == 0);
374	do {
375		ret = close(s);
376	} while (ret < 0 && errno == EINTR);
377	return success;
378}
379
380/*
381 * The following functions determine whether IPv4 or IPv6 connectivity is
382 * available in order to implement AI_ADDRCONFIG.
383 *
384 * Strictly speaking, AI_ADDRCONFIG should not look at whether connectivity is
385 * available, but whether addresses of the specified family are "configured
386 * on the local system". However, bionic doesn't currently support getifaddrs,
387 * so checking for connectivity is the next best thing.
388 */
389static int
390_have_ipv6(unsigned mark) {
391	static const struct sockaddr_in6 sin6_test = {
392		.sin6_family = AF_INET6,
393		.sin6_addr.s6_addr = {  // 2000::
394			0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
395		};
396	sockaddr_union addr = { .in6 = sin6_test };
397	return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6), mark);
398}
399
400static int
401_have_ipv4(unsigned mark) {
402	static const struct sockaddr_in sin_test = {
403		.sin_family = AF_INET,
404		.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
405	};
406	sockaddr_union addr = { .in = sin_test };
407	return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
408}
409
410// Returns 0 on success, else returns on error.
411static int
412android_getaddrinfo_proxy(
413    const char *hostname, const char *servname,
414    const struct addrinfo *hints, struct addrinfo **res, unsigned netid)
415{
416	int sock;
417	const int one = 1;
418	struct sockaddr_un proxy_addr;
419	FILE* proxy = NULL;
420	int success = 0;
421
422	// Clear this at start, as we use its non-NULLness later (in the
423	// error path) to decide if we have to free up any memory we
424	// allocated in the process (before failing).
425	*res = NULL;
426
427	// Bogus things we can't serialize.  Don't use the proxy.  These will fail - let them.
428	if ((hostname != NULL &&
429	     strcspn(hostname, " \n\r\t^'\"") != strlen(hostname)) ||
430	    (servname != NULL &&
431	     strcspn(servname, " \n\r\t^'\"") != strlen(servname))) {
432		return EAI_NODATA;
433	}
434
435	sock = socket(AF_UNIX, SOCK_STREAM, 0);
436	if (sock < 0) {
437		return EAI_NODATA;
438	}
439
440	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
441	memset(&proxy_addr, 0, sizeof(proxy_addr));
442	proxy_addr.sun_family = AF_UNIX;
443	strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
444		sizeof(proxy_addr.sun_path));
445	if (TEMP_FAILURE_RETRY(connect(sock,
446				       (const struct sockaddr*) &proxy_addr,
447				       sizeof(proxy_addr))) != 0) {
448		close(sock);
449		return EAI_NODATA;
450	}
451
452	// Send the request.
453	proxy = fdopen(sock, "r+");
454	if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d %u",
455		    hostname == NULL ? "^" : hostname,
456		    servname == NULL ? "^" : servname,
457		    hints == NULL ? -1 : hints->ai_flags,
458		    hints == NULL ? -1 : hints->ai_family,
459		    hints == NULL ? -1 : hints->ai_socktype,
460		    hints == NULL ? -1 : hints->ai_protocol,
461		    netid) < 0) {
462		goto exit;
463	}
464	// literal NULL byte at end, required by FrameworkListener
465	if (fputc(0, proxy) == EOF ||
466	    fflush(proxy) != 0) {
467		goto exit;
468	}
469
470	char buf[4];
471	// read result code for gethostbyaddr
472	if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) {
473		goto exit;
474	}
475
476	int result_code = (int)strtol(buf, NULL, 10);
477	// verify the code itself
478	if (result_code != DnsProxyQueryResult ) {
479		fread(buf, 1, sizeof(buf), proxy);
480		goto exit;
481	}
482
483	struct addrinfo* ai = NULL;
484	struct addrinfo** nextres = res;
485	while (1) {
486		uint32_t addrinfo_len;
487		if (fread(&addrinfo_len, sizeof(addrinfo_len),
488			  1, proxy) != 1) {
489			break;
490		}
491		addrinfo_len = ntohl(addrinfo_len);
492		if (addrinfo_len == 0) {
493			success = 1;
494			break;
495		}
496
497		if (addrinfo_len < sizeof(struct addrinfo)) {
498			break;
499		}
500		struct addrinfo* ai = calloc(1, addrinfo_len +
501					     sizeof(struct sockaddr_storage));
502		if (ai == NULL) {
503			break;
504		}
505
506		if (fread(ai, addrinfo_len, 1, proxy) != 1) {
507			// Error; fall through.
508			break;
509		}
510
511		// Zero out the pointer fields we copied which aren't
512		// valid in this address space.
513		ai->ai_addr = NULL;
514		ai->ai_canonname = NULL;
515		ai->ai_next = NULL;
516
517		// struct sockaddr
518		uint32_t addr_len;
519		if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
520			break;
521		}
522		addr_len = ntohl(addr_len);
523		if (addr_len != 0) {
524			if (addr_len > sizeof(struct sockaddr_storage)) {
525				// Bogus; too big.
526				break;
527			}
528			struct sockaddr* addr = (struct sockaddr*)(ai + 1);
529			if (fread(addr, addr_len, 1, proxy) != 1) {
530				break;
531			}
532			ai->ai_addr = addr;
533		}
534
535		// cannonname
536		uint32_t name_len;
537		if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
538			break;
539		}
540		name_len = ntohl(name_len);
541		if (name_len != 0) {
542			ai->ai_canonname = (char*) malloc(name_len);
543			if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
544				break;
545			}
546			if (ai->ai_canonname[name_len - 1] != '\0') {
547				// The proxy should be returning this
548				// NULL-terminated.
549				break;
550			}
551		}
552
553		*nextres = ai;
554		nextres = &ai->ai_next;
555		ai = NULL;
556	}
557
558	if (ai != NULL) {
559		// Clean up partially-built addrinfo that we never ended up
560		// attaching to the response.
561		freeaddrinfo(ai);
562	}
563exit:
564	if (proxy != NULL) {
565		fclose(proxy);
566	}
567
568	if (success) {
569		return 0;
570	}
571
572	// Proxy failed;
573	// clean up memory we might've allocated.
574	if (*res) {
575		freeaddrinfo(*res);
576		*res = NULL;
577	}
578	return EAI_NODATA;
579}
580
581int
582getaddrinfo(const char *hostname, const char *servname,
583    const struct addrinfo *hints, struct addrinfo **res)
584{
585	return android_getaddrinfofornet(hostname, servname, hints, NETID_UNSET, MARK_UNSET, res);
586}
587
588int
589android_getaddrinfofornet(const char *hostname, const char *servname,
590    const struct addrinfo *hints, unsigned netid, unsigned mark, struct addrinfo **res)
591{
592	struct addrinfo sentinel;
593	struct addrinfo *cur;
594	int error = 0;
595	struct addrinfo ai;
596	struct addrinfo ai0;
597	struct addrinfo *pai;
598	const struct explore *ex;
599	const char* cache_mode = getenv("ANDROID_DNS_MODE");
600
601	/* hostname is allowed to be NULL */
602	/* servname is allowed to be NULL */
603	/* hints is allowed to be NULL */
604	assert(res != NULL);
605	memset(&sentinel, 0, sizeof(sentinel));
606	cur = &sentinel;
607	pai = &ai;
608	pai->ai_flags = 0;
609	pai->ai_family = PF_UNSPEC;
610	pai->ai_socktype = ANY;
611	pai->ai_protocol = ANY;
612	pai->ai_addrlen = 0;
613	pai->ai_canonname = NULL;
614	pai->ai_addr = NULL;
615	pai->ai_next = NULL;
616
617	if (hostname == NULL && servname == NULL)
618		return EAI_NONAME;
619	if (hints) {
620		/* error check for hints */
621		if (hints->ai_addrlen || hints->ai_canonname ||
622		    hints->ai_addr || hints->ai_next)
623			ERR(EAI_BADHINTS); /* xxx */
624		if (hints->ai_flags & ~AI_MASK)
625			ERR(EAI_BADFLAGS);
626		switch (hints->ai_family) {
627		case PF_UNSPEC:
628		case PF_INET:
629#ifdef INET6
630		case PF_INET6:
631#endif
632			break;
633		default:
634			ERR(EAI_FAMILY);
635		}
636		memcpy(pai, hints, sizeof(*pai));
637
638		/*
639		 * if both socktype/protocol are specified, check if they
640		 * are meaningful combination.
641		 */
642		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
643			for (ex = explore; ex->e_af >= 0; ex++) {
644				if (pai->ai_family != ex->e_af)
645					continue;
646				if (ex->e_socktype == ANY)
647					continue;
648				if (ex->e_protocol == ANY)
649					continue;
650				if (pai->ai_socktype == ex->e_socktype
651				 && pai->ai_protocol != ex->e_protocol) {
652					ERR(EAI_BADHINTS);
653				}
654			}
655		}
656	}
657
658	/*
659	 * check for special cases.  (1) numeric servname is disallowed if
660	 * socktype/protocol are left unspecified. (2) servname is disallowed
661	 * for raw and other inet{,6} sockets.
662	 */
663	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
664#ifdef PF_INET6
665	 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
666#endif
667	    ) {
668		ai0 = *pai;	/* backup *pai */
669
670		if (pai->ai_family == PF_UNSPEC) {
671#ifdef PF_INET6
672			pai->ai_family = PF_INET6;
673#else
674			pai->ai_family = PF_INET;
675#endif
676		}
677		error = get_portmatch(pai, servname);
678		if (error)
679			ERR(error);
680
681		*pai = ai0;
682	}
683
684	ai0 = *pai;
685
686	/* NULL hostname, or numeric hostname */
687	for (ex = explore; ex->e_af >= 0; ex++) {
688		*pai = ai0;
689
690		/* PF_UNSPEC entries are prepared for DNS queries only */
691		if (ex->e_af == PF_UNSPEC)
692			continue;
693
694		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
695			continue;
696		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
697			continue;
698		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
699			continue;
700
701		if (pai->ai_family == PF_UNSPEC)
702			pai->ai_family = ex->e_af;
703		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
704			pai->ai_socktype = ex->e_socktype;
705		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
706			pai->ai_protocol = ex->e_protocol;
707
708		if (hostname == NULL)
709			error = explore_null(pai, servname, &cur->ai_next);
710		else
711			error = explore_numeric_scope(pai, hostname, servname,
712			    &cur->ai_next);
713
714		if (error)
715			goto free;
716
717		while (cur->ai_next)
718			cur = cur->ai_next;
719	}
720
721	/*
722	 * XXX
723	 * If numeric representation of AF1 can be interpreted as FQDN
724	 * representation of AF2, we need to think again about the code below.
725	 */
726	if (sentinel.ai_next)
727		goto good;
728
729	if (hostname == NULL)
730		ERR(EAI_NODATA);
731	if (pai->ai_flags & AI_NUMERICHOST)
732		ERR(EAI_NONAME);
733
734        /*
735         * BEGIN ANDROID CHANGES; proxying to the cache
736         */
737	if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
738		// we're not the proxy - pass the request to them
739		return android_getaddrinfo_proxy(hostname, servname, hints, res, netid);
740	}
741
742	/*
743	 * hostname as alphabetical name.
744	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
745	 * outer loop by AFs.
746	 */
747	for (ex = explore; ex->e_af >= 0; ex++) {
748		*pai = ai0;
749
750		/* require exact match for family field */
751		if (pai->ai_family != ex->e_af)
752			continue;
753
754		if (!MATCH(pai->ai_socktype, ex->e_socktype,
755				WILD_SOCKTYPE(ex))) {
756			continue;
757		}
758		if (!MATCH(pai->ai_protocol, ex->e_protocol,
759				WILD_PROTOCOL(ex))) {
760			continue;
761		}
762
763		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
764			pai->ai_socktype = ex->e_socktype;
765		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
766			pai->ai_protocol = ex->e_protocol;
767
768		error = explore_fqdn(pai, hostname, servname,
769			&cur->ai_next, netid, mark);
770
771		while (cur && cur->ai_next)
772			cur = cur->ai_next;
773	}
774
775	/* XXX */
776	if (sentinel.ai_next)
777		error = 0;
778
779	if (error)
780		goto free;
781	if (error == 0) {
782		if (sentinel.ai_next) {
783 good:
784			*res = sentinel.ai_next;
785			return SUCCESS;
786		} else
787			error = EAI_FAIL;
788	}
789 free:
790 bad:
791	if (sentinel.ai_next)
792		freeaddrinfo(sentinel.ai_next);
793	*res = NULL;
794	return error;
795}
796
797/*
798 * FQDN hostname, DNS lookup
799 */
800static int
801explore_fqdn(const struct addrinfo *pai, const char *hostname,
802    const char *servname, struct addrinfo **res, unsigned netid, unsigned mark)
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, netid, mark)) {
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, 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
1299static struct addrinfo *
1300getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
1301    const struct addrinfo *pai)
1302{
1303	struct addrinfo sentinel, *cur;
1304	struct addrinfo ai;
1305	const struct afd *afd;
1306	char *canonname;
1307	const HEADER *hp;
1308	const u_char *cp;
1309	int n;
1310	const u_char *eom;
1311	char *bp, *ep;
1312	int type, class, ancount, qdcount;
1313	int haveanswer, had_error;
1314	char tbuf[MAXDNAME];
1315	int (*name_ok) (const char *);
1316	char hostbuf[8*1024];
1317
1318	assert(answer != NULL);
1319	assert(qname != NULL);
1320	assert(pai != NULL);
1321
1322	memset(&sentinel, 0, sizeof(sentinel));
1323	cur = &sentinel;
1324
1325	canonname = NULL;
1326	eom = answer->buf + anslen;
1327	switch (qtype) {
1328	case T_A:
1329	case T_AAAA:
1330	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
1331		name_ok = res_hnok;
1332		break;
1333	default:
1334		return NULL;	/* XXX should be abort(); */
1335	}
1336	/*
1337	 * find first satisfactory answer
1338	 */
1339	hp = &answer->hdr;
1340	ancount = ntohs(hp->ancount);
1341	qdcount = ntohs(hp->qdcount);
1342	bp = hostbuf;
1343	ep = hostbuf + sizeof hostbuf;
1344	cp = answer->buf + HFIXEDSZ;
1345	if (qdcount != 1) {
1346		h_errno = NO_RECOVERY;
1347		return (NULL);
1348	}
1349	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1350	if ((n < 0) || !(*name_ok)(bp)) {
1351		h_errno = NO_RECOVERY;
1352		return (NULL);
1353	}
1354	cp += n + QFIXEDSZ;
1355	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1356		/* res_send() has already verified that the query name is the
1357		 * same as the one we sent; this just gets the expanded name
1358		 * (i.e., with the succeeding search-domain tacked on).
1359		 */
1360		n = strlen(bp) + 1;		/* for the \0 */
1361		if (n >= MAXHOSTNAMELEN) {
1362			h_errno = NO_RECOVERY;
1363			return (NULL);
1364		}
1365		canonname = bp;
1366		bp += n;
1367		/* The qname can be abbreviated, but h_name is now absolute. */
1368		qname = canonname;
1369	}
1370	haveanswer = 0;
1371	had_error = 0;
1372	while (ancount-- > 0 && cp < eom && !had_error) {
1373		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1374		if ((n < 0) || !(*name_ok)(bp)) {
1375			had_error++;
1376			continue;
1377		}
1378		cp += n;			/* name */
1379		type = _getshort(cp);
1380 		cp += INT16SZ;			/* type */
1381		class = _getshort(cp);
1382 		cp += INT16SZ + INT32SZ;	/* class, TTL */
1383		n = _getshort(cp);
1384		cp += INT16SZ;			/* len */
1385		if (class != C_IN) {
1386			/* XXX - debug? syslog? */
1387			cp += n;
1388			continue;		/* XXX - had_error++ ? */
1389		}
1390		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1391		    type == T_CNAME) {
1392			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1393			if ((n < 0) || !(*name_ok)(tbuf)) {
1394				had_error++;
1395				continue;
1396			}
1397			cp += n;
1398			/* Get canonical name. */
1399			n = strlen(tbuf) + 1;	/* for the \0 */
1400			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1401				had_error++;
1402				continue;
1403			}
1404			strlcpy(bp, tbuf, (size_t)(ep - bp));
1405			canonname = bp;
1406			bp += n;
1407			continue;
1408		}
1409		if (qtype == T_ANY) {
1410			if (!(type == T_A || type == T_AAAA)) {
1411				cp += n;
1412				continue;
1413			}
1414		} else if (type != qtype) {
1415			if (type != T_KEY && type != T_SIG)
1416				syslog(LOG_NOTICE|LOG_AUTH,
1417	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1418				       qname, p_class(C_IN), p_type(qtype),
1419				       p_type(type));
1420			cp += n;
1421			continue;		/* XXX - had_error++ ? */
1422		}
1423		switch (type) {
1424		case T_A:
1425		case T_AAAA:
1426			if (strcasecmp(canonname, bp) != 0) {
1427				syslog(LOG_NOTICE|LOG_AUTH,
1428				       AskedForGot, canonname, bp);
1429				cp += n;
1430				continue;	/* XXX - had_error++ ? */
1431			}
1432			if (type == T_A && n != INADDRSZ) {
1433				cp += n;
1434				continue;
1435			}
1436			if (type == T_AAAA && n != IN6ADDRSZ) {
1437				cp += n;
1438				continue;
1439			}
1440			if (type == T_AAAA) {
1441				struct in6_addr in6;
1442				memcpy(&in6, cp, IN6ADDRSZ);
1443				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1444					cp += n;
1445					continue;
1446				}
1447			}
1448			if (!haveanswer) {
1449				int nn;
1450
1451				canonname = bp;
1452				nn = strlen(bp) + 1;	/* for the \0 */
1453				bp += nn;
1454			}
1455
1456			/* don't overwrite pai */
1457			ai = *pai;
1458			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1459			afd = find_afd(ai.ai_family);
1460			if (afd == NULL) {
1461				cp += n;
1462				continue;
1463			}
1464			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1465			if (cur->ai_next == NULL)
1466				had_error++;
1467			while (cur && cur->ai_next)
1468				cur = cur->ai_next;
1469			cp += n;
1470			break;
1471		default:
1472			abort();
1473		}
1474		if (!had_error)
1475			haveanswer++;
1476	}
1477	if (haveanswer) {
1478		if (!canonname)
1479			(void)get_canonname(pai, sentinel.ai_next, qname);
1480		else
1481			(void)get_canonname(pai, sentinel.ai_next, canonname);
1482		h_errno = NETDB_SUCCESS;
1483		return sentinel.ai_next;
1484	}
1485
1486	h_errno = NO_RECOVERY;
1487	return NULL;
1488}
1489
1490struct addrinfo_sort_elem {
1491	struct addrinfo *ai;
1492	int has_src_addr;
1493	sockaddr_union src_addr;
1494	int original_order;
1495};
1496
1497/*ARGSUSED*/
1498static int
1499_get_scope(const struct sockaddr *addr)
1500{
1501	if (addr->sa_family == AF_INET6) {
1502		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
1503		if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) {
1504			return IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr);
1505		} else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) ||
1506			   IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) {
1507			/*
1508			 * RFC 4291 section 2.5.3 says loopback is to be treated as having
1509			 * link-local scope.
1510			 */
1511			return IPV6_ADDR_SCOPE_LINKLOCAL;
1512		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
1513			return IPV6_ADDR_SCOPE_SITELOCAL;
1514		} else {
1515			return IPV6_ADDR_SCOPE_GLOBAL;
1516		}
1517	} else if (addr->sa_family == AF_INET) {
1518		const struct sockaddr_in *addr4 = (const struct sockaddr_in *)addr;
1519		unsigned long int na = ntohl(addr4->sin_addr.s_addr);
1520
1521		if (IN_LOOPBACK(na) ||                          /* 127.0.0.0/8 */
1522		    (na & 0xffff0000) == 0xa9fe0000) {          /* 169.254.0.0/16 */
1523			return IPV6_ADDR_SCOPE_LINKLOCAL;
1524		} else {
1525			/*
1526			 * RFC 6724 section 3.2. Other IPv4 addresses, including private addresses
1527			 * and shared addresses (100.64.0.0/10), are assigned global scope.
1528			 */
1529			return IPV6_ADDR_SCOPE_GLOBAL;
1530		}
1531	} else {
1532		/*
1533		 * This should never happen.
1534		 * Return a scope with low priority as a last resort.
1535		 */
1536		return IPV6_ADDR_SCOPE_NODELOCAL;
1537	}
1538}
1539
1540/* These macros are modelled after the ones in <netinet/in6.h>. */
1541
1542/* RFC 4380, section 2.6 */
1543#define IN6_IS_ADDR_TEREDO(a)	 \
1544	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000)))
1545
1546/* RFC 3056, section 2. */
1547#define IN6_IS_ADDR_6TO4(a)	 \
1548	(((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
1549
1550/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
1551#define IN6_IS_ADDR_6BONE(a)      \
1552	(((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
1553
1554/*
1555 * Get the label for a given IPv4/IPv6 address.
1556 * RFC 6724, section 2.1.
1557 */
1558
1559/*ARGSUSED*/
1560static int
1561_get_label(const struct sockaddr *addr)
1562{
1563	if (addr->sa_family == AF_INET) {
1564		return 4;
1565	} else if (addr->sa_family == AF_INET6) {
1566		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
1567		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
1568			return 0;
1569		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
1570			return 4;
1571		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
1572			return 2;
1573		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
1574			return 5;
1575		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
1576			return 13;
1577		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
1578			return 3;
1579		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
1580			return 11;
1581		} else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
1582			return 12;
1583		} else {
1584			/* All other IPv6 addresses, including global unicast addresses. */
1585			return 1;
1586		}
1587	} else {
1588		/*
1589		 * This should never happen.
1590		 * Return a semi-random label as a last resort.
1591		 */
1592		return 1;
1593	}
1594}
1595
1596/*
1597 * Get the precedence for a given IPv4/IPv6 address.
1598 * RFC 6724, section 2.1.
1599 */
1600
1601/*ARGSUSED*/
1602static int
1603_get_precedence(const struct sockaddr *addr)
1604{
1605	if (addr->sa_family == AF_INET) {
1606		return 35;
1607	} else if (addr->sa_family == AF_INET6) {
1608		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
1609		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
1610			return 50;
1611		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
1612			return 35;
1613		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
1614			return 30;
1615		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
1616			return 5;
1617		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
1618			return 3;
1619		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
1620		           IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
1621		           IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
1622			return 1;
1623		} else {
1624			/* All other IPv6 addresses, including global unicast addresses. */
1625			return 40;
1626		}
1627	} else {
1628		return 1;
1629	}
1630}
1631
1632/*
1633 * Find number of matching initial bits between the two addresses a1 and a2.
1634 */
1635
1636/*ARGSUSED*/
1637static int
1638_common_prefix_len(const struct in6_addr *a1, const struct in6_addr *a2)
1639{
1640	const char *p1 = (const char *)a1;
1641	const char *p2 = (const char *)a2;
1642	unsigned i;
1643
1644	for (i = 0; i < sizeof(*a1); ++i) {
1645		int x, j;
1646
1647		if (p1[i] == p2[i]) {
1648			continue;
1649		}
1650		x = p1[i] ^ p2[i];
1651		for (j = 0; j < CHAR_BIT; ++j) {
1652			if (x & (1 << (CHAR_BIT - 1))) {
1653				return i * CHAR_BIT + j;
1654			}
1655			x <<= 1;
1656		}
1657	}
1658	return sizeof(*a1) * CHAR_BIT;
1659}
1660
1661/*
1662 * Compare two source/destination address pairs.
1663 * RFC 6724, section 6.
1664 */
1665
1666/*ARGSUSED*/
1667static int
1668_rfc6724_compare(const void *ptr1, const void* ptr2)
1669{
1670	const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
1671	const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
1672	int scope_src1, scope_dst1, scope_match1;
1673	int scope_src2, scope_dst2, scope_match2;
1674	int label_src1, label_dst1, label_match1;
1675	int label_src2, label_dst2, label_match2;
1676	int precedence1, precedence2;
1677	int prefixlen1, prefixlen2;
1678
1679	/* Rule 1: Avoid unusable destinations. */
1680	if (a1->has_src_addr != a2->has_src_addr) {
1681		return a2->has_src_addr - a1->has_src_addr;
1682	}
1683
1684	/* Rule 2: Prefer matching scope. */
1685	scope_src1 = _get_scope(&a1->src_addr.generic);
1686	scope_dst1 = _get_scope(a1->ai->ai_addr);
1687	scope_match1 = (scope_src1 == scope_dst1);
1688
1689	scope_src2 = _get_scope(&a2->src_addr.generic);
1690	scope_dst2 = _get_scope(a2->ai->ai_addr);
1691	scope_match2 = (scope_src2 == scope_dst2);
1692
1693	if (scope_match1 != scope_match2) {
1694		return scope_match2 - scope_match1;
1695	}
1696
1697	/*
1698	 * Rule 3: Avoid deprecated addresses.
1699	 * TODO(sesse): We don't currently have a good way of finding this.
1700	 */
1701
1702	/*
1703	 * Rule 4: Prefer home addresses.
1704	 * TODO(sesse): We don't currently have a good way of finding this.
1705	 */
1706
1707	/* Rule 5: Prefer matching label. */
1708	label_src1 = _get_label(&a1->src_addr.generic);
1709	label_dst1 = _get_label(a1->ai->ai_addr);
1710	label_match1 = (label_src1 == label_dst1);
1711
1712	label_src2 = _get_label(&a2->src_addr.generic);
1713	label_dst2 = _get_label(a2->ai->ai_addr);
1714	label_match2 = (label_src2 == label_dst2);
1715
1716	if (label_match1 != label_match2) {
1717		return label_match2 - label_match1;
1718	}
1719
1720	/* Rule 6: Prefer higher precedence. */
1721	precedence1 = _get_precedence(a1->ai->ai_addr);
1722	precedence2 = _get_precedence(a2->ai->ai_addr);
1723	if (precedence1 != precedence2) {
1724		return precedence2 - precedence1;
1725	}
1726
1727	/*
1728	 * Rule 7: Prefer native transport.
1729	 * TODO(sesse): We don't currently have a good way of finding this.
1730	 */
1731
1732	/* Rule 8: Prefer smaller scope. */
1733	if (scope_dst1 != scope_dst2) {
1734		return scope_dst1 - scope_dst2;
1735	}
1736
1737	/*
1738	 * Rule 9: Use longest matching prefix.
1739         * We implement this for IPv6 only, as the rules in RFC 6724 don't seem
1740         * to work very well directly applied to IPv4. (glibc uses information from
1741         * the routing table for a custom IPv4 implementation here.)
1742	 */
1743	if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 &&
1744	    a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) {
1745		const struct sockaddr_in6 *a1_src = &a1->src_addr.in6;
1746		const struct sockaddr_in6 *a1_dst = (const struct sockaddr_in6 *)a1->ai->ai_addr;
1747		const struct sockaddr_in6 *a2_src = &a2->src_addr.in6;
1748		const struct sockaddr_in6 *a2_dst = (const struct sockaddr_in6 *)a2->ai->ai_addr;
1749		prefixlen1 = _common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr);
1750		prefixlen2 = _common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr);
1751		if (prefixlen1 != prefixlen2) {
1752			return prefixlen2 - prefixlen1;
1753		}
1754	}
1755
1756	/*
1757	 * Rule 10: Leave the order unchanged.
1758	 * We need this since qsort() is not necessarily stable.
1759	 */
1760	return a1->original_order - a2->original_order;
1761}
1762
1763/*
1764 * Find the source address that will be used if trying to connect to the given
1765 * address. src_addr must be large enough to hold a struct sockaddr_in6.
1766 *
1767 * Returns 1 if a source address was found, 0 if the address is unreachable,
1768 * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are
1769 * undefined.
1770 */
1771
1772/*ARGSUSED*/
1773static int
1774_find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr, unsigned mark)
1775{
1776	int sock;
1777	int ret;
1778	socklen_t len;
1779
1780	switch (addr->sa_family) {
1781	case AF_INET:
1782		len = sizeof(struct sockaddr_in);
1783		break;
1784	case AF_INET6:
1785		len = sizeof(struct sockaddr_in6);
1786		break;
1787	default:
1788		/* No known usable source address for non-INET families. */
1789		return 0;
1790	}
1791
1792	sock = socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
1793	if (sock == -1) {
1794		if (errno == EAFNOSUPPORT) {
1795			return 0;
1796		} else {
1797			return -1;
1798		}
1799	}
1800	if (mark != MARK_UNSET && setsockopt(sock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0)
1801		return 0;
1802	do {
1803		ret = connect(sock, addr, len);
1804	} while (ret == -1 && errno == EINTR);
1805
1806	if (ret == -1) {
1807		close(sock);
1808		return 0;
1809	}
1810
1811	if (getsockname(sock, src_addr, &len) == -1) {
1812		close(sock);
1813		return -1;
1814	}
1815	close(sock);
1816	return 1;
1817}
1818
1819/*
1820 * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
1821 * Will leave the list unchanged if an error occurs.
1822 */
1823
1824/*ARGSUSED*/
1825static void
1826_rfc6724_sort(struct addrinfo *list_sentinel, unsigned mark)
1827{
1828	struct addrinfo *cur;
1829	int nelem = 0, i;
1830	struct addrinfo_sort_elem *elems;
1831
1832	cur = list_sentinel->ai_next;
1833	while (cur) {
1834		++nelem;
1835		cur = cur->ai_next;
1836	}
1837
1838	elems = (struct addrinfo_sort_elem *)malloc(nelem * sizeof(struct addrinfo_sort_elem));
1839	if (elems == NULL) {
1840		goto error;
1841	}
1842
1843	/*
1844	 * Convert the linked list to an array that also contains the candidate
1845	 * source address for each destination address.
1846	 */
1847	for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next) {
1848		int has_src_addr;
1849		assert(cur != NULL);
1850		elems[i].ai = cur;
1851		elems[i].original_order = i;
1852
1853		has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.generic, mark);
1854		if (has_src_addr == -1) {
1855			goto error;
1856		}
1857		elems[i].has_src_addr = has_src_addr;
1858	}
1859
1860	/* Sort the addresses, and rearrange the linked list so it matches the sorted order. */
1861	qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc6724_compare);
1862
1863	list_sentinel->ai_next = elems[0].ai;
1864	for (i = 0; i < nelem - 1; ++i) {
1865		elems[i].ai->ai_next = elems[i + 1].ai;
1866	}
1867	elems[nelem - 1].ai->ai_next = NULL;
1868
1869error:
1870	free(elems);
1871}
1872
1873/*ARGSUSED*/
1874static int
1875_dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
1876{
1877	struct addrinfo *ai;
1878	querybuf *buf, *buf2;
1879	const char *name;
1880	const struct addrinfo *pai;
1881	struct addrinfo sentinel, *cur;
1882	struct res_target q, q2;
1883	res_state res;
1884	unsigned netid, mark;
1885
1886	name = va_arg(ap, char *);
1887	pai = va_arg(ap, const struct addrinfo *);
1888	netid = va_arg(ap, unsigned);
1889	mark = va_arg(ap, unsigned);
1890	//fprintf(stderr, "_dns_getaddrinfo() name = '%s'\n", name);
1891
1892	memset(&q, 0, sizeof(q));
1893	memset(&q2, 0, sizeof(q2));
1894	memset(&sentinel, 0, sizeof(sentinel));
1895	cur = &sentinel;
1896
1897	buf = malloc(sizeof(*buf));
1898	if (buf == NULL) {
1899		h_errno = NETDB_INTERNAL;
1900		return NS_NOTFOUND;
1901	}
1902	buf2 = malloc(sizeof(*buf2));
1903	if (buf2 == NULL) {
1904		free(buf);
1905		h_errno = NETDB_INTERNAL;
1906		return NS_NOTFOUND;
1907	}
1908
1909	switch (pai->ai_family) {
1910	case AF_UNSPEC:
1911		/* prefer IPv6 */
1912		q.name = name;
1913		q.qclass = C_IN;
1914		q.answer = buf->buf;
1915		q.anslen = sizeof(buf->buf);
1916		int query_ipv6 = 1, query_ipv4 = 1;
1917		if (pai->ai_flags & AI_ADDRCONFIG) {
1918			query_ipv6 = _have_ipv6(mark);
1919			query_ipv4 = _have_ipv4(mark);
1920		}
1921		if (query_ipv6) {
1922			q.qtype = T_AAAA;
1923			if (query_ipv4) {
1924				q.next = &q2;
1925				q2.name = name;
1926				q2.qclass = C_IN;
1927				q2.qtype = T_A;
1928				q2.answer = buf2->buf;
1929				q2.anslen = sizeof(buf2->buf);
1930			}
1931		} else if (query_ipv4) {
1932			q.qtype = T_A;
1933		} else {
1934			free(buf);
1935			free(buf2);
1936			return NS_NOTFOUND;
1937		}
1938		break;
1939	case AF_INET:
1940		q.name = name;
1941		q.qclass = C_IN;
1942		q.qtype = T_A;
1943		q.answer = buf->buf;
1944		q.anslen = sizeof(buf->buf);
1945		break;
1946	case AF_INET6:
1947		q.name = name;
1948		q.qclass = C_IN;
1949		q.qtype = T_AAAA;
1950		q.answer = buf->buf;
1951		q.anslen = sizeof(buf->buf);
1952		break;
1953	default:
1954		free(buf);
1955		free(buf2);
1956		return NS_UNAVAIL;
1957	}
1958
1959	res = __res_get_state();
1960	if (res == NULL) {
1961		free(buf);
1962		free(buf2);
1963		return NS_NOTFOUND;
1964	}
1965
1966	/* this just sets our netid val in the thread private data so we don't have to
1967	 * modify the api's all the way down to res_send.c's res_nsend.  We could
1968	 * fully populate the thread private data here, but if we get down there
1969	 * and have a cache hit that would be wasted, so we do the rest there on miss
1970	 */
1971	res_setnetid(res, netid);
1972	res_setmark(res, mark);
1973	if (res_searchN(name, &q, res) < 0) {
1974		__res_put_state(res);
1975		free(buf);
1976		free(buf2);
1977		return NS_NOTFOUND;
1978	}
1979	ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1980	if (ai) {
1981		cur->ai_next = ai;
1982		while (cur && cur->ai_next)
1983			cur = cur->ai_next;
1984	}
1985	if (q.next) {
1986		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1987		if (ai)
1988			cur->ai_next = ai;
1989	}
1990	free(buf);
1991	free(buf2);
1992	if (sentinel.ai_next == NULL) {
1993		__res_put_state(res);
1994		switch (h_errno) {
1995		case HOST_NOT_FOUND:
1996			return NS_NOTFOUND;
1997		case TRY_AGAIN:
1998			return NS_TRYAGAIN;
1999		default:
2000			return NS_UNAVAIL;
2001		}
2002	}
2003
2004	_rfc6724_sort(&sentinel, netid);
2005
2006	__res_put_state(res);
2007
2008	*((struct addrinfo **)rv) = sentinel.ai_next;
2009	return NS_SUCCESS;
2010}
2011
2012static void
2013_sethtent(FILE **hostf)
2014{
2015
2016	if (!*hostf)
2017		*hostf = fopen(_PATH_HOSTS, "r" );
2018	else
2019		rewind(*hostf);
2020}
2021
2022static void
2023_endhtent(FILE **hostf)
2024{
2025
2026	if (*hostf) {
2027		(void) fclose(*hostf);
2028		*hostf = NULL;
2029	}
2030}
2031
2032static struct addrinfo *
2033_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
2034{
2035	char *p;
2036	char *cp, *tname, *cname;
2037	struct addrinfo hints, *res0, *res;
2038	int error;
2039	const char *addr;
2040	char hostbuf[8*1024];
2041
2042//	fprintf(stderr, "_gethtent() name = '%s'\n", name);
2043	assert(name != NULL);
2044	assert(pai != NULL);
2045
2046	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r" )))
2047		return (NULL);
2048 again:
2049	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
2050		return (NULL);
2051	if (*p == '#')
2052		goto again;
2053	if (!(cp = strpbrk(p, "#\n")))
2054		goto again;
2055	*cp = '\0';
2056	if (!(cp = strpbrk(p, " \t")))
2057		goto again;
2058	*cp++ = '\0';
2059	addr = p;
2060	/* if this is not something we're looking for, skip it. */
2061	cname = NULL;
2062	while (cp && *cp) {
2063		if (*cp == ' ' || *cp == '\t') {
2064			cp++;
2065			continue;
2066		}
2067		if (!cname)
2068			cname = cp;
2069		tname = cp;
2070		if ((cp = strpbrk(cp, " \t")) != NULL)
2071			*cp++ = '\0';
2072//		fprintf(stderr, "\ttname = '%s'", tname);
2073		if (strcasecmp(name, tname) == 0)
2074			goto found;
2075	}
2076	goto again;
2077
2078found:
2079	hints = *pai;
2080	hints.ai_flags = AI_NUMERICHOST;
2081	error = getaddrinfo(addr, NULL, &hints, &res0);
2082	if (error)
2083		goto again;
2084	for (res = res0; res; res = res->ai_next) {
2085		/* cover it up */
2086		res->ai_flags = pai->ai_flags;
2087
2088		if (pai->ai_flags & AI_CANONNAME) {
2089			if (get_canonname(pai, res, cname) != 0) {
2090				freeaddrinfo(res0);
2091				goto again;
2092			}
2093		}
2094	}
2095	return res0;
2096}
2097
2098/*ARGSUSED*/
2099static int
2100_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
2101{
2102	const char *name;
2103	const struct addrinfo *pai;
2104	struct addrinfo sentinel, *cur;
2105	struct addrinfo *p;
2106	FILE *hostf = NULL;
2107
2108	name = va_arg(ap, char *);
2109	pai = va_arg(ap, struct addrinfo *);
2110
2111//	fprintf(stderr, "_files_getaddrinfo() name = '%s'\n", name);
2112	memset(&sentinel, 0, sizeof(sentinel));
2113	cur = &sentinel;
2114
2115	_sethtent(&hostf);
2116	while ((p = _gethtent(&hostf, name, pai)) != NULL) {
2117		cur->ai_next = p;
2118		while (cur && cur->ai_next)
2119			cur = cur->ai_next;
2120	}
2121	_endhtent(&hostf);
2122
2123	*((struct addrinfo **)rv) = sentinel.ai_next;
2124	if (sentinel.ai_next == NULL)
2125		return NS_NOTFOUND;
2126	return NS_SUCCESS;
2127}
2128
2129/* resolver logic */
2130
2131/*
2132 * Formulate a normal query, send, and await answer.
2133 * Returned answer is placed in supplied buffer "answer".
2134 * Perform preliminary check of answer, returning success only
2135 * if no error is indicated and the answer count is nonzero.
2136 * Return the size of the response on success, -1 on error.
2137 * Error number is left in h_errno.
2138 *
2139 * Caller must parse answer and determine whether it answers the question.
2140 */
2141static int
2142res_queryN(const char *name, /* domain name */ struct res_target *target,
2143    res_state res)
2144{
2145	u_char buf[MAXPACKET];
2146	HEADER *hp;
2147	int n;
2148	struct res_target *t;
2149	int rcode;
2150	int ancount;
2151
2152	assert(name != NULL);
2153	/* XXX: target may be NULL??? */
2154
2155	rcode = NOERROR;
2156	ancount = 0;
2157
2158	for (t = target; t; t = t->next) {
2159		int class, type;
2160		u_char *answer;
2161		int anslen;
2162
2163		hp = (HEADER *)(void *)t->answer;
2164		hp->rcode = NOERROR;	/* default */
2165
2166		/* make it easier... */
2167		class = t->qclass;
2168		type = t->qtype;
2169		answer = t->answer;
2170		anslen = t->anslen;
2171#ifdef DEBUG
2172		if (res->options & RES_DEBUG)
2173			printf(";; res_nquery(%s, %d, %d)\n", name, class, type);
2174#endif
2175
2176		n = res_nmkquery(res, QUERY, name, class, type, NULL, 0, NULL,
2177		    buf, sizeof(buf));
2178#ifdef RES_USE_EDNS0
2179		if (n > 0 && (res->options & RES_USE_EDNS0) != 0)
2180			n = res_nopt(res, n, buf, sizeof(buf), anslen);
2181#endif
2182		if (n <= 0) {
2183#ifdef DEBUG
2184			if (res->options & RES_DEBUG)
2185				printf(";; res_nquery: mkquery failed\n");
2186#endif
2187			h_errno = NO_RECOVERY;
2188			return n;
2189		}
2190		n = res_nsend(res, buf, n, answer, anslen);
2191#if 0
2192		if (n < 0) {
2193#ifdef DEBUG
2194			if (res->options & RES_DEBUG)
2195				printf(";; res_query: send error\n");
2196#endif
2197			h_errno = TRY_AGAIN;
2198			return n;
2199		}
2200#endif
2201
2202		if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
2203			rcode = hp->rcode;	/* record most recent error */
2204#ifdef DEBUG
2205			if (res->options & RES_DEBUG)
2206				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
2207				    ntohs(hp->ancount));
2208#endif
2209			continue;
2210		}
2211
2212		ancount += ntohs(hp->ancount);
2213
2214		t->n = n;
2215	}
2216
2217	if (ancount == 0) {
2218		switch (rcode) {
2219		case NXDOMAIN:
2220			h_errno = HOST_NOT_FOUND;
2221			break;
2222		case SERVFAIL:
2223			h_errno = TRY_AGAIN;
2224			break;
2225		case NOERROR:
2226			h_errno = NO_DATA;
2227			break;
2228		case FORMERR:
2229		case NOTIMP:
2230		case REFUSED:
2231		default:
2232			h_errno = NO_RECOVERY;
2233			break;
2234		}
2235		return -1;
2236	}
2237	return ancount;
2238}
2239
2240/*
2241 * Formulate a normal query, send, and retrieve answer in supplied buffer.
2242 * Return the size of the response on success, -1 on error.
2243 * If enabled, implement search rules until answer or unrecoverable failure
2244 * is detected.  Error code, if any, is left in h_errno.
2245 */
2246static int
2247res_searchN(const char *name, struct res_target *target, res_state res)
2248{
2249	const char *cp, * const *domain;
2250	HEADER *hp;
2251	u_int dots;
2252	int trailing_dot, ret, saved_herrno;
2253	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
2254
2255	assert(name != NULL);
2256	assert(target != NULL);
2257
2258	hp = (HEADER *)(void *)target->answer;	/*XXX*/
2259
2260	errno = 0;
2261	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
2262	dots = 0;
2263	for (cp = name; *cp; cp++)
2264		dots += (*cp == '.');
2265	trailing_dot = 0;
2266	if (cp > name && *--cp == '.')
2267		trailing_dot++;
2268
2269
2270        //fprintf(stderr, "res_searchN() name = '%s'\n", name);
2271
2272	/*
2273	 * if there aren't any dots, it could be a user-level alias
2274	 */
2275	if (!dots && (cp = __hostalias(name)) != NULL) {
2276		ret = res_queryN(cp, target, res);
2277		return ret;
2278	}
2279
2280	/*
2281	 * If there are dots in the name already, let's just give it a try
2282	 * 'as is'.  The threshold can be set with the "ndots" option.
2283	 */
2284	saved_herrno = -1;
2285	if (dots >= res->ndots) {
2286		ret = res_querydomainN(name, NULL, target, res);
2287		if (ret > 0)
2288			return (ret);
2289		saved_herrno = h_errno;
2290		tried_as_is++;
2291	}
2292
2293	/*
2294	 * We do at least one level of search if
2295	 *	- there is no dot and RES_DEFNAME is set, or
2296	 *	- there is at least one dot, there is no trailing dot,
2297	 *	  and RES_DNSRCH is set.
2298	 */
2299	if ((!dots && (res->options & RES_DEFNAMES)) ||
2300	    (dots && !trailing_dot && (res->options & RES_DNSRCH))) {
2301		int done = 0;
2302
2303		/* Unfortunately we need to set stuff up before
2304		 * the domain stuff is tried.  Will have a better
2305		 * fix after thread pools are used.
2306		 */
2307		_resolv_populate_res_for_net(res);
2308
2309		for (domain = (const char * const *)res->dnsrch;
2310		   *domain && !done;
2311		   domain++) {
2312
2313			ret = res_querydomainN(name, *domain, target, res);
2314			if (ret > 0)
2315				return ret;
2316
2317			/*
2318			 * If no server present, give up.
2319			 * If name isn't found in this domain,
2320			 * keep trying higher domains in the search list
2321			 * (if that's enabled).
2322			 * On a NO_DATA error, keep trying, otherwise
2323			 * a wildcard entry of another type could keep us
2324			 * from finding this entry higher in the domain.
2325			 * If we get some other error (negative answer or
2326			 * server failure), then stop searching up,
2327			 * but try the input name below in case it's
2328			 * fully-qualified.
2329			 */
2330			if (errno == ECONNREFUSED) {
2331				h_errno = TRY_AGAIN;
2332				return -1;
2333			}
2334
2335			switch (h_errno) {
2336			case NO_DATA:
2337				got_nodata++;
2338				/* FALLTHROUGH */
2339			case HOST_NOT_FOUND:
2340				/* keep trying */
2341				break;
2342			case TRY_AGAIN:
2343				if (hp->rcode == SERVFAIL) {
2344					/* try next search element, if any */
2345					got_servfail++;
2346					break;
2347				}
2348				/* FALLTHROUGH */
2349			default:
2350				/* anything else implies that we're done */
2351				done++;
2352			}
2353			/*
2354			 * if we got here for some reason other than DNSRCH,
2355			 * we only wanted one iteration of the loop, so stop.
2356			 */
2357			if (!(res->options & RES_DNSRCH))
2358			        done++;
2359		}
2360	}
2361
2362	/*
2363	 * if we have not already tried the name "as is", do that now.
2364	 * note that we do this regardless of how many dots were in the
2365	 * name or whether it ends with a dot.
2366	 */
2367	if (!tried_as_is) {
2368		ret = res_querydomainN(name, NULL, target, res);
2369		if (ret > 0)
2370			return ret;
2371	}
2372
2373	/*
2374	 * if we got here, we didn't satisfy the search.
2375	 * if we did an initial full query, return that query's h_errno
2376	 * (note that we wouldn't be here if that query had succeeded).
2377	 * else if we ever got a nodata, send that back as the reason.
2378	 * else send back meaningless h_errno, that being the one from
2379	 * the last DNSRCH we did.
2380	 */
2381	if (saved_herrno != -1)
2382		h_errno = saved_herrno;
2383	else if (got_nodata)
2384		h_errno = NO_DATA;
2385	else if (got_servfail)
2386		h_errno = TRY_AGAIN;
2387	return -1;
2388}
2389
2390/*
2391 * Perform a call on res_query on the concatenation of name and domain,
2392 * removing a trailing dot from name if domain is NULL.
2393 */
2394static int
2395res_querydomainN(const char *name, const char *domain,
2396    struct res_target *target, res_state res)
2397{
2398	char nbuf[MAXDNAME];
2399	const char *longname = nbuf;
2400	size_t n, d;
2401
2402	assert(name != NULL);
2403	/* XXX: target may be NULL??? */
2404
2405#ifdef DEBUG
2406	if (res->options & RES_DEBUG)
2407		printf(";; res_querydomain(%s, %s)\n",
2408			name, domain?domain:"<Nil>");
2409#endif
2410	if (domain == NULL) {
2411		/*
2412		 * Check for trailing '.';
2413		 * copy without '.' if present.
2414		 */
2415		n = strlen(name);
2416		if (n + 1 > sizeof(nbuf)) {
2417			h_errno = NO_RECOVERY;
2418			return -1;
2419		}
2420		if (n > 0 && name[--n] == '.') {
2421			strncpy(nbuf, name, n);
2422			nbuf[n] = '\0';
2423		} else
2424			longname = name;
2425	} else {
2426		n = strlen(name);
2427		d = strlen(domain);
2428		if (n + 1 + d + 1 > sizeof(nbuf)) {
2429			h_errno = NO_RECOVERY;
2430			return -1;
2431		}
2432		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
2433	}
2434	return res_queryN(longname, target, res);
2435}
2436