* Try to find records for pending_cname owner from section start. */
cname = pending_cname;
pending_cname = NULL;
+ const int cname_labels = knot_dname_labels(cname, NULL);
for (unsigned i = 0; i < an->count; ++i) {
const knot_rrset_t *rr = knot_pkt_rr(an, i);
continue;
}
+ if (rr->type == KNOT_RRTYPE_RRSIG) {
+ int rrsig_labels = knot_rrsig_labels(&rr->rrs, 0);
+ if (rrsig_labels > cname_labels) {
+ return KR_STATE_FAIL;
+ }
+ if (rrsig_labels < cname_labels) {
+ query->flags |= QUERY_DNSSEC_WEXPAND;
+ }
+ }
+
/* Process records matching current SNAME */
int state = KR_STATE_FAIL;
bool to_wire = false;
}
/* try to unroll cname only within current zone */
const int pending_labels = knot_dname_labels(pending_cname, NULL);
- const int cname_labels = knot_dname_labels(cname, NULL);
if (pending_labels != cname_labels) {
cname = pending_cname;
break;
} else {
next->flags &= ~QUERY_DNSSEC_WANT;
}
- state = pick_authority(pkt, req, false);
- if (state != kr_ok()) {
- return KR_STATE_FAIL;
+ if (!(query->flags & QUERY_FORWARD) ||
+ (query->flags & QUERY_DNSSEC_WEXPAND)) {
+ state = pick_authority(pkt, req, false);
+ if (state != kr_ok()) {
+ return KR_STATE_FAIL;
+ }
}
} else if (!query->parent) {
/* Answer for initial query */
}
}
- if (nods && ns_exist && qtype == KNOT_RRTYPE_NS && !(qry->flags & QUERY_CNAME)) {
+ if (nods && ns_exist && qtype == KNOT_RRTYPE_NS) {
qry->flags &= ~QUERY_DNSSEC_WANT;
qry->flags |= QUERY_DNSSEC_INSECURE;
if (qry->forward_flags & QUERY_CNAME) {
bool has_nsec3 = pkt_has_type(pkt, KNOT_RRTYPE_NSEC3);
const knot_pktsection_t *an = knot_pkt_section(pkt, KNOT_ANSWER);
const bool referral = (an->count == 0 && !knot_wire_get_aa(pkt->wire));
- const bool no_data = (an->count == 0 && knot_wire_get_aa(pkt->wire));
if (!(qry->flags & QUERY_CACHED) && knot_wire_get_aa(pkt->wire)) {
/* Check if answer if not empty,
}
/* Validate non-existence proof if not positive answer. */
- if (!(qry->flags & QUERY_CACHED) && pkt_rcode == KNOT_RCODE_NXDOMAIN) {
+ if (!(qry->flags & QUERY_CACHED) && pkt_rcode == KNOT_RCODE_NXDOMAIN &&
+ ((qry->flags & (QUERY_FORWARD | QUERY_CNAME)) != (QUERY_FORWARD | QUERY_CNAME))) {
/* @todo If knot_pkt_qname(pkt) is used instead of qry->sname then the tests crash. */
if (!has_nsec3) {
ret = kr_nsec_name_error_response_check(pkt, KNOT_AUTHORITY, qry->sname);
/* @todo WTH, this needs API that just tries to find a proof and the caller
* doesn't have to worry about NSEC/NSEC3
* @todo rework this */
- if (!(qry->flags & QUERY_CACHED)) {
- if (pkt_rcode == KNOT_RCODE_NOERROR && no_data) {
+ if (!(qry->flags & QUERY_CACHED) && (pkt_rcode == KNOT_RCODE_NOERROR) &&
+ ((qry->flags & (QUERY_FORWARD | QUERY_CNAME)) != (QUERY_FORWARD | QUERY_CNAME))) {
+ bool no_data = (an->count == 0 && knot_wire_get_aa(pkt->wire));
+ if (no_data) {
/* @todo
* ? quick mechanism to determine which check to preform first
* ? merge the functionality together to share code/resources