Commit 671bf0f5 authored by Marek Vavruša's avatar Marek Vavruša

modules: avoid ffi.new in hotpath

this fixes a bug when a text-declared type wasn’t reused and LJ eventually segfaulted in ffi.new after a lot of redeclarations
parent e0e2d7ad
......@@ -274,6 +274,7 @@ int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen,
]]
-- Metatype for sockaddr
local addr_buf = ffi.new('char[16]')
local sockaddr_t = ffi.typeof('struct sockaddr')
ffi.metatype( sockaddr_t, {
__index = {
......@@ -429,11 +430,10 @@ local kres = {
dname2str = dname2str,
rr2str = rr2str,
str2ip = function (ip)
local buf = ffi.new('char [16]')
local family = C.kr_straddr_family(ip)
local ret = C.inet_pton(family, ip, buf)
local ret = C.inet_pton(family, ip, addr_buf)
if ret ~= 1 then return nil end
return ffi.string(buf, C.kr_family_len(family))
return ffi.string(addr_buf, C.kr_family_len(family))
end,
context = function () return ffi.cast('struct kr_context *', __engine) end,
}
......
......@@ -3,6 +3,7 @@ local ffi = require('ffi')
local bit = require('bit')
local mod = {}
local MARK_DNS64 = bit.lshift(1, 31)
local addr_buf = ffi.new('char[16]')
-- Config
function mod.config (confstr)
if confstr == nil then return end
......@@ -27,19 +28,17 @@ mod.layer = {
local rr = answer[i]
-- Synthesise AAAA from A
if rr.type == kres.type.A then
local rdata = ffi.new('char [16]')
ffi.copy(rdata, mod.proxy)
ffi.copy(rdata + 12, rr.rdata, 4)
req.answer:put(rr.owner, rr.ttl, rr.class, kres.type.AAAA, ffi.string(rdata, 16))
ffi.copy(addr_buf, mod.proxy)
ffi.copy(addr_buf + 12, rr.rdata, 4)
req.answer:put(rr.owner, rr.ttl, rr.class, kres.type.AAAA, ffi.string(addr_buf, 16))
end
end
return state
end
-- Observe AAAA NODATA responses
local is_nodata = (pkt:rcode() == kres.rcode.NOERROR) and (#answer == 0)
if pkt:qtype() == kres.type.AAAA and is_nodata and pkt:qname() == qry:name() and qry:final() then
local next = req:push(pkt:qname(), kres.type.A, kres.class.IN, 0, qry)
next.flags = bit.band(qry.flags, kres.query.DNSSEC_WANT) + kres.query.AWAIT_CUT + MARK_DNS64
else -- Observe AAAA NODATA responses
local is_nodata = (pkt:rcode() == kres.rcode.NOERROR) and (#answer == 0)
if pkt:qtype() == kres.type.AAAA and is_nodata and pkt:qname() == qry:name() and qry:final() then
local next = req:push(pkt:qname(), kres.type.A, kres.class.IN, 0, qry)
next.flags = bit.band(qry.flags, kres.query.DNSSEC_WANT) + kres.query.AWAIT_CUT + MARK_DNS64
end
end
return state
end
......
......@@ -18,6 +18,7 @@ local function match_subnet(family, subnet, bitlen, addr)
return (#addr >= bitlen / 8) and (ffi.C.kr_bitcmp(subnet, addr, bitlen) == 0)
end
-- Renumber address record
local addr_buf = ffi.new('char[16]')
local function renumber(tbl, rr)
for i = 1, #tbl do
local prefix = tbl[i]
......@@ -26,11 +27,11 @@ local function renumber(tbl, rr)
local chunks = to_copy / 8
local rdlen = #rr.rdata
if rdlen < chunks then return rr end -- Address length mismatch
local rd = ffi.new('char [?]', rdlen, rr.rdata)
ffi.copy(rd, prefix[4], chunks)
ffi.copy(addr_buf, rr.rdata, rdlen)
ffi.copy(addr_buf, prefix[4], chunks)
-- @todo: CIDR not supported
to_copy = to_copy - chunks * 8
rr.rdata = ffi.string(rd, rdlen)
rr.rdata = ffi.string(addr_buf, rdlen)
return rr
end
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment