summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVladimír Čunát <vladimir.cunat@nic.cz>2023-09-01 10:36:26 +0200
committerVladimír Čunát <vladimir.cunat@nic.cz>2023-10-05 09:09:53 +0200
commit15fcc1c953dfd093c76554b02941a32bd2ce7c71 (patch)
tree568571f6443255641b3961d628d0a23a6b83cfa9 /lib
parentlib/cache/cdb_*: add API for iteration with MDB_DUPSORT (diff)
downloadknot-resolver-15fcc1c953dfd093c76554b02941a32bd2ce7c71.tar.xz
knot-resolver-15fcc1c953dfd093c76554b02941a32bd2ce7c71.zip
WIP lib/rules: consider multiple tags variants when answering
Diffstat (limited to 'lib')
-rw-r--r--lib/rules/api.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/lib/rules/api.c b/lib/rules/api.c
index 238eeda7..a656eb7e 100644
--- a/lib/rules/api.c
+++ b/lib/rules/api.c
@@ -334,20 +334,20 @@ int rule_local_data_answer(struct kr_query *qry, knot_pkt_t *pkt)
for (int i = 0; i < 1 + want_CNAME; ++i) {
memcpy(key_data + KEY_DNAME_END_OFFSET + 2, &types[i], sizeof(rrtype));
knot_db_val_t val;
- // LATER: use cursor to iterate over multiple rules on the same key,
- // testing tags on each
- ret = ruledb_op(read, &key, &val, 1);
- switch (ret) {
- case -ENOENT: continue;
- case 0: break;
- default: return kr_error(ret);
- }
- if (!kr_rule_consume_tags(&val, qry->request)) continue;
+ // Multiple variants are possible, with different tags.
+ for (ret = ruledb_op(it_first, &key, &val);
+ ret == 0;
+ ret = ruledb_op(it_next, &val)) {
+ if (!kr_rule_consume_tags(&val, qry->request))
+ continue;
- // We found a rule that applies to the dname+rrtype+req.
- ret = answer_exact_match(qry, pkt, types[i],
- val.data, val.data + val.len);
- return ret ? kr_error(ret) : RET_ANSWERED;
+ // We found a rule that applies to the dname+rrtype+req.
+ ret = answer_exact_match(qry, pkt, types[i],
+ val.data, val.data + val.len);
+ return ret ? kr_error(ret) : RET_ANSWERED;
+ }
+ if (kr_fails_assert(ret == 0 || ret == -ENOENT))
+ return kr_error(ret);
}
/* Find the closest zone-like apex that applies.
@@ -714,15 +714,14 @@ static int answer_zla_redirect(struct kr_query *qry, knot_pkt_t *pkt, const char
knot_db_val_t key = local_data_key(&rrs, key_data, ruleset_name);
knot_db_val_t val;
- ret = ruledb_op(read, &key, &val, 1);
- switch (ret) {
- case -ENOENT: goto nodata;
- case 0: break;
- default: return ret;
+ // Multiple variants are possible, with different tags.
+ for (ret = ruledb_op(it_first, &key, &val); ret == 0; ret = ruledb_op(it_next, &val)) {
+ if (kr_rule_consume_tags(&val, qry->request))
+ return answer_exact_match(qry, pkt, qry->stype,
+ val.data, val.data + val.len);
}
- if (kr_rule_consume_tags(&val, qry->request)) // found a match
- return answer_exact_match(qry, pkt, qry->stype,
- val.data, val.data + val.len);
+ if (ret && ret != -ENOENT)
+ return ret;
nodata: // Want NODATA answer (or NOERROR if it hits apex SOA).
// Start constructing the (pseudo-)packet.
@@ -984,6 +983,8 @@ int kr_view_select_action(const struct kr_request *req, knot_db_val_t *selected)
}
}
// We certainly have a matching key (join of various sub-cases).
+ // LATER: we'd iterate on this key's entries and find one
+ // that matches additional conditions (optional ones in future)
if (kr_log_is_debug(RULES, NULL)) {
// it's complex to get zero-terminated string for the action
char act_0t[val.len + 1];