]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #1319: [FR] zone status for Unbound auth-zones.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 22 Aug 2025 10:40:00 +0000 (12:40 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 22 Aug 2025 10:40:00 +0000 (12:40 +0200)
daemon/remote.c
doc/Changelog
services/authzone.c
services/authzone.h

index 07f64ac06fd6f7cca64315a34cb0eccbbfb0f1e1..edf3799125564283ef29a0cfcad387d6bd9550e5 100644 (file)
@@ -3373,7 +3373,7 @@ static void
 do_list_auth_zones(RES* ssl, struct auth_zones* az)
 {
        struct auth_zone* z;
-       char buf[LDNS_MAX_DOMAINLEN], buf2[256];
+       char buf[LDNS_MAX_DOMAINLEN], buf2[256], buf3[256];
        lock_rw_rdlock(&az->lock);
        RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
                lock_rw_rdlock(&z->lock);
@@ -3382,18 +3382,41 @@ do_list_auth_zones(RES* ssl, struct auth_zones* az)
                        snprintf(buf2, sizeof(buf2), "expired");
                else {
                        uint32_t serial = 0;
-                       if(auth_zone_get_serial(z, &serial))
+                       if(auth_zone_get_serial(z, &serial)) {
                                snprintf(buf2, sizeof(buf2), "serial %u",
                                        (unsigned)serial);
-                       else    snprintf(buf2, sizeof(buf2), "no serial");
+                               if(z->soa_zone_acquired != 0) {
+#if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R)
+                                       char tmbuf[32];
+                                       struct tm tm;
+                                       struct tm *tm_p;
+                                       tm_p = localtime_r(
+                                               &z->soa_zone_acquired, &tm);
+                                       if(!strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%dT%H:%M:%S", tm_p))
+                                               snprintf(tmbuf, sizeof(tmbuf), "strftime-err-%u", (unsigned)z->soa_zone_acquired);
+                                       snprintf(buf3, sizeof(buf3),
+                                               "\t since %u %s",
+                                               (unsigned)z->soa_zone_acquired,
+                                               tmbuf);
+#else
+                                       snprintf(buf3, sizeof(buf3),
+                                               "\t since %u",
+                                               (unsigned)z->soa_zone_acquired);
+#endif
+                               } else {
+                                       buf3[0]=0;
+                               }
+                       } else  {
+                               snprintf(buf2, sizeof(buf2), "no serial");
+                               buf3[0]=0;
+                       }
                }
-               if(!ssl_printf(ssl, "%s\t%s\n", buf, buf2)) {
+               lock_rw_unlock(&z->lock);
+               if(!ssl_printf(ssl, "%s\t%s%s\n", buf, buf2, buf3)) {
                        /* failure to print */
-                       lock_rw_unlock(&z->lock);
                        lock_rw_unlock(&az->lock);
                        return;
                }
-               lock_rw_unlock(&z->lock);
        }
        lock_rw_unlock(&az->lock);
 }
@@ -7461,6 +7484,7 @@ fr_worker_auth_add(struct worker* worker, struct fast_reload_auth_change* item,
                        xfr->serial = 0;
                }
        }
+       auth_zone_pickup_initial_zone(item->new_z, &worker->env);
        lock_rw_unlock(&item->new_z->lock);
        lock_rw_unlock(&worker->env.auth_zones->lock);
        lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock);
index 020c89eda3c636a2b67de1cfe9ae9173d3e5ecbb..0391e057f4594639d15ac00296a8b31bfd8282b2 100644 (file)
@@ -1,6 +1,7 @@
 22 August 2025: Wouter
        - For #1318: Fix compile warnings for DoH compile on windows.
        - Fix sha1 enable environment variable in test code on windows.
+       - Fix #1319: [FR] zone status for Unbound auth-zones.
 
 21 August 2025: Wouter
        - Fix to check for extraneous command arguments for unbound-control,
index 591a76cd98d996857a35e192ce3a816a5eeae075..60ccc8698748ba5189b15da57d2e2e034991cf12 100644 (file)
@@ -5024,6 +5024,7 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
 
        xfr->have_zone = 0;
        xfr->serial = 0;
+       xfr->soa_zone_acquired = 0;
 
        /* insert all RRs in to the zone */
        /* insert the SOA only once, skip the last one */
