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