2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

1999. [func] Implement "rrset-order fixed". [RT #13662]

This commit is contained in:
Mark Andrews 2006-03-03 00:43:35 +00:00
parent fb9395c8dd
commit d76ed813a5
48 changed files with 944 additions and 86 deletions

View File

@ -1,3 +1,5 @@
1999. [func] Implement "rrset-order fixed". [RT #13662]
1998. [bug] Restrict handling of fifos as sockets to just SunOS.
This allows named to connect to entropy gathering
daemons that use fifos instead of sockets. [RT #15840]

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: config.c,v 1.69 2006/02/28 02:39:51 marka Exp $ */
/* $Id: config.c,v 1.70 2006/03/03 00:43:34 marka Exp $ */
/*! \file */
@ -80,7 +80,7 @@ options {\n\
#endif
"\
recursive-clients 1000;\n\
rrset-order {order cyclic;};\n\
rrset-order {type NS order random; order cyclic; };\n\
serial-queries 20;\n\
serial-query-rate 20;\n\
server-id none;\n\

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.281 2006/02/28 02:39:51 marka Exp $ */
/* $Id: query.c,v 1.282 2006/03/03 00:43:34 marka Exp $ */
/*! \file */
@ -1914,6 +1914,8 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
rdataset->attributes |= dns_order_find(client->view->order,
fname, rdataset->type,
rdataset->rdclass);
rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
if (NOADDITIONAL(client))
return;

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: update.c,v 1.127 2006/01/06 00:01:44 marka Exp $ */
/* $Id: update.c,v 1.128 2006/03/03 00:43:34 marka Exp $ */
#include <config.h>
@ -1311,8 +1311,8 @@ static isc_result_t
namelist_append_name(dns_diff_t *list, dns_name_t *name) {
isc_result_t result;
dns_difftuple_t *tuple = NULL;
static dns_rdata_t dummy_rdata = { NULL, 0, 0, 0, 0,
{ (void*)(-1), (void*)(-1) } };
static dns_rdata_t dummy_rdata = DNS_RDATA_INIT;
CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0,
&dummy_rdata, &tuple));
dns_diff_append(list, &tuple);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: xfrout.c,v 1.121 2005/10/14 01:14:07 marka Exp $ */
/* $Id: xfrout.c,v 1.122 2006/03/03 00:43:34 marka Exp $ */
#include <config.h>
@ -200,7 +200,7 @@ db_rr_iterator_first(db_rr_iterator_t *it) {
continue;
}
dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
it->result = dns_rdataset_first(&it->rdataset);
return (it->result);
}
@ -250,6 +250,7 @@ db_rr_iterator_next(db_rr_iterator_t *it) {
if (it->result != ISC_R_SUCCESS)
return (it->result);
dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
it->result = dns_rdataset_first(&it->rdataset);
if (it->result != ISC_R_SUCCESS)
return (it->result);

View File

@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: conf.sh.in,v 1.33 2005/09/05 00:10:53 marka Exp $
# $Id: conf.sh.in,v 1.34 2006/03/03 00:43:34 marka Exp $
#
# Common configuration data for system tests, to be sourced into
@ -44,8 +44,8 @@ CHECKCONF=$TOP/bin/check/named-checkconf
# load on the machine to make it unusable to other users.
# v6synth
SUBDIRS="cacheclean checkconf checknames dnssec forward glue ixfr limits
lwresd masterfile masterformat notify nsupdate resolver sortlist stub
tkey unknown upforwd views xfer xferquota zonechecks"
lwresd masterfile masterformat notify nsupdate resolver rrsetorder
sortlist stub tkey unknown upforwd views xfer xferquota zonechecks"
# PERL will be an empty string if no perl interpreter was found.
PERL=@PERL@

View File

@ -0,0 +1,22 @@
#!/bin/sh
#
# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
#
# 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 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.
# $Id: clean.sh,v 1.2 2006/03/03 00:43:34 marka Exp $
rm -f dig.out.cyclic dig.out.fixed dig.out.random
rm -f ns2/root.bk
rm -f ns?/named.run ns?/named.core

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.4
1.2.3.3
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.3
1.2.3.2
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.2
1.2.3.1
1.2.3.4

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.1
1.2.3.4
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.3
1.2.3.1
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.2
1.2.3.3
1.2.3.4

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.3
1.2.3.4
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.4
1.2.3.1
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.4
1.2.3.3
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.1
1.2.3.2
1.2.3.4

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.1
1.2.3.4
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.2
1.2.3.1
1.2.3.4

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.2
1.2.3.4
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.4
1.2.3.1
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.3
1.2.3.4
1.2.3.2
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.1
1.2.3.2
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.2
1.2.3.4
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.1
1.2.3.3
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.2
1.2.3.1
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.2
1.2.3.3
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.3
1.2.3.1
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.4
1.2.3.3
1.2.3.2
1.2.3.1

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.3
1.2.3.2
1.2.3.4

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.3
1.2.3.4
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.4
1.2.3.2
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.1
1.2.3.4
1.2.3.3
1.2.3.2

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.1
1.2.3.3
1.2.3.4

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.1
1.2.3.4
1.2.3.3

View File

@ -0,0 +1,4 @@
1.2.3.2
1.2.3.3
1.2.3.1
1.2.3.4

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
*
* 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 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.
*/
/* $Id: named.conf,v 1.2 2006/03/03 00:43:35 marka Exp $ */
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
rrset-order {
name "fixed.example" order fixed;
name "random.example" order random;
name "cyclic.example" order cyclic;
type NS order random;
order cyclic;
};
};
zone "." {
type master;
file "root.db";
};

View File

@ -0,0 +1,40 @@
; Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
;
; 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 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.
; $Id: root.db,v 1.2 2006/03/03 00:43:35 marka Exp $
$TTL 3600
. SOA hostmaster.isc.org. a.root-servers.nil. (
2000042100
600
600
1200
600 )
. NS a.root-servers.nil.
a.root-servers.nil A 10.53.0.1
;
fixed.example. A 1.2.3.4
fixed.example. A 1.2.3.3
fixed.example. A 1.2.3.1
fixed.example. A 1.2.3.2
;
random.example. A 1.2.3.1
random.example. A 1.2.3.2
random.example. A 1.2.3.3
random.example. A 1.2.3.4
;
cyclic.example. A 1.2.3.4
cyclic.example. A 1.2.3.3
cyclic.example. A 1.2.3.2
cyclic.example. A 1.2.3.1

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
*
* 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 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.
*/
/* $Id: named.conf,v 1.2 2006/03/03 00:43:35 marka Exp $ */
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
notify yes;
// flush-zones-on-shutdown yes;
rrset-order {
name "fixed.example" order fixed;
name "random.example" order random;
name "cyclic.example" order cyclic;
type NS order random;
order cyclic;
};
};
zone "." {
type slave;
masters { 10.53.0.1; };
file "root.bk";
};

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
*
* 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 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.
*/
/* $Id: named.conf,v 1.2 2006/03/03 00:43:35 marka Exp $ */
controls { /* empty */ };
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
recursion yes;
notify yes;
rrset-order {
name "fixed.example" order fixed;
name "random.example" order random;
name "cyclic.example" order cyclic;
type NS order random;
order cyclic;
};
};
zone "." {
type hint;
file "../../common/root.hint";
};

