1/* $NetBSD: res_send.c,v 1.21 2011/02/09 09:46:59 pooka 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 93static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; 94static 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.21 2011/02/09 09:46:59 pooka 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 159static const int highestFD = FD_SETSIZE - 1; 160#endif 161 162/* Forward. */ 163 164static int get_salen __P((const struct sockaddr *)); 165static struct sockaddr * get_nsaddr __P((res_state, size_t)); 166static int send_vc(res_state, const u_char *, int, 167 u_char *, int, int *, int); 168static int send_dg(res_state, const u_char *, int, 169 u_char *, int, int *, int, int, 170 int *, int *); 171static void Aerror(const res_state, FILE *, const char *, int, 172 const struct sockaddr *, int); 173static void Perror(const res_state, FILE *, const char *, int); 174static int sock_eq(struct sockaddr *, struct sockaddr *); 175#if defined(NEED_PSELECT) && !defined(USE_POLL) 176static int pselect(int, void *, void *, void *, 177 struct timespec *, 178 const sigset_t *); 179#endif 180void res_pquery(const res_state, const u_char *, int, FILE *); 181 182static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 183 184/* Public. */ 185 186/*% 187 * looks up "ina" in _res.ns_addr_list[] 188 * 189 * returns: 190 *\li 0 : not found 191 *\li >0 : found 192 * 193 * author: 194 *\li paul vixie, 29may94 195 */ 196int 197res_ourserver_p(const res_state statp, const struct sockaddr *sa) { 198 const struct sockaddr_in *inp, *srv; 199 const struct sockaddr_in6 *in6p, *srv6; 200 int ns; 201 202 switch (sa->sa_family) { 203 case AF_INET: 204 inp = (const struct sockaddr_in *)(const void *)sa; 205 for (ns = 0; ns < statp->nscount; ns++) { 206 srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns); 207 if (srv->sin_family == inp->sin_family && 208 srv->sin_port == inp->sin_port && 209 (srv->sin_addr.s_addr == INADDR_ANY || 210 srv->sin_addr.s_addr == inp->sin_addr.s_addr)) 211 return (1); 212 } 213 break; 214 case AF_INET6: 215 if (EXT(statp).ext == NULL) 216 break; 217 in6p = (const struct sockaddr_in6 *)(const void *)sa; 218 for (ns = 0; ns < statp->nscount; ns++) { 219 srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns); 220 if (srv6->sin6_family == in6p->sin6_family && 221 srv6->sin6_port == in6p->sin6_port && 222#ifdef HAVE_SIN6_SCOPE_ID 223 (srv6->sin6_scope_id == 0 || 224 srv6->sin6_scope_id == in6p->sin6_scope_id) && 225#endif 226 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || 227 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) 228 return (1); 229 } 230 break; 231 default: 232 break; 233 } 234 return (0); 235} 236 237/*% 238 * look for (name,type,class) in the query section of packet (buf,eom) 239 * 240 * requires: 241 *\li buf + HFIXEDSZ <= eom 242 * 243 * returns: 244 *\li -1 : format error 245 *\li 0 : not found 246 *\li >0 : found 247 * 248 * author: 249 *\li paul vixie, 29may94 250 */ 251int 252res_nameinquery(const char *name, int type, int class, 253 const u_char *buf, const u_char *eom) 254{ 255 const u_char *cp = buf + HFIXEDSZ; 256 int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount); 257 258 while (qdcount-- > 0) { 259 char tname[MAXDNAME+1]; 260 int n, ttype, tclass; 261 262 n = dn_expand(buf, eom, cp, tname, sizeof tname); 263 if (n < 0) 264 return (-1); 265 cp += n; 266 if (cp + 2 * INT16SZ > eom) 267 return (-1); 268 ttype = ns_get16(cp); cp += INT16SZ; 269 tclass = ns_get16(cp); cp += INT16SZ; 270 if (ttype == type && tclass == class && 271 ns_samename(tname, name) == 1) 272 return (1); 273 } 274 return (0); 275} 276 277/*% 278 * is there a 1:1 mapping of (name,type,class) 279 * in (buf1,eom1) and (buf2,eom2)? 280 * 281 * returns: 282 *\li -1 : format error 283 *\li 0 : not a 1:1 mapping 284 *\li >0 : is a 1:1 mapping 285 * 286 * author: 287 *\li paul vixie, 29may94 288 */ 289int 290res_queriesmatch(const u_char *buf1, const u_char *eom1, 291 const u_char *buf2, const u_char *eom2) 292{ 293 const u_char *cp = buf1 + HFIXEDSZ; 294 int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount); 295 296 if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) 297 return (-1); 298 299 /* 300 * Only header section present in replies to 301 * dynamic update packets. 302 */ 303 if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) && 304 (((const HEADER *)(const void *)buf2)->opcode == ns_o_update)) 305 return (1); 306 307 if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount)) 308 return (0); 309 while (qdcount-- > 0) { 310 char tname[MAXDNAME+1]; 311 int n, ttype, tclass; 312 313 n = dn_expand(buf1, eom1, cp, tname, sizeof tname); 314 if (n < 0) 315 return (-1); 316 cp += n; 317 if (cp + 2 * INT16SZ > eom1) 318 return (-1); 319 ttype = ns_get16(cp); cp += INT16SZ; 320 tclass = ns_get16(cp); cp += INT16SZ; 321 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) 322 return (0); 323 } 324 return (1); 325} 326 327int 328res_nsend(res_state statp, 329 const u_char *buf, int buflen, u_char *ans, int anssiz) 330{ 331 int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n; 332 char abuf[NI_MAXHOST]; 333 334 (void)res_check(statp, NULL); 335 336 /* No name servers or res_init() failure */ 337 if (statp->nscount == 0 || EXT(statp).ext == NULL) { 338 errno = ESRCH; 339 return (-1); 340 } 341 if (anssiz < HFIXEDSZ) { 342 errno = EINVAL; 343 return (-1); 344 } 345 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), 346 (stdout, ";; res_send()\n"), buf, buflen); 347 v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; 348 gotsomewhere = 0; 349 terrno = ETIMEDOUT; 350 351 /* 352 * If the ns_addr_list in the resolver context has changed, then 353 * invalidate our cached copy and the associated timing data. 354 */ 355 if (EXT(statp).nscount != 0) { 356 int needclose = 0; 357 struct sockaddr_storage peer; 358 ISC_SOCKLEN_T peerlen; 359 360 if (EXT(statp).nscount != statp->nscount) 361 needclose++; 362 else 363 for (ns = 0; ns < statp->nscount; ns++) { 364 if (statp->nsaddr_list[ns].sin_family && 365 !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns], 366 (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) { 367 needclose++; 368 break; 369 } 370 371 if (EXT(statp).nssocks[ns] == -1) 372 continue; 373 peerlen = sizeof(peer); 374 if (getpeername(EXT(statp).nssocks[ns], 375 (struct sockaddr *)(void *)&peer, &peerlen) < 0) { 376 needclose++; 377 break; 378 } 379 if (!sock_eq((struct sockaddr *)(void *)&peer, 380 get_nsaddr(statp, (size_t)ns))) { 381 needclose++; 382 break; 383 } 384 } 385 if (needclose) { 386 res_nclose(statp); 387 EXT(statp).nscount = 0; 388 } 389 } 390 391 /* 392 * Maybe initialize our private copy of the ns_addr_list. 393 */ 394 if (EXT(statp).nscount == 0) { 395 for (ns = 0; ns < statp->nscount; ns++) { 396 EXT(statp).nstimes[ns] = RES_MAXTIME; 397 EXT(statp).nssocks[ns] = -1; 398 if (!statp->nsaddr_list[ns].sin_family) 399 continue; 400 EXT(statp).ext->nsaddrs[ns].sin = 401 statp->nsaddr_list[ns]; 402 } 403 EXT(statp).nscount = statp->nscount; 404 } 405 406 /* 407 * Some resolvers want to even out the load on their nameservers. 408 * Note that RES_BLAST overrides RES_ROTATE. 409 */ 410 if ((statp->options & RES_ROTATE) != 0U && 411 (statp->options & RES_BLAST) == 0U) { 412 union res_sockaddr_union inu; 413 struct sockaddr_in ina; 414 int lastns = statp->nscount - 1; 415 int fd; 416 u_int16_t nstime; 417 418 if (EXT(statp).ext != NULL) 419 inu = EXT(statp).ext->nsaddrs[0]; 420 ina = statp->nsaddr_list[0]; 421 fd = EXT(statp).nssocks[0]; 422 nstime = EXT(statp).nstimes[0]; 423 for (ns = 0; ns < lastns; ns++) { 424 if (EXT(statp).ext != NULL) 425 EXT(statp).ext->nsaddrs[ns] = 426 EXT(statp).ext->nsaddrs[ns + 1]; 427 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; 428 EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; 429 EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; 430 } 431 if (EXT(statp).ext != NULL) 432 EXT(statp).ext->nsaddrs[lastns] = inu; 433 statp->nsaddr_list[lastns] = ina; 434 EXT(statp).nssocks[lastns] = fd; 435 EXT(statp).nstimes[lastns] = nstime; 436 } 437 438 /* 439 * Send request, RETRY times, or until successful. 440 */ 441 for (tries = 0; tries < statp->retry; tries++) { 442 for (ns = 0; ns < statp->nscount; ns++) { 443 struct sockaddr *nsap; 444 int nsaplen; 445 nsap = get_nsaddr(statp, (size_t)ns); 446 nsaplen = get_salen(nsap); 447 statp->_flags &= ~RES_F_LASTMASK; 448 statp->_flags |= (ns << RES_F_LASTSHIFT); 449 same_ns: 450 if (statp->qhook) { 451 int done = 0, loops = 0; 452 453 do { 454 res_sendhookact act; 455 456 act = (*statp->qhook)(&nsap, &buf, &buflen, 457 ans, anssiz, &resplen); 458 switch (act) { 459 case res_goahead: 460 done = 1; 461 break; 462 case res_nextns: 463 res_nclose(statp); 464 goto next_ns; 465 case res_done: 466 return (resplen); 467 case res_modified: 468 /* give the hook another try */ 469 if (++loops < 42) /*doug adams*/ 470 break; 471 /*FALLTHROUGH*/ 472 case res_error: 473 /*FALLTHROUGH*/ 474 default: 475 goto fail; 476 } 477 } while (!done); 478 } 479 480 Dprint(((statp->options & RES_DEBUG) && 481 getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), 482 NULL, 0, niflags) == 0), 483 (stdout, ";; Querying server (# %d) address = %s\n", 484 ns + 1, abuf)); 485 486 487 if (v_circuit) { 488 /* Use VC; at most one attempt per server. */ 489 tries = statp->retry; 490 n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, 491 ns); 492 if (n < 0) 493 goto fail; 494 if (n == 0) 495 goto next_ns; 496 resplen = n; 497 } else { 498 /* Use datagrams. */ 499 n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, 500 ns, tries, &v_circuit, &gotsomewhere); 501 if (n < 0) 502 goto fail; 503 if (n == 0) 504 goto next_ns; 505 if (v_circuit) 506 goto same_ns; 507 resplen = n; 508 } 509 510 Dprint((statp->options & RES_DEBUG) || 511 ((statp->pfcode & RES_PRF_REPLY) && 512 (statp->pfcode & RES_PRF_HEAD1)), 513 (stdout, ";; got answer:\n")); 514 515 DprintQ((statp->options & RES_DEBUG) || 516 (statp->pfcode & RES_PRF_REPLY), 517 (stdout, "%s", ""), 518 ans, (resplen > anssiz) ? anssiz : resplen); 519 520 /* 521 * If we have temporarily opened a virtual circuit, 522 * or if we haven't been asked to keep a socket open, 523 * close the socket. 524 */ 525 if ((v_circuit && (statp->options & RES_USEVC) == 0U) || 526 (statp->options & RES_STAYOPEN) == 0U) { 527 res_nclose(statp); 528 } 529 if (statp->rhook) { 530 int done = 0, loops = 0; 531 532 do { 533 res_sendhookact act; 534 535 act = (*statp->rhook)(nsap, buf, buflen, 536 ans, anssiz, &resplen); 537 switch (act) { 538 case res_goahead: 539 case res_done: 540 done = 1; 541 break; 542 case res_nextns: 543 res_nclose(statp); 544 goto next_ns; 545 case res_modified: 546 /* give the hook another try */ 547 if (++loops < 42) /*doug adams*/ 548 break; 549 /*FALLTHROUGH*/ 550 case res_error: 551 /*FALLTHROUGH*/ 552 default: 553 goto fail; 554 } 555 } while (!done); 556 557 } 558 return (resplen); 559 next_ns: ; 560 } /*foreach ns*/ 561 } /*foreach retry*/ 562 res_nclose(statp); 563 if (!v_circuit) { 564 if (!gotsomewhere) 565 errno = ECONNREFUSED; /*%< no nameservers found */ 566 else 567 errno = ETIMEDOUT; /*%< no answer obtained */ 568 } else 569 errno = terrno; 570 return (-1); 571 fail: 572 res_nclose(statp); 573 return (-1); 574} 575 576/* Private */ 577 578static int 579get_salen(sa) 580 const struct sockaddr *sa; 581{ 582 583#ifdef HAVE_SA_LEN 584 /* There are people do not set sa_len. Be forgiving to them. */ 585 if (sa->sa_len) 586 return (sa->sa_len); 587#endif 588 589 if (sa->sa_family == AF_INET) 590 return (sizeof(struct sockaddr_in)); 591 else if (sa->sa_family == AF_INET6) 592 return (sizeof(struct sockaddr_in6)); 593 else 594 return (0); /*%< unknown, die on connect */ 595} 596 597/*% 598 * pick appropriate nsaddr_list for use. see res_init() for initialization. 599 */ 600static struct sockaddr * 601get_nsaddr(statp, n) 602 res_state statp; 603 size_t n; 604{ 605 606 if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { 607 /* 608 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger 609 * than struct sockaddr, and 610 * - user code did not update statp->nsaddr_list[n]. 611 */ 612 return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; 613 } else { 614 /* 615 * - user code updated statp->nsaddr_list[n], or 616 * - statp->nsaddr_list[n] has the same content as 617 * EXT(statp).ext->nsaddrs[n]. 618 */ 619 return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; 620 } 621} 622 623static int 624send_vc(res_state statp, 625 const u_char *buf, int buflen, u_char *ans, int anssiz, 626 int *terrno, int ns) 627{ 628 const HEADER *hp = (const HEADER *)(const void *)buf; 629 HEADER *anhp = (HEADER *)(void *)ans; 630 struct sockaddr *nsap; 631 int nsaplen; 632 int truncating, connreset, resplen, n; 633 struct iovec iov[2]; 634 u_short len; 635 u_char *cp; 636 void *tmp; 637#ifdef SO_NOSIGPIPE 638 int on = 1; 639#endif 640 641 nsap = get_nsaddr(statp, (size_t)ns); 642 nsaplen = get_salen(nsap); 643 644 connreset = 0; 645 same_ns: 646 truncating = 0; 647 648 /* Are we still talking to whom we want to talk to? */ 649 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { 650 struct sockaddr_storage peer; 651 ISC_SOCKLEN_T size = sizeof peer; 652 653 if (getpeername(statp->_vcsock, 654 (struct sockaddr *)(void *)&peer, &size) < 0 || 655 !sock_eq((struct sockaddr *)(void *)&peer, nsap)) { 656 res_nclose(statp); 657 statp->_flags &= ~RES_F_VC; 658 } 659 } 660 661 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { 662 if (statp->_vcsock >= 0) 663 res_nclose(statp); 664 665 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); 666#ifndef USE_POLL 667 if (statp->_vcsock > highestFD) { 668 res_nclose(statp); 669 errno = ENOTSOCK; 670 } 671#endif 672 if (statp->_vcsock < 0) { 673 switch (errno) { 674 case EPROTONOSUPPORT: 675#ifdef EPFNOSUPPORT 676 case EPFNOSUPPORT: 677#endif 678 case EAFNOSUPPORT: 679 Perror(statp, stderr, "socket(vc)", errno); 680 return (0); 681 default: 682 *terrno = errno; 683 Perror(statp, stderr, "socket(vc)", errno); 684 return (-1); 685 } 686 } 687#ifdef SO_NOSIGPIPE 688 /* 689 * Disable generation of SIGPIPE when writing to a closed 690 * socket. Write should return -1 and set errno to EPIPE 691 * instead. 692 * 693 * Push on even if setsockopt(SO_NOSIGPIPE) fails. 694 */ 695 (void)setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on, 696 sizeof(on)); 697#endif 698 errno = 0; 699 if (connect(statp->_vcsock, nsap, (socklen_t)nsaplen) < 0) { 700 *terrno = errno; 701 Aerror(statp, stderr, "connect/vc", errno, nsap, 702 nsaplen); 703 res_nclose(statp); 704 return (0); 705 } 706 statp->_flags |= RES_F_VC; 707 } 708 709 /* 710 * Send length & message 711 */ 712 ns_put16((u_short)buflen, (u_char*)(void *)&len); 713 iov[0] = evConsIovec(&len, INT16SZ); 714 DE_CONST(buf, tmp); 715 iov[1] = evConsIovec(tmp, (size_t)buflen); 716 if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { 717 *terrno = errno; 718 Perror(statp, stderr, "write failed", errno); 719 res_nclose(statp); 720 return (0); 721 } 722 /* 723 * Receive length & response 724 */ 725 read_len: 726 cp = ans; 727 len = INT16SZ; 728 while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) { 729 cp += n; 730 if ((len -= n) == 0) 731 break; 732 } 733 if (n <= 0) { 734 *terrno = errno; 735 Perror(statp, stderr, "read failed", errno); 736 res_nclose(statp); 737 /* 738 * A long running process might get its TCP 739 * connection reset if the remote server was 740 * restarted. Requery the server instead of 741 * trying a new one. When there is only one 742 * server, this means that a query might work 743 * instead of failing. We only allow one reset 744 * per query to prevent looping. 745 */ 746 if (*terrno == ECONNRESET && !connreset) { 747 connreset = 1; 748 res_nclose(statp); 749 goto same_ns; 750 } 751 res_nclose(statp); 752 return (0); 753 } 754 resplen = ns_get16(ans); 755 if (resplen > anssiz) { 756 Dprint(statp->options & RES_DEBUG, 757 (stdout, ";; response truncated\n") 758 ); 759 truncating = 1; 760 len = anssiz; 761 } else 762 len = resplen; 763 if (len < HFIXEDSZ) { 764 /* 765 * Undersized message. 766 */ 767 Dprint(statp->options & RES_DEBUG, 768 (stdout, ";; undersized: %d\n", len)); 769 *terrno = EMSGSIZE; 770 res_nclose(statp); 771 return (0); 772 } 773 cp = ans; 774 while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){ 775 cp += n; 776 len -= n; 777 } 778 if (n <= 0) { 779 *terrno = errno; 780 Perror(statp, stderr, "read(vc)", errno); 781 res_nclose(statp); 782 return (0); 783 } 784 if (truncating) { 785 /* 786 * Flush rest of answer so connection stays in synch. 787 */ 788 anhp->tc = 1; 789 len = resplen - anssiz; 790 while (len != 0) { 791 char junk[PACKETSZ]; 792 793 n = read(statp->_vcsock, junk, 794 (len > sizeof junk) ? sizeof junk : len); 795 if (n > 0) 796 len -= n; 797 else 798 break; 799 } 800 } 801 /* 802 * If the calling applicating has bailed out of 803 * a previous call and failed to arrange to have 804 * the circuit closed or the server has got 805 * itself confused, then drop the packet and 806 * wait for the correct one. 807 */ 808 if (hp->id != anhp->id) { 809 DprintQ((statp->options & RES_DEBUG) || 810 (statp->pfcode & RES_PRF_REPLY), 811 (stdout, ";; old answer (unexpected):\n"), 812 ans, (resplen > anssiz) ? anssiz: resplen); 813 goto read_len; 814 } 815 816 /* 817 * All is well, or the error is fatal. Signal that the 818 * next nameserver ought not be tried. 819 */ 820 return (resplen); 821} 822 823static int 824send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, 825 int anssiz, int *terrno, int ns, int tries, int *v_circuit, 826 int *gotsomewhere) 827{ 828 const HEADER *hp = (const HEADER *)(const void *)buf; 829 HEADER *anhp = (HEADER *)(void *)ans; 830 const struct sockaddr *nsap; 831 int nsaplen; 832 struct timespec now, timeout, finish; 833 struct sockaddr_storage from; 834 ISC_SOCKLEN_T fromlen; 835 int resplen, seconds, n, s; 836#ifdef USE_POLL 837 int polltimeout; 838 struct pollfd pollfd; 839#else 840 fd_set dsmask; 841#endif 842 843 nsap = get_nsaddr(statp, (size_t)ns); 844 nsaplen = get_salen(nsap); 845 if (EXT(statp).nssocks[ns] == -1) { 846 EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); 847#ifndef USE_POLL 848 if (EXT(statp).nssocks[ns] > highestFD) { 849 res_nclose(statp); 850 errno = ENOTSOCK; 851 } 852#endif 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 1061static void 1062Aerror(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 if ((statp->options & RES_DEBUG) != 0U) { 1070 if (getnameinfo(address, (socklen_t)alen, hbuf, sizeof(hbuf), 1071 sbuf, sizeof(sbuf), niflags)) { 1072 strncpy(hbuf, "?", sizeof(hbuf) - 1); 1073 hbuf[sizeof(hbuf) - 1] = '\0'; 1074 strncpy(sbuf, "?", sizeof(sbuf) - 1); 1075 sbuf[sizeof(sbuf) - 1] = '\0'; 1076 } 1077 fprintf(file, "res_send: %s ([%s].%s): %s\n", 1078 string, hbuf, sbuf, strerror(error)); 1079 } 1080 errno = save; 1081} 1082 1083static void 1084Perror(const res_state statp, FILE *file, const char *string, int error) { 1085 int save = errno; 1086 1087 if ((statp->options & RES_DEBUG) != 0U) 1088 fprintf(file, "res_send: %s: %s\n", 1089 string, strerror(error)); 1090 errno = save; 1091} 1092 1093static int 1094sock_eq(struct sockaddr *a, struct sockaddr *b) { 1095 struct sockaddr_in *a4, *b4; 1096 struct sockaddr_in6 *a6, *b6; 1097 1098 if (a->sa_family != b->sa_family) 1099 return 0; 1100 switch (a->sa_family) { 1101 case AF_INET: 1102 a4 = (struct sockaddr_in *)(void *)a; 1103 b4 = (struct sockaddr_in *)(void *)b; 1104 return a4->sin_port == b4->sin_port && 1105 a4->sin_addr.s_addr == b4->sin_addr.s_addr; 1106 case AF_INET6: 1107 a6 = (struct sockaddr_in6 *)(void *)a; 1108 b6 = (struct sockaddr_in6 *)(void *)b; 1109 return a6->sin6_port == b6->sin6_port && 1110#ifdef HAVE_SIN6_SCOPE_ID 1111 a6->sin6_scope_id == b6->sin6_scope_id && 1112#endif 1113 IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); 1114 default: 1115 return 0; 1116 } 1117} 1118 1119#if defined(NEED_PSELECT) && !defined(USE_POLL) 1120/* XXX needs to move to the porting library. */ 1121static int 1122pselect(int nfds, void *rfds, void *wfds, void *efds, 1123 struct timespec *tsp, const sigset_t *sigmask) 1124{ 1125 struct timeval tv, *tvp; 1126 sigset_t sigs; 1127 int n; 1128 1129 if (tsp) { 1130 tvp = &tv; 1131 tv = evTimeVal(*tsp); 1132 } else 1133 tvp = NULL; 1134 if (sigmask) 1135 sigprocmask(SIG_SETMASK, sigmask, &sigs); 1136 n = select(nfds, rfds, wfds, efds, tvp); 1137 if (sigmask) 1138 sigprocmask(SIG_SETMASK, &sigs, NULL); 1139 if (tsp) 1140 *tsp = evTimeSpec(tv); 1141 return (n); 1142} 1143#endif 1144