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