mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 08:05:21 +00:00
1541. [func] NSEC now uses new bitmap format.
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -1,6 +1,6 @@
|
||||
1542. [placeholder]
|
||||
|
||||
1541. [placeholder] rt10038
|
||||
1541. [func] NSEC now uses new bitmap format.
|
||||
|
||||
1540. [placeholder] rt8934
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dnssec-signzone.c,v 1.170 2003/10/01 04:10:26 marka Exp $ */
|
||||
/* $Id: dnssec-signzone.c,v 1.171 2003/12/13 04:20:42 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -652,11 +652,11 @@ nsec_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type,
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_nsec_t nsec;
|
||||
unsigned int newlen;
|
||||
unsigned char bitmap[16];
|
||||
unsigned char nsecdata[16 + DNS_NAME_MAXWIRE];
|
||||
unsigned char bitmap[8192 + 512];
|
||||
unsigned char nsecdata[8192 + 512 + DNS_NAME_MAXWIRE];
|
||||
isc_boolean_t answer = ISC_FALSE;
|
||||
|
||||
INSIST(type < 128);
|
||||
unsigned int i, len, window;
|
||||
int octet;
|
||||
|
||||
result = dns_rdataset_first(rdataset);
|
||||
check_result(result, "dns_rdataset_first()");
|
||||
@@ -666,14 +666,34 @@ nsec_setbit(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type,
|
||||
|
||||
INSIST(nsec.len <= sizeof(bitmap));
|
||||
|
||||
newlen = sizeof(bitmap);
|
||||
newlen = 0;
|
||||
|
||||
memset(bitmap, 0, sizeof(bitmap));
|
||||
memcpy(bitmap, nsec.typebits, nsec.len);
|
||||
set_bit(bitmap, type, val);
|
||||
|
||||
while (newlen > 0 && bitmap[newlen - 1] == 0)
|
||||
newlen--;
|
||||
for (i = 0; i < nsec.len; i += len) {
|
||||
INSIST(i + 2 <= nsec.len);
|
||||
window = nsec.typebits[i];
|
||||
len = nsec.typebits[i+1];
|
||||
i += 2;
|
||||
INSIST(len > 0 && len <= 32);
|
||||
INSIST(i + len <= nsec.len);
|
||||
memmove(&bitmap[window * 32 + 512], &nsec.typebits[i], len);
|
||||
}
|
||||
set_bit(bitmap + 512, type, val);
|
||||
for (window = 0; window < 256; window++) {
|
||||
for (octet = 31; octet >= 0; octet--)
|
||||
if (bitmap[window * 32 + 512 + octet] != 0)
|
||||
break;
|
||||
if (octet < 0)
|
||||
continue;
|
||||
bitmap[newlen] = window;
|
||||
bitmap[newlen + 1] = octet + 1;
|
||||
newlen += 2;
|
||||
/*
|
||||
* Overlapping move.
|
||||
*/
|
||||
memmove(&bitmap[newlen], &bitmap[window * 32 + 512], octet + 1);
|
||||
newlen += octet + 1;
|
||||
}
|
||||
if (newlen != nsec.len ||
|
||||
memcmp(nsec.typebits, bitmap, newlen) != 0) {
|
||||
dns_rdata_t newrdata = DNS_RDATA_INIT;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: nsec.h,v 1.2 2003/09/30 06:00:39 marka Exp $ */
|
||||
/* $Id: nsec.h,v 1.3 2003/12/13 04:20:43 marka Exp $ */
|
||||
|
||||
#ifndef DNS_NSEC_H
|
||||
#define DNS_NSEC_H 1
|
||||
@@ -23,8 +23,9 @@
|
||||
#include <isc/lang.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
#include <dns/name.h>
|
||||
|
||||
#define DNS_NSEC_BUFFERSIZE (256 + 16)
|
||||
#define DNS_NSEC_BUFFERSIZE (DNS_NAME_MAXWIRE + 8192 + 512)
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
@@ -59,8 +60,6 @@ dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type);
|
||||
*
|
||||
* Requires:
|
||||
* 'nsec' points to a valid rdataset of type NSEC
|
||||
* 'type' < 128
|
||||
*
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: nsec.c,v 1.3 2003/10/01 04:07:27 marka Exp $ */
|
||||
/* $Id: nsec.c,v 1.4 2003/12/13 04:20:43 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -69,9 +69,10 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
||||
isc_result_t result;
|
||||
dns_rdataset_t rdataset;
|
||||
isc_region_t r;
|
||||
int i;
|
||||
unsigned int i, window;
|
||||
int octet;
|
||||
|
||||
unsigned char *nsec_bits;
|
||||
unsigned char *nsec_bits, *bm;
|
||||
unsigned int max_type;
|
||||
dns_rdatasetiter_t *rdsiter;
|
||||
|
||||
@@ -79,8 +80,13 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
||||
dns_name_toregion(target, &r);
|
||||
memcpy(buffer, r.base, r.length);
|
||||
r.base = buffer;
|
||||
/*
|
||||
* Use the end of the space for a raw bitmap leaving enough
|
||||
* space for the window identifiers and length octets.
|
||||
*/
|
||||
bm = r.base + r.length + 512;
|
||||
nsec_bits = r.base + r.length;
|
||||
set_bit(nsec_bits, dns_rdatatype_nsec, 1);
|
||||
set_bit(bm, dns_rdatatype_nsec, 1);
|
||||
max_type = dns_rdatatype_nsec;
|
||||
dns_rdataset_init(&rdataset);
|
||||
rdsiter = NULL;
|
||||
@@ -92,13 +98,10 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
||||
result = dns_rdatasetiter_next(rdsiter))
|
||||
{
|
||||
dns_rdatasetiter_current(rdsiter, &rdataset);
|
||||
if (rdataset.type > 127)
|
||||
/* XXX "rdataset type too large" */
|
||||
return (ISC_R_RANGE);
|
||||
if (rdataset.type != dns_rdatatype_nsec) {
|
||||
if (rdataset.type > max_type)
|
||||
max_type = rdataset.type;
|
||||
set_bit(nsec_bits, rdataset.type, 1);
|
||||
set_bit(bm, rdataset.type, 1);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
}
|
||||
@@ -106,12 +109,12 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
||||
/*
|
||||
* At zone cuts, deny the existence of glue in the parent zone.
|
||||
*/
|
||||
if (bit_isset(nsec_bits, dns_rdatatype_ns) &&
|
||||
! bit_isset(nsec_bits, dns_rdatatype_soa)) {
|
||||
for (i = 0; i < 128; i++) {
|
||||
if (bit_isset(nsec_bits, i) &&
|
||||
if (bit_isset(bm, dns_rdatatype_ns) &&
|
||||
! bit_isset(bm, dns_rdatatype_soa)) {
|
||||
for (i = 0; i <= max_type; i++) {
|
||||
if (bit_isset(bm, i) &&
|
||||
! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
|
||||
set_bit(nsec_bits, i, 0);
|
||||
set_bit(bm, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +122,23 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
|
||||
if (result != ISC_R_NOMORE)
|
||||
return (result);
|
||||
|
||||
r.length += max_type / 8 + 1;
|
||||
for (window = 0; window < 256; window++) {
|
||||
if (window * 256 > max_type)
|
||||
break;
|
||||
for (octet = 31; octet >= 0; octet--)
|
||||
if (bm[window * 32 + octet] != 0)
|
||||
break;
|
||||
if (octet < 0)
|
||||
continue;
|
||||
nsec_bits[0] = window;
|
||||
nsec_bits[1] = octet + 1;
|
||||
/*
|
||||
* Note: potential overlapping move.
|
||||
*/
|
||||
memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
|
||||
nsec_bits += 3 + octet;
|
||||
}
|
||||
r.length = nsec_bits - r.base;
|
||||
INSIST(r.length <= DNS_NSEC_BUFFERSIZE);
|
||||
dns_rdata_fromregion(rdata,
|
||||
dns_db_class(db),
|
||||
@@ -168,19 +187,32 @@ dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) {
|
||||
dns_rdata_nsec_t nsecstruct;
|
||||
isc_result_t result;
|
||||
isc_boolean_t present;
|
||||
unsigned int i, len, window;
|
||||
|
||||
REQUIRE(nsec != NULL);
|
||||
REQUIRE(nsec->type == dns_rdatatype_nsec);
|
||||
REQUIRE(type < 128);
|
||||
|
||||
/* This should never fail */
|
||||
result = dns_rdata_tostruct(nsec, &nsecstruct, NULL);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
||||
if (type >= nsecstruct.len * 8)
|
||||
present = ISC_FALSE;
|
||||
else
|
||||
present = ISC_TF(bit_isset(nsecstruct.typebits, type));
|
||||
for (i = 0; i < nsecstruct.len; i += len) {
|
||||
INSIST(i + 2 <= nsecstruct.len);
|
||||
window = nsecstruct.typebits[i];
|
||||
len = nsecstruct.typebits[i + 1];
|
||||
INSIST(len > 0 && len <= 32);
|
||||
i += 2;
|
||||
INSIST(i + len <= nsecstruct.len);
|
||||
if (window * 256 > type)
|
||||
break;
|
||||
if ((window + 1) * 256 <= type)
|
||||
continue;
|
||||
if (type < (window * 256) + len * 8)
|
||||
present = ISC_TF(bit_isset(&nsecstruct.typebits[i],
|
||||
type % 256));
|
||||
break;
|
||||
}
|
||||
dns_rdata_freestruct(&nsec);
|
||||
return (present);
|
||||
}
|
||||
|
@@ -15,11 +15,11 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: nsec_47.c,v 1.2 2003/09/30 06:00:40 marka Exp $ */
|
||||
/* $Id: nsec_47.c,v 1.3 2003/12/13 04:20:43 marka Exp $ */
|
||||
|
||||
/* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */
|
||||
|
||||
/* RFC 2535 */
|
||||
/* draft-ietf-dnsext-nsec-rdata-01.txt */
|
||||
|
||||
#ifndef RDATA_GENERIC_NSEC_47_C
|
||||
#define RDATA_GENERIC_NSEC_47_C
|
||||
@@ -38,9 +38,9 @@ fromtext_nsec(ARGS_FROMTEXT) {
|
||||
char *e;
|
||||
unsigned char bm[8*1024]; /* 64k bits */
|
||||
dns_rdatatype_t covered;
|
||||
dns_rdatatype_t maxcovered = 0;
|
||||
isc_boolean_t first = ISC_TRUE;
|
||||
long n;
|
||||
int octet;
|
||||
int window;
|
||||
|
||||
REQUIRE(type == 47);
|
||||
|
||||
@@ -64,36 +64,35 @@ fromtext_nsec(ARGS_FROMTEXT) {
|
||||
isc_tokentype_string, ISC_TRUE));
|
||||
if (token.type != isc_tokentype_string)
|
||||
break;
|
||||
n = strtol(DNS_AS_STR(token), &e, 10);
|
||||
if (e != DNS_AS_STR(token) && *e == '\0') {
|
||||
covered = (dns_rdatatype_t)n;
|
||||
} else if (dns_rdatatype_fromtext(&covered,
|
||||
&token.value.as_textregion) == DNS_R_UNKNOWN)
|
||||
RETTOK(DNS_R_UNKNOWN);
|
||||
/*
|
||||
* NSEC is only specified for types 1..127.
|
||||
*/
|
||||
if (covered < 1 || covered > 127)
|
||||
return (ISC_R_RANGE);
|
||||
if (first || covered > maxcovered)
|
||||
maxcovered = covered;
|
||||
first = ISC_FALSE;
|
||||
RETTOK(dns_rdatatype_fromtext(&covered,
|
||||
&token.value.as_textregion));
|
||||
bm[covered/8] |= (0x80>>(covered%8));
|
||||
} while (1);
|
||||
isc_lex_ungettoken(lexer, &token);
|
||||
if (first)
|
||||
for (window = 0; window < 256 ; window++) {
|
||||
/*
|
||||
* Find if we have a type in this window.
|
||||
*/
|
||||
for (octet = 31; octet >= 0; octet--)
|
||||
if (bm[window * 32 + octet] != 0)
|
||||
break;
|
||||
if (octet < 0)
|
||||
continue;
|
||||
RETERR(uint8_tobuffer(window, target));
|
||||
RETERR(uint8_tobuffer(octet + 1, target));
|
||||
RETERR(mem_tobuffer(target, &bm[window * 32], octet + 1));
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
n = (maxcovered + 8) / 8;
|
||||
return (mem_tobuffer(target, bm, n));
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
totext_nsec(ARGS_TOTEXT) {
|
||||
isc_region_t sr;
|
||||
unsigned int i, j;
|
||||
unsigned int i, j, k;
|
||||
dns_name_t name;
|
||||
dns_name_t prefix;
|
||||
isc_boolean_t sub;
|
||||
unsigned int window, len;
|
||||
|
||||
REQUIRE(rdata->type == 47);
|
||||
REQUIRE(rdata->length != 0);
|
||||
@@ -106,30 +105,44 @@ totext_nsec(ARGS_TOTEXT) {
|
||||
sub = name_prefix(&name, tctx->origin, &prefix);
|
||||
RETERR(dns_name_totext(&prefix, sub, target));
|
||||
|
||||
for (i = 0; i < sr.length; i++) {
|
||||
if (sr.base[i] != 0)
|
||||
for (j = 0; j < 8; j++)
|
||||
if ((sr.base[i] & (0x80 >> j)) != 0) {
|
||||
dns_rdatatype_t t = i * 8 + j;
|
||||
|
||||
for (i = 0; i < sr.length; i += len) {
|
||||
INSIST(i + 2 <= sr.length);
|
||||
window = sr.base[i];
|
||||
len = sr.base[i + 1];
|
||||
INSIST(len > 0 && len <= 32);
|
||||
i += 2;
|
||||
INSIST(i + len <= sr.length);
|
||||
for (j = 0; j < len; j++) {
|
||||
dns_rdatatype_t t;
|
||||
if (sr.base[i + j] == 0)
|
||||
continue;
|
||||
for (k = 0; k < 8; k++) {
|
||||
if ((sr.base[i + j] & (0x80 >> k)) == 0)
|
||||
continue;
|
||||
t = window * 256 + j * 8 + k;
|
||||
RETERR(str_totext(" ", target));
|
||||
if (dns_rdatatype_isknown(t)) {
|
||||
RETERR(dns_rdatatype_totext(t,
|
||||
target));
|
||||
RETERR(dns_rdatatype_totext(t, target));
|
||||
} else {
|
||||
char buf[sizeof("65535")];
|
||||
sprintf(buf, "%u", t);
|
||||
RETERR(str_totext(buf,
|
||||
target));
|
||||
char buf[sizeof("TYPE65535")];
|
||||
sprintf(buf, "TYPE%u", t);
|
||||
RETERR(str_totext(buf, target));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
static /* inline */ isc_result_t
|
||||
fromwire_nsec(ARGS_FROMWIRE) {
|
||||
isc_region_t sr;
|
||||
dns_name_t name;
|
||||
unsigned int window, lastwindow = 0;
|
||||
unsigned int len;
|
||||
isc_boolean_t first = ISC_TRUE;
|
||||
unsigned int i;
|
||||
|
||||
REQUIRE(type == 47);
|
||||
|
||||
@@ -142,9 +155,47 @@ fromwire_nsec(ARGS_FROMWIRE) {
|
||||
RETERR(dns_name_fromwire(&name, source, dctx, downcase, target));
|
||||
|
||||
isc_buffer_activeregion(source, &sr);
|
||||
/* XXXRTH Enforce RFC 2535 length rules if bit 0 is not set. */
|
||||
if (sr.length > 8 * 1024)
|
||||
for (i = 0; i < sr.length; i += len) {
|
||||
/*
|
||||
* Check for overflow.
|
||||
*/
|
||||
if (i + 2 > sr.length)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
window = sr.base[i];
|
||||
len = sr.base[i + 1];
|
||||
i += 2;
|
||||
/*
|
||||
* Check that bitmap windows are in the correct order.
|
||||
*/
|
||||
if (!first && window <= lastwindow)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
/*
|
||||
* Check for legal lengths.
|
||||
*/
|
||||
if (len < 1 || len > 32)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
/*
|
||||
* Check for overflow.
|
||||
*/
|
||||
if (i + len > sr.length)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
/*
|
||||
* The last octet of the bitmap must be non zero.
|
||||
*/
|
||||
if (sr.base[i + len - 1] == 0)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
/*
|
||||
* Type 0 is not valid.
|
||||
*/
|
||||
if (window == 0 && (sr.base[0] & 0x80) != 0)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
lastwindow = window;
|
||||
first = ISC_FALSE;
|
||||
}
|
||||
if (i != sr.length)
|
||||
return (DNS_R_EXTRADATA);
|
||||
if (first)
|
||||
RETERR(DNS_R_FORMERR);
|
||||
RETERR(mem_tobuffer(target, sr.base, sr.length));
|
||||
isc_buffer_forward(source, sr.length);
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -189,6 +240,8 @@ static inline isc_result_t
|
||||
fromstruct_nsec(ARGS_FROMSTRUCT) {
|
||||
dns_rdata_nsec_t *nsec = source;
|
||||
isc_region_t region;
|
||||
unsigned int i, len, window, lastwindow = 0;
|
||||
isc_boolean_t first = ISC_TRUE;
|
||||
|
||||
REQUIRE(type == 47);
|
||||
REQUIRE(source != NULL);
|
||||
@@ -201,7 +254,22 @@ fromstruct_nsec(ARGS_FROMSTRUCT) {
|
||||
|
||||
dns_name_toregion(&nsec->next, ®ion);
|
||||
RETERR(isc_buffer_copyregion(target, ®ion));
|
||||
|
||||
/*
|
||||
* Perform sanity check.
|
||||
*/
|
||||
for (i = 0; i < nsec->len ; i += len) {
|
||||
INSIST(i + 2 <= nsec->len);
|
||||
window = nsec->typebits[i];
|
||||
len = nsec->typebits[i+1];
|
||||
i += 2;
|
||||
INSIST(first || window > lastwindow);
|
||||
INSIST(len > 0 && len <= 32);
|
||||
INSIST(i + len <= nsec->len);
|
||||
INSIST(nsec->typebits[i + len - 1] != 0);
|
||||
lastwindow = window;
|
||||
first = ISC_FALSE;
|
||||
}
|
||||
INSIST(!first);
|
||||
return (mem_tobuffer(target, nsec->typebits, nsec->len));
|
||||
}
|
||||
|
||||
|
@@ -18,9 +18,9 @@
|
||||
#ifndef GENERIC_NSEC_47_H
|
||||
#define GENERIC_NSEC_47_H 1
|
||||
|
||||
/* $Id: nsec_47.h,v 1.2 2003/09/30 06:00:40 marka Exp $ */
|
||||
/* $Id: nsec_47.h,v 1.3 2003/12/13 04:20:44 marka Exp $ */
|
||||
|
||||
/* RFC 2535 */
|
||||
/* draft-ietf-dnsext-nsec-rdata-01.txt */
|
||||
|
||||
typedef struct dns_rdata_nsec {
|
||||
dns_rdatacommon_t common;
|
||||
|
Reference in New Issue
Block a user