~blamar/+junk/openstack-api-arrrg

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/names/common.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.names.test -*-
 
2
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
"""
 
6
Base functionality useful to various parts of Twisted Names.
 
7
"""
 
8
 
 
9
import socket
 
10
 
 
11
from twisted.names import dns
 
12
from twisted.names.error import DNSFormatError, DNSServerError, DNSNameError
 
13
from twisted.names.error import DNSNotImplementedError, DNSQueryRefusedError
 
14
from twisted.names.error import DNSUnknownError
 
15
 
 
16
from twisted.internet import defer, error
 
17
from twisted.python import failure
 
18
 
 
19
EMPTY_RESULT = (), (), ()
 
20
 
 
21
class ResolverBase:
 
22
    """
 
23
    L{ResolverBase} is a base class for L{IResolver} implementations which
 
24
    deals with a lot of the boilerplate of implementing all of the lookup
 
25
    methods.
 
26
 
 
27
    @cvar _errormap: A C{dict} mapping DNS protocol failure response codes
 
28
        to exception classes which will be used to represent those failures.
 
29
    """
 
30
    _errormap = {
 
31
        dns.EFORMAT: DNSFormatError,
 
32
        dns.ESERVER: DNSServerError,
 
33
        dns.ENAME: DNSNameError,
 
34
        dns.ENOTIMP: DNSNotImplementedError,
 
35
        dns.EREFUSED: DNSQueryRefusedError}
 
36
 
 
37
    typeToMethod = None
 
38
 
 
39
    def __init__(self):
 
40
        self.typeToMethod = {}
 
41
        for (k, v) in typeToMethod.items():
 
42
            self.typeToMethod[k] = getattr(self, v)
 
43
 
 
44
 
 
45
    def exceptionForCode(self, responseCode):
 
46
        """
 
47
        Convert a response code (one of the possible values of
 
48
        L{dns.Message.rCode} to an exception instance representing it.
 
49
 
 
50
        @since: 10.0
 
51
        """
 
52
        return self._errormap.get(responseCode, DNSUnknownError)
 
53
 
 
54
 
 
55
    def query(self, query, timeout = None):
 
56
        try:
 
57
            return self.typeToMethod[query.type](str(query.name), timeout)
 
58
        except KeyError, e:
 
59
            return defer.fail(failure.Failure(NotImplementedError(str(self.__class__) + " " + str(query.type))))
 
60
 
 
61
    def _lookup(self, name, cls, type, timeout):
 
62
        return defer.fail(NotImplementedError("ResolverBase._lookup"))
 
63
 
 
64
    def lookupAddress(self, name, timeout = None):
 
65
        """
 
66
        @see: twisted.names.client.lookupAddress
 
67
        """
 
68
        return self._lookup(name, dns.IN, dns.A, timeout)
 
69
 
 
70
    def lookupIPV6Address(self, name, timeout = None):
 
71
        """
 
72
        @see: twisted.names.client.lookupIPV6Address
 
73
        """
 
74
        return self._lookup(name, dns.IN, dns.AAAA, timeout)
 
75
 
 
76
    def lookupAddress6(self, name, timeout = None):
 
77
        """
 
78
        @see: twisted.names.client.lookupAddress6
 
79
        """
 
80
        return self._lookup(name, dns.IN, dns.A6, timeout)
 
81
 
 
82
    def lookupMailExchange(self, name, timeout = None):
 
83
        """
 
84
        @see: twisted.names.client.lookupMailExchange
 
85
        """
 
86
        return self._lookup(name, dns.IN, dns.MX, timeout)
 
87
 
 
88
    def lookupNameservers(self, name, timeout = None):
 
89
        """
 
90
        @see: twisted.names.client.lookupNameservers
 
91
        """
 
92
        return self._lookup(name, dns.IN, dns.NS, timeout)
 
93
 
 
94
    def lookupCanonicalName(self, name, timeout = None):
 
