mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
exorcized local compression
This commit is contained in:
@@ -83,7 +83,6 @@ main(int argc, char *argv[]) {
|
||||
test(DNS_COMPRESS_GLOBAL14, &name1, &name2, &name3, plain,
|
||||
sizeof plain);
|
||||
test(DNS_COMPRESS_GLOBAL, &name1, &name2, &name3, plain, sizeof plain);
|
||||
test(DNS_COMPRESS_LOCAL, &name1, &name2, &name3, plain, sizeof plain);
|
||||
test(DNS_COMPRESS_ALL, &name1, &name2, &name3, plain, sizeof plain);
|
||||
|
||||
dns_name_init(&name1, NULL);
|
||||
@@ -104,7 +103,6 @@ main(int argc, char *argv[]) {
|
||||
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);
|
||||
test(DNS_COMPRESS_LOCAL, &name1, &name2, &name3, bit, sizeof bit);
|
||||
test(DNS_COMPRESS_ALL, &name1, &name2, &name3, bit, sizeof bit);
|
||||
|
||||
exit(0);
|
||||
@@ -130,7 +128,6 @@ test(unsigned int allowed, dns_name_t *name1, dns_name_t *name2,
|
||||
case DNS_COMPRESS_GLOBAL14: s = "DNS_COMPRESS_GLOBAL14"; break;
|
||||
case DNS_COMPRESS_GLOBAL16: s = "DNS_COMPRESS_GLOBAL16"; break;
|
||||
case DNS_COMPRESS_GLOBAL: s = "DNS_COMPRESS_GLOBAL"; break;
|
||||
case DNS_COMPRESS_LOCAL: s = "DNS_COMPRESS_LOCAL"; break;
|
||||
case DNS_COMPRESS_ALL: s = "DNS_COMPRESS_ALL"; break;
|
||||
default: s = "UNKOWN"; break;
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -16,7 +16,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_name is the expected name after any decompression
|
||||
|
@@ -10,7 +10,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_data is the expected wire format data in hex format
|
||||
|
@@ -10,7 +10,6 @@
|
||||
# DNS_COMPRESS_GLOBAL
|
||||
# DNS_COMPRESS_GLOBAL14
|
||||
# DNS_COMPRESS_GLOBAL16
|
||||
# DNS_COMPRESS_LOCAL
|
||||
# DNS_COMPRESS_NONE
|
||||
#
|
||||
# and where exp_data is the expected wire format data in hex format
|
||||
|
@@ -2251,8 +2251,6 @@ t_dns_name_fromwire_x(char *testfile, size_t buflen) {
|
||||
dc_method = DNS_COMPRESS_GLOBAL16;
|
||||
else if (! strcmp(tok, "DNS_COMPRESS_GLOBAL"))
|
||||
dc_method = DNS_COMPRESS_GLOBAL;
|
||||
else if (! strcmp(tok, "DNS_COMPRESS_LOCAL"))
|
||||
dc_method = DNS_COMPRESS_LOCAL;
|
||||
else if (! strcmp(tok, "DNS_COMPRESS_ALL"))
|
||||
dc_method = DNS_COMPRESS_ALL;
|
||||
|
||||
|
@@ -224,7 +224,7 @@ decompression methods if there is a domain name in the rdata.
|
||||
<CODE>if (dns_decompress_edns(dctx) >= # || !dns_decompress_strict(dctx))
|
||||
dns_decompress_setmethods(dctx, DNS_COMPRESS_ALL);
|
||||
else
|
||||
dns_decompress_setmethods(dctx, DNS_COMPRESS_LOCAL);</CODE>
|
||||
dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);</CODE>
|
||||
</PRE>
|
||||
|
||||
<DL>
|
||||
@@ -282,7 +282,7 @@ domain name in the rdata.
|
||||
<CODE>if (dns_compress_getedns(cctx) >= #)
|
||||
dns_compress_setmethods(cctx, DNS_COMPRESS_ALL);
|
||||
else
|
||||
dns_compress_setmethods(cctx, DNS_COMPRESS_LOCAL);</CODE>
|
||||
dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);</CODE>
|
||||
</PRE>
|
||||
<DL>
|
||||
<DT><CODE>rdata</CODE></DT>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: compress.c,v 1.21 2000/03/17 17:49:37 gson Exp $ */
|
||||
/* $Id: compress.c,v 1.22 2000/03/23 05:18:41 tale Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
@@ -58,7 +58,6 @@ dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx)
|
||||
cctx->rdata = 0;
|
||||
cctx->global16 = (edns >= 1) ? ISC_TRUE : ISC_FALSE;
|
||||
cctx->edns = edns;
|
||||
cctx->local = NULL;
|
||||
cctx->global = NULL;
|
||||
result = dns_rbt_create(mctx, free_offset, mctx, &cctx->global);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
@@ -68,129 +67,6 @@ dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx)
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_compress_localinit(dns_compress_t *cctx, dns_name_t *owner,
|
||||
isc_buffer_t *target)
|
||||
{
|
||||
isc_result_t result;
|
||||
unsigned int labels;
|
||||
unsigned int ll; /* logical label length w/o root label */
|
||||
unsigned int wl; /* wire labels */
|
||||
unsigned int bits;
|
||||
dns_name_t name;
|
||||
dns_name_t prefix;
|
||||
dns_name_t suffix;
|
||||
dns_label_t label;
|
||||
isc_uint16_t *data;
|
||||
unsigned char buf[34];
|
||||
unsigned char namebuf[255];
|
||||
isc_buffer_t t;
|
||||
isc_region_t region;
|
||||
|
||||
REQUIRE(VALID_CCTX(cctx));
|
||||
REQUIRE(cctx->local == NULL);
|
||||
REQUIRE(dns_name_isabsolute(owner) == ISC_TRUE);
|
||||
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
|
||||
|
||||
result = dns_rbt_create(cctx->mctx, free_offset, cctx->mctx,
|
||||
&cctx->local);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
/*
|
||||
* Errors from here on are not passed back up.
|
||||
*/
|
||||
cctx->rdata = target->used; /* XXX layer violation */
|
||||
labels = dns_name_countlabels(owner);
|
||||
if (labels <= 1) /* can't compress root label */
|
||||
return (DNS_R_SUCCESS);
|
||||
ll = 0; /* logical label index 0 == TLD not root */
|
||||
wl = 2; /* minimum number of wire labels */
|
||||
dns_name_init(&name, NULL);
|
||||
dns_name_init(&prefix, NULL);
|
||||
dns_name_init(&suffix, NULL);
|
||||
/*
|
||||
* Work from the TLD label to the least signfiant label.
|
||||
*/
|
||||
while (labels >= wl) {
|
||||
dns_name_getlabelsequence(owner, labels - wl, wl, &name);
|
||||
dns_name_getlabel(&name, 0, &label);
|
||||
/*
|
||||
* If it is not a bit string label add to tree.
|
||||
*/
|
||||
if (dns_label_type(&label) != dns_labeltype_bitstring) {
|
||||
data = isc_mem_get(cctx->mctx, sizeof *data);
|
||||
if (data == NULL)
|
||||
return (DNS_R_SUCCESS);
|
||||
*data = ll;
|
||||
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);
|
||||
}
|
||||
wl++;
|
||||
ll++;
|
||||
if (ll > 254)
|
||||
return (DNS_R_SUCCESS);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Have to compute logical for bit string labels.
|
||||
*/
|
||||
|
||||
bits = dns_label_countbits(&label);
|
||||
INSIST(label.length < sizeof buf);
|
||||
memcpy(buf, label.base, label.length);
|
||||
region.base = buf;
|
||||
dns_name_getlabelsequence(owner, 1, wl - 1, &suffix);
|
||||
/*
|
||||
* It is easier to do this the reverse way.
|
||||
* Adding 'bits' to 'll' may exceed the maximum logical
|
||||
* offset index. Throw away bits until ll <= 254.
|
||||
*/
|
||||
ll += bits - 1;
|
||||
while (ll > 254 && bits > 0) {
|
||||
/* clear bit */
|
||||
bits--;
|
||||
buf[2 + bits / 8] &= ~(1 << (7 - (bits % 8)));
|
||||
ll--;
|
||||
}
|
||||
/*
|
||||
* Add entries to tree.
|
||||
*/
|
||||
do {
|
||||
region.length = 2 + (bits + 7) / 8;
|
||||
buf[1] = bits;
|
||||
dns_name_fromregion(&prefix, ®ion);
|
||||
isc_buffer_init(&t, namebuf, sizeof namebuf,
|
||||
ISC_BUFFERTYPE_BINARY);
|
||||
result = dns_name_concatenate(&prefix, &suffix, &name,
|
||||
&t);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
return (DNS_R_SUCCESS);
|
||||
data = isc_mem_get(cctx->mctx, sizeof *data);
|
||||
if (data == NULL)
|
||||
return (DNS_R_SUCCESS);
|
||||
*data = ll;
|
||||
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 */
|
||||
bits--;
|
||||
buf[2 + bits / 8] &= ~(1 << (7 - (bits % 8)));
|
||||
ll--;
|
||||
} while (bits > 0);
|
||||
wl++;
|
||||
bits = dns_label_countbits(&label);
|
||||
ll += bits;
|
||||
if (ll > 254)
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_compress_invalidate(dns_compress_t *cctx) {
|
||||
|
||||
@@ -199,23 +75,12 @@ dns_compress_invalidate(dns_compress_t *cctx) {
|
||||
cctx->magic = 0;
|
||||
if (cctx->global != NULL)
|
||||
dns_rbt_destroy(&cctx->global);
|
||||
if (cctx->local != NULL)
|
||||
dns_rbt_destroy(&cctx->local);
|
||||
cctx->allowed = 0;
|
||||
cctx->rdata = 0;
|
||||
cctx->global16 = ISC_FALSE;
|
||||
cctx->edns = -1;
|
||||
}
|
||||
|
||||
void
|
||||
dns_compress_localinvalidate(dns_compress_t *cctx) {
|
||||
|
||||
REQUIRE(VALID_CCTX(cctx));
|
||||
|
||||
if (cctx->local != NULL)
|
||||
dns_rbt_destroy(&cctx->local);
|
||||
}
|
||||
|
||||
void
|
||||
dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) {
|
||||
REQUIRE(VALID_CCTX(cctx));
|
||||
@@ -250,36 +115,12 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name,
|
||||
workspace));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_compress_findlocal(dns_compress_t *cctx, dns_name_t *name,
|
||||
dns_name_t *prefix, dns_name_t *suffix,
|
||||
isc_uint16_t *offset, isc_buffer_t *workspace)
|
||||
{
|
||||
REQUIRE(VALID_CCTX(cctx));
|
||||
REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
|
||||
REQUIRE(offset != NULL);
|
||||
|
||||
if (cctx->local == NULL)
|
||||
return (ISC_FALSE);
|
||||
return (compress_find(cctx->local, name, prefix, suffix, offset,
|
||||
workspace));
|
||||
}
|
||||
|
||||
void
|
||||
dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix,
|
||||
dns_name_t *suffix, isc_uint16_t offset,
|
||||
isc_boolean_t local)
|
||||
dns_name_t *suffix, isc_uint16_t offset)
|
||||
{
|
||||
isc_uint16_t localoffset;
|
||||
REQUIRE(VALID_CCTX(cctx));
|
||||
|
||||
if (cctx->local != NULL && (cctx->allowed & DNS_COMPRESS_LOCAL) != 0) {
|
||||
REQUIRE(cctx->rdata <= offset);
|
||||
localoffset = offset - cctx->rdata + 256;
|
||||
compress_add(cctx->local, prefix, suffix, localoffset, ISC_TRUE,
|
||||
cctx->mctx);
|
||||
}
|
||||
if ((cctx->edns > -1) || !local)
|
||||
compress_add(cctx->global, prefix, suffix, offset,
|
||||
cctx->global16, cctx->mctx);
|
||||
}
|
||||
@@ -360,23 +201,9 @@ dns_decompress_init(dns_decompress_t *dctx, int edns, isc_boolean_t strict) {
|
||||
dctx->edns = edns;
|
||||
dctx->strict = strict;
|
||||
dctx->rdata = 0;
|
||||
dns_name_init(&dctx->owner_name, NULL);
|
||||
dns_name_invalidate(&dctx->owner_name);
|
||||
dctx->magic = DCTX_MAGIC;
|
||||
}
|
||||
|
||||
void
|
||||
dns_decompress_localinit(dns_decompress_t *dctx, dns_name_t *name,
|
||||
isc_buffer_t *source)
|
||||
{
|
||||
REQUIRE(VALID_DCTX(dctx));
|
||||
REQUIRE(dns_name_isabsolute(name) == ISC_TRUE);
|
||||
REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_BINARY);
|
||||
|
||||
dctx->rdata = source->current; /* XXX layer violation */
|
||||
dctx->owner_name = *name;
|
||||
}
|
||||
|
||||
void
|
||||
dns_decompress_invalidate(dns_decompress_t *dctx) {
|
||||
|
||||
@@ -385,14 +212,6 @@ dns_decompress_invalidate(dns_decompress_t *dctx) {
|
||||
dctx->magic = 0;
|
||||
}
|
||||
|
||||
void
|
||||
dns_decompress_localinvalidate(dns_decompress_t *dctx) {
|
||||
|
||||
REQUIRE(VALID_DCTX(dctx));
|
||||
|
||||
dns_name_invalidate(&dctx->owner_name);
|
||||
}
|
||||
|
||||
void
|
||||
dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed) {
|
||||
|
||||
|
@@ -28,10 +28,17 @@ ISC_LANG_BEGINDECLS
|
||||
|
||||
#define DNS_COMPRESS_NONE 0x00 /* no compression */
|
||||
#define DNS_COMPRESS_GLOBAL14 0x01 /* "normal" compression. */
|
||||
#define DNS_COMPRESS_GLOBAL16 0x02 /* 16-bit global comp. */
|
||||
#define DNS_COMPRESS_GLOBAL16 0x02 /* 16-bit edns global comp. */
|
||||
#define DNS_COMPRESS_GLOBAL 0x03 /* all global comp. */
|
||||
#define DNS_COMPRESS_LOCAL 0x04 /* local compression. */
|
||||
#define DNS_COMPRESS_ALL 0x07 /* all compression. */
|
||||
/*
|
||||
* Synonymous with DNS_COMPRESS_GLOBAL. A genuine difference existed when
|
||||
* local compression was an IETF draft, but that draft has been retired without
|
||||
* becoming a standard. Numerous bits of code referred to DNS_COMPRESS_ALL
|
||||
* already, and rather than change them all, the DNS_COMPRESS_ALL definition
|
||||
* was left in, but no longer refers to local compression.
|
||||
*/
|
||||
#define DNS_COMPRESS_ALL 0x03 /* all compression. */
|
||||
|
||||
|
||||
/*
|
||||
* XXX An API for manipulating these structures will be forthcoming.
|
||||
@@ -45,7 +52,6 @@ struct dns_compress {
|
||||
unsigned int rdata; /* Start of local rdata. */
|
||||
isc_boolean_t global16; /* 16 bit offsets allowed. */
|
||||
int edns; /* Edns version or -1. */
|
||||
dns_rbt_t *local; /* Local RBT. */
|
||||
dns_rbt_t *global; /* Global RBT. */
|
||||
isc_mem_t *mctx; /* Memeory context. */
|
||||
};
|
||||
@@ -56,7 +62,6 @@ struct dns_decompress {
|
||||
unsigned int rdata; /* Start of local rdata. */
|
||||
int edns; /* Edns version or -1. */
|
||||
isc_boolean_t strict; /* Strict checking */
|
||||
dns_name_t owner_name; /* For local compression. */
|
||||
};
|
||||
|
||||
isc_result_t dns_compress_init(dns_compress_t *cctx, int edns,
|
||||
@@ -75,29 +80,6 @@ isc_result_t dns_compress_init(dns_compress_t *cctx, int edns,
|
||||
* failures from dns_rbt_create()
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_compress_localinit(dns_compress_t *cctx, dns_name_t *owner,
|
||||
isc_buffer_t *target);
|
||||
|
||||
/*
|
||||
* Initalise 'cctx->local'.
|
||||
* All compression pointers pointing to logical labels in owner.
|
||||
* Record start of rdata 'target->used'.
|
||||
*
|
||||
* Ensures:
|
||||
* 'cctx->local' is valid.
|
||||
*
|
||||
* Requires:
|
||||
* 'cctx' initaliased
|
||||
* 'cctx->local' be NULL
|
||||
* 'owner' is a absolute name
|
||||
* 'target' is a valid buffer
|
||||
*
|
||||
* Returns:
|
||||
* DNS_R_SUCCESS
|
||||
* failures from dns_rbt_create()
|
||||
*/
|
||||
|
||||
void
|
||||
dns_compress_invalidate(dns_compress_t *cctx);
|
||||
|
||||
@@ -109,16 +91,6 @@ dns_compress_invalidate(dns_compress_t *cctx);
|
||||
* 'cctx' to be initalised.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_compress_localinvalidate(dns_compress_t *cctx);
|
||||
|
||||
/*
|
||||
* Destroys 'cctx->local'.
|
||||
*
|
||||
* Requires:
|
||||
* 'cctx' to be initalised.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed);
|
||||
|
||||
@@ -180,42 +152,13 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name,
|
||||
* ISC_TRUE / ISC_FALSE
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_compress_findlocal(dns_compress_t *cctx, dns_name_t *name,
|
||||
dns_name_t *prefix, dns_name_t *suffix,
|
||||
isc_uint16_t *offset, isc_buffer_t *workspace);
|
||||
|
||||
/*
|
||||
* Finds longest possible match of 'name' in the local compression
|
||||
* RBT. Workspace needs to be large enough to hold 'name' when split
|
||||
* in two (length->name + 3).
|
||||
*
|
||||
* Requires:
|
||||
* 'cctx' to be initalised.
|
||||
* 'name' to be a absolute name.
|
||||
* 'prefix' to be initalised.
|
||||
* 'suffix' to be initalised.
|
||||
* 'offset' to point to a isc_uint16_t.
|
||||
* 'workspace' to be initalised.
|
||||
*
|
||||
* Ensures:
|
||||
* 'prefix', 'suffix' and 'offset' are valid is ISC_TRUE is
|
||||
* returned.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_TRUE / ISC_FALSE
|
||||
*/
|
||||
|
||||
void
|
||||
dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix,
|
||||
dns_name_t *suffix, isc_uint16_t offset,
|
||||
isc_boolean_t local);
|
||||
dns_name_t *suffix, isc_uint16_t offset);
|
||||
/*
|
||||
* Add compression pointers for labels in prefix to RBT's.
|
||||
* If 'prefix' is absolute 'suffix' must be NULL otherwise
|
||||
* suffix must be absolute.
|
||||
* 'local' indicates that the domain name at offset contains
|
||||
* a local compression pointer.
|
||||
*
|
||||
* Requires:
|
||||
* 'cctx' initalised
|
||||
@@ -244,20 +187,6 @@ dns_decompress_init(dns_decompress_t *dctx, int edns, isc_boolean_t strict);
|
||||
* 'dctx' to be a valid pointer.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_decompress_localinit(dns_decompress_t *dctx, dns_name_t *name,
|
||||
isc_buffer_t *source);
|
||||
|
||||
/*
|
||||
* Initalises 'dctx->name' from name.
|
||||
* Records 'source->current' as the start of the rdata section.
|
||||
*
|
||||
* Requires:
|
||||
* 'dctx' to be initalised
|
||||
* 'name' to be absolute
|
||||
* 'source' to be a BINARY buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_decompress_invalidate(dns_decompress_t *dctx);
|
||||
|
||||
@@ -268,16 +197,6 @@ dns_decompress_invalidate(dns_decompress_t *dctx);
|
||||
* 'dctx' to be initalised
|
||||
*/
|
||||
|
||||
void
|
||||
dns_decompress_localinvalidate(dns_decompress_t *dctx);
|
||||
|
||||
/*
|
||||
* Invalidates 'dctx->name'.
|
||||
*
|
||||
* Requires:
|
||||
* 'dctx' to be initalised
|
||||
*/
|
||||
|
||||
void
|
||||
dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed);
|
||||
|
||||
|
@@ -96,7 +96,6 @@ ISC_LANG_BEGINDECLS
|
||||
|
||||
#define DNS_LABELTYPE_GLOBALCOMP16 0x40
|
||||
#define DNS_LABELTYPE_BITSTRING 0x41
|
||||
#define DNS_LABELTYPE_LOCALCOMP 0x42
|
||||
|
||||
/***
|
||||
*** Properties
|
||||
|
@@ -708,9 +708,9 @@ getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
getrdata(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
||||
dns_decompress_t *dctx, dns_rdataclass_t rdclass,
|
||||
dns_rdatatype_t rdtype, unsigned int rdatalen, dns_rdata_t *rdata)
|
||||
getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||
dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
|
||||
unsigned int rdatalen, dns_rdata_t *rdata)
|
||||
{
|
||||
isc_buffer_t *scratch;
|
||||
isc_result_t result;
|
||||
@@ -735,7 +735,6 @@ getrdata(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
||||
scratch = currentbuffer(msg);
|
||||
|
||||
isc_buffer_setactive(source, rdatalen);
|
||||
dns_decompress_localinit(dctx, name, source);
|
||||
|
||||
/*
|
||||
* First try: use current buffer.
|
||||
@@ -1087,12 +1086,11 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||
attributes = DNS_NAMEATTR_DNAME;
|
||||
skip_name_search = ISC_TRUE;
|
||||
}
|
||||
result = getrdata(name, source, msg, dctx,
|
||||
msg->rdclass, rdtype,
|
||||
rdatalen, rdata);
|
||||
result = getrdata(source, msg, dctx, msg->rdclass,
|
||||
rdtype, rdatalen, rdata);
|
||||
} else
|
||||
result = getrdata(name, source, msg, dctx,
|
||||
rdclass, rdtype, rdatalen, rdata);
|
||||
result = getrdata(source, msg, dctx, rdclass,
|
||||
rdtype, rdatalen, rdata);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto cleanup;
|
||||
rdata->rdclass = rdclass;
|
||||
|
165
lib/dns/name.c
165
lib/dns/name.c
@@ -59,8 +59,7 @@ typedef enum {
|
||||
fw_ordinary,
|
||||
fw_copy,
|
||||
fw_bitstring,
|
||||
fw_newcurrent,
|
||||
fw_local
|
||||
fw_newcurrent
|
||||
} fw_state;
|
||||
|
||||
static char digitvalue[256] = {
|
||||
@@ -2125,8 +2124,8 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
{
|
||||
unsigned char *cdata, *ndata;
|
||||
unsigned int cused, hops, nrem, nused, labels, n, i, ll;
|
||||
unsigned int current, new_current, biggest_pointer, lcount;
|
||||
isc_boolean_t saw_bitstring, done, local;
|
||||
unsigned int current, new_current, biggest_pointer;
|
||||
isc_boolean_t saw_bitstring, done;
|
||||
fw_state state = fw_start;
|
||||
unsigned int c;
|
||||
unsigned char *offsets;
|
||||
@@ -2170,7 +2169,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
*/
|
||||
labels = 0;
|
||||
hops = 0;
|
||||
local = ISC_FALSE;
|
||||
saw_bitstring = ISC_FALSE;
|
||||
done = ISC_FALSE;
|
||||
ndata = (unsigned char *)target->base + target->used;
|
||||
@@ -2210,14 +2208,10 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
} else if (c >= 128 && c < 192) {
|
||||
/*
|
||||
* 14 bit local compression pointer.
|
||||
* Local compression is no longer an
|
||||
* IETF draft.
|
||||
*/
|
||||
if ((dctx->allowed & DNS_COMPRESS_LOCAL) ==
|
||||
0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
local = ISC_TRUE;
|
||||
new_current = c & 0x3F;
|
||||
n = 1;
|
||||
state = fw_newcurrent;
|
||||
return (DNS_R_BADLABELTYPE);
|
||||
} else if (c >= 192) {
|
||||
/*
|
||||
* Ordinary 14-bit pointer.
|
||||
@@ -2225,7 +2219,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
|
||||
0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
local = ISC_FALSE;
|
||||
new_current = c & 0x3F;
|
||||
n = 1;
|
||||
state = fw_newcurrent;
|
||||
@@ -2245,18 +2238,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
if ((dctx->allowed & DNS_COMPRESS_GLOBAL16) ==
|
||||
0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
local = ISC_FALSE;
|
||||
new_current = 0;
|
||||
n = 2;
|
||||
state = fw_newcurrent;
|
||||
} else if (c == DNS_LABELTYPE_LOCALCOMP) {
|
||||
/*
|
||||
* 16 bit local compression.
|
||||
*/
|
||||
if ((dctx->allowed & DNS_COMPRESS_LOCAL) ==
|
||||
0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
local = ISC_TRUE;
|
||||
new_current = 0;
|
||||
n = 2;
|
||||
state = fw_newcurrent;
|
||||
@@ -2293,89 +2274,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
n--;
|
||||
if (n != 0)
|
||||
break;
|
||||
if (local && new_current < 256) {
|
||||
/* logical label count */
|
||||
if (new_current == 255)
|
||||
return (DNS_R_BADPOINTER);
|
||||
lcount = dctx->owner_name.labels;
|
||||
if (lcount == 1)
|
||||
return (DNS_R_BADPOINTER);
|
||||
lcount--;
|
||||
i = 0;
|
||||
ll = 0;
|
||||
/*
|
||||
* Work down owner label from TLD until we
|
||||
* have found 'new_current + 1' logical labels.
|
||||
*/
|
||||
while (i <= lcount && ll <= new_current) {
|
||||
dns_name_getlabel(&dctx->owner_name,
|
||||
lcount - i - 1,
|
||||
&label);
|
||||
labeltype = dns_label_type(&label);
|
||||
if (labeltype ==
|
||||
dns_labeltype_ordinary) {
|
||||
i++;
|
||||
ll++;
|
||||
continue;
|
||||
}
|
||||
INSIST(labeltype ==
|
||||
dns_labeltype_bitstring);
|
||||
bits = dns_label_countbits(&label);
|
||||
if (bits + ll <= new_current) {
|
||||
i++;
|
||||
ll += bits;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Logical label count inside current
|
||||
* label.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (i > lcount)
|
||||
return (DNS_R_BADPOINTER);
|
||||
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;
|
||||
/*
|
||||
* 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);
|
||||
} while (bits != 0);
|
||||
labels++;
|
||||
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,
|
||||
i + 1, &suffix);
|
||||
if (suffix.length > nrem)
|
||||
return (DNS_R_NOSPACE);
|
||||
memcpy(ndata, suffix.ndata, suffix.length);
|
||||
ndata += suffix.length;
|
||||
nused += suffix.length;
|
||||
nrem -= suffix.length;
|
||||
labels += suffix.labels;
|
||||
done = ISC_TRUE;
|
||||
break;
|
||||
}
|
||||
if (local)
|
||||
new_current += dctx->rdata - 256;
|
||||
if (new_current >= biggest_pointer)
|
||||
return (DNS_R_BADPOINTER);
|
||||
biggest_pointer = new_current;
|
||||
@@ -2424,15 +2322,10 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
|
||||
unsigned int methods;
|
||||
isc_uint16_t offset;
|
||||
dns_name_t gp, gs;
|
||||
dns_name_t lp, ls;
|
||||
isc_boolean_t gf;
|
||||
isc_boolean_t lf;
|
||||
isc_uint16_t go;
|
||||
isc_uint16_t lo;
|
||||
unsigned char gb[257];
|
||||
unsigned char lb[257];
|
||||
isc_buffer_t gws;
|
||||
isc_buffer_t lws;
|
||||
|
||||
/*
|
||||
* Convert 'name' into wire format, compressing it as specified by the
|
||||
@@ -2443,12 +2336,9 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
|
||||
REQUIRE(cctx != NULL);
|
||||
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
|
||||
|
||||
dns_name_init(&lp, NULL);
|
||||
dns_name_init(&gp, NULL);
|
||||
dns_name_init(&ls, NULL);
|
||||
dns_name_init(&gs, NULL);
|
||||
isc_buffer_init(&gws, gb, sizeof gb, ISC_BUFFERTYPE_BINARY);
|
||||
isc_buffer_init(&lws, lb, sizeof lb, ISC_BUFFERTYPE_BINARY);
|
||||
|
||||
offset = target->used; /*XXX*/
|
||||
|
||||
@@ -2459,30 +2349,12 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
|
||||
else
|
||||
gf = ISC_FALSE;
|
||||
|
||||
if ((methods & DNS_COMPRESS_LOCAL) != 0)
|
||||
lf = dns_compress_findlocal(cctx, name, &lp, &ls, &lo, &lws);
|
||||
else
|
||||
lf = ISC_FALSE;
|
||||
|
||||
/*
|
||||
* 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 + ((lo < 16384) ? 2 : 3)) <
|
||||
(gp.length + ((go < 16384) ? 2 : 3)))
|
||||
gf = ISC_FALSE;
|
||||
else
|
||||
lf = ISC_FALSE;
|
||||
}
|
||||
|
||||
if (gf) {
|
||||
if (target->length - target->used < gp.length)
|
||||
return (DNS_R_NOSPACE);
|
||||
@@ -2503,35 +2375,14 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx,
|
||||
isc_buffer_putuint16(target, go);
|
||||
}
|
||||
if (gp.length != 0)
|
||||
dns_compress_add(cctx, &gp, &gs, offset, ISC_FALSE);
|
||||
} else if (lf) {
|
||||
if (target->length - target->used < lp.length)
|
||||
return (DNS_R_NOSPACE);
|
||||
(void)memcpy((unsigned char *)target->base + target->used,
|
||||
lp.ndata, (size_t)lp.length);
|
||||
isc_buffer_add(target, lp.length);
|
||||
if (lo < 16384) {
|
||||
lo |= 0x8000;
|
||||
if (target->length - target->used < 2)
|
||||
return (DNS_R_NOSPACE);
|
||||
isc_buffer_putuint16(target, lo);
|
||||
} else {
|
||||
if (target->length - target->used < 3)
|
||||
return (DNS_R_NOSPACE);
|
||||
*((unsigned char*)target->base + target->used) =
|
||||
DNS_LABELTYPE_LOCALCOMP;
|
||||
isc_buffer_add(target, 1);
|
||||
isc_buffer_putuint16(target, lo);
|
||||
}
|
||||
if (lp.length != 0)
|
||||
dns_compress_add(cctx, &lp, &ls, offset, ISC_TRUE);
|
||||
dns_compress_add(cctx, &gp, &gs, offset);
|
||||
} else {
|
||||
if (target->length - target->used < name->length)
|
||||
return (DNS_R_NOSPACE);
|
||||
(void)memcpy((unsigned char *)target->base + target->used,
|
||||
name->ndata, (size_t)name->length);
|
||||
isc_buffer_add(target, name->length);
|
||||
dns_compress_add(cctx, name, NULL, offset, ISC_FALSE);
|
||||
dns_compress_add(cctx, name, NULL, offset);
|
||||
}
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
|
@@ -345,12 +345,7 @@ dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
|
||||
/*
|
||||
* Write the rdata.
|
||||
*/
|
||||
result = dns_compress_localinit(cctx, &name, target);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto rollback;
|
||||
|
||||
result = dns_rdata_towire(&rdata, cctx, target);
|
||||
dns_compress_localinvalidate(cctx);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto rollback;
|
||||
|
||||
|
@@ -394,12 +394,7 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
||||
rdata = shuffled[i];
|
||||
else
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
result = dns_compress_localinit(cctx, owner_name,
|
||||
target);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto rollback;
|
||||
result = dns_rdata_towire(&rdata, cctx, target);
|
||||
dns_compress_localinvalidate(cctx);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto rollback;
|
||||
INSIST((target->used >= rdlen.used + 2) &&
|
||||
|
@@ -620,7 +620,6 @@ struct dc_method_map {
|
||||
{ DNS_COMPRESS_GLOBAL14, "DNS_COMPRESS_GLOBAL14" },
|
||||
{ DNS_COMPRESS_GLOBAL16, "DNS_COMPRESS_GLOBAL16" },
|
||||
{ DNS_COMPRESS_GLOBAL, "DNS_COMPRESS_GLOBAL" },
|
||||
{ DNS_COMPRESS_LOCAL, "DNS_COMPRESS_LOCAL" },
|
||||
{ DNS_COMPRESS_ALL, "DNS_COMPRESS_ALL" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
Reference in New Issue
Block a user