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