fix: usr: Fix a bug in the statistics channel when querying zone transfers information

When querying zone transfers information from the statistics channel there was a rare possibility that `named` could terminate unexpectedly if a zone transfer was in a state when transferring from all the available primary servers had failed earlier. This has been fixed.

Closes #5198

Merge branch '5198-dns_remote_curraddr-bug-fix' into 'main'

See merge request isc-projects/bind9!10182
This commit is contained in:
Arаm Sаrgsyаn 2025-02-28 15:34:05 +00:00
commit e02d73e7e3
3 changed files with 33 additions and 15 deletions

View file

@ -1617,9 +1617,13 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
} else if (is_presoa) {
addr = dns_zone_getprimaryaddr(zone);
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
if (dns_zone_getprimaryaddr(zone, &addr) == ISC_R_SUCCESS) {
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR addr_buf));
} else {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
} else {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
@ -2671,10 +2675,15 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string(addr_buf));
} else if (is_presoa) {
addr = dns_zone_getprimaryaddr(zone);
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string(addr_buf));
if (dns_zone_getprimaryaddr(zone, &addr) == ISC_R_SUCCESS) {
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
json_object_object_add(
xfrinobj, "remoteaddr",
json_object_new_string(addr_buf));
} else {
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string("-"));
}
} else {
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string("-"));

View file

@ -1539,14 +1539,19 @@ dns_zone_getsourceaddr(dns_zone_t *zone);
* \li 'zone' has a non-empty primaries list.
*/
isc_sockaddr_t
dns_zone_getprimaryaddr(dns_zone_t *zone);
isc_result_t
dns_zone_getprimaryaddr(dns_zone_t *zone, isc_sockaddr_t *dest);
/*%<
* Get the zone's current primary server.
* Get the zone's current primary server into '*dest'.
*
* Requires:
* \li 'zone' to be a valid zone.
* \li 'zone' has a non-empty primaries list.
* \li 'dest' != NULL.
*
* Returns:
*\li #ISC_R_SUCCESS if the current primary server was found
*\li #ISC_R_NOMORE if all the primaries were already iterated over
*/
isc_time_t

View file

@ -18385,18 +18385,22 @@ dns_zone_getsourceaddr(dns_zone_t *zone) {
return sourceaddr;
}
isc_sockaddr_t
dns_zone_getprimaryaddr(dns_zone_t *zone) {
isc_sockaddr_t curraddr;
isc_result_t
dns_zone_getprimaryaddr(dns_zone_t *zone, isc_sockaddr_t *dest) {
isc_result_t result = ISC_R_NOMORE;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(dest != NULL);
LOCK_ZONE(zone);
INSIST(dns_remote_count(&zone->primaries) > 0);
curraddr = dns_remote_curraddr(&zone->primaries);
if (!dns_remote_done(&zone->primaries)) {
*dest = dns_remote_curraddr(&zone->primaries);
result = ISC_R_SUCCESS;
}
UNLOCK_ZONE(zone);
return curraddr;
return result;
}
isc_time_t