From: Mark Andrews Date: Mon, 12 Jan 2004 04:19:42 +0000 (+0000) Subject: 1555. [func] 'rrset-order cyclic' now longer has a random starting X-Git-Tag: v9.2.4rc1~81^2~35 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=61fb42c4ef45d88e115bd769c30c4f36b461870b;p=thirdparty%2Fbind9.git 1555. [func] 'rrset-order cyclic' now longer has a random starting point. [RT #7572] --- diff --git a/CHANGES b/CHANGES index 928efca3aa1..29e8725a729 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1555. [func] 'rrset-order cyclic' now longer has a random starting + point. [RT #7572] + 1554. [bug] dig, host, nsloolup failed when no nameservers were specified in /etc/resolv.conf. [RT #8232] diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index 3ca396f42e9..3b000a6cf0f 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.h,v 1.47 2003/02/26 23:52:30 marka Exp $ */ +/* $Id: rdataset.h,v 1.48 2004/01/12 04:19:42 marka Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 @@ -97,6 +97,13 @@ struct dns_rdataset { * attributes */ unsigned int attributes; + /* + * the counter provides the starting point in the "cyclic" order. + * The value ISC_UINT32_MAX has a special meaning of "picking up a + * random value." in order to take care of databases that do not + * increment the counter. + */ + isc_uint32_t count; /* * These are for use by the rdataset implementation, and MUST NOT * be changed by clients. diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index f54952e8cb1..c2016d58458 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.190 2003/10/17 05:31:05 marka Exp $ */ +/* $Id: rbtdb.c,v 1.191 2004/01/12 04:19:42 marka Exp $ */ /* * Principal Author: Bob Halley @@ -122,6 +122,14 @@ typedef struct rdatasetheader { * this rdataset. */ + isc_uint32_t count; + /* + * Monotonously increased every time this rdataset is bound so that + * it is used as the base of the starting point in DNS responses + * when the "cyclic" rrset-order is required. Since the ordering + * should not be so crucial, no lock is set for the counter for + * performance reasons. + */ } rdatasetheader_t; #define RDATASET_ATTR_NONEXISTENT 0x0001 @@ -1355,7 +1363,10 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdataset->private2 = node; raw = (unsigned char *)header + sizeof(*header); rdataset->private3 = raw; - + rdataset->count = header->count++; + if (header->count == ISC_UINT32_MAX) + header->count = 0; + /* * Reset iterator state. */ @@ -3973,6 +3984,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type, rdataset->covers); newheader->attributes = 0; + newheader->count = 0; if (rbtversion != NULL) { newheader->serial = rbtversion->serial; newheader->trust = 0; @@ -4039,6 +4051,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->attributes = 0; newheader->serial = rbtversion->serial; newheader->trust = 0; + newheader->count = 0; LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); @@ -4108,6 +4121,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->attributes = RDATASET_ATTR_NONEXISTENT; newheader->trust = 0; newheader->serial = rbtversion->serial; + newheader->count = 0; } else { free_rdataset(rbtdb->common.mctx, newheader); goto unlock; @@ -4176,6 +4190,7 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->serial = rbtversion->serial; else newheader->serial = 0; + newheader->count = 0; LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); @@ -4251,6 +4266,7 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) { newheader->attributes = 0; newheader->trust = rdataset->trust; newheader->serial = 1; + newheader->count = 0; result = add(rbtdb, node, rbtdb->current_version, newheader, DNS_DBADD_MERGE, ISC_TRUE, NULL, 0); diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index f36834ced51..f99f673edcf 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.c,v 1.68 2003/09/30 05:56:12 marka Exp $ */ +/* $Id: rdataset.c,v 1.69 2004/01/12 04:19:42 marka Exp $ */ #include @@ -49,6 +49,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) { rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; + rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; @@ -74,6 +75,7 @@ dns_rdataset_invalidate(dns_rdataset_t *rdataset) { rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; + rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; @@ -100,6 +102,7 @@ dns_rdataset_disassociate(dns_rdataset_t *rdataset) { rdataset->trust = 0; rdataset->covers = 0; rdataset->attributes = 0; + rdataset->count = ISC_UINT32_MAX; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = NULL; @@ -392,7 +395,9 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, isc_uint32_t val; unsigned int j; - isc_random_get(&val); + val = rdataset->count; + if (val == ISC_UINT32_MAX) + isc_random_get(&val); j = val % count; for (i = 0; i < count; i++) { if (order != NULL)