1 /*
2  * Copyright (C) 2021 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 
18 #define LOG_TAG "resolv_private_dns_test"
19 
20 #include <regex>
21 
22 #include <aidl/android/net/IDnsResolver.h>
23 #include <android-base/file.h>
24 #include <android-base/logging.h>
25 #include <android/binder_manager.h>
26 #include <android/binder_process.h>
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29 #include <netdutils/InternetAddresses.h>
30 #include <netdutils/NetNativeTestBase.h>
31 #include <netdutils/Stopwatch.h>
32 #include <nettestutils/DumpService.h>
33 
34 #include "doh_frontend.h"
35 #include "tests/dns_responder/dns_responder.h"
36 #include "tests/dns_responder/dns_responder_client_ndk.h"
37 #include "tests/dns_responder/dns_tls_frontend.h"
38 #include "tests/resolv_test_utils.h"
39 #include "tests/unsolicited_listener/unsolicited_event_listener.h"
40 
41 #include <android/multinetwork.h>  // ResNsendFlags
42 #include <arpa/inet.h>
43 #include <poll.h>
44 #include "NetdClient.h"
45 
46 using aidl::android::net::resolv::aidl::DohParamsParcel;
47 using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener;
48 using android::base::GetProperty;
49 using android::base::ReadFdToString;
50 using android::base::unique_fd;
51 using android::net::resolv::aidl::UnsolicitedEventListener;
52 using android::netdutils::IPSockAddr;
53 using android::netdutils::ScopedAddrinfo;
54 using android::netdutils::Stopwatch;
55 using std::chrono::milliseconds;
56 using std::this_thread::sleep_for;
57 using ::testing::AnyOf;
58 
59 constexpr int MAXPACKET = (8 * 1024);
60 
61 // Constant values sync'd from PrivateDnsConfiguration.
62 constexpr int kDohIdleDefaultTimeoutMs = 55000;
63 
64 namespace {
65 
getAsyncResponse(int fd,int * rcode,uint8_t * buf,int bufLen)66 int getAsyncResponse(int fd, int* rcode, uint8_t* buf, int bufLen) {
67     struct pollfd wait_fd[1];
68     wait_fd[0].fd = fd;
69     wait_fd[0].events = POLLIN;
70     short revents;
71 
72     if (int ret = poll(wait_fd, 1, -1); ret <= 0) {
73         return -1;
74     }
75 
76     revents = wait_fd[0].revents;
77     if (revents & POLLIN) {
78         return resNetworkResult(fd, rcode, buf, bufLen);
79     }
80     return -1;
81 }
82 
toString(uint8_t * buf,int bufLen,int ipType)83 std::string toString(uint8_t* buf, int bufLen, int ipType) {
84     ns_msg handle;
85     ns_rr rr;
86 
87     if (ns_initparse((const uint8_t*)buf, bufLen, &handle) >= 0) {
88         if (ns_parserr(&handle, ns_s_an, 0, &rr) == 0) {
89             const uint8_t* rdata = ns_rr_rdata(rr);
90             char buffer[INET6_ADDRSTRLEN];
91             if (inet_ntop(ipType, (const char*)rdata, buffer, sizeof(buffer))) {
92                 return buffer;
93             }
94         }
95     }
96     return "";
97 }
98 
expectAnswersValid(int fd,int ipType,const std::string & expectedAnswer)99 void expectAnswersValid(int fd, int ipType, const std::string& expectedAnswer) {
100     int rcode = -1;
101     uint8_t buf[MAXPACKET] = {};
102 
103     int res = getAsyncResponse(fd, &rcode, buf, MAXPACKET);
104     EXPECT_GT(res, 0);
105     EXPECT_EQ(expectedAnswer, toString(buf, res, ipType));
106 }
107 
108 // A helper which can propagate the failure to outside of the stmt to know which line
109 // of stmt fails. The expectation fails only for the first failed stmt.
110 #define EXPECT_NO_FAILURE(stmt)                                         \
111     do {                                                                \
112         bool alreadyFailed = HasFailure();                              \
113         stmt;                                                           \
114         if (!alreadyFailed && HasFailure()) EXPECT_FALSE(HasFailure()); \
115     } while (0)
116 
117 }  // namespace
118 
119 // Base class to deal with netd binder service and resolver binder service.
120 // TODO: derive ResolverTest from this base class.
121 class BaseTest : public NetNativeTestBase {
122   public:
SetUpTestSuite()123     static void SetUpTestSuite() {
124         // Get binder service.
125         // Note that |mDnsClient| is not used for getting binder service in this static function.
126         // The reason is that wants to keep |mDnsClient| as a non-static data member. |mDnsClient|
127         // which sets up device network configuration could be independent from every test.
128         // TODO: Perhaps add a static function in resolv_test_binder_utils.{cpp,h} to get binder
129         // service.
130         AIBinder* binder = AServiceManager_getService("dnsresolver");
131         sResolvBinder = ndk::SpAIBinder(binder);
132         auto resolvService = aidl::android::net::IDnsResolver::fromBinder(sResolvBinder);
133         ASSERT_NE(nullptr, resolvService.get());
134 
135         // Subscribe the death recipient to the service IDnsResolver for detecting Netd death.
136         // GTEST assertion macros are not invoked for generating a test failure in the death
137         // recipient because the macros can't indicate failed test if Netd died between tests.
138         // Moreover, continuing testing may have no meaningful after Netd death. Therefore, the
139         // death recipient aborts process by GTEST_LOG_(FATAL) once Netd died.
140         sResolvDeathRecipient = AIBinder_DeathRecipient_new([](void*) {
141             constexpr char errorMessage[] = "Netd died";
142             LOG(ERROR) << errorMessage;
143             GTEST_LOG_(FATAL) << errorMessage;
144         });
145         ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, sResolvDeathRecipient, nullptr));
146 
147         // Subscribe the unsolicited event listener for verifying unsolicited event contents.
148         sUnsolicitedEventListener = ndk::SharedRefBase::make<UnsolicitedEventListener>(TEST_NETID);
149         ASSERT_TRUE(
150                 resolvService->registerUnsolicitedEventListener(sUnsolicitedEventListener).isOk());
151 
152         // Start the binder thread pool for listening DNS metrics events and receiving death
153         // recipient.
154         ABinderProcess_startThreadPool();
155     }
TearDownTestSuite()156     static void TearDownTestSuite() { AIBinder_DeathRecipient_delete(sResolvDeathRecipient); }
157 
158   protected:
SetUp()159     void SetUp() {
160         mDnsClient.SetUp();
161         sUnsolicitedEventListener->reset();
162     }
163 
TearDown()164     void TearDown() {
165         // Ensure the dump works at the end of each test.
166         mDnsClient.TearDown();
167     }
168 
resetNetwork()169     void resetNetwork() {
170         EXPECT_EQ(mDnsClient.TearDownOemNetwork(TEST_NETID), 0);
171         EXPECT_EQ(mDnsClient.SetupOemNetwork(TEST_NETID), 0);
172     }
173 
flushCache()174     void flushCache() { mDnsClient.resolvService()->flushNetworkCache(TEST_NETID); }
175 
WaitForDotValidation(std::string serverAddr,bool validated)176     bool WaitForDotValidation(std::string serverAddr, bool validated) {
177         return WaitForPrivateDnsValidation(serverAddr, validated,
178                                            IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT);
179     }
180 
WaitForDotValidationSuccess(std::string serverAddr)181     bool WaitForDotValidationSuccess(std::string serverAddr) {
182         return WaitForDotValidation(serverAddr, true);
183     }
184 
WaitForDotValidationFailure(std::string serverAddr)185     bool WaitForDotValidationFailure(std::string serverAddr) {
186         return WaitForDotValidation(serverAddr, false);
187     }
188 
WaitForDohValidation(std::string serverAddr,bool validated)189     bool WaitForDohValidation(std::string serverAddr, bool validated) {
190         return WaitForPrivateDnsValidation(serverAddr, validated,
191                                            IDnsResolverUnsolicitedEventListener::PROTOCOL_DOH);
192     }
193 
WaitForDohValidationSuccess(std::string serverAddr)194     bool WaitForDohValidationSuccess(std::string serverAddr) {
195         return WaitForDohValidation(serverAddr, true);
196     }
197 
WaitForDohValidationFailure(std::string serverAddr)198     bool WaitForDohValidationFailure(std::string serverAddr) {
199         return WaitForDohValidation(serverAddr, false);
200     }
201 
WaitForPrivateDnsValidation(std::string serverAddr,bool validated,int protocol)202     bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated, int protocol) {
203         return sUnsolicitedEventListener->waitForPrivateDnsValidation(
204                 serverAddr,
205                 validated ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS
206                           : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE,
207                 protocol);
208     }
209 
hasUncaughtPrivateDnsValidation(const std::string & serverAddr)210     bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) {
211         sleep_for(milliseconds(200));
212         return sUnsolicitedEventListener->findValidationRecord(
213                        serverAddr, IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT) ||
214                sUnsolicitedEventListener->findValidationRecord(
215                        serverAddr, IDnsResolverUnsolicitedEventListener::PROTOCOL_DOH);
216     }
217 
expectLog(const std::string & ipAddrOrNoData,const std::string & port)218     bool expectLog(const std::string& ipAddrOrNoData, const std::string& port) {
219         std::vector<std::string> lines;
220         const android::status_t ret =
221                 dumpService(sResolvBinder, /*args=*/nullptr, /*num_args=*/0, lines);
222         if (ret != android::OK) {
223             ADD_FAILURE() << "Error dumping service: " << android::statusToString(ret);
224             return false;
225         }
226 
227         const std::string expectedLog =
228                 port.empty() ? ipAddrOrNoData
229                              : IPSockAddr::toIPSockAddr(ipAddrOrNoData, std::stoi(port)).toString();
230         const std::regex pattern(R"(^\s{4,}([0-9a-fA-F:\.\]\[]*)[ ]?([<(].*[>)])[ ]?(\S*)$)");
231 
232         for (const auto& line : lines) {
233             if (line.empty()) continue;
234 
235             std::smatch match;
236             if (std::regex_match(line, match, pattern)) {
237                 if (match[1] == expectedLog || match[2] == expectedLog) return true;
238             }
239         }
240         return false;
241     }
242 
243     DnsResponderClient mDnsClient;
244 
245     // Use a shared static DNS listener for all tests to avoid registering lots of listeners
246     // which may be released late until process terminated. Currently, registered DNS listener
247     // is removed by binder death notification which is fired when the process hosting an
248     // IBinder has gone away. If every test registers its DNS listener, Netd
249     // may temporarily hold lots of dead listeners until the unit test process terminates.
250     // TODO: Perhaps add an unregistering listener binder call or fork a listener process which
251     // could be terminated earlier.
252     inline static std::shared_ptr<UnsolicitedEventListener> sUnsolicitedEventListener;
253 
254     // Use a shared static death recipient to monitor the service death. The static death
255     // recipient could monitor the death not only during the test but also between tests.
256     inline static AIBinder_DeathRecipient* sResolvDeathRecipient;
257 
258     // The linked AIBinder_DeathRecipient will be automatically unlinked if the binder is deleted.
259     // The binder needs to be retained throughout tests.
260     inline static ndk::SpAIBinder sResolvBinder;
261 };
262 
263 class BasePrivateDnsTest : public BaseTest {
264   public:
SetUpTestSuite()265     static void SetUpTestSuite() {
266         BaseTest::SetUpTestSuite();
267         test::DohFrontend::initRustAndroidLogger();
268     }
269 
270   protected:
SetUp()271     void SetUp() override {
272         mDohQueryTimeoutScopedProp =
273                 std::make_unique<ScopedSystemProperties>(kDohQueryTimeoutFlag, "1000");
274         unsigned int expectedProbeTimeout = kExpectedDohValidationTimeWhenTimeout.count();
275         mDohProbeTimeoutScopedProp = std::make_unique<ScopedSystemProperties>(
276                 kDohProbeTimeoutFlag, std::to_string(expectedProbeTimeout));
277         BaseTest::SetUp();
278 
279         static const std::vector<DnsRecord> records = {
280                 {kQueryHostname, ns_type::ns_t_a, kQueryAnswerA},
281                 {kQueryHostname, ns_type::ns_t_aaaa, kQueryAnswerAAAA},
282         };
283 
284         for (const auto& r : records) {
285             dns.addMapping(r.host_name, r.type, r.addr);
286             dot_backend.addMapping(r.host_name, r.type, r.addr);
287             doh_backend.addMapping(r.host_name, r.type, r.addr);
288         }
289     }
290 
TearDown()291     void TearDown() override {
292         DumpResolverService();
293         BaseTest::TearDown();
294     }
295 
sendQueryAndCheckResult(const char * host_name=kQueryHostname)296     void sendQueryAndCheckResult(const char* host_name = kQueryHostname) {
297         const addrinfo hints = {.ai_socktype = SOCK_DGRAM};
298         ScopedAddrinfo result = safe_getaddrinfo(host_name, nullptr, &hints);
299         EXPECT_THAT(ToStrings(result),
300                     testing::UnorderedElementsAreArray({kQueryAnswerAAAA, kQueryAnswerA}));
301     };
302 
expectQueries(int dnsQueries,int dotQueries,int dohQueries)303     void expectQueries(int dnsQueries, int dotQueries, int dohQueries) {
304         EXPECT_EQ(dns.queries().size(), static_cast<size_t>(dnsQueries));
305         EXPECT_EQ(dot.queries(), dotQueries);
306         EXPECT_EQ(doh.queries(), dohQueries);
307     }
308 
309     // Used when a DoH probe is sent while the DoH server doesn't respond.
waitForDohValidationTimeout()310     void waitForDohValidationTimeout() {
311         std::this_thread::sleep_for(kExpectedDohValidationTimeWhenTimeout);
312     }
313 
314     // Used when a DoH probe is sent while the DoH server is not listening on the port.
waitForDohValidationFailed()315     void waitForDohValidationFailed() {
316         std::this_thread::sleep_for(kExpectedDohValidationTimeWhenServerUnreachable);
317     }
318 
DumpResolverService()319     void DumpResolverService() {
320         unique_fd fd(open("/dev/null", O_WRONLY));
321         EXPECT_EQ(mDnsClient.resolvService()->dump(fd, nullptr, 0), 0);
322 
323         const char* querylogCmd[] = {"querylog"};  // Keep it sync with DnsQueryLog::DUMP_KEYWORD.
324         EXPECT_EQ(mDnsClient.resolvService()->dump(fd, querylogCmd, std::size(querylogCmd)), 0);
325     }
326 
expectQueriesAreBlocked()327     void expectQueriesAreBlocked() {
328         // getaddrinfo should fail
329         const addrinfo hints = {.ai_socktype = SOCK_DGRAM};
330         EXPECT_FALSE(safe_getaddrinfo(kQueryHostname, nullptr, &hints));
331 
332         // gethostbyname should fail
333         EXPECT_FALSE(gethostbyname(kQueryHostname));
334 
335         // gethostbyaddr should fail
336         in6_addr v6addr;
337         inet_pton(AF_INET6, "2001:db8::102:304", &v6addr);
338         EXPECT_FALSE(gethostbyaddr(&v6addr, sizeof(v6addr), AF_INET6));
339 
340         // resNetworkQuery should fail
341         int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa, 0);
342         EXPECT_TRUE(fd != -1);
343 
344         uint8_t buf[MAXPACKET] = {};
345         int rcode;
346         EXPECT_EQ(-ECONNREFUSED, getAsyncResponse(fd, &rcode, buf, MAXPACKET));
347     }
348 
349     static constexpr milliseconds kExpectedDohValidationTimeWhenTimeout{1000};
350     static constexpr milliseconds kExpectedDohValidationTimeWhenServerUnreachable{1000};
351     static constexpr char kQueryHostname[] = "TransportParameterizedTest.example.com.";
352     static constexpr char kQueryAnswerA[] = "1.2.3.4";
353     static constexpr char kQueryAnswerAAAA[] = "2001:db8::100";
354 
355     test::DNSResponder dns{test::kDefaultListenAddr, kDnsPortString};
356     test::DohFrontend doh{test::kDefaultListenAddr, kDohPortString, "127.0.1.3", kDnsPortString};
357     test::DnsTlsFrontend dot{test::kDefaultListenAddr, kDotPortString, "127.0.2.3", kDnsPortString};
358     test::DNSResponder doh_backend{"127.0.1.3", kDnsPortString};
359     test::DNSResponder dot_backend{"127.0.2.3", kDnsPortString};
360 
361     // Used to set up a shorter timeout.
362     std::unique_ptr<ScopedSystemProperties> mDohQueryTimeoutScopedProp;
363     std::unique_ptr<ScopedSystemProperties> mDohProbeTimeoutScopedProp;
364 };
365 
366 // Parameterized test for the combination of DoH and DoT.
367 //  - DoT: the assigned private DNS servers support DoT only.
368 //  - DoH: the assigned private DNS servers support DoH only.
369 //  - DOT + DoH: the assigned private DNS servers support both DoT and DoH.
370 class TransportParameterizedTest : public BasePrivateDnsTest,
371                                    public testing::WithParamInterface<uint8_t> {
372   public:
373     static constexpr uint8_t kDotBit = 0x01;
374     static constexpr uint8_t kDohBit = 0x02;
375     static constexpr std::array<uint8_t, 3> sParams = {kDotBit, kDohBit, kDotBit | kDohBit};
376 
377   protected:
SetUp()378     void SetUp() override {
379         BasePrivateDnsTest::SetUp();
380 
381         ASSERT_TRUE(dns.startServer());
382         if (testParamHasDot()) {
383             ASSERT_TRUE(dot_backend.startServer());
384             ASSERT_TRUE(dot.startServer());
385         }
386         if (testParamHasDoh()) {
387             ASSERT_TRUE(doh_backend.startServer());
388             ASSERT_TRUE(doh.startServer());
389         }
390         SetMdnsRoute();
391     }
392 
TearDown()393     void TearDown() override {
394         RemoveMdnsRoute();
395         BasePrivateDnsTest::TearDown();
396     }
397 
testParamHasDot()398     bool testParamHasDot() { return GetParam() & kDotBit; }
testParamHasDoh()399     bool testParamHasDoh() { return GetParam() & kDohBit; }
400 };
401 
402 INSTANTIATE_TEST_SUITE_P(PrivateDns, TransportParameterizedTest,
403                          testing::ValuesIn(TransportParameterizedTest::sParams),
__anon5805527c0302(const testing::TestParamInfo<uint8_t>& info) 404                          [](const testing::TestParamInfo<uint8_t>& info) {
405                              std::string name;
406                              if (info.param & TransportParameterizedTest::kDotBit) name += "DoT";
407                              if (info.param & TransportParameterizedTest::kDohBit) name += "DoH";
408                              return name;
409                          });
410 
TEST_P(TransportParameterizedTest,GetAddrInfo)411 TEST_P(TransportParameterizedTest, GetAddrInfo) {
412     // TODO: Remove the flags and fix the test.
413     ScopedSystemProperties sp1(kDotAsyncHandshakeFlag, "0");
414     ScopedSystemProperties sp2(kDotMaxretriesFlag, "3");
415     resetNetwork();
416 
417     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
418     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
419 
420     if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
421     if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
422 
423     // This waiting time is expected to avoid that the DoH validation event interferes other tests.
424     if (!testParamHasDoh()) waitForDohValidationFailed();
425 
426     // Have the test independent of the number of sent queries in private DNS validation, because
427     // the DnsResolver can send either 1 or 2 queries in DoT validation.
428     if (testParamHasDoh()) {
429         doh.clearQueries();
430     }
431     if (testParamHasDot()) {
432         EXPECT_TRUE(dot.waitForQueries(1));
433         dot.clearQueries();
434     }
435     dns.clearQueries();
436 
437     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
438     if (testParamHasDoh()) {
439         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
440     } else {
441         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 2 /* dot */, 0 /* doh */));
442     }
443 
444     // Stop the private DNS servers. Since we are in opportunistic mode, queries will
445     // fall back to the cleartext nameserver.
446     flushCache();
447     dot.stopServer();
448     doh.stopServer();
449 
450     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
451     if (testParamHasDoh()) {
452         EXPECT_NO_FAILURE(expectQueries(2 /* dns */, 0 /* dot */, 2 /* doh */));
453     } else {
454         EXPECT_NO_FAILURE(expectQueries(2 /* dns */, 2 /* dot */, 0 /* doh */));
455     }
456 }
457 
TEST_P(TransportParameterizedTest,MdnsGetAddrInfo_fallback)458 TEST_P(TransportParameterizedTest, MdnsGetAddrInfo_fallback) {
459     // TODO: Remove the flags and fix the test.
460     ScopedSystemProperties sp1(kDotAsyncHandshakeFlag, "0");
461     ScopedSystemProperties sp2(kDotMaxretriesFlag, "3");
462     resetNetwork();
463 
464     constexpr char host_name[] = "hello.local.";
465     test::DNSResponder mdnsv4("127.0.0.3", test::kDefaultMdnsListenService,
466                               static_cast<ns_rcode>(-1));
467     test::DNSResponder mdnsv6("::1", test::kDefaultMdnsListenService, static_cast<ns_rcode>(-1));
468     // Set unresponsive on multicast.
469     mdnsv4.setResponseProbability(0.0);
470     mdnsv6.setResponseProbability(0.0);
471     ASSERT_TRUE(mdnsv4.startServer());
472     ASSERT_TRUE(mdnsv6.startServer());
473 
474     const std::vector<DnsRecord> records = {
475             {host_name, ns_type::ns_t_a, kQueryAnswerA},
476             {host_name, ns_type::ns_t_aaaa, kQueryAnswerAAAA},
477     };
478 
479     for (const auto& r : records) {
480         dns.addMapping(r.host_name, r.type, r.addr);
481         dot_backend.addMapping(r.host_name, r.type, r.addr);
482         doh_backend.addMapping(r.host_name, r.type, r.addr);
483     }
484 
485     auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
486     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
487 
488     if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
489     if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
490 
491     // This waiting time is expected to avoid that the DoH validation event interferes other tests.
492     if (!testParamHasDoh()) waitForDohValidationFailed();
493 
494     // Have the test independent of the number of sent queries in private DNS validation, because
495     // the DnsResolver can send either 1 or 2 queries in DoT validation.
496     if (testParamHasDoh()) {
497         doh.clearQueries();
498     }
499     if (testParamHasDot()) {
500         EXPECT_TRUE(dot.waitForQueries(1));
501         dot.clearQueries();
502     }
503     dns.clearQueries();
504 
505     EXPECT_NO_FAILURE(sendQueryAndCheckResult("hello.local"));
506     EXPECT_EQ(1U, GetNumQueries(mdnsv4, host_name));
507     EXPECT_EQ(1U, GetNumQueries(mdnsv6, host_name));
508     if (testParamHasDoh()) {
509         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
510     } else {
511         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 2 /* dot */, 0 /* doh */));
512     }
513 
514     // Stop the private DNS servers. Since we are in opportunistic mode, queries will
515     // fall back to the cleartext nameserver.
516     flushCache();
517     dot.stopServer();
518     doh.stopServer();
519     mdnsv4.clearQueries();
520     mdnsv6.clearQueries();
521 
522     EXPECT_NO_FAILURE(sendQueryAndCheckResult("hello.local"));
523     EXPECT_EQ(1U, GetNumQueries(mdnsv4, host_name));
524     EXPECT_EQ(1U, GetNumQueries(mdnsv6, host_name));
525     if (testParamHasDoh()) {
526         EXPECT_NO_FAILURE(expectQueries(2 /* dns */, 0 /* dot */, 2 /* doh */));
527     } else {
528         EXPECT_NO_FAILURE(expectQueries(2 /* dns */, 2 /* dot */, 0 /* doh */));
529     }
530 }
531 
TEST_P(TransportParameterizedTest,BlockDnsQuery)532 TEST_P(TransportParameterizedTest, BlockDnsQuery) {
533     SKIP_IF_BEFORE_T;
534     SKIP_IF_DEPENDENT_LIB_DOES_NOT_EXIST(DNS_HELPER);
535 
536     constexpr char ptr_name[] = "v4v6.example.com.";
537     // PTR record for IPv6 address 2001:db8::102:304
538     constexpr char ptr_addr_v6[] =
539             "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.";
540     const DnsRecord r = {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name};
541     dns.addMapping(r.host_name, r.type, r.addr);
542     dot_backend.addMapping(r.host_name, r.type, r.addr);
543     doh_backend.addMapping(r.host_name, r.type, r.addr);
544 
545     // TODO: Remove the flags and fix the test.
546     // These two flags are not necessary for this test case because the test does not expect DNS
547     // queries to be sent by DNS resolver. However, We should still set these two flags so that we
548     // don't forget to set them when writing similar tests in the future by referring to this one.
549     ScopedSystemProperties sp1(kDotAsyncHandshakeFlag, "0");
550     ScopedSystemProperties sp2(kDotMaxretriesFlag, "3");
551 
552     auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
553     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
554 
555     if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
556     if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
557 
558     // This waiting time is expected to avoid that the DoH validation event interferes other tests.
559     if (!testParamHasDoh()) waitForDohValidationFailed();
560 
561     // Have the test independent of the number of sent queries in private DNS validation, because
562     // the DnsResolver can send either 1 or 2 queries in DoT validation.
563     if (testParamHasDoh()) {
564         doh.clearQueries();
565     }
566     if (testParamHasDot()) {
567         EXPECT_TRUE(dot.waitForQueries(1));
568         dot.clearQueries();
569     }
570     dns.clearQueries();
571 
572     for (const bool testDataSaver : {false, true}) {
573         SCOPED_TRACE(fmt::format("test {}", testDataSaver ? "data saver" : "UID firewall rules"));
574         if (testDataSaver) {
575             // Data Saver applies on metered networks only.
576             parcel.meteredNetwork = true;
577             ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
578 
579             // Block network access by enabling data saver.
580             ScopedSetDataSaverByBPF scopedSetDataSaverByBPF(true);
581             ScopedChangeUID scopedChangeUID(TEST_UID);
582 
583             // DataSaver information is only meaningful after V.
584             // TODO: Add 'else' to check that DNS queries are not blocked before V.
585             if (android::modules::sdklevel::IsAtLeastV()) {
586                 EXPECT_NO_FAILURE(expectQueriesAreBlocked());
587             }
588         } else {
589             // Block network access by setting UID firewall rules.
590             ScopeBlockedUIDRule scopeBlockUidRule(mDnsClient.netdService(), TEST_UID);
591             EXPECT_NO_FAILURE(expectQueriesAreBlocked());
592         }
593         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 0 /* doh */));
594     }
595 }
596 
597 // Verify whether the DNS fail-fast feature can be turned off by flag.
TEST_P(TransportParameterizedTest,BlockDnsQuery_FlaggedOff)598 TEST_P(TransportParameterizedTest, BlockDnsQuery_FlaggedOff) {
599     SKIP_IF_BEFORE_T;
600     SKIP_IF_DEPENDENT_LIB_DOES_NOT_EXIST(DNS_HELPER);
601 
602     constexpr char ptr_name[] = "v4v6.example.com.";
603     // PTR record for IPv6 address 2001:db8::102:304
604     constexpr char ptr_addr_v6[] =
605             "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.";
606     const DnsRecord r = {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name};
607     dns.addMapping(r.host_name, r.type, r.addr);
608     dot_backend.addMapping(r.host_name, r.type, r.addr);
609     doh_backend.addMapping(r.host_name, r.type, r.addr);
610 
611     ScopedSystemProperties sp1(kFailFastOnUidNetworkBlockingFlag, "0");
612     // TODO: Remove the flags and fix the test.
613     // Context: Fake DoT server closes SSL connection after replying to each query. But a single DNS
614     // API can send two queries for A and AAAA. One of them will failed in MTS because the current
615     // setting pushed by server is no retry.
616     ScopedSystemProperties sp2(kDotAsyncHandshakeFlag, "0");
617     ScopedSystemProperties sp3(kDotMaxretriesFlag, "3");
618 
619     resetNetwork();
620 
621     auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
622     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
623 
624     if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
625     if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
626 
627     // This waiting time is expected to avoid that the DoH validation event interferes other tests.
628     if (!testParamHasDoh()) waitForDohValidationFailed();
629 
630     // Have the test independent of the number of sent queries in private DNS validation, because
631     // the DnsResolver can send either 1 or 2 queries in DoT validation.
632     if (testParamHasDoh()) {
633         doh.clearQueries();
634     }
635     if (testParamHasDot()) {
636         EXPECT_TRUE(dot.waitForQueries(1));
637         dot.clearQueries();
638     }
639     dns.clearQueries();
640 
641     for (const bool testDataSaver : {false, true}) {
642         SCOPED_TRACE(fmt::format("test {}", testDataSaver ? "data saver" : "UID firewall rules"));
643         if (testDataSaver) {
644             // Data Saver applies on metered networks only.
645             parcel.meteredNetwork = true;
646             ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
647 
648             // Block network access by enabling data saver.
649             ScopedSetDataSaverByBPF scopedSetDataSaverByBPF(true);
650             ScopedChangeUID scopedChangeUID(TEST_UID);
651             EXPECT_NO_FAILURE(sendQueryAndCheckResult());
652         } else {
653             // Block network access by setting UID firewall rules.
654             ScopeBlockedUIDRule scopeBlockUidRule(mDnsClient.netdService(), TEST_UID);
655             EXPECT_NO_FAILURE(sendQueryAndCheckResult());
656         }
657 
658         if (testParamHasDoh()) {
659             EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
660             doh.clearQueries();
661         } else {
662             EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 2 /* dot */, 0 /* doh */));
663             dot.clearQueries();
664         }
665         flushCache();
666     }
667 }
668 
669 class PrivateDnsDohTest : public BasePrivateDnsTest {
670   protected:
SetUp()671     void SetUp() override {
672         BasePrivateDnsTest::SetUp();
673 
674         ASSERT_TRUE(dns.startServer());
675         ASSERT_TRUE(dot_backend.startServer());
676         ASSERT_TRUE(dot.startServer());
677         ASSERT_TRUE(doh_backend.startServer());
678         ASSERT_TRUE(doh.startServer());
679     }
680 };
681 
682 // Tests that DoH validation doesn't take much time in the following scenario:
683 //   - DoH server is unreachable.
684 //   - DoH server does not respond.
TEST_F(PrivateDnsDohTest,ValidationFail)685 TEST_F(PrivateDnsDohTest, ValidationFail) {
686     using std::chrono::microseconds;
687 
688     constexpr milliseconds TIMING_TOLERANCE{1000};
689 
690     // Make the DoT server broken so that the test can receive the validation event of both
691     // DoT and DoH, so we can calculate the time taken on DoH validation.
692     dot.stopServer();
693 
694     // Set the DoH server unreachable.
695     doh.stopServer();
696 
697     Stopwatch s;
698     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
699     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
700     EXPECT_TRUE(WaitForDohValidationFailure(test::kDefaultListenAddr));
701     EXPECT_TRUE(WaitForDotValidationFailure(test::kDefaultListenAddr));
702     EXPECT_LT(s.getTimeAndResetUs(),
703               microseconds(kExpectedDohValidationTimeWhenServerUnreachable + TIMING_TOLERANCE)
704                       .count());
705 
706     // Set the DoH server unresponsive.
707     ASSERT_TRUE(doh.startServer());
708     doh_backend.setResponseProbability(0.0);
709     doh_backend.setErrorRcode(static_cast<ns_rcode>(-1));
710 
711     s.getTimeAndResetUs();
712     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
713     EXPECT_TRUE(WaitForDohValidationFailure(test::kDefaultListenAddr));
714     EXPECT_TRUE(WaitForDotValidationFailure(test::kDefaultListenAddr));
715     EXPECT_LT(s.getTimeAndResetUs(),
716               microseconds(kExpectedDohValidationTimeWhenTimeout + TIMING_TOLERANCE).count());
717 
718     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
719     EXPECT_FALSE(hasUncaughtPrivateDnsValidation(test::kDefaultListenAddr));
720 }
721 
722 // Tests that DoH query fails and fallback happens.
723 //   - Fallback to UDP if DoH query times out
724 //   - Fallback to DoT if DoH validation is in progress or has failed.
TEST_F(PrivateDnsDohTest,QueryFailover)725 TEST_F(PrivateDnsDohTest, QueryFailover) {
726     // TODO: Remove the flags and fix the test.
727     ScopedSystemProperties sp1(kDotAsyncHandshakeFlag, "0");
728     ScopedSystemProperties sp2(kDotMaxretriesFlag, "3");
729     resetNetwork();
730 
731     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
732     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
733     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
734     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
735     EXPECT_TRUE(dot.waitForQueries(1));
736     dot.clearQueries();
737     dns.clearQueries();
738 
739     doh_backend.setResponseProbability(0.0);
740     doh_backend.setErrorRcode(static_cast<ns_rcode>(-1));
741 
742     // Expect that the query fall back to UDP.
743     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
744     EXPECT_EQ(dot.queries(), 0);
745     EXPECT_EQ(dns.queries().size(), 2U);
746     flushCache();
747 
748     resetNetwork();
749     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
750 
751     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
752     EXPECT_TRUE(dot.waitForQueries(1));
753     dot.clearQueries();
754     dns.clearQueries();
755 
756     // Expect that the query fall back to DoT as DoH validation is in progress.
757     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
758 
759     EXPECT_EQ(dot.queries(), 2);
760     EXPECT_EQ(dns.queries().size(), 0U);
761     waitForDohValidationTimeout();
762     flushCache();
763 
764     // Expect that this query fall back to DoT as DoH validation has failed.
765     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
766     EXPECT_EQ(dot.queries(), 4);
767     EXPECT_EQ(dns.queries().size(), 0U);
768 }
769 
770 // Tests that the DnsResolver prioritizes IPv6 DoH servers over IPv4 DoH servers.
TEST_F(PrivateDnsDohTest,PreferIpv6)771 TEST_F(PrivateDnsDohTest, PreferIpv6) {
772     constexpr char listen_ipv6_addr[] = "::1";
773     const std::vector<std::vector<std::string>> testConfig = {
774             {test::kDefaultListenAddr, listen_ipv6_addr},
775             {listen_ipv6_addr, test::kDefaultListenAddr},
776     };
777 
778     // To simplify the test, set the DoT server broken.
779     dot.stopServer();
780 
781     test::DNSResponder dns_ipv6{listen_ipv6_addr, kDnsPortString};
782     test::DohFrontend doh_ipv6{listen_ipv6_addr, kDohPortString, listen_ipv6_addr, kDnsPortString};
783     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_a, kQueryAnswerA);
784     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_aaaa, kQueryAnswerAAAA);
785     ASSERT_TRUE(dns_ipv6.startServer());
786     ASSERT_TRUE(doh_ipv6.startServer());
787 
788     for (const auto& serverList : testConfig) {
789         SCOPED_TRACE(fmt::format("serverList: [{}]", fmt::join(serverList, ", ")));
790 
791         auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
792         parcel.servers = serverList;
793         parcel.tlsServers = serverList;
794         ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
795 
796         // Currently, DnsResolver sorts the server list and did DoH validation only
797         // for the first server.
798         EXPECT_TRUE(WaitForDohValidationSuccess(listen_ipv6_addr));
799 
800         doh.clearQueries();
801         doh_ipv6.clearQueries();
802 
803         EXPECT_NO_FAILURE(sendQueryAndCheckResult());
804         EXPECT_EQ(doh_ipv6.queries(), 2);
805         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 0 /* doh */));
806 
807         resetNetwork();
808     }
809 }
810 
811 // Tests that DoH server setting can be replaced/removed correctly.
TEST_F(PrivateDnsDohTest,ChangeAndClearPrivateDnsServer)812 TEST_F(PrivateDnsDohTest, ChangeAndClearPrivateDnsServer) {
813     constexpr char listen_ipv6_addr[] = "::1";
814 
815     // To simplify the test, set the DoT server broken.
816     dot.stopServer();
817 
818     test::DNSResponder dns_ipv6{listen_ipv6_addr, kDnsPortString};
819     test::DohFrontend doh_ipv6{listen_ipv6_addr, kDohPortString, listen_ipv6_addr, kDnsPortString};
820     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_a, kQueryAnswerA);
821     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_aaaa, kQueryAnswerAAAA);
822     ASSERT_TRUE(dns_ipv6.startServer());
823     ASSERT_TRUE(doh_ipv6.startServer());
824 
825     auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
826     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
827 
828     // Use v4 DoH server first.
829     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
830     doh.clearQueries();
831     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
832     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
833 
834     // Change to the v6 DoH server.
835     parcel.servers = {listen_ipv6_addr};
836     parcel.tlsServers = {listen_ipv6_addr};
837     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
838     EXPECT_TRUE(WaitForDohValidationSuccess(listen_ipv6_addr));
839     doh.clearQueries();
840     doh_ipv6.clearQueries();
841     flushCache();
842     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
843     EXPECT_EQ(doh_ipv6.queries(), 2);
844     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 0 /* doh */));
845 
846     // Change to an invalid DoH server.
847     parcel.tlsServers = {kHelloExampleComAddrV4};
848     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
849     doh_ipv6.clearQueries();
850     dns_ipv6.clearQueries();
851     flushCache();
852     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
853     EXPECT_EQ(doh_ipv6.queries(), 0);
854     EXPECT_EQ(dns_ipv6.queries().size(), 2U);
855 
856     // Remove private DNS servers.
857     parcel.tlsServers = {};
858     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
859     doh_ipv6.clearQueries();
860     dns_ipv6.clearQueries();
861     flushCache();
862     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
863     EXPECT_EQ(doh_ipv6.queries(), 0);
864     EXPECT_EQ(dns_ipv6.queries().size(), 2U);
865 }
866 
TEST_F(PrivateDnsDohTest,ChangePrivateDnsServerAndVerifyOutput)867 TEST_F(PrivateDnsDohTest, ChangePrivateDnsServerAndVerifyOutput) {
868     // To simplify the test, set the DoT server broken.
869     dot.stopServer();
870 
871     static const std::string ipv4DohServerAddr = "127.0.0.3";
872     static const std::string ipv6DohServerAddr = "::1";
873 
874     test::DNSResponder dns_ipv6{ipv6DohServerAddr, kDnsPortString};
875     test::DohFrontend doh_ipv6{ipv6DohServerAddr, kDohPortString, ipv6DohServerAddr,
876                                kDnsPortString};
877     dns.addMapping(kQueryHostname, ns_type::ns_t_a, kQueryAnswerA);
878     dns.addMapping(kQueryHostname, ns_type::ns_t_aaaa, kQueryAnswerAAAA);
879     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_a, kQueryAnswerA);
880     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_aaaa, kQueryAnswerAAAA);
881     ASSERT_TRUE(dns_ipv6.startServer());
882     ASSERT_TRUE(doh_ipv6.startServer());
883 
884     // Start the v4 DoH server.
885     auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
886     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
887     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
888     EXPECT_TRUE(expectLog(ipv4DohServerAddr, kDohPortString));
889 
890     // Change to an invalid DoH server.
891     parcel.tlsServers = {kHelloExampleComAddrV4};
892     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
893     EXPECT_FALSE(expectLog(kHelloExampleComAddrV4, kDohPortString));
894     EXPECT_TRUE(expectLog("<no data>", ""));
895 
896     // Change to the v6 DoH server.
897     parcel.servers = {ipv6DohServerAddr};
898     parcel.tlsServers = {ipv6DohServerAddr};
899     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
900     EXPECT_TRUE(WaitForDohValidationSuccess(ipv6DohServerAddr));
901     EXPECT_TRUE(expectLog(ipv6DohServerAddr, kDohPortString));
902     EXPECT_FALSE(expectLog(ipv4DohServerAddr, kDohPortString));
903 
904     // Remove the private DNS server.
905     parcel.tlsServers = {};
906     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
907     EXPECT_FALSE(expectLog(ipv4DohServerAddr, kDohPortString));
908     EXPECT_FALSE(expectLog(ipv6DohServerAddr, kDohPortString));
909     EXPECT_TRUE(expectLog("<no data>", ""));
910 }
911 
912 // Tests that a DoH query is sent while the network is stalled temporarily.
TEST_F(PrivateDnsDohTest,TemporaryConnectionStalled)913 TEST_F(PrivateDnsDohTest, TemporaryConnectionStalled) {
914     const int connectionStalledTimeMs = 3000;
915     ScopedSystemProperties sp(kDohQueryTimeoutFlag, "10000");
916     resetNetwork();
917 
918     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
919     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
920     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
921     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
922     EXPECT_TRUE(dot.waitForQueries(1));
923     dot.clearQueries();
924     doh.clearQueries();
925     dns.clearQueries();
926 
927     EXPECT_TRUE(doh.block_sending(true));
928     Stopwatch s;
929     int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_a,
930                              ANDROID_RESOLV_NO_CACHE_LOOKUP);
931     sleep_for(milliseconds(connectionStalledTimeMs));
932     EXPECT_TRUE(doh.block_sending(false));
933 
934     expectAnswersValid(fd, AF_INET, kQueryAnswerA);
935     EXPECT_GT(s.timeTakenUs() / 1000, connectionStalledTimeMs);
936     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 1 /* doh */));
937 }
938 
939 // (b/207301204): Tests that the DnsResolver will try DoT rather than DoH if there are excess
940 // DNS requests. In addition, tests that sending DNS requests to other networks succeeds.
941 // Note: This test is subject to MAX_BUFFERED_COMMANDS. If the value is changed, this test might
942 // need to be modified as well.
TEST_F(PrivateDnsDohTest,ExcessDnsRequests)943 TEST_F(PrivateDnsDohTest, ExcessDnsRequests) {
944     const int total_queries = 70;
945 
946     // In most cases, the number of timed-out DoH queries is MAX_BUFFERED_COMMANDS + 2 (one that
947     // will be queued in connection's mpsc::channel; the other one that will get blocked at
948     // dispatcher's mpsc::channel), as shown below:
949     //
950     // dispatcher's mpsc::channel -----> network's mpsc:channel -----> connection's mpsc::channel
951     // (expect 1 query queued here)   (size: MAX_BUFFERED_COMMANDS)   (expect 1 query queued here)
952     //
953     // However, it's still possible that the (MAX_BUFFERED_COMMANDS + 2)th query is sent to the DoH
954     // engine before the DoH engine moves a query to connection's mpsc::channel. In that case,
955     // the (MAX_BUFFERED_COMMANDS + 2)th query will be fallback'ed to DoT immediately rather than
956     // be waiting until DoH timeout, which result in only (MAX_BUFFERED_COMMANDS + 1) timed-out
957     // DoH queries.
958     const int doh_timeout_queries = 52;
959 
960     // If early data flag is enabled, DnsResolver doesn't wait for the connection established.
961     // It will send DNS queries along with 0-RTT rather than queue them in connection mpsc channel.
962     // So we disable the flag.
963     ScopedSystemProperties sp(kDohEarlyDataFlag, "0");
964     resetNetwork();
965 
966     const int initial_max_idle_timeout_ms = 2000;
967     ASSERT_TRUE(doh.stopServer());
968     EXPECT_TRUE(doh.setMaxIdleTimeout(initial_max_idle_timeout_ms));
969     ASSERT_TRUE(doh.startServer());
970 
971     auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
972     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
973     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
974     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
975     EXPECT_TRUE(dot.waitForQueries(1));
976     dot.clearQueries();
977     doh.clearQueries();
978     dns.clearQueries();
979 
980     // Set the DoT server not to close the connection until it receives enough queries or timeout.
981     dot.setDelayQueries(total_queries - doh_timeout_queries);
982     dot.setDelayQueriesTimeout(200);
983 
984     // Set the server blocking, wait for the connection closed, and send some DNS requests.
985     EXPECT_TRUE(doh.block_sending(true));
986     EXPECT_TRUE(doh.waitForAllClientsDisconnected());
987     std::array<int, total_queries> fds;
988     for (auto& fd : fds) {
989         fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa,
990                              ANDROID_RESOLV_NO_CACHE_LOOKUP);
991     }
992     for (const auto& fd : fds) {
993         expectAnswersValid(fd, AF_INET6, kQueryAnswerAAAA);
994     }
995     EXPECT_TRUE(doh.block_sending(false));
996 
997     // There are some queries that fall back to DoT rather than UDP since the DoH client rejects
998     // any new DNS requests when the capacity is full.
999     EXPECT_THAT(dns.queries().size(), AnyOf(doh_timeout_queries, doh_timeout_queries - 1));
1000     EXPECT_THAT(dot.queries(), AnyOf(total_queries - doh_timeout_queries,
1001                                      total_queries - doh_timeout_queries + 1));
1002     EXPECT_EQ(doh.queries(), 0);
1003 
1004     // Set up another network and send a DNS query. Expect that this network is unaffected.
1005     constexpr int TEST_NETID_2 = 31;
1006     constexpr char listen_ipv6_addr[] = "::1";
1007     test::DNSResponder dns_ipv6{listen_ipv6_addr, kDnsPortString};
1008     test::DnsTlsFrontend dot_ipv6{listen_ipv6_addr, kDotPortString, listen_ipv6_addr,
1009                                   kDnsPortString};
1010     test::DohFrontend doh_ipv6{listen_ipv6_addr, kDohPortString, listen_ipv6_addr, kDnsPortString};
1011 
1012     dns_ipv6.addMapping(kQueryHostname, ns_type::ns_t_aaaa, kQueryAnswerAAAA);
1013     ASSERT_TRUE(dns_ipv6.startServer());
1014     ASSERT_TRUE(dot_ipv6.startServer());
1015     ASSERT_TRUE(doh_ipv6.startServer());
1016 
1017     mDnsClient.SetupOemNetwork(TEST_NETID_2);
1018     parcel.netId = TEST_NETID_2;
1019     parcel.servers = {listen_ipv6_addr};
1020     parcel.tlsServers = {listen_ipv6_addr};
1021     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1022 
1023     // Sleep a while to wait for DoH and DoT validation.
1024     // TODO: Extend WaitForDohValidation() to support passing a netId.
1025     sleep_for(milliseconds(200));
1026     EXPECT_TRUE(dot_ipv6.waitForQueries(1));
1027 
1028     int fd = resNetworkQuery(TEST_NETID_2, kQueryHostname, ns_c_in, ns_t_aaaa,
1029                              ANDROID_RESOLV_NO_CACHE_LOOKUP);
1030     expectAnswersValid(fd, AF_INET6, kQueryAnswerAAAA);
1031 
1032     // Expect two queries: one for DoH probe and the other one for kQueryHostname.
1033     EXPECT_EQ(doh_ipv6.queries(), 2);
1034 
1035     mDnsClient.TearDownOemNetwork(TEST_NETID_2);
1036 
1037     // The DnsResolver will reconnect to the DoH server for the query that gets blocked at
1038     // dispatcher sending channel. However, there's no way to know when the reconnection will start.
1039     // We have to periodically send a DNS request to check it. After the reconnection starts, the
1040     // DNS query will be sent to the Doh server instead of the cleartext DNS server. Then, we
1041     // are safe to end the test. Otherwise, the reconnection will interfere other tests.
1042     EXPECT_EQ(doh.queries(), 0);
1043     for (int i = 0; i < 50; i++) {
1044         sleep_for(milliseconds(100));
1045         int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa,
1046                                  ANDROID_RESOLV_NO_CACHE_LOOKUP);
1047         expectAnswersValid(fd, AF_INET6, kQueryAnswerAAAA);
1048         if (doh.queries() > 0) break;
1049     }
1050     EXPECT_GT(doh.queries(), 0);
1051 }
1052 
1053 // Tests the scenario where the DnsResolver runs out of QUIC connection data limit.
TEST_F(PrivateDnsDohTest,RunOutOfDataLimit)1054 TEST_F(PrivateDnsDohTest, RunOutOfDataLimit) {
1055     // Each DoH query consumes about 100 bytes of QUIC connection send capacity.
1056     // Set initial_max_data to 450 so the fifth DoH query will get blocked.
1057     const int queries = 4;
1058     const int initial_max_data = 450;
1059 
1060     ScopedSystemProperties sp(kDohQueryTimeoutFlag, "3000");
1061     resetNetwork();
1062 
1063     ASSERT_TRUE(doh.stopServer());
1064     EXPECT_TRUE(doh.setMaxBufferSize(initial_max_data));
1065     ASSERT_TRUE(doh.startServer());
1066 
1067     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1068     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1069     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1070     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1071     EXPECT_TRUE(dot.waitForQueries(1));
1072     dot.clearQueries();
1073     doh.clearQueries();
1074     dns.clearQueries();
1075 
1076     // Block the DoH server from sending data for a while.
1077     EXPECT_TRUE(doh.block_sending(true));
1078     std::vector<std::thread> threads(queries);
1079     for (std::thread& thread : threads) {
1080         thread = std::thread([&]() {
1081             int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_a,
1082                                      ANDROID_RESOLV_NO_CACHE_LOOKUP);
1083             expectAnswersValid(fd, AF_INET, kQueryAnswerA);
1084         });
1085     }
1086     sleep_for(milliseconds(500));
1087     EXPECT_TRUE(doh.block_sending(false));
1088 
1089     // In current implementation, the fifth DoH query will get blocked and result in timeout.
1090     int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_a,
1091                              ANDROID_RESOLV_NO_CACHE_LOOKUP);
1092     expectAnswersValid(fd, AF_INET, kQueryAnswerA);
1093 
1094     for (std::thread& thread : threads) {
1095         thread.join();
1096     }
1097 
1098     // TODO: see how we can improve the DnsResolver to make all of the DNS queries resolved by DoH.
1099     // EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 5 /* doh */));
1100 }
1101 
1102 // Tests the scenario where the DnsResolver runs out of QUIC streams limit.
TEST_F(PrivateDnsDohTest,RunOutOfStreams)1103 TEST_F(PrivateDnsDohTest, RunOutOfStreams) {
1104     const int queries = 6;
1105     const int initial_max_streams_bidi = 5;
1106 
1107     // Since the last query won't be issued until there are streams available, lengthen the
1108     // timeout to 3 seconds.
1109     ScopedSystemProperties sp(kDohQueryTimeoutFlag, "3000");
1110     resetNetwork();
1111 
1112     ASSERT_TRUE(doh.stopServer());
1113     EXPECT_TRUE(doh.setMaxStreamsBidi(initial_max_streams_bidi));
1114     ASSERT_TRUE(doh.startServer());
1115 
1116     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1117     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1118     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1119     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1120     EXPECT_TRUE(dot.waitForQueries(1));
1121     dot.clearQueries();
1122     doh.clearQueries();
1123     dns.clearQueries();
1124 
1125     // Block the DoH server from sending data for a while.
1126     EXPECT_TRUE(doh.block_sending(true));
1127     std::vector<std::thread> threads(queries);
1128     for (std::thread& thread : threads) {
1129         thread = std::thread([&]() {
1130             int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_a,
1131                                      ANDROID_RESOLV_NO_CACHE_LOOKUP);
1132             expectAnswersValid(fd, AF_INET, kQueryAnswerA);
1133         });
1134     }
1135     sleep_for(milliseconds(500));
1136     EXPECT_TRUE(doh.block_sending(false));
1137 
1138     for (std::thread& thread : threads) {
1139         thread.join();
1140     }
1141 
1142     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 6 /* doh */));
1143 }
1144 
1145 // Tests that the DnsResolver automatically reconnects to the DoH server when needed.
1146 // Session resumption should be used in each reconnection.
TEST_F(PrivateDnsDohTest,ReconnectAfterIdleTimeout)1147 TEST_F(PrivateDnsDohTest, ReconnectAfterIdleTimeout) {
1148     const int initial_max_idle_timeout_ms = 1000;
1149 
1150     ASSERT_TRUE(doh.stopServer());
1151     EXPECT_TRUE(doh.setMaxIdleTimeout(initial_max_idle_timeout_ms));
1152     ASSERT_TRUE(doh.startServer());
1153 
1154     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1155     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1156     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1157     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1158     EXPECT_TRUE(dot.waitForQueries(1));
1159     dot.clearQueries();
1160     doh.clearQueries();
1161     dns.clearQueries();
1162 
1163     for (int i = 0; i < 5; i++) {
1164         SCOPED_TRACE(fmt::format("Round: {}", i));
1165         sleep_for(milliseconds(initial_max_idle_timeout_ms + 500));
1166 
1167         // As the connection is closed, the DnsResolver will reconnect to the DoH server
1168         // for this DNS request.
1169         int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_a,
1170                                  ANDROID_RESOLV_NO_CACHE_LOOKUP);
1171         expectAnswersValid(fd, AF_INET, kQueryAnswerA);
1172     }
1173 
1174     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 5 /* doh */));
1175     EXPECT_EQ(doh.connections(), 6);
1176 }
1177 
1178 // Tests that the experiment flag doh_idle_timeout_ms is effective.
TEST_F(PrivateDnsDohTest,ConnectionIdleTimer)1179 TEST_F(PrivateDnsDohTest, ConnectionIdleTimer) {
1180     const int connection_idle_timeout = 1500;
1181     const int tolerance_ms = 200;
1182 
1183     // Check if the default value or the timeout the device is using is too short for the test.
1184     const int device_connection_idle_timeout =
1185             std::min(std::stoi(GetProperty(kDohIdleTimeoutFlag, "9999")), kDohIdleDefaultTimeoutMs);
1186     if (device_connection_idle_timeout <= connection_idle_timeout + tolerance_ms) {
1187         GTEST_LOG_(INFO) << "The test can't guarantee that the flag takes effect because "
1188                          << "device_connection_idle_timeout is too short: "
1189                          << device_connection_idle_timeout << " ms.";
1190     }
1191 
1192     ScopedSystemProperties sp(kDohIdleTimeoutFlag, std::to_string(connection_idle_timeout));
1193     resetNetwork();
1194 
1195     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1196     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1197     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1198     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1199     EXPECT_TRUE(dot.waitForQueries(1));
1200     dot.clearQueries();
1201     doh.clearQueries();
1202     dns.clearQueries();
1203 
1204     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
1205     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
1206     flushCache();
1207     EXPECT_EQ(doh.connections(), 1);
1208 
1209     // Expect that the DoH connection gets disconnected while sleeping.
1210     sleep_for(milliseconds(connection_idle_timeout + tolerance_ms));
1211 
1212     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
1213     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 4 /* doh */));
1214     EXPECT_EQ(doh.connections(), 2);
1215 }
1216 
1217 // Tests that the flag "doh_session_resumption" works as expected.
TEST_F(PrivateDnsDohTest,SessionResumption)1218 TEST_F(PrivateDnsDohTest, SessionResumption) {
1219     const int initial_max_idle_timeout_ms = 1000;
1220     for (const auto& flag : {"0", "1"}) {
1221         SCOPED_TRACE(fmt::format("flag: {}", flag));
1222         ScopedSystemProperties sp(kDohSessionResumptionFlag, flag);
1223         resetNetwork();
1224 
1225         ASSERT_TRUE(doh.stopServer());
1226         EXPECT_TRUE(doh.setMaxIdleTimeout(initial_max_idle_timeout_ms));
1227         ASSERT_TRUE(doh.startServer());
1228 
1229         const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1230         ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1231         EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1232         EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1233         EXPECT_TRUE(dot.waitForQueries(1));
1234         dot.clearQueries();
1235         doh.clearQueries();
1236         dns.clearQueries();
1237 
1238         for (int i = 0; i < 2; i++) {
1239             SCOPED_TRACE(fmt::format("Round: {}", i));
1240             sleep_for(milliseconds(initial_max_idle_timeout_ms + 500));
1241 
1242             // As the connection is closed, the DnsResolver will reconnect to the DoH server
1243             // for this DNS request.
1244             int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_a,
1245                                      ANDROID_RESOLV_NO_CACHE_LOOKUP);
1246             expectAnswersValid(fd, AF_INET, kQueryAnswerA);
1247         }
1248 
1249         EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
1250         EXPECT_EQ(doh.connections(), 3);
1251         EXPECT_EQ(doh.resumedConnections(), (strcmp(flag, "1") ? 0 : 2));
1252     }
1253 }
1254 
1255 // Tests that the flag "doh_early_data" works as expected.
TEST_F(PrivateDnsDohTest,TestEarlyDataFlag)1256 TEST_F(PrivateDnsDohTest, TestEarlyDataFlag) {
1257     const int initial_max_idle_timeout_ms = 1000;
1258     for (const auto& flag : {"0", "1"}) {
1259         SCOPED_TRACE(fmt::format("flag: {}", flag));
1260         ScopedSystemProperties sp1(kDohSessionResumptionFlag, flag);
1261         ScopedSystemProperties sp2(kDohEarlyDataFlag, flag);
1262         resetNetwork();
1263 
1264         ASSERT_TRUE(doh.stopServer());
1265         EXPECT_TRUE(doh.setMaxIdleTimeout(initial_max_idle_timeout_ms));
1266         ASSERT_TRUE(doh.startServer());
1267 
1268         const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1269         ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1270         EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1271         EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1272         EXPECT_TRUE(dot.waitForQueries(1));
1273         dot.clearQueries();
1274         doh.clearQueries();
1275         dns.clearQueries();
1276 
1277         // Wait for the connection closed, and then send a DNS query.
1278         // Expect the query to be sent in early data if the flag is on.
1279         sleep_for(milliseconds(initial_max_idle_timeout_ms + 500));
1280         int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa,
1281                                  ANDROID_RESOLV_NO_CACHE_LOOKUP);
1282         expectAnswersValid(fd, AF_INET6, kQueryAnswerAAAA);
1283         EXPECT_EQ(doh.earlyDataConnections(), (strcmp(flag, "1") ? 0 : 1));
1284     }
1285 }
1286 
1287 // Tests that after the connection is closed by the server (known by sending CONNECTION_CLOSE
1288 // frame), the DnsResolver can initiate another new connection for DNS requests.
TEST_F(PrivateDnsDohTest,RemoteConnectionClosed)1289 TEST_F(PrivateDnsDohTest, RemoteConnectionClosed) {
1290     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1291     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1292     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1293     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1294     EXPECT_TRUE(dot.waitForQueries(1));
1295     dot.clearQueries();
1296     doh.clearQueries();
1297     dns.clearQueries();
1298 
1299     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
1300     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
1301     flushCache();
1302     EXPECT_EQ(doh.connections(), 1);
1303 
1304     // Make the server close the connection. This will also reset the stats, so the doh query
1305     // count below is still 2 rather than 4.
1306     ASSERT_TRUE(doh.stopServer());
1307     ASSERT_TRUE(doh.startServer());
1308 
1309     EXPECT_NO_FAILURE(sendQueryAndCheckResult());
1310     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */));
1311     EXPECT_EQ(doh.connections(), 1);
1312 }
1313 
1314 // Tests that a DNS query can quickly fall back from DoH to other dns protocols if server responds
1315 // the DNS query with RESET_STREAM, and that it doesn't influence subsequent DoH queries.
TEST_F(PrivateDnsDohTest,ReceiveResetStream)1316 TEST_F(PrivateDnsDohTest, ReceiveResetStream) {
1317     const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
1318     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
1319     EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr));
1320     EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr));
1321     EXPECT_TRUE(dot.waitForQueries(1));
1322     dot.clearQueries();
1323     doh.clearQueries();
1324     dns.clearQueries();
1325 
1326     // DnsResolver uses bidirectional streams for DoH queries (See
1327     // RFC9000#name-stream-types-and-identifier), and stream 0 has been used for DoH probe, so
1328     // the next stream for the next DoH query will be 4.
1329     EXPECT_TRUE(doh.setResetStreamId(4));
1330 
1331     // Send a DNS request. The DoH query will be sent on stream 4 and fail.
1332     Stopwatch s;
1333     int fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa,
1334                              ANDROID_RESOLV_NO_CACHE_LOOKUP);
1335     expectAnswersValid(fd, AF_INET6, kQueryAnswerAAAA);
1336     EXPECT_LT(s.timeTakenUs() / 1000, 500);
1337     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 1 /* dot */, 1 /* doh */));
1338 
1339     // Send another DNS request. The DoH query will be sent on stream 8 and succeed.
1340     fd = resNetworkQuery(TEST_NETID, kQueryHostname, ns_c_in, ns_t_aaaa,
1341                          ANDROID_RESOLV_NO_CACHE_LOOKUP);
1342     expectAnswersValid(fd, AF_INET6, kQueryAnswerAAAA);
1343     EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 1 /* dot */, 2 /* doh */));
1344 }
1345 
1346 // Tests that, given an IP address with an allowed DoH provider name, PrivateDnsConfiguration
1347 // attempts to probe the server for DoH.
1348 // This test is representative of DoH using DDR in opportunistic mode.
TEST_F(PrivateDnsDohTest,UseDohAsLongAsHostnameMatch)1349 TEST_F(PrivateDnsDohTest, UseDohAsLongAsHostnameMatch) {
1350     // "example.com" is an allowed DoH provider name defined in
1351     // PrivateDnsConfiguration::mAvailableDoHProviders.
1352     constexpr char allowedDohName[] = "example.com";
1353     constexpr char someOtherIp[] = "127.99.99.99";
1354 
1355     // The test currently doesn't support testing DoH in private DNS strict mode, so DnsResolver
1356     // can't connect to the testing DoH servers. We use onPrivateDnsValidationEvent() to check
1357     // whether DoT/DoH probes are performed.
1358     // Without an allowed private DNS provider hostname, expect PrivateDnsConfiguration to probe
1359     // the server for DoT only.
1360     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(
1361             ResolverParams::Builder().setDotServers({someOtherIp}).build()));
1362     EXPECT_TRUE(WaitForDotValidationFailure(someOtherIp));
1363     EXPECT_FALSE(hasUncaughtPrivateDnsValidation(someOtherIp));
1364 
1365     // With an allowed private DNS provider hostname, expect PrivateDnsConfiguration to probe the
1366     // server for both DoT and DoH.
1367     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(ResolverParams::Builder()
1368                                                           .setDotServers({someOtherIp})
1369                                                           .setPrivateDnsProvider(allowedDohName)
1370                                                           .build()));
1371     EXPECT_TRUE(WaitForDotValidationFailure(someOtherIp));
1372     EXPECT_TRUE(WaitForDohValidationFailure(someOtherIp));
1373 
1374     // Disable DoT and DoH. This ensures that when DoT is re-enabled right afterwards, the test
1375     // observes a validation failure.
1376     ASSERT_TRUE(
1377             mDnsClient.SetResolversFromParcel(ResolverParams::Builder().setDotServers({}).build()));
1378 
1379     // If DDR is enabled and reports no results (empty DoH params), don't probe for DoH.
1380     DohParamsParcel emptyDohParams = {};
1381     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(ResolverParams::Builder()
1382                                                           .setDotServers({someOtherIp})
1383                                                           .setPrivateDnsProvider(allowedDohName)
1384                                                           .setDohParams(emptyDohParams)
1385                                                           .build()));
1386     EXPECT_TRUE(WaitForDotValidationFailure(someOtherIp));
1387     EXPECT_FALSE(WaitForDohValidationFailure(someOtherIp));
1388 
1389     EXPECT_FALSE(hasUncaughtPrivateDnsValidation(someOtherIp));
1390 }
1391 
1392 // Tests that if DDR is enabled, but returns no parameters, that DoH is not enabled.
TEST_F(PrivateDnsDohTest,DdrEnabledButNoResponse)1393 TEST_F(PrivateDnsDohTest, DdrEnabledButNoResponse) {
1394     // "example.com" is an allowed DoH provider name defined in
1395     // PrivateDnsConfiguration::mAvailableDoHProviders.
1396     constexpr char allowedDohName[] = "example.com";
1397     constexpr char someOtherIp[] = "127.99.99.99";
1398 
1399     // If DDR is enabled and reports no results (empty DoH params), don't probe for DoH.
1400     DohParamsParcel emptyDohParams = {};
1401     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(ResolverParams::Builder()
1402                                                           .setDotServers({someOtherIp})
1403                                                           .setPrivateDnsProvider(allowedDohName)
1404                                                           .setDohParams(emptyDohParams)
1405                                                           .build()));
1406     EXPECT_TRUE(WaitForDotValidationFailure(someOtherIp));
1407     EXPECT_FALSE(WaitForDohValidationFailure(someOtherIp));
1408 
1409     EXPECT_FALSE(hasUncaughtPrivateDnsValidation(someOtherIp));
1410 }
1411 // Tests DoH with a hostname.
1412 // This test is representative of DoH using DDR in strict mode.
TEST_F(PrivateDnsDohTest,DohParamsParcel)1413 TEST_F(PrivateDnsDohTest, DohParamsParcel) {
1414     // Because the test doesn't support serving DoH in strict mode, it cannot check for actual DoH
1415     // queries, it can only check for validation attempts.
1416     constexpr char name[] = "example.com";
1417     constexpr char dohIp[] = "127.99.99.99";
1418     DohParamsParcel dohParams = {
1419             .name = name,
1420             .ips = {dohIp},
1421             .dohpath = "/dns-query{?dns}",
1422             .port = 443,
1423     };
1424 
1425     // Only DoH enabled.
1426     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(
1427             ResolverParams::Builder().setDohParams(dohParams).build()));
1428     EXPECT_FALSE(WaitForDotValidationFailure(dohIp));
1429     EXPECT_TRUE(WaitForDohValidationFailure(dohIp));
1430 
1431     // Both DoT and DoH enabled.
1432     constexpr char dotIp[] = "127.88.88.88";
1433     ASSERT_TRUE(mDnsClient.SetResolversFromParcel(ResolverParams::Builder()
1434                                                           .setPrivateDnsProvider(name)
1435                                                           .setDotServers({dotIp})
1436                                                           .setDohParams(dohParams)
1437                                                           .build()));
1438     EXPECT_TRUE(WaitForDotValidationFailure(dotIp));
1439     EXPECT_TRUE(WaitForDohValidationFailure(dohIp));
1440 
1441     EXPECT_FALSE(hasUncaughtPrivateDnsValidation(dohIp));
1442     EXPECT_FALSE(hasUncaughtPrivateDnsValidation(dotIp));
1443 }
1444