Commit b1692fac authored by Jan Kadlec's avatar Jan Kadlec

node-refactor: Moved rr-related functions into new file.

- new types: knot_rr_t and knot_rrs_t
- these can be used in the node structure instead of knot_rrset_t
parent 0a74d5a0
......@@ -285,3 +285,5 @@ tests/slab.c
tests/wire.c
tests/zonedb.c
tests/ztree.c
src/libknot/rr.c
src/libknot/rr.h
......@@ -170,6 +170,8 @@ libknot_la_SOURCES = \
libknot/rdata.h \
libknot/rrset-dump.c \
libknot/rrset-dump.h \
libknot/rr.c \
libknot/rr.h \
libknot/rrset.c \
libknot/rrset.h \
libknot/tsig-op.c \
......
......@@ -282,7 +282,7 @@ int xfrin_process_axfr_packet(knot_pkt_t *pkt, knot_ns_xfr_t *xfr, knot_zone_con
} else {
ret = zcreator_step(&zc, rr);
if (ret != KNOT_EOK) {
knot_rrset_free(&rr, NULL);
// 'rr' is either inserted, or free'd
return ret;
}
ret = xfrin_take_rr(answer, &rr, &rr_id);
......
......@@ -94,6 +94,7 @@ int zcreator_step(zcreator_t *zc, knot_rrset_t *rr)
if (ret < 0) {
if (!handle_err(zc, rr, ret)) {
// Fatal error
knot_rrset_free(&rr, NULL);
return ret;
}
// Recoverable error, skip record
......
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "libknot/rr.h"
#include "libknot/common.h"
#include "common/errcode.h"
static const size_t RR_META_SIZE = sizeof(uint16_t) + sizeof(uint32_t);
uint16_t knot_rr_size(const knot_rr_t *rr)
{
return *((uint16_t *)rr);
}
uint32_t knot_rr_ttl(const knot_rr_t *rr)
{
return *((uint32_t *)(rr + sizeof(uint16_t)));
}
const uint8_t *knot_rr_rdata(const knot_rr_t *rr)
{
return (const uint8_t *)(rr + RR_META_SIZE);
}
uint8_t *knot_rr_get_rdata(knot_rr_t *rr)
{
return rr + RR_META_SIZE;
}
void knot_rr_set_size(knot_rr_t *rr, uint16_t size)
{
*((uint16_t *)rr) = size;
}
void knot_rr_set_ttl(knot_rr_t *rr, uint32_t ttl)
{
*((uint32_t *)(rr + sizeof(uint16_t))) = ttl;
}
static knot_rr_t *rr_seek(knot_rr_t *d, size_t pos)
{
if (d == NULL) {
return NULL;
}
size_t offset = 0;
for (size_t i = 0; i < pos; i++) {
knot_rr_t *rr = d + offset;
offset += knot_rr_size(rr) + RR_META_SIZE;
}
return d + offset;
}
knot_rr_t *knot_rrs_get_rr(const knot_rrs_t *rrs, size_t pos)
{
if (rrs == NULL || pos >= rrs->rr_count) {
return NULL;
}
return rr_seek(rrs->data, pos);
}
const knot_rr_t *knot_rrs_rr(const knot_rrs_t *rrs, size_t pos)
{
if (rrs == NULL || pos >= rrs->rr_count) {
return NULL;
}
return (const knot_rr_t *)rr_seek(rrs->data, pos);
}
size_t knot_rrs_size(const knot_rrs_t *rrs)
{
if (rrs == NULL) {
return 0;
}
size_t total_size = 0;
for (size_t i = 0; i < rrs->rr_count; ++i) {
const knot_rr_t *rr = knot_rrs_rr(rrs, i);
assert(rr);
total_size += knot_rr_size(rr) + RR_META_SIZE;
}
return total_size;
}
int knot_rrs_remove_rr_at_pos(knot_rrs_t *rrs, size_t pos, mm_ctx_t *mm)
{
if (rrs == NULL || pos >= rrs->rr_count) {
return KNOT_EINVAL;
}
knot_rr_t *old_rr = knot_rrs_get_rr(rrs, pos);
knot_rr_t *last_rr = knot_rrs_get_rr(rrs, rrs->rr_count - 1);
assert(old_rr);
assert(last_rr);
size_t total_size = knot_rrs_size(rrs);
uint16_t old_size = knot_rr_size(old_rr);
void *old_threshold = old_rr + old_size + RR_META_SIZE;
void *last_threshold = last_rr + knot_rr_size(last_rr) + RR_META_SIZE;
// Move RDATA
memmove(old_rr, old_threshold,
last_threshold - old_threshold);
if (rrs->rr_count > 1) {
// Realloc RDATA
void *tmp = mm_realloc(mm, rrs->data,
total_size - (old_size + RR_META_SIZE),
total_size);
if (tmp == NULL) {
ERR_ALLOC_FAILED;
} else {
rrs->data = tmp;
}
} else {
// Free RDATA
mm_free(mm, rrs->data);
rrs->data = NULL;
}
rrs->rr_count--;
return KNOT_EOK;
}
uint8_t* knot_rrs_create_rr_at_pos(knot_rrs_t *rrs,
size_t pos, uint16_t size,
uint32_t ttl, mm_ctx_t *mm)
{
if (rrs == NULL || pos > rrs->rr_count) {
return NULL;
}
if (pos == rrs->rr_count) {
// Normal RDATA addition
return knot_rrs_create_rr(rrs, size, ttl, mm);
}
size_t total_size = knot_rrs_size(rrs);
// Realloc data.
void *tmp = mm_realloc(mm, rrs->data,
total_size + size + RR_META_SIZE,
total_size);
if (tmp) {
rrs->data = tmp;
} else {
ERR_ALLOC_FAILED;
return NULL;
}
knot_rr_t *old_rr = knot_rrs_get_rr(rrs, pos);
knot_rr_t *last_rr = knot_rrs_get_rr(rrs, rrs->rr_count - 1);
assert(old_rr);
assert(last_rr);
// Make space for new data by moving the array
memmove(old_rr + size + RR_META_SIZE, old_rr,
(last_rr + RR_META_SIZE + knot_rr_size(last_rr)) - old_rr);
// Set size for new RR
knot_rr_set_size(old_rr, size);
knot_rr_set_ttl(old_rr, ttl);
rrs->rr_count++;
assert(knot_rr_size(old_rr) > 0);
return knot_rr_get_rdata(old_rr);
}
uint8_t* knot_rrs_create_rr(knot_rrs_t *rrs, const uint16_t size,
const uint32_t ttl, mm_ctx_t *mm)
{
if (rrs == NULL) {
return NULL;
}
size_t total_size = knot_rrs_size(rrs);
/* Realloc RRs. */
void *tmp = mm_realloc(mm, rrs->data, total_size + size + RR_META_SIZE,
total_size);
if (tmp) {
rrs->data = tmp;
} else {
ERR_ALLOC_FAILED;
return NULL;
}
rrs->rr_count++;
knot_rr_t *rr = knot_rrs_get_rr(rrs, rrs->rr_count - 1);
assert(rr);
knot_rr_set_size(rr, size);
knot_rr_set_ttl(rr, ttl);
return knot_rr_get_rdata(rr);
}
void knot_rrs_init(knot_rrs_t *rrs)
{
if (rrs) {
rrs->rr_count = 0;
rrs->data = NULL;
}
}
void knot_rrs_free(knot_rrs_t *rrs, mm_ctx_t *mm)
{
if (rrs) {
mm_free(mm, rrs->data);
mm_free(mm, rrs);
}
}
void knot_rrs_clear(knot_rrs_t *rrs, mm_ctx_t *mm)
{
if (rrs) {
mm_free(mm, rrs->data);
rrs->rr_count = 0;
}
}
#pragma once
#include <stdlib.h>
#include <stdint.h>
#include "common/mempattern.h"
typedef uint8_t knot_rr_t;
typedef struct knot_rrs {
uint16_t rr_count;
knot_rr_t *data;
} knot_rrs_t;
uint16_t knot_rr_size(const knot_rr_t *rr);
uint32_t knot_rr_ttl(const knot_rr_t *rr);
const uint8_t *knot_rr_rdata(const knot_rr_t *rr);
uint8_t *knot_rr_get_rdata(knot_rr_t *rr);
void knot_rr_set_size(knot_rr_t *rr, uint16_t size);
void knot_rr_set_ttl(knot_rr_t *rr, uint32_t ttl);
void knot_rrs_init(knot_rrs_t *rrs);
size_t knot_rrs_size(const knot_rrs_t *rrs);
knot_rr_t *knot_rrs_get_rr(const knot_rrs_t *rrs, size_t pos);
const knot_rr_t *knot_rrs_rr(const knot_rrs_t *rrs, size_t pos);
uint8_t* knot_rrs_create_rr(knot_rrs_t *rrs, const uint16_t size,
const uint32_t ttl, mm_ctx_t *mm);
uint8_t* knot_rrs_create_rr_at_pos(knot_rrs_t *rrs,
size_t pos, uint16_t size,
uint32_t ttl, mm_ctx_t *mm);
int knot_rrs_remove_rr_at_pos(knot_rrs_t *rrs, size_t pos, mm_ctx_t *mm);
void knot_rrs_free(knot_rrs_t *rrs, mm_ctx_t *mm);
void knot_rrs_clear(knot_rrs_t *rrs, mm_ctx_t *mm);
This diff is collapsed.
......@@ -34,6 +34,7 @@
#include "common/mempattern.h"
#include "libknot/dname.h"
#include "libknot/rr.h"
struct knot_compr;
struct knot_node;
......@@ -48,13 +49,7 @@ struct knot_rrset {
knot_dname_t *owner; /*!< Domain name being the owner of the RRSet. */
uint16_t type; /*!< TYPE of the RRset. */
uint16_t rclass; /*!< CLASS of the RRSet. */
uint16_t rr_count; /*!< Count of RRs in RRSet */
/*! \brief RDATA array (for all RRs). DNAMEs stored as full,
* uncompressed wire. Binary data stored in wireformat order.
* Each RR is prepended with RDATA length and TTL, respectively.
* Do not work directly with this value.
*/
uint8_t *rrs;
knot_rrs_t rrs; /*!< RRSet's RRs */
/* Optional fields. */
struct knot_node **additional; /*!< Additional records. */
};
......
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