]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
tweak handling of ANY and RRSIG in QTYPE docs-any-rrsig-ip2fgc/deployments/8513
authorVladimír Čunát <vladimir.cunat@nic.cz>
Sun, 1 Feb 2026 09:58:21 +0000 (10:58 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 3 Feb 2026 08:09:27 +0000 (09:09 +0100)
- advanced users can configure these QTYPEs on Lua level, e.g.
    option('QTYPE_ANY', true)
- fix handling these QTYPEs, e.g.
  - caching: as whole packet only (simple and "safer" here)
  - iterator wasn't finding ANY records in answer :-)
- I wanted to disable RRSIG by default, but let's delay that

daemon/lua/kres-gen-33.lua
lib/cache/api.c
lib/cache/impl.h
lib/layer/iterate.c
lib/resolve-produce.c
lib/resolve.c
lib/rplan.h

index 54f01bb67fa2ae8f6ab9d82bdde75df345514199..bba6888ab6d4905491e76cdc7ab892c553893360 100644 (file)
@@ -143,6 +143,8 @@ struct kr_qflags {
        _Bool DNS64_DISABLE : 1;
        _Bool PASSTHRU_LEGACY : 1;
        _Bool FALLBACK_DISABLE : 1;
+       _Bool QTYPE_ANY : 1;
+       _Bool QTYPE_RRSIG : 1;
 };
 typedef struct ranked_rr_array_entry {
        uint32_t qry_uid;
index 4e7eb3766da3dfeba634d7676361d714747beed4..d5f7f21d35fe3816579caf8d8ba868f0182398f8 100644 (file)
@@ -296,8 +296,7 @@ static bool check_dname_for_lf(const knot_dname_t *n, const struct kr_query *qry
 /** Return false on types to be ignored.  Meant both for sname and direct cache requests. */
 static bool check_rrtype(uint16_t type, const struct kr_query *qry/*logging*/)
 {
-       const bool ret = !knot_rrtype_is_metatype(type)
-                       && type != KNOT_RRTYPE_RRSIG;
+       const bool ret = !knot_rrtype_is_metatype(type) || type == KNOT_RRTYPE_ANY;
        if (!ret && kr_log_is_debug_qry(CACHE, qry)) {
                auto_free char *type_str = kr_rrtype_text(type);
                VERBOSE_MSG(qry, "=> skipping RR type %s\n", type_str);
@@ -311,9 +310,6 @@ knot_db_val_t key_exact_type_maypkt(struct key *k, uint16_t type)
        if (kr_fails_assert(check_rrtype(type, NULL)))
                return (knot_db_val_t){ NULL, 0 };
        switch (type) {
-       case KNOT_RRTYPE_RRSIG: /* no RRSIG query caching, at least for now */
-               kr_assert(false);
-               return (knot_db_val_t){ NULL, 0 };
        /* xNAME lumped into NS. */
        case KNOT_RRTYPE_CNAME:
        case KNOT_RRTYPE_DNAME:
@@ -360,7 +356,7 @@ int cache_peek(kr_layer_t *ctx, knot_pkt_t *pkt)
 
        /* We first check various exit-conditions and then call the _real function. */
        if (!kr_cache_is_open(&req->ctx->cache)
-           || !check_rrtype(qry->stype, qry) /* LATER: some other behavior for some of these? */
+           || !check_rrtype(qry->stype, qry)
            || qry->sclass != KNOT_CLASS_IN) {
                return ctx->state; /* Already resolved/failed or already tried, etc. */
        }
@@ -422,6 +418,14 @@ int cache_stash(kr_layer_t *ctx, knot_pkt_t *pkt)
                needs_pkt = true;
                goto stash_packet;
        }
+       if (qry->stype == KNOT_RRTYPE_ANY || qry->stype == KNOT_RRTYPE_RRSIG) {
+               /* In case of _ANY, useful records could be expected,
+                * but let's be careful and only stash the whole packet,
+                * as behavior of servers for _ANY is underspecified and tricky.
+                * The effect is basically caching _ANY separately from other types. */
+               needs_pkt = true;
+               goto stash_packet;
+       }
 
        /* Stash individual records. */
        ranked_rr_array_t *selected[] = kr_request_selected(req);
index bafaecf59416fa16e23dd0dc99eb4d2fa99761b0..6aff055fe8c60e91eda0353b144b78c3d6fd1350 100644 (file)
@@ -151,6 +151,8 @@ static inline knot_db_val_t key_exact_type(struct key *k, uint16_t type)
        /* Sanity check: forbidden types represented in other way(s). */
        case KNOT_RRTYPE_NSEC:
        case KNOT_RRTYPE_NSEC3:
+       case KNOT_RRTYPE_ANY:
+       case KNOT_RRTYPE_RRSIG:
                kr_assert(false);
                return (knot_db_val_t){ NULL, 0 };
        }
index 9a9a41a771c84f8f10ea037553e8b33b707212a3..d84d5ae4a524779fdc2e86ff866aae25ec576496 100644 (file)
@@ -421,7 +421,7 @@ static int process_authority(knot_pkt_t *pkt, struct kr_request *req)
                /* Work around for these NSs which are authoritative both for
                 * parent and child and mixes data from both zones in single answer */
                if (knot_wire_get_aa(pkt->wire) &&
-                   (rr->type == qry->stype) &&
+                   (rr->type == qry->stype || qry->stype == KNOT_RRTYPE_ANY) &&
                    (knot_dname_is_equal(rr->owner, qry->sname))) {
                        return KR_STATE_CONSUME;
                }
@@ -537,6 +537,7 @@ static int unroll_cname(knot_pkt_t *pkt, struct kr_request *req, bool referral,
                        /* Skip the RR if its owner+type doesn't interest us. */
                        const uint16_t type = kr_rrset_type_maysig(rr);
                        const bool type_OK = rr->type == query->stype || type == query->stype
+                                               || query->stype == KNOT_RRTYPE_ANY
                                                || type == KNOT_RRTYPE_CNAME;
                        if (rr->rclass != KNOT_CLASS_IN
                            || knot_dname_in_bailiwick(rr->owner, query->zone_cut.name) < 0) {
@@ -689,7 +690,7 @@ static int process_final(knot_pkt_t *pkt, struct kr_request *req,
                        continue;
                }
                if ((rr->rclass != query->sclass) ||
-                   (rr->type != query->stype)) {
+                   (rr->type != query->stype && query->stype != KNOT_RRTYPE_ANY)) {
                        continue;
                }
                const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0);
@@ -922,8 +923,20 @@ static int begin(kr_layer_t *ctx)
        }
 
        struct kr_query *qry = ctx->req->current_query;
-       /* Avoid any other classes, and avoid any meta-types. */
-       if (qry->sclass != KNOT_CLASS_IN || knot_rrtype_is_metatype(qry->stype)) {
+       /* Avoid any other classes, and avoid any meta-types (except if allowed). */
+       bool typeOK;
+       switch (qry->stype) {
+       case KNOT_RRTYPE_ANY:
+               typeOK = qry->flags.QTYPE_ANY;
+               break;
+       case KNOT_RRTYPE_RRSIG:
+               typeOK = qry->flags.QTYPE_RRSIG;
+               break;
+       default:
+               typeOK = !knot_rrtype_is_metatype(qry->stype);
+               break;
+       }
+       if (qry->sclass != KNOT_CLASS_IN || !typeOK) {
                knot_pkt_t *ans = kr_request_ensure_answer(ctx->req);
                if (!ans)
                        return ctx->req->state;
index a3a2401e41dd5487ee6cf79af55734c877dddd59..e165a56f7e0d5099e4f5fbff5a11b21b78e4c5b1 100644 (file)
@@ -666,10 +666,9 @@ int kr_resolve_produce(struct kr_request *request, struct kr_transport **transpo
        }
        /* At this point we need to send a query upstream to proceed towards success. */
 
-       /* This query has RD=0 or is ANY, stop here. */
-       if (qry->stype == KNOT_RRTYPE_ANY ||
-           !knot_wire_get_rd(request->qsource.packet->wire)) {
-               VERBOSE_MSG(qry, "=> qtype is ANY or RD=0, bail out\n");
+       /* This query has RD=0, stop here. */
+       if (!knot_wire_get_rd(request->qsource.packet->wire)) {
+               VERBOSE_MSG(qry, "=> RD=0, bail out\n");
                return KR_STATE_FAIL;
        }
 
index 7426e1ac96efe92a48dee340c9fe5b783fe66d5e..54ce0b509486e20bbc95e068e24ad48c00fe2a4c 100644 (file)
@@ -481,6 +481,7 @@ int kr_resolver_init(module_array_t *modules, knot_mm_t *pool)
 
        /* Default options (request flags). */
        the_resolver->options.REORDER_RR = true;
+       the_resolver->options.QTYPE_RRSIG = true;
        the_resolver->vld_limit_crypto = KR_VLD_LIMIT_CRYPTO_DEFAULT;
 
        /* Open resolution context */
index 779d6d250a280857df57d4373c82f2fa113bf880..3e11232022b1df97fd40301e346cd91157c19ce8 100644 (file)
@@ -60,6 +60,8 @@ struct kr_qflags {
        bool DNS64_DISABLE : 1;  /**< Don't do any DNS64 stuff (meant for view:addr). */
        bool PASSTHRU_LEGACY : 1;/**< Ignore local-data overrides/blocks for this kr_request. */
        bool FALLBACK_DISABLE : 1;/**< Don't attempt fallback.  Meant for views.  */
+       bool QTYPE_ANY : 1;      /**< Allow ANY as QTYPE. */
+       bool QTYPE_RRSIG : 1;    /**< Allow RRSIG as QTYPE. */
 };
 
 /** Combine flags together.  This means set union for simple flags. */