Implementation of control flags in asynchronous DNS query API
Flags definitions are in multinetwork.h
Test: built, flashed, booted
system/netd/tests/runtests.sh passes
Change-Id: Iab1983b783d1470bc1cf23489abbef7a2d88e860
diff --git a/resolv/res_send.cpp b/resolv/res_send.cpp
index a8b2aeb..21017ac 100644
--- a/resolv/res_send.cpp
+++ b/resolv/res_send.cpp
@@ -388,7 +388,8 @@
return (1);
}
-int res_nsend(res_state statp, const u_char* buf, int buflen, u_char* ans, int anssiz, int* rcode) {
+int res_nsend(res_state statp, const u_char* buf, int buflen, u_char* ans, int anssiz, int* rcode,
+ uint32_t flags) {
int gotsomewhere, terrno, v_circuit, resplen, n;
ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
@@ -404,7 +405,7 @@
terrno = ETIMEDOUT;
int anslen = 0;
- cache_status = _resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen);
+ cache_status = _resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen, flags);
if (cache_status == RESOLV_CACHE_FOUND) {
return anslen;
@@ -417,7 +418,7 @@
// We have no nameservers configured, so there's no point trying.
// Tell the cache the query failed, or any retries and anyone else asking the same
// question will block for PENDING_REQUEST_TIMEOUT seconds instead of failing fast.
- _resolv_cache_query_failed(statp->netid, buf, buflen);
+ _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
// TODO: Remove errno once callers stop using it
errno = ESRCH;
@@ -507,7 +508,9 @@
/*
* Send request, RETRY times, or until successful.
*/
- for (int attempt = 0; attempt < statp->retry; ++attempt) {
+ int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : statp->retry;
+
+ for (int attempt = 0; attempt < retryTimes; ++attempt) {
struct res_stats stats[MAXNS];
struct __res_params params;
int revision_id = resolv_cache_get_resolver_stats(statp->netid, ¶ms, stats);
@@ -539,7 +542,7 @@
return resplen;
}
if (!fallback) {
- _resolv_cache_query_failed(statp->netid, buf, buflen);
+ _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
res_nclose(statp);
return -terrno;
}
@@ -554,7 +557,8 @@
if (v_circuit) {
/* Use VC; at most one attempt per server. */
- attempt = statp->retry;
+ bool shouldRecordStats = (attempt == 0);
+ attempt = retryTimes;
n = send_vc(statp, ¶ms, buf, buflen, ans, anssiz, &terrno, ns, &now, rcode,
&delay);
@@ -564,7 +568,7 @@
* queries that deterministically fail (e.g., a name that always returns
* SERVFAIL or times out) do not unduly affect the stats.
*/
- if (attempt == 0) {
+ if (shouldRecordStats) {
res_sample sample;
_res_stats_set_sample(&sample, now, *rcode, delay);
_resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, ns, &sample,
@@ -574,7 +578,7 @@
VLOG << "used send_vc " << n;
if (n < 0) {
- _resolv_cache_query_failed(statp->netid, buf, buflen);
+ _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
res_nclose(statp);
return -terrno;
};
@@ -598,7 +602,7 @@
VLOG << "used send_dg " << n;
if (n < 0) {
- _resolv_cache_query_failed(statp->netid, buf, buflen);
+ _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
res_nclose(statp);
return -terrno;
};
@@ -645,7 +649,7 @@
} else {
errno = terrno;
}
- _resolv_cache_query_failed(statp->netid, buf, buflen);
+ _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
return -terrno;
}
@@ -1314,11 +1318,11 @@
}
}
-int resolv_res_nsend(const android_net_context* netContext, const u_char* msg, int msgLen,
- u_char* ans, int ansLen, int* rcode) {
+int resolv_res_nsend(const android_net_context* netContext, const uint8_t* msg, int msgLen,
+ uint8_t* ans, int ansLen, int* rcode, uint32_t flags) {
res_state res = res_get_state();
res_setnetcontext(res, netContext);
_resolv_populate_res_for_net(res);
*rcode = NOERROR;
- return res_nsend(res, msg, msgLen, ans, ansLen, rcode);
-}
+ return res_nsend(res, msg, msgLen, ans, ansLen, rcode, flags);
+}
\ No newline at end of file