diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index 2ba5614790..f44eddce71 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -1564,7 +1564,8 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "refreshqueued")); TRY0(xmlTextWriterWriteString( - writer, ISC_XMLCHAR(needs_refresh ? "Yes" : "No"))); + writer, + ISC_XMLCHAR(is_running && needs_refresh ? "Yes" : "No"))); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "localaddr")); @@ -2605,7 +2606,8 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) { json_object_object_add( xfrinobj, "refreshqueued", - json_object_new_string(needs_refresh ? "Yes" : "No")); + json_object_new_string(is_running && needs_refresh ? "Yes" + : "No")); if (is_running) { addrp = dns_xfrin_getsourceaddr(xfr); diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index dcd87b5968..e22a255cec 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -7576,8 +7576,9 @@ Incoming Zone Transfers this zone. Possible values and their meanings are: ``Needs Refresh`` - The zone is flagged for a refresh, but the process - hasn't started yet. + The zone needs a refresh, but the process hasn't started yet, + which can be due to different factors, like the retry interval of + the zone. ``Pending`` The zone is flagged for a refresh, but the process is currently @@ -7592,7 +7593,9 @@ Incoming Zone Transfers Otherwise, the zone transfer procedure can still be initiated, and the SOA request will be attempted using the same transport as the zone transfer. The ``Duration (s)`` timer restarts before - entering this state, and for each attempted primary server. + entering this state, and for each attempted connection (note that + in UDP mode there can be several retries during one "connection" + attempt). ``Deferred`` The zone is going to be refreshed, but the process was diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c500cbfde2..bf49b693b4 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -19297,6 +19297,7 @@ dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_running, *is_deferred = false; *is_presoa = false; *is_pending = false; + *needs_refresh = false; RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); LOCK_ZONE(zone); @@ -19305,6 +19306,11 @@ dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_running, } if (zone->statelist == &zone->zmgr->xfrin_in_progress) { *is_running = true; + /* + * The NEEDREFRESH flag is set only when a notify was received + * while the current zone transfer is running. + */ + *needs_refresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH); } else if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { *is_deferred = true; } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { @@ -19313,8 +19319,24 @@ dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_running, } else { *is_pending = true; } + } else { + /* + * No operation is ongoing or pending, just check if the zone + * needs a refresh by looking at the refresh and expire times. + */ + if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && + (zone->type == dns_zone_secondary || + zone->type == dns_zone_mirror || + zone->type == dns_zone_stub)) + { + isc_time_t now = isc_time_now(); + if (isc_time_compare(&now, &zone->refreshtime) >= 0 || + isc_time_compare(&now, &zone->expiretime) >= 0) + { + *needs_refresh = true; + } + } } - *needs_refresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH); UNLOCK_ZONE(zone); RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read);