]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add TCP garbage system test
authorOndřej Surý <ondrej@isc.org>
Tue, 15 Feb 2022 20:01:25 +0000 (21:01 +0100)
committerOndřej Surý <ondrej@isc.org>
Thu, 17 Feb 2022 19:39:55 +0000 (20:39 +0100)
Test if the TCP connection gets reset when garbage instead of DNS
message is sent.

I'm only happy when it rains
Pour some misery down on me
- Garbage

bin/tests/system/tcp/clean.sh
bin/tests/system/tcp/conftest.py [new file with mode: 0644]
bin/tests/system/tcp/ns7/named.conf.in [new file with mode: 0644]
bin/tests/system/tcp/ns7/root.db [new file with mode: 0644]
bin/tests/system/tcp/setup.sh
bin/tests/system/tcp/tests-tcp.py [new file with mode: 0644]

index 850f5f9b1c58f940bb648f9dc77216e62ddbf478..1ea5b60d0f409309e46f6595e6ae797de9072332 100644 (file)
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.
 
-rm -f */named.memstats
-rm -f */named.run
-rm -f */named.conf
-rm -f */named.stats*
+rm -f ./*/named.memstats
+rm -f ./*/named.run
+rm -f ./*/named.conf
+rm -f ./*/named.stats*
 rm -f ans6/ans.run*
 rm -f dig.out*
 rm -f rndc.out*
diff --git a/bin/tests/system/tcp/conftest.py b/bin/tests/system/tcp/conftest.py
new file mode 100644 (file)
index 0000000..0ce749b
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0.  If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+import os
+import pytest
+
+
+def pytest_configure(config):
+    config.addinivalue_line(
+        "markers", "dnspython: mark tests that need dnspython to function"
+    )
+    config.addinivalue_line(
+        "markers", "dnspython2: mark tests that need dnspython >= 2.0.0"
+    )
+
+
+def pytest_collection_modifyitems(config, items):
+    # pylint: disable=unused-argument,unused-import,too-many-branches
+    # pylint: disable=import-outside-toplevel
+
+    # Test for dnspython module
+    skip_dnspython = pytest.mark.skip(
+        reason="need dnspython module to run")
+    try:
+        import dns.query  # noqa: F401
+    except ModuleNotFoundError:
+        for item in items:
+            if "dnspython" in item.keywords:
+                item.add_marker(skip_dnspython)
+
+    # Test for dnspython >= 2.0.0 module
+    skip_dnspython2 = pytest.mark.skip(
+        reason="need dnspython >= 2.0.0 module to run")
+    try:
+        from dns.query import send_tcp  # noqa: F401
+    except ImportError:
+        for item in items:
+            if "dnspython2" in item.keywords:
+                item.add_marker(skip_dnspython2)
+
+
+@pytest.fixture
+def port(request):
+    # pylint: disable=unused-argument
+    env_port = os.getenv("PORT")
+    if port is None:
+        env_port = 5300
+    else:
+        env_port = int(env_port)
+
+    return env_port
diff --git a/bin/tests/system/tcp/ns7/named.conf.in b/bin/tests/system/tcp/ns7/named.conf.in
new file mode 100644 (file)
index 0000000..bf434d9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0.  If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+       query-source address 10.53.0.7;
+       notify-source 10.53.0.7;
+       transfer-source 10.53.0.7;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.7; };
+       listen-on-v6 { none; };
+       recursion no;
+       notify yes;
+       statistics-file "named.stats";
+       tcp-clients 1;
+       keep-response-order { any; };
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.7 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+zone "." {
+       type primary;
+       file "root.db";
+};
diff --git a/bin/tests/system/tcp/ns7/root.db b/bin/tests/system/tcp/ns7/root.db
new file mode 100644 (file)
index 0000000..bb31741
--- /dev/null
@@ -0,0 +1,24 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300
+.                      IN SOA  gson.nominum.com. a.root.servers.nil. (
+                               2000042100      ; serial
+                               600             ; refresh
+                               600             ; retry
+                               1200            ; expire
+                               600             ; minimum
+                               )
+.                      NS      a.root-servers.nil.
+a.root-servers.nil.    A       10.53.0.7
+
+example.               NS      ns2.example.
+ns2.example.           A       10.53.0.2
index 124326f88276725c0e2b3475c9632e6d956c1a92..475f399048358604c1dabd0229f76f0fa04673c8 100644 (file)
@@ -20,3 +20,4 @@ copy_setports ns2/named.conf.in ns2/named.conf
 copy_setports ns3/named.conf.in ns3/named.conf
 copy_setports ns4/named.conf.in ns4/named.conf
 copy_setports ns5/named.conf.in ns5/named.conf
+copy_setports ns7/named.conf.in ns7/named.conf
diff --git a/bin/tests/system/tcp/tests-tcp.py b/bin/tests/system/tcp/tests-tcp.py
new file mode 100644 (file)
index 0000000..7ff84f2
--- /dev/null
@@ -0,0 +1,94 @@
+#!/usr/bin/python3
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0.  If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+# pylint: disable=unused-variable
+
+import socket
+import struct
+import time
+
+import pytest
+
+TIMEOUT = 10
+
+
+def create_msg(qname, qtype):
+    import dns.message
+    msg = dns.message.make_query(qname, qtype, want_dnssec=True,
+                                 use_edns=0, payload=4096)
+    return msg
+
+
+def timeout():
+    return time.time() + TIMEOUT
+
+
+def create_socket(host, port):
+    sock = socket.create_connection((host, port), timeout=1)
+    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
+    return sock
+
+
+@pytest.mark.dnspython
+@pytest.mark.dnspython2
+def test_tcp_garbage(port):
+    import dns.query
+
+    with create_socket("10.53.0.7", port) as sock:
+
+        msg = create_msg("a.example.", "A")
+        (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
+        (response, rtime) = dns.query.receive_tcp(sock, timeout())
+
+        wire = msg.to_wire()
+        assert len(wire) > 0
+
+        # Send DNS message shorter than DNS message header (12),
+        # this should cause the connection to be terminated
+        sock.send(struct.pack('!H', 11))
+        sock.send(struct.pack('!s', b'0123456789a'))
+
+        with pytest.raises(EOFError):
+            try:
+                (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
+                (response, rtime) = dns.query.receive_tcp(sock, timeout())
+            except ConnectionError as e:
+                raise EOFError from e
+
+
+@pytest.mark.dnspython
+@pytest.mark.dnspython2
+def test_tcp_garbage_response(port):
+    import dns.query
+    import dns.message
+
+    with create_socket("10.53.0.7", port) as sock:
+
+        msg = create_msg("a.example.", "A")
+        (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
+        (response, rtime) = dns.query.receive_tcp(sock, timeout())
+
+        wire = msg.to_wire()
+        assert len(wire) > 0
+
+        # Send DNS response instead of DNS query, this should cause
+        # the connection to be terminated
+
+        rmsg = dns.message.make_response(msg)
+        (sbytes, stime) = dns.query.send_tcp(sock, rmsg, timeout())
+
+        with pytest.raises(EOFError):
+            try:
+                (response, rtime) = dns.query.receive_tcp(sock, timeout())
+            except ConnectionError as e:
+                raise EOFError from e