95
        """
 
96
        @see: twisted.names.client.lookupCanonicalName
 
97
        """
 
98
        return self._lookup(name, dns.IN, dns.CNAME, timeout)
 
99
 
 
100
    def lookupMailBox(self, name, timeout = None):
 
101
        """
 
102
        @see: twisted.names.client.lookupMailBox
 
103
        """
 
104
        return self._lookup(name, dns.IN, dns.MB, timeout)
 
105
 
 
106
    def lookupMailGroup(self, name, timeout = None):
 
107
        """
 
108
        @see: twisted.names.client.lookupMailGroup
 
109
        """
 
110
        return self._lookup(name, dns.IN, dns.MG, timeout)
 
111
 
 
112
    def lookupMailRename(self, name, timeout = None):
 
113
        """
 
114
        @see: twisted.names.client.lookupMailRename
 
115
        """
 
116
        return self._lookup(name, dns.IN, dns.MR, timeout)
 
117
 
 
118
    def lookupPointer(self, name, timeout = None):
 
119
        """
 
120
        @see: twisted.names.client.lookupPointer
 
121
        """
 
122
        return self._lookup(name, dns.IN, dns.PTR, timeout)
 
123
 
 
124
    def lookupAuthority(self, name, timeout = None):
 
125
        """
 
126
        @see: twisted.names.client.lookupAuthority
 
127
        """
 
128
        return self._lookup(name, dns.IN, dns.SOA, timeout)
 
129
 
 
130
    def lookupNull(self, name, timeout = None):
 
131
        """
 
132
        @see: twisted.names.client.lookupNull
 
133
        """
 
134
        return self._lookup(name, dns.IN, dns.NULL, timeout)
 
135
 
 
136
    def lookupWellKnownServices(self, name, timeout = None):
 
137
        """
 
138
        @see: twisted.names.client.lookupWellKnownServices
 
139
        """
 
140
        return self._lookup(name, dns.IN, dns.WKS, timeout)
 
141
 
 
142
    def lookupService(self, name, timeout = None):
 
143
        """
 
144
        @see: twisted.names.client.lookupService
 
145
        """
 
146
        return self._lookup(name, dns.IN, dns.SRV, timeout)
 
147
 
 
148
    def lookupHostInfo(self, name, timeout = None):
 
149
        """
 
150
        @see: twisted.names.client.lookupHostInfo
 
151
        """
 
152
        return self._lookup(name, dns.IN, dns.HINFO, timeout)
 
153
 
 
154
    def lookupMailboxInfo(self, name, timeout = None):
 
155
        """
 
156
        @see: twisted.names.client.lookupMailboxInfo
 
157
        """
 
158
        return self._lookup(name, dns.IN, dns.MINFO, timeout)
 
159
 
 
160
    def lookupText(self, name, timeout = None):
 
161
        """
 
162
        @see: twisted.names.client.lookupText
 
163
        """
 
164
        return self._lookup(name, dns.IN, dns.TXT, timeout)
 
165
 
 
166
    def lookupResponsibility(self, name, timeout = None):
 
167
        """
 
168
        @see: twisted.names.client.lookupResponsibility
 
169
        """
 
170
        return self._lookup(name, dns.IN, dns.RP, timeout)
 
171
 
 
172
    def lookupAFSDatabase(self, name, timeout = None):
 
173
        """
 
174
        @see: twisted.names.client.lookupAFSDatabase
 
175
        """
 
176
        return self._lookup(name, dns.IN, dns.AFSDB, timeout)
 
177
 
 
178
    def lookupZone(self, name, timeout = None):
 
179
        """
 
180
        @see: twisted.names.client.lookupZone
 
181
        """
 
182
        return self._lookup(name, dns.IN, dns.AXFR, timeout)
 
183
 
 
184
 
 
185
    def lookupNamingAuthorityPointer(self, name, timeout=None):
 
186
        """
 
187
        @see: twisted.names.client.lookupNamingAuthorityPointer
 
188
        """
 
