Пример #1
0
_public_
int knot_rdataset_reserve(knot_rdataset_t *rrs, size_t size, knot_mm_t *mm)
{
	if (rrs == NULL || size > MAX_RDLENGTH) {
		return KNOT_EINVAL;
	}

	size_t total_size = knot_rdataset_size(rrs);
	size_t new_size = total_size + knot_rdata_array_size(size);

	uint8_t *tmp = mm_realloc(mm, rrs->data, new_size, total_size);
	if (tmp == NULL) {
		return KNOT_ENOMEM;
	}

	rrs->data = tmp;
	rrs->rr_count++;

	// We have to initialise the 'size' field in the reserved space.
	knot_rdata_t *rr = knot_rdataset_at(rrs, rrs->rr_count - 1);
	assert(rr);
	knot_rdata_set_rdlen(rr, size);

	return KNOT_EOK;
}
Пример #2
0
static int pack_entry(MDB_val *data, struct entry *entry)
{
	char *stream = data->mv_data;
	char *bptr = stream;
	pack_bin(&stream, &entry->data.type, sizeof(entry->data.type));
	knot_rdataset_t *rrs = &entry->data.rrs;
	pack_bin(&stream, &rrs->rr_count, sizeof(rrs->rr_count));
	pack_bin(&stream, rrs->data, knot_rdataset_size(rrs));

	pack_str(&stream, entry->threat_code);
	pack_str(&stream, entry->syslog_ip);

	data->mv_size = (stream - bptr);
	return KNOT_EOK;
}
Пример #3
0
static int add_rr_at(knot_rdataset_t *rrs, const knot_rdata_t *rr, size_t pos,
                     knot_mm_t *mm)
{
	if (rrs == NULL || pos > rrs->rr_count) {
		return KNOT_EINVAL;
	}
	const uint16_t size = knot_rdata_rdlen(rr);
	const uint32_t ttl = knot_rdata_ttl(rr);
	const uint8_t *rdata = knot_rdata_data(rr);

	size_t total_size = knot_rdataset_size(rrs);

	// Realloc data.
	void *tmp = mm_realloc(mm, rrs->data,
	                       total_size + knot_rdata_array_size(size),
	                       total_size);
	if (tmp) {
		rrs->data = tmp;
	} else {
		return KNOT_ENOMEM;
	}

	if (rrs->rr_count == 0 || pos == rrs->rr_count) {
		// No need to rearange RDATA
		rrs->rr_count++;
		knot_rdata_t *new_rr = knot_rdataset_at(rrs, pos);
		knot_rdata_init(new_rr, size, rdata, ttl);
		return KNOT_EOK;
	}

	// RDATA have to be rearanged.
	knot_rdata_t *last_rr = knot_rdataset_at(rrs, rrs->rr_count - 1);
	knot_rdata_t *old_rr = knot_rdataset_at(rrs, pos);
	assert(last_rr);
	assert(old_rr);

	// Make space for new data by moving the array
	memmove(old_rr + knot_rdata_array_size(size), old_rr,
	        (last_rr + knot_rdata_array_size(knot_rdata_rdlen(last_rr))) - old_rr);

	// Set new RR
	knot_rdata_init(old_rr, size, rdata, ttl);

	rrs->rr_count++;
	return KNOT_EOK;
}
Пример #4
0
_public_
int knot_rdataset_copy(knot_rdataset_t *dst, const knot_rdataset_t *src, knot_mm_t *mm)
{
	if (dst == NULL || src == NULL) {
		return KNOT_EINVAL;
	}

	dst->rr_count = src->rr_count;
	size_t src_size = knot_rdataset_size(src);
	dst->data = mm_alloc(mm, src_size);
	if (dst->data == NULL) {
		return KNOT_ENOMEM;
	}

	memcpy(dst->data, src->data, src_size);
	return KNOT_EOK;
}
Пример #5
0
static int remove_rr_at(knot_rdataset_t *rrs, size_t pos, knot_mm_t *mm)
{
	if (rrs == NULL || pos >= rrs->rr_count) {
		return KNOT_EINVAL;
	}

	knot_rdata_t *old_rr = knot_rdataset_at(rrs, pos);
	knot_rdata_t *last_rr = knot_rdataset_at(rrs, rrs->rr_count - 1);
	assert(old_rr);
	assert(last_rr);

	size_t total_size = knot_rdataset_size(rrs);
	uint16_t old_size = knot_rdata_rdlen(old_rr);

	uint8_t *old_threshold = old_rr + knot_rdata_array_size(old_size);
	uint8_t *last_threshold = last_rr + knot_rdata_array_size(knot_rdata_rdlen(last_rr));
	// 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 - (knot_rdata_array_size(old_size)),
		                       total_size);
		if (tmp == NULL) {
			return KNOT_ENOMEM;
		} else {
			rrs->data = tmp;
		}
	} else {
		// Free RDATA
		mm_free(mm, rrs->data);
		rrs->data = NULL;
	}
	rrs->rr_count--;

	return KNOT_EOK;
}
Пример #6
0
static int rosedb_list(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
{
	MDB_cursor *cursor = cursor_acquire(txn, cache->dbi);
	MDB_val key, data;
	char dname_str[KNOT_DNAME_MAXLEN] = {'\0'};
	char type_str[16] = { '\0' };

	int ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
	while (ret == 0) {
		struct entry entry;
		unpack_entry(&data, &entry);
		knot_dname_to_str(dname_str, key.mv_data, sizeof(dname_str));
		knot_rrtype_to_string(entry.data.type, type_str, sizeof(type_str));
		printf("%s\t%s RDATA=%zuB\t%s\t%s\n", dname_str, type_str,
		       knot_rdataset_size(&entry.data.rrs), entry.threat_code, entry.syslog_ip);

		ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT);
	}

	cursor_release(cursor);

	return KNOT_EOK;
}
Пример #7
0
int main(int argc, char *argv[])
{
	plan(34);

	// Test init
	knot_rdataset_t rdataset;
	knot_rdataset_init(&rdataset);
	ok(rdataset.data == NULL && rdataset.rr_count == 0, "rdataset: init.");

	// Test rdata addition
	knot_rdata_t rdata_gt[knot_rdata_array_size(4)];
	knot_rdata_init(rdata_gt, 4, (uint8_t *)"wxyz", 3600);

	int ret = knot_rdataset_add(NULL, NULL, NULL);
	ok(ret == KNOT_EINVAL, "rdataset: add NULL.");
	ret = knot_rdataset_add(&rdataset, rdata_gt, NULL);
	bool add_ok = ret == KNOT_EOK && rdataset.rr_count == 1 &&
	              knot_rdata_cmp(rdata_gt, rdataset.data) == 0;
	ok(add_ok, "rdataset: add.");

	knot_rdata_t rdata_lo[knot_rdata_array_size(4)];
	knot_rdata_init(rdata_lo, 4, (uint8_t *)"abcd", 3600);
	ret = knot_rdataset_add(&rdataset, rdata_lo, NULL);
	add_ok = ret == KNOT_EOK && rdataset.rr_count == 2 &&
	         knot_rdata_cmp(rdata_lo, rdataset.data) == 0;
	ok(add_ok, "rdataset: add lower.");

	// Test getters
	ok(knot_rdata_cmp(knot_rdataset_at(&rdataset, 0), rdata_lo) == 0 &&
	   knot_rdata_cmp(knot_rdataset_at(&rdataset, 1), rdata_gt) == 0,
	   "rdataset: at.");

	ok(knot_rdataset_size(&rdataset) == knot_rdata_array_size(4) * 2,
	   "rdataset: size.");

	// Test copy
	ok(knot_rdataset_copy(NULL, NULL, NULL) == KNOT_EINVAL,
	   "rdataset: copy NULL.");
	knot_rdataset_t copy;
	ret = knot_rdataset_copy(&copy, &rdataset, NULL);
	const bool copy_ok = ret == KNOT_EOK && copy.rr_count == rdataset.rr_count &&
	                     knot_rdataset_size(&copy) == knot_rdataset_size(&rdataset) &&
	                     memcmp(rdataset.data, copy.data,
	                            knot_rdataset_size(&rdataset)) == 0;
	ok(copy_ok, "rdataset: copy");

	// Test eq
	ok(knot_rdataset_eq(&rdataset, &copy), "rdataset: equal");

	// Test clear
	knot_rdataset_clear(&copy, NULL);
	ok(copy.rr_count == 0 && copy.data == NULL, "rdataset: clear.");

	// Test not equal (different count)
	ok(!knot_rdataset_eq(&rdataset, &copy), "rdataset: not equal - count");

	// Test member
	knot_rdata_t not_a_member[knot_rdata_array_size(1)];
	knot_rdata_init(not_a_member, 1, (uint8_t *)"?", 3600);
	ok(knot_rdataset_member(&rdataset, rdata_gt, true), "rdataset: is member.");
	ok(!knot_rdataset_member(&rdataset, not_a_member, true), "rdataset: is not member.");

	knot_rdata_set_ttl(rdata_gt, 1234);
	ok(knot_rdataset_member(&rdataset, rdata_gt, false), "rdataset: is member TTL.");
	ok(!knot_rdataset_member(&rdataset, rdata_gt, true), "rdataset: is not member TTL.");

	// Test merge
	ok(knot_rdataset_merge(NULL, NULL, NULL) == KNOT_EINVAL,
	   "rdataset: merge NULL.");
	knot_rdataset_t empty;
	knot_rdataset_init(&empty);
	ret = knot_rdataset_merge(&empty, &rdataset, NULL);
	bool merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&empty, &rdataset);
	ok(merge_ok, "rdataset: merge empty.");
	knot_rdata_t *data_before = rdataset.data;
	ret = knot_rdataset_merge(&rdataset, &rdataset, NULL);
	merge_ok = ret == KNOT_EOK && rdataset.rr_count == 2 &&
	           data_before == rdataset.data;
	ok(merge_ok, "rdataset: merge self.");

	knot_rdataset_clear(&empty, NULL);

	// Init structs for merge sort testing
	knot_rdataset_t rdataset_lo; // "Lower" rdataset
	knot_rdataset_init(&rdataset_lo);
	RDATASET_INIT_WITH(rdataset_lo, rdata_lo);
	knot_rdataset_t rdataset_gt; // "Greater" rdataset
	knot_rdataset_init(&rdataset_gt);
	RDATASET_INIT_WITH(rdataset_gt, rdata_gt);

	// Test not equal - different data
	ok(!knot_rdataset_eq(&rdataset_gt, &rdataset_lo), "rdataset: data not equal.");

	// Test that merge keeps the sorted order
	ret = knot_rdataset_merge(&rdataset_lo, &rdataset_gt, NULL);
	merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_lo, &rdataset);
	ok(merge_ok, "rdataset: merge into lower.");

	RDATASET_INIT_WITH(rdataset_lo, rdata_lo);
	RDATASET_INIT_WITH(rdataset_gt, rdata_gt);
	ret = knot_rdataset_merge(&rdataset_gt, &rdataset_lo, NULL);
	merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_gt, &rdataset);
	ok(merge_ok, "rdataset: merge into greater.");

	// Test intersect
	ok(knot_rdataset_intersect(NULL, NULL, NULL, NULL) == KNOT_EINVAL,
	   "rdataset: intersect NULL.");

	knot_rdataset_t intersection;
	ret = knot_rdataset_intersect(&rdataset, &rdataset, &intersection, NULL);
	bool intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &intersection);
	ok(intersect_ok, "rdataset: intersect self.");
	knot_rdataset_clear(&intersection, NULL);

	RDATASET_INIT_WITH(rdataset_lo, rdata_lo);
	RDATASET_INIT_WITH(rdataset_gt, rdata_gt);
	ret = knot_rdataset_intersect(&rdataset_lo, &rdataset_gt, &intersection, NULL);
	intersect_ok = ret == KNOT_EOK && intersection.rr_count == 0;
	ok(intersect_ok, "rdataset: intersect no common.");

	ret = knot_rdataset_intersect(&rdataset, &rdataset_lo, &intersection, NULL);
	intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&intersection, &rdataset_lo);
	ok(intersect_ok, "rdataset: intersect normal.");
	knot_rdataset_clear(&intersection, NULL);

	// Test subtract
	ok(knot_rdataset_subtract(NULL, NULL, NULL) == KNOT_EINVAL,
	   "rdataset: subtract NULL.");
	ok(knot_rdataset_subtract(&rdataset, &rdataset, NULL) == KNOT_EINVAL,
	   "rdataset: subtract self.");

	ret = knot_rdataset_copy(&copy, &rdataset, NULL);
	assert(ret == KNOT_EOK);
	ret = knot_rdataset_subtract(&copy, &rdataset, NULL);
	bool subtract_ok = ret == KNOT_EOK && copy.rr_count == 0;
	ok(subtract_ok, "rdataset: subtract identical.");

	RDATASET_INIT_WITH(rdataset_lo, rdata_lo);
	RDATASET_INIT_WITH(rdataset_gt, rdata_gt);
	data_before = rdataset_lo.data;
	ret = knot_rdataset_subtract(&rdataset_lo, &rdataset_gt, NULL);
	subtract_ok = ret == KNOT_EOK && rdataset_lo.rr_count == 1 &&
	              rdataset_lo.data == data_before;
	ok(subtract_ok, "rdataset: subtract no common.");

	ret = knot_rdataset_subtract(&rdataset, &rdataset_gt, NULL);
	subtract_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &rdataset_lo);
	ok(subtract_ok, "rdataset: subtract normal.");

	ret = knot_rdataset_subtract(&rdataset, &rdataset_lo, NULL);
	subtract_ok = ret == KNOT_EOK && rdataset.rr_count == 0 &&
	              rdataset.data == NULL;
	ok(subtract_ok, "rdataset: subtract last.");

	ret = knot_rdataset_reserve(&rdataset, 65536, NULL);
	ok(ret == KNOT_EINVAL, "rdataset: reserve too much");

	RDATASET_INIT_WITH(rdataset, rdata_gt);

	size_t old_rrs_size = knot_rdataset_size(&rdataset);
	size_t rr_size = knot_rdata_rdlen(rdata_lo);
	ret = knot_rdataset_reserve(&rdataset, rr_size, NULL);
	size_t new_rrs_size = knot_rdataset_size(&rdataset);
	bool reserve_ok = ret == KNOT_EOK && new_rrs_size == (old_rrs_size + knot_rdata_array_size(rr_size));
	ok(reserve_ok, "rdataset: reserve normal");

	RDATASET_INIT_WITH(copy, rdata_lo);
	knot_rdataset_add(&copy, rdata_gt, NULL);

	knot_rdata_init(knot_rdataset_at(&rdataset, 1), 4, (uint8_t *)"abcd", 3600);

	ret = knot_rdataset_sort_at(&rdataset, 1, NULL);
	bool sort_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &copy);
	ok(sort_ok, "rdataset: sort reserved space");

	knot_rdataset_clear(&copy, NULL);
	knot_rdataset_clear(&rdataset, NULL);
	knot_rdataset_clear(&rdataset_lo, NULL);
	knot_rdataset_clear(&rdataset_gt, NULL);

	return EXIT_SUCCESS;
}