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