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