View File

@ -0,0 +1,329 @@
#!/bin/sh
#
# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
#
# 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 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.
# $Id: tests.sh,v 1.2 2006/03/03 00:43:34 marka Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
#
#
#
echo "I: Checking order fixed (master)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.1 fixed.example > dig.out.fixed || ret=1
cmp -s dig.out.fixed dig.out.fixed.good || ret=1
done
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
#
#
#
echo "I: Checking order cyclic (master)"
ret=0
match1=0
match2=0
match3=0
match4=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.1 cyclic.example > dig.out.cyclic || ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 || \
cmp -s dig.out.cyclic dig.out.cyclic.good2 || \
cmp -s dig.out.cyclic dig.out.cyclic.good3 || \
cmp -s dig.out.cyclic dig.out.cyclic.good4 || \
ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 && match1=1
cmp -s dig.out.cyclic dig.out.cyclic.good2 && match2=1
cmp -s dig.out.cyclic dig.out.cyclic.good3 && match3=1
cmp -s dig.out.cyclic dig.out.cyclic.good4 && match4=1
done
match=`expr $match1 + $match2 + $match3 + $match4`
if [ $match != 4 ]; then ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: Checking order random (master)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval match$i=0
done
for i in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 9
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.1 random.example > dig.out.random || ret=1
match=0
for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "cmp -s dig.out.random dig.out.random.good$j && match$j=1 match=1"
if [ $match -eq 1 ]; then break; fi
done
if [ $match -eq 0 ]; then ret=1; fi
done
match=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "match=\`expr \$match + \$match$i\`"
done
echo "I: Random selection return $match of 24 possible orders in 36 samples"
if [ $match -lt 8 ]; then echo ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
#
#
#
echo "I: Checking order fixed (slave)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.2 fixed.example > dig.out.fixed || ret=1
cmp -s dig.out.fixed dig.out.fixed.good || ret=1
done
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
#
#
#
echo "I: Checking order cyclic (slave)"
ret=0
match1=0
match2=0
match3=0
match4=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.2 cyclic.example > dig.out.cyclic || ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 || \
cmp -s dig.out.cyclic dig.out.cyclic.good2 || \
cmp -s dig.out.cyclic dig.out.cyclic.good3 || \
cmp -s dig.out.cyclic dig.out.cyclic.good4 || \
ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 && match1=1
cmp -s dig.out.cyclic dig.out.cyclic.good2 && match2=1
cmp -s dig.out.cyclic dig.out.cyclic.good3 && match3=1
cmp -s dig.out.cyclic dig.out.cyclic.good4 && match4=1
done
match=`expr $match1 + $match2 + $match3 + $match4`
if [ $match != 4 ]; then ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: Checking order random (slave)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval match$i=0
done
for i in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 9
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.2 random.example > dig.out.random || ret=1
match=0
for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "cmp -s dig.out.random dig.out.random.good$j && match$j=1 match=1"
if [ $match -eq 1 ]; then break; fi
done
if [ $match -eq 0 ]; then ret=1; fi
done
match=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "match=\`expr \$match + \$match$i\`"
done
echo "I: Random selection return $match of 24 possible orders in 36 samples"
if [ $match -lt 8 ]; then echo ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: Shutting down slave"
(cd ..; sh stop.sh rrsetorder ns2 )
echo "I: Checking for slave's on disk copy of zone"
if [ ! -f ns2/root.bk ]
then
echo "I:failed";
status=`expr $status + 1`
fi
echo "I: Re-starting slave"
(cd ..; sh start.sh --noclean rrsetorder ns2 )
#
#
#
echo "I: Checking order fixed (slave loaded from disk)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.2 fixed.example > dig.out.fixed || ret=1
cmp -s dig.out.fixed dig.out.fixed.good || ret=1
done
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
#
#
#
echo "I: Checking order cyclic (slave loaded from disk)"
ret=0
match1=0
match2=0
match3=0
match4=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.2 cyclic.example > dig.out.cyclic || ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 || \
cmp -s dig.out.cyclic dig.out.cyclic.good2 || \
cmp -s dig.out.cyclic dig.out.cyclic.good3 || \
cmp -s dig.out.cyclic dig.out.cyclic.good4 || \
ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 && match1=1
cmp -s dig.out.cyclic dig.out.cyclic.good2 && match2=1
cmp -s dig.out.cyclic dig.out.cyclic.good3 && match3=1
cmp -s dig.out.cyclic dig.out.cyclic.good4 && match4=1
done
match=`expr $match1 + $match2 + $match3 + $match4`
if [ $match != 4 ]; then ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: Checking order random (slave loaded from disk)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval match$i=0
done
for i in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 9
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.2 random.example > dig.out.random || ret=1
match=0
for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "cmp -s dig.out.random dig.out.random.good$j && match$j=1 match=1"
if [ $match -eq 1 ]; then break; fi
done
if [ $match -eq 0 ]; then ret=1; fi
done
match=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "match=\`expr \$match + \$match$i\`"
done
echo "I: Random selection return $match of 24 possible orders in 36 samples"
if [ $match -lt 8 ]; then echo ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
#
#
#
echo "I: Checking order fixed (cache)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.3 fixed.example > dig.out.fixed || ret=1
cmp -s dig.out.fixed dig.out.fixed.good || ret=1
done
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
#
#
#
echo "I: Checking order cyclic (cache)"
ret=0
match1=0
match2=0
match3=0
match4=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.3 cyclic.example > dig.out.cyclic || ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 || \
cmp -s dig.out.cyclic dig.out.cyclic.good2 || \
cmp -s dig.out.cyclic dig.out.cyclic.good3 || \
cmp -s dig.out.cyclic dig.out.cyclic.good4 || \
ret=1
cmp -s dig.out.cyclic dig.out.cyclic.good1 && match1=1
cmp -s dig.out.cyclic dig.out.cyclic.good2 && match2=1
cmp -s dig.out.cyclic dig.out.cyclic.good3 && match3=1
cmp -s dig.out.cyclic dig.out.cyclic.good4 && match4=1
done
match=`expr $match1 + $match2 + $match3 + $match4`
if [ $match != 4 ]; then ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I: Checking order random (cache)"
ret=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval match$i=0
done
for i in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 9
do
$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat +short \
-p 5300 @10.53.0.3 random.example > dig.out.random || ret=1
match=0
for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "cmp -s dig.out.random dig.out.random.good$j && match$j=1 match=1"
if [ $match -eq 1 ]; then break; fi
done
if [ $match -eq 0 ]; then ret=1; fi
done
match=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
eval "match=\`expr \$match + \$match$i\`"
done
echo "I: Random selection return $match of 24 possible orders in 36 samples"
if [ $match -lt 8 ]; then echo ret=1; fi
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View File

