From 3008c3b768f2cb8ab735e8ebbda2d4322910b19e Mon Sep 17 00:00:00 2001
From: Nick Mathewson <nickm@torproject.org>
Date: Wed, 28 Feb 2007 20:24:23 +0000
Subject: [PATCH]  r12000@catbus:  nickm | 2007-02-28 15:12:21 -0500  Try to
 fix eventdns bug 326 again, this time by noting that rcode 2 (serverfailed)
 does not really mean "The server is useless."

svn:r9687
---
 ChangeLog         |  4 ++++
 src/or/eventdns.c | 21 +++++++++++++++------
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5ee17fcd34..f91dd07d05 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,10 @@ Changes in version 0.1.2.9-??? - 2007-??-??
       to INT32_MAX.
     - Fix a potential race condition in the rpm installer.  Found by
       Stefan Nordhausen.
+    - Try to fix eventdns warnings once and for all: do not treat a dns rcode
+      of 2 as indicating that the server is completely bad; it sometimes
+      means that the server is just bad for the request in question. (may fix
+      the last of bug 326.)
 
 
 Changes in version 0.1.2.8-beta - 2007-02-26
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index bb97c31c74..7270df5052 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -696,7 +696,6 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
 		}
 
 		switch(error) {
-		case DNS_ERR_SERVERFAILED:
 		case DNS_ERR_NOTIMPL:
 		case DNS_ERR_REFUSED:
 			// we regard these errors as marking a bad nameserver
@@ -708,6 +707,15 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
 				if (!request_reissue(req)) return;
 			}
 			break;
+		case DNS_ERR_SERVERFAILED:
+			// rcode 2 (servfailed) sometimes means "we are broken" and
+			// sometimes (with some binds) means "that request was very
+			// confusing."  Treat this as a timeout, not a failure.
+			/*XXXX refactor the parts of */
+			log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
+				"will allow the request to time out.",
+				debug_nota(req->ns->address));
+			break;
 		default:
 			// we got a good reply from the nameserver
 			nameserver_up(req->ns);
@@ -1876,9 +1884,9 @@ evdns_request_transmit(struct request *req) {
 	case 2:
 		// failed in some other way
 		retcode = 1;
-		// fall through
+		break;
 	default:
-		// all ok
+		// transmitted; we need to check for timeout.
 		log(EVDNS_LOG_DEBUG,
 			"Setting timeout for request %lx", (unsigned long) req);
 		evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
@@ -1888,10 +1896,11 @@ evdns_request_transmit(struct request *req) {
 				(unsigned long) req);
 			// ???? Do more?
 		}
-		req->tx_count++;
-		req->transmit_me = 0;
-		return retcode;
 	}
+
+	req->tx_count++;
+	req->transmit_me = 0;
+	return retcode;
 }
 
 static void
-- 
GitLab