res_send.c revision ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39b
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 77static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; 78static 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 <fcntl.h> 103#include <netdb.h> 104#ifdef ANDROID_CHANGES 105#include "resolv_private.h" 106#else 107#include <resolv.h> 108#endif 109#include <signal.h> 110#include <stdio.h> 111#include <stdlib.h> 112#include <string.h> 113#include <time.h> 114#include <unistd.h> 115 116#include <isc/eventlib.h> 117 118#if USE_RESOLV_CACHE 119# include <resolv_cache.h> 120#endif 121 122#include "logd.h" 123 124#ifndef DE_CONST 125#define DE_CONST(c,v) v = ((c) ? \ 126 strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL) 127#endif 128 129/* Options. Leave them on. */ 130#ifndef DEBUG 131#define DEBUG 132#endif 133#include "res_debug.h" 134#include "res_private.h" 135 136#define EXT(res) ((res)->_u._ext) 137#define DBG 0 138 139static const int highestFD = FD_SETSIZE - 1; 140 141/* Forward. */ 142 143static int get_salen __P((const struct sockaddr *)); 144static struct sockaddr * get_nsaddr __P((res_state, size_t)); 145static int send_vc(res_state, const u_char *, int, 146 u_char *, int, int *, int); 147static int send_dg(res_state, const u_char *, int, 148 u_char *, 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#ifdef NEED_PSELECT 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 *); 160static int connect_with_timeout(int sock, const struct sockaddr *nsap, 161 socklen_t salen, int sec); 162static int retrying_select(const int sock, fd_set *readset, fd_set *writeset, 163 const struct timespec *finish); 164 165/* BIONIC-BEGIN: implement source port randomization */ 166typedef union { 167 struct sockaddr sa; 168 struct sockaddr_in sin; 169 struct sockaddr_in6 sin6; 170} _sockaddr_union; 171 172static int 173random_bind( int s, int family ) 174{ 175 _sockaddr_union u; 176 int j; 177 socklen_t slen; 178 179 /* clear all, this also sets the IP4/6 address to 'any' */ 180 memset( &u, 0, sizeof u ); 181 182 switch (family) { 183 case AF_INET: 184 u.sin.sin_family = family; 185 slen = sizeof u.sin; 186 break; 187 case AF_INET6: 188 u.sin6.sin6_family = family; 189 slen = sizeof u.sin6; 190 break; 191 default: 192 errno = EPROTO; 193 return -1; 194 } 195 196 /* first try to bind to a random source port a few times */ 197 for (j = 0; j < 10; j++) { 198 /* find a random port between 1025 .. 65534 */ 199 int port = 1025 + (res_randomid() % (65535-1025)); 200 if (family == AF_INET) 201 u.sin.sin_port = htons(port); 202 else 203 u.sin6.sin6_port = htons(port); 204 205 if ( !bind( s, &u.sa, slen ) ) 206 return 0; 207 } 208 209 /* nothing after 10 tries, our network table is probably busy */ 210 /* let the system decide which port is best */ 211 if (family == AF_INET) 212 u.sin.sin_port = 0; 213 else 214 u.sin6.sin6_port = 0; 215 216 return bind( s, &u.sa, slen ); 217} 218/* BIONIC-END */ 219 220static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 221 222/* Public. */ 223 224/* int 225 * res_isourserver(ina) 226 * looks up "ina" in _res.ns_addr_list[] 227 * returns: 228 * 0 : not found 229 * >0 : found 230 * author: 231 * paul vixie, 29may94 232 */ 233__LIBC_HIDDEN__ int 234res_ourserver_p(const res_state statp, const struct sockaddr *sa) { 235 const struct sockaddr_in *inp, *srv; 236 const struct sockaddr_in6 *in6p, *srv6; 237 int ns; 238 239 switch (sa->sa_family) { 240 case AF_INET: 241 inp = (const struct sockaddr_in *)(const void *)sa; 242 for (ns = 0; ns < statp->nscount; ns++) { 243 srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns); 244 if (srv->sin_family == inp->sin_family && 245 srv->sin_port == inp->sin_port && 246 (srv->sin_addr.s_addr == INADDR_ANY || 247 srv->sin_addr.s_addr == inp->sin_addr.s_addr)) 248 return (1); 249 } 250 break; 251 case AF_INET6: 252 if (EXT(statp).ext == NULL) 253 break; 254 in6p = (const struct sockaddr_in6 *)(const void *)sa; 255 for (ns = 0; ns < statp->nscount; ns++) { 256 srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns); 257 if (srv6->sin6_family == in6p->sin6_family && 258 srv6->sin6_port == in6p->sin6_port && 259#ifdef HAVE_SIN6_SCOPE_ID 260 (srv6->sin6_scope_id == 0 || 261 srv6->sin6_scope_id == in6p->sin6_scope_id) && 262#endif 263 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || 264 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) 265 return (1); 266 } 267 break; 268 default: 269 break; 270 } 271 return (0); 272} 273 274/* int 275 * res_nameinquery(name, type, class, buf, eom) 276 * look for (name,type,class) in the query section of packet (buf,eom) 277 * requires: 278 * buf + HFIXEDSZ <= eom 279 * returns: 280 * -1 : format error 281 * 0 : not found 282 * >0 : found 283 * author: 284 * paul vixie, 29may94 285 */ 286int 287res_nameinquery(const char *name, int type, int class, 288 const u_char *buf, const u_char *eom) 289{ 290 const u_char *cp = buf + HFIXEDSZ; 291 int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount); 292 293 while (qdcount-- > 0) { 294 char tname[MAXDNAME+1]; 295 int n, ttype, tclass; 296 297 n = dn_expand(buf, eom, cp, tname, sizeof tname); 298 if (n < 0) 299 return (-1); 300 cp += n; 301 if (cp + 2 * INT16SZ > eom) 302 return (-1); 303 ttype = ns_get16(cp); cp += INT16SZ; 304 tclass = ns_get16(cp); cp += INT16SZ; 305 if (ttype == type && tclass == class && 306 ns_samename(tname, name) == 1) 307 return (1); 308 } 309 return (0); 310} 311 312/* int 313 * res_queriesmatch(buf1, eom1, buf2, eom2) 314 * is there a 1:1 mapping of (name,type,class) 315 * in (buf1,eom1) and (buf2,eom2)? 316 * returns: 317 * -1 : format error 318 * 0 : not a 1:1 mapping 319 * >0 : is a 1:1 mapping 320 * author: 321 * paul vixie, 29may94 322 */ 323int 324res_queriesmatch(const u_char *buf1, const u_char *eom1, 325 const u_char *buf2, const u_char *eom2) 326{ 327 const u_char *cp = buf1 + HFIXEDSZ; 328 int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount); 329 330 if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) 331 return (-1); 332 333 /* 334 * Only header section present in replies to 335 * dynamic update packets. 336 */ 337 if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) && 338 (((const HEADER *)(const void *)buf2)->opcode == ns_o_update)) 339 return (1); 340 341 if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount)) 342 return (0); 343 while (qdcount-- > 0) { 344 char tname[MAXDNAME+1]; 345 int n, ttype, tclass; 346 347 n = dn_expand(buf1, eom1, cp, tname, sizeof tname); 348 if (n < 0) 349 return (-1); 350 cp += n; 351 if (cp + 2 * INT16SZ > eom1) 352 return (-1); 353 ttype = ns_get16(cp); cp += INT16SZ; 354 tclass = ns_get16(cp); cp += INT16SZ; 355 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) 356 return (0); 357 } 358 return (1); 359} 360 361 362int 363res_nsend(res_state statp, 364 const u_char *buf, int buflen, u_char *ans, int anssiz) 365{ 366 int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; 367 char abuf[NI_MAXHOST]; 368#if USE_RESOLV_CACHE 369 struct resolv_cache* cache; 370 ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED; 371#endif 372 373 if (statp->nscount == 0) { 374 errno = ESRCH; 375 return (-1); 376 } 377 if (anssiz < HFIXEDSZ) { 378 errno = EINVAL; 379 return (-1); 380 } 381 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), 382 (stdout, ";; res_send()\n"), buf, buflen); 383 v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; 384 gotsomewhere = 0; 385 terrno = ETIMEDOUT; 386 387#if USE_RESOLV_CACHE 388 cache = __get_res_cache(); 389 if (cache != NULL) { 390 int anslen = 0; 391 cache_status = _resolv_cache_lookup( 392 cache, buf, buflen, 393 ans, anssiz, &anslen); 394 395 if (cache_status == RESOLV_CACHE_FOUND) { 396 return anslen; 397 } 398 } 399#endif 400 401 /* 402 * If the ns_addr_list in the resolver context has changed, then 403 * invalidate our cached copy and the associated timing data. 404 */ 405 if (EXT(statp).nscount != 0) { 406 int needclose = 0; 407 struct sockaddr_storage peer; 408 socklen_t peerlen; 409 410 if (EXT(statp).nscount != statp->nscount) 411 needclose++; 412 else 413 for (ns = 0; ns < statp->nscount; ns++) { 414 if (statp->nsaddr_list[ns].sin_family && 415 !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns], 416 (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) { 417 needclose++; 418 break; 419 } 420 421 if (EXT(statp).nssocks[ns] == -1) 422 continue; 423 peerlen = sizeof(peer); 424 if (getpeername(EXT(statp).nssocks[ns], 425 (struct sockaddr *)(void *)&peer, &peerlen) < 0) { 426 needclose++; 427 break; 428 } 429 if (!sock_eq((struct sockaddr *)(void *)&peer, 430 get_nsaddr(statp, (size_t)ns))) { 431 needclose++; 432 break; 433 } 434 } 435 if (needclose) { 436 res_nclose(statp); 437 EXT(statp).nscount = 0; 438 } 439 } 440 441 /* 442 * Maybe initialize our private copy of the ns_addr_list. 443 */ 444 if (EXT(statp).nscount == 0) { 445 for (ns = 0; ns < statp->nscount; ns++) { 446 EXT(statp).nstimes[ns] = RES_MAXTIME; 447 EXT(statp).nssocks[ns] = -1; 448 if (!statp->nsaddr_list[ns].sin_family) 449 continue; 450 EXT(statp).ext->nsaddrs[ns].sin = 451 statp->nsaddr_list[ns]; 452 } 453 EXT(statp).nscount = statp->nscount; 454 } 455 456 /* 457 * Some resolvers want to even out the load on their nameservers. 458 * Note that RES_BLAST overrides RES_ROTATE. 459 */ 460 if ((statp->options & RES_ROTATE) != 0U && 461 (statp->options & RES_BLAST) == 0U) { 462 union res_sockaddr_union inu; 463 struct sockaddr_in ina; 464 int lastns = statp->nscount - 1; 465 int fd; 466 u_int16_t nstime; 467 468 if (EXT(statp).ext != NULL) 469 inu = EXT(statp).ext->nsaddrs[0]; 470 ina = statp->nsaddr_list[0]; 471 fd = EXT(statp).nssocks[0]; 472 nstime = EXT(statp).nstimes[0]; 473 for (ns = 0; ns < lastns; ns++) { 474 if (EXT(statp).ext != NULL) 475 EXT(statp).ext->nsaddrs[ns] = 476 EXT(statp).ext->nsaddrs[ns + 1]; 477 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; 478 EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; 479 EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; 480 } 481 if (EXT(statp).ext != NULL) 482 EXT(statp).ext->nsaddrs[lastns] = inu; 483 statp->nsaddr_list[lastns] = ina; 484 EXT(statp).nssocks[lastns] = fd; 485 EXT(statp).nstimes[lastns] = nstime; 486 } 487 488 /* 489 * Send request, RETRY times, or until successful. 490 */ 491 for (try = 0; try < statp->retry; try++) { 492 for (ns = 0; ns < statp->nscount; ns++) { 493 struct sockaddr *nsap; 494 int nsaplen; 495 nsap = get_nsaddr(statp, (size_t)ns); 496 nsaplen = get_salen(nsap); 497 statp->_flags &= ~RES_F_LASTMASK; 498 statp->_flags |= (ns << RES_F_LASTSHIFT); 499 same_ns: 500 if (statp->qhook) { 501 int done = 0, loops = 0; 502 503 do { 504 res_sendhookact act; 505 506 act = (*statp->qhook)(&nsap, &buf, &buflen, 507 ans, anssiz, &resplen); 508 switch (act) { 509 case res_goahead: 510 done = 1; 511 break; 512 case res_nextns: 513 res_nclose(statp); 514 goto next_ns; 515 case res_done: 516 return (resplen); 517 case res_modified: 518 /* give the hook another try */ 519 if (++loops < 42) /*doug adams*/ 520 break; 521 /*FALLTHROUGH*/ 522 case res_error: 523 /*FALLTHROUGH*/ 524 default: 525 goto fail; 526 } 527 } while (!done); 528 } 529 530 Dprint(((statp->options & RES_DEBUG) && 531 getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), 532 NULL, 0, niflags) == 0), 533 (stdout, ";; Querying server (# %d) address = %s\n", 534 ns + 1, abuf)); 535 536 537 if (v_circuit) { 538 /* Use VC; at most one attempt per server. */ 539 try = statp->retry; 540 541 n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, 542 ns); 543 544 if (DBG) { 545 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 546 "used send_vc %d\n", n); 547 } 548 549 if (n < 0) 550 goto fail; 551 if (n == 0) 552 goto next_ns; 553 resplen = n; 554 } else { 555 /* Use datagrams. */ 556 if (DBG) { 557 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 558 "using send_dg\n"); 559 } 560 561 n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, 562 ns, &v_circuit, &gotsomewhere); 563 if (DBG) { 564 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 565 "used send_dg %d\n",n); 566 } 567 568 if (n < 0) 569 goto fail; 570 if (n == 0) 571 goto next_ns; 572 if (DBG) { 573 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 574 "time=%d, %d\n",time(NULL), time(NULL)%2); 575 } 576 if (v_circuit) 577 goto same_ns; 578 resplen = n; 579 } 580 581 Dprint((statp->options & RES_DEBUG) || 582 ((statp->pfcode & RES_PRF_REPLY) && 583 (statp->pfcode & RES_PRF_HEAD1)), 584 (stdout, ";; got answer:\n")); 585 586 DprintQ((statp->options & RES_DEBUG) || 587 (statp->pfcode & RES_PRF_REPLY), 588 (stdout, "%s", ""), 589 ans, (resplen > anssiz) ? anssiz : resplen); 590 591#if USE_RESOLV_CACHE 592 if (cache_status == RESOLV_CACHE_NOTFOUND) { 593 _resolv_cache_add(cache, buf, buflen, 594 ans, resplen); 595 } 596#endif 597 /* 598 * If we have temporarily opened a virtual circuit, 599 * or if we haven't been asked to keep a socket open, 600 * close the socket. 601 */ 602 if ((v_circuit && (statp->options & RES_USEVC) == 0U) || 603 (statp->options & RES_STAYOPEN) == 0U) { 604 res_nclose(statp); 605 } 606 if (statp->rhook) { 607 int done = 0, loops = 0; 608 609 do { 610 res_sendhookact act; 611 612 act = (*statp->rhook)(nsap, buf, buflen, 613 ans, anssiz, &resplen); 614 switch (act) { 615 case res_goahead: 616 case res_done: 617 done = 1; 618 break; 619 case res_nextns: 620 res_nclose(statp); 621 goto next_ns; 622 case res_modified: 623 /* give the hook another try */ 624 if (++loops < 42) /*doug adams*/ 625 break; 626 /*FALLTHROUGH*/ 627 case res_error: 628 /*FALLTHROUGH*/ 629 default: 630 goto fail; 631 } 632 } while (!done); 633 634 } 635 return (resplen); 636 next_ns: ; 637 } /*foreach ns*/ 638 } /*foreach retry*/ 639 res_nclose(statp); 640 if (!v_circuit) { 641 if (!gotsomewhere) 642 errno = ECONNREFUSED; /* no nameservers found */ 643 else 644 errno = ETIMEDOUT; /* no answer obtained */ 645 } else 646 errno = terrno; 647 648#if USE_RESOLV_CACHE 649 _resolv_cache_query_failed(cache, buf, buflen); 650#endif 651 652 return (-1); 653 fail: 654#if USE_RESOLV_CACHE 655 _resolv_cache_query_failed(cache, buf, buflen); 656#endif 657 res_nclose(statp); 658 return (-1); 659} 660 661/* Private */ 662 663static int 664get_salen(sa) 665 const struct sockaddr *sa; 666{ 667 668#ifdef HAVE_SA_LEN 669 /* There are people do not set sa_len. Be forgiving to them. */ 670 if (sa->sa_len) 671 return (sa->sa_len); 672#endif 673 674 if (sa->sa_family == AF_INET) 675 return (sizeof(struct sockaddr_in)); 676 else if (sa->sa_family == AF_INET6) 677 return (sizeof(struct sockaddr_in6)); 678 else 679 return (0); /* unknown, die on connect */ 680} 681 682/* 683 * pick appropriate nsaddr_list for use. see res_init() for initialization. 684 */ 685static struct sockaddr * 686get_nsaddr(statp, n) 687 res_state statp; 688 size_t n; 689{ 690 691 if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { 692 /* 693 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger 694 * than struct sockaddr, and 695 * - user code did not update statp->nsaddr_list[n]. 696 */ 697 return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; 698 } else { 699 /* 700 * - user code updated statp->nsaddr_list[n], or 701 * - statp->nsaddr_list[n] has the same content as 702 * EXT(statp).ext->nsaddrs[n]. 703 */ 704 return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; 705 } 706} 707 708static int get_timeout(const res_state statp, const int ns) 709{ 710 int timeout = (statp->retrans << ns); 711 if (ns > 0) { 712 timeout /= statp->nscount; 713 } 714 if (timeout <= 0) { 715 timeout = 1; 716 } 717 if (DBG) { 718 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 719 "using timeout of %d sec\n", timeout); 720 } 721 722 return timeout; 723} 724 725static int 726send_vc(res_state statp, 727 const u_char *buf, int buflen, u_char *ans, int anssiz, 728 int *terrno, int ns) 729{ 730 const HEADER *hp = (const HEADER *)(const void *)buf; 731 HEADER *anhp = (HEADER *)(void *)ans; 732 struct sockaddr *nsap; 733 int nsaplen; 734 int truncating, connreset, resplen, n; 735 struct iovec iov[2]; 736 u_short len; 737 u_char *cp; 738 void *tmp; 739 740 if (DBG) { 741 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); 742 } 743 744 nsap = get_nsaddr(statp, (size_t)ns); 745 nsaplen = get_salen(nsap); 746 747 connreset = 0; 748 same_ns: 749 truncating = 0; 750 751 /* Are we still talking to whom we want to talk to? */ 752 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { 753 struct sockaddr_storage peer; 754 socklen_t size = sizeof peer; 755 756 if (getpeername(statp->_vcsock, 757 (struct sockaddr *)(void *)&peer, &size) < 0 || 758 !sock_eq((struct sockaddr *)(void *)&peer, nsap)) { 759 res_nclose(statp); 760 statp->_flags &= ~RES_F_VC; 761 } 762 } 763 764 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { 765 if (statp->_vcsock >= 0) 766 res_nclose(statp); 767 768 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); 769 if (statp->_vcsock > highestFD) { 770 res_nclose(statp); 771 errno = ENOTSOCK; 772 } 773 if (statp->_vcsock < 0) { 774 switch (errno) { 775 case EPROTONOSUPPORT: 776#ifdef EPFNOSUPPORT 777 case EPFNOSUPPORT: 778#endif 779 case EAFNOSUPPORT: 780 Perror(statp, stderr, "socket(vc)", errno); 781 return (0); 782 default: 783 *terrno = errno; 784 Perror(statp, stderr, "socket(vc)", errno); 785 return (-1); 786 } 787 } 788 errno = 0; 789 if (random_bind(statp->_vcsock,nsap->sa_family) < 0) { 790 *terrno = errno; 791 Aerror(statp, stderr, "bind/vc", errno, nsap, 792 nsaplen); 793 res_nclose(statp); 794 return (0); 795 } 796 if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t)nsaplen, 797 get_timeout(statp, ns)) < 0) { 798 *terrno = errno; 799 Aerror(statp, stderr, "connect/vc", errno, nsap, 800 nsaplen); 801 res_nclose(statp); 802 return (0); 803 } 804 statp->_flags |= RES_F_VC; 805 } 806 807 /* 808 * Send length & message 809 */ 810 ns_put16((u_short)buflen, (u_char*)(void *)&len); 811 iov[0] = evConsIovec(&len, INT16SZ); 812 DE_CONST(buf, tmp); 813 iov[1] = evConsIovec(tmp, (size_t)buflen); 814 if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { 815 *terrno = errno; 816 Perror(statp, stderr, "write failed", errno); 817 res_nclose(statp); 818 return (0); 819 } 820 /* 821 * Receive length & response 822 */ 823 read_len: 824 cp = ans; 825 len = INT16SZ; 826 while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) { 827 cp += n; 828 if ((len -= n) == 0) 829 break; 830 } 831 if (n <= 0) { 832 *terrno = errno; 833 Perror(statp, stderr, "read failed", errno); 834 res_nclose(statp); 835 /* 836 * A long running process might get its TCP 837 * connection reset if the remote server was 838 * restarted. Requery the server instead of 839 * trying a new one. When there is only one 840 * server, this means that a query might work 841 * instead of failing. We only allow one reset 842 * per query to prevent looping. 843 */ 844 if (*terrno == ECONNRESET && !connreset) { 845 connreset = 1; 846 res_nclose(statp); 847 goto same_ns; 848 } 849 res_nclose(statp); 850 return (0); 851 } 852 resplen = ns_get16(ans); 853 if (resplen > anssiz) { 854 Dprint(statp->options & RES_DEBUG, 855 (stdout, ";; response truncated\n") 856 ); 857 truncating = 1; 858 len = anssiz; 859 } else 860 len = resplen; 861 if (len < HFIXEDSZ) { 862 /* 863 * Undersized message. 864 */ 865 Dprint(statp->options & RES_DEBUG, 866 (stdout, ";; undersized: %d\n", len)); 867 *terrno = EMSGSIZE; 868 res_nclose(statp); 869 return (0); 870 } 871 cp = ans; 872 while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){ 873 cp += n; 874 len -= n; 875 } 876 if (n <= 0) { 877 *terrno = errno; 878 Perror(statp, stderr, "read(vc)", errno); 879 res_nclose(statp); 880 return (0); 881 } 882 if (truncating) { 883 /* 884 * Flush rest of answer so connection stays in synch. 885 */ 886 anhp->tc = 1; 887 len = resplen - anssiz; 888 while (len != 0) { 889 char junk[PACKETSZ]; 890 891 n = read(statp->_vcsock, junk, 892 (len > sizeof junk) ? sizeof junk : len); 893 if (n > 0) 894 len -= n; 895 else 896 break; 897 } 898 } 899 /* 900 * If the calling applicating has bailed out of 901 * a previous call and failed to arrange to have 902 * the circuit closed or the server has got 903 * itself confused, then drop the packet and 904 * wait for the correct one. 905 */ 906 if (hp->id != anhp->id) { 907 DprintQ((statp->options & RES_DEBUG) || 908 (statp->pfcode & RES_PRF_REPLY), 909 (stdout, ";; old answer (unexpected):\n"), 910 ans, (resplen > anssiz) ? anssiz: resplen); 911 goto read_len; 912 } 913 914 /* 915 * All is well, or the error is fatal. Signal that the 916 * next nameserver ought not be tried. 917 */ 918 return (resplen); 919} 920 921/* return -1 on error (errno set), 0 on success */ 922static int 923connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int sec) 924{ 925 int res, origflags; 926 fd_set rset, wset; 927 struct timespec now, timeout, finish; 928 929 origflags = fcntl(sock, F_GETFL, 0); 930 fcntl(sock, F_SETFL, origflags | O_NONBLOCK); 931 932 res = connect(sock, nsap, salen); 933 if (res < 0 && errno != EINPROGRESS) { 934 res = -1; 935 goto done; 936 } 937 if (res != 0) { 938 now = evNowTime(); 939 timeout = evConsTime((long)sec, 0L); 940 finish = evAddTime(now, timeout); 941 if (DBG) { 942 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 943 " %d send_vc\n", sock); 944 } 945 946 res = retrying_select(sock, &rset, &wset, &finish); 947 if (res <= 0) { 948 res = -1; 949 } 950 } 951done: 952 fcntl(sock, F_SETFL, origflags); 953 if (DBG) { 954 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 955 " %d connect_with_timeout returning %s\n", sock, res); 956 } 957 return res; 958} 959 960static int 961retrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct timespec *finish) 962{ 963 struct timespec now, timeout; 964 int n, error; 965 socklen_t len; 966 967 968retry: 969 if (DBG) { 970 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", " %d retying_select\n", sock); 971 } 972 973 now = evNowTime(); 974 if (readset) { 975 FD_ZERO(readset); 976 FD_SET(sock, readset); 977 } 978 if (writeset) { 979 FD_ZERO(writeset); 980 FD_SET(sock, writeset); 981 } 982 if (evCmpTime(*finish, now) > 0) 983 timeout = evSubTime(*finish, now); 984 else 985 timeout = evConsTime(0L, 0L); 986 987 n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL); 988 if (n == 0) { 989 if (DBG) { 990 __libc_android_log_print(ANDROID_LOG_DEBUG, " libc", 991 " %d retrying_select timeout\n", sock); 992 } 993 errno = ETIMEDOUT; 994 return 0; 995 } 996 if (n < 0) { 997 if (errno == EINTR) 998 goto retry; 999 if (DBG) { 1000 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 1001 " %d retrying_select got error %d\n",sock, n); 1002 } 1003 return n; 1004 } 1005 if ((readset && FD_ISSET(sock, readset)) || (writeset && FD_ISSET(sock, writeset))) { 1006 len = sizeof(error); 1007 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { 1008 errno = error; 1009 if (DBG) { 1010 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 1011 " %d retrying_select dot error2 %d\n", sock, errno); 1012 } 1013 1014 return -1; 1015 } 1016 } 1017 if (DBG) { 1018 __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 1019 " %d retrying_select returning %d for %d\n",sock, n); 1020 } 1021 1022 return n; 1023} 1024 1025 1026static int 1027send_dg(res_state statp, 1028 const u_char *buf, int buflen, u_char *ans, int anssiz, 1029 int *terrno, int ns, int *v_circuit, int *gotsomewhere) 1030{ 1031 const HEADER *hp = (const HEADER *)(const void *)buf; 1032 HEADER *anhp = (HEADER *)(void *)ans; 1033 const struct sockaddr *nsap; 1034 int nsaplen; 1035 struct timespec now, timeout, finish; 1036 fd_set dsmask; 1037 struct sockaddr_storage from; 1038 socklen_t fromlen; 1039 int resplen, seconds, n, s; 1040 1041 nsap = get_nsaddr(statp, (size_t)ns); 1042 nsaplen = get_salen(nsap); 1043 if (EXT(statp).nssocks[ns] == -1) { 1044 EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); 1045 if (EXT(statp).nssocks[ns] > highestFD) { 1046 res_nclose(statp); 1047 errno = ENOTSOCK; 1048 } 1049 if (EXT(statp).nssocks[ns] < 0) { 1050 switch (errno) { 1051 case EPROTONOSUPPORT: 1052#ifdef EPFNOSUPPORT 1053 case EPFNOSUPPORT: 1054#endif 1055 case EAFNOSUPPORT: 1056 Perror(statp, stderr, "socket(dg)", errno); 1057 return (0); 1058 default: 1059 *terrno = errno; 1060 Perror(statp, stderr, "socket(dg)", errno); 1061 return (-1); 1062 } 1063 } 1064#ifndef CANNOT_CONNECT_DGRAM 1065 /* 1066 * On a 4.3BSD+ machine (client and server, 1067 * actually), sending to a nameserver datagram 1068 * port with no nameserver will cause an 1069 * ICMP port unreachable message to be returned. 1070 * If our datagram socket is "connected" to the 1071 * server, we get an ECONNREFUSED error on the next 1072 * socket operation, and select returns if the 1073 * error message is received. We can thus detect 1074 * the absence of a nameserver without timing out. 1075 */ 1076 if (random_bind(EXT(statp).nssocks[ns], nsap->sa_family) < 0) { 1077 Aerror(statp, stderr, "bind(dg)", errno, nsap, 1078 nsaplen); 1079 res_nclose(statp); 1080 return (0); 1081 } 1082 if (connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) { 1083 Aerror(statp, stderr, "connect(dg)", errno, nsap, 1084 nsaplen); 1085 res_nclose(statp); 1086 return (0); 1087 } 1088#endif /* !CANNOT_CONNECT_DGRAM */ 1089 Dprint(statp->options & RES_DEBUG, 1090 (stdout, ";; new DG socket\n")) 1091 } 1092 s = EXT(statp).nssocks[ns]; 1093#ifndef CANNOT_CONNECT_DGRAM 1094 if (send(s, (const char*)buf, (size_t)buflen, 0) != buflen) { 1095 Perror(statp, stderr, "send", errno); 1096 res_nclose(statp); 1097 return (0); 1098 } 1099#else /* !CANNOT_CONNECT_DGRAM */ 1100 if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) 1101 { 1102 Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); 1103 res_nclose(statp); 1104 return (0); 1105 } 1106#endif /* !CANNOT_CONNECT_DGRAM */ 1107 1108 /* 1109 * Wait for reply. 1110 */ 1111 seconds = get_timeout(statp, ns); 1112 now = evNowTime(); 1113 timeout = evConsTime((long)seconds, 0L); 1114 finish = evAddTime(now, timeout); 1115retry: 1116 n = retrying_select(s, &dsmask, NULL, &finish); 1117 1118 if (n == 0) { 1119 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); 1120 *gotsomewhere = 1; 1121 return (0); 1122 } 1123 if (n < 0) { 1124 Perror(statp, stderr, "select", errno); 1125 res_nclose(statp); 1126 return (0); 1127 } 1128 errno = 0; 1129 fromlen = sizeof(from); 1130 resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0, 1131 (struct sockaddr *)(void *)&from, &fromlen); 1132 if (resplen <= 0) { 1133 Perror(statp, stderr, "recvfrom", errno); 1134 res_nclose(statp); 1135 return (0); 1136 } 1137 *gotsomewhere = 1; 1138 if (resplen < HFIXEDSZ) { 1139 /* 1140 * Undersized message. 1141 */ 1142 Dprint(statp->options & RES_DEBUG, 1143 (stdout, ";; undersized: %d\n", 1144 resplen)); 1145 *terrno = EMSGSIZE; 1146 res_nclose(statp); 1147 return (0); 1148 } 1149 if (hp->id != anhp->id) { 1150 /* 1151 * response from old query, ignore it. 1152 * XXX - potential security hazard could 1153 * be detected here. 1154 */ 1155#ifdef ANDROID_CHANGES 1156 __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_OLD_RESPONSE); 1157#endif 1158 DprintQ((statp->options & RES_DEBUG) || 1159 (statp->pfcode & RES_PRF_REPLY), 1160 (stdout, ";; old answer:\n"), 1161 ans, (resplen > anssiz) ? anssiz : resplen); 1162 goto retry; 1163 } 1164 if (!(statp->options & RES_INSECURE1) && 1165 !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) { 1166 /* 1167 * response from wrong server? ignore it. 1168 * XXX - potential security hazard could 1169 * be detected here. 1170 */ 1171#ifdef ANDROID_CHANGES 1172 __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_SERVER); 1173#endif 1174 DprintQ((statp->options & RES_DEBUG) || 1175 (statp->pfcode & RES_PRF_REPLY), 1176 (stdout, ";; not our server:\n"), 1177 ans, (resplen > anssiz) ? anssiz : resplen); 1178 goto retry; 1179 } 1180#ifdef RES_USE_EDNS0 1181 if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) { 1182 /* 1183 * Do not retry if the server do not understand EDNS0. 1184 * The case has to be captured here, as FORMERR packet do not 1185 * carry query section, hence res_queriesmatch() returns 0. 1186 */ 1187 DprintQ(statp->options & RES_DEBUG, 1188 (stdout, "server rejected query with EDNS0:\n"), 1189 ans, (resplen > anssiz) ? anssiz : resplen); 1190 /* record the error */ 1191 statp->_flags |= RES_F_EDNS0ERR; 1192 res_nclose(statp); 1193 return (0); 1194 } 1195#endif 1196 if (!(statp->options & RES_INSECURE2) && 1197 !res_queriesmatch(buf, buf + buflen, 1198 ans, ans + anssiz)) { 1199 /* 1200 * response contains wrong query? ignore it. 1201 * XXX - potential security hazard could 1202 * be detected here. 1203 */ 1204#ifdef ANDROID_CHANGES 1205 __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_QUERY); 1206#endif 1207 DprintQ((statp->options & RES_DEBUG) || 1208 (statp->pfcode & RES_PRF_REPLY), 1209 (stdout, ";; wrong query name:\n"), 1210 ans, (resplen > anssiz) ? anssiz : resplen); 1211 goto retry;; 1212 } 1213 if (anhp->rcode == SERVFAIL || 1214 anhp->rcode == NOTIMP || 1215 anhp->rcode == REFUSED) { 1216 DprintQ(statp->options & RES_DEBUG, 1217 (stdout, "server rejected query:\n"), 1218 ans, (resplen > anssiz) ? anssiz : resplen); 1219 res_nclose(statp); 1220 /* don't retry if called from dig */ 1221 if (!statp->pfcode) 1222 return (0); 1223 } 1224 if (!(statp->options & RES_IGNTC) && anhp->tc) { 1225 /* 1226 * To get the rest of answer, 1227 * use TCP with same server. 1228 */ 1229 Dprint(statp->options & RES_DEBUG, 1230 (stdout, ";; truncated answer\n")); 1231 *v_circuit = 1; 1232 res_nclose(statp); 1233 return (1); 1234 } 1235 /* 1236 * All is well, or the error is fatal. Signal that the 1237 * next nameserver ought not be tried. 1238 */ 1239 return (resplen); 1240} 1241 1242static void 1243Aerror(const res_state statp, FILE *file, const char *string, int error, 1244 const struct sockaddr *address, int alen) 1245{ 1246 int save = errno; 1247 char hbuf[NI_MAXHOST]; 1248 char sbuf[NI_MAXSERV]; 1249 1250 alen = alen; 1251 1252 if ((statp->options & RES_DEBUG) != 0U) { 1253 if (getnameinfo(address, (socklen_t)alen, hbuf, sizeof(hbuf), 1254 sbuf, sizeof(sbuf), niflags)) { 1255 strncpy(hbuf, "?", sizeof(hbuf) - 1); 1256 hbuf[sizeof(hbuf) - 1] = '\0'; 1257 strncpy(sbuf, "?", sizeof(sbuf) - 1); 1258 sbuf[sizeof(sbuf) - 1] = '\0'; 1259 } 1260 fprintf(file, "res_send: %s ([%s].%s): %s\n", 1261 string, hbuf, sbuf, strerror(error)); 1262 } 1263 errno = save; 1264} 1265 1266static void 1267Perror(const res_state statp, FILE *file, const char *string, int error) { 1268 int save = errno; 1269 1270 if ((statp->options & RES_DEBUG) != 0U) 1271 fprintf(file, "res_send: %s: %s\n", 1272 string, strerror(error)); 1273 errno = save; 1274} 1275 1276static int 1277sock_eq(struct sockaddr *a, struct sockaddr *b) { 1278 struct sockaddr_in *a4, *b4; 1279 struct sockaddr_in6 *a6, *b6; 1280 1281 if (a->sa_family != b->sa_family) 1282 return 0; 1283 switch (a->sa_family) { 1284 case AF_INET: 1285 a4 = (struct sockaddr_in *)(void *)a; 1286 b4 = (struct sockaddr_in *)(void *)b; 1287 return a4->sin_port == b4->sin_port && 1288 a4->sin_addr.s_addr == b4->sin_addr.s_addr; 1289 case AF_INET6: 1290 a6 = (struct sockaddr_in6 *)(void *)a; 1291 b6 = (struct sockaddr_in6 *)(void *)b; 1292 return a6->sin6_port == b6->sin6_port && 1293#ifdef HAVE_SIN6_SCOPE_ID 1294 a6->sin6_scope_id == b6->sin6_scope_id && 1295#endif 1296 IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); 1297 default: 1298 return 0; 1299 } 1300} 1301 1302#ifdef NEED_PSELECT 1303/* XXX needs to move to the porting library. */ 1304static int 1305pselect(int nfds, void *rfds, void *wfds, void *efds, 1306 struct timespec *tsp, const sigset_t *sigmask) 1307{ 1308 struct timeval tv, *tvp; 1309 sigset_t sigs; 1310 int n; 1311 1312 if (tsp) { 1313 tvp = &tv; 1314 tv = evTimeVal(*tsp); 1315 } else 1316 tvp = NULL; 1317 if (sigmask) 1318 sigprocmask(SIG_SETMASK, sigmask, &sigs); 1319 n = select(nfds, rfds, wfds, efds, tvp); 1320 if (sigmask) 1321 sigprocmask(SIG_SETMASK, &sigs, NULL); 1322 if (tsp) 1323 *tsp = evTimeSpec(tv); 1324 return (n); 1325} 1326#endif 1327