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