mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 18:22:05 -04:00
Add none parameter to query-source and query-source-v6 to disable IPv4 or IPv6 upstream queries
Add a none parameter to named configuration option `query-source` (respectively `query-source-v6`) which forbid usage of IPv4 (respectively IPv6) addresses when named is doing an upstream query. Closes #4981 Turning-off upstream IPv6 queries while still listening to downstream queries on IPv6. Merge branch 'colin/querysource-none' into 'main' See merge request isc-projects/bind9!9727 Backport of MR !9727 Some changes had to be done to the existing 9.20.x code in order to make this backport compatible: - first, the 9.20.x branches support the `port` parameter in query-source[-v6], where 9.21.x does not. The original changes depend on things that can't be backported because that would break `port` support. - second, the changes remove the optional `address` parameter from the canonical form. So `query-source address <ip>` is now printed as `query-source <ip>`. This means that `named-checkconf -p` will now generate different output if users have `query-source address <ip>` or `query-source address <ip> port <port>`; it will now generate `query-source <ip>` or `query-source <ip> port <port>`. This is a non-breaking change, because the parser has been updated to support this form as well.
This commit is contained in:
parent
efbfa541b5
commit
32f5b69703
27 changed files with 769 additions and 52 deletions
|
|
@ -1290,8 +1290,21 @@ get_view_querysource_dispatch(const cfg_obj_t **maps, int af,
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
sa = *(cfg_obj_assockaddr(obj));
|
||||
INSIST(isc_sockaddr_pf(&sa) == af);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't support this address family, we're done!
|
||||
|
|
@ -1618,6 +1631,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;
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ TESTS = \
|
|||
proxy \
|
||||
pipelined \
|
||||
qmin \
|
||||
query-source \
|
||||
reclimit \
|
||||
redirect \
|
||||
resolver \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -20,3 +20,7 @@ options {
|
|||
range 8610 8614;
|
||||
};
|
||||
};
|
||||
|
||||
server 1.2.3.4 {
|
||||
query-source 10.10.10.10;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,3 +20,7 @@ zone example {
|
|||
primaries { 1.2.3.4; };
|
||||
notify-source 10.53.0.1 port 100;
|
||||
};
|
||||
|
||||
server fd92:7065:b8e:ffff::1 {
|
||||
query-source-v6 fd92:7065:b8e:ffff::2;
|
||||
};
|
||||
|
|
|
|||
37
bin/tests/system/query-source/ns1/named.conf.in
Normal file
37
bin/tests/system/query-source/ns1/named.conf.in
Normal file
|
|
@ -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";
|
||||
};
|
||||
16
bin/tests/system/query-source/ns1/root.db
Normal file
16
bin/tests/system/query-source/ns1/root.db
Normal file
|
|
@ -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
|
||||
37
bin/tests/system/query-source/ns2/named.conf.in
Normal file
37
bin/tests/system/query-source/ns2/named.conf.in
Normal file
|
|
@ -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";
|
||||
};
|
||||
14
bin/tests/system/query-source/ns2/root.hint
Normal file
14
bin/tests/system/query-source/ns2/root.hint
Normal file
|
|
@ -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
|
||||
37
bin/tests/system/query-source/ns3/named.conf.in
Normal file
37
bin/tests/system/query-source/ns3/named.conf.in
Normal file
|
|
@ -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";
|
||||
};
|
||||
14
bin/tests/system/query-source/ns3/root.hint
Normal file
14
bin/tests/system/query-source/ns3/root.hint
Normal file
|
|
@ -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
|
||||
37
bin/tests/system/query-source/ns4/named.conf.in
Normal file
37
bin/tests/system/query-source/ns4/named.conf.in
Normal file
|
|
@ -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";
|
||||
};
|
||||
14
bin/tests/system/query-source/ns4/root.hint
Normal file
14
bin/tests/system/query-source/ns4/root.hint
Normal file
|
|
@ -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
|
||||
37
bin/tests/system/query-source/ns5/named.conf.in
Normal file
37
bin/tests/system/query-source/ns5/named.conf.in
Normal file
|
|
@ -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";
|
||||
};
|
||||
14
bin/tests/system/query-source/ns5/root.hint
Normal file
14
bin/tests/system/query-source/ns5/root.hint
Normal file
|
|
@ -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
|
||||
20
bin/tests/system/query-source/setup.sh
Normal file
20
bin/tests/system/query-source/setup.sh
Normal file
|
|
@ -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
|
||||
58
bin/tests/system/query-source/tests_querysource_none.py
Normal file
58
bin/tests/system/query-source/tests_querysource_none.py
Normal file
|
|
@ -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)
|
||||
|
|
@ -3316,11 +3316,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 and port used for
|
||||
|
|
|
|||
|
|
@ -233,8 +233,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>;
|
||||
|
|
@ -520,8 +520,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>;
|
||||
|
|
|
|||
|
|
@ -1338,25 +1338,49 @@ 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) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'%s' cannot specify the "
|
||||
"DNS listener port (%d)",
|
||||
sources[i], port);
|
||||
result = ISC_R_FAILURE;
|
||||
} else if (port != 0) {
|
||||
cfg_obj_log(obj, logctx,
|
||||
ISC_LOG_WARNING,
|
||||
"'%s': specifying a port "
|
||||
"is not recommended",
|
||||
sources[i]);
|
||||
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, logctx,
|
||||
ISC_LOG_ERROR,
|
||||
"'%s' cannot "
|
||||
"specify the "
|
||||
"DNS listener port "
|
||||
"(%d)",
|
||||
sources[i], port);
|
||||
result = ISC_R_FAILURE;
|
||||
} else if (port != 0) {
|
||||
cfg_obj_log(
|
||||
obj, logctx,
|
||||
ISC_LOG_WARNING,
|
||||
"'%s': specifying a "
|
||||
"port "
|
||||
"is not recommended",
|
||||
sources[i]);
|
||||
}
|
||||
} else if (cfg_obj_isvoid(obj)) {
|
||||
none_found++;
|
||||
|
||||
if (none_found > 1) {
|
||||
cfg_obj_log(obj, logctx,
|
||||
ISC_LOG_ERROR,
|
||||
"query-source and "
|
||||
"query-source-v6 "
|
||||
"can't be "
|
||||
"none at the same "
|
||||
"time.");
|
||||
result = ISC_R_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4479,14 +4503,27 @@ 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, logctx,
|
||||
ISC_LOG_ERROR,
|
||||
"'%s' cannot "
|
||||
"specify the "
|
||||
"DNS listener port "
|
||||
"(%d)",
|
||||
xfr, port);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
} else {
|
||||
cfg_obj_log(obj, logctx, 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,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;
|
||||
|
|
@ -2724,8 +2726,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-nsid", &cfg_type_boolean, 0 },
|
||||
|
|
@ -3358,6 +3360,7 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|||
unsigned int have_address = 0;
|
||||
unsigned int have_port = 0;
|
||||
unsigned int have_tls = 0;
|
||||
bool has_none = false;
|
||||
const unsigned int *flagp = type->of;
|
||||
|
||||
if ((*flagp & CFG_ADDR_V4OK) != 0) {
|
||||
|
|
@ -3371,12 +3374,25 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|||
for (;;) {
|
||||
CHECK(cfg_peektoken(pctx, 0));
|
||||
if (pctx->token.type == isc_tokentype_string) {
|
||||
if (strcasecmp(TOKEN_STRING(pctx), "address") == 0) {
|
||||
if (strcasecmp(TOKEN_STRING(pctx), "none") == 0) {
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
has_none = true;
|
||||
} else if (strcasecmp(TOKEN_STRING(pctx), "address") ==
|
||||
0)
|
||||
{
|
||||
/* read "address" */
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
CHECK(cfg_parse_rawaddr(pctx, *flagp,
|
||||
&netaddr));
|
||||
have_address++;
|
||||
|
||||
CHECK(cfg_peektoken(pctx, 0));
|
||||
if (strcasecmp(TOKEN_STRING(pctx), "none") == 0)
|
||||
{
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
has_none = true;
|
||||
} else {
|
||||
CHECK(cfg_parse_rawaddr(pctx, *flagp,
|
||||
&netaddr));
|
||||
have_address++;
|
||||
}
|
||||
} else if (strcasecmp(TOKEN_STRING(pctx), "port") == 0)
|
||||
{
|
||||
/* read "port" */
|
||||
|
|
@ -3396,7 +3412,9 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|||
} else if (have_port == 0 && have_tls == 0 &&
|
||||
have_address == 0)
|
||||
{
|
||||
return cfg_parse_sockaddr(pctx, type, ret);
|
||||
CHECK(cfg_parse_rawaddr(pctx, *flagp,
|
||||
&netaddr));
|
||||
have_address++;
|
||||
} else {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"expected 'address' "
|
||||
|
|
@ -3408,25 +3426,31 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
|||
}
|
||||
}
|
||||
|
||||
if (have_address > 1 || have_port > 1 || have_address + have_port == 0)
|
||||
{
|
||||
cfg_parser_error(pctx, 0, "expected one address and/or port");
|
||||
return ISC_R_UNEXPECTEDTOKEN;
|
||||
}
|
||||
if (!has_none) {
|
||||
if (have_address > 1 || have_port > 1 ||
|
||||
have_address + have_port == 0)
|
||||
{
|
||||
cfg_parser_error(pctx, 0,
|
||||
"expected one address and/or port");
|
||||
return ISC_R_UNEXPECTEDTOKEN;
|
||||
}
|
||||
if (have_tls > 0) {
|
||||
cfg_parser_error(pctx, 0, "unexpected tls");
|
||||
return ISC_R_UNEXPECTEDTOKEN;
|
||||
}
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj));
|
||||
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
|
||||
|
||||
if (have_tls > 0) {
|
||||
cfg_parser_error(pctx, 0, "unexpected tls");
|
||||
return ISC_R_UNEXPECTEDTOKEN;
|
||||
} else {
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_none, &obj));
|
||||
}
|
||||
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj));
|
||||
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
|
||||
*ret = obj;
|
||||
return ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source");
|
||||
CLEANUP_OBJ(obj);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -3434,17 +3458,17 @@ 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);
|
||||
cfg_print_cstr(pctx, " port ");
|
||||
cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr));
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -3452,7 +3476,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;
|
||||
|
|
@ -3468,6 +3507,19 @@ static cfg_type_t cfg_type_querysource6 = {
|
|||
NULL, &sockaddr6wild_flags
|
||||
};
|
||||
|
||||
static unsigned int querysource4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK;
|
||||
static unsigned int querysource6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK;
|
||||
|
||||
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 };
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ LDADD += \
|
|||
|
||||
check_PROGRAMS = \
|
||||
duration_test \
|
||||
parser_test
|
||||
parser_test \
|
||||
grammar_test
|
||||
|
||||
include $(top_srcdir)/Makefile.tests
|
||||
|
|
|
|||
184
tests/isccfg/grammar_test.c
Normal file
184
tests/isccfg/grammar_test.c
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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));
|
||||
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, lctx, &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 port 0; }; ");
|
||||
test__query_source_print(" options{query-source-v6 address ::1; };",
|
||||
"options { query-source-v6 ::1 port 0; }; ");
|
||||
test__query_source_print(
|
||||
" options{query-source 127.0.0.1;};",
|
||||
"options { query-source 127.0.0.1 port 0; }; ");
|
||||
test__query_source_print(" options{query-source-v6 ::1; };",
|
||||
"options { query-source-v6 ::1 port 0; }; ");
|
||||
test__query_source_print(
|
||||
"options { query-source 127.0.0.1 port 6666; };",
|
||||
"options { query-source 127.0.0.1 port 6666; }; ");
|
||||
}
|
||||
|
||||
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)
|
||||
Loading…
Reference in a new issue