11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $ */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright 2008 Android Open Source Project (source port randomization) 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1985, 1989, 1993 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The Regents of the University of California. All rights reserved. 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation and/or other materials provided with the distribution. 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. All advertising materials mentioning features or use of this software 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * must display the following acknowledgement: 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This product includes software developed by the University of 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * California, Berkeley and its contributors. 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 4. Neither the name of the University nor the names of its contributors 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * may be used to endorse or promote products derived from this software 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * without specific prior written permission. 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1993 by Digital Equipment Corporation. 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies, and that 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the name of Digital Equipment Corporation not be used in advertising or 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * publicity pertaining to distribution of the document or software without 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * specific, written prior permission. 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SOFTWARE. 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1996-1999 by Internet Software Consortium. 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies. 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h> 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(LIBC_SCCS) && !defined(lint) 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef notdef 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char rcsid[] = "Id: res_send.c,v 1.5.2.2.4.5 2004/08/10 02:19:56 marka Exp"; 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $"); 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* LIBC_SCCS and not lint */ 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* set to 1 to use our small/simple/limited DNS cache */ 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define USE_RESOLV_CACHE 1 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send query to name server and wait for reply. 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h> 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h> 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/time.h> 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/socket.h> 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/uio.h> 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netinet/in.h> 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "arpa_nameser.h" 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <arpa/inet.h> 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h> 102ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#include <fcntl.h> 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netdb.h> 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h" 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <resolv.h> 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <signal.h> 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 113ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#include <time.h> 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h> 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <isc/eventlib.h> 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# include <resolv_cache.h> 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 122ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#include "logd.h" 123ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DE_CONST 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DE_CONST(c,v) v = ((c) ? \ 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL) 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Options. Leave them on. */ 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DEBUG 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DEBUG 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "res_debug.h" 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "res_private.h" 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define EXT(res) ((res)->_u._ext) 137ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#define DBG 0 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const int highestFD = FD_SETSIZE - 1; 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Forward. */ 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int get_salen __P((const struct sockaddr *)); 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct sockaddr * get_nsaddr __P((res_state, size_t)); 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int send_vc(res_state, const u_char *, int, 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *, int, int *, int); 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int send_dg(res_state, const u_char *, int, 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *, int, int *, int, 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *, int *); 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void Aerror(const res_state, FILE *, const char *, int, 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *, int); 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void Perror(const res_state, FILE *, const char *, int); 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int sock_eq(struct sockaddr *, struct sockaddr *); 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef NEED_PSELECT 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int pselect(int, void *, void *, void *, 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec *, 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const sigset_t *); 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid res_pquery(const res_state, const u_char *, int, FILE *); 160ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int connect_with_timeout(int sock, const struct sockaddr *nsap, 161ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt socklen_t salen, int sec); 162ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int retrying_select(const int sock, fd_set *readset, fd_set *writeset, 163ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt const struct timespec *finish); 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC-BEGIN: implement source port randomization */ 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union { 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr sa; 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in sin; 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in6 sin6; 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} _sockaddr_union; 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrandom_bind( int s, int family ) 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _sockaddr_union u; 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int j; 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t slen; 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* clear all, this also sets the IP4/6 address to 'any' */ 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset( &u, 0, sizeof u ); 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (family) { 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_family = family; 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project slen = sizeof u.sin; 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_family = family; 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project slen = sizeof u.sin6; 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EPROTO; 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return -1; 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* first try to bind to a random source port a few times */ 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (j = 0; j < 10; j++) { 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* find a random port between 1025 .. 65534 */ 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int port = 1025 + (res_randomid() % (65535-1025)); 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (family == AF_INET) 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_port = htons(port); 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_port = htons(port); 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( !bind( s, &u.sa, slen ) ) 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* nothing after 10 tries, our network table is probably busy */ 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* let the system decide which port is best */ 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (family == AF_INET) 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_port = 0; 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_port = 0; 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return bind( s, &u.sa, slen ); 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC-END */ 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public. */ 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_isourserver(ina) 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * looks up "ina" in _res.ns_addr_list[] 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not found 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : found 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2337cc5666d94615d9249163dc7ac0f58c2614497ceJim Huang__LIBC_HIDDEN__ int 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_ourserver_p(const res_state statp, const struct sockaddr *sa) { 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr_in *inp, *srv; 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr_in6 *in6p, *srv6; 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ns; 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (sa->sa_family) { 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project inp = (const struct sockaddr_in *)(const void *)sa; 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns); 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srv->sin_family == inp->sin_family && 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv->sin_port == inp->sin_port && 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (srv->sin_addr.s_addr == INADDR_ANY || 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv->sin_addr.s_addr == inp->sin_addr.s_addr)) 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext == NULL) 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project in6p = (const struct sockaddr_in6 *)(const void *)sa; 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns); 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srv6->sin6_family == in6p->sin6_family && 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6->sin6_port == in6p->sin6_port && 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SIN6_SCOPE_ID 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (srv6->sin6_scope_id == 0 || 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6->sin6_scope_id == in6p->sin6_scope_id) && 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_nameinquery(name, type, class, buf, eom) 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * look for (name,type,class) in the query section of packet (buf,eom) 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * requires: 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * buf + HFIXEDSZ <= eom 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -1 : format error 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not found 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : found 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nameinquery(const char *name, int type, int class, 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, const u_char *eom) 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *cp = buf + HFIXEDSZ; 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount); 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (qdcount-- > 0) { 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char tname[MAXDNAME+1]; 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, ttype, tclass; 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = dn_expand(buf, eom, cp, tname, sizeof tname); 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp + 2 * INT16SZ > eom) 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ttype = ns_get16(cp); cp += INT16SZ; 3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tclass = ns_get16(cp); cp += INT16SZ; 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ttype == type && tclass == class && 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns_samename(tname, name) == 1) 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_queriesmatch(buf1, eom1, buf2, eom2) 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is there a 1:1 mapping of (name,type,class) 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * in (buf1,eom1) and (buf2,eom2)? 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -1 : format error 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not a 1:1 mapping 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : is a 1:1 mapping 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_queriesmatch(const u_char *buf1, const u_char *eom1, 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf2, const u_char *eom2) 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *cp = buf1 + HFIXEDSZ; 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount); 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Only header section present in replies to 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * dynamic update packets. 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) && 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (((const HEADER *)(const void *)buf2)->opcode == ns_o_update)) 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount)) 3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (qdcount-- > 0) { 3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char tname[MAXDNAME+1]; 3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, ttype, tclass; 3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = dn_expand(buf1, eom1, cp, tname, sizeof tname); 3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp + 2 * INT16SZ > eom1) 3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ttype = ns_get16(cp); cp += INT16SZ; 3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tclass = ns_get16(cp); cp += INT16SZ; 3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) 3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nsend(res_state statp, 3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz) 3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; 3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char abuf[NI_MAXHOST]; 3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct resolv_cache* cache; 3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED; 3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->nscount == 0) { 3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ESRCH; 3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anssiz < HFIXEDSZ) { 3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EINVAL; 3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), 3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; res_send()\n"), buf, buflen); 3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; 3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project gotsomewhere = 0; 3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project terrno = ETIMEDOUT; 3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cache = __get_res_cache(); 3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cache != NULL) { 3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int anslen = 0; 3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cache_status = _resolv_cache_lookup( 3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cache, buf, buflen, 3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &anslen); 3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cache_status == RESOLV_CACHE_FOUND) { 3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return anslen; 3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the ns_addr_list in the resolver context has changed, then 4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * invalidate our cached copy and the associated timing data. 4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount != 0) { 4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int needclose = 0; 4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage peer; 4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t peerlen; 4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount != statp->nscount) 4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->nsaddr_list[ns].sin_family && 4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns], 4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) { 4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] == -1) 4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project peerlen = sizeof(peer); 42487043f9c89593125a27199d0c1b4069d088672d7Jim Huang if (getpeername(EXT(statp).nssocks[ns], 4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&peer, &peerlen) < 0) { 4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!sock_eq((struct sockaddr *)(void *)&peer, 4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project get_nsaddr(statp, (size_t)ns))) { 4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (needclose) { 4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nscount = 0; 4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Maybe initialize our private copy of the ns_addr_list. 4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount == 0) { 4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[ns] = RES_MAXTIME; 4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = -1; 4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->nsaddr_list[ns].sin_family) 4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns].sin = 4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[ns]; 4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nscount = statp->nscount; 4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Some resolvers want to even out the load on their nameservers. 4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note that RES_BLAST overrides RES_ROTATE. 4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_ROTATE) != 0U && 4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->options & RES_BLAST) == 0U) { 4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project union res_sockaddr_union inu; 4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in ina; 4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int lastns = statp->nscount - 1; 4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int fd; 4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_int16_t nstime; 4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project inu = EXT(statp).ext->nsaddrs[0]; 4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ina = statp->nsaddr_list[0]; 4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fd = EXT(statp).nssocks[0]; 4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nstime = EXT(statp).nstimes[0]; 4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < lastns; ns++) { 4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns] = 4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns + 1]; 4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; 4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; 4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; 4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[lastns] = inu; 4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[lastns] = ina; 4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[lastns] = fd; 4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[lastns] = nstime; 4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send request, RETRY times, or until successful. 4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (try = 0; try < statp->retry; try++) { 4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr *nsap; 4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags &= ~RES_F_LASTMASK; 4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= (ns << RES_F_LASTSHIFT); 4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project same_ns: 5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->qhook) { 5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int done = 0, loops = 0; 5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_sendhookact act; 5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project act = (*statp->qhook)(&nsap, &buf, &buflen, 5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &resplen); 5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (act) { 5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_goahead: 5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project done = 1; 5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_nextns: 5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_done: 5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_modified: 5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* give the hook another try */ 5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++loops < 42) /*doug adams*/ 5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_error: 5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (!done); 5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(((statp->options & RES_DEBUG) && 5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), 532ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt NULL, 0, niflags) == 0), 533ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt (stdout, ";; Querying server (# %d) address = %s\n", 534ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt ns + 1, abuf)); 5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (v_circuit) { 5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Use VC; at most one attempt per server. */ 5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project try = statp->retry; 540ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, 5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns); 543ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 544ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 545ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 546ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "used send_vc %d\n", n); 547ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 548ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 5531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = n; 5541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 5551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Use datagrams. */ 556ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 557ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 558ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "using send_dg\n"); 559ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 560ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, 5621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns, &v_circuit, &gotsomewhere); 563ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 564ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 565ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "used send_dg %d\n",n); 566ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 567ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 572ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 573ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 574ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "time=%d, %d\n",time(NULL), time(NULL)%2); 575ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (v_circuit) 5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto same_ns; 5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = n; 5791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint((statp->options & RES_DEBUG) || 5821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((statp->pfcode & RES_PRF_REPLY) && 5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_HEAD1)), 5841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; got answer:\n")); 5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 5881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "%s", ""), 5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cache_status == RESOLV_CACHE_NOTFOUND) { 5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _resolv_cache_add(cache, buf, buflen, 5941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, resplen); 5951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If we have temporarily opened a virtual circuit, 5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * or if we haven't been asked to keep a socket open, 6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * close the socket. 6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((v_circuit && (statp->options & RES_USEVC) == 0U) || 6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->options & RES_STAYOPEN) == 0U) { 6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->rhook) { 6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int done = 0, loops = 0; 6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_sendhookact act; 6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project act = (*statp->rhook)(nsap, buf, buflen, 6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &resplen); 6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (act) { 6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_goahead: 6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_done: 6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project done = 1; 6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_nextns: 6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_modified: 6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* give the hook another try */ 6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++loops < 42) /*doug adams*/ 6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_error: 6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (!done); 6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project next_ns: ; 6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } /*foreach ns*/ 6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } /*foreach retry*/ 6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!v_circuit) { 6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!gotsomewhere) 6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ECONNREFUSED; /* no nameservers found */ 6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ETIMEDOUT; /* no answer obtained */ 6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = terrno; 647ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström 648ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström#if USE_RESOLV_CACHE 649ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström _resolv_cache_query_failed(cache, buf, buflen); 650ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström#endif 651ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström 6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fail: 654a59cfcfd0821f51ee77f13105099f700ccbf9252Mattias Falk#if USE_RESOLV_CACHE 655a59cfcfd0821f51ee77f13105099f700ccbf9252Mattias Falk _resolv_cache_query_failed(cache, buf, buflen); 656a59cfcfd0821f51ee77f13105099f700ccbf9252Mattias Falk#endif 6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private */ 6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectget_salen(sa) 6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *sa; 6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SA_LEN 6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* There are people do not set sa_len. Be forgiving to them. */ 6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sa->sa_len) 6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sa->sa_len); 6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sa->sa_family == AF_INET) 6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sizeof(struct sockaddr_in)); 6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (sa->sa_family == AF_INET6) 6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sizeof(struct sockaddr_in6)); 6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); /* unknown, die on connect */ 6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * pick appropriate nsaddr_list for use. see res_init() for initialization. 6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct sockaddr * 6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectget_nsaddr(statp, n) 6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_state statp; 6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t n; 6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { 6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - EXT(statp).ext->nsaddrs[n] holds an address that is larger 6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * than struct sockaddr, and 6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - user code did not update statp->nsaddr_list[n]. 6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; 6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - user code updated statp->nsaddr_list[n], or 7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - statp->nsaddr_list[n] has the same content as 7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * EXT(statp).ext->nsaddrs[n]. 7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; 7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 708ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int get_timeout(const res_state statp, const int ns) 709ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 710ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int timeout = (statp->retrans << ns); 711ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (ns > 0) { 712ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout /= statp->nscount; 713ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 714ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (timeout <= 0) { 715ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = 1; 716ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 717ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 718ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 719ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "using timeout of %d sec\n", timeout); 720ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 721ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 722ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return timeout; 723ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 724ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsend_vc(res_state statp, 7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz, 7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *terrno, int ns) 7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const HEADER *hp = (const HEADER *)(const void *)buf; 7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project HEADER *anhp = (HEADER *)(void *)ans; 7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr *nsap; 7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int truncating, connreset, resplen, n; 7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct iovec iov[2]; 7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_short len; 7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *cp; 7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project void *tmp; 7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 740ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 741ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); 742ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 743ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 7461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project connreset = 0; 7481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project same_ns: 7491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project truncating = 0; 7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Are we still talking to whom we want to talk to? */ 7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { 7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage peer; 7541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t size = sizeof peer; 7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (getpeername(statp->_vcsock, 7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&peer, &size) < 0 || 7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !sock_eq((struct sockaddr *)(void *)&peer, nsap)) { 7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags &= ~RES_F_VC; 7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { 7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock >= 0) 7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); 7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock > highestFD) { 7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOTSOCK; 7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock < 0) { 7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (errno) { 7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPROTONOSUPPORT: 7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef EPFNOSUPPORT 7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPFNOSUPPORT: 7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 7791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EAFNOSUPPORT: 7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(vc)", errno); 7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 7841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(vc)", errno); 7851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (random_bind(statp->_vcsock,nsap->sa_family) < 0) { 7901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "bind/vc", errno, nsap, 7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 796ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t)nsaplen, 797ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt get_timeout(statp, ns)) < 0) { 7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "connect/vc", errno, nsap, 8001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 8011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= RES_F_VC; 8051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send length & message 8091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns_put16((u_short)buflen, (u_char*)(void *)&len); 8111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[0] = evConsIovec(&len, INT16SZ); 8121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DE_CONST(buf, tmp); 8131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[1] = evConsIovec(tmp, (size_t)buflen); 8141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { 8151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "write failed", errno); 8171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Receive length & response 8221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project read_len: 8241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = ans; 8251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = INT16SZ; 8261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) { 8271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 8281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((len -= n) == 0) 8291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 8301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) { 8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "read failed", errno); 8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * A long running process might get its TCP 8371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * connection reset if the remote server was 8381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * restarted. Requery the server instead of 8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * trying a new one. When there is only one 8401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * server, this means that a query might work 8411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * instead of failing. We only allow one reset 8421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * per query to prevent looping. 8431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*terrno == ECONNRESET && !connreset) { 8451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project connreset = 1; 8461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto same_ns; 8481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = ns_get16(ans); 8531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen > anssiz) { 8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; response truncated\n") 8561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ); 8571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project truncating = 1; 8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = anssiz; 8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 8601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = resplen; 8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (len < HFIXEDSZ) { 8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Undersized message. 8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 8661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; undersized: %d\n", len)); 8671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = EMSGSIZE; 8681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = ans; 8721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){ 8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len -= n; 8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) { 8771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "read(vc)", errno); 8791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (truncating) { 8831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flush rest of answer so connection stays in synch. 8851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->tc = 1; 8871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = resplen - anssiz; 8881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (len != 0) { 8891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char junk[PACKETSZ]; 8901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = read(statp->_vcsock, junk, 8921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (len > sizeof junk) ? sizeof junk : len); 8931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n > 0) 8941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len -= n; 8951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 8961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 8971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the calling applicating has bailed out of 9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * a previous call and failed to arrange to have 9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the circuit closed or the server has got 9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * itself confused, then drop the packet and 9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * wait for the correct one. 9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (hp->id != anhp->id) { 9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 9081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; old answer (unexpected):\n"), 9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz: resplen); 9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto read_len; 9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All is well, or the error is fatal. Signal that the 9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * next nameserver ought not be tried. 9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 9201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 921ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt/* return -1 on error (errno set), 0 on success */ 922ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int 923ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltconnect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int sec) 924ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 925ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int res, origflags; 926ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fd_set rset, wset; 927ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt struct timespec now, timeout, finish; 928ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 929ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt origflags = fcntl(sock, F_GETFL, 0); 930ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fcntl(sock, F_SETFL, origflags | O_NONBLOCK); 931ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 932ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = connect(sock, nsap, salen); 933ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res < 0 && errno != EINPROGRESS) { 934ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = -1; 935ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto done; 936ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 937ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res != 0) { 938ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt now = evNowTime(); 939ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evConsTime((long)sec, 0L); 940ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt finish = evAddTime(now, timeout); 941ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 942ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 943ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d send_vc\n", sock); 944ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 945ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 946ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = retrying_select(sock, &rset, &wset, &finish); 947ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res <= 0) { 948ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = -1; 949ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 950ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 951ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltdone: 952ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fcntl(sock, F_SETFL, origflags); 953ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 954ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 955ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d connect_with_timeout returning %s\n", sock, res); 956ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 957ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return res; 958ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 959ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 960ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int 961ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct timespec *finish) 962ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 963ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt struct timespec now, timeout; 964ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int n, error; 965ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt socklen_t len; 966ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 967ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 968ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretry: 969ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 970ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", " %d retying_select\n", sock); 971ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 972ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 973ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt now = evNowTime(); 974ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (readset) { 975ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_ZERO(readset); 976ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_SET(sock, readset); 977ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 978ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (writeset) { 979ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_ZERO(writeset); 980ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_SET(sock, writeset); 981ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 982ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (evCmpTime(*finish, now) > 0) 983ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evSubTime(*finish, now); 984ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt else 985ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evConsTime(0L, 0L); 986ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 987ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL); 988ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (n == 0) { 989ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 990ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, " libc", 991ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select timeout\n", sock); 992ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 993ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt errno = ETIMEDOUT; 994ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return 0; 995ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 996ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (n < 0) { 997ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (errno == EINTR) 998ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 999ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 1000ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 1001ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select got error %d\n",sock, n); 1002ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1003ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return n; 1004ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1005ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if ((readset && FD_ISSET(sock, readset)) || (writeset && FD_ISSET(sock, writeset))) { 1006ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt len = sizeof(error); 1007ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { 1008ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt errno = error; 1009ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 1010ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 1011ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select dot error2 %d\n", sock, errno); 1012ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1013ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1014ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return -1; 1015ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1016ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1017ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 1018ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", 1019ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select returning %d for %d\n",sock, n); 1020ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1021ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1022ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return n; 1023ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 1024ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1025ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 10261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 10271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsend_dg(res_state statp, 10281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz, 10291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *terrno, int ns, int *v_circuit, int *gotsomewhere) 10301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 10311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const HEADER *hp = (const HEADER *)(const void *)buf; 10321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project HEADER *anhp = (HEADER *)(void *)ans; 10331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *nsap; 10341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 10351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec now, timeout, finish; 10361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fd_set dsmask; 10371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage from; 10381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t fromlen; 10391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int resplen, seconds, n, s; 10401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 10411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 10421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 10431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] == -1) { 10441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); 10451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] > highestFD) { 10461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 10471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOTSOCK; 10481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] < 0) { 10501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (errno) { 10511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPROTONOSUPPORT: 10521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef EPFNOSUPPORT 10531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPFNOSUPPORT: 10541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 10551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EAFNOSUPPORT: 10561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(dg)", errno); 10571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 10581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 10591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 10601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(dg)", errno); 10611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 10621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CANNOT_CONNECT_DGRAM 10651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 10661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * On a 4.3BSD+ machine (client and server, 10671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * actually), sending to a nameserver datagram 10681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * port with no nameserver will cause an 10691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ICMP port unreachable message to be returned. 10701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If our datagram socket is "connected" to the 10711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * server, we get an ECONNREFUSED error on the next 10721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * socket operation, and select returns if the 10731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * error message is received. We can thus detect 10741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the absence of a nameserver without timing out. 10751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 10761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (random_bind(EXT(statp).nssocks[ns], nsap->sa_family) < 0) { 10771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "bind(dg)", errno, nsap, 10781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 10801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 10811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) { 10831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "connect(dg)", errno, nsap, 10841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 10851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 10861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 10871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !CANNOT_CONNECT_DGRAM */ 10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; new DG socket\n")) 10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project s = EXT(statp).nssocks[ns]; 10931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CANNOT_CONNECT_DGRAM 10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (send(s, (const char*)buf, (size_t)buflen, 0) != buflen) { 10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "send", errno); 10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 10971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !CANNOT_CONNECT_DGRAM */ 11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) 11011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); 11031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !CANNOT_CONNECT_DGRAM */ 11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Wait for reply. 11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1111ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt seconds = get_timeout(statp, ns); 11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project now = evNowTime(); 11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project timeout = evConsTime((long)seconds, 0L); 11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project finish = evAddTime(now, timeout); 1115ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretry: 1116ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt n = retrying_select(s, &dsmask, NULL, &finish); 1117ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) { 11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); 11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gotsomewhere = 1; 11211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) { 11241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "select", errno); 11251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fromlen = sizeof(from); 11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0, 11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&from, &fromlen); 11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen <= 0) { 11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "recvfrom", errno); 11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gotsomewhere = 1; 11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen < HFIXEDSZ) { 11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Undersized message. 11411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; undersized: %d\n", 11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen)); 11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = EMSGSIZE; 11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (hp->id != anhp->id) { 11501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response from old query, ignore it. 11521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 11531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1155524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1156524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_OLD_RESPONSE); 1157524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; old answer:\n"), 11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1162ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_INSECURE1) && 11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) { 11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response from wrong server? ignore it. 11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1171524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1172524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_SERVER); 1173524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 11751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; not our server:\n"), 11771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1178ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 11791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RES_USE_EDNS0 11811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) { 11821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Do not retry if the server do not understand EDNS0. 11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The case has to be captured here, as FORMERR packet do not 11851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * carry query section, hence res_queriesmatch() returns 0. 11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ(statp->options & RES_DEBUG, 11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "server rejected query with EDNS0:\n"), 11891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* record the error */ 11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= RES_F_EDNS0ERR; 11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 11961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_INSECURE2) && 11971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !res_queriesmatch(buf, buf + buflen, 11981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, ans + anssiz)) { 11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response contains wrong query? ignore it. 12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 12031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1204524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1205524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_QUERY); 1206524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; wrong query name:\n"), 12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1211ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry;; 12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anhp->rcode == SERVFAIL || 12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->rcode == NOTIMP || 12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->rcode == REFUSED) { 12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ(statp->options & RES_DEBUG, 12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "server rejected query:\n"), 12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* don't retry if called from dig */ 12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->pfcode) 12221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_IGNTC) && anhp->tc) { 12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * To get the rest of answer, 12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * use TCP with same server. 12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 12301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; truncated answer\n")); 12311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *v_circuit = 1; 12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All is well, or the error is fatal. Signal that the 12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * next nameserver ought not be tried. 12381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 12401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectAerror(const res_state statp, FILE *file, const char *string, int error, 12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *address, int alen) 12451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 12461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save = errno; 12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char hbuf[NI_MAXHOST]; 12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char sbuf[NI_MAXSERV]; 12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project alen = alen; 12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_DEBUG) != 0U) { 12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (getnameinfo(address, (socklen_t)alen, hbuf, sizeof(hbuf), 12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sbuf, sizeof(sbuf), niflags)) { 12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strncpy(hbuf, "?", sizeof(hbuf) - 1); 12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project hbuf[sizeof(hbuf) - 1] = '\0'; 12571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strncpy(sbuf, "?", sizeof(sbuf) - 1); 12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sbuf[sizeof(sbuf) - 1] = '\0'; 12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fprintf(file, "res_send: %s ([%s].%s): %s\n", 12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project string, hbuf, sbuf, strerror(error)); 12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save; 12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectPerror(const res_state statp, FILE *file, const char *string, int error) { 12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save = errno; 12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_DEBUG) != 0U) 12711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fprintf(file, "res_send: %s: %s\n", 12721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project string, strerror(error)); 12731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save; 12741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsock_eq(struct sockaddr *a, struct sockaddr *b) { 12781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in *a4, *b4; 12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in6 *a6, *b6; 12801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (a->sa_family != b->sa_family) 12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (a->sa_family) { 12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a4 = (struct sockaddr_in *)(void *)a; 12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b4 = (struct sockaddr_in *)(void *)b; 12871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return a4->sin_port == b4->sin_port && 12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a4->sin_addr.s_addr == b4->sin_addr.s_addr; 12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 12901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a6 = (struct sockaddr_in6 *)(void *)a; 12911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b6 = (struct sockaddr_in6 *)(void *)b; 12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return a6->sin6_port == b6->sin6_port && 12931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SIN6_SCOPE_ID 12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a6->sin6_scope_id == b6->sin6_scope_id && 12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); 12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 13001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef NEED_PSELECT 13031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* XXX needs to move to the porting library. */ 13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpselect(int nfds, void *rfds, void *wfds, void *efds, 13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec *tsp, const sigset_t *sigmask) 13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timeval tv, *tvp; 13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigset_t sigs; 13101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; 13111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tsp) { 13131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tvp = &tv; 13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tv = evTimeVal(*tsp); 13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tvp = NULL; 13171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sigmask) 13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigprocmask(SIG_SETMASK, sigmask, &sigs); 13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = select(nfds, rfds, wfds, efds, tvp); 13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sigmask) 13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigprocmask(SIG_SETMASK, &sigs, NULL); 13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tsp) 13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *tsp = evTimeSpec(tv); 13241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (n); 13251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1327