:return: Toggle verbose logging.
+.. function:: mode('strict' | 'normal' | 'permissive')
+
+ :return: Change resolver strictness checking level.
+
+ By default, resolver runs in *normal* mode. There are possibly many small adjustments
+ hidden behind the mode settings, but the main idea is that in *permissive* mode, the resolver
+ tries to resolve a name with as few lookups as possible, while in *strict* mode it spends much
+ more effort resolving and checking referral path. However, if majority of the traffic is covered
+ by DNSSEC, some of the strict checking actions are counter-productive.
+
+ .. csv-table::
+ :header: "Action", "Modes"
+
+ "Use mandatory glue", "strict, normal, permissive"
+ "Use in-bailiwick glue", "normal, permissive"
+ "Use any glue records", "permissive"
+
.. function:: user(name, [group])
:param string name: user name
"user(name[, group])\n change process user (and group)\n"
"verbose(true|false)\n toggle verbose mode\n"
"option(opt[, new_val])\n get/set server option\n"
+ "mode(strict|normal|permissive)\n set resolver strictness level\n"
"resolve(name, type[, class, flags, callback])\n resolve query, callback when it's finished\n"
"todname(name)\n convert name to wire format\n"
"net\n network configuration\n"
static const int DNSSEC_INSECURE = 1 << 16;
static const int STUB = 1 << 17;
static const int ALWAYS_CUT = 1 << 18;
+ static const int PERMISSIVE = 1 << 20;
+ static const int STRICT = 1 << 21;
};
/*
todname = kres.str2dname
end
+-- Resolver mode of operation
+local current_mode = 'normal'
+local mode_table = { normal=0, strict=1, permissive=2 }
+function mode(m)
+ if not m then return current_mode end
+ if not mode_table[m] then error('unsupported mode: '..m) end
+ -- Update current operation mode
+ current_mode = m
+ option('STRICT', current_mode == 'strict')
+ option('PERMISSIVE', current_mode == 'permissive')
+ return true
+end
+
-- Function aliases
-- `env.VAR returns os.getenv(VAR)`
env = {}
return KNOT_STATE_DONE;
}
-static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, struct kr_query *qry)
+static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, struct kr_request *req)
{
+ bool used_glue = false;
for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
for (unsigned k = 0; k < sec->count; ++k) {
const knot_rrset_t *rr = knot_pkt_rr(sec, k);
if (knot_dname_is_equal(ns, rr->owner)) {
- (void) update_nsaddr(rr, qry);
+ (void) update_nsaddr(rr, req->current_query);
+ used_glue = true;
}
}
}
+ WITH_DEBUG {
+ char name_str[KNOT_DNAME_MAXLEN];
+ knot_dname_to_str(name_str, ns, sizeof(name_str));
+ if (used_glue) {
+ DEBUG_MSG("<= using glue for '%s'\n", name_str);
+ }
+ }
}
/** Attempt to find glue for given nameserver name (best effort). */
continue;
}
kr_zonecut_add(cut, ns_name, NULL);
- /* Use glue only in permissive mode or when in bailiwick. */
- if ((qry->flags & QUERY_PERMISSIVE) || knot_dname_in(current_cut, ns_name)) {
- fetch_glue(pkt, ns_name, qry);
+ /* Choose when to use glue records. */
+ if (qry->flags & QUERY_PERMISSIVE) {
+ fetch_glue(pkt, ns_name, req);
+ } else if (qry->flags & QUERY_STRICT) {
+ /* Strict mode uses only mandatory glue. */
+ if (knot_dname_in(cut->name, ns_name))
+ fetch_glue(pkt, ns_name, req);
+ } else {
+ /* Normal mode uses in-bailiwick glue. */
+ if (knot_dname_in(current_cut, ns_name))
+ fetch_glue(pkt, ns_name, req);
}
}
X(STUB, 1 << 17) /**< Stub resolution, accept received answer as solved. */ \
X(ALWAYS_CUT, 1 << 18) /**< Always recover zone cut (even if cached). */ \
X(DNSSEC_WEXPAND, 1 << 19) /**< Query response has wildcard expansion. */ \
- X(PERMISSIVE, 1 << 20) /**< Permissive referral path resolution. */
+ X(PERMISSIVE, 1 << 20) /**< Permissive resolver mode. */ \
+ X(STRICT, 1 << 21) /**< Strict resolver mode. */
/** Query flags */
enum kr_query_flag {