2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 05:28:00 +00:00

Local compression fixes to use rbt bitstrings.

This commit is contained in:
Mark Andrews 1999-04-28 03:03:56 +00:00
parent 075a8494bd
commit a41d348e14
3 changed files with 176 additions and 44 deletions

View File

@ -26,11 +26,13 @@
#include <dns/compress.h>
#include <dns/name.h>
unsigned char plain1[] = "\003foo";
unsigned char plain2[] = "\003bar\003foo";
unsigned char plain1[] = "\003yyy\003foo";
unsigned char plain2[] = "\003bar\003yyy\003foo";
unsigned char plain3[] = "\003xxx\003bar\003foo";
unsigned char plain[] =
"\003foo\0\003bar\003foo\0\003bar\003foo\0\003xxx\003bar\003foo";
"\003yyy\003foo\0\003bar\003yyy\003foo\0\003bar\003yyy\003foo\0\003xxx\003bar\003foo";
/* result concatenate (plain1, plain2, plain2, plain3) */
unsigned char bit1[] = "\101\010b";
unsigned char bit2[] = "\101\014b\260";
@ -50,13 +52,9 @@ main(int argc, char *argv[]) {
dns_name_t name3;
isc_region_t region;
int c;
int bitstrings = 0;
while ((c = getopt(argc, argv, "brv")) != -1) {
while ((c = getopt(argc, argv, "rv")) != -1) {
switch (c) {
case 'b':
bitstrings++;
break;
case 'r':
raw++;
break;
@ -103,12 +101,6 @@ main(int argc, char *argv[]) {
region.length = sizeof bit3;
dns_name_fromregion(&name3, &region);
if (bitstrings == 0) {
fprintf(stdout, "Bit string tests not performed.");
fprintf(stdout, " Awaiting RBT support\n");
exit (0);
}
test(DNS_COMPRESS_NONE, &name1, &name2, &name3, bit, sizeof bit);
test(DNS_COMPRESS_GLOBAL14, &name1, &name2, &name3, bit, sizeof bit);
test(DNS_COMPRESS_GLOBAL, &name1, &name2, &name3, bit, sizeof bit);
@ -207,6 +199,7 @@ test(unsigned int allowed, dns_name_t *name1, dns_name_t *name2,
fputs(" ", stdout);
}
fputs("\n", stdout);
fflush(stdout);
}
RUNTIME_CHECK(target.used == length);

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: compress.c,v 1.12 1999/04/14 17:40:22 halley Exp $ */
/* $Id: compress.c,v 1.13 1999/04/28 03:03:55 marka Exp $ */
#include <config.h>
#include <string.h>
@ -42,6 +42,12 @@ void compress_add(dns_rbt_t *root, dns_name_t *prefix,
dns_name_t *suffix, isc_uint16_t offset,
isc_boolean_t global16, isc_mem_t *mctx);
#undef MPADRC
#ifdef MPADRC
isc_buffer_t x;
char xxxx[1024];
#endif
/***
*** Compression
***/
@ -87,7 +93,6 @@ dns_compress_localinit(dns_compress_t *cctx, dns_name_t *owner,
isc_buffer_t t;
isc_region_t region;
REQUIRE(VALID_CCTX(cctx));
REQUIRE(cctx->local == NULL);
REQUIRE(dns_name_isabsolute(owner) == ISC_TRUE);
@ -124,6 +129,16 @@ dns_compress_localinit(dns_compress_t *cctx, dns_name_t *owner,
if (data == NULL)
return (DNS_R_SUCCESS);
*data = ll;
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(&name, ISC_FALSE, &x);
fprintf(stdout,
"dns_rbt_addname(local, \"%.*s\", %d)\n",
(int)x.used, (char*)x.base, *data);
#endif
result = dns_rbt_addname(cctx->local, &name, data);
if (result != DNS_R_SUCCESS) {
isc_mem_put(cctx->mctx, data, sizeof *data);
@ -151,11 +166,11 @@ dns_compress_localinit(dns_compress_t *cctx, dns_name_t *owner,
* Adding 'bits' to 'll' may exceed the maximum logical
* offset index. Throw away bits until ll <= 254.
*/
ll += bits;
ll += bits - 1;
while (ll > 254 && bits > 0) {
/* clear bit */
buf[2 + bits / 8] &= ~(1 << (7 - (bits % 8)));
bits--;
buf[2 + bits / 8] &= ~(1 << (7 - (bits % 8)));
ll--;
}
/*
@ -175,14 +190,25 @@ dns_compress_localinit(dns_compress_t *cctx, dns_name_t *owner,
if (data == NULL)
return (DNS_R_SUCCESS);
*data = ll;
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(&name, ISC_FALSE, &x);
fprintf(stdout,
"dns_rbt_addname(local, \"%.*s\", %d)\n",
(int)x.used, (char *)x.base,
*data);
#endif
result = dns_rbt_addname(cctx->local, &name, data);
if (result != DNS_R_SUCCESS) {
isc_mem_put(cctx->mctx, data, sizeof *data);
return (DNS_R_SUCCESS);
}
/* clear bit */
buf[2 + bits / 8] &= ~(1 << (7 - (bits % 8)));
bits--;
buf[2 + bits / 8] &= ~(1 << (7 - (bits % 8)));
ll--;
} while (bits > 0);
wl++;
@ -249,6 +275,15 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name,
REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
REQUIRE(offset != NULL);
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(name, ISC_FALSE, &x);
fprintf(stdout, "compress_find(global, name \"%.*s\", ...)\n",
(int)x.used, (char*)x.base);
#endif
return (compress_find(cctx->global, name, prefix, suffix, offset,
workspace));
}
@ -264,6 +299,16 @@ dns_compress_findlocal(dns_compress_t *cctx, dns_name_t *name,
if (cctx->local == NULL)
return (ISC_FALSE);
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(name, ISC_FALSE, &x);
fprintf(stdout, "compress_find(local, name \"%.*s\", ...)\n",
(int)x.used, (char*)x.base);
#endif
return (compress_find(cctx->local, name, prefix, suffix, offset,
workspace));
}
@ -279,12 +324,19 @@ dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix,
if (cctx->local != NULL && (cctx->allowed & DNS_COMPRESS_LOCAL) != 0) {
REQUIRE(cctx->rdata <= offset);
localoffset = offset - cctx->rdata + 256;
#ifdef MPADRC
fprintf(stdout, "compress_add(local, ...)\n");
#endif
compress_add(cctx->local, prefix, suffix, localoffset, ISC_TRUE,
cctx->mctx);
}
if ((cctx->edns > -1) || !local)
if ((cctx->edns > -1) || !local) {
#ifdef MPADRC
fprintf(stdout, "compress_add(global, ...)\n");
#endif
compress_add(cctx->global, prefix, suffix, offset,
cctx->global16, cctx->mctx);
}
}
void
@ -424,6 +476,16 @@ compress_add(dns_rbt_t *root, dns_name_t *prefix, dns_name_t *suffix,
if (data == NULL)
return;
*data = offset;
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(&full, ISC_FALSE, &x);
fprintf(stdout,
"dns_rbt_addname(root, \"%.*s\", %d)\n",
(int)x.used, (char*)x.base, *data);
#endif
result = dns_rbt_addname(root, &full, data);
if (result != DNS_R_SUCCESS) {
isc_mem_put(mctx, data, sizeof *data);
@ -474,10 +536,19 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
return (ISC_FALSE);
if (data == NULL) /* root label */
return (ISC_FALSE);
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(foundname, ISC_FALSE, &x);
fprintf(stdout, "foundname \"%.*s\" %d\n",
(int)x.used, (char*)x.base, *data);
#endif
/*
* Do we have to do bit string processing?
*/
dns_name_getlabel(dns_fixedname_name(&found), 0, &foundlabel);
dns_name_getlabel(foundname, 0, &foundlabel);
foundlabels = dns_name_countlabels(foundname);
INSIST(foundlabels > 1); /* root labels are not added to tree */
namelabels = dns_name_countlabels(name);
@ -499,6 +570,24 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
dns_name_getlabelsequence(name, 0, prefixlen, prefix);
dns_name_getlabelsequence(foundname, 0, foundlabels, suffix);
*offset = *data;
#ifdef MPADRC
if (prefixlen != 0) {
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(prefix, ISC_FALSE, &x);
fprintf(stdout, "prefix \"%.*s\"\n",
(int)x.used, (char*)x.base);
} else
fprintf(stdout, "prefix <EMPTY>\n");
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(suffix, ISC_FALSE, &x);
fprintf(stdout, "suffix \"%.*s\"\n",
(int)x.used, (char*)x.base);
#endif
return (ISC_TRUE);
}
/* XXX MPA needs to be tested */
@ -525,7 +614,6 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
*/
while (j < bits) {
bit = dns_label_getbit(&namelabel, foundbits + j);
j++;
if (bit)
buf[2 + j / 8] |= (1 << (7 - (j % 8)));
j++;
@ -533,12 +621,27 @@ compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix,
buf[0] = DNS_LABELTYPE_BITSTRING;
buf[1] = j;
region.base = buf;
region.length = 2 + j / 8;
region.length = 2 + (j + 7) / 8;
dns_name_fromregion(&tmpsuffix, &region);
result = dns_name_concatenate(&tmpprefix, &tmpsuffix, prefix,
workspace);
if (result != DNS_R_SUCCESS)
return (ISC_FALSE);
*offset = *data;
#ifdef MPADRC
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(prefix, ISC_FALSE, &x);
fprintf(stdout, "prefix \"%.*s\"\n",
(int)x.used, (char*)x.base);
isc_buffer_init(&x, xxxx, sizeof xxxx,
ISC_BUFFERTYPE_TEXT);
dns_name_totext(suffix, ISC_FALSE, &x);
fprintf(stdout, "suffix \"%.*s\"\n",
(int)x.used, (char*)x.base);
#endif
return (ISC_TRUE);
}

View File

@ -33,6 +33,8 @@
#define NAME_MAGIC 0x444E536EU /* DNSn. */
#define VALID_NAME(n) ((n) != NULL && \
(n)->magic == NAME_MAGIC)
isc_buffer_t x;
char xxxx[1024];
typedef enum {
ft_init = 0,
@ -806,6 +808,8 @@ void
dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
unsigned char *offsets;
dns_offsets_t odata;
unsigned int len;
isc_region_t r2;
/*
* Make 'name' refer to region 'r'.
@ -813,13 +817,23 @@ dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
REQUIRE(VALID_NAME(name));
REQUIRE(r != NULL);
REQUIRE(r->length <= 255);
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
INIT_OFFSETS(name, offsets, odata);
name->ndata = r->base;
name->length = r->length;
if (name->buffer != NULL) {
isc_buffer_clear(name->buffer);
isc_buffer_available(name->buffer, &r2);
len = (r->length < r2.length) ? r->length : r2.length;
if (len > 255)
len = 255;
memcpy(r2.base, r->base, len);
name->ndata = r2.base;
name->length = len;
} else {
name->ndata = r->base;
name->length = (r->length <= 255) ? r->length : 255;
}
if (r->length > 0)
set_offsets(name, offsets, ISC_TRUE, ISC_TRUE, ISC_TRUE);
@ -827,6 +841,9 @@ dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
name->labels = 0;
name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
}
if (name->buffer != NULL)
isc_buffer_add(name->buffer, name->length);
}
void
@ -1921,9 +1938,9 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
ll = 0;
/*
* Work down owner label from TLD until we
* have found 'new_current' logical labels.
* have found 'new_current + 1' logical labels.
*/
while (i < lcount && ll < new_current) {
while (i <= lcount && ll <= new_current) {
dns_name_getlabel(&dctx->owner_name,
lcount - i - 1,
&label);
@ -1934,7 +1951,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
ll++;
continue;
}
/* XXX MPA test */
INSIST(labeltype ==
dns_labeltype_bitstring);
bits = dns_label_countbits(&label);
@ -1949,30 +1965,38 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
*/
break;
}
if (i == lcount)
if (i > lcount)
return (DNS_R_BADPOINTER);
bits = new_current - ll;
if (bits != 0) {
/* XXX MPA test */
if (ll <= new_current) {
dns_name_getlabel(&dctx->owner_name,
lcount - i - 1,
&label);
bits = new_current + 1 - ll;
if (nrem < 2 + (bits + 7) / 8)
return (DNS_R_NOSPACE);
*ndata++ = DNS_LABELTYPE_BITSTRING;
*ndata++ = bits;
ndata[bits/8] = 0;
while (bits) {
/*
* Zero all bits of last octet of
* label.
*/
ndata[(bits - 1) / 8] = 0;
do {
bits--;
bit = dns_label_getbit(&label,
bits);
set_bit(ndata, bits, bit);
bits--;
}
ndata += (new_current - ll + 7) / 8;
} while (bits != 0);
labels++;
i++;
bits = new_current + 1 - ll;
ndata += (bits + 7) / 8;
nused += (bits + 7) / 8 + 2;
nrem -= (bits + 7) / 8 - 2;
}
dns_name_init(&suffix, NULL);
dns_name_getlabelsequence(&dctx->owner_name,
lcount - i - 1,
i + 2, &suffix);
lcount - i,
i + 1, &suffix);
if (suffix.length > nrem)
return (DNS_R_NOSPACE);
memcpy(ndata, suffix.ndata, suffix.length);
@ -2074,9 +2098,20 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
else
lf = ISC_FALSE;
/* find the best compression */
/*
* Will the compression pointer reduce the message size?
*/
if (lf && (lp.length + ((lo < 16384) ? 2 : 3)) >= name->length)
lf = ISC_FALSE;
if (gf && (gp.length + ((go < 16384) ? 2 : 3)) >= name->length)
gf = ISC_FALSE;
/*
*
*/
if (lf && gf) {
if (lp.length < gp.length)
if ((lp.length + ((lo < 16384) ? 2 : 3)) <
(gp.length + ((go < 16384) ? 2 : 3)))
gf = ISC_FALSE;
else
lf = ISC_FALSE;
@ -2517,12 +2552,13 @@ dns_name_split(dns_name_t *name,
/*
* XXX DCL better way to decide memcpy vs memmove?
*/
if (len > 0)
if (len > 0) {
if ((dst <= src && dst + len > src) ||
(src <= dst && src + len > dst))
memmove(dst, src, len);
else
memcpy(dst, src, len);
}
suffix->buffer->used = suffix->length;
suffix->ndata = suffix->buffer->base;