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 <array>
18
19 #include <android-base/test_utils.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <netdutils/NetNativeTestBase.h>
23
24 #include "DnsStats.h"
25
26 namespace android::net {
27
28 using namespace std::chrono_literals;
29 using android::netdutils::IPSockAddr;
30 using std::chrono::microseconds;
31 using std::chrono::milliseconds;
32 using ::testing::IsEmpty;
33 using ::testing::UnorderedElementsAreArray;
34
35 namespace {
36
37 constexpr auto NO_AVERAGE_LATENCY = std::nullopt;
38
39 // A helper which can propagate the failure to outside of the stmt to know which line
40 // of stmt fails. The expectation fails only for the first failed stmt.
41 #define EXPECT_NO_FAILURE(stmt) \
42 do { \
43 bool alreadyFailed = HasFailure(); \
44 stmt; \
45 if (!alreadyFailed && HasFailure()) EXPECT_FALSE(HasFailure()); \
46 } while (0)
47
makeDnsQueryEvent(const Protocol protocol,const NsRcode rcode,const milliseconds & latency)48 DnsQueryEvent makeDnsQueryEvent(const Protocol protocol, const NsRcode rcode,
49 const milliseconds& latency) {
50 DnsQueryEvent event;
51 event.set_protocol(protocol);
52 event.set_rcode(rcode);
53 event.set_latency_micros(latency.count() * 1000);
54 return event;
55 }
56
makeStatsData(const IPSockAddr & server,const int total,const microseconds & latencyUs,const std::map<int,int> & rcodeCounts)57 StatsData makeStatsData(const IPSockAddr& server, const int total, const microseconds& latencyUs,
58 const std::map<int, int>& rcodeCounts) {
59 StatsData ret(server);
60 ret.total = total;
61 ret.latencyUs = latencyUs;
62 ret.rcodeCounts = rcodeCounts;
63 return ret;
64 }
65
66 } // namespace
67
68 // TODO: add StatsDataTest to ensure its methods return correct outputs.
69
70 class StatsRecordsTest : public NetNativeTestBase {};
71
TEST_F(StatsRecordsTest,PushRecord)72 TEST_F(StatsRecordsTest, PushRecord) {
73 const IPSockAddr server = IPSockAddr::toIPSockAddr("127.0.0.2", 53);
74 constexpr size_t size = 3;
75 const StatsRecords::Record recordNoError = {
76 .rcode = NS_R_NO_ERROR,
77 .linux_errno = 0,
78 .latencyUs{10ms},
79 };
80 const StatsRecords::Record recordTimeout = {
81 .rcode = NS_R_TIMEOUT,
82 .linux_errno = 0,
83 .latencyUs{250ms},
84 };
85
86 StatsRecords sr(server, size);
87 EXPECT_EQ(sr.getStatsData(), makeStatsData(server, 0, 0ms, {}));
88
89 sr.push(recordNoError);
90 EXPECT_EQ(sr.getStatsData(), makeStatsData(server, 1, 10ms, {{NS_R_NO_ERROR, 1}}));
91
92 sr.push(recordNoError);
93 EXPECT_EQ(sr.getStatsData(), makeStatsData(server, 2, 20ms, {{NS_R_NO_ERROR, 2}}));
94
95 sr.push(recordTimeout);
96 EXPECT_EQ(sr.getStatsData(),
97 makeStatsData(server, 3, 270ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 1}}));
98
99 sr.push(recordTimeout);
100 EXPECT_EQ(sr.getStatsData(),
101 makeStatsData(server, 3, 510ms, {{NS_R_NO_ERROR, 1}, {NS_R_TIMEOUT, 2}}));
102
103 sr.push(recordTimeout);
104 EXPECT_EQ(sr.getStatsData(),
105 makeStatsData(server, 3, 750ms, {{NS_R_NO_ERROR, 0}, {NS_R_TIMEOUT, 3}}));
106 }
107
108 class DnsStatsTest : public NetNativeTestBase {
109 protected:
captureDumpOutput()110 std::string captureDumpOutput() {
111 netdutils::DumpWriter dw(STDOUT_FILENO);
112 CapturedStdout captured;
113 mDnsStats.dump(dw);
114 return captured.str();
115 }
116
117 // Get the output string from dump() and check the content.
verifyDumpOutput(const std::vector<StatsData> & tcpData,const std::vector<StatsData> & udpData,const std::vector<StatsData> & dotData,const std::vector<StatsData> & mdnsData,const std::vector<StatsData> & dohData)118 void verifyDumpOutput(const std::vector<StatsData>& tcpData,
119 const std::vector<StatsData>& udpData,
120 const std::vector<StatsData>& dotData,
121 const std::vector<StatsData>& mdnsData,
122 const std::vector<StatsData>& dohData) {
123 // A pattern to capture three matches:
124 // server address (empty allowed), the statistics, and the score.
125 const std::regex pattern(R"(\s{4,}([0-9a-fA-F:\.\]\[]*)[ ]?([<(].*[>)])[ ]?(\S*))");
126 std::string dumpString = captureDumpOutput();
127
128 const auto check = [&](const std::vector<StatsData>& statsData, const std::string& protocol,
129 std::string* dumpString) {
130 SCOPED_TRACE(protocol);
131 ASSERT_NE(dumpString->find(protocol), std::string::npos);
132 std::smatch sm;
133
134 // Expect to show something even if none of servers or mdns multicast addresses is set.
135 if (statsData.empty()) {
136 ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern));
137 EXPECT_TRUE(sm[1].str().empty());
138 EXPECT_EQ(sm[2], "<no data>");
139 EXPECT_TRUE(sm[3].str().empty());
140 *dumpString = sm.suffix();
141 return;
142 }
143
144 for (const auto& stats : statsData) {
145 ASSERT_TRUE(std::regex_search(*dumpString, sm, pattern));
146 EXPECT_EQ(sm[1], stats.sockAddr.toString());
147 EXPECT_FALSE(sm[2].str().empty());
148 EXPECT_FALSE(sm[3].str().empty());
149 *dumpString = sm.suffix();
150 }
151 };
152
153 check(udpData, "UDP", &dumpString);
154 check(dohData, "DOH", &dumpString);
155 check(dotData, "TLS", &dumpString);
156 check(tcpData, "TCP", &dumpString);
157 check(mdnsData, "MDNS", &dumpString);
158
159 // Ensure the whole string has been checked.
160 EXPECT_EQ(dumpString, "\n");
161 }
162
verifyDnsStatsContent(Protocol protocol,const std::vector<StatsData> & expectedStats,const std::optional<microseconds> & expectedAvgLatency)163 void verifyDnsStatsContent(Protocol protocol, const std::vector<StatsData>& expectedStats,
164 const std::optional<microseconds>& expectedAvgLatency) {
165 if (expectedStats.empty()) {
166 EXPECT_THAT(mDnsStats.getStats(protocol), IsEmpty());
167 } else {
168 EXPECT_THAT(mDnsStats.getStats(protocol), UnorderedElementsAreArray(expectedStats));
169 }
170
171 EXPECT_EQ(mDnsStats.getAverageLatencyUs(protocol), expectedAvgLatency);
172 }
173
174 DnsStats mDnsStats;
175 };
176
TEST_F(DnsStatsTest,SetAddrs)177 TEST_F(DnsStatsTest, SetAddrs) {
178 // Check before any operation to mDnsStats.
179 verifyDumpOutput({}, {}, {}, {}, {});
180
181 static const struct {
182 std::vector<std::string> servers;
183 std::vector<std::string> expectation;
184 bool isSuccess;
185 } tests[] = {
186 // Normal case.
187 {
188 {"127.0.0.1", "127.0.0.2", "fe80::1%22", "2001:db8::2", "::1"},
189 {"127.0.0.1", "127.0.0.2", "fe80::1%22", "2001:db8::2", "::1"},
190 true,
191 },
192 // Duplicate servers.
193 {
194 {"127.0.0.1", "2001:db8::2", "127.0.0.1", "2001:db8::2"},
195 {"127.0.0.1", "2001:db8::2"},
196 true,
197 },
198 // Invalid server addresses. The state remains in previous state.
199 {
200 {"not_an_ip", "127.0.0.3", "127.a.b.2"},
201 {"127.0.0.1", "2001:db8::2"},
202 false,
203 },
204 // Clean up the old servers 127.0.0.1 and 127.0.0.2.
205 {
206 {"127.0.0.4", "2001:db8::5"},
207 {"127.0.0.4", "2001:db8::5"},
208 true,
209 },
210 // Empty list.
211 {{}, {}, true},
212 };
213
214 for (const auto& [servers, expectation, isSuccess] : tests) {
215 std::vector<IPSockAddr> ipSockAddrs;
216 ipSockAddrs.reserve(servers.size());
217 for (const auto& server : servers) {
218 ipSockAddrs.push_back(IPSockAddr::toIPSockAddr(server, 53));
219 }
220
221 EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_TCP) == isSuccess);
222 EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_UDP) == isSuccess);
223 EXPECT_TRUE(mDnsStats.setAddrs(ipSockAddrs, PROTO_DOT) == isSuccess);
224
225 std::vector<StatsData> expectedStats;
226 expectedStats.reserve(expectation.size());
227 for (const auto& exp : expectation) {
228 expectedStats.push_back(makeStatsData(IPSockAddr::toIPSockAddr(exp, 53), 0, 0ms, {}));
229 }
230
231 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY));
232 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY));
233 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY));
234 }
235
236 verifyDumpOutput({}, {}, {}, {}, {});
237 }
238
TEST_F(DnsStatsTest,SetServersDifferentPorts)239 TEST_F(DnsStatsTest, SetServersDifferentPorts) {
240 const std::vector<IPSockAddr> servers = {
241 IPSockAddr::toIPSockAddr("127.0.0.1", 0), IPSockAddr::toIPSockAddr("fe80::1", 0),
242 IPSockAddr::toIPSockAddr("127.0.0.1", 53), IPSockAddr::toIPSockAddr("127.0.0.1", 853),
243 IPSockAddr::toIPSockAddr("127.0.0.1", 5353), IPSockAddr::toIPSockAddr("fe80::1", 53),
244 IPSockAddr::toIPSockAddr("fe80::1", 853), IPSockAddr::toIPSockAddr("fe80::1", 5353),
245 };
246
247 // Servers setup fails due to port unset.
248 EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_TCP));
249 EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_UDP));
250 EXPECT_FALSE(mDnsStats.setAddrs(servers, PROTO_DOT));
251
252 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY));
253 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY));
254 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY));
255 verifyDumpOutput({}, {}, {}, {}, {});
256
257 EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP));
258 EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_UDP));
259 EXPECT_TRUE(mDnsStats.setAddrs(std::vector(servers.begin() + 2, servers.end()), PROTO_DOT));
260
261 const std::vector<StatsData> expectedStats = {
262 makeStatsData(servers[2], 0, 0ms, {}), makeStatsData(servers[3], 0, 0ms, {}),
263 makeStatsData(servers[4], 0, 0ms, {}), makeStatsData(servers[5], 0, 0ms, {}),
264 makeStatsData(servers[6], 0, 0ms, {}), makeStatsData(servers[7], 0, 0ms, {}),
265 };
266
267 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY));
268 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY));
269 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY));
270 verifyDumpOutput(expectedStats, expectedStats, expectedStats, {}, {});
271 }
272
TEST_F(DnsStatsTest,AddStatsAndClear)273 TEST_F(DnsStatsTest, AddStatsAndClear) {
274 const std::vector<IPSockAddr> servers = {
275 IPSockAddr::toIPSockAddr("127.0.0.1", 53),
276 IPSockAddr::toIPSockAddr("127.0.0.2", 53),
277 };
278 const std::vector<IPSockAddr> mdnsaddrs = {
279 IPSockAddr::toIPSockAddr("ff02::fb", 5353),
280 IPSockAddr::toIPSockAddr("224.0.0.251", 5353),
281 };
282 const DnsQueryEvent record = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms);
283 const DnsQueryEvent mdnsrecord = makeDnsQueryEvent(PROTO_MDNS, NS_R_NO_ERROR, 10ms);
284
285 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_TCP));
286 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP));
287 EXPECT_TRUE(mDnsStats.setAddrs(mdnsaddrs, PROTO_MDNS));
288
289 // Fail to add stats because of incorrect arguments.
290 EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.0.0.4", 53), record));
291 EXPECT_FALSE(mDnsStats.addStats(IPSockAddr::toIPSockAddr("127.a.b.4", 53), record));
292
293 EXPECT_TRUE(mDnsStats.addStats(servers[0], record));
294 EXPECT_TRUE(mDnsStats.addStats(servers[0], record));
295 EXPECT_TRUE(mDnsStats.addStats(servers[1], record));
296 EXPECT_TRUE(mDnsStats.addStats(mdnsaddrs[0], mdnsrecord));
297 EXPECT_TRUE(mDnsStats.addStats(mdnsaddrs[1], mdnsrecord));
298
299 const std::vector<StatsData> expectedStatsForTcp = {
300 makeStatsData(servers[0], 0, 0ms, {}),
301 makeStatsData(servers[1], 0, 0ms, {}),
302 };
303 const std::vector<StatsData> expectedStatsForUdp = {
304 makeStatsData(servers[0], 2, 20ms, {{NS_R_NO_ERROR, 2}}),
305 makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}),
306 };
307
308 const std::vector<StatsData> expectedStatsForMdns = {
309 makeStatsData(mdnsaddrs[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}),
310 makeStatsData(mdnsaddrs[0], 1, 10ms, {{NS_R_NO_ERROR, 1}}),
311 };
312
313 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY));
314 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms));
315 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY));
316 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, expectedStatsForMdns, 10ms));
317 verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {}, expectedStatsForMdns, {});
318
319 // Clear stats.
320 EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_TCP));
321 EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_UDP));
322 EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_DOT));
323 EXPECT_TRUE(mDnsStats.setAddrs({}, PROTO_MDNS));
324 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY));
325 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY));
326 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY));
327 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, {}, NO_AVERAGE_LATENCY));
328 verifyDumpOutput({}, {}, {}, {}, {});
329 }
330
TEST_F(DnsStatsTest,StatsRemainsInExistentServer)331 TEST_F(DnsStatsTest, StatsRemainsInExistentServer) {
332 std::vector<IPSockAddr> servers = {
333 IPSockAddr::toIPSockAddr("127.0.0.1", 53),
334 IPSockAddr::toIPSockAddr("127.0.0.2", 53),
335 };
336 const DnsQueryEvent recordNoError = makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms);
337 const DnsQueryEvent recordTimeout = makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 250ms);
338
339 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP));
340
341 // Add a record to 127.0.0.1.
342 EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError));
343
344 // Add four records to 127.0.0.2.
345 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordNoError));
346 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordNoError));
347 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordTimeout));
348 EXPECT_TRUE(mDnsStats.addStats(servers[1], recordTimeout));
349
350 std::vector<StatsData> expectedStats = {
351 makeStatsData(servers[0], 1, 10ms, {{NS_R_NO_ERROR, 1}}),
352 makeStatsData(servers[1], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}),
353 };
354 EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
355 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms));
356 verifyDumpOutput({}, expectedStats, {}, {}, {});
357
358 // Update the server list, the stats of 127.0.0.2 will remain.
359 servers = {
360 IPSockAddr::toIPSockAddr("127.0.0.2", 53),
361 IPSockAddr::toIPSockAddr("127.0.0.3", 53),
362 IPSockAddr::toIPSockAddr("127.0.0.4", 53),
363 };
364 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP));
365 expectedStats = {
366 makeStatsData(servers[0], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}),
367 makeStatsData(servers[1], 0, 0ms, {}),
368 makeStatsData(servers[2], 0, 0ms, {}),
369 };
370 EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
371 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms));
372 verifyDumpOutput({}, expectedStats, {}, {}, {});
373
374 // Let's add a record to 127.0.0.2 again.
375 EXPECT_TRUE(mDnsStats.addStats(servers[0], recordNoError));
376 expectedStats = {
377 makeStatsData(servers[0], 5, 530ms, {{NS_R_NO_ERROR, 3}, {NS_R_TIMEOUT, 2}}),
378 makeStatsData(servers[1], 0, 0ms, {}),
379 makeStatsData(servers[2], 0, 0ms, {}),
380 };
381 EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
382 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms));
383 verifyDumpOutput({}, expectedStats, {}, {}, {});
384 }
385
TEST_F(DnsStatsTest,AddStatsRecords_100000)386 TEST_F(DnsStatsTest, AddStatsRecords_100000) {
387 constexpr size_t operations = 100000;
388 constexpr size_t logSize = DnsStats::kLogSize;
389 constexpr size_t rcodeNum = 4; // A value by which kLogSize is divisible.
390 ASSERT_EQ(logSize % rcodeNum, 0U);
391
392 const std::vector<IPSockAddr> servers = {
393 IPSockAddr::toIPSockAddr("127.0.0.1", 53),
394 IPSockAddr::toIPSockAddr("127.0.0.2", 53),
395 IPSockAddr::toIPSockAddr("127.0.0.3", 53),
396 IPSockAddr::toIPSockAddr("127.0.0.4", 53),
397 };
398
399 const std::vector<IPSockAddr> mdnsaddrs = {
400 IPSockAddr::toIPSockAddr("ff02::fb", 5353),
401 IPSockAddr::toIPSockAddr("224.0.0.251", 5353),
402 };
403
404 // To test unknown rcode in rcodeToName(), store the elements as type int.
405 const std::array<int, rcodeNum> rcodes = {
406 NS_R_NO_ERROR, // NOERROR
407 NS_R_NXDOMAIN, // NXDOMAIN
408 99, // UNKNOWN(99)
409 NS_R_INTERNAL_ERROR, // INTERNAL_ERROR
410 };
411
412 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_TCP));
413 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_UDP));
414 EXPECT_TRUE(mDnsStats.setAddrs(servers, PROTO_DOT));
415 EXPECT_TRUE(mDnsStats.setAddrs(mdnsaddrs, PROTO_MDNS));
416
417 for (size_t i = 0; i < operations; i++) {
418 const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]);
419 const auto eventTcp = makeDnsQueryEvent(PROTO_TCP, rcode, milliseconds(i));
420 const auto eventUdp = makeDnsQueryEvent(PROTO_UDP, rcode, milliseconds(i));
421 const auto eventDot = makeDnsQueryEvent(PROTO_DOT, rcode, milliseconds(i));
422 for (const auto& server : servers) {
423 SCOPED_TRACE(server.toString() + "-" + std::to_string(i));
424 ASSERT_TRUE(mDnsStats.addStats(server, eventTcp));
425 ASSERT_TRUE(mDnsStats.addStats(server, eventUdp));
426 ASSERT_TRUE(mDnsStats.addStats(server, eventDot));
427 }
428 const auto eventMdns = makeDnsQueryEvent(PROTO_MDNS, rcode, milliseconds(i));
429 for (const auto& mdnsaddr : mdnsaddrs) {
430 SCOPED_TRACE(mdnsaddr.toString() + "-" + std::to_string(i));
431 ASSERT_TRUE(mDnsStats.addStats(mdnsaddr, eventMdns));
432 }
433 }
434
435 std::map<int, int> expectedRcodeCounts;
436 for (const auto& rcode : rcodes) {
437 expectedRcodeCounts.try_emplace(rcode, 32);
438 }
439
440 // The average latency 99935.5 ms is derived from (99872ms + 99873ms + ... + 99999ms) / logSize,
441 // where logSize is 128.
442 const std::vector<StatsData> expectedStats = {
443 makeStatsData(servers[0], logSize, logSize * 99935500us, expectedRcodeCounts),
444 makeStatsData(servers[1], logSize, logSize * 99935500us, expectedRcodeCounts),
445 makeStatsData(servers[2], logSize, logSize * 99935500us, expectedRcodeCounts),
446 makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts),
447 };
448
449 const std::vector<StatsData> expectedMdnsStats = {
450 makeStatsData(mdnsaddrs[1], logSize, logSize * 99935500us, expectedRcodeCounts),
451 makeStatsData(mdnsaddrs[0], logSize, logSize * 99935500us, expectedRcodeCounts),
452 };
453 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us));
454 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us));
455 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us));
456 EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_MDNS, expectedMdnsStats, 99935500us));
457 verifyDumpOutput(expectedStats, expectedStats, expectedStats, expectedMdnsStats, {});
458 }
459
TEST_F(DnsStatsTest,GetServers_SortingByLatency)460 TEST_F(DnsStatsTest, GetServers_SortingByLatency) {
461 const IPSockAddr server1 = IPSockAddr::toIPSockAddr("127.0.0.1", 53);
462 const IPSockAddr server2 = IPSockAddr::toIPSockAddr("127.0.0.2", 53);
463 const IPSockAddr server3 = IPSockAddr::toIPSockAddr("2001:db8:cafe:d00d::1", 53);
464 const IPSockAddr server4 = IPSockAddr::toIPSockAddr("2001:db8:cafe:d00d::2", 53);
465
466 // Return empty list before setup.
467 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP), IsEmpty());
468
469 // Before there's any stats, the list of the sorted servers is the same as the setup's one.
470 EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_UDP));
471 EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_DOT));
472 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
473 testing::ElementsAreArray({server1, server2, server3, server4}));
474
475 // Add a record to server1. The qualities of the other servers increase.
476 EXPECT_TRUE(mDnsStats.addStats(server1, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms)));
477 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
478 testing::ElementsAreArray({server2, server3, server4, server1}));
479
480 // Add a record, with less repose time than server1, to server3.
481 EXPECT_TRUE(mDnsStats.addStats(server3, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 5ms)));
482 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
483 testing::ElementsAreArray({server2, server4, server3, server1}));
484
485 // Even though server2 has zero response time, select server4 as the first server because it
486 // doesn't have stats yet.
487 EXPECT_TRUE(mDnsStats.addStats(server2, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 0ms)));
488 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
489 testing::ElementsAreArray({server4, server2, server3, server1}));
490
491 // Updating DoT record to server4 changes nothing.
492 EXPECT_TRUE(mDnsStats.addStats(server4, makeDnsQueryEvent(PROTO_DOT, NS_R_NO_ERROR, 10ms)));
493 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
494 testing::ElementsAreArray({server4, server2, server3, server1}));
495
496 // Add a record, with a very large value of respose time, to server4.
497 EXPECT_TRUE(mDnsStats.addStats(server4, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 500000ms)));
498 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
499 testing::ElementsAreArray({server2, server3, server1, server4}));
500
501 // Add some internal_error records with permission error to server2.
502 // The internal_error won't cause the priority of server2 drop. (but some of the other
503 // quality factors will still be counted, such as skipped_count and latency)
504 auto recordFromNetworkRestricted = makeDnsQueryEvent(PROTO_UDP, NS_R_INTERNAL_ERROR, 1ms);
505 recordFromNetworkRestricted.set_linux_errno(static_cast<LinuxErrno>(EPERM));
506 for (int i = 0; i < 3; i++) {
507 EXPECT_TRUE(mDnsStats.addStats(server2, recordFromNetworkRestricted));
508 }
509 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
510 testing::ElementsAreArray({server2, server3, server1, server4}));
511
512 // The list of the DNS servers changed.
513 EXPECT_TRUE(mDnsStats.setAddrs({server2, server4}, PROTO_UDP));
514 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
515 testing::ElementsAreArray({server2, server4}));
516
517 // It fails to add records to an non-existing server, and nothing is changed in getting
518 // the sorted servers.
519 EXPECT_FALSE(mDnsStats.addStats(server1, makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 10ms)));
520 EXPECT_THAT(mDnsStats.getSortedServers(PROTO_UDP),
521 testing::ElementsAreArray({server2, server4}));
522 }
523
TEST_F(DnsStatsTest,GetServers_DeprioritizingBadServers)524 TEST_F(DnsStatsTest, GetServers_DeprioritizingBadServers) {
525 const IPSockAddr server1 = IPSockAddr::toIPSockAddr("127.0.0.1", 53);
526 const IPSockAddr server2 = IPSockAddr::toIPSockAddr("127.0.0.2", 53);
527 const IPSockAddr server3 = IPSockAddr::toIPSockAddr("127.0.0.3", 53);
528 const IPSockAddr server4 = IPSockAddr::toIPSockAddr("127.0.0.4", 53);
529
530 EXPECT_TRUE(mDnsStats.setAddrs({server1, server2, server3, server4}, PROTO_UDP));
531
532 int server1Counts = 0;
533 int server2Counts = 0;
534 for (int i = 0; i < 5000; i++) {
535 const auto servers = mDnsStats.getSortedServers(PROTO_UDP);
536 EXPECT_EQ(servers.size(), 4U);
537 if (servers[0] == server1) {
538 // server1 is relatively slowly responsive.
539 EXPECT_TRUE(mDnsStats.addStats(servers[0],
540 makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 200ms)));
541 server1Counts++;
542 } else if (servers[0] == server2) {
543 // server2 is relatively quickly responsive.
544 EXPECT_TRUE(mDnsStats.addStats(servers[0],
545 makeDnsQueryEvent(PROTO_UDP, NS_R_NO_ERROR, 100ms)));
546 server2Counts++;
547 } else if (servers[0] == server3) {
548 // server3 always times out.
549 EXPECT_TRUE(mDnsStats.addStats(servers[0],
550 makeDnsQueryEvent(PROTO_UDP, NS_R_TIMEOUT, 1000ms)));
551 } else if (servers[0] == server4) {
552 // server4 is unusable.
553 EXPECT_TRUE(mDnsStats.addStats(servers[0],
554 makeDnsQueryEvent(PROTO_UDP, NS_R_INTERNAL_ERROR, 1ms)));
555 }
556 }
557
558 const std::vector<StatsData> allStatsData = mDnsStats.getStats(PROTO_UDP);
559 for (const auto& data : allStatsData) {
560 EXPECT_EQ(data.rcodeCounts.size(), 1U);
561 if (data.sockAddr == server1 || data.sockAddr == server2) {
562 const auto it = data.rcodeCounts.find(NS_R_NO_ERROR);
563 ASSERT_NE(it, data.rcodeCounts.end());
564 EXPECT_GT(server2Counts, 2 * server1Counts); // At least twice larger.
565 } else if (data.sockAddr == server3) {
566 const auto it = data.rcodeCounts.find(NS_R_TIMEOUT);
567 ASSERT_NE(it, data.rcodeCounts.end());
568 EXPECT_LT(it->second, 10);
569 } else if (data.sockAddr == server4) {
570 const auto it = data.rcodeCounts.find(NS_R_INTERNAL_ERROR);
571 ASSERT_NE(it, data.rcodeCounts.end());
572 EXPECT_LT(it->second, 10);
573 }
574 }
575 }
576
577 } // namespace android::net
578