コード例 #1
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
void
dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) {
	REQUIRE(VALID_CCTX(cctx));

	cctx->allowed &= ~DNS_COMPRESS_ALL;
	cctx->allowed |= (allowed & DNS_COMPRESS_ALL);
}
コード例 #2
0
ファイル: compress.c プロジェクト: each/bind9-collab
void
dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) {
	unsigned int i;
	dns_compressnode_t *node;

	REQUIRE(VALID_CCTX(cctx));

	if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
		return;

	for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
		node = cctx->table[i];
		/*
		 * This relies on nodes with greater offsets being
		 * closer to the beginning of the list, and the
		 * items with the greatest offsets being at the end
		 * of the initialnodes[] array.
		 */
		while (node != NULL && (node->offset & 0x7fff) >= offset) {
			cctx->table[i] = node->next;
			if ((node->offset & 0x8000) != 0)
				isc_mem_put(cctx->mctx, node->r.base,
					    node->r.length);
			if (node->count >= DNS_COMPRESS_INITIALNODES)
				isc_mem_put(cctx->mctx, node, sizeof(*node));
			cctx->count--;
			node = cctx->table[i];
		}
	}
}
コード例 #3
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
void
dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive) {
	REQUIRE(VALID_CCTX(cctx));

	if (sensitive)
		cctx->allowed |= DNS_COMPRESS_CASESENSITIVE;
	else
		cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE;
}
コード例 #4
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
void
dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
		 const dns_name_t *prefix, isc_uint16_t offset)
{
	dns_name_t tname;
	unsigned int start;
	unsigned int n;
	unsigned int count;
	unsigned int hash;
	dns_compressnode_t *node;
	unsigned int length;
	unsigned int tlength;
	isc_uint16_t toffset;

	REQUIRE(VALID_CCTX(cctx));
	REQUIRE(dns_name_isabsolute(name));

	dns_name_init(&tname, NULL);

	n = dns_name_countlabels(name);
	count = dns_name_countlabels(prefix);
	if (dns_name_isabsolute(prefix))
		count--;
	start = 0;
	length = name_length(name);
	while (count > 0) {
		if (offset >= 0x4000)
			break;
		dns_name_getlabelsequence(name, start, n, &tname);
		hash = dns_name_hash(&tname, ISC_FALSE) %
		       DNS_COMPRESS_TABLESIZE;
		tlength = name_length(&tname);
		toffset = (isc_uint16_t)(offset + (length - tlength));
		/*
		 * Create a new node and add it.
		 */
		if (cctx->count < DNS_COMPRESS_INITIALNODES)
			node = &cctx->initialnodes[cctx->count];
		else {
			node = isc_mem_get(cctx->mctx,
					   sizeof(dns_compressnode_t));
			if (node == NULL)
				return;
		}
		node->count = cctx->count++;
		node->offset = toffset;
		dns_name_toregion(&tname, &node->r);
		node->labels = (isc_uint8_t)dns_name_countlabels(&tname);
		node->next = cctx->table[hash];
		cctx->table[hash] = node;
		start++;
		n--;
		count--;
	}
}
コード例 #5
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
/*
 * Find the longest match of name in the table.
 * If match is found return ISC_TRUE. prefix, suffix and offset are updated.
 * If no match is found return ISC_FALSE.
 */
