From: Aram Sargsyan Date: Wed, 28 Sep 2022 09:01:05 +0000 (+0000) Subject: Fix dynamic update forwarding when using a TLS-enabled primary X-Git-Tag: v9.19.6~24^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3d7103bd2197c3898d066b47a179b29bd77dcc8c;p=thirdparty%2Fbind9.git Fix dynamic update forwarding when using a TLS-enabled primary Now that the 'dns_request' supports using TLS transport, implement dynamic update forwarding using DoT when the primary server is configured to use a TLS transport. Previously, when using such configuration, the dynamic update forwarding feature was broken. --- diff --git a/lib/dns/zone.c b/lib/dns/zone.c index fba7cb44851..9a7ab8f89b4 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -717,6 +717,7 @@ struct dns_forward { dns_request_t *request; uint32_t which; isc_sockaddr_t addr; + dns_transport_t *transport; dns_updatecallback_t callback; void *callback_arg; unsigned int options; @@ -18286,6 +18287,9 @@ forward_destroy(dns_forward_t *forward) { if (forward->msgbuf != NULL) { isc_buffer_free(&forward->msgbuf); } + if (forward->transport != NULL) { + dns_transport_detach(&forward->transport); + } if (forward->zone != NULL) { LOCK(&forward->zone->lock); if (ISC_LINK_LINKED(forward, link)) { @@ -18302,20 +18306,22 @@ sendtoprimary(dns_forward_t *forward) { isc_result_t result; isc_sockaddr_t src; isc_dscp_t dscp = -1; + dns_zone_t *zone = forward->zone; + bool tls_transport_invalid = false; - LOCK_ZONE(forward->zone); + LOCK_ZONE(zone); - if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { - UNLOCK_ZONE(forward->zone); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { + UNLOCK_ZONE(zone); return (ISC_R_CANCELED); } - if (forward->which >= forward->zone->primariescnt) { - UNLOCK_ZONE(forward->zone); + if (forward->which >= zone->primariescnt) { + UNLOCK_ZONE(zone); return (ISC_R_NOMORE); } - forward->addr = forward->zone->primaries[forward->which]; + forward->addr = zone->primaries[forward->which]; /* * Always use TCP regardless of whether the original update * used TCP. @@ -18324,30 +18330,59 @@ sendtoprimary(dns_forward_t *forward) { */ switch (isc_sockaddr_pf(&forward->addr)) { case PF_INET: - src = forward->zone->xfrsource4; - dscp = forward->zone->xfrsource4dscp; + src = zone->xfrsource4; + dscp = zone->xfrsource4dscp; break; case PF_INET6: - src = forward->zone->xfrsource6; - dscp = forward->zone->xfrsource6dscp; + src = zone->xfrsource6; + dscp = zone->xfrsource6dscp; break; default: result = ISC_R_NOTIMPLEMENTED; goto unlock; } + + if (forward->transport != NULL) { + dns_transport_detach(&forward->transport); + } + + if (zone->primarytlsnames != NULL && + zone->primarytlsnames[forward->which] != NULL) + { + dns_view_t *view = dns_zone_getview(zone); + dns_name_t *tlsname = zone->primarytlsnames[zone->curprimary]; + + result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, + &forward->transport); + + if (result != ISC_R_SUCCESS) { + /* Log the error message when unlocked. */ + tls_transport_invalid = true; + goto unlock; + } + } + result = dns_request_createraw( forward->zone->view->requestmgr, forward->msgbuf, &src, - &forward->addr, NULL, NULL, dscp, forward->options, - 15 /* XXX */, 0, 0, forward->zone->task, forward_callback, - forward, &forward->request); + &forward->addr, forward->transport, zone->zmgr->tlsctx_cache, + dscp, forward->options, 15 /* XXX */, 0, 0, forward->zone->task, + forward_callback, forward, &forward->request); if (result == ISC_R_SUCCESS) { if (!ISC_LINK_LINKED(forward, link)) { - ISC_LIST_APPEND(forward->zone->forwards, forward, link); + ISC_LIST_APPEND(zone->forwards, forward, link); } } unlock: - UNLOCK_ZONE(forward->zone); + UNLOCK_ZONE(zone); + + if (tls_transport_invalid) { + dns_zone_log(zone, ISC_LOG_ERROR, + "could not get TLS configuration " + "for dynamic update: %s", + isc_result_totext(result)); + } + return (result); } @@ -18487,17 +18522,12 @@ dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, REQUIRE(callback != NULL); forward = isc_mem_get(zone->mctx, sizeof(*forward)); - - forward->request = NULL; - forward->zone = NULL; - forward->msgbuf = NULL; - forward->which = 0; - forward->mctx = 0; - forward->callback = callback; - forward->callback_arg = callback_arg; + *forward = (dns_forward_t){ .callback = callback, + .callback_arg = callback_arg, + .options = DNS_REQUESTOPT_TCP }; ISC_LINK_INIT(forward, link); forward->magic = FORWARD_MAGIC; - forward->options = DNS_REQUESTOPT_TCP; + /* * If we have a SIG(0) signed message we need to preserve the * query id as that is included in the SIG(0) computation.