diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 2004-09-28 17:14:10 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 2004-09-28 17:14:10 +0000 |
commit | ff09ecf5e523f7c1678821dfc8753880775b9bc9 (patch) | |
tree | cfbc352a0605ad89a62d844079441dca80fca83d /usr.sbin/bind/lib/dns/rdataset.c | |
parent | ae87190605c9d85eaf9ba7728034f343685da32a (diff) |
resolve conflicts
Diffstat (limited to 'usr.sbin/bind/lib/dns/rdataset.c')
-rw-r--r-- | usr.sbin/bind/lib/dns/rdataset.c | 165 |
1 files changed, 125 insertions, 40 deletions
diff --git a/usr.sbin/bind/lib/dns/rdataset.c b/usr.sbin/bind/lib/dns/rdataset.c index 7a950ae1b10..f865adeef81 100644 --- a/usr.sbin/bind/lib/dns/rdataset.c +++ b/usr.sbin/bind/lib/dns/rdataset.c @@ -1,27 +1,28 @@ /* - * Copyright (C) 1999-2001, 2003 Internet Software Consortium. + * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -/* $ISC: rdataset.c,v 1.58.2.3 2003/08/05 00:42:55 marka Exp $ */ +/* $ISC: rdataset.c,v 1.58.2.2.2.10 2004/03/08 09:04:31 marka Exp $ */ #include <config.h> #include <stdlib.h> #include <isc/buffer.h> +#include <isc/mem.h> #include <isc/random.h> #include <isc/util.h> @@ -49,11 +50,13 @@ dns_rdataset_init(dns_rdataset_t *rdataset) { rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; + rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; rdataset->privateuint4 = 0; rdataset->private5 = NULL; + rdataset->private6 = NULL; } void @@ -74,6 +77,7 @@ dns_rdataset_invalidate(dns_rdataset_t *rdataset) { rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; + rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; @@ -100,11 +104,13 @@ dns_rdataset_disassociate(dns_rdataset_t *rdataset) { rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; + rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; rdataset->privateuint4 = 0; rdataset->private5 = NULL; + rdataset->private6 = NULL; } isc_boolean_t @@ -166,7 +172,9 @@ static dns_rdatasetmethods_t question_methods = { question_cursor, question_current, question_clone, - question_count + question_count, + NULL, + NULL }; void @@ -257,6 +265,7 @@ dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { #define MAX_SHUFFLE 32 #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0) +#define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0) struct towire_sort { int key; @@ -274,19 +283,19 @@ static isc_result_t towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, void *order_arg, - isc_boolean_t partial, unsigned int *countp, - void **state) + isc_boolean_t partial, unsigned int options, + unsigned int *countp, void **state) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r; isc_result_t result; - unsigned int i, count, added; + unsigned int i, count, added, choice; isc_buffer_t savedbuffer, rdlen, rrbuffer; 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 +307,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) { @@ -309,7 +319,11 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, /* * This is a negative caching rdataset. */ - return (dns_ncache_towire(rdataset, cctx, target, countp)); + unsigned int ncache_opts = 0; + if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0) + ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC; + return (dns_ncache_towire(rdataset, cctx, target, ncache_opts, + countp)); } else { count = (rdataset->methods->count)(rdataset); result = dns_rdataset_first(rdataset); @@ -320,18 +334,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 && - rdataset->type != dns_rdatatype_sig) - { + if (!question && count > 1 && + (!WANT_FIXED(rdataset) || order != NULL) && + rdataset->type != dns_rdatatype_rrsig) 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,22 +364,42 @@ 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. */ - if (order != NULL) { + if (WANT_FIXED(rdataset)) { /* - * Sorted order. + * 'Fixed' order. */ + INSIST(order != NULL); for (i = 0; i < count; i++) { sorted[i].key = (*order)(&shuffled[i], order_arg); sorted[i].rdata = &shuffled[i]; } - qsort(sorted, count, sizeof(sorted[0]), - towire_compare); + } else if (WANT_RANDOM(rdataset)) { + /* + * 'Random' order. + */ + for (i = 0; i < count; i++) { + dns_rdata_t rdata; + isc_uint32_t val; + + isc_random_get(&val); + choice = i + (val % (count - i)); + rdata = shuffled[i]; + shuffled[i] = shuffled[choice]; + shuffled[choice] = rdata; + if (order != NULL) + sorted[i].key = (*order)(&shuffled[i], + order_arg); + else + sorted[i].key = 0; /* Unused */ + sorted[i].rdata = &shuffled[i]; + } } else { /* * "Cyclic" order. @@ -367,16 +407,29 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, isc_uint32_t val; unsigned int j; - isc_random_get(&val); + val = rdataset->count; + if (val == ISC_UINT32_MAX) + isc_random_get(&val); j = val % count; for (i = 0; i < count; i++) { - sorted[j].key = 0; /* Unused */ + if (order != NULL) + sorted[j].key = (*order)(&shuffled[i], + order_arg); + else + sorted[j].key = 0; /* Unused */ sorted[j].rdata = &shuffled[i]; j++; if (j == count) j = 0; /* Wrap around. */ } } + + /* + * Sorted order. + */ + if (order != NULL) + qsort(sorted, count, sizeof(sorted[0]), + towire_compare); } savedbuffer = *target; @@ -449,7 +502,8 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, *countp += count; - return (ISC_R_SUCCESS); + result = ISC_R_SUCCESS; + goto cleanup; rollback: if (partial && result == ISC_R_NOSPACE) { @@ -457,13 +511,18 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, 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); } @@ -474,10 +533,12 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset, isc_buffer_t *target, dns_rdatasetorderfunc_t order, void *order_arg, + unsigned int options, unsigned int *countp) { return (towiresorted(rdataset, owner_name, cctx, target, - order, order_arg, ISC_FALSE, countp, NULL)); + order, order_arg, ISC_FALSE, options, + countp, NULL)); } isc_result_t @@ -487,12 +548,14 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset, isc_buffer_t *target, dns_rdatasetorderfunc_t order, void *order_arg, + unsigned int options, unsigned int *countp, void **state) { REQUIRE(state == NULL); /* XXX remove when implemented */ return (towiresorted(rdataset, owner_name, cctx, target, - order, order_arg, ISC_TRUE, countp, state)); + order, order_arg, ISC_TRUE, options, + countp, state)); } isc_result_t @@ -500,10 +563,11 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, + unsigned int options, unsigned int *countp) { return (towiresorted(rdataset, owner_name, cctx, target, - NULL, NULL, ISC_FALSE, countp, NULL)); + NULL, NULL, ISC_FALSE, options, countp, NULL)); } isc_result_t @@ -538,4 +602,25 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset, return (ISC_R_SUCCESS); } - + +isc_result_t +dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) { + + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + if (rdataset->methods->addnoqname == NULL) + return (ISC_R_NOTIMPLEMENTED); + return((rdataset->methods->addnoqname)(rdataset, name)); +} + +isc_result_t +dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, + dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) +{ + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (rdataset->methods->getnoqname == NULL) + return (ISC_R_NOTIMPLEMENTED); + return((rdataset->methods->getnoqname)(rdataset, name, nsec, nsecsig)); +} |