[PATCH] Move dns_hub.py into selftest directory

Tim Beale timbeale at catalyst.net.nz
Thu Jan 31 03:38:54 UTC 2019


I was wondering if it might make sense for dns_hub.py to live under the
selftest directory, seeing as it's part of the selftest infrastructure
rather than a test per se. The attached patch moves it. Also fixed up a
few flake8 warnings and added a description to the selftest/target/README.

CI pass: https://gitlab.com/catalyst-samba/samba/pipelines/45355409

Review appreciated. Thanks.

-------------- next part --------------
From 7e7109181a5bdfe32b0530508a8fa606d1e761d3 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 30 Jan 2019 13:24:45 +1300
Subject: [PATCH 1/3] dns_hub: Fix flake8 warnings

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 python/samba/tests/dns_forwarder_helpers/dns_hub.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/python/samba/tests/dns_forwarder_helpers/dns_hub.py b/python/samba/tests/dns_forwarder_helpers/dns_hub.py
index 2ac6753..97b7432 100755
--- a/python/samba/tests/dns_forwarder_helpers/dns_hub.py
+++ b/python/samba/tests/dns_forwarder_helpers/dns_hub.py
@@ -20,11 +20,9 @@
 
 import threading
 import sys
-import os
 import select
 import socket
 from samba.dcerpc import dns
-from samba.tests.dns_base import DNSTest
 import samba.ndr as ndr
 
 if sys.version_info[0] < 3:
@@ -34,6 +32,7 @@ else:
     import socketserver
     sserver = socketserver
 
+
 class DnsHandler(sserver.BaseRequestHandler):
     def dns_transaction_udp(self, packet, host):
         "send a DNS query and read the reply"
@@ -90,7 +89,7 @@ class DnsHandler(sserver.BaseRequestHandler):
 
     def handle(self):
         data, sock = self.request
-        query = ndr.ndr_unpack(dns.name_packet, data);
+        query = ndr.ndr_unpack(dns.name_packet, data)
         name = query.questions[0].name
         forwarder = self.forwarder(name)
         response = None
@@ -134,9 +133,10 @@ class server_thread(threading.Thread):
         self.server.serve_forever()
         print("dns_hub: after serve_forever()")
 
+
 def main():
-    timeout = int(sys.argv[1])*1000
-    timeout = min(timeout, 2**31-1) # poll with 32-bit int can't take more
+    timeout = int(sys.argv[1]) * 1000
+    timeout = min(timeout, 2**31 - 1)  # poll with 32-bit int can't take more
     host = sys.argv[2]
     server = sserver.UDPServer((host, int(53)), DnsHandler)
     t = server_thread(server)
-- 
2.7.4


From fe50f283c96b8aae83915d7ceea947ddad732e31 Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 30 Jan 2019 13:26:49 +1300
Subject: [PATCH 2/3] selftest: Move dns_hub.py into selftest directory

As dns_hub.py is now integral to the selftest environments, it seems to
make sense for it to live under the selftest/ directory.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 .../samba/tests/dns_forwarder_helpers/dns_hub.py   | 154 ---------------------
 selftest/target/Samba4.pm                          |   2 +-
 selftest/target/dns_hub.py                         | 154 +++++++++++++++++++++
 3 files changed, 155 insertions(+), 155 deletions(-)
 delete mode 100755 python/samba/tests/dns_forwarder_helpers/dns_hub.py
 create mode 100755 selftest/target/dns_hub.py

