4079. [func] Preserve the case of the ownername of records to

the RRset level. [RT #37442]
This commit is contained in:
Mark Andrews 2015-02-27 15:08:38 +11:00
parent 414aa6bc3d
commit a8da00ef95
34 changed files with 593 additions and 109 deletions

View file

@ -1,3 +1,6 @@
4079. [func] Preserve the case of the ownername of records to
the RRset level. [RT #37442]
4078. [bug] Hand the case where CMSG_SPACE(sizeof(int)) !=
CMSG_SPACE(sizeof(int)). [RT #38621]

View file

@ -2380,6 +2380,7 @@ query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset,
result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_rdataset_setownercase(dns64_rdataset, mname);
client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
dns64_rdataset->trust = rdataset->trust;
query_addrdataset(client, mname, dns64_rdataset);
@ -2514,6 +2515,7 @@ query_filter64(ns_client_t *client, dns_name_t **namep,
result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_rdataset_setownercase(myrdataset, name);
client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
if (mname == name) {
if (dbuf != NULL)
@ -2920,11 +2922,11 @@ query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,
rdata->rdclass = client->message->rdclass;
rdata->type = dns_rdatatype_cname;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
== ISC_R_SUCCESS);
rdataset->trust = trust;
dns_rdataset_setownercase(rdataset, aname);
query_addrrset(client, &aname, &rdataset, NULL, NULL,
DNS_SECTION_ANSWER);

View file

@ -224,6 +224,28 @@ struct update_event {
dns_message_t *answer;
};
/*%
* Prepare an RR for the addition of the new RR 'ctx->update_rr',
* with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting
* the RRs if it is replaced by the new RR or has a conflicting TTL.
* The necessary changes are appended to ctx->del_diff and ctx->add_diff;
* we need to do all deletions before any additions so that we don't run
* into transient states with conflicting TTLs.
*/
typedef struct {
dns_db_t *db;
dns_dbversion_t *ver;
dns_diff_t *diff;
dns_name_t *name;
dns_name_t *oldname;
dns_rdata_t *update_rr;
dns_ttl_t update_rr_ttl;
isc_boolean_t ignore_add;
dns_diff_t del_diff;
dns_diff_t add_diff;
} add_rr_prepare_ctx_t;
/**************************************************************************/
/*
* Forward declarations.
@ -233,6 +255,7 @@ static void update_action(isc_task_t *task, isc_event_t *event);
static void updatedone_action(isc_task_t *task, isc_event_t *event);
static isc_result_t send_forward_event(ns_client_t *client, dns_zone_t *zone);
static void forward_done(isc_task_t *task, isc_event_t *event);
static isc_result_t add_rr_prepare_action(void *data, rr_t *rr);
/**************************************************************************/
@ -636,6 +659,7 @@ foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
dns_dbversion_t *oldver = NULL;
dns_fixedname_t fixed;
dns_clientinfomethods_init(&cm, ns_client_sourceip);
@ -673,6 +697,15 @@ foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
if (result != ISC_R_SUCCESS)
goto cleanup_node;
if (rr_action == add_rr_prepare_action) {
add_rr_prepare_ctx_t *ctx = rr_action_data;
dns_fixedname_init(&fixed);
ctx->oldname = dns_fixedname_name(&fixed);
dns_name_copy(name, ctx->oldname, NULL);
dns_rdataset_getownercase(&rdataset, ctx->oldname);
}
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset))
@ -1290,40 +1323,30 @@ delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver,
}
/**************************************************************************/
/*%
* Prepare an RR for the addition of the new RR 'ctx->update_rr',
* with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting
* the RRs if it is replaced by the new RR or has a conflicting TTL.
* The necessary changes are appended to ctx->del_diff and ctx->add_diff;
* we need to do all deletions before any additions so that we don't run
* into transient states with conflicting TTLs.
*/
typedef struct {
dns_db_t *db;
dns_dbversion_t *ver;
dns_diff_t *diff;
dns_name_t *name;
dns_rdata_t *update_rr;
dns_ttl_t update_rr_ttl;
isc_boolean_t ignore_add;
dns_diff_t del_diff;
dns_diff_t add_diff;
} add_rr_prepare_ctx_t;
static isc_result_t
add_rr_prepare_action(void *data, rr_t *rr) {
isc_result_t result = ISC_R_SUCCESS;
add_rr_prepare_ctx_t *ctx = data;
dns_difftuple_t *tuple = NULL;
isc_boolean_t equal;
isc_boolean_t equal, case_equal, ttl_equal;
/*
* If the update RR is a "duplicate" of the update RR,
* Are the new and old cases equal?
*/
case_equal = dns_name_caseequal(ctx->name, ctx->oldname);
/*
* Are the ttl's equal?
*/
ttl_equal = rr->ttl == ctx->update_rr_ttl;
/*
* If the update RR is a "duplicate" of a existing RR,
* the update should be silently ignored.
*/
equal = ISC_TF(dns_rdata_casecompare(&rr->rdata, ctx->update_rr) == 0);
if (equal && rr->ttl == ctx->update_rr_ttl) {
if (equal && case_equal && ttl_equal) {
ctx->ignore_add = ISC_TRUE;
return (ISC_R_SUCCESS);
}
@ -1334,19 +1357,19 @@ add_rr_prepare_action(void *data, rr_t *rr) {
*/
if (replaces_p(ctx->update_rr, &rr->rdata)) {
CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL,
ctx->name, rr->ttl, &rr->rdata,
ctx->oldname, rr->ttl, &rr->rdata,
&tuple));
dns_diff_append(&ctx->del_diff, &tuple);
return (ISC_R_SUCCESS);
}
/*
* If this RR differs in TTL from the update RR,
* its TTL must be adjusted.
* If this RR differs in TTL or case from the update RR,
* its TTL and case must be adjusted.
*/
if (rr->ttl != ctx->update_rr_ttl) {
if (!ttl_equal || !case_equal) {
CHECK(dns_difftuple_create(ctx->del_diff.mctx, DNS_DIFFOP_DEL,
ctx->name, rr->ttl, &rr->rdata,
ctx->oldname, rr->ttl, &rr->rdata,
&tuple));
dns_diff_append(&ctx->del_diff, &tuple);
if (!equal) {
@ -2931,6 +2954,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
ctx.ver = ver;
ctx.diff = &diff;
ctx.name = name;
ctx.oldname = name;
ctx.update_rr = &rdata;
ctx.update_rr_ttl = ttl;
ctx.ignore_add = ISC_FALSE;

View file

@ -15,5 +15,9 @@
# PERFORMANCE OF THIS SOFTWARE.
rm -f dig.ns*.test*
rm -f ns2/example.bk
rm -f ns*/named.lock
rm -f ns1/dynamic.db
rm -f ns1/dynamic.db.jnl
rm -f ns2/dynamic.bk
rm -f ns2/dynamic.bk.jnl
rm -f ns2/example.bk

View file

@ -0,0 +1,6 @@
DyNaMiC. 300 IN SOA mname1. . 2000042407 20 20 1814400 3600
DyNaMiC. 300 IN NS ns1.DYNAMIC.
DyNaMiC. 300 IN MX 0 mail.eXaMpLe.
mAiL.DynamiC. 300 IN A 10.53.0.1
ns1.DYNAMIC. 300 IN A 10.53.0.1
DyNaMiC. 300 IN SOA mname1. . 2000042407 20 20 1814400 3600

View file

@ -0,0 +1,30 @@
; Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
;
; Permission to use, copy, modify, and/or 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 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.
$TTL 300 ; 5 minutes
$ORIGIN DyNaMiC.
@ IN SOA mname1. . (
2000042407 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
$ORIGIN DYNAMIC.
NS ns1
ns1 A 10.53.0.1
$ORIGIN DynamiC.
@ MX 0 mail.eXaMpLe.
mAiL A 10.53.0.1

View file

@ -33,4 +33,12 @@ options {
zone "example" {
type master;
file "example.db";
also-notify { 10.53.0.2; };
};
zone "dynamic" {
type master;
file "dynamic.db";
allow-update { any; };
also-notify { 10.53.0.2; };
};

View file

@ -36,3 +36,9 @@ zone "example" {
file "example.bk";
masters { 10.53.0.1; };
};
zone "dynamic" {
type slave;
file "dynamic.bk";
masters { 10.53.0.1; };
};

View file

@ -0,0 +1,14 @@
; <<>> DiG 9.11.0pre-alpha <<>> axfr dynamic @10.53.0.1 -p 5300
;; global options: +cmd
dYNAMIc. 0 IN SOA mname1. . 2000042409 20 20 1814400 3600
DyNaMiC. 300 IN NS ns1.DYNAMIC.
DyNaMiC. 300 IN MX 0 mail.eXaMpLe.
mAiL.DynamiC. 300 IN A 10.53.0.1
Ns1.DyNaMIC. 300 IN A 10.53.0.1
dYNAMIc. 0 IN SOA mname1. . 2000042409 20 20 1814400 3600
;; Query time: 0 msec
;; SERVER: 10.53.0.1#5300(10.53.0.1)
;; WHEN: Mon Jan 19 14:50:54 EST 2015
;; XFR size: 6 records (messages 1, bytes 234)

View file

@ -0,0 +1,6 @@
dYNAMIc. 300 IN SOA mname1. . 2000042408 20 20 1814400 3600
DyNaMiC. 300 IN NS ns1.DYNAMIC.
DyNaMiC. 300 IN MX 0 mail.eXaMpLe.
mAiL.DynamiC. 300 IN A 10.53.0.1
ns1.DYNAMIC. 300 IN A 10.53.0.1
dYNAMIc. 300 IN SOA mname1. . 2000042408 20 20 1814400 3600

View file

@ -0,0 +1,2 @@
sh clean.sh
cp ns1/dynamic.db.in ns1/dynamic.db

View file

@ -29,6 +29,13 @@ for i in 1 2 3 4 5 6 7 8 9
do
$DIG $DIGOPTS soa example. @10.53.0.2 -p 5300 > dig.ns2.test$n
grep SOA dig.ns2.test$n > /dev/null && break
sleep 1
done
for i in 1 2 3 4 5 6 7 8 9
do
$DIG $DIGOPTS soa dynamic. @10.53.0.2 -p 5300 > dig.ns2.test$n
grep SOA dig.ns2.test$n > /dev/null && break
sleep 1
done
n=`expr $n + 1`
@ -57,5 +64,78 @@ grep "mail.example" dig.ns2.test$n > /dev/null || ret=1
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:testing load of dynamic zone with various \$ORIGIN values ($n)"
ret=0
$DIG axfr dynamic @10.53.0.1 -p 5300 > dig.ns1.test$n
$PERL ../digcomp.pl dig.ns1.test$n dynamic.good || ret=1
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:transfer of dynamic zone with various \$ORIGIN values ($n)"
ret=0
$DIG axfr dynamic @10.53.0.2 -p 5300 > dig.ns2.test$n
$PERL ../digcomp.pl dig.ns2.test$n dynamic.good || ret=1
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I:change SOA owner case via update ($n)"
$NSUPDATE << EOF
server 10.53.0.1 5300
zone dynamic
update add dYNAMIc 0 SOA mname1. . 2000042408 20 20 1814400 3600
send
EOF
$DIG axfr dynamic @10.53.0.1 -p 5300 > dig.ns1.test$n
$PERL ../digcomp.pl dig.ns1.test$n postupdate.good || ret=1
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
for i in 1 2 3 4 5 6 7 8 9
do
$DIG soa dynamic @10.53.0.2 -p 5300 | grep 2000042408 > /dev/null && break
sleep 1
done
n=`expr $n + 1`
echo "I:check SOA owner case is transfered to slave ($n)"
ret=0
$DIG axfr dynamic @10.53.0.2 -p 5300 > dig.ns2.test$n
$PERL ../digcomp.pl dig.ns2.test$n postupdate.good || ret=1
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
#update delete Ns1.DyNaMIC. 300 IN A 10.53.0.1
n=`expr $n + 1`
echo "I:change A record owner case via update ($n)"
$NSUPDATE << EOF
server 10.53.0.1 5300
zone dynamic
update add Ns1.DyNaMIC. 300 IN A 10.53.0.1
send
EOF
$DIG axfr dynamic @10.53.0.1 -p 5300 > dig.ns1.test$n
$PERL ../digcomp.pl dig.ns1.test$n postns1.good || ret=1
test $ret -eq 0 || echo "I:failed"
status=`expr $status + $ret`
for i in 1 2 3 4 5 6 7 8 9
do
$DIG soa dynamic @10.53.0.2 -p 5300 | grep 2000042409 > /dev/null && break
sleep 1
done
n=`expr $n + 1`
echo "I:check A owner case is transfered to slave ($n)"
ret=0
$DIG axfr dynamic @10.53.0.2 -p 5300 > dig.ns2.test$n
$PERL ../digcomp.pl dig.ns2.test$n postns1.good || ret=1
echo "I:exit status: $status"
exit $status

View file

@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: compress.c,v 1.59 2007/06/19 23:47:16 tbox Exp $ */
/*! \file */
#define DNS_NAME_USEINLINE 1
@ -71,6 +69,9 @@ dns_compress_invalidate(dns_compress_t *cctx) {
while (cctx->table[i] != NULL) {
node = cctx->table[i];
cctx->table[i] = cctx->table[i]->next;
if ((node->offset & 0x8000) != 0)
isc_mem_put(cctx->mctx, node->r.base,
node->r.length);
if (node->count < DNS_COMPRESS_INITIALNODES)
continue;
isc_mem_put(cctx->mctx, node, sizeof(*node));
@ -181,7 +182,7 @@ dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
else
dns_name_getlabelsequence(name, 0, n, prefix);
*offset = node->offset;
*offset = (node->offset & 0x7fff);
return (ISC_TRUE);
}
@ -196,7 +197,7 @@ void
dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
const dns_name_t *prefix, isc_uint16_t offset)
{
dns_name_t tname;
dns_name_t tname, xname;
unsigned int start;
unsigned int n;
unsigned int count;
@ -205,22 +206,37 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
unsigned int length;
unsigned int tlength;
isc_uint16_t toffset;
unsigned char *tmp;
isc_region_t r;
REQUIRE(VALID_CCTX(cctx));
REQUIRE(dns_name_isabsolute(name));
if (offset > 0x4000)
return;
dns_name_init(&tname, NULL);
dns_name_init(&xname, NULL);
n = dns_name_countlabels(name);
count = dns_name_countlabels(prefix);
if (dns_name_isabsolute(prefix))
count--;
if (count == 0)
return;
start = 0;
length = name_length(name);
dns_name_toregion(name, &r);
length = r.length;
tmp = isc_mem_get(cctx->mctx, length);
if (tmp == NULL)
return;
memmove(tmp, r.base, r.length);
r.base = tmp;
dns_name_fromregion(&xname, &r);
while (count > 0) {
if (offset >= 0x4000)
break;
dns_name_getlabelsequence(name, start, n, &tname);
dns_name_getlabelsequence(&xname, start, n, &tname);
hash = dns_name_hash(&tname, ISC_FALSE) %
DNS_COMPRESS_TABLESIZE;
tlength = name_length(&tname);
@ -233,10 +249,16 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
else {
node = isc_mem_get(cctx->mctx,
sizeof(dns_compressnode_t));
if (node == NULL)
if (node == NULL) {
if (start == 0)
isc_mem_put(cctx->mctx,
r.base, r.length);
return;
}
}
node->count = cctx->count++;
if (start == 0)
toffset |= 0x8000;
node->offset = toffset;
dns_name_toregion(&tname, &node->r);
node->labels = (isc_uint8_t)dns_name_countlabels(&tname);
@ -263,8 +285,11 @@ dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) {
* items with the greatest offsets being at the end
* of the initialnodes[] array.
*/
while (node != NULL && node->offset >= offset) {
while (node != NULL && (node->offset & 0x7fff) >= offset) {
cctx->table[i] = node->next;
if ((node->offset & 0x8000) != 0)
isc_mem_put(cctx->mctx, node->r.base,
node->r.length);
if (node->count >= DNS_COMPRESS_INITIALNODES)
isc_mem_put(cctx->mctx, node, sizeof(*node));
cctx->count--;

View file

@ -175,7 +175,7 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep)
ot = next_ot)
{
next_ot = ISC_LIST_NEXT(ot, link);
if (dns_name_equal(&ot->name, &(*tuplep)->name) &&
if (dns_name_caseequal(&ot->name, &(*tuplep)->name) &&
dns_rdata_compare(&ot->rdata, &(*tuplep)->rdata) == 0 &&
ot->ttl == (*tuplep)->ttl)
{
@ -233,6 +233,18 @@ setresign(dns_rdataset_t *modified) {
return (when);
}
static void
getownercase(dns_rdataset_t *rdataset, dns_name_t *name) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_getownercase(rdataset, name);
}
static void
setownercase(dns_rdataset_t *rdataset, dns_name_t *name) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_setownercase(rdataset, name);
}
static isc_result_t
diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
isc_boolean_t warn)
@ -268,7 +280,7 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
dns_rdatalist_t rdl;
dns_rdataset_t rds;
dns_rdataset_t ardataset;
dns_rdataset_t *modified = NULL;
unsigned int options;
op = t->op;
type = t->rdata.type;
@ -311,13 +323,20 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
t->rdata.type == type &&
rdata_covers(&t->rdata) == covers)
{
dns_name_format(name, namebuf, sizeof(namebuf));
dns_rdatatype_format(t->rdata.type, typebuf,
sizeof(typebuf));
dns_rdataclass_format(t->rdata.rdclass,
classbuf,
sizeof(classbuf));
if (t->ttl != rdl.ttl && warn)
/*
* Remember the add name for
* dns_rdataset_setownercase.
*/
name = &t->name;
if (t->ttl != rdl.ttl && warn) {
dns_name_format(name, namebuf,
sizeof(namebuf));
dns_rdatatype_format(t->rdata.type,
typebuf,
sizeof(typebuf));
dns_rdataclass_format(t->rdata.rdclass,
classbuf,
sizeof(classbuf));
isc_log_write(DIFF_COMMON_LOGARGS,
ISC_LOG_WARNING,
"'%s/%s/%s': TTL differs in "
@ -326,6 +345,7 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
namebuf, typebuf, classbuf,
(unsigned long) t->ttl,
(unsigned long) rdl.ttl);
}
ISC_LIST_APPEND(rdl.rdata, &t->rdata, link);
t = ISC_LIST_NEXT(t, link);
}
@ -334,17 +354,8 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
* Convert the rdatalist into a rdataset.
*/
dns_rdataset_init(&rds);
dns_rdataset_init(&ardataset);
CHECK(dns_rdatalist_tordataset(&rdl, &rds));
if (rds.type == dns_rdatatype_rrsig)
switch (op) {
case DNS_DIFFOP_ADDRESIGN:
case DNS_DIFFOP_DELRESIGN:
modified = &ardataset;
dns_rdataset_init(modified);
break;
default:
break;
}
rds.trust = dns_trust_ultimate;
/*
@ -353,31 +364,38 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
switch (op) {
case DNS_DIFFOP_ADD:
case DNS_DIFFOP_ADDRESIGN:
options = DNS_DBADD_MERGE | DNS_DBADD_EXACT |
DNS_DBADD_EXACTTTL;
result = dns_db_addrdataset(db, node, ver,
0, &rds,
DNS_DBADD_MERGE|
DNS_DBADD_EXACT|
DNS_DBADD_EXACTTTL,
modified);
0, &rds, options,
&ardataset);
break;
case DNS_DIFFOP_DEL:
case DNS_DIFFOP_DELRESIGN:
options = DNS_DBSUB_EXACT | DNS_DBSUB_WANTOLD;
result = dns_db_subtractrdataset(db, node, ver,
&rds,
DNS_DBSUB_EXACT,
modified);
&rds, options,
&ardataset);
break;
default:
INSIST(0);
}
if (result == ISC_R_SUCCESS) {
if (modified != NULL) {
if (rds.type == dns_rdatatype_rrsig &&
(op == DNS_DIFFOP_DELRESIGN ||
op == DNS_DIFFOP_ADDRESIGN)) {
isc_stdtime_t resign;
resign = setresign(modified);
dns_db_setsigningtime(db, modified,
resign = setresign(&ardataset);
dns_db_setsigningtime(db, &ardataset,
resign);
}
if (op == DNS_DIFFOP_ADD ||
op == DNS_DIFFOP_ADDRESIGN)
setownercase(&ardataset, name);
if (op == DNS_DIFFOP_DEL ||
op == DNS_DIFFOP_DELRESIGN)
getownercase(&ardataset, name);
} else if (result == DNS_R_UNCHANGED) {
/*
* This will not happen when executing a
@ -400,20 +418,29 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
"update with no effect",
namebuf, classbuf);
}
if (op == DNS_DIFFOP_ADD ||
op == DNS_DIFFOP_ADDRESIGN)
setownercase(&ardataset, name);
if (op == DNS_DIFFOP_DEL ||
op == DNS_DIFFOP_DELRESIGN)
getownercase(&ardataset, name);
} else if (result == DNS_R_NXRRSET) {
/*
* OK.
*/
if (op == DNS_DIFFOP_DEL ||
op == DNS_DIFFOP_DELRESIGN)
getownercase(&ardataset, name);
if (dns_rdataset_isassociated(&ardataset))
dns_rdataset_disassociate(&ardataset);
} else {
if (modified != NULL &&
dns_rdataset_isassociated(modified))
dns_rdataset_disassociate(modified);
if (dns_rdataset_isassociated(&ardataset))
dns_rdataset_disassociate(&ardataset);
CHECK(result);
}
dns_db_detachnode(db, &node);
if (modified != NULL &&
dns_rdataset_isassociated(modified))
dns_rdataset_disassociate(modified);
if (dns_rdataset_isassociated(&ardataset))
dns_rdataset_disassociate(&ardataset);
}
}
return (ISC_R_SUCCESS);

View file

@ -114,7 +114,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL, /* putadditional */
rdataset_settrust, /* settrust */
NULL, /* expire */
NULL /* clearprefetch */
NULL, /* clearprefetch */
NULL, /* setownercase */
NULL /* getownercase */
};
typedef struct ecdb_rdatasetiter {

View file

@ -260,6 +260,7 @@ struct dns_db {
* Options that can be specified for dns_db_subtractrdataset().
*/
#define DNS_DBSUB_EXACT 0x01
#define DNS_DBSUB_WANTOLD 0x02
/*@{*/
/*%
@ -1281,6 +1282,9 @@ dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
* become nonexistent. If DNS_DBSUB_EXACT is set then all elements
* of 'rdataset' must exist at 'node'.
*
*\li If DNS_DBSUB_WANTOLD is set and the entire rdataset was deleted
* then return the original rdatatset in newrdataset if that existed.
*
* Requires:
*
* \li 'db' is a valid database.

View file

@ -811,14 +811,15 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
#define DNS_NAME_MASTERFILE 0x02U /* escape $ and @ */
isc_result_t
dns_name_toprincipal(dns_name_t *name, isc_buffer_t *target);
dns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target);
isc_result_t
dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
dns_name_totext(const dns_name_t *name, isc_boolean_t omit_final_dot,
isc_buffer_t *target);
isc_result_t
dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target);
dns_name_totext2(const dns_name_t *name, unsigned int options,
isc_buffer_t *target);
/*%<
* Convert 'name' into text format, storing the result in 'target'.
*
@ -1125,7 +1126,7 @@ dns_name_print(dns_name_t *name, FILE *stream);
*/
void
dns_name_format(dns_name_t *name, char *cp, unsigned int size);
dns_name_format(const dns_name_t *name, char *cp, unsigned int size);
/*%<
* Format 'name' as text appropriate for use in log messages.
*
@ -1222,7 +1223,7 @@ dns_name_settotextfilter(dns_name_totextfilter_t proc);
*/
isc_result_t
dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target);
dns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target);
/*%<
* Makes 'dest' refer to a copy of the name in 'source'. The data are
* either copied to 'target' or the dedicated buffer in 'dest'.

View file

@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdatalist.h,v 1.22 2008/04/03 06:09:05 tbox Exp $ */
#ifndef DNS_RDATALIST_H
#define DNS_RDATALIST_H 1
@ -58,6 +56,12 @@ struct dns_rdatalist {
dns_ttl_t ttl;
ISC_LIST(dns_rdata_t) rdata;
ISC_LINK(dns_rdatalist_t) link;
/*%<
* Case vector. If the bit is set then the corresponding
* character in the owner name needs to be AND'd with 0x20,
* rendering that character upper case.
*/
unsigned char upper[32];
};
ISC_LANG_BEGINDECLS

View file

@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataset.h,v 1.72 2011/06/08 22:13:51 each Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
@ -115,6 +113,9 @@ typedef struct dns_rdatasetmethods {
dns_trust_t trust);
void (*expire)(dns_rdataset_t *rdataset);
void (*clearprefetch)(dns_rdataset_t *rdataset);
void (*setownercase)(dns_rdataset_t *rdataset,
const dns_name_t *name);
void (*getownercase)(const dns_rdataset_t *rdataset, dns_name_t *name);
} dns_rdatasetmethods_t;
#define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R')
@ -666,6 +667,22 @@ dns_rdataset_clearprefetch(dns_rdataset_t *rdataset);
* It has no function in other databases.
*/
void
dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name);
/*%<
* Store the casing of 'name', the owner name of 'rdataset', into
* a bitfield so that the name can be capitalized the same when when
* the rdataset is used later. This sets the CASESET attribute.
*/
void
dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name);
/*%<
* If the CASESET attribute is set, retrieve the case bitfield that was
* previously stored by dns_rdataset_getownername(), and capitalize 'name'
* according to it. If CASESET is not set, do nothing.
*/
void
dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,

