コード例 #1
0
ファイル: dname.c プロジェクト: gitter-badger/knot
/*----------------------------------------------------------------------------*/
_public_
int knot_dname_cmp_wire(const knot_dname_t *d1, const knot_dname_t *d2,
                        const uint8_t *pkt)
{
	/* This would be hard to catch since -1 is a good result, assert instead. */
	assert(d1 != NULL || d2 != NULL);

	/* Convert to lookup format. */
	uint8_t d1_lf[KNOT_DNAME_MAXLEN], d2_lf[KNOT_DNAME_MAXLEN];
	if (knot_dname_lf(d1_lf, d1, pkt) < 0 || knot_dname_lf(d2_lf, d2, pkt) < 0) {
		assert(0); /* This must not happend as the d1, d2 are checked. */
		return KNOT_EINVAL;
	}

	/* Compare common part. */
	uint8_t common = d1_lf[0];
	if (common > d2_lf[0])
		common = d2_lf[0];
	int ret = memcmp(d1_lf+1, d2_lf+1, common);
	if (ret != 0)
		return ret;

	/* If they match, compare lengths. */
	if (d1_lf[0] < d2_lf[0])
		return -1;
	if (d1_lf[0] > d2_lf[0])
		return 1;
	return 0;
}
コード例 #2
0
ファイル: zone-tree.c プロジェクト: idtek/knot
int zone_tree_remove(zone_tree_t *tree,
                     const knot_dname_t *owner,
                     zone_node_t **removed)
{
	if (owner == NULL) {
		return KNOT_EINVAL;
	}

	if (zone_tree_is_empty(tree)) {
		return KNOT_ENONODE;
	}

	uint8_t lf[KNOT_DNAME_MAXLEN];
	knot_dname_lf(lf, owner, NULL);

	value_t *rval = hattrie_tryget(tree, (char*)lf+1, *lf);
	if (rval == NULL) {
		return KNOT_ENOENT;
	} else {
		*removed = (zone_node_t *)(*rval);
	}

	hattrie_del(tree, (char*)lf+1, *lf);
	return KNOT_EOK;
}
コード例 #3
0
ファイル: zone-tree.c プロジェクト: idtek/knot
zone_node_t *zone_tree_get_next(zone_tree_t *tree,
                                const knot_dname_t *owner)
{
	if (tree == NULL || owner == NULL) {
		return NULL;
	}

	uint8_t lf[KNOT_DNAME_MAXLEN];
	knot_dname_lf(lf, owner, NULL);

	value_t *fval = NULL;
	zone_node_t *n = NULL;
	(void)hattrie_find_next(tree, (char*)lf + 1, *lf, &fval);
	if (fval == NULL) {
		/* Return first node. */
		hattrie_iter_t *it = hattrie_iter_begin(tree, true);
		if (it == NULL) {
			return NULL;
		}
		fval = hattrie_iter_val(it);
		hattrie_iter_free(it);
	}

	n = (zone_node_t *)*fval;
	/* Next node must be non-empty and auth. */
	if (n->rrset_count == 0 || n->flags & NODE_FLAGS_NONAUTH) {
		return zone_tree_get_next(tree, n->owner);
	} else {
		return n;
	}
}
コード例 #4
0
ファイル: zone-tree.c プロジェクト: idtek/knot
int zone_tree_insert(zone_tree_t *tree, zone_node_t *node)
{
	if (tree == NULL) {
		return KNOT_EINVAL;
	}

	assert(tree && node && node->owner);
	uint8_t lf[KNOT_DNAME_MAXLEN];
	knot_dname_lf(lf, node->owner, NULL);

	*hattrie_get(tree, (char*)lf+1, *lf) = node;
	return KNOT_EOK;
}
コード例 #5
0
ファイル: zone-tree.c プロジェクト: idtek/knot
int zone_tree_get_less_or_equal(zone_tree_t *tree,
                                const knot_dname_t *owner,
                                zone_node_t **found,
                                zone_node_t **previous)
{
	if (owner == NULL || found == NULL || previous == NULL) {
		return KNOT_EINVAL;
	}

	if (zone_tree_is_empty(tree)) {
		return KNOT_ENONODE;
	}

	uint8_t lf[KNOT_DNAME_MAXLEN];
	knot_dname_lf(lf, owner, NULL);

	value_t *fval = NULL;
	int ret = hattrie_find_leq(tree, (char*)lf+1, *lf, &fval);
	if (fval) {
		*found = (zone_node_t *)(*fval);
	}
	int exact_match = 0;
	if (ret == 0) {
		if (fval) {
			*previous = (*found)->prev;
		}
		exact_match = 1;
	} else if (ret < 0) {
		*previous = *found;
		*found = NULL;
	} else if (ret > 0) {
		/* Previous should be the rightmost node.
		 * For regular zone it is the node left of apex, but for some
		 * cases like NSEC3, there is no such sort of thing (name wise).
		 */
		/*! \todo We could store rightmost node in zonetree probably. */
		hattrie_iter_t *i = hattrie_iter_begin(tree, 1);
		*previous = *(zone_node_t **)hattrie_iter_val(i); /* leftmost */
		*previous = (*previous)->prev; /* rightmost */
		*found = NULL;
		hattrie_iter_free(i);
	}

	/* Previous node for proof must be non-empty and authoritative. */
	if (*previous &&
	    ((*previous)->rrset_count == 0 || (*previous)->flags & NODE_FLAGS_NONAUTH)) {
		*previous = (*previous)->prev;
	}

	return exact_match;
}
コード例 #6
0
ファイル: zone-tree.c プロジェクト: idtek/knot
int zone_tree_get(zone_tree_t *tree, const knot_dname_t *owner,
                  zone_node_t **found)
{
	if (owner == NULL) {
		return KNOT_EINVAL;
	}

	if (zone_tree_is_empty(tree)) {
		return KNOT_ENONODE;
	}

	uint8_t lf[KNOT_DNAME_MAXLEN];
	knot_dname_lf(lf, owner, NULL);

	value_t *val = hattrie_tryget(tree, (char*)lf+1, *lf);
	if (val == NULL) {
		*found = NULL;
	} else {
		*found = (zone_node_t*)(*val);
	}

	return KNOT_EOK;
}