summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-05-11 20:51:47 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-05-11 20:51:47 +0200
commit480f29f31db110bdcabe3de357e0091deb5220bc (patch)
tree8c37e0ef81942e5208bd49c62adf2926a7739f28
downloadmdns-resolver-480f29f31db110bdcabe3de357e0091deb5220bc.tar
mdns-resolver-480f29f31db110bdcabe3de357e0091deb5220bc.zip
Initial version
-rw-r--r--.gitignore1
-rwxr-xr-xmdns-resolver99
2 files changed, 100 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b25c15b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/mdns-resolver b/mdns-resolver
new file mode 100755
index 0000000..b58d55b
--- /dev/null
+++ b/mdns-resolver
@@ -0,0 +1,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)