1999-01-15 03:31:17 +00:00
|
|
|
/*
|
2011-03-12 04:59:49 +00:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
1999-01-15 03:31:17 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
1999-01-15 03:31:17 +00:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
1999-01-15 03:31:17 +00:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
|
|
|
*/
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*! \file */
|
2000-06-22 22:00:42 +00:00
|
|
|
|
2018-03-28 14:19:37 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2000-02-24 21:08:34 +00:00
|
|
|
#include <stdlib.h>
|
1999-01-15 03:31:17 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/buffer.h>
|
2004-02-19 01:23:42 +00:00
|
|
|
#include <isc/mem.h>
|
2002-12-05 04:36:26 +00:00
|
|
|
#include <isc/random.h>
|
2012-07-25 17:06:34 -05:00
|
|
|
#include <isc/serial.h>
|
2000-04-28 01:12:23 +00:00
|
|
|
#include <isc/util.h>
|
1999-01-15 03:31:17 +00:00
|
|
|
|
2015-02-27 15:08:38 +11:00
|
|
|
#include <dns/compress.h>
|
|
|
|
#include <dns/fixedname.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/name.h>
|
1999-09-22 00:26:40 +00:00
|
|
|
#include <dns/ncache.h>
|
1999-01-15 19:36:07 +00:00
|
|
|
#include <dns/rdata.h>
|
1999-01-15 03:31:17 +00:00
|
|
|
#include <dns/rdataset.h>
|
|
|
|
|
2011-05-26 07:56:39 +00:00
|
|
|
static const char *trustnames[] = {
|
|
|
|
"none", "pending-additional",
|
|
|
|
"pending-answer", "additional",
|
|
|
|
"glue", "answer",
|
|
|
|
"authauthority", "authanswer",
|
|
|
|
"secure", "local" /* aka ultimate */
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *
|
|
|
|
dns_trust_totext(dns_trust_t trust) {
|
|
|
|
if (trust >= sizeof(trustnames) / sizeof(*trustnames)) {
|
|
|
|
return ("bad");
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-05-26 07:56:39 +00:00
|
|
|
return (trustnames[trust]);
|
|
|
|
}
|
|
|
|
|
1999-01-15 03:31:17 +00:00
|
|
|
void
|
|
|
|
dns_rdataset_init(dns_rdataset_t *rdataset) {
|
|
|
|
/*
|
|
|
|
* Make 'rdataset' a valid, disassociated rdataset.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(rdataset != NULL);
|
|
|
|
|
2023-04-25 17:26:47 +01:00
|
|
|
*rdataset = (dns_rdataset_t){
|
|
|
|
.magic = DNS_RDATASET_MAGIC,
|
|
|
|
.link = ISC_LINK_INITIALIZER,
|
|
|
|
.count = DNS_RDATASET_COUNT_UNDEFINED,
|
|
|
|
};
|
1999-01-15 03:31:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
|
|
|
|
/*
|
|
|
|
* Invalidate 'rdataset'.
|
|
|
|
*/
|
|
|
|
|
1999-01-15 08:07:09 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
1999-01-15 03:31:17 +00:00
|
|
|
REQUIRE(rdataset->methods == NULL);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
*rdataset = (dns_rdataset_t){
|
|
|
|
.magic = 0,
|
|
|
|
.link = ISC_LINK_INITIALIZER,
|
|
|
|
.count = DNS_RDATASET_COUNT_UNDEFINED,
|
|
|
|
};
|
1999-01-15 03:31:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-01-05 09:12:35 +01:00
|
|
|
dns__rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG) {
|
1999-01-15 03:31:17 +00:00
|
|
|
/*
|
1999-01-28 23:52:24 +00:00
|
|
|
* Disassociate 'rdataset' from its rdata, allowing it to be reused.
|
1999-01-15 03:31:17 +00:00
|
|
|
*/
|
|
|
|
|
1999-01-15 08:07:09 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
1999-04-01 04:01:30 +00:00
|
|
|
REQUIRE(rdataset->methods != NULL);
|
1999-01-15 03:31:17 +00:00
|
|
|
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
if (rdataset->methods->disassociate != NULL) {
|
|
|
|
(rdataset->methods->disassociate)(rdataset DNS__DB_FLARG_PASS);
|
|
|
|
}
|
|
|
|
*rdataset = (dns_rdataset_t){
|
|
|
|
.magic = DNS_RDATASET_MAGIC,
|
|
|
|
.link = ISC_LINK_INITIALIZER,
|
|
|
|
.count = DNS_RDATASET_COUNT_UNDEFINED,
|
|
|
|
};
|
1999-01-15 03:31:17 +00:00
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
1999-08-19 20:44:56 +00:00
|
|
|
dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
|
|
|
|
/*
|
|
|
|
* Is 'rdataset' associated?
|
|
|
|
*/
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-08-19 20:44:56 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
|
|
|
|
if (rdataset->methods != NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-19 20:44:56 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-08-19 20:44:56 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static isc_result_t
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
question_cursor(dns_rdataset_t *rdataset ISC_ATTR_UNUSED) {
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOMORE);
|
1999-07-03 20:52:50 +00:00
|
|
|
}
|
|
|
|
|
1999-07-13 01:50:22 +00:00
|
|
|
static void
|
2023-01-05 09:12:35 +01:00
|
|
|
question_clone(dns_rdataset_t *source, dns_rdataset_t *target DNS__DB_FLARG) {
|
1999-07-13 01:50:22 +00:00
|
|
|
*target = *source;
|
|
|
|
}
|
|
|
|
|
1999-07-03 20:52:50 +00:00
|
|
|
static dns_rdatasetmethods_t question_methods = {
|
2023-02-17 11:46:58 -08:00
|
|
|
.first = question_cursor,
|
|
|
|
.next = question_cursor,
|
|
|
|
.clone = question_clone,
|
1999-07-03 20:52:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
|
|
|
|
dns_rdatatype_t type) {
|
|
|
|
/*
|
|
|
|
* Make 'rdataset' a valid, associated, question rdataset, with a
|
|
|
|
* question class of 'rdclass' and type 'type'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods == NULL);
|
|
|
|
|
|
|
|
rdataset->methods = &question_methods;
|
|
|
|
rdataset->rdclass = rdclass;
|
|
|
|
rdataset->type = type;
|
|
|
|
rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
|
|
|
|
}
|
|
|
|
|
1999-09-21 20:40:42 +00:00
|
|
|
unsigned int
|
|
|
|
dns_rdataset_count(dns_rdataset_t *rdataset) {
|
|
|
|
/*
|
|
|
|
* Return the number of records in 'rdataset'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
REQUIRE(rdataset->methods->count != NULL);
|
1999-09-21 20:40:42 +00:00
|
|
|
|
|
|
|
return ((rdataset->methods->count)(rdataset));
|
|
|
|
}
|
|
|
|
|
1999-07-13 01:50:22 +00:00
|
|
|
void
|
2023-01-05 09:12:35 +01:00
|
|
|
dns__rdataset_clone(dns_rdataset_t *source,
|
|
|
|
dns_rdataset_t *target DNS__DB_FLARG) {
|
1999-07-13 01:50:22 +00:00
|
|
|
/*
|
|
|
|
* Make 'target' refer to the same rdataset as 'source'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(source));
|
|
|
|
REQUIRE(source->methods != NULL);
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(target));
|
|
|
|
REQUIRE(target->methods == NULL);
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2023-01-05 09:12:35 +01:00
|
|
|
(source->methods->clone)(source, target DNS__DB_FLARG_PASS);
|
1999-07-13 01:50:22 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-01-15 03:31:17 +00:00
|
|
|
dns_rdataset_first(dns_rdataset_t *rdataset) {
|
|
|
|
/*
|
|
|
|
* Move the rdata cursor to the first rdata in the rdataset (if any).
|
|
|
|
*/
|
|
|
|
|
1999-01-15 08:07:09 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
1999-04-01 04:01:30 +00:00
|
|
|
REQUIRE(rdataset->methods != NULL);
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
REQUIRE(rdataset->methods->first != NULL);
|
1999-01-15 03:31:17 +00:00
|
|
|
|
|
|
|
return ((rdataset->methods->first)(rdataset));
|
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-01-15 03:31:17 +00:00
|
|
|
dns_rdataset_next(dns_rdataset_t *rdataset) {
|
|
|
|
/*
|
|
|
|
* Move the rdata cursor to the next rdata in the rdataset (if any).
|
|
|
|
*/
|
|
|
|
|
1999-01-15 08:07:09 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
1999-04-01 04:01:30 +00:00
|
|
|
REQUIRE(rdataset->methods != NULL);
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
REQUIRE(rdataset->methods->next != NULL);
|
1999-01-15 03:31:17 +00:00
|
|
|
|
|
|
|
return ((rdataset->methods->next)(rdataset));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
|
|
|
|
/*
|
|
|
|
* Make 'rdata' refer to the current rdata.
|
|
|
|
*/
|
|
|
|
|
1999-01-15 08:07:09 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
1999-04-01 04:01:30 +00:00
|
|
|
REQUIRE(rdataset->methods != NULL);
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
REQUIRE(rdataset->methods->current != NULL);
|
1999-01-15 03:31:17 +00:00
|
|
|
|
|
|
|
(rdataset->methods->current)(rdataset, rdata);
|
|
|
|
}
|
|
|
|
|
2000-02-24 21:08:34 +00:00
|
|
|
#define MAX_SHUFFLE 32
|
|
|
|
#define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
|
2002-03-07 13:46:41 +00:00
|
|
|
#define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
|
2017-04-22 08:25:10 +05:30
|
|
|
#define WANT_CYCLIC(r) (((r)->attributes & DNS_RDATASETATTR_CYCLIC) != 0)
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-11-10 03:16:26 +00:00
|
|
|
struct towire_sort {
|
|
|
|
int key;
|
|
|
|
dns_rdata_t *rdata;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
|
|
|
towire_compare(const void *av, const void *bv) {
|
|
|
|
const struct towire_sort *a = (const struct towire_sort *)av;
|
|
|
|
const struct towire_sort *b = (const struct towire_sort *)bv;
|
|
|
|
return (a->key - b->key);
|
|
|
|
}
|
2000-02-24 21:08:34 +00:00
|
|
|
|
2021-10-11 13:43:12 +02:00
|
|
|
static void
|
2018-08-05 07:18:27 +02:00
|
|
|
swap_rdata(dns_rdata_t *in, unsigned int a, unsigned int b) {
|
2018-08-24 21:38:39 +02:00
|
|
|
dns_rdata_t rdata = in[a];
|
2018-08-05 07:18:27 +02:00
|
|
|
in[a] = in[b];
|
|
|
|
in[b] = rdata;
|
|
|
|
}
|
|
|
|
|
2001-06-05 09:02:16 +00:00
|
|
|
static isc_result_t
|
2006-02-28 02:39:52 +00:00
|
|
|
towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
|
2001-06-05 09:02:16 +00:00
|
|
|
dns_compress_t *cctx, isc_buffer_t *target,
|
2006-02-28 02:39:52 +00:00
|
|
|
dns_rdatasetorderfunc_t order, const void *order_arg, bool partial,
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
unsigned int options, unsigned int *countp,
|
|
|
|
void **state ISC_ATTR_UNUSED) {
|
1999-01-27 05:54:39 +00:00
|
|
|
isc_region_t r;
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t result;
|
2018-08-05 07:18:27 +02:00
|
|
|
unsigned int i, count = 0, added;
|
2001-06-05 09:17:21 +00:00
|
|
|
isc_buffer_t savedbuffer, rdlen, rrbuffer;
|
1999-04-30 07:08:55 +00:00
|
|
|
unsigned int headlen;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool question = false;
|
|
|
|
bool shuffle = false, sort = false;
|
|
|
|
bool want_random, want_cyclic;
|
2017-07-21 11:52:24 +10:00
|
|
|
dns_rdata_t in_fixed[MAX_SHUFFLE];
|
|
|
|
dns_rdata_t *in = in_fixed;
|
|
|
|
struct towire_sort out_fixed[MAX_SHUFFLE];
|
|
|
|
struct towire_sort *out = out_fixed;
|
2015-02-27 15:08:38 +11:00
|
|
|
dns_fixedname_t fixed;
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
dns_name_t *name = NULL;
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t offset;
|
1999-01-15 03:31:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert 'rdataset' to wire format, compressing names as specified
|
|
|
|
* in cctx, and storing the result in 'target'.
|
|
|
|
*/
|
|
|
|
|
1999-01-15 19:36:07 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
2017-01-31 11:20:03 +11:00
|
|
|
REQUIRE(rdataset->methods != NULL);
|
1999-01-30 05:01:01 +00:00
|
|
|
REQUIRE(countp != NULL);
|
2004-02-19 01:23:42 +00:00
|
|
|
REQUIRE(cctx != NULL && cctx->mctx != NULL);
|
1999-01-15 19:36:07 +00:00
|
|
|
|
2017-09-27 10:27:09 +10:00
|
|
|
want_random = WANT_RANDOM(rdataset);
|
|
|
|
want_cyclic = WANT_CYCLIC(rdataset);
|
|
|
|
|
1999-08-03 20:54:56 +00:00
|
|
|
if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
question = true;
|
2000-02-24 21:08:34 +00:00
|
|
|
count = 1;
|
1999-08-03 20:54:56 +00:00
|
|
|
result = dns_rdataset_first(rdataset);
|
2000-04-06 22:03:35 +00:00
|
|
|
INSIST(result == ISC_R_NOMORE);
|
2011-06-08 22:13:51 +00:00
|
|
|
} else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
|
1999-09-22 00:26:40 +00:00
|
|
|
/*
|
|
|
|
* This is a negative caching rdataset.
|
|
|
|
*/
|
2002-01-23 08:46:40 +00:00
|
|
|
unsigned int ncache_opts = 0;
|
|
|
|
if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0) {
|
|
|
|
ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-01-23 08:46:40 +00:00
|
|
|
return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
|
2002-01-22 09:07:30 +00:00
|
|
|
countp));
|
1999-08-03 20:54:56 +00:00
|
|
|
} else {
|
Give the rdataset->privateN fields more helpful names
BIND's rdataset structure is a view of some DNS records. It is
polymorphic, so the details of how the records are stored can vary.
For instance, the records can be held in an rdatalist, or in an
rdataslab in the rbtdb.
The dns_rdataset structure previously had a number of fields called
`private1` up to `private7`, which were used by the various rdataset
implementations. It was not at all clear what these fields were for,
without reading the code and working it out from context.
This change makes the rdataset inheritance hierarchy more clear. The
polymorphic part of a `struct dns_rdataset` is now a union of structs,
each of which is named for the class of implementation using it. The
fields of these structs replace the old `privateN` fields. (Note: the
term "inheritance hierarchy" refers to the fact that the builtin and
SDLZ implementations are based on and inherit from the rdatalist
implementation, which in turn inherits from the generic rdataset.
Most of this change is mechanical, but there are a few extras.
In keynode.c there were a number of REQUIRE()ments that were not
necessary: they had already been checked by the rdataset method
dispatch code. On the other hand, In ncache.c there was a public
function which needed to REQUIRE() that an rdataset was valid.
I have removed lots of "reset iterator state" comments, because it
should now be clear from `target->iter = NULL` where before
`target->private5 = NULL` could have been doing anything.
Initialization is a bit neater in a few places, using C structure
literals where appropriate.
The pointer arithmetic for translating between an rdataslab header and
its raw contents is now fractionally safer.
2023-04-28 01:12:39 +01:00
|
|
|
count = dns_rdataset_count(rdataset);
|
1999-07-03 20:52:50 +00:00
|
|
|
result = dns_rdataset_first(rdataset);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result == ISC_R_NOMORE) {
|
|
|
|
return (ISC_R_SUCCESS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-07-03 20:52:50 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-07-03 20:52:50 +00:00
|
|
|
}
|
|
|
|
|
2000-11-10 03:16:26 +00:00
|
|
|
/*
|
2017-04-22 08:25:10 +05:30
|
|
|
* Do we want to sort and/or shuffle this answer?
|
2000-11-10 03:16:26 +00:00
|
|
|
*/
|
2017-04-22 08:25:10 +05:30
|
|
|
if (!question && count > 1 && rdataset->type != dns_rdatatype_rrsig) {
|
|
|
|
if (order != NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
sort = true;
|
2017-04-22 08:25:10 +05:30
|
|
|
}
|
2017-09-27 10:27:09 +10:00
|
|
|
if (want_random || want_cyclic) {
|
2018-04-17 08:29:14 -07:00
|
|
|
shuffle = true;
|
2017-04-22 08:25:10 +05:30
|
|
|
}
|
2004-02-19 01:23:42 +00:00
|
|
|
}
|
|
|
|
|
2018-08-05 07:18:27 +02:00
|
|
|
if ((shuffle || sort)) {
|
|
|
|
if (count > MAX_SHUFFLE) {
|
|
|
|
in = isc_mem_get(cctx->mctx, count * sizeof(*in));
|
|
|
|
out = isc_mem_get(cctx->mctx, count * sizeof(*out));
|
|
|
|
if (in == NULL || out == NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
shuffle = sort = false;
|
2018-08-05 07:18:27 +02:00
|
|
|
}
|
|
|
|
}
|
2017-04-22 08:25:10 +05:30
|
|
|
}
|
|
|
|
|
2018-08-05 07:18:27 +02:00
|
|
|
if ((shuffle || sort)) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint32_t seed = 0;
|
2018-08-24 21:38:39 +02:00
|
|
|
unsigned int j = 0;
|
2018-08-07 20:11:46 -07:00
|
|
|
|
2000-11-10 03:16:26 +00:00
|
|
|
/*
|
|
|
|
* First we get handles to all of the rdata.
|
|
|
|
*/
|
|
|
|
i = 0;
|
|
|
|
do {
|
|
|
|
INSIST(i < count);
|
2017-07-21 11:52:24 +10:00
|
|
|
dns_rdata_init(&in[i]);
|
|
|
|
dns_rdataset_current(rdataset, &in[i]);
|
2000-11-10 03:16:26 +00:00
|
|
|
i++;
|
|
|
|
result = dns_rdataset_next(rdataset);
|
|
|
|
} while (result == ISC_R_SUCCESS);
|
2018-08-05 07:18:27 +02:00
|
|
|
if (result != ISC_R_NOMORE) {
|
2004-02-19 01:23:42 +00:00
|
|
|
goto cleanup;
|
2018-08-05 07:18:27 +02:00
|
|
|
}
|
2000-11-10 03:16:26 +00:00
|
|
|
INSIST(i == count);
|
2002-03-07 13:46:41 +00:00
|
|
|
|
2021-10-14 10:33:24 +02:00
|
|
|
if (want_random) {
|
2018-08-05 07:18:27 +02:00
|
|
|
seed = isc_random32();
|
|
|
|
}
|
|
|
|
|
2021-10-14 10:33:24 +02:00
|
|
|
if (want_cyclic &&
|
2022-11-02 19:33:14 +01:00
|
|
|
(rdataset->count != DNS_RDATASET_COUNT_UNDEFINED))
|
|
|
|
{
|
2018-08-05 07:18:27 +02:00
|
|
|
j = rdataset->count % count;
|
|
|
|
}
|
2002-12-05 04:36:26 +00:00
|
|
|
|
2018-08-05 07:18:27 +02:00
|
|
|
for (i = 0; i < count; i++) {
|
2021-10-14 10:33:24 +02:00
|
|
|
if (want_random) {
|
2018-08-05 07:18:27 +02:00
|
|
|
swap_rdata(in, j, j + seed % (count - j));
|
2018-04-22 14:56:28 +02:00
|
|
|
}
|
2018-08-05 07:18:27 +02:00
|
|
|
|
|
|
|
out[i].key = (sort) ? (*order)(&in[j], order_arg) : 0;
|
|
|
|
out[i].rdata = &in[j];
|
|
|
|
if (++j == count) {
|
|
|
|
j = 0;
|
2000-02-24 21:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-05 07:18:27 +02:00
|
|
|
/*
|
|
|
|
* Sortlist order.
|
|
|
|
*/
|
|
|
|
if (sort) {
|
|
|
|
qsort(out, count, sizeof(out[0]), towire_compare);
|
2017-04-22 08:25:10 +05:30
|
|
|
}
|
|
|
|
}
|
2002-03-07 13:46:41 +00:00
|
|
|
|
1999-09-22 00:26:40 +00:00
|
|
|
savedbuffer = *target;
|
2000-11-10 03:16:26 +00:00
|
|
|
i = 0;
|
2001-06-05 09:02:16 +00:00
|
|
|
added = 0;
|
1999-09-22 00:26:40 +00:00
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
name = dns_fixedname_initname(&fixed);
|
2021-05-21 17:20:44 -07:00
|
|
|
dns_name_copy(owner_name, name);
|
2015-02-27 15:08:38 +11:00
|
|
|
dns_rdataset_getownercase(rdataset, name);
|
2017-09-13 09:24:34 +10:00
|
|
|
offset = 0xffff;
|
2015-02-27 15:08:38 +11:00
|
|
|
|
2022-10-13 10:33:41 +02:00
|
|
|
name->attributes.nocompress |= owner_name->attributes.nocompress;
|
2017-09-01 11:17:59 +10:00
|
|
|
|
1999-01-27 05:54:39 +00:00
|
|
|
do {
|
|
|
|
/*
|
2000-05-08 14:38:29 +00:00
|
|
|
* Copy out the name, type, class, ttl.
|
1999-01-27 05:54:39 +00:00
|
|
|
*/
|
2008-04-01 23:47:10 +00:00
|
|
|
|
2001-06-05 09:17:21 +00:00
|
|
|
rrbuffer = *target;
|
2022-05-05 14:52:44 +01:00
|
|
|
dns_compress_setpermitted(cctx, true);
|
2017-09-13 09:24:34 +10:00
|
|
|
result = dns_name_towire2(name, cctx, target, &offset);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-09-22 00:26:40 +00:00
|
|
|
goto rollback;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-04-30 07:08:55 +00:00
|
|
|
headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
|
1999-07-03 20:52:50 +00:00
|
|
|
if (!question) {
|
1999-04-30 07:08:55 +00:00
|
|
|
headlen += sizeof(dns_ttl_t) + 2;
|
|
|
|
} /* XXX 2 for rdata len
|
|
|
|
*/
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_availableregion(target, &r);
|
1999-04-30 07:08:55 +00:00
|
|
|
if (r.length < headlen) {
|
1999-09-22 00:26:40 +00:00
|
|
|
result = ISC_R_NOSPACE;
|
|
|
|
goto rollback;
|
1999-02-22 07:24:05 +00:00
|
|
|
}
|
1999-01-27 06:18:45 +00:00
|
|
|
isc_buffer_putuint16(target, rdataset->type);
|
1999-03-04 02:48:47 +00:00
|
|
|
isc_buffer_putuint16(target, rdataset->rdclass);
|
1999-07-03 20:52:50 +00:00
|
|
|
if (!question) {
|
2018-08-05 07:18:27 +02:00
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
|
|
|
|
1999-04-30 07:08:55 +00:00
|
|
|
isc_buffer_putuint32(target, rdataset->ttl);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Save space for rdlen.
|
|
|
|
*/
|
|
|
|
rdlen = *target;
|
|
|
|
isc_buffer_add(target, 2);
|
|
|
|
|
|
|
|
/*
|
2000-05-08 14:38:29 +00:00
|
|
|
* Copy out the rdata
|
1999-04-30 07:08:55 +00:00
|
|
|
*/
|
2017-04-22 08:25:10 +05:30
|
|
|
if (shuffle || sort) {
|
2017-07-21 11:52:24 +10:00
|
|
|
rdata = *(out[i].rdata);
|
2017-04-22 08:25:10 +05:30
|
|
|
} else {
|
2000-12-14 22:10:37 +00:00
|
|
|
dns_rdata_reset(&rdata);
|
2000-02-24 21:08:34 +00:00
|
|
|
dns_rdataset_current(rdataset, &rdata);
|
2000-10-25 04:26:57 +00:00
|
|
|
}
|
1999-04-30 07:08:55 +00:00
|
|
|
result = dns_rdata_towire(&rdata, cctx, target);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-09-22 00:26:40 +00:00
|
|
|
goto rollback;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-17 22:40:05 +00:00
|
|
|
INSIST((target->used >= rdlen.used + 2) &&
|
|
|
|
(target->used - rdlen.used - 2 < 65536));
|
1999-04-30 07:08:55 +00:00
|
|
|
isc_buffer_putuint16(
|
|
|
|
&rdlen,
|
2018-03-28 14:19:37 +02:00
|
|
|
(uint16_t)(target->used - rdlen.used - 2));
|
2001-06-05 09:02:16 +00:00
|
|
|
added++;
|
1999-02-22 07:24:05 +00:00
|
|
|
}
|
1999-01-27 05:54:39 +00:00
|
|
|
|
2017-04-22 08:25:10 +05:30
|
|
|
if (shuffle || sort) {
|
2000-02-24 21:08:34 +00:00
|
|
|
i++;
|
|
|
|
if (i == count) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMORE;
|
2000-02-24 21:08:34 +00:00
|
|
|
} else {
|
|
|
|
result = ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-11-10 03:16:26 +00:00
|
|
|
} else {
|
2000-02-24 21:08:34 +00:00
|
|
|
result = dns_rdataset_next(rdataset);
|
2000-11-10 03:16:26 +00:00
|
|
|
}
|
2000-04-06 22:03:35 +00:00
|
|
|
} while (result == ISC_R_SUCCESS);
|
1999-01-27 05:54:39 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_NOMORE) {
|
2000-02-24 21:08:34 +00:00
|
|
|
goto rollback;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 05:54:39 +00:00
|
|
|
|
1999-01-30 05:01:01 +00:00
|
|
|
*countp += count;
|
|
|
|
|
2004-02-19 01:23:42 +00:00
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
goto cleanup;
|
1999-09-22 00:26:40 +00:00
|
|
|
|
|
|
|
rollback:
|
2001-06-05 09:02:16 +00:00
|
|
|
if (partial && result == ISC_R_NOSPACE) {
|
2022-06-23 21:53:46 +01:00
|
|
|
dns_compress_rollback(cctx, rrbuffer.used);
|
2001-06-05 09:02:16 +00:00
|
|
|
*countp += added;
|
2001-06-05 09:23:14 +00:00
|
|
|
*target = rrbuffer;
|
2004-02-19 01:23:42 +00:00
|
|
|
goto cleanup;
|
2001-06-05 09:02:16 +00:00
|
|
|
}
|
2022-06-23 21:53:46 +01:00
|
|
|
dns_compress_rollback(cctx, savedbuffer.used);
|
1999-09-22 00:26:40 +00:00
|
|
|
*countp = 0;
|
|
|
|
*target = savedbuffer;
|
|
|
|
|
2004-02-19 01:23:42 +00:00
|
|
|
cleanup:
|
2017-07-21 11:52:24 +10:00
|
|
|
if (out != NULL && out != out_fixed) {
|
|
|
|
isc_mem_put(cctx->mctx, out, count * sizeof(*out));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-07-21 11:52:24 +10:00
|
|
|
if (in != NULL && in != in_fixed) {
|
|
|
|
isc_mem_put(cctx->mctx, in, count * sizeof(*in));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-09-22 00:26:40 +00:00
|
|
|
return (result);
|
1999-01-15 03:31:17 +00:00
|
|
|
}
|
1999-08-02 22:18:31 +00:00
|
|
|
|
2001-06-05 09:02:16 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
2006-02-28 02:39:52 +00:00
|
|
|
const dns_name_t *owner_name, dns_compress_t *cctx,
|
2001-06-05 09:02:16 +00:00
|
|
|
isc_buffer_t *target, dns_rdatasetorderfunc_t order,
|
2006-02-28 02:39:52 +00:00
|
|
|
const void *order_arg, unsigned int options,
|
2001-06-05 09:02:16 +00:00
|
|
|
unsigned int *countp) {
|
|
|
|
return (towiresorted(rdataset, owner_name, cctx, target, order,
|
2018-04-17 08:29:14 -07:00
|
|
|
order_arg, false, options, countp, NULL));
|
2001-06-05 09:02:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
|
2006-02-28 02:39:52 +00:00
|
|
|
const dns_name_t *owner_name, dns_compress_t *cctx,
|
2001-06-05 09:02:16 +00:00
|
|
|
isc_buffer_t *target, dns_rdatasetorderfunc_t order,
|
2006-02-28 02:39:52 +00:00
|
|
|
const void *order_arg, unsigned int options,
|
2001-06-05 09:02:16 +00:00
|
|
|
unsigned int *countp, void **state) {
|
|
|
|
REQUIRE(state == NULL); /* XXX remove when implemented */
|
|
|
|
return (towiresorted(rdataset, owner_name, cctx, target, order,
|
2018-04-17 08:29:14 -07:00
|
|
|
order_arg, true, options, countp, state));
|
2001-06-05 09:02:16 +00:00
|
|
|
}
|
|
|
|
|
2000-11-10 03:16:26 +00:00
|
|
|
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) {
|
2001-06-05 09:02:16 +00:00
|
|
|
return (towiresorted(rdataset, owner_name, cctx, target, NULL, NULL,
|
2018-04-17 08:29:14 -07:00
|
|
|
false, options, countp, NULL));
|
2000-11-10 03:16:26 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-08-02 22:18:31 +00:00
|
|
|
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
2019-07-05 16:20:20 +10:00
|
|
|
const dns_name_t *owner_name,
|
1999-08-02 22:18:31 +00:00
|
|
|
dns_additionaldatafunc_t add, void *arg) {
|
2000-12-11 23:09:47 +00:00
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t result;
|
1999-08-02 22:18:31 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* For each rdata in rdataset, call 'add' for each name and type in the
|
|
|
|
* rdata which is subject to additional section processing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
|
|
|
|
|
|
|
|
result = dns_rdataset_first(rdataset);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-08-02 22:18:31 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-02 22:18:31 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
dns_rdataset_current(rdataset, &rdata);
|
2019-07-05 16:20:20 +10:00
|
|
|
result = dns_rdata_additionaldata(&rdata, owner_name, add, arg);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
1999-08-02 22:18:31 +00:00
|
|
|
result = dns_rdataset_next(rdataset);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-12-14 22:10:37 +00:00
|
|
|
dns_rdata_reset(&rdata);
|
2000-04-06 22:03:35 +00:00
|
|
|
} while (result == ISC_R_SUCCESS);
|
1999-08-02 22:18:31 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_NOMORE) {
|
1999-08-02 22:18:31 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-02 22:18:31 +00:00
|
|
|
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-08-02 22:18:31 +00:00
|
|
|
}
|
2004-01-14 02:06:51 +00:00
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
if (rdataset->methods->addnoqname == NULL) {
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2004-01-14 02:06:51 +00:00
|
|
|
return ((rdataset->methods->addnoqname)(rdataset, name));
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2023-01-05 09:12:35 +01:00
|
|
|
dns__rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
|
|
|
|
dns_rdataset_t *neg,
|
|
|
|
dns_rdataset_t *negsig DNS__DB_FLARG) {
|
2004-01-14 02:06:51 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
|
|
|
if (rdataset->methods->getnoqname == NULL) {
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2023-01-05 09:12:35 +01:00
|
|
|
return ((rdataset->methods->getnoqname)(rdataset, name, neg,
|
|
|
|
negsig DNS__DB_FLARG_PASS));
|
2008-09-24 02:46:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_rdataset_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name) {
|
2008-09-24 02:46:23 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
if (rdataset->methods->addclosest == NULL) {
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-09-24 02:46:23 +00:00
|
|
|
return ((rdataset->methods->addclosest)(rdataset, name));
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2023-01-05 09:12:35 +01:00
|
|
|
dns__rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
|
|
|
|
dns_rdataset_t *neg,
|
|
|
|
dns_rdataset_t *negsig DNS__DB_FLARG) {
|
2008-09-24 02:46:23 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
|
|
|
if (rdataset->methods->getclosest == NULL) {
|
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2023-01-05 09:12:35 +01:00
|
|
|
return ((rdataset->methods->getclosest)(rdataset, name, neg,
|
|
|
|
negsig DNS__DB_FLARG_PASS));
|
2004-01-14 02:06:51 +00:00
|
|
|
}
|
2004-12-21 10:45:20 +00:00
|
|
|
|
2010-02-25 04:39:13 +00:00
|
|
|
void
|
|
|
|
dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
|
|
|
if (rdataset->methods->settrust != NULL) {
|
|
|
|
(rdataset->methods->settrust)(rdataset, trust);
|
|
|
|
} else {
|
|
|
|
rdataset->trust = trust;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-02-25 04:39:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-01-05 09:12:35 +01:00
|
|
|
dns__rdataset_expire(dns_rdataset_t *rdataset DNS__DB_FLARG) {
|
2010-02-25 04:39:13 +00:00
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
|
|
|
if (rdataset->methods->expire != NULL) {
|
2023-01-05 09:12:35 +01:00
|
|
|
(rdataset->methods->expire)(rdataset DNS__DB_FLARG_PASS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-02-25 04:39:13 +00:00
|
|
|
}
|
2012-07-25 17:06:34 -05:00
|
|
|
|
2014-11-24 11:18:30 +11:00
|
|
|
void
|
|
|
|
dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) {
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
|
|
|
if (rdataset->methods->clearprefetch != NULL) {
|
|
|
|
(rdataset->methods->clearprefetch)(rdataset);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2014-11-24 11:18:30 +11:00
|
|
|
}
|
|
|
|
|
2015-02-27 15:08:38 +11:00
|
|
|
void
|
|
|
|
dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
2023-04-25 17:26:47 +01:00
|
|
|
if (rdataset->methods->setownercase != NULL &&
|
|
|
|
(rdataset->attributes & DNS_RDATASETATTR_KEEPCASE) == 0)
|
|
|
|
{
|
2015-02-27 15:08:38 +11:00
|
|
|
(rdataset->methods->setownercase)(rdataset, name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-02-27 15:08:38 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(rdataset->methods != NULL);
|
|
|
|
|
2023-04-25 17:26:47 +01:00
|
|
|
if (rdataset->methods->getownercase != NULL &&
|
|
|
|
(rdataset->attributes & DNS_RDATASETATTR_KEEPCASE) == 0)
|
|
|
|
{
|
2015-02-27 15:08:38 +11:00
|
|
|
(rdataset->methods->getownercase)(rdataset, name);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-02-27 15:08:38 +11:00
|
|
|
}
|
|
|
|
|
2012-07-25 17:06:34 -05:00
|
|
|
void
|
|
|
|
dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
|
|
|
|
dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
|
2018-04-17 08:29:14 -07:00
|
|
|
bool acceptexpired) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint32_t ttl = 0;
|
2012-07-25 17:06:34 -05:00
|
|
|
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
|
|
|
REQUIRE(DNS_RDATASET_VALID(sigrdataset));
|
|
|
|
REQUIRE(rrsig != NULL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we accept expired RRsets keep them for no more than 120 seconds.
|
|
|
|
*/
|
|
|
|
if (acceptexpired &&
|
|
|
|
(isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
|
|
|
|
isc_serial_le(rrsig->timeexpire, now)))
|
|
|
|
{
|
|
|
|
ttl = 120;
|
|
|
|
} else if (isc_serial_ge(rrsig->timeexpire, now)) {
|
|
|
|
ttl = rrsig->timeexpire - now;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-07-25 23:46:04 +00:00
|
|
|
|
2012-07-25 17:06:34 -05:00
|
|
|
ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
|
|
|
|
ISC_MIN(rrsig->originalttl, ttl));
|
|
|
|
rdataset->ttl = ttl;
|
|
|
|
sigrdataset->ttl = ttl;
|
|
|
|
}
|