Commit 0d1f54a7 authored by Daniel Salzman's avatar Daniel Salzman

libknot: add no canonicalization flag to packet parsing

parent 0c752a76
......@@ -771,7 +771,7 @@ int knot_pkt_parse_rr(knot_pkt_t *pkt, unsigned flags)
size_t rr_size = pkt->parsed;
knot_rrset_t *rr = &pkt->rr[pkt->rrset_count];
ret = knot_rrset_rr_from_wire(pkt->wire, &pkt->parsed, pkt->size,
&pkt->mm, rr);
&pkt->mm, rr, !(flags & KNOT_PF_NOCANON));
if (ret != KNOT_EOK) {
return ret;
}
......
......@@ -70,7 +70,8 @@ enum {
KNOT_PF_FREE = 1 << 1, /*!< Free with packet. */
KNOT_PF_NOTRUNC = 1 << 2, /*!< Don't truncate. */
KNOT_PF_CHECKDUP = 1 << 3, /*!< Check for duplicates. */
KNOT_PF_KEEPWIRE = 1 << 4 /*!< Keep wireformat untouched when parsing. */
KNOT_PF_KEEPWIRE = 1 << 4, /*!< Keep wireformat untouched when parsing. */
KNOT_PF_NOCANON = 1 << 5, /*!< Don't canonicalize rrsets during parsing. */
};
/*!
......
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -690,9 +690,8 @@ static int parse_rdata(const uint8_t *pkt_wire, size_t *pos, size_t pkt_size,
}
_public_
int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos,
size_t pkt_size, knot_mm_t *mm,
knot_rrset_t *rrset)
int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos, size_t pkt_size,
knot_mm_t *mm, knot_rrset_t *rrset, bool canonical)
{
if (!pkt_wire || !pos || !rrset || *pos > pkt_size) {
return KNOT_EINVAL;
......@@ -712,10 +711,11 @@ int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos,
}
/* Convert RR to canonical format. */
ret = knot_rrset_rr_to_canonical(rrset);
if (ret != KNOT_EOK) {
knot_rrset_clear(rrset, mm);
if (canonical) {
ret = knot_rrset_rr_to_canonical(rrset);
if (ret != KNOT_EOK) {
knot_rrset_clear(rrset, mm);
}
}
return KNOT_EOK;
......
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -14,10 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file rrset.h
*
* \author Lubos Slovak <lubos.slovak@nic.cz>
* \author Jan Vcelak <jan.vcelak@nic.cz>
* \file
*
* \brief RRSet from/to wire conversion functions.
*
......@@ -57,10 +54,11 @@ int knot_rrset_to_wire(const knot_rrset_t *rrset, uint8_t *wire, uint16_t max_si
* \param pkt_size Total size of data in \a wire (size of the packet).
* \param mm Memory context.
* \param rrset Destination RRSet.
* \param canonical Convert rrset to canonical format indication.
*
* \return KNOT_E*
*/
int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos,
size_t pkt_size, knot_mm_t *mm, knot_rrset_t *rrset);
int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos, size_t pkt_size,
knot_mm_t *mm, knot_rrset_t *rrset, bool canonical);
/*! @} */
/* Copyright (C) 2014 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -192,23 +192,73 @@ static const struct wire_data FROM_CASES[FROM_CASE_COUNT] = {
#define TEST_CASE_FROM(rrset, i) size_t _pos##i = FROM_CASES[i].pos; \
ok(knot_rrset_rr_from_wire(FROM_CASES[i].wire, &_pos##i, FROM_CASES[i].size, \
NULL, rrset) == FROM_CASES[i].code, "rrset wire: %s", FROM_CASES[i].msg)
NULL, rrset, true) == FROM_CASES[i].code, "rrset wire: %s", FROM_CASES[i].msg)
int main(int argc, char *argv[])
static void test_inputs(void)
{
plan(1 + FROM_CASE_COUNT);
// Test NULL params.
int ret = knot_rrset_rr_from_wire(NULL, NULL, 0, NULL, NULL);
ok(ret == KNOT_EINVAL, "rr wire: Invalid params");
// Test defined cases
for (size_t i = 0; i < FROM_CASE_COUNT; ++i) {
knot_rrset_t rrset;
knot_rrset_init_empty(&rrset);
TEST_CASE_FROM(&rrset, i);
knot_rrset_clear(&rrset, NULL);
}
}
static void check_canon(uint8_t *wire, size_t size, size_t pos, bool canon,
knot_dname_t *qname, knot_dname_t *dname)
{
knot_rrset_t rrset;
knot_rrset_init_empty(&rrset);
int ret = knot_rrset_rr_from_wire(wire, &pos, size, NULL, &rrset, canon);
ok(ret == KNOT_EOK, "OK %s canonization", canon ? "with" : "without");
ok(memcmp(rrset.owner, qname, knot_dname_size(qname)) == 0, "compare owner");
uint8_t *rdata = knot_rdata_data(knot_rdataset_at(&rrset.rrs, 0));
ok(memcmp(rdata, dname, knot_dname_size(dname)) == 0, "compare rdata dname");
knot_rrset_clear(&rrset, NULL);
}
static void test_canonization(void)
{
#define UPP_QNAME_SIZE 5
#define UPP_QNAME 0x01, 0x41, 0x01, 0x5a, 0x00 // A.Z.
#define LOW_QNAME 0x01, 0x61, 0x01, 0x7a, 0x00 // a.z.
#define UPP_DNAME_SIZE 3
#define UPP_DNAME 0x01, 0x58, 0x00 // X.
#define LOW_DNAME 0x01, 0x78, 0x00 // x.
uint8_t wire[] = {
MESSAGE_HEADER(1, 0, 0), QUERY(UPP_QNAME, KNOT_RRTYPE_NS),
RR_HEADER(UPP_QNAME, KNOT_RRTYPE_NS, 0x00, UPP_DNAME_SIZE), UPP_DNAME
};
size_t size = QUERY_SIZE + RR_HEADER_SIZE + UPP_QNAME_SIZE * 2 + UPP_DNAME_SIZE;
size_t pos = QUERY_SIZE + UPP_QNAME_SIZE;
knot_dname_t upp_qname[] = { UPP_QNAME };
knot_dname_t upp_dname[] = { UPP_DNAME };
check_canon(wire, size, pos, false, upp_qname, upp_dname);
knot_dname_t low_qname[] = { LOW_QNAME };
knot_dname_t low_dname[] = { LOW_DNAME };
check_canon(wire, size, pos, true, low_qname, low_dname);
}
int main(int argc, char *argv[])
{
plan_lazy();
diag("Test NULL parameters");
int ret = knot_rrset_rr_from_wire(NULL, NULL, 0, NULL, NULL, true);
ok(ret == KNOT_EINVAL, "rr wire: Invalid params");
diag("Test various inputs");
test_inputs();
diag("Test canonization");
test_canonization();
return EXIT_SUCCESS;
}
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