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