diff options
author | Luke Huang <huangluke@google.com> | 2021-08-06 15:35:28 +0800 |
---|---|---|
committer | Luke Huang <huangluke@google.com> | 2021-08-06 14:06:34 +0000 |
commit | a8b0eec0461c195f0c44ab8ede96109b0d628131 (patch) | |
tree | 0150079259980dedfb3c75265c284082d7a19c2b | |
parent | cb206f26574298ffe3df65c4030f2cbbb1cb1d71 (diff) | |
download | DnsResolver-a8b0eec0461c195f0c44ab8ede96109b0d628131.tar.gz |
Implement a new IPC setResolverOptions in DnsResolverandroid-12.0.0_r32android-12.0.0_r29android-12.0.0_r27android-12.0.0_r21android-12.0.0_r20android-12.0.0_r19android-12.0.0_r18android12-qpr1-d-s3-releaseandroid12-qpr1-d-s2-releaseandroid12-qpr1-d-s1-releaseandroid12-qpr1-d-releaseandroid12-dev
1. Implement the new method added in V9, setResolverOptions
2. Add its relevant binder test and update integration test to use this
new method if the remote version is new enough.
Test: atest
Bug: 194048056
Change-Id: I9a18f11769fd154e7cc6f35090e6c8fe61853d2a
Merged-In: I9a18f11769fd154e7cc6f35090e6c8fe61853d2a
-rw-r--r-- | DnsResolverService.cpp | 9 | ||||
-rw-r--r-- | DnsResolverService.h | 2 | ||||
-rw-r--r-- | res_cache.cpp | 42 | ||||
-rw-r--r-- | resolv_cache.h | 3 | ||||
-rw-r--r-- | tests/dnsresolver_binder_test.cpp | 15 | ||||
-rw-r--r-- | tests/resolv_integration_test.cpp | 92 |
6 files changed, 134 insertions, 29 deletions
diff --git a/DnsResolverService.cpp b/DnsResolverService.cpp index 899f7265..7e29a9d4 100644 --- a/DnsResolverService.cpp +++ b/DnsResolverService.cpp @@ -36,6 +36,7 @@ #include "ResolverEventReporter.h" #include "resolv_cache.h" +using aidl::android::net::ResolverOptionsParcel; using aidl::android::net::ResolverParamsParcel; using android::base::Join; using android::base::StringPrintf; @@ -307,5 +308,13 @@ binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t num return statusFromErrcode(res); } +::ndk::ScopedAStatus DnsResolverService::setResolverOptions(int32_t netId, + const ResolverOptionsParcel& options) { + // Locking happens in res_cache.cpp functions. + ENFORCE_NETWORK_STACK_PERMISSIONS(); + + return statusFromErrcode(resolv_set_options(netId, options)); +} + } // namespace net } // namespace android diff --git a/DnsResolverService.h b/DnsResolverService.h index fe39301f..8acd2319 100644 --- a/DnsResolverService.h +++ b/DnsResolverService.h @@ -55,6 +55,8 @@ class DnsResolverService : public aidl::android::net::BnDnsResolver { ::ndk::ScopedAStatus destroyNetworkCache(int32_t netId) override; ::ndk::ScopedAStatus createNetworkCache(int32_t netId) override; ::ndk::ScopedAStatus flushNetworkCache(int32_t netId) override; + ::ndk::ScopedAStatus setResolverOptions( + int32_t netId, const aidl::android::net::ResolverOptionsParcel& options) override; // DNS64-related commands ::ndk::ScopedAStatus startPrefix64Discovery(int32_t netId) override; diff --git a/res_cache.cpp b/res_cache.cpp index a2ede896..768dc779 100644 --- a/res_cache.cpp +++ b/res_cache.cpp @@ -1004,7 +1004,23 @@ struct NetConfig { dns_event_subsampling_map = resolv_get_dns_event_subsampling_map(); } int nameserverCount() { return nameserverSockAddrs.size(); } + int setOptions(const ResolverOptionsParcel& resolverOptions) { + customizedTable.clear(); + for (const auto& host : resolverOptions.hosts) { + if (!host.hostName.empty() && !host.ipAddr.empty()) + customizedTable.emplace(host.hostName, host.ipAddr); + } + if (resolverOptions.tcMode < aidl::android::net::IDnsResolver::TC_MODE_DEFAULT || + resolverOptions.tcMode > aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP) { + LOG(WARNING) << __func__ << ": netid = " << netid + << ", invalid TC mode: " << resolverOptions.tcMode; + return -EINVAL; + } + tc_mode = resolverOptions.tcMode; + enforceDnsUid = resolverOptions.enforceDnsUid; + return 0; + } const unsigned netid; std::unique_ptr<Cache> cache; std::vector<std::string> nameservers; @@ -1655,28 +1671,20 @@ int resolv_set_nameservers(unsigned netid, const std::vector<std::string>& serve LOG(WARNING) << __func__ << ": netid = " << netid << ", failed to set dns stats"; return -EINVAL; } - netconfig->customizedTable.clear(); - + netconfig->transportTypes = transportTypes; if (optionalResolverOptions.has_value()) { const ResolverOptionsParcel& resolverOptions = optionalResolverOptions.value(); - for (const auto& host : resolverOptions.hosts) { - if (!host.hostName.empty() && !host.ipAddr.empty()) - netconfig->customizedTable.emplace(host.hostName, host.ipAddr); - } - - if (resolverOptions.tcMode < aidl::android::net::IDnsResolver::TC_MODE_DEFAULT || - resolverOptions.tcMode > aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP) { - LOG(WARNING) << __func__ << ": netid = " << netid - << ", invalid TC mode: " << resolverOptions.tcMode; - return -EINVAL; - } - netconfig->tc_mode = resolverOptions.tcMode; - netconfig->enforceDnsUid = resolverOptions.enforceDnsUid; + return netconfig->setOptions(resolverOptions); } + return 0; +} - netconfig->transportTypes = transportTypes; +int resolv_set_options(unsigned netid, const ResolverOptionsParcel& options) { + std::lock_guard guard(cache_mutex); + NetConfig* netconfig = find_netconfig_locked(netid); - return 0; + if (netconfig == nullptr) return -ENONET; + return netconfig->setOptions(options); } static bool resolv_is_nameservers_equal(const std::vector<std::string>& oldServers, diff --git a/resolv_cache.h b/resolv_cache.h index 7011e5a4..970459b2 100644 --- a/resolv_cache.h +++ b/resolv_cache.h @@ -82,6 +82,9 @@ int resolv_set_nameservers(unsigned netid, const std::vector<std::string>& serve std::optional<aidl::android::net::ResolverOptionsParcel> resolverOptions, const std::vector<int32_t>& transportTypes = {}); +// Sets options for a given network. +int resolv_set_options(unsigned netid, const aidl::android::net::ResolverOptionsParcel& options); + // Creates the cache associated with the given network. int resolv_create_cache_for_net(unsigned netid); diff --git a/tests/dnsresolver_binder_test.cpp b/tests/dnsresolver_binder_test.cpp index 3f478fa1..55a67e17 100644 --- a/tests/dnsresolver_binder_test.cpp +++ b/tests/dnsresolver_binder_test.cpp @@ -626,3 +626,18 @@ TEST_F(DnsResolverBinderTest, setLogSeverity) { EXPECT_TRUE(mDnsResolver->setLogSeverity(IDnsResolver::DNS_RESOLVER_LOG_WARNING).isOk()); mExpectedLogData.push_back({"setLogSeverity(3)", "setLogSeverity.*3"}); } + +TEST_F(DnsResolverBinderTest, SetResolverOptions) { + SKIP_IF_REMOTE_VERSION_LESS_THAN(mDnsResolver.get(), 9); + ResolverOptionsParcel options; + options.tcMode = 1; + options.enforceDnsUid = true; + EXPECT_TRUE(mDnsResolver->setResolverOptions(TEST_NETID, options).isOk()); + mExpectedLogData.push_back( + {"setResolverOptions(30, " + toString(options) + ")", "setResolverOptions.*30"}); + EXPECT_EQ(ENONET, mDnsResolver->setResolverOptions(-1, options).getServiceSpecificError()); + mExpectedLogData.push_back({"setResolverOptions(-1, " + toString(options) + + ") -> ServiceSpecificException(64, \"Machine is not on the " + "network\")", + "setResolverOptions.*-1.*64"}); +} diff --git a/tests/resolv_integration_test.cpp b/tests/resolv_integration_test.cpp index 6213b6c8..b602d85d 100644 --- a/tests/resolv_integration_test.cpp +++ b/tests/resolv_integration_test.cpp @@ -102,6 +102,7 @@ using namespace std::chrono_literals; using aidl::android::net::IDnsResolver; using aidl::android::net::INetd; +using aidl::android::net::ResolverOptionsParcel; using aidl::android::net::ResolverParamsParcel; using aidl::android::net::metrics::INetdEventListener; using aidl::android::net::resolv::aidl::DnsHealthEventParcel; @@ -237,6 +238,8 @@ class ResolverTest : public ::testing::Test { mDnsClient.SetUp(); sDnsMetricsListener->reset(); sUnsolicitedEventListener->reset(); + mIsResolverOptionIPCSupported = + DnsResponderClient::isRemoteVersionSupported(mDnsClient.resolvService(), 9); } void TearDown() { @@ -404,6 +407,8 @@ class ResolverTest : public ::testing::Test { DnsResponderClient mDnsClient; + bool mIsResolverOptionIPCSupported = false; + // Use a shared static DNS listener for all tests to avoid registering lots of listeners // which may be released late until process terminated. Currently, registered DNS listener // is removed by binder death notification which is fired when the process hosting an @@ -1315,8 +1320,18 @@ TEST_F(ResolverTest, GetAddrInfoFromCustTable_InvalidInput) { test::DNSResponder dns; StartDns(dns, {}); auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); - resolverParams.resolverOptions->hosts = invalidCustHosts; + + ResolverOptionsParcel resolverOptions; + resolverOptions.hosts = invalidCustHosts; + if (!mIsResolverOptionIPCSupported) { + resolverParams.resolverOptions = resolverOptions; + } ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk()); + if (mIsResolverOptionIPCSupported) { + ASSERT_TRUE(mDnsClient.resolvService() + ->setResolverOptions(resolverParams.netId, resolverOptions) + .isOk()); + } for (const auto& hostname : {hostnameNoip, hostnameInvalidip}) { // The query won't get data from customized table because of invalid customized table // and DNSResponder also has no records. hostnameNoip has never registered and @@ -1390,8 +1405,18 @@ TEST_F(ResolverTest, GetAddrInfoFromCustTable) { StartDns(dns, config.dnsserverHosts); auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); - resolverParams.resolverOptions->hosts = config.customizedHosts; + ResolverOptionsParcel resolverOptions; + resolverOptions.hosts = config.customizedHosts; + if (!mIsResolverOptionIPCSupported) { + resolverParams.resolverOptions = resolverOptions; + } ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk()); + + if (mIsResolverOptionIPCSupported) { + ASSERT_TRUE(mDnsClient.resolvService() + ->setResolverOptions(resolverParams.netId, resolverOptions) + .isOk()); + } const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM}; ScopedAddrinfo result = safe_getaddrinfo(config.name.c_str(), nullptr, &hints); if (config.customizedHosts.empty() && config.dnsserverHosts.empty()) { @@ -1426,16 +1451,34 @@ TEST_F(ResolverTest, GetAddrInfoFromCustTable_Modify) { StartDns(dns, dnsSvHostV4V6); auto resolverParams = DnsResponderClient::GetDefaultResolverParamsParcel(); - resolverParams.resolverOptions->hosts = custHostV4V6; + ResolverOptionsParcel resolverOptions; + resolverOptions.hosts = custHostV4V6; + if (!mIsResolverOptionIPCSupported) { + resolverParams.resolverOptions = resolverOptions; + } ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk()); + + if (mIsResolverOptionIPCSupported) { + ASSERT_TRUE(mDnsClient.resolvService() + ->setResolverOptions(resolverParams.netId, resolverOptions) + .isOk()); + } + const addrinfo hints = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM}; ScopedAddrinfo result = safe_getaddrinfo(hostnameV4V6, nullptr, &hints); ASSERT_TRUE(result != nullptr); EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray({custAddrV4, custAddrV6})); EXPECT_EQ(0U, GetNumQueries(dns, hostnameV4V6)); - resolverParams.resolverOptions->hosts = {}; - ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk()); + resolverOptions.hosts = {}; + if (!mIsResolverOptionIPCSupported) { + resolverParams.resolverOptions = resolverOptions; + ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(resolverParams).isOk()); + } else { + ASSERT_TRUE(mDnsClient.resolvService() + ->setResolverOptions(resolverParams.netId, resolverOptions) + .isOk()); + } result = safe_getaddrinfo(hostnameV4V6, nullptr, &hints); ASSERT_TRUE(result != nullptr); EXPECT_THAT(ToStrings(result), testing::UnorderedElementsAreArray({dnsSvAddrV4, dnsSvAddrV6})); @@ -4365,8 +4408,17 @@ TEST_F(ResolverTest, EnforceDnsUid) { } memset(buf, 0, MAXPACKET); - parcel.resolverOptions->enforceDnsUid = true; - ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk()); + ResolverOptionsParcel resolverOptions; + resolverOptions.enforceDnsUid = true; + if (!mIsResolverOptionIPCSupported) { + parcel.resolverOptions = resolverOptions; + ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk()); + } else { + ASSERT_TRUE(mDnsClient.resolvService() + ->setResolverOptions(parcel.netId, resolverOptions) + .isOk()); + } + { ScopeBlockedUIDRule scopeBlockUidRule(netdService, TEST_UID); // Dns Queries should NOT be blocked @@ -5042,8 +5094,8 @@ TEST_F(ResolverTest, TruncatedRspMode) { // clang-format off {std::nullopt, true, 0}, /* mode unset */ {aidl::android::net::IDnsResolver::TC_MODE_DEFAULT, true, 0}, /* default mode */ + {-666, false, 0}, /* invalid input */ {aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP, true, 1}, /* alternative mode */ - {-666, false, 1}, /* invalid input */ // clang-format on }; @@ -5052,10 +5104,21 @@ TEST_F(ResolverTest, TruncatedRspMode) { ResolverParamsParcel parcel = DnsResponderClient::GetDefaultResolverParamsParcel(); parcel.servers = {listen_addr, listen_addr2}; - if (config.tcMode) { - parcel.resolverOptions->tcMode = config.tcMode.value(); + ResolverOptionsParcel resolverOptions; + if (config.tcMode.has_value()) resolverOptions.tcMode = config.tcMode.value(); + if (!mIsResolverOptionIPCSupported) { + parcel.resolverOptions = resolverOptions; + ASSERT_EQ(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk(), + config.ret); + } else { + ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk()); + } + if (mIsResolverOptionIPCSupported) { + ASSERT_EQ(mDnsClient.resolvService() + ->setResolverOptions(parcel.netId, resolverOptions) + .isOk(), + config.ret); } - ASSERT_EQ(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk(), config.ret); const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM}; ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints); @@ -5075,7 +5138,12 @@ TEST_F(ResolverTest, TruncatedRspMode) { // Clear the stats to make the resolver always choose the same server for the first query. parcel.servers.clear(); parcel.tlsServers.clear(); - ASSERT_EQ(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk(), config.ret); + if (!mIsResolverOptionIPCSupported) { + ASSERT_EQ(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk(), + config.ret); + } else { + ASSERT_TRUE(mDnsClient.resolvService()->setResolverConfiguration(parcel).isOk()); + } } } |