@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: start.pl,v 1.7 2005/06/12 00:03:20 marka Exp $
# $Id: start.pl,v 1.8 2006/03/03 00:43:34 marka Exp $
# Framework for starting test servers.
# Based on the type of server specified, check for port availability, remove
@ -47,8 +47,8 @@ if (!$test) {
if (!-d $test) {
print "No test directory: \"$test\"\n";
}
if ($server && !-d $server) {
print "No server directory: \"$test\"\n";
if ($server && !-d "$test/$server") {
print "No server directory: \"$test/$server\"\n";
}
# Global variables

View File

@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: stop.pl,v 1.8 2005/09/30 00:39:50 marka Exp $
# $Id: stop.pl,v 1.9 2006/03/03 00:43:34 marka Exp $
# Framework for stopping test servers
# Based on the type of server specified, signal the server to stop, wait
@ -50,7 +50,7 @@ my $errors = 0;
die "$usage\n" unless defined($test);
die "No test directory: \"$test\"\n" unless (-d $test);
die "No server directory: \"$server\"\n" if (defined($server) && !-d $server);
die "No server directory: \"$server\"\n" if (defined($server) && !-d "$test/$server");
# Global variables
my $testdir = abs_path($test);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: check.c,v 1.70 2006/02/28 02:39:51 marka Exp $ */
/* $Id: check.c,v 1.71 2006/03/03 00:43:35 marka Exp $ */
/*! \file */
@ -121,10 +121,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) {
cfg_obj_log(ent, logctx, ISC_LOG_ERROR,
"rrset-order: missing ordering");
result = ISC_R_FAILURE;
} else if (strcasecmp(cfg_obj_asstring(obj), "fixed") == 0) {
cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
"rrset-order: order 'fixed' not fully implemented");
} else if (/* strcasecmp(cfg_obj_asstring(obj), "fixed") != 0 && */
} else if (strcasecmp(cfg_obj_asstring(obj), "fixed") != 0 &&
strcasecmp(cfg_obj_asstring(obj), "random") != 0 &&
strcasecmp(cfg_obj_asstring(obj), "cyclic") != 0) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataset.h,v 1.58 2006/03/02 00:37:23 marka Exp $ */
/* $Id: rdataset.h,v 1.59 2006/03/03 00:43:35 marka Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
@ -161,6 +161,9 @@ struct dns_rdataset {
* \def DNS_RDATASETATTR_TTLADJUSTED
* Used by message.c to indicate that the rdataset's rdata had differing
* TTL values, and the rdataset->ttl holds the smallest.
*
* \def DNS_RDATASETATTR_LOADORDER
* Output the RRset in load order.
*/
#define DNS_RDATASETATTR_QUESTION 0x00000001
@ -180,6 +183,7 @@ struct dns_rdataset {
#define DNS_RDATASETATTR_NOQNAME 0x00004000
#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */
#define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000
#define DNS_RDATASETATTR_LOADORDER 0x00020000
/*%
* _OMITDNSSEC:

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: masterdump.c,v 1.83 2005/11/30 03:33:49 marka Exp $ */
/* $Id: masterdump.c,v 1.84 2006/03/03 00:43:35 marka Exp $ */
/*! \file */
@ -358,6 +358,7 @@ rdataset_totext(dns_rdataset_t *rdataset,
REQUIRE(DNS_RDATASET_VALID(rdataset));
rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
result = dns_rdataset_first(rdataset);
REQUIRE(result == ISC_R_SUCCESS);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.227 2006/03/02 23:00:32 marka Exp $ */
/* $Id: rbtdb.c,v 1.228 2006/03/03 00:43:35 marka Exp $ */
/*! \file */
@ -856,7 +856,7 @@ free_acachearray(isc_mem_t *mctx, rdatasetheader_t *header,
{
unsigned int count;
unsigned int i;
unsigned char *raw;
unsigned char *raw; /* RDATASLAB */
/*
* The caller must be holding the corresponding node lock.
@ -1816,7 +1816,7 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
rdatasetheader_t *header, isc_stdtime_t now,
dns_rdataset_t *rdataset)
{
unsigned char *raw;
unsigned char *raw; /* RDATASLAB */
/*
* Caller must be holding the node reader lock.
@ -1924,7 +1924,7 @@ static inline isc_boolean_t
valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type,
dns_rbtnode_t *node)
{
unsigned char *raw;
unsigned char *raw; /* RDATASLAB */
unsigned int count, size;
dns_name_t ns_name;
isc_boolean_t valid = ISC_FALSE;
@ -1953,12 +1953,12 @@ valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type,
header = search->zonecut_rdataset;
raw = (unsigned char *)header + sizeof(*header);
count = raw[0] * 256 + raw[1];
raw += 2;
raw += 2 + (4 * count);
while (count > 0) {
count--;
size = raw[0] * 256 + raw[1];
raw += 2;
raw += 4;
region.base = raw;
region.length = size;
raw += size;
@ -5619,7 +5619,7 @@ rdataset_disassociate(dns_rdataset_t *rdataset) {
static isc_result_t
rdataset_first(dns_rdataset_t *rdataset) {
unsigned char *raw = rdataset->private3;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
unsigned int count;
count = raw[0] * 256 + raw[1];
@ -5627,11 +5627,20 @@ rdataset_first(dns_rdataset_t *rdataset) {
rdataset->private5 = NULL;
return (ISC_R_NOMORE);
}
raw += 2;
if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0)
raw += 2 + (4 * count);
else
raw += 2;
/*
* The privateuint4 field is the number of rdata beyond the cursor
* position, so we decrement the total count by one before storing
* it.
* The privateuint4 field is the number of rdata beyond the
* cursor position, so we decrement the total count by one
* before storing it.
*
* If DNS_RDATASETATTR_LOADORDER is not set 'raw' points to the
* first record. If DNS_RDATASETATTR_LOADORDER is set 'raw' points
* to the first entry in the offset table.
*/
count--;
rdataset->privateuint4 = count;
@ -5644,30 +5653,40 @@ static isc_result_t
rdataset_next(dns_rdataset_t *rdataset) {
unsigned int count;
unsigned int length;
unsigned char *raw;
unsigned char *raw; /* RDATASLAB */
count = rdataset->privateuint4;
if (count == 0)
return (ISC_R_NOMORE);
count--;
rdataset->privateuint4 = count;
raw = rdataset->private5;
length = raw[0] * 256 + raw[1];
raw += length + 2;
rdataset->private5 = raw;
if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) {
raw = rdataset->private5;
length = raw[0] * 256 + raw[1];
raw += length + 4;
rdataset->private5 = raw;
} else
rdataset->private5 += 4;
return (ISC_R_SUCCESS);
}
static void
rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
unsigned char *raw = rdataset->private5;
unsigned char *raw = rdataset->private5; /* RDATASLAB */
unsigned int offset;
isc_region_t r;
REQUIRE(raw != NULL);
if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) != 0) {
offset = (raw[0] << 24) + (raw[1] << 16) +
(raw[2] << 8) + raw[3];
raw = rdataset->private3 + offset;
}
r.length = raw[0] * 256 + raw[1];
raw += 2;
raw += 4;
r.base = raw;
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
}
@ -5690,7 +5709,7 @@ rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
static unsigned int
rdataset_count(dns_rdataset_t *rdataset) {
unsigned char *raw = rdataset->private3;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
unsigned int count;
count = raw[0] * 256 + raw[1];
@ -6346,7 +6365,7 @@ rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
{
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
unsigned int current_count = rdataset->privateuint4;
unsigned int count;
rdatasetheader_t *header;
@ -6361,7 +6380,7 @@ rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
header = (struct rdatasetheader *)(raw - sizeof(*header));
total_count = rdataset_count(rdataset);
total_count = raw[0] * 256 + raw[1];
INSIST(total_count > current_count);
count = total_count - current_count - 1;
@ -6488,7 +6507,7 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
{
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
unsigned int current_count = rdataset->privateuint4;
rdatasetheader_t *header;
unsigned int total_count, count;
@ -6505,7 +6524,7 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
header = (struct rdatasetheader *)(raw - sizeof(*header));
total_count = rdataset_count(rdataset);
total_count = raw[0] * 256 + raw[1];
INSIST(total_count > current_count);
count = total_count - current_count - 1; /* should be private data */
@ -6613,7 +6632,7 @@ rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
{
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
unsigned int current_count = rdataset->privateuint4;
rdatasetheader_t *header;
nodelock_t *nodelock;
@ -6630,7 +6649,7 @@ rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
header = (struct rdatasetheader *)(raw - sizeof(*header));
total_count = rdataset_count(rdataset);
total_count = raw[0] * 256 + raw[1];
INSIST(total_count > current_count);
count = total_count - current_count - 1;

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataslab.c,v 1.38 2005/04/29 00:22:51 marka Exp $ */
/* $Id: rdataslab.c,v 1.39 2006/03/03 00:43:35 marka Exp $ */
/*! \file */
@ -33,25 +33,95 @@
#include <dns/rdataset.h>
#include <dns/rdataslab.h>
/*
* The rdataslab structure allows iteration to occur in both load order
* and DNSSEC order. The structure is as follows:
*
* header (reservelen bytes)
* record count (2 bytes)
* offset table (4 x record count bytes in load order)
* data records
* data length (2 bytes)
* order (2 bytes)
* data (data length bytes)
*
* Offsets are from the end of the header.
*
* Load order traversal is performed by walking the offset table to find
* the start of the record.
*
* DNSSEC order traversal is performed by walking the data records.
*
* The order is stored with record to allow for efficient reconstuction of
* of the offset table following a merge or subtraction.
*
* The iterator methods here currently only support DNSSEC order iteration.
*
* The iterator methods in rbtdb support both load order and DNSSEC order
* iteration.
*
* WARNING:
* rbtdb.c directly interacts with the slab's raw structures. If the
* structure changes then rbtdb.c also needs to be updated to reflect
* the changes. See the areas tagged with "RDATASLAB".
*/
struct xrdata {
dns_rdata_t rdata;
unsigned int order;
};
/*% Note: the "const void *" are just to make qsort happy. */
static int
compare_rdata(const void *p1, const void *p2) {
const dns_rdata_t *rdata1 = p1;
const dns_rdata_t *rdata2 = p2;
return (dns_rdata_compare(rdata1, rdata2));
const struct xrdata *x1 = p1;
const struct xrdata *x2 = p2;
return (dns_rdata_compare(&x1->rdata, &x2->rdata));
}
static void
fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
unsigned length)
{
unsigned int i, j;
unsigned char *raw;
for (i = 0, j = 0; i < length; i++) {
if (offsettable[i] == 0)
continue;
/*
* Fill in offset table.
*/
raw = &offsetbase[j*4 + 2];
*raw++ = (offsettable[i] & 0xff000000) >> 24;
*raw++ = (offsettable[i] & 0xff0000) >> 16;
*raw++ = (offsettable[i] & 0xff00) >> 8;
*raw = offsettable[i] & 0xff;
/*
* Fill in table index.
*/
raw = offsetbase + offsettable[i] + 2;
*raw++ = (j & 0xff00) >> 8;
*raw = j++ & 0xff;
}
}
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
isc_region_t *region, unsigned int reservelen)
{
dns_rdata_t *rdatas;
struct xrdata *x;
unsigned char *rawbuf;
unsigned char *offsetbase;
unsigned int buflen;
isc_result_t result;
unsigned int nitems;
unsigned int nalloc;
unsigned int i;
unsigned int *offsettable;
buflen = reservelen + 2;
@ -60,8 +130,11 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
if (nitems == 0)
return (ISC_R_FAILURE);
rdatas = isc_mem_get(mctx, nalloc * sizeof(dns_rdata_t));
if (rdatas == NULL)
if (nalloc > 0xffff)
return (ISC_R_NOSPACE);
x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata));
if (x == NULL)
return (ISC_R_NOMEMORY);
/*
@ -72,8 +145,9 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
goto free_rdatas;
for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) {
INSIST(result == ISC_R_SUCCESS);
dns_rdata_init(&rdatas[i]);
dns_rdataset_current(rdataset, &rdatas[i]);
dns_rdata_init(&x[i].rdata);
dns_rdataset_current(rdataset, &x[i].rdata);
x[i].order = i;
result = dns_rdataset_next(rdataset);
}
if (result != ISC_R_NOMORE)
@ -87,7 +161,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
goto free_rdatas;
}
qsort(rdatas, nalloc, sizeof(dns_rdata_t), compare_rdata);
/*
* Put into DNSSEC order.
*/
qsort(x, nalloc, sizeof(struct xrdata), compare_rdata);
/*
* Remove duplicates and compute the total storage required.
@ -95,20 +172,27 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
* If an rdata is not a duplicate, accumulate the storage size
* required for the rdata. We do not store the class, type, etc,
* just the rdata, so our overhead is 2 bytes for the number of
* records, and 2 for each rdata length, and then the rdata itself.
* records, and 8 for each rdata, (length(2), offset(4) and order(2))
* and then the rdata itself.
*/
for (i = 1; i < nalloc; i++) {
if (compare_rdata(&rdatas[i-1], &rdatas[i]) == 0) {
rdatas[i-1].data = NULL;
rdatas[i-1].length = 0;
if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
x[i-1].rdata.data = NULL;
x[i-1].rdata.length = 0;
/*
* Preserve the least order so A, B, A -> A, B
* after duplicate removal.
*/
if (x[i-1].order < x[i].order)
x[i].order = x[i-1].order;
nitems--;
} else
buflen += (2 + rdatas[i-1].length);
buflen += (8 + x[i-1].rdata.length);
}
/*
* Don't forget the last item!
*/
buflen += (2 + rdatas[i-1].length);
buflen += (8 + x[i-1].rdata.length);
/*
* Ensure that singleton types are actually singletons.
@ -131,26 +215,47 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
result = ISC_R_NOMEMORY;
goto free_rdatas;
}
/* Allocate temporary offset table. */
offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int));
if (offsettable == NULL) {
isc_mem_put(mctx, rawbuf, buflen);
result = ISC_R_NOMEMORY;
goto free_rdatas;
}
memset(offsettable, 0, nalloc * sizeof(unsigned int));
region->base = rawbuf;
region->length = buflen;
rawbuf += reservelen;
offsetbase = rawbuf;
*rawbuf++ = (nitems & 0xff00) >> 8;
*rawbuf++ = (nitems & 0x00ff);
/* Skip load order table. Filled in later. */
rawbuf += nitems * 4;
for (i = 0; i < nalloc; i++) {
if (rdatas[i].data == NULL)
if (x[i].rdata.data == NULL)
continue;
*rawbuf++ = (rdatas[i].length & 0xff00) >> 8;
*rawbuf++ = (rdatas[i].length & 0x00ff);
memcpy(rawbuf, rdatas[i].data, rdatas[i].length);
rawbuf += rdatas[i].length;
offsettable[x[i].order] = rawbuf - offsetbase;
*rawbuf++ = (x[i].rdata.length & 0xff00) >> 8;
*rawbuf++ = (x[i].rdata.length & 0x00ff);
rawbuf += 2; /* filled in later */
memcpy(rawbuf, x[i].rdata.data, x[i].rdata.length);
rawbuf += x[i].rdata.length;
}
fillin_offsets(offsetbase, offsettable, nalloc);
isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int));
result = ISC_R_SUCCESS;
free_rdatas:
isc_mem_put(mctx, rdatas, nalloc * sizeof(dns_rdata_t));
isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata));
return (result);
}
@ -169,7 +274,7 @@ rdataset_first(dns_rdataset_t *rdataset) {
rdataset->private5 = NULL;
return (ISC_R_NOMORE);
}
raw += 2;
raw += 2 + (4 * count);
/*
* The privateuint4 field is the number of rdata beyond the cursor
* position, so we decrement the total count by one before storing
@ -195,7 +300,7 @@ rdataset_next(dns_rdataset_t *rdataset) {
rdataset->privateuint4 = count;
raw = rdataset->private5;
length = raw[0] * 256 + raw[1];
raw += length + 2;
raw += length + 4;
rdataset->private5 = raw;
return (ISC_R_SUCCESS);
@ -209,7 +314,7 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
REQUIRE(raw != NULL);
r.length = raw[0] * 256 + raw[1];
raw += 2;
raw += 4;
r.base = raw;
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
}
@ -285,11 +390,12 @@ dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) {
current = slab + reservelen;
count = *current++ * 256;
count += *current++;
current += (4 * count);
while (count > 0) {
count--;
length = *current++ * 256;
length += *current++;
current += length;
current += length + 2;
}
return ((unsigned int)(current - slab));
@ -311,6 +417,7 @@ rdata_from_slab(unsigned char **current,
region.length = *tcurrent++ * 256;
region.length += *tcurrent++;
tcurrent += 2;
region.base = tcurrent;
tcurrent += region.length;
dns_rdata_fromregion(rdata, rdclass, type, &region);
@ -330,15 +437,22 @@ rdata_in_slab(unsigned char *slab, unsigned int reservelen,
unsigned int count, i;
unsigned char *current;
dns_rdata_t trdata = DNS_RDATA_INIT;
int n;
current = slab + reservelen;
count = *current++ * 256;
count += *current++;
current += (4 * count);
for (i = 0; i < count; i++) {
rdata_from_slab(&current, rdclass, type, &trdata);
if (dns_rdata_compare(&trdata, rdata) == 0)
n = dns_rdata_compare(&trdata, rdata);
if (n == 0)
return (ISC_TRUE);
if (n > 0) /* In DNSSEC order. */
break;
dns_rdata_reset(&trdata);
}
return (ISC_FALSE);
@ -359,6 +473,11 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
unsigned int oadded = 0;
unsigned int nadded = 0;
unsigned int nncount = 0;
unsigned int oncount;
unsigned int norder = 0;
unsigned int oorder = 0;
unsigned char *offsetbase;
unsigned int *offsettable;
/*
* XXX Need parameter to allow "delete rdatasets in nslab" merge,
@ -371,12 +490,16 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
ocurrent = oslab + reservelen;
ocount = *ocurrent++ * 256;
ocount += *ocurrent++;
ocurrent += (4 * ocount);
ostart = ocurrent;
ncurrent = nslab + reservelen;
ncount = *ncurrent++ * 256;
ncount += *ncurrent++;
ncurrent += (4 * ncount);
INSIST(ocount > 0 && ncount > 0);
oncount = ncount;
/*
* Yes, this is inefficient!
*/
@ -388,8 +511,8 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
for (count = 0; count < ocount; count++) {
length = *ocurrent++ * 256;
length += *ocurrent++;
olength += length + 2;
ocurrent += length;
olength += length + 8;
ocurrent += length + 2;
}
/*
@ -405,6 +528,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
do {
nregion.length = *ncurrent++ * 256;
nregion.length += *ncurrent++;
ncurrent += 2;
nregion.base = ncurrent;
dns_rdata_init(&nrdata);
dns_rdata_fromregion(&nrdata, rdclass, type, &nregion);
@ -413,7 +537,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
/*
* This rdata isn't in the old slab.
*/
tlength += nregion.length + 2;
tlength += nregion.length + 8;
tcount++;
nncount++;
added_something = ISC_TRUE;
@ -441,6 +565,9 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
return (DNS_R_SINGLETON);
}
if (tcount > 0xffff)
return (ISC_R_NOSPACE);
/*
* Copy the reserved area from the new slab.
*/
@ -449,6 +576,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
return (ISC_R_NOMEMORY);
memcpy(tstart, nslab, reservelen);
tcurrent = tstart + reservelen;
offsetbase = tcurrent;
/*
* Write the new count.
@ -456,17 +584,36 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
*tcurrent++ = (tcount & 0xff00) >> 8;
*tcurrent++ = (tcount & 0x00ff);
/*
* Skip offset table.
*/
tcurrent += (tcount * 4);
offsettable = isc_mem_get(mctx,
(ocount + oncount) * sizeof(unsigned int));
if (offsettable == NULL) {
isc_mem_put(mctx, tstart, tlength);
return (ISC_R_NOMEMORY);
}
memset(offsettable, 0, (ocount + oncount) * sizeof(unsigned int));
/*
* Merge the two slabs.
*/
ocurrent = ostart;
INSIST(ocount != 0);
oorder = ocurrent[2] * 256 + ocurrent[3];
INSIST(oorder < ocount);
rdata_from_slab(&ocurrent, rdclass, type, &ordata);
ncurrent = nslab + reservelen + 2;
ncurrent += (4 * oncount);
if (ncount > 0) {
do {
dns_rdata_reset(&nrdata);
norder = ncurrent[2] * 256 + ncurrent[3];
INSIST(norder < oncount);
rdata_from_slab(&ncurrent, rdclass, type, &nrdata);
} while (rdata_in_slab(oslab, reservelen, rdclass,
type, &nrdata));
@ -481,27 +628,35 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
else
fromold = ISC_TF(compare_rdata(&ordata, &nrdata) < 0);
if (fromold) {
offsettable[oorder] = tcurrent - offsetbase;
length = ordata.length;
*tcurrent++ = (length & 0xff00) >> 8;
*tcurrent++ = (length & 0x00ff);
tcurrent += 2; /* fill in later */
memcpy(tcurrent, ordata.data, length);
tcurrent += length;
oadded++;
if (oadded < ocount) {
dns_rdata_reset(&ordata);
oorder = ocurrent[2] * 256 + ocurrent[3];
INSIST(oorder < ocount);
rdata_from_slab(&ocurrent, rdclass, type,
&ordata);
}
} else {
offsettable[ocount + norder] = tcurrent - offsetbase;
length = nrdata.length;
*tcurrent++ = (length & 0xff00) >> 8;
*tcurrent++ = (length & 0x00ff);
tcurrent += 2; /* fill in later */
memcpy(tcurrent, nrdata.data, length);
tcurrent += length;
nadded++;
if (nadded < ncount) {
do {
dns_rdata_reset(&nrdata);
norder = ncurrent[2] * 256 + ncurrent[3];
INSIST(norder < oncount);
rdata_from_slab(&ncurrent, rdclass,
type, &nrdata);
} while (rdata_in_slab(oslab, reservelen,
@ -511,6 +666,11 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
}
}
fillin_offsets(offsetbase, offsettable, ocount + oncount);
isc_mem_put(mctx, offsettable,
(ocount + oncount) * sizeof(unsigned int));
INSIST(tcurrent == tstart + tlength);
*tslabp = tstart;
@ -525,9 +685,12 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
unsigned int flags, unsigned char **tslabp)
{
unsigned char *mcurrent, *sstart, *scurrent, *tstart, *tcurrent;
unsigned int mcount, scount, rcount ,count, tlength, tcount;
unsigned int mcount, scount, rcount ,count, tlength, tcount, i;
dns_rdata_t srdata = DNS_RDATA_INIT;
dns_rdata_t mrdata = DNS_RDATA_INIT;
unsigned char *offsetbase;
unsigned int *offsettable;
unsigned int order;
REQUIRE(tslabp != NULL && *tslabp == NULL);
REQUIRE(mslab != NULL && sslab != NULL);
@ -538,7 +701,6 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
scurrent = sslab + reservelen;
scount = *scurrent++ * 256;
scount += *scurrent++;
sstart = scurrent;
INSIST(mcount > 0 && scount > 0);
/*
@ -552,11 +714,15 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
tcount = 0;
rcount = 0;
mcurrent += 4 * mcount;
scurrent += 4 * scount;
sstart = scurrent;
/*
* Add in the length of rdata in the mslab that aren't in
* the sslab.
*/
do {
for (i = 0; i < mcount; i++) {
unsigned char *mrdatabegin = mcurrent;
rdata_from_slab(&mcurrent, rdclass, type, &mrdata);
scurrent = sstart;
@ -575,9 +741,10 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
tcount++;
} else
rcount++;
mcount--;
dns_rdata_reset(&mrdata);
} while (mcount > 0);
}
tlength += (4 * tcount);
/*
* Check that all the records originally existed. The numeric
@ -606,6 +773,14 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
return (ISC_R_NOMEMORY);
memcpy(tstart, mslab, reservelen);
tcurrent = tstart + reservelen;
offsetbase = tcurrent;
offsettable = isc_mem_get(mctx, mcount * sizeof(unsigned int));
if (offsettable == NULL) {
isc_mem_put(mctx, tstart, tlength);
return (ISC_R_NOMEMORY);
}
memset(offsettable, 0, mcount * sizeof(unsigned int));
/*
* Write the new count.
@ -613,14 +788,19 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
*tcurrent++ = (tcount & 0xff00) >> 8;
*tcurrent++ = (tcount & 0x00ff);
tcurrent += (4 * tcount);
/*
* Copy the parts of mslab not in sslab.
*/
mcurrent = mslab + reservelen;
mcount = *mcurrent++ * 256;
mcount += *mcurrent++;
do {
mcurrent += (4 * mcount);
for (i = 0; i < mcount; i++) {
unsigned char *mrdatabegin = mcurrent;
order = mcurrent[2] * 256 + mcurrent[3];
INSIST(order < mcount);
rdata_from_slab(&mcurrent, rdclass, type, &mrdata);
scurrent = sstart;
for (count = 0; count < scount; count++) {
@ -635,12 +815,16 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
* copied to the tslab.
*/
unsigned int length = mcurrent - mrdatabegin;
offsettable[order] = tcurrent - offsetbase;
memcpy(tcurrent, mrdatabegin, length);
tcurrent += length;
}
dns_rdata_reset(&mrdata);
mcount--;
} while (mcount > 0);
}
fillin_offsets(offsetbase, offsettable, mcount);
isc_mem_put(mctx, offsettable, mcount * sizeof(unsigned int));
INSIST(tcurrent == tstart + tlength);
@ -668,6 +852,9 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
if (count1 != count2)
return (ISC_FALSE);
current1 += (4 * count1);
current2 += (4 * count2);
while (count1 > 0) {
length1 = *current1++ * 256;
length1 += *current1++;
@ -675,6 +862,9 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
length2 = *current2++ * 256;
length2 += *current2++;
current1 += 2;
current2 += 2;
if (length1 != length2 ||
memcmp(current1, current2, length1) != 0)
return (ISC_FALSE);
@ -708,6 +898,9 @@ dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2,
if (count1 != count2)
return (ISC_FALSE);
current1 += (4 * count1);
current2 += (4 * count2);
while (count1-- > 0) {
rdata_from_slab(&current1, rdclass, type, &rdata1);
rdata_from_slab(&current2, rdclass, type, &rdata2);