From 8ac1d4e0daee6fc785377761da42023127ec2284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 7 Sep 2021 14:40:19 +0200 Subject: [PATCH 1/3] Remove the code to adjust listening interfaces for *-source-v6 Previously, named would run with a configuration where *-source-v6 (notify-source-v6, transfer-source-v6 and query-source-v6) address and port could be simultaneously used for listening. This is no longer true for BIND 9.16+ and the code that would do interface adjustments would unexpectedly disable listening on TCP for such interfaces. This commit removes the code that would adjust listening interfaces for addresses/ports configured in *-source-v6 option. --- bin/named/server.c | 163 ------------------------------- lib/ns/include/ns/interfacemgr.h | 14 --- lib/ns/interfacemgr.c | 117 +++++++--------------- 3 files changed, 33 insertions(+), 261 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index fcbca7e863..dffa7de289 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -6946,161 +6946,6 @@ directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { return (ISC_R_SUCCESS); } -static isc_result_t -add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr, - isc_dscp_t dscp, bool wcardport_ok) { - ns_listenelt_t *lelt = NULL; - dns_acl_t *src_acl = NULL; - isc_result_t result; - isc_sockaddr_t any_sa6; - isc_netaddr_t netaddr; - - REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); - - isc_sockaddr_any6(&any_sa6); - if (!isc_sockaddr_equal(&any_sa6, addr) && - (wcardport_ok || isc_sockaddr_getport(addr) != 0)) - { - isc_netaddr_fromin6(&netaddr, &addr->type.sin6.sin6_addr); - - result = dns_acl_create(mctx, 0, &src_acl); - if (result != ISC_R_SUCCESS) { - return (result); - } - - result = dns_iptable_addprefix(src_acl->iptable, &netaddr, 128, - true); - if (result != ISC_R_SUCCESS) { - goto clean; - } - - result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), - dscp, src_acl, false, NULL, NULL, - &lelt); - if (result != ISC_R_SUCCESS) { - goto clean; - } - ISC_LIST_APPEND(list->elts, lelt, link); - } - - return (ISC_R_SUCCESS); - -clean: - INSIST(lelt == NULL); - dns_acl_detach(&src_acl); - - return (result); -} - -/* - * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() - * to update the listening interfaces accordingly. - * We currently only consider IPv6, because this only affects IPv6 wildcard - * sockets. - */ -static void -adjust_interfaces(named_server_t *server, isc_mem_t *mctx) { - isc_result_t result; - ns_listenlist_t *list = NULL; - dns_view_t *view; - dns_zone_t *zone, *next; - isc_sockaddr_t addr, *addrp; - isc_dscp_t dscp = -1; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) { - return; - } - - for (view = ISC_LIST_HEAD(server->viewlist); view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - dns_dispatch_t *dispatch6; - - dispatch6 = dns_resolver_dispatchv6(view->resolver); - if (dispatch6 == NULL) { - continue; - } - result = dns_dispatch_getlocaladdress(dispatch6, &addr); - if (result != ISC_R_SUCCESS) { - goto fail; - } - - /* - * We always add non-wildcard address regardless of whether - * the port is 'any' (the fourth arg is TRUE): if the port is - * specific, we need to add it since it may conflict with a - * listening interface; if it's zero, we'll dynamically open - * query ports, and some of them may override an existing - * wildcard IPv6 port. - */ - /* XXXMPA fix dscp */ - result = add_listenelt(mctx, list, &addr, dscp, true); - if (result != ISC_R_SUCCESS) { - goto fail; - } - } - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) - { - dns_view_t *zoneview; - - /* - * At this point the zone list may contain a stale zone - * just removed from the configuration. To see the validity, - * check if the corresponding view is in our current view list. - * There may also be old zones that are still in the process - * of shutting down and have detached from their old view - * (zoneview == NULL). - */ - zoneview = dns_zone_getview(zone); - if (zoneview == NULL) { - continue; - } - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL && view != zoneview; - view = ISC_LIST_NEXT(view, link)) - {} - if (view == NULL) { - continue; - } - - addrp = dns_zone_getnotifysrc6(zone); - dscp = dns_zone_getnotifysrc6dscp(zone); - result = add_listenelt(mctx, list, addrp, dscp, false); - if (result != ISC_R_SUCCESS) { - goto fail; - } - - addrp = dns_zone_getxfrsource6(zone); - dscp = dns_zone_getxfrsource6dscp(zone); - result = add_listenelt(mctx, list, addrp, dscp, false); - if (result != ISC_R_SUCCESS) { - goto fail; - } - } - - ns_interfacemgr_adjust(server->interfacemgr, list, true); - -clean: - ns_listenlist_detach(&list); - return; - -fail: - /* - * Even when we failed the procedure, most of other interfaces - * should work correctly. We therefore just warn it. - */ - isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, - NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING, - "could not adjust the listen-on list; " - "some interfaces may not work"); - goto clean; -} - /* * This event callback is invoked to do periodic network interface * scanning. @@ -9880,14 +9725,6 @@ cleanup: isc_mem_put(server->sctx->mctx, altsecret, sizeof(*altsecret)); } - /* - * Adjust the listening interfaces in accordance with the source - * addresses specified in views and zones. - */ - if (isc_net_probeipv6() == ISC_R_SUCCESS) { - adjust_interfaces(server, named_g_mctx); - } - /* * Record the time of most recent configuration */ diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h index c6482e2040..9a975c6eb5 100644 --- a/lib/ns/include/ns/interfacemgr.h +++ b/lib/ns/include/ns/interfacemgr.h @@ -147,20 +147,6 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose); * in named.conf. */ -isc_result_t -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - bool verbose); -/*%< - * Similar to ns_interfacemgr_scan(), but this function also tries to see the - * need for an explicit listen-on when a list element in 'list' is going to - * override an already-listening a wildcard interface. - * - * This function does not update localhost and localnets ACLs. - * - * This should be called once on server startup, after configuring views and - * zones. - */ - void ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); /*%< diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 0d45dde91f..649dbc8ef8 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -605,7 +605,7 @@ ns_interface_listenhttp(ns_interface_t *ifp, isc_tlsctx_t *sslctx, char **eps, static isc_result_t ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret, bool accept_tcp, + const char *name, ns_interface_t **ifpret, ns_listenelt_t *elt, bool *addr_in_use) { isc_result_t result; ns_interface_t *ifp = NULL; @@ -648,7 +648,7 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, goto cleanup_interface; } - if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0) && accept_tcp) { + if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0)) { result = ns_interface_listentcp(ifp); if (result != ISC_R_SUCCESS) { if ((result == ISC_R_ADDRINUSE) && @@ -902,11 +902,10 @@ clearlistenon(ns_interfacemgr_t *mgr) { } static isc_result_t -do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { +do_scan(ns_interfacemgr_t *mgr, bool verbose) { isc_interfaceiter_t *iter = NULL; bool scan_ipv4 = false; bool scan_ipv6 = false; - bool adjusting = false; bool ipv6only = true; bool ipv6pktinfo = true; isc_result_t result; @@ -920,10 +919,6 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { bool tried_listening; bool all_addresses_in_use; - if (ext_listen != NULL) { - adjusting = true; - } - if (isc_net_probeipv6() == ISC_R_SUCCESS) { scan_ipv6 = true; } else if ((mgr->sctx->options & NS_SERVER_DISABLE6) == 0) { @@ -992,8 +987,8 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { "interfaces, port %u", le->port); result = ns_interface_setup(mgr, &listen_addr, - "", &ifp, true, - le, NULL); + "", &ifp, le, + NULL); if (result == ISC_R_SUCCESS) { ifp->flags |= NS_INTERFACEFLAG_ANYADDR; } else { @@ -1015,17 +1010,15 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { return (result); } - if (!adjusting) { - result = clearacl(mgr->mctx, &mgr->aclenv->localhost); - if (result != ISC_R_SUCCESS) { - goto cleanup_iter; - } - result = clearacl(mgr->mctx, &mgr->aclenv->localnets); - if (result != ISC_R_SUCCESS) { - goto cleanup_iter; - } - clearlistenon(mgr); + result = clearacl(mgr->mctx, &mgr->aclenv->localhost); + if (result != ISC_R_SUCCESS) { + goto cleanup_iter; } + result = clearacl(mgr->mctx, &mgr->aclenv->localnets); + if (result != ISC_R_SUCCESS) { + goto cleanup_iter; + } + clearlistenon(mgr); tried_listening = false; all_addresses_in_use = true; @@ -1068,22 +1061,19 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { continue; } - if (!adjusting) { - /* - * If running with -T fixedlocal, then we only - * want 127.0.0.1 and ::1 in the localhost ACL. - */ - if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) != - 0) && - !isc_netaddr_isloopback(&interface.address)) - { - goto listenon; - } + /* + * If running with -T fixedlocal, then we only + * want 127.0.0.1 and ::1 in the localhost ACL. + */ + if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) != 0) && + !isc_netaddr_isloopback(&interface.address)) + { + goto listenon; + } - result = setup_locals(mgr, &interface); - if (result != ISC_R_SUCCESS) { - goto ignore_interface; - } + result = setup_locals(mgr, &interface); + if (result != ISC_R_SUCCESS) { + goto ignore_interface; } listenon: @@ -1123,7 +1113,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { continue; } - if (!adjusting && dolistenon) { + if (dolistenon) { setup_listenon(mgr, &interface, le->port); dolistenon = false; } @@ -1137,37 +1127,6 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { ipv6_wildcard = true; } - /* - * When adjusting interfaces with extra a listening - * list, see if the address matches the extra list. - * If it does, and is also covered by a wildcard - * interface, we need to listen on the address - * explicitly. - */ - if (adjusting) { - ns_listenelt_t *ele; - - match = 0; - for (ele = ISC_LIST_HEAD(ext_listen->elts); - ele != NULL; - ele = ISC_LIST_NEXT(ele, link)) - { - (void)dns_acl_match(&listen_netaddr, - NULL, ele->acl, - NULL, &match, NULL); - if (match > 0 && - (ele->port == le->port || - ele->port == 0)) { - break; - } else { - match = 0; - } - } - if (ipv6_wildcard && match == 0) { - continue; - } - } - ifp = find_matching_interface(mgr, &listen_sockaddr); if (ifp != NULL) { ifp->generation = mgr->generation; @@ -1186,12 +1145,12 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { } else { bool addr_in_use = false; - if (!adjusting && ipv6_wildcard) { + if (ipv6_wildcard) { continue; } if (log_explicit && family == AF_INET6 && - !adjusting && listenon_is_ip6_any(le)) { + listenon_is_ip6_any(le)) { isc_log_write( IFMGR_COMMON_LOGARGS, verbose ? ISC_LOG_INFO @@ -1206,17 +1165,14 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { sizeof(sabuf)); isc_log_write( IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, - "%s" "listening on %s interface " "%s, %s", - (adjusting) ? "additionally " : "", (family == AF_INET) ? "IPv4" : "IPv6", interface.name, sabuf); result = ns_interface_setup( mgr, &listen_sockaddr, interface.name, - &ifp, (adjusting) ? false : true, le, - &addr_in_use); + &ifp, le, &addr_in_use); tried_listening = true; if (!addr_in_use) { @@ -1263,8 +1219,7 @@ cleanup_iter: } static isc_result_t -ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - bool verbose) { +ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, bool verbose) { isc_result_t result; bool purge = true; @@ -1272,7 +1227,7 @@ ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, mgr->generation++; /* Increment the generation count. */ - result = do_scan(mgr, ext_listen, verbose); + result = do_scan(mgr, verbose); if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) { purge = false; } @@ -1290,7 +1245,7 @@ ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, /* * Warn if we are not listening on any interface. */ - if (ext_listen == NULL && ISC_LIST_EMPTY(mgr->interfaces)) { + if (ISC_LIST_EMPTY(mgr->interfaces)) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, "not listening on any interfaces"); } @@ -1320,7 +1275,7 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose) { unlock = true; } - result = ns_interfacemgr_scan0(mgr, NULL, verbose); + result = ns_interfacemgr_scan0(mgr, verbose); if (unlock) { isc_task_endexclusive(mgr->excl); @@ -1329,12 +1284,6 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose) { return (result); } -isc_result_t -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - bool verbose) { - return (ns_interfacemgr_scan0(mgr, list, verbose)); -} - void ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { REQUIRE(NS_INTERFACEMGR_VALID(mgr)); From 8a4c44ca24124b661666ce82358152c09afbd31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 7 Sep 2021 15:00:06 +0200 Subject: [PATCH 2/3] Adjust system forward test to also use IPv6 addresses The ns3->ns2 forwarding is now done using the IPv6 addresses, so we also test that the query-source-v6 address is still operational after removal of interface adjustment. --- bin/tests/system/forward/ns1/named.conf.in | 5 ++++- bin/tests/system/forward/ns2/named.conf.in | 5 ++++- bin/tests/system/forward/ns3/named1.conf.in | 7 +++++-- bin/tests/system/forward/ns3/named2.conf.in | 5 ++++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/bin/tests/system/forward/ns1/named.conf.in b/bin/tests/system/forward/ns1/named.conf.in index 28d1b33785..4aef4e55e5 100644 --- a/bin/tests/system/forward/ns1/named.conf.in +++ b/bin/tests/system/forward/ns1/named.conf.in @@ -11,12 +11,15 @@ options { query-source address 10.53.0.1; + query-source-v6 address fd92:7065:b8e:ffff::1; notify-source 10.53.0.1; + notify-source-v6 fd92:7065:b8e:ffff::1; transfer-source 10.53.0.1; + transfer-source-v6 fd92:7065:b8e:ffff::1; port @PORT@; pid-file "named.pid"; listen-on { 10.53.0.1; }; - listen-on-v6 { none; }; + listen-on-v6 { fd92:7065:b8e:ffff::1; }; recursion no; dnssec-validation no; }; diff --git a/bin/tests/system/forward/ns2/named.conf.in b/bin/tests/system/forward/ns2/named.conf.in index f7256abb14..31e5f05546 100644 --- a/bin/tests/system/forward/ns2/named.conf.in +++ b/bin/tests/system/forward/ns2/named.conf.in @@ -11,12 +11,15 @@ options { query-source address 10.53.0.2; + query-source-v6 address fd92:7065:b8e:ffff::2; notify-source 10.53.0.2; + notify-source-v6 fd92:7065:b8e:ffff::2; transfer-source 10.53.0.2; + transfer-source-v6 fd92:7065:b8e:ffff::2; port @PORT@; pid-file "named.pid"; listen-on { 10.53.0.2; }; - listen-on-v6 { none; }; + listen-on-v6 { fd92:7065:b8e:ffff::2; }; recursion no; dnssec-validation no; }; diff --git a/bin/tests/system/forward/ns3/named1.conf.in b/bin/tests/system/forward/ns3/named1.conf.in index 326befd99b..da0979f29e 100644 --- a/bin/tests/system/forward/ns3/named1.conf.in +++ b/bin/tests/system/forward/ns3/named1.conf.in @@ -11,13 +11,16 @@ options { query-source address 10.53.0.3; + query-source-v6 address fd92:7065:b8e:ffff::3; notify-source 10.53.0.3; + notify-source-v6 fd92:7065:b8e:ffff::3; transfer-source 10.53.0.3; + transfer-source-v6 fd92:7065:b8e:ffff::3; port @PORT@; pid-file "named.pid"; listen-on { 10.53.0.3; }; - listen-on-v6 { none; }; - forwarders { 10.53.0.2; }; + listen-on-v6 { fd92:7065:b8e:ffff::3; }; + forwarders { fd92:7065:b8e:ffff::2; }; forward first; dnssec-validation yes; }; diff --git a/bin/tests/system/forward/ns3/named2.conf.in b/bin/tests/system/forward/ns3/named2.conf.in index cf45ea62a9..4eb98edcb5 100644 --- a/bin/tests/system/forward/ns3/named2.conf.in +++ b/bin/tests/system/forward/ns3/named2.conf.in @@ -11,12 +11,15 @@ options { query-source address 10.53.0.3; + query-source-v6 address fd92:7065:b8e:ffff::3; notify-source 10.53.0.3; + notify-source-v6 fd92:7065:b8e:ffff::3; transfer-source 10.53.0.3; + transfer-source-v6 fd92:7065:b8e:ffff::3; port @PORT@; pid-file "named.pid"; listen-on { 10.53.0.3; }; - listen-on-v6 { none; }; + listen-on-v6 { fd92:7065:b8e:ffff::3; }; forwarders { 10.53.0.6; }; dnssec-validation yes; }; From 23624a7adb01f668849075a3df2bbb96a3aa2fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 7 Sep 2021 21:44:17 +0200 Subject: [PATCH 3/3] Add CHANGES and release note for [GL #2852] --- CHANGES | 8 ++++++++ doc/notes/notes-current.rst | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/CHANGES b/CHANGES index 9778ad6f07..f5cf53ffec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +5714. [bug] Remove the "adjust interface" mechanism that + set up a listener on interfaces where the *-source(-v6) + address and port were the same as the listening + address and port. Such a configuration is no longer + supported; in practice, this would disable + listening on TCP ports under certain timing conditions. + [GL #2852] + 5713. [func] Added "primaries" as a synonym for "masters" and "default-primaries" as a synonym for "default-masters" for catalog zones configuration options. [GL #2818] diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 3d999eacf4..efa5c2eb40 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -59,3 +59,7 @@ Bug Fixes that were no longer compatible, triggering an assertion failure on startup. The MAPAPI value has now been updated, so ``named`` will reject outdated files when encountering them. :gl:`#2872` + +- When new IP addresses were added to the system during ``named`` + startup, ``named`` failed to listen on TCP for the newly added + interfaces. :gl:`#2852`