root / trunk / twisted / names / secondary.py

Revision 16333, 3.1 kB (checked in by exarkun, 3 years ago)

Merge names-whitespace-1583

Author: exarkun
Reviewer: radix
Fixes #1583

This removes a bunch of trailing whitespace and adds some missing copyright
headers.

Line 
1 # Copyright (c) 2001-2006 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 from twisted.internet import task, defer
5 from twisted.names import dns
6 from twisted.names import common
7 from twisted.names import client
8 from twisted.names import resolve
9 from twisted.python import log, failure
10 from twisted.application import service
11
12 class SecondaryAuthorityService(service.Service):
13     calls = None
14
15     def __init__(self, primary, domains):
16         """
17         @param primary: The IP address of the server from which to perform
18         zone transfers.
19
20         @param domains: A sequence of domain names for which to perform
21         zone transfers.
22         """
23         self.primary = primary
24         self.domains = [SecondaryAuthority(primary, d) for d in domains]
25
26     def getAuthority(self):
27         return resolve.ResolverChain(self.domains)
28
29     def startService(self):
30         service.Service.startService(self)
31         self.calls = [task.LoopingCall(d.transfer) for d in self.domains]
32         i = 0
33         from twisted.internet import reactor
34         for c in self.calls:
35             # XXX Add errbacks, respect proper timeouts
36             reactor.callLater(i, c.start, 60 * 60)
37             i += 1
38
39     def stopService(self):
40         service.Service.stopService(self)
41         for c in self.calls:
42             c.stop()
43
44
45 from twisted.names.authority import FileAuthority
46
47 class SecondaryAuthority(common.ResolverBase):
48     """An Authority that keeps itself updated by performing zone transfers"""
49
50     transferring = False
51
52     soa = records = None
53     def __init__(self, primaryIP, domain):
54         common.ResolverBase.__init__(self)
55         self.primary = primaryIP
56         self.domain = domain
57
58     def transfer(self):
59         if self.transferring:
60             return
61         self.transfering = True
62         return client.Resolver(servers=[(self.primary, dns.PORT)]
63             ).lookupZone(self.domain
64             ).addCallback(self._cbZone
65             ).addErrback(self._ebZone
66             )
67
68
69     def _lookup(self, name, cls, type, timeout=None):
70         if not self.soa or not self.records:
71             return defer.fail(failure.Failure(dns.DomainError(name)))
72
73
74         return FileAuthority.__dict__['_lookup'](self, name, cls, type, timeout)
75
76     #shouldn't we just subclass? :P
77
78     lookupZone = FileAuthority.__dict__['lookupZone']
79
80     def _cbZone(self, zone):
81         ans, _, _ = zone
82         self.records = r = {}
83         for rec in ans:
84             if not self.soa and rec.type == dns.SOA:
85                 self.soa = (str(rec.name).lower(), rec.payload)
86             else:
87                 r.setdefault(str(rec.name).lower(), []).append(rec.payload)
88
89     def _ebZone(self, failure):
90         log.msg("Updating %s from %s failed during zone transfer" % (self.domain, self.primary))
91         log.err(failure)
92
93     def update(self):
94         self.transfer().addCallbacks(self._cbTransferred, self._ebTransferred)
95
96     def _cbTransferred(self, result):
97         self.transferring = False
98
99     def _ebTransferred(self, failure):
100         self.transferred = False
101         log.msg("Transferring %s from %s failed after zone transfer" % (self.domain, self.primary))
102         log.err(failure)
Note: See TracBrowser for help on using the browser.