@@ -5125,6 +5126,7 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
 
        xfr->have_zone = 0;
        xfr->serial = 0;
+       xfr->soa_zone_acquired = 0;
 
        chunk = xfr->task_transfer->chunks_first;
        chunk_pos = 0;
@@ -5335,6 +5337,8 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
                        " (or malformed RR)", xfr->task_transfer->master->host);
                return 0;
        }
+       z->soa_zone_acquired = *env->now;
+       xfr->soa_zone_acquired = *env->now;
 
        /* release xfr lock while verifying zonemd because it may have
         * to spawn lookups in the state machines */
@@ -7004,13 +7008,23 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
        comm_timer_set(xfr->task_nextprobe->timer, &tv);
 }
 
+void auth_zone_pickup_initial_zone(struct auth_zone* z, struct module_env* env)
+{
+       /* Set the time, because we now have timestamp in env,
+        * (not earlier during startup and apply_cfg), and this
+        * notes the start time when the data was acquired. */
+       z->soa_zone_acquired = *env->now;
+}
+
 void auth_xfer_pickup_initial_zone(struct auth_xfer* x, struct module_env* env)
 {
        /* set lease_time, because we now have timestamp in env,
         * (not earlier during startup and apply_cfg), and this
         * notes the start time when the data was acquired */
-       if(x->have_zone)
+       if(x->have_zone) {
                x->lease_time = *env->now;
+               x->soa_zone_acquired = *env->now;
+       }
        if(x->task_nextprobe && x->task_nextprobe->worker == NULL) {
                xfr_set_timeout(x, env, 0, 1);
        }
@@ -7021,7 +7035,13 @@ void
 auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
 {
        struct auth_xfer* x;
+       struct auth_zone* z;
        lock_rw_wrlock(&az->lock);
+       RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
+               lock_rw_wrlock(&z->lock);
+               auth_zone_pickup_initial_zone(z, env);
+               lock_rw_unlock(&z->lock);
+       }
        RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
                lock_basic_lock(&x->lock);
                auth_xfer_pickup_initial_zone(x, env);
@@ -7106,6 +7126,7 @@ auth_xfer_new(struct auth_zone* z)
        lock_protect(&xfr->lock, &xfr->notify_serial, sizeof(xfr->notify_serial));
        lock_protect(&xfr->lock, &xfr->zone_expired, sizeof(xfr->zone_expired));
        lock_protect(&xfr->lock, &xfr->have_zone, sizeof(xfr->have_zone));
+       lock_protect(&xfr->lock, &xfr->soa_zone_acquired, sizeof(xfr->soa_zone_acquired));
        lock_protect(&xfr->lock, &xfr->serial, sizeof(xfr->serial));
        lock_protect(&xfr->lock, &xfr->retry, sizeof(xfr->retry));
        lock_protect(&xfr->lock, &xfr->refresh, sizeof(xfr->refresh));
index b11e7f1449e0038cfbbf8f3354d16ad62dcda7d1..ceb933bbb9363a2bd42ada98a430fa1bba051ed5 100644 (file)
@@ -118,6 +118,8 @@ struct auth_zone {
        char* zonefile;
        /** fallback to the internet on failure or ttl-expiry of auth zone */
        int fallback_enabled;
+       /** the time when zone was transferred from upstream */
+       time_t soa_zone_acquired;
        /** the zone has expired (enabled by the xfer worker), fallback
         * happens if that option is enabled. */
        int zone_expired;
@@ -261,6 +263,8 @@ struct auth_xfer {
        int zone_expired;
        /** do we have a zone (if 0, no zone data at all) */
        int have_zone;
+       /** the time when zone was transferred from upstream */
+       time_t soa_zone_acquired;
 
        /** current serial (from SOA), if we have no zone, 0 */
        uint32_t serial;
@@ -800,6 +804,14 @@ size_t auth_zones_get_mem(struct auth_zones* zones);
 void auth_xfer_pickup_initial_zone(struct auth_xfer* x,
        struct module_env* env);
 
+/**
+ * Initial pick up of the auth zone, it sets the acquired time.
+ * @param z: the zone, locked by caller.
+ * @param env: environment of the worker, with current time.
+ */
+void auth_zone_pickup_initial_zone(struct auth_zone* z,
+       struct module_env* env);
+
 /**
  * Delete auth xfer structure
  * @param xfr: delete this xfer and its tasks.