0
# DNS Implementation
1
2
DNS protocol implementation with client resolvers, server functionality, and caching capabilities for domain name resolution. Twisted Names provides comprehensive DNS support for both client and server applications.
3
4
## Capabilities
5
6
### DNS Client Resolution
7
8
DNS client functionality for resolving domain names to IP addresses and other record types.
9
10
```python { .api }
11
class client.Resolver:
12
"""
13
DNS resolver for performing domain name lookups.
14
15
Attributes:
16
- servers: List of DNS server addresses
17
- timeout: Query timeout in seconds
18
- tries: Number of retry attempts
19
"""
20
servers = None
21
timeout = 10
22
tries = 3
23
24
def __init__(self, resolv=None, servers=None):
25
"""
26
Args:
27
resolv (str): Path to resolv.conf file
28
servers (list): List of DNS server addresses
29
"""
30
31
def lookupAddress(self, name, timeout=None):
32
"""
33
Look up A records for hostname.
34
35
Args:
36
name (str): Hostname to resolve
37
timeout (int): Query timeout override
38
39
Returns:
40
Deferred[list]: List of A record objects
41
"""
42
43
def lookupIPV6Address(self, name, timeout=None):
44
"""
45
Look up AAAA records for hostname.
46
47
Args:
48
name (str): Hostname to resolve
49
timeout (int): Query timeout override
50
51
Returns:
52
Deferred[list]: List of AAAA record objects
53
"""
54
55
def lookupMailExchange(self, name, timeout=None):
56
"""
57
Look up MX records for domain.
58
59
Args:
60
name (str): Domain name
61
timeout (int): Query timeout override
62
63
Returns:
64
Deferred[list]: List of MX record objects
65
"""
66
67
def lookupNameservers(self, name, timeout=None):
68
"""
69
Look up NS records for domain.
70
71
Args:
72
name (str): Domain name
73
timeout (int): Query timeout override
74
75
Returns:
76
Deferred[list]: List of NS record objects
77
"""
78
79
def lookupCanonicalName(self, name, timeout=None):
80
"""
81
Look up CNAME records for hostname.
82
83
Args:
84
name (str): Hostname
85
timeout (int): Query timeout override
86
87
Returns:
88
Deferred[list]: List of CNAME record objects
89
"""
90
91
def lookupPointer(self, name, timeout=None):
92
"""
93
Look up PTR records for reverse DNS.
94
95
Args:
96
name (str): IP address or reverse domain
97
timeout (int): Query timeout override
98
99
Returns:
100
Deferred[list]: List of PTR record objects
101
"""
102
103
def lookupText(self, name, timeout=None):
104
"""
105
Look up TXT records for domain.
106
107
Args:
108
name (str): Domain name
109
timeout (int): Query timeout override
110
111
Returns:
112
Deferred[list]: List of TXT record objects
113
"""
114
115
def lookupService(self, name, timeout=None):
116
"""
117
Look up SRV records for service.
118
119
Args:
120
name (str): Service name (_service._proto.domain)
121
timeout (int): Query timeout override
122
123
Returns:
124
Deferred[list]: List of SRV record objects
125
"""
126
127
def queryUDP(self, queries, timeout=None):
128
"""
129
Perform DNS query over UDP.
130
131
Args:
132
queries (list): List of Query objects
133
timeout (int): Query timeout override
134
135
Returns:
136
Deferred[Message]: DNS response message
137
"""
138
139
def queryTCP(self, queries, timeout=None):
140
"""
141
Perform DNS query over TCP.
142
143
Args:
144
queries (list): List of Query objects
145
timeout (int): Query timeout override
146
147
Returns:
148
Deferred[Message]: DNS response message
149
"""
150
151
class client.ThreadedResolver:
152
"""
153
DNS resolver that uses threads for blocking DNS calls.
154
"""
155
def __init__(self, reactor=None, getHostByName=None):
156
"""
157
Args:
158
reactor: Reactor to use
159
getHostByName: Function for host resolution
160
"""
161
162
def getHostByName(self, name, timeout=None):
163
"""
164
Resolve hostname to IP address.
165
166
Args:
167
name (str): Hostname
168
timeout (int): Resolution timeout
169
170
Returns:
171
Deferred[str]: IP address
172
"""
173
```
174
175
**DNS Client Usage Example**:
176
177
```python
178
from twisted.names import client
179
from twisted.internet import reactor, defer
180
181
# Create resolver
182
resolver = client.Resolver()
183
184
@defer.inlineCallbacks
185
def resolve_domains():
186
try:
187
# Look up A records
188
a_records = yield resolver.lookupAddress('example.com')
189
for record in a_records[0]:
190
print(f"A: {record.payload.dottedQuad()}")
191
192
# Look up MX records
193
mx_records = yield resolver.lookupMailExchange('example.com')
194
for record in mx_records[0]:
195
print(f"MX: {record.payload.exchange} (priority {record.payload.preference})")
196
197
# Look up TXT records
198
txt_records = yield resolver.lookupText('example.com')
199
for record in txt_records[0]:
200
print(f"TXT: {record.payload.data}")
201
202
# Reverse DNS lookup
203
ptr_records = yield resolver.lookupPointer('8.8.8.8.in-addr.arpa')
204
for record in ptr_records[0]:
205
print(f"PTR: {record.payload.name}")
206
207
except Exception as e:
208
print(f"DNS lookup failed: {e}")
209
210
reactor.stop()
211
212
resolve_domains()
213
reactor.run()
214
```
215
216
### DNS Protocol and Messages
217
218
Core DNS protocol implementation and message parsing.
219
220
```python { .api }
221
class dns.DNSDatagramProtocol:
222
"""
223
DNS protocol over UDP.
224
225
Attributes:
226
- controller: DNS controller object
227
"""
228
controller = None
229
230
def __init__(self, controller):
231
"""
232
Args:
233
controller: DNS controller
234
"""
235
236
def query(self, address, queries, timeout=10, id=None):
237
"""
238
Send DNS query.
239
240
Args:
241
address: Server address tuple (host, port)
242
queries (list): List of Query objects
243
timeout (int): Query timeout
244
id (int): Query ID
245
246
Returns:
247
Deferred[Message]: DNS response
248
"""
249
250
class dns.DNSProtocol:
251
"""
252
DNS protocol over TCP.
253
"""
254
def __init__(self, controller):
255
"""
256
Args:
257
controller: DNS controller
258
"""
259
260
def query(self, queries, timeout=60):
261
"""
262
Send DNS query over TCP.
263
264
Args:
265
queries (list): List of Query objects
266
timeout (int): Query timeout
267
268
Returns:
269
Deferred[Message]: DNS response
270
"""
271
272
class dns.Message:
273
"""
274
DNS message representation.
275
276
Attributes:
277
- id: Message ID
278
- answer: Answer flag
279
- opCode: Operation code
280
- auth: Authoritative answer flag
281
- trunc: Truncated flag
282
- recDes: Recursion desired flag
283
- recAv: Recursion available flag
284
- rCode: Response code
285
- queries: List of queries
286
- answers: List of answer records
287
- authority: List of authority records
288
- additional: List of additional records
289
"""
290
id = 0
291
answer = 0
292
opCode = 0
293
auth = 0
294
trunc = 0
295
recDes = 0
296
recAv = 0
297
rCode = 0
298
queries = None
299
answers = None
300
authority = None
301
additional = None
302
303
def __init__(self, id=0, answer=0, opCode=0, recDes=0, recAv=0, auth=0, rCode=0, trunc=0, maxSize=512):
304
"""
305
Args:
306
id (int): Message ID
307
answer (int): Answer flag
308
opCode (int): Operation code
309
recDes (int): Recursion desired
310
recAv (int): Recursion available
311
auth (int): Authoritative answer
312
rCode (int): Response code
313
trunc (int): Truncated flag
314
maxSize (int): Maximum message size
315
"""
316
317
def addQuery(self, name, type=A, cls=IN):
318
"""
319
Add query to message.
320
321
Args:
322
name (str): Query name
323
type (int): Record type
324
cls (int): Record class
325
"""
326
327
def encode(self, strio):
328
"""
329
Encode message to wire format.
330
331
Args:
332
strio: String buffer to write to
333
"""
334
335
def decode(self, strio):
336
"""
337
Decode message from wire format.
338
339
Args:
340
strio: String buffer to read from
341
"""
342
343
class dns.Query:
344
"""
345
DNS query representation.
346
347
Attributes:
348
- name: Query name
349
- type: Record type
350
- cls: Record class
351
"""
352
name = None
353
type = None
354
cls = None
355
356
def __init__(self, name='', type=A, cls=IN):
357
"""
358
Args:
359
name (str): Query name
360
type (int): Record type (A, AAAA, MX, etc.)
361
cls (int): Record class (IN, etc.)
362
"""
363
364
class dns.RRHeader:
365
"""
366
DNS resource record header.
367
368
Attributes:
369
- name: Record name
370
- type: Record type
371
- cls: Record class
372
- ttl: Time to live
373
- payload: Record payload
374
"""
375
name = None
376
type = None
377
cls = None
378
ttl = None
379
payload = None
380
381
def __init__(self, name='', type=A, cls=IN, ttl=0, payload=None, auth=False):
382
"""
383
Args:
384
name (str): Record name
385
type (int): Record type
386
cls (int): Record class
387
ttl (int): Time to live in seconds
388
payload: Record data
389
auth (bool): Authoritative flag
390
"""
391
```
392
393
### DNS Record Types
394
395
Implementations of various DNS record types.
396
397
```python { .api }
398
class dns.Record_A:
399
"""
400
A record (IPv4 address).
401
402
Attributes:
403
- address: IPv4 address (4 bytes)
404
"""
405
address = None
406
407
def __init__(self, address='0.0.0.0', ttl=None):
408
"""
409
Args:
410
address (str): IPv4 address
411
ttl (int): Time to live
412
"""
413
414
def dottedQuad(self):
415
"""
416
Get dotted quad representation.
417
418
Returns:
419
str: Dotted quad IPv4 address
420
"""
421
422
class dns.Record_AAAA:
423
"""
424
AAAA record (IPv6 address).
425
426
Attributes:
427
- address: IPv6 address (16 bytes)
428
"""
429
address = None
430
431
def __init__(self, address='::', ttl=None):
432
"""
433
Args:
434
address (str): IPv6 address
435
ttl (int): Time to live
436
"""
437
438
class dns.Record_CNAME:
439
"""
440
CNAME record (canonical name).
441
442
Attributes:
443
- name: Canonical name
444
"""
445
name = None
446
447
def __init__(self, name='', ttl=None):
448
"""
449
Args:
450
name (str): Canonical name
451
ttl (int): Time to live
452
"""
453
454
class dns.Record_MX:
455
"""
456
MX record (mail exchange).
457
458
Attributes:
459
- preference: Priority preference
460
- exchange: Mail server name
461
"""
462
preference = None
463
exchange = None
464
465
def __init__(self, preference=10, exchange='', ttl=None):
466
"""
467
Args:
468
preference (int): Priority (lower = higher priority)
469
exchange (str): Mail server hostname
470
ttl (int): Time to live
471
"""
472
473
class dns.Record_NS:
474
"""
475
NS record (name server).
476
477
Attributes:
478
- name: Name server hostname
479
"""
480
name = None
481
482
def __init__(self, name='', ttl=None):
483
"""
484
Args:
485
name (str): Name server hostname
486
ttl (int): Time to live
487
"""
488
489
class dns.Record_PTR:
490
"""
491
PTR record (pointer for reverse DNS).
492
493
Attributes:
494
- name: Pointed-to name
495
"""
496
name = None
497
498
def __init__(self, name='', ttl=None):
499
"""
500
Args:
501
name (str): Target hostname
502
ttl (int): Time to live
503
"""
504
505
class dns.Record_SOA:
506
"""
507
SOA record (start of authority).
508
509
Attributes:
510
- mname: Primary name server
511
- rname: Responsible person email
512
- serial: Serial number
513
- refresh: Refresh interval
514
- retry: Retry interval
515
- expire: Expiration time
516
- minimum: Minimum TTL
517
"""
518
mname = None
519
rname = None
520
serial = None
521
refresh = None
522
retry = None
523
expire = None
524
minimum = None
525
526
def __init__(self, mname='', rname='', serial=0, refresh=3600, retry=900, expire=604800, minimum=86400, ttl=None):
527
"""
528
Args:
529
mname (str): Primary name server
530
rname (str): Responsible person email
531
serial (int): Serial number
532
refresh (int): Refresh interval
533
retry (int): Retry interval
534
expire (int): Expiration time
535
minimum (int): Minimum TTL
536
ttl (int): Record TTL
537
"""
538
539
class dns.Record_SRV:
540
"""
541
SRV record (service location).
542
543
Attributes:
544
- priority: Service priority
545
- weight: Service weight
546
- port: Service port
547
- target: Service hostname
548
"""
549
priority = None
550
weight = None
551
port = None
552
target = None
553
554
def __init__(self, priority=0, weight=0, port=0, target='', ttl=None):
555
"""
556
Args:
557
priority (int): Service priority
558
weight (int): Service weight
559
port (int): Service port number
560
target (str): Service hostname
561
ttl (int): Time to live
562
"""
563
564
class dns.Record_TXT:
565
"""
566
TXT record (text data).
567
568
Attributes:
569
- data: Text data (list of strings)
570
"""
571
data = None
572
573
def __init__(self, *data, **kw):
574
"""
575
Args:
576
*data: Text strings
577
**kw: Additional parameters (ttl, etc.)
578
"""
579
```
580
581
### DNS Constants
582
583
DNS protocol constants and record type definitions.
584
585
```python { .api }
586
# Record types
587
dns.A = 1 # IPv4 address
588
dns.NS = 2 # Name server
589
dns.CNAME = 5 # Canonical name
590
dns.SOA = 6 # Start of authority
591
dns.PTR = 12 # Pointer
592
dns.MX = 15 # Mail exchange
593
dns.TXT = 16 # Text
594
dns.AAAA = 28 # IPv6 address
595
dns.SRV = 33 # Service location
596
597
# Record classes
598
dns.IN = 1 # Internet class
599
dns.CS = 2 # CSNET class
600
dns.CH = 3 # CHAOS class
601
dns.HS = 4 # Hesiod class
602
603
# Response codes
604
dns.OK = 0 # No error
605
dns.EFORMAT = 1 # Format error
606
dns.ESERVER = 2 # Server failure
607
dns.ENAME = 3 # Name error
608
dns.ENOTIMP = 4 # Not implemented
609
dns.EREFUSED = 5 # Refused
610
611
# Operation codes
612
dns.OP_QUERY = 0 # Standard query
613
dns.OP_IQUERY = 1 # Inverse query
614
dns.OP_STATUS = 2 # Server status
615
```
616
617
### DNS Server
618
619
DNS server implementation for authoritative and caching servers.
620
621
```python { .api }
622
class server.DNSServerFactory:
623
"""
624
DNS server factory.
625
626
Attributes:
627
- authorities: List of authority resolvers
628
- caches: List of cache resolvers
629
- clients: List of client resolvers
630
"""
631
authorities = None
632
caches = None
633
clients = None
634
635
def __init__(self, authorities=None, caches=None, clients=None, verbose=0):
636
"""
637
Args:
638
authorities (list): Authority resolvers
639
caches (list): Cache resolvers
640
clients (list): Client resolvers
641
verbose (int): Verbosity level
642
"""
643
644
def buildProtocol(self, addr):
645
"""
646
Build DNS server protocol.
647
648
Args:
649
addr: Connection address
650
651
Returns:
652
DNSProtocol: DNS server protocol
653
"""
654
```
655
656
### DNS Caching
657
658
DNS caching resolver for improved performance.
659
660
```python { .api }
661
class cache.CacheResolver:
662
"""
663
DNS caching resolver.
664
665
Attributes:
666
- cache: Cache storage
667
- reactor: Reactor for timeouts
668
"""
669
cache = None
670
reactor = None
671
672
def __init__(self, _cache=None, reactor=None):
673
"""
674
Args:
675
_cache: Cache storage object
676
reactor: Reactor instance
677
"""
678
679
def query(self, query, timeout=None):
680
"""
681
Perform cached DNS query.
682
683
Args:
684
query: DNS query object
685
timeout (int): Query timeout
686
687
Returns:
688
Deferred[Message]: DNS response (cached or fresh)
689
"""
690
691
def lookupAddress(self, name, timeout=None):
692
"""
693
Cached A record lookup.
694
695
Args:
696
name (str): Hostname
697
timeout (int): Query timeout
698
699
Returns:
700
Deferred[list]: A records
701
"""
702
```
703
704
### DNS Authority
705
706
Authoritative DNS server for specific domains.
707
708
```python { .api }
709
class authority.FileAuthority:
710
"""
711
File-based DNS authority.
712
713
Loads DNS records from zone files.
714
"""
715
def __init__(self, file):
716
"""
717
Args:
718
file (str): Zone file path
719
"""
720
721
def _lookup(self, name, cls, type, timeout=None):
722
"""
723
Look up records in authority data.
724
725
Args:
726
name (str): Query name
727
cls (int): Record class
728
type (int): Record type
729
timeout (int): Query timeout
730
731
Returns:
732
Deferred: Query results
733
"""
734
```
735
736
**DNS Server Example**:
737
738
```python
739
from twisted.names import dns, server, authority, cache, client
740
from twisted.internet import reactor, endpoints
741
from twisted.application import service
742
743
# Create resolvers
744
authority_resolver = authority.FileAuthority('/etc/bind/db.example.com')
745
cache_resolver = cache.CacheResolver()
746
client_resolver = client.Resolver()
747
748
# Create DNS server factory
749
dns_factory = server.DNSServerFactory(
750
authorities=[authority_resolver],
751
caches=[cache_resolver],
752
clients=[client_resolver]
753
)
754
755
# Start DNS server
756
udp_endpoint = endpoints.UDP4ServerEndpoint(reactor, 53)
757
tcp_endpoint = endpoints.TCP4ServerEndpoint(reactor, 53)
758
759
udp_endpoint.listen(dns.DNSDatagramProtocol(dns_factory))
760
tcp_endpoint.listen(dns_factory)
761
762
print("DNS server listening on port 53")
763
reactor.run()
764
```
765
766
### Hosts File Resolver
767
768
DNS resolver that uses system hosts file.
769
770
```python { .api }
771
class hosts.Resolver:
772
"""
773
DNS resolver using hosts file.
774
"""
775
def __init__(self, file='/etc/hosts'):
776
"""
777
Args:
778
file (str): Hosts file path
779
"""
780
781
def lookupAddress(self, name, timeout=None):
782
"""
783
Look up address in hosts file.
784
785
Args:
786
name (str): Hostname
787
timeout (int): Query timeout (ignored)
788
789
Returns:
790
Deferred[list]: A records from hosts file
791
"""
792
```