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