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