}
/** Compute rank appropriate for RRs present in the packet. */
-static inline kr_validation_rank_t get_initial_rank(const struct kr_request *req)
+static inline uint8_t get_initial_rank(const knot_rrset_t *rr,
+ const struct kr_query *qry, bool answer)
{
- const uint32_t qflags = req->current_query->flags;
- if ((qflags & QUERY_CACHED)
- && !knot_wire_get_cd(req->answer->wire)
- && (qflags & QUERY_DNSSEC_WANT)
- && !(qflags & (QUERY_DNSSEC_INSECURE|QUERY_DNSSEC_BOGUS)))
- return KR_VLDRANK_SECURE;
- /* TODO: make cache better signal real ranks of individual RRs. */
- return KR_VLDRANK_INITIAL;
+ const uint32_t qflags = qry->flags;
+ uintptr_t rank = (uintptr_t)rr->additional;
+ assert((((qflags & QUERY_CACHED) == 0) && (rr->additional == NULL)) ||
+ (rank <= KR_RANK_SECURE));
+ if (((qflags & QUERY_CACHED) == 0) && answer) {
+ rank |= KR_RANK_AUTH;
+ }
+ return (uint8_t)rank;
}
static int pick_authority(knot_pkt_t *pkt, struct kr_request *req, bool to_wire)
struct kr_query *qry = req->current_query;
const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
- kr_validation_rank_t rank = get_initial_rank(req);
-
const knot_dname_t *zonecut_name = qry->zone_cut.name;
bool referral = !knot_wire_get_aa(pkt->wire);
if (referral) {
if (!knot_dname_in(zonecut_name, rr->owner)) {
continue;
}
+ uint8_t rank = get_initial_rank(rr, qry, false);
int ret = kr_ranked_rrarray_add(&req->auth_selected, rr,
rank, to_wire, qry->uid, &req->pool);
if (ret != kr_ok()) {
const knot_dname_t *cname = NULL;
const knot_dname_t *pending_cname = query->sname;
unsigned cname_chain_len = 0;
- kr_validation_rank_t rank = get_initial_rank(req);
bool is_final = (query->parent == NULL);
uint32_t iter_count = 0;
bool strict_mode = (query->flags & QUERY_STRICT);
return state;
}
}
+ uint8_t rank = get_initial_rank(rr, query, true);
state = kr_ranked_rrarray_add(&req->answ_selected, rr,
rank, to_wire, query->uid, &req->pool);
if (state != kr_ok()) {
for (unsigned i = 0; i < an->count; ++i) {
const knot_rrset_t *rr = knot_pkt_rr(an, i);
int err = kr_ranked_rrarray_add(&req->answ_selected, rr,
- KR_VLDRANK_INITIAL, true, query->uid, &req->pool);
+ KR_RANK_INITIAL | KR_RANK_AUTH, true, query->uid, &req->pool);
if (err != kr_ok()) {
return KR_STATE_FAIL;
}
return section_has_type(knot_pkt_section(pkt, KNOT_ADDITIONAL), type);
}
+static inline uint8_t rank_get_value(uint8_t rank)
+{
+ return rank & 0x07;
+}
+
+static inline uint8_t rank_get_flags(uint8_t rank)
+{
+ return rank & ~0x07;
+}
+
+static inline void rank_set_value(uint8_t *rank, uint8_t value)
+{
+ assert(rank);
+ *rank = rank_get_flags(*rank) | rank_get_value(value);
+}
+
+static inline void rank_set_flag(uint8_t *rank, uint8_t flag)
+{
+ assert(rank);
+ *rank = rank_get_flags(flag) | rank_get_value(*rank);
+}
+
+static inline bool rank_test_flag(uint8_t rank, uint8_t flag)
+{
+ return (rank | rank_get_flags(flag)) != 0;
+}
+
static int validate_section(kr_rrset_validation_ctx_t *vctx, knot_mm_t *pool)
{
if (!vctx) {
for (ssize_t i = 0; i < vctx->rrs->len; ++i) {
ranked_rr_array_entry_t *entry = vctx->rrs->at[i];
const knot_rrset_t *rr = entry->rr;
- if (entry->rank == KR_VLDRANK_SECURE ||
+ assert((entry->rank & (KR_RANK_SECURE | KR_RANK_INSECURE)) != (KR_RANK_SECURE | KR_RANK_INSECURE));
+ if (rank_test_flag(entry->rank, KR_RANK_SECURE) ||
entry->yielded || vctx->qry_uid != entry->qry_uid) {
continue;
}
if (rr->type == KNOT_RRTYPE_RRSIG) {
const knot_dname_t *signer_name = knot_rrsig_signer_name(&rr->rrs, 0);
if (!knot_dname_is_equal(vctx->zone_name, signer_name)) {
- entry->rank = KR_VLDRANK_MISMATCH;
+ rank_set_value(&entry->rank, KR_RANK_MISMATCH);
vctx->err_cnt += 1;
break;
}
- entry->rank = KR_VLDRANK_SECURE; /* TODO: not good semantically for RRSIGs */
+ rank_set_value(&entry->rank, KR_RANK_OMIT);
continue;
}
if ((rr->type == KNOT_RRTYPE_NS) && (vctx->section_id == KNOT_AUTHORITY)) {
- entry->rank = KR_VLDRANK_SECURE; /* FIXME: dangerous, most likely */
+ rank_set_value(&entry->rank, KR_RANK_OMIT);
continue;
}
validation_result = kr_rrset_validate(vctx, rr);
if (validation_result == kr_ok()) {
- entry->rank = KR_VLDRANK_SECURE;
+ rank_set_flag(&entry->rank, KR_RANK_SECURE);
} else if (validation_result == kr_error(ENOENT)) {
/* no RRSIGs found */
- entry->rank = KR_VLDRANK_INSECURE;
+ rank_set_flag(&entry->rank, KR_RANK_INSECURE);
vctx->err_cnt += 1;
} else {
- entry->rank = KR_VLDRANK_UNKNOWN;
+ rank_set_value(&entry->rank, KR_RANK_BOGUS);
vctx->err_cnt += 1;
}
}
for (size_t i = 0; i < arr->len; ++i) {
ranked_rr_array_entry_t *entry = arr->at[i];
const knot_rrset_t *rr = entry->rr;
- if (entry->yielded || entry->rank != KR_VLDRANK_INITIAL) {
+ if (entry->yielded || rank_get_value(entry->rank) != KR_RANK_INITIAL) {
continue;
}
if (rr->type == KNOT_RRTYPE_RRSIG) {
if (entry->yielded || entry->qry_uid != qry->uid) {
continue;
}
- if (entry->rank == KR_VLDRANK_MISMATCH) {
+ if (rank_get_value(entry->rank) == KR_RANK_MISMATCH) {
invalid_entry = entry;
break;
- } else if (entry->rank == KR_VLDRANK_INSECURE &&
+ } else if (rank_test_flag(entry->rank, KR_RANK_INSECURE) &&
!invalid_entry) {
invalid_entry = entry;
- } else if (entry->rank != KR_VLDRANK_SECURE &&
+ } else if (!rank_test_flag(entry->rank, KR_RANK_SECURE) &&
!invalid_entry) {
invalid_entry = entry;
}
return ret;
}
- if ((invalid_entry->rank != KR_VLDRANK_SECURE) &&
+ if (!rank_test_flag(invalid_entry->rank, KR_RANK_SECURE) &&
(++(invalid_entry->revalidation_cnt) > MAX_REVALIDATION_CNT)) {
VERBOSE_MSG(qry, "<= continuous revalidation, fails\n");
qry->flags |= QUERY_DNSSEC_BOGUS;
}
const knot_rrset_t *rr = invalid_entry->rr;
- if (invalid_entry->rank == KR_VLDRANK_MISMATCH) {
+ if (rank_get_value(invalid_entry->rank) == KR_RANK_MISMATCH) {
const knot_dname_t *signer_name = knot_rrsig_signer_name(&rr->rrs, 0);
if (knot_dname_is_sub(signer_name, qry->zone_cut.name)) {
qry->zone_cut.name = knot_dname_copy(signer_name, &req->pool);
}
VERBOSE_MSG(qry, ">< cut changed (new signer), needs revalidation\n");
ret = KR_STATE_YIELD;
- } else if (invalid_entry->rank == KR_VLDRANK_INSECURE) {
+ } else if (rank_test_flag(invalid_entry->rank, KR_RANK_INSECURE)) {
ret = rrsig_not_found(ctx, rr);
- } else if (invalid_entry->rank != KR_VLDRANK_SECURE) {
+ } else if (!rank_test_flag(invalid_entry->rank, KR_RANK_SECURE)) {
qry->flags |= QUERY_DNSSEC_BOGUS;
ret = KR_STATE_FAIL;
}