#include "contrib/openbsd/siphash.h"
#include "contrib/string.h"
#include "contrib/wire_ctx.h"
-#include "libdnssec/binary.h"
#include "knot/common/log.h"
#include "knot/conf/conf.h"
#define CATALOG_VERSION "1.0"
#define CATALOG_ZONE_VERSION "2" // must be just one char long
-#define CATALOG_ZONES_LABEL "zones"
+#define CATALOG_ZONES_LABEL "\x05""zones"
#define CATALOG_SOA_REFRESH 3600
#define CATALOG_SOA_RETRY 600
#define CATALOG_SOA_EXPIRE (INT32_MAX - 1)
}
size_t hexlen = strlen(hexhash);
assert(hexlen == 16);
- size_t zoneslen = strlen(CATALOG_ZONES_LABEL);
+ size_t zoneslen = knot_dname_size((uint8_t *)CATALOG_ZONES_LABEL);
assert(hexlen <= KNOT_DNAME_MAXLABELLEN && zoneslen <= KNOT_DNAME_MAXLABELLEN);
size_t catzlen = knot_dname_size(catzone);
- size_t outlen = 1 + hexlen + 1 + zoneslen + catzlen;
+ size_t outlen = hexlen + zoneslen + catzlen;
knot_dname_t *out;
if (outlen > KNOT_DNAME_MAXLEN || (out = malloc(outlen)) == NULL) {
free(hexhash);
wire_ctx_t wire = wire_ctx_init(out, outlen);
wire_ctx_write_u8(&wire, hexlen);
wire_ctx_write(&wire, hexhash, hexlen);
- wire_ctx_write_u8(&wire, zoneslen);
wire_ctx_write(&wire, CATALOG_ZONES_LABEL, zoneslen);
+ wire_ctx_skip(&wire, -1);
wire_ctx_write(&wire, catzone, catzlen);
assert(wire.error == KNOT_EOK);
return ret;
}
+static size_t dname_append(knot_dname_storage_t storage, const knot_dname_t *name)
+{
+ size_t old_len = knot_dname_size(storage);
+ size_t name_len = knot_dname_size(name);
+ size_t new_len = old_len - 1 + name_len;
+ if (old_len == 0 || name_len == 0 || new_len > KNOT_DNAME_MAXLEN) {
+ return 0;
+ }
+ memcpy(storage + old_len - 1, name, name_len);
+ return new_len;
+}
+
int catalog_update_from_zone(catalog_update_t *u, struct zone_contents *zone,
bool remove, bool check_ver, catalog_t *check)
{
return KNOT_EZONEINVAL;
}
- size_t zone_size = knot_dname_size(zone->apex->owner);
- knot_dname_t sub[zone_size + 6];
- memcpy(sub, "\x05""zones", 6);
- memcpy(sub + 6, zone->apex->owner, zone_size);
+ knot_dname_storage_t sub;
+ if (knot_dname_store(sub, (uint8_t *)CATALOG_ZONES_LABEL) == 0 ||
+ dname_append(sub, zone->apex->owner ) == 0) {
+ return KNOT_EINVAL;
+ }
if (zone_contents_find_node(zone, sub) == NULL) {
return KNOT_EOK;
return c;
}
- // temporary storage to avoid allocations
- uint8_t tmp[512];
- knot_rdata_t *rdata = (knot_rdata_t *)tmp;
- knot_dname_t *tmpname = tmp + 256;
- wire_ctx_t wire;
zone_node_t *unused = NULL;
- knot_rrset_t rrset = { 0 };
- char invalid[9] = "\x07""invalid";
- char version[8] = "\x07""version";
- uint8_t version2[2] = "\x01" CATALOG_ZONE_VERSION;
+ uint8_t invalid[9] = "\x07""invalid";
+ uint8_t version[9] = "\x07""version";
+ uint8_t cat_version[2] = "\x01" CATALOG_ZONE_VERSION;
+
+ // prepare common rrset with one rdata item
+ uint8_t rdata[256] = { 0 };
+ knot_rrset_t rrset;
+ knot_rrset_init(&rrset, (knot_dname_t *)catzone, KNOT_RRTYPE_SOA, KNOT_CLASS_IN, 0);
+ rrset.rrs.rdata = (knot_rdata_t *)rdata;
+ rrset.rrs.count = 1;
// set catalog zone's SOA
- rrset.owner = (knot_dname_t *)catzone;
- rrset.type = KNOT_RRTYPE_SOA;
- rrset.rclass = KNOT_CLASS_IN;
- rrset.ttl = 0;
- rrset.rrs.count = 1;
- rrset.rrs.rdata = rdata;
- wire = wire_ctx_init(rdata->data, 250);
+ uint8_t data[250];
+ assert(sizeof(knot_rdata_t) + sizeof(data) <= sizeof(rdata));
+ wire_ctx_t wire = wire_ctx_init(data, sizeof(data));
wire_ctx_write(&wire, invalid, sizeof(invalid));
wire_ctx_write(&wire, invalid, sizeof(invalid));
wire_ctx_write_u32(&wire, soa_serial);
wire_ctx_write_u32(&wire, CATALOG_SOA_RETRY);
wire_ctx_write_u32(&wire, CATALOG_SOA_EXPIRE);
wire_ctx_write_u32(&wire, 0);
- rdata->len = wire_ctx_offset(&wire);
- rrset.rrs.size = knot_rdata_size(rdata->len);
+ set_rdata(&rrset, data, wire_ctx_offset(&wire));
if (zone_contents_add_rr(c, &rrset, &unused) != KNOT_EOK) {
goto fail;
}
// set catalog zone's NS
unused = NULL;
rrset.type = KNOT_RRTYPE_NS;
- set_rdata(&rrset, (uint8_t *)invalid, sizeof(invalid));
+ set_rdata(&rrset, invalid, sizeof(invalid));
if (zone_contents_add_rr(c, &rrset, &unused) != KNOT_EOK) {
goto fail;
}
// set catalog zone's version TXT
unused = NULL;
- rrset.type = KNOT_RRTYPE_TXT;
- set_rdata(&rrset, version2, 2);
- size_t catz_len = knot_dname_size(catzone);
- if (catz_len + sizeof(version) > KNOT_DNAME_MAXLEN) {
+ knot_dname_storage_t owner;
+ if (knot_dname_store(owner, version) == 0 || dname_append(owner, catzone) == 0) {
goto fail;
}
- memcpy(tmpname, version, sizeof(version));
- memcpy(tmpname + sizeof(version), catzone, catz_len);
- rrset.owner = tmpname;
+ rrset.owner = owner;
+ rrset.type = KNOT_RRTYPE_TXT;
+ set_rdata(&rrset, cat_version, sizeof(cat_version));
if (zone_contents_add_rr(c, &rrset, &unused) != KNOT_EOK) {
goto fail;
}
int catalog_update_to_update(catalog_update_t *u, struct zone_update *zu)
{
- knot_rrset_t ptr = { 0 };
- ptr.type = KNOT_RRTYPE_PTR;
- ptr.rclass = KNOT_CLASS_IN;
- ptr.ttl = 0;
+ knot_rrset_t ptr;
+ knot_rrset_init(&ptr, NULL, KNOT_RRTYPE_PTR, KNOT_CLASS_IN, 0);
uint8_t tmp[KNOT_DNAME_MAXLEN + sizeof(knot_rdata_t)];
- ptr.rrs.count = 1;
ptr.rrs.rdata = (knot_rdata_t *)tmp;
+ ptr.rrs.count = 1;
int ret = u->error;
catalog_it_t *it = catalog_it_begin(u, true);