refactor DNS logic; fix some bugs in reverse-resolution
authorGreg Price <price@mit.edu>
Fri, 27 Feb 2009 09:38:26 +0000 (04:38 -0500)
committerGreg Price <price@mit.edu>
Fri, 27 Feb 2009 09:38:26 +0000 (04:38 -0500)
Namely, stop returning answers to A and NS queries on *.in-addr.arpa.

I found these bugs because I was simplifying the logic, after the
author had said it was correct and he and another developer had
tested it.  This is why it matters to get the code clear.

svn path=/trunk/packages/invirt-dns/; revision=2208

invirt-dns

index 32b18c2..1744ac8 100755 (executable)
@@ -82,11 +82,27 @@ class DatabaseAuthority(common.ResolverBase):
                                       3600, self.ns, auth=True))
 
         if cls == dns.IN:
-            host = name[:-len(domain)-1]
-            if not host and type != dns.PTR: # Request for the domain itself.
+            if name.endswith(".in-addr.arpa"):
+                if type in (dns.PTR, dns.ALL_RECORDS):
+                    ip = '.'.join(reversed(name.split('.')[:-2]))
+                    value = invirt.database.NIC.query.filter_by(ip=ip).first()
+                    if value and value.hostname:
+                        hostname = value.hostname
+                        if '.' not in hostname:
+                            hostname = hostname + "." + config.dns.domains[0]
+                        record = dns.Record_PTR(hostname, ttl)
+                        results.append(dns.RRHeader(name, dns.PTR, dns.IN,
+                                                    ttl, record, auth=True))
+                    else: # IP address doesn't point to an active host
+                        return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
+                elif type == dns.SOA:
+                    results.append(dns.RRHeader(domain, dns.SOA, dns.IN,
+                                                ttl, self.soa, auth=True))
+                # FIXME: Should only return success with no records if the name actually exists
+            elif name == domain or name == '.'+domain:
                 if type in (dns.A, dns.ALL_RECORDS):
                     record = dns.Record_A(config.dns.nameservers[0].ip, ttl)
-                    results.append(dns.RRHeader(name, dns.A, dns.IN, 
+                    results.append(dns.RRHeader(name, dns.A, dns.IN,
                                                 ttl, record, auth=True))
                 elif type == dns.NS:
                     results.append(dns.RRHeader(domain, dns.NS, dns.IN,
@@ -95,42 +111,28 @@ class DatabaseAuthority(common.ResolverBase):
                 elif type == dns.SOA:
                     results.append(dns.RRHeader(domain, dns.SOA, dns.IN,
                                                 ttl, self.soa, auth=True))
-            else: # Request for a subdomain.
-                if name.endswith(".in-addr.arpa"): # Reverse resolution here
-                    if type in (dns.PTR, dns.ALL_RECORDS):
-                        ip = '.'.join(reversed(name.split('.')[:-2]))
-                        value = invirt.database.NIC.query.filter_by(ip=ip).first()
-                        if value and value.hostname:
-                            hostname = value.hostname
-                            if '.' not in hostname:
-                                hostname = hostname + "." + config.dns.domains[0]
-                            record = dns.Record_PTR(hostname, ttl)
-                            results.append(dns.RRHeader(name, dns.PTR, dns.IN,
-                                                        ttl, record, auth=True))
-                        else: # IP address doesn't point to an active host
-                            return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
-                    # FIXME: Should only return success with no records if the name actually exists
-                else: # Forward resolution here
-                    value = invirt.database.NIC.query.filter_by(hostname=host).first()
+            else:
+                host = name[:-len(domain)-1]
+                value = invirt.database.NIC.query.filter_by(hostname=host).first()
+                if value:
+                    ip = value.ip
+                else:
+                    value = invirt.database.Machine.query().filter_by(name=host).first()
                     if value:
-                        ip = value.ip
+                        ip = value.nics[0].ip
                     else:
-                        value = invirt.database.Machine.query().filter_by(name=host).first()
-                        if value:
-                            ip = value.nics[0].ip
-                        else:
-                            return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
-                
-                    if ip is None:
                         return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
 
-                    if type in (dns.A, dns.ALL_RECORDS):
-                        record = dns.Record_A(ip, ttl)
-                        results.append(dns.RRHeader(name, dns.A, dns.IN, 
-                                                    ttl, record, auth=True))
-                    elif type == dns.SOA:
-                        results.append(dns.RRHeader(domain, dns.SOA, dns.IN,
-                                                    ttl, self.soa, auth=True))
+                if ip is None:
+                    return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
+
+                if type in (dns.A, dns.ALL_RECORDS):
+                    record = dns.Record_A(ip, ttl)
+                    results.append(dns.RRHeader(name, dns.A, dns.IN,
+                                                ttl, record, auth=True))
+                elif type == dns.SOA:
+                    results.append(dns.RRHeader(domain, dns.SOA, dns.IN,
+                                                ttl, self.soa, auth=True))
             if len(results) == 0:
                 authority = []
                 additional = []