summaryrefslogtreecommitdiff
path: root/usr.sbin/bind/lib/dns/rdataset.c
diff options
context:
space:
mode:
authorJakob Schlyter <jakob@cvs.openbsd.org>2004-09-28 17:14:10 +0000
committerJakob Schlyter <jakob@cvs.openbsd.org>2004-09-28 17:14:10 +0000
commitff09ecf5e523f7c1678821dfc8753880775b9bc9 (patch)
treecfbc352a0605ad89a62d844079441dca80fca83d /usr.sbin/bind/lib/dns/rdataset.c
parentae87190605c9d85eaf9ba7728034f343685da32a (diff)
resolve conflicts
Diffstat (limited to 'usr.sbin/bind/lib/dns/rdataset.c')
-rw-r--r--usr.sbin/bind/lib/dns/rdataset.c165
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));
+}