From 81c045a2a712f44d3c4d57561d6fd972122f6797 Mon Sep 17 00:00:00 2001 From: Jan Kadlec <jan.kadlec@nic.cz> Date: Mon, 7 Apr 2014 13:20:24 +0200 Subject: [PATCH] new_node: Moved some RRSet API functions to zones.c and internet.c. --- src/knot/nameserver/internet.c | 29 +++++- src/knot/server/zones.c | 155 +++++++++++++++++++++++++++- src/libknot/rrset.c | 181 --------------------------------- src/libknot/rrset.h | 52 ++-------- 4 files changed, 186 insertions(+), 231 deletions(-) diff --git a/src/knot/nameserver/internet.c b/src/knot/nameserver/internet.c index ebb36634a..f11b00329 100644 --- a/src/knot/nameserver/internet.c +++ b/src/knot/nameserver/internet.c @@ -39,6 +39,31 @@ static int wildcard_visit(struct query_data *qdata, const knot_node_t *node, con return KNOT_EOK; } +/*! \brief Moves data from 'src' to 'dst', owner and RRs are deep copied. */ +int move_rrset(knot_rrset_t *dst, const knot_rrset_t *src, mm_ctx_t *mm) +{ + if (dst == NULL || src == NULL) { + return KNOT_EINVAL; + } + + dst->type = src->type; + dst->additional = src->additional; + dst->rclass = src->rclass; + + dst->owner = knot_dname_copy(src->owner, mm); + if (dst->owner == NULL) { + return KNOT_ENOMEM; + } + knot_rrs_init(&dst->rrs); + int ret = knot_rrs_copy(&dst->rrs, &src->rrs, mm); + if (ret != KNOT_EOK) { + knot_dname_free(&dst->owner, mm); + return ret; + } + + return KNOT_EOK; +} + /*! \brief Synthetizes a CNAME RR from a DNAME. */ static int dname_cname_synth(const knot_rrset_t *dname_rr, const knot_dname_t *qname, @@ -230,7 +255,7 @@ static int put_authority_soa(knot_pkt_t *pkt, struct query_data *qdata, uint32_t min = knot_rrs_soa_minimum(&soa_rrset.rrs); if (min < knot_rrset_rr_ttl(&soa_rrset, 0)) { knot_rrset_t copy; - ret = knot_rrset_copy_int(©, &soa_rrset, &pkt->mm); + ret = move_rrset(©, &soa_rrset, &pkt->mm); if (ret != KNOT_EOK) { return ret; } @@ -675,7 +700,7 @@ int ns_put_rr(knot_pkt_t *pkt, knot_rrset_t *rr, if (compr_hint == COMPR_HINT_NONE && expand) { rr->owner = (knot_dname_t *)qdata->name; knot_rrset_t copy; - int ret = knot_rrset_copy_int(©, rr, &pkt->mm); + int ret = move_rrset(©, rr, &pkt->mm); if (ret != KNOT_EOK) { return ret; } diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 2cb7736d0..538ff715f 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -470,6 +470,9 @@ static inline uint64_t ixfrdb_key_make(uint32_t from, uint32_t to) /*----------------------------------------------------------------------------*/ +static int rrset_deserialize(const uint8_t *stream, size_t *stream_size, + knot_rrset_t **rrset); + int zones_changesets_from_binary(knot_changesets_t *chgsets) { /*! \todo #1291 Why doesn't this just increment stream ptr? */ @@ -1168,9 +1171,41 @@ int zones_save_zone(const knot_ns_xfr_t *xfr) } /*----------------------------------------------------------------------------*/ -/* Counting size of changeset in serialized form. */ +/* Changeset serialization and storing (new) */ /*----------------------------------------------------------------------------*/ +static size_t rr_binary_size(const knot_rrset_t *rrset, size_t rdata_pos) +{ + const knot_rr_t *rr = knot_rrs_rr(&rrset->rrs, rdata_pos); + if (rr) { + // RR size + TTL + return knot_rr_rdata_size(rr) + sizeof(uint32_t); + } else { + return 0; + } +} + +static uint64_t rrset_binary_size(const knot_rrset_t *rrset) +{ + if (rrset == NULL || knot_rrset_rr_count(rrset) == 0) { + return 0; + } + uint64_t size = sizeof(uint64_t) + // size at the beginning + knot_dname_size(rrset->owner) + // owner data + sizeof(uint16_t) + // type + sizeof(uint16_t) + // class + sizeof(uint16_t); //RR count + uint16_t rdata_count = knot_rrset_rr_count(rrset); + for (uint16_t i = 0; i < rdata_count; i++) { + /* Space to store length of one RR. */ + size += sizeof(uint32_t); + /* Actual data. */ + size += rr_binary_size(rrset, i); + } + + return size; +} + int zones_changeset_binary_size(const knot_changeset_t *chgset, size_t *size) { if (chgset == NULL || size == NULL) { @@ -1201,9 +1236,121 @@ int zones_changeset_binary_size(const knot_changeset_t *chgset, size_t *size) return KNOT_EOK; } -/*----------------------------------------------------------------------------*/ -/* Changeset serialization and storing (new) */ -/*----------------------------------------------------------------------------*/ +static void serialize_rr(const knot_rrset_t *rrset, size_t rdata_pos, + uint8_t *stream) +{ + const knot_rr_t *rr = knot_rrs_rr(&rrset->rrs, rdata_pos); + assert(rr); + uint32_t ttl = knot_rr_ttl(rr); + memcpy(stream, &ttl, sizeof(uint32_t)); + memcpy(stream + sizeof(uint32_t), knot_rr_rdata(rr), knot_rr_rdata_size(rr)); +} + +static int deserialize_rr(knot_rrset_t *rrset, + const uint8_t *stream, uint32_t rdata_size) +{ + uint32_t ttl; + memcpy(&ttl, stream, sizeof(uint32_t)); + return knot_rrset_add_rr(rrset, stream + sizeof(uint32_t), + rdata_size - sizeof(uint32_t), ttl, NULL); +} + +static int rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, + size_t *size) +{ + if (rrset == NULL || rrset->rrs.data == NULL) { + return KNOT_EINVAL; + } + + uint64_t rrset_length = rrset_binary_size(rrset); + memcpy(stream, &rrset_length, sizeof(uint64_t)); + + size_t offset = sizeof(uint64_t); + /* Save RR count. */ + const uint16_t rr_count = knot_rrset_rr_count(rrset); + memcpy(stream + offset, &rr_count, sizeof(uint16_t)); + offset += sizeof(uint16_t); + /* Save owner. */ + offset += knot_dname_to_wire(stream + offset, rrset->owner, rrset_length - offset); + + /* Save static data. */ + memcpy(stream + offset, &rrset->type, sizeof(uint16_t)); + offset += sizeof(uint16_t); + memcpy(stream + offset, &rrset->rclass, sizeof(uint16_t)); + offset += sizeof(uint16_t); + + /* Copy RDATA. */ + for (uint16_t i = 0; i < rr_count; i++) { + uint32_t knot_rr_size = rr_binary_size(rrset, i); + memcpy(stream + offset, &knot_rr_size, sizeof(uint32_t)); + offset += sizeof(uint32_t); + serialize_rr(rrset, i, stream + offset); + offset += knot_rr_size; + } + + *size = offset; + assert(*size == rrset_length); + return KNOT_EOK; +} + +static int rrset_deserialize(const uint8_t *stream, size_t *stream_size, + knot_rrset_t **rrset) +{ + if (sizeof(uint64_t) > *stream_size) { + return KNOT_ESPACE; + } + uint64_t rrset_length = 0; + memcpy(&rrset_length, stream, sizeof(uint64_t)); + if (rrset_length > *stream_size) { + return KNOT_ESPACE; + } + + size_t offset = sizeof(uint64_t); + uint16_t rdata_count = 0; + memcpy(&rdata_count, stream + offset, sizeof(uint16_t)); + offset += sizeof(uint16_t); + /* Read owner from the stream. */ + unsigned owner_size = knot_dname_size(stream + offset); + knot_dname_t *owner = knot_dname_copy_part(stream + offset, owner_size, NULL); + assert(owner); + offset += owner_size; + /* Read type. */ + uint16_t type = 0; + memcpy(&type, stream + offset, sizeof(uint16_t)); + offset += sizeof(uint16_t); + /* Read class. */ + uint16_t rclass = 0; + memcpy(&rclass, stream + offset, sizeof(uint16_t)); + offset += sizeof(uint16_t); + + /* Create new RRSet. */ + *rrset = knot_rrset_new(owner, type, rclass, NULL); + if (*rrset == NULL) { + knot_dname_free(&owner, NULL); + return KNOT_ENOMEM; + } + + /* Read RRs. */ + for (uint16_t i = 0; i < rdata_count; i++) { + /* + * There's always size of rdata in the beginning. + * Needed because of remainders. + */ + uint32_t rdata_size = 0; + memcpy(&rdata_size, stream + offset, sizeof(uint32_t)); + offset += sizeof(uint32_t); + int ret = deserialize_rr((*rrset), stream + offset, rdata_size); + if (ret != KNOT_EOK) { + knot_rrset_free(rrset, NULL); + return ret; + } + offset += rdata_size; + } + + *stream_size = *stream_size - offset; + + return KNOT_EOK; +} static int zones_rrset_write_to_mem(const knot_rrset_t *rr, char **entry, size_t *remaining) { diff --git a/src/libknot/rrset.c b/src/libknot/rrset.c index 15b002d34..f616fb371 100644 --- a/src/libknot/rrset.c +++ b/src/libknot/rrset.c @@ -380,37 +380,6 @@ static int knot_rrset_rdata_store_binary(uint8_t *rdata, size_t *offset, return KNOT_EOK; } -static size_t rrset_binary_size_one(const knot_rrset_t *rrset, - size_t rdata_pos) -{ - const knot_rr_t *rr = knot_rrs_rr(&rrset->rrs, rdata_pos); - if (rr) { - // RR size + TTL - return knot_rr_rdata_size(rr) + sizeof(uint32_t); - } else { - return 0; - } -} - -static void rrset_serialize_rr(const knot_rrset_t *rrset, size_t rdata_pos, - uint8_t *stream) -{ - const knot_rr_t *rr = knot_rrs_rr(&rrset->rrs, rdata_pos); - assert(rr); - uint32_t ttl = knot_rr_ttl(rr); - memcpy(stream, &ttl, sizeof(uint32_t)); - memcpy(stream + sizeof(uint32_t), knot_rr_rdata(rr), knot_rr_rdata_size(rr)); -} - -static int rrset_deserialize_rr(knot_rrset_t *rrset, - const uint8_t *stream, uint32_t rdata_size) -{ - uint32_t ttl; - memcpy(&ttl, stream, sizeof(uint32_t)); - return knot_rrset_add_rr(rrset, stream + sizeof(uint32_t), - rdata_size - sizeof(uint32_t), ttl, NULL); -} - void knot_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner, uint16_t type, uint16_t rclass) { @@ -776,132 +745,6 @@ bool knot_rrset_is_nsec3rel(const knot_rrset_t *rr) == KNOT_RRTYPE_NSEC3)); } -uint64_t rrset_binary_size(const knot_rrset_t *rrset) -{ - if (rrset == NULL || knot_rrset_rr_count(rrset) == 0) { - return 0; - } - uint64_t size = sizeof(uint64_t) + // size at the beginning - knot_dname_size(rrset->owner) + // owner data - sizeof(uint16_t) + // type - sizeof(uint16_t) + // class - sizeof(uint16_t); //RR count - uint16_t rdata_count = knot_rrset_rr_count(rrset); - for (uint16_t i = 0; i < rdata_count; i++) { - /* Space to store length of one RR. */ - size += sizeof(uint32_t); - /* Actual data. */ - size += rrset_binary_size_one(rrset, i); - } - - return size; -} - -int rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, size_t *size) -{ - if (rrset == NULL || rrset->rrs.data == NULL) { - return KNOT_EINVAL; - } - - uint64_t rrset_length = rrset_binary_size(rrset); - dbg_rrset_detail("rr: serialize: Binary size=%"PRIu64"\n", rrset_length); - memcpy(stream, &rrset_length, sizeof(uint64_t)); - - size_t offset = sizeof(uint64_t); - /* Save RR count. */ - const uint16_t rr_count = knot_rrset_rr_count(rrset); - memcpy(stream + offset, &rr_count, sizeof(uint16_t)); - offset += sizeof(uint16_t); - /* Save owner. */ - offset += knot_dname_to_wire(stream + offset, rrset->owner, rrset_length - offset); - - /* Save static data. */ - memcpy(stream + offset, &rrset->type, sizeof(uint16_t)); - offset += sizeof(uint16_t); - memcpy(stream + offset, &rrset->rclass, sizeof(uint16_t)); - offset += sizeof(uint16_t); - - /* Copy RDATA. */ - for (uint16_t i = 0; i < rr_count; i++) { - uint32_t knot_rr_size = rrset_binary_size_one(rrset, i); - dbg_rrset_detail("rr: serialize: RR index=%d size=%d\n", - i, knot_rr_size); - memcpy(stream + offset, &knot_rr_size, sizeof(uint32_t)); - offset += sizeof(uint32_t); - rrset_serialize_rr(rrset, i, stream + offset); - offset += knot_rr_size; - } - - *size = offset; - assert(*size == rrset_length); - dbg_rrset_detail("rr: serialize: RRSet serialized, size=%zu\n", *size); - return KNOT_EOK; -} - -int rrset_deserialize(const uint8_t *stream, size_t *stream_size, - knot_rrset_t **rrset) -{ - if (sizeof(uint64_t) > *stream_size) { - dbg_rrset("rr: deserialize: No space for length.\n"); - return KNOT_ESPACE; - } - uint64_t rrset_length = 0; - memcpy(&rrset_length, stream, sizeof(uint64_t)); - if (rrset_length > *stream_size) { - dbg_rrset("rr: deserialize: No space for whole RRSet. " - "(given=%zu needed=%"PRIu64")\n", *stream_size, - rrset_length); - return KNOT_ESPACE; - } - - size_t offset = sizeof(uint64_t); - uint16_t rdata_count = 0; - memcpy(&rdata_count, stream + offset, sizeof(uint16_t)); - offset += sizeof(uint16_t); - /* Read owner from the stream. */ - unsigned owner_size = knot_dname_size(stream + offset); - knot_dname_t *owner = knot_dname_copy_part(stream + offset, owner_size, NULL); - assert(owner); - offset += owner_size; - /* Read type. */ - uint16_t type = 0; - memcpy(&type, stream + offset, sizeof(uint16_t)); - offset += sizeof(uint16_t); - /* Read class. */ - uint16_t rclass = 0; - memcpy(&rclass, stream + offset, sizeof(uint16_t)); - offset += sizeof(uint16_t); - - /* Create new RRSet. */ - *rrset = knot_rrset_new(owner, type, rclass, NULL); - if (*rrset == NULL) { - knot_dname_free(&owner, NULL); - return KNOT_ENOMEM; - } - - /* Read RRs. */ - for (uint16_t i = 0; i < rdata_count; i++) { - /* - * There's always size of rdata in the beginning. - * Needed because of remainders. - */ - uint32_t rdata_size = 0; - memcpy(&rdata_size, stream + offset, sizeof(uint32_t)); - offset += sizeof(uint32_t); - int ret = rrset_deserialize_rr((*rrset), stream + offset, - rdata_size); - if (ret != KNOT_EOK) { - knot_rrset_free(rrset, NULL); - return ret; - } - offset += rdata_size; - } - - *stream_size = *stream_size - offset; - - return KNOT_EOK; -} - int knot_rrset_find_rr_pos(const knot_rrset_t *rr_search_in, const knot_rrset_t *rr_reference, size_t pos, size_t *pos_out) @@ -1085,30 +928,6 @@ bool knot_rrset_empty(const knot_rrset_t *rrset) return rr_count == 0; } -int knot_rrset_copy_int(knot_rrset_t *dst, const knot_rrset_t *src, mm_ctx_t *mm) -{ - if (dst == NULL || src == NULL) { - return KNOT_EINVAL; - } - - dst->type = src->type; - dst->additional = src->additional; - dst->rclass = src->rclass; - - dst->owner = knot_dname_copy(src->owner, mm); - if (dst->owner == NULL) { - return KNOT_ENOMEM; - } - knot_rrs_init(&dst->rrs); - int ret = knot_rrs_copy(&dst->rrs, &src->rrs, mm); - if (ret != KNOT_EOK) { - knot_dname_free(&dst->owner, mm); - return ret; - } - - return KNOT_EOK; -} - knot_rrset_t *knot_rrset_copy(const knot_rrset_t *src, mm_ctx_t *mm) { if (src == NULL) { diff --git a/src/libknot/rrset.h b/src/libknot/rrset.h index 40dbc9285..3de4130ee 100644 --- a/src/libknot/rrset.h +++ b/src/libknot/rrset.h @@ -82,7 +82,6 @@ knot_rrset_t *knot_rrset_new(knot_dname_t *owner, uint16_t type, void knot_rrset_init(knot_rrset_t *rrset, knot_dname_t *owner, uint16_t type, uint16_t rclass); -void knot_rrset_clear(knot_rrset_t *rrset, mm_ctx_t *mm); /*! * \brief Creates a new RRSet according to given template RRSet. @@ -183,6 +182,14 @@ bool knot_rrset_equal(const knot_rrset_t *r1, */ void knot_rrset_free(knot_rrset_t **rrset, mm_ctx_t *mm); +/*! + * \brief Frees structures inside RRSet, but not the RRSet itself. + * + * \param rrset RRSet to be cleared. + * \param mm Memory context used for allocations. + */ +void knot_rrset_clear(knot_rrset_t *rrset, mm_ctx_t *mm); + /*! * \brief Converts RRSet structure to wireformat, compression included. * @@ -216,38 +223,6 @@ int knot_rrset_merge(knot_rrset_t *rrset1, const knot_rrset_t *rrset2, mm_ctx_t */ bool knot_rrset_is_nsec3rel(const knot_rrset_t *rr); -/*! - * \brief Returns binary size of RRSet. - * - * \param rrset RRSet. - * - * \return Binary size. - */ -uint64_t rrset_binary_size(const knot_rrset_t *rrset); - -/*! - * \brief Serializes RRSet into given stream. - * - * \param rrset RRSet to be serialized. - * \param stream Output stream - * \param size Size written. - * - * \return KNOT_E* - */ -int rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, size_t *size); - -/*! - * \brief Deserializes RRSet structure. - * - * \param stream Input stream. - * \param stream_size Input stream size. - * \param rrset Output RRSet. - * - * \return KNOT_E* - */ -int rrset_deserialize(const uint8_t *stream, size_t *stream_size, - knot_rrset_t **rrset); - /*! * \brief Adds RR on 'pos' position from 'source' to 'dest'. * @@ -345,17 +320,6 @@ int knot_rrset_synth_rrsig(const knot_dname_t *owner, uint16_t type, */ bool knot_rrset_empty(const knot_rrset_t *rrset); -/*! - * \brief Deep copies one RRSet into another. - * - * \param dst Destination RRSet. - * \param src Source RRSet. - * \param mm Memory context. - * - * \return KNOT_E* - */ -int knot_rrset_copy_int(knot_rrset_t *dst, const knot_rrset_t *src, mm_ctx_t *mm); - /*! * \brief Creates new RRSet from \a src RRSet. * -- GitLab