diff --git a/CHANGES b/CHANGES
index 9d9077e748..f56478cc0c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3778. [bug] Log a warning when the wrong address family is
+ used in "listen-on" or "listen-on-v6". [RT #17848]
+
3777. [bug] EDNS EXPIRE code could dump core when processing
DLZ queries. [RT #35493]
diff --git a/bin/named/server.c b/bin/named/server.c
index 5b25cb8186..c7dcf2fbc5 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -378,12 +378,12 @@ ns_server_reload(isc_task_t *task, isc_event_t *event);
static isc_result_t
ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
- cfg_aclconfctx_t *actx,
- isc_mem_t *mctx, ns_listenelt_t **target);
+ cfg_aclconfctx_t *actx, isc_mem_t *mctx,
+ isc_uint16_t family, ns_listenelt_t **target);
static isc_result_t
ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
- cfg_aclconfctx_t *actx,
- isc_mem_t *mctx, ns_listenlist_t **target);
+ cfg_aclconfctx_t *actx, isc_mem_t *mctx,
+ isc_uint16_t family, ns_listenlist_t **target);
static isc_result_t
configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
@@ -5676,7 +5676,8 @@ load_configuration(const char *filename, ns_server_t *server,
/* check return code? */
(void)ns_listenlist_fromconfig(clistenon, config,
ns_g_aclconfctx,
- ns_g_mctx, &listenon);
+ ns_g_mctx, AF_INET,
+ &listenon);
} else if (!ns_g_lwresdonly) {
/*
* Not specified, use default.
@@ -5703,7 +5704,8 @@ load_configuration(const char *filename, ns_server_t *server,
/* check return code? */
(void)ns_listenlist_fromconfig(clistenon, config,
ns_g_aclconfctx,
- ns_g_mctx, &listenon);
+ ns_g_mctx, AF_INET6,
+ &listenon);
} else if (!ns_g_lwresdonly) {
/*
* Not specified, use default.
@@ -7343,8 +7345,8 @@ ns_server_togglequerylog(ns_server_t *server, char *args) {
static isc_result_t
ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
- cfg_aclconfctx_t *actx,
- isc_mem_t *mctx, ns_listenlist_t **target)
+ cfg_aclconfctx_t *actx, isc_mem_t *mctx,
+ isc_uint16_t family, ns_listenlist_t **target)
{
isc_result_t result;
const cfg_listelt_t *element;
@@ -7363,7 +7365,7 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
ns_listenelt_t *delt = NULL;
const cfg_obj_t *listener = cfg_listelt_value(element);
result = ns_listenelt_fromconfig(listener, config, actx,
- mctx, &delt);
+ mctx, family, &delt);
if (result != ISC_R_SUCCESS)
goto cleanup;
ISC_LIST_APPEND(dlist->elts, delt, link);
@@ -7382,8 +7384,8 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
*/
static isc_result_t
ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
- cfg_aclconfctx_t *actx,
- isc_mem_t *mctx, ns_listenelt_t **target)
+ cfg_aclconfctx_t *actx, isc_mem_t *mctx,
+ isc_uint16_t family, ns_listenelt_t **target)
{
isc_result_t result;
const cfg_obj_t *portobj, *dscpobj;
@@ -7428,9 +7430,9 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
if (result != ISC_R_SUCCESS)
return (result);
- result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"),
- config, ns_g_lctx, actx, mctx, 0,
- &delt->acl);
+ result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"),
+ config, ns_g_lctx, actx, mctx, 0,
+ family, &delt->acl);
if (result != ISC_R_SUCCESS) {
ns_listenelt_destroy(delt);
return (result);
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index d5f8bcf6f8..6392a36248 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -4669,8 +4669,8 @@ badresp:1,adberr:0,findfail:0,valfail:0]
The listen-on statement specifies a
list of
- addresses (and ports) that this instance of a lightweight resolver
- daemon
+ IPv4 addresses (and ports) that this instance of a lightweight
+ resolver daemon
should accept requests on. If no port is specified, port 921 is
used.
If this statement is omitted, requests will be accepted on
@@ -7342,7 +7342,9 @@ options {
The interfaces and ports that the server will answer queries
from may be specified using the listen-on option. listen-on takes
- an optional port and an address_match_list.
+ an optional port and an address_match_list
+ of IPv4 addresses. (IPv6 addresses are ignored, with a
+ logged warning.)
The server will listen on all interfaces allowed by the address
match list. If a port is not specified, port 53 will be used.
@@ -7394,6 +7396,8 @@ listen-on port 1234 { !1.2.3.4; 1.2/16; };
the server listens on a separate socket for each specified
address,
regardless of whether the desired API is supported by the system.
+ IPv4 addresses specified in listen-on-v6
+ will be ignored, with a logged warning.
diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c
index bcd50e0173..5945c1db03 100644
--- a/lib/isccfg/aclconf.c
+++ b/lib/isccfg/aclconf.c
@@ -543,13 +543,20 @@ parse_geoip_element(const cfg_obj_t *obj, isc_log_t *lctx,
#endif
isc_result_t
-cfg_acl_fromconfig(const cfg_obj_t *caml,
- const cfg_obj_t *cctx,
- isc_log_t *lctx,
- cfg_aclconfctx_t *ctx,
- isc_mem_t *mctx,
- unsigned int nest_level,
+cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_log_t *lctx, cfg_aclconfctx_t *ctx,
+ isc_mem_t *mctx, unsigned int nest_level,
dns_acl_t **target)
+{
+ return (cfg_acl_fromconfig2(caml, cctx, lctx, ctx, mctx,
+ nest_level, 0, target));
+}
+
+isc_result_t
+cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_log_t *lctx, cfg_aclconfctx_t *ctx,
+ isc_mem_t *mctx, unsigned int nest_level,
+ isc_uint16_t family, dns_acl_t **target)
{
isc_result_t result;
dns_acl_t *dacl = NULL, *inneracl = NULL;
@@ -632,6 +639,16 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
unsigned int bitlen;
cfg_obj_asnetprefix(ce, &addr, &bitlen);
+ if (family != 0 && family != addr.family) {
+ char buf[ISC_NETADDR_FORMATSIZE + 1];
+ isc_netaddr_format(&addr, buf, sizeof(buf));
+ cfg_obj_log(ce, lctx, ISC_LOG_WARNING,
+ "'%s': incorrect address family; "
+ "ignoring", buf);
+ if (nest_level != 0)
+ dns_acl_detach(&de->nestedacl);
+ continue;
+ }
/*
* If nesting ACLs (nest_level != 0), we negate
diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h
index ba4e828fd1..c087792459 100644
--- a/lib/isccfg/include/isccfg/aclconf.h
+++ b/lib/isccfg/include/isccfg/aclconf.h
@@ -64,13 +64,16 @@ cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest);
*/
isc_result_t
-cfg_acl_fromconfig(const cfg_obj_t *caml,
- const cfg_obj_t *cctx,
- isc_log_t *lctx,
- cfg_aclconfctx_t *ctx,
- isc_mem_t *mctx,
- unsigned int nest_level,
+cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_log_t *lctx, cfg_aclconfctx_t *ctx,
+ isc_mem_t *mctx, unsigned int nest_level,
dns_acl_t **target);
+
+isc_result_t
+cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx,
+ isc_log_t *lctx, cfg_aclconfctx_t *ctx,
+ isc_mem_t *mctx, unsigned int nest_level,
+ isc_uint16_t family, dns_acl_t **target);
/*
* Construct a new dns_acl_t from configuration data in 'caml' and
* 'cctx'. Memory is allocated through 'mctx'.
@@ -81,6 +84,11 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
* nested dns_acl_t object when the referring objects were created
* passing the same ACL configuration context 'ctx'.
*
+ * cfg_acl_fromconfig() is a backward-compatible version of
+ * cfg_acl_fromconfig2(), which allows an address family to be
+ * specified. If 'family' is not zero, then only addresses/prefixes
+ * of a matching family (AF_INET or AF_INET6) may be configured.
+ *
* On success, attach '*target' to the new dns_acl_t object.
*/
diff --git a/lib/isccfg/win32/libisccfg.def b/lib/isccfg/win32/libisccfg.def
index 7367d3d0dd..403c0c2c31 100644
--- a/lib/isccfg/win32/libisccfg.def
+++ b/lib/isccfg/win32/libisccfg.def
@@ -4,6 +4,7 @@ LIBRARY libisccfg
EXPORTS
cfg_acl_fromconfig
+cfg_acl_fromconfig2
cfg_aclconfctx_attach
cfg_aclconfctx_create
cfg_aclconfctx_detach