DNS server!
[invirt/packages/invirt-dns.git] / dnsserver.py
1 #!/usr/bin/python
2 from twisted.internet import reactor
3 from twisted.names import server
4 from twisted.names import dns
5 from twisted.names import common
6 from twisted.internet import defer
7 from twisted.python import failure
8
9 import sipb_xen_database
10
11 class DatabaseAuthority(common.ResolverBase):
12     """An Authority that is loaded from a file."""
13
14     soa = None
15
16     def __init__(self, domain, database=None):
17         common.ResolverBase.__init__(self)
18         if database is not None:
19             sipb_xen_database.connect(database)
20         self.domain = domain
21         self.soa = dns.Record_SOA(mname='sipb-xen-dev.mit.edu', 
22                                   rname='sipb-xen.mit.edu',
23                                   serial=1, refresh=3600, retry=900,
24                                   expire=3600000, minimum=21600, ttl=3600)
25     def _lookup(self, name, cls, type, timeout = None):
26         if not (name.lower() == self.domain or 
27                 name.lower().endswith('.'+self.domain)):
28             #Not us
29             return defer.fail(failure.Failure(dns.DomainError(name)))
30         results = []
31         if cls == dns.IN and type in (dns.A, dns.ALL_RECORDS):
32             host = name[:-len(self.domain)-1]
33             value = sipb_xen_database.NIC.get_by(hostname=host)
34             if value is None:
35                 return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
36             ip = value.ip
37             if ip is None:  #Deactivated?
38                 return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
39             ttl = 900
40             record = dns.Record_A(ip, ttl)
41             results.append(dns.RRHeader(name, dns.A, dns.IN, 
42                                         ttl, record, auth=True))
43         authority = []
44         authority.append(dns.RRHeader(self.domain, dns.SOA, dns.IN, 3600,
45                                       self.soa, auth=True))
46         return defer.succeed((results, authority, []))
47         #Doesn't exist
48         return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
49
50 if '__main__' == __name__:
51     resolver = DatabaseAuthority('servers.csail.mit.edu',
52                                  'postgres://sipb-xen@sipb-xen-dev/sipb_xen')
53
54     verbosity = 0
55     f = server.DNSServerFactory(authorities=[resolver], verbose=verbosity)
56     p = dns.DNSDatagramProtocol(f)
57     f.noisy = p.noisy = verbosity
58     
59     reactor.listenUDP(53, p)
60     reactor.listenTCP(53, f)
61     reactor.run()