Fix potential bugs that may cause resolver to retry endlessly

[1] If DNS-over-TLS validation success, but server does not
respond to DNS-over-TLS query after a while (the server can still
respond to DNS-over-UDP). Then, query a non-exist domain.

[2] If DNS-over-TLS validation success, but server does not
respond to DNS-over-TLS query after a while. Also, the server always
responds RCODE=RES_F_EDNS0ERR on DNS-over-UDP.

These strange network behaviors should not happen. However, once they
happen (maybe by bogus servers), the resolver should be able to handle
it gracefully.

Bug: 120910570
Test: runtests.sh pass
Change-Id: I7e3044e012303a7991b04e7d38e55340e2a5db1a
diff --git a/resolv/res_query.cpp b/resolv/res_query.cpp
index 4ae13bf..acf6160 100644
--- a/resolv/res_query.cpp
+++ b/resolv/res_query.cpp
@@ -117,10 +117,8 @@
     u_char buf[MAXPACKET];
     HEADER* hp = (HEADER*) (void*) answer;
     int n;
-    u_int oflags;
     int rcode = NOERROR;
-
-    oflags = statp->_flags;
+    bool retried = false;
 
 again:
     hp->rcode = NOERROR; /* default */
@@ -130,8 +128,7 @@
 #endif
 
     n = res_nmkquery(statp, QUERY, name, cl, type, NULL, 0, NULL, buf, sizeof(buf));
-    if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 &&
-        (statp->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0U)
+    if (n > 0 && (statp->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0U && !retried)
         n = res_nopt(statp, n, buf, sizeof(buf), anslen);
     if (n <= 0) {
 #ifdef DEBUG
@@ -144,9 +141,9 @@
     if (n < 0) {
         /* if the query choked with EDNS0, retry without EDNS0 */
         if ((statp->options & (RES_USE_EDNS0 | RES_USE_DNSSEC)) != 0U &&
-            ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
-            statp->_flags |= RES_F_EDNS0ERR;
+            (statp->_flags & RES_F_EDNS0ERR) && !retried) {
             if (statp->options & RES_DEBUG) printf(";; res_nquery: retry without EDNS0\n");
+            retried = true;
             goto again;
         }
 #ifdef DEBUG