about summary refs log tree commit diff
path: root/resolv/res_query.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-02-09 23:46:29 +0000
committerUlrich Drepper <drepper@redhat.com>2007-02-09 23:46:29 +0000
commit2bbb7d5b3c517956e95e5827037a76cbc39a20c8 (patch)
treee5d2f14edf74a9e9992ebe907e5feffd9dca7c7e /resolv/res_query.c
parent00458b5bee15b31f90bca83c79f29e168f04ecc8 (diff)
downloadglibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.tar.gz
glibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.tar.xz
glibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.zip
* resolv/res_init.c (res_setoptions): Recognize edns0 option.
	* resolv/res_mkquery.c: Define __res_nopt.
	* resolv/res_query.c (__libc_res_nquery): If RES_USE_EDNS0 is set
	try adding EDNS0 record.
	* resolv/res_send.c (send_dg): If request failed with FORMERR and
	EDNS0 record was send make sure we don't try it again.
	* resolv/resolv.h: Define RES_F_EDNS0ERR and RES_USE_EDNS0.
	* include/resolv.h: Declare __res_nopt.
Diffstat (limited to 'resolv/res_query.c')
-rw-r--r--resolv/res_query.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 85bad97d2d..4371af5b05 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -120,10 +120,13 @@ __libc_res_nquery(res_state statp,
 	u_char *buf;
 	HEADER *hp = (HEADER *) answer;
 	int n, use_malloc = 0;
+        u_int oflags = statp->_flags;
 
-	hp->rcode = NOERROR;	/* default */
+	size_t bufsize = QUERYSIZE;
+	buf = alloca (bufsize);
 
-	buf = alloca (QUERYSIZE);
+ again:
+	hp->rcode = NOERROR;	/* default */
 
 #ifdef DEBUG
 	if (statp->options & RES_DEBUG)
@@ -131,18 +134,30 @@ __libc_res_nquery(res_state statp,
 #endif
 
 	n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
-			 buf, QUERYSIZE);
-	if (__builtin_expect (n <= 0, 0)) {
+			 buf, bufsize);
+	if (n > 0
+	    && (oflags & RES_F_EDNS0ERR) == 0
+	    && (statp->options & RES_USE_EDNS0) != 0)
+		n = __res_nopt(statp, n, buf, bufsize, anslen);
+	if (__builtin_expect (n <= 0, 0) && !use_malloc) {
 		/* Retry just in case res_nmkquery failed because of too
 		   short buffer.  Shouldn't happen.  */
-		buf = malloc (MAXPACKET);
+		bufsize = MAXPACKET;
+		buf = malloc (bufsize);
 		if (buf != NULL) {
 			use_malloc = 1;
-			n = res_nmkquery(statp, QUERY, name, class, type, NULL,
-					 0, NULL, buf, MAXPACKET);
+			goto again;
 		}
 	}
 	if (__builtin_expect (n <= 0, 0)) {
+		/* If the query choked with EDNS0, retry without EDNS0.  */
+		if ((statp->options & RES_USE_EDNS0) != 0
+		    && ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
+			statp->_flags |= RES_F_EDNS0ERR;
+			if (statp->options & RES_DEBUG)
+				printf(";; res_nquery: retry without EDNS0\n");
+                        goto again;
+		}
 #ifdef DEBUG
 		if (statp->options & RES_DEBUG)
 			printf(";; res_query: mkquery failed\n");