View file

@ -139,9 +139,12 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
dns_dbnode_t *node;
dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_fixedname_t fixed;
dns_name_t *zonename;
zonename = dns_db_origin(db);
dns_fixedname_init(&fixed);
zonename = dns_fixedname_name(&fixed);
dns_name_copy(dns_db_origin(db), zonename, NULL);
node = NULL;
result = dns_db_findnode(db, zonename, ISC_FALSE, &node);
@ -159,6 +162,7 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
goto freenode;
dns_rdataset_current(&rdataset, &rdata);
dns_rdataset_getownercase(&rdataset, zonename);
result = dns_difftuple_create(mctx, op, zonename, rdataset.ttl,
&rdata, tp);

View file

@ -449,6 +449,8 @@ rdataset_totext(dns_rdataset_t *rdataset,
isc_boolean_t current_ttl_valid;
dns_rdatatype_t type;
unsigned int type_start;
dns_fixedname_t fixed;
dns_name_t *name = NULL;
REQUIRE(DNS_RDATASET_VALID(rdataset));
@ -458,6 +460,13 @@ rdataset_totext(dns_rdataset_t *rdataset,
current_ttl = ctx->current_ttl;
current_ttl_valid = ctx->current_ttl_valid;
if (owner_name != NULL) {
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
dns_name_copy(owner_name, name, NULL);
dns_rdataset_getownercase(rdataset, name);
}
while (result == ISC_R_SUCCESS) {
column = 0;
@ -470,14 +479,12 @@ rdataset_totext(dns_rdataset_t *rdataset,
/*
* Owner name.
*/
if (owner_name != NULL &&
if (name != NULL &&
! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 &&
!first))
{
unsigned int name_start = target->used;
RETERR(dns_name_totext(owner_name,
omit_final_dot,
target));
RETERR(dns_name_totext(name, omit_final_dot, target));
column += target->used - name_start;
}

View file

@ -336,6 +336,7 @@ newrdatalist(dns_message_t *msg) {
rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
if (rdatalist != NULL) {
ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
dns_rdatalist_init(rdatalist);
return (rdatalist);
}
@ -352,6 +353,8 @@ newrdatalist(dns_message_t *msg) {
rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
}
if (rdatalist != NULL)
dns_rdatalist_init(rdatalist);
return (rdatalist);
}
@ -1127,10 +1130,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* the name.
*/
rdatalist->type = rdtype;
rdatalist->covers = 0;
rdatalist->rdclass = rdclass;
rdatalist->ttl = 0;
ISC_LIST_INIT(rdatalist->rdata);
dns_rdataset_init(rdataset);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
@ -1491,12 +1491,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
rdatalist->covers = covers;
rdatalist->rdclass = rdclass;
rdatalist->ttl = ttl;
ISC_LIST_INIT(rdatalist->rdata);
dns_rdataset_init(rdataset);
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
rdataset)
== ISC_R_SUCCESS);
dns_rdataset_setownercase(rdataset, name);
if (rdtype != dns_rdatatype_opt &&
rdtype != dns_rdatatype_tsig &&

View file

@ -1368,7 +1368,7 @@ totext_filter_proc_key_init(void) {
#endif
isc_result_t
dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
dns_name_totext(const dns_name_t *name, isc_boolean_t omit_final_dot,
isc_buffer_t *target)
{
unsigned int options = DNS_NAME_MASTERFILE;
@ -1379,12 +1379,13 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
}
isc_result_t
dns_name_toprincipal(dns_name_t *name, isc_buffer_t *target) {
dns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target) {
return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target));
}
isc_result_t
dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target)
dns_name_totext2(const dns_name_t *name, unsigned int options,
isc_buffer_t *target)
{
unsigned char *ndata;
char *tdata;
@ -2383,7 +2384,7 @@ dns_name_settotextfilter(dns_name_totextfilter_t proc) {
}
void
dns_name_format(dns_name_t *name, char *cp, unsigned int size) {
dns_name_format(const dns_name_t *name, char *cp, unsigned int size) {
isc_result_t result;
isc_buffer_t buf;
@ -2476,7 +2477,7 @@ dns_name_fromstring2(dns_name_t *target, const char *src,
}
isc_result_t
dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
dns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
unsigned char *ndata;
/*

View file

@ -504,6 +504,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
rdataset_settrust,
NULL,
NULL,
NULL,
NULL
};

View file

@ -149,6 +149,7 @@ typedef isc_uint64_t rbtdb_serial_t;
#define dbiterator_methods dbiterator_methods64
#define rdataset_methods rdataset_methods64
#define rdatasetiter_methods rdatasetiter_methods64
#define slab_methods slab_methods64
#define zone_methods zone_methods64
#define acache_callback acache_callback64
@ -451,6 +452,12 @@ typedef struct rdatasetheader {
* Used for TTL-based cache cleaning.
*/
isc_stdtime_t resign;
/*%<
* Case vector. If the bit is set then the corresponding
* character in the owner name needs to be AND'd with 0x20,
* rendering that character upper case.
*/
unsigned char upper[32];
} rdatasetheader_t;
typedef ISC_LIST(rdatasetheader_t) rdatasetheaderlist_t;
@ -466,6 +473,7 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
#define RDATASET_ATTR_OPTOUT 0x0080
#define RDATASET_ATTR_NEGATIVE 0x0100
#define RDATASET_ATTR_PREFETCH 0x0200
#define RDATASET_ATTR_CASESET 0x0400
typedef struct acache_cbarg {
dns_rdatasetadditional_t type;
@ -508,6 +516,8 @@ struct acachectl {
(((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
#define PREFETCH(header) \
(((header)->attributes & RDATASET_ATTR_PREFETCH) != 0)
#define CASESET(header) \
(((header)->attributes & RDATASET_ATTR_CASESET) != 0)
#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
@ -746,6 +756,10 @@ static void prune_tree(isc_task_t *task, isc_event_t *event);
static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
static void rdataset_expire(dns_rdataset_t *rdataset);
static void rdataset_clearprefetch(dns_rdataset_t *rdataset);
static void rdataset_setownercase(dns_rdataset_t *rdataset,
const dns_name_t *name);
static void rdataset_getownercase(const dns_rdataset_t *rdataset,
dns_name_t *name);
static dns_rdatasetmethods_t rdataset_methods = {
rdataset_disassociate,
@ -763,7 +777,30 @@ static dns_rdatasetmethods_t rdataset_methods = {
rdataset_putadditional,
rdataset_settrust,
rdataset_expire,
rdataset_clearprefetch
rdataset_clearprefetch,
rdataset_setownercase,
rdataset_getownercase
};
static dns_rdatasetmethods_t slab_methods = {
rdataset_disassociate,
rdataset_first,
rdataset_next,
rdataset_current,
rdataset_clone,
rdataset_count,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
@ -841,6 +878,7 @@ static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log,
isc_event_t *event);
static void overmem(dns_db_t *db, isc_boolean_t over);
static void setnsec3parameters(dns_db_t *db, rbtdb_version_t *version);
static void setownercase(rdatasetheader_t *header, const dns_name_t *name);
/* Pad to 32 bytes */
static char FILE_VERSION[32] = "\0";
@ -1543,6 +1581,10 @@ update_newheader(rdatasetheader_t *new, rdatasetheader_t *old) {
p += (uintptr_t)old->node;
new->node = (dns_rbtnode_t *)p;
}
if (CASESET(old)) {
memmove(new->upper, old->upper, sizeof(old->upper));
new->attributes |= RDATASET_ATTR_CASESET;
}
}
static inline rdatasetheader_t *
@ -1557,6 +1599,7 @@ new_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx) {
if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in)
fprintf(stderr, "allocated header: %p\n", h);
#endif
memset(h->upper, 0xeb, sizeof(h->upper));
init_rdataset(rbtdb, h);
return (h);
}
@ -6619,6 +6662,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_boolean_t newnsec;
isc_boolean_t tree_locked = ISC_FALSE;
isc_boolean_t cache_is_overmem = ISC_FALSE;
dns_fixedname_t fixed;
dns_name_t *name;
REQUIRE(VALID_RBTDB(rbtdb));
INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
@ -6642,8 +6687,14 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
return (result);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
dns_rbt_fullnamefromnode(node, name);
dns_rdataset_getownercase(rdataset, name);
newheader = (rdatasetheader_t *)region.base;
init_rdataset(rbtdb, newheader);
setownercase(newheader, name);
set_ttl(rbtdb, newheader, rdataset->ttl + now);
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
@ -6825,8 +6876,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
rdataset->covers != dns_rdatatype_nsec3)));
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
&region,
sizeof(rdatasetheader_t));
&region, sizeof(rdatasetheader_t));
if (result != ISC_R_SUCCESS)
return (result);
newheader = (rdatasetheader_t *)region.base;
@ -6973,6 +7023,10 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
if (result == ISC_R_SUCCESS && newrdataset != NULL)
bind_rdataset(rbtdb, rbtnode, newheader, 0, newrdataset);
if (result == DNS_R_NXRRSET && newrdataset != NULL &&
(options & DNS_DBSUB_WANTOLD) != 0)
bind_rdataset(rbtdb, rbtnode, header, 0, newrdataset);
unlock:
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_write);
@ -7240,6 +7294,8 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
newheader->additional_glue = NULL;
newheader->last_used = 0;
newheader->node = node;
setownercase(newheader, name);
if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
newheader->attributes |= RDATASET_ATTR_RESIGN;
newheader->resign = rdataset->resign;
@ -8615,7 +8671,7 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
cloned_node = NULL;
attachnode(db, node, &cloned_node);
nsec->methods = &rdataset_methods;
nsec->methods = &slab_methods;
nsec->rdclass = db->rdclass;
nsec->type = noqname->type;
nsec->covers = 0;
@ -8631,7 +8687,7 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
cloned_node = NULL;
attachnode(db, node, &cloned_node);
nsecsig->methods = &rdataset_methods;
nsecsig->methods = &slab_methods;
nsecsig->rdclass = db->rdclass;
nsecsig->type = dns_rdatatype_rrsig;
nsecsig->covers = noqname->type;
@ -8661,7 +8717,7 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
cloned_node = NULL;
attachnode(db, node, &cloned_node);
nsec->methods = &rdataset_methods;
nsec->methods = &slab_methods;
nsec->rdclass = db->rdclass;
nsec->type = closest->type;
nsec->covers = 0;
@ -8677,7 +8733,7 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
cloned_node = NULL;
attachnode(db, node, &cloned_node);
nsecsig->methods = &rdataset_methods;
nsecsig->methods = &slab_methods;
nsecsig->rdclass = db->rdclass;
nsecsig->type = dns_rdatatype_rrsig;
nsecsig->covers = closest->type;
@ -9774,6 +9830,54 @@ rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
return (ISC_R_SUCCESS);
}
static void
setownercase(rdatasetheader_t *header, const dns_name_t *name) {
unsigned int i;
/*
* We do not need to worry about label lengths as they are all
* less than or equal to 63.
*/
memset(header->upper, 0, sizeof(header->upper));
for (i = 0; i < name->length; i++)
if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
header->upper[i/8] |= 1 << (i%8);
header->attributes |= RDATASET_ATTR_CASESET;
}
static void
rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
unsigned char *raw = rdataset->private3; /* RDATASLAB */
rdatasetheader_t *header;
header = (struct rdatasetheader *)(raw - sizeof(*header));
setownercase(header, name);
}
static void
rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
const unsigned char *raw = rdataset->private3; /* RDATASLAB */
const rdatasetheader_t *header;
unsigned int i;
header = (const struct rdatasetheader *)(raw - sizeof(*header));
if (!CASESET(header))
return;
for (i = 0; i < name->length; i++) {
/*
* Set the case bit if it does not match the recorded bit.
*/
if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
(header->upper[i/8] & (1 << (i%8))) != 0)
name->ndata[i] &= ~0x20; /* clear the lower case bit */
else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
(header->upper[i/8] & (1 << (i%8))) == 0)
name->ndata[i] |= 0x20; /* set the lower case bit */
}
}
/*%
* Routines for LRU-based cache management.
*/

