Loading DnsProxyListener.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -708,6 +708,12 @@ bool isUidNetworkingBlocked(uid_t uid, unsigned netId) { // application's UID. Its DNS packets are not subject to certain network restriction features. if (resolv_is_enforceDnsUid_enabled_network(netId)) return false; // Feature flag that can disable the feature. if (!android::net::Experiments::getInstance()->getFlag("fail_fast_on_uid_network_blocking", 1)) { return false; } return (*ADnsHelper_isUidNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1; } Loading Experiments.h +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ class Experiments { "dot_validation_latency_factor", "dot_validation_latency_offset_ms", "dot_xport_unusable_threshold", "fail_fast_on_uid_network_blocking", "keep_listening_udp", "max_cache_entries", "max_queries_global", Loading tests/resolv_integration_test.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -5782,8 +5782,9 @@ TEST_F(ResolverTest, RepeatedSetup_KeepChangingPrivateDnsServers) { for (const auto& serverState : {WORKING, UNSUPPORTED, UNRESPONSIVE}) { int testIndex = 0; for (const auto& config : testConfigs) { SCOPED_TRACE(fmt::format("serverState:{} testIndex:{} testConfig:[{}]", serverState, testIndex++, config.asTestName())); SCOPED_TRACE(fmt::format("serverState:{} testIndex:{} testConfig:[{}]", static_cast<int>(serverState), testIndex++, config.asTestName())); auto& tls = (config.tlsServer == addr1) ? tls1 : tls2; if (serverState == UNSUPPORTED && tls.running()) ASSERT_TRUE(tls.stopServer()); Loading Loading @@ -7431,7 +7432,7 @@ TEST_F(ResolverMultinetworkTest, GetAddrInfo_AI_ADDRCONFIG) { ConnectivityType::V4V6, }; for (const auto& type : allTypes) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", type)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(type))); // Create a network. ScopedPhysicalNetwork network = CreateScopedPhysicalNetwork(type); Loading Loading @@ -7563,7 +7564,7 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) { {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}}, }; for (const auto& [type, result] : testPairs) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", type)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(type))); // Create a network. ScopedPhysicalNetwork underlyingNetwork = CreateScopedPhysicalNetwork(type, "Underlying"); Loading Loading @@ -7683,7 +7684,7 @@ TEST_F(ResolverMultinetworkTest, PerAppDefaultNetwork) { {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}}, }; for (const auto& [ipVersion, expectedDnsReply] : testPairs) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", ipVersion)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(ipVersion))); // Create networks. ScopedPhysicalNetwork sysDefaultNetwork = Loading Loading @@ -7928,7 +7929,7 @@ TEST_F(ResolverMultinetworkTest, UidAllowedNetworks) { {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}}, }; for (const auto& [ipVersion, expectedDnsReply] : testPairs) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", ipVersion)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(ipVersion))); // Create networks. ScopedPhysicalNetwork sysDefaultNetwork = Loading tests/resolv_private_dns_test.cpp +64 −0 Original line number Diff line number Diff line Loading @@ -603,6 +603,70 @@ TEST_P(TransportParameterizedTest, BlockDnsQuery) { } } // Verify whether the DNS fail-fast feature can be turned off by flag. TEST_P(TransportParameterizedTest, BlockDnsQuery_FlaggedOff) { SKIP_IF_BEFORE_T; SKIP_IF_DEPENDENT_LIB_DOES_NOT_EXIST(DNS_HELPER); constexpr char ptr_name[] = "v4v6.example.com."; // PTR record for IPv6 address 2001:db8::102:304 constexpr char ptr_addr_v6[] = "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."; const DnsRecord r = {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name}; dns.addMapping(r.host_name, r.type, r.addr); dot_backend.addMapping(r.host_name, r.type, r.addr); doh_backend.addMapping(r.host_name, r.type, r.addr); ScopedSystemProperties sp1(kFailFastOnUidNetworkBlockingFlag, "0"); resetNetwork(); auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel(); ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel)); if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr)); if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr)); // This waiting time is expected to avoid that the DoH validation event interferes other tests. if (!testParamHasDoh()) waitForDohValidationFailed(); // Have the test independent of the number of sent queries in private DNS validation, because // the DnsResolver can send either 1 or 2 queries in DoT validation. if (testParamHasDoh()) { doh.clearQueries(); } if (testParamHasDot()) { EXPECT_TRUE(dot.waitForQueries(1)); dot.clearQueries(); } dns.clearQueries(); for (const bool testDataSaver : {false, true}) { SCOPED_TRACE(fmt::format("test {}", testDataSaver ? "data saver" : "UID firewall rules")); if (testDataSaver) { // Data Saver applies on metered networks only. parcel.meteredNetwork = true; ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel)); // Block network access by enabling data saver. ScopedSetDataSaverByBPF scopedSetDataSaverByBPF(true); ScopedChangeUID scopedChangeUID(TEST_UID); EXPECT_NO_FAILURE(sendQueryAndCheckResult()); } else { // Block network access by setting UID firewall rules. ScopeBlockedUIDRule scopeBlockUidRule(mDnsClient.netdService(), TEST_UID); EXPECT_NO_FAILURE(sendQueryAndCheckResult()); } if (testParamHasDoh()) { EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */)); dot.clearQueries(); } else { EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 2 /* dot */, 0 /* doh */)); doh.clearQueries(); } } } class PrivateDnsDohTest : public BasePrivateDnsTest { protected: void SetUp() override { Loading tests/resolv_test_utils.h +2 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ const std::string kDotXportUnusableThresholdFlag(kFlagPrefix + "dot_xport_unusab const std::string kDotValidationLatencyFactorFlag(kFlagPrefix + "dot_validation_latency_factor"); const std::string kDotValidationLatencyOffsetMsFlag(kFlagPrefix + "dot_validation_latency_offset_ms"); const std::string kFailFastOnUidNetworkBlockingFlag(kFlagPrefix + "fail_fast_on_uid_network_blocking"); const std::string kKeepListeningUdpFlag(kFlagPrefix + "keep_listening_udp"); const std::string kParallelLookupSleepTimeFlag(kFlagPrefix + "parallel_lookup_sleep_time"); const std::string kRetransIntervalFlag(kFlagPrefix + "retransmission_time_interval"); Loading Loading
DnsProxyListener.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -708,6 +708,12 @@ bool isUidNetworkingBlocked(uid_t uid, unsigned netId) { // application's UID. Its DNS packets are not subject to certain network restriction features. if (resolv_is_enforceDnsUid_enabled_network(netId)) return false; // Feature flag that can disable the feature. if (!android::net::Experiments::getInstance()->getFlag("fail_fast_on_uid_network_blocking", 1)) { return false; } return (*ADnsHelper_isUidNetworkingBlocked)(uid, resolv_is_metered_network(netId)) == 1; } Loading
Experiments.h +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ class Experiments { "dot_validation_latency_factor", "dot_validation_latency_offset_ms", "dot_xport_unusable_threshold", "fail_fast_on_uid_network_blocking", "keep_listening_udp", "max_cache_entries", "max_queries_global", Loading
tests/resolv_integration_test.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -5782,8 +5782,9 @@ TEST_F(ResolverTest, RepeatedSetup_KeepChangingPrivateDnsServers) { for (const auto& serverState : {WORKING, UNSUPPORTED, UNRESPONSIVE}) { int testIndex = 0; for (const auto& config : testConfigs) { SCOPED_TRACE(fmt::format("serverState:{} testIndex:{} testConfig:[{}]", serverState, testIndex++, config.asTestName())); SCOPED_TRACE(fmt::format("serverState:{} testIndex:{} testConfig:[{}]", static_cast<int>(serverState), testIndex++, config.asTestName())); auto& tls = (config.tlsServer == addr1) ? tls1 : tls2; if (serverState == UNSUPPORTED && tls.running()) ASSERT_TRUE(tls.stopServer()); Loading Loading @@ -7431,7 +7432,7 @@ TEST_F(ResolverMultinetworkTest, GetAddrInfo_AI_ADDRCONFIG) { ConnectivityType::V4V6, }; for (const auto& type : allTypes) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", type)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(type))); // Create a network. ScopedPhysicalNetwork network = CreateScopedPhysicalNetwork(type); Loading Loading @@ -7563,7 +7564,7 @@ TEST_F(ResolverMultinetworkTest, DnsWithVpn) { {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}}, }; for (const auto& [type, result] : testPairs) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", type)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(type))); // Create a network. ScopedPhysicalNetwork underlyingNetwork = CreateScopedPhysicalNetwork(type, "Underlying"); Loading Loading @@ -7683,7 +7684,7 @@ TEST_F(ResolverMultinetworkTest, PerAppDefaultNetwork) { {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}}, }; for (const auto& [ipVersion, expectedDnsReply] : testPairs) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", ipVersion)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(ipVersion))); // Create networks. ScopedPhysicalNetwork sysDefaultNetwork = Loading Loading @@ -7928,7 +7929,7 @@ TEST_F(ResolverMultinetworkTest, UidAllowedNetworks) { {ConnectivityType::V4V6, {ipv6_addr, ipv4_addr}}, }; for (const auto& [ipVersion, expectedDnsReply] : testPairs) { SCOPED_TRACE(fmt::format("ConnectivityType: {}", ipVersion)); SCOPED_TRACE(fmt::format("ConnectivityType: {}", static_cast<int>(ipVersion))); // Create networks. ScopedPhysicalNetwork sysDefaultNetwork = Loading
tests/resolv_private_dns_test.cpp +64 −0 Original line number Diff line number Diff line Loading @@ -603,6 +603,70 @@ TEST_P(TransportParameterizedTest, BlockDnsQuery) { } } // Verify whether the DNS fail-fast feature can be turned off by flag. TEST_P(TransportParameterizedTest, BlockDnsQuery_FlaggedOff) { SKIP_IF_BEFORE_T; SKIP_IF_DEPENDENT_LIB_DOES_NOT_EXIST(DNS_HELPER); constexpr char ptr_name[] = "v4v6.example.com."; // PTR record for IPv6 address 2001:db8::102:304 constexpr char ptr_addr_v6[] = "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."; const DnsRecord r = {ptr_addr_v6, ns_type::ns_t_ptr, ptr_name}; dns.addMapping(r.host_name, r.type, r.addr); dot_backend.addMapping(r.host_name, r.type, r.addr); doh_backend.addMapping(r.host_name, r.type, r.addr); ScopedSystemProperties sp1(kFailFastOnUidNetworkBlockingFlag, "0"); resetNetwork(); auto parcel = DnsResponderClient::GetDefaultResolverParamsParcel(); ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel)); if (testParamHasDoh()) EXPECT_TRUE(WaitForDohValidationSuccess(test::kDefaultListenAddr)); if (testParamHasDot()) EXPECT_TRUE(WaitForDotValidationSuccess(test::kDefaultListenAddr)); // This waiting time is expected to avoid that the DoH validation event interferes other tests. if (!testParamHasDoh()) waitForDohValidationFailed(); // Have the test independent of the number of sent queries in private DNS validation, because // the DnsResolver can send either 1 or 2 queries in DoT validation. if (testParamHasDoh()) { doh.clearQueries(); } if (testParamHasDot()) { EXPECT_TRUE(dot.waitForQueries(1)); dot.clearQueries(); } dns.clearQueries(); for (const bool testDataSaver : {false, true}) { SCOPED_TRACE(fmt::format("test {}", testDataSaver ? "data saver" : "UID firewall rules")); if (testDataSaver) { // Data Saver applies on metered networks only. parcel.meteredNetwork = true; ASSERT_TRUE(mDnsClient.SetResolversFromParcel(parcel)); // Block network access by enabling data saver. ScopedSetDataSaverByBPF scopedSetDataSaverByBPF(true); ScopedChangeUID scopedChangeUID(TEST_UID); EXPECT_NO_FAILURE(sendQueryAndCheckResult()); } else { // Block network access by setting UID firewall rules. ScopeBlockedUIDRule scopeBlockUidRule(mDnsClient.netdService(), TEST_UID); EXPECT_NO_FAILURE(sendQueryAndCheckResult()); } if (testParamHasDoh()) { EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 0 /* dot */, 2 /* doh */)); dot.clearQueries(); } else { EXPECT_NO_FAILURE(expectQueries(0 /* dns */, 2 /* dot */, 0 /* doh */)); doh.clearQueries(); } } } class PrivateDnsDohTest : public BasePrivateDnsTest { protected: void SetUp() override { Loading
tests/resolv_test_utils.h +2 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ const std::string kDotXportUnusableThresholdFlag(kFlagPrefix + "dot_xport_unusab const std::string kDotValidationLatencyFactorFlag(kFlagPrefix + "dot_validation_latency_factor"); const std::string kDotValidationLatencyOffsetMsFlag(kFlagPrefix + "dot_validation_latency_offset_ms"); const std::string kFailFastOnUidNetworkBlockingFlag(kFlagPrefix + "fail_fast_on_uid_network_blocking"); const std::string kKeepListeningUdpFlag(kFlagPrefix + "keep_listening_udp"); const std::string kParallelLookupSleepTimeFlag(kFlagPrefix + "parallel_lookup_sleep_time"); const std::string kRetransIntervalFlag(kFlagPrefix + "retransmission_time_interval"); Loading