Make DoT retries configurable
DnsTlsTransport re-issues pending queries when onClosed is called.
The call to onClosed is triggered when 1) asynchronous handshake
fails and 2) SSL socket idles for 20 seconds. In either case, retry
on the same DoT server is not always a good solution. Instead, there
are some considerable options, like trying next DoT server, fallbacking
to Do53, or simply returning query failure.
Tuning DoT retries is especially significant to asynchronous
handshake feature because the timeout of the feature is calculated as:
timeout = dot_connect_timeout_ms * dot_maxtries
Bug: 149445907
Test: cd packages/modules/DnsResolver
atest with combination of (dot_async_handshake, dot_maxtries)
which are (0, 3), (0, 1), (1, 3), and (1, 1)
Change-Id: Iceb7bc7f0f6736d900384d1a11eea470761ee32c
diff --git a/tests/resolv_integration_test.cpp b/tests/resolv_integration_test.cpp
index f95316e..7c3fcb0 100644
--- a/tests/resolv_integration_test.cpp
+++ b/tests/resolv_integration_test.cpp
@@ -81,6 +81,7 @@
const std::string kDotConnectTimeoutMsFlag(
"persist.device_config.netd_native.dot_connect_timeout_ms");
const std::string kDotAsyncHandshakeFlag("persist.device_config.netd_native.dot_async_handshake");
+const std::string kDotMaxretriesFlag("persist.device_config.netd_native.dot_maxtries");
// Semi-public Bionic hook used by the NDK (frameworks/base/native/android/net.c)
// Tested here for convenience.
@@ -4283,17 +4284,22 @@
static const struct TestConfig {
bool asyncHandshake;
+ int maxRetries;
+
+ // if asyncHandshake:
+ // expectedTimeout = dotConnectTimeoutMs * maxRetries
+ // otherwise:
+ // expectedTimeout = dotConnectTimeoutMs
int expectedTimeout;
} testConfigs[] = {
- // expectedTimeout = dotConnectTimeoutMs
- {false, 1000},
+ // Test mis-configured dot_maxtries flag.
+ {false, 0, 1000}, {true, 0, 1000},
- // expectedTimeout = dotConnectTimeoutMs * DnsTlsQueryMap::kMaxTries
- {true, 3000},
+ {false, 1, 1000}, {false, 3, 1000}, {true, 1, 1000}, {true, 3, 3000},
};
for (const auto& config : testConfigs) {
- SCOPED_TRACE(fmt::format("testConfig: [{}]", config.asyncHandshake));
+ SCOPED_TRACE(fmt::format("testConfig: [{}, {}]", config.asyncHandshake, config.maxRetries));
// Because a DnsTlsTransport lasts at least 5 minutes in spite of network
// destroyed, let the resolver creates an unique DnsTlsTransport every time
@@ -4304,8 +4310,10 @@
test::DnsTlsFrontend tls(addr, "853", addr, "53");
ASSERT_TRUE(tls.startServer());
- ScopedSystemProperties scopedSystemProperties(kDotAsyncHandshakeFlag,
- config.asyncHandshake ? "1" : "0");
+ ScopedSystemProperties scopedSystemProperties1(kDotAsyncHandshakeFlag,
+ config.asyncHandshake ? "1" : "0");
+ ScopedSystemProperties scopedSystemProperties2(kDotMaxretriesFlag,
+ std::to_string(config.maxRetries));
resetNetwork();
// Set up resolver to opportunistic mode.
@@ -4362,14 +4370,22 @@
static const struct TestConfig {
bool asyncHandshake;
int dotConnectTimeoutMs;
+ int maxRetries;
int concurrency;
+
+ // if asyncHandshake:
+ // expectedTimeout = dotConnectTimeoutMs * maxRetries
+ // otherwise:
+ // expectedTimeout = dotConnectTimeoutMs * concurrency
int expectedTimeout;
} testConfigs[] = {
- // expectedTimeout = dotConnectTimeoutMs * concurrency
- {false, 1000, 5, 5000},
-
- // expectedTimeout = dotConnectTimeoutMs * DnsTlsQueryMap::kMaxTries
- {true, 1000, 5, 3000},
+ // clang-format off
+ {false, 1000, 1, 5, 5000},
+ {false, 1000, 3, 5, 5000},
+ {true, 1000, 1, 5, 1000},
+ {true, 2500, 1, 10, 2500},
+ {true, 1000, 3, 5, 3000},
+ // clang-format on
};
// Launch query threads. Expected behaviors are:
@@ -4382,6 +4398,8 @@
std::to_string(config.dotConnectTimeoutMs));
ScopedSystemProperties scopedSystemProperties2(kDotAsyncHandshakeFlag,
config.asyncHandshake ? "1" : "0");
+ ScopedSystemProperties scopedSystemProperties3(kDotMaxretriesFlag,
+ std::to_string(config.maxRetries));
resetNetwork();
for (const auto& dnsMode : {"OPPORTUNISTIC", "STRICT"}) {