diff --git a/CHANGES b/CHANGES index f375b4d48f..c32b573b7e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1582. [bug] rrset-order failed to work on RRsets with more + than 32 elements. [RT #10381] + 1576. [bug] Race condition in dns_dispatch_addresponse(). [RT# 10272] diff --git a/lib/dns/compress.c b/lib/dns/compress.c index d4ce5a1499..ff766faebb 100644 --- a/lib/dns/compress.c +++ b/lib/dns/compress.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.c,v 1.50 2001/06/04 19:32:59 tale Exp $ */ +/* $Id: compress.c,v 1.50.2.1 2004/02/19 01:59:55 marka Exp $ */ #define DNS_NAME_USEINLINE 1 @@ -45,7 +45,7 @@ dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) { unsigned int i; REQUIRE(cctx != NULL); - REQUIRE(mctx != NULL); + REQUIRE(mctx != NULL); /* See: rdataset.c:towiresorted(). */ cctx->allowed = 0; cctx->edns = edns; diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index f8ab7731c9..914a086247 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -15,13 +15,14 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.c,v 1.58.2.3 2003/08/05 00:42:55 marka Exp $ */ +/* $Id: rdataset.c,v 1.58.2.4 2004/02/19 01:59:55 marka Exp $ */ #include #include #include +#include #include #include @@ -285,8 +286,8 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, unsigned int headlen; isc_boolean_t question = ISC_FALSE; isc_boolean_t shuffle = ISC_FALSE; - dns_rdata_t shuffled[MAX_SHUFFLE]; - struct towire_sort sorted[MAX_SHUFFLE]; + dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE]; + struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE]; UNUSED(state); @@ -298,6 +299,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(countp != NULL); REQUIRE((order == NULL) == (order_arg == NULL)); + REQUIRE(cctx != NULL && cctx->mctx != NULL); count = 0; if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) { @@ -320,18 +322,24 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, } /* - * We'll only shuffle if we've got enough slots in our - * deck. - * - * There's no point to shuffling SIGs. + * Do we want to shuffle this anwer? */ - if (!question && - count > 1 && - !WANT_FIXED(rdataset) && - count <= MAX_SHUFFLE && + if (!question && count > 1 && + (!WANT_FIXED(rdataset) || order != NULL) && rdataset->type != dns_rdatatype_sig) - { shuffle = ISC_TRUE; + + if (shuffle && count > MAX_SHUFFLE) { + shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled)); + sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted)); + if (shuffled == NULL || sorted == NULL) + shuffle = ISC_FALSE; + } else { + shuffled = shuffled_fixed; + sorted = sorted_fixed; + } + + if (shuffle) { /* * First we get handles to all of the rdata. */ @@ -344,7 +352,7 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, result = dns_rdataset_next(rdataset); } while (result == ISC_R_SUCCESS); if (result != ISC_R_NOMORE) - return (result); + goto cleanup; INSIST(i == count); /* * Now we shuffle. @@ -449,21 +457,27 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, *countp += count; - return (ISC_R_SUCCESS); + result = ISC_R_SUCCESS; + goto cleanup; - rollback: + rollback: if (partial && result == ISC_R_NOSPACE) { INSIST(rrbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used); *countp += added; *target = rrbuffer; - return (result); + goto cleanup; } INSIST(savedbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used); *countp = 0; *target = savedbuffer; + cleanup: + if (sorted != NULL && sorted != sorted_fixed) + isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted)); + if (shuffled != NULL && shuffled != shuffled_fixed) + isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled)); return (result); }