diff --git a/python/samba/tests/dns_forwarder_helpers/dns_hub.py b/python/samba/tests/dns_forwarder_helpers/dns_hub.py
deleted file mode 100755
index 97b7432..0000000
--- a/python/samba/tests/dns_forwarder_helpers/dns_hub.py
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-#
-# Unix SMB/CIFS implementation.
-# Copyright (C) Volker Lendecke 2017
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Based on the EchoServer example from python docs
-
-import threading
-import sys
-import select
-import socket
-from samba.dcerpc import dns
-import samba.ndr as ndr
-
-if sys.version_info[0] < 3:
-    import SocketServer
-    sserver = SocketServer
-else:
-    import socketserver
-    sserver = socketserver
-
-
-class DnsHandler(sserver.BaseRequestHandler):
-    def dns_transaction_udp(self, packet, host):
-        "send a DNS query and read the reply"
-        s = None
-        try:
-            send_packet = ndr.ndr_pack(packet)
-            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
-            s.settimeout(5)
-            s.connect((host, 53))
-            s.sendall(send_packet, 0)
-            recv_packet = s.recv(2048, 0)
-            return ndr.ndr_unpack(dns.name_packet, recv_packet)
-        except socket.error as err:
-            print("Error sending to host %s for name %s: %s\n" %
-                  (host, packet.questions[0].name, err.errno))
-            raise
-        finally:
-            if s is not None:
-                s.close()
-        return None
-
-    def forwarder(self, name):
-        lname = name.lower()
-
-        if lname.endswith('an-address-that-will-not-resolve'):
-            return 'ignore'
-        if lname.endswith('dsfsdfs'):
-            return 'fail'
-        if lname.endswith('adnonssdom.samba.example.com'):
-            return '127.0.0.17'
-        if lname.endswith('adnontlmdom.samba.example.com'):
-            return '127.0.0.18'
-        if lname.endswith('samba2000.example.com'):
-            return '127.0.0.25'
-        if lname.endswith('samba2003.example.com'):
-            return '127.0.0.26'
-        if lname.endswith('samba2008r2.example.com'):
-            return '127.0.0.27'
-        if lname.endswith('addom.samba.example.com'):
-            return '127.0.0.30'
-        if lname.endswith('sub.samba.example.com'):
-            return '127.0.0.31'
-        if lname.endswith('chgdcpassword.samba.example.com'):
-            return '127.0.0.32'
-        if lname.endswith('backupdom.samba.example.com'):
-            return '127.0.0.40'
-        if lname.endswith('renamedom.samba.example.com'):
-            return '127.0.0.42'
-        if lname.endswith('labdom.samba.example.com'):
-            return '127.0.0.43'
-        if lname.endswith('samba.example.com'):
-            return '127.0.0.21'
-        return None
-
-    def handle(self):
-        data, sock = self.request
-        query = ndr.ndr_unpack(dns.name_packet, data)
-        name = query.questions[0].name
-        forwarder = self.forwarder(name)
-        response = None
-
-        if forwarder is 'ignore':
-            return
-        elif forwarder is 'fail':
-            pass
-        elif forwarder is not None:
-            response = self.dns_transaction_udp(query, forwarder)
-        else:
-            response = query
-            response.operation |= dns.DNS_FLAG_REPLY
-            response.operation |= dns.DNS_FLAG_RECURSION_AVAIL
-            response.operation |= dns.DNS_RCODE_NXDOMAIN
-
-        if response is None:
-            response = query
-            response.operation |= dns.DNS_FLAG_REPLY
-            response.operation |= dns.DNS_FLAG_RECURSION_AVAIL
-            response.operation |= dns.DNS_RCODE_SERVFAIL
-
-        send_packet = ndr.ndr_pack(response)
-
-        print("dns_hub: sending %s to address %s for name %s\n" %
-            (forwarder, self.client_address, name))
-
-        try:
-            sock.sendto(send_packet, self.client_address)
-        except socket.error as err:
-            print("Error sending %s to address %s for name %s: %s\n" %
-                (forwarder, self.client_address, name, err))
-
-
-class server_thread(threading.Thread):
-    def __init__(self, server):
-        threading.Thread.__init__(self)
-        self.server = server
-
-    def run(self):
-        self.server.serve_forever()
-        print("dns_hub: after serve_forever()")
-
-
-def main():
-    timeout = int(sys.argv[1]) * 1000
-    timeout = min(timeout, 2**31 - 1)  # poll with 32-bit int can't take more
-    host = sys.argv[2]
-    server = sserver.UDPServer((host, int(53)), DnsHandler)
-    t = server_thread(server)
-    t.start()
-    p = select.poll()
-    stdin = sys.stdin.fileno()
-    p.register(stdin, select.POLLIN)
-    p.poll(timeout)
-    print("dns_hub: after poll()")
-    server.shutdown()
-    t.join()
-    print("dns_hub: before exit()")
-    sys.exit(0)
-
-main()
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index f2635e5..fe9ee2e 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -398,7 +398,7 @@ sub setup_dns_hub_internal($$$)
 		} else {
 		    push (@preargs, $ENV{PYTHON});
 		}
