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/* 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send query to name server and wait for reply. 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h> 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h> 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/time.h> 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/socket.h> 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/uio.h> 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netinet/in.h> 95569fb9887d00104509df79fa77d92e3cf9afe7dbCalin Juravle#include <arpa/nameser.h> 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <arpa/inet.h> 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h> 99ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#include <fcntl.h> 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netdb.h> 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES 102ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak#include "resolv_netid.h" 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h" 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <resolv.h> 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <signal.h> 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h> 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 111ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#include <time.h> 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h> 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <isc/eventlib.h> 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1164d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai#include <resolv_cache.h> 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 118eb847bc8666842a3cfc9c06e8458ad1abebebaf0Elliott Hughes#include "private/libc_logging.h" 119ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DE_CONST 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DE_CONST(c,v) v = ((c) ? \ 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL) 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Options. Leave them on. */ 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DEBUG 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DEBUG 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "res_debug.h" 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "res_private.h" 1314d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai#include "resolv_stats.h" 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define EXT(res) ((res)->_u._ext) 134ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt#define DBG 0 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const int highestFD = FD_SETSIZE - 1; 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Forward. */ 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int get_salen __P((const struct sockaddr *)); 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct sockaddr * get_nsaddr __P((res_state, size_t)); 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int send_vc(res_state, const u_char *, int, 1434d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai u_char *, int, int *, int, 1444d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai time_t *, int *, int *); 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int send_dg(res_state, const u_char *, int, 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *, int, int *, int, 1474d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai int *, int *, 1484d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai time_t *, int *, int *); 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void Aerror(const res_state, FILE *, const char *, int, 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *, int); 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void Perror(const res_state, FILE *, const char *, int); 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int sock_eq(struct sockaddr *, struct sockaddr *); 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef NEED_PSELECT 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int pselect(int, void *, void *, void *, 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec *, 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const sigset_t *); 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid res_pquery(const res_state, const u_char *, int, FILE *); 159ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int connect_with_timeout(int sock, const struct sockaddr *nsap, 160ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt socklen_t salen, int sec); 161ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int retrying_select(const int sock, fd_set *readset, fd_set *writeset, 162ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt const struct timespec *finish); 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC-BEGIN: implement source port randomization */ 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union { 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr sa; 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in sin; 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in6 sin6; 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} _sockaddr_union; 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectrandom_bind( int s, int family ) 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project _sockaddr_union u; 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int j; 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t slen; 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* clear all, this also sets the IP4/6 address to 'any' */ 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memset( &u, 0, sizeof u ); 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (family) { 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_family = family; 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project slen = sizeof u.sin; 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_family = family; 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project slen = sizeof u.sin6; 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EPROTO; 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return -1; 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* first try to bind to a random source port a few times */ 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (j = 0; j < 10; j++) { 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* find a random port between 1025 .. 65534 */ 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int port = 1025 + (res_randomid() % (65535-1025)); 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (family == AF_INET) 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_port = htons(port); 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_port = htons(port); 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( !bind( s, &u.sa, slen ) ) 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* nothing after 10 tries, our network table is probably busy */ 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* let the system decide which port is best */ 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (family == AF_INET) 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin.sin_port = 0; 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u.sin6.sin6_port = 0; 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return bind( s, &u.sa, slen ); 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* BIONIC-END */ 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public. */ 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_isourserver(ina) 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * looks up "ina" in _res.ns_addr_list[] 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not found 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : found 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2327cc5666d94615d9249163dc7ac0f58c2614497ceJim Huang__LIBC_HIDDEN__ int 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_ourserver_p(const res_state statp, const struct sockaddr *sa) { 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr_in *inp, *srv; 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr_in6 *in6p, *srv6; 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int ns; 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (sa->sa_family) { 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project inp = (const struct sockaddr_in *)(const void *)sa; 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv = (struct sockaddr_in *)(void *)get_nsaddr(statp, (size_t)ns); 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srv->sin_family == inp->sin_family && 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv->sin_port == inp->sin_port && 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (srv->sin_addr.s_addr == INADDR_ANY || 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv->sin_addr.s_addr == inp->sin_addr.s_addr)) 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext == NULL) 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project in6p = (const struct sockaddr_in6 *)(const void *)sa; 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6 = (struct sockaddr_in6 *)(void *)get_nsaddr(statp, (size_t)ns); 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (srv6->sin6_family == in6p->sin6_family && 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6->sin6_port == in6p->sin6_port && 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SIN6_SCOPE_ID 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (srv6->sin6_scope_id == 0 || 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project srv6->sin6_scope_id == in6p->sin6_scope_id) && 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) || 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr))) 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_nameinquery(name, type, class, buf, eom) 2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * look for (name,type,class) in the query section of packet (buf,eom) 2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * requires: 2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * buf + HFIXEDSZ <= eom 2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -1 : format error 2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not found 2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : found 2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nameinquery(const char *name, int type, int class, 2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, const u_char *eom) 2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *cp = buf + HFIXEDSZ; 2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int qdcount = ntohs(((const HEADER*)(const void *)buf)->qdcount); 2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (qdcount-- > 0) { 2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char tname[MAXDNAME+1]; 2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, ttype, tclass; 2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = dn_expand(buf, eom, cp, tname, sizeof tname); 2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp + 2 * INT16SZ > eom) 3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ttype = ns_get16(cp); cp += INT16SZ; 3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tclass = ns_get16(cp); cp += INT16SZ; 3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ttype == type && tclass == class && 3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns_samename(tname, name) == 1) 3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* int 3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * res_queriesmatch(buf1, eom1, buf2, eom2) 3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is there a 1:1 mapping of (name,type,class) 3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * in (buf1,eom1) and (buf2,eom2)? 3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * returns: 3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -1 : format error 3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 0 : not a 1:1 mapping 3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * >0 : is a 1:1 mapping 3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * author: 3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * paul vixie, 29may94 3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_queriesmatch(const u_char *buf1, const u_char *eom1, 3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf2, const u_char *eom2) 3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *cp = buf1 + HFIXEDSZ; 3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int qdcount = ntohs(((const HEADER*)(const void *)buf1)->qdcount); 3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) 3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Only header section present in replies to 3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * dynamic update packets. 3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((((const HEADER *)(const void *)buf1)->opcode == ns_o_update) && 3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (((const HEADER *)(const void *)buf2)->opcode == ns_o_update)) 3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (qdcount != ntohs(((const HEADER*)(const void *)buf2)->qdcount)) 3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (qdcount-- > 0) { 3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char tname[MAXDNAME+1]; 3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n, ttype, tclass; 3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = dn_expand(buf1, eom1, cp, tname, sizeof tname); 3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (cp + 2 * INT16SZ > eom1) 3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ttype = ns_get16(cp); cp += INT16SZ; 3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tclass = ns_get16(cp); cp += INT16SZ; 3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) 3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint 3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nsend(res_state statp, 3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz) 3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; 3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char abuf[NI_MAXHOST]; 3664d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED; 367c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk 3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anssiz < HFIXEDSZ) { 3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EINVAL; 3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), 3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; res_send()\n"), buf, buflen); 3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ; 3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project gotsomewhere = 0; 3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project terrno = ETIMEDOUT; 3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 37841d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen int anslen = 0; 37941d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen cache_status = _resolv_cache_lookup( 38041d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen statp->netid, buf, buflen, 38141d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen ans, anssiz, &anslen); 38241d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen 38341d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen if (cache_status == RESOLV_CACHE_FOUND) { 38441d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen return anslen; 38541d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen } else if (cache_status != RESOLV_CACHE_UNSUPPORTED) { 38641d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen // had a cache miss for a known network, so populate the thread private 38741d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen // data so the normal resolve path can do its thing 38841d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen _resolv_populate_res_for_net(statp); 389c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk } 390c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk if (statp->nscount == 0) { 391e5477f83b0a639b86d8cbe710f25d9808a8f72afLorenzo Colitti // We have no nameservers configured, so there's no point trying. 392e5477f83b0a639b86d8cbe710f25d9808a8f72afLorenzo Colitti // Tell the cache the query failed, or any retries and anyone else asking the same 393e5477f83b0a639b86d8cbe710f25d9808a8f72afLorenzo Colitti // question will block for PENDING_REQUEST_TIMEOUT seconds instead of failing fast. 394e5477f83b0a639b86d8cbe710f25d9808a8f72afLorenzo Colitti _resolv_cache_query_failed(statp->netid, buf, buflen); 395c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk errno = ESRCH; 396c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk return (-1); 397c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk } 3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the ns_addr_list in the resolver context has changed, then 4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * invalidate our cached copy and the associated timing data. 4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount != 0) { 4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int needclose = 0; 4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage peer; 4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t peerlen; 4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4084d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai if (EXT(statp).nscount != statp->nscount) { 4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4104d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai } else { 4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->nsaddr_list[ns].sin_family && 4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !sock_eq((struct sockaddr *)(void *)&statp->nsaddr_list[ns], 4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[ns])) { 4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] == -1) 4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project peerlen = sizeof(peer); 42287043f9c89593125a27199d0c1b4069d088672d7Jim Huang if (getpeername(EXT(statp).nssocks[ns], 4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&peer, &peerlen) < 0) { 4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!sock_eq((struct sockaddr *)(void *)&peer, 4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project get_nsaddr(statp, (size_t)ns))) { 4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project needclose++; 4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4334d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai } 4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (needclose) { 4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nscount = 0; 4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Maybe initialize our private copy of the ns_addr_list. 4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nscount == 0) { 4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[ns] = RES_MAXTIME; 4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = -1; 4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->nsaddr_list[ns].sin_family) 4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns].sin = 4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[ns]; 4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nscount = statp->nscount; 4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Some resolvers want to even out the load on their nameservers. 4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note that RES_BLAST overrides RES_ROTATE. 4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_ROTATE) != 0U && 4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->options & RES_BLAST) == 0U) { 4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project union res_sockaddr_union inu; 4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in ina; 4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int lastns = statp->nscount - 1; 4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int fd; 4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_int16_t nstime; 4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project inu = EXT(statp).ext->nsaddrs[0]; 4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ina = statp->nsaddr_list[0]; 4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fd = EXT(statp).nssocks[0]; 4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nstime = EXT(statp).nstimes[0]; 4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < lastns; ns++) { 4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4744d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai EXT(statp).ext->nsaddrs[ns] = 4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[ns + 1]; 4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1]; 4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1]; 4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1]; 4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).ext != NULL) 4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).ext->nsaddrs[lastns] = inu; 4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->nsaddr_list[lastns] = ina; 4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nssocks[lastns] = fd; 4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXT(statp).nstimes[lastns] = nstime; 4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send request, RETRY times, or until successful. 4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (try = 0; try < statp->retry; try++) { 491589afca92c2fa026f908ec2c54c0450c438c602cPierre Imai struct __res_stats stats[MAXNS]; 4924d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai struct __res_params params; 4934d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai int revision_id = _resolv_cache_get_resolver_stats(statp->netid, ¶ms, stats); 494589afca92c2fa026f908ec2c54c0450c438c602cPierre Imai bool usable_servers[MAXNS]; 49521bf06372742b0524c358502eb692a2245d64ddaPierre Imai android_net_res_stats_get_usable_servers(¶ms, stats, statp->nscount, 49621bf06372742b0524c358502eb692a2245d64ddaPierre Imai usable_servers); 4974d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (ns = 0; ns < statp->nscount; ns++) { 4994d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai if (!usable_servers[ns]) continue; 5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr *nsap; 5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 5024d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai time_t now = 0; 5034d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai int rcode = RCODE_INTERNAL_ERROR; 5044d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai int delay = 0; 5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags &= ~RES_F_LASTMASK; 5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= (ns << RES_F_LASTSHIFT); 5094d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project same_ns: 5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->qhook) { 5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int done = 0, loops = 0; 5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_sendhookact act; 5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project act = (*statp->qhook)(&nsap, &buf, &buflen, 5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &resplen); 5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (act) { 5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_goahead: 5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project done = 1; 5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_nextns: 5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_done: 5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_modified: 5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* give the hook another try */ 5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++loops < 42) /*doug adams*/ 5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_error: 5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (!done); 5391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(((statp->options & RES_DEBUG) && 5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), 543ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt NULL, 0, niflags) == 0), 544ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt (stdout, ";; Querying server (# %d) address = %s\n", 545ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt ns + 1, abuf)); 5461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 5481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (v_circuit) { 5491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Use VC; at most one attempt per server. */ 5501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project try = statp->retry; 551ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, 5534d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai ns, &now, &rcode, &delay); 5544d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 5550b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai /* 5560b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai * Only record stats the first time we try a query. This ensures that 5570b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai * queries that deterministically fail (e.g., a name that always returns 5580b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai * SERVFAIL or times out) do not unduly affect the stats. 5590b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai */ 5600b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai if (try == 0) { 5610b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai struct __res_sample sample; 5620b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai _res_stats_set_sample(&sample, now, rcode, delay); 5630b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, 5640b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai ns, &sample, params.max_samples); 5650b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai } 566ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 567ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 5688f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 569ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt "used send_vc %d\n", n); 570ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 571ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 5751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 5761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = n; 5771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 5781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Use datagrams. */ 579ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 5808f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using send_dg\n"); 581ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 582ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, 5844d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai ns, &v_circuit, &gotsomewhere, &now, &rcode, &delay); 5854d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 5860b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai /* Only record stats the first time we try a query. See above. */ 5870b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai if (try == 0) { 5880b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai struct __res_sample sample; 5890b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai _res_stats_set_sample(&sample, now, rcode, delay); 5900b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, 5910b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai ns, &sample, params.max_samples); 5920b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai } 5934d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 594ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 5958f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "used send_dg %d\n",n); 596ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 597ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 5981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) 5991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 6001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) 6011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 602ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 603bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng __libc_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n", 6044d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai time(NULL)); 605ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (v_circuit) 6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto same_ns; 6081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = n; 6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint((statp->options & RES_DEBUG) || 6121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((statp->pfcode & RES_PRF_REPLY) && 6131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_HEAD1)), 6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; got answer:\n")); 6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 6171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "%s", ""), 6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6214d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai if (cache_status == RESOLV_CACHE_NOTFOUND) { 6224d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai _resolv_cache_add(statp->netid, buf, buflen, 6234d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai ans, resplen); 6244d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai } 6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If we have temporarily opened a virtual circuit, 6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * or if we haven't been asked to keep a socket open, 6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * close the socket. 6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((v_circuit && (statp->options & RES_USEVC) == 0U) || 6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->options & RES_STAYOPEN) == 0U) { 6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->rhook) { 6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int done = 0, loops = 0; 6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project do { 6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_sendhookact act; 6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project act = (*statp->rhook)(nsap, buf, buflen, 6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, anssiz, &resplen); 6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (act) { 6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_goahead: 6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_done: 6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project done = 1; 6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_nextns: 6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto next_ns; 6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_modified: 6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* give the hook another try */ 6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (++loops < 42) /*doug adams*/ 6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case res_error: 6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /*FALLTHROUGH*/ 6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto fail; 6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } while (!done); 6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project next_ns: ; 6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } /*foreach ns*/ 6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } /*foreach retry*/ 6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!v_circuit) { 6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!gotsomewhere) 6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ECONNREFUSED; /* no nameservers found */ 6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ETIMEDOUT; /* no answer obtained */ 6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = terrno; 675ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström 6764d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai _resolv_cache_query_failed(statp->netid, buf, buflen); 677ce5ba8bfcd8ecfb7bfee4412f4f686cecc17e39bHenrik Engström 6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fail: 6804d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 68141d9a503716ed6f3291f4cae097dca08d459429cPaul Jensen _resolv_cache_query_failed(statp->netid, buf, buflen); 6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private */ 6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectget_salen(sa) 6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *sa; 6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SA_LEN 6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* There are people do not set sa_len. Be forgiving to them. */ 6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sa->sa_len) 6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sa->sa_len); 6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sa->sa_family == AF_INET) 7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sizeof(struct sockaddr_in)); 7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (sa->sa_family == AF_INET6) 7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (sizeof(struct sockaddr_in6)); 7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); /* unknown, die on connect */ 7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * pick appropriate nsaddr_list for use. see res_init() for initialization. 7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct sockaddr * 7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectget_nsaddr(statp, n) 7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_state statp; 7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t n; 7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) { 7171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - EXT(statp).ext->nsaddrs[n] holds an address that is larger 7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * than struct sockaddr, and 7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - user code did not update statp->nsaddr_list[n]. 7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n]; 7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - user code updated statp->nsaddr_list[n], or 7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * - statp->nsaddr_list[n] has the same content as 7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * EXT(statp).ext->nsaddrs[n]. 7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (struct sockaddr *)(void *)&statp->nsaddr_list[n]; 7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 733ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int get_timeout(const res_state statp, const int ns) 734ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 735ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int timeout = (statp->retrans << ns); 736ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (ns > 0) { 737ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout /= statp->nscount; 738ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 739ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (timeout <= 0) { 740ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = 1; 741ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 742ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 7438f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using timeout of %d sec\n", timeout); 744ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 745ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 746ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return timeout; 747ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 748ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 7491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 7501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsend_vc(res_state statp, 7511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz, 7524d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai int *terrno, int ns, time_t* at, int* rcode, int* delay) 7531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 7540b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai *at = time(NULL); 7554d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = RCODE_INTERNAL_ERROR; 7564d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *delay = 0; 7571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const HEADER *hp = (const HEADER *)(const void *)buf; 7581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project HEADER *anhp = (HEADER *)(void *)ans; 7591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr *nsap; 7601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 7611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int truncating, connreset, resplen, n; 7621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct iovec iov[2]; 7631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_short len; 7641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_char *cp; 7651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project void *tmp; 7661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 767ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 7688f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); 769ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 770ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 7711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 7721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 7731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project connreset = 0; 7751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project same_ns: 7761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project truncating = 0; 7771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7784d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai struct timespec now = evNowTime(); 7794d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 7801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Are we still talking to whom we want to talk to? */ 7811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { 7821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage peer; 7831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t size = sizeof peer; 784ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak unsigned old_mark; 78537b1b5bbcd1cddf833c9ca18a5976efbbf88dabfElliott Hughes socklen_t mark_size = sizeof(old_mark); 7861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (getpeername(statp->_vcsock, 7871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&peer, &size) < 0 || 788c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker !sock_eq((struct sockaddr *)(void *)&peer, nsap) || 789c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker getsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &old_mark, &mark_size) < 0 || 790c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker old_mark != statp->_mark) { 7911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags &= ~RES_F_VC; 7931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 7951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 7961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { 7971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock >= 0) 7981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 7991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8001781ed7774671d5a750839650b9582ff0abbcf42Nick Kralevich statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); 8011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock > highestFD) { 8021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOTSOCK; 8041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (statp->_vcsock < 0) { 8061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (errno) { 8071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPROTONOSUPPORT: 8081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef EPFNOSUPPORT 8091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPFNOSUPPORT: 8101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 8111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EAFNOSUPPORT: 8121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(vc)", errno); 8131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 8151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(vc)", errno); 8171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 8181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 820ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak if (statp->_mark != MARK_UNSET) { 821c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker if (setsockopt(statp->_vcsock, SOL_SOCKET, 8224d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai SO_MARK, &statp->_mark, sizeof(statp->_mark)) < 0) { 823c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker *terrno = errno; 824c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker Perror(statp, stderr, "setsockopt", errno); 825c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker return -1; 826c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 827c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 8281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 8291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (random_bind(statp->_vcsock,nsap->sa_family) < 0) { 8301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "bind/vc", errno, nsap, 8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 836ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t)nsaplen, 837ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt get_timeout(statp, ns)) < 0) { 8381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "connect/vc", errno, nsap, 8401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 8411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8424d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai /* 8434d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai * The way connect_with_timeout() is implemented prevents us from reliably 8444d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai * determining whether this was really a timeout or e.g. ECONNREFUSED. Since 8454d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai * currently both cases are handled in the same way, there is no need to 8464d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai * change this (yet). If we ever need to reliably distinguish between these 8474d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai * cases, both connect_with_timeout() and retrying_select() need to be 8484d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai * modified, though. 8494d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai */ 8504d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = RCODE_TIMEOUT; 8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= RES_F_VC; 8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Send length & message 8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ns_put16((u_short)buflen, (u_char*)(void *)&len); 8601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[0] = evConsIovec(&len, INT16SZ); 8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DE_CONST(buf, tmp); 8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project iov[1] = evConsIovec(tmp, (size_t)buflen); 8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) { 8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "write failed", errno); 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 /* 8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Receive length & response 8711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project read_len: 8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = ans; 8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = INT16SZ; 8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0) { 8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 8771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((len -= n) == 0) 8781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 8791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) { 8811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 8821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "read failed", errno); 8831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 8851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * A long running process might get its TCP 8861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * connection reset if the remote server was 8871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * restarted. Requery the server instead of 8881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * trying a new one. When there is only one 8891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * server, this means that a query might work 8901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * instead of failing. We only allow one reset 8911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * per query to prevent looping. 8921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 8931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (*terrno == ECONNRESET && !connreset) { 8941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project connreset = 1; 8951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto same_ns; 8971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 8981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 8991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = ns_get16(ans); 9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen > anssiz) { 9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; response truncated\n") 9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ); 9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project truncating = 1; 9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = anssiz; 9081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = resplen; 9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (len < HFIXEDSZ) { 9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Undersized message. 9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; undersized: %d\n", len)); 9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = EMSGSIZE; 9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp = ans; 9211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (size_t)len)) > 0){ 9221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project cp += n; 9231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len -= n; 9241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n <= 0) { 9261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 9271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "read(vc)", errno); 9281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 9291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 9301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9314d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai 9321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (truncating) { 9331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Flush rest of answer so connection stays in synch. 9351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->tc = 1; 9371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len = resplen - anssiz; 9381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while (len != 0) { 9391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char junk[PACKETSZ]; 9401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = read(statp->_vcsock, junk, 9421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (len > sizeof junk) ? sizeof junk : len); 9431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n > 0) 9441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project len -= n; 9451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 9461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 9471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If the calling applicating has bailed out of 9511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * a previous call and failed to arrange to have 9521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the circuit closed or the server has got 9531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * itself confused, then drop the packet and 9541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * wait for the correct one. 9551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (hp->id != anhp->id) { 9571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 9581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 9591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; old answer (unexpected):\n"), 9601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz: resplen); 9611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto read_len; 9621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 9631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 9641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 9651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All is well, or the error is fatal. Signal that the 9661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * next nameserver ought not be tried. 9671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 9684d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai if (resplen > 0) { 9690b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai struct timespec done = evNowTime(); 9704d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *delay = _res_stats_calculate_rtt(&done, &now); 9714d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = anhp->rcode; 9724d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai } 9731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 9741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 9751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 976ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt/* return -1 on error (errno set), 0 on success */ 977ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int 978ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltconnect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int sec) 979ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 980ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int res, origflags; 981ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fd_set rset, wset; 982ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt struct timespec now, timeout, finish; 983ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 984ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt origflags = fcntl(sock, F_GETFL, 0); 985ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fcntl(sock, F_SETFL, origflags | O_NONBLOCK); 986ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 98731ad03761d35ce5bff48cc1cb3764816727ac1f0Paul Jensen res = __connect(sock, nsap, salen); 988ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res < 0 && errno != EINPROGRESS) { 9894d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai res = -1; 9904d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai goto done; 991ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 992ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res != 0) { 993ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt now = evNowTime(); 994ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evConsTime((long)sec, 0L); 995ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt finish = evAddTime(now, timeout); 996ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 9978f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", " %d send_vc\n", sock); 998ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 999ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1000ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt res = retrying_select(sock, &rset, &wset, &finish); 1001ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (res <= 0) { 10024d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai res = -1; 1003ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1004ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1005ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltdone: 1006ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt fcntl(sock, F_SETFL, origflags); 1007ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10088f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1009bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng " %d connect_with_timeout returning %d\n", sock, res); 1010ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1011ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return res; 1012ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 1013ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1014ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltstatic int 1015ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct timespec *finish) 1016ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt{ 1017ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt struct timespec now, timeout; 1018ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt int n, error; 1019ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt socklen_t len; 1020ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1021ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1022ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretry: 1023ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10244d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai __libc_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_select\n", sock); 1025ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1026ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1027ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt now = evNowTime(); 1028ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (readset) { 1029ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_ZERO(readset); 1030ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_SET(sock, readset); 1031ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1032ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (writeset) { 1033ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_ZERO(writeset); 1034ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt FD_SET(sock, writeset); 1035ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1036ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (evCmpTime(*finish, now) > 0) 1037ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evSubTime(*finish, now); 1038ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt else 1039ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt timeout = evConsTime(0L, 0L); 1040ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1041ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL); 1042ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (n == 0) { 1043ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10448f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, " libc", 1045ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select timeout\n", sock); 1046ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1047ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt errno = ETIMEDOUT; 1048ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return 0; 1049ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1050ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (n < 0) { 1051ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (errno == EINTR) 1052ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 1053ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10548f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1055ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select got error %d\n",sock, n); 1056ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1057ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return n; 1058ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1059ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if ((readset && FD_ISSET(sock, readset)) || (writeset && FD_ISSET(sock, writeset))) { 1060ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt len = sizeof(error); 1061ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { 1062ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt errno = error; 1063ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10648f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1065ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt " %d retrying_select dot error2 %d\n", sock, errno); 1066ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1067ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1068ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return -1; 1069ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1070ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1071ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt if (DBG) { 10728f2a5a0b40fc82126c691d5c30131d908772aab7Elliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "libc", 1073bb0b09cad6cb950a824cfa46743fe27a0997411bKito Cheng " %d retrying_select returning %d\n",sock, n); 1074ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt } 1075ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 1076ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt return n; 1077ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt} 1078ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 10801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsend_dg(res_state statp, 10811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const u_char *buf, int buflen, u_char *ans, int anssiz, 10824d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai int *terrno, int ns, int *v_circuit, int *gotsomewhere, 10834d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai time_t *at, int *rcode, int* delay) 10841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 10850b1a71f9a49ed13a680ff299c8d798cf36d565eaPierre Imai *at = time(NULL); 10864d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = RCODE_INTERNAL_ERROR; 10874d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *delay = 0; 10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const HEADER *hp = (const HEADER *)(const void *)buf; 10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project HEADER *anhp = (HEADER *)(void *)ans; 10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *nsap; 10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nsaplen; 10924d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai struct timespec now, timeout, finish, done; 10931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fd_set dsmask; 10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_storage from; 10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project socklen_t fromlen; 10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int resplen, seconds, n, s; 10971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsap = get_nsaddr(statp, (size_t)ns); 10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen = get_salen(nsap); 11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] == -1) { 11011781ed7774671d5a750839650b9582ff0abbcf42Nick Kralevich EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0); 11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] > highestFD) { 11031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = ENOTSOCK; 11051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (EXT(statp).nssocks[ns] < 0) { 11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (errno) { 11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPROTONOSUPPORT: 11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef EPFNOSUPPORT 11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EPFNOSUPPORT: 11111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case EAFNOSUPPORT: 11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(dg)", errno); 11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 11161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = errno; 11171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "socket(dg)", errno); 11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (-1); 11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1121c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker 1122ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak if (statp->_mark != MARK_UNSET) { 1123c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker if (setsockopt(EXT(statp).nssocks[ns], SOL_SOCKET, 1124c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker SO_MARK, &(statp->_mark), sizeof(statp->_mark)) < 0) { 1125c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker res_nclose(statp); 1126c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker return -1; 1127c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 1128c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker } 11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CANNOT_CONNECT_DGRAM 11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * On a 4.3BSD+ machine (client and server, 11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * actually), sending to a nameserver datagram 11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * port with no nameserver will cause an 11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ICMP port unreachable message to be returned. 11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If our datagram socket is "connected" to the 11361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * server, we get an ECONNREFUSED error on the next 11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * socket operation, and select returns if the 11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * error message is received. We can thus detect 11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the absence of a nameserver without timing out. 11401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 11411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (random_bind(EXT(statp).nssocks[ns], nsap->sa_family) < 0) { 11421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "bind(dg)", errno, nsap, 11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 114731ad03761d35ce5bff48cc1cb3764816727ac1f0Paul Jensen if (__connect(EXT(statp).nssocks[ns], nsap, (socklen_t)nsaplen) < 0) { 11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "connect(dg)", errno, nsap, 11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project nsaplen); 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#endif /* !CANNOT_CONNECT_DGRAM */ 11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 11551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; new DG socket\n")) 1156c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker 11571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project s = EXT(statp).nssocks[ns]; 11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef CANNOT_CONNECT_DGRAM 11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (send(s, (const char*)buf, (size_t)buflen, 0) != buflen) { 11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "send", errno); 11621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !CANNOT_CONNECT_DGRAM */ 11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) 11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Aerror(statp, stderr, "sendto", errno, nsap, nsaplen); 11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !CANNOT_CONNECT_DGRAM */ 11731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 11751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Wait for reply. 11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1177ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt seconds = get_timeout(statp, ns); 11781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project now = evNowTime(); 11791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project timeout = evConsTime((long)seconds, 0L); 11801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project finish = evAddTime(now, timeout); 1181ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwaltretry: 1182ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt n = retrying_select(s, &dsmask, NULL, &finish); 1183ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt 11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n == 0) { 11854d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = RCODE_TIMEOUT; 11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); 11871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gotsomewhere = 1; 11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n < 0) { 11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "select", errno); 11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 11961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fromlen = sizeof(from); 11971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen = recvfrom(s, (char*)ans, (size_t)anssiz,0, 11981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (struct sockaddr *)(void *)&from, &fromlen); 11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen <= 0) { 12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Perror(statp, stderr, "recvfrom", errno); 12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gotsomewhere = 1; 12051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (resplen < HFIXEDSZ) { 12061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Undersized message. 12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; undersized: %d\n", 12111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project resplen)); 12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *terrno = EMSGSIZE; 12131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (hp->id != anhp->id) { 12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response from old query, ignore it. 12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1222524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1223524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_OLD_RESPONSE); 1224524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; old answer:\n"), 12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1229ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 12301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_INSECURE1) && 12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) { 12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response from wrong server? ignore it. 12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 12361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1238524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1239524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_SERVER); 1240524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; not our server:\n"), 12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1245ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry; 12461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RES_USE_EDNS0 12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) { 12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Do not retry if the server do not understand EDNS0. 12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The case has to be captured here, as FORMERR packet do not 12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * carry query section, hence res_queriesmatch() returns 0. 12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ(statp->options & RES_DEBUG, 12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "server rejected query with EDNS0:\n"), 12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 12571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* record the error */ 12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project statp->_flags |= RES_F_EDNS0ERR; 12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_INSECURE2) && 12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project !res_queriesmatch(buf, buf + buflen, 12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, ans + anssiz)) { 12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * response contains wrong query? ignore it. 12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * XXX - potential security hazard could 12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * be detected here. 12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 1271524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#ifdef ANDROID_CHANGES 1272524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra __libc_android_log_event_uid(BIONIC_EVENT_RESOLVER_WRONG_QUERY); 1273524c87c61c1d39dd60aaa8ae01ec3528ce212288Geremy Condra#endif 12741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ((statp->options & RES_DEBUG) || 12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (statp->pfcode & RES_PRF_REPLY), 12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; wrong query name:\n"), 12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 1278ecd0e95a0276c1ba72c7331f5e4617815f015f22Robert Greenwalt goto retry;; 12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12804d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai done = evNowTime(); 12814d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *delay = _res_stats_calculate_rtt(&done, &now); 12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (anhp->rcode == SERVFAIL || 12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->rcode == NOTIMP || 12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project anhp->rcode == REFUSED) { 12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DprintQ(statp->options & RES_DEBUG, 12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, "server rejected query:\n"), 12871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ans, (resplen > anssiz) ? anssiz : resplen); 12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* don't retry if called from dig */ 12904d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai if (!statp->pfcode) { 12914d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = anhp->rcode; 12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (0); 12934d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai } 12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!(statp->options & RES_IGNTC) && anhp->tc) { 12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * To get the rest of answer, 12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * use TCP with same server. 12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 13001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Dprint(statp->options & RES_DEBUG, 13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (stdout, ";; truncated answer\n")); 13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *v_circuit = 1; 13031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_nclose(statp); 13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (1); 13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* 13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All is well, or the error is fatal. Signal that the 13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * next nameserver ought not be tried. 13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 13104d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai if (resplen > 0) { 13114d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai *rcode = anhp->rcode; 13124d8e740b0868b2670599b949ff07d74e5f317114Pierre Imai } 13131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (resplen); 13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 13171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectAerror(const res_state statp, FILE *file, const char *string, int error, 13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const struct sockaddr *address, int alen) 13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save = errno; 13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char hbuf[NI_MAXHOST]; 13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char sbuf[NI_MAXSERV]; 13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_DEBUG) != 0U) { 13251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (getnameinfo(address, (socklen_t)alen, hbuf, sizeof(hbuf), 13261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sbuf, sizeof(sbuf), niflags)) { 13271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strncpy(hbuf, "?", sizeof(hbuf) - 1); 13281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project hbuf[sizeof(hbuf) - 1] = '\0'; 13291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project strncpy(sbuf, "?", sizeof(sbuf) - 1); 13301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sbuf[sizeof(sbuf) - 1] = '\0'; 13311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 13321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fprintf(file, "res_send: %s ([%s].%s): %s\n", 13331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project string, hbuf, sbuf, strerror(error)); 13341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 13351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save; 13361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void 13391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectPerror(const res_state statp, FILE *file, const char *string, int error) { 13401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save = errno; 13411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((statp->options & RES_DEBUG) != 0U) 13431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project fprintf(file, "res_send: %s: %s\n", 13441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project string, strerror(error)); 13451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save; 13461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsock_eq(struct sockaddr *a, struct sockaddr *b) { 13501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in *a4, *b4; 13511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct sockaddr_in6 *a6, *b6; 13521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (a->sa_family != b->sa_family) 13541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 13551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project switch (a->sa_family) { 13561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET: 13571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a4 = (struct sockaddr_in *)(void *)a; 13581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b4 = (struct sockaddr_in *)(void *)b; 13591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return a4->sin_port == b4->sin_port && 13601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a4->sin_addr.s_addr == b4->sin_addr.s_addr; 13611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project case AF_INET6: 13621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a6 = (struct sockaddr_in6 *)(void *)a; 13631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b6 = (struct sockaddr_in6 *)(void *)b; 13641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return a6->sin6_port == b6->sin6_port && 13651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef HAVE_SIN6_SCOPE_ID 13661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project a6->sin6_scope_id == b6->sin6_scope_id && 13671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 13681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr); 13691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project default: 13701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 13711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 13721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef NEED_PSELECT 13751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* XXX needs to move to the porting library. */ 13761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int 13771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpselect(int nfds, void *rfds, void *wfds, void *efds, 13781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timespec *tsp, const sigset_t *sigmask) 13791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 13801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct timeval tv, *tvp; 13811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigset_t sigs; 13821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n; 13831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tsp) { 13851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tvp = &tv; 13861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tv = evTimeVal(*tsp); 13871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else 13881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project tvp = NULL; 13891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sigmask) 13901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigprocmask(SIG_SETMASK, sigmask, &sigs); 13911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project n = select(nfds, rfds, wfds, efds, tvp); 13921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (sigmask) 13931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sigprocmask(SIG_SETMASK, &sigs, NULL); 13941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (tsp) 13951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *tsp = evTimeSpec(tv); 13961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (n); 13971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 13981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 1399