res_send.c revision 41d9a503716ed6f3291f4cae097dca08d459429c
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> 98569fb9887d00104509df79fa77d92e3cf9afe7dbCalin Juravle#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 105ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak#include "resolv_netid.h" 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h" 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <resolv.h> 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <signal.h> 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 114ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#include <time.h> 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h> 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <isc/eventlib.h> 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# include <resolv_cache.h> 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 123eb847bc8666842a3cfc9c06e8458ad1abebebaf0Elliott Hughes#include "private/libc_logging.h" 124ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DE_CONST 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DE_CONST(c,v) v = ((c) ? \ 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL) 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Options. Leave them on. */ 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DEBUG 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DEBUG 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "res_debug.h" 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "res_private.h" 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define EXT(res) ((res)->_u._ext) 138ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#define DBG 0 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const int highestFD = FD_SETSIZE - 1; 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Forward. */ 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int get_salen __P((const struct sockaddr *)); 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct sockaddr * get_nsaddr __P((res_state, size_t)); 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int send_vc(res_state, const u_char *, int, 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *, int, int *, int); 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int send_dg(res_state, const u_char *, int, 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *, int, int *, int, 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *, int *); 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void Aerror(const res_state, FILE *, const char *, int, 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *, int); 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void Perror(const res_state, FILE *, const char *, int); 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int sock_eq(struct sockaddr *, struct sockaddr *); 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef NEED_PSELECT 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int pselect(int, void *, void *, void *, 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec *, 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const sigset_t *); 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid res_pquery(const res_state, const u_char *, int, FILE *); 161ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int connect_with_timeout(int sock, const struct sockaddr *nsap, 162ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt socklen_t salen, int sec); 163ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int retrying_select(const int sock, fd_set *readset, fd_set *writeset, 164ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt const struct timespec *finish); 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC-BEGIN: implement source port randomization */ 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union { 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr sa; 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in sin; 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in6 sin6; 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} _sockaddr_union; 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrandom_bind( int s, int family ) 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _sockaddr_union u; 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int j; 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t slen; 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* clear all, this also sets the IP4/6 address to 'any' */ 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset( &u, 0, sizeof u ); 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (family) { 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_family = family; 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project slen = sizeof u.sin; 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_family = family; 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project slen = sizeof u.sin6; 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EPROTO; 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return -1; 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* first try to bind to a random source port a few times */ 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (j = 0; j < 10; j++) { 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* find a random port between 1025 .. 65534 */ 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int port = 1025 + (res_randomid() % (65535-1025)); 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (family == AF_INET) 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_port = htons(port); 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_port = htons(port); 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( !bind( s, &u.sa, slen ) ) 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* nothing after 10 tries, our network table is probably busy */ 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* let the system decide which port is best */ 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (family == AF_INET) 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_port = 0; 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_port = 0; 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return bind( s, &u.sa, slen ); 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC-END */ 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public. */ 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_isourserver(ina) 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * looks up "ina" in _res.ns_addr_list[] 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not found 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : found 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2347cc5666d94615d9249163dc7ac0f58c2614497ceJim Huang__LIBC_HIDDEN__ int 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_ourserver_p(const res_state statp, const struct sockaddr *sa) { 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr_in *inp, *srv; 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr_in6 *in6p, *srv6; 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ns; 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (sa->sa_family) { 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project inp = (const struct sockaddr_in *)(const void *)sa; 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns); 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srv->sin_family == inp->sin_family && 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv->sin_port == inp->sin_port && 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (srv->sin_addr.s_addr == INADDR_ANY || 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv->sin_addr.s_addr == inp->sin_addr.s_addr)) 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext == NULL) 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project in6p = (const struct sockaddr_in6 *)(const void *)sa; 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns); 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srv6->sin6_family == in6p->sin6_family && 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6->sin6_port == in6p->sin6_port && 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SIN6_SCOPE_ID 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (srv6->sin6_scope_id == 0 || 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6->sin6_scope_id == in6p->sin6_scope_id) && 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_nameinquery(name, type, class, buf, eom) 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * look for (name,type,class) in the query section of packet (buf,eom) 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * requires: 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * buf + HFIXEDSZ <= eom 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -1 : format error 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not found 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : found 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nameinquery(const char *name, int type, int class, 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, const u_char *eom) 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *cp = buf + HFIXEDSZ; 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount); 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (qdcount-- > 0) { 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char tname[MAXDNAME+1]; 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, ttype, tclass; 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = dn_expand(buf, eom, cp, tname, sizeof tname); 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp + 2 * INT16SZ > eom) 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ttype = ns_get16(cp); cp += INT16SZ; 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tclass = ns_get16(cp); cp += INT16SZ; 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ttype == type && tclass == class && 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns_samename(tname, name) == 1) 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_queriesmatch(buf1, eom1, buf2, eom2) 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is there a 1:1 mapping of (name,type,class) 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * in (buf1,eom1) and (buf2,eom2)? 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -1 : format error 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not a 1:1 mapping 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : is a 1:1 mapping 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_queriesmatch(const u_char *buf1, const u_char *eom1, 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf2, const u_char *eom2) 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *cp = buf1 + HFIXEDSZ; 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount); 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Only header section present in replies to 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * dynamic update packets. 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) && 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (((const HEADER *)(const void *)buf2)->opcode == ns_o_update)) 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount)) 3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (qdcount-- > 0) { 3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char tname[MAXDNAME+1]; 3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, ttype, tclass; 3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = dn_expand(buf1, eom1, cp, tname, sizeof tname); 3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp + 2 * INT16SZ > eom1) 3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ttype = ns_get16(cp); cp += INT16SZ; 3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tclass = ns_get16(cp); cp += INT16SZ; 3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) 3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nsend(res_state statp, 3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz) 3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; 3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char abuf[NI_MAXHOST]; 3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED; 3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 373c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk#if !USE_RESOLV_CACHE 3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->nscount == 0) { 3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ESRCH; 3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 378c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk#endif 379c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk 3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anssiz < HFIXEDSZ) { 3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EINVAL; 3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), 3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; res_send()\n"), buf, buflen); 3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; 3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project gotsomewhere = 0; 3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project terrno = ETIMEDOUT; 3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 39141d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen int anslen = 0; 39241d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen cache_status = _resolv_cache_lookup( 39341d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen statp->netid, buf, buflen, 39441d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen ans, anssiz, &anslen); 39541d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen 39641d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen if (cache_status == RESOLV_CACHE_FOUND) { 39741d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen return anslen; 39841d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen } else if (cache_status != RESOLV_CACHE_UNSUPPORTED) { 39941d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen // had a cache miss for a known network, so populate the thread private 40041d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen // data so the normal resolve path can do its thing 40141d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen _resolv_populate_res_for_net(statp); 402c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk } 403c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk 404c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk if (statp->nscount == 0) { 405c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk errno = ESRCH; 406c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk return (-1); 407c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk } 4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the ns_addr_list in the resolver context has changed, then 4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * invalidate our cached copy and the associated timing data. 4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount != 0) { 4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int needclose = 0; 4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage peer; 4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t peerlen; 4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount != statp->nscount) 4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->nsaddr_list[ns].sin_family && 4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns], 4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) { 4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] == -1) 4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project peerlen = sizeof(peer); 43387043f9c89593125a27199d0c1b4069d088672d7Jim Huang if (getpeername(EXT(statp).nssocks[ns], 4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&peer, &peerlen) < 0) { 4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!sock_eq((struct sockaddr *)(void *)&peer, 4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project get_nsaddr(statp, (size_t)ns))) { 4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (needclose) { 4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nscount = 0; 4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Maybe initialize our private copy of the ns_addr_list. 4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount == 0) { 4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[ns] = RES_MAXTIME; 4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = -1; 4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->nsaddr_list[ns].sin_family) 4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns].sin = 4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[ns]; 4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nscount = statp->nscount; 4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Some resolvers want to even out the load on their nameservers. 4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note that RES_BLAST overrides RES_ROTATE. 4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_ROTATE) != 0U && 4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->options & RES_BLAST) == 0U) { 4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project union res_sockaddr_union inu; 4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in ina; 4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int lastns = statp->nscount - 1; 4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int fd; 4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_int16_t nstime; 4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project inu = EXT(statp).ext->nsaddrs[0]; 4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ina = statp->nsaddr_list[0]; 4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fd = EXT(statp).nssocks[0]; 4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nstime = EXT(statp).nstimes[0]; 4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < lastns; ns++) { 4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns] = 4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns + 1]; 4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; 4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; 4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; 4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[lastns] = inu; 4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[lastns] = ina; 4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[lastns] = fd; 4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[lastns] = nstime; 4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send request, RETRY times, or until successful. 4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (try = 0; try < statp->retry; try++) { 5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr *nsap; 5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags &= ~RES_F_LASTMASK; 5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= (ns << RES_F_LASTSHIFT); 5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project same_ns: 5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->qhook) { 5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int done = 0, loops = 0; 5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_sendhookact act; 5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project act = (*statp->qhook)(&nsap, &buf, &buflen, 5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &resplen); 5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (act) { 5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_goahead: 5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project done = 1; 5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_nextns: 5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_done: 5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_modified: 5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* give the hook another try */ 5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++loops < 42) /*doug adams*/ 5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_error: 5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (!done); 5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(((statp->options & RES_DEBUG) && 5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), 541ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt NULL, 0, niflags) == 0), 542ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt (stdout, ";; Querying server (# %d) address = %s\n", 543ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt ns + 1, abuf)); 5441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (v_circuit) { 5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Use VC; at most one attempt per server. */ 5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project try = statp->retry; 549ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, 5511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns); 552ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 553ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 5548f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 555ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "used send_vc %d\n", n); 556ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 557ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 5591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 5611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 5621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = n; 5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 5641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Use datagrams. */ 565ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 5668f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using send_dg\n"); 567ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 568ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, 5701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns, &v_circuit, &gotsomewhere); 571ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 5728f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "used send_dg %d\n",n); 573ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 574ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 579ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 580bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng __libc_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n", 581bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng time(NULL)); 582ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (v_circuit) 5841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto same_ns; 5851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = n; 5861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint((statp->options & RES_DEBUG) || 5891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((statp->pfcode & RES_PRF_REPLY) && 5901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_HEAD1)), 5911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; got answer:\n")); 5921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 5941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 5951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "%s", ""), 5961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 5971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if USE_RESOLV_CACHE 5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cache_status == RESOLV_CACHE_NOTFOUND) { 60041d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen _resolv_cache_add(statp->netid, buf, buflen, 6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, resplen); 6021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 6041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If we have temporarily opened a virtual circuit, 6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * or if we haven't been asked to keep a socket open, 6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * close the socket. 6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((v_circuit && (statp->options & RES_USEVC) == 0U) || 6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->options & RES_STAYOPEN) == 0U) { 6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->rhook) { 6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int done = 0, loops = 0; 6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_sendhookact act; 6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project act = (*statp->rhook)(nsap, buf, buflen, 6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &resplen); 6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (act) { 6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_goahead: 6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_done: 6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project done = 1; 6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_nextns: 6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_modified: 6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* give the hook another try */ 6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++loops < 42) /*doug adams*/ 6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_error: 6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (!done); 6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project next_ns: ; 6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } /*foreach ns*/ 6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } /*foreach retry*/ 6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!v_circuit) { 6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!gotsomewhere) 6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ECONNREFUSED; /* no nameservers found */ 6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ETIMEDOUT; /* no answer obtained */ 6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = terrno; 654ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström 655ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström#if USE_RESOLV_CACHE 65641d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen _resolv_cache_query_failed(statp->netid, buf, buflen); 657ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström#endif 658ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström 6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fail: 661a59cfcfd0821f51ee77f13105099f700ccbf9252Mattias Falk#if USE_RESOLV_CACHE 66241d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen _resolv_cache_query_failed(statp->netid, buf, buflen); 663a59cfcfd0821f51ee77f13105099f700ccbf9252Mattias Falk#endif 6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private */ 6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectget_salen(sa) 6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *sa; 6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SA_LEN 6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* There are people do not set sa_len. Be forgiving to them. */ 6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sa->sa_len) 6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sa->sa_len); 6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sa->sa_family == AF_INET) 6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sizeof(struct sockaddr_in)); 6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (sa->sa_family == AF_INET6) 6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sizeof(struct sockaddr_in6)); 6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); /* unknown, die on connect */ 6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * pick appropriate nsaddr_list for use. see res_init() for initialization. 6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct sockaddr * 6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectget_nsaddr(statp, n) 6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_state statp; 6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t n; 6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { 6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - EXT(statp).ext->nsaddrs[n] holds an address that is larger 7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * than struct sockaddr, and 7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - user code did not update statp->nsaddr_list[n]. 7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; 7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - user code updated statp->nsaddr_list[n], or 7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - statp->nsaddr_list[n] has the same content as 7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * EXT(statp).ext->nsaddrs[n]. 7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; 7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 715ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int get_timeout(const res_state statp, const int ns) 716ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 717ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int timeout = (statp->retrans << ns); 718ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (ns > 0) { 719ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout /= statp->nscount; 720ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 721ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (timeout <= 0) { 722ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = 1; 723ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 724ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 7258f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using timeout of %d sec\n", timeout); 726ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 727ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 728ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return timeout; 729ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 730ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsend_vc(res_state statp, 7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz, 7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *terrno, int ns) 7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const HEADER *hp = (const HEADER *)(const void *)buf; 7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project HEADER *anhp = (HEADER *)(void *)ans; 7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr *nsap; 7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int truncating, connreset, resplen, n; 7411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct iovec iov[2]; 7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_short len; 7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *cp; 7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project void *tmp; 7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 746ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 7478f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); 748ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 749ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 7521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project connreset = 0; 7541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project same_ns: 7551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project truncating = 0; 7561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Are we still talking to whom we want to talk to? */ 7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { 7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage peer; 7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t size = sizeof peer; 761ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak unsigned old_mark; 762c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker int mark_size = sizeof(old_mark); 7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (getpeername(statp->_vcsock, 7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&peer, &size) < 0 || 765c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker !sock_eq((struct sockaddr *)(void *)&peer, nsap) || 766c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker getsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &old_mark, &mark_size) < 0 || 767c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker old_mark != statp->_mark) { 7681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags &= ~RES_F_VC; 7701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { 7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock >= 0) 7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0); 7781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock > highestFD) { 7791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOTSOCK; 7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock < 0) { 7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (errno) { 7841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPROTONOSUPPORT: 7851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef EPFNOSUPPORT 7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPFNOSUPPORT: 7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 7881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EAFNOSUPPORT: 7891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(vc)", errno); 7901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(vc)", errno); 7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 797ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak if (statp->_mark != MARK_UNSET) { 798c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker if (setsockopt(statp->_vcsock, SOL_SOCKET, 799c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker SO_MARK, &statp->_mark, sizeof(statp->_mark)) < 0) { 800c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker *terrno = errno; 801c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker Perror(statp, stderr, "setsockopt", errno); 802c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker return -1; 803c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 804c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 8051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 8061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (random_bind(statp->_vcsock,nsap->sa_family) < 0) { 8071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "bind/vc", errno, nsap, 8091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 8101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 813ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t)nsaplen, 814ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt get_timeout(statp, ns)) < 0) { 8151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "connect/vc", errno, nsap, 8171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 8181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= RES_F_VC; 8221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send length & message 8261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns_put16((u_short)buflen, (u_char*)(void *)&len); 8281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[0] = evConsIovec(&len, INT16SZ); 8291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DE_CONST(buf, tmp); 8301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[1] = evConsIovec(tmp, (size_t)buflen); 8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { 8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "write failed", errno); 8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Receive length & response 8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project read_len: 8411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = ans; 8421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = INT16SZ; 8431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) { 8441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 8451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((len -= n) == 0) 8461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 8471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) { 8491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "read failed", errno); 8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * A long running process might get its TCP 8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * connection reset if the remote server was 8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * restarted. Requery the server instead of 8561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * trying a new one. When there is only one 8571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * server, this means that a query might work 8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * instead of failing. We only allow one reset 8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * per query to prevent looping. 8601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*terrno == ECONNRESET && !connreset) { 8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project connreset = 1; 8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto same_ns; 8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = ns_get16(ans); 8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen > anssiz) { 8711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 8721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; response truncated\n") 8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ); 8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project truncating = 1; 8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = anssiz; 8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 8771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = resplen; 8781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (len < HFIXEDSZ) { 8791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Undersized message. 8811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 8831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; undersized: %d\n", len)); 8841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = EMSGSIZE; 8851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = ans; 8891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){ 8901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 8911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len -= n; 8921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) { 8941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "read(vc)", errno); 8961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (truncating) { 9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flush rest of answer so connection stays in synch. 9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->tc = 1; 9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = resplen - anssiz; 9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (len != 0) { 9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char junk[PACKETSZ]; 9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = read(statp->_vcsock, junk, 9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (len > sizeof junk) ? sizeof junk : len); 9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n > 0) 9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len -= n; 9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the calling applicating has bailed out of 9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * a previous call and failed to arrange to have 9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the circuit closed or the server has got 9201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * itself confused, then drop the packet and 9211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * wait for the correct one. 9221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (hp->id != anhp->id) { 9241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 9251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 9261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; old answer (unexpected):\n"), 9271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz: resplen); 9281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto read_len; 9291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All is well, or the error is fatal. Signal that the 9331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * next nameserver ought not be tried. 9341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 9361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 9371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 938ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt/* return -1 on error (errno set), 0 on success */ 939ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int 940ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltconnect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int sec) 941ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 942ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int res, origflags; 943ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fd_set rset, wset; 944ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt struct timespec now, timeout, finish; 945ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 946ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt origflags = fcntl(sock, F_GETFL, 0); 947ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fcntl(sock, F_SETFL, origflags | O_NONBLOCK); 948ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 949ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = connect(sock, nsap, salen); 950ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res < 0 && errno != EINPROGRESS) { 951ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = -1; 952ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto done; 953ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 954ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res != 0) { 955ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt now = evNowTime(); 956ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evConsTime((long)sec, 0L); 957ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt finish = evAddTime(now, timeout); 958ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 9598f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", " %d send_vc\n", sock); 960ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 961ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 962ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = retrying_select(sock, &rset, &wset, &finish); 963ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res <= 0) { 964ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = -1; 965ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 966ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 967ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltdone: 968ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fcntl(sock, F_SETFL, origflags); 969ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 9708f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 971bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng " %d connect_with_timeout returning %d\n", sock, res); 972ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 973ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return res; 974ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 975ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 976ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int 977ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct timespec *finish) 978ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 979ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt struct timespec now, timeout; 980ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int n, error; 981ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt socklen_t len; 982ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 983ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 984ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretry: 985ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 9868f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", " %d retying_select\n", sock); 987ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 988ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 989ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt now = evNowTime(); 990ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (readset) { 991ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_ZERO(readset); 992ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_SET(sock, readset); 993ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 994ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (writeset) { 995ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_ZERO(writeset); 996ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_SET(sock, writeset); 997ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 998ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (evCmpTime(*finish, now) > 0) 999ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evSubTime(*finish, now); 1000ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt else 1001ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evConsTime(0L, 0L); 1002ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1003ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL); 1004ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (n == 0) { 1005ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10068f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, " libc", 1007ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select timeout\n", sock); 1008ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1009ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt errno = ETIMEDOUT; 1010ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return 0; 1011ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1012ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (n < 0) { 1013ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (errno == EINTR) 1014ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 1015ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10168f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1017ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select got error %d\n",sock, n); 1018ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1019ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return n; 1020ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1021ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if ((readset && FD_ISSET(sock, readset)) || (writeset && FD_ISSET(sock, writeset))) { 1022ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt len = sizeof(error); 1023ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { 1024ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt errno = error; 1025ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10268f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1027ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select dot error2 %d\n", sock, errno); 1028ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1029ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1030ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return -1; 1031ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1032ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1033ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10348f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1035bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng " %d retrying_select returning %d\n",sock, n); 1036ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1037ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1038ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return n; 1039ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 1040ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1041ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 10421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 10431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsend_dg(res_state statp, 10441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz, 10451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int *terrno, int ns, int *v_circuit, int *gotsomewhere) 10461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 10471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const HEADER *hp = (const HEADER *)(const void *)buf; 10481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project HEADER *anhp = (HEADER *)(void *)ans; 10491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *nsap; 10501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 10511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec now, timeout, finish; 10521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fd_set dsmask; 10531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage from; 10541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t fromlen; 10551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int resplen, seconds, n, s; 10561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 10571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 10581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 10591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] == -1) { 10601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0); 10611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] > highestFD) { 10621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 10631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOTSOCK; 10641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] < 0) { 10661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (errno) { 10671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPROTONOSUPPORT: 10681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef EPFNOSUPPORT 10691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPFNOSUPPORT: 10701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 10711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EAFNOSUPPORT: 10721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(dg)", errno); 10731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 10741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 10751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 10761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(dg)", errno); 10771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 10781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1080c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker 1081ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak if (statp->_mark != MARK_UNSET) { 1082c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker if (setsockopt(EXT(statp).nssocks[ns], SOL_SOCKET, 1083c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker SO_MARK, &(statp->_mark), sizeof(statp->_mark)) < 0) { 1084c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker res_nclose(statp); 1085c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker return -1; 1086c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 1087c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CANNOT_CONNECT_DGRAM 10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * On a 4.3BSD+ machine (client and server, 10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * actually), sending to a nameserver datagram 10921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * port with no nameserver will cause an 10931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ICMP port unreachable message to be returned. 10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If our datagram socket is "connected" to the 10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * server, we get an ECONNREFUSED error on the next 10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * socket operation, and select returns if the 10971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * error message is received. We can thus detect 10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the absence of a nameserver without timing out. 10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (random_bind(EXT(statp).nssocks[ns], nsap->sa_family) < 0) { 11011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "bind(dg)", errno, nsap, 11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 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 if (connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) { 11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "connect(dg)", errno, nsap, 11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !CANNOT_CONNECT_DGRAM */ 11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; new DG socket\n")) 1115c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker 11161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project s = EXT(statp).nssocks[ns]; 11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CANNOT_CONNECT_DGRAM 11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (send(s, (const char*)buf, (size_t)buflen, 0) != buflen) { 11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "send", errno); 11211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !CANNOT_CONNECT_DGRAM */ 11251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) 11261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 11271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); 11281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !CANNOT_CONNECT_DGRAM */ 11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Wait for reply. 11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1136ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt seconds = get_timeout(statp, ns); 11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project now = evNowTime(); 11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project timeout = evConsTime((long)seconds, 0L); 11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project finish = evAddTime(now, timeout); 1140ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretry: 1141ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt n = retrying_select(s, &dsmask, NULL, &finish); 1142ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) { 11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); 11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gotsomewhere = 1; 11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) { 11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "select", errno); 11501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fromlen = sizeof(from); 11551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0, 11561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&from, &fromlen); 11571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen <= 0) { 11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "recvfrom", errno); 11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gotsomewhere = 1; 11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen < HFIXEDSZ) { 11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Undersized message. 11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; undersized: %d\n", 11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen)); 11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = EMSGSIZE; 11711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (hp->id != anhp->id) { 11751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response from old query, ignore it. 11771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 11781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 11791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1180524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1181524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_OLD_RESPONSE); 1182524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 11831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 11851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; old answer:\n"), 11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1187ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_INSECURE1) && 11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) { 11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response from wrong server? ignore it. 11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1196524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1197524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_SERVER); 1198524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; not our server:\n"), 12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1203ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 12041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RES_USE_EDNS0 12061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) { 12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Do not retry if the server do not understand EDNS0. 12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The case has to be captured here, as FORMERR packet do not 12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * carry query section, hence res_queriesmatch() returns 0. 12111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ(statp->options & RES_DEBUG, 12131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "server rejected query with EDNS0:\n"), 12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* record the error */ 12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= RES_F_EDNS0ERR; 12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_INSECURE2) && 12221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !res_queriesmatch(buf, buf + buflen, 12231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, ans + anssiz)) { 12241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response contains wrong query? ignore it. 12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1229524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1230524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_QUERY); 1231524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; wrong query name:\n"), 12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1236ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry;; 12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anhp->rcode == SERVFAIL || 12391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->rcode == NOTIMP || 12401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->rcode == REFUSED) { 12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ(statp->options & RES_DEBUG, 12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "server rejected query:\n"), 12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* don't retry if called from dig */ 12461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->pfcode) 12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_IGNTC) && anhp->tc) { 12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * To get the rest of answer, 12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * use TCP with same server. 12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; truncated answer\n")); 12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *v_circuit = 1; 12571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All is well, or the error is fatal. Signal that the 12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * next nameserver ought not be tried. 12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectAerror(const res_state statp, FILE *file, const char *string, int error, 12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *address, int alen) 12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 12711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save = errno; 12721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char hbuf[NI_MAXHOST]; 12731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char sbuf[NI_MAXSERV]; 12741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project alen = alen; 12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_DEBUG) != 0U) { 12781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (getnameinfo(address, (socklen_t)alen, hbuf, sizeof(hbuf), 12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sbuf, sizeof(sbuf), niflags)) { 12801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strncpy(hbuf, "?", sizeof(hbuf) - 1); 12811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project hbuf[sizeof(hbuf) - 1] = '\0'; 12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strncpy(sbuf, "?", sizeof(sbuf) - 1); 12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sbuf[sizeof(sbuf) - 1] = '\0'; 12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fprintf(file, "res_send: %s ([%s].%s): %s\n", 12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project string, hbuf, sbuf, strerror(error)); 12871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save; 12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 12901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectPerror(const res_state statp, FILE *file, const char *string, int error) { 12931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save = errno; 12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_DEBUG) != 0U) 12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fprintf(file, "res_send: %s: %s\n", 12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project string, strerror(error)); 12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save; 12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsock_eq(struct sockaddr *a, struct sockaddr *b) { 13031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in *a4, *b4; 13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in6 *a6, *b6; 13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (a->sa_family != b->sa_family) 13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (a->sa_family) { 13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 13101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a4 = (struct sockaddr_in *)(void *)a; 13111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b4 = (struct sockaddr_in *)(void *)b; 13121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return a4->sin_port == b4->sin_port && 13131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a4->sin_addr.s_addr == b4->sin_addr.s_addr; 13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a6 = (struct sockaddr_in6 *)(void *)a; 13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b6 = (struct sockaddr_in6 *)(void *)b; 13171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return a6->sin6_port == b6->sin6_port && 13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SIN6_SCOPE_ID 13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a6->sin6_scope_id == b6->sin6_scope_id && 13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); 13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 13241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 13251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef NEED_PSELECT 13281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* XXX needs to move to the porting library. */ 13291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpselect(int nfds, void *rfds, void *wfds, void *efds, 13311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec *tsp, const sigset_t *sigmask) 13321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 13331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timeval tv, *tvp; 13341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigset_t sigs; 13351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; 13361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tsp) { 13381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tvp = &tv; 13391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tv = evTimeVal(*tsp); 13401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 13411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tvp = NULL; 13421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sigmask) 13431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigprocmask(SIG_SETMASK, sigmask, &sigs); 13441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = select(nfds, rfds, wfds, efds, tvp); 13451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sigmask) 13461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigprocmask(SIG_SETMASK, &sigs, NULL); 13471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tsp) 13481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *tsp = evTimeSpec(tv); 13491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (n); 13501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1352