mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 08:05:21 +00:00
4718. [func] Avoid seaching for a owner name compression pointer
more than once when writing out a RRset. [RT #45802]
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
|||||||
|
4718. [func] Avoid seaching for a owner name compression pointer
|
||||||
|
more than once when writing out a RRset. [RT #45802]
|
||||||
|
|
||||||
4717. [bug] Treat replies with QCOUNT=0 as truncated if TC=1,
|
4717. [bug] Treat replies with QCOUNT=0 as truncated if TC=1,
|
||||||
FORMERR if TC=0, and log the error correctly.
|
FORMERR if TC=0, and log the error correctly.
|
||||||
[RT #45836]
|
[RT #45836]
|
||||||
|
@@ -739,6 +739,9 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
||||||
isc_buffer_t *target);
|
isc_buffer_t *target);
|
||||||
|
isc_result_t
|
||||||
|
dns_name_towire2(const dns_name_t *name, dns_compress_t *cctx,
|
||||||
|
isc_buffer_t *target, isc_uint16_t *comp_offsetp);
|
||||||
/*%<
|
/*%<
|
||||||
* Convert 'name' into wire format, compressing it as specified by the
|
* Convert 'name' into wire format, compressing it as specified by the
|
||||||
* compression context 'cctx', and storing the result in 'target'.
|
* compression context 'cctx', and storing the result in 'target'.
|
||||||
|
@@ -1987,6 +1987,13 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
|||||||
isc_result_t
|
isc_result_t
|
||||||
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
||||||
isc_buffer_t *target)
|
isc_buffer_t *target)
|
||||||
|
{
|
||||||
|
return (dns_name_towire2(name, cctx, target, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_name_towire2(const dns_name_t *name, dns_compress_t *cctx,
|
||||||
|
isc_buffer_t *target, isc_uint16_t *comp_offsetp)
|
||||||
{
|
{
|
||||||
unsigned int methods;
|
unsigned int methods;
|
||||||
isc_uint16_t offset;
|
isc_uint16_t offset;
|
||||||
@@ -2005,6 +2012,23 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
|||||||
REQUIRE(cctx != NULL);
|
REQUIRE(cctx != NULL);
|
||||||
REQUIRE(ISC_BUFFER_VALID(target));
|
REQUIRE(ISC_BUFFER_VALID(target));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this exact name was already rendered before, and the
|
||||||
|
* offset of the previously rendered name is passed to us, write
|
||||||
|
* a compression pointer directly.
|
||||||
|
*/
|
||||||
|
methods = dns_compress_getmethods(cctx);
|
||||||
|
if (comp_offsetp != NULL && *comp_offsetp < 0x4000 &&
|
||||||
|
(name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
|
||||||
|
(methods & DNS_COMPRESS_GLOBAL14) != 0) {
|
||||||
|
if (ISC_UNLIKELY(target->length - target->used < 2))
|
||||||
|
return (ISC_R_NOSPACE);
|
||||||
|
offset = *comp_offsetp;
|
||||||
|
offset |= 0xc000;
|
||||||
|
isc_buffer_putuint16(target, offset);
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If 'name' doesn't have an offsets table, make a clone which
|
* If 'name' doesn't have an offsets table, make a clone which
|
||||||
* has one.
|
* has one.
|
||||||
@@ -2022,8 +2046,6 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
|||||||
|
|
||||||
offset = target->used; /*XXX*/
|
offset = target->used; /*XXX*/
|
||||||
|
|
||||||
methods = dns_compress_getmethods(cctx);
|
|
||||||
|
|
||||||
if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
|
if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
|
||||||
(methods & DNS_COMPRESS_GLOBAL14) != 0)
|
(methods & DNS_COMPRESS_GLOBAL14) != 0)
|
||||||
gf = dns_compress_findglobal(cctx, name, &gp, &go);
|
gf = dns_compress_findglobal(cctx, name, &gp, &go);
|
||||||
@@ -2034,7 +2056,7 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
|||||||
* If the offset is too high for 14 bit global compression, we're
|
* If the offset is too high for 14 bit global compression, we're
|
||||||
* out of luck.
|
* out of luck.
|
||||||
*/
|
*/
|
||||||
if (gf && go >= 0x4000)
|
if (gf && ISC_UNLIKELY(go >= 0x4000))
|
||||||
gf = ISC_FALSE;
|
gf = ISC_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2044,25 +2066,32 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
|
|||||||
gf = ISC_FALSE;
|
gf = ISC_FALSE;
|
||||||
|
|
||||||
if (gf) {
|
if (gf) {
|
||||||
if (target->length - target->used < gp.length)
|
if (ISC_UNLIKELY(target->length - target->used < gp.length))
|
||||||
return (ISC_R_NOSPACE);
|
return (ISC_R_NOSPACE);
|
||||||
(void)memmove((unsigned char *)target->base + target->used,
|
(void)memmove((unsigned char *)target->base + target->used,
|
||||||
gp.ndata, (size_t)gp.length);
|
gp.ndata, (size_t)gp.length);
|
||||||
isc_buffer_add(target, gp.length);
|
isc_buffer_add(target, gp.length);
|
||||||
go |= 0xc000;
|
if (ISC_UNLIKELY(target->length - target->used < 2))
|
||||||
if (target->length - target->used < 2)
|
|
||||||
return (ISC_R_NOSPACE);
|
return (ISC_R_NOSPACE);
|
||||||
isc_buffer_putuint16(target, go);
|
isc_buffer_putuint16(target, go | 0xc000);
|
||||||
if (gp.length != 0)
|
if (gp.length != 0) {
|
||||||
dns_compress_add(cctx, name, &gp, offset);
|
dns_compress_add(cctx, name, &gp, offset);
|
||||||
|
if (comp_offsetp != NULL)
|
||||||
|
*comp_offsetp = offset;
|
||||||
|
} else if (comp_offsetp != NULL) {
|
||||||
|
*comp_offsetp = go;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (target->length - target->used < name->length)
|
if (ISC_UNLIKELY(target->length - target->used < name->length))
|
||||||
return (ISC_R_NOSPACE);
|
return (ISC_R_NOSPACE);
|
||||||
(void)memmove((unsigned char *)target->base + target->used,
|
(void)memmove((unsigned char *)target->base + target->used,
|
||||||
name->ndata, (size_t)name->length);
|
name->ndata, (size_t)name->length);
|
||||||
isc_buffer_add(target, name->length);
|
isc_buffer_add(target, name->length);
|
||||||
dns_compress_add(cctx, name, name, offset);
|
dns_compress_add(cctx, name, name, offset);
|
||||||
|
if (comp_offsetp != NULL)
|
||||||
|
*comp_offsetp = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -324,6 +324,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
|
|||||||
struct towire_sort *out = out_fixed;
|
struct towire_sort *out = out_fixed;
|
||||||
dns_fixedname_t fixed;
|
dns_fixedname_t fixed;
|
||||||
dns_name_t *name;
|
dns_name_t *name;
|
||||||
|
isc_uint16_t offset;
|
||||||
|
|
||||||
UNUSED(state);
|
UNUSED(state);
|
||||||
|
|
||||||
@@ -464,6 +465,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
|
|||||||
name = dns_fixedname_name(&fixed);
|
name = dns_fixedname_name(&fixed);
|
||||||
dns_name_copy(owner_name, name, NULL);
|
dns_name_copy(owner_name, name, NULL);
|
||||||
dns_rdataset_getownercase(rdataset, name);
|
dns_rdataset_getownercase(rdataset, name);
|
||||||
|
offset = 0xffff;
|
||||||
|
|
||||||
name->attributes |= owner_name->attributes &
|
name->attributes |= owner_name->attributes &
|
||||||
DNS_NAMEATTR_NOCOMPRESS;
|
DNS_NAMEATTR_NOCOMPRESS;
|
||||||
@@ -475,7 +477,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
|
|||||||
|
|
||||||
rrbuffer = *target;
|
rrbuffer = *target;
|
||||||
dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
|
dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
|
||||||
result = dns_name_towire(name, cctx, target);
|
result = dns_name_towire2(name, cctx, target, &offset);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto rollback;
|
goto rollback;
|
||||||
headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
|
headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
|
||||||
|
Reference in New Issue
Block a user