Be tolerant of requests for unimplemented record types.
authorMitchell E Berger <mitchb@mit.edu>
Sat, 4 Oct 2014 18:19:20 +0000 (14:19 -0400)
committerMitchell E Berger <mitchb@mit.edu>
Sat, 4 Oct 2014 18:19:20 +0000 (14:19 -0400)
Fixes: Anders's home router
Resolves: LP#1376373

debian/changelog
invirt-dns

index 1e721c4..5615a20 100644 (file)
@@ -1,3 +1,12 @@
+invirt-dns (0.0.16) precise; urgency=low
+
+  * Be tolerant of requests for record types that have not been
+    implemented by Twisted yet - instead of returning SERVFAIL,
+    return either NXDOMAIN or an empty result set with NOERROR
+    as appropriate depending on whether the name exists in our zones.
+
+ -- Mitchell Berger <mitchb@mit.edu>  Sat, 04 Oct 2014 14:10:00 - 0400
+
 invirt-dns (0.0.15) precise; urgency=low
 
   * Updating version for precise migration.
index c320e51..8cd8337 100755 (executable)
@@ -4,6 +4,7 @@ from twisted.names import server
 from twisted.names import dns
 from twisted.names import common
 from twisted.names import authority
+from twisted.names import resolve
 from twisted.internet import defer
 from twisted.python import failure
 
@@ -220,6 +221,26 @@ class DelegatingQuotingBindAuthority(authority.BindAuthority):
             deferredResult = defer.succeed(([], nsResults, nsAdditional))
         return deferredResult
 
+class TypeLenientResolverChain(resolve.ResolverChain):
+    """
+    This is a ResolverChain which is more lenient in its handling of
+    queries requesting unimplemented record types.
+    """
+
+    def query(self, query, timeout = None):
+        try:
+            return self.typeToMethod[query.type](str(query.name), timeout)
+        except KeyError, e:
+            # We don't support the requested record type.  Twisted would
+            # have us return SERVFAIL.  Instead, we'll check whether the
+            # name exists in our zone at all and return NXDOMAIN or an empty
+            # result set with NOERROR as appropriate.
+            deferredResult = self.lookupAllRecords(str(query.name), timeout)
+            if isinstance(deferredResult.result, failure.Failure):
+                return deferredResult
+            (results, authority, additional) = deferredResult.result
+            return defer.succeed(([], authority, additional))
+
 if '__main__' == __name__:
     resolvers = []
     try:
@@ -240,7 +261,8 @@ if '__main__' == __name__:
     resolvers.append(DatabaseAuthority())
 
     verbosity = 0
-    f = server.DNSServerFactory(authorities=resolvers, verbose=verbosity)
+    f = server.DNSServerFactory(verbose=verbosity)
+    f.resolver = TypeLenientResolverChain(resolvers)
     p = dns.DNSDatagramProtocol(f)
     f.noisy = p.noisy = verbosity