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);
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);
}
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);
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,
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 */
xfr->have_zone = 0;
xfr->serial = 0;
+ xfr->soa_zone_acquired = 0;
chunk = xfr->task_transfer->chunks_first;
chunk_pos = 0;
" (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 */
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);
}
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);
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));
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;
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;
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.