Skip to content
Snippets Groups Projects
Commit 4d6d4f8e authored by Daniel Salzman's avatar Daniel Salzman
Browse files

dnssec: fix zone expiration based on EXPIRE if zone signing results in up-to-date

parent 1913c0f1
No related branches found
No related tags found
No related merge requests found
......@@ -271,6 +271,12 @@ int knot_dnssec_zone_sign(zone_update_t *update,
if (zone_update_no_change(update)) {
log_zone_info(zone_name, "DNSSEC, zone is up-to-date");
update->zone->zonefile.resigned = false;
if (update->zone->contents != NULL) {
/* In this case zone_update_commit() might roll-back the update,
* throwing off the correct update->new_cont->dnssec_expire.
* Therefore it's necessary to also set it in the live contents. */
ATOMIC_SET(update->zone->contents->dnssec_expire, ctx.stats->expire);
}
goto done;
} else {
update->zone->zonefile.resigned = true;
......
......@@ -364,7 +364,7 @@ static int answer_edns_put(knot_pkt_t *resp, knotd_qdata_t *qdata)
if (knot_pkt_edns_option(qdata->query, KNOT_EDNS_OPTION_EXPIRE) != NULL &&
qdata->extra->contents != NULL && !qdata->extra->zone->is_catalog_flag) {
int64_t timer = qdata->extra->zone->timers.next_expire;
timer = knot_time_min(timer, qdata->extra->contents->dnssec_expire); // NOOP if zero
timer = knot_time_min(timer, ATOMIC_GET(qdata->extra->contents->dnssec_expire)); // NOOP if zero
timer = (timer == 0 ? zone_soa_expire(qdata->extra->zone) : timer - time(NULL));
timer = MAX(timer, 0);
uint32_t timer_be;
......
......@@ -16,7 +16,7 @@
#pragma once
#include "contrib/time.h"
#include "contrib/atomic.h"
#include "libdnssec/nsec.h"
#include "libknot/rrtype/nsec3param.h"
#include "knot/zone/node.h"
......@@ -36,10 +36,10 @@ typedef struct zone_contents {
trie_t *adds_tree; // "additionals tree" for reverse lookup of nodes affected by additionals
dnssec_nsec3_params_t nsec3_params;
knot_atomic_uint64_t dnssec_expire;
size_t size;
uint32_t max_ttl;
bool dnssec;
knot_time_t dnssec_expire;
} zone_contents_t;
/*!
......
$ORIGIN example.com.
$TTL 2
@ SOA dns1.example.net. hostmaster 1 2 2 30 1
NS dns1
dns1 A 192.0.2.1
#!/usr/bin/env python3
'''Test of EDNS expire based on RRSIG validity if when signing up-to-date'''
from dnstest.test import Test
from dnstest.utils import *
t = Test()
master = t.server("knot")
slave = t.server("knot")
zones = t.zone("example.com", storage=".")
t.link(zones, master, slave, ixfr=True, ddns=True)
for z in zones:
master.dnssec(z).enable = True
master.dnssec(z).rrsig_lifetime = 40
master.dnssec(z).rrsig_refresh = 5
master.dnssec(z).rrsig_prerefresh = 0
master.dnssec(z).propagation_delay = 0
def send_ddns(server, zone, data):
up = server.update(zone)
up.delete("test." + zone.name, "TXT")
up.add("test." + zone.name, 2, "TXT", data)
up.send("NOERROR")
t.start()
master.zones_wait(zones)
send_ddns(master, zones[0], "init")
master.ctl("zone-sign", wait=True)
t.sleep(20)
send_ddns(master, zones[0], "first")
t.sleep(20)
send_ddns(master, zones[0], "second")
t.sleep(22)
soa = slave.dig(zones[0].name, "SOA")
soa.check(rcode="NOERROR")
if slave.log_search("expired"):
set_err("ZONE EXPIRED")
t.end()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment