Commit fac2b82e authored by Jan Včelák's avatar Jan Včelák 🚀

Merge branch 'rrset-from-wire' into 'master'

RRSet from wire refactoring

Refactored conversion functions for parsing RRSet from wire according to older code and moved from/to wire functions to `packet/`. Also unified a bit with the 'to wire' functions (common RDATA-traversing function).

Also takes into account issue #289.

Fixes #228.

See merge request !275
parents 98038e8e 6ea7ab7f
......@@ -229,6 +229,8 @@ src/libknot/packet/compr.c
src/libknot/packet/compr.h
src/libknot/packet/pkt.c
src/libknot/packet/pkt.h
src/libknot/packet/rrset-wire.c
src/libknot/packet/rrset-wire.h
src/libknot/packet/wire.h
src/libknot/processing/process.c
src/libknot/processing/process.h
......
......@@ -171,6 +171,8 @@ libknot_la_SOURCES = \
libknot/packet/compr.h \
libknot/packet/pkt.c \
libknot/packet/pkt.h \
libknot/packet/rrset-wire.c \
libknot/packet/rrset-wire.h \
libknot/packet/wire.h \
libknot/processing/process.c \
libknot/processing/process.h \
......
......@@ -37,11 +37,6 @@
#define KNOT_DNAME_MAXLEN 255 /*!< 1-byte maximum. */
#define KNOT_DNAME_MAXLABELS 127 /*!< 1-char labels. */
/*!
* \brief Often used sizes.
*/
#define KNOT_RR_HEADER_SIZE 10
/*!
* \brief Address family numbers.
*
......
......@@ -29,6 +29,7 @@
#include <stdio.h> // size_t
#define KNOT_MAX_RDATA_BLOCKS 8
#define KNOT_MAX_RDATA_DNAMES 2 // update this when defining new RR types
/*!
* \brief Resource record class codes.
......
......@@ -166,32 +166,16 @@ knot_dname_t *knot_dname_copy_part(const knot_dname_t *name, unsigned len,
int knot_dname_to_wire(uint8_t *dst, const knot_dname_t *src, size_t maxlen)
{
if (dst == NULL || src == NULL)
if (dst == NULL || src == NULL) {
return KNOT_EINVAL;
/* Write out non or partially compressed name. */
int len = 0;
while (*src != '\0' && !knot_wire_is_pointer(src)) {
uint8_t lblen = *src + 1;
if (len + lblen > maxlen)
return KNOT_ESPACE;
memcpy(dst + len, src, lblen);
len += lblen;
src += lblen;
}
/* Terminated either FQDN \x00, or as a pointer. */
if (*src == '\0') {
if (len + 1> maxlen)
return KNOT_ESPACE;
*(dst + len) = '\0';
len += 1; /* \x00 */
} else {
if (len + 2 > maxlen)
return KNOT_ESPACE;
memcpy(dst + len, src, sizeof(uint16_t));
len += 2; /* ptr */
int len = knot_dname_size(src);
if (len > maxlen) {
return KNOT_ESPACE;
}
memcpy(dst, src, len);
return len;
}
......
......@@ -28,6 +28,7 @@
#include "libknot/packet/wire.h"
#include "libknot/rrset.h"
#include "libknot/rrtype/rrsig.h"
#include "libknot/packet/rrset-wire.h"
#define RRSIG_RDATA_SIGNER_OFFSET 18
......
......@@ -22,6 +22,7 @@
#include "libknot/dnssec/sig0.h"
#include "libknot/dnssec/sign.h"
#include "libknot/packet/wire.h"
#include "libknot/packet/rrset-wire.h"
/*!
* \brief Lifetime fudge of the SIG(0) packets in seconds.
......
......@@ -27,6 +27,7 @@
#include "libknot/packet/wire.h"
#include "libknot/rrtype/tsig.h"
#include "libknot/tsig-op.h"
#include "libknot/packet/rrset-wire.h"
/*! \brief Scan packet for RRSet existence. */
static bool pkt_contains(const knot_pkt_t *packet,
......@@ -607,54 +608,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 +672,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;
......
/*!
* \file pkt.h
*
* \author Lubos Slovak <lubos.slovak@nic.cz>
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
* \brief Structure for holding DNS packet data and metadata.
*
......
This diff is collapsed.
/* Copyright (C) 2014 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
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>
*
* \brief RRSet from/to wire conversion functions.
*
* \addtogroup libknot
* @{
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "libknot/mempattern.h"
#include "libknot/dname.h"
#include "libknot/rrset.h"
struct knot_compr;
/*!
* \brief Flags controlling RR set from/to wire conversion.
*/
enum knot_rrset_wire_flags {
KNOT_RRSET_WIRE_NONE = 0,
KNOT_RRSET_WIRE_CANONICAL = 1 << 0,
};
typedef enum knot_rrset_wire_flags knot_rrset_wire_flags_t;
/*!
* \brief Write RR Set content to a wire.
*
* Function accepts \ref KNOT_RRSET_WIRE_CANONICAL flag, which causes the
* output to be written in canonical representation.
*
* \param rrset RRSet to be converted.
* \param wire Output wire buffer.
* \param max_size Capacity of wire buffer.
* \param compr Compression context.
* \param flags Flags controlling the output.
*
* \return Output size, negative number on error (KNOT_E*).
*/
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 \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);
This diff is collapsed.
......@@ -34,8 +34,6 @@
#include "libknot/dname.h"
#include "libknot/rdataset.h"
struct knot_compr;
/*!
* \brief Structure for representing RRSet.
*
......@@ -123,53 +121,6 @@ void knot_rrset_free(knot_rrset_t **rrset, mm_ctx_t *mm);
*/
void knot_rrset_clear(knot_rrset_t *rrset, mm_ctx_t *mm);
/* ---------- Wire conversions (legacy, to be done in knot_pkt_t) ----------- */
/*!
* \brief Flags controlling RR set from/to wire conversion.
*/
enum knot_rrset_wire_flags {
KNOT_RRSET_WIRE_NONE = 0,
KNOT_RRSET_WIRE_CANONICAL = 1 << 0,
};
typedef enum knot_rrset_wire_flags knot_rrset_wire_flags_t;
/*!
* \brief Write RR Set content to a wire.
*
* Function accepts \ref KNOT_RRSET_WIRE_CANONICAL flag, which causes the
* output to be written in canonical representation.
*
* \param rrset RRSet to be converted.
* \param wire Output wire buffer.
* \param max_size Capacity of wire buffer.
* \param compr Compression context.
* \param flags Flags controlling the output.
*
* \return Output size, negative number on error (KNOT_E*).
*/
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);
/* ---------- RR addition. (legacy, functionality in knot_rdataset_t) ------- */
/*!
......
......@@ -31,6 +31,7 @@
#include "libknot/packet/wire.h"
#include "libknot/consts.h"
#include "libknot/dnssec/key.h"
#include "libknot/packet/rrset-wire.h"
const int KNOT_TSIG_MAX_DIGEST_SIZE = 64; // size of HMAC-SHA512 digest
const uint16_t KNOT_TSIG_FUDGE_DEFAULT = 300; // default Fudge value
......
......@@ -337,7 +337,6 @@ static knot_pkt_t* create_query_packet(const query_t *query)
if (query->type_num == KNOT_RRTYPE_IXFR) {
// SOA rdata in wireformat.
uint8_t wire[22] = { 0x0 };
size_t pos = 0;
// Create rrset with SOA record.
knot_rrset_t *soa = knot_rrset_new(qname,
......@@ -351,10 +350,8 @@ static knot_pkt_t* create_query_packet(const query_t *query)
}
// 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_add_rdata(soa, wire, sizeof(wire), 0,
&packet->mm);
if (ret != KNOT_EOK) {
knot_rrset_free(&soa, &packet->mm);
knot_pkt_free(&packet);
......
......@@ -342,12 +342,8 @@ 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);
int ret = knot_rrset_add_rdata(rr, s->r_data, s->r_data_length,
s->r_ttl, NULL);
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