From: Mark Andrews Date: Thu, 29 Aug 2024 01:05:09 +0000 (+1000) Subject: Add dns_zone_getzoneversion X-Git-Tag: v9.21.7~34^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ebe751f88cd4a473b9b732367812aaadcb2b8643;p=thirdparty%2Fbind9.git Add dns_zone_getzoneversion Returns the EDNS ZONEVERSION for the zone. Return the database specific version otherwise return a type 0 version (serial). --- diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index b000f27e103..cec638fe64a 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -2785,6 +2785,24 @@ dns_zone_getrad(dns_zone_t *zone, dns_name_t *name); * \li 'name' is a valid name with a buffer. */ +isc_result_t +dns_zone_getzoneversion(dns_zone_t *zone, isc_buffer_t *b); +/**< + * Return the EDNS ZONEVERSION for this zone. + * + * Note: For type SERIAL a buffer of at least 6 octets is required. + * + * Requires: + * \li 'zone' to be a valid zone. + * \li 'b' to be a valid buffer. + * + * Returns + * \li ISC_R_SUCCESS if the zone is loaded and supports ZONEVERSION. + * \li ISC_R_NOSPACE if the buffer is too small. + * \li DNS_R_NOTLOADED if the database is not loaded. + * \li ISC_R_FAILURE other failure. + */ + #if DNS_ZONE_TRACE #define dns_zone_ref(ptr) dns_zone__ref(ptr, __func__, __FILE__, __LINE__) #define dns_zone_unref(ptr) dns_zone__unref(ptr, __func__, __FILE__, __LINE__) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 1ec93ef51c7..8d4c101f32d 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1497,6 +1497,46 @@ dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) { return result; } +isc_result_t +dns_zone_getzoneversion(dns_zone_t *zone, isc_buffer_t *b) { + isc_result_t result = DNS_R_NOTLOADED; + unsigned int soacount; + uint32_t serial; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(b != NULL); + + LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { + result = dns_db_getzoneversion(zone->db, b); + if (result == ISC_R_NOTIMPLEMENTED) { + result = zone_get_from_db(zone, zone->db, NULL, + &soacount, NULL, &serial, + NULL, NULL, NULL, NULL, NULL); + if (result == ISC_R_SUCCESS && soacount == 0) { + result = ISC_R_FAILURE; + } + if (result == ISC_R_SUCCESS) { + if (isc_buffer_availablelength(b) >= 6) { + isc_buffer_putuint8( + b, dns_name_countlabels( + &zone->origin) - + 1); + isc_buffer_putuint8(b, 0); + isc_buffer_putuint32(b, serial); + } else { + result = ISC_R_NOSPACE; + } + } + } + } + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + UNLOCK_ZONE(zone); + + return result; +} + /* * Single shot. */