View file

@ -22,6 +22,7 @@
#include <config.h>
#include <stddef.h>
#include <string.h>
#include <isc/util.h>
@ -49,7 +50,9 @@ static dns_rdatasetmethods_t methods = {
NULL,
NULL,
NULL,
NULL
NULL,
isc__rdatalist_setownercase,
isc__rdatalist_getownercase
};
void
@ -67,6 +70,11 @@ dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
rdatalist->ttl = 0;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LINK_INIT(rdatalist, link);
memset(rdatalist->upper, 0xeb, sizeof(rdatalist->upper));
/*
* Clear upper set bit.
*/
rdatalist->upper[0] &= ~0x01;
}
isc_result_t
@ -368,3 +376,44 @@ isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_clone(tnegsig, negsig);
return (ISC_R_SUCCESS);
}
void
isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
dns_rdatalist_t *rdatalist;
unsigned int i;
/*
* We do not need to worry about label lengths as they are all
* less than or equal to 63.
*/
rdatalist = rdataset->private1;
memset(rdatalist->upper, 0, sizeof(rdatalist->upper));
for (i = 1; i < name->length; i++)
if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
rdatalist->upper[i/8] |= 1 << (i%8);
/*
* Record that upper has been set.
*/
rdatalist->upper[0] |= 0x01;
}
void
isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
dns_rdatalist_t *rdatalist;
unsigned int i;
rdatalist = rdataset->private1;
if ((rdatalist->upper[0] & 0x01) == 0)
return;
for (i = 0; i < name->length; i++) {
/*
* Set the case bit if it does not match the recorded bit.
*/
if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
(rdatalist->upper[i/8] & (1 << (i%8))) != 0)
name->ndata[i] &= ~0x20; /* clear the lower case bit */
else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
(rdatalist->upper[i/8] & (1 << (i%8))) == 0)
name->ndata[i] |= 0x20; /* set the lower case bit */
}
}

