From: Konstantin Amelichev Date: Sat, 28 May 2022 11:30:32 +0000 (+0400) Subject: renumber: allow renumbering a subnet to a single IP X-Git-Tag: v5.5.1~9^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f96a1ad4b63e9e5ee2e473282ca3fdba75f950a6;p=thirdparty%2Fknot-resolver.git renumber: allow renumbering a subnet to a single IP https://github.com/CZ-NIC/knot-resolver/pull/77 originally but changed by vcunat quite a bit. --- diff --git a/modules/renumber/renumber.lua b/modules/renumber/renumber.lua index 4272fbd1f..caa47779c 100644 --- a/modules/renumber/renumber.lua +++ b/modules/renumber/renumber.lua @@ -3,25 +3,41 @@ local ffi = require('ffi') local prefixes_global = {} +-- get address from config: either subnet prefix or fixed endpoint +local function extract_address(target) + local idx = string.find(target, "!", 1, true) + if idx == nil then + return target, false + end + if idx ~= #target then + error("[renumber] \"!\" symbol in target is only accepted at the end of address") + end + return string.sub(target, 1, idx - 1), true +end + -- Create subnet prefix rule local function matchprefix(subnet, addr) + local is_exact + addr, is_exact = extract_address(addr) local target = kres.str2ip(addr) if target == nil then error('[renumber] invalid address: '..addr) end local addrtype = string.find(addr, ':', 1, true) and kres.type.AAAA or kres.type.A local subnet_cd = ffi.new('char[16]') local bitlen = ffi.C.kr_straddr_subnet(subnet_cd, subnet) if bitlen < 0 then error('[renumber] invalid subnet: '..subnet) end - return {subnet_cd, bitlen, target, addrtype} + return {subnet_cd, bitlen, target, addrtype, is_exact} end -- Create name match rule local function matchname(name, addr) + local is_exact + addr, is_exact = extract_address(addr) -- though matchname() always leads to replacing whole address local target = kres.str2ip(addr) if target == nil then error('[renumber] invalid address: '..addr) end local owner = todname(name) if not name then error('[renumber] invalid name: '..name) end local addrtype = string.find(addr, ':', 1, true) and kres.type.AAAA or kres.type.A - return {owner, nil, target, addrtype} + return {owner, nil, target, addrtype, is_exact} end -- Add subnet prefix rewrite rule @@ -50,7 +66,12 @@ local function renumber_record(tbl, rr) -- If provided, compare record owner to prefix name if match_subnet(prefix[1], prefix[2], prefix[4], rr) then -- Replace part or whole address - local to_copy = prefix[2] or (#prefix[3] * 8) + local to_copy + if prefix[2] and not prefix[5] then + to_copy = prefix[2] + else + to_copy = #prefix[3] * 8 + end local chunks = to_copy / 8 local rdlen = #rr.rdata if rdlen < chunks then return rr end -- Address length mismatch