blob: 5da47fd4436cbf5f9e701d3def480a23e03dbb90 [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 Innocentie9ba09c2018-09-12 23:20:10 +090077constexpr bool kVerboseLogging = false;
78#define LOG_TAG "res_send"
79
Bernie Innocenti55864192018-08-30 04:05:20 +090080#include <sys/param.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090081#include <sys/socket.h>
Bernie Innocentif12d5bb2018-08-31 14:09:46 +090082#include <sys/time.h>
83#include <sys/types.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090084#include <sys/uio.h>
85
Bernie Innocenti55864192018-08-30 04:05:20 +090086#include <arpa/inet.h>
Bernie Innocentif12d5bb2018-08-31 14:09:46 +090087#include <arpa/nameser.h>
88#include <netinet/in.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090089
90#include <errno.h>
91#include <fcntl.h>
92#include <netdb.h>
93#include <poll.h>
Bernie Innocenti55864192018-08-30 04:05:20 +090094#include <signal.h>
95#include <stdio.h>
96#include <stdlib.h>
97#include <string.h>
98#include <time.h>
99#include <unistd.h>
100
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900101#include <android-base/logging.h>
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900102#include <android/multinetwork.h> // ResNsendFlags
Bernie Innocenti55864192018-08-30 04:05:20 +0900103
Mike Yua46fae72018-11-01 20:07:00 +0800104#include <netdutils/Slice.h>
Bernie Innocentiad4e26e2019-01-30 11:16:36 +0900105#include "DnsTlsDispatcher.h"
106#include "DnsTlsTransport.h"
107#include "PrivateDnsConfiguration.h"
Bernie Innocenti189eb502018-10-01 23:10:18 +0900108#include "netd_resolv/resolv.h"
109#include "netd_resolv/stats.h"
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900110#include "private/android_filesystem_config.h"
Bernie Innocenti189eb502018-10-01 23:10:18 +0900111#include "res_state_ext.h"
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900112#include "resolv_cache.h"
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900113#include "resolv_private.h"
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900114
Mike Yua46fae72018-11-01 20:07:00 +0800115// TODO: use the namespace something like android::netd_resolv for libnetd_resolv
116using namespace android::net;
Bernie Innocentiad4e26e2019-01-30 11:16:36 +0900117using android::netdutils::Slice;
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900118
119#define VLOG if (!kVerboseLogging) {} else LOG(INFO)
120
121#ifndef RESOLV_ALLOW_VERBOSE_LOGGING
122static_assert(kVerboseLogging == false,
123 "Verbose logging floods logs at high-rate and exposes privacy-sensitive information. "
124 "Do not enable in release builds.");
Bernie Innocenti55864192018-08-30 04:05:20 +0900125#endif
Bernie Innocenti2fd418e2018-08-30 12:04:03 +0900126
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900127#ifndef DEBUG
128#define Dprint(cond, args) /*empty*/
129#define DprintQ(cond, args, query, size) /*empty*/
130#else
131// TODO: convert to Android logging
132#define Dprint(cond, args) \
133 if (cond) { \
134 fprintf args; \
135 } else { \
136 }
137#define DprintQ(cond, args, query, size) \
138 if (cond) { \
139 fprintf args; \
140 res_pquery(statp, query, size, stdout); \
141 } else { \
142 }
143#endif // DEBUG
Bernie Innocenti55864192018-08-30 04:05:20 +0900144
Mike Yua46fae72018-11-01 20:07:00 +0800145static DnsTlsDispatcher sDnsTlsDispatcher;
146
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900147static int get_salen(const struct sockaddr*);
148static struct sockaddr* get_nsaddr(res_state, size_t);
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900149static int send_vc(res_state, res_params* params, const u_char*, int, u_char*, int, int*, int,
150 time_t*, int*, int*);
151static int send_dg(res_state, res_params* params, const u_char*, int, u_char*, int, int*, int, int*,
152 int*, time_t*, int*, int*);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900153static void Aerror(const res_state, FILE*, const char*, int, const struct sockaddr*, int);
154static void Perror(const res_state, FILE*, const char*, int);
155static int sock_eq(struct sockaddr*, struct sockaddr*);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900156static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
157 const struct timespec timeout);
Bernie Innocenti55864192018-08-30 04:05:20 +0900158static int retrying_poll(const int sock, short events, const struct timespec* finish);
Luke Huang490551d2018-11-21 20:37:50 +0800159static int res_tls_send(res_state, const Slice query, const Slice answer, int* rcode,
Mike Yu69615f62018-11-06 15:42:36 +0800160 bool* fallback);
Bernie Innocenti55864192018-08-30 04:05:20 +0900161
162/* BIONIC-BEGIN: implement source port randomization */
Bernie Innocenti55864192018-08-30 04:05:20 +0900163
Bernie Innocentif89b3512018-08-30 07:34:37 +0900164// BEGIN: Code copied from ISC eventlib
165// TODO: move away from this code
166
167#define BILLION 1000000000
168
169static struct timespec evConsTime(time_t sec, long nsec) {
170 struct timespec x;
171
172 x.tv_sec = sec;
173 x.tv_nsec = nsec;
174 return (x);
175}
176
177static struct timespec evAddTime(struct timespec addend1, struct timespec addend2) {
178 struct timespec x;
179
180 x.tv_sec = addend1.tv_sec + addend2.tv_sec;
181 x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
182 if (x.tv_nsec >= BILLION) {
183 x.tv_sec++;
184 x.tv_nsec -= BILLION;
185 }
186 return (x);
187}
188
189static struct timespec evSubTime(struct timespec minuend, struct timespec subtrahend) {
190 struct timespec x;
191
192 x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
193 if (minuend.tv_nsec >= subtrahend.tv_nsec)
194 x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
195 else {
196 x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
197 x.tv_sec--;
198 }
199 return (x);
200}
201
202static int evCmpTime(struct timespec a, struct timespec b) {
203#define SGN(x) ((x) < 0 ? (-1) : (x) > 0 ? (1) : (0));
204 time_t s = a.tv_sec - b.tv_sec;
205 long n;
206
207 if (s != 0) return SGN(s);
208
209 n = a.tv_nsec - b.tv_nsec;
210 return SGN(n);
211}
212
Bernie Innocentif89b3512018-08-30 07:34:37 +0900213static struct timespec evNowTime(void) {
Bernie Innocentif89b3512018-08-30 07:34:37 +0900214 struct timespec tsnow;
Bernie Innocenti357339c2018-08-31 16:11:41 +0900215 clock_gettime(CLOCK_REALTIME, &tsnow);
216 return tsnow;
Bernie Innocentif89b3512018-08-30 07:34:37 +0900217}
218
219static struct iovec evConsIovec(void* buf, size_t cnt) {
220 struct iovec ret;
221
222 memset(&ret, 0xf5, sizeof ret);
223 ret.iov_base = buf;
224 ret.iov_len = cnt;
Bernie Innocenti357339c2018-08-31 16:11:41 +0900225 return ret;
Bernie Innocentif89b3512018-08-30 07:34:37 +0900226}
227
228// END: Code copied from ISC eventlib
229
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900230static int random_bind(int s, int family) {
nuccachene172a4e2018-10-23 17:10:58 +0800231 sockaddr_union u;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900232 int j;
233 socklen_t slen;
Bernie Innocenti55864192018-08-30 04:05:20 +0900234
235 /* clear all, this also sets the IP4/6 address to 'any' */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900236 memset(&u, 0, sizeof u);
Bernie Innocenti55864192018-08-30 04:05:20 +0900237
238 switch (family) {
239 case AF_INET:
240 u.sin.sin_family = family;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900241 slen = sizeof u.sin;
Bernie Innocenti55864192018-08-30 04:05:20 +0900242 break;
243 case AF_INET6:
244 u.sin6.sin6_family = family;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900245 slen = sizeof u.sin6;
Bernie Innocenti55864192018-08-30 04:05:20 +0900246 break;
247 default:
248 errno = EPROTO;
249 return -1;
250 }
251
252 /* first try to bind to a random source port a few times */
253 for (j = 0; j < 10; j++) {
254 /* find a random port between 1025 .. 65534 */
Luke Huang042e9422019-02-13 14:05:02 +0800255 int port = 1025 + (arc4random_uniform(65535 - 1025));
Bernie Innocenti55864192018-08-30 04:05:20 +0900256 if (family == AF_INET)
257 u.sin.sin_port = htons(port);
258 else
259 u.sin6.sin6_port = htons(port);
260
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900261 if (!bind(s, &u.sa, slen)) return 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900262 }
263
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900264 // nothing after 10 attempts, our network table is probably busy
265 // let the system decide which port is best
Bernie Innocenti55864192018-08-30 04:05:20 +0900266 if (family == AF_INET)
267 u.sin.sin_port = 0;
268 else
269 u.sin6.sin6_port = 0;
270
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900271 return bind(s, &u.sa, slen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900272}
273/* BIONIC-END */
274
Bernie Innocenti55864192018-08-30 04:05:20 +0900275/* int
276 * res_isourserver(ina)
277 * looks up "ina" in _res.ns_addr_list[]
278 * returns:
279 * 0 : not found
280 * >0 : found
281 * author:
282 * paul vixie, 29may94
283 */
Bernie Innocenti4acba1a2018-09-26 11:52:04 +0900284static int res_ourserver_p(const res_state statp, const sockaddr* sa) {
285 const sockaddr_in *inp, *srv;
286 const sockaddr_in6 *in6p, *srv6;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900287 int ns;
Bernie Innocenti55864192018-08-30 04:05:20 +0900288
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900289 switch (sa->sa_family) {
290 case AF_INET:
291 inp = (const struct sockaddr_in*) (const void*) sa;
292 for (ns = 0; ns < statp->nscount; ns++) {
293 srv = (struct sockaddr_in*) (void*) get_nsaddr(statp, (size_t) ns);
294 if (srv->sin_family == inp->sin_family && srv->sin_port == inp->sin_port &&
295 (srv->sin_addr.s_addr == INADDR_ANY ||
296 srv->sin_addr.s_addr == inp->sin_addr.s_addr))
Bernie Innocenti4acba1a2018-09-26 11:52:04 +0900297 return 1;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900298 }
299 break;
300 case AF_INET6:
Ken Chencf6ded62018-10-16 23:12:09 +0800301 if (statp->_u._ext.ext == NULL) break;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900302 in6p = (const struct sockaddr_in6*) (const void*) sa;
303 for (ns = 0; ns < statp->nscount; ns++) {
304 srv6 = (struct sockaddr_in6*) (void*) get_nsaddr(statp, (size_t) ns);
305 if (srv6->sin6_family == in6p->sin6_family && srv6->sin6_port == in6p->sin6_port &&
Bernie Innocenti55864192018-08-30 04:05:20 +0900306#ifdef HAVE_SIN6_SCOPE_ID
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900307 (srv6->sin6_scope_id == 0 || srv6->sin6_scope_id == in6p->sin6_scope_id) &&
Bernie Innocenti55864192018-08-30 04:05:20 +0900308#endif
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900309 (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
310 IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
Bernie Innocenti4acba1a2018-09-26 11:52:04 +0900311 return 1;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900312 }
313 break;
314 default:
315 break;
316 }
Bernie Innocenti4acba1a2018-09-26 11:52:04 +0900317 return 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900318}
319
320/* int
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900321 * res_nameinquery(name, type, cl, buf, eom)
322 * look for (name, type, cl) in the query section of packet (buf, eom)
Bernie Innocenti55864192018-08-30 04:05:20 +0900323 * requires:
324 * buf + HFIXEDSZ <= eom
325 * returns:
326 * -1 : format error
327 * 0 : not found
328 * >0 : found
329 * author:
330 * paul vixie, 29may94
331 */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900332int res_nameinquery(const char* name, int type, int cl, const u_char* buf, const u_char* eom) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900333 const u_char* cp = buf + HFIXEDSZ;
334 int qdcount = ntohs(((const HEADER*) (const void*) buf)->qdcount);
Bernie Innocenti55864192018-08-30 04:05:20 +0900335
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900336 while (qdcount-- > 0) {
337 char tname[MAXDNAME + 1];
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900338 int n = dn_expand(buf, eom, cp, tname, sizeof tname);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900339 if (n < 0) return (-1);
340 cp += n;
341 if (cp + 2 * INT16SZ > eom) return (-1);
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900342 int ttype = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900343 cp += INT16SZ;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900344 int tclass = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900345 cp += INT16SZ;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900346 if (ttype == type && tclass == cl && ns_samename(tname, name) == 1) return (1);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900347 }
348 return (0);
Bernie Innocenti55864192018-08-30 04:05:20 +0900349}
350
351/* int
352 * res_queriesmatch(buf1, eom1, buf2, eom2)
353 * is there a 1:1 mapping of (name,type,class)
354 * in (buf1,eom1) and (buf2,eom2)?
355 * returns:
356 * -1 : format error
357 * 0 : not a 1:1 mapping
358 * >0 : is a 1:1 mapping
359 * author:
360 * paul vixie, 29may94
361 */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900362int res_queriesmatch(const u_char* buf1, const u_char* eom1, const u_char* buf2,
363 const u_char* eom2) {
364 const u_char* cp = buf1 + HFIXEDSZ;
365 int qdcount = ntohs(((const HEADER*) (const void*) buf1)->qdcount);
Bernie Innocenti55864192018-08-30 04:05:20 +0900366
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900367 if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900368
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900369 /*
370 * Only header section present in replies to
371 * dynamic update packets.
372 */
373 if ((((const HEADER*) (const void*) buf1)->opcode == ns_o_update) &&
374 (((const HEADER*) (const void*) buf2)->opcode == ns_o_update))
375 return (1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900376
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900377 if (qdcount != ntohs(((const HEADER*) (const void*) buf2)->qdcount)) return (0);
378 while (qdcount-- > 0) {
379 char tname[MAXDNAME + 1];
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900380 int n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900381 if (n < 0) return (-1);
382 cp += n;
383 if (cp + 2 * INT16SZ > eom1) return (-1);
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900384 int ttype = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900385 cp += INT16SZ;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900386 int tclass = ns_get16(cp);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900387 cp += INT16SZ;
388 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0);
389 }
390 return (1);
Bernie Innocenti55864192018-08-30 04:05:20 +0900391}
392
Luke Huang952d0942018-12-26 16:53:03 +0800393int res_nsend(res_state statp, const u_char* buf, int buflen, u_char* ans, int anssiz, int* rcode,
394 uint32_t flags) {
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900395 int gotsomewhere, terrno, v_circuit, resplen, n;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900396 ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
Bernie Innocenti55864192018-08-30 04:05:20 +0900397
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900398 if (anssiz < HFIXEDSZ) {
Luke Huang8c0e98f2018-12-03 15:37:28 +0800399 // TODO: Remove errno once callers stop using it
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900400 errno = EINVAL;
Luke Huang8c0e98f2018-12-03 15:37:28 +0800401 return -EINVAL;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900402 }
403 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
404 (stdout, ";; res_send()\n"), buf, buflen);
405 v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
406 gotsomewhere = 0;
407 terrno = ETIMEDOUT;
Bernie Innocenti55864192018-08-30 04:05:20 +0900408
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900409 int anslen = 0;
Luke Huang952d0942018-12-26 16:53:03 +0800410 cache_status = _resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen, flags);
Bernie Innocenti55864192018-08-30 04:05:20 +0900411
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900412 if (cache_status == RESOLV_CACHE_FOUND) {
413 return anslen;
414 } else if (cache_status != RESOLV_CACHE_UNSUPPORTED) {
415 // had a cache miss for a known network, so populate the thread private
416 // data so the normal resolve path can do its thing
417 _resolv_populate_res_for_net(statp);
418 }
419 if (statp->nscount == 0) {
420 // We have no nameservers configured, so there's no point trying.
421 // Tell the cache the query failed, or any retries and anyone else asking the same
422 // question will block for PENDING_REQUEST_TIMEOUT seconds instead of failing fast.
Luke Huang952d0942018-12-26 16:53:03 +0800423 _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
Luke Huang8c0e98f2018-12-03 15:37:28 +0800424
425 // TODO: Remove errno once callers stop using it
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900426 errno = ESRCH;
Luke Huang8c0e98f2018-12-03 15:37:28 +0800427 return -ESRCH;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900428 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900429
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900430 /*
431 * If the ns_addr_list in the resolver context has changed, then
432 * invalidate our cached copy and the associated timing data.
433 */
Ken Chencf6ded62018-10-16 23:12:09 +0800434 if (statp->_u._ext.nscount != 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900435 int needclose = 0;
436 struct sockaddr_storage peer;
437 socklen_t peerlen;
Bernie Innocenti55864192018-08-30 04:05:20 +0900438
Ken Chencf6ded62018-10-16 23:12:09 +0800439 if (statp->_u._ext.nscount != statp->nscount) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900440 needclose++;
441 } else {
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900442 for (int ns = 0; ns < statp->nscount; ns++) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900443 if (statp->nsaddr_list[ns].sin_family &&
444 !sock_eq((struct sockaddr*) (void*) &statp->nsaddr_list[ns],
Ken Chencf6ded62018-10-16 23:12:09 +0800445 (struct sockaddr*) (void*) &statp->_u._ext.ext->nsaddrs[ns])) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900446 needclose++;
447 break;
448 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900449
Ken Chencf6ded62018-10-16 23:12:09 +0800450 if (statp->_u._ext.nssocks[ns] == -1) continue;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900451 peerlen = sizeof(peer);
Ken Chencf6ded62018-10-16 23:12:09 +0800452 if (getpeername(statp->_u._ext.nssocks[ns], (struct sockaddr*) (void*) &peer,
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900453 &peerlen) < 0) {
454 needclose++;
455 break;
456 }
457 if (!sock_eq((struct sockaddr*) (void*) &peer, get_nsaddr(statp, (size_t) ns))) {
458 needclose++;
459 break;
460 }
461 }
462 }
463 if (needclose) {
464 res_nclose(statp);
Ken Chencf6ded62018-10-16 23:12:09 +0800465 statp->_u._ext.nscount = 0;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900466 }
467 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900468
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900469 /*
470 * Maybe initialize our private copy of the ns_addr_list.
471 */
Ken Chencf6ded62018-10-16 23:12:09 +0800472 if (statp->_u._ext.nscount == 0) {
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900473 for (int ns = 0; ns < statp->nscount; ns++) {
Ken Chencf6ded62018-10-16 23:12:09 +0800474 statp->_u._ext.nstimes[ns] = RES_MAXTIME;
475 statp->_u._ext.nssocks[ns] = -1;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900476 if (!statp->nsaddr_list[ns].sin_family) continue;
Ken Chencf6ded62018-10-16 23:12:09 +0800477 statp->_u._ext.ext->nsaddrs[ns].sin = statp->nsaddr_list[ns];
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900478 }
Ken Chencf6ded62018-10-16 23:12:09 +0800479 statp->_u._ext.nscount = statp->nscount;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900480 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900481
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900482 /*
483 * Some resolvers want to even out the load on their nameservers.
484 * Note that RES_BLAST overrides RES_ROTATE.
485 */
486 if ((statp->options & RES_ROTATE) != 0U && (statp->options & RES_BLAST) == 0U) {
nuccachene172a4e2018-10-23 17:10:58 +0800487 sockaddr_union inu;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900488 struct sockaddr_in ina;
489 int lastns = statp->nscount - 1;
490 int fd;
491 u_int16_t nstime;
Bernie Innocenti55864192018-08-30 04:05:20 +0900492
Ken Chencf6ded62018-10-16 23:12:09 +0800493 if (statp->_u._ext.ext != NULL) inu = statp->_u._ext.ext->nsaddrs[0];
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900494 ina = statp->nsaddr_list[0];
Ken Chencf6ded62018-10-16 23:12:09 +0800495 fd = statp->_u._ext.nssocks[0];
496 nstime = statp->_u._ext.nstimes[0];
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900497 for (int ns = 0; ns < lastns; ns++) {
Ken Chencf6ded62018-10-16 23:12:09 +0800498 if (statp->_u._ext.ext != NULL)
499 statp->_u._ext.ext->nsaddrs[ns] = statp->_u._ext.ext->nsaddrs[ns + 1];
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900500 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
Ken Chencf6ded62018-10-16 23:12:09 +0800501 statp->_u._ext.nssocks[ns] = statp->_u._ext.nssocks[ns + 1];
502 statp->_u._ext.nstimes[ns] = statp->_u._ext.nstimes[ns + 1];
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900503 }
Ken Chencf6ded62018-10-16 23:12:09 +0800504 if (statp->_u._ext.ext != NULL) statp->_u._ext.ext->nsaddrs[lastns] = inu;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900505 statp->nsaddr_list[lastns] = ina;
Ken Chencf6ded62018-10-16 23:12:09 +0800506 statp->_u._ext.nssocks[lastns] = fd;
507 statp->_u._ext.nstimes[lastns] = nstime;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900508 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900509
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900510 res_stats stats[MAXNS];
511 res_params params;
waynemad193e4d2019-02-18 17:47:59 +0800512 int revision_id = resolv_cache_get_resolver_stats(statp->netid, &params, stats);
513 bool usable_servers[MAXNS];
514 android_net_res_stats_get_usable_servers(&params, stats, statp->nscount, usable_servers);
515 if (params.retry_count != 0) statp->retry = params.retry_count;
516
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900517 /*
518 * Send request, RETRY times, or until successful.
519 */
Luke Huang952d0942018-12-26 16:53:03 +0800520 int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : statp->retry;
521
522 for (int attempt = 0; attempt < retryTimes; ++attempt) {
Bernie Innocenti55864192018-08-30 04:05:20 +0900523
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900524 for (int ns = 0; ns < statp->nscount; ns++) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900525 if (!usable_servers[ns]) continue;
526 struct sockaddr* nsap;
527 int nsaplen;
528 time_t now = 0;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900529 int delay = 0;
Mike Yu69615f62018-11-06 15:42:36 +0800530 *rcode = RCODE_INTERNAL_ERROR;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900531 nsap = get_nsaddr(statp, (size_t) ns);
532 nsaplen = get_salen(nsap);
Bernie Innocenti55864192018-08-30 04:05:20 +0900533
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900534 same_ns:
Mike Yu69615f62018-11-06 15:42:36 +0800535 // TODO: Since we expect there is only one DNS server being queried here while this
536 // function tries to query all of private DNS servers. Consider moving it to other
537 // reasonable place. In addition, maybe add stats for private DNS.
538 if (!statp->use_local_nameserver) {
539 bool fallback = false;
540 resplen = res_tls_send(statp, Slice(const_cast<u_char*>(buf), buflen),
541 Slice(ans, anssiz), rcode, &fallback);
542 if (resplen > 0) {
543 if (cache_status == RESOLV_CACHE_NOTFOUND) {
544 _resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
545 }
546 return resplen;
Mike Yua46fae72018-11-01 20:07:00 +0800547 }
Mike Yu69615f62018-11-06 15:42:36 +0800548 if (!fallback) {
Luke Huang952d0942018-12-26 16:53:03 +0800549 _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
Luke Huang8c0e98f2018-12-03 15:37:28 +0800550 res_nclose(statp);
551 return -terrno;
Mike Yu69615f62018-11-06 15:42:36 +0800552 }
553 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900554
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900555 [[maybe_unused]] static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
556 [[maybe_unused]] char abuf[NI_MAXHOST];
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900557 Dprint(((statp->options & RES_DEBUG) &&
558 getnameinfo(nsap, (socklen_t) nsaplen, abuf, sizeof(abuf), NULL, 0, niflags) ==
559 0),
560 (stdout, ";; Querying server (# %d) address = %s\n", ns + 1, abuf));
Bernie Innocenti55864192018-08-30 04:05:20 +0900561
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900562 if (v_circuit) {
563 /* Use VC; at most one attempt per server. */
Luke Huang952d0942018-12-26 16:53:03 +0800564 bool shouldRecordStats = (attempt == 0);
565 attempt = retryTimes;
Bernie Innocenti55864192018-08-30 04:05:20 +0900566
Mike Yu69615f62018-11-06 15:42:36 +0800567 n = send_vc(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &now, rcode,
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900568 &delay);
Bernie Innocenti55864192018-08-30 04:05:20 +0900569
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900570 /*
571 * Only record stats the first time we try a query. This ensures that
572 * queries that deterministically fail (e.g., a name that always returns
573 * SERVFAIL or times out) do not unduly affect the stats.
574 */
Luke Huang952d0942018-12-26 16:53:03 +0800575 if (shouldRecordStats) {
Bernie Innocenti189eb502018-10-01 23:10:18 +0900576 res_sample sample;
Mike Yu69615f62018-11-06 15:42:36 +0800577 _res_stats_set_sample(&sample, now, *rcode, delay);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900578 _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
579 params.max_samples);
580 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900581
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900582 VLOG << "used send_vc " << n;
Bernie Innocenti55864192018-08-30 04:05:20 +0900583
Luke Huang8c0e98f2018-12-03 15:37:28 +0800584 if (n < 0) {
Luke Huang952d0942018-12-26 16:53:03 +0800585 _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
Luke Huang8c0e98f2018-12-03 15:37:28 +0800586 res_nclose(statp);
587 return -terrno;
588 };
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900589 if (n == 0) goto next_ns;
590 resplen = n;
591 } else {
592 /* Use datagrams. */
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900593 VLOG << "using send_dg";
Bernie Innocenti55864192018-08-30 04:05:20 +0900594
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900595 n = send_dg(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &v_circuit,
Mike Yu69615f62018-11-06 15:42:36 +0800596 &gotsomewhere, &now, rcode, &delay);
Bernie Innocenti55864192018-08-30 04:05:20 +0900597
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900598 /* Only record stats the first time we try a query. See above. */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900599 if (attempt == 0) {
Bernie Innocenti189eb502018-10-01 23:10:18 +0900600 res_sample sample;
Mike Yu69615f62018-11-06 15:42:36 +0800601 _res_stats_set_sample(&sample, now, *rcode, delay);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900602 _resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
603 params.max_samples);
604 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900605
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900606 VLOG << "used send_dg " << n;
Bernie Innocenti55864192018-08-30 04:05:20 +0900607
Luke Huang8c0e98f2018-12-03 15:37:28 +0800608 if (n < 0) {
Luke Huang952d0942018-12-26 16:53:03 +0800609 _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
Luke Huang8c0e98f2018-12-03 15:37:28 +0800610 res_nclose(statp);
611 return -terrno;
612 };
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900613 if (n == 0) goto next_ns;
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900614 VLOG << "time=" << time(NULL);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900615 if (v_circuit) goto same_ns;
616 resplen = n;
617 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900618
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900619 Dprint((statp->options & RES_DEBUG) ||
620 ((statp->pfcode & RES_PRF_REPLY) && (statp->pfcode & RES_PRF_HEAD1)),
621 (stdout, ";; got answer:\n"));
Bernie Innocenti55864192018-08-30 04:05:20 +0900622
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900623 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
624 (stdout, "%s", ""), ans, (resplen > anssiz) ? anssiz : resplen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900625
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900626 if (cache_status == RESOLV_CACHE_NOTFOUND) {
627 _resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
628 }
629 /*
630 * If we have temporarily opened a virtual circuit,
631 * or if we haven't been asked to keep a socket open,
632 * close the socket.
633 */
634 if ((v_circuit && (statp->options & RES_USEVC) == 0U) ||
635 (statp->options & RES_STAYOPEN) == 0U) {
636 res_nclose(statp);
637 }
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900638 return (resplen);
639 next_ns:;
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900640 } // for each ns
641 } // for each retry
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900642 res_nclose(statp);
643 if (!v_circuit) {
Luke Huang8c0e98f2018-12-03 15:37:28 +0800644 if (!gotsomewhere) {
645 // TODO: Remove errno once callers stop using it
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900646 errno = ECONNREFUSED; /* no nameservers found */
Luke Huang8c0e98f2018-12-03 15:37:28 +0800647 terrno = ECONNREFUSED;
648 } else {
649 // TODO: Remove errno once callers stop using it
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900650 errno = ETIMEDOUT; /* no answer obtained */
Luke Huang8c0e98f2018-12-03 15:37:28 +0800651 terrno = ETIMEDOUT;
652 }
653 } else {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900654 errno = terrno;
Luke Huang8c0e98f2018-12-03 15:37:28 +0800655 }
Luke Huang952d0942018-12-26 16:53:03 +0800656 _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
Bernie Innocenti55864192018-08-30 04:05:20 +0900657
Luke Huang8c0e98f2018-12-03 15:37:28 +0800658 return -terrno;
Bernie Innocenti55864192018-08-30 04:05:20 +0900659}
660
661/* Private */
662
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900663static int get_salen(const struct sockaddr* sa) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900664 if (sa->sa_family == AF_INET)
665 return (sizeof(struct sockaddr_in));
666 else if (sa->sa_family == AF_INET6)
667 return (sizeof(struct sockaddr_in6));
668 else
669 return (0); /* unknown, die on connect */
Bernie Innocenti55864192018-08-30 04:05:20 +0900670}
671
672/*
673 * pick appropriate nsaddr_list for use. see res_init() for initialization.
674 */
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900675static struct sockaddr* get_nsaddr(res_state statp, size_t n) {
Ken Chencf6ded62018-10-16 23:12:09 +0800676 if (!statp->nsaddr_list[n].sin_family && statp->_u._ext.ext) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900677 /*
Ken Chencf6ded62018-10-16 23:12:09 +0800678 * - statp->_u._ext.ext->nsaddrs[n] holds an address that is larger
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900679 * than struct sockaddr, and
680 * - user code did not update statp->nsaddr_list[n].
681 */
Ken Chencf6ded62018-10-16 23:12:09 +0800682 return (struct sockaddr*) (void*) &statp->_u._ext.ext->nsaddrs[n];
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900683 } else {
684 /*
685 * - user code updated statp->nsaddr_list[n], or
686 * - statp->nsaddr_list[n] has the same content as
Ken Chencf6ded62018-10-16 23:12:09 +0800687 * statp->_u._ext.ext->nsaddrs[n].
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900688 */
689 return (struct sockaddr*) (void*) &statp->nsaddr_list[n];
690 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900691}
692
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900693static struct timespec get_timeout(const res_state statp, const res_params* params, const int ns) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900694 int msec;
695 if (params->base_timeout_msec != 0) {
696 // TODO: scale the timeout by retry attempt and maybe number of servers
697 msec = params->base_timeout_msec;
698 } else {
699 // Legacy algorithm which scales the timeout by nameserver number.
700 // For instance, with 4 nameservers: 5s, 2.5s, 5s, 10s
701 // This has no effect with 1 or 2 nameservers
702 msec = (statp->retrans * 1000) << ns;
703 if (ns > 0) {
704 msec /= statp->nscount;
705 }
706 if (msec < 1000) {
707 msec = 1000; // Use at least 100ms
708 }
709 }
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900710 VLOG << "using timeout of " << msec << " msec";
Bernie Innocenti55864192018-08-30 04:05:20 +0900711
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900712 struct timespec result;
713 result.tv_sec = msec / 1000;
714 result.tv_nsec = (msec % 1000) * 1000000;
715 return result;
Bernie Innocenti55864192018-08-30 04:05:20 +0900716}
717
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900718static int send_vc(res_state statp, res_params* params, const u_char* buf, int buflen, u_char* ans,
719 int anssiz, int* terrno, int ns, time_t* at, int* rcode, int* delay) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900720 *at = time(NULL);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900721 *delay = 0;
722 const HEADER* hp = (const HEADER*) (const void*) buf;
723 HEADER* anhp = (HEADER*) (void*) ans;
724 struct sockaddr* nsap;
725 int nsaplen;
726 int truncating, connreset, resplen, n;
727 struct iovec iov[2];
728 u_short len;
729 u_char* cp;
Bernie Innocenti55864192018-08-30 04:05:20 +0900730
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900731 VLOG << "using send_vc";
Bernie Innocenti55864192018-08-30 04:05:20 +0900732
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900733 nsap = get_nsaddr(statp, (size_t) ns);
734 nsaplen = get_salen(nsap);
Bernie Innocenti55864192018-08-30 04:05:20 +0900735
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900736 connreset = 0;
737same_ns:
738 truncating = 0;
Bernie Innocenti55864192018-08-30 04:05:20 +0900739
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900740 struct timespec now = evNowTime();
Bernie Innocenti55864192018-08-30 04:05:20 +0900741
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900742 /* Are we still talking to whom we want to talk to? */
743 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
744 struct sockaddr_storage peer;
745 socklen_t size = sizeof peer;
746 unsigned old_mark;
747 socklen_t mark_size = sizeof(old_mark);
748 if (getpeername(statp->_vcsock, (struct sockaddr*) (void*) &peer, &size) < 0 ||
749 !sock_eq((struct sockaddr*) (void*) &peer, nsap) ||
750 getsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &old_mark, &mark_size) < 0 ||
751 old_mark != statp->_mark) {
752 res_nclose(statp);
753 statp->_flags &= ~RES_F_VC;
754 }
755 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900756
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900757 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
758 if (statp->_vcsock >= 0) res_nclose(statp);
Bernie Innocenti55864192018-08-30 04:05:20 +0900759
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900760 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
761 if (statp->_vcsock < 0) {
762 switch (errno) {
763 case EPROTONOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900764 case EPFNOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900765 case EAFNOSUPPORT:
766 Perror(statp, stderr, "socket(vc)", errno);
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900767 return 0;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900768 default:
769 *terrno = errno;
770 Perror(statp, stderr, "socket(vc)", errno);
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900771 return -1;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900772 }
773 }
774 fchown(statp->_vcsock, AID_DNS, -1);
775 if (statp->_mark != MARK_UNSET) {
776 if (setsockopt(statp->_vcsock, SOL_SOCKET, SO_MARK, &statp->_mark,
777 sizeof(statp->_mark)) < 0) {
778 *terrno = errno;
779 Perror(statp, stderr, "setsockopt", errno);
780 return -1;
781 }
782 }
783 errno = 0;
784 if (random_bind(statp->_vcsock, nsap->sa_family) < 0) {
785 *terrno = errno;
786 Aerror(statp, stderr, "bind/vc", errno, nsap, nsaplen);
787 res_nclose(statp);
788 return (0);
789 }
790 if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t) nsaplen,
791 get_timeout(statp, params, ns)) < 0) {
792 *terrno = errno;
793 Aerror(statp, stderr, "connect/vc", errno, nsap, nsaplen);
794 res_nclose(statp);
795 /*
796 * The way connect_with_timeout() is implemented prevents us from reliably
797 * determining whether this was really a timeout or e.g. ECONNREFUSED. Since
798 * currently both cases are handled in the same way, there is no need to
799 * change this (yet). If we ever need to reliably distinguish between these
800 * cases, both connect_with_timeout() and retrying_poll() need to be
801 * modified, though.
802 */
803 *rcode = RCODE_TIMEOUT;
804 return (0);
805 }
806 statp->_flags |= RES_F_VC;
807 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900808
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900809 /*
810 * Send length & message
811 */
812 ns_put16((u_short) buflen, (u_char*) (void*) &len);
813 iov[0] = evConsIovec(&len, INT16SZ);
Bernie Innocenti1f4a9fd2018-09-07 21:10:25 +0900814 iov[1] = evConsIovec((void*) buf, (size_t) buflen);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900815 if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
816 *terrno = errno;
817 Perror(statp, stderr, "write failed", errno);
818 res_nclose(statp);
819 return (0);
820 }
821 /*
822 * Receive length & response
823 */
824read_len:
825 cp = ans;
826 len = INT16SZ;
827 while ((n = read(statp->_vcsock, (char*) cp, (size_t) len)) > 0) {
828 cp += n;
829 if ((len -= n) == 0) break;
830 }
831 if (n <= 0) {
832 *terrno = errno;
833 Perror(statp, stderr, "read failed", errno);
834 res_nclose(statp);
835 /*
836 * A long running process might get its TCP
837 * connection reset if the remote server was
838 * restarted. Requery the server instead of
839 * trying a new one. When there is only one
840 * server, this means that a query might work
841 * instead of failing. We only allow one reset
842 * per query to prevent looping.
843 */
844 if (*terrno == ECONNRESET && !connreset) {
845 connreset = 1;
846 res_nclose(statp);
847 goto same_ns;
848 }
849 res_nclose(statp);
850 return (0);
851 }
852 resplen = ns_get16(ans);
853 if (resplen > anssiz) {
854 Dprint(statp->options & RES_DEBUG, (stdout, ";; response truncated\n"));
855 truncating = 1;
856 len = anssiz;
857 } else
858 len = resplen;
859 if (len < HFIXEDSZ) {
860 /*
861 * Undersized message.
862 */
863 Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len));
864 *terrno = EMSGSIZE;
865 res_nclose(statp);
866 return (0);
867 }
868 cp = ans;
869 while (len != 0 && (n = read(statp->_vcsock, (char*) cp, (size_t) len)) > 0) {
870 cp += n;
871 len -= n;
872 }
873 if (n <= 0) {
874 *terrno = errno;
875 Perror(statp, stderr, "read(vc)", errno);
876 res_nclose(statp);
877 return (0);
878 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900879
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900880 if (truncating) {
881 /*
882 * Flush rest of answer so connection stays in synch.
883 */
884 anhp->tc = 1;
885 len = resplen - anssiz;
886 while (len != 0) {
887 char junk[PACKETSZ];
Bernie Innocenti55864192018-08-30 04:05:20 +0900888
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900889 n = read(statp->_vcsock, junk, (len > sizeof junk) ? sizeof junk : len);
890 if (n > 0)
891 len -= n;
892 else
893 break;
894 }
895 }
896 /*
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900897 * If the calling application has bailed out of
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900898 * a previous call and failed to arrange to have
899 * the circuit closed or the server has got
900 * itself confused, then drop the packet and
901 * wait for the correct one.
902 */
903 if (hp->id != anhp->id) {
904 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
905 (stdout, ";; old answer (unexpected):\n"), ans,
906 (resplen > anssiz) ? anssiz : resplen);
907 goto read_len;
908 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900909
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900910 /*
911 * All is well, or the error is fatal. Signal that the
912 * next nameserver ought not be tried.
913 */
914 if (resplen > 0) {
915 struct timespec done = evNowTime();
916 *delay = _res_stats_calculate_rtt(&done, &now);
917 *rcode = anhp->rcode;
918 }
919 return (resplen);
Bernie Innocenti55864192018-08-30 04:05:20 +0900920}
921
922/* return -1 on error (errno set), 0 on success */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900923static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
924 const struct timespec timeout) {
925 int res, origflags;
Bernie Innocenti55864192018-08-30 04:05:20 +0900926
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900927 origflags = fcntl(sock, F_GETFL, 0);
928 fcntl(sock, F_SETFL, origflags | O_NONBLOCK);
Bernie Innocenti55864192018-08-30 04:05:20 +0900929
Bernie Innocentif89b3512018-08-30 07:34:37 +0900930 res = connect(sock, nsap, salen);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900931 if (res < 0 && errno != EINPROGRESS) {
932 res = -1;
933 goto done;
934 }
935 if (res != 0) {
936 struct timespec now = evNowTime();
937 struct timespec finish = evAddTime(now, timeout);
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900938 VLOG << sock << " send_vc";
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900939 res = retrying_poll(sock, POLLIN | POLLOUT, &finish);
940 if (res <= 0) {
941 res = -1;
942 }
943 }
Bernie Innocenti55864192018-08-30 04:05:20 +0900944done:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900945 fcntl(sock, F_SETFL, origflags);
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900946 VLOG << sock << " connect_with_const timeout returning " << res;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900947 return res;
Bernie Innocenti55864192018-08-30 04:05:20 +0900948}
949
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900950static int retrying_poll(const int sock, const short events, const struct timespec* finish) {
951 struct timespec now, timeout;
Bernie Innocenti55864192018-08-30 04:05:20 +0900952
953retry:
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900954 VLOG << " " << sock << " retrying_poll";
Bernie Innocenti55864192018-08-30 04:05:20 +0900955
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900956 now = evNowTime();
957 if (evCmpTime(*finish, now) > 0)
958 timeout = evSubTime(*finish, now);
959 else
960 timeout = evConsTime(0L, 0L);
961 struct pollfd fds = {.fd = sock, .events = events};
962 int n = ppoll(&fds, 1, &timeout, /*sigmask=*/NULL);
963 if (n == 0) {
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900964 VLOG << " " << sock << "retrying_poll timeout";
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900965 errno = ETIMEDOUT;
966 return 0;
967 }
968 if (n < 0) {
969 if (errno == EINTR) goto retry;
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900970 VLOG << " " << sock << " retrying_poll got error " << n;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900971 return n;
972 }
973 if (fds.revents & (POLLIN | POLLOUT | POLLERR)) {
974 int error;
975 socklen_t len = sizeof(error);
976 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) {
977 errno = error;
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900978 VLOG << " " << sock << " retrying_poll dot error2 " << errno;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900979 return -1;
980 }
981 }
Bernie Innocentie9ba09c2018-09-12 23:20:10 +0900982 VLOG << " " << sock << " retrying_poll returning " << n;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900983 return n;
Bernie Innocenti55864192018-08-30 04:05:20 +0900984}
985
Bernie Innocenti34de3ba2019-02-19 18:08:36 +0900986static int send_dg(res_state statp, res_params* params, const u_char* buf, int buflen, u_char* ans,
987 int anssiz, int* terrno, int ns, int* v_circuit, int* gotsomewhere, time_t* at,
988 int* rcode, int* delay) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900989 *at = time(NULL);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +0900990 *delay = 0;
991 const HEADER* hp = (const HEADER*) (const void*) buf;
992 HEADER* anhp = (HEADER*) (void*) ans;
993 const struct sockaddr* nsap;
994 int nsaplen;
995 struct timespec now, timeout, finish, done;
996 struct sockaddr_storage from;
997 socklen_t fromlen;
998 int resplen, n, s;
Bernie Innocenti55864192018-08-30 04:05:20 +0900999
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001000 nsap = get_nsaddr(statp, (size_t) ns);
1001 nsaplen = get_salen(nsap);
Ken Chencf6ded62018-10-16 23:12:09 +08001002 if (statp->_u._ext.nssocks[ns] == -1) {
1003 statp->_u._ext.nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1004 if (statp->_u._ext.nssocks[ns] < 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001005 switch (errno) {
1006 case EPROTONOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001007 case EPFNOSUPPORT:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001008 case EAFNOSUPPORT:
1009 Perror(statp, stderr, "socket(dg)", errno);
1010 return (0);
1011 default:
1012 *terrno = errno;
1013 Perror(statp, stderr, "socket(dg)", errno);
1014 return (-1);
1015 }
1016 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001017
Ken Chencf6ded62018-10-16 23:12:09 +08001018 fchown(statp->_u._ext.nssocks[ns], AID_DNS, -1);
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001019 if (statp->_mark != MARK_UNSET) {
Ken Chencf6ded62018-10-16 23:12:09 +08001020 if (setsockopt(statp->_u._ext.nssocks[ns], SOL_SOCKET, SO_MARK, &(statp->_mark),
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001021 sizeof(statp->_mark)) < 0) {
1022 res_nclose(statp);
1023 return -1;
1024 }
1025 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001026#ifndef CANNOT_CONNECT_DGRAM
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001027 /*
1028 * On a 4.3BSD+ machine (client and server,
1029 * actually), sending to a nameserver datagram
1030 * port with no nameserver will cause an
1031 * ICMP port unreachable message to be returned.
1032 * If our datagram socket is "connected" to the
1033 * server, we get an ECONNREFUSED error on the next
1034 * socket operation, and select returns if the
1035 * error message is received. We can thus detect
1036 * the absence of a nameserver without timing out.
1037 */
Ken Chencf6ded62018-10-16 23:12:09 +08001038 if (random_bind(statp->_u._ext.nssocks[ns], nsap->sa_family) < 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001039 Aerror(statp, stderr, "bind(dg)", errno, nsap, nsaplen);
1040 res_nclose(statp);
1041 return (0);
1042 }
Ken Chencf6ded62018-10-16 23:12:09 +08001043 if (connect(statp->_u._ext.nssocks[ns], nsap, (socklen_t) nsaplen) < 0) {
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001044 Aerror(statp, stderr, "connect(dg)", errno, nsap, nsaplen);
1045 res_nclose(statp);
1046 return (0);
1047 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001048#endif /* !CANNOT_CONNECT_DGRAM */
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001049 Dprint(statp->options & RES_DEBUG, (stdout, ";; new DG socket\n"))
1050 }
Ken Chencf6ded62018-10-16 23:12:09 +08001051 s = statp->_u._ext.nssocks[ns];
Bernie Innocenti55864192018-08-30 04:05:20 +09001052#ifndef CANNOT_CONNECT_DGRAM
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001053 if (send(s, (const char*) buf, (size_t) buflen, 0) != buflen) {
1054 Perror(statp, stderr, "send", errno);
1055 res_nclose(statp);
1056 return (0);
1057 }
1058#else /* !CANNOT_CONNECT_DGRAM */
1059 if (sendto(s, (const char*) buf, buflen, 0, nsap, nsaplen) != buflen) {
1060 Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
1061 res_nclose(statp);
1062 return (0);
1063 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001064#endif /* !CANNOT_CONNECT_DGRAM */
1065
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001066 /*
1067 * Wait for reply.
1068 */
1069 timeout = get_timeout(statp, params, ns);
1070 now = evNowTime();
1071 finish = evAddTime(now, timeout);
Bernie Innocenti55864192018-08-30 04:05:20 +09001072retry:
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001073 n = retrying_poll(s, POLLIN, &finish);
Bernie Innocenti55864192018-08-30 04:05:20 +09001074
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001075 if (n == 0) {
1076 *rcode = RCODE_TIMEOUT;
1077 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
1078 *gotsomewhere = 1;
1079 return (0);
1080 }
1081 if (n < 0) {
1082 Perror(statp, stderr, "poll", errno);
1083 res_nclose(statp);
1084 return (0);
1085 }
1086 errno = 0;
1087 fromlen = sizeof(from);
1088 resplen = recvfrom(s, (char*) ans, (size_t) anssiz, 0, (struct sockaddr*) (void*) &from,
1089 &fromlen);
1090 if (resplen <= 0) {
1091 Perror(statp, stderr, "recvfrom", errno);
1092 res_nclose(statp);
1093 return (0);
1094 }
1095 *gotsomewhere = 1;
1096 if (resplen < HFIXEDSZ) {
1097 /*
1098 * Undersized message.
1099 */
1100 Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", resplen));
1101 *terrno = EMSGSIZE;
1102 res_nclose(statp);
1103 return (0);
1104 }
1105 if (hp->id != anhp->id) {
1106 /*
1107 * response from old query, ignore it.
1108 * XXX - potential security hazard could
1109 * be detected here.
1110 */
1111 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
1112 (stdout, ";; old answer:\n"), ans, (resplen > anssiz) ? anssiz : resplen);
1113 goto retry;
1114 }
1115 if (!(statp->options & RES_INSECURE1) &&
1116 !res_ourserver_p(statp, (struct sockaddr*) (void*) &from)) {
1117 /*
1118 * response from wrong server? ignore it.
1119 * XXX - potential security hazard could
1120 * be detected here.
1121 */
1122 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
1123 (stdout, ";; not our server:\n"), ans, (resplen > anssiz) ? anssiz : resplen);
1124 goto retry;
1125 }
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001126 if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) {
1127 /*
1128 * Do not retry if the server do not understand EDNS0.
1129 * The case has to be captured here, as FORMERR packet do not
1130 * carry query section, hence res_queriesmatch() returns 0.
1131 */
1132 DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query with EDNS0:\n"), ans,
1133 (resplen > anssiz) ? anssiz : resplen);
1134 /* record the error */
1135 statp->_flags |= RES_F_EDNS0ERR;
1136 res_nclose(statp);
1137 return (0);
1138 }
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001139 if (!(statp->options & RES_INSECURE2) &&
1140 !res_queriesmatch(buf, buf + buflen, ans, ans + anssiz)) {
1141 /*
1142 * response contains wrong query? ignore it.
1143 * XXX - potential security hazard could
1144 * be detected here.
1145 */
1146 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY),
1147 (stdout, ";; wrong query name:\n"), ans, (resplen > anssiz) ? anssiz : resplen);
1148 goto retry;
1149 ;
1150 }
1151 done = evNowTime();
1152 *delay = _res_stats_calculate_rtt(&done, &now);
1153 if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || anhp->rcode == REFUSED) {
1154 DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query:\n"), ans,
1155 (resplen > anssiz) ? anssiz : resplen);
1156 res_nclose(statp);
1157 /* don't retry if called from dig */
1158 if (!statp->pfcode) {
1159 *rcode = anhp->rcode;
1160 return (0);
1161 }
1162 }
1163 if (!(statp->options & RES_IGNTC) && anhp->tc) {
1164 /*
1165 * To get the rest of answer,
1166 * use TCP with same server.
1167 */
1168 Dprint(statp->options & RES_DEBUG, (stdout, ";; truncated answer\n"));
1169 *v_circuit = 1;
1170 res_nclose(statp);
1171 return (1);
1172 }
1173 /*
1174 * All is well, or the error is fatal. Signal that the
1175 * next nameserver ought not be tried.
1176 */
1177 if (resplen > 0) {
1178 *rcode = anhp->rcode;
1179 }
1180 return (resplen);
Bernie Innocenti55864192018-08-30 04:05:20 +09001181}
1182
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001183static void Aerror(const res_state statp, FILE* file, const char* string, int error,
1184 const struct sockaddr* address, int alen) {
Bernie Innocentie9ba09c2018-09-12 23:20:10 +09001185 if (!kVerboseLogging) return;
1186
1187 const int save = errno;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001188 char hbuf[NI_MAXHOST];
1189 char sbuf[NI_MAXSERV];
Bernie Innocentie9ba09c2018-09-12 23:20:10 +09001190 constexpr int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
Bernie Innocenti55864192018-08-30 04:05:20 +09001191
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001192 if ((statp->options & RES_DEBUG) != 0U) {
1193 if (getnameinfo(address, (socklen_t) alen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
1194 niflags)) {
1195 strncpy(hbuf, "?", sizeof(hbuf) - 1);
1196 hbuf[sizeof(hbuf) - 1] = '\0';
1197 strncpy(sbuf, "?", sizeof(sbuf) - 1);
1198 sbuf[sizeof(sbuf) - 1] = '\0';
1199 }
1200 fprintf(file, "res_send: %s ([%s].%s): %s\n", string, hbuf, sbuf, strerror(error));
1201 }
1202 errno = save;
Bernie Innocenti55864192018-08-30 04:05:20 +09001203}
1204
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001205static void Perror(const res_state statp, FILE* file, const char* string, int error) {
Bernie Innocentie9ba09c2018-09-12 23:20:10 +09001206 if (!kVerboseLogging) return;
Bernie Innocenti55864192018-08-30 04:05:20 +09001207
Bernie Innocentie9ba09c2018-09-12 23:20:10 +09001208 const int save = errno;
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001209 if ((statp->options & RES_DEBUG) != 0U)
1210 fprintf(file, "res_send: %s: %s\n", string, strerror(error));
1211 errno = save;
Bernie Innocenti55864192018-08-30 04:05:20 +09001212}
1213
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001214static int sock_eq(struct sockaddr* a, struct sockaddr* b) {
1215 struct sockaddr_in *a4, *b4;
1216 struct sockaddr_in6 *a6, *b6;
Bernie Innocenti55864192018-08-30 04:05:20 +09001217
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001218 if (a->sa_family != b->sa_family) return 0;
1219 switch (a->sa_family) {
1220 case AF_INET:
1221 a4 = (struct sockaddr_in*) (void*) a;
1222 b4 = (struct sockaddr_in*) (void*) b;
1223 return a4->sin_port == b4->sin_port && a4->sin_addr.s_addr == b4->sin_addr.s_addr;
1224 case AF_INET6:
1225 a6 = (struct sockaddr_in6*) (void*) a;
1226 b6 = (struct sockaddr_in6*) (void*) b;
1227 return a6->sin6_port == b6->sin6_port &&
Bernie Innocenti55864192018-08-30 04:05:20 +09001228#ifdef HAVE_SIN6_SCOPE_ID
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001229 a6->sin6_scope_id == b6->sin6_scope_id &&
Bernie Innocenti55864192018-08-30 04:05:20 +09001230#endif
Bernie Innocentif12d5bb2018-08-31 14:09:46 +09001231 IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
1232 default:
1233 return 0;
1234 }
Bernie Innocenti55864192018-08-30 04:05:20 +09001235}
Mike Yua46fae72018-11-01 20:07:00 +08001236
Luke Huang490551d2018-11-21 20:37:50 +08001237static int res_tls_send(res_state statp, const Slice query, const Slice answer, int* rcode,
Mike Yu69615f62018-11-06 15:42:36 +08001238 bool* fallback) {
1239 int resplen = 0;
Mike Yua46fae72018-11-01 20:07:00 +08001240 const unsigned netId = statp->netid;
1241 const unsigned mark = statp->_mark;
1242
Mike Yu69615f62018-11-06 15:42:36 +08001243 PrivateDnsStatus privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId);
1244
1245 if (privateDnsStatus.mode == PrivateDnsMode::OFF) {
1246 *fallback = true;
1247 return -1;
Mike Yua46fae72018-11-01 20:07:00 +08001248 }
1249
Mike Yua46fae72018-11-01 20:07:00 +08001250 if (privateDnsStatus.validatedServers.empty()) {
1251 if (privateDnsStatus.mode == PrivateDnsMode::OPPORTUNISTIC) {
Mike Yu69615f62018-11-06 15:42:36 +08001252 *fallback = true;
1253 return -1;
Mike Yua46fae72018-11-01 20:07:00 +08001254 } else {
1255 // Sleep and iterate some small number of times checking for the
1256 // arrival of resolved and validated server IP addresses, instead
1257 // of returning an immediate error.
Mike Yu5b9ffb22018-12-02 17:54:29 +09001258 // This is needed because as soon as a network becomes the default network, apps will
1259 // send DNS queries on that network. If no servers have yet validated, and we do not
1260 // block those queries, they would immediately fail, causing application-visible errors.
1261 // Note that this can happen even before the network validates, since an unvalidated
1262 // network can become the default network if no validated networks are available.
1263 //
1264 // TODO: see if there is a better way to address this problem, such as buffering the
1265 // queries in a queue or only blocking queries for the first few seconds after a default
1266 // network change.
Mike Yu69615f62018-11-06 15:42:36 +08001267 for (int i = 0; i < 42; i++) {
1268 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1269 if (!gPrivateDnsConfiguration.getStatus(netId).validatedServers.empty()) {
1270 privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId);
1271 break;
1272 }
1273 }
1274 if (privateDnsStatus.validatedServers.empty()) {
1275 return -1;
1276 }
Mike Yua46fae72018-11-01 20:07:00 +08001277 }
1278 }
1279
1280 VLOG << __func__ << ": performing query over TLS";
1281
1282 const auto response = sDnsTlsDispatcher.query(privateDnsStatus.validatedServers, mark, query,
Mike Yu69615f62018-11-06 15:42:36 +08001283 answer, &resplen);
Mike Yua46fae72018-11-01 20:07:00 +08001284
Mike Yu69615f62018-11-06 15:42:36 +08001285 VLOG << __func__ << ": TLS query result: " << static_cast<int>(response);
Mike Yua46fae72018-11-01 20:07:00 +08001286
1287 if (privateDnsStatus.mode == PrivateDnsMode::OPPORTUNISTIC) {
1288 // In opportunistic mode, handle falling back to cleartext in some
1289 // cases (DNS shouldn't fail if a validated opportunistic mode server
1290 // becomes unreachable for some reason).
1291 switch (response) {
Mike Yu69615f62018-11-06 15:42:36 +08001292 case DnsTlsTransport::Response::success:
Luke Huang490551d2018-11-21 20:37:50 +08001293 *rcode = reinterpret_cast<HEADER*>(answer.base())->rcode;
Mike Yu69615f62018-11-06 15:42:36 +08001294 return resplen;
Mike Yua46fae72018-11-01 20:07:00 +08001295 case DnsTlsTransport::Response::network_error:
Mike Yu69615f62018-11-06 15:42:36 +08001296 // No need to set the error timeout here since it will fallback to UDP.
Mike Yua46fae72018-11-01 20:07:00 +08001297 case DnsTlsTransport::Response::internal_error:
1298 // Note: this will cause cleartext queries to be emitted, with
1299 // all of the EDNS0 goodness enabled. Fingers crossed. :-/
Mike Yu69615f62018-11-06 15:42:36 +08001300 *fallback = true;
1301 [[fallthrough]];
Mike Yua46fae72018-11-01 20:07:00 +08001302 default:
Mike Yu69615f62018-11-06 15:42:36 +08001303 return -1;
1304 }
1305 } else {
1306 // Strict mode
1307 switch (response) {
1308 case DnsTlsTransport::Response::success:
Luke Huang490551d2018-11-21 20:37:50 +08001309 *rcode = reinterpret_cast<HEADER*>(answer.base())->rcode;
Mike Yu69615f62018-11-06 15:42:36 +08001310 return resplen;
1311 case DnsTlsTransport::Response::network_error:
1312 // This case happens when the query stored in DnsTlsTransport is expired since
1313 // either 1) the query has been tried for 3 times but no response or 2) fail to
1314 // establish the connection with the server.
Luke Huang490551d2018-11-21 20:37:50 +08001315 *rcode = RCODE_TIMEOUT;
Mike Yu69615f62018-11-06 15:42:36 +08001316 [[fallthrough]];
1317 default:
1318 return -1;
Mike Yua46fae72018-11-01 20:07:00 +08001319 }
1320 }
Mike Yua46fae72018-11-01 20:07:00 +08001321}
Luke Huangeefb7772018-11-19 20:17:26 +08001322
Luke Huang952d0942018-12-26 16:53:03 +08001323int resolv_res_nsend(const android_net_context* netContext, const uint8_t* msg, int msgLen,
1324 uint8_t* ans, int ansLen, int* rcode, uint32_t flags) {
Luke Huangeefb7772018-11-19 20:17:26 +08001325 res_state res = res_get_state();
1326 res_setnetcontext(res, netContext);
1327 _resolv_populate_res_for_net(res);
1328 *rcode = NOERROR;
Luke Huang952d0942018-12-26 16:53:03 +08001329 return res_nsend(res, msg, msgLen, ans, ansLen, rcode, flags);
Bernie Innocentiad4e26e2019-01-30 11:16:36 +09001330}