summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/dns/rdataslab.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns/rdataslab.c')
-rw-r--r--contrib/bind9/lib/dns/rdataslab.c111
1 files changed, 79 insertions, 32 deletions
diff --git a/contrib/bind9/lib/dns/rdataslab.c b/contrib/bind9/lib/dns/rdataslab.c
index 5d89d01..b22868d 100644
--- a/contrib/bind9/lib/dns/rdataslab.c
+++ b/contrib/bind9/lib/dns/rdataslab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataslab.c,v 1.35.18.8 2007/08/28 07:20:05 tbox Exp $ */
+/* $Id: rdataslab.c,v 1.48.50.2 2009/01/18 23:47:40 tbox Exp $ */
/*! \file */
@@ -33,10 +33,6 @@
#include <dns/rdataset.h>
#include <dns/rdataslab.h>
-#ifndef DNS_RDATASET_FIXED
-#define DNS_RDATASET_FIXED 1
-#endif
-
/*
* The rdataslab structure allows iteration to occur in both load order
* and DNSSEC order. The structure is as follows:
@@ -47,6 +43,7 @@
* data records
* data length (2 bytes)
* order (2 bytes)
+ * meta data (1 byte for RRSIG's)
* data (data length bytes)
*
* If DNS_RDATASET_FIXED is defined to be zero (0) the format of a
@@ -65,7 +62,7 @@
*
* DNSSEC order traversal is performed by walking the data records.
*
- * The order is stored with record to allow for efficient reconstuction of
+ * The order is stored with record to allow for efficient reconstruction
* of the offset table following a merge or subtraction.
*
* The iterator methods here currently only support DNSSEC order iteration.
@@ -141,6 +138,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
#if DNS_RDATASET_FIXED
unsigned int *offsettable;
#endif
+ unsigned int length;
buflen = reservelen + 2;
@@ -209,12 +207,18 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
x[i].order = x[i-1].order;
#endif
nitems--;
- } else
+ } else {
#if DNS_RDATASET_FIXED
buflen += (8 + x[i-1].rdata.length);
#else
buflen += (2 + x[i-1].rdata.length);
#endif
+ /*
+ * Provide space to store the per RR meta data.
+ */
+ if (rdataset->type == dns_rdatatype_rrsig)
+ buflen++;
+ }
}
/*
* Don't forget the last item!
@@ -224,6 +228,11 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
#else
buflen += (2 + x[i-1].rdata.length);
#endif
+ /*
+ * Provide space to store the per RR meta data.
+ */
+ if (rdataset->type == dns_rdatatype_rrsig)
+ buflen++;
/*
* Ensure that singleton types are actually singletons.
@@ -246,7 +255,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
result = ISC_R_NOMEMORY;
goto free_rdatas;
}
-
+
#if DNS_RDATASET_FIXED
/* Allocate temporary offset table. */
offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int));
@@ -280,15 +289,25 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
#if DNS_RDATASET_FIXED
offsettable[x[i].order] = rawbuf - offsetbase;
#endif
- *rawbuf++ = (x[i].rdata.length & 0xff00) >> 8;
- *rawbuf++ = (x[i].rdata.length & 0x00ff);
+ length = x[i].rdata.length;
+ if (rdataset->type == dns_rdatatype_rrsig)
+ length++;
+ *rawbuf++ = (length & 0xff00) >> 8;
+ *rawbuf++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED
rawbuf += 2; /* filled in later */
#endif
+ /*
+ * Store the per RR meta data.
+ */
+ if (rdataset->type == dns_rdatatype_rrsig) {
+ *rawbuf++ |= (x[i].rdata.flags & DNS_RDATA_OFFLINE) ?
+ DNS_RDATASLAB_OFFLINE : 0;
+ }
memcpy(rawbuf, x[i].rdata.data, x[i].rdata.length);
rawbuf += x[i].rdata.length;
}
-
+
#if DNS_RDATASET_FIXED
fillin_offsets(offsetbase, offsettable, nalloc);
isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int));
@@ -360,17 +379,27 @@ static void
rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
unsigned char *raw = rdataset->private5;
isc_region_t r;
+ unsigned int length;
+ unsigned int flags = 0;
REQUIRE(raw != NULL);
- r.length = raw[0] * 256 + raw[1];
+ length = raw[0] * 256 + raw[1];
#if DNS_RDATASET_FIXED
raw += 4;
#else
raw += 2;
-#endif
+#endif
+ if (rdataset->type == dns_rdatatype_rrsig) {
+ if (*raw & DNS_RDATASLAB_OFFLINE)
+ flags |= DNS_RDATA_OFFLINE;
+ length--;
+ raw++;
+ }
+ r.length = length;
r.base = raw;
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
+ rdata->flags |= flags;
}
static void
@@ -405,6 +434,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -474,15 +505,27 @@ rdata_from_slab(unsigned char **current,
{
unsigned char *tcurrent = *current;
isc_region_t region;
+ unsigned int length;
+ isc_boolean_t offline = ISC_FALSE;
- region.length = *tcurrent++ * 256;
- region.length += *tcurrent++;
+ length = *tcurrent++ * 256;
+ length += *tcurrent++;
+
+ if (type == dns_rdatatype_rrsig) {
+ if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0)
+ offline = ISC_TRUE;
+ length--;
+ tcurrent++;
+ }
+ region.length = length;
#if DNS_RDATASET_FIXED
tcurrent += 2;
#endif
region.base = tcurrent;
tcurrent += region.length;
dns_rdata_fromregion(rdata, rdclass, type, &region);
+ if (offline)
+ rdata->flags |= DNS_RDATA_OFFLINE;
*current = tcurrent;
}
@@ -511,7 +554,7 @@ rdata_in_slab(unsigned char *slab, unsigned int reservelen,
for (i = 0; i < count; i++) {
rdata_from_slab(&current, rdclass, type, &trdata);
-
+
n = dns_rdata_compare(&trdata, rdata);
if (n == 0)
return (ISC_TRUE);
@@ -528,9 +571,8 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
dns_rdataclass_t rdclass, dns_rdatatype_t type,
unsigned int flags, unsigned char **tslabp)
{
- unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent;
+ unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data;
unsigned int ocount, ncount, count, olength, tlength, tcount, length;
- isc_region_t nregion;
dns_rdata_t ordata = DNS_RDATA_INIT;
dns_rdata_t nrdata = DNS_RDATA_INIT;
isc_boolean_t added_something = ISC_FALSE;
@@ -603,29 +645,24 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
* the old slab.
*/
do {
- nregion.length = *ncurrent++ * 256;
- nregion.length += *ncurrent++;
-#if DNS_RDATASET_FIXED
- ncurrent += 2; /* Skip order. */
-#endif
- nregion.base = ncurrent;
dns_rdata_init(&nrdata);
- dns_rdata_fromregion(&nrdata, rdclass, type, &nregion);
+ rdata_from_slab(&ncurrent, rdclass, type, &nrdata);
if (!rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata))
{
/*
* This rdata isn't in the old slab.
*/
#if DNS_RDATASET_FIXED
- tlength += nregion.length + 8;
+ tlength += nrdata.length + 8;
#else
- tlength += nregion.length + 2;
+ tlength += nrdata.length + 2;
#endif
+ if (type == dns_rdatatype_rrsig)
+ tlength++;
tcount++;
nncount++;
added_something = ISC_TRUE;
}
- ncurrent += nregion.length;
ncount--;
} while (ncount > 0);
ncount = nncount;
@@ -726,12 +763,17 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
offsettable[oorder] = tcurrent - offsetbase;
#endif
length = ordata.length;
+ data = ordata.data;
+ if (type == dns_rdatatype_rrsig) {
+ length++;
+ data--;
+ }
*tcurrent++ = (length & 0xff00) >> 8;
*tcurrent++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED
tcurrent += 2; /* fill in later */
#endif
- memcpy(tcurrent, ordata.data, length);
+ memcpy(tcurrent, data, length);
tcurrent += length;
oadded++;
if (oadded < ocount) {
@@ -748,12 +790,17 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
offsettable[ocount + norder] = tcurrent - offsetbase;
#endif
length = nrdata.length;
+ data = nrdata.data;
+ if (type == dns_rdatatype_rrsig) {
+ length++;
+ data--;
+ }
*tcurrent++ = (length & 0xff00) >> 8;
*tcurrent++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED
tcurrent += 2; /* fill in later */
#endif
- memcpy(tcurrent, nrdata.data, length);
+ memcpy(tcurrent, data, length);
tcurrent += length;
nadded++;
if (nadded < ncount) {
@@ -799,8 +846,8 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
#if DNS_RDATASET_FIXED
unsigned char *offsetbase;
unsigned int *offsettable;
-#endif
unsigned int order;
+#endif
REQUIRE(tslabp != NULL && *tslabp == NULL);
REQUIRE(mslab != NULL && sslab != NULL);
OpenPOWER on IntegriCloud