]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add a none parameter to query-source[-v6]
authorColin Vidal <colin@cvidal.org>
Tue, 5 Nov 2024 12:40:55 +0000 (13:40 +0100)
committerColin Vidal <colin@isc.org>
Tue, 26 Nov 2024 07:45:50 +0000 (08:45 +0100)
This change adds a "none" parameter to the query-source[-v6]
options in named.conf, which forbid the usage of IPv4 or IPv6
addresses when doing upstream queries.

27 files changed:
bin/named/server.c
bin/tests/system/Makefile.am
bin/tests/system/checkconf/bad-options-query-source-address-v4-v6.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-query-source-address-v4-none.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-query-source-address-v6-none.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-options-query-source-address-v4-none.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-options-query-source-address-v6-none.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-query-source-address-v4-1.conf
bin/tests/system/checkconf/good-query-source-address-v6-1.conf
bin/tests/system/query-source/ns1/named.conf.in [new file with mode: 0644]
bin/tests/system/query-source/ns1/root.db [new file with mode: 0644]
bin/tests/system/query-source/ns2/named.conf.in [new file with mode: 0644]
bin/tests/system/query-source/ns2/root.hint [new file with mode: 0644]
bin/tests/system/query-source/ns3/named.conf.in [new file with mode: 0644]
bin/tests/system/query-source/ns3/root.hint [new file with mode: 0644]
bin/tests/system/query-source/ns4/named.conf.in [new file with mode: 0644]
bin/tests/system/query-source/ns4/root.hint [new file with mode: 0644]
bin/tests/system/query-source/ns5/named.conf.in [new file with mode: 0644]
bin/tests/system/query-source/ns5/root.hint [new file with mode: 0644]
bin/tests/system/query-source/setup.sh [new file with mode: 0644]
bin/tests/system/query-source/tests_querysource_none.py [new file with mode: 0644]
doc/arm/reference.rst
doc/misc/options
lib/isccfg/check.c
lib/isccfg/namedconf.c
tests/isccfg/Makefile.am
tests/isccfg/grammar_test.c [new file with mode: 0644]

index 08b3f62735b6b0003bcdc68afb1ae0136c7f603c..722e4d8de29c361ef39dd622b8652ba6dcb31bb2 100644 (file)
@@ -1288,9 +1288,22 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af,
                UNREACHABLE();
        }
 
-       sa = *(cfg_obj_assockaddr(obj));
-       INSIST(isc_sockaddr_pf(&sa) == af);
-       INSIST(isc_sockaddr_getport(&sa) == 0);
+       if (cfg_obj_isvoid(obj)) {
+               /*
+                * We don't want to use this address family, let's
+                * bail now. The dispatch object for this family will
+                * be null then not used to run queries.
+                */
+               return ISC_R_SUCCESS;
+       } else {
+               /*
+                * obj _has_ to be sockaddr here, cfg_obj_assockaddr()
+                * asserts this internally.
+                */
+               sa = *(cfg_obj_assockaddr(obj));
+               INSIST(isc_sockaddr_pf(&sa) == af);
+               INSIST(isc_sockaddr_getport(&sa) == 0);
+       }
 
        /*
         * If we don't support this address family, we're done!
@@ -1614,6 +1627,7 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
                (void)cfg_map_get(cpeer, "query-source-v6", &obj);
        }
        if (obj != NULL) {
+               INSIST(cfg_obj_issockaddr(obj));
                result = dns_peer_setquerysource(peer, cfg_obj_assockaddr(obj));
                if (result != ISC_R_SUCCESS) {
                        goto cleanup;
index 58cfdfe0a4c4bad71bb80ad1afdde20d30c5a8cb..530ca500532c3561e22bc28ce06a2a295e789a0f 100644 (file)
@@ -134,6 +134,7 @@ TESTS =                             \
        proxy                   \
        pipelined               \
        qmin                    \
+       query-source            \
        reclimit                \
        redirect                \
        resolver                \
diff --git a/bin/tests/system/checkconf/bad-options-query-source-address-v4-v6.conf b/bin/tests/system/checkconf/bad-options-query-source-address-v4-v6.conf
new file mode 100644 (file)
index 0000000..a10cf04
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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 none;
+       query-source-v6 none;
+};
diff --git a/bin/tests/system/checkconf/bad-query-source-address-v4-none.conf b/bin/tests/system/checkconf/bad-query-source-address-v4-none.conf
new file mode 100644 (file)
index 0000000..497c2f0
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+server 1.2.3.4 {
+       query-source none;
+};
diff --git a/bin/tests/system/checkconf/bad-query-source-address-v6-none.conf b/bin/tests/system/checkconf/bad-query-source-address-v6-none.conf
new file mode 100644 (file)
index 0000000..4ea1ba7
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+server fd92:7065:b8e:ffff::1 {
+       query-source-v6 none;
+};
diff --git a/bin/tests/system/checkconf/good-options-query-source-address-v4-none.conf b/bin/tests/system/checkconf/good-options-query-source-address-v4-none.conf
new file mode 100644 (file)
index 0000000..5e0159d
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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 none;
+};
diff --git a/bin/tests/system/checkconf/good-options-query-source-address-v6-none.conf b/bin/tests/system/checkconf/good-options-query-source-address-v6-none.conf
new file mode 100644 (file)
index 0000000..4298881
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * 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-v6 none;
+};
index d787448334f87999c71641d2d409eb7fa602967b..9f8b340cd8aa8b62d758ae71a6cbfdac9529cead 100644 (file)
@@ -12,5 +12,5 @@
  */
 
 server 1.2.3.4 {
-       query-source address 10.10.10.10;
+       query-source 10.10.10.10;
 };
