From: Marek Vavruša Date: Tue, 17 Nov 2015 22:20:46 +0000 (+0100) Subject: modules: avoid ffi.new in hotpath X-Git-Tag: v1.0.0-beta2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=671bf0f5b321d326597d5ee080e1ec682344a5ce;p=thirdparty%2Fknot-resolver.git 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 --- diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index e91223b7a..82a9aca66 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -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, } diff --git a/modules/dns64/dns64.lua b/modules/dns64/dns64.lua index c089d4830..22b4ba2f6 100644 --- a/modules/dns64/dns64.lua +++ b/modules/dns64/dns64.lua @@ -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 diff --git a/modules/renumber/renumber.lua b/modules/renumber/renumber.lua index 1cf8c5df5..88c60bc01 100644 --- a/modules/renumber/renumber.lua +++ b/modules/renumber/renumber.lua @@ -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