Support alternative handling on truncated DNS response

The default behavior of UDP truncated DNS response is that the DNS
resolver fallback on TCP on the same server. If the fallback retry is
failed, do TCP retry on the rest of servers. However, OEM reported
that the rest of servers may respond a valid answer on UDP connection,
but support no TCP connection. Thus, an alternative truncated response
handling mode is added for OEMs. With the alternative mode, the DNS
resolver fallback retries on TCP on the same server. If the TCP retry
is failed, do UDP retry on the next server, then TCP, and so on.

Set mode by ResolverExperimentalOptionsParcel in ResolverParamsParcel.
tcMode=0 or absent, run default behavior (TCP-only on each DNS server).
tcMode=1, run alternative mode (UDP first on each DNS server).
other values are invalid input, take no effect.

Bug: 139646101
Change-Id: I724cc54bd9fad95954de84c281dd6f1d0b764caa
diff --git a/res_send.cpp b/res_send.cpp
index 3b088b9..831f27b 100644
--- a/res_send.cpp
+++ b/res_send.cpp
@@ -509,13 +509,21 @@
                 attempt = retryTimes;
                 resplen = send_vc(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &now,
                                   rcode, &delay);
+
+                if (buflen <= PACKETSZ && resplen <= 0 &&
+                    statp->tc_mode == aidl::android::net::IDnsResolver::TC_MODE_UDP_TCP) {
+                    // reset to UDP for next query on next DNS server if resolver is currently doing
+                    // TCP fallback retry and current server does not support TCP connectin
+                    useTcp = false;
+                }
+                LOG(INFO) << __func__ << ": used send_vc " << resplen;
             } else {
                 // UDP
                 resplen = send_dg(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &useTcp,
                                   &gotsomewhere, &now, rcode, &delay);
                 fallbackTCP = useTcp ? true : false;
+                LOG(INFO) << __func__ << ": used send_dg " << resplen;
             }
-            LOG(INFO) << __func__ << ": used send_" << ((useTcp) ? "vc " : "dg ") << resplen;
 
             DnsQueryEvent* dnsQueryEvent = addDnsQueryEvent(statp->event);
             dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(cache_status));