index 9ced5a5fe07c43150865978e84c63283fc5c1450..ea3e76cee7be000b392a8d39b86b365baa6ac598 100644 (file)
@@ -12,5 +12,5 @@
  */
 
 server fd92:7065:b8e:ffff::1 {
-       query-source-v6 address fd92:7065:b8e:ffff::2;
+       query-source-v6 fd92:7065:b8e:ffff::2;
 };
diff --git a/bin/tests/system/query-source/ns1/named.conf.in b/bin/tests/system/query-source/ns1/named.conf.in
new file mode 100644 (file)
index 0000000..58ca683
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on-v6 { fd92:7065:b8e:ffff::1; };
+       listen-on { 10.53.0.1; };
+       recursion no;
+       dnssec-validation no;
+       query-source 10.53.0.1;
+       query-source-v6 fd92:7065:b8e:ffff::1;
+};
+
+zone "." {
+       type primary;
+       file "root.db";
+};
diff --git a/bin/tests/system/query-source/ns1/root.db b/bin/tests/system/query-source/ns1/root.db
new file mode 100644 (file)
index 0000000..e635a62
--- /dev/null
@@ -0,0 +1,16 @@
+; 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.
+
+.                      300     SOA     . . 0 0 0 0 0
+.                      300     NS      a.root-servers.nil.
+a.root-servers.nil.    300     A       10.53.0.1
+example.               300     A       10.53.0.10
+exampletwo.            300     A       10.53.0.11
\ No newline at end of file
diff --git a/bin/tests/system/query-source/ns2/named.conf.in b/bin/tests/system/query-source/ns2/named.conf.in
new file mode 100644 (file)
index 0000000..de69fe3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.2; };
+       listen-on-v6 { fd92:7065:b8e:ffff::2; };
+       recursion yes;
+       dnssec-validation no;
+       query-source none;
+       query-source-v6 fd92:7065:b8e:ffff::2;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/query-source/ns2/root.hint b/bin/tests/system/query-source/ns2/root.hint
new file mode 100644 (file)
index 0000000..315a233
--- /dev/null
@@ -0,0 +1,14 @@
+; 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 999999
+.                       IN NS          a.root-servers.nil.
+a.root-servers.nil.     IN AAAA        fd92:7065:b8e:ffff::1
diff --git a/bin/tests/system/query-source/ns3/named.conf.in b/bin/tests/system/query-source/ns3/named.conf.in
new file mode 100644 (file)
index 0000000..408edb3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.3; };
+       listen-on-v6 { fd92:7065:b8e:ffff::3; };
+       recursion yes;
+       dnssec-validation no;
+       query-source-v6 none;
+       query-source 10.53.0.3;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/query-source/ns3/root.hint b/bin/tests/system/query-source/ns3/root.hint
new file mode 100644 (file)
index 0000000..e0f186c
--- /dev/null
@@ -0,0 +1,14 @@
+; 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 999999
+.                       IN NS  a.root-servers.nil.
+a.root-servers.nil.     IN A   10.53.0.1
diff --git a/bin/tests/system/query-source/ns4/named.conf.in b/bin/tests/system/query-source/ns4/named.conf.in
new file mode 100644 (file)
index 0000000..7fc4dab
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.4; };
+       listen-on-v6 { fd92:7065:b8e:ffff::4; };
+       recursion yes;
+       dnssec-validation no;
+       query-source none;
+       query-source-v6 fd92:7065:b8e:ffff::4;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/query-source/ns4/root.hint b/bin/tests/system/query-source/ns4/root.hint
new file mode 100644 (file)
index 0000000..49dcae0
--- /dev/null
@@ -0,0 +1,14 @@
+; 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 999999
+.                       IN NS  a.root-servers.nil.
+a.root-servers.nil.     IN  A  10.53.0.1
diff --git a/bin/tests/system/query-source/ns5/named.conf.in b/bin/tests/system/query-source/ns5/named.conf.in
new file mode 100644 (file)
index 0000000..df8975f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.5; };
+       listen-on-v6 { fd92:7065:b8e:ffff::5; };
+       recursion yes;
+       dnssec-validation no;
+       query-source 10.53.0.5;
+       query-source-v6 none;
+};
+
+zone "." {
+       type hint;
+       file "root.hint";
+};
diff --git a/bin/tests/system/query-source/ns5/root.hint b/bin/tests/system/query-source/ns5/root.hint
new file mode 100644 (file)
index 0000000..315a233
--- /dev/null
@@ -0,0 +1,14 @@
+; 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 999999
+.                       IN NS          a.root-servers.nil.
+a.root-servers.nil.     IN AAAA        fd92:7065:b8e:ffff::1
diff --git a/bin/tests/system/query-source/setup.sh b/bin/tests/system/query-source/setup.sh
new file mode 100644 (file)
index 0000000..5d12d6a
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# 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.
+
+. ../conf.sh
+
+copy_setports ns1/named.conf.in ns1/named.conf
+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
diff --git a/bin/tests/system/query-source/tests_querysource_none.py b/bin/tests/system/query-source/tests_querysource_none.py
new file mode 100644 (file)
index 0000000..0f19d05
--- /dev/null
@@ -0,0 +1,58 @@
+#!/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.
+
+import pytest
+import isctest
+
+pytest.importorskip("dns")
+import dns.message
+
+pytestmark = pytest.mark.extra_artifacts(
+    [
+        "ns*/named.pid",
+        "ns*/managed-keys.bind*",
+    ]
+)
+
+
+def test_querysource_none():
+    msg = dns.message.make_query("example.", "A", want_dnssec=False)
+
+    res = isctest.query.udp(msg, "10.53.0.2")
+    isctest.check.noerror(res)
+
+    res = isctest.query.udp(msg, "10.53.0.3")
+    isctest.check.noerror(res)
+
+    res = isctest.query.udp(msg, "10.53.0.4")
+    isctest.check.servfail(res)
+
+    res = isctest.query.udp(msg, "10.53.0.5")
+    isctest.check.servfail(res)
+
+    # using a different name below to make sure we don't use the
+    # resolver cache
+
+    msg = dns.message.make_query("exampletwo.", "A", want_dnssec=False)
+
+    res = isctest.query.udp(msg, "fd92:7065:b8e:ffff::2")
+    isctest.check.noerror(res)
+
+    res = isctest.query.udp(msg, "fd92:7065:b8e:ffff::3")
+    isctest.check.noerror(res)
+
+    res = isctest.query.udp(msg, "fd92:7065:b8e:ffff::4")
+    isctest.check.servfail(res)
+
+    res = isctest.query.udp(msg, "fd92:7065:b8e:ffff::5")
+    isctest.check.servfail(res)
index 83f5a222edb3e1be6fb774dd6c551e1f019b7d51..8851c842c01ceffbe833ad5ccb66d700b3bc14e4 100644 (file)
@@ -3304,11 +3304,15 @@ Query Address
 
 .. namedconf:statement:: query-source
    :tags: query
