]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
fallback: module prototype docs-fallback-bwj41e/deployments/7334 fallback
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 28 Jul 2025 07:03:55 +0000 (09:03 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 4 Aug 2025 08:09:47 +0000 (10:09 +0200)
The module switches individual queries to a forwarding config
when failing to resolve the normal way (non-forwarding typically).
Internally the mechanism is close to the serve_stale module.

For now it has Lua config only, e.g.:

modules = { 'fallback' }
fallback.config({
targets = {
{'193.17.47.1', tls = false},
{'2001:148f:fffe::1', tls = false},
},
options = {
},
})

TODO: right now it's not yet possible to specify a list of source
addresses for which this mechanism won't be applied.

modules/fallback/fallback.lua

index 36e7e12f45f52bcf79243477ba3f61c5c129d2b5..804bf3fe22fae9c697f99987dd67391bf9cc7d34 100644 (file)
@@ -12,16 +12,25 @@ function M.config(cfg)
 
        local targets_split = policy.forward_convert_targets(cfg.options, cfg.targets)
 
-       M.targets_ptr = ffi.new('knot_db_val_t')
-       M.targets_ptr.len = #cfg.targets * ffi.C.KR_SOCKADDR_SIZE
-       M.targets_ptr_data = ffi.new('char [?]', #cfg.targets * ffi.C.KR_SOCKADDR_SIZE)
-       M.targets_ptr.data = M.targets_ptr_data -- TODO: explain
-       ffi.C.kr_rule_coalesce_targets(targets_split, M.targets_ptr.data)
+       M.data_src = ffi.new('struct kr_query_data_src')
+       M.data_src.initialized = true
+       M.data_src.all_set = false
+       M.data_src.rule_depth = 0
+       assert(cfg.options.auth or false == false)
+       M.data_src.flags.is_auth = false
+       M.data_src.flags.is_tcp = false
+       assert(cfg.options.dnssec or true == true)
+       M.data_src.flags.is_nods = false
+
+       M.data_src.targets_ptr.len = #cfg.targets * ffi.C.KR_SOCKADDR_SIZE
+       M.targets_ptr_data = ffi.new('char [?]', M.data_src.targets_ptr.len)
+       M.data_src.targets_ptr.data = M.targets_ptr_data -- TODO: explain
+       ffi.C.kr_rule_coalesce_targets(targets_split, M.targets_ptr_data)
 end
 
 M.layer = {}
 M.layer.produce = function (state, req, pkt)
-       if not M.targets_ptr or state == kres.FAIL or state == kres.DONE then return state end
+       if not M.data_src or state == kres.FAIL or state == kres.DONE then return state end
 
        local qry = req:current()
        -- Don't do anything for priming, prefetching, etc.
@@ -36,13 +45,7 @@ M.layer.produce = function (state, req, pkt)
                        '   => no reachable NS, activating fallback forwarding',
                        kres.dname2str(qry:name()))
                
-               qry.data_src.initialized = true
-               qry.data_src.all_set = false
-               qry.data_src.rule_depth = 0
-               qry.data_src.flags.is_auth = false
-               qry.data_src.flags.is_tcp = true   -- FIXME
-               qry.data_src.flags.is_nods = false
-               qry.data_src.targets_ptr = M.targets_ptr
+               qry.data_src = M.data_src
                qry.flags.FORWARD = true
                qry.flags.STUB = false
                if qry.data_src.flags.is_tcp then qry.flags.TCP = true end