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