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