diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-09-04 13:01:24 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-09-04 13:01:24 +0000 |
commit | 2d11885c5b9d63df1aa5c0ebc8937a0d0865801c (patch) | |
tree | fa59788028778f30d4c441c9e411141148250fe0 | |
parent | adb1e7c002a2aa5fe1741e2d5c85ee1621f39c70 (diff) | |
parent | 99de1f690b7ecaf09803bf7273facec58cd406f5 (diff) | |
download | DnsResolver-2d11885c5b9d63df1aa5c0ebc8937a0d0865801c.tar.gz |
Snap for 10758424 from 99de1f690b7ecaf09803bf7273facec58cd406f5 to mainline-sdkext-releaseaml_sdk_341110080aml_sdk_341110000
Change-Id: I9b0b034c14a90d278dd4957a14082fa8e81d548a
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | Dns64Configuration.cpp | 17 | ||||
-rw-r--r-- | Dns64Configuration.h | 3 | ||||
-rw-r--r-- | DnsProxyListener.cpp | 9 | ||||
-rw-r--r-- | OperationLimiter.h | 9 | ||||
-rw-r--r-- | ResolverController.cpp | 14 | ||||
-rw-r--r-- | ResolverController.h | 6 | ||||
-rw-r--r-- | tests/Android.bp | 15 | ||||
-rw-r--r-- | tests/resolv_cache_unit_test.cpp | 3 | ||||
-rw-r--r-- | tests/resolv_integration_test.cpp | 64 |
10 files changed, 75 insertions, 66 deletions
@@ -230,6 +230,7 @@ cc_library { "libprotobuf-cpp-lite", "libstatslog_resolv", "libsysutils", + "libutils", "netd_event_listener_interface-lateststable-ndk", "server_configurable_flags", "stats_proto", diff --git a/Dns64Configuration.cpp b/Dns64Configuration.cpp index a1fe8717..fc1428db 100644 --- a/Dns64Configuration.cpp +++ b/Dns64Configuration.cpp @@ -24,6 +24,7 @@ #include <netdutils/DumpWriter.h> #include <netdutils/InternetAddresses.h> #include <netdutils/ThreadUtil.h> +#include <utils/StrongPointer.h> #include <thread> #include <utility> @@ -36,6 +37,7 @@ namespace android { +using android::sp; using netdutils::DumpWriter; using netdutils::IPAddress; using netdutils::IPPrefix; @@ -61,8 +63,9 @@ void Dns64Configuration::startPrefixDiscovery(unsigned netId) { // Emplace a copy of |cfg| in the map. mDns64Configs.emplace(std::make_pair(netId, cfg)); + const sp<Dns64Configuration> thiz = sp<Dns64Configuration>::fromExisting(this); // Note that capturing |cfg| in this lambda creates a copy. - std::thread discovery_thread([this, cfg, netId] { + std::thread discovery_thread([thiz, cfg, netId] { setThreadName(fmt::format("Nat64Pfx_{}", netId)); // Make a mutable copy rather than mark the whole lambda mutable. @@ -75,28 +78,28 @@ void Dns64Configuration::startPrefixDiscovery(unsigned netId) { .build(); while (true) { - if (!this->shouldContinueDiscovery(evalCfg)) break; + if (!thiz->shouldContinueDiscovery(evalCfg)) break; android_net_context netcontext{}; - mGetNetworkContextCallback(evalCfg.netId, 0, &netcontext); + thiz->mGetNetworkContextCallback(evalCfg.netId, 0, &netcontext); // Prefix discovery must bypass private DNS because in strict mode // the server generally won't know the NAT64 prefix. netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS; if (doRfc7050PrefixDiscovery(netcontext, &evalCfg)) { - this->recordDns64Config(evalCfg); + thiz->recordDns64Config(evalCfg); break; } - if (!this->shouldContinueDiscovery(evalCfg)) break; + if (!thiz->shouldContinueDiscovery(evalCfg)) break; if (!backoff.hasNextTimeout()) break; { - std::unique_lock<std::mutex> cvGuard(mMutex); + std::unique_lock<std::mutex> cvGuard(thiz->mMutex); // TODO: Consider some chrono math, combined with wait_until() // perhaps, to prevent early re-resolves from the removal of // other netids with IPv6-only nameservers. - mCv.wait_for(cvGuard, backoff.getNextTimeout()); + thiz->mCv.wait_for(cvGuard, backoff.getNextTimeout()); } } }); diff --git a/Dns64Configuration.h b/Dns64Configuration.h index 7f982989..4170e32d 100644 --- a/Dns64Configuration.h +++ b/Dns64Configuration.h @@ -27,6 +27,7 @@ #include <android-base/thread_annotations.h> #include <netdutils/DumpWriter.h> #include <netdutils/InternetAddresses.h> +#include <utils/RefBase.h> struct android_net_context; @@ -48,7 +49,7 @@ namespace net { * Thread-safety: All public methods in this class MUST be thread-safe. * (In other words: this class handles all its locking privately.) */ -class Dns64Configuration { +class Dns64Configuration : virtual public RefBase { public: // Simple data struct for passing back packet NAT64 prefix event information to the // Dns64PrefixCallback callback. diff --git a/DnsProxyListener.cpp b/DnsProxyListener.cpp index 0de74939..8f49eef6 100644 --- a/DnsProxyListener.cpp +++ b/DnsProxyListener.cpp @@ -70,20 +70,19 @@ using std::span; namespace android { +using netdutils::MAX_QUERIES_IN_TOTAL; +using netdutils::MAX_QUERIES_PER_UID; using netdutils::ResponseCode; using netdutils::Stopwatch; namespace net { namespace { -// Limits the number of outstanding DNS queries by client UID. -constexpr int MAX_QUERIES_PER_UID = 256; - android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID); bool startQueryLimiter(uid_t uid) { - const int globalLimit = - android::net::Experiments::getInstance()->getFlag("max_queries_global", INT_MAX); + const int globalLimit = android::net::Experiments::getInstance()->getFlag("max_queries_global", + MAX_QUERIES_IN_TOTAL); return queryLimiter.start(uid, globalLimit); } diff --git a/OperationLimiter.h b/OperationLimiter.h index 24f4dc3c..335ec5a3 100644 --- a/OperationLimiter.h +++ b/OperationLimiter.h @@ -28,6 +28,11 @@ namespace android { namespace netdutils { +// Limits the number of outstanding DNS queries by client UID. +constexpr int MAX_QUERIES_PER_UID = 256; +// Limits the total number of outstanding DNS queries. +constexpr int MAX_QUERIES_IN_TOTAL = 2500; + // Tracks the number of operations in progress on behalf of a particular key or // ID, rejecting further attempts to start new operations after a configurable // limit has been reached. @@ -56,11 +61,11 @@ class OperationLimiter { // // Note: each successful start(key) must be matched by exactly one call to // finish(key). - bool start(KeyType key, int globalLimit = INT_MAX) EXCLUDES(mMutex) { + bool start(KeyType key, int globalLimit = MAX_QUERIES_IN_TOTAL) EXCLUDES(mMutex) { std::lock_guard lock(mMutex); if (globalLimit < mLimitPerKey) { LOG(ERROR) << "Misconfiguration on max_queries_global " << globalLimit; - globalLimit = INT_MAX; + globalLimit = MAX_QUERIES_IN_TOTAL; } if (mGlobalCounter >= globalLimit) { // Oh, no! diff --git a/ResolverController.cpp b/ResolverController.cpp index 7fe01d48..66361143 100644 --- a/ResolverController.cpp +++ b/ResolverController.cpp @@ -155,11 +155,11 @@ int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<st } // namespace ResolverController::ResolverController() - : mDns64Configuration( + : mDns64Configuration(android::sp<Dns64Configuration>::make( [](uint32_t netId, uint32_t uid, android_net_context* netcontext) { gResNetdCallbacks.get_network_context(netId, uid, netcontext); }, - std::bind(sendNat64PrefixEvent, std::placeholders::_1)) {} + std::bind(sendNat64PrefixEvent, std::placeholders::_1))) {} void ResolverController::destroyNetworkCache(unsigned netId) { LOG(VERBOSE) << __func__ << ": netId = " << netId; @@ -173,7 +173,7 @@ void ResolverController::destroyNetworkCache(unsigned netId) { event.network_type(), event.private_dns_modes(), bytesField); resolv_delete_cache_for_net(netId); - mDns64Configuration.stopPrefixDiscovery(netId); + mDns64Configuration->stopPrefixDiscovery(netId); privateDnsConfiguration.clear(netId); // Don't get this instance in PrivateDnsConfiguration. It's probe to deadlock. @@ -276,16 +276,16 @@ int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* } void ResolverController::startPrefix64Discovery(int32_t netId) { - mDns64Configuration.startPrefixDiscovery(netId); + mDns64Configuration->startPrefixDiscovery(netId); } void ResolverController::stopPrefix64Discovery(int32_t netId) { - return mDns64Configuration.stopPrefixDiscovery(netId); + return mDns64Configuration->stopPrefixDiscovery(netId); } // TODO: use StatusOr<T> to wrap the result. int ResolverController::getPrefix64(unsigned netId, netdutils::IPPrefix* prefix) { - netdutils::IPPrefix p = mDns64Configuration.getPrefix64(netId); + netdutils::IPPrefix p = mDns64Configuration->getPrefix64(netId); if (p.family() != AF_INET6 || p.length() == 0) { return -ENOENT; } @@ -352,7 +352,7 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { params.max_samples, params.base_timeout_msec, params.retry_count); } - mDns64Configuration.dump(dw, netId); + mDns64Configuration->dump(dw, netId); const auto privateDnsStatus = PrivateDnsConfiguration::getInstance().getStatus(netId); dw.println("Private DNS mode: %s", getPrivateDnsModeString(privateDnsStatus.mode)); if (privateDnsStatus.dotServersMap.size() == 0) { diff --git a/ResolverController.h b/ResolverController.h index 0af830ee..b74cff92 100644 --- a/ResolverController.h +++ b/ResolverController.h @@ -55,10 +55,10 @@ class ResolverController { // Set or clear a NAT64 prefix discovered by other sources (e.g., RA). int setPrefix64(unsigned netId, const netdutils::IPPrefix& prefix) { - return mDns64Configuration.setPrefix64(netId, prefix); + return mDns64Configuration->setPrefix64(netId, prefix); } - int clearPrefix64(unsigned netId) { return mDns64Configuration.clearPrefix64(netId); } + int clearPrefix64(unsigned netId) { return mDns64Configuration->clearPrefix64(netId); } // Return the current NAT64 prefix network, regardless of how it was discovered. int getPrefix64(unsigned netId, netdutils::IPPrefix* prefix); @@ -66,7 +66,7 @@ class ResolverController { void dump(netdutils::DumpWriter& dw, unsigned netId); private: - Dns64Configuration mDns64Configuration; + android::sp<Dns64Configuration> mDns64Configuration; }; } // namespace net } // namespace android diff --git a/tests/Android.bp b/tests/Android.bp index 72fb008b..9d8f1e7f 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -271,6 +271,7 @@ cc_test { "libstatslog_resolv", "libstatspush_compat", "libsysutils", + "libutils", "resolv_stats_test_utils", "server_configurable_flags", "stats_proto", @@ -377,6 +378,18 @@ cc_defaults { "server_configurable_flags", "stats_proto", ], + target: { + android: { + shared_libs: [ + "libutils", + ], + }, + host: { + static_libs: [ + "libutils", + ], + }, + }, fuzz_config: { cc: [ "cken@google.com", @@ -421,14 +434,12 @@ cc_fuzz { shared_libs: [ "libbinder_ndk", "libbinder", - "libutils", ], }, host: { static_libs: [ "libbinder_ndk", "libbinder", - "libutils", ], }, darwin: { diff --git a/tests/resolv_cache_unit_test.cpp b/tests/resolv_cache_unit_test.cpp index 9667d131..defd2da6 100644 --- a/tests/resolv_cache_unit_test.cpp +++ b/tests/resolv_cache_unit_test.cpp @@ -630,9 +630,6 @@ class ResolvCacheParameterizedTest : public ResolvCacheTest, INSTANTIATE_TEST_SUITE_P(MaxCacheEntries, ResolvCacheParameterizedTest, testing::Values(MAX_ENTRIES_LOWER_BOUND - 1, MAX_ENTRIES_UPPER_BOUND + 1), [](const testing::TestParamInfo<int>& info) { - if (info.param < 0) { // '-' is an invalid character in test name - return "negative_" + std::to_string(abs(info.param)); - } return std::to_string(info.param); }); diff --git a/tests/resolv_integration_test.cpp b/tests/resolv_integration_test.cpp index 8623e153..ff62da45 100644 --- a/tests/resolv_integration_test.cpp +++ b/tests/resolv_integration_test.cpp @@ -4099,54 +4099,46 @@ TEST_F(ResolverTest, GetHostByName2_Dns64QuerySpecialUseIPv4Addresses) { TEST_F(ResolverTest, PrefixDiscoveryBypassTls) { constexpr char listen_addr[] = "::1"; - constexpr char cleartext_port[] = "53"; - constexpr char tls_port[] = "853"; constexpr char dns64_name[] = "ipv4only.arpa."; const std::vector<std::string> servers = {listen_addr}; test::DNSResponder dns(listen_addr); StartDns(dns, {{dns64_name, ns_type::ns_t_aaaa, "64:ff9b::192.0.0.170"}}); - test::DnsTlsFrontend tls(listen_addr, tls_port, listen_addr, cleartext_port); + test::DnsTlsFrontend tls(listen_addr, "853", listen_addr, "53"); ASSERT_TRUE(tls.startServer()); - // Setup OPPORTUNISTIC mode and wait for the validation complete. - ASSERT_TRUE(mDnsClient.SetResolversFromParcel( - ResolverParams::Builder().setDnsServers(servers).setDotServers(servers).build())); - EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true)); - EXPECT_TRUE(tls.waitForQueries(1)); - tls.clearQueries(); - - // Start NAT64 prefix discovery and wait for it complete. - EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk()); - EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND)); + for (const std::string_view dnsMode : {"OPPORTUNISTIC", "STRICT"}) { + SCOPED_TRACE(fmt::format("testConfig: [{}]", dnsMode)); + auto builder = ResolverParams::Builder().setDnsServers(servers).setDotServers(servers); + if (dnsMode == "STRICT") { + builder.setPrivateDnsProvider(kDefaultPrivateDnsHostName); + } + ASSERT_TRUE(mDnsClient.SetResolversFromParcel(builder.build())); + EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true)); + EXPECT_TRUE(tls.waitForQueries(1)); + tls.clearQueries(); - // Verify it bypassed TLS even though there's a TLS server available. - EXPECT_EQ(0, tls.queries()) << dns.dumpQueries(); - EXPECT_EQ(1U, GetNumQueries(dns, dns64_name)) << dns.dumpQueries(); + // Start NAT64 prefix discovery. + EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk()); + EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND)); - // Restart the testing network to reset the cache. - mDnsClient.TearDown(); - mDnsClient.SetUp(); - dns.clearQueries(); + // Verify that the DNS query for the NAT64 prefix bypassed private DNS. + EXPECT_EQ(0, tls.queries()) << dns.dumpQueries(); + EXPECT_EQ(1U, GetNumQueries(dns, dns64_name)) << dns.dumpQueries(); - // Setup STRICT mode and wait for the validation complete. - ASSERT_TRUE(mDnsClient.SetResolversFromParcel( - ResolverParams::Builder() - .setDnsServers(servers) - .setDotServers(servers) - .setPrivateDnsProvider(kDefaultPrivateDnsHostName) - .build())); - EXPECT_TRUE(WaitForPrivateDnsValidation(tls.listen_address(), true)); - EXPECT_TRUE(tls.waitForQueries(1)); - tls.clearQueries(); + // Stop the prefix discovery to make DnsResolver send the prefix-removed event + // earlier. Without this, DnsResolver still sends the event once the network + // is destroyed; however, it will fail the next test if the test unexpectedly + // receives the event that it doesn't want. + EXPECT_TRUE(mDnsClient.resolvService()->stopPrefix64Discovery(TEST_NETID).isOk()); + EXPECT_TRUE(WaitForNat64Prefix(EXPECT_NOT_FOUND)); - // Start NAT64 prefix discovery and wait for it to complete. - EXPECT_TRUE(mDnsClient.resolvService()->startPrefix64Discovery(TEST_NETID).isOk()); - EXPECT_TRUE(WaitForNat64Prefix(EXPECT_FOUND)); + dns.clearQueries(); + EXPECT_TRUE(mDnsClient.resolvService()->flushNetworkCache(TEST_NETID).isOk()); + } - // Verify it bypassed TLS despite STRICT mode. - EXPECT_EQ(0, tls.queries()) << dns.dumpQueries(); - EXPECT_EQ(1U, GetNumQueries(dns, dns64_name)) << dns.dumpQueries(); + EXPECT_EQ(0, sDnsMetricsListener->getUnexpectedNat64PrefixUpdates()); + EXPECT_EQ(0, sUnsolicitedEventListener->getUnexpectedNat64PrefixUpdates()); } TEST_F(ResolverTest, SetAndClearNat64Prefix) { |