Loading Experiments.h +8 −7 Original line number Diff line number Diff line Loading @@ -46,13 +46,8 @@ class Experiments { void updateInternal() EXCLUDES(mMutex); mutable std::mutex mMutex; std::map<std::string_view, int> mFlagsMapInt GUARDED_BY(mMutex); // TODO: Migrate other experiment flags to here. // (retry_count, retransmission_time_interval) // Sort the list by alphabet ordering. static constexpr const char* const kExperimentFlagKeyList[] = { "keep_listening_udp", "parallel_lookup_release", "parallel_lookup_sleep_time", "sort_nameservers", "dot_async_handshake", "dot_connect_timeout_ms", "dot_maxtries", Loading @@ -68,8 +63,14 @@ class Experiments { "doh_probe_timeout_ms", "doh_idle_timeout_ms", "doh_session_resumption", "mdns_resolution", "keep_listening_udp", "max_queries_global", "mdns_resolution", "parallel_lookup_release", "parallel_lookup_sleep_time", "retransmission_time_interval", "retry_count", "sort_nameservers", }; // This value is used in updateInternal as the default value if any flags can't be found. static constexpr int kFlagIntDefault = INT_MIN; Loading res_cache.cpp +14 −12 Original line number Diff line number Diff line Loading @@ -1542,17 +1542,6 @@ static NetConfig* find_netconfig_locked(unsigned netid) { return nullptr; } static void resolv_set_experiment_params(res_params* params) { if (params->retry_count == 0) { params->retry_count = getExperimentFlagInt("retry_count", RES_DFLRETRY); } if (params->base_timeout_msec == 0) { params->base_timeout_msec = getExperimentFlagInt("retransmission_time_interval", RES_TIMEOUT); } } android::net::NetworkType resolv_get_network_types_for_net(unsigned netid) { std::lock_guard guard(cache_mutex); NetConfig* netconfig = find_netconfig_locked(netid); Loading Loading @@ -1660,7 +1649,20 @@ int resolv_set_nameservers(unsigned netid, const std::vector<std::string>& serve uint8_t old_max_samples = netconfig->params.max_samples; netconfig->params = params; resolv_set_experiment_params(&netconfig->params); const int retryCount = Experiments::getInstance()->getFlag("retry_count", RES_DFLRETRY); const int retransmissionInterval = Experiments::getInstance()->getFlag("retransmission_time_interval", RES_TIMEOUT); // This check must always be true, but add a protection against OEMs configure negative values // for retry_count and base_timeout_msec. if (netconfig->params.retry_count == 0) { netconfig->params.retry_count = (retryCount <= 0) ? RES_DFLRETRY : retryCount; } if (netconfig->params.base_timeout_msec == 0) { netconfig->params.base_timeout_msec = (retransmissionInterval <= 0) ? RES_TIMEOUT : retransmissionInterval; } if (!resolv_is_nameservers_equal(netconfig->nameservers, nameservers)) { // free current before adding new free_nameservers_locked(netconfig); Loading tests/resolv_integration_test.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,10 @@ constexpr int TEST_VPN_NETID = 65502; constexpr int MAXPACKET = (8 * 1024); // Sync from packages/modules/DnsResolver/resolv_private.h constexpr int RES_TIMEOUT = 5000; /* min. milliseconds between retries */ constexpr int RES_DFLRETRY = 2; /* Default #/tries. */ const std::string kSortNameserversFlag("persist.device_config.netd_native.sort_nameservers"); const std::string kDotConnectTimeoutMsFlag( "persist.device_config.netd_native.dot_connect_timeout_ms"); Loading @@ -94,6 +98,9 @@ const std::string kDotValidationLatencyFactorFlag( const std::string kDotValidationLatencyOffsetMsFlag( "persist.device_config.netd_native.dot_validation_latency_offset_ms"); const std::string kDotQuickFallbackFlag("persist.device_config.netd_native.dot_quick_fallback"); const std::string kRetransIntervalFlag( "persist.device_config.netd_native.retransmission_time_interval"); const std::string kRetryCountFlag("persist.device_config.netd_native.retry_count"); // Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c) // Tested here for convenience. extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname, Loading Loading @@ -7619,3 +7626,47 @@ TEST_F(ResolverMultinetworkTest, PerAppDefaultNetwork) { appDefaultNetId); } } TEST_F(ResolverTest, NegativeValueInExperimentFlag_WithValidParams) { ScopedSystemProperties sp1(kRetransIntervalFlag, "-3000"); ScopedSystemProperties sp2(kRetryCountFlag, "-2"); resetNetwork(); ResolverParamsParcel setupParams = DnsResponderClient::GetDefaultResolverParamsParcel(); ASSERT_TRUE(mDnsClient.SetResolversFromParcel(setupParams)); std::vector<std::string> res_servers; std::vector<std::string> res_domains; std::vector<std::string> res_tls_servers; res_params res_params; std::vector<ResolverStats> res_stats; int wait_for_pending_req_timeout_count; ASSERT_TRUE(DnsResponderClient::GetResolverInfo( mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count)); EXPECT_EQ(setupParams.retryCount, res_params.retry_count); EXPECT_EQ(setupParams.baseTimeoutMsec, res_params.base_timeout_msec); } TEST_F(ResolverTest, NegativeValueInExperimentFlag_WithZeroParams) { ScopedSystemProperties sp1(kRetransIntervalFlag, "-3000"); ScopedSystemProperties sp2(kRetryCountFlag, "-2"); resetNetwork(); ResolverParamsParcel setupParams = DnsResponderClient::GetDefaultResolverParamsParcel(); setupParams.retryCount = 0; setupParams.baseTimeoutMsec = 0; ASSERT_TRUE(mDnsClient.SetResolversFromParcel(setupParams)); std::vector<std::string> res_servers; std::vector<std::string> res_domains; std::vector<std::string> res_tls_servers; res_params res_params; std::vector<ResolverStats> res_stats; int wait_for_pending_req_timeout_count; ASSERT_TRUE(DnsResponderClient::GetResolverInfo( mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count)); EXPECT_EQ(RES_DFLRETRY, res_params.retry_count); EXPECT_EQ(RES_TIMEOUT, res_params.base_timeout_msec); } Loading
Experiments.h +8 −7 Original line number Diff line number Diff line Loading @@ -46,13 +46,8 @@ class Experiments { void updateInternal() EXCLUDES(mMutex); mutable std::mutex mMutex; std::map<std::string_view, int> mFlagsMapInt GUARDED_BY(mMutex); // TODO: Migrate other experiment flags to here. // (retry_count, retransmission_time_interval) // Sort the list by alphabet ordering. static constexpr const char* const kExperimentFlagKeyList[] = { "keep_listening_udp", "parallel_lookup_release", "parallel_lookup_sleep_time", "sort_nameservers", "dot_async_handshake", "dot_connect_timeout_ms", "dot_maxtries", Loading @@ -68,8 +63,14 @@ class Experiments { "doh_probe_timeout_ms", "doh_idle_timeout_ms", "doh_session_resumption", "mdns_resolution", "keep_listening_udp", "max_queries_global", "mdns_resolution", "parallel_lookup_release", "parallel_lookup_sleep_time", "retransmission_time_interval", "retry_count", "sort_nameservers", }; // This value is used in updateInternal as the default value if any flags can't be found. static constexpr int kFlagIntDefault = INT_MIN; Loading
res_cache.cpp +14 −12 Original line number Diff line number Diff line Loading @@ -1542,17 +1542,6 @@ static NetConfig* find_netconfig_locked(unsigned netid) { return nullptr; } static void resolv_set_experiment_params(res_params* params) { if (params->retry_count == 0) { params->retry_count = getExperimentFlagInt("retry_count", RES_DFLRETRY); } if (params->base_timeout_msec == 0) { params->base_timeout_msec = getExperimentFlagInt("retransmission_time_interval", RES_TIMEOUT); } } android::net::NetworkType resolv_get_network_types_for_net(unsigned netid) { std::lock_guard guard(cache_mutex); NetConfig* netconfig = find_netconfig_locked(netid); Loading Loading @@ -1660,7 +1649,20 @@ int resolv_set_nameservers(unsigned netid, const std::vector<std::string>& serve uint8_t old_max_samples = netconfig->params.max_samples; netconfig->params = params; resolv_set_experiment_params(&netconfig->params); const int retryCount = Experiments::getInstance()->getFlag("retry_count", RES_DFLRETRY); const int retransmissionInterval = Experiments::getInstance()->getFlag("retransmission_time_interval", RES_TIMEOUT); // This check must always be true, but add a protection against OEMs configure negative values // for retry_count and base_timeout_msec. if (netconfig->params.retry_count == 0) { netconfig->params.retry_count = (retryCount <= 0) ? RES_DFLRETRY : retryCount; } if (netconfig->params.base_timeout_msec == 0) { netconfig->params.base_timeout_msec = (retransmissionInterval <= 0) ? RES_TIMEOUT : retransmissionInterval; } if (!resolv_is_nameservers_equal(netconfig->nameservers, nameservers)) { // free current before adding new free_nameservers_locked(netconfig); Loading
tests/resolv_integration_test.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,10 @@ constexpr int TEST_VPN_NETID = 65502; constexpr int MAXPACKET = (8 * 1024); // Sync from packages/modules/DnsResolver/resolv_private.h constexpr int RES_TIMEOUT = 5000; /* min. milliseconds between retries */ constexpr int RES_DFLRETRY = 2; /* Default #/tries. */ const std::string kSortNameserversFlag("persist.device_config.netd_native.sort_nameservers"); const std::string kDotConnectTimeoutMsFlag( "persist.device_config.netd_native.dot_connect_timeout_ms"); Loading @@ -94,6 +98,9 @@ const std::string kDotValidationLatencyFactorFlag( const std::string kDotValidationLatencyOffsetMsFlag( "persist.device_config.netd_native.dot_validation_latency_offset_ms"); const std::string kDotQuickFallbackFlag("persist.device_config.netd_native.dot_quick_fallback"); const std::string kRetransIntervalFlag( "persist.device_config.netd_native.retransmission_time_interval"); const std::string kRetryCountFlag("persist.device_config.netd_native.retry_count"); // Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c) // Tested here for convenience. extern "C" int android_getaddrinfofornet(const char* hostname, const char* servname, Loading Loading @@ -7619,3 +7626,47 @@ TEST_F(ResolverMultinetworkTest, PerAppDefaultNetwork) { appDefaultNetId); } } TEST_F(ResolverTest, NegativeValueInExperimentFlag_WithValidParams) { ScopedSystemProperties sp1(kRetransIntervalFlag, "-3000"); ScopedSystemProperties sp2(kRetryCountFlag, "-2"); resetNetwork(); ResolverParamsParcel setupParams = DnsResponderClient::GetDefaultResolverParamsParcel(); ASSERT_TRUE(mDnsClient.SetResolversFromParcel(setupParams)); std::vector<std::string> res_servers; std::vector<std::string> res_domains; std::vector<std::string> res_tls_servers; res_params res_params; std::vector<ResolverStats> res_stats; int wait_for_pending_req_timeout_count; ASSERT_TRUE(DnsResponderClient::GetResolverInfo( mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count)); EXPECT_EQ(setupParams.retryCount, res_params.retry_count); EXPECT_EQ(setupParams.baseTimeoutMsec, res_params.base_timeout_msec); } TEST_F(ResolverTest, NegativeValueInExperimentFlag_WithZeroParams) { ScopedSystemProperties sp1(kRetransIntervalFlag, "-3000"); ScopedSystemProperties sp2(kRetryCountFlag, "-2"); resetNetwork(); ResolverParamsParcel setupParams = DnsResponderClient::GetDefaultResolverParamsParcel(); setupParams.retryCount = 0; setupParams.baseTimeoutMsec = 0; ASSERT_TRUE(mDnsClient.SetResolversFromParcel(setupParams)); std::vector<std::string> res_servers; std::vector<std::string> res_domains; std::vector<std::string> res_tls_servers; res_params res_params; std::vector<ResolverStats> res_stats; int wait_for_pending_req_timeout_count; ASSERT_TRUE(DnsResponderClient::GetResolverInfo( mDnsClient.resolvService(), TEST_NETID, &res_servers, &res_domains, &res_tls_servers, &res_params, &res_stats, &wait_for_pending_req_timeout_count)); EXPECT_EQ(RES_DFLRETRY, res_params.retry_count); EXPECT_EQ(RES_TIMEOUT, res_params.base_timeout_msec); }