Commit c9100436 authored by Lubos Slovak's avatar Lubos Slovak

RRSet wire: Moved RRSet parsing from pkt to rrset.

Also refactored a bit.
TODO: Remove the use of parse_rdata() function in utilities, so
      that it may become static.
parent ddeb82bf
......@@ -607,54 +607,6 @@ int knot_pkt_parse_question(knot_pkt_t *pkt)
return KNOT_EOK;
}
/*! \note Legacy code, mainly for transfers and updates.
* RRSets should use packet memory context for allocation and
* should be copied if they are supposed to be stored in zone permanently.
*/
static int knot_pkt_rr_from_wire(const uint8_t *wire, size_t *pos,
size_t size, mm_ctx_t *mm, knot_rrset_t *rrset)
{
dbg_packet("%s(%p, %zu, %zu)\n", __func__, wire, *pos, size);
assert(wire);
assert(pos);
knot_dname_t *owner = knot_dname_parse(wire, pos, size, mm);
if (owner == NULL) {
return KNOT_EMALF;
}
knot_dname_to_lower(owner);
if (size - *pos < KNOT_RR_HEADER_SIZE) {
dbg_packet("%s: not enough data to parse RR HEADER\n", __func__);
knot_dname_free(&owner, mm);
return KNOT_EMALF;
}
uint16_t type = knot_wire_read_u16(wire + *pos);
uint16_t rclass = knot_wire_read_u16(wire + *pos + sizeof(uint16_t));
uint32_t ttl = knot_wire_read_u32(wire + *pos + 2 * sizeof(uint16_t));
uint16_t rdlength = knot_wire_read_u16(wire + *pos + 4 * sizeof(uint16_t));
*pos += KNOT_RR_HEADER_SIZE;
if (size - *pos < rdlength) {
dbg_packet("%s: not enough data to parse RDATA\n", __func__);
knot_dname_free(&owner, mm);
return KNOT_EMALF;
}
knot_rrset_init(rrset, owner, type, rclass);
int ret = knot_rrset_rdata_from_wire_one(rrset, wire, pos, size, ttl,
rdlength, mm);
if (ret != KNOT_EOK) {
dbg_packet("%s: failed to parse RDATA (%d)\n", __func__, ret);
knot_rrset_clear(rrset, mm);
return ret;
}
return KNOT_EOK;
}
/* \note Private for check_rr_constraints(). */
#define CHECK_AR_CONSTRAINTS(pkt, rr, var, check_func) \
if ((pkt)->current != KNOT_ADDITIONAL) { \
......@@ -719,8 +671,8 @@ int knot_pkt_parse_rr(knot_pkt_t *pkt, unsigned flags)
/* Parse wire format. */
size_t rr_size = pkt->parsed;
knot_rrset_t *rr = &pkt->rr[pkt->rrset_count];
ret = knot_pkt_rr_from_wire(pkt->wire, &pkt->parsed, pkt->max_size,
&pkt->mm, rr);
ret = knot_rrset_rr_from_wire(pkt->wire, &pkt->parsed, pkt->max_size,
&pkt->mm, rr);
if (ret != KNOT_EOK) {
dbg_packet("%s: failed to parse RR\n", __func__);
return ret;
......
......@@ -290,7 +290,6 @@ static int decompress_dname(const uint8_t **src, size_t *src_avail,
assert(src_avail);
assert(dst && *dst);
assert(dst_avail);
UNUSED(compr);
UNUSED(compr_hint);
......@@ -577,17 +576,15 @@ static bool allow_zero_rdata(const knot_rrset_t *rr, const rdata_descriptor_t *d
desc->type_name == NULL; // Unknown RR types can have 0 RDLENGTH
}
int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset,
const uint8_t *wire, size_t *pos,
size_t total_size, uint32_t ttl,
size_t rdlength,
mm_ctx_t *mm)
int knot_rrset_parse_rdata(const uint8_t *pkt_wire, size_t *pos, size_t pkt_size,
mm_ctx_t *mm, uint32_t ttl, uint16_t rdlength,
knot_rrset_t *rrset)
{
if (rrset == NULL || wire == NULL || pos == NULL) {
return KNOT_EINVAL;
}
assert(pkt_wire);
assert(pos);
assert(rrset);
if (total_size - *pos < rdlength) {
if (pkt_size - *pos < rdlength) {
return KNOT_EMALF;
}
......@@ -610,12 +607,12 @@ int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset,
uint8_t rdata_buffer[dst_avail];
memset(rdata_buffer, 0, dst_avail);
const uint8_t *src = wire + *pos;
const uint8_t *src = pkt_wire + *pos;
size_t src_avail = rdlength;
uint8_t *dst = rdata_buffer;
int ret = traverse_rdata(desc, &src, &src_avail, &dst, &dst_avail,
NULL, 0, KNOT_RRSET_WIRE_NONE, wire,
NULL, 0, KNOT_RRSET_WIRE_NONE, pkt_wire,
decompress_dname);
if (ret != KNOT_EOK) {
return ret;
......@@ -630,6 +627,65 @@ int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset,
return knot_rrset_add_rdata(rrset, rdata_buffer, dst_size, ttl, mm);
}
static int parse_header(const uint8_t *pkt_wire, size_t *pos,
size_t pkt_size, mm_ctx_t *mm, knot_rrset_t *rrset,
uint32_t *ttl, uint16_t *rdlen)
{
assert(pkt_wire);
assert(pos);
assert(rrset);
assert(ttl);
assert(rdlen);
knot_dname_t *owner = knot_dname_parse(pkt_wire, pos, pkt_size, mm);
if (owner == NULL) {
return KNOT_EMALF;
}
knot_dname_to_lower(owner);
if (pkt_size - *pos < KNOT_RR_HEADER_SIZE) {
knot_dname_free(&owner, mm);
return KNOT_EMALF;
}
uint16_t type = knot_wire_read_u16(pkt_wire + *pos);
uint16_t rclass = knot_wire_read_u16(pkt_wire + *pos + sizeof(uint16_t));
*ttl = knot_wire_read_u32(pkt_wire + *pos + 2 * sizeof(uint16_t));
*rdlen = knot_wire_read_u16(pkt_wire + *pos + 4 * sizeof(uint16_t));
*pos += KNOT_RR_HEADER_SIZE;
if (pkt_size - *pos < *rdlen) {
knot_dname_free(&owner, mm);
return KNOT_EMALF;
}
knot_rrset_init(rrset, owner, type, rclass);
return KNOT_EOK;
}
int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos,
size_t pkt_size, mm_ctx_t *mm, knot_rrset_t *rrset)
{
if (pkt_wire == NULL || pos == NULL || rrset == NULL) {
return KNOT_EINVAL;
}
uint32_t ttl = 0;
uint16_t rdlen = 0;
int ret = parse_header(pkt_wire, pos, pkt_size, mm, rrset, &ttl, &rdlen);
if (ret == KNOT_EOK) {
ret = knot_rrset_parse_rdata(pkt_wire, pos, pkt_size, mm, ttl, rdlen,
rrset);
if (ret != KNOT_EOK) {
knot_rrset_clear(rrset, mm);
}
}
return ret;
}
int knot_rrset_add_rdata(knot_rrset_t *rrset,
const uint8_t *rdata, const uint16_t size,
const uint32_t ttl, mm_ctx_t *mm)
......
......@@ -152,23 +152,23 @@ typedef enum knot_rrset_wire_flags knot_rrset_wire_flags_t;
int knot_rrset_to_wire(const knot_rrset_t *rrset, uint8_t *wire, uint16_t max_size,
struct knot_compr *compr, knot_rrset_wire_flags_t flags);
/*!
* \brief Creates one RR from wire, stores it into 'rrset'
*
* \param rrset Destination RRSet.
* \param wire Source wire.
* \param pos Position in wire.
* \param total_size Size of wire.
* \param ttl Use this TTL to create RR.
* \param rdlength RDLENGTH.
* \param mm Memory context.
*
* \return KNOT_E*
*/
int knot_rrset_rdata_from_wire_one(knot_rrset_t *rrset,
const uint8_t *wire, size_t *pos,
size_t total_size, uint32_t ttl, size_t rdlength,
mm_ctx_t *mm);
int knot_rrset_parse_rdata(const uint8_t *pkt_wire, size_t *pos, size_t pkt_size,
mm_ctx_t *mm, uint32_t ttl, uint16_t rdlength,
knot_rrset_t *rrset);
/*!
* \brief Creates one RR from wire, stores it into \a rrset.
*
* \param pkt_wire Source wire (the whole packet).
* \param pos Position in \a wire where to start parsing.
* \param pkt_size Total size of data in \a wire (size of the packet).
* \param mm Memory context.
* \param rrset Destination RRSet.
*
* \return KNOT_E*
*/
int knot_rrset_rr_from_wire(const uint8_t *pkt_wire, size_t *pos,
size_t pkt_size, mm_ctx_t *mm, knot_rrset_t *rrset);
/* ---------- RR addition. (legacy, functionality in knot_rdataset_t) ------- */
......
......@@ -350,11 +350,10 @@ static knot_pkt_t* create_query_packet(const query_t *query)
return NULL;
}
/* TODO [rrset]: replace */
// Fill in blank SOA rdata to rrset.
ret = knot_rrset_rdata_from_wire_one(soa, wire, &pos,
sizeof(wire),
0, sizeof(wire),
&packet->mm);
ret = knot_rrset_parse_rdata(wire, &pos, sizeof(wire),
&packet->mm, 0, sizeof(wire), soa);
if (ret != KNOT_EOK) {
knot_rrset_free(&soa, &packet->mm);
knot_pkt_free(&packet);
......
......@@ -343,11 +343,9 @@ static int rr_list_append(zs_scanner_t *s, list_t *target_list, mm_ctx_t *mm)
/* Create RDATA. */
size_t pos = 0;
int ret = knot_rrset_rdata_from_wire_one(rr, s->r_data, &pos,
s->r_data_length,
s->r_ttl,
s->r_data_length,
NULL);
/* TODO [rrset]: replace */
int ret = knot_rrset_parse_rdata(s->r_data, &pos, s->r_data_length,
NULL, s->r_ttl, s->r_data_length, rr);
if (ret != KNOT_EOK) {
DBG("%s: failed to set rrset from wire - %s\n",
__func__, knot_strerror(ret));
......
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