1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <netdb.h>
18 
19 #include <array>
20 #include <atomic>
21 #include <chrono>
22 #include <ctime>
23 #include <span>
24 #include <thread>
25 
26 #include <android-base/logging.h>
27 #include <android/multinetwork.h>
28 #include <arpa/inet.h>
29 #include <cutils/properties.h>
30 #include <gmock/gmock-matchers.h>
31 #include <gtest/gtest.h>
32 #include <netdutils/NetNativeTestBase.h>
33 
34 #include "Experiments.h"
35 #include "resolv_cache.h"
36 #include "resolv_private.h"
37 #include "stats.h"
38 #include "tests/dns_responder/dns_responder.h"
39 #include "tests/resolv_test_utils.h"
40 
41 using namespace std::chrono_literals;
42 
43 using android::netdutils::IPSockAddr;
44 
45 const std::string kMaxCacheEntriesFlag("persist.device_config.netd_native.max_cache_entries");
46 
47 constexpr int TEST_NETID_2 = 31;
48 constexpr int DNS_PORT = 53;
49 
50 // Constant values sync'd from res_cache.cpp
51 constexpr int DNS_HEADER_SIZE = 12;
52 constexpr int MAX_ENTRIES_DEFAULT = 64 * 2 * 5;
53 constexpr int MAX_ENTRIES_LOWER_BOUND = 1;
54 constexpr int MAX_ENTRIES_UPPER_BOUND = 100 * 1000;
55 
56 namespace {
57 
58 struct CacheEntry {
59     std::vector<uint8_t> query;
60     std::vector<uint8_t> answer;
61 };
62 
63 struct SetupParams {
64     std::vector<std::string> servers;
65     std::vector<std::string> domains;
66     res_params params;
67     aidl::android::net::ResolverOptionsParcel resolverOptions;
68     std::vector<int32_t> transportTypes;
69     bool metered;
70 };
71 
72 struct CacheStats {
73     SetupParams setup;
74     std::vector<res_stats> stats;
75     int pendingReqTimeoutCount;
76 };
77 
makeQuery(int op,const char * qname,int qclass,int qtype)78 std::vector<uint8_t> makeQuery(int op, const char* qname, int qclass, int qtype) {
79     uint8_t buf[MAXPACKET] = {};
80     const int len = res_nmkquery(op, qname, qclass, qtype, {}, buf, /*netcontext_flags=*/0);
81     return std::vector<uint8_t>(buf, buf + len);
82 }
83 
makeAnswer(const std::vector<uint8_t> & query,const char * rdata_str,const unsigned ttl)84 std::vector<uint8_t> makeAnswer(const std::vector<uint8_t>& query, const char* rdata_str,
85                                 const unsigned ttl) {
86     test::DNSHeader header;
87     header.read(reinterpret_cast<const char*>(query.data()),
88                 reinterpret_cast<const char*>(query.data()) + query.size());
89 
90     for (const test::DNSQuestion& question : header.questions) {
91         std::string rname(question.qname.name);
92         test::DNSRecord record{
93                 .name = {.name = question.qname.name},
94                 .rtype = question.qtype,
95                 .rclass = question.qclass,
96                 .ttl = ttl,
97         };
98         test::DNSResponder::fillRdata(rdata_str, record);
99         header.answers.push_back(std::move(record));
100     }
101 
102     char answer[MAXPACKET] = {};
103     char* answer_end = header.write(answer, answer + sizeof(answer));
104     return std::vector<uint8_t>(answer, answer_end);
105 }
106 
107 // Get the current time in unix timestamp since the Epoch.
currentTime()108 time_t currentTime() {
109     return std::time(nullptr);
110 }
111 
112 // Comparison for res_sample.
operator ==(const res_sample & a,const res_sample & b)113 bool operator==(const res_sample& a, const res_sample& b) {
114     return std::tie(a.at, a.rtt, a.rcode) == std::tie(b.at, b.rtt, b.rcode);
115 }
116 
117 // Comparison for res_stats.
operator ==(const res_stats & a,const res_stats & b)118 bool operator==(const res_stats& a, const res_stats& b) {
119     if (std::tie(a.sample_count, a.sample_next) != std::tie(b.sample_count, b.sample_next)) {
120         return false;
121     }
122     for (int i = 0; i < a.sample_count; i++) {
123         if (a.samples[i] != b.samples[i]) return false;
124     }
125     return true;
126 }
127 
128 // Comparison for res_params.
operator ==(const res_params & a,const res_params & b)129 bool operator==(const res_params& a, const res_params& b) {
130     return std::tie(a.sample_validity, a.success_threshold, a.min_samples, a.max_samples,
131                     a.base_timeout_msec, a.retry_count) ==
132            std::tie(b.sample_validity, b.success_threshold, b.min_samples, b.max_samples,
133                     b.base_timeout_msec, b.retry_count);
134 }
135 
136 }  // namespace
137 
138 class ResolvCacheTest : public NetNativeTestBase {
139   protected:
140     static constexpr res_params kParams = {
141             .sample_validity = 300,
142             .success_threshold = 25,
143             .min_samples = 8,
144             .max_samples = 8,
145             .base_timeout_msec = 1000,
146             .retry_count = 2,
147     };
148 
ResolvCacheTest()149     ResolvCacheTest() {
150         // Store the default one and conceal 10000+ lines of resolver cache logs.
151         defaultLogSeverity = android::base::SetMinimumLogSeverity(
152                 static_cast<android::base::LogSeverity>(android::base::WARNING));
153     }
~ResolvCacheTest()154     ~ResolvCacheTest() {
155         cacheDelete(TEST_NETID);
156         cacheDelete(TEST_NETID_2);
157 
158         // Restore the log severity.
159         android::base::SetMinimumLogSeverity(defaultLogSeverity);
160     }
161 
cacheLookup(ResolvCacheStatus expectedCacheStatus,uint32_t netId,const CacheEntry & ce,uint32_t flags=0)162     [[nodiscard]] bool cacheLookup(ResolvCacheStatus expectedCacheStatus, uint32_t netId,
163                                    const CacheEntry& ce, uint32_t flags = 0) {
164         int anslen = 0;
165         std::vector<uint8_t> answer(MAXPACKET);
166         const auto cacheStatus = resolv_cache_lookup(netId, ce.query, answer, &anslen, flags);
167         if (cacheStatus != expectedCacheStatus) {
168             ADD_FAILURE() << "cacheStatus: expected = " << expectedCacheStatus
169                           << ", actual =" << cacheStatus;
170             return false;
171         }
172 
173         if (cacheStatus == RESOLV_CACHE_FOUND) {
174             answer.resize(anslen);
175             if (answer != ce.answer) {
176                 ADD_FAILURE() << "The answer from the cache is not as expected.";
177                 return false;
178             }
179         }
180         return true;
181     }
182 
cacheCreate(uint32_t netId)183     int cacheCreate(uint32_t netId) {
184         return resolv_create_cache_for_net(netId);
185     }
186 
cacheDelete(uint32_t netId)187     void cacheDelete(uint32_t netId) {
188         resolv_delete_cache_for_net(netId);
189     }
190 
cacheAdd(uint32_t netId,const CacheEntry & ce)191     int cacheAdd(uint32_t netId, const CacheEntry& ce) {
192         return resolv_cache_add(netId, ce.query, ce.answer);
193     }
194 
cacheAdd(uint32_t netId,const std::vector<uint8_t> & query,const std::vector<uint8_t> & answer)195     int cacheAdd(uint32_t netId, const std::vector<uint8_t>& query,
196                  const std::vector<uint8_t>& answer) {
197         return resolv_cache_add(netId, query, answer);
198     }
199 
cacheGetExpiration(uint32_t netId,const std::vector<uint8_t> & query,time_t * expiration)200     int cacheGetExpiration(uint32_t netId, const std::vector<uint8_t>& query, time_t* expiration) {
201         return resolv_cache_get_expiration(netId, query, expiration);
202     }
203 
cacheQueryFailed(uint32_t netId,const CacheEntry & ce,uint32_t flags)204     void cacheQueryFailed(uint32_t netId, const CacheEntry& ce, uint32_t flags) {
205         _resolv_cache_query_failed(netId, ce.query, flags);
206     }
207 
cacheSetupResolver(uint32_t netId,const SetupParams & setup)208     int cacheSetupResolver(uint32_t netId, const SetupParams& setup) {
209         return resolv_set_nameservers(netId, setup.servers, setup.domains, setup.params,
210                                       setup.resolverOptions, setup.transportTypes, setup.metered);
211     }
212 
cacheAddStats(uint32_t netId,int revision_id,const IPSockAddr & ipsa,const res_sample & sample,int max_samples)213     void cacheAddStats(uint32_t netId, int revision_id, const IPSockAddr& ipsa,
214                        const res_sample& sample, int max_samples) {
215         resolv_cache_add_resolver_stats_sample(netId, revision_id, ipsa, sample, max_samples);
216     }
217 
cacheFlush(uint32_t netId)218     int cacheFlush(uint32_t netId) { return resolv_flush_cache_for_net(netId); }
219 
expectCacheStats(const std::string & msg,uint32_t netId,const CacheStats & expected)220     void expectCacheStats(const std::string& msg, uint32_t netId, const CacheStats& expected) {
221         int nscount = -1;
222         sockaddr_storage servers[MAXNS];
223         int dcount = -1;
224         char domains[MAXDNSRCH][MAXDNSRCHPATH];
225         res_stats stats[MAXNS];
226         res_params params = {};
227         int res_wait_for_pending_req_timeout_count;
228         android_net_res_stats_get_info_for_net(netId, &nscount, servers, &dcount, domains, &params,
229                                                stats, &res_wait_for_pending_req_timeout_count);
230 
231         // Server checking.
232         EXPECT_EQ(nscount, static_cast<int>(expected.setup.servers.size())) << msg;
233         for (int i = 0; i < nscount; i++) {
234             EXPECT_EQ(ToString(&servers[i]), expected.setup.servers[i]) << msg;
235         }
236 
237         // Domain checking
238         EXPECT_EQ(dcount, static_cast<int>(expected.setup.domains.size())) << msg;
239         for (int i = 0; i < dcount; i++) {
240             EXPECT_EQ(std::string(domains[i]), expected.setup.domains[i]) << msg;
241         }
242 
243         // res_params checking.
244         EXPECT_TRUE(params == expected.setup.params) << msg;
245 
246         // res_stats checking.
247         if (expected.stats.size() == 0) {
248             for (int ns = 0; ns < nscount; ns++) {
249                 EXPECT_EQ(0U, stats[ns].sample_count) << msg;
250             }
251         }
252         for (size_t i = 0; i < expected.stats.size(); i++) {
253             EXPECT_TRUE(stats[i] == expected.stats[i]) << msg;
254         }
255 
256         // wait_for_pending_req_timeout_count checking.
257         EXPECT_EQ(res_wait_for_pending_req_timeout_count, expected.pendingReqTimeoutCount) << msg;
258     }
259 
makeCacheEntry(int op,const char * qname,int qclass,int qtype,const char * rdata,std::chrono::seconds ttl=10s)260     CacheEntry makeCacheEntry(int op, const char* qname, int qclass, int qtype, const char* rdata,
261                               std::chrono::seconds ttl = 10s) {
262         CacheEntry ce;
263         ce.query = makeQuery(op, qname, qclass, qtype);
264         ce.answer = makeAnswer(ce.query, rdata, static_cast<unsigned>(ttl.count()));
265         return ce;
266     }
267 
268   private:
269     android::base::LogSeverity defaultLogSeverity;
270 };
271 
TEST_F(ResolvCacheTest,CreateAndDeleteCache)272 TEST_F(ResolvCacheTest, CreateAndDeleteCache) {
273     // Create the cache for network 1.
274     EXPECT_EQ(0, cacheCreate(TEST_NETID));
275     EXPECT_EQ(-EEXIST, cacheCreate(TEST_NETID));
276     EXPECT_TRUE(has_named_cache(TEST_NETID));
277 
278     // Create the cache for network 2.
279     EXPECT_EQ(0, cacheCreate(TEST_NETID_2));
280     EXPECT_EQ(-EEXIST, cacheCreate(TEST_NETID_2));
281     EXPECT_TRUE(has_named_cache(TEST_NETID_2));
282 
283     // Delete the cache in network 1.
284     cacheDelete(TEST_NETID);
285     EXPECT_FALSE(has_named_cache(TEST_NETID));
286     EXPECT_TRUE(has_named_cache(TEST_NETID_2));
287 }
288 
289 // Missing checks for the argument 'answer'.
TEST_F(ResolvCacheTest,CacheAdd_InvalidArgs)290 TEST_F(ResolvCacheTest, CacheAdd_InvalidArgs) {
291     EXPECT_EQ(0, cacheCreate(TEST_NETID));
292 
293     const std::vector<uint8_t> queryEmpty(MAXPACKET, 0);
294     const std::vector<uint8_t> queryTooSmall(DNS_HEADER_SIZE - 1, 0);
295     CacheEntry ce = makeCacheEntry(QUERY, "valid.cache", ns_c_in, ns_t_a, "1.2.3.4");
296 
297     EXPECT_EQ(-EINVAL, cacheAdd(TEST_NETID, queryEmpty, ce.answer));
298     EXPECT_EQ(-EINVAL, cacheAdd(TEST_NETID, queryTooSmall, ce.answer));
299 
300     // Cache not existent in TEST_NETID_2.
301     EXPECT_EQ(-ENONET, cacheAdd(TEST_NETID_2, ce));
302 }
303 
TEST_F(ResolvCacheTest,CacheAdd_DuplicateEntry)304 TEST_F(ResolvCacheTest, CacheAdd_DuplicateEntry) {
305     EXPECT_EQ(0, cacheCreate(TEST_NETID));
306     CacheEntry ce = makeCacheEntry(QUERY, "existent.in.cache", ns_c_in, ns_t_a, "1.2.3.4");
307     time_t now = currentTime();
308 
309     // Add the cache entry.
310     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
311     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
312     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
313 
314     // Get the expiration time and verify its value is greater than now.
315     time_t expiration1;
316     EXPECT_EQ(0, cacheGetExpiration(TEST_NETID, ce.query, &expiration1));
317     EXPECT_GT(expiration1, now);
318 
319     // Adding the duplicate entry will return an error, and the expiration time won't be modified.
320     EXPECT_EQ(-EEXIST, cacheAdd(TEST_NETID, ce));
321     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
322     time_t expiration2;
323     EXPECT_EQ(0, cacheGetExpiration(TEST_NETID, ce.query, &expiration2));
324     EXPECT_EQ(expiration1, expiration2);
325 }
326 
TEST_F(ResolvCacheTest,CacheLookup)327 TEST_F(ResolvCacheTest, CacheLookup) {
328     EXPECT_EQ(0, cacheCreate(TEST_NETID));
329     EXPECT_EQ(0, cacheCreate(TEST_NETID_2));
330     CacheEntry ce = makeCacheEntry(QUERY, "existent.in.cache", ns_c_in, ns_t_a, "1.2.3.4");
331 
332     // Cache found in network 1.
333     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
334     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
335     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
336 
337     // No cache found in network 2.
338     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID_2, ce));
339 
340     ce = makeCacheEntry(QUERY, "existent.in.cache", ns_c_in, ns_t_aaaa, "2001:db8::1.2.3.4");
341 
342     // type A and AAAA are independent.
343     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
344     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
345     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
346 }
347 
TEST_F(ResolvCacheTest,CacheLookup_CacheFlags)348 TEST_F(ResolvCacheTest, CacheLookup_CacheFlags) {
349     EXPECT_EQ(0, cacheCreate(TEST_NETID));
350     std::vector<char> answerFromCache;
351     CacheEntry ce = makeCacheEntry(QUERY, "existent.in.cache", ns_c_in, ns_t_a, "1.2.3.4");
352 
353     // The entry can't be found when only no-cache-lookup bit is carried.
354     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce, ANDROID_RESOLV_NO_CACHE_LOOKUP));
355 
356     // Ensure RESOLV_CACHE_SKIP is returned when there's no such the same entry in the cache.
357     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_SKIP, TEST_NETID, ce, ANDROID_RESOLV_NO_CACHE_STORE));
358 
359     // Skip the cache lookup if no-cache-lookup and no-cache-store bits are carried
360     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_SKIP, TEST_NETID, ce,
361                             ANDROID_RESOLV_NO_CACHE_LOOKUP | ANDROID_RESOLV_NO_CACHE_STORE));
362 
363     // Add the cache entry.
364     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
365     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
366     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
367 
368     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce, ANDROID_RESOLV_NO_CACHE_LOOKUP));
369 
370     // Now no-cache-store has no effect if a same entry is existent in the cache.
371     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_SKIP, TEST_NETID, ce, ANDROID_RESOLV_NO_CACHE_STORE));
372 
373     // Skip the cache lookup again regardless of a same entry being already in the cache.
374     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_SKIP, TEST_NETID, ce,
375                             ANDROID_RESOLV_NO_CACHE_LOOKUP | ANDROID_RESOLV_NO_CACHE_STORE));
376 }
377 
TEST_F(ResolvCacheTest,CacheLookup_Types)378 TEST_F(ResolvCacheTest, CacheLookup_Types) {
379     EXPECT_EQ(0, cacheCreate(TEST_NETID));
380     static const struct QueryTypes {
381         int type;
382         std::string rdata;
383     } Types[] = {
384             {ns_t_a, "1.2.3.4"},
385             {ns_t_aaaa, "2001:db8::1.2.3.4"},
386             {ns_t_ptr, "4.3.2.1.in-addr.arpa."},
387             {ns_t_ptr, "4.0.3.0.2.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa."},
388     };
389 
390     for (const auto& t : Types) {
391         std::string name = fmt::format("cache.lookup.type.{}", t.rdata);
392         SCOPED_TRACE(name);
393 
394         CacheEntry ce = makeCacheEntry(QUERY, name.data(), ns_c_in, t.type, t.rdata.data());
395         EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
396         EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
397         EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
398     }
399 }
400 
TEST_F(ResolvCacheTest,CacheLookup_InvalidArgs)401 TEST_F(ResolvCacheTest, CacheLookup_InvalidArgs) {
402     EXPECT_EQ(0, cacheCreate(TEST_NETID));
403 
404     const std::vector<uint8_t> queryEmpty(MAXPACKET, 0);
405     const std::vector<uint8_t> queryTooSmall(DNS_HEADER_SIZE - 1, 0);
406     std::vector<uint8_t> answerTooSmall(DNS_HEADER_SIZE - 1, 0);
407     const CacheEntry ce = makeCacheEntry(QUERY, "valid.cache", ns_c_in, ns_t_a, "1.2.3.4");
408     auto cacheLookupFn = [](const std::vector<uint8_t>& query,
409                             std::vector<uint8_t> answer) -> ResolvCacheStatus {
410         int anslen = 0;
411         return resolv_cache_lookup(TEST_NETID, query, answer, &anslen, 0);
412     };
413 
414     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
415 
416     EXPECT_EQ(RESOLV_CACHE_UNSUPPORTED, cacheLookupFn(queryEmpty, ce.answer));
417     EXPECT_EQ(RESOLV_CACHE_UNSUPPORTED, cacheLookupFn(queryTooSmall, ce.answer));
418     EXPECT_EQ(RESOLV_CACHE_UNSUPPORTED, cacheLookupFn(ce.query, answerTooSmall));
419 
420     // It can actually be found with valid arguments.
421     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
422 
423     // Cache not existent in TEST_NETID_2.
424     EXPECT_EQ(-ENONET, cacheAdd(TEST_NETID_2, ce));
425     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_UNSUPPORTED, TEST_NETID_2, ce));
426 }
427 
TEST_F(ResolvCacheTest,CacheLookup_Expired)428 TEST_F(ResolvCacheTest, CacheLookup_Expired) {
429     EXPECT_EQ(0, cacheCreate(TEST_NETID));
430 
431     // An entry with zero ttl won't be stored in the cache.
432     CacheEntry ce = makeCacheEntry(QUERY, "expired.in.0s", ns_c_in, ns_t_a, "1.2.3.4", 0s);
433     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
434     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
435 
436     // Create an entry expired in 1s.
437     ce = makeCacheEntry(QUERY, "expired.in.1s", ns_c_in, ns_t_a, "1.2.3.4", 1s);
438     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
439 
440     // Cache found.
441     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
442     time_t expiration;
443     EXPECT_EQ(0, cacheGetExpiration(TEST_NETID, ce.query, &expiration));
444 
445     // Wait for the cache expired.
446     std::this_thread::sleep_for(1500ms);
447     EXPECT_GE(currentTime(), expiration);
448     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
449 }
450 
TEST_F(ResolvCacheTest,PendingRequest_QueryDeferred)451 TEST_F(ResolvCacheTest, PendingRequest_QueryDeferred) {
452     EXPECT_EQ(0, cacheCreate(TEST_NETID));
453     EXPECT_EQ(0, cacheCreate(TEST_NETID_2));
454 
455     CacheEntry ce = makeCacheEntry(QUERY, "query.deferred", ns_c_in, ns_t_a, "1.2.3.4");
456     std::atomic_bool done(false);
457 
458     // This is the first lookup. The following lookups from other threads will be in the
459     // pending request list.
460     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
461 
462     std::vector<std::thread> threads(5);
463     for (std::thread& thread : threads) {
464         thread = std::thread([&]() {
465             EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
466 
467             // Ensure this thread gets stuck in lookups before we wake it.
468             EXPECT_TRUE(done);
469         });
470     }
471 
472     // Wait for a while for the threads performing lookups.
473     // TODO: Perhaps implement a test-only function to get the number of pending requests
474     // instead of sleep.
475     std::this_thread::sleep_for(100ms);
476 
477     // The threads keep waiting regardless of any other networks or even if cache flag is set.
478     EXPECT_EQ(0, cacheAdd(TEST_NETID_2, ce));
479     cacheQueryFailed(TEST_NETID, ce, ANDROID_RESOLV_NO_CACHE_STORE);
480     cacheQueryFailed(TEST_NETID, ce, ANDROID_RESOLV_NO_CACHE_LOOKUP);
481     cacheQueryFailed(TEST_NETID_2, ce, ANDROID_RESOLV_NO_CACHE_STORE);
482     cacheQueryFailed(TEST_NETID_2, ce, ANDROID_RESOLV_NO_CACHE_LOOKUP);
483     cacheDelete(TEST_NETID_2);
484 
485     // Ensure none of the threads has finished the lookups.
486     std::this_thread::sleep_for(100ms);
487 
488     // Wake up the threads
489     done = true;
490     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
491 
492     for (std::thread& thread : threads) {
493         thread.join();
494     }
495 }
496 
TEST_F(ResolvCacheTest,PendingRequest_QueryFailed)497 TEST_F(ResolvCacheTest, PendingRequest_QueryFailed) {
498     EXPECT_EQ(0, cacheCreate(TEST_NETID));
499 
500     CacheEntry ce = makeCacheEntry(QUERY, "query.failed", ns_c_in, ns_t_a, "1.2.3.4");
501     std::atomic_bool done(false);
502 
503     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
504 
505     std::vector<std::thread> threads(5);
506     for (std::thread& thread : threads) {
507         thread = std::thread([&]() {
508             EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
509 
510             // Ensure this thread gets stuck in lookups before we wake it.
511             EXPECT_TRUE(done);
512         });
513     }
514 
515     // Wait for a while for the threads performing lookups.
516     std::this_thread::sleep_for(100ms);
517 
518     // Wake up the threads
519     done = true;
520     cacheQueryFailed(TEST_NETID, ce, 0);
521 
522     for (std::thread& thread : threads) {
523         thread.join();
524     }
525 }
526 
TEST_F(ResolvCacheTest,PendingRequest_CacheDestroyed)527 TEST_F(ResolvCacheTest, PendingRequest_CacheDestroyed) {
528     EXPECT_EQ(0, cacheCreate(TEST_NETID));
529     EXPECT_EQ(0, cacheCreate(TEST_NETID_2));
530 
531     CacheEntry ce = makeCacheEntry(QUERY, "query.failed", ns_c_in, ns_t_a, "1.2.3.4");
532     std::atomic_bool done(false);
533 
534     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
535 
536     std::vector<std::thread> threads(5);
537     for (std::thread& thread : threads) {
538         thread = std::thread([&]() {
539             EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce));
540 
541             // Ensure this thread gets stuck in lookups before we wake it.
542             EXPECT_TRUE(done);
543         });
544     }
545 
546     // Wait for a while for the threads performing lookups.
547     std::this_thread::sleep_for(100ms);
548 
549     // Deleting another network must not cause the threads to wake up.
550     cacheDelete(TEST_NETID_2);
551 
552     // Ensure none of the threads has finished the lookups.
553     std::this_thread::sleep_for(100ms);
554 
555     // Wake up the threads
556     done = true;
557     cacheDelete(TEST_NETID);
558 
559     for (std::thread& thread : threads) {
560         thread.join();
561     }
562 }
563 
TEST_F(ResolvCacheTest,MaxEntries)564 TEST_F(ResolvCacheTest, MaxEntries) {
565     EXPECT_EQ(0, cacheCreate(TEST_NETID));
566     std::vector<CacheEntry> ces;
567     const int max_cache_entries = resolv_get_max_cache_entries(TEST_NETID);
568 
569     for (int i = 0; i < 2 * max_cache_entries; i++) {
570         std::string qname = fmt::format("cache.{:06d}", i);
571         SCOPED_TRACE(qname);
572         CacheEntry ce = makeCacheEntry(QUERY, qname.data(), ns_c_in, ns_t_a, "1.2.3.4");
573         EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
574         EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
575         ces.emplace_back(ce);
576     }
577 
578     for (int i = 0; i < 2 * max_cache_entries; i++) {
579         std::string qname = fmt::format("cache.{:06d}", i);
580         SCOPED_TRACE(qname);
581         if (i < max_cache_entries) {
582             // Because the cache is LRU, the oldest queries should have been purged,
583             // and the most recent max_cache_entries ones should still be present.
584             EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ces[i]));
585         } else {
586             EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ces[i]));
587         }
588     }
589 }
590 
TEST_F(ResolvCacheTest,CacheFull)591 TEST_F(ResolvCacheTest, CacheFull) {
592     EXPECT_EQ(0, cacheCreate(TEST_NETID));
593 
594     CacheEntry ce1 = makeCacheEntry(QUERY, "cache.000000", ns_c_in, ns_t_a, "1.2.3.4", 100s);
595     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce1));
596     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce1));
597 
598     CacheEntry ce2 = makeCacheEntry(QUERY, "cache.000001", ns_c_in, ns_t_a, "1.2.3.4", 1s);
599     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce2));
600     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce2));
601 
602     // Stuff the resolver cache.
603     const int max_cache_entries = resolv_get_max_cache_entries(TEST_NETID);
604     for (int i = 2; i < max_cache_entries; i++) {
605         std::string qname = fmt::format("cache.{:06d}", i);
606         SCOPED_TRACE(qname);
607         CacheEntry ce = makeCacheEntry(QUERY, qname.data(), ns_c_in, ns_t_a, "1.2.3.4", 50s);
608         EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
609         EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce));
610     }
611 
612     // Wait for ce2 expired.
613     std::this_thread::sleep_for(1500ms);
614 
615     // The cache is full now, and the expired ce2 will be removed first.
616     CacheEntry ce3 = makeCacheEntry(QUERY, "cache.overfilled.1", ns_c_in, ns_t_a, "1.2.3.4", 50s);
617     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce3));
618     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce3));
619     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce2));
620 
621     // The cache is full again but there's no one expired, so the oldest ce1 will be removed.
622     CacheEntry ce4 = makeCacheEntry(QUERY, "cache.overfilled.2", ns_c_in, ns_t_a, "1.2.3.4", 50s);
623     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce4));
624     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_FOUND, TEST_NETID, ce4));
625     EXPECT_TRUE(cacheLookup(RESOLV_CACHE_NOTFOUND, TEST_NETID, ce1));
626 }
627 
628 class ResolvCacheParameterizedTest : public ResolvCacheTest,
629                                      public testing::WithParamInterface<int> {};
630 
631 INSTANTIATE_TEST_SUITE_P(MaxCacheEntries, ResolvCacheParameterizedTest,
632                          testing::Values(MAX_ENTRIES_LOWER_BOUND - 1, MAX_ENTRIES_UPPER_BOUND + 1),
__anonccdfe95a0602(const testing::TestParamInfo<int>& info) 633                          [](const testing::TestParamInfo<int>& info) {
634                              return std::to_string(info.param);
635                          });
636 
TEST_P(ResolvCacheParameterizedTest,IrrationalCacheSize)637 TEST_P(ResolvCacheParameterizedTest, IrrationalCacheSize) {
638     // Assign an out-of-bounds value.
639     ScopedSystemProperties sp1(kMaxCacheEntriesFlag, std::to_string(GetParam()));
640     android::net::Experiments::getInstance()->update();
641     EXPECT_EQ(0, cacheCreate(TEST_NETID));
642     EXPECT_EQ(MAX_ENTRIES_DEFAULT, resolv_get_max_cache_entries(TEST_NETID));
643 }
644 
TEST_F(ResolvCacheTest,ResolverSetup)645 TEST_F(ResolvCacheTest, ResolverSetup) {
646     const SetupParams setup = {
647             .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
648             .domains = {"domain1.com", "domain2.com"},
649             .params = kParams,
650     };
651 
652     // Failed to setup resolver because of the cache not created.
653     EXPECT_EQ(-ENONET, cacheSetupResolver(TEST_NETID, setup));
654     EXPECT_FALSE(resolv_has_nameservers(TEST_NETID));
655 
656     // The cache is created now.
657     EXPECT_EQ(0, cacheCreate(TEST_NETID));
658     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
659     EXPECT_TRUE(resolv_has_nameservers(TEST_NETID));
660 }
661 
TEST_F(ResolvCacheTest,ResolverSetup_InvalidNameServers)662 TEST_F(ResolvCacheTest, ResolverSetup_InvalidNameServers) {
663     EXPECT_EQ(0, cacheCreate(TEST_NETID));
664     const std::string invalidServers[]{
665             "127.A.b.1",
666             "127.^.0",
667             "::^:1",
668             "",
669     };
670     SetupParams setup = {
671             .servers = {},
672             .domains = {"domain1.com"},
673             .params = kParams,
674     };
675 
676     // Failed to setup resolver because of invalid name servers.
677     for (const auto& server : invalidServers) {
678         SCOPED_TRACE(server);
679         setup.servers = {"127.0.0.1", server, "127.0.0.2"};
680         EXPECT_EQ(-EINVAL, cacheSetupResolver(TEST_NETID, setup));
681         EXPECT_FALSE(resolv_has_nameservers(TEST_NETID));
682     }
683 }
684 
TEST_F(ResolvCacheTest,ResolverSetup_DropDomain)685 TEST_F(ResolvCacheTest, ResolverSetup_DropDomain) {
686     EXPECT_EQ(0, cacheCreate(TEST_NETID));
687 
688     // Setup with one domain which is too long.
689     const std::vector<std::string> servers = {"127.0.0.1", "fe80::1"};
690     const std::string domainTooLong(MAXDNSRCHPATH, '1');
691     const std::string validDomain1(MAXDNSRCHPATH - 1, '2');
692     const std::string validDomain2(MAXDNSRCHPATH - 1, '3');
693     SetupParams setup = {
694             .servers = servers,
695             .domains = {},
696             .params = kParams,
697     };
698     CacheStats expect = {
699             .setup = setup,
700             .stats = {},
701             .pendingReqTimeoutCount = 0,
702     };
703 
704     // Overlength domains are dropped.
705     setup.domains = {validDomain1, domainTooLong, validDomain2};
706     expect.setup.domains = {validDomain1, validDomain2};
707     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
708     EXPECT_TRUE(resolv_has_nameservers(TEST_NETID));
709     expectCacheStats("ResolverSetup_Domains drop overlength", TEST_NETID, expect);
710 
711     // Duplicate domains are dropped.
712     setup.domains = {validDomain1, validDomain2, validDomain1, validDomain2};
713     expect.setup.domains = {validDomain1, validDomain2};
714     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
715     EXPECT_TRUE(resolv_has_nameservers(TEST_NETID));
716     expectCacheStats("ResolverSetup_Domains drop duplicates", TEST_NETID, expect);
717 }
718 
TEST_F(ResolvCacheTest,ResolverSetup_Prune)719 TEST_F(ResolvCacheTest, ResolverSetup_Prune) {
720     EXPECT_EQ(0, cacheCreate(TEST_NETID));
721     const std::vector<std::string> servers = {"127.0.0.1", "::127.0.0.2", "fe80::1", "fe80::2",
722                                               "fe80::3"};
723     const std::vector<std::string> domains = {"d1.com", "d2.com", "d3.com", "d4.com",
724                                               "d5.com", "d6.com", "d7.com"};
725     const SetupParams setup = {
726             .servers = servers,
727             .domains = domains,
728             .params = kParams,
729     };
730 
731     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
732     EXPECT_TRUE(resolv_has_nameservers(TEST_NETID));
733 
734     const CacheStats cacheStats = {
735             .setup = {.servers = std::vector(servers.begin(), servers.begin() + MAXNS),
736                       .domains = std::vector(domains.begin(), domains.begin() + MAXDNSRCH),
737                       .params = setup.params},
738             .stats = {},
739             .pendingReqTimeoutCount = 0,
740     };
741     expectCacheStats("ResolverSetup_Prune", TEST_NETID, cacheStats);
742 }
743 
TEST_F(ResolvCacheTest,GetStats)744 TEST_F(ResolvCacheTest, GetStats) {
745     EXPECT_EQ(0, cacheCreate(TEST_NETID));
746     const SetupParams setup = {
747             .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
748             .domains = {"domain1.com", "domain2.com"},
749             .params = kParams,
750     };
751 
752     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
753     EXPECT_TRUE(resolv_has_nameservers(TEST_NETID));
754 
755     const CacheStats cacheStats = {
756             .setup = setup,
757             .stats = {},
758             .pendingReqTimeoutCount = 0,
759     };
760     expectCacheStats("GetStats", TEST_NETID, cacheStats);
761 }
762 
TEST_F(ResolvCacheTest,FlushCache)763 TEST_F(ResolvCacheTest, FlushCache) {
764     EXPECT_EQ(0, cacheCreate(TEST_NETID));
765     const SetupParams setup = {
766             .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
767             .domains = {"domain1.com", "domain2.com"},
768             .params = kParams,
769     };
770     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
771     EXPECT_TRUE(resolv_has_nameservers(TEST_NETID));
772 
773     res_sample sample = {.at = time(NULL), .rtt = 100, .rcode = ns_r_noerror};
774     sockaddr_in sin = {.sin_family = AF_INET, .sin_port = htons(DNS_PORT)};
775     ASSERT_TRUE(inet_pton(AF_INET, setup.servers[0].c_str(), &sin.sin_addr));
776     cacheAddStats(TEST_NETID, 1 /*revision_id*/, IPSockAddr(sin), sample, setup.params.max_samples);
777 
778     const CacheStats cacheStats = {
779             .setup = setup,
780             .stats = {{{sample}, 1 /*sample_count*/, 1 /*sample_next*/}},
781             .pendingReqTimeoutCount = 0,
782     };
783     expectCacheStats("FlushCache: a record in cache stats", TEST_NETID, cacheStats);
784 
785     EXPECT_EQ(0, cacheFlush(TEST_NETID));
786     const CacheStats cacheStats_empty = {
787             .setup = setup,
788             .stats = {},
789             .pendingReqTimeoutCount = 0,
790     };
791     expectCacheStats("FlushCache: no record in cache stats", TEST_NETID, cacheStats_empty);
792 }
793 
TEST_F(ResolvCacheTest,GetHostByAddrFromCache_InvalidArgs)794 TEST_F(ResolvCacheTest, GetHostByAddrFromCache_InvalidArgs) {
795     char domain_name[NS_MAXDNAME] = {};
796     const char query_v4[] = "1.2.3.5";
797 
798     // invalid buffer size
799     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME + 1, nullptr,
800                                                  AF_INET));
801     EXPECT_STREQ("", domain_name);
802 
803     // invalid query
804     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, nullptr,
805                                                  AF_INET));
806     EXPECT_STREQ("", domain_name);
807 
808     // unsupported AF
809     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v4,
810                                                  AF_UNSPEC));
811     EXPECT_STREQ("", domain_name);
812 }
813 
TEST_F(ResolvCacheTest,GetHostByAddrFromCache)814 TEST_F(ResolvCacheTest, GetHostByAddrFromCache) {
815     char domain_name[NS_MAXDNAME] = {};
816     const char query_v4[] = "1.2.3.5";
817     const char query_v6[] = "2001:db8::102:304";
818     const char query_v6_unabbreviated[] = "2001:0db8:0000:0000:0000:0000:0102:0304";
819     const char query_v6_mixed[] = "2001:db8::1.2.3.4";
820     const char answer[] = "existent.in.cache";
821 
822     // cache does not exist
823     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v4,
824                                                  AF_INET));
825     EXPECT_STREQ("", domain_name);
826 
827     // cache is empty
828     EXPECT_EQ(0, cacheCreate(TEST_NETID));
829     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v4,
830                                                  AF_INET));
831     EXPECT_STREQ("", domain_name);
832 
833     // no v4 match in cache
834     CacheEntry ce = makeCacheEntry(QUERY, "any.data", ns_c_in, ns_t_a, "1.2.3.4");
835     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
836     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v4,
837                                                  AF_INET));
838     EXPECT_STREQ("", domain_name);
839 
840     // v4 match
841     ce = makeCacheEntry(QUERY, answer, ns_c_in, ns_t_a, query_v4);
842     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
843     EXPECT_TRUE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v4,
844                                                 AF_INET));
845     EXPECT_STREQ(answer, domain_name);
846 
847     // no v6 match in cache
848     memset(domain_name, 0, NS_MAXDNAME);
849     EXPECT_FALSE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v6,
850                                                  AF_INET6));
851     EXPECT_STREQ("", domain_name);
852 
853     // v6 match
854     ce = makeCacheEntry(QUERY, answer, ns_c_in, ns_t_aaaa, query_v6);
855     EXPECT_EQ(0, cacheAdd(TEST_NETID, ce));
856     EXPECT_TRUE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME, query_v6,
857                                                 AF_INET6));
858     EXPECT_STREQ(answer, domain_name);
859 
860     // v6 match with unabbreviated address format
861     memset(domain_name, 0, NS_MAXDNAME);
862     EXPECT_TRUE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME,
863                                                 query_v6_unabbreviated, AF_INET6));
864     EXPECT_STREQ(answer, domain_name);
865 
866     // v6 with mixed address format
867     memset(domain_name, 0, NS_MAXDNAME);
868     EXPECT_TRUE(resolv_gethostbyaddr_from_cache(TEST_NETID, domain_name, NS_MAXDNAME,
869                                                 query_v6_mixed, AF_INET6));
870     EXPECT_STREQ(answer, domain_name);
871 }
872 
TEST_F(ResolvCacheTest,GetResolverStats)873 TEST_F(ResolvCacheTest, GetResolverStats) {
874     const res_sample sample1 = {.at = time(nullptr), .rtt = 100, .rcode = ns_r_noerror};
875     const res_sample sample2 = {.at = time(nullptr), .rtt = 200, .rcode = ns_r_noerror};
876     const res_sample sample3 = {.at = time(nullptr), .rtt = 300, .rcode = ns_r_noerror};
877     const res_stats expectedStats[MAXNS] = {
878             {{sample1}, 1 /*sample_count*/, 1 /*sample_next*/},
879             {{sample2}, 1, 1},
880             {{sample3}, 1, 1},
881     };
882     std::vector<IPSockAddr> nameserverSockAddrs = {
883             IPSockAddr::toIPSockAddr("127.0.0.1", DNS_PORT),
884             IPSockAddr::toIPSockAddr("::127.0.0.2", DNS_PORT),
885             IPSockAddr::toIPSockAddr("fe80::3", DNS_PORT),
886     };
887     const SetupParams setup = {
888             .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
889             .domains = {"domain1.com", "domain2.com"},
890             .params = kParams,
891     };
892     EXPECT_EQ(0, cacheCreate(TEST_NETID));
893     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
894     int revision_id = 1;
895     cacheAddStats(TEST_NETID, revision_id, nameserverSockAddrs[0], sample1,
896                   setup.params.max_samples);
897     cacheAddStats(TEST_NETID, revision_id, nameserverSockAddrs[1], sample2,
898                   setup.params.max_samples);
899     cacheAddStats(TEST_NETID, revision_id, nameserverSockAddrs[2], sample3,
900                   setup.params.max_samples);
901 
902     res_stats cacheStats[MAXNS]{};
903     res_params params;
904     EXPECT_EQ(resolv_cache_get_resolver_stats(TEST_NETID, &params, cacheStats, nameserverSockAddrs),
905               revision_id);
906     EXPECT_TRUE(params == kParams);
907     for (size_t i = 0; i < MAXNS; i++) {
908         EXPECT_TRUE(cacheStats[i] == expectedStats[i]);
909     }
910 
911     // pass another list of IPSockAddr
912     const res_stats expectedStats2[MAXNS] = {
913             {{sample3, sample2}, 2, 2},
914             {{sample2}, 1, 1},
915             {{sample1}, 1, 1},
916     };
917     nameserverSockAddrs = {
918             IPSockAddr::toIPSockAddr("fe80::3", DNS_PORT),
919             IPSockAddr::toIPSockAddr("::127.0.0.2", DNS_PORT),
920             IPSockAddr::toIPSockAddr("127.0.0.1", DNS_PORT),
921     };
922     cacheAddStats(TEST_NETID, revision_id, nameserverSockAddrs[0], sample2,
923                   setup.params.max_samples);
924     EXPECT_EQ(resolv_cache_get_resolver_stats(TEST_NETID, &params, cacheStats, nameserverSockAddrs),
925               revision_id);
926     EXPECT_TRUE(params == kParams);
927     for (size_t i = 0; i < MAXNS; i++) {
928         EXPECT_TRUE(cacheStats[i] == expectedStats2[i]);
929     }
930 }
931 
TEST_F(ResolvCacheTest,IsEnforceDnsUidEnabled)932 TEST_F(ResolvCacheTest, IsEnforceDnsUidEnabled) {
933     const SetupParams unenforcedDnsUidCfg = {
934             .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
935             .domains = {"domain1.com", "domain2.com"},
936             .params = kParams,
937     };
938     // Network #1
939     EXPECT_EQ(0, cacheCreate(TEST_NETID));
940     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, unenforcedDnsUidCfg));
941     EXPECT_FALSE(resolv_is_enforceDnsUid_enabled_network(TEST_NETID));
942 
943     // Network #2
944     EXPECT_EQ(0, cacheCreate(TEST_NETID + 1));
945     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID + 1, unenforcedDnsUidCfg));
946     EXPECT_FALSE(resolv_is_enforceDnsUid_enabled_network(TEST_NETID + 1));
947 
948     // Change the enforceDnsUid setting on network #1
949     const SetupParams enforcedDnsUidCfg = {
950             .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
951             .domains = {"domain1.com", "domain2.com"},
952             .params = kParams,
953             .resolverOptions = {.enforceDnsUid = true},
954     };
955     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, enforcedDnsUidCfg));
956     EXPECT_TRUE(resolv_is_enforceDnsUid_enabled_network(TEST_NETID));
957 
958     // Network #2 is unaffected
959     EXPECT_FALSE(resolv_is_enforceDnsUid_enabled_network(TEST_NETID + 1));
960 
961     // Returns false on non-existent network
962     EXPECT_FALSE(resolv_is_enforceDnsUid_enabled_network(TEST_NETID + 2));
963 }
964 
TEST_F(ResolvCacheTest,IsNetworkMetered)965 TEST_F(ResolvCacheTest, IsNetworkMetered) {
966     const SetupParams defaultCfg = {
967             .servers = {"127.0.0.1"},
968             .domains = {"domain1.com"},
969             .params = kParams,
970     };
971     // Network #1
972     EXPECT_EQ(0, cacheCreate(TEST_NETID));
973     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, defaultCfg));
974     EXPECT_FALSE(resolv_is_metered_network(TEST_NETID));
975 
976     // Network #2
977     EXPECT_EQ(0, cacheCreate(TEST_NETID + 1));
978     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID + 1, defaultCfg));
979     EXPECT_FALSE(resolv_is_metered_network(TEST_NETID + 1));
980 
981     // Change the metered setting on network #1
982     const SetupParams meteredCfg = {
983             .servers = {"127.0.0.1"},
984             .domains = {"domain1.com"},
985             .params = kParams,
986             .metered = true,
987     };
988     EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, meteredCfg));
989     EXPECT_TRUE(resolv_is_metered_network(TEST_NETID));
990 
991     // Network #2 is unaffected
992     EXPECT_FALSE(resolv_is_metered_network(TEST_NETID + 1));
993 
994     // Returns false on non-existent network
995     EXPECT_FALSE(resolv_is_metered_network(TEST_NETID + 2));
996 }
997 
998 namespace {
999 
1000 constexpr int EAI_OK = 0;
1001 constexpr char DNS_EVENT_SUBSAMPLING_MAP_FLAG[] =
1002         "persist.device_config.netd_native.dns_event_subsample_map";
1003 constexpr char MDNS_EVENT_SUBSAMPLING_MAP_FLAG[] =
1004         "persist.device_config.netd_native.mdns_event_subsample_map";
1005 
1006 class ScopedCacheCreate {
1007   public:
ScopedCacheCreate(unsigned netid,const char * subsampling_map,const char * property)1008     explicit ScopedCacheCreate(unsigned netid, const char* subsampling_map, const char* property)
1009         : mStoredNetId(netid), mStoredProperty(property) {
1010         property_get(property, mStoredMap, "");
1011         property_set(property, subsampling_map);
1012         EXPECT_EQ(0, resolv_create_cache_for_net(netid));
1013     }
~ScopedCacheCreate()1014     ~ScopedCacheCreate() {
1015         resolv_delete_cache_for_net(mStoredNetId);
1016         property_set(mStoredProperty, mStoredMap);
1017     }
1018 
1019   private:
1020     unsigned mStoredNetId;
1021     const char* mStoredProperty;
1022     char mStoredMap[PROPERTY_VALUE_MAX]{};
1023 };
1024 
1025 }  // namespace
1026 
TEST_F(ResolvCacheTest,DnsEventSubsampling)1027 TEST_F(ResolvCacheTest, DnsEventSubsampling) {
1028     // Test defaults, default flag is "default:8 0:400 2:110 7:110" if no experiment flag is set
1029     {
1030         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "", DNS_EVENT_SUBSAMPLING_MAP_FLAG);
1031         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_AGAIN, false), 110U);
1032         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, false), 110U);
1033         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, false), 400U);
1034         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS, false),
1035                   8U);  // default
1036         EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID, false),
1037                     testing::UnorderedElementsAreArray({"default:8", "0:400", "2:110", "7:110"}));
1038     }
1039     // Now change the experiment flag to "0:42 default:666"
1040     {
1041         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "0:42 default:666",
1042                                             DNS_EVENT_SUBSAMPLING_MAP_FLAG);
1043         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, false), 42U);
1044         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, false),
1045                   666U);  // default
1046         EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID, false),
1047                     testing::UnorderedElementsAreArray({"default:666", "0:42"}));
1048     }
1049     // Now change the experiment flag to something illegal
1050     {
1051         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "asvaxx", DNS_EVENT_SUBSAMPLING_MAP_FLAG);
1052         // 0(disable log) is the default value if experiment flag is invalid.
1053         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, false), 0U);
1054         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, false), 0U);
1055         EXPECT_TRUE(resolv_cache_dump_subsampling_map(TEST_NETID, false).empty());
1056     }
1057     // Test negative and zero denom
1058     {
1059         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "0:-42 default:-666 7:10 10:0",
1060                                             DNS_EVENT_SUBSAMPLING_MAP_FLAG);
1061         // 0(disable log) is the default value if no valid denom is set
1062         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, false), 0U);
1063         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS, false), 0U);
1064         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, false), 10U);
1065         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_SOCKTYPE, false), 0U);
1066         EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID, false),
1067                     testing::UnorderedElementsAreArray({"7:10", "10:0"}));
1068     }
1069 }
1070 
TEST_F(ResolvCacheTest,MdnsEventSubsampling)1071 TEST_F(ResolvCacheTest, MdnsEventSubsampling) {
1072     // Test defaults, DEFAULT_MDNS_SUBSAMPLING_MAP is "default:1" if no experiment flag is set
1073     {
1074         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "", MDNS_EVENT_SUBSAMPLING_MAP_FLAG);
1075         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_AGAIN, true),
1076                   1U);  // default for all return_code
1077         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, true), 1U);
1078         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS, true), 1U);
1079         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, true), 1U);
1080         // not equal to DEFAULT_SUBSAMPLING_MAP[] = "default:8 0:400 2:110 7:110";
1081         EXPECT_NE(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_AGAIN, true), 110U);
1082         EXPECT_NE(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, true), 110U);
1083         EXPECT_NE(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, true), 400U);
1084         EXPECT_NE(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS, true), 8U);
1085         EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID, true),
1086                     testing::UnorderedElementsAreArray({"default:1"}));
1087     }
1088     // Now change the experiment flag to "default:1 0:10"
1089     {
1090         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "0:10 default:1",
1091                                             MDNS_EVENT_SUBSAMPLING_MAP_FLAG);
1092         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, true), 10U);
1093         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, true), 1U);  // default
1094         EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID, true),
1095                     testing::UnorderedElementsAreArray({"0:10", "default:1"}));
1096     }
1097     // Now change the experiment flag to something illegal
1098     {
1099         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "asvaxx", MDNS_EVENT_SUBSAMPLING_MAP_FLAG);
1100         // 0(disable log) is the default value if experiment flag is invalid.
1101         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, true), 0U);
1102         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, true), 0U);
1103         EXPECT_TRUE(resolv_cache_dump_subsampling_map(TEST_NETID, true).empty());
1104     }
1105     // Test negative and zero denom
1106     {
1107         ScopedCacheCreate scopedCacheCreate(TEST_NETID, "0:-42 default:-666 7:10 10:0",
1108                                             MDNS_EVENT_SUBSAMPLING_MAP_FLAG);
1109         // 0(disable log) is the default value if no valid denom is set
1110         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_OK, true), 0U);
1111         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_BADFLAGS, true), 0U);
1112         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_NODATA, true), 10U);
1113         EXPECT_EQ(resolv_cache_get_subsampling_denom(TEST_NETID, EAI_SOCKTYPE, true), 0U);
1114         EXPECT_THAT(resolv_cache_dump_subsampling_map(TEST_NETID, true),
1115                     testing::UnorderedElementsAreArray({"7:10", "10:0"}));
1116     }
1117 }
1118 // TODO: Tests for NetConfig, including:
1119 //     - res_stats
1120 //         -- _resolv_cache_add_resolver_stats_sample()
1121 //         -- android_net_res_stats_get_info_for_net()
1122 // TODO: inject a mock timer into the cache to make TTL tests pass instantly
1123 // TODO: test TTL of RFC 2308 negative caching
1124