File: fallback.lua

package info (click to toggle)
knot-resolver 6.0.17-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,376 kB
  • sloc: javascript: 42,732; ansic: 40,311; python: 12,580; cpp: 2,121; sh: 1,988; xml: 193; makefile: 181
file content (60 lines) | stat: -rw-r--r-- 1,828 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
-- SPDX-License-Identifier: GPL-3.0-or-later
local M = {} -- the module

local ffi = require('ffi')

function M.config(cfg)
	if not cfg then return end

	-- Beware that the timeout is only considered at certain points in time;
	-- approximately at multiples of KR_CONN_RTT_MAX.
	M.timeout = cfg.timeout or 3*sec

	local targets_split = policy.forward_convert_targets(cfg.options, cfg.targets)

	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.data_src or state == kres.FAIL or state == kres.DONE then return state end

	local qry = req:current()
	if qry.flags.FALLBACK_DISABLE then return state end

	-- Don't do anything for priming, prefetching, etc.
	-- TODO: not all cases detected ATM.
	if qry.flags.NO_CACHE then return state end

	local now = ffi.C.kr_now()
	local deadline = qry.creation_time_mono + M.timeout
	if now > deadline or qry.flags.NO_NS_FOUND then
		log_qry(qry, ffi.C.LOG_GRP_SRVSTALE,
			'   => no reachable NS, activating fallback forwarding',
			kres.dname2str(qry:name()))

		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
		ffi.C.kr_make_query(qry, pkt)
	end

	return state
end

return M