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