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);
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 *);
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
knot_pkt_qclass
knot_pkt_begin
knot_pkt_put_question
+ knot_pkt_put
knot_pkt_rr
knot_pkt_section
knot_pkt_new
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,
},
})
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)
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))
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')
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
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