-		$ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "python/samba/tests/dns_forwarder_helpers/dns_hub.py");
+		$ENV{MAKE_TEST_BINARY} = "$self->{srcdir}/selftest/target/dns_hub.py";
 		push (@args, "$self->{server_maxtime}");
 		push (@args, "$env->{ipv4}");
 		close($env->{STDIN_PIPE});
diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
new file mode 100755
index 0000000..97b7432
--- /dev/null
+++ b/selftest/target/dns_hub.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+#
+# Unix SMB/CIFS implementation.
+# Copyright (C) Volker Lendecke 2017
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Based on the EchoServer example from python docs
+
+import threading
+import sys
+import select
+import socket
+from samba.dcerpc import dns
+import samba.ndr as ndr
+
+if sys.version_info[0] < 3:
+    import SocketServer
+    sserver = SocketServer
+else:
+    import socketserver
+    sserver = socketserver
+
+
+class DnsHandler(sserver.BaseRequestHandler):
+    def dns_transaction_udp(self, packet, host):
+        "send a DNS query and read the reply"
+        s = None
+        try:
+            send_packet = ndr.ndr_pack(packet)
+            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
+            s.settimeout(5)
+            s.connect((host, 53))
+            s.sendall(send_packet, 0)
+            recv_packet = s.recv(2048, 0)
+            return ndr.ndr_unpack(dns.name_packet, recv_packet)
+        except socket.error as err:
+            print("Error sending to host %s for name %s: %s\n" %
+                  (host, packet.questions[0].name, err.errno))
+            raise
+        finally:
+            if s is not None:
+                s.close()
+        return None
+
+    def forwarder(self, name):
+        lname = name.lower()
+
+        if lname.endswith('an-address-that-will-not-resolve'):
+            return 'ignore'
+        if lname.endswith('dsfsdfs'):
+            return 'fail'
+        if lname.endswith('adnonssdom.samba.example.com'):
+            return '127.0.0.17'
+        if lname.endswith('adnontlmdom.samba.example.com'):
+            return '127.0.0.18'
+        if lname.endswith('samba2000.example.com'):
+            return '127.0.0.25'
+        if lname.endswith('samba2003.example.com'):
+            return '127.0.0.26'
+        if lname.endswith('samba2008r2.example.com'):
+            return '127.0.0.27'
+        if lname.endswith('addom.samba.example.com'):
+            return '127.0.0.30'
+        if lname.endswith('sub.samba.example.com'):
+            return '127.0.0.31'
+        if lname.endswith('chgdcpassword.samba.example.com'):
+            return '127.0.0.32'
+        if lname.endswith('backupdom.samba.example.com'):
+            return '127.0.0.40'
+        if lname.endswith('renamedom.samba.example.com'):
+            return '127.0.0.42'
+        if lname.endswith('labdom.samba.example.com'):
+            return '127.0.0.43'
+        if lname.endswith('samba.example.com'):
+            return '127.0.0.21'
+        return None
+
+    def handle(self):
+        data, sock = self.request
+        query = ndr.ndr_unpack(dns.name_packet, data)
+        name = query.questions[0].name
+        forwarder = self.forwarder(name)
+        response = None
+
+        if forwarder is 'ignore':
+            return
+        elif forwarder is 'fail':
+            pass
+        elif forwarder is not None:
+            response = self.dns_transaction_udp(query, forwarder)
+        else:
+            response = query
+            response.operation |= dns.DNS_FLAG_REPLY
+            response.operation |= dns.DNS_FLAG_RECURSION_AVAIL
+            response.operation |= dns.DNS_RCODE_NXDOMAIN
+
+        if response is None:
+            response = query
+            response.operation |= dns.DNS_FLAG_REPLY
+            response.operation |= dns.DNS_FLAG_RECURSION_AVAIL
+            response.operation |= dns.DNS_RCODE_SERVFAIL
+
+        send_packet = ndr.ndr_pack(response)
+
+        print("dns_hub: sending %s to address %s for name %s\n" %
+            (forwarder, self.client_address, name))
+
+        try:
+            sock.sendto(send_packet, self.client_address)
+        except socket.error as err:
+            print("Error sending %s to address %s for name %s: %s\n" %
+                (forwarder, self.client_address, name, err))
+
+
+class server_thread(threading.Thread):
+    def __init__(self, server):
+        threading.Thread.__init__(self)
+        self.server = server
+
+    def run(self):
+        self.server.serve_forever()
+        print("dns_hub: after serve_forever()")
+
+
+def main():
+    timeout = int(sys.argv[1]) * 1000
+    timeout = min(timeout, 2**31 - 1)  # poll with 32-bit int can't take more
+    host = sys.argv[2]
+    server = sserver.UDPServer((host, int(53)), DnsHandler)
+    t = server_thread(server)
+    t.start()
+    p = select.poll()
+    stdin = sys.stdin.fileno()
+    p.register(stdin, select.POLLIN)
+    p.poll(timeout)
+    print("dns_hub: after poll()")
+    server.shutdown()
+    t.join()
+    print("dns_hub: before exit()")
+    sys.exit(0)
+
+main()
-- 
2.7.4


