]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules: avoid ffi.new in hotpath
authorMarek Vavruša <marek.vavrusa@nic.cz>
Tue, 17 Nov 2015 22:20:46 +0000 (23:20 +0100)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Tue, 17 Nov 2015 22:20:46 +0000 (23:20 +0100)
this fixes a bug when a text-declared type wasn’t reused and LJ eventually segfaulted in ffi.new after a lot of redeclarations

daemon/lua/kres.lua
modules/dns64/dns64.lua
modules/renumber/renumber.lua

index e91223b7a19fced8f27351c4714263c66c53961b..82a9aca6618404b1b32376bfbbd9839a410a1913 100644 (file)
@@ -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,
 }
index c089d483092c98c9072a2197dc99b987d4acc040..22b4ba2f6416b528a403e93b1c0c60e35e4161d3 100644 (file)
@@ -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
index 1cf8c5df566a4c926fff3384f96fa60c12420944..88c60bc010a32b560de95c7e428140e3e00e53e3 100644 (file)
@@ -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