--- djbdns-1.05-original/tdlookup.c	Sun Feb 11 21:11:45 2001
+++ djbdns-1.05/tdlookup.c	Thu Apr  3 11:56:47 2003
@@ -103,12 +103,13 @@
   return response_addname(d1);
 }
 
-static int doit(char *q,char qtype[2])
+static int doit1(char **pqname,char qtype[2])
 {
   unsigned int bpos;
   unsigned int anpos;
   unsigned int aupos;
   unsigned int arpos;
+  char *q;
   char *control;
   char *wild;
   int flaggavesoa;
@@ -122,6 +123,12 @@
   int addrnum;
   uint32 addrttl;
   int i;
+  int loop = 0 ;
+
+RESTART:
+  if (loop++ >= 100) return 0 ;
+
+  q = *pqname ;
 
   anpos = response_len;
 
@@ -136,7 +143,14 @@
       if (byte_equal(type,2,DNS_T_NS)) flagns = 1;
     }
     if (flagns) break;
-    if (!*control) return 0; /* q is not within our bailiwick */
+    if (!*control) { /* q is not within our bailiwick */
+      if (loop <= 1)
+        return 0 ;
+      else {
+        response[2] &= ~4;
+        goto DONE; /* The administrator has issued contradictory instructions */
+      }
+    }
     control += *control;
     control += 1;
   }
@@ -172,8 +186,16 @@
 	continue;
       }
       if (!response_rstart(q,type,ttl)) return 0;
-      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) {
+      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_PTR)) {
+	if (!doname()) return 0;
+      }
+      else if (byte_equal(type,2,DNS_T_CNAME)) {
 	if (!doname()) return 0;
+        if (byte_diff(type,2,qtype)) {
+	  response_rfinish(RESPONSE_ANSWER);
+	  if (!dns_domain_copy(pqname,d1)) return 0 ;
+	  goto RESTART ;
+	}
       }
       else if (byte_equal(type,2,DNS_T_MX)) {
 	if (!dobytes(2)) return 0;
@@ -275,9 +297,21 @@
     }
   }
 
+DONE:
   return 1;
 }
 
+static int doit(char *qname,char qtype[2])
+{
+  int r ;
+  char * q = 0 ;
+
+  if (!dns_domain_copy(&q, qname)) return 0 ;
+  r = doit1(&q, qtype) ;
+  dns_domain_free(&q) ;
+  return r ;
+}
+
 int respond(char *q,char qtype[2],char ip[4])
 {
   int fd;