Commit daec2e4e authored by Marek Vavruša's avatar Marek Vavruša

zone-load: moved legacy code from zones.c, mtime checking working

parent 72e2af05
......@@ -115,6 +115,8 @@ src/knot/nameserver/internet.c
src/knot/nameserver/internet.h
src/knot/nameserver/ixfr.c
src/knot/nameserver/ixfr.h
src/knot/nameserver/notify.c
src/knot/nameserver/notify.h
src/knot/nameserver/nsec_proofs.c
src/knot/nameserver/nsec_proofs.h
src/knot/nameserver/process_query.c
......@@ -130,8 +132,6 @@ src/knot/server/journal.c
src/knot/server/journal.h
src/knot/server/net.c
src/knot/server/net.h
src/knot/server/notify.c
src/knot/server/notify.h
src/knot/server/rrl.c
src/knot/server/rrl.h
src/knot/server/serialization.c
......@@ -144,10 +144,6 @@ src/knot/server/udp-handler.c
src/knot/server/udp-handler.h
src/knot/server/xfr-handler.c
src/knot/server/xfr-handler.h
src/knot/server/zone-load.c
src/knot/server/zone-load.h
src/knot/server/zones.c
src/knot/server/zones.h
src/knot/updates/acl.c
src/knot/updates/acl.h
src/knot/updates/changesets.c
......@@ -168,8 +164,6 @@ src/knot/zone/estimator.c
src/knot/zone/estimator.h
src/knot/zone/events.c
src/knot/zone/events.h
src/knot/zone/load.c
src/knot/zone/load.h
src/knot/zone/node.c
src/knot/zone/node.h
src/knot/zone/semantic-check.c
......@@ -178,10 +172,14 @@ src/knot/zone/zone-diff.c
src/knot/zone/zone-diff.h
src/knot/zone/zone-dump.c
src/knot/zone/zone-dump.h
src/knot/zone/zone-load.c
src/knot/zone/zone-load.h
src/knot/zone/zone-tree.c
src/knot/zone/zone-tree.h
src/knot/zone/zone.c
src/knot/zone/zone.h
src/knot/zone/zonedb-load.c
src/knot/zone/zonedb-load.h
src/knot/zone/zonedb.c
src/knot/zone/zonedb.h
src/knot/zone/zonefile.c
......
......@@ -240,6 +240,8 @@ libknotd_la_SOURCES = \
knot/nameserver/query_module.h \
knot/nameserver/update.c \
knot/nameserver/update.h \
knot/nameserver/notify.c \
knot/nameserver/notify.h \
knot/modules/synth_record.c \
knot/modules/synth_record.h \
knot/other/debug.h \
......@@ -247,8 +249,6 @@ libknotd_la_SOURCES = \
knot/server/dthreads.h \
knot/server/journal.c \
knot/server/journal.h \
knot/server/notify.c \
knot/server/notify.h \
knot/server/rrl.c \
knot/server/rrl.h \
knot/server/server.c \
......@@ -261,10 +261,6 @@ libknotd_la_SOURCES = \
knot/server/udp-handler.h \
knot/server/xfr-handler.c \
knot/server/xfr-handler.h \
knot/server/zone-load.c \
knot/server/zone-load.h \
knot/server/zones.c \
knot/server/zones.h \
knot/server/serialization.c \
knot/server/serialization.h \
knot/updates/acl.c \
......@@ -287,8 +283,6 @@ libknotd_la_SOURCES = \
knot/zone/estimator.h \
knot/zone/events.c \
knot/zone/events.h \
knot/zone/load.c \
knot/zone/load.h \
knot/zone/node.c \
knot/zone/node.h \
knot/zone/semantic-check.c \
......@@ -301,8 +295,12 @@ libknotd_la_SOURCES = \
knot/zone/zone-tree.h \
knot/zone/zone.c \
knot/zone/zone.h \
knot/zone/zone-load.c \
knot/zone/zone-load.h \
knot/zone/zonedb.c \
knot/zone/zonedb.h \
knot/zone/zonedb-load.c \
knot/zone/zonedb-load.h \
knot/zone/zonefile.c \
knot/zone/zonefile.h
......
......@@ -33,7 +33,6 @@
#include "knot/zone/zonefile.h"
#include "knot/server/tcp-handler.h"
#include "libknot/packet/wire.h"
#include "knot/server/zone-load.h"
#include "knot/zone/estimator.h"
/*! \brief Controller flags. */
......
......@@ -22,7 +22,6 @@
#include "knot/conf/conf.h"
#include "knot/server/net.h"
#include "knot/server/tcp-handler.h"
#include "knot/server/zones.h"
#include "libknot/packet/wire.h"
#include "common/descriptor.h"
#include "libknot/tsig-op.h"
......@@ -148,13 +147,15 @@ static int remote_zone_sign(server_t *server, const zone_t *zone)
char *zone_name = knot_dname_to_str(zone->name);
log_server_info("Requested zone resign for '%s'.\n", zone_name);
free(zone_name);
#warning TODO: remote_zone_sign should create and wait for zone sign event
#if 0
uint32_t refresh_at = 0;
zone_t *wzone = (zone_t *)zone;
zones_cancel_dnssec(wzone);
zones_dnssec_sign(wzone, true, &refresh_at);
zones_schedule_dnssec(wzone, refresh_at);
#endif
return KNOT_EOK;
}
......
......@@ -17,7 +17,6 @@
#include <assert.h>
#include <time.h>
#include "knot/conf/conf.h"
#include "knot/server/zones.h"
#include "libknot/dnssec/policy.h"
#include "knot/dnssec/zone-events.h"
#include "knot/dnssec/zone-keys.h"
......
......@@ -37,7 +37,6 @@
#include "knot/ctl/remote.h"
#include "knot/conf/conf.h"
#include "knot/conf/logconf.h"
#include "knot/server/zones.h"
#include "knot/server/tcp-handler.h"
/* Signal flags. */
......
......@@ -17,10 +17,10 @@
#include "knot/nameserver/axfr.h"
#include "knot/nameserver/internet.h"
#include "knot/nameserver/process_query.h"
#include "knot/updates/xfr-in.h"
#include "common/debug.h"
#include "common/descriptor.h"
#include "common/lists.h"
#include "knot/server/zones.h"
/* AXFR context. @note aliasing the generic xfr_proc */
struct axfr_proc {
......
......@@ -24,7 +24,6 @@
#include "knot/nameserver/nsec_proofs.h"
#include "knot/nameserver/process_query.h"
#include "knot/zone/zonedb.h"
#include "knot/server/zones.h"
/*! \brief Check if given node was already visited. */
static int wildcard_has_visited(struct query_data *qdata, const knot_node_t *node)
......
......@@ -2,8 +2,8 @@
#include "knot/nameserver/axfr.h"
#include "knot/nameserver/internet.h"
#include "knot/nameserver/process_query.h"
#include "knot/updates/xfr-in.h"
#include "common/debug.h"
#include "knot/server/zones.h"
#include "common/descriptor.h"
#include "libknot/util/utils.h"
#include "libknot/rdata/soa.h"
......
......@@ -16,7 +16,7 @@
#include <assert.h>
#include "knot/server/notify.h"
#include "knot/nameserver/notify.h"
#include "libknot/dname.h"
#include "common/descriptor.h"
......@@ -26,7 +26,6 @@
#include "knot/zone/zonedb.h"
#include "libknot/common.h"
#include "libknot/packet/wire.h"
#include "knot/server/zones.h"
#include "knot/updates/acl.h"
#include "common/evsched.h"
#include "knot/other/debug.h"
......
......@@ -8,7 +8,7 @@
#include "knot/nameserver/ixfr.h"
#include "knot/nameserver/update.h"
#include "knot/nameserver/nsec_proofs.h"
#include "knot/server/notify.h"
#include "knot/nameserver/notify.h"
#include "knot/server/server.h"
#include "knot/server/rrl.h"
#include "knot/updates/acl.h"
......
#include "knot/nameserver/update.h"
#include "knot/nameserver/internet.h"
#include "knot/nameserver/process_query.h"
#include "knot/updates/xfr-in.h"
#include "knot/dnssec/zone-sign.h"
#include "common/debug.h"
#include "knot/dnssec/zone-events.h"
#include "knot/updates/ddns.h"
#include "common/descriptor.h"
#include "knot/server/zones.h"
#include "libknot/tsig-op.h"
#include "knot/zone/zone.h"
......
......@@ -1248,8 +1248,9 @@ int journal_store_changesets(knot_changesets_t *src, const char *path, size_t si
WALK_LIST(chs, src->sets) {
/* Make key from serials. */
ret = changeset_pack(chs, journal);
if (ret != KNOT_EOK)
if (ret != KNOT_EOK) {
break;
}
}
/*! @note If the journal is full, this function returns KNOT_EBUSY. */
......
......@@ -25,11 +25,9 @@
#include "knot/server/server.h"
#include "knot/server/udp-handler.h"
#include "knot/server/tcp-handler.h"
#include "knot/server/zones.h"
#include "knot/server/zone-load.h"
#include "knot/conf/conf.h"
#include "knot/worker/pool.h"
#include "knot/zone/zonedb.h"
#include "knot/zone/zonedb-load.h"
#include "libknot/dname.h"
#include "libknot/dnssec/crypto.h"
#include "libknot/dnssec/random.h"
......@@ -606,7 +604,7 @@ int server_update_zones(const struct conf_t *conf, void *data)
{
server_t *server = (server_t *)data;
int ret = load_zones_from_config(conf, server);
int ret = zonedb_reload(conf, server);
if (ret != KNOT_EOK) {
return ret;
}
......
......@@ -37,7 +37,6 @@
#include "knot/knot.h"
#include "knot/server/tcp-handler.h"
#include "knot/server/xfr-handler.h"
#include "knot/server/zones.h"
#include "libknot/packet/wire.h"
#include "knot/nameserver/process_query.h"
#include "libknot/dnssec/crypto.h"
......
......@@ -45,8 +45,6 @@
#include "libknot/packet/wire.h"
#include "libknot/consts.h"
#include "libknot/packet/pkt.h"
#include "knot/server/zones.h"
#include "knot/server/notify.h"
#include "libknot/dnssec/crypto.h"
#include "libknot/processing/process.h"
......
......@@ -35,7 +35,8 @@
#include "knot/updates/xfr-in.h"
#include "knot/nameserver/axfr.h"
#include "knot/nameserver/ixfr.h"
#include "knot/server/zones.h"
#include "knot/nameserver/internet.h"
#include "knot/nameserver/notify.h"
#include "knot/knot.h"
#include "libknot/tsig-op.h"
#include "common/evsched.h"
......@@ -52,6 +53,10 @@
#define XFR_MSG_DLTTR 9 /*! Index of letter differentiating IXFR/AXFR in log msg. */
#define XFR_TSIG_DATA_MAX_SIZE (100 * 64 * 1024) /*! Naximum size of TSIG buffers. */
#define ZONES_JITTER_PCT 10 /*!< +-N% jitter to timers. */
#define AXFR_BOOTSTRAP_RETRY (30*1000) /*!< Jitter cap between AXFR bootstrap retries. */
#define AXFR_RETRY_MAXTIME (24*60*60*1000) /*!< Maximum AXFR retry interval cap of 24 hours. */
/* Messages */
static knot_lookup_table_t xfr_type_table[] = {
......@@ -617,6 +622,15 @@ static int xfr_task_finalize(knot_ns_xfr_t *rq)
return ret;
}
knot_ns_xfr_type_t zones_transfer_to_use(zone_t *zone)
{
if (zone == NULL || !journal_exists(zone->conf->ixfr_db)) {
return XFR_TYPE_AIN;
}
return XFR_TYPE_IIN;
}
static int xfr_task_resp_process(server_t *server,
int exp_msgid,
struct sockaddr_storage *from,
......
This diff is collapsed.
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file zones.h
*
* \author Lubos Slovak <lubos.slovak@nic.cz>
*
* Contains functions for updating zone database from configuration.
*
* \addtogroup server
* @{
*/
#ifndef _KNOTD_ZONES_H_
#define _KNOTD_ZONES_H_
#include <stddef.h>
#include "common/lists.h"
#include "knot/updates/acl.h"
#include "common/evsched.h"
#include "knot/zone/zonedb.h"
#include "knot/conf/conf.h"
#include "knot/server/notify.h"
#include "knot/server/server.h"
#include "knot/server/journal.h"
#include "knot/zone/zone.h"
#include "knot/updates/xfr-in.h"
/* Constants. */
#define ZONES_JITTER_PCT 10 /*!< +-N% jitter to timers. */
#define AXFR_BOOTSTRAP_RETRY (30*1000) /*!< Jitter cap between AXFR bootstrap retries. */
#define AXFR_RETRY_MAXTIME (24*60*60*1000) /*!< Maximum AXFR retry interval cap of 24 hours. */
/* Timer special values. */
#define REFRESH_DEFAULT -1 /* Use time value from zone structure. */
#define REFRESH_NOW (knot_random_uint16_t() % 1000) /* Now, but with jitter. */
/*!
* \brief Decides what type of transfer should be used to update the given zone.
*.
* \param zone Zone.
*
* \retval
*/
knot_ns_xfr_type_t zones_transfer_to_use(zone_t *zone);
/*!
* \brief Update zone timers.
*
* REFRESH/RETRY/EXPIRE timers are updated according to SOA.
*
* \param zone Related zone.
* \param time Specific timeout or REFRESH_DEFAULT for default.
*
* \retval KNOT_EOK
* \retval KNOT_EINVAL
* \retval KNOT_ERROR
*/
int zones_schedule_refresh(zone_t *zone, int64_t timeout);
/*!
* \brief Schedule NOTIFY after zone update.
* \param zone Related zone.
*
* \retval KNOT_EOK
* \retval KNOT_ERROR
*/
int zones_schedule_notify(zone_t *zone, server_t *server);
/*!
* \brief Cancel DNSSEC event.
*
* \param zone Related zone.
*
* \return Error code, KNOT_OK if successful.
*/
int zones_cancel_dnssec(zone_t *zone);
/*!
* \brief Schedule DNSSEC event.
* \param zone Related zone.
* \param unixtime When to schedule.
* \param force Force sign or not
*
* \return Error code, KNOT_OK if successful.
*/
int zones_schedule_dnssec(zone_t *zone, time_t unixtime);
/*! \brief Just sign current zone. */
int zones_dnssec_sign(zone_t *zone, bool force, uint32_t *expires_at);
#endif // _KNOTD_ZONES_H_
/*! @} */
......@@ -933,8 +933,7 @@ static int xfrin_apply_changeset(list_t *old_rrs, list_t *new_rrs,
// check if serial matches
const knot_rdataset_t *soa = knot_node_rdataset(contents->apex, KNOT_RRTYPE_SOA);
if (soa == NULL || knot_soa_serial(soa)
!= chset->serial_from) {
if (soa == NULL || knot_soa_serial(soa) != chset->serial_from) {
dbg_xfrin("SOA serials do not match!!\n");
return KNOT_EINVAL;
}
......
......@@ -1446,10 +1446,22 @@ void zone_contents_deep_free(zone_contents_t **contents)
/*----------------------------------------------------------------------------*/
const knot_rdataset_t *zone_contents_soa(const zone_contents_t *zone)
{
if (zone == NULL) {
return NULL;
}
return knot_node_rdataset(zone->apex, KNOT_RRTYPE_SOA);
}
uint32_t zone_contents_serial(const zone_contents_t *zone)
{
if (!zone) return 0;
const knot_rdataset_t *soa = knot_node_rdataset(zone->apex, KNOT_RRTYPE_SOA);
const knot_rdataset_t *soa = zone_contents_soa(zone);
if (soa == NULL) {
return 0;
}
return knot_soa_serial(soa);
}
......
......@@ -316,6 +316,9 @@ void zone_contents_free(zone_contents_t **contents);
void zone_contents_deep_free(zone_contents_t **contents);
/*! \brief Return zone SOA rdataset. */
const knot_rdataset_t *zone_contents_soa(const zone_contents_t *zone);
/*!
* \brief Fetch zone serial.
*
......@@ -325,6 +328,7 @@ void zone_contents_deep_free(zone_contents_t **contents);
*/
uint32_t zone_contents_serial(const zone_contents_t *zone);
/*! \brief Calculate next serial. */
uint32_t zone_contents_next_serial(const zone_contents_t *zone, int policy);
......
......@@ -23,8 +23,10 @@
#include "knot/worker/pool.h"
#include "knot/worker/task.h"
#include "knot/zone/events.h"
#include "knot/zone/load.h"
#include "knot/zone/zone.h"
#include "knot/zone/zone-load.h"
#include "knot/zone/zonefile.h"
#include "libknot/rdata/soa.h"
/* -- zone events handling callbacks --------------------------------------- */
......@@ -34,45 +36,121 @@ static int event_reload(zone_t *zone)
{
assert(zone);
zone_contents_t *content = zone_load_contents(zone->conf);
if (!content) {
/* Take zone file mtime and load it. */
time_t mtime = zonefile_mtime(zone->conf->file);
conf_zone_t *zone_config = zone->conf;
zone_contents_t *contents = zone_load_contents(zone_config);
if (!contents) {
return KNOT_ERROR; // TODO: specific error code
}
int result = apply_journal(content, zone->conf);
/* Apply changes in journal. */
int result = zone_load_journal(contents, zone_config);
if (result != KNOT_EOK) {
zone_contents_deep_free(&content);
return result;
goto fail;
}
// TODO: do diff and sign
result = post_load(content, zone);
/* Post load actions - calculate delta, sign with DNSSEC... */
result = zone_load_post(contents, zone);
if (result != KNOT_EOK) {
if (result == KNOT_ESPACE) {
log_zone_error("Zone '%s' journal size is too small to fit the changes.\n",
zone->conf->name);
zone_config->name);
} else {
log_zone_error("Zone '%s' failed to store changes in the journal - %s\n",
zone->conf->name, knot_strerror(result));
zone_config->name, knot_strerror(result));
}
zone_contents_deep_free(&content);
return result;
goto fail;
}
zone_contents_t *old = zone_switch_contents(zone, content);
/* Check zone contents consistency. */
result = zone_load_check(contents, zone_config);
if (result != KNOT_EOK) {
goto fail;
}
/* Everything went alright, switch the contents. */
zone->zonefile_mtime = mtime;
zone_contents_t *old = zone_switch_contents(zone, contents);
if (old != NULL) {
synchronize_rcu();
zone_contents_deep_free(&old);
}
log_zone_info("Zone '%s' loaded.\n", zone->conf->name);
log_zone_info("Zone '%s' loaded.\n", zone_config->name);
return KNOT_EOK;
fail:
zone_contents_deep_free(&contents);
return result;
}
static int event_refresh(zone_t *zone)
{
assert(zone);
#warning TODO: implement event_refresh
#if 0
assert(event);
dbg_zones("zone: REFRESH/RETRY timer event\n");
rcu_read_lock();
zone_t *zone = (zone_t *)event->data;
if (zone == NULL) {
rcu_read_unlock();
return KNOT_EINVAL;
}
if (zone->flags & ZONE_DISCARDED) {
rcu_read_unlock();
return KNOT_EOK;
}
/* Create XFR request. */
knot_ns_xfr_t *rq = xfr_task_create(zone, XFR_TYPE_SOA, XFR_FLAG_TCP);
rcu_read_unlock(); /* rq now holds a reference to zone */
if (!rq) {
return KNOT_EINVAL;
}
const conf_iface_t *master = zone_master(zone);
xfr_task_setaddr(rq, &master->addr, &master->via);
rq->tsig_key = master->key;
/* Check for contents. */
int ret = KNOT_EOK;
if (!zone->contents) {
/* Bootstrap over TCP. */
rq->type = XFR_TYPE_AIN;
rq->flags = XFR_FLAG_TCP;
evsched_end_process(event->sched);
/* Check transfer state. */
pthread_mutex_lock(&zone->lock);
if (zone->xfr_in.state == XFR_PENDING) {
pthread_mutex_unlock(&zone->lock);
xfr_task_free(rq);
return KNOT_EOK;
} else {
zone->xfr_in.state = XFR_PENDING;
}
/* Issue request. */
#warning "XFR enqueue."
pthread_mutex_unlock(&zone->lock);
return ret;
}
/* Reschedule as RETRY timer. */
uint32_t retry_tmr = zones_jitter(zones_soa_retry(zone));
evsched_schedule(event, retry_tmr);
dbg_zones("zone: RETRY of '%s' after %u seconds\n",
zone->conf->name, retry_tmr / 1000);
/* Issue request. */
evsched_end_process(event->sched);
#warning "XFR enqueue."
#endif
// zone_schedule_event(zone, ZONE_EVENT_REFRESH, time);
......@@ -94,7 +172,7 @@ static int event_expire(zone_t *zone)
static int event_flush(zone_t *zone)
{
#warning Implement me.
#warning TODO: implement event_flush
#if 0
assert(event);
dbg_zones("zone: zonefile SYNC timer event\n");
......@@ -123,6 +201,7 @@ static int event_dnssec(zone_t *zone)
{
assert(zone);
#warning TODO: implement event_dnssec
return KNOT_ERROR;
#if 0
knot_changesets_t *chs = knot_changesets_create();
......@@ -452,3 +531,151 @@ void zone_events_start(zone_t *zone)
reschedule(&zone->events);
pthread_mutex_unlock(&zone->events.mx);
}
/* ------------ Legacy API to be converted (not functional now) ------------- */
#warning TODO: vvv legacy API to be converted vvv
int zones_schedule_refresh(zone_t *zone, int64_t timeout)
{
if (!zone) {
return KNOT_EINVAL;
}
#warning TODO: reimplement schedule_refresh
#if 0
/* Cancel REFRESH/EXPIRE timer. */
// evsched_cancel(zone->xfr_in.expire);
// evsched_cancel(zone->xfr_in.timer);
/* Check XFR/IN master server. */
pthread_mutex_lock(&zone->lock);
rcu_read_lock();
if (zone_master(zone) != NULL) {
knot_rdataset_t *soa = zone_contents_soa(zone->contents);
/* Schedule EXPIRE timer. */
if (zone->contents != NULL) {
int64_t expire_tmr = knot_soa_expire(soa);
// Allow for timeouts. Otherwise zones with very short
// expiry may expire before the timeout is reached.
expire_tmr += 2 * (conf()->max_conn_idle * 1000);
// evsched_schedule(zone->xfr_in.expire, expire_tmr);
}
/* Schedule REFRESH timer. */
if (timeout < 0) {
if (zone->contents) {
timeout = knot_soa_refresh(soa);
} else {
timeout = zone->xfr_in.bootstrap_retry;
}
}
// evsched_schedule(zone->xfr_in.timer, timeout);
}
rcu_read_unlock();
pthread_mutex_unlock(&zone->lock);
#endif
return KNOT_EOK;
}
int zones_schedule_notify(zone_t *zone, server_t *server)
{
if (!zone) {
return KNOT_EINVAL;
}
#warning TODO: reimplement schedule_notify
#if 0
/* Do not issue NOTIFY queries if stub. */
if (!zone->contents) {
return KNOT_EOK;
}
/* Schedule NOTIFY to slaves. */
conf_zone_t *cfg = zone->conf;
conf_remote_t *r = 0;
WALK_LIST(r, cfg->acl.notify_out) {
/* Fetch remote. */
conf_iface_t *cfg_if = r->remote;
/* Create request. */
knot_ns_xfr_t *rq = xfr_task_create(zone, XFR_TYPE_NOTIFY, XFR_FLAG_UDP);
if (!rq) {
log_zone_error("Failed to create NOTIFY for '%s', "
"not enough memory.\n", cfg->name);
continue;
}
xfr_task_setaddr(rq, &cfg_if->addr, &cfg_if->via);
rq->tsig_key = cfg_if->key;
rq->data = (void *)((long)cfg->notify_retries);
#warning "XFR enqueue."
// if (xfr_enqueue(server->xfr, rq) != KNOT_EOK) {
// log_zone_error("Failed to enqueue NOTIFY for '%s'.\n",
// cfg->name);
// continue;
// }
}
#endif
return KNOT_EOK;
}
int zones_schedule_dnssec(zone_t *zone, time_t unixtime)
{
if (!zone) {
return KNOT_EINVAL;
}
#warning TODO: reimplement schedule_dnssec
#if 0
char *zname = knot_dname_to_str(zone->name);
// absolute time -> relative time
time_t now = time(NULL);
int32_t relative = 0;
if (unixtime <= now) {
log_zone_warning("DNSSEC: Zone %s: Signature life time too low, "
"set higher value in configuration!\n", zname);
} else {
relative = unixtime - now;
}
</