Do SERVFAIL, therefore continue when searching for DS in TCP path too.
diff --git a/src/forward.c b/src/forward.c
index 941f80d..81ae3ee 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1453,8 +1453,13 @@
 	      newhash = hash_questions(header, (unsigned int)m, name);
 	      if (newhash && memcmp(hash, newhash, HASH_SIZE) == 0)
 		{
-		  /* Note this trashes all three name workspaces */
-		  status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount);
+		   /* In this case only, a SERVFAIL reply allows us to continue up the tree, looking for a 
+		      suitable NSEC reply to DS queries. */
+		  if (RCODE(header) == SERVFAIL)
+		    status = STAT_INSECURE;
+		  else
+		    /* Note this trashes all three name workspaces */
+		    status = tcp_key_recurse(now, STAT_NEED_DS_NEG, header, m, class, name, keyname, server, keycount);
 		  
 		  /* We've found a DS which proves the bit of the DNS where the
 		     original query is, is unsigned, so the answer is OK, 
@@ -1830,6 +1835,10 @@
 			}
 		      
 		      *length = htons(size);
+
+		      /* get query name again for logging - may have been overwritten */
+		      if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
+			strcpy(daemon->namebuff, "query");
 		      
 		      if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) ||
 			  !read_write(last_server->tcpfd, &c1, 1, 1) ||
@@ -1843,8 +1852,6 @@
 		      
 		      m = (c1 << 8) | c2;
 		      
-		      if (!gotname)
-			strcpy(daemon->namebuff, "query");
 		      if (last_server->addr.sa.sa_family == AF_INET)
 			log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
 				  (struct all_addr *)&last_server->addr.in.sin_addr, NULL);