diff --git a/CHANGES b/CHANGES index 8eff7be497..72c9a9b44a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +5668. [bug] When a zone fails to load on startup, the setnsec3param + task is rescheduled. This caused a hang on shutdown, and + is now fixed. [GL #2791] + 5667. [bug] The configuration-checking code failed to account for the inheritance rules of the "dnssec-policy" option. [GL #2780] diff --git a/bin/tests/system/nsec3/ns3/named.conf.in b/bin/tests/system/nsec3/ns3/named.conf.in index 791881225b..2241bc87bf 100644 --- a/bin/tests/system/nsec3/ns3/named.conf.in +++ b/bin/tests/system/nsec3/ns3/named.conf.in @@ -111,3 +111,11 @@ zone "nsec3-to-nsec.kasp" { file "nsec3-to-nsec.kasp.db"; dnssec-policy "nsec3"; }; + +/* The zone fails to load, this should not prevent shutdown. */ +zone "nsec3-fails-to-load.kasp" { + type primary; + file "nsec3-fails-to-load.kasp.db"; + dnssec-policy "nsec3"; + allow-update { any; }; +}; diff --git a/bin/tests/system/nsec3/ns3/named2.conf.in b/bin/tests/system/nsec3/ns3/named2.conf.in index ece1549395..380e56654c 100644 --- a/bin/tests/system/nsec3/ns3/named2.conf.in +++ b/bin/tests/system/nsec3/ns3/named2.conf.in @@ -117,3 +117,11 @@ zone "nsec3-to-nsec.kasp" { //dnssec-policy "nsec3"; dnssec-policy "nsec"; }; + +/* The zone fails to load, but is fixed after a reload. */ +zone "nsec3-fails-to-load.kasp" { + type primary; + file "nsec3-fails-to-load.kasp.db"; + dnssec-policy "nsec3"; + allow-update { any; }; +}; diff --git a/bin/tests/system/nsec3/ns3/nsec3-fails-to-load.kasp.db.in b/bin/tests/system/nsec3/ns3/nsec3-fails-to-load.kasp.db.in new file mode 100644 index 0000000000..5703d810d3 --- /dev/null +++ b/bin/tests/system/nsec3/ns3/nsec3-fails-to-load.kasp.db.in @@ -0,0 +1,8 @@ +@ IN SOA kasp. nsec3-fails-to-load.kasp. ( + 1 ; serial + 30 ; refresh (30 seconds) + 10 ; retry (10 seconds) + 3600000 ; expire (5 weeks 6 days 16 hours) + 300 ; minimum (5 minutes) + ) + NS nsec3-fails-to-load.kasp. diff --git a/bin/tests/system/nsec3/ns3/setup.sh b/bin/tests/system/nsec3/ns3/setup.sh index 4b529d33d9..ffedec558f 100644 --- a/bin/tests/system/nsec3/ns3/setup.sh +++ b/bin/tests/system/nsec3/ns3/setup.sh @@ -27,3 +27,5 @@ for zn in nsec-to-nsec3 nsec3 nsec3-other nsec3-change nsec3-to-nsec \ do setup "${zn}.kasp" done + +cp nsec3-fails-to-load.kasp.db.in nsec3-fails-to-load.kasp.db diff --git a/bin/tests/system/nsec3/tests.sh b/bin/tests/system/nsec3/tests.sh index 62c49e5904..ac3a3c13cd 100644 --- a/bin/tests/system/nsec3/tests.sh +++ b/bin/tests/system/nsec3/tests.sh @@ -218,7 +218,6 @@ echo_i "reconfig dnssec-policy to trigger nsec3 rollovers" copy_setports ns3/named2.conf.in ns3/named.conf rndc_reconfig ns3 10.53.0.3 - # Zone: nsec-to-nsec3.kasp. (reconfigured) set_zone_policy "nsec-to-nsec3.kasp" "nsec3" set_nsec3param "0" "5" "8" @@ -324,5 +323,15 @@ echo_i "check zone ${ZONE} after restart has salt ${SALT}" check_nsec3 dnssec_verify +# Zone: nsec3-fails-to-load.kasp. (should be fixed after reload) +cp ns3/template.db.in ns3/nsec3-fails-to-load.kasp.db +rndc_reload ns3 10.53.0.3 + +set_zone_policy "nsec3-fails-to-load.kasp" "nsec3" +set_nsec3param "0" "5" "8" +echo_i "check zone ${ZONE} after reload" +check_nsec3 +dnssec_verify + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 0755baf636..3d24967577 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -21228,6 +21228,7 @@ static void setnsec3param(isc_task_t *task, isc_event_t *event) { const char *me = "setnsec3param"; dns_zone_t *zone = event->ev_arg; + bool loadpending; INSIST(DNS_ZONE_VALID(zone)); @@ -21235,6 +21236,10 @@ setnsec3param(isc_task_t *task, isc_event_t *event) { ENTER; + LOCK_ZONE(zone); + loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); + UNLOCK_ZONE(zone); + /* * If receive_secure_serial is still processing or we have a * queued event append rss_post queue. @@ -21252,7 +21257,7 @@ setnsec3param(isc_task_t *task, isc_event_t *event) { * be picked up later. This turns this function into a busy * wait, but it only happens at startup. */ - if (zone->db == NULL) { + if (zone->db == NULL && loadpending) { rescheduled = true; isc_task_send(task, &event); }