0
# DNS Resolution
1
2
High-level DNS resolution functionality that provides the simplest interface for common DNS operations. The resolver module handles automatic retry logic, caching, and provides convenient access to all DNS record types.
3
4
## Capabilities
5
6
### Query Functions
7
8
Perform DNS queries using the default resolver with automatic error handling and retry logic.
9
10
```python { .api }
11
def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, tcp=False, source=None,
12
raise_on_no_answer=True, source_port=0, lifetime=None):
13
"""
14
Query using the default resolver.
15
16
Args:
17
qname (str or dns.name.Name): Domain name to query
18
rdtype (str or int): Record type (default 'A')
19
rdclass (str or int): Record class (default 'IN')
20
tcp (bool): Use TCP instead of UDP
21
source (str): Source IP address
22
raise_on_no_answer (bool): Raise exception if no answer
23
source_port (int): Source port number
24
lifetime (float): Total query lifetime in seconds
25
26
Returns:
27
dns.resolver.Answer: Query result with sequence-like access
28
"""
29
30
def zone_for_name(name, rdclass='IN', tcp=False, resolver=None):
31
"""
32
Find the zone containing the specified name.
33
34
Args:
35
name (str or dns.name.Name): Domain name
36
rdclass (str or int): Record class (default 'IN')
37
tcp (bool): Use TCP instead of UDP
38
resolver (dns.resolver.Resolver): Custom resolver
39
40
Returns:
41
dns.name.Name: Zone name containing the specified name
42
"""
43
44
def get_default_resolver():
45
"""
46
Get the default resolver instance.
47
48
Returns:
49
dns.resolver.Resolver: Default resolver
50
"""
51
52
def reset_default_resolver():
53
"""Re-initialize the default resolver from system configuration."""
54
55
def override_system_resolver(resolver=None):
56
"""
57
Override system DNS resolution functions.
58
59
Args:
60
resolver (dns.resolver.Resolver): Custom resolver or None for default
61
"""
62
63
def restore_system_resolver():
64
"""Restore original system DNS resolution functions."""
65
```
66
67
### Resolver Class
68
69
Configurable DNS resolver with support for custom nameservers, timeouts, and query options.
70
71
```python { .api }
72
class Resolver:
73
"""
74
A DNS resolver with configurable options.
75
76
Attributes:
77
nameservers (list): List of nameserver IP addresses
78
port (int): Default port for queries (default 53)
79
timeout (float): Timeout for individual queries
80
lifetime (float): Total timeout for all queries
81
search (list): Search domains for relative names
82
domain (dns.name.Name): Local domain name
83
ndots (int): Minimum dots for absolute name treatment
84
rotate (bool): Rotate through nameservers
85
cache (dns.resolver.Cache): Answer cache
86
flags (int): Query flags
87
edns (int): EDNS version (-1 to disable)
88
ednsflags (int): EDNS flags
89
payload (int): EDNS payload size
90
keyring (dict): TSIG keyring
91
keyname (dns.name.Name): TSIG key name
92
keyalgorithm (dns.name.Name): TSIG algorithm
93
"""
94
95
def __init__(self, filename='/etc/resolv.conf', configure=True):
96
"""
97
Initialize resolver.
98
99
Args:
100
filename (str): Configuration file path
101
configure (bool): Configure from system settings
102
"""
103
104
def query(self, qname, rdtype='A', rdclass='IN', tcp=False, source=None,
105
raise_on_no_answer=True, source_port=0):
106
"""
107
Query using this resolver instance.
108
109
Returns:
110
dns.resolver.Answer: Query result
111
"""
112
113
def read_resolv_conf(self, f):
114
"""
115
Read configuration from resolv.conf format file.
116
117
Args:
118
f (file-like): File to read from
119
"""
120
121
def use_tsig(self, keyring, keyname=None, algorithm=dns.tsig.default_algorithm):
122
"""
123
Configure TSIG authentication for queries.
124
125
Args:
126
keyring (dict): TSIG keyring mapping key names to key values
127
keyname (dns.name.Name): TSIG key name (optional, uses first key if None)
128
algorithm (dns.name.Name): TSIG algorithm (default: HMAC-MD5)
129
"""
130
```
131
132
### Answer Class
133
134
Result wrapper that provides sequence-like access to resource records with metadata.
135
136
```python { .api }
137
class Answer:
138
"""
139
DNS query answer with sequence-like access to resource records.
140
141
Attributes:
142
qname (dns.name.Name): Query name
143
rdtype (int): Record type queried
144
rdclass (int): Record class queried
145
response (dns.message.Message): Full DNS response
146
rrset (dns.rrset.RRset): Answer resource record set
147
canonical_name (dns.name.Name): Canonical name after CNAME following
148
expiration (float): Answer expiration time
149
"""
150
151
def __iter__(self):
152
"""Iterate over resource records in the answer."""
153
154
def __len__(self):
155
"""Return number of resource records."""
156
157
def __getitem__(self, index):
158
"""Get resource record by index."""
159
```
160
161
### Cache Classes
162
163
DNS answer caching with configurable size and TTL handling.
164
165
```python { .api }
166
class Cache:
167
"""
168
Simple thread-safe DNS answer cache.
169
170
Args:
171
cleaning_interval (float): Cache cleaning interval in seconds
172
"""
173
174
def get(self, key):
175
"""Get cached answer for key."""
176
177
def put(self, key, value):
178
"""Store answer in cache."""
179
180
def flush(self, key=None):
181
"""Remove items from cache."""
182
183
class LRUCache(Cache):
184
"""
185
Bounded least-recently-used DNS answer cache.
186
187
Args:
188
max_size (int): Maximum cache entries (default 100000)
189
"""
190
```
191
192
## Usage Examples
193
194
### Basic DNS Queries
195
196
```python
197
import dns.resolver
198
199
# Simple A record lookup
200
result = dns.resolver.query('example.com', 'A')
201
for rdata in result:
202
print(f"IP: {rdata.address}")
203
204
# MX record lookup
205
mx_result = dns.resolver.query('example.com', 'MX')
206
for rdata in mx_result:
207
print(f"Mail server: {rdata.exchange}, priority: {rdata.preference}")
208
209
# TXT record lookup
210
txt_result = dns.resolver.query('example.com', 'TXT')
211
for rdata in txt_result:
212
print(f"TXT: {rdata.strings}")
213
```
214
215
### Custom Resolver Configuration
216
217
```python
218
import dns.resolver
219
220
# Create custom resolver
221
resolver = dns.resolver.Resolver()
222
resolver.nameservers = ['8.8.8.8', '8.8.4.4'] # Google DNS
223
resolver.timeout = 10
224
resolver.lifetime = 30
225
226
# Query using custom resolver
227
result = resolver.query('example.com', 'AAAA')
228
for rdata in result:
229
print(f"IPv6: {rdata.address}")
230
231
# Configure search domains
232
resolver.search = [dns.name.from_text('example.com')]
233
resolver.domain = dns.name.from_text('example.com')
234
```
235
236
### Error Handling
237
238
```python
239
import dns.resolver
240
import dns.exception
241
242
try:
243
result = dns.resolver.query('nonexistent.example.com', 'A')
244
except dns.resolver.NXDOMAIN as e:
245
print(f"Domain does not exist: {e}")
246
except dns.resolver.NoAnswer as e:
247
print(f"No answer for query: {e}")
248
except dns.resolver.Timeout as e:
249
print(f"Query timed out: {e}")
250
except dns.exception.DNSException as e:
251
print(f"DNS error occurred: {e}")
252
```
253
254
## Exceptions
255
256
```python { .api }
257
class NXDOMAIN(DNSException):
258
"""The query name does not exist."""
259
260
class YXDOMAIN(DNSException):
261
"""The query name is too long after DNAME substitution."""
262
263
class NoAnswer(DNSException):
264
"""The DNS response does not contain an answer to the question."""
265
266
class NoNameservers(DNSException):
267
"""All nameservers failed to answer the query."""
268
269
class NotAbsolute(DNSException):
270
"""An absolute domain name is required but was not provided."""
271
272
class NoRootSOA(DNSException):
273
"""There is no SOA RR at the DNS root name."""
274
275
class NoMetaqueries(DNSException):
276
"""DNS metaqueries are not allowed."""
277
```