import sqlalchemy
import time
import re
+import sys
class DatabaseAuthority(common.ResolverBase):
"""An Authority that is loaded from a file."""
L.append(split_line)
return filter(None, L)
+ # See https://twistedmatrix.com/documents/13.1.0/api/twisted.internet.defer.html#inlineCallbacks
+ @defer.inlineCallbacks
def _lookup(self, name, cls, type, timeout = None):
- maybeDelegate = False
- deferredResult = authority.BindAuthority._lookup(self, name, cls,
- type, timeout)
- # If we didn't find an exact match for the name we were seeking,
- # check if it's within a subdomain we're supposed to delegate to
- # some other DNS server.
- while (isinstance(deferredResult.result, failure.Failure)
- and '.' in name):
- maybeDelegate = True
- name = name[name.find('.') + 1 :]
- deferredResult = authority.BindAuthority._lookup(self, name, cls,
- dns.NS, timeout)
- return deferredResult
+ try:
+ result = yield authority.BindAuthority._lookup(self, name, cls,
+ type, timeout)
+ defer.returnValue(result)
+ except Exception as e:
+ # XXX: Twisted returns DomainError even if it is
+ # authoritative for the domain because our SOA record
+ # incorrectly contains (origin + "." + origin)
+ if not isinstance(e, (dns.DomainError, dns.AuthoritativeDomainError)):
+ sys.stderr.write("while looking up '%s', got: %s\n" % (name, e))
+
+ # If we didn't find an exact match for the name we were
+ # seeking, check if it's within a subdomain we're supposed
+ # to delegate to some other DNS server.
+ while '.' in name:
+ _, name = name.split('.', 1)
+ try:
+ # BindAuthority puts the NS in the authority
+ # section automatically for us, so just return
+ # it. We override the type to NS.
+ result = yield authority.BindAuthority._lookup(self, name, cls,
+ dns.NS, timeout)
+ defer.returnValue(result)
+ except Exception: # Should be one of (dns.DomainError, dns.AuthoritativeDomainError)
+ pass
+ # We didn't find a delegation, so return the original
+ # NXDOMAIN.
+ raise
class TypeLenientResolverChain(resolve.ResolverChain):
"""
r = DelegatingQuotingBindAuthority(zone)
# This sucks, but if I want a generic zone file, I have to
# reload the information by hand
+ # XXX: This causes our SOA record to contain
+ # (origin + "." + origin)
+ # As a result the resolver never believes it is authoritative.
r.origin = origin
lines = open(zone).readlines()
lines = r.collapseContinuations(r.stripComments(lines))