]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
kres: added interface for RR set wire size and packet remaining bytes
authorMarek Vavruša <marek@vavrusa.com>
Thu, 15 Mar 2018 23:13:47 +0000 (16:13 -0700)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 23 Apr 2018 12:34:41 +0000 (14:34 +0200)
daemon/lua/kres-gen.lua
daemon/lua/kres-gen.sh
daemon/lua/kres.lua
tests/config/basic.test.lua

index 7a8e59732ff906c1bde903beea1db2be658b1922..911e2e0905deec573f98e0c2608cee2c03cde6df 100644 (file)
@@ -252,6 +252,7 @@ void knot_rrset_init_empty(knot_rrset_t *);
 uint32_t knot_rrset_ttl(const knot_rrset_t *);
 int knot_rrset_txt_dump(const knot_rrset_t *, char **, size_t *, const knot_dump_style_t *);
 int knot_rrset_txt_dump_data(const knot_rrset_t *, const size_t, char *, const size_t, const knot_dump_style_t *);
+size_t knot_rrset_size(const knot_rrset_t *);
 uint16_t knot_rrsig_type_covered(const knot_rdataset_t *, size_t);
 uint32_t knot_rrsig_sig_expiration(const knot_rdataset_t *, size_t);
 uint32_t knot_rrsig_sig_inception(const knot_rdataset_t *, size_t);
@@ -260,6 +261,7 @@ uint16_t knot_pkt_qtype(const knot_pkt_t *);
 uint16_t knot_pkt_qclass(const knot_pkt_t *);
 int knot_pkt_begin(knot_pkt_t *, knot_section_t);
 int knot_pkt_put_question(knot_pkt_t *, const knot_dname_t *, uint16_t, uint16_t);
+int knot_pkt_put(knot_pkt_t *, uint16_t, const knot_rrset_t *, uint16_t);
 const knot_rrset_t *knot_pkt_rr(const knot_pktsection_t *, uint16_t);
 const knot_pktsection_t *knot_pkt_section(const knot_pkt_t *, knot_section_t);
 knot_pkt_t *knot_pkt_new(void *, uint16_t, knot_mm_t *);
index 9c7b5581881b517ec6100a92a7ac6ce2af048be0..fa2f1146118f2124f2c11b7e5e74f4f47a214696 100755 (executable)
@@ -111,6 +111,7 @@ printf "\tchar _stub[];\n};\n"
        knot_rrset_ttl
        knot_rrset_txt_dump
        knot_rrset_txt_dump_data
+       knot_rrset_size
        knot_rrsig_type_covered
        knot_rrsig_sig_expiration
        knot_rrsig_sig_inception
@@ -120,6 +121,7 @@ printf "\tchar _stub[];\n};\n"
        knot_pkt_qclass
        knot_pkt_begin
        knot_pkt_put_question
+       knot_pkt_put
        knot_pkt_rr
        knot_pkt_section
        knot_pkt_new
index b75f5c79a9bf50af8d15cdd2907be5d2cb9df40d..61cac2267aa5ce8d0dbe55b3a60c50cf57e80227 100644 (file)
@@ -379,6 +379,11 @@ ffi.metatype( knot_rrset_t, {
                        assert(rrsig.type == const_type.RRSIG)
                        return (rr.type == rrsig:type_covered() and rr:owner() == rrsig:owner())
                end,
+               -- Return RR set wire size
+               wire_size = function(rr)
+                       assert(ffi.istype(knot_rrset_t, rr))
+                       return tonumber(knot.knot_rrset_size(rr))
+               end,
        },
 })
 
@@ -560,6 +565,15 @@ ffi.metatype( knot_pkt_t, {
                        if ret ~= 0 then return nil, knot_error_t(ret) end
                        return true
                end,
+               -- Put an RR set in the packet
+               -- Note: the packet doesn't take ownership of the RR set
+               put_rr = function (pkt, rr)
+                       assert(ffi.istype(knot_pkt_t, pkt))
+                       assert(ffi.istype(knot_rrset_t, rr))
+                       local ret = C.knot_pkt_put(pkt, 0, rr, 0)
+                       if ret ~= 0 then return nil, knot_error_t(ret) end
+                       return true
+               end,
                recycle = function (pkt)
                        assert(ffi.istype(knot_pkt_t, pkt))
                        local ret = C.kr_pkt_recycle(pkt)
@@ -588,6 +602,14 @@ ffi.metatype( knot_pkt_t, {
                        assert(ffi.istype(knot_pkt_t, pkt))
                        return packet_tostring(pkt)
                end,
+               -- Return number of remaining empty bytes in the packet
+               -- This is generally useful to check if there's enough space
+               remaining_bytes = function (pkt)
+                       assert(ffi.istype(knot_pkt_t, pkt))
+                       local occupied = pkt.size + pkt.reserved
+                       assert(pkt.max_size >= occupied)
+                       return tonumber(pkt.max_size - occupied)
+               end,
                -- Packet manipulation
                parse = function (pkt)
                        assert(ffi.istype(knot_pkt_t, pkt))
index 55f133393c5beed67ef16bc8de22ec6c023c74c1..95c24bc567ae048cf1a455aa85c59f668bad96ba 100644 (file)
@@ -45,7 +45,9 @@ local function test_rrset_functions()
        same(rr:class(kres.class.IN), kres.class.IN, 'can restore a class')
        same(rr.type, kres.type.A, 'created RR has correct type')
        -- test adding rdata
+       same(rr:wire_size(), 0, 'empty RR wire size is zero')
        ok(rr:add_rdata('\1\2\3\4', 4, 66), 'adding RDATA works')
+       same(rr:wire_size(), 5 + 4 + 4 + 2 + 4, 'RR wire size works after adding RDATA')
        -- test conversion to text
        local expect = 'com.                    66      A       1.2.3.4\n'
        same(rr:txt_dump(), expect, 'RR to text works')
@@ -104,7 +106,9 @@ local function test_packet_functions()
        boom(pkt.begin, {pkt, 10}, 'switching to invalid section doesnt work')
        ok(pkt:begin(kres.section.ADDITIONAL), 'switching to different section works')
        boom(pkt.begin, {pkt, 0}, 'rewinding sections doesnt work')
+       local before_insert = pkt:remaining_bytes()
        ok(pkt:put(pkt:qname(), 900, pkt:qclass(), kres.type.A, '\4\3\2\1'), 'adding rrsets to different section works')
+       same(pkt:remaining_bytes(), before_insert - (2 + 4 + 4 + 2 + 4), 'remaining bytes count goes down with insertions')
        -- Test conversions to text
        like(pkt:tostring(), '->>HEADER<<-', 'packet to text works')
        -- Test deserialization
@@ -126,6 +130,15 @@ local function test_packet_functions()
        same(parsed:arcount(), pkt:arcount(), 'parsed packet has same additional count')
        same(parsed:tostring(), pkt:tostring(), 'parsed packet is equal to source packet')
 
+       -- Test adding RR sets directly
+       local copy = kres.packet(512)
+       copy:question(todname('hello'), kres.class.IN, kres.type.A)
+       copy:begin(kres.section.ANSWER)
+       local rr = kres.rrset(pkt:qname(), kres.type.A)
+       rr:add_rdata('\4\3\2\1', 4, 66)
+       ok(copy:put_rr(rr), 'adding RR sets directly works')
+       ok(copy:recycle())
+
        -- Test recycling of packets
        -- Clear_payload keeps header + question intact
        local cleared = kres.packet(#wire, wire) -- same as "parsed" above