From ad7d2c9f05a654443d63800aadc32c77810b843e Mon Sep 17 00:00:00 2001 From: Michael Kuron Date: Sun, 2 Aug 2020 17:31:50 +0200 Subject: [PATCH] rough draft --- README.md | 4 +++ proxy.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ 3 files changed, 74 insertions(+) create mode 100644 README.md create mode 100644 proxy.py create mode 100644 requirements.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..3441412 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +https://opensource.apple.com/source/mDNSResponder/mDNSResponder-1096.60.2/ServiceRegistration/dnssd-proxy.c.auto.html +https://github.com/sbyx/ohybridproxy + +requires https://github.com/jstasiak/python-zeroconf \ No newline at end of file diff --git a/proxy.py b/proxy.py new file mode 100644 index 0000000..082f682 --- /dev/null +++ b/proxy.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange +import sys +import time +from twisted.internet import reactor, defer +from twisted.names import client, dns, error, server +from twisted.python import log + +domain = sys.argv[1] +port = int(sys.argv[2]) + +class DynamicResolver(object): + def _dynamicResponseRequired(self, query): + if str(query.name).endswith(domain): + return True + + return False + + def _doDynamicResponse(self, query): + if query.type == dns.SOA: + return [], [], [] + + localname = str(query.name)[:-len(domain)] + "local." + + services = [] + def handler(zeroconf, service_type, name, state_change): + if state_change is ServiceStateChange.Added: + services.append(name) + + answers = [] + if query.type == dns.PTR: + zeroconf = Zeroconf(ip_version=4) + sb = ServiceBrowser(zeroconf, localname, [handler]) + time.sleep(2) # TODO: non-blocking + sb.cancel() + for service in services: + answers.append(dns.RRHeader(name=query.name.name, type=query.type, payload=dns.Record_PTR( + name=service[:-6] + domain + ))) + else: + # TODO: other types + print(query) + + return answers, [], [] + + def query(self, query, timeout=None): + if self._dynamicResponseRequired(query): + return defer.succeed(self._doDynamicResponse(query)) + else: + return defer.fail(error.DomainError()) + +def main(): + factory = server.DNSServerFactory( + clients=[DynamicResolver()], + verbose=0 + ) + + protocol = dns.DNSDatagramProtocol(controller=factory) + + reactor.listenUDP(port, protocol) + reactor.listenTCP(port, factory) + + log.startLogging(sys.stdout) + reactor.run() + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1817370 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +zeroconf +twisted \ No newline at end of file