Commit f992cf25 authored by Marek Vavrusa's avatar Marek Vavrusa

Merge branch 'master' into packet-api-rewrite

Conflicts:
	src/knot/server/zones.c
	src/libknot/nameserver/name-server.c
parents a5738f67 b6558976
......@@ -16,6 +16,7 @@ doc/running.texi
doc/security.texi
doc/troubleshooting.texi
man/Makefile.am
patches/Makefile.am
samples/Makefile.am
src/Makefile.am
src/common/acl.c
......@@ -141,6 +142,7 @@ src/libknot/dnssec/key.h
src/libknot/dnssec/nsec-bitmap.h
src/libknot/dnssec/nsec3.c
src/libknot/dnssec/nsec3.h
src/libknot/dnssec/policy.c
src/libknot/dnssec/policy.h
src/libknot/dnssec/random.h
src/libknot/dnssec/rrset-sign.c
......
Knot DNS NEWS
v1.4.2 - Jan ??, 2014
v1.4.2 - Jan 27, 2014
---------------------
Bugfixes:
* AXFR/IXFR compatibility issues with tinydns/axfrdns
* Journal file is created only when needed
* Zone-related log messages are logged into correct category
* DNSSEC: Refresh signatures earlier (3 days before their expiration
with the default signature lifetime)
* Fixed RCU synchronization causing deadlock on 'knotc signzone'
* RRSIG not fitting in the additional records doesn't cause truncation
v1.4.1 - Jan 13, 2014
---------------------
......
......@@ -285,7 +285,7 @@ AS_IF([test "$with_openssl" = "no"],[
AC_EGREP_CPP(openssl_version_ok,
[#include <openssl/crypto.h>
#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
openssl_version_ok
#endif
],[],[AC_MSG_ERROR([OpenSSL library version >= 1.0.0 is required.])]
......
......@@ -899,11 +899,10 @@ Default value (in @code{zone} config): inherited from @code{zones} section
Specifies how long should the automatically generated DNSSEC signatures be valid.
Expiration will thus be set as current time (in the moment of signing)
+ @code{signature-lifetime}.
Possible values are from 10801 to INT_MAX. The lower limit is because the server
will trigger resign when any of the signatures expires in 7200 seconds or less
and it was chosen as a reasonable value with regard to signing overhead. Setting
the signature lifetime to minimum value will result in re-signing the zone each
hour. For information about zone expiration date, invoke the
Possible values are from 10801 to INT_MAX. The signatures are refreshed one
tenth of the signature lifetime before the signature expiration (i.e., 3 days
before the expiration with the default value). For information about zone
expiration date, invoke the
@code{knotc zonestatus} command.
Default value: @kbd{30d} (@kbd{2592000})
......
......@@ -270,9 +270,8 @@ serves as an example of the configuration for knotc(8) and knotd(8).
# Default value: 30d (30 days or 2592000 seconds)
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 day, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# The lower limit is because the server will trigger resign when any of the
# signatures expires in 7200 seconds or less and it was chosen as a
# reasonable value with regard to signing overhead.
# The signatures are refreshed one tenth of the signature lifetime before
# the signature expiration (i.e., 3 days before by default)
signature-lifetime 30d;
# Serial policy after DDNS and automatic DNSSEC signing.
......
......@@ -266,9 +266,8 @@ zones {
# Default value: 30d (30 days or 2592000 seconds)
# It is also possible to suffix with unit size [s/m/h/d]
# f.e. 1s = 1 day, 1m = 1 minute, 1h = 1 hour, 1d = 1 day
# The lower limit is because the server will trigger resign when any of the
# signatures expires in less than 7200 seconds and it was chosen as a
# reasonable value with regard to signing overhead.
# The signatures are refreshed one tenth of the signature lifetime before
# the signature expiration (i.e., 3 days before by default)
# signature-lifetime 30d;
# Serial policy after DDNS and automatic DNSSEC signing.
......
......@@ -173,6 +173,7 @@ libknot_la_SOURCES = \
libknot/dnssec/nsec-bitmap.h \
libknot/dnssec/nsec3.c \
libknot/dnssec/nsec3.h \
libknot/dnssec/policy.c \
libknot/dnssec/policy.h \
libknot/dnssec/random.h \
libknot/dnssec/rrset-sign.c \
......
......@@ -223,8 +223,7 @@ static int _log_msg(logsrc_t src, int level, const char *msg)
precise = true;
#endif /* ENABLE_MICROSECONDS_LOG */
tlen = strftime(tstr, sizeof(tstr),
"%Y-%m-%dT%H:%M:%S ", &lt);
tlen = strftime(tstr, sizeof(tstr), KNOT_LOG_TIME_FORMAT " ", &lt);
if (precise && tlen > 0) {
char pm = (lt.tm_gmtoff > 0) ? '+' : '-';
......
......@@ -62,6 +62,9 @@ typedef enum {
/*! \brief Severity mapping. */
#define LOG_FATAL LOG_CRIT /*!< Fatal errors cannot be masked. */
/*! \brief Format for timestamps in log files. */
#define KNOT_LOG_TIME_FORMAT "%Y-%m-%dT%H:%M:%S"
/* Logging facility setup. */
/*!
......
......@@ -176,12 +176,10 @@ static int remote_zone_sign(server_t *server, const knot_zone_t *zone)
log_server_info("Requested zone resign for '%s'.\n", zone_name);
free(zone_name);
uint32_t expires_at = 0;
uint32_t refresh_at = 0;
zones_cancel_dnssec((knot_zone_t *)zone);
rcu_read_lock();
zones_dnssec_sign((knot_zone_t *)zone, true, &expires_at);
rcu_read_unlock();
zones_schedule_dnssec((knot_zone_t *)zone, expires_at);
zones_dnssec_sign((knot_zone_t *)zone, true, &refresh_at);
zones_schedule_dnssec((knot_zone_t *)zone, refresh_at);
return KNOT_EOK;
}
......
......@@ -839,20 +839,6 @@ static int zones_merge_and_store_changesets(knot_zone_t *zone,
return KNOT_EOK;
}
static uint32_t expiration_to_relative(uint32_t exp,
const knot_zone_t *zone) {
time_t t = time(NULL);
if (t >= exp) {
char *zname = knot_dname_to_str(zone->name);
log_zone_warning("DNSSEC: Zone %s: Signature lifetime too low, "
"set higher value in configuration!\n", zname);
free(zname);
return 0;
} else {
return (exp - t) * 1000;
}
}
static int zones_serial_policy(const knot_zone_t *zone)
{
assert(zone != NULL);
......@@ -895,21 +881,17 @@ static uint32_t zones_next_serial(knot_zone_t *zone)
}
static int replan_zone_sign_after_ddns(knot_zone_t *zone, zonedata_t *zd,
uint32_t expires_at)
uint32_t refresh_at)
{
assert(zone);
assert(zd);
int ret = KNOT_EOK;
uint32_t new_expire = time(NULL) + expires_at;
if (new_expire < zd->dnssec_timer->tv.tv_sec) {
// Drop old event, earlier signing needed
zones_cancel_dnssec(zone);
ret = zones_schedule_dnssec(zone,
expiration_to_relative(new_expire,
zone));
if (zd->dnssec_timer->tv.tv_sec <= refresh_at) {
return KNOT_EOK;
}
return ret;
zones_cancel_dnssec(zone);
return zones_schedule_dnssec(zone, refresh_at);
}
static bool apex_rr_changed(const knot_zone_contents_t *old_contents,
......@@ -1015,7 +997,7 @@ int zones_process_update_auth(knot_zone_t *zone, knot_pkt_t *query,
knot_changesets_t *sec_chs = NULL;
knot_changeset_t *sec_ch = NULL;
uint32_t expires_at = 0;
uint32_t refresh_at = 0;
conf_zone_t *zone_config = ((zonedata_t *)knot_zone_data(zone))->conf;
assert(zone_config);
......@@ -1057,20 +1039,14 @@ int zones_process_update_auth(knot_zone_t *zone, knot_pkt_t *query,
zones_nsec3param_changed(old_contents, new_contents)) {
ret = knot_dnssec_zone_sign(fake_zone, sec_ch,
KNOT_SOA_SERIAL_KEEP,
&expires_at, new_serial);
&refresh_at, new_serial);
} else {
// Sign the created changeset
uint32_t used_lifetime = 0;
uint32_t used_refresh = 0;
knot_zone_contents_load_nsec3param(new_contents);
ret = knot_dnssec_sign_changeset(fake_zone,
knot_changesets_get_last(chgsets),
sec_ch, KNOT_SOA_SERIAL_KEEP,
&used_lifetime, &used_refresh,
new_serial);
expires_at = used_lifetime - used_refresh;
knot_changesets_get_last(chgsets),
sec_ch, KNOT_SOA_SERIAL_KEEP,
&refresh_at, new_serial);
}
if (ret != KNOT_EOK) {
......@@ -1127,7 +1103,7 @@ int zones_process_update_auth(knot_zone_t *zone, knot_pkt_t *query,
// Plan zone resign if needed
zonedata_t *zd = (zonedata_t *)zone->data;
assert(zd && zd->dnssec_timer);
ret = replan_zone_sign_after_ddns(zone, zd, expires_at);
ret = replan_zone_sign_after_ddns(zone, zd, refresh_at);
if (ret != KNOT_EOK) {
log_zone_error("%s: Failed to replan zone sign %s\n",
msg, knot_strerror(ret));
......@@ -2030,11 +2006,11 @@ int zones_schedule_refresh(knot_zone_t *zone, int64_t time)
return KNOT_EOK;
}
int zones_dnssec_sign(knot_zone_t *zone, bool force, uint32_t *expires_at)
int zones_dnssec_sign(knot_zone_t *zone, bool force, uint32_t *refresh_at)
{
int ret = KNOT_EOK;
char *msgpref = NULL;
*expires_at = 0;
*refresh_at = 0;
knot_changesets_t *chs = knot_changesets_create();
if (chs == NULL) {
......@@ -2065,11 +2041,11 @@ int zones_dnssec_sign(knot_zone_t *zone, bool force, uint32_t *expires_at)
uint32_t new_serial = zones_next_serial(zone);
if (force) {
ret = knot_dnssec_zone_sign_force(zone, ch, expires_at,
ret = knot_dnssec_zone_sign_force(zone, ch, refresh_at,
new_serial);
} else {
ret = knot_dnssec_zone_sign(zone, ch, KNOT_SOA_SERIAL_UPDATE,
expires_at, new_serial);
refresh_at, new_serial);
}
if (ret != KNOT_EOK) {
goto done;
......@@ -2100,14 +2076,13 @@ int zones_dnssec_ev(event_t *event)
// We will be working with zone, don't want it to change in the meantime
rcu_read_lock();
knot_zone_t *zone = (knot_zone_t *)event->data;
uint32_t expires_at = 0;
uint32_t refresh_at = 0;
int ret = zones_dnssec_sign(zone, false, &expires_at);
if (expires_at != 0) {
ret = zones_schedule_dnssec(zone,
expiration_to_relative(expires_at,
zone));
int ret = zones_dnssec_sign(zone, false, &refresh_at);
if (refresh_at != 0) {
ret = zones_schedule_dnssec(zone, refresh_at);
}
rcu_read_unlock();
return ret;
......@@ -2129,7 +2104,7 @@ int zones_cancel_dnssec(knot_zone_t *zone)
return KNOT_EOK;
}
int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time)
int zones_schedule_dnssec(knot_zone_t *zone, time_t unixtime)
{
if (!zone || !zone->data) {
return KNOT_EINVAL;
......@@ -2138,21 +2113,45 @@ int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time)
zonedata_t *zd = (zonedata_t *)zone->data;
evsched_t *scheduler = zd->server->sched;
char *zname = knot_dname_to_str(knot_zone_name(zone));
log_zone_info("DNSSEC: Zone %s - planning next resign %" PRIu32 "s"
"(%" PRIu32 "h) from now.\n", zname, time / 1000,
time / 3600000);
free(zname);
// event not created yet
if (zd->dnssec_timer == NULL) {
return KNOT_EAGAIN;
}
if (zd->dnssec_timer) {
// Event created already, just reschedule
evsched_schedule(scheduler, zd->dnssec_timer, time);
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;
}
// log the message
char time_str[64] = {'\0'};
struct tm time_gm = {0};
gmtime_r(&unixtime, &time_gm);
strftime(time_str, sizeof(time_str), KNOT_LOG_TIME_FORMAT, &time_gm);
log_zone_info("DNSSEC: Zone %s: Next signing planned on %s.\n",
zname, time_str);
free(zname);
// schedule
evsched_schedule(scheduler, zd->dnssec_timer, relative * 1000);
return KNOT_EOK;
}
/*!
* \brief Schedule IXFR sync for given zone.
*/
......@@ -2456,7 +2455,7 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone,
knot_changesets_t *sec_chs = NULL;
knot_changeset_t *sec_ch = NULL;
knot_zone_contents_t *new_contents = NULL;
uint32_t expires_at = 0;
uint32_t refresh_at = 0;
if (z->dnssec_enable) {
sec_chs = knot_changesets_create();
if (sec_chs == NULL) {
......@@ -2484,7 +2483,7 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone,
*/
int ret = knot_dnssec_zone_sign(zone, sec_ch,
KNOT_SOA_SERIAL_UPDATE,
&expires_at, new_serial);
&refresh_at, new_serial);
if (ret != KNOT_EOK) {
knot_changesets_free(&diff_chs);
knot_changesets_free(&sec_chs);
......@@ -2560,9 +2559,7 @@ int zones_do_diff_and_sign(const conf_zone_t *z, knot_zone_t *zone,
// Schedule next zone signing
if (z->dnssec_enable) {
ret = zones_schedule_dnssec(zone,
expiration_to_relative(expires_at,
zone));
ret = zones_schedule_dnssec(zone, refresh_at);
}
return ret;
......
......@@ -278,12 +278,12 @@ int zones_cancel_dnssec(knot_zone_t *zone);
/*!
* \brief Schedule DNSSEC event.
* \param zone Related zone.
* \param time When to schedule. Time difference in milliseconds from now.
* \param unixtime When to schedule.
* \param force Force sign or not
*
* \return Error code, KNOT_OK if successful.
*/
int zones_schedule_dnssec(knot_zone_t *zone, uint32_t time);
int zones_schedule_dnssec(knot_zone_t *zone, time_t unixtime);
/*!
* \brief Schedule IXFR sync for given zone.
......
......@@ -160,10 +160,12 @@ static knot_node_t *create_node(knot_zone_contents_t *zone,
dbg_zload_verb("zp: create_node: Creating node using RRSet: %p.\n",
current_rrset);
knot_node_t *node = knot_node_new(current_rrset->owner, NULL, 0);
if (node == NULL) {
return NULL;
}
int ret = node_add_func(zone, node, 1, 0);
if (ret != KNOT_EOK) {
log_zone_warning("Node could not be added (%s).\n",
knot_strerror(ret));
knot_node_free(&node);
return NULL;
}
......@@ -179,10 +181,13 @@ static void process_rrsigs_in_node(parser_context_t *parser,
node);
rrset_list_t *tmp = parser->node_rrsigs;
while (tmp != NULL) {
if (find_rrset_for_rrsig_in_node(zone, node,
tmp->data) != KNOT_EOK) {
int ret = find_rrset_for_rrsig_in_node(zone, node, tmp->data);
if (ret != KNOT_EOK) {
parser->ret = KNOT_ERROR;
log_zone_error("Could not add RRSIG to zone!\n");
char *rr_name = knot_dname_to_str(node->owner);
log_zone_error("Can't add RRSIG for '%s': %s\n",
rr_name, knot_strerror(ret));
free(rr_name);
return;
}
tmp = tmp->next;
......@@ -260,7 +265,10 @@ static void process_rr(const scanner_t *scanner)
int ret = add_rdata_to_rr(current_rrset, scanner);
if (ret != KNOT_EOK) {
log_zone_error("Cannot add RDATA to zone, load failed.\n");
char *rr_name = knot_dname_to_str(current_owner);
log_zone_error("%s:%"PRIu64": Can't add RDATA for '%s'.\n",
scanner->file_name, scanner->line_counter, rr_name);
free(rr_name);
parser->ret = ret;
return;
}
......@@ -301,14 +309,18 @@ static void process_rr(const scanner_t *scanner)
if (!knot_rrset_equal(current_rrset,
knot_node_rrset(knot_zone_contents_apex(contents),
KNOT_RRTYPE_SOA), KNOT_RRSET_COMPARE_WHOLE)) {
log_zone_error("Extra SOA record in the "
"zone.\n");
char *rr_name = knot_dname_to_str(current_owner);
log_zone_error("%s:%"PRIu64": Extra SOA record in the zone '%s'.\n",
scanner->file_name, scanner->line_counter, rr_name);
free(rr_name);
/*!< \todo consider a new error */
parser->ret = KNOT_EMALF;
return;
} else {
log_zone_warning("encountered identical "
"extra SOA record\n");
char *rr_name = knot_dname_to_str(current_owner);
log_zone_error("%s:%"PRIu64": encountered identical extra SOA record '%s'.\n",
scanner->file_name, scanner->line_counter, rr_name);
free(rr_name);
knot_rrset_deep_free(&current_rrset, 1);
parser->ret = KNOT_EOK;
return;
......@@ -318,10 +330,12 @@ static void process_rr(const scanner_t *scanner)
if (current_rrset->type == KNOT_RRTYPE_SOA) {
if (knot_dname_cmp(current_rrset->owner,
parser->origin_from_config) != 0) {
log_zone_error("SOA record has a different "
"owner than the one specified "
"in config! \n");
parser->origin_from_config) != 0) {
char *rr_name = knot_dname_to_str(current_owner);
log_zone_error("%s:%"PRIu64": SOA record '%s' has a different "
"owner than the one specified in config!.\n",
scanner->file_name, scanner->line_counter, rr_name);
free(rr_name);
/* Such SOA cannot even be added, because
* it would not be in the zone apex. */
parser->ret = KNOT_EOUTOFZONE;
......@@ -369,9 +383,10 @@ static void process_rr(const scanner_t *scanner)
node_add_func))
== NULL) {
knot_rrset_free(&tmp_rrsig);
dbg_zload("zp: process_rr: Cannot "
"create new node.\n");
log_zone_error("None cannot be created.\n");
char *rr_name = knot_dname_to_str(current_owner);
log_zone_error("%s:%"PRIu64": Can't create node for '%s'.\n",
scanner->file_name, scanner->line_counter, rr_name);
free(rr_name);
/*!< \todo consider a new error */
parser->ret = KNOT_ERROR;
return;
......@@ -419,15 +434,10 @@ static void process_rr(const scanner_t *scanner)
if ((node = create_node(contents, current_rrset,
node_add_func)) == NULL) {
dbg_zload("zp: process_rr: Cannot "
"create new node.\n");
char *zone_name = knot_dname_to_str(contents->apex->owner);
char *name = knot_dname_to_str(current_rrset->owner);
log_zone_warning("Zone %s: Cannot create new "
"node owned by %s, skipping.\n",
zone_name, name);
free(name);
free(zone_name);
char *rr_name = knot_dname_to_str(current_owner);
log_zone_error("%s:%"PRIu64": Can't create node for '%s'.\n",
scanner->file_name, scanner->line_counter, rr_name);
free(rr_name);
knot_rrset_deep_free(&current_rrset, 1);
return;
}
......@@ -440,11 +450,13 @@ static void process_rr(const scanner_t *scanner)
*/
const knot_rrset_t *rrset_in_node =
knot_node_rrset(node, current_rrset->type);
if (rrset_in_node &&
current_rrset->ttl != rrset_in_node->ttl) {
log_zone_warning("TTL does not match TTL of its RRSet."
"Changing to %"PRIu32"\n",
rrset_in_node->ttl);
if (rrset_in_node && current_rrset->ttl != rrset_in_node->ttl) {
char *rr_name = knot_dname_to_str(current_owner);
log_zone_warning("%s:%"PRIu64": TTL of '%s/TYPE%u' does not match TTL "
"of its RRSet. Changing to %"PRIu32"\n",
scanner->file_name, scanner->line_counter,
rr_name, current_rrset->type, rrset_in_node->ttl);
free(rr_name);
/* Actual change will happen in merge. */
}
}
......@@ -469,15 +481,16 @@ static void process_rr(const scanner_t *scanner)
parser->err_handler, true,
&sem_fatal_error);
if (ret != KNOT_EOK) {
log_zone_error("Semantic check failed to run (%s)\n",
log_zone_error("%s:%"PRIu64": Semantic check failed: %s\n",
scanner->file_name, scanner->line_counter,
knot_strerror(ret));
parser->ret = ret;
return;
}
if (sem_fatal_error) {
log_zone_error("Semantic check found fatal error "
"on line=%"PRIu64"\n",
scanner->line_counter);
log_zone_error("%s:%"PRIu64": Semantic check found fatal error: %s\n",
scanner->file_name, scanner->line_counter,
knot_strerror(ret));
parser->ret = KNOT_EMALF;
return;
}
......@@ -571,8 +584,8 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
assert(c);
int ret = file_loader_process(loader->file_loader);
if (ret != ZSCANNER_OK) {
log_zone_error("Zone could not be loaded (%s).\n",
zscanner_strerror(ret));
log_zone_error("%s: zone file could not be loaded (%s).\n",
loader->source, zscanner_strerror(ret));
}
if (c->last_node && c->node_rrsigs) {
......@@ -580,8 +593,8 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
}
if (c->ret != KNOT_EOK) {
log_zone_error("Zone could not be loaded (%s).\n",
knot_strerror(c->ret));
log_zone_error("%s: zone file could not be loaded (%s).\n",
loader->source, zscanner_strerror(c->ret));
rrset_list_delete(&c->node_rrsigs);
knot_zone_t *zone_to_free = c->current_zone->zone;
knot_zone_deep_free(&zone_to_free);
......@@ -589,8 +602,9 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
}
if (loader->file_loader->scanner->error_counter > 0) {
log_zone_error("Zone could not be loaded due to %"PRIu64" errors"
" encountered.\n",
log_zone_error("%s: zone file could not be loaded due to "
"%"PRIu64" errors encountered.\n",
loader->source,
loader->file_loader->scanner->error_counter);
rrset_list_delete(&c->node_rrsigs);
knot_zone_t *zone_to_free = c->current_zone->zone;
......@@ -601,7 +615,8 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
if (knot_zone_contents_apex(c->current_zone) == NULL ||
knot_node_rrset(knot_zone_contents_apex(c->current_zone),
KNOT_RRTYPE_SOA) == NULL) {
log_zone_error("No SOA record in the zone file.\n");
log_zone_error("%s: no SOA record in the zone file.\n",
loader->source);
rrset_list_delete(&c->node_rrsigs);
knot_zone_t *zone_to_free = c->current_zone->zone;
knot_zone_deep_free(&zone_to_free);
......@@ -614,8 +629,8 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
int kret = knot_zone_contents_adjust(c->current_zone, &first_nsec3_node,
&last_nsec3_node, 0);
if (kret != KNOT_EOK) {
log_zone_error("Failed to finalize zone contents: %s\n",
knot_strerror(kret));
log_zone_error("%s: Failed to finalize zone contents: %s\n",
loader->source, knot_strerror(kret));
rrset_list_delete(&c->node_rrsigs);
knot_zone_t *zone_to_free = c->current_zone->zone;
knot_zone_deep_free(&zone_to_free);
......
/* Copyright (C) 2014 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/>.
*/
#include <config.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include "libknot/dnssec/policy.h"
uint32_t knot_dnssec_policy_refresh_time(const knot_dnssec_policy_t *policy,
uint32_t earliest_expiration)
{
if (policy == NULL) {
return 0;
}
uint32_t signature_safety = policy->sign_lifetime / 10;
if (earliest_expiration <= signature_safety) {
return 0;
}
return earliest_expiration - signature_safety;
}
void knot_dnssec_policy_set_sign_lifetime(knot_dnssec_policy_t *policy,
uint32_t sign_lifetime)
{
if (policy == NULL) {
return;
}
uint32_t max_expiration = policy->now + sign_lifetime;
policy->sign_lifetime = sign_lifetime;
policy->refresh_before = knot_dnssec_policy_refresh_time(policy,
max_expiration);
}
void knot_dnssec_init_default_policy(knot_dnssec_policy_t *policy)
{
if (policy == NULL) {
return;
}
memset(policy, 0, sizeof(*policy));
policy->now = time(NULL);
policy->soa_up = KNOT_SOA_SERIAL_UPDATE;
knot_dnssec_policy_set_sign_lifetime(policy, KNOT_DNSSEC_DEFAULT_LIFETIME);
}
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2014 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
......@@ -27,6 +27,9 @@
#ifndef _KNOT_DNSSEC_POLICY_H_
#define _KNOT_DNSSEC_POLICY_H_
#include <stdbool.h>
#include <stdint.h>
typedef enum knot_update_serial {
KNOT_SOA_SERIAL_UPDATE = 1 << 0,
KNOT_SOA_SERIAL_KEEP = 1 << 1
......@@ -34,25 +37,31 @@ typedef enum knot_update_serial {
typedef struct {
uint32_t now; //! Current time.
uint32_t refresh_before; //! Refresh signatures expiring before to this time.
uint32_t sign_lifetime; //! Signature life time.
uint32_t sign_refresh; //! Sig. refresh time before expiration.
bool forced_sign; //! Drop valid signatures as well.
knot_update_serial_t soa_up;//! Policy for serial updating.
} knot_dnssec_policy_t;
#define KNOT_DNSSEC_DEFAULT_LIFETIME 2592000
#define KNOT_DNSSEC_DEFAULT_REFRESH 7200
#define DEFAULT_DNSSEC_POLICY { .now = time_now(), \
.sign_lifetime = KNOT_DNSSEC_DEFAULT_LIFETIME, \
.sign_refresh = KNOT_DNSSEC_DEFAULT_REFRESH, \
.forced_sign = false, \
.soa_up = KNOT_SOA_SERIAL_UPDATE }
#define FORCED_DNSSEC_POLICY { .now = time_now(), \
.sign_lifetime = KNOT_DNSSEC_DEFAULT_LIFETIME, \
.sign_refresh = KNOT_DNSSEC_DEFAULT_REFRESH, \
.forced_sign = true, \
.soa_up = KNOT_SOA_SERIAL_UPDATE }
/*!
* \brief Initialize default signing policy.
*/
void knot_dnssec_init_default_policy(knot_dnssec_policy_t *policy);
/*!
* \brief Set policy timing data according to requested signature lifetime.
*/
void knot_dnssec_policy_set_sign_lifetime(knot_dnssec_policy_t *policy,
uint32_t sign_lifetime);
/*!
* \brief Get signature refresh time from the earliest expiration time.
*/
uint32_t knot_dnssec_policy_refresh_time(const knot_dnssec_policy_t *policy,
uint32_t earliest_expiration);
#endif // _KNOT_DNSSEC_POLICY_H_
......
......@@ -334,11 +334,9 @@ static bool is_expired_signature(const knot_rrset_t *rrsigs, size_t pos,
assert(rrsigs->type == KNOT_RRTYPE_RRSIG);
assert(policy);
uint32_t now = policy->now;
uint32_t refresh = policy->sign_refresh;
uint32_t expiration = knot_rdata_rrsig_sig_expiration(rrsigs, pos);
return (expiration - refresh) <= now;
return (expiration <= policy->refresh_before);
}
/*!
......
......@@ -27,27 +27,6 @@
#include "libknot/util/debug.h"
#include "libknot/zone/zone.h"
static uint32_t time_now(void)
{
return (uint32_t)time(NULL);
}
static void init_default_policy(knot_dnssec_policy_t *p,
knot_update_serial_t soa_up)
{
knot_dnssec_policy_t p_image = DEFAULT_DNSSEC_POLICY;
memcpy(p, &p_image, sizeof(knot_dnssec_policy_t));
p->soa_up = soa_up;