View file

@ -59,6 +59,12 @@ isc_result_t
isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *neg, dns_rdataset_t *negsig);
void
isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name);
void
isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name);
ISC_LANG_ENDDECLS
#endif /* DNS_RDATALIST_P_H */

View file

@ -29,11 +29,12 @@
#include <isc/serial.h>
#include <isc/util.h>
#include <dns/compress.h>
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/ncache.h>
#include <dns/rdata.h>
#include <dns/rdataset.h>
#include <dns/compress.h>
static const char *trustnames[] = {
"none",
@ -207,6 +208,8 @@ static dns_rdatasetmethods_t question_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
@ -329,6 +332,8 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
isc_boolean_t shuffle = ISC_FALSE;
dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];
dns_fixedname_t fixed;
dns_name_t *name;
UNUSED(state);
@ -467,6 +472,11 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
i = 0;
added = 0;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
dns_name_copy(owner_name, name, NULL);
dns_rdataset_getownercase(rdataset, name);
do {
/*
* Copy out the name, type, class, ttl.
@ -474,7 +484,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
rrbuffer = *target;
dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
result = dns_name_towire(owner_name, cctx, target);
result = dns_name_towire(name, cctx, target);
if (result != ISC_R_SUCCESS)
goto rollback;
headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
@ -784,6 +794,24 @@ dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) {
(rdataset->methods->clearprefetch)(rdataset);
}
void
dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL);
if (rdataset->methods->setownercase != NULL)
(rdataset->methods->setownercase)(rdataset, name);
}
void
dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL);
if (rdataset->methods->getownercase != NULL)
(rdataset->methods->getownercase)(rdataset, name);
}
void
dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,

View file

@ -467,6 +467,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};

View file

@ -100,6 +100,8 @@ dns_rriterator_first(dns_rriterator_t *it) {
continue;
}
dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
dns_rdataset_getownercase(&it->rdataset,
dns_fixedname_name(&it->fixedname));
it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
it->result = dns_rdataset_first(&it->rdataset);
return (it->result);
@ -140,6 +142,8 @@ dns_rriterator_nextrrset(dns_rriterator_t *it) {
if (it->result != ISC_R_SUCCESS)
return (it->result);
dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
dns_rdataset_getownercase(&it->rdataset,
dns_fixedname_name(&it->fixedname));
it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
it->result = dns_rdataset_first(&it->rdataset);
return (it->result);

View file

@ -1430,6 +1430,8 @@ static dns_rdatasetmethods_t methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};

View file

@ -1482,6 +1482,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};

View file

@ -13763,6 +13763,8 @@ checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_buffer_t b;
isc_result_t result;
unsigned char buf[DNS_SOA_BUFFERSIZE];
dns_fixedname_t fixed;
dns_name_t *name;
result = dns_rdataset_first(rdataset);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@ -13799,6 +13801,11 @@ checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdataset_init(&temprdataset);
result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
dns_rbtnode_nodename(node, name);
dns_rdataset_getownercase(rdataset, name);
dns_rdataset_setownercase(&temprdataset, name);
return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
0, NULL));
}

View file

@ -587,7 +587,6 @@ update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete,
rdatalist->rdclass = rdataclass;
rdatalist->covers = rdatatype;
rdatalist->ttl = (dns_ttl_t)ttl;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
ISC_LIST_APPEND(usedrdatalists, rdatalist, link);
@ -598,6 +597,7 @@ update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete,
}
dns_rdataset_init(rdataset);
dns_rdatalist_tordataset(rdatalist, rdataset);
dns_rdataset_setownercase(rdataset, name);
ISC_LIST_INIT(name->list);
ISC_LIST_APPEND(name->list, rdataset, link);
}
@ -700,6 +700,7 @@ make_prereq(isc_mem_t *mctx, char *cmdline, isc_boolean_t ispositive,
}
dns_rdataset_init(rdataset);
dns_rdatalist_tordataset(rdatalist, rdataset);
dns_rdataset_setownercase(rdataset, name);
ISC_LIST_INIT(name->list);
ISC_LIST_APPEND(name->list, rdataset, link);
}