Loading PrivateDnsConfiguration.cpp +33 −13 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,8 @@ #include "netdutils/BackoffSequence.h" #include "netdutils/BackoffSequence.h" #include "util.h" #include "util.h" using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel; using android::base::StringPrintf; using android::base::StringPrintf; using android::netdutils::setThreadName; using android::netdutils::setThreadName; using std::chrono::milliseconds; using std::chrono::milliseconds; Loading Loading @@ -222,6 +224,35 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign validate_thread.detach(); validate_thread.detach(); } } void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& server, unsigned netId, bool success) { LOG(DEBUG) << "Sending validation " << (success ? "success" : "failure") << " event on netId " << netId << " for " << server.toIpString() << " with hostname {" << server.name << "}"; // Send a validation event to NetdEventListenerService. const auto& listeners = ResolverEventReporter::getInstance().getListeners(); if (listeners.empty()) { LOG(ERROR) << "Validation event not sent since no INetdEventListener receiver is available."; } for (const auto& it : listeners) { it->onPrivateDnsValidationEvent(netId, server.toIpString(), server.name, success); } // Send a validation event to unsolicited event listeners. const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners(); const PrivateDnsValidationEventParcel validationEvent = { .netId = static_cast<int32_t>(netId), .ipAddress = server.toIpString(), .hostname = server.name, .validation = success ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE, }; for (const auto& it : unsolEventListeners) { it->onPrivateDnsValidationEvent(validationEvent); } } bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) { bool success) { constexpr bool NEEDS_REEVALUATION = true; constexpr bool NEEDS_REEVALUATION = true; Loading Loading @@ -268,19 +299,8 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser reevaluationStatus = DONT_REEVALUATE; reevaluationStatus = DONT_REEVALUATE; } } // Send a validation event to NetdEventListenerService. // Send private dns validation result to listeners. const auto& listeners = ResolverEventReporter::getInstance().getListeners(); sendPrivateDnsValidationEvent(server, netId, success); if (listeners.size() != 0) { for (const auto& it : listeners) { it->onPrivateDnsValidationEvent(netId, server.toIpString(), server.name, success); } LOG(DEBUG) << "Sent validation " << (success ? "success" : "failure") << " event on netId " << netId << " for " << server.toIpString() << " with hostname {" << server.name << "}"; } else { LOG(ERROR) << "Validation event not sent since no INetdEventListener receiver is available."; } if (success) { if (success) { updateServerState(identity, Validation::success, netId); updateServerState(identity, Validation::success, netId); Loading PrivateDnsConfiguration.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -103,6 +103,9 @@ class PrivateDnsConfiguration { bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) EXCLUDES(mPrivateDnsLock); EXCLUDES(mPrivateDnsLock); void sendPrivateDnsValidationEvent(const DnsTlsServer& server, unsigned netId, bool success) REQUIRES(mPrivateDnsLock); // Decide if a validation for |server| is needed. Note that servers that have failed // Decide if a validation for |server| is needed. Note that servers that have failed // multiple validation attempts but for which there is still a validating // multiple validation attempts but for which there is still a validating // thread running are marked as being Validation::in_process. // thread running are marked as being Validation::in_process. Loading tests/dnsresolver_binder_test.cpp +5 −5 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,7 @@ using android::base::StringPrintf; using android::base::unique_fd; using android::base::unique_fd; using android::net::ResolverStats; using android::net::ResolverStats; using android::net::metrics::TestOnDnsEvent; using android::net::metrics::TestOnDnsEvent; using android::net::resolv::aidl::UnsolicitedEventListener; using android::netdutils::Stopwatch; using android::netdutils::Stopwatch; // TODO: make this dynamic and stop depending on implementation details. // TODO: make this dynamic and stop depending on implementation details. Loading Loading @@ -302,17 +303,16 @@ TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_NullListener) { } } TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_DuplicateSubscription) { TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_DuplicateSubscription) { class FakeListener : public android::net::resolv::aidl::UnsolicitedEventListener {}; // Expect to subscribe successfully. // Expect to subscribe successfully. std::shared_ptr<FakeListener> fakeListener = ndk::SharedRefBase::make<FakeListener>(); std::shared_ptr<UnsolicitedEventListener> listener = ::ndk::ScopedAStatus status = mDnsResolver->registerUnsolicitedEventListener(fakeListener); ndk::SharedRefBase::make<UnsolicitedEventListener>(TEST_NETID); ::ndk::ScopedAStatus status = mDnsResolver->registerUnsolicitedEventListener(listener); ASSERT_TRUE(status.isOk()) << status.getMessage(); ASSERT_TRUE(status.isOk()) << status.getMessage(); mExpectedLogData.push_back( mExpectedLogData.push_back( {"registerUnsolicitedEventListener()", "registerUnsolicitedEventListener.*"}); {"registerUnsolicitedEventListener()", "registerUnsolicitedEventListener.*"}); // Expect to subscribe failed with registered listener instance. // Expect to subscribe failed with registered listener instance. status = mDnsResolver->registerUnsolicitedEventListener(fakeListener); status = mDnsResolver->registerUnsolicitedEventListener(listener); ASSERT_FALSE(status.isOk()); ASSERT_FALSE(status.isOk()); ASSERT_EQ(EEXIST, status.getServiceSpecificError()); ASSERT_EQ(EEXIST, status.getServiceSpecificError()); mExpectedLogData.push_back( mExpectedLogData.push_back( Loading tests/resolv_integration_test.cpp +21 −2 Original line number Original line Diff line number Diff line Loading @@ -71,6 +71,7 @@ #include "tests/dns_responder/dns_tls_frontend.h" #include "tests/dns_responder/dns_tls_frontend.h" #include "tests/resolv_test_utils.h" #include "tests/resolv_test_utils.h" #include "tests/tun_forwarder.h" #include "tests/tun_forwarder.h" #include "tests/unsolicited_listener/unsolicited_event_listener.h" // Valid VPN netId range is 100 ~ 65535 // Valid VPN netId range is 100 ~ 65535 constexpr int TEST_VPN_NETID = 65502; constexpr int TEST_VPN_NETID = 65502; Loading @@ -94,6 +95,8 @@ using aidl::android::net::IDnsResolver; using aidl::android::net::INetd; using aidl::android::net::INetd; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel; using android::base::Error; using android::base::Error; using android::base::ParseInt; using android::base::ParseInt; using android::base::Result; using android::base::Result; Loading @@ -102,6 +105,7 @@ using android::base::unique_fd; using android::net::ResolverStats; using android::net::ResolverStats; using android::net::TunForwarder; using android::net::TunForwarder; using android::net::metrics::DnsMetricsListener; using android::net::metrics::DnsMetricsListener; using android::net::resolv::aidl::UnsolicitedEventListener; using android::netdutils::enableSockopt; using android::netdutils::enableSockopt; using android::netdutils::makeSlice; using android::netdutils::makeSlice; using android::netdutils::ResponseCode; using android::netdutils::ResponseCode; Loading Loading @@ -204,6 +208,12 @@ class ResolverTest : public ::testing::Test { TEST_NETID /*monitor specific network*/); TEST_NETID /*monitor specific network*/); ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk()); ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk()); // Subscribe the unsolicited event listener for verifying unsolicited event contents. sUnsolicitedEventListener = ndk::SharedRefBase::make<UnsolicitedEventListener>( TEST_NETID /*monitor specific network*/); ASSERT_TRUE( resolvService->registerUnsolicitedEventListener(sUnsolicitedEventListener).isOk()); // Start the binder thread pool for listening DNS metrics events and receiving death // Start the binder thread pool for listening DNS metrics events and receiving death // recipient. // recipient. ABinderProcess_startThreadPool(); ABinderProcess_startThreadPool(); Loading @@ -214,6 +224,7 @@ class ResolverTest : public ::testing::Test { void SetUp() { void SetUp() { mDnsClient.SetUp(); mDnsClient.SetUp(); sDnsMetricsListener->reset(); sDnsMetricsListener->reset(); sUnsolicitedEventListener->reset(); } } void TearDown() { void TearDown() { Loading Loading @@ -251,11 +262,16 @@ class ResolverTest : public ::testing::Test { } } bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) { bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) { return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated); return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated) && sUnsolicitedEventListener->waitForPrivateDnsValidation( serverAddr, validated ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE); } } bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) { bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) { return sDnsMetricsListener->findValidationRecord(serverAddr); return sDnsMetricsListener->findValidationRecord(serverAddr) && sUnsolicitedEventListener->findValidationRecord(serverAddr); } } void ExpectDnsEvent(int32_t eventType, int32_t returnCode, const std::string& hostname, void ExpectDnsEvent(int32_t eventType, int32_t returnCode, const std::string& hostname, Loading Loading @@ -367,6 +383,9 @@ class ResolverTest : public ::testing::Test { static std::shared_ptr<DnsMetricsListener> static std::shared_ptr<DnsMetricsListener> sDnsMetricsListener; // Initialized in SetUpTestSuite. sDnsMetricsListener; // Initialized in SetUpTestSuite. inline static std::shared_ptr<UnsolicitedEventListener> sUnsolicitedEventListener; // Initialized in SetUpTestSuite. // Use a shared static death recipient to monitor the service death. The static death // Use a shared static death recipient to monitor the service death. The static death // recipient could monitor the death not only during the test but also between tests. // recipient could monitor the death not only during the test but also between tests. static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestSuite. static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestSuite. Loading tests/unsolicited_listener/unsolicited_event_listener.cpp +46 −5 Original line number Original line Diff line number Diff line Loading @@ -16,24 +16,65 @@ #include "unsolicited_event_listener.h" #include "unsolicited_event_listener.h" #include <thread> #include <android-base/chrono_utils.h> #include <android-base/format.h> namespace android::net::resolv::aidl { namespace android::net::resolv::aidl { using ::aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel; using android::base::ScopedLockAssertion; using std::chrono::milliseconds; constexpr milliseconds kEventTimeoutMs{5000}; ::ndk::ScopedAStatus UnsolicitedEventListener::onDnsHealthEvent( ::ndk::ScopedAStatus UnsolicitedEventListener::onDnsHealthEvent( const ::aidl::android::net::resolv::aidl::DnsHealthEventParcel&) { const ::aidl::android::net::resolv::aidl::DnsHealthEventParcel&) { // default no-op // default no-op return ::ndk::ScopedAStatus::ok(); return ::ndk::ScopedAStatus::ok(); }; } ::ndk::ScopedAStatus UnsolicitedEventListener::onNat64PrefixEvent( ::ndk::ScopedAStatus UnsolicitedEventListener::onNat64PrefixEvent( const ::aidl::android::net::resolv::aidl::Nat64PrefixEventParcel&) { const ::aidl::android::net::resolv::aidl::Nat64PrefixEventParcel&) { // default no-op // default no-op return ::ndk::ScopedAStatus::ok(); return ::ndk::ScopedAStatus::ok(); }; } ::ndk::ScopedAStatus UnsolicitedEventListener::onPrivateDnsValidationEvent( ::ndk::ScopedAStatus UnsolicitedEventListener::onPrivateDnsValidationEvent( const ::aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel&) { const PrivateDnsValidationEventParcel& event) { // default no-op { std::lock_guard lock(mMutex); // keep updating the server to have latest validation status. mValidationRecords.insert_or_assign({event.netId, event.ipAddress}, event.validation); } mCv.notify_one(); return ::ndk::ScopedAStatus::ok(); return ::ndk::ScopedAStatus::ok(); }; } bool UnsolicitedEventListener::waitForPrivateDnsValidation(const std::string& serverAddr, int validation) { const auto now = std::chrono::steady_clock::now(); std::unique_lock lock(mMutex); ScopedLockAssertion assume_lock(mMutex); // onPrivateDnsValidationEvent() might already be invoked. Search for the record first. do { if (findAndRemoveValidationRecord({mNetId, serverAddr}, validation)) return true; } while (mCv.wait_until(lock, now + kEventTimeoutMs) != std::cv_status::timeout); // Timeout. return false; } bool UnsolicitedEventListener::findAndRemoveValidationRecord(const ServerKey& key, int value) { auto it = mValidationRecords.find(key); if (it != mValidationRecords.end() && it->second == value) { mValidationRecords.erase(it); return true; } return false; } } // namespace android::net::resolv::aidl } // namespace android::net::resolv::aidl Loading
PrivateDnsConfiguration.cpp +33 −13 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,8 @@ #include "netdutils/BackoffSequence.h" #include "netdutils/BackoffSequence.h" #include "util.h" #include "util.h" using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel; using android::base::StringPrintf; using android::base::StringPrintf; using android::netdutils::setThreadName; using android::netdutils::setThreadName; using std::chrono::milliseconds; using std::chrono::milliseconds; Loading Loading @@ -222,6 +224,35 @@ void PrivateDnsConfiguration::startValidation(const DnsTlsServer& server, unsign validate_thread.detach(); validate_thread.detach(); } } void PrivateDnsConfiguration::sendPrivateDnsValidationEvent(const DnsTlsServer& server, unsigned netId, bool success) { LOG(DEBUG) << "Sending validation " << (success ? "success" : "failure") << " event on netId " << netId << " for " << server.toIpString() << " with hostname {" << server.name << "}"; // Send a validation event to NetdEventListenerService. const auto& listeners = ResolverEventReporter::getInstance().getListeners(); if (listeners.empty()) { LOG(ERROR) << "Validation event not sent since no INetdEventListener receiver is available."; } for (const auto& it : listeners) { it->onPrivateDnsValidationEvent(netId, server.toIpString(), server.name, success); } // Send a validation event to unsolicited event listeners. const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners(); const PrivateDnsValidationEventParcel validationEvent = { .netId = static_cast<int32_t>(netId), .ipAddress = server.toIpString(), .hostname = server.name, .validation = success ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE, }; for (const auto& it : unsolEventListeners) { it->onPrivateDnsValidationEvent(validationEvent); } } bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) { bool success) { constexpr bool NEEDS_REEVALUATION = true; constexpr bool NEEDS_REEVALUATION = true; Loading Loading @@ -268,19 +299,8 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser reevaluationStatus = DONT_REEVALUATE; reevaluationStatus = DONT_REEVALUATE; } } // Send a validation event to NetdEventListenerService. // Send private dns validation result to listeners. const auto& listeners = ResolverEventReporter::getInstance().getListeners(); sendPrivateDnsValidationEvent(server, netId, success); if (listeners.size() != 0) { for (const auto& it : listeners) { it->onPrivateDnsValidationEvent(netId, server.toIpString(), server.name, success); } LOG(DEBUG) << "Sent validation " << (success ? "success" : "failure") << " event on netId " << netId << " for " << server.toIpString() << " with hostname {" << server.name << "}"; } else { LOG(ERROR) << "Validation event not sent since no INetdEventListener receiver is available."; } if (success) { if (success) { updateServerState(identity, Validation::success, netId); updateServerState(identity, Validation::success, netId); Loading
PrivateDnsConfiguration.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -103,6 +103,9 @@ class PrivateDnsConfiguration { bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) bool recordPrivateDnsValidation(const DnsTlsServer& server, unsigned netId, bool success) EXCLUDES(mPrivateDnsLock); EXCLUDES(mPrivateDnsLock); void sendPrivateDnsValidationEvent(const DnsTlsServer& server, unsigned netId, bool success) REQUIRES(mPrivateDnsLock); // Decide if a validation for |server| is needed. Note that servers that have failed // Decide if a validation for |server| is needed. Note that servers that have failed // multiple validation attempts but for which there is still a validating // multiple validation attempts but for which there is still a validating // thread running are marked as being Validation::in_process. // thread running are marked as being Validation::in_process. Loading
tests/dnsresolver_binder_test.cpp +5 −5 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,7 @@ using android::base::StringPrintf; using android::base::unique_fd; using android::base::unique_fd; using android::net::ResolverStats; using android::net::ResolverStats; using android::net::metrics::TestOnDnsEvent; using android::net::metrics::TestOnDnsEvent; using android::net::resolv::aidl::UnsolicitedEventListener; using android::netdutils::Stopwatch; using android::netdutils::Stopwatch; // TODO: make this dynamic and stop depending on implementation details. // TODO: make this dynamic and stop depending on implementation details. Loading Loading @@ -302,17 +303,16 @@ TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_NullListener) { } } TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_DuplicateSubscription) { TEST_F(DnsResolverBinderTest, RegisterUnsolicitedEventListener_DuplicateSubscription) { class FakeListener : public android::net::resolv::aidl::UnsolicitedEventListener {}; // Expect to subscribe successfully. // Expect to subscribe successfully. std::shared_ptr<FakeListener> fakeListener = ndk::SharedRefBase::make<FakeListener>(); std::shared_ptr<UnsolicitedEventListener> listener = ::ndk::ScopedAStatus status = mDnsResolver->registerUnsolicitedEventListener(fakeListener); ndk::SharedRefBase::make<UnsolicitedEventListener>(TEST_NETID); ::ndk::ScopedAStatus status = mDnsResolver->registerUnsolicitedEventListener(listener); ASSERT_TRUE(status.isOk()) << status.getMessage(); ASSERT_TRUE(status.isOk()) << status.getMessage(); mExpectedLogData.push_back( mExpectedLogData.push_back( {"registerUnsolicitedEventListener()", "registerUnsolicitedEventListener.*"}); {"registerUnsolicitedEventListener()", "registerUnsolicitedEventListener.*"}); // Expect to subscribe failed with registered listener instance. // Expect to subscribe failed with registered listener instance. status = mDnsResolver->registerUnsolicitedEventListener(fakeListener); status = mDnsResolver->registerUnsolicitedEventListener(listener); ASSERT_FALSE(status.isOk()); ASSERT_FALSE(status.isOk()); ASSERT_EQ(EEXIST, status.getServiceSpecificError()); ASSERT_EQ(EEXIST, status.getServiceSpecificError()); mExpectedLogData.push_back( mExpectedLogData.push_back( Loading
tests/resolv_integration_test.cpp +21 −2 Original line number Original line Diff line number Diff line Loading @@ -71,6 +71,7 @@ #include "tests/dns_responder/dns_tls_frontend.h" #include "tests/dns_responder/dns_tls_frontend.h" #include "tests/resolv_test_utils.h" #include "tests/resolv_test_utils.h" #include "tests/tun_forwarder.h" #include "tests/tun_forwarder.h" #include "tests/unsolicited_listener/unsolicited_event_listener.h" // Valid VPN netId range is 100 ~ 65535 // Valid VPN netId range is 100 ~ 65535 constexpr int TEST_VPN_NETID = 65502; constexpr int TEST_VPN_NETID = 65502; Loading @@ -94,6 +95,8 @@ using aidl::android::net::IDnsResolver; using aidl::android::net::INetd; using aidl::android::net::INetd; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener; using aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel; using android::base::Error; using android::base::Error; using android::base::ParseInt; using android::base::ParseInt; using android::base::Result; using android::base::Result; Loading @@ -102,6 +105,7 @@ using android::base::unique_fd; using android::net::ResolverStats; using android::net::ResolverStats; using android::net::TunForwarder; using android::net::TunForwarder; using android::net::metrics::DnsMetricsListener; using android::net::metrics::DnsMetricsListener; using android::net::resolv::aidl::UnsolicitedEventListener; using android::netdutils::enableSockopt; using android::netdutils::enableSockopt; using android::netdutils::makeSlice; using android::netdutils::makeSlice; using android::netdutils::ResponseCode; using android::netdutils::ResponseCode; Loading Loading @@ -204,6 +208,12 @@ class ResolverTest : public ::testing::Test { TEST_NETID /*monitor specific network*/); TEST_NETID /*monitor specific network*/); ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk()); ASSERT_TRUE(resolvService->registerEventListener(sDnsMetricsListener).isOk()); // Subscribe the unsolicited event listener for verifying unsolicited event contents. sUnsolicitedEventListener = ndk::SharedRefBase::make<UnsolicitedEventListener>( TEST_NETID /*monitor specific network*/); ASSERT_TRUE( resolvService->registerUnsolicitedEventListener(sUnsolicitedEventListener).isOk()); // Start the binder thread pool for listening DNS metrics events and receiving death // Start the binder thread pool for listening DNS metrics events and receiving death // recipient. // recipient. ABinderProcess_startThreadPool(); ABinderProcess_startThreadPool(); Loading @@ -214,6 +224,7 @@ class ResolverTest : public ::testing::Test { void SetUp() { void SetUp() { mDnsClient.SetUp(); mDnsClient.SetUp(); sDnsMetricsListener->reset(); sDnsMetricsListener->reset(); sUnsolicitedEventListener->reset(); } } void TearDown() { void TearDown() { Loading Loading @@ -251,11 +262,16 @@ class ResolverTest : public ::testing::Test { } } bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) { bool WaitForPrivateDnsValidation(std::string serverAddr, bool validated) { return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated); return sDnsMetricsListener->waitForPrivateDnsValidation(serverAddr, validated) && sUnsolicitedEventListener->waitForPrivateDnsValidation( serverAddr, validated ? IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_SUCCESS : IDnsResolverUnsolicitedEventListener::VALIDATION_RESULT_FAILURE); } } bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) { bool hasUncaughtPrivateDnsValidation(const std::string& serverAddr) { return sDnsMetricsListener->findValidationRecord(serverAddr); return sDnsMetricsListener->findValidationRecord(serverAddr) && sUnsolicitedEventListener->findValidationRecord(serverAddr); } } void ExpectDnsEvent(int32_t eventType, int32_t returnCode, const std::string& hostname, void ExpectDnsEvent(int32_t eventType, int32_t returnCode, const std::string& hostname, Loading Loading @@ -367,6 +383,9 @@ class ResolverTest : public ::testing::Test { static std::shared_ptr<DnsMetricsListener> static std::shared_ptr<DnsMetricsListener> sDnsMetricsListener; // Initialized in SetUpTestSuite. sDnsMetricsListener; // Initialized in SetUpTestSuite. inline static std::shared_ptr<UnsolicitedEventListener> sUnsolicitedEventListener; // Initialized in SetUpTestSuite. // Use a shared static death recipient to monitor the service death. The static death // Use a shared static death recipient to monitor the service death. The static death // recipient could monitor the death not only during the test but also between tests. // recipient could monitor the death not only during the test but also between tests. static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestSuite. static AIBinder_DeathRecipient* sResolvDeathRecipient; // Initialized in SetUpTestSuite. Loading
tests/unsolicited_listener/unsolicited_event_listener.cpp +46 −5 Original line number Original line Diff line number Diff line Loading @@ -16,24 +16,65 @@ #include "unsolicited_event_listener.h" #include "unsolicited_event_listener.h" #include <thread> #include <android-base/chrono_utils.h> #include <android-base/format.h> namespace android::net::resolv::aidl { namespace android::net::resolv::aidl { using ::aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel; using android::base::ScopedLockAssertion; using std::chrono::milliseconds; constexpr milliseconds kEventTimeoutMs{5000}; ::ndk::ScopedAStatus UnsolicitedEventListener::onDnsHealthEvent( ::ndk::ScopedAStatus UnsolicitedEventListener::onDnsHealthEvent( const ::aidl::android::net::resolv::aidl::DnsHealthEventParcel&) { const ::aidl::android::net::resolv::aidl::DnsHealthEventParcel&) { // default no-op // default no-op return ::ndk::ScopedAStatus::ok(); return ::ndk::ScopedAStatus::ok(); }; } ::ndk::ScopedAStatus UnsolicitedEventListener::onNat64PrefixEvent( ::ndk::ScopedAStatus UnsolicitedEventListener::onNat64PrefixEvent( const ::aidl::android::net::resolv::aidl::Nat64PrefixEventParcel&) { const ::aidl::android::net::resolv::aidl::Nat64PrefixEventParcel&) { // default no-op // default no-op return ::ndk::ScopedAStatus::ok(); return ::ndk::ScopedAStatus::ok(); }; } ::ndk::ScopedAStatus UnsolicitedEventListener::onPrivateDnsValidationEvent( ::ndk::ScopedAStatus UnsolicitedEventListener::onPrivateDnsValidationEvent( const ::aidl::android::net::resolv::aidl::PrivateDnsValidationEventParcel&) { const PrivateDnsValidationEventParcel& event) { // default no-op { std::lock_guard lock(mMutex); // keep updating the server to have latest validation status. mValidationRecords.insert_or_assign({event.netId, event.ipAddress}, event.validation); } mCv.notify_one(); return ::ndk::ScopedAStatus::ok(); return ::ndk::ScopedAStatus::ok(); }; } bool UnsolicitedEventListener::waitForPrivateDnsValidation(const std::string& serverAddr, int validation) { const auto now = std::chrono::steady_clock::now(); std::unique_lock lock(mMutex); ScopedLockAssertion assume_lock(mMutex); // onPrivateDnsValidationEvent() might already be invoked. Search for the record first. do { if (findAndRemoveValidationRecord({mNetId, serverAddr}, validation)) return true; } while (mCv.wait_until(lock, now + kEventTimeoutMs) != std::cv_status::timeout); // Timeout. return false; } bool UnsolicitedEventListener::findAndRemoveValidationRecord(const ServerKey& key, int value) { auto it = mValidationRecords.find(key); if (it != mValidationRecords.end() && it->second == value) { mValidationRecords.erase(it); return true; } return false; } } // namespace android::net::resolv::aidl } // namespace android::net::resolv::aidl