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