1
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2
# See LICENSE for details.
11
from twisted.python import usage
12
from twisted.names import dns
13
from twisted.application import internet, service
15
from twisted.names import server
16
from twisted.names import authority
17
from twisted.names import secondary
19
class Options(usage.Options):
21
["interface", "i", "", "The interface to which to bind"],
22
["port", "p", "53", "The port on which to listen"],
23
["resolv-conf", None, None,
24
"Override location of resolv.conf (implies --recursive)"],
25
["hosts-file", None, None, "Perform lookups with a hosts file"],
29
["cache", "c", "Enable record caching"],
30
["recursive", "r", "Perform recursive lookups"],
31
["verbose", "v", "Log verbosely"],
38
usage.Options.__init__(self)
45
def opt_pyzone(self, filename):
46
"""Specify the filename of a Python syntax zone definition"""
47
if not os.path.exists(filename):
48
raise usage.UsageError(filename + ": No such file")
49
self.zonefiles.append(filename)
51
def opt_bindzone(self, filename):
52
"""Specify the filename of a BIND9 syntax zone definition"""
53
if not os.path.exists(filename):
54
raise usage.UsageError(filename + ": No such file")
55
self.bindfiles.append(filename)
58
def opt_secondary(self, ip_domain):
59
"""Act as secondary for the specified domain, performing
60
zone transfers from the specified IP (IP/domain)
62
args = ip_domain.split('/', 1)
64
raise usage.UsageError("Argument must be of the form IP/domain")
65
self.secondaries.append((args[0], [args[1]]))
67
def opt_verbose(self):
68
"""Increment verbosity level"""
72
def postOptions(self):
73
if self['resolv-conf']:
74
self['recursive'] = True
78
for f in self.zonefiles:
80
self.zones.append(authority.PySourceAuthority(f))
83
raise usage.UsageError("Invalid syntax in " + f)
84
for f in self.bindfiles:
86
self.zones.append(authority.BindAuthority(f))
89
raise usage.UsageError("Invalid syntax in " + f)
90
for f in self.secondaries:
91
self.svcs.append(secondary.SecondaryAuthorityService(*f))
92
self.zones.append(self.svcs[-1].getAuthority())
94
self['port'] = int(self['port'])
96
raise usage.UsageError("Invalid port: %r" % (self['port'],))
99
def makeService(config):
100
import client, cache, hosts
104
ca.append(cache.CacheResolver(verbose=config['verbose']))
105
if config['recursive']:
106
cl.append(client.createResolver(resolvconf=config['resolv-conf']))
107
if config['hosts-file']:
108
cl.append(hosts.Resolver(file=config['hosts-file']))
110
f = server.DNSServerFactory(config.zones, ca, cl, config['verbose'])
111
p = dns.DNSDatagramProtocol(f)
113
ret = service.MultiService()
114
for (klass, arg) in [(internet.TCPServer, f), (internet.UDPServer, p)]:
115
s = klass(config['port'], arg, interface=config['interface'])
116
s.setServiceParent(ret)
117
for svc in config.svcs:
118
svc.setServiceParent(ret)