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:
parent
075a8494bd
commit
a41d348e14
@ -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, ®ion);
|
||||
|
||||
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);
|
||||
|
@ -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, ®ion);
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user