From 7cea40d3e0818b645b01fdefe990559c07b9a39b Mon Sep 17 00:00:00 2001
From: Tim Beale <timbeale at catalyst.net.nz>
Date: Wed, 30 Jan 2019 15:10:45 +1300
Subject: [PATCH 3/3] selftest: Add dns_hub to selftest/target/README

Add a description explaining what dns_hub does and why we need it.

Signed-off-by: Tim Beale <timbeale at catalyst.net.nz>
---
 selftest/target/README     | 13 +++++++++++++
 selftest/target/dns_hub.py |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/selftest/target/README b/selftest/target/README
index 36b68d5..69d7021 100644
--- a/selftest/target/README
+++ b/selftest/target/README
@@ -41,6 +41,19 @@ Note that several of the testenvs also use local in their name, e.g.
 'localvampiredc'. In particular, there's the 'localdc', which is the NetBIOS
 name of the DC in the 'ad_dc_ntvfs' testenv.
 
+dns_hub
+-------
+dns_hub doesn't run a Samba/smbd server like the other testenvs do. It's there
+to solve the problem of how to do DNS more nicely in selftest. Running
+autobuild can start up a lot of different testenvs, and so we end up with
+different DCs running in different domains. Each test suite only wants to talk
+to a specific domain at a time. However, by default the tests all use a common
+client.conf - essentially the tests are simulating a single client that's
+pretending to be in several different domains. The problem is when the test
+wants to resolve a DNS host, which DC should it ask? Each DC only knows about its
+own realm. dns_hub.py acts as a proxy, so it works out the correct DC to forward
+the query to, based on the queried host's realm.
+
 Vampire DC
 ----------
 Vampire DC gets its name for historic reasons. It's one of the few testenvs
diff --git a/selftest/target/dns_hub.py b/selftest/target/dns_hub.py
index 97b7432..d2d1f39 100755
--- a/selftest/target/dns_hub.py
+++ b/selftest/target/dns_hub.py
@@ -16,6 +16,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
+# Used by selftest to proxy DNS queries to the correct testenv DC.
+# See selftest/target/README for more details.
 # Based on the EchoServer example from python docs
 
 import threading
-- 
2.7.4



More information about the samba-technical mailing list