1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#!/usr/bin/env python3
import errno
import signal
import socket
import subprocess
import sys
import threading
import traceback
import dns.flags
import dns.message
import dns.name
import dns.opcode
import dns.query
import dns.rcode
import dns.rdataclass
import dns.rdatatype
import dns.rdtypes.IN.A
import dns.rdtypes.IN.AAAA
import dns.rrset
### Config ###
domain = 'mesh.ffhl'
port = 3535
ttl = 600
### Config end ###
class ResolverThread(threading.Thread):
def __init__(self, data, addr):
threading.Thread.__init__(self)
self.daemon = True
self._data = data
self._addr = addr
def run(self):
request = dns.message.from_wire(self._data, question_only=True)
if request.opcode() != dns.opcode.QUERY:
return
reply = dns.message.Message(request.id)
reply.flags = dns.flags.QR
reply.set_opcode(dns.opcode.QUERY)
reply.set_rcode(dns.rcode.NOERROR)
for question in request.question:
if question.rdclass != dns.rdataclass.IN:
continue
domainname = dns.name.from_text(domain)
if len(question.name) != len(domainname)+1:
continue
if not question.name.is_subdomain(domainname):
continue
answer = dns.rrset.RRset(question.name, question.rdclass, question.rdtype)
answer.ttl = ttl
if question.rdtype == dns.rdatatype.A:
output = subprocess.check_output(['avahi-resolve', '-n', '-4', question.name[0]+b'.local']).split(b'\t')
if output[0] == question.name[0]+b'.local':
answer.add(dns.rdtypes.IN.A.A(question.rdclass, question.rdtype, str(output[1], encoding='ASCII').strip()))
elif question.rdtype == dns.rdatatype.AAAA:
output = subprocess.check_output(['avahi-resolve', '-n', '-6', question.name[0]+b'.local']).split(b'\t')
if output[0] == question.name[0]+b'.local':
answer.add(dns.rdtypes.IN.AAAA.AAAA(question.rdclass, question.rdtype, str(output[1], encoding='ASCII').strip()))
else:
continue
reply.answer.append(answer)
sock.sendto(reply.to_wire(), self._addr)
run = True
def exitHandler(signum, frame):
global run
run = False
signal.signal(signal.SIGINT, exitHandler)
signal.signal(signal.SIGTERM, exitHandler)
signal.signal(signal.SIGQUIT, exitHandler)
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.bind(('::1', port))
while run:
try:
data, addr = sock.recvfrom(1024)
ResolverThread(data, addr).start()
except socket.error:
if sys.exc_info()[1].errno != errno.EINTR:
traceback.print_exc(file=sys.stderr)
|