- 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
_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;
/** 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);
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:
/* 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. */
}
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);
/* 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 };
}
/* 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;
}
/* 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) {
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);
}
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;
}
/* 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;
}
/* 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 */
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. */