It happens if the server does not know about the DS special case.
Treat the delegation as a unsigned NODATA answer in that case.
For example for sthc.nordlo.cloud we go from the existing:
```
[1] sthc.nordlo.cloud: Resolved 'nordlo.cloud' NS ns2.zetup.se to: 159.253.27.75
[1] sthc.nordlo.cloud: Trying IP 159.253.27.75:53, asking 'sthc.nordlo.cloud|DS'
[1] sthc.nordlo.cloud: Got 3 answers from ns2.zetup.se (159.253.27.75), rcode=0 (No Error), aa=0, in 35ms
[1] sthc.nordlo.cloud: accept answer 'sthc.nordlo.cloud|NS|ns2.loopia.se.' from 'nordlo.cloud' nameservers? ttl=3600, place=2 YES!
[1] sthc.nordlo.cloud: accept answer 'sthc.nordlo.cloud|NS|ns1.loopia.se.' from 'nordlo.cloud' nameservers? ttl=3600, place=2 YES!
[1] sthc.nordlo.cloud: OPT answer '.' from 'nordlo.cloud' nameservers
[1] sthc.nordlo.cloud: determining status after receiving this packet
[1] sthc.nordlo.cloud: got NS record 'sthc.nordlo.cloud' -> 'ns2.loopia.se.'
[1] sthc.nordlo.cloud: got NS record 'sthc.nordlo.cloud' -> 'ns1.loopia.se.'
[1] sthc.nordlo.cloud: status=did not resolve, got 2 NS, looping to them
[1] sthc.nordlo.cloud.: Nameservers: ns1.loopia.se(37.85ms), ns2.loopia.se(38.26ms)
[1] sthc.nordlo.cloud: Trying to resolve NS 'ns1.loopia.se' (1/2)
[1] Nameserver ns1.loopia.se IPs: 93.188.0.20(37.85ms)
[1] sthc.nordlo.cloud: Resolved 'sthc.nordlo.cloud' NS ns1.loopia.se to: 93.188.0.20
[1] sthc.nordlo.cloud: Trying IP 93.188.0.20:53, asking 'sthc.nordlo.cloud|DS'
```
to:
```
[1] sthc.nordlo.cloud: Resolved 'nordlo.cloud' NS ns2.zetup.se to: 159.253.27.75
[1] sthc.nordlo.cloud: Trying IP 159.253.27.75:53, asking 'sthc.nordlo.cloud|DS'
[1] sthc.nordlo.cloud: Got 3 answers from ns2.zetup.se (159.253.27.75), rcode=0 (No Error), aa=0, in 35ms
[1] sthc.nordlo.cloud: accept answer 'sthc.nordlo.cloud|NS|ns2.loopia.se.' from 'nordlo.cloud' nameservers? ttl=3600, place=2 YES!
[1] sthc.nordlo.cloud: accept answer 'sthc.nordlo.cloud|NS|ns1.loopia.se.' from 'nordlo.cloud' nameservers? ttl=3600, place=2 YES!
[1] sthc.nordlo.cloud: OPT answer '.' from 'nordlo.cloud' nameservers
[1] sthc.nordlo.cloud: determining status after receiving this packet
[1] sthc.nordlo.cloud: got NS record 'sthc.nordlo.cloud' -> 'ns2.loopia.se.'
[1] sthc.nordlo.cloud: got (implicit) negative indication of DS record for 'sthc.nordlo.cloud'
[1] sthc.nordlo.cloud: got NS record 'sthc.nordlo.cloud' -> 'ns1.loopia.se.'
[1] sthc.nordlo.cloud: status=noerror, other types may exist, but we are done (have negative SOA)
[1] : no signatures for sthc.nordlo.cloud, we likely missed a cut between cloud and nordlo.cloud, looking for it
```
if (moreSpecificThan(rec.d_name,auth)) {
newauth = rec.d_name;
LOG(prefix<<qname<<": got NS record '"<<rec.d_name<<"' -> '"<<rec.d_content->getZoneRepresentation()<<"'"<<endl);
- realreferral = true;
+
+ if (!negindic && qtype == QType::DS && qname == newauth) {
+ /* just got a referral from the parent zone when asking for a DS, looks like this server did not get the DNSSE memo.. */
+ LOG(prefix<<qname<<": got (implicit) negative indication of DS record for '"<<qname<<"'"<<endl);
+ negindic = true;
+ negIndicHasSignatures = false;
+ nsset.clear();
+ }
+ else {
+ realreferral = true;
+ }
}
else {
LOG(prefix<<qname<<": got upwards/level NS record '"<<rec.d_name<<"' -> '"<<rec.d_content->getZoneRepresentation()<<"', had '"<<auth<<"'"<<endl);
}
- if (auto content = getRR<NSRecordContent>(rec)) {
- nsset.insert(content->getNS());
+ if (!negindic) {
+ if (auto content = getRR<NSRecordContent>(rec)) {
+ nsset.insert(content->getNS());
+ }
}
}
else if (rec.d_place==DNSResourceRecord::AUTHORITY && rec.d_type==QType::DS && qname.isPartOf(rec.d_name)) {
g_negCache->add(ne);
}
- if (qname == newauth && qtype == QType::DS) {
+ if (qtype == QType::DS && qname == newauth) {
/* we are actually done! */
negindic = true;
negIndicHasSignatures = !ne.authoritySOA.signatures.empty() || !ne.DNSSECRecords.signatures.empty();