189
        return self._lookup(name, dns.IN, dns.NAPTR, timeout)
 
190
 
 
191
 
 
192
    def lookupAllRecords(self, name, timeout = None):
 
193
        """
 
194
        @see: twisted.names.client.lookupAllRecords
 
195
        """
 
196
        return self._lookup(name, dns.IN, dns.ALL_RECORDS, timeout)
 
197
 
 
198
    def getHostByName(self, name, timeout = None, effort = 10):
 
199
        """
 
200
        @see: twisted.names.client.getHostByName
 
201
        """
 
202
        # XXX - respect timeout
 
203
        return self.lookupAllRecords(name, timeout
 
204
            ).addCallback(self._cbRecords, name, effort
 
205
            )
 
206
 
 
207
    def _cbRecords(self, (ans, auth, add), name, effort):
 
208
        result = extractRecord(self, dns.Name(name), ans + auth + add, effort)
 
209
        if not result:
 
210
            raise error.DNSLookupError(name)
 
211
        return result
 
212
 
 
213
def extractRecord(resolver, name, answers, level = 10):
 
214
    if not level:
 
215
        return None
 
216
    if hasattr(socket, 'inet_ntop'):
 
217
        for r in answers:
 
218
            if r.name == name and r.type == dns.A6:
 
219
                return socket.inet_ntop(socket.AF_INET6, r.payload.address)
 
220
        for r in answers:
 
221
            if r.name == name and r.type == dns.AAAA:
 
222
                return socket.inet_ntop(socket.AF_INET6, r.payload.address)
 
223
    for r in answers:
 
224
        if r.name == name and r.type == dns.A:
 
225
            return socket.inet_ntop(socket.AF_INET, r.payload.address)
 
226
    for r in answers:
 
227
        if r.name == name and r.type == dns.CNAME:
 
228
            result = extractRecord(resolver, r.payload.name, answers, level - 1)
 
229
            if not result:
 
230
                return resolver.getHostByName(str(r.payload.name), effort=level-1)
 
231
            return result
 
232
    # No answers, but maybe there's a hint at who we should be asking about this
 
233
    for r in answers:
 
234
        if r.type == dns.NS:
 
235
            from twisted.names import client
 
236
            r = client.Resolver(servers=[(str(r.payload.name), dns.PORT)])
 
237
            return r.lookupAddress(str(name)
 
238
                ).addCallback(lambda (ans, auth, add): extractRecord(r, name, ans + auth + add, level - 1)
 
239
                ).addBoth(lambda passthrough: (r.protocol.transport.stopListening(), passthrough)[1])
 
240
 
 
241
typeToMethod = {
 
242
    dns.A:     'lookupAddress',
 
243
    dns.AAAA:  'lookupIPV6Address',
 
244
    dns.A6:    'lookupAddress6',
 
245
    dns.NS:    'lookupNameservers',
 
246
    dns.CNAME: 'lookupCanonicalName',
 
247
    dns.SOA:   'lookupAuthority',
 
248
    dns.MB:    'lookupMailBox',
 
249
    dns.MG:    'lookupMailGroup',
 
250
    dns.MR:    'lookupMailRename',
 
251
    dns.NULL:  'lookupNull',
 
252
    dns.WKS:   'lookupWellKnownServices',
 
253
    dns.PTR:   'lookupPointer',
 
254
    dns.HINFO: 'lookupHostInfo',
 
255
    dns.MINFO: 'lookupMailboxInfo',
 
256
    dns.MX:    'lookupMailExchange',
 
257
    dns.TXT:   'lookupText',
 
258
 
 
259
    dns.RP:    'lookupResponsibility',
 
260
    dns.AFSDB: 'lookupAFSDatabase',
 
261
    dns.SRV:   'lookupService',
 
262
    dns.NAPTR: 'lookupNamingAuthorityPointer',
 
263
    dns.AXFR:         'lookupZone',
 
264
    dns.ALL_RECORDS:  'lookupAllRecords',
 
265
}