Allow changing retry limit and timeout via experiment flags.
Test: built / flashed / booted
netd_unit_test, netd_integration_test, libnetd_resolv_test
Change-Id: Ica8f2ccddc60f2b8e006ac6923064b6171a13821
diff --git a/resolv/Android.bp b/resolv/Android.bp
index a54245f..7f0df77 100644
--- a/resolv/Android.bp
+++ b/resolv/Android.bp
@@ -54,6 +54,7 @@
"libsysutils",
"netd_event_listener_interface-ndk_platform",
"dnsresolver_aidl_interface-ndk_platform",
+ "server_configurable_flags",
],
shared_libs: [
"libbinder_ndk",
@@ -131,5 +132,6 @@
"libnetd_resolv",
"libnetd_test_dnsresponder",
"libnetdutils",
+ "server_configurable_flags",
],
}
diff --git a/resolv/dns_responder/dns_responder_client.h b/resolv/dns_responder/dns_responder_client.h
index b31d987..6dc6ae3 100644
--- a/resolv/dns_responder/dns_responder_client.h
+++ b/resolv/dns_responder/dns_responder_client.h
@@ -35,11 +35,11 @@
inline const std::vector<std::string> kDefaultServers = {"127.0.0.3"};
inline const std::vector<std::string> kDefaultSearchDomains = {"example.com"};
inline const std::vector<int> kDefaultParams = {
- 300, // sample validity in seconds
- 25, // success threshod in percent
- 8, 8, // {MIN,MAX}_SAMPLES
- 100, // BASE_TIMEOUT_MSEC
- 2, // retry count
+ 300, // sample validity in seconds
+ 25, // success threshod in percent
+ 8, 8, // {MIN,MAX}_SAMPLES
+ 1000, // BASE_TIMEOUT_MSEC
+ 2, // retry count
};
class DnsResponderClient {
diff --git a/resolv/libnetd_resolv_test.cpp b/resolv/libnetd_resolv_test.cpp
index f4812a6..d5b1b73 100644
--- a/resolv/libnetd_resolv_test.cpp
+++ b/resolv/libnetd_resolv_test.cpp
@@ -84,7 +84,8 @@
.success_threshold = 25,
.min_samples = 8,
.max_samples = 8,
- .base_timeout_msec = 100,
+ .base_timeout_msec = 1000,
+ .retry_count = 2,
};
const android_net_context mNetcontext = {
.app_netid = TEST_NETID,
diff --git a/resolv/res_cache.cpp b/resolv/res_cache.cpp
index ad5a2c5..53122f6 100644
--- a/resolv/res_cache.cpp
+++ b/resolv/res_cache.cpp
@@ -46,9 +46,12 @@
#include <netdb.h>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/thread_annotations.h>
#include <android/multinetwork.h> // ResNsendFlags
+#include <server_configurable_flags/get_flags.h>
+
#include "res_state_ext.h"
#include "resolv_private.h"
@@ -1674,6 +1677,22 @@
params->retry_count = 0;
}
+static void resolv_set_experiment_params(res_params* params) {
+ using android::base::ParseInt;
+ using server_configurable_flags::GetServerConfigurableFlag;
+
+ if (params->retry_count == 0) {
+ params->retry_count = RES_DFLRETRY;
+ ParseInt(GetServerConfigurableFlag("netd_native", "retry_count", ""), ¶ms->retry_count);
+ }
+
+ if (params->base_timeout_msec == 0) {
+ params->base_timeout_msec = RES_TIMEOUT;
+ ParseInt(GetServerConfigurableFlag("netd_native", "retransmission_time_interval", ""),
+ ¶ms->base_timeout_msec);
+ }
+}
+
int resolv_set_nameservers_for_net(unsigned netid, const char** servers, const int numservers,
const char* domains, const res_params* params) {
char* cp;
@@ -1717,7 +1736,7 @@
} else {
resolv_set_default_params(&cache_info->params);
}
-
+ resolv_set_experiment_params(&cache_info->params);
if (!resolv_is_nameservers_equal_locked(cache_info, servers, numservers)) {
// free current before adding new
free_nameservers_locked(cache_info);
diff --git a/resolv/res_init.cpp b/resolv/res_init.cpp
index 921445c..7f11ce6 100644
--- a/resolv/res_init.cpp
+++ b/resolv/res_init.cpp
@@ -140,8 +140,6 @@
if (!preinit) {
statp->netid = NETID_UNSET;
- statp->retrans = RES_TIMEOUT;
- statp->retry = RES_DFLRETRY;
statp->options = RES_DEFAULT;
statp->id = arc4random_uniform(65536);
statp->_mark = MARK_UNSET;
@@ -218,27 +216,8 @@
statp->ndots = i;
else
statp->ndots = RES_MAXNDOTS;
-
LOG(DEBUG) << ";;\tndots=" << statp->ndots;
- } else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
- i = atoi(cp + sizeof("timeout:") - 1);
- if (i <= RES_MAXRETRANS)
- statp->retrans = i;
- else
- statp->retrans = RES_MAXRETRANS;
-
- LOG(DEBUG) << ";;\ttimeout=" << statp->retrans;
-
- } else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)) {
- i = atoi(cp + sizeof("attempts:") - 1);
- if (i <= RES_MAXRETRY)
- statp->retry = i;
- else
- statp->retry = RES_MAXRETRY;
-
- LOG(DEBUG) << ";;\tattempts=" << statp->retry;
-
} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
if (!(statp->options & RES_DEBUG)) {
LOG(DEBUG) << ";; res_setoptions(\"" << options << "\", \"" << source << "\")..";
diff --git a/resolv/res_send.cpp b/resolv/res_send.cpp
index 118a081..daa86ec 100644
--- a/resolv/res_send.cpp
+++ b/resolv/res_send.cpp
@@ -512,12 +512,11 @@
int selectedServer = (hp->id % usableServersCount) + 1;
res_set_usable_server(selectedServer, statp->nscount, usable_servers);
}
- if (params.retry_count != 0) statp->retry = params.retry_count;
/*
* Send request, RETRY times, or until successful.
*/
- int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : statp->retry;
+ int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : params.retry_count;
for (int attempt = 0; attempt < retryTimes; ++attempt) {
@@ -685,20 +684,16 @@
static struct timespec get_timeout(const res_state statp, const res_params* params, const int ns) {
int msec;
- if (params->base_timeout_msec != 0) {
- // TODO: scale the timeout by retry attempt and maybe number of servers
- msec = params->base_timeout_msec;
- } else {
- // Legacy algorithm which scales the timeout by nameserver number.
- // For instance, with 4 nameservers: 5s, 2.5s, 5s, 10s
- // This has no effect with 1 or 2 nameservers
- msec = (statp->retrans * 1000) << ns;
- if (ns > 0) {
- msec /= statp->nscount;
- }
- if (msec < 1000) {
- msec = 1000; // Use at least 100ms
- }
+ // Legacy algorithm which scales the timeout by nameserver number.
+ // For instance, with 4 nameservers: 5s, 2.5s, 5s, 10s
+ // This has no effect with 1 or 2 nameservers
+ msec = params->base_timeout_msec << ns;
+ if (ns > 0) {
+ msec /= statp->nscount;
+ }
+ // For safety, don't allow OEMs and experiments to configure a timeout shorter than 1s.
+ if (msec < 1000) {
+ msec = 1000; // Use at least 1000ms
}
LOG(INFO) << "using timeout of " << msec << " msec";
diff --git a/resolv/resolv_private.h b/resolv/resolv_private.h
index 46590b8..9fb0d48 100644
--- a/resolv/resolv_private.h
+++ b/resolv/resolv_private.h
@@ -78,11 +78,9 @@
#define MAXDFLSRCH 3 /* # default domain levels to try */
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
-#define RES_TIMEOUT 5 /* min. seconds between retries */
+#define RES_TIMEOUT 5000 /* min. milliseconds between retries */
#define MAXRESOLVSORT 10 /* number of net to sort on */
#define RES_MAXNDOTS 15 /* should reflect bit field size */
-#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
-#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
#define RES_DFLRETRY 2 /* Default #/tries. */
#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
@@ -90,8 +88,6 @@
struct __res_state {
unsigned netid; /* NetId: cache key and socket mark */
- int retrans; /* retransmission time interval */
- int retry; /* number of times to retransmit */
u_long options; /* option flags - see below. */
int nscount; /* number of name srvers */
struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */