1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #define LOG_TAG "resolv"
30 
31 #include "resolv_cache.h"
32 
33 #include <resolv.h>
34 #include <stdarg.h>
35 #include <stdint.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <time.h>
39 #include <algorithm>
40 #include <mutex>
41 #include <set>
42 #include <string>
43 #include <unordered_map>
44 #include <vector>
45 
46 #include <arpa/inet.h>
47 #include <arpa/nameser.h>
48 #include <errno.h>
49 #include <linux/if.h>
50 #include <net/if.h>
51 #include <netdb.h>
52 
53 #include <aidl/android/net/IDnsResolver.h>
54 #include <android-base/logging.h>
55 #include <android-base/parseint.h>
56 #include <android-base/strings.h>
57 #include <android-base/thread_annotations.h>
58 #include <android/multinetwork.h>  // ResNsendFlags
59 
60 #include <server_configurable_flags/get_flags.h>
61 
62 #include "DnsStats.h"
63 #include "Experiments.h"
64 #include "res_comp.h"
65 #include "res_debug.h"
66 #include "resolv_private.h"
67 #include "util.h"
68 
69 using aidl::android::net::IDnsResolver;
70 using aidl::android::net::ResolverOptionsParcel;
71 using aidl::android::net::ResolverParamsParcel;
72 using android::net::DnsQueryEvent;
73 using android::net::DnsStats;
74 using android::net::Experiments;
75 using android::net::PROTO_TCP;
76 using android::net::PROTO_UDP;
77 using android::net::Protocol;
78 using android::netdutils::DumpWriter;
79 using android::netdutils::IPSockAddr;
80 using std::span;
81 
82 /* This code implements a small and *simple* DNS resolver cache.
83  *
84  * It is only used to cache DNS answers for a time defined by the smallest TTL
85  * among the answer records in order to reduce DNS traffic. It is not supposed
86  * to be a full DNS cache, since we plan to implement that in the future in a
87  * dedicated process running on the system.
88  *
89  * Note that its design is kept simple very intentionally, i.e.:
90  *
91  *  - it takes raw DNS query packet data as input, and returns raw DNS
92  *    answer packet data as output
93  *
94  *    (this means that two similar queries that encode the DNS name
95  *     differently will be treated distinctly).
96  *
97  *    the smallest TTL value among the answer records are used as the time
98  *    to keep an answer in the cache.
99  *
100  *    this is bad, but we absolutely want to avoid parsing the answer packets
101  *    (and should be solved by the later full DNS cache process).
102  *
103  *  - the implementation is just a (query-data) => (answer-data) hash table
104  *    with a trivial least-recently-used expiration policy.
105  *
106  * Doing this keeps the code simple and avoids to deal with a lot of things
107  * that a full DNS cache is expected to do.
108  *
109  * The API is also very simple:
110  *
111  *   - the client calls resolv_cache_lookup() before performing a query
112  *
113  *     If the function returns RESOLV_CACHE_FOUND, a copy of the answer data
114  *     has been copied into the client-provided answer buffer.
115  *
116  *     If the function returns RESOLV_CACHE_NOTFOUND, the client should perform
117  *     a request normally, *then* call resolv_cache_add() to add the received
118  *     answer to the cache.
119  *
120  *     If the function returns RESOLV_CACHE_UNSUPPORTED, the client should
121  *     perform a request normally, and *not* call resolv_cache_add()
122  *
123  *     Note that RESOLV_CACHE_UNSUPPORTED is also returned if the answer buffer
124  *     is too short to accomodate the cached result.
125  */
126 
127 /* Default number of entries kept in the cache. This value has been
128  * determined by browsing through various sites and counting the number
129  * of corresponding requests. Keep in mind that our framework is currently
130  * performing two requests per name lookup (one for IPv4, the other for IPv6)
131  *
132  *    www.google.com      4
133  *    www.ysearch.com     6
134  *    www.amazon.com      8
135  *    www.nytimes.com     22
136  *    www.espn.com        28
137  *    www.msn.com         28
138  *    www.lemonde.fr      35
139  *
140  * (determined in 2009-2-17 from Paris, France, results may vary depending
141  *  on location)
142  *
143  * most high-level websites use lots of media/ad servers with different names
144  * but these are generally reused when browsing through the site.
145  *
146  * As such, a value of 64 should be relatively comfortable at the moment.
147  *
148  * ******************************************
149  * * NOTE - this has changed.
150  * * 1) we've added IPv6 support so each dns query results in 2 responses
151  * * 2) we've made this a system-wide cache, so the cost is less (it's not
152  * *    duplicated in each process) and the need is greater (more processes
153  * *    making different requests).
154  * * Upping by 2x for IPv6
155  * * Upping by another 5x for the centralized nature
156  * *****************************************
157  */
158 const int MAX_ENTRIES_DEFAULT = 64 * 2 * 5;
159 const int MAX_ENTRIES_LOWER_BOUND = 1;
160 const int MAX_ENTRIES_UPPER_BOUND = 100 * 1000;
161 constexpr int DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY = -1;
162 
_time_now(void)163 static time_t _time_now(void) {
164     struct timeval tv;
165 
166     gettimeofday(&tv, NULL);
167     return tv.tv_sec;
168 }
169 
170 /* reminder: the general format of a DNS packet is the following:
171  *
172  *    HEADER  (12 bytes)
173  *    QUESTION  (variable)
174  *    ANSWER (variable)
175  *    AUTHORITY (variable)
176  *    ADDITIONNAL (variable)
177  *
178  * the HEADER is made of:
179  *
180  *   ID     : 16 : 16-bit unique query identification field
181  *
182  *   QR     :  1 : set to 0 for queries, and 1 for responses
183  *   Opcode :  4 : set to 0 for queries
184  *   AA     :  1 : set to 0 for queries
185  *   TC     :  1 : truncation flag, will be set to 0 in queries
186  *   RD     :  1 : recursion desired
187  *
188  *   RA     :  1 : recursion available (0 in queries)
189  *   Z      :  3 : three reserved zero bits
190  *   RCODE  :  4 : response code (always 0=NOERROR in queries)
191  *
192  *   QDCount: 16 : question count
193  *   ANCount: 16 : Answer count (0 in queries)
194  *   NSCount: 16: Authority Record count (0 in queries)
195  *   ARCount: 16: Additionnal Record count (0 in queries)
196  *
197  * the QUESTION is made of QDCount Question Record (QRs)
198  * the ANSWER is made of ANCount RRs
199  * the AUTHORITY is made of NSCount RRs
200  * the ADDITIONNAL is made of ARCount RRs
201  *
202  * Each Question Record (QR) is made of:
203  *
204  *   QNAME   : variable : Query DNS NAME
205  *   TYPE    : 16       : type of query (A=1, PTR=12, MX=15, AAAA=28, ALL=255)
206  *   CLASS   : 16       : class of query (IN=1)
207  *
208  * Each Resource Record (RR) is made of:
209  *
210  *   NAME    : variable : DNS NAME
211  *   TYPE    : 16       : type of query (A=1, PTR=12, MX=15, AAAA=28, ALL=255)
212  *   CLASS   : 16       : class of query (IN=1)
213  *   TTL     : 32       : seconds to cache this RR (0=none)
214  *   RDLENGTH: 16       : size of RDDATA in bytes
215  *   RDDATA  : variable : RR data (depends on TYPE)
216  *
217  * Each QNAME contains a domain name encoded as a sequence of 'labels'
218  * terminated by a zero. Each label has the following format:
219  *
220  *    LEN  : 8     : lenght of label (MUST be < 64)
221  *    NAME : 8*LEN : label length (must exclude dots)
222  *
223  * A value of 0 in the encoding is interpreted as the 'root' domain and
224  * terminates the encoding. So 'www.android.com' will be encoded as:
225  *
226  *   <3>www<7>android<3>com<0>
227  *
228  * Where <n> represents the byte with value 'n'
229  *
230  * Each NAME reflects the QNAME of the question, but has a slightly more
231  * complex encoding in order to provide message compression. This is achieved
232  * by using a 2-byte pointer, with format:
233  *
234  *    TYPE   : 2  : 0b11 to indicate a pointer, 0b01 and 0b10 are reserved
235  *    OFFSET : 14 : offset to another part of the DNS packet
236  *
237  * The offset is relative to the start of the DNS packet and must point
238  * A pointer terminates the encoding.
239  *
240  * The NAME can be encoded in one of the following formats:
241  *
242  *   - a sequence of simple labels terminated by 0 (like QNAMEs)
243  *   - a single pointer
244  *   - a sequence of simple labels terminated by a pointer
245  *
246  * A pointer shall always point to either a pointer of a sequence of
247  * labels (which can themselves be terminated by either a 0 or a pointer)
248  *
249  * The expanded length of a given domain name should not exceed 255 bytes.
250  *
251  * NOTE: we don't parse the answer packets, so don't need to deal with NAME
252  *       records, only QNAMEs.
253  */
254 
255 #define DNS_HEADER_SIZE 12
256 
257 struct DnsPacket {
258     const uint8_t* base;
259     const uint8_t* end;
260     const uint8_t* cursor;
261 };
262 
res_tolower(uint8_t c)263 static uint8_t res_tolower(uint8_t c) {
264     return (c >= 'A' && c <= 'Z') ? (c | 0x20) : c;
265 }
266 
res_memcasecmp(const unsigned char * s1,const unsigned char * s2,size_t len)267 static int res_memcasecmp(const unsigned char *s1, const unsigned char *s2, size_t len) {
268     for (size_t i = 0; i < len; i++) {
269         int ch1 = *s1++;
270         int ch2 = *s2++;
271         int d = res_tolower(ch1) - res_tolower(ch2);
272         if (d != 0) {
273             return d;
274         }
275     }
276     return 0;
277 }
278 
_dnsPacket_init(DnsPacket * packet,const uint8_t * buff,int bufflen)279 static void _dnsPacket_init(DnsPacket* packet, const uint8_t* buff, int bufflen) {
280     packet->base = buff;
281     packet->end = buff + bufflen;
282     packet->cursor = buff;
283 }
284 
_dnsPacket_rewind(DnsPacket * packet)285 static void _dnsPacket_rewind(DnsPacket* packet) {
286     packet->cursor = packet->base;
287 }
288 
_dnsPacket_skip(DnsPacket * packet,int count)289 static void _dnsPacket_skip(DnsPacket* packet, int count) {
290     const uint8_t* p = packet->cursor + count;
291 
292     if (p > packet->end) p = packet->end;
293 
294     packet->cursor = p;
295 }
296 
_dnsPacket_readInt16(DnsPacket * packet)297 static int _dnsPacket_readInt16(DnsPacket* packet) {
298     const uint8_t* p = packet->cursor;
299 
300     if (p + 2 > packet->end) return -1;
301 
302     packet->cursor = p + 2;
303     return (p[0] << 8) | p[1];
304 }
305 
306 /** QUERY CHECKING **/
307 
308 /* check bytes in a dns packet. returns 1 on success, 0 on failure.
309  * the cursor is only advanced in the case of success
310  */
_dnsPacket_checkBytes(DnsPacket * packet,int numBytes,const void * bytes)311 static int _dnsPacket_checkBytes(DnsPacket* packet, int numBytes, const void* bytes) {
312     const uint8_t* p = packet->cursor;
313 
314     if (p + numBytes > packet->end) return 0;
315 
316     if (memcmp(p, bytes, numBytes) != 0) return 0;
317 
318     packet->cursor = p + numBytes;
319     return 1;
320 }
321 
_dnsPacket_checkBE16(DnsPacket * packet,uint16_t v)322 static int _dnsPacket_checkBE16(DnsPacket* packet, uint16_t v) {
323     uint16_t be16 = htons(v);
324     return _dnsPacket_checkBytes(packet, sizeof(be16), &be16);
325 }
326 
327 /* parse and skip a given QNAME stored in a query packet,
328  * from the current cursor position. returns 1 on success,
329  * or 0 for malformed data.
330  */
_dnsPacket_checkQName(DnsPacket * packet)331 static int _dnsPacket_checkQName(DnsPacket* packet) {
332     const uint8_t* p = packet->cursor;
333     const uint8_t* end = packet->end;
334 
335     for (;;) {
336         int c;
337 
338         if (p >= end) break;
339 
340         c = *p++;
341 
342         if (c == 0) {
343             packet->cursor = p;
344             return 1;
345         }
346 
347         /* we don't expect label compression in QNAMEs */
348         if (c >= 64) break;
349 
350         p += c;
351         /* we rely on the bound check at the start
352          * of the loop here */
353     }
354     /* malformed data */
355     LOG(INFO) << __func__ << ": malformed QNAME";
356     return 0;
357 }
358 
359 /* parse and skip a given QR stored in a packet.
360  * returns 1 on success, and 0 on failure
361  */
_dnsPacket_checkQR(DnsPacket * packet)362 static int _dnsPacket_checkQR(DnsPacket* packet) {
363     if (!_dnsPacket_checkQName(packet)) return 0;
364 
365     /* TYPE must be one of the things we support */
366     if (!_dnsPacket_checkBE16(packet, ns_type::ns_t_a) &&
367         !_dnsPacket_checkBE16(packet, ns_type::ns_t_ptr) &&
368         !_dnsPacket_checkBE16(packet, ns_type::ns_t_mx) &&
369         !_dnsPacket_checkBE16(packet, ns_type::ns_t_aaaa) &&
370         !_dnsPacket_checkBE16(packet, ns_type::ns_t_any /*all*/)) {
371         LOG(INFO) << __func__ << ": unsupported TYPE";
372         return 0;
373     }
374     /* CLASS must be IN */
375     if (!_dnsPacket_checkBE16(packet, ns_class::ns_c_in)) {
376         LOG(INFO) << __func__ << ": unsupported CLASS";
377         return 0;
378     }
379 
380     return 1;
381 }
382 
383 /* check the header of a DNS Query packet, return 1 if it is one
384  * type of query we can cache, or 0 otherwise
385  */
_dnsPacket_checkQuery(DnsPacket * packet)386 static int _dnsPacket_checkQuery(DnsPacket* packet) {
387     const uint8_t* p = packet->base;
388     int qdCount, anCount, dnCount, arCount;
389 
390     if (p + DNS_HEADER_SIZE > packet->end) {
391         LOG(INFO) << __func__ << ": query packet too small";
392         return 0;
393     }
394 
395     /* QR must be set to 0, opcode must be 0 and AA must be 0 */
396     /* RA, Z, and RCODE must be 0 */
397     if ((p[2] & 0xFC) != 0 || (p[3] & 0xCF) != 0) {
398         LOG(INFO) << __func__ << ": query packet flags unsupported";
399         return 0;
400     }
401 
402     /* Note that we ignore the TC, RD, CD, and AD bits here for the
403      * following reasons:
404      *
405      * - there is no point for a query packet sent to a server
406      *   to have the TC bit set, but the implementation might
407      *   set the bit in the query buffer for its own needs
408      *   between a resolv_cache_lookup and a resolv_cache_add.
409      *   We should not freak out if this is the case.
410      *
411      * - we consider that the result from a query might depend on
412      *   the RD, AD, and CD bits, so these bits
413      *   should be used to differentiate cached result.
414      *
415      *   this implies that these bits are checked when hashing or
416      *   comparing query packets, but not TC
417      */
418 
419     /* ANCOUNT, DNCOUNT and ARCOUNT must be 0 */
420     qdCount = (p[4] << 8) | p[5];
421     anCount = (p[6] << 8) | p[7];
422     dnCount = (p[8] << 8) | p[9];
423     arCount = (p[10] << 8) | p[11];
424 
425     if (anCount != 0 || dnCount != 0 || arCount > 1) {
426         LOG(INFO) << __func__ << ": query packet contains non-query records";
427         return 0;
428     }
429 
430     if (qdCount == 0) {
431         LOG(INFO) << __func__ << ": query packet doesn't contain query record";
432         return 0;
433     }
434 
435     /* Check QDCOUNT QRs */
436     packet->cursor = p + DNS_HEADER_SIZE;
437 
438     for (; qdCount > 0; qdCount--)
439         if (!_dnsPacket_checkQR(packet)) return 0;
440 
441     return 1;
442 }
443 
444 /** QUERY HASHING SUPPORT
445  **
446  ** THE FOLLOWING CODE ASSUMES THAT THE INPUT PACKET HAS ALREADY
447  ** BEEN SUCCESFULLY CHECKED.
448  **/
449 
450 /* use 32-bit FNV hash function */
451 #define FNV_MULT 16777619U
452 #define FNV_BASIS 2166136261U
453 
_dnsPacket_hashBytes(DnsPacket * packet,int numBytes,unsigned hash)454 static unsigned _dnsPacket_hashBytes(DnsPacket* packet, int numBytes, unsigned hash) {
455     const uint8_t* p = packet->cursor;
456     const uint8_t* end = packet->end;
457 
458     while (numBytes > 0 && p < end) {
459         hash = hash * FNV_MULT ^ *p++;
460         numBytes--;
461     }
462     packet->cursor = p;
463     return hash;
464 }
465 
_dnsPacket_hashQName(DnsPacket * packet,unsigned hash)466 static unsigned _dnsPacket_hashQName(DnsPacket* packet, unsigned hash) {
467     const uint8_t* p = packet->cursor;
468     const uint8_t* end = packet->end;
469 
470     for (;;) {
471         if (p >= end) { /* should not happen */
472             LOG(INFO) << __func__ << ": INTERNAL_ERROR: read-overflow";
473             break;
474         }
475 
476         int c = *p++;
477 
478         if (c == 0) break;
479 
480         if (c >= 64) {
481             LOG(INFO) << __func__ << ": INTERNAL_ERROR: malformed domain";
482             break;
483         }
484         if (p + c >= end) {
485             LOG(INFO) << __func__ << ": INTERNAL_ERROR: simple label read-overflow";
486             break;
487         }
488 
489         while (c > 0) {
490             uint8_t ch = *p++;
491             ch = res_tolower(ch);
492             hash = hash * FNV_MULT ^ ch;
493             c--;
494         }
495     }
496     packet->cursor = p;
497     return hash;
498 }
499 
_dnsPacket_hashQR(DnsPacket * packet,unsigned hash)500 static unsigned _dnsPacket_hashQR(DnsPacket* packet, unsigned hash) {
501     hash = _dnsPacket_hashQName(packet, hash);
502     hash = _dnsPacket_hashBytes(packet, 4, hash); /* TYPE and CLASS */
503     return hash;
504 }
505 
_dnsPacket_hashRR(DnsPacket * packet,unsigned hash)506 static unsigned _dnsPacket_hashRR(DnsPacket* packet, unsigned hash) {
507     int rdlength;
508     hash = _dnsPacket_hashQR(packet, hash);
509     hash = _dnsPacket_hashBytes(packet, 4, hash); /* TTL */
510     rdlength = _dnsPacket_readInt16(packet);
511     hash = _dnsPacket_hashBytes(packet, rdlength, hash); /* RDATA */
512     return hash;
513 }
514 
_dnsPacket_hashQuery(DnsPacket * packet)515 static unsigned _dnsPacket_hashQuery(DnsPacket* packet) {
516     unsigned hash = FNV_BASIS;
517     int count, arcount;
518     _dnsPacket_rewind(packet);
519 
520     /* ignore the ID */
521     _dnsPacket_skip(packet, 2);
522 
523     /* we ignore the TC bit for reasons explained in
524      * _dnsPacket_checkQuery().
525      *
526      * however we hash the RD bit to differentiate
527      * between answers for recursive and non-recursive
528      * queries.
529      */
530     hash = hash * FNV_MULT ^ (packet->base[2] & 1);
531 
532     /* mark the first header byte as processed */
533     _dnsPacket_skip(packet, 1);
534 
535     /* process the second header byte */
536     hash = _dnsPacket_hashBytes(packet, 1, hash);
537 
538     /* read QDCOUNT */
539     count = _dnsPacket_readInt16(packet);
540 
541     /* assume: ANcount and NScount are 0 */
542     _dnsPacket_skip(packet, 4);
543 
544     /* read ARCOUNT */
545     arcount = _dnsPacket_readInt16(packet);
546 
547     /* hash QDCOUNT QRs */
548     for (; count > 0; count--) hash = _dnsPacket_hashQR(packet, hash);
549 
550     /* hash ARCOUNT RRs */
551     for (; arcount > 0; arcount--) hash = _dnsPacket_hashRR(packet, hash);
552 
553     return hash;
554 }
555 
556 /** QUERY COMPARISON
557  **
558  ** THE FOLLOWING CODE ASSUMES THAT THE INPUT PACKETS HAVE ALREADY
559  ** BEEN SUCCESSFULLY CHECKED.
560  **/
561 
_dnsPacket_isEqualDomainName(DnsPacket * pack1,DnsPacket * pack2)562 static int _dnsPacket_isEqualDomainName(DnsPacket* pack1, DnsPacket* pack2) {
563     const uint8_t* p1 = pack1->cursor;
564     const uint8_t* end1 = pack1->end;
565     const uint8_t* p2 = pack2->cursor;
566     const uint8_t* end2 = pack2->end;
567 
568     for (;;) {
569         if (p1 >= end1 || p2 >= end2) {
570             LOG(INFO) << __func__ << ": INTERNAL_ERROR: read-overflow";
571             break;
572         }
573         int c1 = *p1++;
574         int c2 = *p2++;
575         if (c1 != c2) break;
576 
577         if (c1 == 0) {
578             pack1->cursor = p1;
579             pack2->cursor = p2;
580             return 1;
581         }
582         if (c1 >= 64) {
583             LOG(INFO) << __func__ << ": INTERNAL_ERROR: malformed domain";
584             break;
585         }
586         if ((p1 + c1 > end1) || (p2 + c1 > end2)) {
587             LOG(INFO) << __func__ << ": INTERNAL_ERROR: simple label read-overflow";
588             break;
589         }
590         if (res_memcasecmp(p1, p2, c1) != 0) break;
591         p1 += c1;
592         p2 += c1;
593         /* we rely on the bound checks at the start of the loop */
594     }
595     /* not the same, or one is malformed */
596     LOG(INFO) << __func__ << ": different DN";
597     return 0;
598 }
599 
_dnsPacket_isEqualBytes(DnsPacket * pack1,DnsPacket * pack2,int numBytes)600 static int _dnsPacket_isEqualBytes(DnsPacket* pack1, DnsPacket* pack2, int numBytes) {
601     const uint8_t* p1 = pack1->cursor;
602     const uint8_t* p2 = pack2->cursor;
603 
604     if (p1 + numBytes > pack1->end || p2 + numBytes > pack2->end) return 0;
605 
606     if (memcmp(p1, p2, numBytes) != 0) return 0;
607 
608     pack1->cursor += numBytes;
609     pack2->cursor += numBytes;
610     return 1;
611 }
612 
_dnsPacket_isEqualQR(DnsPacket * pack1,DnsPacket * pack2)613 static int _dnsPacket_isEqualQR(DnsPacket* pack1, DnsPacket* pack2) {
614     /* compare domain name encoding + TYPE + CLASS */
615     if (!_dnsPacket_isEqualDomainName(pack1, pack2) ||
616         !_dnsPacket_isEqualBytes(pack1, pack2, 2 + 2))
617         return 0;
618 
619     return 1;
620 }
621 
_dnsPacket_isEqualRR(DnsPacket * pack1,DnsPacket * pack2)622 static int _dnsPacket_isEqualRR(DnsPacket* pack1, DnsPacket* pack2) {
623     int rdlength1, rdlength2;
624     /* compare query + TTL */
625     if (!_dnsPacket_isEqualQR(pack1, pack2) || !_dnsPacket_isEqualBytes(pack1, pack2, 4)) return 0;
626 
627     /* compare RDATA */
628     rdlength1 = _dnsPacket_readInt16(pack1);
629     rdlength2 = _dnsPacket_readInt16(pack2);
630     if (rdlength1 != rdlength2 || !_dnsPacket_isEqualBytes(pack1, pack2, rdlength1)) return 0;
631 
632     return 1;
633 }
634 
_dnsPacket_isEqualQuery(DnsPacket * pack1,DnsPacket * pack2)635 static int _dnsPacket_isEqualQuery(DnsPacket* pack1, DnsPacket* pack2) {
636     int count1, count2, arcount1, arcount2;
637 
638     /* compare the headers, ignore most fields */
639     _dnsPacket_rewind(pack1);
640     _dnsPacket_rewind(pack2);
641 
642     /* compare RD, ignore TC, see comment in _dnsPacket_checkQuery */
643     if ((pack1->base[2] & 1) != (pack2->base[2] & 1)) {
644         LOG(INFO) << __func__ << ": different RD";
645         return 0;
646     }
647 
648     if (pack1->base[3] != pack2->base[3]) {
649         LOG(INFO) << __func__ << ": different CD or AD";
650         return 0;
651     }
652 
653     /* mark ID and header bytes as compared */
654     _dnsPacket_skip(pack1, 4);
655     _dnsPacket_skip(pack2, 4);
656 
657     /* compare QDCOUNT */
658     count1 = _dnsPacket_readInt16(pack1);
659     count2 = _dnsPacket_readInt16(pack2);
660     if (count1 != count2 || count1 < 0) {
661         LOG(INFO) << __func__ << ": different QDCOUNT";
662         return 0;
663     }
664 
665     /* assume: ANcount and NScount are 0 */
666     _dnsPacket_skip(pack1, 4);
667     _dnsPacket_skip(pack2, 4);
668 
669     /* compare ARCOUNT */
670     arcount1 = _dnsPacket_readInt16(pack1);
671     arcount2 = _dnsPacket_readInt16(pack2);
672     if (arcount1 != arcount2 || arcount1 < 0) {
673         LOG(INFO) << __func__ << ": different ARCOUNT";
674         return 0;
675     }
676 
677     /* compare the QDCOUNT QRs */
678     for (; count1 > 0; count1--) {
679         if (!_dnsPacket_isEqualQR(pack1, pack2)) {
680             LOG(INFO) << __func__ << ": different QR";
681             return 0;
682         }
683     }
684 
685     /* compare the ARCOUNT RRs */
686     for (; arcount1 > 0; arcount1--) {
687         if (!_dnsPacket_isEqualRR(pack1, pack2)) {
688             LOG(INFO) << __func__ << ": different additional RR";
689             return 0;
690         }
691     }
692     return 1;
693 }
694 
695 /* cache entry. for simplicity, 'hash' and 'hlink' are inlined in this
696  * structure though they are conceptually part of the hash table.
697  *
698  * similarly, mru_next and mru_prev are part of the global MRU list
699  */
700 struct Entry {
701     unsigned int hash;   /* hash value */
702     struct Entry* hlink; /* next in collision chain */
703     struct Entry* mru_prev;
704     struct Entry* mru_next;
705 
706     const uint8_t* query;
707     int querylen;
708     const uint8_t* answer;
709     int answerlen;
710     time_t expires; /* time_t when the entry isn't valid any more */
711     int id;         /* for debugging purpose */
712 };
713 
714 /*
715  * Find the TTL for a negative DNS result.  This is defined as the minimum
716  * of the SOA records TTL and the MINIMUM-TTL field (RFC-2308).
717  *
718  * Return 0 if not found.
719  */
answer_getNegativeTTL(ns_msg handle)720 static uint32_t answer_getNegativeTTL(ns_msg handle) {
721     int n, nscount;
722     uint32_t result = 0;
723     ns_rr rr;
724 
725     nscount = ns_msg_count(handle, ns_s_ns);
726     for (n = 0; n < nscount; n++) {
727         if ((ns_parserr(&handle, ns_s_ns, n, &rr) == 0) && (ns_rr_type(rr) == ns_t_soa)) {
728             const uint8_t* rdata = ns_rr_rdata(rr);          // find the data
729             const uint8_t* edata = rdata + ns_rr_rdlen(rr);  // add the len to find the end
730             int len;
731             uint32_t ttl, rec_result = rr.ttl;
732 
733             // find the MINIMUM-TTL field from the blob of binary data for this record
734             // skip the server name
735             len = dn_skipname(rdata, edata);
736             if (len == -1) continue;  // error skipping
737             rdata += len;
738 
739             // skip the admin name
740             len = dn_skipname(rdata, edata);
741             if (len == -1) continue;  // error skipping
742             rdata += len;
743 
744             if (edata - rdata != 5 * NS_INT32SZ) continue;
745             // skip: serial number + refresh interval + retry interval + expiry
746             rdata += NS_INT32SZ * 4;
747             // finally read the MINIMUM TTL
748             ttl = ntohl(*reinterpret_cast<const uint32_t*>(rdata));
749             if (ttl < rec_result) {
750                 rec_result = ttl;
751             }
752             // Now that the record is read successfully, apply the new min TTL
753             if (n == 0 || rec_result < result) {
754                 result = rec_result;
755             }
756         }
757     }
758     return result;
759 }
760 
761 /*
762  * Parse the answer records and find the appropriate
763  * smallest TTL among the records.  This might be from
764  * the answer records if found or from the SOA record
765  * if it's a negative result.
766  *
767  * The returned TTL is the number of seconds to
768  * keep the answer in the cache.
769  *
770  * In case of parse error zero (0) is returned which
771  * indicates that the answer shall not be cached.
772  */
answer_getTTL(span<const uint8_t> answer)773 static uint32_t answer_getTTL(span<const uint8_t> answer) {
774     ns_msg handle;
775     int ancount, n;
776     uint32_t result, ttl;
777     ns_rr rr;
778 
779     result = 0;
780     if (ns_initparse(answer.data(), answer.size(), &handle) >= 0) {
781         // get number of answer records
782         ancount = ns_msg_count(handle, ns_s_an);
783 
784         if (ancount == 0) {
785             // a response with no answers?  Cache this negative result.
786             result = answer_getNegativeTTL(handle);
787         } else {
788             for (n = 0; n < ancount; n++) {
789                 if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
790                     ttl = rr.ttl;
791                     if (n == 0 || ttl < result) {
792                         result = ttl;
793                     }
794                 } else {
795                     PLOG(INFO) << __func__ << ": ns_parserr failed ancount no = " << n;
796                 }
797             }
798         }
799     } else {
800         PLOG(INFO) << __func__ << ": ns_initparse failed";
801     }
802 
803     LOG(DEBUG) << __func__ << ": TTL = " << result;
804     return result;
805 }
806 
entry_free(Entry * e)807 static void entry_free(Entry* e) {
808     /* everything is allocated in a single memory block */
809     if (e) {
810         free(e);
811     }
812 }
813 
entry_mru_remove(Entry * e)814 static void entry_mru_remove(Entry* e) {
815     e->mru_prev->mru_next = e->mru_next;
816     e->mru_next->mru_prev = e->mru_prev;
817 }
818 
entry_mru_add(Entry * e,Entry * list)819 static void entry_mru_add(Entry* e, Entry* list) {
820     Entry* first = list->mru_next;
821 
822     e->mru_next = first;
823     e->mru_prev = list;
824 
825     list->mru_next = e;
826     first->mru_prev = e;
827 }
828 
829 /* compute the hash of a given entry, this is a hash of most
830  * data in the query (key) */
entry_hash(const Entry * e)831 static unsigned entry_hash(const Entry* e) {
832     DnsPacket pack[1];
833 
834     _dnsPacket_init(pack, e->query, e->querylen);
835     return _dnsPacket_hashQuery(pack);
836 }
837 
838 /* initialize an Entry as a search key, this also checks the input query packet
839  * returns 1 on success, or 0 in case of unsupported/malformed data */
entry_init_key(Entry * e,span<const uint8_t> query)840 static int entry_init_key(Entry* e, span<const uint8_t> query) {
841     DnsPacket pack[1];
842 
843     memset(e, 0, sizeof(*e));
844 
845     e->query = query.data();
846     e->querylen = query.size();
847     e->hash = entry_hash(e);
848 
849     _dnsPacket_init(pack, e->query, e->querylen);
850 
851     return _dnsPacket_checkQuery(pack);
852 }
853 
854 /* allocate a new entry as a cache node */
entry_alloc(const Entry * init,span<const uint8_t> answer)855 static Entry* entry_alloc(const Entry* init, span<const uint8_t> answer) {
856     Entry* e;
857     int size;
858 
859     size = sizeof(*e) + init->querylen + answer.size();
860     e = (Entry*) calloc(size, 1);
861     if (e == NULL) return e;
862 
863     e->hash = init->hash;
864     e->query = (const uint8_t*) (e + 1);
865     e->querylen = init->querylen;
866 
867     memcpy((char*) e->query, init->query, e->querylen);
868 
869     e->answer = e->query + e->querylen;
870     e->answerlen = answer.size();
871 
872     memcpy((char*)e->answer, answer.data(), e->answerlen);
873 
874     return e;
875 }
876 
entry_equals(const Entry * e1,const Entry * e2)877 static int entry_equals(const Entry* e1, const Entry* e2) {
878     DnsPacket pack1[1], pack2[1];
879 
880     if (e1->querylen != e2->querylen) {
881         return 0;
882     }
883     _dnsPacket_init(pack1, e1->query, e1->querylen);
884     _dnsPacket_init(pack2, e2->query, e2->querylen);
885 
886     return _dnsPacket_isEqualQuery(pack1, pack2);
887 }
888 
889 /* We use a simple hash table with external collision lists
890  * for simplicity, the hash-table fields 'hash' and 'hlink' are
891  * inlined in the Entry structure.
892  */
893 
894 /* Maximum time for a thread to wait for an pending request */
895 constexpr int PENDING_REQUEST_TIMEOUT = 20;
896 
897 // lock protecting everything in NetConfig.
898 static std::mutex cache_mutex;
899 static std::condition_variable cv;
900 
901 namespace {
902 
903 // Map format: ReturnCode:rate_denom
904 // if the ReturnCode is not associated with any rate_denom, use default
905 // Sampling rate varies by return code; events to log are chosen randomly, with a
906 // probability proportional to the sampling rate.
907 constexpr const char DEFAULT_SUBSAMPLING_MAP[] = "default:8 0:400 2:110 7:110";
908 constexpr const char DEFAULT_MDNS_SUBSAMPLING_MAP[] = "default:1";
909 
resolv_get_dns_event_subsampling_map(bool isMdns)910 std::unordered_map<int, uint32_t> resolv_get_dns_event_subsampling_map(bool isMdns) {
911     using android::base::ParseInt;
912     using android::base::ParseUint;
913     using android::base::Split;
914     using server_configurable_flags::GetServerConfigurableFlag;
915     std::unordered_map<int, uint32_t> sampling_rate_map{};
916     const char* flag = isMdns ? "mdns_event_subsample_map" : "dns_event_subsample_map";
917     const char* defaultMap = isMdns ? DEFAULT_MDNS_SUBSAMPLING_MAP : DEFAULT_SUBSAMPLING_MAP;
918     const std::vector<std::string> subsampling_vector =
919             Split(GetServerConfigurableFlag("netd_native", flag, defaultMap), " ");
920 
921     for (const auto& pair : subsampling_vector) {
922         std::vector<std::string> rate_denom = Split(pair, ":");
923         int return_code;
924         uint32_t denom;
925         if (rate_denom.size() != 2) {
926             LOG(ERROR) << __func__ << ": invalid subsampling_pair = " << pair;
927             continue;
928         }
929         if (rate_denom[0] == "default") {
930             return_code = DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY;
931         } else if (!ParseInt(rate_denom[0], &return_code)) {
932             LOG(ERROR) << __func__ << ": parse subsampling_pair failed = " << pair;
933             continue;
934         }
935         if (!ParseUint(rate_denom[1], &denom)) {
936             LOG(ERROR) << __func__ << ": parse subsampling_pair failed = " << pair;
937             continue;
938         }
939         sampling_rate_map[return_code] = denom;
940     }
941     return sampling_rate_map;
942 }
943 
944 }  // namespace
945 
946 // Note that Cache is not thread-safe per se, access to its members must be protected
947 // by an external mutex.
948 //
949 // TODO: move all cache manipulation code here and make data members private.
950 struct Cache {
CacheCache951     Cache() : max_cache_entries(get_max_cache_entries_from_flag()) {
952         entries.resize(max_cache_entries);
953         mru_list.mru_prev = mru_list.mru_next = &mru_list;
954     }
~CacheCache955     ~Cache() { flush(); }
956 
flushCache957     void flush() {
958         for (int nn = 0; nn < max_cache_entries; nn++) {
959             Entry** pnode = (Entry**)&entries[nn];
960 
961             while (*pnode) {
962                 Entry* node = *pnode;
963                 *pnode = node->hlink;
964                 entry_free(node);
965             }
966         }
967 
968         flushPendingRequests();
969 
970         mru_list.mru_next = mru_list.mru_prev = &mru_list;
971         num_entries = 0;
972         last_id = 0;
973 
974         LOG(INFO) << "DNS cache flushed";
975     }
976 
flushPendingRequestsCache977     void flushPendingRequests() {
978         pending_req_info* ri = pending_requests.next;
979         while (ri) {
980             pending_req_info* tmp = ri;
981             ri = ri->next;
982             free(tmp);
983         }
984 
985         pending_requests.next = nullptr;
986         cv.notify_all();
987     }
988 
get_max_cache_entriesCache989     int get_max_cache_entries() { return max_cache_entries; }
990 
991     int num_entries = 0;
992 
993     // TODO: convert to std::list
994     Entry mru_list;
995     int last_id = 0;
996     std::vector<Entry> entries;
997 
998     // TODO: convert to std::vector
999     struct pending_req_info {
1000         unsigned int hash;
1001         struct pending_req_info* next;
1002     } pending_requests{};
1003 
1004   private:
get_max_cache_entries_from_flagCache1005     int get_max_cache_entries_from_flag() {
1006         int entries = android::net::Experiments::getInstance()->getFlag("max_cache_entries",
1007                                                                         MAX_ENTRIES_DEFAULT);
1008         // Check both lower and upper bounds to prevent irrational values mistakenly pushed by
1009         // server.
1010         if (entries < MAX_ENTRIES_LOWER_BOUND || entries > MAX_ENTRIES_UPPER_BOUND) {
1011             LOG(ERROR) << "Misconfiguration on max_cache_entries " << entries;
1012             entries = MAX_ENTRIES_DEFAULT;
1013         }
1014         return entries;
1015     }
1016 
1017     const int max_cache_entries;
1018 };
1019 
1020 struct NetConfig {
NetConfigNetConfig1021     explicit NetConfig(unsigned netId) : netid(netId) {
1022         cache = std::make_unique<Cache>();
1023         dns_event_subsampling_map = resolv_get_dns_event_subsampling_map(false);
1024         mdns_event_subsampling_map = resolv_get_dns_event_subsampling_map(true);
1025     }
nameserverCountNetConfig1026     int nameserverCount() { return nameserverSockAddrs.size(); }
setOptionsNetConfig1027     int setOptions(const ResolverOptionsParcel& resolverOptions) {
1028         customizedTable.clear();
1029         for (const auto& host : resolverOptions.hosts) {
1030             if (!host.hostName.empty() && !host.ipAddr.empty())
1031                 customizedTable.emplace(host.hostName, host.ipAddr);
1032         }
1033 
1034         if (resolverOptions.tcMode < aidl::android::net::IDnsResolver::TC_MODE_DEFAULT ||
1035             resolverOptions.tcMode > aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP) {
1036             LOG(WARNING) << __func__ << ": netid = " << netid
1037                          << ", invalid TC mode: " << resolverOptions.tcMode;
1038             return -EINVAL;
1039         }
1040         tc_mode = resolverOptions.tcMode;
1041         enforceDnsUid = resolverOptions.enforceDnsUid;
1042         return 0;
1043     }
1044     const unsigned netid;
1045     std::unique_ptr<Cache> cache;
1046     std::vector<std::string> nameservers;
1047     std::vector<IPSockAddr> nameserverSockAddrs;
1048     int revision_id = 0;  // # times the nameservers have been replaced
1049     res_params params{};
1050     res_stats nsstats[MAXNS]{};
1051     std::vector<std::string> search_domains;
1052     int wait_for_pending_req_timeout_count = 0;
1053     // Map format: ReturnCode:rate_denom
1054     std::unordered_map<int, uint32_t> dns_event_subsampling_map;
1055     std::unordered_map<int, uint32_t> mdns_event_subsampling_map;
1056     DnsStats dnsStats;
1057 
1058     // Customized hostname/address table will be stored in customizedTable.
1059     // If resolverParams.hosts is empty, the existing customized table will be erased.
1060     typedef std::multimap<std::string /* hostname */, std::string /* IPv4/IPv6 address */>
1061             HostMapping;
1062     HostMapping customizedTable = {};
1063 
1064     int tc_mode = aidl::android::net::IDnsResolver::TC_MODE_DEFAULT;
1065     bool enforceDnsUid = false;
1066     std::vector<int32_t> transportTypes;
1067     bool metered = false;
1068     std::vector<std::string> interfaceNames;
1069 };
1070 
1071 /* gets cache associated with a network, or NULL if none exists */
1072 static Cache* find_named_cache_locked(unsigned netid) REQUIRES(cache_mutex);
1073 
1074 // Return true - if there is a pending request in |cache| matching |key|.
1075 // Return false - if no pending request is found matching the key. Optionally
1076 //                link a new one if parameter append_if_not_found is true.
cache_has_pending_request_locked(Cache * cache,const Entry * key,bool append_if_not_found)1077 static bool cache_has_pending_request_locked(Cache* cache, const Entry* key,
1078                                              bool append_if_not_found) {
1079     if (!cache || !key) return false;
1080 
1081     Cache::pending_req_info* ri = cache->pending_requests.next;
1082     Cache::pending_req_info* prev = &cache->pending_requests;
1083     while (ri) {
1084         if (ri->hash == key->hash) {
1085             return true;
1086         }
1087         prev = ri;
1088         ri = ri->next;
1089     }
1090 
1091     if (append_if_not_found) {
1092         ri = (Cache::pending_req_info*)calloc(1, sizeof(Cache::pending_req_info));
1093         if (ri) {
1094             ri->hash = key->hash;
1095             prev->next = ri;
1096         }
1097     }
1098     return false;
1099 }
1100 
1101 // Notify all threads that the cache entry |key| has become available
cache_notify_waiting_tid_locked(struct Cache * cache,const Entry * key)1102 static void cache_notify_waiting_tid_locked(struct Cache* cache, const Entry* key) {
1103     if (!cache || !key) return;
1104 
1105     Cache::pending_req_info* ri = cache->pending_requests.next;
1106     Cache::pending_req_info* prev = &cache->pending_requests;
1107     while (ri) {
1108         if (ri->hash == key->hash) {
1109             // remove item from list and destroy
1110             prev->next = ri->next;
1111             free(ri);
1112             cv.notify_all();
1113             return;
1114         }
1115         prev = ri;
1116         ri = ri->next;
1117     }
1118 }
1119 
_resolv_cache_query_failed(unsigned netid,span<const uint8_t> query,uint32_t flags)1120 void _resolv_cache_query_failed(unsigned netid, span<const uint8_t> query, uint32_t flags) {
1121     // We should not notify with these flags.
1122     if (flags & (ANDROID_RESOLV_NO_CACHE_STORE | ANDROID_RESOLV_NO_CACHE_LOOKUP)) {
1123         return;
1124     }
1125     Entry key[1];
1126 
1127     if (!entry_init_key(key, query)) return;
1128 
1129     std::lock_guard guard(cache_mutex);
1130 
1131     Cache* cache = find_named_cache_locked(netid);
1132 
1133     if (cache) {
1134         cache_notify_waiting_tid_locked(cache, key);
1135     }
1136 }
1137 
cache_dump_mru_locked(Cache * cache)1138 static void cache_dump_mru_locked(Cache* cache) {
1139     std::string buf = fmt::format("MRU LIST ({:2d}): ", cache->num_entries);
1140     for (Entry* e = cache->mru_list.mru_next; e != &cache->mru_list; e = e->mru_next) {
1141         fmt::format_to(std::back_inserter(buf), " {}", e->id);
1142     }
1143 
1144     LOG(DEBUG) << __func__ << ": " << buf;
1145 }
1146 
1147 /* This function tries to find a key within the hash table
1148  * In case of success, it will return a *pointer* to the hashed key.
1149  * In case of failure, it will return a *pointer* to NULL
1150  *
1151  * So, the caller must check '*result' to check for success/failure.
1152  *
1153  * The main idea is that the result can later be used directly in
1154  * calls to resolv_cache_add or _resolv_cache_remove as the 'lookup'
1155  * parameter. This makes the code simpler and avoids re-searching
1156  * for the key position in the htable.
1157  *
1158  * The result of a lookup_p is only valid until you alter the hash
1159  * table.
1160  */
_cache_lookup_p(Cache * cache,Entry * key)1161 static Entry** _cache_lookup_p(Cache* cache, Entry* key) {
1162     int index = key->hash % cache->get_max_cache_entries();
1163     Entry** pnode = (Entry**) &cache->entries[index];
1164 
1165     while (*pnode != NULL) {
1166         Entry* node = *pnode;
1167 
1168         if (node == NULL) break;
1169 
1170         if (node->hash == key->hash && entry_equals(node, key)) break;
1171 
1172         pnode = &node->hlink;
1173     }
1174     return pnode;
1175 }
1176 
1177 /* Add a new entry to the hash table. 'lookup' must be the
1178  * result of an immediate previous failed _lookup_p() call
1179  * (i.e. with *lookup == NULL), and 'e' is the pointer to the
1180  * newly created entry
1181  */
_cache_add_p(Cache * cache,Entry ** lookup,Entry * e)1182 static void _cache_add_p(Cache* cache, Entry** lookup, Entry* e) {
1183     *lookup = e;
1184     e->id = ++cache->last_id;
1185     entry_mru_add(e, &cache->mru_list);
1186     cache->num_entries += 1;
1187 
1188     LOG(DEBUG) << __func__ << ": entry " << e->id << " added (count=" << cache->num_entries << ")";
1189 }
1190 
1191 /* Remove an existing entry from the hash table,
1192  * 'lookup' must be the result of an immediate previous
1193  * and succesful _lookup_p() call.
1194  */
_cache_remove_p(Cache * cache,Entry ** lookup)1195 static void _cache_remove_p(Cache* cache, Entry** lookup) {
1196     Entry* e = *lookup;
1197 
1198     LOG(DEBUG) << __func__ << ": entry " << e->id << " removed (count=" << cache->num_entries - 1
1199                << ")";
1200 
1201     entry_mru_remove(e);
1202     *lookup = e->hlink;
1203     entry_free(e);
1204     cache->num_entries -= 1;
1205 }
1206 
1207 /* Remove the oldest entry from the hash table.
1208  */
_cache_remove_oldest(Cache * cache)1209 static void _cache_remove_oldest(Cache* cache) {
1210     Entry* oldest = cache->mru_list.mru_prev;
1211     Entry** lookup = _cache_lookup_p(cache, oldest);
1212 
1213     if (*lookup == NULL) { /* should not happen */
1214         LOG(INFO) << __func__ << ": OLDEST NOT IN HTABLE ?";
1215         return;
1216     }
1217     LOG(DEBUG) << __func__ << ": Cache full - removing oldest";
1218     res_pquery(std::span(oldest->query, oldest->querylen));
1219     _cache_remove_p(cache, lookup);
1220 }
1221 
1222 /* Remove all expired entries from the hash table.
1223  */
_cache_remove_expired(Cache * cache)1224 static void _cache_remove_expired(Cache* cache) {
1225     Entry* e;
1226     time_t now = _time_now();
1227 
1228     for (e = cache->mru_list.mru_next; e != &cache->mru_list;) {
1229         // Entry is old, remove
1230         if (now >= e->expires) {
1231             Entry** lookup = _cache_lookup_p(cache, e);
1232             if (*lookup == NULL) { /* should not happen */
1233                 LOG(INFO) << __func__ << ": ENTRY NOT IN HTABLE ?";
1234                 return;
1235             }
1236             e = e->mru_next;
1237             _cache_remove_p(cache, lookup);
1238         } else {
1239             e = e->mru_next;
1240         }
1241     }
1242 }
1243 
1244 // Get a NetConfig associated with a network, or nullptr if not found.
1245 static NetConfig* find_netconfig_locked(unsigned netid) REQUIRES(cache_mutex);
1246 
resolv_cache_lookup(unsigned netid,span<const uint8_t> query,span<uint8_t> answer,int * answerlen,uint32_t flags)1247 ResolvCacheStatus resolv_cache_lookup(unsigned netid, span<const uint8_t> query,
1248                                       span<uint8_t> answer, int* answerlen, uint32_t flags) {
1249     // Skip cache lookup, return RESOLV_CACHE_NOTFOUND directly so that it is
1250     // possible to cache the answer of this query.
1251     // If ANDROID_RESOLV_NO_CACHE_STORE is set, return RESOLV_CACHE_SKIP to skip possible cache
1252     // storing.
1253     // (b/150371903): ANDROID_RESOLV_NO_CACHE_STORE should imply ANDROID_RESOLV_NO_CACHE_LOOKUP
1254     // to avoid side channel attack.
1255     if (flags & (ANDROID_RESOLV_NO_CACHE_LOOKUP | ANDROID_RESOLV_NO_CACHE_STORE)) {
1256         return flags & ANDROID_RESOLV_NO_CACHE_STORE ? RESOLV_CACHE_SKIP : RESOLV_CACHE_NOTFOUND;
1257     }
1258     Entry key;
1259     Entry** lookup;
1260     Entry* e;
1261     time_t now;
1262 
1263     LOG(DEBUG) << __func__ << ": lookup";
1264 
1265     /* we don't cache malformed queries */
1266     if (!entry_init_key(&key, query)) {
1267         LOG(INFO) << __func__ << ": unsupported query";
1268         return RESOLV_CACHE_UNSUPPORTED;
1269     }
1270     /* lookup cache */
1271     std::unique_lock lock(cache_mutex);
1272     android::base::ScopedLockAssertion assume_lock(cache_mutex);
1273     Cache* cache = find_named_cache_locked(netid);
1274     if (cache == nullptr) {
1275         return RESOLV_CACHE_UNSUPPORTED;
1276     }
1277 
1278     /* see the description of _lookup_p to understand this.
1279      * the function always return a non-NULL pointer.
1280      */
1281     lookup = _cache_lookup_p(cache, &key);
1282     e = *lookup;
1283 
1284     if (e == NULL) {
1285         LOG(DEBUG) << __func__ << ": NOT IN CACHE";
1286 
1287         if (!cache_has_pending_request_locked(cache, &key, true)) {
1288             return RESOLV_CACHE_NOTFOUND;
1289         }
1290 
1291         LOG(INFO) << __func__ << ": Waiting for previous request";
1292         // wait until (1) timeout OR
1293         //            (2) cv is notified AND no pending request matching the |key|
1294         // (cv notifier should delete pending request before sending notification.)
1295         const bool ret = cv.wait_for(lock, std::chrono::seconds(PENDING_REQUEST_TIMEOUT),
1296                                 [netid, &cache, &key]() REQUIRES(cache_mutex) {
1297                                     // Must update cache as it could have been deleted
1298                                     cache = find_named_cache_locked(netid);
1299                                     return !cache_has_pending_request_locked(cache, &key, false);
1300                                 });
1301         if (!cache) {
1302             return RESOLV_CACHE_NOTFOUND;
1303         }
1304         if (ret == false) {
1305             NetConfig* info = find_netconfig_locked(netid);
1306             if (info != NULL) {
1307                 info->wait_for_pending_req_timeout_count++;
1308             }
1309         }
1310         lookup = _cache_lookup_p(cache, &key);
1311         e = *lookup;
1312         if (e == NULL) {
1313             return RESOLV_CACHE_NOTFOUND;
1314         }
1315     }
1316 
1317     now = _time_now();
1318 
1319     /* remove stale entries here */
1320     if (now >= e->expires) {
1321         LOG(DEBUG) << __func__ << ": NOT IN CACHE (STALE ENTRY " << *lookup << "DISCARDED)";
1322         res_pquery(std::span(e->query, e->querylen));
1323         _cache_remove_p(cache, lookup);
1324         return RESOLV_CACHE_NOTFOUND;
1325     }
1326 
1327     *answerlen = e->answerlen;
1328     if (e->answerlen > static_cast<ptrdiff_t>(answer.size())) {
1329         /* NOTE: we return UNSUPPORTED if the answer buffer is too short */
1330         LOG(INFO) << __func__ << ": ANSWER TOO LONG";
1331         return RESOLV_CACHE_UNSUPPORTED;
1332     }
1333 
1334     memcpy(answer.data(), e->answer, e->answerlen);
1335 
1336     /* bump up this entry to the top of the MRU list */
1337     if (e != cache->mru_list.mru_next) {
1338         entry_mru_remove(e);
1339         entry_mru_add(e, &cache->mru_list);
1340     }
1341 
1342     LOG(INFO) << __func__ << ": FOUND IN CACHE entry=" << e;
1343     return RESOLV_CACHE_FOUND;
1344 }
1345 
resolv_cache_add(unsigned netid,span<const uint8_t> query,span<const uint8_t> answer)1346 int resolv_cache_add(unsigned netid, span<const uint8_t> query, span<const uint8_t> answer) {
1347     Entry key[1];
1348     Entry* e;
1349     Entry** lookup;
1350     uint32_t ttl;
1351     Cache* cache = NULL;
1352 
1353     /* don't assume that the query has already been cached
1354      */
1355     if (!entry_init_key(key, query)) {
1356         LOG(INFO) << __func__ << ": passed invalid query?";
1357         return -EINVAL;
1358     }
1359 
1360     std::lock_guard guard(cache_mutex);
1361 
1362     cache = find_named_cache_locked(netid);
1363     if (cache == nullptr) {
1364         return -ENONET;
1365     }
1366 
1367     lookup = _cache_lookup_p(cache, key);
1368     e = *lookup;
1369 
1370     // Should only happen on ANDROID_RESOLV_NO_CACHE_LOOKUP
1371     if (e != NULL) {
1372         LOG(INFO) << __func__ << ": ALREADY IN CACHE (" << e << ") ? IGNORING ADD";
1373         cache_notify_waiting_tid_locked(cache, key);
1374         return -EEXIST;
1375     }
1376 
1377     if (cache->num_entries >= cache->get_max_cache_entries()) {
1378         _cache_remove_expired(cache);
1379         if (cache->num_entries >= cache->get_max_cache_entries()) {
1380             _cache_remove_oldest(cache);
1381         }
1382         // TODO: It looks useless, remove below code after having test to prove it.
1383         lookup = _cache_lookup_p(cache, key);
1384         e = *lookup;
1385         if (e != NULL) {
1386             LOG(INFO) << __func__ << ": ALREADY IN CACHE (" << e << ") ? IGNORING ADD";
1387             cache_notify_waiting_tid_locked(cache, key);
1388             return -EEXIST;
1389         }
1390     }
1391 
1392     ttl = answer_getTTL(answer);
1393     if (ttl > 0) {
1394         e = entry_alloc(key, answer);
1395         if (e != NULL) {
1396             e->expires = ttl + _time_now();
1397             _cache_add_p(cache, lookup, e);
1398         }
1399     }
1400 
1401     cache_dump_mru_locked(cache);
1402     cache_notify_waiting_tid_locked(cache, key);
1403 
1404     return 0;
1405 }
1406 
resolv_gethostbyaddr_from_cache(unsigned netid,char domain_name[],size_t domain_name_size,const char * ip_address,int af)1407 bool resolv_gethostbyaddr_from_cache(unsigned netid, char domain_name[], size_t domain_name_size,
1408                                      const char* ip_address, int af) {
1409     if (domain_name_size > NS_MAXDNAME) {
1410         LOG(WARNING) << __func__ << ": invalid domain_name_size " << domain_name_size;
1411         return false;
1412     } else if (ip_address == nullptr || ip_address[0] == '\0') {
1413         LOG(WARNING) << __func__ << ": invalid ip_address";
1414         return false;
1415     } else if (af != AF_INET && af != AF_INET6) {
1416         LOG(WARNING) << __func__ << ": unsupported AF";
1417         return false;
1418     }
1419 
1420     Cache* cache = nullptr;
1421     Entry* node = nullptr;
1422 
1423     ns_rr rr;
1424     ns_msg handle;
1425     ns_rr rr_query;
1426 
1427     struct sockaddr_in sa;
1428     struct sockaddr_in6 sa6;
1429     char* addr_buf = nullptr;
1430 
1431     std::lock_guard guard(cache_mutex);
1432 
1433     cache = find_named_cache_locked(netid);
1434     if (cache == nullptr) {
1435         return false;
1436     }
1437 
1438     for (node = cache->mru_list.mru_next; node != nullptr && node != &cache->mru_list;
1439          node = node->mru_next) {
1440         if (node->answer == nullptr) {
1441             continue;
1442         }
1443 
1444         memset(&handle, 0, sizeof(handle));
1445 
1446         if (ns_initparse(node->answer, node->answerlen, &handle) < 0) {
1447             continue;
1448         }
1449 
1450         for (int n = 0; n < ns_msg_count(handle, ns_s_an); n++) {
1451             memset(&rr, 0, sizeof(rr));
1452 
1453             if (ns_parserr(&handle, ns_s_an, n, &rr)) {
1454                 continue;
1455             }
1456 
1457             if (ns_rr_type(rr) == ns_t_a && af == AF_INET) {
1458                 addr_buf = (char*)&(sa.sin_addr);
1459             } else if (ns_rr_type(rr) == ns_t_aaaa && af == AF_INET6) {
1460                 addr_buf = (char*)&(sa6.sin6_addr);
1461             } else {
1462                 continue;
1463             }
1464 
1465             if (inet_pton(af, ip_address, addr_buf) != 1) {
1466                 LOG(WARNING) << __func__ << ": inet_pton() fail";
1467                 return false;
1468             }
1469 
1470             if (memcmp(ns_rr_rdata(rr), addr_buf, ns_rr_rdlen(rr)) == 0) {
1471                 int query_count = ns_msg_count(handle, ns_s_qd);
1472                 for (int i = 0; i < query_count; i++) {
1473                     memset(&rr_query, 0, sizeof(rr_query));
1474                     if (ns_parserr(&handle, ns_s_qd, i, &rr_query)) {
1475                         continue;
1476                     }
1477                     strlcpy(domain_name, ns_rr_name(rr_query), domain_name_size);
1478                     if (domain_name[0] != '\0') {
1479                         return true;
1480                     }
1481                 }
1482             }
1483         }
1484     }
1485 
1486     return false;
1487 }
1488 
1489 static std::unordered_map<unsigned, std::unique_ptr<NetConfig>> sNetConfigMap
1490         GUARDED_BY(cache_mutex);
1491 
1492 // Clears nameservers set for |netconfig| and clears the stats
1493 static void free_nameservers_locked(NetConfig* netconfig);
1494 // Order-insensitive comparison for the two set of servers.
1495 static bool resolv_is_nameservers_equal(const std::vector<std::string>& oldServers,
1496                                         const std::vector<std::string>& newServers);
1497 // clears the stats samples contained withing the given netconfig.
1498 static void res_cache_clear_stats_locked(NetConfig* netconfig);
1499 
1500 // public API for netd to query if name server is set on specific netid
resolv_has_nameservers(unsigned netid)1501 bool resolv_has_nameservers(unsigned netid) {
1502     std::lock_guard guard(cache_mutex);
1503     NetConfig* info = find_netconfig_locked(netid);
1504     return (info != nullptr) && (info->nameserverCount() > 0);
1505 }
1506 
resolv_create_cache_for_net(unsigned netid)1507 int resolv_create_cache_for_net(unsigned netid) {
1508     std::lock_guard guard(cache_mutex);
1509     if (sNetConfigMap.find(netid) != sNetConfigMap.end()) {
1510         LOG(ERROR) << __func__ << ": Cache is already created, netId: " << netid;
1511         return -EEXIST;
1512     }
1513 
1514     sNetConfigMap[netid] = std::make_unique<NetConfig>(netid);
1515 
1516     return 0;
1517 }
1518 
resolv_delete_cache_for_net(unsigned netid)1519 void resolv_delete_cache_for_net(unsigned netid) {
1520     std::lock_guard guard(cache_mutex);
1521     sNetConfigMap.erase(netid);
1522 }
1523 
resolv_flush_cache_for_net(unsigned netid)1524 int resolv_flush_cache_for_net(unsigned netid) {
1525     std::lock_guard guard(cache_mutex);
1526 
1527     NetConfig* netconfig = find_netconfig_locked(netid);
1528     if (netconfig == nullptr) {
1529         return -ENONET;
1530     }
1531     netconfig->cache->flush();
1532 
1533     // Also clear the NS statistics.
1534     res_cache_clear_stats_locked(netconfig);
1535     return 0;
1536 }
1537 
resolv_list_caches()1538 std::vector<unsigned> resolv_list_caches() {
1539     std::lock_guard guard(cache_mutex);
1540     std::vector<unsigned> result;
1541     result.reserve(sNetConfigMap.size());
1542     for (const auto& [netId, _] : sNetConfigMap) {
1543         result.push_back(netId);
1544     }
1545     return result;
1546 }
1547 
find_named_cache_locked(unsigned netid)1548 static Cache* find_named_cache_locked(unsigned netid) {
1549     NetConfig* info = find_netconfig_locked(netid);
1550     if (info != nullptr) return info->cache.get();
1551     return nullptr;
1552 }
1553 
find_netconfig_locked(unsigned netid)1554 static NetConfig* find_netconfig_locked(unsigned netid) {
1555     if (auto it = sNetConfigMap.find(netid); it != sNetConfigMap.end()) {
1556         return it->second.get();
1557     }
1558     return nullptr;
1559 }
1560 
resolv_get_network_types_for_net(unsigned netid)1561 android::net::NetworkType resolv_get_network_types_for_net(unsigned netid) {
1562     std::lock_guard guard(cache_mutex);
1563     NetConfig* netconfig = find_netconfig_locked(netid);
1564     if (netconfig == nullptr) return android::net::NT_UNKNOWN;
1565     return convert_network_type(netconfig->transportTypes);
1566 }
1567 
is_mdns_supported_transport_types(const std::vector<int32_t> & transportTypes)1568 bool is_mdns_supported_transport_types(const std::vector<int32_t>& transportTypes) {
1569     for (const auto& tp : transportTypes) {
1570         if (tp == IDnsResolver::TRANSPORT_CELLULAR || tp == IDnsResolver::TRANSPORT_VPN) {
1571             return false;
1572         }
1573     }
1574     return true;
1575 }
1576 
is_mdns_supported_network(unsigned netid)1577 bool is_mdns_supported_network(unsigned netid) {
1578     std::lock_guard guard(cache_mutex);
1579     NetConfig* netconfig = find_netconfig_locked(netid);
1580     if (netconfig == nullptr) return false;
1581     return is_mdns_supported_transport_types(netconfig->transportTypes);
1582 }
1583 
1584 namespace {
1585 
1586 // Returns valid domains without duplicates which are limited to max size |MAXDNSRCH|.
filter_domains(const std::vector<std::string> & domains)1587 std::vector<std::string> filter_domains(const std::vector<std::string>& domains) {
1588     std::set<std::string> tmp_set;
1589     std::vector<std::string> res;
1590 
1591     std::copy_if(domains.begin(), domains.end(), std::back_inserter(res),
1592                  [&tmp_set](const std::string& str) {
1593                      return !(str.size() > MAXDNSRCHPATH - 1) && (tmp_set.insert(str).second);
1594                  });
1595     if (res.size() > MAXDNSRCH) {
1596         LOG(WARNING) << __func__ << ": valid domains=" << res.size()
1597                      << ", but MAXDNSRCH=" << MAXDNSRCH;
1598         res.resize(MAXDNSRCH);
1599     }
1600     return res;
1601 }
1602 
filter_nameservers(const std::vector<std::string> & servers)1603 std::vector<std::string> filter_nameservers(const std::vector<std::string>& servers) {
1604     std::vector<std::string> res = servers;
1605     if (res.size() > MAXNS) {
1606         LOG(WARNING) << __func__ << ": too many servers: " << res.size();
1607         res.resize(MAXNS);
1608     }
1609     return res;
1610 }
1611 
isValidServer(const std::string & server)1612 bool isValidServer(const std::string& server) {
1613     const addrinfo hints = {
1614             .ai_family = AF_UNSPEC,
1615             .ai_socktype = SOCK_DGRAM,
1616     };
1617     addrinfo* result = nullptr;
1618     if (int err = getaddrinfo_numeric(server.c_str(), "53", hints, &result); err != 0) {
1619         LOG(WARNING) << __func__ << ": getaddrinfo_numeric(" << server
1620                      << ") = " << gai_strerror(err);
1621         return false;
1622     }
1623     freeaddrinfo(result);
1624     return true;
1625 }
1626 
1627 }  // namespace
1628 
getCustomizedTableByName(const size_t netid,const char * hostname)1629 std::vector<std::string> getCustomizedTableByName(const size_t netid, const char* hostname) {
1630     std::lock_guard guard(cache_mutex);
1631     NetConfig* netconfig = find_netconfig_locked(netid);
1632 
1633     std::vector<std::string> result;
1634     if (netconfig != nullptr) {
1635         const auto& hosts = netconfig->customizedTable.equal_range(hostname);
1636         for (auto i = hosts.first; i != hosts.second; ++i) {
1637             result.push_back(i->second);
1638         }
1639     }
1640     return result;
1641 }
1642 
resolv_get_interface_names(int netid)1643 std::vector<std::string> resolv_get_interface_names(int netid) {
1644     std::lock_guard guard(cache_mutex);
1645 
1646     NetConfig* netconfig = find_netconfig_locked(netid);
1647     if (netconfig != nullptr) return netconfig->interfaceNames;
1648     return {};
1649 }
1650 
resolv_set_nameservers(const ResolverParamsParcel & params)1651 int resolv_set_nameservers(const ResolverParamsParcel& params) {
1652     const unsigned netid = params.netId;
1653     std::vector<std::string> nameservers = filter_nameservers(params.servers);
1654     const int numservers = static_cast<int>(nameservers.size());
1655 
1656     LOG(DEBUG) << __func__ << ": netId = " << netid << ", numservers = " << numservers;
1657 
1658     // Parse the addresses before actually locking or changing any state, in case there is an error.
1659     // As a side effect this also reduces the time the lock is kept.
1660     std::vector<IPSockAddr> ipSockAddrs;
1661     ipSockAddrs.reserve(nameservers.size());
1662     for (const auto& server : nameservers) {
1663         if (!isValidServer(server)) return -EINVAL;
1664         ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53));
1665     }
1666 
1667     std::lock_guard guard(cache_mutex);
1668     NetConfig* netconfig = find_netconfig_locked(netid);
1669 
1670     if (netconfig == nullptr) return -ENONET;
1671 
1672     uint8_t old_max_samples = netconfig->params.max_samples;
1673 
1674     memset(&netconfig->params, 0, sizeof(netconfig->params));
1675     netconfig->params.sample_validity = params.sampleValiditySeconds;
1676     netconfig->params.success_threshold = params.successThreshold;
1677     netconfig->params.min_samples = params.minSamples;
1678     netconfig->params.max_samples = params.maxSamples;
1679     netconfig->params.base_timeout_msec = params.baseTimeoutMsec;
1680     netconfig->params.retry_count = params.retryCount;
1681 
1682     // This check must always be true, but add a protection against OEMs configure negative values
1683     // for retry_count and base_timeout_msec.
1684     if (netconfig->params.retry_count == 0) {
1685         const int retryCount = Experiments::getInstance()->getFlag("retry_count", RES_DFLRETRY);
1686         netconfig->params.retry_count = (retryCount <= 0) ? RES_DFLRETRY : retryCount;
1687     }
1688     if (netconfig->params.base_timeout_msec == 0) {
1689         const int retransmissionInterval =
1690                 Experiments::getInstance()->getFlag("retransmission_time_interval", RES_TIMEOUT);
1691         netconfig->params.base_timeout_msec =
1692                 (retransmissionInterval <= 0) ? RES_TIMEOUT : retransmissionInterval;
1693     }
1694 
1695     if (!resolv_is_nameservers_equal(netconfig->nameservers, params.servers)) {
1696         // free current before adding new
1697         free_nameservers_locked(netconfig);
1698         netconfig->nameservers = std::move(nameservers);
1699         for (int i = 0; i < numservers; i++) {
1700             LOG(INFO) << __func__ << ": netid = " << netid
1701                       << ", addr = " << netconfig->nameservers[i];
1702         }
1703         netconfig->nameserverSockAddrs = std::move(ipSockAddrs);
1704     } else {
1705         if (netconfig->params.max_samples != old_max_samples) {
1706             // If the maximum number of samples changes, the overhead of keeping the most recent
1707             // samples around is not considered worth the effort, so they are cleared instead.
1708             // All other parameters do not affect shared state: Changing these parameters does
1709             // not invalidate the samples, as they only affect aggregation and the conditions
1710             // under which servers are considered usable.
1711             res_cache_clear_stats_locked(netconfig);
1712         }
1713     }
1714 
1715     // Always update the search paths. Cache-flushing however is not necessary,
1716     // since the stored cache entries do contain the domain, not just the host name.
1717     netconfig->search_domains = filter_domains(params.domains);
1718 
1719     // Setup stats for cleartext dns servers.
1720     if (!netconfig->dnsStats.setAddrs(netconfig->nameserverSockAddrs, PROTO_TCP) ||
1721         !netconfig->dnsStats.setAddrs(netconfig->nameserverSockAddrs, PROTO_UDP)) {
1722         LOG(WARNING) << __func__ << ": netid = " << netid << ", failed to set dns stats";
1723         return -EINVAL;
1724     }
1725     netconfig->transportTypes = std::move(params.transportTypes);
1726     netconfig->metered = params.meteredNetwork;
1727     netconfig->interfaceNames = std::move(params.interfaceNames);
1728 
1729     if (params.resolverOptions.has_value()) {
1730         return netconfig->setOptions(params.resolverOptions.value());
1731     }
1732 
1733     return 0;
1734 }
1735 
resolv_set_options(unsigned netid,const ResolverOptionsParcel & options)1736 int resolv_set_options(unsigned netid, const ResolverOptionsParcel& options) {
1737     std::lock_guard guard(cache_mutex);
1738     NetConfig* netconfig = find_netconfig_locked(netid);
1739 
1740     if (netconfig == nullptr) return -ENONET;
1741     return netconfig->setOptions(options);
1742 }
1743 
resolv_is_nameservers_equal(const std::vector<std::string> & oldServers,const std::vector<std::string> & newServers)1744 static bool resolv_is_nameservers_equal(const std::vector<std::string>& oldServers,
1745                                         const std::vector<std::string>& newServers) {
1746     const std::set<std::string> olds(oldServers.begin(), oldServers.end());
1747     const std::set<std::string> news(newServers.begin(), newServers.end());
1748 
1749     // TODO: this is incorrect if the list of current or previous nameservers
1750     // contains duplicates. This does not really matter because the framework
1751     // filters out duplicates, but we should probably fix it. It's also
1752     // insensitive to the order of the nameservers; we should probably fix that
1753     // too.
1754     return olds == news;
1755 }
1756 
free_nameservers_locked(NetConfig * netconfig)1757 static void free_nameservers_locked(NetConfig* netconfig) {
1758     netconfig->nameservers.clear();
1759     netconfig->nameserverSockAddrs.clear();
1760     res_cache_clear_stats_locked(netconfig);
1761 }
1762 
resolv_populate_res_for_net(ResState * statp)1763 void resolv_populate_res_for_net(ResState* statp) {
1764     if (statp == nullptr) {
1765         return;
1766     }
1767     LOG(DEBUG) << __func__ << ": netid=" << statp->netid;
1768 
1769     std::lock_guard guard(cache_mutex);
1770     NetConfig* info = find_netconfig_locked(statp->netid);
1771     if (info == nullptr) return;
1772 
1773     const bool sortNameservers = Experiments::getInstance()->getFlag("sort_nameservers", 0);
1774     statp->sort_nameservers = sortNameservers;
1775     statp->nsaddrs = sortNameservers ? info->dnsStats.getSortedServers(PROTO_UDP)
1776                                      : info->nameserverSockAddrs;
1777     statp->search_domains = info->search_domains;
1778     statp->tc_mode = info->tc_mode;
1779     statp->enforce_dns_uid = info->enforceDnsUid;
1780 }
1781 
1782 /* Resolver reachability statistics. */
1783 
res_cache_add_stats_sample_locked(res_stats * stats,const res_sample & sample,int max_samples)1784 static void res_cache_add_stats_sample_locked(res_stats* stats, const res_sample& sample,
1785                                               int max_samples) {
1786     // Note: This function expects max_samples > 0, otherwise a (harmless) modification of the
1787     // allocated but supposedly unused memory for samples[0] will happen
1788     LOG(DEBUG) << __func__ << ": adding sample to stats, next = " << unsigned(stats->sample_next)
1789                << ", count = " << unsigned(stats->sample_count);
1790     stats->samples[stats->sample_next] = sample;
1791     if (stats->sample_count < max_samples) {
1792         ++stats->sample_count;
1793     }
1794     if (++stats->sample_next >= max_samples) {
1795         stats->sample_next = 0;
1796     }
1797 }
1798 
res_cache_clear_stats_locked(NetConfig * netconfig)1799 static void res_cache_clear_stats_locked(NetConfig* netconfig) {
1800     for (int i = 0; i < MAXNS; ++i) {
1801         netconfig->nsstats[i].sample_count = 0;
1802         netconfig->nsstats[i].sample_next = 0;
1803     }
1804 
1805     // Increment the revision id to ensure that sample state is not written back if the
1806     // servers change; in theory it would suffice to do so only if the servers or
1807     // max_samples actually change, in practice the overhead of checking is higher than the
1808     // cost, and overflows are unlikely.
1809     ++netconfig->revision_id;
1810 }
1811 
android_net_res_stats_get_info_for_net(unsigned netid,int * nscount,struct sockaddr_storage servers[MAXNS],int * dcount,char domains[MAXDNSRCH][MAXDNSRCHPATH],res_params * params,struct res_stats stats[MAXNS],int * wait_for_pending_req_timeout_count)1812 int android_net_res_stats_get_info_for_net(unsigned netid, int* nscount,
1813                                            struct sockaddr_storage servers[MAXNS], int* dcount,
1814                                            char domains[MAXDNSRCH][MAXDNSRCHPATH],
1815                                            res_params* params, struct res_stats stats[MAXNS],
1816                                            int* wait_for_pending_req_timeout_count) {
1817     std::lock_guard guard(cache_mutex);
1818     NetConfig* info = find_netconfig_locked(netid);
1819     if (!info) return -1;
1820 
1821     const int num = info->nameserverCount();
1822     if (num > MAXNS) {
1823         LOG(INFO) << __func__ << ": nscount " << num << " > MAXNS " << MAXNS;
1824         errno = EFAULT;
1825         return -1;
1826     }
1827 
1828     for (int i = 0; i < num; i++) {
1829         servers[i] = info->nameserverSockAddrs[i];
1830         stats[i] = info->nsstats[i];
1831     }
1832 
1833     for (size_t i = 0; i < info->search_domains.size(); i++) {
1834         strlcpy(domains[i], info->search_domains[i].c_str(), MAXDNSRCHPATH);
1835     }
1836 
1837     *nscount = num;
1838     *dcount = static_cast<int>(info->search_domains.size());
1839     *params = info->params;
1840     *wait_for_pending_req_timeout_count = info->wait_for_pending_req_timeout_count;
1841 
1842     return info->revision_id;
1843 }
1844 
resolv_cache_dump_subsampling_map(unsigned netid,bool is_mdns)1845 std::vector<std::string> resolv_cache_dump_subsampling_map(unsigned netid, bool is_mdns) {
1846     std::lock_guard guard(cache_mutex);
1847     NetConfig* netconfig = find_netconfig_locked(netid);
1848     if (netconfig == nullptr) return {};
1849     std::vector<std::string> result;
1850     const auto& subsampling_map = (!is_mdns) ? netconfig->dns_event_subsampling_map
1851                                              : netconfig->mdns_event_subsampling_map;
1852     result.reserve(subsampling_map.size());
1853     for (const auto& [return_code, rate_denom] : subsampling_map) {
1854         result.push_back(fmt::format("{}:{}",
1855                                      (return_code == DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY)
1856                                              ? "default"
1857                                              : std::to_string(return_code),
1858                                      rate_denom));
1859     }
1860     return result;
1861 }
1862 
1863 // Decides whether an event should be sampled using a random number generator and
1864 // a sampling factor derived from the netid and the return code.
1865 //
1866 // Returns the subsampling rate if the event should be sampled, or 0 if it should be discarded.
resolv_cache_get_subsampling_denom(unsigned netid,int return_code,bool is_mdns)1867 uint32_t resolv_cache_get_subsampling_denom(unsigned netid, int return_code, bool is_mdns) {
1868     std::lock_guard guard(cache_mutex);
1869     NetConfig* netconfig = find_netconfig_locked(netid);
1870     if (netconfig == nullptr) return 0;  // Don't log anything at all.
1871     const auto& subsampling_map = (!is_mdns) ? netconfig->dns_event_subsampling_map
1872                                              : netconfig->mdns_event_subsampling_map;
1873     auto search_returnCode = subsampling_map.find(return_code);
1874     uint32_t denom;
1875     if (search_returnCode != subsampling_map.end()) {
1876         denom = search_returnCode->second;
1877     } else {
1878         auto search_default = subsampling_map.find(DNSEVENT_SUBSAMPLING_MAP_DEFAULT_KEY);
1879         denom = (search_default == subsampling_map.end()) ? 0 : search_default->second;
1880     }
1881     return denom;
1882 }
1883 
resolv_cache_get_resolver_stats(unsigned netid,res_params * params,res_stats stats[MAXNS],const std::vector<IPSockAddr> & serverSockAddrs)1884 int resolv_cache_get_resolver_stats(unsigned netid, res_params* params, res_stats stats[MAXNS],
1885                                     const std::vector<IPSockAddr>& serverSockAddrs) {
1886     std::lock_guard guard(cache_mutex);
1887     NetConfig* info = find_netconfig_locked(netid);
1888     if (!info) {
1889         LOG(WARNING) << __func__ << ": NetConfig for netid " << netid << " not found";
1890         return -1;
1891     }
1892 
1893     for (size_t i = 0; i < serverSockAddrs.size(); i++) {
1894         for (size_t j = 0; j < info->nameserverSockAddrs.size(); j++) {
1895             // Should never happen. Just in case because of the fix-sized array |stats|.
1896             if (j >= MAXNS) {
1897                 LOG(WARNING) << __func__ << ": unexpected size " << j;
1898                 return -1;
1899             }
1900 
1901             // It's possible that the server is not found, e.g. when a new list of nameservers
1902             // is updated to the NetConfig just after this look up thread being populated.
1903             // Keep the server valid as-is (by means of keeping stats[i] unset), but we should
1904             // think about if there's a better way.
1905             if (info->nameserverSockAddrs[j] == serverSockAddrs[i]) {
1906                 stats[i] = info->nsstats[j];
1907                 break;
1908             }
1909         }
1910     }
1911 
1912     *params = info->params;
1913     return info->revision_id;
1914 }
1915 
resolv_cache_add_resolver_stats_sample(unsigned netid,int revision_id,const IPSockAddr & serverSockAddr,const res_sample & sample,int max_samples)1916 void resolv_cache_add_resolver_stats_sample(unsigned netid, int revision_id,
1917                                             const IPSockAddr& serverSockAddr,
1918                                             const res_sample& sample, int max_samples) {
1919     if (max_samples <= 0) return;
1920 
1921     std::lock_guard guard(cache_mutex);
1922     NetConfig* info = find_netconfig_locked(netid);
1923 
1924     if (info && info->revision_id == revision_id) {
1925         const int serverNum = std::min(MAXNS, static_cast<int>(info->nameserverSockAddrs.size()));
1926         for (int ns = 0; ns < serverNum; ns++) {
1927             if (serverSockAddr == info->nameserverSockAddrs[ns]) {
1928                 res_cache_add_stats_sample_locked(&info->nsstats[ns], sample, max_samples);
1929                 return;
1930             }
1931         }
1932     }
1933 }
1934 
has_named_cache(unsigned netid)1935 bool has_named_cache(unsigned netid) {
1936     std::lock_guard guard(cache_mutex);
1937     return find_named_cache_locked(netid) != nullptr;
1938 }
1939 
resolv_cache_get_expiration(unsigned netid,span<const uint8_t> query,time_t * expiration)1940 int resolv_cache_get_expiration(unsigned netid, span<const uint8_t> query, time_t* expiration) {
1941     Entry key;
1942     *expiration = -1;
1943 
1944     // A malformed query is not allowed.
1945     if (!entry_init_key(&key, query)) {
1946         LOG(WARNING) << __func__ << ": unsupported query";
1947         return -EINVAL;
1948     }
1949 
1950     // lookup cache.
1951     Cache* cache;
1952     std::lock_guard guard(cache_mutex);
1953     if (cache = find_named_cache_locked(netid); cache == nullptr) {
1954         LOG(WARNING) << __func__ << ": cache not created in the network " << netid;
1955         return -ENONET;
1956     }
1957     Entry** lookup = _cache_lookup_p(cache, &key);
1958     Entry* e = *lookup;
1959     if (e == NULL) {
1960         LOG(WARNING) << __func__ << ": not in cache";
1961         return -ENODATA;
1962     }
1963 
1964     if (_time_now() >= e->expires) {
1965         LOG(WARNING) << __func__ << ": entry expired";
1966         return -ENODATA;
1967     }
1968 
1969     *expiration = e->expires;
1970     return 0;
1971 }
1972 
resolv_stats_set_addrs(unsigned netid,Protocol proto,const std::vector<std::string> & addrs,int port)1973 int resolv_stats_set_addrs(unsigned netid, Protocol proto, const std::vector<std::string>& addrs,
1974                            int port) {
1975     std::lock_guard guard(cache_mutex);
1976     const auto info = find_netconfig_locked(netid);
1977 
1978     if (info == nullptr) {
1979         LOG(WARNING) << __func__ << ": Network " << netid << " not found for "
1980                      << Protocol_Name(proto);
1981         return -ENONET;
1982     }
1983 
1984     std::vector<IPSockAddr> sockAddrs;
1985     sockAddrs.reserve(addrs.size());
1986     for (const auto& addr : addrs) {
1987         sockAddrs.push_back(IPSockAddr::toIPSockAddr(addr, port));
1988     }
1989 
1990     if (!info->dnsStats.setAddrs(sockAddrs, proto)) {
1991         LOG(WARNING) << __func__ << ": Failed to set " << Protocol_Name(proto) << " on network "
1992                      << netid;
1993         return -EINVAL;
1994     }
1995 
1996     return 0;
1997 }
1998 
resolv_stats_add(unsigned netid,const android::netdutils::IPSockAddr & server,const DnsQueryEvent * record)1999 bool resolv_stats_add(unsigned netid, const android::netdutils::IPSockAddr& server,
2000                       const DnsQueryEvent* record) {
2001     if (record == nullptr) return false;
2002 
2003     std::lock_guard guard(cache_mutex);
2004     if (const auto info = find_netconfig_locked(netid); info != nullptr) {
2005         return info->dnsStats.addStats(server, *record);
2006     }
2007     return false;
2008 }
2009 
tc_mode_to_str(const int mode)2010 static const char* tc_mode_to_str(const int mode) {
2011     switch (mode) {
2012         case aidl::android::net::IDnsResolver::TC_MODE_DEFAULT:
2013             return "default";
2014         case aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP:
2015             return "UDP_TCP";
2016         default:
2017             return "unknown";
2018     }
2019 }
2020 
to_stats_network_type(int32_t mainType,bool withVpn)2021 static android::net::NetworkType to_stats_network_type(int32_t mainType, bool withVpn) {
2022     switch (mainType) {
2023         case IDnsResolver::TRANSPORT_CELLULAR:
2024             return withVpn ? android::net::NT_CELLULAR_VPN : android::net::NT_CELLULAR;
2025         case IDnsResolver::TRANSPORT_WIFI:
2026             return withVpn ? android::net::NT_WIFI_VPN : android::net::NT_WIFI;
2027         case IDnsResolver::TRANSPORT_BLUETOOTH:
2028             return withVpn ? android::net::NT_BLUETOOTH_VPN : android::net::NT_BLUETOOTH;
2029         case IDnsResolver::TRANSPORT_ETHERNET:
2030             return withVpn ? android::net::NT_ETHERNET_VPN : android::net::NT_ETHERNET;
2031         case IDnsResolver::TRANSPORT_SATELLITE:
2032             return withVpn ? android::net::NT_UNKNOWN : android::net::NT_SATELLITE;
2033         case IDnsResolver::TRANSPORT_VPN:
2034             return withVpn ? android::net::NT_UNKNOWN : android::net::NT_VPN;
2035         case IDnsResolver::TRANSPORT_WIFI_AWARE:
2036             return withVpn ? android::net::NT_UNKNOWN : android::net::NT_WIFI_AWARE;
2037         case IDnsResolver::TRANSPORT_LOWPAN:
2038             return withVpn ? android::net::NT_UNKNOWN : android::net::NT_LOWPAN;
2039         default:
2040             return android::net::NT_UNKNOWN;
2041     }
2042 }
2043 
convert_network_type(const std::vector<int32_t> & transportTypes)2044 android::net::NetworkType convert_network_type(const std::vector<int32_t>& transportTypes) {
2045     // The valid transportTypes size is 1 to 3.
2046     if (transportTypes.size() > 3 || transportTypes.size() == 0) return android::net::NT_UNKNOWN;
2047     // TransportTypes size == 1, map the type to stats network type directly.
2048     if (transportTypes.size() == 1) return to_stats_network_type(transportTypes[0], false);
2049     // TransportTypes size == 3, only cellular + wifi + vpn is valid.
2050     if (transportTypes.size() == 3) {
2051         std::vector<int32_t> sortedTransTypes = transportTypes;
2052         std::sort(sortedTransTypes.begin(), sortedTransTypes.end());
2053         if (sortedTransTypes != std::vector<int32_t>{IDnsResolver::TRANSPORT_CELLULAR,
2054                                                      IDnsResolver::TRANSPORT_WIFI,
2055                                                      IDnsResolver::TRANSPORT_VPN}) {
2056             return android::net::NT_UNKNOWN;
2057         }
2058         return android::net::NT_WIFI_CELLULAR_VPN;
2059     }
2060     // TransportTypes size == 2, it shoud be 1 main type + vpn type.
2061     // Otherwise, consider it as UNKNOWN.
2062     bool hasVpn = false;
2063     int32_t mainType = IDnsResolver::TRANSPORT_UNKNOWN;
2064     for (const auto& transportType : transportTypes) {
2065         if (transportType == IDnsResolver::TRANSPORT_VPN) {
2066             hasVpn = true;
2067             continue;
2068         }
2069         mainType = transportType;
2070     }
2071     return hasVpn ? to_stats_network_type(mainType, true) : android::net::NT_UNKNOWN;
2072 }
2073 
transport_type_to_str(const std::vector<int32_t> & transportTypes)2074 static const char* transport_type_to_str(const std::vector<int32_t>& transportTypes) {
2075     switch (convert_network_type(transportTypes)) {
2076         case android::net::NT_CELLULAR:
2077             return "CELLULAR";
2078         case android::net::NT_WIFI:
2079             return "WIFI";
2080         case android::net::NT_BLUETOOTH:
2081             return "BLUETOOTH";
2082         case android::net::NT_ETHERNET:
2083             return "ETHERNET";
2084         case android::net::NT_VPN:
2085             return "VPN";
2086         case android::net::NT_WIFI_AWARE:
2087             return "WIFI_AWARE";
2088         case android::net::NT_LOWPAN:
2089             return "LOWPAN";
2090         case android::net::NT_CELLULAR_VPN:
2091             return "CELLULAR_VPN";
2092         case android::net::NT_WIFI_VPN:
2093             return "WIFI_VPN";
2094         case android::net::NT_BLUETOOTH_VPN:
2095             return "BLUETOOTH_VPN";
2096         case android::net::NT_ETHERNET_VPN:
2097             return "ETHERNET_VPN";
2098         case android::net::NT_WIFI_CELLULAR_VPN:
2099             return "WIFI_CELLULAR_VPN";
2100         case android::net::NT_SATELLITE:
2101             return "SATELLITE";
2102         default:
2103             return "UNKNOWN";
2104     }
2105 }
2106 
resolv_netconfig_dump(DumpWriter & dw,unsigned netid)2107 void resolv_netconfig_dump(DumpWriter& dw, unsigned netid) {
2108     std::lock_guard guard(cache_mutex);
2109     if (const auto info = find_netconfig_locked(netid); info != nullptr) {
2110         info->dnsStats.dump(dw);
2111         // TODO: dump info->hosts
2112         dw.println("TC mode: %s", tc_mode_to_str(info->tc_mode));
2113         dw.println("TransportType: %s", transport_type_to_str(info->transportTypes));
2114         dw.println("Metered: %s", info->metered ? "true" : "false");
2115     }
2116 }
2117 
resolv_get_max_cache_entries(unsigned netid)2118 int resolv_get_max_cache_entries(unsigned netid) {
2119     std::lock_guard guard(cache_mutex);
2120     NetConfig* info = find_netconfig_locked(netid);
2121     if (!info) {
2122         LOG(WARNING) << __func__ << ": NetConfig for netid " << netid << " not found";
2123         return -1;
2124     }
2125     return info->cache->get_max_cache_entries();
2126 }
2127 
resolv_is_enforceDnsUid_enabled_network(unsigned netid)2128 bool resolv_is_enforceDnsUid_enabled_network(unsigned netid) {
2129     std::lock_guard guard(cache_mutex);
2130     if (const auto info = find_netconfig_locked(netid); info != nullptr) {
2131         return info->enforceDnsUid;
2132     }
2133     return false;
2134 }
2135 
resolv_is_metered_network(unsigned netid)2136 bool resolv_is_metered_network(unsigned netid) {
2137     std::lock_guard guard(cache_mutex);
2138     if (const auto info = find_netconfig_locked(netid); info != nullptr) {
2139         return info->metered;
2140     }
2141     return false;
2142 }
2143