-   :short: Controls the IPv4 address from which queries are issued.
+   :short: Controls the IPv4 address from which queries are issued. If
+           `none`, then no IPv4 address would be used to issue the
+           query and therefore only IPv6 servers are queried.
 
 .. namedconf:statement:: query-source-v6
    :tags: query
-   :short: Controls the IPv6 address from which queries are issued.
+   :short: Controls the IPv6 address from which queries are issued. If
+           `none`, then no IPv6 address would be used to issue the
+           query and therefore only IPv4 servers are quried.
 
    If the server does not know the answer to a question, it queries other
    name servers. :any:`query-source` specifies the address used for
index 44186cd37b11bc8c8a3573d0f630b2a694041cda..eacf6936347c84e9cf850520e3fe0b4c52f80344 100644 (file)
@@ -228,8 +228,8 @@ options {
        prefetch <integer> [ <integer> ];
        provide-ixfr <boolean>;
        qname-minimization ( strict | relaxed | disabled | off );
-       query-source [ address ] ( <ipv4_address> | * );
-       query-source-v6 [ address ] ( <ipv6_address> | * );
+       query-source [ address ] ( <ipv4_address> | * | none );
+       query-source-v6 [ address ] ( <ipv6_address> | * | none );
        querylog <boolean>;
        rate-limit {
                all-per-second <integer>;
@@ -514,8 +514,8 @@ view <string> [ <class> ] {
        prefetch <integer> [ <integer> ];
        provide-ixfr <boolean>;
        qname-minimization ( strict | relaxed | disabled | off );
-       query-source [ address ] ( <ipv4_address> | * );
-       query-source-v6 [ address ] ( <ipv6_address> | * );
+       query-source [ address ] ( <ipv4_address> | * | none );
+       query-source-v6 [ address ] ( <ipv6_address> | * | none );
        rate-limit {
                all-per-second <integer>;
                errors-per-second <integer>;
index ea465cb49448c7d9e846ba99e4f203defdd84621..460973477977ad352381a6aac2e49148e5f3b32b 100644 (file)
@@ -1315,24 +1315,21 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
                 * Warn if query-source or query-source-v6 options specify
                 * a port, and fail if they specify the DNS port.
                 */
+               unsigned int none_found = false;
+
                for (i = 0; i < ARRAY_SIZE(sources); i++) {
                        obj = NULL;
                        (void)cfg_map_get(options, sources[i], &obj);
-                       if (obj != NULL) {
-                               const isc_sockaddr_t *sa =
-                                       cfg_obj_assockaddr(obj);
-                               in_port_t port = isc_sockaddr_getport(sa);
-                               if (port == dnsport) {
+                       if (obj != NULL && cfg_obj_isvoid(obj)) {
+                               none_found++;
+
+                               if (none_found > 1) {
                                        cfg_obj_log(obj, ISC_LOG_ERROR,
-                                                   "'%s' cannot specify the "
-                                                   "DNS listener port (%d)",
-                                                   sources[i], port);
+                                                   "query-source and "
+                                                   "query-source-v6 can't be "
+                                                   "none at the same time.");
                                        result = ISC_R_FAILURE;
-                               } else if (port != 0) {
-                                       cfg_obj_log(obj, ISC_LOG_WARNING,
-                                                   "'%s': specifying a port "
-                                                   "is not recommended",
-                                                   sources[i]);
+                                       break;
                                }
                        }
                }
@@ -4419,14 +4416,26 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
                        }
                        (void)cfg_map_get(v1, xfr, &obj);
                        if (obj != NULL) {
-                               const isc_sockaddr_t *sa =
-                                       cfg_obj_assockaddr(obj);
-                               in_port_t port = isc_sockaddr_getport(sa);
-                               if (port == dnsport) {
+                               if (cfg_obj_issockaddr(obj)) {
+                                       const isc_sockaddr_t *sa =
+                                               cfg_obj_assockaddr(obj);
+                                       in_port_t port =
+                                               isc_sockaddr_getport(sa);
+                                       if (port == dnsport) {
+                                               cfg_obj_log(obj, ISC_LOG_ERROR,
+                                                           "'%s' cannot "
+                                                           "specify the "
+                                                           "DNS listener port "
+                                                           "(%d)",
+                                                           xfr, port);
+                                               result = ISC_R_FAILURE;
+                                       }
+                               } else {
                                        cfg_obj_log(obj, ISC_LOG_ERROR,
-                                                   "'%s' cannot specify the "
-                                                   "DNS listener port (%d)",
-                                                   xfr, port);
+                                                   "'none' is not a legal "
+                                                   "'%s' parameter in a "
+                                                   "server block",
+                                                   xfr);
                                        result = ISC_R_FAILURE;
                                }
                        }
index 8eb846b9a1a7d463dff7caa5347fe1c87616b863..02057b2cf71e2e90501fb929e7e49a1efde3f836 100644 (file)
@@ -131,6 +131,8 @@ static cfg_type_t cfg_type_printtime;
 static cfg_type_t cfg_type_qminmethod;
 static cfg_type_t cfg_type_querysource4;
 static cfg_type_t cfg_type_querysource6;
+static cfg_type_t cfg_type_server_querysource4;
+static cfg_type_t cfg_type_server_querysource6;
 static cfg_type_t cfg_type_querysource;
 static cfg_type_t cfg_type_server;
 static cfg_type_t cfg_type_server_key_kludge;
@@ -2603,8 +2605,8 @@ static cfg_clausedef_t server_clauses[] = {
        { "notify-source-v6", &cfg_type_sockaddr6wild, 0 },
        { "padding", &cfg_type_uint32, 0 },
        { "provide-ixfr", &cfg_type_boolean, 0 },
-       { "query-source", &cfg_type_querysource4, 0 },
-       { "query-source-v6", &cfg_type_querysource6, 0 },
+       { "query-source", &cfg_type_server_querysource4, 0 },
+       { "query-source-v6", &cfg_type_server_querysource6, 0 },
        { "request-expire", &cfg_type_boolean, 0 },
        { "request-ixfr", &cfg_type_boolean, 0 },
        { "request-ixfr-max-diffs", &cfg_type_uint32, 0 },
@@ -3218,14 +3220,33 @@ static cfg_type_t cfg_type_optional_class = { "optional_class",
 
 static isc_result_t
 parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+       isc_result_t result;
+
        REQUIRE(type != NULL);
+       CHECK(cfg_peektoken(pctx, 0));
 
-       isc_result_t result = cfg_parse_sockaddr_generic(
-               pctx, &cfg_type_querysource, type, ret);
-       /* Preserve legacy query-source logging. */
+       if (pctx->token.type == isc_tokentype_string &&
+           strcasecmp(TOKEN_STRING(pctx), "address") == 0)
+       {
+               CHECK(cfg_gettoken(pctx, 0));
+               CHECK(cfg_peektoken(pctx, 0));
+       }
+
+       if (pctx->token.type == isc_tokentype_string &&
+           strcasecmp(TOKEN_STRING(pctx), "none") == 0)
+       {
+               CHECK(cfg_gettoken(pctx, 0));
+               CHECK(cfg_create_obj(pctx, &cfg_type_none, ret));
+       } else {
+               CHECK(cfg_parse_sockaddr_generic(pctx, &cfg_type_querysource,
+                                                type, ret));
+       }
+
+cleanup:
        if (result != ISC_R_SUCCESS) {
                cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source");
        }
+
        return result;
 }
 
@@ -3233,15 +3254,15 @@ static void
 print_querysource(cfg_printer_t *pctx, const cfg_obj_t *obj) {
        isc_netaddr_t na;
        isc_netaddr_fromsockaddr(&na, &obj->value.sockaddr);
-       cfg_print_cstr(pctx, "address ");
        cfg_print_rawaddr(pctx, &na);
 }
 
 static void
-doc_querysource(cfg_printer_t *pctx, const cfg_type_t *type) {
+doc__querysource(cfg_printer_t *pctx, const cfg_type_t *type, bool has_none) {
        const unsigned int *flagp = type->of;
 
        cfg_print_cstr(pctx, "[ address ] ( ");
+
        if ((*flagp & CFG_ADDR_V4OK) != 0) {
                cfg_print_cstr(pctx, "<ipv4_address>");
        } else if ((*flagp & CFG_ADDR_V6OK) != 0) {
@@ -3249,7 +3270,22 @@ doc_querysource(cfg_printer_t *pctx, const cfg_type_t *type) {
        } else {
                UNREACHABLE();
        }
-       cfg_print_cstr(pctx, " | * )");
+
+       cfg_print_cstr(pctx, " | *");
+       if (has_none) {
+               cfg_print_cstr(pctx, " | none");
+       }
+       cfg_print_cstr(pctx, " )");
+}
+
+static void
+doc_querysource(cfg_printer_t *pctx, const cfg_type_t *type) {
+       doc__querysource(pctx, type, true);
+}
+
+static void
+doc_serverquerysource(cfg_printer_t *pctx, const cfg_type_t *type) {
+       doc__querysource(pctx, type, false);
 }
 
 static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK;
@@ -3270,6 +3306,16 @@ static cfg_type_t cfg_type_querysource6 = {
        NULL,           &querysource6wild_flags
 };
 
+static cfg_type_t cfg_type_server_querysource4 = {
+       "querysource4", parse_querysource,      NULL, doc_serverquerysource,
+       NULL,           &querysource4wild_flags
+};
+
+static cfg_type_t cfg_type_server_querysource6 = {
+       "querysource6", parse_querysource,      NULL, doc_serverquerysource,
+       NULL,           &querysource6wild_flags
+};
+
 static cfg_type_t cfg_type_querysource = { "querysource",     NULL,
                                           print_querysource, NULL,
                                           &cfg_rep_sockaddr, NULL };
index 5a6fb03ac4d7e2c64ddad13aabf1af20faff5981..1a1887d917ed36b2fa1e30ad65e90ad98056fca6 100644 (file)
@@ -15,6 +15,7 @@ LDADD +=                      \
 
 check_PROGRAMS =               \
        duration_test           \
-       parser_test
+       parser_test             \
+       grammar_test
 
 include $(top_srcdir)/Makefile.tests
diff --git a/tests/isccfg/grammar_test.c b/tests/isccfg/grammar_test.c
new file mode 100644 (file)
index 0000000..e276287
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+#include <inttypes.h>
+#include <sched.h> /* IWYU pragma: keep */
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define UNIT_TESTING
+#include <cmocka.h>
+
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#include <isccfg/cfg.h>
+#include <isccfg/grammar.h>
+#include <isccfg/namedconf.h>
+
+#include <tests/isc.h>
+
+static void
+write_to_buffer(void *closure, const char *text, int textlen);
+
+static isc_buffer_t gbuffer;
+static char gtext[512];
+static cfg_printer_t gprinter = {
+       .f = write_to_buffer, .closure = &gbuffer, .indent = 0, .flags = 0
+};
+
+ISC_SETUP_TEST_IMPL(group) {
+       isc_buffer_init(&gbuffer, gtext, sizeof(gtext));
+       isc_logconfig_t *logconfig = isc_logconfig_get();
+       isc_log_createandusechannel(
+               logconfig, "default_stderr", ISC_LOG_TOFILEDESC,
+               ISC_LOG_DYNAMIC, ISC_LOGDESTINATION_STDERR, 0,
+               ISC_LOGCATEGORY_DEFAULT, ISC_LOGMODULE_DEFAULT);
+
+       return 0;
+}
+
+static void
+write_to_buffer(void *closure, const char *text, int textlen) {
+       isc_buffer_putmem((isc_buffer_t *)closure, (const unsigned char *)text,
+                         textlen);
+}
+
+static void
+assert_text(const char *text) {
+       assert_int_equal(strcasecmp(text, isc_buffer_base(&gbuffer)), 0);
+       isc_buffer_clear(&gbuffer);
+       memset(gtext, 0, sizeof(gtext));
+}
+
+static const cfg_clausedef_t *
+find_clause(const cfg_type_t *map, const char *name) {
+       const char *found_name = NULL;
+       const void *clauses = NULL;
+       unsigned int idx;
+
+       found_name = cfg_map_firstclause(map, &clauses, &idx);
+       while (name != NULL && strcasecmp(name, found_name)) {
+               found_name = cfg_map_nextclause(map, &clauses, &idx);
+       }
+
+       return ((cfg_clausedef_t *)clauses) + idx;
+}
+
+static void
+test__querysource(const char *clause_name, const char *name,
+                 const char *expected) {
+       const cfg_clausedef_t *options_clause = NULL;
+       options_clause = find_clause(&cfg_type_namedconf, clause_name);
+       assert_non_null(options_clause);
+
+       const cfg_clausedef_t *querysource_clause = NULL;
+       querysource_clause = find_clause(options_clause->type, name);
+       assert_non_null(querysource_clause);
+       querysource_clause->type->doc(&gprinter, querysource_clause->type);
+       assert_text(expected);
+}
+
+ISC_RUN_TEST_IMPL(query_source) {
+       test__querysource("options", "query-source",
+                         "[ address ] ( <ipv4_address> | * | none )");
+}
+
+ISC_RUN_TEST_IMPL(query_source_v6) {
+       test__querysource("options", "query-source-v6",
+                         "[ address ] ( <ipv6_address> | * | none )");
+}
+
+ISC_RUN_TEST_IMPL(server_query_source) {
+       test__querysource("server", "query-source",
+                         "[ address ] ( <ipv4_address> | * )");
+}
+
+ISC_RUN_TEST_IMPL(server_query_source_v6) {
+       test__querysource("server", "query-source-v6",
+                         "[ address ] ( <ipv6_address> | * )");
+}
+
+static void
+test__query_source_print(const char *config, const char *expected) {
+       isc_result_t result;
+       isc_buffer_t buffer;
+       cfg_parser_t *parser = NULL;
+       cfg_obj_t *output_conf = NULL;
+
+       result = cfg_parser_create(mctx, &parser);
+       assert_int_equal(result, ISC_R_SUCCESS);
+
+       isc_buffer_constinit(&buffer, config, strlen(config));
+       isc_buffer_add(&buffer, strlen(config));
+
+       result = cfg_parse_buffer(parser, &buffer, "text1", 0,
+                                 &cfg_type_namedconf, 0, &output_conf);
+       assert_int_equal(result, ISC_R_SUCCESS);
+       assert_non_null(output_conf);
+
+       cfg_printer_t pctx = gprinter;
+       pctx.flags = CFG_PRINTER_ONELINE;
+
+       output_conf->type->print(&pctx, output_conf);
+       assert_text(expected);
+
+       cfg_obj_destroy(parser, &output_conf);
+       cfg_parser_reset(parser);
+       cfg_parser_destroy(&parser);
+}
+
+ISC_RUN_TEST_IMPL(query_source_print_none) {
+       test__query_source_print(" options     {    query-source none;     };",
+                                "options { query-source none; }; ");
+       test__query_source_print(
+               " options     { query-source address none;  };",
+               "options { query-source none; }; ");
+       test__query_source_print(" options     {query-source-v6 none;     };",
+                                "options { query-source-v6 none; }; ");
+       test__query_source_print(" options {query-source-v6 address none;  };",
+                                "options { query-source-v6 none; }; ");
+}
+
+ISC_RUN_TEST_IMPL(query_source_print_addr) {
+       test__query_source_print(" options{query-source address 127.0.0.1;};",
+                                "options { query-source 127.0.0.1; }; ");
+       test__query_source_print(" options{query-source 127.0.0.1;};",
+                                "options { query-source 127.0.0.1; }; ");
+       test__query_source_print(" options{query-source-v6 address ::1;     };",
+                                "options { query-source-v6 ::1; }; ");
+       test__query_source_print(" options{query-source-v6 ::1;     };",
+                                "options { query-source-v6 ::1; }; ");
+}
+
+ISC_TEST_LIST_START
+
+ISC_TEST_ENTRY(query_source)
+ISC_TEST_ENTRY(query_source_v6)
+ISC_TEST_ENTRY(server_query_source)
+ISC_TEST_ENTRY(server_query_source_v6)
+ISC_TEST_ENTRY(query_source_print_none)
+ISC_TEST_ENTRY(query_source_print_addr)
+
+ISC_TEST_LIST_END
+
+ISC_TEST_MAIN_CUSTOM(setup_test_group, NULL)