Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03e4903f authored by Mike Yu's avatar Mike Yu
Browse files

Report private DNS protocols in onPrivateDnsValidationEvent

PrivateDnsDohTest.QueryFailover fails in waiting for the second
onPrivateDnsValidationEvent if DoT validation result and DoH
validation result are reported at the same time.

To fix the flaky test, this change makes the validation results
distinguishable by private DNS protocols.

Bug: 198111329
Test: PrivateDnsDohTest.QueryFailover 200 times passed on cuttlefish
Test: PrivateDnsDohTest.ValidationFail 500 times passed on cuttlefish
Change-Id: I8649b21bff176c6f2a1158f04812c8c8e96ad7d9
parent f34e87cd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ cc_library_headers {
    ],
}

dnsresolver_aidl_interface_lateststable_version = "V9"
dnsresolver_aidl_interface_lateststable_version = "V10"

cc_library_static {
    name: "dnsresolver_aidl_interface-lateststable-ndk",
+3 −0
Original line number Diff line number Diff line
@@ -252,6 +252,9 @@ void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const ServerIdentity
            .hostname = identity.provider,
            .validation = success ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS
                                  : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE,
            .protocol = (identity.sockaddr.port() == 853)
                                ? IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT
                                : IDnsResolverUnsolicitedEventListener::PROTOCOL_DOH,
    };
    for (const auto& it : unsolEventListeners) {
        it->onPrivateDnsValidationEvent(validationEvent);
+4 −2
Original line number Diff line number Diff line
@@ -262,12 +262,14 @@ class ResolverTest : public ::testing::Test {
               sUnsolicitedEventListener->waitForPrivateDnsValidation(
                       serverAddr,
                       validated ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS
                                 : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE);
                                 : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE,
                       IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT);
    }

    bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) {
        return sDnsMetricsListener->findValidationRecord(serverAddr) &&
               sUnsolicitedEventListener->findValidationRecord(serverAddr);
               sUnsolicitedEventListener->findValidationRecord(
                       serverAddr, IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT);
    }

    void ExpectDnsEvent(int32_t eventType, int32_t returnCode, const std::string& hostname,
+35 −16
Original line number Diff line number Diff line
@@ -113,16 +113,30 @@ class BaseTest : public ::testing::Test {

    void flushCache() { mDnsClient.resolvService()->flushNetworkCache(TEST_NETID); }

    bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) {
    bool WaitForDotValidation(std::string serverAddr, bool validated) {
        return WaitForPrivateDnsValidation(serverAddr, validated,
                                           IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT);
    }

    bool WaitForDohValidation(std::string serverAddr, bool validated) {
        return WaitForPrivateDnsValidation(serverAddr, validated,
                                           IDnsResolverUnsolicitedEventListener::PROTOCOL_DOH);
    }

    bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated, int protocol) {
        return sUnsolicitedEventListener->waitForPrivateDnsValidation(
                serverAddr,
                validated ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS
                          : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE);
                          : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE,
                protocol);
    }

    bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) {
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        return sUnsolicitedEventListener->findValidationRecord(serverAddr);
        return sUnsolicitedEventListener->findValidationRecord(
                       serverAddr, IDnsResolverUnsolicitedEventListener::PROTOCOL_DOT) ||
               sUnsolicitedEventListener->findValidationRecord(
                       serverAddr, IDnsResolverUnsolicitedEventListener::PROTOCOL_DOH);
    }

    DnsResponderClient mDnsClient;
@@ -263,9 +277,8 @@ TEST_P(TransportParameterizedTest, GetAddrInfo) {
    const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));

    // TODO: check that the validation is for DoT or for DoH.
    if (testParamHasDoh()) EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, true));
    if (testParamHasDot()) EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, true));
    if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidation(test::kDefaultListenAddr, true));
    if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidation(test::kDefaultListenAddr, true));

    // This waiting time is expected to avoid that the DoH validation event interferes other tests.
    if (!testParamHasDoh()) waitForDohValidationFailed();
@@ -333,8 +346,8 @@ TEST_F(PrivateDnsDohTest, ValidationFail) {
    Stopwatch s;
    const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, false));
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, false));
    EXPECT_TRUE(WaitForDohValidation(test::kDefaultListenAddr, false));
    EXPECT_TRUE(WaitForDotValidation(test::kDefaultListenAddr, false));
    EXPECT_LT(s.getTimeAndResetUs(),
              microseconds(kExpectedDohValidationTimeWhenServerUnreachable + TIMING_TOLERANCE)
                      .count());
