Commit 43f776c4 authored by Vladimír Čunát's avatar Vladimír Čunát

Merge !316: release 1.3.1

parents 62b49006 65629bd0
Pipeline #6343 passed with stages
in 80 minutes and 20 seconds
Knot Resolver 1.3.1 (2017-06-xx)
Knot Resolver 1.3.1 (2017-06-23)
================================
Bugfixes
......
# Project
MAJOR := 1
MINOR := 3
PATCH := 0
PATCH := 1
EXTRA :=
ABIVER := 3
BUILDMODE := dynamic
......
......@@ -449,6 +449,7 @@ static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral,
* 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);
......@@ -461,6 +462,16 @@ static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral,
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;
......@@ -509,7 +520,6 @@ static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral,
}
/* 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;
......@@ -675,9 +685,12 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
} 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 */
......
......@@ -229,8 +229,16 @@ static int pktcache_stash(kr_layer_t *ctx, knot_pkt_t *pkt)
/* Cache only NODATA/NXDOMAIN or metatype/RRSIG or wildcard expanded answers. */
const uint16_t qtype = knot_pkt_qtype(pkt);
const bool is_eligible = (knot_rrtype_is_metatype(qtype) || qtype == KNOT_RRTYPE_RRSIG);
const bool is_negative = kr_response_classify(pkt) & (PKT_NODATA|PKT_NXDOMAIN);
if (!(is_eligible || is_negative || (qry->flags & QUERY_DNSSEC_WEXPAND))) {
bool is_negative = kr_response_classify(pkt) & (PKT_NODATA|PKT_NXDOMAIN);
bool wcard_expansion = (qry->flags & QUERY_DNSSEC_WEXPAND);
if (is_negative && ((qry->flags & (QUERY_FORWARD | QUERY_CNAME)) ==
(QUERY_FORWARD | QUERY_CNAME))) {
/* Don't cache CNAME'ed NXDOMAIN answer in forwarding mode
since it can contain records
which have not been validated by validator */
return ctx->state;
}
if (!(is_eligible || is_negative || wcard_expansion)) {
return ctx->state;
}
uint32_t ttl = packet_ttl(pkt, is_negative);
......
......@@ -316,7 +316,7 @@ static int update_parent_keys(struct kr_request *req, uint16_t answer_type)
mark_insecure_parents(qry);
}
}
} else if ((qry->flags & (QUERY_DNSSEC_NODS | QUERY_FORWARD | QUERY_DNSSEC_OPTOUT)) ==
} else if ((qry->flags & (QUERY_DNSSEC_NODS | QUERY_FORWARD)) ==
(QUERY_DNSSEC_NODS | QUERY_FORWARD)) {
int ret = kr_dnssec_matches_name_and_type(&req->auth_selected, qry->uid,
qry->sname, KNOT_RRTYPE_NS);
......@@ -590,7 +590,7 @@ static int unsigned_forward(kr_layer_t *ctx, knot_pkt_t *pkt)
}
}
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) {
......@@ -859,7 +859,6 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
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,
......@@ -896,7 +895,8 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
}
/* 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);
......@@ -920,8 +920,10 @@ static int validate(kr_layer_t *ctx, knot_pkt_t *pkt)
/* @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
......
......@@ -1007,10 +1007,6 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query
return KR_STATE_DONE;
}
if (qry->parent == NULL && (qry->flags & QUERY_CNAME)) {
return KR_STATE_PRODUCE;
}
bool nods = false;
bool ds_req = false;
bool ns_req = false;
......@@ -1041,19 +1037,22 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query
knot_dname_is_equal(q->sname, wanted_name)) {
if (q->stype == KNOT_RRTYPE_DS) {
ds_req = true;
if (qry->flags & QUERY_DNSSEC_NODS) {
if (q->flags & QUERY_DNSSEC_NODS) {
nods = true;
}
if (qry->flags & QUERY_CNAME) {
if (q->flags & QUERY_CNAME) {
nods = true;
ns_req = true;
}
if (!(q->flags & QUERY_DNSSEC_OPTOUT)) {
ns_exist = false;
} else if (!(q->flags & QUERY_DNSSEC_OPTOUT)) {
int ret = kr_dnssec_matches_name_and_type(&request->auth_selected, q->uid,
wanted_name, KNOT_RRTYPE_NS);
ns_exist = (ret == kr_ok());
}
} else {
if (q->flags & QUERY_CNAME) {
nods = true;
ns_exist = false;
}
ns_req = true;
}
}
......@@ -1068,6 +1067,11 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query
return KR_STATE_DONE;
}
if (qry->parent == NULL && (qry->flags & QUERY_CNAME) &&
ds_req && ns_req) {
return KR_STATE_PRODUCE;
}
if ((qry->stype == KNOT_RRTYPE_DS) &&
knot_dname_is_equal(wanted_name, qry->sname)) {
nods = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment