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, ¶ms,
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, ¶ms, 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, ¶ms, 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