2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-05 09:05:40 +00:00

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.
This commit is contained in:
Aram Sargsyan
2022-09-28 09:01:05 +00:00
parent 445aeee58d
commit 3d7103bd21

View File

@@ -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.