matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.1 cyclic.example >dig.out.cyclic || ret=1
+ dig_cmd +qid=$i @10.53.0.1 cyclic.example >dig.out.cyclic || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.1 cyclic2.example >dig.out.cyclic2 || ret=1
+ dig_cmd +qid=$i @10.53.0.1 cyclic2.example >dig.out.cyclic2 || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic2 dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.2 cyclic.example >dig.out.cyclic || ret=1
+ dig_cmd +qid=$i @10.53.0.2 cyclic.example >dig.out.cyclic || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.2 cyclic2.example >dig.out.cyclic2 || ret=1
+ dig_cmd +qid=$i @10.53.0.2 cyclic2.example >dig.out.cyclic2 || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic2 dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.2 cyclic.example >dig.out.cyclic || ret=1
+ dig_cmd +qid=$i @10.53.0.2 cyclic.example >dig.out.cyclic || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.2 cyclic2.example >dig.out.cyclic2 || ret=1
+ dig_cmd +qid=$i @10.53.0.2 cyclic2.example >dig.out.cyclic2 || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic2 dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.3 cyclic.example >dig.out.cyclic || ret=1
+ dig_cmd +qid=$i @10.53.0.3 cyclic.example >dig.out.cyclic || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic dig.out.$j
else
matches=0
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
j=$((i % 4))
- dig_cmd @10.53.0.3 cyclic2.example >dig.out.cyclic2 || ret=1
+ dig_cmd +qid=$i @10.53.0.3 cyclic2.example >dig.out.cyclic2 || ret=1
if [ $i -le 4 ]; then
cp dig.out.cyclic2 dig.out.$j
else
exactly like ``cyclic``.
``cyclic``
- Records are returned in a cyclic round-robin order, rotating by one
- record per query.
+ Records are returned in a cyclic round-robin order, offset is based
+ on the query ID, for speed and thread safety.
``none``
Records are returned in the order they were retrieved from the
statements are present in the configuration file used by :iscman:`named`:
- If no :any:`rrset-order` statement is present in the configuration
- file, the implicit default is to return all records in ``random``
+ file, the implicit default is to return all records in ``cyclic``
order.
- If any :any:`rrset-order` statements are present in the configuration
dns_orderopt_t order : 2;
} attributes;
- /*%
- * the counter provides the starting point in the "cyclic" order.
- * The value 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.
- */
- uint32_t count;
-
/*
* This RRSIG RRset should be re-generated around this time.
* Only valid if 'resign' attribute is set.
};
};
-#define DNS_RDATASET_COUNT_UNDEFINED UINT32_MAX
-
-#define DNS_RDATASET_INIT \
- { .magic = DNS_RDATASET_MAGIC, \
- .link = ISC_LINK_INITIALIZER, \
- .count = DNS_RDATASET_COUNT_UNDEFINED }
+#define DNS_RDATASET_INIT \
+ { \
+ .magic = DNS_RDATASET_MAGIC, \
+ .link = ISC_LINK_INITIALIZER, \
+ }
/* clang-format off */
/*
isc_result_t
dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
- dns_compress_t *cctx, isc_buffer_t *target,
- unsigned int options, unsigned int *countp);
+ uint16_t id, dns_compress_t *cctx, isc_buffer_t *target,
+ bool partial, unsigned int options, unsigned int *countp);
/*%<
* Convert 'rdataset' to wire format, compressing names as specified
* in 'cctx', and storing the result in 'target'.
* Notes:
*\li The rdata cursor position will be changed.
*
+ *\li If 'partial' is true, a partial rdataset may be written.
+ *
*\li The number of RRs added to target will be added to *countp.
*
* Requires:
* dns_name_towire().
*/
-isc_result_t
-dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
- const dns_name_t *owner_name, dns_compress_t *cctx,
- isc_buffer_t *target, unsigned int options,
- unsigned int *countp, void **state);
-/*%<
- * Like dns_rdataset_towire() except that a partial rdataset may be written.
- *
- * Requires:
- *\li All the requirements of dns_rdataset_towiresorted().
- * If 'state' is non NULL then the current position in the
- * rdataset will be remembered if the rdataset in not
- * completely written and should be passed on on subsequent
- * calls (NOT CURRENTLY IMPLEMENTED).
- *
- * Returns:
- *\li #ISC_R_SUCCESS if all of the records were written.
- *\li #ISC_R_NOSPACE if unable to fit in all of the records. *countp
- * will be updated to reflect the number of records
- * written.
- */
-
isc_result_t
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
const dns_name_t *owner_name,
};
dns_typepair_t typepair;
- _Atomic(uint16_t) count;
- /*%<
- * Monotonically 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.
- */
-
/* resigning (zone) and TTL-cleaning (cache) */
uint16_t resign_lsb : 1;
isc_stdtime_t resign;
}
static isc_result_t
-renderset(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
+renderset(dns_rdataset_t *rdataset, const dns_name_t *owner_name, uint16_t id,
dns_compress_t *cctx, isc_buffer_t *target, unsigned int reserved,
unsigned int options, unsigned int *countp) {
isc_result_t result;
}
target->length -= reserved;
- result = dns_rdataset_towire(rdataset, owner_name, cctx, target,
- options, countp);
+ result = dns_rdataset_towire(rdataset, owner_name, id, cctx, target,
+ false, options, countp);
target->length += reserved;
return result;
{
st = *(msg->buffer);
count = 0;
- if (partial) {
- result = dns_rdataset_towirepartial(
- rdataset, name, msg->cctx, msg->buffer,
- rd_options, &count, NULL);
- } else {
- result = dns_rdataset_towire(
- rdataset, name, msg->cctx, msg->buffer,
- rd_options, &count);
- }
+ result = dns_rdataset_towire(
+ rdataset, name, msg->id, msg->cctx, msg->buffer,
+ partial, rd_options, &count);
total += count;
if (partial && result == ISC_R_NOSPACE) {
msg->flags |= DNS_MESSAGEFLAG_TC;
st = *(msg->buffer);
count = 0;
- if (partial) {
- result = dns_rdataset_towirepartial(
- rds, n, msg->cctx, msg->buffer,
- rd_options, &count, NULL);
- } else {
- result = dns_rdataset_towire(
- rds, n, msg->cctx, msg->buffer,
- rd_options, &count);
- }
+ result = dns_rdataset_towire(
+ rds, n, msg->id, msg->cctx, msg->buffer,
+ partial, rd_options, &count);
total += count;
* Render.
*/
count = 0;
- result = renderset(msg->opt, dns_rootname, msg->cctx,
+ result = renderset(msg->opt, dns_rootname, msg->id, msg->cctx,
msg->buffer, msg->reserved, 0, &count);
msg->counts[DNS_SECTION_ADDITIONAL] += count;
if (result != ISC_R_SUCCESS) {
return result;
}
count = 0;
- result = renderset(msg->tsig, msg->tsigname, msg->cctx,
+ result = renderset(msg->tsig, msg->tsigname, msg->id, msg->cctx,
msg->buffer, msg->reserved, 0, &count);
msg->counts[DNS_SECTION_ADDITIONAL] += count;
if (result != ISC_R_SUCCESS) {
* the owner name of a SIG(0) is irrelevant, and will not
* be set in a message being rendered.
*/
- result = renderset(msg->sig0, dns_rootname, msg->cctx,
+ result = renderset(msg->sig0, dns_rootname, msg->id, msg->cctx,
msg->buffer, msg->reserved, 0, &count);
msg->counts[DNS_SECTION_ADDITIONAL] += count;
if (result != ISC_R_SUCCESS) {
static void
cleanup_deadnodes_cb(void *arg);
-/*%
- * 'init_count' is used to initialize 'newheader->count' which in turn
- * is used to determine where in the cycle rrset-order cyclic starts.
- * We don't lock this as we don't care about simultaneous updates.
- */
-static atomic_uint_fast16_t init_count = 0;
-
/*
* Locking
*
rdataset->ttl = 0;
}
- rdataset->count = atomic_fetch_add_relaxed(&header->count, 1);
-
rdataset->slab.db = (dns_db_t *)qpdb;
rdataset->slab.node = (dns_dbnode_t *)node;
rdataset->slab.raw = header->raw;
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_ZEROTTL);
}
- atomic_init(&newheader->count,
- atomic_fetch_add_relaxed(&init_count, 1));
if (rdataset->attributes.prefetch) {
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_PREFETCH);
}
enum { full, nonsec3, nsec3only } nsec3mode;
} qpdb_dbiterator_t;
-/*%
- * 'init_count' is used to initialize 'newheader->count' which inturn
- * is used to determine where in the cycle rrset-order cyclic starts.
- * We don't lock this as we don't care about simultaneous updates.
- */
-static atomic_uint_fast16_t init_count = 0;
-
/*
* Locking
*
rdataset->attributes.optout = true;
}
- rdataset->count = atomic_fetch_add_relaxed(&header->count, 1);
-
rdataset->slab.db = (dns_db_t *)qpdb;
rdataset->slab.node = (dns_dbnode_t *)node;
rdataset->slab.raw = header->raw;
newheader->ttl = rdataset->ttl;
newheader->trust = rdataset->trust;
newheader->serial = 1;
- newheader->count = 1;
dns_slabheader_setownercase(newheader, name);
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_ZEROTTL);
}
- atomic_init(&newheader->count,
- atomic_fetch_add_relaxed(&init_count, 1));
-
newheader->serial = version->serial;
if (rdataset->attributes.resign) {
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_RESIGN);
newheader->ttl = rdataset->ttl;
atomic_init(&newheader->attributes, 0);
newheader->serial = version->serial;
- atomic_init(&newheader->count,
- atomic_fetch_add_relaxed(&init_count, 1));
if (rdataset->attributes.resign) {
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_RESIGN);
newheader->resign =
.rdlist.list = rdatalist,
.link = rdataset->link,
- .count = rdataset->count,
.attributes = rdataset->attributes,
.magic = rdataset->magic,
};
*rdataset = (dns_rdataset_t){
.magic = DNS_RDATASET_MAGIC,
.link = ISC_LINK_INITIALIZER,
- .count = DNS_RDATASET_COUNT_UNDEFINED,
};
}
*rdataset = (dns_rdataset_t){
.magic = 0,
.link = ISC_LINK_INITIALIZER,
- .count = DNS_RDATASET_COUNT_UNDEFINED,
};
}
*rdataset = (dns_rdataset_t){
.magic = DNS_RDATASET_MAGIC,
.link = ISC_LINK_INITIALIZER,
- .count = DNS_RDATASET_COUNT_UNDEFINED,
};
}
static isc_result_t
towire_question(dns_rdataset_t *rdataset, const dns_name_t *name,
dns_compress_t *cctx, isc_buffer_t *target,
- isc_buffer_t *rrbuffer, unsigned int options ISC_ATTR_UNUSED,
- unsigned int *countp) {
+ isc_buffer_t *rrbuffer, unsigned int *countp) {
isc_result_t result;
result = dns_rdataset_first(rdataset);
static isc_result_t
towire_answer(dns_rdataset_t *rdataset, const dns_name_t *name,
dns_compress_t *cctx, isc_buffer_t *target,
- isc_buffer_t *rrbuffer, unsigned int options ISC_ATTR_UNUSED,
- unsigned int *countp) {
+ isc_buffer_t *rrbuffer, uint16_t id, unsigned int *countp) {
isc_result_t result;
size_t start = 0, count = 0, added = 0;
isc_buffer_t rdlen;
return result;
}
- if (WANT_CYCLIC(rdataset) && rdataset->type != dns_rdatatype_rrsig &&
- rdataset->count != DNS_RDATASET_COUNT_UNDEFINED)
- {
- start = rdataset->count % count;
+ if (WANT_CYCLIC(rdataset) && rdataset->type != dns_rdatatype_rrsig) {
+ start = id % count;
/* Do we need larger buffer? */
if (start > ARRAY_SIZE(dns__rdataset_rdatas)) {
return result;
}
-static isc_result_t
-towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
- dns_compress_t *cctx, isc_buffer_t *target, bool partial,
- unsigned int options, unsigned int *countp,
- void **state ISC_ATTR_UNUSED) {
+isc_result_t
+dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
+ uint16_t id, dns_compress_t *cctx, isc_buffer_t *target,
+ bool partial, unsigned int options, unsigned int *countp) {
isc_result_t result;
isc_buffer_t savedbuffer = *target;
isc_buffer_t rrbuffer;
if (rdataset->attributes.question) {
result = towire_question(rdataset, name, cctx, target,
- &rrbuffer, options, countp);
+ &rrbuffer, countp);
if (result != ISC_R_SUCCESS) {
goto rollback;
}
} else {
result = towire_answer(rdataset, name, cctx, target, &rrbuffer,
- options, countp);
+ id, countp);
if (result != ISC_R_SUCCESS) {
goto rollback;
}
return result;
}
-isc_result_t
-dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
- const dns_name_t *owner_name, dns_compress_t *cctx,
- isc_buffer_t *target, unsigned int options,
- unsigned int *countp, void **state) {
- REQUIRE(state == NULL); /* XXX remove when implemented */
- return towire(rdataset, owner_name, cctx, target, true, options, countp,
- state);
-}
-
-isc_result_t
-dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
- dns_compress_t *cctx, isc_buffer_t *target,
- unsigned int options, unsigned int *countp) {
- return towire(rdataset, owner_name, cctx, target, false, options,
- countp, NULL);
-}
-
isc_result_t
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
const dns_name_t *owner_name,
.slab.node = node,
.slab.raw = noqname->neg,
.link = nsec->link,
- .count = nsec->count,
.attributes = nsec->attributes,
.magic = nsec->magic,
};
.slab.node = node,
.slab.raw = noqname->negsig,
.link = nsecsig->link,
- .count = nsecsig->count,
.attributes = nsecsig->attributes,
.magic = nsecsig->magic,
};
.slab.node = node,
.slab.raw = closest->neg,
.link = nsec->link,
- .count = nsec->count,
.attributes = nsec->attributes,
.magic = nsec->magic,
};
.slab.node = node,
.slab.raw = closest->negsig,
.link = nsecsig->link,
- .count = nsecsig->count,
.attributes = nsecsig->attributes,
.magic = nsecsig->magic,
};
ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
dns_rdataset_init(&rdataset);
dns_rdatalist_tordataset(&rdatalist, &rdataset);
- CHECK(dns_rdataset_towire(&rdataset, key->name, &cctx, target, 0,
- &count));
+ CHECK(dns_rdataset_towire(&rdataset, key->name, 0, &cctx, target, false,
+ 0, &count));
/*
* Fixup additional record count.