1/*
2 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 *
5 * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
6 */
7
8
9/*
10 * Portions Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
11 * Portions Copyright (C) 1996-2003  Internet Software Consortium.
12 *
13 * Permission to use, copy, modify, and/or distribute this software for any
14 * purpose with or without fee is hereby granted, provided that the above
15 * copyright notice and this permission notice appear in all copies.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
18 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
20 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 */
25
26/*
27 * Copyright (c) 1985, 1989, 1993
28 *    The Regents of the University of California.  All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 *    notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 *    notice, this list of conditions and the following disclaimer in the
37 *    documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 *    must display the following acknowledgement:
40 * 	This product includes software developed by the University of
41 * 	California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 *    may be used to endorse or promote products derived from this software
44 *    without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 */
58
59/*
60 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
61 *
62 * Permission to use, copy, modify, and distribute this software for any
63 * purpose with or without fee is hereby granted, provided that the above
64 * copyright notice and this permission notice appear in all copies, and that
65 * the name of Digital Equipment Corporation not be used in advertising or
66 * publicity pertaining to distribution of the document or software without
67 * specific, written prior permission.
68 *
69 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
70 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
71 * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
72 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
73 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
74 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
75 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
76 * SOFTWARE.
77 */
78
79/*! \file
80 * \brief
81 * Send query to name server and wait for reply.
82 */
83
84#include "port_before.h"
85#include "fd_setsize.h"
86
87#include <sys/types.h>
88#include <sys/param.h>
89#include <sys/time.h>
90#include <sys/socket.h>
91#include <sys/uio.h>
92
93#include <netinet/in.h>
94#include <netinet/tcp.h>
95#include <arpa/nameser.h>
96#include <arpa/inet.h>
97
98#include <errno.h>
99#include <netdb.h>
100#include <resolv.h>
101#include <signal.h>
102#include <stdio.h>
103#include <stdlib.h>
104#include <string.h>
105#include <unistd.h>
106
107#include <isc/eventlib.h>
108
109#include "port_after.h"
110
111#ifdef USE_POLL
112#ifdef HAVE_STROPTS_H
113#include <stropts.h>
114#endif
115#include <poll.h>
116#endif /* USE_POLL */
117
118/* Options.  Leave them on. */
119#define DEBUG
120#include "res_debug.h"
121#include "res_private.h"
122
123#define EXT(res) ((res)->_u._ext)
124
125#ifndef USE_POLL
126static const int highestFD = FD_SETSIZE - 1;
127#else
128static int highestFD = 0;
129#endif
130
131/* Forward. */
132
133static int		get_salen __P((const struct sockaddr *));
134static struct sockaddr * get_nsaddr __P((res_state, size_t));
135static int		send_vc(res_state, const u_char *, int,
136				u_char *, int, int *, int);
137static int		send_dg(res_state, const u_char *, int,
138				u_char *, int, int *, int, int,
139				int *, int *);
140static void		Aerror(const res_state, FILE *, const char *, int,
141			       const struct sockaddr *, int);
142static void		Perror(const res_state, FILE *, const char *, int);
143static int		sock_eq(struct sockaddr *, struct sockaddr *);
144#if defined(NEED_PSELECT) && !defined(USE_POLL)
145static int		pselect(int, void *, void *, void *,
146				struct timespec *,
147				const sigset_t *);
148#endif
149void res_pquery(const res_state, const u_char *, int, FILE *);
150
151#ifndef	ORIGINAL_ISC_CODE
152#pragma weak	__res_nameinquery	=	res_nameinquery
153#pragma weak	__res_queriesmatch	=	res_queriesmatch
154#pragma weak	res_nisourserver	=	res_ourserver_p
155#endif	/* ORIGINAL_ISC_CODE */
156
157static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
158
159/* Public. */
160
161/*%
162 *	looks up "ina" in _res.ns_addr_list[]
163 *
164 * returns:
165 *\li	0  : not found
166 *\li	>0 : found
167 *
168 * author:
169 *\li	paul vixie, 29may94
170 */
171int
172res_ourserver_p(const res_state statp, const struct sockaddr *sa) {
173	const struct sockaddr_in *inp, *srv;
174	const struct sockaddr_in6 *in6p, *srv6;
175	int ns;
176
177	switch (sa->sa_family) {
178	case AF_INET:
179		inp = (const struct sockaddr_in *)sa;
180		for (ns = 0;  ns < statp->nscount;  ns++) {
181			srv = (struct sockaddr_in *)get_nsaddr(statp, ns);
182			if (srv->sin_family == inp->sin_family &&
183			    srv->sin_port == inp->sin_port &&
184			    (srv->sin_addr.s_addr == INADDR_ANY ||
185			     srv->sin_addr.s_addr == inp->sin_addr.s_addr))
186				return (1);
187		}
188		break;
189	case AF_INET6:
190		if (EXT(statp).ext == NULL)
191			break;
192		in6p = (const struct sockaddr_in6 *)sa;
193		for (ns = 0;  ns < statp->nscount;  ns++) {
194			srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);
195			if (srv6->sin6_family == in6p->sin6_family &&
196			    srv6->sin6_port == in6p->sin6_port &&
197#ifdef HAVE_SIN6_SCOPE_ID
198			    (srv6->sin6_scope_id == 0 ||
199			     srv6->sin6_scope_id == in6p->sin6_scope_id) &&
200#endif
201			    (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
202			     IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
203				return (1);
204		}
205		break;
206	default:
207		break;
208	}
209	return (0);
210}
211
212/*%
213 *	look for (name,type,class) in the query section of packet (buf,eom)
214 *
215 * requires:
216 *\li	buf + HFIXEDSZ <= eom
217 *
218 * returns:
219 *\li	-1 : format error
220 *\li	0  : not found
221 *\li	>0 : found
222 *
223 * author:
224 *\li	paul vixie, 29may94
225 */
226int
227res_nameinquery(const char *name, int type, int class,
228		const u_char *buf, const u_char *eom)
229{
230	const u_char *cp = buf + HFIXEDSZ;
231	int qdcount = ntohs(((const HEADER*)buf)->qdcount);
232
233	while (qdcount-- > 0) {
234		char tname[MAXDNAME+1];
235		int n, ttype, tclass;
236
237		n = dn_expand(buf, eom, cp, tname, sizeof tname);
238		if (n < 0)
239			return (-1);
240		cp += n;
241		if (cp + 2 * INT16SZ > eom)
242			return (-1);
243		ttype = ns_get16(cp); cp += INT16SZ;
244		tclass = ns_get16(cp); cp += INT16SZ;
245		if (ttype == type && tclass == class &&
246		    ns_samename(tname, name) == 1)
247			return (1);
248	}
249	return (0);
250}
251
252/*%
253 *	is there a 1:1 mapping of (name,type,class)
254 *	in (buf1,eom1) and (buf2,eom2)?
255 *
256 * returns:
257 *\li	-1 : format error
258 *\li	0  : not a 1:1 mapping
259 *\li	>0 : is a 1:1 mapping
260 *
261 * author:
262 *\li	paul vixie, 29may94
263 */
264int
265res_queriesmatch(const u_char *buf1, const u_char *eom1,
266		 const u_char *buf2, const u_char *eom2)
267{
268	const u_char *cp = buf1 + HFIXEDSZ;
269	int qdcount = ntohs(((const HEADER*)buf1)->qdcount);
270
271	if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
272		return (-1);
273
274	/*
275	 * Only header section present in replies to
276	 * dynamic update packets.
277	 */
278	if ((((const HEADER *)buf1)->opcode == ns_o_update) &&
279	    (((const HEADER *)buf2)->opcode == ns_o_update))
280		return (1);
281
282	if (qdcount != ntohs(((const HEADER*)buf2)->qdcount))
283		return (0);
284	while (qdcount-- > 0) {
285		char tname[MAXDNAME+1];
286		int n, ttype, tclass;
287
288		n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
289		if (n < 0)
290			return (-1);
291		cp += n;
292		if (cp + 2 * INT16SZ > eom1)
293			return (-1);
294		ttype = ns_get16(cp);	cp += INT16SZ;
295		tclass = ns_get16(cp); cp += INT16SZ;
296		if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
297			return (0);
298	}
299	return (1);
300}
301
302int
303res_nsend(res_state statp,
304	  const u_char *buf, int buflen, u_char *ans, int anssiz)
305{
306	int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n;
307	char abuf[NI_MAXHOST];
308
309#ifdef USE_POLL
310	highestFD = sysconf(_SC_OPEN_MAX) - 1;
311#endif
312
313	/* No name servers or res_init() failure */
314	if (statp->nscount == 0 || EXT(statp).ext == NULL) {
315		errno = ESRCH;
316		return (-1);
317	}
318	if (anssiz < HFIXEDSZ) {
319		errno = EINVAL;
320		return (-1);
321	}
322	DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
323		(stdout, ";; res_send()\n"), buf, buflen);
324	v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
325	gotsomewhere = 0;
326	terrno = ETIMEDOUT;
327
328	/*
329	 * If the ns_addr_list in the resolver context has changed, then
330	 * invalidate our cached copy and the associated timing data.
331	 */
332	if (EXT(statp).nscount != 0) {
333		int needclose = 0;
334		struct sockaddr_storage peer;
335		ISC_SOCKLEN_T peerlen;
336
337		if (EXT(statp).nscount != statp->nscount)
338			needclose++;
339		else
340			for (ns = 0; ns < statp->nscount; ns++) {
341				if (statp->nsaddr_list[ns].sin_family &&
342				    !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],
343					     (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {
344					needclose++;
345					break;
346				}
347
348				if (EXT(statp).nssocks[ns] == -1)
349					continue;
350				peerlen = sizeof(peer);
351				if (getpeername(EXT(statp).nssocks[ns],
352				    (struct sockaddr *)&peer, &peerlen) < 0) {
353					needclose++;
354					break;
355				}
356				if (!sock_eq((struct sockaddr *)&peer,
357				    get_nsaddr(statp, ns))) {
358					needclose++;
359					break;
360				}
361			}
362		if (needclose) {
363			res_nclose(statp);
364			EXT(statp).nscount = 0;
365		}
366	}
367
368	/*
369	 * Maybe initialize our private copy of the ns_addr_list.
370	 */
371	if (EXT(statp).nscount == 0) {
372		for (ns = 0; ns < statp->nscount; ns++) {
373			EXT(statp).nstimes[ns] = RES_MAXTIME;
374			EXT(statp).nssocks[ns] = -1;
375			if (!statp->nsaddr_list[ns].sin_family)
376				continue;
377			EXT(statp).ext->nsaddrs[ns].sin =
378				 statp->nsaddr_list[ns];
379		}
380		EXT(statp).nscount = statp->nscount;
381	}
382
383	/*
384	 * Some resolvers want to even out the load on their nameservers.
385	 * Note that RES_BLAST overrides RES_ROTATE.
386	 */
387	if ((statp->options & RES_ROTATE) != 0U &&
388	    (statp->options & RES_BLAST) == 0U) {
389		union res_sockaddr_union inu;
390		struct sockaddr_in ina;
391		int lastns = statp->nscount - 1;
392		int fd;
393		u_int16_t nstime;
394
395		if (EXT(statp).ext != NULL)
396			inu = EXT(statp).ext->nsaddrs[0];
397		ina = statp->nsaddr_list[0];
398		fd = EXT(statp).nssocks[0];
399		nstime = EXT(statp).nstimes[0];
400		for (ns = 0; ns < lastns; ns++) {
401			if (EXT(statp).ext != NULL)
402				EXT(statp).ext->nsaddrs[ns] =
403					EXT(statp).ext->nsaddrs[ns + 1];
404			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
405			EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
406			EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];
407		}
408		if (EXT(statp).ext != NULL)
409			EXT(statp).ext->nsaddrs[lastns] = inu;
410		statp->nsaddr_list[lastns] = ina;
411		EXT(statp).nssocks[lastns] = fd;
412		EXT(statp).nstimes[lastns] = nstime;
413	}
414
415	/*
416	 * Send request, RETRY times, or until successful.
417	 */
418	for (tries = 0; tries < statp->retry; tries++) {
419	    for (ns = 0; ns < statp->nscount; ns++) {
420		struct sockaddr *nsap;
421		int nsaplen;
422		nsap = get_nsaddr(statp, ns);
423		nsaplen = get_salen(nsap);
424		statp->_flags &= ~RES_F_LASTMASK;
425		statp->_flags |= (ns << RES_F_LASTSHIFT);
426 same_ns:
427		if (statp->qhook) {
428			int done = 0, loops = 0;
429
430			do {
431				res_sendhookact act;
432
433				act = (*statp->qhook)(&nsap, &buf, &buflen,
434						      ans, anssiz, &resplen);
435				switch (act) {
436				case res_goahead:
437					done = 1;
438					break;
439				case res_nextns:
440					res_nclose(statp);
441					goto next_ns;
442				case res_done:
443					return (resplen);
444				case res_modified:
445					/* give the hook another try */
446					if (++loops < 42) /*doug adams*/
447						break;
448					/*FALLTHROUGH*/
449				case res_error:
450					/*FALLTHROUGH*/
451				default:
452					goto fail;
453				}
454			} while (!done);
455		}
456
457		Dprint(((statp->options & RES_DEBUG) &&
458			getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),
459				    NULL, 0, niflags) == 0),
460		       (stdout, ";; Querying server (# %d) address = %s\n",
461			ns + 1, abuf));
462
463
464		if (v_circuit) {
465			/* Use VC; at most one attempt per server. */
466			tries = statp->retry;
467			n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
468				    ns);
469			if (n < 0)
470				goto fail;
471			if (n == 0)
472				goto next_ns;
473			resplen = n;
474		} else {
475			/* Use datagrams. */
476			n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,
477				    ns, tries, &v_circuit, &gotsomewhere);
478			if (n < 0)
479				goto fail;
480			if (n == 0)
481				goto next_ns;
482			if (v_circuit)
483				goto same_ns;
484			resplen = n;
485		}
486
487		Dprint((statp->options & RES_DEBUG) ||
488		       ((statp->pfcode & RES_PRF_REPLY) &&
489			(statp->pfcode & RES_PRF_HEAD1)),
490		       (stdout, ";; got answer:\n"));
491
492		DprintQ((statp->options & RES_DEBUG) ||
493			(statp->pfcode & RES_PRF_REPLY),
494			(stdout, "%s", ""),
495			ans, (resplen > anssiz) ? anssiz : resplen);
496
497		/*
498		 * If we have temporarily opened a virtual circuit,
499		 * or if we haven't been asked to keep a socket open,
500		 * close the socket.
501		 */
502		if ((v_circuit && (statp->options & RES_USEVC) == 0U) ||
503		    (statp->options & RES_STAYOPEN) == 0U) {
504			res_nclose(statp);
505		}
506		if (statp->rhook) {
507			int done = 0, loops = 0;
508
509			do {
510				res_sendhookact act;
511
512				act = (*statp->rhook)(nsap, buf, buflen,
513						      ans, anssiz, &resplen);
514				switch (act) {
515				case res_goahead:
516				case res_done:
517					done = 1;
518					break;
519				case res_nextns:
520					res_nclose(statp);
521					goto next_ns;
522				case res_modified:
523					/* give the hook another try */
524					if (++loops < 42) /*doug adams*/
525						break;
526					/*FALLTHROUGH*/
527				case res_error:
528					/*FALLTHROUGH*/
529				default:
530					goto fail;
531				}
532			} while (!done);
533
534		}
535		return (resplen);
536 next_ns: ;
537	   } /*foreach ns*/
538	} /*foreach retry*/
539	res_nclose(statp);
540	if (!v_circuit) {
541		if (!gotsomewhere)
542			errno = ECONNREFUSED;	/*%< no nameservers found */
543		else
544			errno = ETIMEDOUT;	/*%< no answer obtained */
545	} else
546		errno = terrno;
547	return (-1);
548 fail:
549	res_nclose(statp);
550	return (-1);
551}
552
553/* Private */
554
555static int
556get_salen(sa)
557	const struct sockaddr *sa;
558{
559
560#ifdef HAVE_SA_LEN
561	/* There are people do not set sa_len.  Be forgiving to them. */
562	if (sa->sa_len)
563		return (sa->sa_len);
564#endif
565
566	if (sa->sa_family == AF_INET)
567		return (sizeof(struct sockaddr_in));
568	else if (sa->sa_family == AF_INET6)
569		return (sizeof(struct sockaddr_in6));
570	else
571		return (0);	/*%< unknown, die on connect */
572}
573
574/*%
575 * pick appropriate nsaddr_list for use.  see res_init() for initialization.
576 */
577static struct sockaddr *
578get_nsaddr(statp, n)
579	res_state statp;
580	size_t n;
581{
582
583	if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
584		/*
585		 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
586		 *   than struct sockaddr, and
587		 * - user code did not update statp->nsaddr_list[n].
588		 */
589		return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n];
590	} else {
591		/*
592		 * - user code updated statp->nsaddr_list[n], or
593		 * - statp->nsaddr_list[n] has the same content as
594		 *   EXT(statp).ext->nsaddrs[n].
595		 */
596		return (struct sockaddr *)(void *)&statp->nsaddr_list[n];
597	}
598}
599
600static int
601send_vc(res_state statp,
602	const u_char *buf, int buflen, u_char *ans, int anssiz,
603	int *terrno, int ns)
604{
605	const HEADER *hp = (const HEADER *) buf;
606	HEADER *anhp = (HEADER *) ans;
607	struct sockaddr *nsap;
608	int nsaplen;
609	int truncating, connreset, resplen, n;
610	struct iovec iov[2];
611	u_short len;
612	u_char *cp;
613	void *tmp;
614#ifdef SO_NOSIGPIPE
615	int on = 1;
616#endif
617
618	nsap = get_nsaddr(statp, ns);
619	nsaplen = get_salen(nsap);
620
621	connreset = 0;
622 same_ns:
623	truncating = 0;
624
625	/* Are we still talking to whom we want to talk to? */
626	if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
627		struct sockaddr_storage peer;
628		ISC_SOCKLEN_T size = sizeof peer;
629
630		if (getpeername(statp->_vcsock,
631				(struct sockaddr *)&peer, &size) < 0 ||
632		    !sock_eq((struct sockaddr *)&peer, nsap)) {
633			res_nclose(statp);
634			statp->_flags &= ~RES_F_VC;
635		}
636	}
637
638	if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
639		if (statp->_vcsock >= 0)
640			res_nclose(statp);
641
642		statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
643		if (statp->_vcsock > highestFD) {
644			res_nclose(statp);
645			errno = ENOTSOCK;
646		}
647		if (statp->_vcsock < 0) {
648			switch (errno) {
649			case EPROTONOSUPPORT:
650#ifdef EPFNOSUPPORT
651			case EPFNOSUPPORT:
652#endif
653			case EAFNOSUPPORT:
654				Perror(statp, stderr, "socket(vc)", errno);
655				return (0);
656			default:
657				*terrno = errno;
658				Perror(statp, stderr, "socket(vc)", errno);
659				return (-1);
660			}
661		}
662#ifdef SO_NOSIGPIPE
663		/*
664		 * Disable generation of SIGPIPE when writing to a closed
665		 * socket.  Write should return -1 and set errno to EPIPE
666		 * instead.
667		 *
668		 * Push on even if setsockopt(SO_NOSIGPIPE) fails.
669		 */
670		(void)setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on,
671				 sizeof(on));
672#endif
673#ifdef TCP_CONN_ABORT_THRESHOLD
674		/*
675		 * The default connection timeout is over two minutes.
676		 * We need something more reasonable here.  The default
677		 * retrans value is 5 sec., then 10, 20, 40, on retries.
678		 * TCP connect does its own retries, so we want just one
679		 * reasonable timeout value.  Using 2X retrans, which
680		 * gives us a 10 sec. connect timeout.  If we're waiting
681		 * that long to connect, we probably want to give up and
682		 * try the next DNS server in our list.
683		 *
684		 * It might be reasonable to do this for all callers,
685		 * but for now do it only when we see MS_INTEROP in the
686		 * environment (set in smbd and idmapd)
687		 */
688		if (getenv("MS_INTEROP") != NULL) {
689			int conn_tmo;
690			conn_tmo = statp->retrans * 2000; /* mSec */
691			(void)setsockopt(statp->_vcsock, IPPROTO_TCP,
692			    TCP_CONN_ABORT_THRESHOLD, &conn_tmo,
693			     sizeof(conn_tmo));
694		}
695#endif
696		errno = 0;
697		if (connect(statp->_vcsock, nsap, nsaplen) < 0) {
698			*terrno = errno;
699			Aerror(statp, stderr, "connect/vc", errno, nsap,
700			    nsaplen);
701			res_nclose(statp);
702			return (0);
703		}
704		statp->_flags |= RES_F_VC;
705	}
706
707	/*
708	 * Send length & message
709	 */
710	ns_put16((u_short)buflen, (u_char*)&len);
711	iov[0] = evConsIovec(&len, INT16SZ);
712	DE_CONST(buf, tmp);
713	iov[1] = evConsIovec(tmp, buflen);
714	if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
715		*terrno = errno;
716		Perror(statp, stderr, "write failed", errno);
717		res_nclose(statp);
718		return (0);
719	}
720	/*
721	 * Receive length & response
722	 */
723 read_len:
724	cp = ans;
725	len = INT16SZ;
726	while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) {
727		cp += n;
728		if ((len -= n) == 0)
729			break;
730	}
731	if (n <= 0) {
732		*terrno = errno;
733		Perror(statp, stderr, "read failed", errno);
734		res_nclose(statp);
735		/*
736		 * A long running process might get its TCP
737		 * connection reset if the remote server was
738		 * restarted.  Requery the server instead of
739		 * trying a new one.  When there is only one
740		 * server, this means that a query might work
741		 * instead of failing.  We only allow one reset
742		 * per query to prevent looping.
743		 */
744		if (*terrno == ECONNRESET && !connreset) {
745			connreset = 1;
746			res_nclose(statp);
747			goto same_ns;
748		}
749		res_nclose(statp);
750		return (0);
751	}
752	resplen = ns_get16(ans);
753	if (resplen > anssiz) {
754		Dprint(statp->options & RES_DEBUG,
755		       (stdout, ";; response truncated\n")
756		       );
757		truncating = 1;
758		len = anssiz;
759	} else
760		len = resplen;
761	if (len < HFIXEDSZ) {
762		/*
763		 * Undersized message.
764		 */
765		Dprint(statp->options & RES_DEBUG,
766		       (stdout, ";; undersized: %d\n", len));
767		*terrno = EMSGSIZE;
768		res_nclose(statp);
769		return (0);
770	}
771	cp = ans;
772	while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
773		cp += n;
774		len -= n;
775	}
776	if (n <= 0) {
777		*terrno = errno;
778		Perror(statp, stderr, "read(vc)", errno);
779		res_nclose(statp);
780		return (0);
781	}
782	if (truncating) {
783		/*
784		 * Flush rest of answer so connection stays in synch.
785		 */
786		anhp->tc = 1;
787		len = resplen - anssiz;
788		while (len != 0) {
789			char junk[PACKETSZ];
790
791			n = read(statp->_vcsock, junk,
792				 (len > sizeof junk) ? sizeof junk : len);
793			if (n > 0)
794				len -= n;
795			else
796				break;
797		}
798	}
799	/*
800	 * If the calling applicating has bailed out of
801	 * a previous call and failed to arrange to have
802	 * the circuit closed or the server has got
803	 * itself confused, then drop the packet and
804	 * wait for the correct one.
805	 */
806	if (hp->id != anhp->id) {
807		DprintQ((statp->options & RES_DEBUG) ||
808			(statp->pfcode & RES_PRF_REPLY),
809			(stdout, ";; old answer (unexpected):\n"),
810			ans, (resplen > anssiz) ? anssiz: resplen);
811		goto read_len;
812	}
813
814	/*
815	 * All is well, or the error is fatal.  Signal that the
816	 * next nameserver ought not be tried.
817	 */
818	return (resplen);
819}
820
821static int
822send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans,
823	int anssiz, int *terrno, int ns, int tries, int *v_circuit,
824	int *gotsomewhere)
825{
826	const HEADER *hp = (const HEADER *) buf;
827	HEADER *anhp = (HEADER *) ans;
828	const struct sockaddr *nsap;
829	int nsaplen;
830	struct timespec now, timeout, finish;
831	struct sockaddr_storage from;
832	ISC_SOCKLEN_T fromlen;
833	int resplen, seconds, n, s;
834#ifdef USE_POLL
835	int     polltimeout;
836	struct pollfd   pollfd;
837#else
838	fd_set dsmask;
839#endif
840
841	nsap = get_nsaddr(statp, ns);
842	nsaplen = get_salen(nsap);
843	if (EXT(statp).nssocks[ns] == -1) {
844		EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0);
845		if (EXT(statp).nssocks[ns] > highestFD) {
846			res_nclose(statp);
847			errno = ENOTSOCK;
848		}
849		if (EXT(statp).nssocks[ns] < 0) {
850			switch (errno) {
851			case EPROTONOSUPPORT:
852#ifdef EPFNOSUPPORT
853			case EPFNOSUPPORT:
854#endif
855			case EAFNOSUPPORT:
856				Perror(statp, stderr, "socket(dg)", errno);
857				return (0);
858			default:
859				*terrno = errno;
860				Perror(statp, stderr, "socket(dg)", errno);
861				return (-1);
862			}
863		}
864#ifndef CANNOT_CONNECT_DGRAM
865		/*
866		 * On a 4.3BSD+ machine (client and server,
867		 * actually), sending to a nameserver datagram
868		 * port with no nameserver will cause an
869		 * ICMP port unreachable message to be returned.
870		 * If our datagram socket is "connected" to the
871		 * server, we get an ECONNREFUSED error on the next
872		 * socket operation, and select returns if the
873		 * error message is received.  We can thus detect
874		 * the absence of a nameserver without timing out.
875		 */
876		if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) {
877			Aerror(statp, stderr, "connect(dg)", errno, nsap,
878			    nsaplen);
879			res_nclose(statp);
880			return (0);
881		}
882#endif /* !CANNOT_CONNECT_DGRAM */
883		Dprint(statp->options & RES_DEBUG,
884		       (stdout, ";; new DG socket\n"))
885	}
886	s = EXT(statp).nssocks[ns];
887#ifndef CANNOT_CONNECT_DGRAM
888	if (send(s, (const char*)buf, buflen, 0) != buflen) {
889		Perror(statp, stderr, "send", errno);
890		res_nclose(statp);
891		return (0);
892	}
893#else /* !CANNOT_CONNECT_DGRAM */
894	if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen)
895	{
896		Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
897		res_nclose(statp);
898		return (0);
899	}
900#endif /* !CANNOT_CONNECT_DGRAM */
901
902	/*
903	 * Wait for reply.
904	 */
905	seconds = (statp->retrans << tries);
906	if (ns > 0)
907		seconds /= statp->nscount;
908	if (seconds <= 0)
909		seconds = 1;
910	now = evNowTime();
911	timeout = evConsTime(seconds, 0);
912	finish = evAddTime(now, timeout);
913	goto nonow;
914 wait:
915	now = evNowTime();
916 nonow:
917#ifndef USE_POLL
918	FD_ZERO(&dsmask);
919	FD_SET(s, &dsmask);
920	if (evCmpTime(finish, now) > 0)
921		timeout = evSubTime(finish, now);
922	else
923		timeout = evConsTime(0, 0);
924	n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
925#else
926	timeout = evSubTime(finish, now);
927	if (timeout.tv_sec < 0)
928		timeout = evConsTime(0, 0);
929	polltimeout = 1000*timeout.tv_sec +
930		timeout.tv_nsec/1000000;
931	pollfd.fd = s;
932	pollfd.events = POLLRDNORM;
933	n = poll(&pollfd, 1, polltimeout);
934#endif /* USE_POLL */
935
936	if (n == 0) {
937		Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
938		*gotsomewhere = 1;
939		return (0);
940	}
941	if (n < 0) {
942		if (errno == EINTR)
943			goto wait;
944#ifndef USE_POLL
945		Perror(statp, stderr, "select", errno);
946#else
947		Perror(statp, stderr, "poll", errno);
948#endif /* USE_POLL */
949		res_nclose(statp);
950		return (0);
951	}
952	errno = 0;
953	fromlen = sizeof(from);
954	resplen = recvfrom(s, (char*)ans, anssiz,0,
955			   (struct sockaddr *)&from, &fromlen);
956	if (resplen <= 0) {
957		Perror(statp, stderr, "recvfrom", errno);
958		res_nclose(statp);
959		return (0);
960	}
961	*gotsomewhere = 1;
962	if (resplen < HFIXEDSZ) {
963		/*
964		 * Undersized message.
965		 */
966		Dprint(statp->options & RES_DEBUG,
967		       (stdout, ";; undersized: %d\n",
968			resplen));
969		*terrno = EMSGSIZE;
970		res_nclose(statp);
971		return (0);
972	}
973	if (hp->id != anhp->id) {
974		/*
975		 * response from old query, ignore it.
976		 * XXX - potential security hazard could
977		 *	 be detected here.
978		 */
979		DprintQ((statp->options & RES_DEBUG) ||
980			(statp->pfcode & RES_PRF_REPLY),
981			(stdout, ";; old answer:\n"),
982			ans, (resplen > anssiz) ? anssiz : resplen);
983		goto wait;
984	}
985	if (!(statp->options & RES_INSECURE1) &&
986	    !res_ourserver_p(statp, (struct sockaddr *)&from)) {
987		/*
988		 * response from wrong server? ignore it.
989		 * XXX - potential security hazard could
990		 *	 be detected here.
991		 */
992		DprintQ((statp->options & RES_DEBUG) ||
993			(statp->pfcode & RES_PRF_REPLY),
994			(stdout, ";; not our server:\n"),
995			ans, (resplen > anssiz) ? anssiz : resplen);
996		goto wait;
997	}
998#ifdef RES_USE_EDNS0
999	if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) {
1000		/*
1001		 * Do not retry if the server do not understand EDNS0.
1002		 * The case has to be captured here, as FORMERR packet do not
1003		 * carry query section, hence res_queriesmatch() returns 0.
1004		 */
1005		DprintQ(statp->options & RES_DEBUG,
1006			(stdout, "server rejected query with EDNS0:\n"),
1007			ans, (resplen > anssiz) ? anssiz : resplen);
1008		/* record the error */
1009		statp->_flags |= RES_F_EDNS0ERR;
1010		res_nclose(statp);
1011		return (0);
1012	}
1013#endif
1014	if (!(statp->options & RES_INSECURE2) &&
1015	    !res_queriesmatch(buf, buf + buflen,
1016			      ans, ans + anssiz)) {
1017		/*
1018		 * response contains wrong query? ignore it.
1019		 * XXX - potential security hazard could
1020		 *	 be detected here.
1021		 */
1022		DprintQ((statp->options & RES_DEBUG) ||
1023			(statp->pfcode & RES_PRF_REPLY),
1024			(stdout, ";; wrong query name:\n"),
1025			ans, (resplen > anssiz) ? anssiz : resplen);
1026		goto wait;
1027	}
1028	if (anhp->rcode == SERVFAIL ||
1029	    anhp->rcode == NOTIMP ||
1030	    anhp->rcode == REFUSED) {
1031		DprintQ(statp->options & RES_DEBUG,
1032			(stdout, "server rejected query:\n"),
1033			ans, (resplen > anssiz) ? anssiz : resplen);
1034		res_nclose(statp);
1035		/* don't retry if called from dig */
1036		if (!statp->pfcode)
1037			return (0);
1038	}
1039	if (!(statp->options & RES_IGNTC) && anhp->tc) {
1040		/*
1041		 * To get the rest of answer,
1042		 * use TCP with same server.
1043		 */
1044		Dprint(statp->options & RES_DEBUG,
1045		       (stdout, ";; truncated answer\n"));
1046		*v_circuit = 1;
1047		res_nclose(statp);
1048		return (1);
1049	}
1050	/*
1051	 * All is well, or the error is fatal.  Signal that the
1052	 * next nameserver ought not be tried.
1053	 */
1054	return (resplen);
1055}
1056
1057static void
1058Aerror(const res_state statp, FILE *file, const char *string, int error,
1059       const struct sockaddr *address, int alen)
1060{
1061	int save = errno;
1062	char hbuf[NI_MAXHOST];
1063	char sbuf[NI_MAXSERV];
1064
1065	alen = alen;
1066
1067	if ((statp->options & RES_DEBUG) != 0U) {
1068		if (getnameinfo(address, alen, hbuf, sizeof(hbuf),
1069		    sbuf, sizeof(sbuf), niflags)) {
1070			strncpy(hbuf, "?", sizeof(hbuf) - 1);
1071			hbuf[sizeof(hbuf) - 1] = '\0';
1072			strncpy(sbuf, "?", sizeof(sbuf) - 1);
1073			sbuf[sizeof(sbuf) - 1] = '\0';
1074		}
1075		fprintf(file, "res_send: %s ([%s].%s): %s\n",
1076			string, hbuf, sbuf, strerror(error));
1077	}
1078	errno = save;
1079}
1080
1081static void
1082Perror(const res_state statp, FILE *file, const char *string, int error) {
1083	int save = errno;
1084
1085	if ((statp->options & RES_DEBUG) != 0U)
1086		fprintf(file, "res_send: %s: %s\n",
1087			string, strerror(error));
1088	errno = save;
1089}
1090
1091static int
1092sock_eq(struct sockaddr *a, struct sockaddr *b) {
1093	struct sockaddr_in *a4, *b4;
1094	struct sockaddr_in6 *a6, *b6;
1095
1096	if (a->sa_family != b->sa_family)
1097		return 0;
1098	switch (a->sa_family) {
1099	case AF_INET:
1100		a4 = (struct sockaddr_in *)a;
1101		b4 = (struct sockaddr_in *)b;
1102		return a4->sin_port == b4->sin_port &&
1103		    a4->sin_addr.s_addr == b4->sin_addr.s_addr;
1104	case AF_INET6:
1105		a6 = (struct sockaddr_in6 *)a;
1106		b6 = (struct sockaddr_in6 *)b;
1107		return a6->sin6_port == b6->sin6_port &&
1108#ifdef HAVE_SIN6_SCOPE_ID
1109		    a6->sin6_scope_id == b6->sin6_scope_id &&
1110#endif
1111		    IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
1112	default:
1113		return 0;
1114	}
1115}
1116
1117#if defined(NEED_PSELECT) && !defined(USE_POLL)
1118/* XXX needs to move to the porting library. */
1119static int
1120pselect(int nfds, void *rfds, void *wfds, void *efds,
1121	struct timespec *tsp, const sigset_t *sigmask)
1122{
1123	struct timeval tv, *tvp;
1124	sigset_t sigs;
1125	int n;
1126
1127	if (tsp) {
1128		tvp = &tv;
1129		tv = evTimeVal(*tsp);
1130	} else
1131		tvp = NULL;
1132	if (sigmask)
1133		sigprocmask(SIG_SETMASK, sigmask, &sigs);
1134	n = select(nfds, rfds, wfds, efds, tvp);
1135	if (sigmask)
1136		sigprocmask(SIG_SETMASK, &sigs, NULL);
1137	if (tsp)
1138		*tsp = evTimeSpec(tv);
1139	return (n);
1140}
1141#endif
1142