@@ -346,8 +359,8 @@ TEST_F(PrivateDnsDohTest, ValidationFail) {

    s.getTimeAndResetUs();
    ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, false));
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, false));
    EXPECT_TRUE(WaitForDohValidation(test::kDefaultListenAddr, false));
    EXPECT_TRUE(WaitForDotValidation(test::kDefaultListenAddr, false));
    EXPECT_LT(s.getTimeAndResetUs(),
              microseconds(kExpectedDohValidationTimeWhenTimeout + TIMING_TOLERANCE).count());

@@ -361,8 +374,8 @@ TEST_F(PrivateDnsDohTest, ValidationFail) {
TEST_F(PrivateDnsDohTest, QueryFailover) {
    const auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel();
    ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, true));
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, true));
    EXPECT_TRUE(WaitForDohValidation(test::kDefaultListenAddr, true));
    EXPECT_TRUE(WaitForDotValidation(test::kDefaultListenAddr, true));
    EXPECT_TRUE(dot.waitForQueries(1));
    dot.clearQueries();
    dns.clearQueries();
@@ -379,17 +392,23 @@ TEST_F(PrivateDnsDohTest, QueryFailover) {
    resetNetwork();
    ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel));

    // This event comes from DoT validation.
    EXPECT_TRUE(WaitForPrivateDnsValidation(test::kDefaultListenAddr, true));
    EXPECT_TRUE(WaitForDotValidation(test::kDefaultListenAddr, true));
    EXPECT_TRUE(dot.waitForQueries(1));
    dot.clearQueries();
    dns.clearQueries();

    // Expect that the query fall back to DoT.
    // Expect that the query fall back to DoT as DoH validation is in progress.
    EXPECT_NO_FAILURE(sendQueryAndCheckResult());

    EXPECT_EQ(dot.queries(), 2);
    EXPECT_EQ(dns.queries().size(), 0U);
    waitForDohValidationTimeout();
    flushCache();

    // Expect that this query fall back to DoT as DoH validation has failed.
    EXPECT_NO_FAILURE(sendQueryAndCheckResult());
    EXPECT_EQ(dot.queries(), 4);
    EXPECT_EQ(dns.queries().size(), 0U);
}

// Tests that the DnsResolver prioritizes IPv6 DoH servers over IPv4 DoH servers.
@@ -420,7 +439,7 @@ TEST_F(PrivateDnsDohTest, PreferIpv6) {

        // Currently, DnsResolver sorts the server list and did DoH validation only
        // for the first server.
        EXPECT_TRUE(WaitForPrivateDnsValidation(listen_ipv6_addr, true));
        EXPECT_TRUE(WaitForDohValidation(listen_ipv6_addr, true));

        doh.clearQueries();
        doh_ipv6.clearQueries();
+4 −3
Original line number Diff line number Diff line
@@ -59,14 +59,15 @@ constexpr milliseconds kRetryIntervalMs{20};
    {
        std::lock_guard lock(mMutex);
        // keep updating the server to have latest validation status.
        mValidationRecords.insert_or_assign({event.netId, event.ipAddress}, event.validation);
        mValidationRecords.insert_or_assign({event.netId, event.ipAddress, event.protocol},
                                            event.validation);
    }
    mCv.notify_one();
    return ::ndk::ScopedAStatus::ok();
}

bool UnsolicitedEventListener::waitForPrivateDnsValidation(const std::string& serverAddr,
                                                           int validation) {
                                                           int validation, int protocol) {
    const auto now = std::chrono::steady_clock::now();

    std::unique_lock lock(mMutex);
@@ -74,7 +75,7 @@ bool UnsolicitedEventListener::waitForPrivateDnsValidation(const std::string& se

    // onPrivateDnsValidationEvent() might already be invoked. Search for the record first.
    do {
        if (findAndRemoveValidationRecord({mNetId, serverAddr}, validation)) return true;
        if (findAndRemoveValidationRecord({mNetId, serverAddr, protocol}, validation)) return true;
    } while (mCv.wait_until(lock, now + kEventTimeoutMs) != std::cv_status::timeout);

    // Timeout.
Loading