isc_boolean_t
dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
			dns_name_t *prefix, isc_uint16_t *offset)
{
	dns_name_t tname, nname;
	dns_compressnode_t *node = NULL;
	unsigned int labels, hash, n;

	REQUIRE(VALID_CCTX(cctx));
	REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
	REQUIRE(offset != NULL);

	if (cctx->count == 0)
		return (ISC_FALSE);

	labels = dns_name_countlabels(name);
	INSIST(labels > 0);

	dns_name_init(&tname, NULL);
	dns_name_init(&nname, NULL);

	for (n = 0; n < labels - 1; n++) {
		dns_name_getlabelsequence(name, n, labels - n, &tname);
		hash = dns_name_hash(&tname, ISC_FALSE) %
		       DNS_COMPRESS_TABLESIZE;
		for (node = cctx->table[hash]; node != NULL; node = node->next)
		{
			NODENAME(node, &nname);
			if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) {
				if (dns_name_caseequal(&nname, &tname))
					break;
			} else {
				if (dns_name_equal(&nname, &tname))
					break;
			}
		}
		if (node != NULL)
			break;
	}

	/*
	 * If node == NULL, we found no match at all.
	 */
	if (node == NULL)
		return (ISC_FALSE);

	if (n == 0)
		dns_name_reset(prefix);
	else
		dns_name_getlabelsequence(name, 0, n, prefix);

	*offset = node->offset;
	return (ISC_TRUE);
}
コード例 #6
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
void
dns_compress_invalidate(dns_compress_t *cctx) {
	dns_compressnode_t *node;
	unsigned int i;

	REQUIRE(VALID_CCTX(cctx));

	cctx->magic = 0;
	for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
		while (cctx->table[i] != NULL) {
			node = cctx->table[i];
			cctx->table[i] = cctx->table[i]->next;
			if (node->count < DNS_COMPRESS_INITIALNODES)
				continue;
			isc_mem_put(cctx->mctx, node, sizeof(*node));
		}
	}
	cctx->allowed = 0;
	cctx->edns = -1;
}
コード例 #7
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
unsigned int
dns_compress_getmethods(dns_compress_t *cctx) {
	REQUIRE(VALID_CCTX(cctx));
	return (cctx->allowed & DNS_COMPRESS_ALL);
}
コード例 #8
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
int
dns_compress_getedns(dns_compress_t *cctx) {
	REQUIRE(VALID_CCTX(cctx));
	return (cctx->edns);
}
コード例 #9
0
ファイル: compress.c プロジェクト: rodrigc/bz-vimage
isc_boolean_t
dns_compress_getsensitive(dns_compress_t *cctx) {
	REQUIRE(VALID_CCTX(cctx));

	return (ISC_TF((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0));
}
コード例 #10
0
ファイル: compress.c プロジェクト: each/bind9-collab
void
dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
		 const dns_name_t *prefix, isc_uint16_t offset)
{
	dns_name_t tname, xname;
	unsigned int start;
	unsigned int n;
	unsigned int count;
	unsigned int i;
	dns_compressnode_t *node;
	unsigned int length;
	unsigned int tlength;
	isc_uint16_t toffset;
	unsigned char *tmp;
	isc_region_t r;

	REQUIRE(VALID_CCTX(cctx));
	REQUIRE(dns_name_isabsolute(name));

	if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
		return;

	if (offset >= 0x4000)
		return;
	dns_name_init(&tname, NULL);
	dns_name_init(&xname, NULL);

	n = dns_name_countlabels(name);
	count = dns_name_countlabels(prefix);
	if (dns_name_isabsolute(prefix))
		count--;
	if (count == 0)
		return;
	start = 0;
	dns_name_toregion(name, &r);
	length = r.length;
	tmp = isc_mem_get(cctx->mctx, length);
	if (tmp == NULL)
		return;
	/*
	 * Copy name data to 'tmp' and make 'r' use 'tmp'.
	 */
	memmove(tmp, r.base, r.length);
	r.base = tmp;
	dns_name_fromregion(&xname, &r);

	if (count > 2U)
		count = 2U;

	while (count > 0) {
		unsigned char ch;

		dns_name_getlabelsequence(&xname, start, n, &tname);
		/*
		 * We calculate the table index using the first
		 * character in the first label of tname.
		 */
		ch = tname.ndata[1];
		i = tableindex[ch];
		tlength = name_length(&tname);
		toffset = (isc_uint16_t)(offset + (length - tlength));
		if (toffset >= 0x4000)
			break;
		/*
		 * Create a new node and add it.
		 */
		if (cctx->count < DNS_COMPRESS_INITIALNODES)
			node = &cctx->initialnodes[cctx->count];
		else {
			node = isc_mem_get(cctx->mctx,
					   sizeof(dns_compressnode_t));
			if (node == NULL)
				break;
		}
		node->count = cctx->count++;
		/*
		 * 'node->r.base' becomes 'tmp' when start == 0.
		 * Record this by setting 0x8000 so it can be freed later.
		 */
		if (start == 0)
			toffset |= 0x8000;
		node->offset = toffset;
		dns_name_toregion(&tname, &node->r);
		dns_name_init(&node->name, NULL);
		node->name.length = node->r.length;
		node->name.ndata = node->r.base;
		node->name.labels = tname.labels;
		node->name.attributes = DNS_NAMEATTR_ABSOLUTE;
		node->next = cctx->table[i];
		cctx->table[i] = node;
		start++;
		n--;
		count--;
	}

	if (start == 0)
		isc_mem_put(cctx->mctx, tmp, length);
}
コード例 #11
0
ファイル: compress.c プロジェクト: each/bind9-collab
/*
 * Find the longest match of name in the table.
 * If match is found return ISC_TRUE. prefix, suffix and offset are updated.
 * If no match is found return ISC_FALSE.
 */
