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