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