isc_boolean_t
dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
			dns_name_t *prefix, isc_uint16_t *offset)
{
	dns_name_t tname;
	dns_compressnode_t *node = NULL;
	unsigned int labels, i, n;
	unsigned int numlabels;
	unsigned char *p;

	REQUIRE(VALID_CCTX(cctx));
	REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
	REQUIRE(offset != NULL);

	if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
		return (ISC_FALSE);

	if (cctx->count == 0)
		return (ISC_FALSE);

	labels = dns_name_countlabels(name);
	INSIST(labels > 0);

	dns_name_init(&tname, NULL);

	numlabels = labels > 3U ? 3U : labels;
	p = name->ndata;

	for (n = 0; n < numlabels - 1; n++) {
		unsigned char ch, llen;
		unsigned int firstoffset, length;

		firstoffset = (unsigned int)(p - name->ndata);
		length = name->length - firstoffset;

		/*
		 * We calculate the table index using the first
		 * character in the first label of the suffix name.
		 */
		ch = p[1];
		i = tableindex[ch];
		if (ISC_LIKELY((cctx->allowed &
				DNS_COMPRESS_CASESENSITIVE) != 0))
		{
			for (node = cctx->table[i];
			     node != NULL;
			     node = node->next)
			{
				if (ISC_UNLIKELY(node->name.length != length))
					continue;

				if (ISC_LIKELY(memcmp(node->name.ndata,
						      p, length) == 0))
					goto found;
			}
		} else {
			for (node = cctx->table[i];
			     node != NULL;
			     node = node->next)
			{
				unsigned int l, count;
				unsigned char c;
				unsigned char *label1, *label2;

				if (ISC_UNLIKELY(node->name.length != length))
					continue;

				l = labels - n;
				if (ISC_UNLIKELY(node->name.labels != l))
					continue;

				label1 = node->name.ndata;
				label2 = p;
				while (ISC_LIKELY(l-- > 0)) {
					count = *label1++;
					if (count != *label2++)
						goto cont1;

					/* no bitstring support */
					INSIST(count <= 63);

					/* Loop unrolled for performance */
					while (ISC_LIKELY(count > 3)) {
						c = maptolower[label1[0]];
						if (c != maptolower[label2[0]])
							goto cont1;
						c = maptolower[label1[1]];
						if (c != maptolower[label2[1]])
							goto cont1;
						c = maptolower[label1[2]];
						if (c != maptolower[label2[2]])
							goto cont1;
						c = maptolower[label1[3]];
						if (c != maptolower[label2[3]])
							goto cont1;
						count -= 4;
						label1 += 4;
						label2 += 4;
					}
					while (ISC_LIKELY(count-- > 0)) {
						c = maptolower[*label1++];
						if (c != maptolower[*label2++])
							goto cont1;
					}
				}
				break;
 cont1:
				continue;
			}
		}

		if (node != NULL)
			break;

		llen = *p;
		p += llen + 1;
	}

 found:
	/*
	 * If node == NULL, we found no match at all.
	 */
	if (node == NULL)
		return (ISC_FALSE);

	if (n == 0)
		dns_name_reset(prefix);
	else
		dns_name_getlabelsequence(name, 0, n, prefix);

	*offset = (node->offset & 0x7fff);
	return (ISC_TRUE);
}
コード例 #12
0
ファイル: compress.c プロジェクト: each/bind9-collab
void
dns_compress_disable(dns_compress_t *cctx) {
	REQUIRE(VALID_CCTX(cctx));
	cctx->allowed &= ~DNS_COMPRESS_ENABLED;
}