blob: fad08eef3c0db43236c5e24fa1a06ebc97fcf6ef [file] [log] [blame]
Bernie Innocenti55864192018-08-30 04:05:20 +09001/* $NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $ */
2
3/*
4 * Copyright (c) 1985, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/*
37 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
38 *
39 * Permission to use, copy, modify, and distribute this software for any
40 * purpose with or without fee is hereby granted, provided that the above
41 * copyright notice and this permission notice appear in all copies, and that
42 * the name of Digital Equipment Corporation not be used in advertising or
43 * publicity pertaining to distribution of the document or software without
44 * specific, written prior permission.
45 *
46 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
47 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
49 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
50 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
51 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 * SOFTWARE.
54 */
55
56/*
57 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
58 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
59 *
60 * Permission to use, copy, modify, and distribute this software for any
61 * purpose with or without fee is hereby granted, provided that the above
62 * copyright notice and this permission notice appear in all copies.
63 *
64 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
65 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
66 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
67 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
68 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
69 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
70 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
71 */
72
Bernie Innocenti55864192018-08-30 04:05:20 +090073/*
74 * Send query to name server and wait for reply.
75 */
76
Bernie Innocenti55864192018-08-30 04:05:20 +090077#include <sys/param.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090078#include <sys/socket.h>
Bernie Innocentif12d5bb2018-08-31 14:09:46 +090079#include <sys/time.h>
80#include <sys/types.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090081#include <sys/uio.h>
82
Bernie Innocenti55864192018-08-30 04:05:20 +090083#include <arpa/inet.h>
Bernie Innocentif12d5bb2018-08-31 14:09:46 +090084#include <arpa/nameser.h>
85#include <netinet/in.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090086
87#include <errno.h>
88#include <fcntl.h>
89#include <netdb.h>
90#include <poll.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090091#include <signal.h>
92#include <stdio.h>
93#include <stdlib.h>
94#include <string.h>
95#include <time.h>
96#include <unistd.h>
97
Bernie Innocenti55864192018-08-30 04:05:20 +090098#include <async_safe/log.h>
99
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900100#include "private/android_filesystem_config.h"
101#include "res_private.h"
102#include "resolv_cache.h"
103#include "resolv_netid.h"
104#include "resolv_private.h"
105#include "resolv_stats.h"
106
Bernie Innocenti55864192018-08-30 04:05:20 +0900107/* Options. Leave them on. */
108#ifndef DEBUG
109#define DEBUG
110#endif
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900111
Bernie Innocenti55864192018-08-30 04:05:20 +0900112#include "res_debug.h"
Bernie Innocenti55864192018-08-30 04:05:20 +0900113
114#define EXT(res) ((res)->_u._ext)
115#define DBG 0
116
117/* Forward. */
118
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900119static int get_salen(const struct sockaddr*);
120static struct sockaddr* get_nsaddr(res_state, size_t);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900121static int send_vc(res_state, struct __res_params* params, const u_char*, int, u_char*, int, int*,
122 int, time_t*, int*, int*);
123static int send_dg(res_state, struct __res_params* params, const u_char*, int, u_char*, int, int*,
124 int, int*, int*, time_t*, int*, int*);
125static void Aerror(const res_state, FILE*, const char*, int, const struct sockaddr*, int);
126static void Perror(const res_state, FILE*, const char*, int);
127static int sock_eq(struct sockaddr*, struct sockaddr*);
128void res_pquery(const res_state, const u_char*, int, FILE*);
129static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
130 const struct timespec timeout);
Bernie Innocenti55864192018-08-30 04:05:20 +0900131static int retrying_poll(const int sock, short events, const struct timespec* finish);
132
133/* BIONIC-BEGIN: implement source port randomization */
134typedef union {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900135 struct sockaddr sa;
136 struct sockaddr_in sin;
137 struct sockaddr_in6 sin6;
Bernie Innocenti55864192018-08-30 04:05:20 +0900138} _sockaddr_union;
139
Bernie Innocentif89b3512018-08-30 07:34:37 +0900140// BEGIN: Code copied from ISC eventlib
141// TODO: move away from this code
142
143#define BILLION 1000000000
144
145static struct timespec evConsTime(time_t sec, long nsec) {
146 struct timespec x;
147
148 x.tv_sec = sec;
149 x.tv_nsec = nsec;
150 return (x);
151}
152
153static struct timespec evAddTime(struct timespec addend1, struct timespec addend2) {
154 struct timespec x;
155
156 x.tv_sec = addend1.tv_sec + addend2.tv_sec;
157 x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
158 if (x.tv_nsec >= BILLION) {
159 x.tv_sec++;
160 x.tv_nsec -= BILLION;
161 }
162 return (x);
163}
164
165static struct timespec evSubTime(struct timespec minuend, struct timespec subtrahend) {
166 struct timespec x;
167
168 x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
169 if (minuend.tv_nsec >= subtrahend.tv_nsec)
170 x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
171 else {
172 x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
173 x.tv_sec--;
174 }
175 return (x);
176}
177
178static int evCmpTime(struct timespec a, struct timespec b) {
179#define SGN(x) ((x) < 0 ? (-1) : (x) > 0 ? (1) : (0));
180 time_t s = a.tv_sec - b.tv_sec;
181 long n;
182
183 if (s != 0) return SGN(s);
184
185 n = a.tv_nsec - b.tv_nsec;
186 return SGN(n);
187}
188
Bernie Innocentif89b3512018-08-30 07:34:37 +0900189static struct timespec evNowTime(void) {
Bernie Innocentif89b3512018-08-30 07:34:37 +0900190 struct timespec tsnow;
Bernie Innocenti357339c2018-08-31 16:11:41 +0900191 clock_gettime(CLOCK_REALTIME, &tsnow);
192 return tsnow;
Bernie Innocentif89b3512018-08-30 07:34:37 +0900193}
194
195static struct iovec evConsIovec(void* buf, size_t cnt) {
196 struct iovec ret;
197
198 memset(&ret, 0xf5, sizeof ret);
199 ret.iov_base = buf;
200 ret.iov_len = cnt;
Bernie Innocenti357339c2018-08-31 16:11:41 +0900201 return ret;
Bernie Innocentif89b3512018-08-30 07:34:37 +0900202}
203
204// END: Code copied from ISC eventlib
205
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900206static int random_bind(int s, int family) {
207 _sockaddr_union u;
208 int j;
209 socklen_t slen;
Bernie Innocenti55864192018-08-30 04:05:20 +0900210
211 /* clear all, this also sets the IP4/6 address to 'any' */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900212 memset(&u, 0, sizeof u);
Bernie Innocenti55864192018-08-30 04:05:20 +0900213
214 switch (family) {
215 case AF_INET:
216 u.sin.sin_family = family;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900217 slen = sizeof u.sin;
Bernie Innocenti55864192018-08-30 04:05:20 +0900218 break;
219 case AF_INET6:
220 u.sin6.sin6_family = family;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900221 slen = sizeof u.sin6;
Bernie Innocenti55864192018-08-30 04:05:20 +0900222 break;
223 default:
224 errno = EPROTO;
225 return -1;
226 }
227
228 /* first try to bind to a random source port a few times */
229 for (j = 0; j < 10; j++) {
230 /* find a random port between 1025 .. 65534 */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900231 int port = 1025 + (res_randomid() % (65535 - 1025));
Bernie Innocenti55864192018-08-30 04:05:20 +0900232 if (family == AF_INET)
233 u.sin.sin_port = htons(port);
234 else
235 u.sin6.sin6_port = htons(port);
236
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900237 if (!bind(s, &u.sa, slen)) return 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900238 }
239
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900240 // nothing after 10 attempts, our network table is probably busy
241 // let the system decide which port is best
Bernie Innocenti55864192018-08-30 04:05:20 +0900242 if (family == AF_INET)
243 u.sin.sin_port = 0;
244 else
245 u.sin6.sin6_port = 0;
246
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900247 return bind(s, &u.sa, slen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900248}
249/* BIONIC-END */
250
251static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
252
253/* Public. */
254
255/* int
256 * res_isourserver(ina)
257 * looks up "ina" in _res.ns_addr_list[]
258 * returns:
259 * 0 : not found
260 * >0 : found
261 * author:
262 * paul vixie, 29may94
263 */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900264__LIBC_HIDDEN__ int res_ourserver_p(const res_state statp, const struct sockaddr* sa) {
265 const struct sockaddr_in *inp, *srv;
266 const struct sockaddr_in6 *in6p, *srv6;
267 int ns;
Bernie Innocenti55864192018-08-30 04:05:20 +0900268
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900269 switch (sa->sa_family) {
270 case AF_INET:
271 inp = (const struct sockaddr_in*) (const void*) sa;
272 for (ns = 0; ns < statp->nscount; ns++) {
273 srv = (struct sockaddr_in*) (void*) get_nsaddr(statp, (size_t) ns);
274 if (srv->sin_family == inp->sin_family && srv->sin_port == inp->sin_port &&
275 (srv->sin_addr.s_addr == INADDR_ANY ||
276 srv->sin_addr.s_addr == inp->sin_addr.s_addr))
277 return (1);
278 }
279 break;
280 case AF_INET6:
281 if (EXT(statp).ext == NULL) break;
282 in6p = (const struct sockaddr_in6*) (const void*) sa;
283 for (ns = 0; ns < statp->nscount; ns++) {
284 srv6 = (struct sockaddr_in6*) (void*) get_nsaddr(statp, (size_t) ns);
285 if (srv6->sin6_family == in6p->sin6_family && srv6->sin6_port == in6p->sin6_port &&
Bernie Innocenti55864192018-08-30 04:05:20 +0900286#ifdef HAVE_SIN6_SCOPE_ID
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900287 (srv6->sin6_scope_id == 0 || srv6->sin6_scope_id == in6p->sin6_scope_id) &&
Bernie Innocenti55864192018-08-30 04:05:20 +0900288#endif
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900289 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
290 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
291 return (1);
292 }
293 break;
294 default:
295 break;
296 }
297 return (0);
Bernie Innocenti55864192018-08-30 04:05:20 +0900298}
299
300/* int
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900301 * res_nameinquery(name, type, cl, buf, eom)
302 * look for (name, type, cl) in the query section of packet (buf, eom)
Bernie Innocenti55864192018-08-30 04:05:20 +0900303 * requires:
304 * buf + HFIXEDSZ <= eom
305 * returns:
306 * -1 : format error
307 * 0 : not found
308 * >0 : found
309 * author:
310 * paul vixie, 29may94
311 */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900312int res_nameinquery(const char* name, int type, int cl, const u_char* buf, const u_char* eom) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900313 const u_char* cp = buf + HFIXEDSZ;
314 int qdcount = ntohs(((const HEADER*) (const void*) buf)->qdcount);
Bernie Innocenti55864192018-08-30 04:05:20 +0900315
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900316 while (qdcount-- > 0) {
317 char tname[MAXDNAME + 1];
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900318 int n = dn_expand(buf, eom, cp, tname, sizeof tname);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900319 if (n < 0) return (-1);
320 cp += n;
321 if (cp + 2 * INT16SZ > eom) return (-1);
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900322 int ttype = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900323 cp += INT16SZ;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900324 int tclass = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900325 cp += INT16SZ;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900326 if (ttype == type && tclass == cl && ns_samename(tname, name) == 1) return (1);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900327 }
328 return (0);
Bernie Innocenti55864192018-08-30 04:05:20 +0900329}
330
331/* int
332 * res_queriesmatch(buf1, eom1, buf2, eom2)
333 * is there a 1:1 mapping of (name,type,class)
334 * in (buf1,eom1) and (buf2,eom2)?
335 * returns:
336 * -1 : format error
337 * 0 : not a 1:1 mapping
338 * >0 : is a 1:1 mapping
339 * author:
340 * paul vixie, 29may94
341 */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900342int res_queriesmatch(const u_char* buf1, const u_char* eom1, const u_char* buf2,
343 const u_char* eom2) {
344 const u_char* cp = buf1 + HFIXEDSZ;
345 int qdcount = ntohs(((const HEADER*) (const void*) buf1)->qdcount);
Bernie Innocenti55864192018-08-30 04:05:20 +0900346
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900347 if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900348
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900349 /*
350 * Only header section present in replies to
351 * dynamic update packets.
352 */
353 if ((((const HEADER*) (const void*) buf1)->opcode == ns_o_update) &&
354 (((const HEADER*) (const void*) buf2)->opcode == ns_o_update))
355 return (1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900356
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900357 if (qdcount != ntohs(((const HEADER*) (const void*) buf2)->qdcount)) return (0);
358 while (qdcount-- > 0) {
359 char tname[MAXDNAME + 1];
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900360 int n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900361 if (n < 0) return (-1);
362 cp += n;
363 if (cp + 2 * INT16SZ > eom1) return (-1);
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900364 int ttype = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900365 cp += INT16SZ;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900366 int tclass = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900367 cp += INT16SZ;
368 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0);
369 }
370 return (1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900371}
372
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900373int res_nsend(res_state statp, const u_char* buf, int buflen, u_char* ans, int anssiz) {
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900374 int gotsomewhere, terrno, v_circuit, resplen, n;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900375 char abuf[NI_MAXHOST];
376 ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
Bernie Innocenti55864192018-08-30 04:05:20 +0900377
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900378 if (anssiz < HFIXEDSZ) {
379 errno = EINVAL;
380 return (-1);
381 }
382 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
383 (stdout, ";; res_send()\n"), buf, buflen);
384 v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
385 gotsomewhere = 0;
386 terrno = ETIMEDOUT;
Bernie Innocenti55864192018-08-30 04:05:20 +0900387
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900388 int anslen = 0;
389 cache_status = _resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900390
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900391 if (cache_status == RESOLV_CACHE_FOUND) {
392 return anslen;
393 } else if (cache_status != RESOLV_CACHE_UNSUPPORTED) {
394 // had a cache miss for a known network, so populate the thread private
395 // data so the normal resolve path can do its thing
396 _resolv_populate_res_for_net(statp);
397 }
398 if (statp->nscount == 0) {
399 // We have no nameservers configured, so there's no point trying.
400 // Tell the cache the query failed, or any retries and anyone else asking the same
401 // question will block for PENDING_REQUEST_TIMEOUT seconds instead of failing fast.
402 _resolv_cache_query_failed(statp->netid, buf, buflen);
403 errno = ESRCH;
404 return (-1);
405 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900406
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900407 /*
408 * If the ns_addr_list in the resolver context has changed, then
409 * invalidate our cached copy and the associated timing data.
410 */
411 if (EXT(statp).nscount != 0) {
412 int needclose = 0;
413 struct sockaddr_storage peer;
414 socklen_t peerlen;
Bernie Innocenti55864192018-08-30 04:05:20 +0900415
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900416 if (EXT(statp).nscount != statp->nscount) {
417 needclose++;
418 } else {
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900419 for (int ns = 0; ns < statp->nscount; ns++) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900420 if (statp->nsaddr_list[ns].sin_family &&
421 !sock_eq((struct sockaddr*) (void*) &statp->nsaddr_list[ns],
422 (struct sockaddr*) (void*) &EXT(statp).ext->nsaddrs[ns])) {
423 needclose++;
424 break;
425 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900426
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900427 if (EXT(statp).nssocks[ns] == -1) continue;
428 peerlen = sizeof(peer);
429 if (getpeername(EXT(statp).nssocks[ns], (struct sockaddr*) (void*) &peer,
430 &peerlen) < 0) {
431 needclose++;
432 break;
433 }
434 if (!sock_eq((struct sockaddr*) (void*) &peer, get_nsaddr(statp, (size_t) ns))) {
435 needclose++;
436 break;
437 }
438 }
439 }
440 if (needclose) {
441 res_nclose(statp);
442 EXT(statp).nscount = 0;
443 }
444 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900445
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900446 /*
447 * Maybe initialize our private copy of the ns_addr_list.
448 */
449 if (EXT(statp).nscount == 0) {
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900450 for (int ns = 0; ns < statp->nscount; ns++) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900451 EXT(statp).nstimes[ns] = RES_MAXTIME;
452 EXT(statp).nssocks[ns] = -1;
453 if (!statp->nsaddr_list[ns].sin_family) continue;
454 EXT(statp).ext->nsaddrs[ns].sin = statp->nsaddr_list[ns];
455 }
456 EXT(statp).nscount = statp->nscount;
457 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900458
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900459 /*
460 * Some resolvers want to even out the load on their nameservers.
461 * Note that RES_BLAST overrides RES_ROTATE.
462 */
463 if ((statp->options & RES_ROTATE) != 0U && (statp->options & RES_BLAST) == 0U) {
464 union res_sockaddr_union inu;
465 struct sockaddr_in ina;
466 int lastns = statp->nscount - 1;
467 int fd;
468 u_int16_t nstime;
Bernie Innocenti55864192018-08-30 04:05:20 +0900469
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900470 if (EXT(statp).ext != NULL) inu = EXT(statp).ext->nsaddrs[0];
471 ina = statp->nsaddr_list[0];
472 fd = EXT(statp).nssocks[0];
473 nstime = EXT(statp).nstimes[0];
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900474 for (int ns = 0; ns < lastns; ns++) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900475 if (EXT(statp).ext != NULL)
476 EXT(statp).ext->nsaddrs[ns] = EXT(statp).ext->nsaddrs[ns + 1];
477 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
478 EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
479 EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];
480 }
481 if (EXT(statp).ext != NULL) EXT(statp).ext->nsaddrs[lastns] = inu;
482 statp->nsaddr_list[lastns] = ina;
483 EXT(statp).nssocks[lastns] = fd;
484 EXT(statp).nstimes[lastns] = nstime;
485 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900486
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900487 /*
488 * Send request, RETRY times, or until successful.
489 */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900490 for (int attempt = 0; attempt < statp->retry; ++attempt) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900491 struct __res_stats stats[MAXNS];
492 struct __res_params params;
493 int revision_id = _resolv_cache_get_resolver_stats(statp->netid, &params, stats);
494 bool usable_servers[MAXNS];
495 android_net_res_stats_get_usable_servers(&params, stats, statp->nscount, usable_servers);
Bernie Innocenti55864192018-08-30 04:05:20 +0900496
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900497 for (int ns = 0; ns < statp->nscount; ns++) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900498 if (!usable_servers[ns]) continue;
499 struct sockaddr* nsap;
500 int nsaplen;
501 time_t now = 0;
502 int rcode = RCODE_INTERNAL_ERROR;
503 int delay = 0;
504 nsap = get_nsaddr(statp, (size_t) ns);
505 nsaplen = get_salen(nsap);
506 statp->_flags &= ~RES_F_LASTMASK;
507 statp->_flags |= (ns << RES_F_LASTSHIFT);
Bernie Innocenti55864192018-08-30 04:05:20 +0900508
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900509 same_ns:
510 if (statp->qhook) {
511 int done = 0, loops = 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900512
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900513 do {
514 res_sendhookact act;
Bernie Innocenti55864192018-08-30 04:05:20 +0900515
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900516 act = (*statp->qhook)(&nsap, &buf, &buflen, ans, anssiz, &resplen);
517 switch (act) {
518 case res_goahead:
519 done = 1;
520 break;
521 case res_nextns:
522 res_nclose(statp);
523 goto next_ns;
524 case res_done:
525 if (cache_status == RESOLV_CACHE_NOTFOUND) {
526 _resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
527 }
528 return (resplen);
529 case res_modified:
530 /* give the hook another try */
531 if (++loops < 42) /*doug adams*/
532 break;
533 /*FALLTHROUGH*/
534 case res_error:
535 /*FALLTHROUGH*/
536 default:
537 goto fail;
538 }
539 } while (!done);
540 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900541
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900542 Dprint(((statp->options & RES_DEBUG) &&
543 getnameinfo(nsap, (socklen_t) nsaplen, abuf, sizeof(abuf), NULL, 0, niflags) ==
544 0),
545 (stdout, ";; Querying server (# %d) address = %s\n", ns + 1, abuf));
Bernie Innocenti55864192018-08-30 04:05:20 +0900546
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900547 if (v_circuit) {
548 /* Use VC; at most one attempt per server. */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900549 attempt = statp->retry;
Bernie Innocenti55864192018-08-30 04:05:20 +0900550
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900551 n = send_vc(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &now, &rcode,
552 &delay);
Bernie Innocenti55864192018-08-30 04:05:20 +0900553
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900554 /*
555 * Only record stats the first time we try a query. This ensures that
556 * queries that deterministically fail (e.g., a name that always returns
557 * SERVFAIL or times out) do not unduly affect the stats.
558 */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900559 if (attempt == 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900560 struct __res_sample sample;
561 _res_stats_set_sample(&sample, now, rcode, delay);
562 _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
563 params.max_samples);
564 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900565
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900566 if (DBG) {
567 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "used send_vc %d\n", n);
568 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900569
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900570 if (n < 0) goto fail;
571 if (n == 0) goto next_ns;
572 resplen = n;
573 } else {
574 /* Use datagrams. */
575 if (DBG) {
576 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "using send_dg\n");
577 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900578
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900579 n = send_dg(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &v_circuit,
580 &gotsomewhere, &now, &rcode, &delay);
Bernie Innocenti55864192018-08-30 04:05:20 +0900581
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900582 /* Only record stats the first time we try a query. See above. */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900583 if (attempt == 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900584 struct __res_sample sample;
585 _res_stats_set_sample(&sample, now, rcode, delay);
586 _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
587 params.max_samples);
588 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900589
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900590 if (DBG) {
591 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "used send_dg %d\n", n);
592 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900593
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900594 if (n < 0) goto fail;
595 if (n == 0) goto next_ns;
596 if (DBG) {
597 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n", time(NULL));
598 }
599 if (v_circuit) goto same_ns;
600 resplen = n;
601 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900602
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900603 Dprint((statp->options & RES_DEBUG) ||
604 ((statp->pfcode & RES_PRF_REPLY) && (statp->pfcode & RES_PRF_HEAD1)),
605 (stdout, ";; got answer:\n"));
Bernie Innocenti55864192018-08-30 04:05:20 +0900606
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900607 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
608 (stdout, "%s", ""), ans, (resplen > anssiz) ? anssiz : resplen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900609
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900610 if (cache_status == RESOLV_CACHE_NOTFOUND) {
611 _resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
612 }
613 /*
614 * If we have temporarily opened a virtual circuit,
615 * or if we haven't been asked to keep a socket open,
616 * close the socket.
617 */
618 if ((v_circuit && (statp->options & RES_USEVC) == 0U) ||
619 (statp->options & RES_STAYOPEN) == 0U) {
620 res_nclose(statp);
621 }
622 if (statp->rhook) {
623 int done = 0, loops = 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900624
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900625 do {
626 res_sendhookact act;
Bernie Innocenti55864192018-08-30 04:05:20 +0900627
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900628 act = (*statp->rhook)(nsap, buf, buflen, ans, anssiz, &resplen);
629 switch (act) {
630 case res_goahead:
631 case res_done:
632 done = 1;
633 break;
634 case res_nextns:
635 res_nclose(statp);
636 goto next_ns;
637 case res_modified:
638 /* give the hook another try */
639 if (++loops < 42) /*doug adams*/
640 break;
641 /*FALLTHROUGH*/
642 case res_error:
643 /*FALLTHROUGH*/
644 default:
645 goto fail;
646 }
647 } while (!done);
648 }
649 return (resplen);
650 next_ns:;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900651 } // for each ns
652 } // for each retry
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900653 res_nclose(statp);
654 if (!v_circuit) {
655 if (!gotsomewhere)
656 errno = ECONNREFUSED; /* no nameservers found */
657 else
658 errno = ETIMEDOUT; /* no answer obtained */
659 } else
660 errno = terrno;
Bernie Innocenti55864192018-08-30 04:05:20 +0900661
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900662 _resolv_cache_query_failed(statp->netid, buf, buflen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900663
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900664 return (-1);
665fail:
Bernie Innocenti55864192018-08-30 04:05:20 +0900666
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900667 _resolv_cache_query_failed(statp->netid, buf, buflen);
668 res_nclose(statp);
669 return (-1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900670}
671
672/* Private */
673
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900674static int get_salen(const struct sockaddr* sa) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900675 if (sa->sa_family == AF_INET)
676 return (sizeof(struct sockaddr_in));
677 else if (sa->sa_family == AF_INET6)
678 return (sizeof(struct sockaddr_in6));
679 else
680 return (0); /* unknown, die on connect */
Bernie Innocenti55864192018-08-30 04:05:20 +0900681}
682
683/*
684 * pick appropriate nsaddr_list for use. see res_init() for initialization.
685 */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900686static struct sockaddr* get_nsaddr(res_state statp, size_t n) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900687 if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
688 /*
689 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
690 * than struct sockaddr, and
691 * - user code did not update statp->nsaddr_list[n].
692 */
693 return (struct sockaddr*) (void*) &EXT(statp).ext->nsaddrs[n];
694 } else {
695 /*
696 * - user code updated statp->nsaddr_list[n], or
697 * - statp->nsaddr_list[n] has the same content as
698 * EXT(statp).ext->nsaddrs[n].
699 */
700 return (struct sockaddr*) (void*) &statp->nsaddr_list[n];
701 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900702}
703
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900704static struct timespec get_timeout(const res_state statp, const struct __res_params* params,
705 const int ns) {
706 int msec;
707 if (params->base_timeout_msec != 0) {
708 // TODO: scale the timeout by retry attempt and maybe number of servers
709 msec = params->base_timeout_msec;
710 } else {
711 // Legacy algorithm which scales the timeout by nameserver number.
712 // For instance, with 4 nameservers: 5s, 2.5s, 5s, 10s
713 // This has no effect with 1 or 2 nameservers
714 msec = (statp->retrans * 1000) << ns;
715 if (ns > 0) {
716 msec /= statp->nscount;
717 }
718 if (msec < 1000) {
719 msec = 1000; // Use at least 100ms
720 }
721 }
722 if (DBG) {
723 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "using timeout of %d msec\n", msec);
724 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900725
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900726 struct timespec result;
727 result.tv_sec = msec / 1000;
728 result.tv_nsec = (msec % 1000) * 1000000;
729 return result;
Bernie Innocenti55864192018-08-30 04:05:20 +0900730}
731
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900732static int send_vc(res_state statp, struct __res_params* params, const u_char* buf, int buflen,
733 u_char* ans, int anssiz, int* terrno, int ns, time_t* at, int* rcode,
734 int* delay) {
735 *at = time(NULL);
736 *rcode = RCODE_INTERNAL_ERROR;
737 *delay = 0;
738 const HEADER* hp = (const HEADER*) (const void*) buf;
739 HEADER* anhp = (HEADER*) (void*) ans;
740 struct sockaddr* nsap;
741 int nsaplen;
742 int truncating, connreset, resplen, n;
743 struct iovec iov[2];
744 u_short len;
745 u_char* cp;
Bernie Innocenti55864192018-08-30 04:05:20 +0900746
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900747 if (DBG) {
748 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "using send_vc\n");
749 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900750
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900751 nsap = get_nsaddr(statp, (size_t) ns);
752 nsaplen = get_salen(nsap);
Bernie Innocenti55864192018-08-30 04:05:20 +0900753
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900754 connreset = 0;
755same_ns:
756 truncating = 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900757
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900758 struct timespec now = evNowTime();
Bernie Innocenti55864192018-08-30 04:05:20 +0900759
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900760 /* Are we still talking to whom we want to talk to? */
761 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
762 struct sockaddr_storage peer;
763 socklen_t size = sizeof peer;
764 unsigned old_mark;
765 socklen_t mark_size = sizeof(old_mark);
766 if (getpeername(statp->_vcsock, (struct sockaddr*) (void*) &peer, &size) < 0 ||
767 !sock_eq((struct sockaddr*) (void*) &peer, nsap) ||
768 getsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &old_mark, &mark_size) < 0 ||
769 old_mark != statp->_mark) {
770 res_nclose(statp);
771 statp->_flags &= ~RES_F_VC;
772 }
773 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900774
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900775 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
776 if (statp->_vcsock >= 0) res_nclose(statp);
Bernie Innocenti55864192018-08-30 04:05:20 +0900777
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900778 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
779 if (statp->_vcsock < 0) {
780 switch (errno) {
781 case EPROTONOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900782 case EPFNOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900783 case EAFNOSUPPORT:
784 Perror(statp, stderr, "socket(vc)", errno);
785 return (0);
786 default:
787 *terrno = errno;
788 Perror(statp, stderr, "socket(vc)", errno);
789 return (-1);
790 }
791 }
792 fchown(statp->_vcsock, AID_DNS, -1);
793 if (statp->_mark != MARK_UNSET) {
794 if (setsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &statp->_mark,
795 sizeof(statp->_mark)) < 0) {
796 *terrno = errno;
797 Perror(statp, stderr, "setsockopt", errno);
798 return -1;
799 }
800 }
801 errno = 0;
802 if (random_bind(statp->_vcsock, nsap->sa_family) < 0) {
803 *terrno = errno;
804 Aerror(statp, stderr, "bind/vc", errno, nsap, nsaplen);
805 res_nclose(statp);
806 return (0);
807 }
808 if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t) nsaplen,
809 get_timeout(statp, params, ns)) < 0) {
810 *terrno = errno;
811 Aerror(statp, stderr, "connect/vc", errno, nsap, nsaplen);
812 res_nclose(statp);
813 /*
814 * The way connect_with_timeout() is implemented prevents us from reliably
815 * determining whether this was really a timeout or e.g. ECONNREFUSED. Since
816 * currently both cases are handled in the same way, there is no need to
817 * change this (yet). If we ever need to reliably distinguish between these
818 * cases, both connect_with_timeout() and retrying_poll() need to be
819 * modified, though.
820 */
821 *rcode = RCODE_TIMEOUT;
822 return (0);
823 }
824 statp->_flags |= RES_F_VC;
825 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900826
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900827 /*
828 * Send length & message
829 */
830 ns_put16((u_short) buflen, (u_char*) (void*) &len);
831 iov[0] = evConsIovec(&len, INT16SZ);
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900832 iov[1] = evConsIovec((void*) buf, (size_t) buflen);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900833 if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
834 *terrno = errno;
835 Perror(statp, stderr, "write failed", errno);
836 res_nclose(statp);
837 return (0);
838 }
839 /*
840 * Receive length & response
841 */
842read_len:
843 cp = ans;
844 len = INT16SZ;
845 while ((n = read(statp->_vcsock, (char*) cp, (size_t) len)) > 0) {
846 cp += n;
847 if ((len -= n) == 0) break;
848 }
849 if (n <= 0) {
850 *terrno = errno;
851 Perror(statp, stderr, "read failed", errno);
852 res_nclose(statp);
853 /*
854 * A long running process might get its TCP
855 * connection reset if the remote server was
856 * restarted. Requery the server instead of
857 * trying a new one. When there is only one
858 * server, this means that a query might work
859 * instead of failing. We only allow one reset
860 * per query to prevent looping.
861 */
862 if (*terrno == ECONNRESET && !connreset) {
863 connreset = 1;
864 res_nclose(statp);
865 goto same_ns;
866 }
867 res_nclose(statp);
868 return (0);
869 }
870 resplen = ns_get16(ans);
871 if (resplen > anssiz) {
872 Dprint(statp->options & RES_DEBUG, (stdout, ";; response truncated\n"));
873 truncating = 1;
874 len = anssiz;
875 } else
876 len = resplen;
877 if (len < HFIXEDSZ) {
878 /*
879 * Undersized message.
880 */
881 Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len));
882 *terrno = EMSGSIZE;
883 res_nclose(statp);
884 return (0);
885 }
886 cp = ans;
887 while (len != 0 && (n = read(statp->_vcsock, (char*) cp, (size_t) len)) > 0) {
888 cp += n;
889 len -= n;
890 }
891 if (n <= 0) {
892 *terrno = errno;
893 Perror(statp, stderr, "read(vc)", errno);
894 res_nclose(statp);
895 return (0);
896 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900897
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900898 if (truncating) {
899 /*
900 * Flush rest of answer so connection stays in synch.
901 */
902 anhp->tc = 1;
903 len = resplen - anssiz;
904 while (len != 0) {
905 char junk[PACKETSZ];
Bernie Innocenti55864192018-08-30 04:05:20 +0900906
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900907 n = read(statp->_vcsock, junk, (len > sizeof junk) ? sizeof junk : len);
908 if (n > 0)
909 len -= n;
910 else
911 break;
912 }
913 }
914 /*
915 * If the calling applicating has bailed out of
916 * a previous call and failed to arrange to have
917 * the circuit closed or the server has got
918 * itself confused, then drop the packet and
919 * wait for the correct one.
920 */
921 if (hp->id != anhp->id) {
922 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
923 (stdout, ";; old answer (unexpected):\n"), ans,
924 (resplen > anssiz) ? anssiz : resplen);
925 goto read_len;
926 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900927
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900928 /*
929 * All is well, or the error is fatal. Signal that the
930 * next nameserver ought not be tried.
931 */
932 if (resplen > 0) {
933 struct timespec done = evNowTime();
934 *delay = _res_stats_calculate_rtt(&done, &now);
935 *rcode = anhp->rcode;
936 }
937 return (resplen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900938}
939
940/* return -1 on error (errno set), 0 on success */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900941static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
942 const struct timespec timeout) {
943 int res, origflags;
Bernie Innocenti55864192018-08-30 04:05:20 +0900944
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900945 origflags = fcntl(sock, F_GETFL, 0);
946 fcntl(sock, F_SETFL, origflags | O_NONBLOCK);
Bernie Innocenti55864192018-08-30 04:05:20 +0900947
Bernie Innocentif89b3512018-08-30 07:34:37 +0900948 res = connect(sock, nsap, salen);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900949 if (res < 0 && errno != EINPROGRESS) {
950 res = -1;
951 goto done;
952 }
953 if (res != 0) {
954 struct timespec now = evNowTime();
955 struct timespec finish = evAddTime(now, timeout);
956 if (DBG) {
957 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d send_vc\n", sock);
958 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900959
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900960 res = retrying_poll(sock, POLLIN | POLLOUT, &finish);
961 if (res <= 0) {
962 res = -1;
963 }
964 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900965done:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900966 fcntl(sock, F_SETFL, origflags);
967 if (DBG) {
968 async_safe_format_log(ANDROID_LOG_DEBUG, "libc",
969 " %d connect_with_const timeout returning %d\n", sock, res);
970 }
971 return res;
Bernie Innocenti55864192018-08-30 04:05:20 +0900972}
973
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900974static int retrying_poll(const int sock, const short events, const struct timespec* finish) {
975 struct timespec now, timeout;
Bernie Innocenti55864192018-08-30 04:05:20 +0900976
977retry:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900978 if (DBG) {
979 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_poll\n", sock);
980 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900981
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900982 now = evNowTime();
983 if (evCmpTime(*finish, now) > 0)
984 timeout = evSubTime(*finish, now);
985 else
986 timeout = evConsTime(0L, 0L);
987 struct pollfd fds = {.fd = sock, .events = events};
988 int n = ppoll(&fds, 1, &timeout, /*sigmask=*/NULL);
989 if (n == 0) {
990 if (DBG) {
991 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_poll timeout\n", sock);
992 }
993 errno = ETIMEDOUT;
994 return 0;
995 }
996 if (n < 0) {
997 if (errno == EINTR) goto retry;
998 if (DBG) {
999 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_poll got error %d\n",
1000 sock, n);
1001 }
1002 return n;
1003 }
1004 if (fds.revents & (POLLIN | POLLOUT | POLLERR)) {
1005 int error;
1006 socklen_t len = sizeof(error);
1007 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) {
1008 errno = error;
1009 if (DBG) {
1010 async_safe_format_log(ANDROID_LOG_DEBUG, "libc",
1011 " %d retrying_poll dot error2 %d\n", sock, errno);
1012 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001013
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001014 return -1;
1015 }
1016 }
1017 if (DBG) {
1018 async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_poll returning %d\n", sock,
1019 n);
1020 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001021
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001022 return n;
Bernie Innocenti55864192018-08-30 04:05:20 +09001023}
1024
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001025static int send_dg(res_state statp, struct __res_params* params, const u_char* buf, int buflen,
1026 u_char* ans, int anssiz, int* terrno, int ns, int* v_circuit, int* gotsomewhere,
1027 time_t* at, int* rcode, int* delay) {
1028 *at = time(NULL);
1029 *rcode = RCODE_INTERNAL_ERROR;
1030 *delay = 0;
1031 const HEADER* hp = (const HEADER*) (const void*) buf;
1032 HEADER* anhp = (HEADER*) (void*) ans;
1033 const struct sockaddr* nsap;
1034 int nsaplen;
1035 struct timespec now, timeout, finish, done;
1036 struct sockaddr_storage from;
1037 socklen_t fromlen;
1038 int resplen, n, s;
Bernie Innocenti55864192018-08-30 04:05:20 +09001039
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001040 nsap = get_nsaddr(statp, (size_t) ns);
1041 nsaplen = get_salen(nsap);
1042 if (EXT(statp).nssocks[ns] == -1) {
1043 EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1044 if (EXT(statp).nssocks[ns] < 0) {
1045 switch (errno) {
1046 case EPROTONOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001047 case EPFNOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001048 case EAFNOSUPPORT:
1049 Perror(statp, stderr, "socket(dg)", errno);
1050 return (0);
1051 default:
1052 *terrno = errno;
1053 Perror(statp, stderr, "socket(dg)", errno);
1054 return (-1);
1055 }
1056 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001057
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001058 fchown(EXT(statp).nssocks[ns], AID_DNS, -1);
1059 if (statp->_mark != MARK_UNSET) {
1060 if (setsockopt(EXT(statp).nssocks[ns], SOL_SOCKET, SO_MARK, &(statp->_mark),
1061 sizeof(statp->_mark)) < 0) {
1062 res_nclose(statp);
1063 return -1;
1064 }
1065 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001066#ifndef CANNOT_CONNECT_DGRAM
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001067 /*
1068 * On a 4.3BSD+ machine (client and server,
1069 * actually), sending to a nameserver datagram
1070 * port with no nameserver will cause an
1071 * ICMP port unreachable message to be returned.
1072 * If our datagram socket is "connected" to the
1073 * server, we get an ECONNREFUSED error on the next
1074 * socket operation, and select returns if the
1075 * error message is received. We can thus detect
1076 * the absence of a nameserver without timing out.
1077 */
1078 if (random_bind(EXT(statp).nssocks[ns], nsap->sa_family) < 0) {
1079 Aerror(statp, stderr, "bind(dg)", errno, nsap, nsaplen);
1080 res_nclose(statp);
1081 return (0);
1082 }
Bernie Innocentif89b3512018-08-30 07:34:37 +09001083 if (connect(EXT(statp).nssocks[ns], nsap, (socklen_t) nsaplen) < 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001084 Aerror(statp, stderr, "connect(dg)", errno, nsap, nsaplen);
1085 res_nclose(statp);
1086 return (0);
1087 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001088#endif /* !CANNOT_CONNECT_DGRAM */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001089 Dprint(statp->options & RES_DEBUG, (stdout, ";; new DG socket\n"))
1090 }
1091 s = EXT(statp).nssocks[ns];
Bernie Innocenti55864192018-08-30 04:05:20 +09001092#ifndef CANNOT_CONNECT_DGRAM
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001093 if (send(s, (const char*) buf, (size_t) buflen, 0) != buflen) {
1094 Perror(statp, stderr, "send", errno);
1095 res_nclose(statp);
1096 return (0);
1097 }
1098#else /* !CANNOT_CONNECT_DGRAM */
1099 if (sendto(s, (const char*) buf, buflen, 0, nsap, nsaplen) != buflen) {
1100 Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
1101 res_nclose(statp);
1102 return (0);
1103 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001104#endif /* !CANNOT_CONNECT_DGRAM */
1105
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001106 /*
1107 * Wait for reply.
1108 */
1109 timeout = get_timeout(statp, params, ns);
1110 now = evNowTime();
1111 finish = evAddTime(now, timeout);
Bernie Innocenti55864192018-08-30 04:05:20 +09001112retry:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001113 n = retrying_poll(s, POLLIN, &finish);
Bernie Innocenti55864192018-08-30 04:05:20 +09001114
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001115 if (n == 0) {
1116 *rcode = RCODE_TIMEOUT;
1117 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
1118 *gotsomewhere = 1;
1119 return (0);
1120 }
1121 if (n < 0) {
1122 Perror(statp, stderr, "poll", errno);
1123 res_nclose(statp);
1124 return (0);
1125 }
1126 errno = 0;
1127 fromlen = sizeof(from);
1128 resplen = recvfrom(s, (char*) ans, (size_t) anssiz, 0, (struct sockaddr*) (void*) &from,
1129 &fromlen);
1130 if (resplen <= 0) {
1131 Perror(statp, stderr, "recvfrom", errno);
1132 res_nclose(statp);
1133 return (0);
1134 }
1135 *gotsomewhere = 1;
1136 if (resplen < HFIXEDSZ) {
1137 /*
1138 * Undersized message.
1139 */
1140 Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", resplen));
1141 *terrno = EMSGSIZE;
1142 res_nclose(statp);
1143 return (0);
1144 }
1145 if (hp->id != anhp->id) {
1146 /*
1147 * response from old query, ignore it.
1148 * XXX - potential security hazard could
1149 * be detected here.
1150 */
1151 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
1152 (stdout, ";; old answer:\n"), ans, (resplen > anssiz) ? anssiz : resplen);
1153 goto retry;
1154 }
1155 if (!(statp->options & RES_INSECURE1) &&
1156 !res_ourserver_p(statp, (struct sockaddr*) (void*) &from)) {
1157 /*
1158 * response from wrong server? ignore it.
1159 * XXX - potential security hazard could
1160 * be detected here.
1161 */
1162 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
1163 (stdout, ";; not our server:\n"), ans, (resplen > anssiz) ? anssiz : resplen);
1164 goto retry;
1165 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001166#ifdef RES_USE_EDNS0
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001167 if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) {
1168 /*
1169 * Do not retry if the server do not understand EDNS0.
1170 * The case has to be captured here, as FORMERR packet do not
1171 * carry query section, hence res_queriesmatch() returns 0.
1172 */
1173 DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query with EDNS0:\n"), ans,
1174 (resplen > anssiz) ? anssiz : resplen);
1175 /* record the error */
1176 statp->_flags |= RES_F_EDNS0ERR;
1177 res_nclose(statp);
1178 return (0);
1179 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001180#endif
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001181 if (!(statp->options & RES_INSECURE2) &&
1182 !res_queriesmatch(buf, buf + buflen, ans, ans + anssiz)) {
1183 /*
1184 * response contains wrong query? ignore it.
1185 * XXX - potential security hazard could
1186 * be detected here.
1187 */
1188 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
1189 (stdout, ";; wrong query name:\n"), ans, (resplen > anssiz) ? anssiz : resplen);
1190 goto retry;
1191 ;
1192 }
1193 done = evNowTime();
1194 *delay = _res_stats_calculate_rtt(&done, &now);
1195 if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || anhp->rcode == REFUSED) {
1196 DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query:\n"), ans,
1197 (resplen > anssiz) ? anssiz : resplen);
1198 res_nclose(statp);
1199 /* don't retry if called from dig */
1200 if (!statp->pfcode) {
1201 *rcode = anhp->rcode;
1202 return (0);
1203 }
1204 }
1205 if (!(statp->options & RES_IGNTC) && anhp->tc) {
1206 /*
1207 * To get the rest of answer,
1208 * use TCP with same server.
1209 */
1210 Dprint(statp->options & RES_DEBUG, (stdout, ";; truncated answer\n"));
1211 *v_circuit = 1;
1212 res_nclose(statp);
1213 return (1);
1214 }
1215 /*
1216 * All is well, or the error is fatal. Signal that the
1217 * next nameserver ought not be tried.
1218 */
1219 if (resplen > 0) {
1220 *rcode = anhp->rcode;
1221 }
1222 return (resplen);
Bernie Innocenti55864192018-08-30 04:05:20 +09001223}
1224
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001225static void Aerror(const res_state statp, FILE* file, const char* string, int error,
1226 const struct sockaddr* address, int alen) {
1227 int save = errno;
1228 char hbuf[NI_MAXHOST];
1229 char sbuf[NI_MAXSERV];
Bernie Innocenti55864192018-08-30 04:05:20 +09001230
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001231 if ((statp->options & RES_DEBUG) != 0U) {
1232 if (getnameinfo(address, (socklen_t) alen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
1233 niflags)) {
1234 strncpy(hbuf, "?", sizeof(hbuf) - 1);
1235 hbuf[sizeof(hbuf) - 1] = '\0';
1236 strncpy(sbuf, "?", sizeof(sbuf) - 1);
1237 sbuf[sizeof(sbuf) - 1] = '\0';
1238 }
1239 fprintf(file, "res_send: %s ([%s].%s): %s\n", string, hbuf, sbuf, strerror(error));
1240 }
1241 errno = save;
Bernie Innocenti55864192018-08-30 04:05:20 +09001242}
1243
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001244static void Perror(const res_state statp, FILE* file, const char* string, int error) {
1245 int save = errno;
Bernie Innocenti55864192018-08-30 04:05:20 +09001246
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001247 if ((statp->options & RES_DEBUG) != 0U)
1248 fprintf(file, "res_send: %s: %s\n", string, strerror(error));
1249 errno = save;
Bernie Innocenti55864192018-08-30 04:05:20 +09001250}
1251
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001252static int sock_eq(struct sockaddr* a, struct sockaddr* b) {
1253 struct sockaddr_in *a4, *b4;
1254 struct sockaddr_in6 *a6, *b6;
Bernie Innocenti55864192018-08-30 04:05:20 +09001255
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001256 if (a->sa_family != b->sa_family) return 0;
1257 switch (a->sa_family) {
1258 case AF_INET:
1259 a4 = (struct sockaddr_in*) (void*) a;
1260 b4 = (struct sockaddr_in*) (void*) b;
1261 return a4->sin_port == b4->sin_port && a4->sin_addr.s_addr == b4->sin_addr.s_addr;
1262 case AF_INET6:
1263 a6 = (struct sockaddr_in6*) (void*) a;
1264 b6 = (struct sockaddr_in6*) (void*) b;
1265 return a6->sin6_port == b6->sin6_port &&
Bernie Innocenti55864192018-08-30 04:05:20 +09001266#ifdef HAVE_SIN6_SCOPE_ID
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001267 a6->sin6_scope_id == b6->sin6_scope_id &&
Bernie Innocenti55864192018-08-30 04:05:20 +09001268#endif
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001269 IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
1270 default:
1271 return 0;
1272 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001273}