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:
@@ -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.
|
||||
|
Reference in New Issue
Block a user