Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: rdataset.h,v 1.16 2026/04/08 00:16:14 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #pragma once
     17 
     18 /*****
     19 ***** Module Info
     20 *****/
     21 
     22 /*! \file dns/rdataset.h
     23  * \brief
     24  * A DNS rdataset is a handle that can be associated with a collection of
     25  * rdata all having a common owner name, class, and type.
     26  *
     27  * The dns_rdataset_t type is like a "virtual class".  To actually use
     28  * rdatasets, an implementation of the method suite (e.g. "slabbed rdata") is
     29  * required.
     30  *
     31  * XXX <more> XXX
     32  *
     33  * MP:
     34  *\li	Clients of this module must impose any required synchronization.
     35  *
     36  * Reliability:
     37  *\li	No anticipated impact.
     38  *
     39  * Resources:
     40  *\li	TBS
     41  *
     42  * Security:
     43  *\li	No anticipated impact.
     44  *
     45  * Standards:
     46  *\li	None.
     47  */
     48 
     49 #include <inttypes.h>
     50 #include <stdbool.h>
     51 
     52 #include <isc/lang.h>
     53 #include <isc/magic.h>
     54 #include <isc/stdtime.h>
     55 
     56 #include <dns/rdatastruct.h>
     57 #include <dns/types.h>
     58 
     59 #define DNS_RDATASET_MAXADDITIONAL 13
     60 
     61 /* Fixed RRSet helper macros */
     62 
     63 #define DNS_RDATASET_LENGTH 2;
     64 
     65 #if DNS_RDATASET_FIXED
     66 #define DNS_RDATASET_ORDER 2
     67 #define DNS_RDATASET_COUNT (count * 4)
     68 #else /* !DNS_RDATASET_FIXED */
     69 #define DNS_RDATASET_ORDER 0
     70 #define DNS_RDATASET_COUNT 0
     71 #endif /* DNS_RDATASET_FIXED */
     72 
     73 ISC_LANG_BEGINDECLS
     74 
     75 typedef enum {
     76 	dns_rdatasetadditional_fromauth,
     77 	dns_rdatasetadditional_fromcache,
     78 	dns_rdatasetadditional_fromglue
     79 } dns_rdatasetadditional_t;
     80 
     81 typedef struct dns_rdatasetmethods {
     82 	void (*disassociate)(dns_rdataset_t *rdataset DNS__DB_FLARG);
     83 	isc_result_t (*first)(dns_rdataset_t *rdataset);
     84 	isc_result_t (*next)(dns_rdataset_t *rdataset);
     85 	void (*current)(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
     86 	void (*clone)(dns_rdataset_t	    *source,
     87 		      dns_rdataset_t *target DNS__DB_FLARG);
     88 	unsigned int (*count)(dns_rdataset_t *rdataset);
     89 	isc_result_t (*addnoqname)(dns_rdataset_t   *rdataset,
     90 				   const dns_name_t *name);
     91 	isc_result_t (*getnoqname)(dns_rdataset_t *rdataset, dns_name_t *name,
     92 				   dns_rdataset_t	 *neg,
     93 				   dns_rdataset_t *negsig DNS__DB_FLARG);
     94 	isc_result_t (*addclosest)(dns_rdataset_t   *rdataset,
     95 				   const dns_name_t *name);
     96 	isc_result_t (*getclosest)(dns_rdataset_t *rdataset, dns_name_t *name,
     97 				   dns_rdataset_t	 *neg,
     98 				   dns_rdataset_t *negsig DNS__DB_FLARG);
     99 	void (*settrust)(dns_rdataset_t *rdataset, dns_trust_t trust);
    100 	void (*expire)(dns_rdataset_t *rdataset DNS__DB_FLARG);
    101 	void (*clearprefetch)(dns_rdataset_t *rdataset);
    102 	void (*setownercase)(dns_rdataset_t *rdataset, const dns_name_t *name);
    103 	void (*getownercase)(const dns_rdataset_t *rdataset, dns_name_t *name);
    104 	isc_result_t (*addglue)(dns_rdataset_t	*rdataset,
    105 				dns_dbversion_t *version, dns_message_t *msg);
    106 } dns_rdatasetmethods_t;
    107 
    108 #define DNS_RDATASET_MAGIC	ISC_MAGIC('D', 'N', 'S', 'R')
    109 #define DNS_RDATASET_VALID(set) ISC_MAGIC_VALID(set, DNS_RDATASET_MAGIC)
    110 
    111 /*%
    112  * Direct use of this structure by clients is strongly discouraged, except
    113  * for the 'link' field which may be used however the client wishes.  The
    114  * 'private', 'current', and 'index' fields MUST NOT be changed by clients.
    115  * rdataset implementations may change any of the fields.
    116  */
    117 struct dns_rdataset {
    118 	unsigned int	       magic;
    119 	dns_rdatasetmethods_t *methods;
    120 	ISC_LINK(dns_rdataset_t) link;
    121 
    122 	/*
    123 	 * XXX do we need these, or should they be retrieved by methods?
    124 	 * Leaning towards the latter, since they are not frequently required
    125 	 * once you have the rdataset.
    126 	 */
    127 	dns_rdataclass_t rdclass;
    128 	dns_rdatatype_t	 type;
    129 	dns_ttl_t	 ttl;
    130 
    131 	dns_trust_t	trust;
    132 	dns_rdatatype_t covers;
    133 
    134 	/*
    135 	 * attributes
    136 	 */
    137 	unsigned int attributes;
    138 
    139 	/*%
    140 	 * the counter provides the starting point in the "cyclic" order.
    141 	 * The value UINT32_MAX has a special meaning of "picking up a
    142 	 * random value." in order to take care of databases that do not
    143 	 * increment the counter.
    144 	 */
    145 	uint32_t count;
    146 
    147 	/*
    148 	 * This RRSIG RRset should be re-generated around this time.
    149 	 * Only valid if DNS_RDATASETATTR_RESIGN is set in attributes.
    150 	 */
    151 	union {
    152 		isc_stdtime_t resign;
    153 		isc_stdtime_t expire;
    154 	};
    155 
    156 	/*%
    157 	 * Extra fields used by various rdataset implementations, that is, by
    158 	 * the code referred to in the rdataset methods table. The names of
    159 	 * the structures roughly correspond to the file containing the
    160 	 * implementation, except that `rdlist` is used by `rdatalist.c`,
    161 	 * `sdb.c`, and `sdlz.c`.
    162 	 *
    163 	 * Pointers in these structs use incomplete structure types,
    164 	 * because the structure definitions and corresponding typedef
    165 	 * names might not be in scope in this header.
    166 	 */
    167 	/*@}*/
    168 	union {
    169 		struct {
    170 			struct dns_keynode *node;
    171 			dns_rdata_t	   *iter;
    172 		} keytable;
    173 
    174 		/*
    175 		 * An ncache rdataset is a view of memory held elsewhere:
    176 		 * raw can point to either a buffer on the stack or to an
    177 		 * rdataslab, such as in an rbtdb database.
    178 		 */
    179 		struct {
    180 			unsigned char *raw;
    181 			unsigned char *iter_pos;
    182 			unsigned int   iter_count;
    183 		} ncache;
    184 
    185 		/*
    186 		 * A slab rdataset provides access to an rdataslab. In
    187 		 * an rbtdb database, 'raw' will generally point to the
    188 		 * memory immediately following a slabheader. (There
    189 		 * is an exception in the case of rdatasets returned by
    190 		 * the `getnoqname` and `getclosest` methods; see
    191 		 * comments in rbtdb.c for details.)
    192 		 */
    193 		struct {
    194 			struct dns_db	       *db;
    195 			dns_dbnode_t	       *node;
    196 			unsigned char	       *raw;
    197 			unsigned char	       *iter_pos;
    198 			unsigned int		iter_count;
    199 			dns_slabheader_proof_t *noqname, *closest;
    200 		} slab;
    201 
    202 		/*
    203 		 * A simple rdatalist, plus an optional dbnode used by
    204 		 * builtin and sdlz.
    205 		 */
    206 		struct {
    207 			struct dns_rdatalist *list;
    208 			struct dns_rdata     *iter;
    209 
    210 			/*
    211 			 * These refer to names passed in by the caller of
    212 			 * dns_rdataset_addnoqname() and _addclosest()
    213 			 */
    214 			const struct dns_name *noqname, *closest;
    215 			dns_dbnode_t	      *node;
    216 		} rdlist;
    217 
    218 #ifdef USE_DNSRPS
    219 		/*
    220 		 * DNSRPS rdatasets. dns_rpsdb_t is defined in dnsrps.h.
    221 		 */
    222 		struct {
    223 			dns_rpsdb_t *db;
    224 			void	    *iter_pos;
    225 			unsigned int iter_count;
    226 		} rps;
    227 #endif /* USE_DNSRPS */
    228 	};
    229 };
    230 
    231 #define DNS_RDATASET_COUNT_UNDEFINED UINT32_MAX
    232 
    233 #define DNS_RDATASET_INIT               \
    234 	{ .magic = DNS_RDATASET_MAGIC,  \
    235 	  .link = ISC_LINK_INITIALIZER, \
    236 	  .count = DNS_RDATASET_COUNT_UNDEFINED }
    237 
    238 /*!
    239  * \def DNS_RDATASETATTR_RENDERED
    240  *	Used by message.c to indicate that the rdataset was rendered.
    241  *
    242  * \def DNS_RDATASETATTR_TTLADJUSTED
    243  *	Used by message.c to indicate that the rdataset's rdata had differing
    244  *	TTL values, and the rdataset->ttl holds the smallest.
    245  *
    246  * \def DNS_RDATASETATTR_LOADORDER
    247  *	Output the RRset in load order.
    248  */
    249 
    250 #define DNS_RDATASETATTR_NONE	      0x00000000 /*%< No ordering. */
    251 #define DNS_RDATASETATTR_QUESTION     0x00000001
    252 #define DNS_RDATASETATTR_RENDERED     0x00000002 /*%< Used by message.c */
    253 #define DNS_RDATASETATTR_ANSWERED     0x00000004 /*%< Used by server. */
    254 #define DNS_RDATASETATTR_CACHE	      0x00000008 /*%< Used by resolver. */
    255 #define DNS_RDATASETATTR_ANSWER	      0x00000010 /*%< Used by resolver. */
    256 #define DNS_RDATASETATTR_ANSWERSIG    0x00000020 /*%< Used by resolver. */
    257 #define DNS_RDATASETATTR_EXTERNAL     0x00000040 /*%< Used by resolver. */
    258 #define DNS_RDATASETATTR_NCACHE	      0x00000080 /*%< Used by resolver. */
    259 #define DNS_RDATASETATTR_CHAINING     0x00000100 /*%< Used by resolver. */
    260 #define DNS_RDATASETATTR_TTLADJUSTED  0x00000200 /*%< Used by message.c */
    261 #define DNS_RDATASETATTR_FIXEDORDER   0x00000400 /*%< Fixed ordering. */
    262 #define DNS_RDATASETATTR_RANDOMIZE    0x00000800 /*%< Random ordering. */
    263 #define DNS_RDATASETATTR_CHASE	      0x00001000 /*%< Used by resolver. */
    264 #define DNS_RDATASETATTR_NXDOMAIN     0x00002000
    265 #define DNS_RDATASETATTR_NOQNAME      0x00004000
    266 #define DNS_RDATASETATTR_CHECKNAMES   0x00008000 /*%< Used by resolver. */
    267 #define DNS_RDATASETATTR_REQUIRED     0x00010000
    268 #define DNS_RDATASETATTR_REQUIREDGLUE DNS_RDATASETATTR_REQUIRED
    269 #define DNS_RDATASETATTR_LOADORDER    0x00020000
    270 #define DNS_RDATASETATTR_RESIGN	      0x00040000
    271 #define DNS_RDATASETATTR_CLOSEST      0x00080000
    272 #define DNS_RDATASETATTR_OPTOUT	      0x00100000 /*%< OPTOUT proof */
    273 #define DNS_RDATASETATTR_NEGATIVE     0x00200000
    274 #define DNS_RDATASETATTR_PREFETCH     0x00400000
    275 #define DNS_RDATASETATTR_CYCLIC	      0x00800000 /*%< Cyclic ordering. */
    276 #define DNS_RDATASETATTR_STALE	      0x01000000
    277 #define DNS_RDATASETATTR_ANCIENT      0x02000000
    278 #define DNS_RDATASETATTR_STALE_WINDOW 0x04000000
    279 /* #define DNS_RDATASETATTR_STALE_ADDED  0x08000000 - Obsolete */
    280 #define DNS_RDATASETATTR_KEEPCASE   0x10000000
    281 #define DNS_RDATASETATTR_STATICSTUB 0x20000000
    282 
    283 /*%
    284  * _OMITDNSSEC:
    285  * 	Omit DNSSEC records when rendering ncache records.
    286  */
    287 #define DNS_RDATASETTOWIRE_OMITDNSSEC 0x0001
    288 
    289 void
    290 dns_rdataset_init(dns_rdataset_t *rdataset);
    291 /*%<
    292  * Make 'rdataset' a valid, disassociated rdataset.
    293  *
    294  * Requires:
    295  *\li	'rdataset' is not NULL.
    296  *
    297  * Ensures:
    298  *\li	'rdataset' is a valid, disassociated rdataset.
    299  */
    300 
    301 void
    302 dns_rdataset_invalidate(dns_rdataset_t *rdataset);
    303 /*%<
    304  * Invalidate 'rdataset'.
    305  *
    306  * Requires:
    307  *\li	'rdataset' is a valid, disassociated rdataset.
    308  *
    309  * Ensures:
    310  *\li	If assertion checking is enabled, future attempts to use 'rdataset'
    311  *	without initializing it will cause an assertion failure.
    312  */
    313 
    314 #define dns_rdataset_disassociate(rdataset) \
    315 	dns__rdataset_disassociate(rdataset DNS__DB_FILELINE)
    316 void
    317 dns__rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG);
    318 /*%<
    319  * Disassociate 'rdataset' from its rdata, allowing it to be reused.
    320  *
    321  * Notes:
    322  *\li	The client must ensure it has no references to rdata in the rdataset
    323  *	before disassociating.
    324  *
    325  * Requires:
    326  *\li	'rdataset' is a valid, associated rdataset.
    327  *
    328  * Ensures:
    329  *\li	'rdataset' is a valid, disassociated rdataset.
    330  */
    331 
    332 bool
    333 dns_rdataset_isassociated(dns_rdataset_t *rdataset);
    334 /*%<
    335  * Is 'rdataset' associated?
    336  *
    337  * Requires:
    338  *\li	'rdataset' is a valid rdataset.
    339  *
    340  * Returns:
    341  *\li	#true			'rdataset' is associated.
    342  *\li	#false			'rdataset' is not associated.
    343  */
    344 
    345 void
    346 dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
    347 			  dns_rdatatype_t type);
    348 /*%<
    349  * Make 'rdataset' a valid, associated, question rdataset, with a
    350  * question class of 'rdclass' and type 'type'.
    351  *
    352  * Notes:
    353  *\li	Question rdatasets have a class and type, but no rdata.
    354  *
    355  * Requires:
    356  *\li	'rdataset' is a valid, disassociated rdataset.
    357  *
    358  * Ensures:
    359  *\li	'rdataset' is a valid, associated, question rdataset.
    360  */
    361 
    362 #define dns_rdataset_clone(source, target) \
    363 	dns__rdataset_clone(source, target DNS__DB_FILELINE)
    364 void
    365 dns__rdataset_clone(dns_rdataset_t	  *source,
    366 		    dns_rdataset_t *target DNS__DB_FLARG);
    367 /*%<
    368  * Make 'target' refer to the same rdataset as 'source'.
    369  *
    370  * Requires:
    371  *\li	'source' is a valid, associated rdataset.
    372  *
    373  *\li	'target' is a valid, dissociated rdataset.
    374  *
    375  * Ensures:
    376  *\li	'target' references the same rdataset as 'source'.
    377  */
    378 
    379 unsigned int
    380 dns_rdataset_count(dns_rdataset_t *rdataset);
    381 /*%<
    382  * Return the number of records in 'rdataset'.
    383  *
    384  * Requires:
    385  *\li	'rdataset' is a valid, associated rdataset.
    386  *
    387  * Returns:
    388  *\li	The number of records in 'rdataset'.
    389  */
    390 
    391 isc_result_t
    392 dns_rdataset_first(dns_rdataset_t *rdataset);
    393 /*%<
    394  * Move the rdata cursor to the first rdata in the rdataset (if any).
    395  *
    396  * Requires:
    397  *\li	'rdataset' is a valid, associated rdataset.
    398  *
    399  * Returns:
    400  *\li	#ISC_R_SUCCESS
    401  *\li	#ISC_R_NOMORE			There are no rdata in the set.
    402  */
    403 
    404 isc_result_t
    405 dns_rdataset_next(dns_rdataset_t *rdataset);
    406 /*%<
    407  * Move the rdata cursor to the next rdata in the rdataset (if any).
    408  *
    409  * Requires:
    410  *\li	'rdataset' is a valid, associated rdataset.
    411  *
    412  * Returns:
    413  *\li	#ISC_R_SUCCESS
    414  *\li	#ISC_R_NOMORE			There are no more rdata in the set.
    415  */
    416 
    417 void
    418 dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
    419 /*%<
    420  * Make 'rdata' refer to the current rdata.
    421  *
    422  * Notes:
    423  *
    424  *\li	The data returned in 'rdata' is valid for the life of the
    425  *	rdataset; in particular, subsequent changes in the cursor position
    426  *	do not invalidate 'rdata'.
    427  *
    428  * Requires:
    429  *\li	'rdataset' is a valid, associated rdataset.
    430  *
    431  *\li	The rdata cursor of 'rdataset' is at a valid location (i.e. the
    432  *	result of last call to a cursor movement command was ISC_R_SUCCESS).
    433  *
    434  * Ensures:
    435  *\li	'rdata' refers to the rdata at the rdata cursor location of
    436  *\li	'rdataset'.
    437  */
    438 
    439 isc_result_t
    440 dns_rdataset_totext(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
    441 		    bool omit_final_dot, bool question, isc_buffer_t *target);
    442 /*%<
    443  * Convert 'rdataset' to text format, storing the result in 'target'.
    444  *
    445  * Notes:
    446  *\li	The rdata cursor position will be changed.
    447  *
    448  *\li	The 'question' flag should normally be #false.  If it is
    449  *	#true, the TTL and rdata fields are not printed.  This is
    450  *	for use when printing an rdata representing a question section.
    451  *
    452  *\li	This interface is deprecated; use dns_master_rdatasettottext()
    453  * 	and/or dns_master_questiontotext() instead.
    454  *
    455  * Requires:
    456  *\li	'rdataset' is a valid rdataset.
    457  *
    458  *\li	'rdataset' is not empty.
    459  */
    460 
    461 isc_result_t
    462 dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
    463 		    dns_compress_t *cctx, isc_buffer_t *target,
    464 		    unsigned int options, unsigned int *countp);
    465 /*%<
    466  * Convert 'rdataset' to wire format, compressing names as specified
    467  * in 'cctx', and storing the result in 'target'.
    468  *
    469  * Notes:
    470  *\li	The rdata cursor position will be changed.
    471  *
    472  *\li	The number of RRs added to target will be added to *countp.
    473  *
    474  * Requires:
    475  *\li	'rdataset' is a valid rdataset.
    476  *
    477  *\li	'rdataset' is not empty.
    478  *
    479  *\li	'countp' is a valid pointer.
    480  *
    481  * Ensures:
    482  *\li	On a return of ISC_R_SUCCESS, 'target' contains a wire format
    483  *	for the data contained in 'rdataset'.  Any error return leaves
    484  *	the buffer unchanged.
    485  *
    486  *\li	*countp has been incremented by the number of RRs added to
    487  *	target.
    488  *
    489  * Returns:
    490  *\li	#ISC_R_SUCCESS		- all ok
    491  *\li	#ISC_R_NOSPACE		- 'target' doesn't have enough room
    492  *
    493  *\li	Any error returned by dns_rdata_towire(), dns_rdataset_next(),
    494  *	dns_name_towire().
    495  */
    496 
    497 isc_result_t
    498 dns_rdataset_towiresorted(dns_rdataset_t   *rdataset,
    499 			  const dns_name_t *owner_name, dns_compress_t *cctx,
    500 			  isc_buffer_t *target, dns_rdatasetorderfunc_t order,
    501 			  const void *order_arg, unsigned int options,
    502 			  unsigned int *countp);
    503 /*%<
    504  * Like dns_rdataset_towire(), but sorting the rdatasets according to
    505  * the integer value returned by 'order' when called with the rdataset
    506  * and 'order_arg' as arguments.
    507  *
    508  * Requires:
    509  *\li	All the requirements of dns_rdataset_towire(), and
    510  *	that order_arg is NULL if and only if order is NULL.
    511  */
    512 
    513 isc_result_t
    514 dns_rdataset_towirepartial(dns_rdataset_t   *rdataset,
    515 			   const dns_name_t *owner_name, dns_compress_t *cctx,
    516 			   isc_buffer_t *target, dns_rdatasetorderfunc_t order,
    517 			   const void *order_arg, unsigned int options,
    518 			   unsigned int *countp, void **state);
    519 /*%<
    520  * Like dns_rdataset_towiresorted() except that a partial rdataset
    521  * may be written.
    522  *
    523  * Requires:
    524  *\li	All the requirements of dns_rdataset_towiresorted().
    525  *	If 'state' is non NULL then the current position in the
    526  *	rdataset will be remembered if the rdataset in not
    527  *	completely written and should be passed on on subsequent
    528  *	calls (NOT CURRENTLY IMPLEMENTED).
    529  *
    530  * Returns:
    531  *\li	#ISC_R_SUCCESS if all of the records were written.
    532  *\li	#ISC_R_NOSPACE if unable to fit in all of the records. *countp
    533  *		      will be updated to reflect the number of records
    534  *		      written.
    535  */
    536 
    537 isc_result_t
    538 dns_rdataset_additionaldata(dns_rdataset_t	    *rdataset,
    539 			    const dns_name_t	    *owner_name,
    540 			    dns_additionaldatafunc_t add, void *arg,
    541 			    size_t limit);
    542 /*%<
    543  * For each rdata in rdataset, call 'add' for each name and type in the
    544  * rdata which is subject to additional section processing.
    545  *
    546  * Requires:
    547  *
    548  *\li	'rdataset' is a valid, non-question rdataset.
    549  *
    550  *\li	'add' is a valid dns_additionaldatafunc_t
    551  *
    552  * Ensures:
    553  *
    554  *\li	If successful, dns_rdata_additionaldata() will have been called for
    555  *	each rdata in 'rdataset'.
    556  *
    557  *\li	If a call to dns_rdata_additionaldata() is not successful, the
    558  *	result returned will be the result of dns_rdataset_additionaldata().
    559  *
    560  *\li	If 'limit' is non-zero and the number of the rdatasets is larger
    561  *	than 'limit', no additional data will be processed.
    562  *
    563  * Returns:
    564  *
    565  *\li	#ISC_R_SUCCESS
    566  *
    567  *\li	#DNS_R_TOOMANYRECORDS in case rdataset count is larger than 'limit'
    568  *
    569  *\li	Any error that dns_rdata_additionaldata() can return.
    570  */
    571 
    572 #define dns_rdataset_getnoqname(rdataset, name, neg, negsig) \
    573 	dns__rdataset_getnoqname(rdataset, name, neg, negsig DNS__DB_FILELINE)
    574 isc_result_t
    575 dns__rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
    576 			 dns_rdataset_t	       *neg,
    577 			 dns_rdataset_t *negsig DNS__DB_FLARG);
    578 /*%<
    579  * Return the noqname proof for this record.
    580  *
    581  * Requires:
    582  *\li	'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set.
    583  *\li	'name' to be valid.
    584  *\li	'neg' and 'negsig' to be valid and not associated.
    585  */
    586 
    587 isc_result_t
    588 dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name);
    589 /*%<
    590  * Associate a noqname proof with this record.
    591  * Sets #DNS_RDATASETATTR_NOQNAME if successful.
    592  * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and
    593  * the 'nsec'/'nsec3' and 'rrsig(nsec)'/'rrsig(nsec3)' ttl.
    594  *
    595  * Requires:
    596  *\li	'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set.
    597  *\li	'name' to be valid and have NSEC or NSEC3 and associated RRSIG
    598  *	 rdatasets.
    599  */
    600 
    601 #define dns_rdataset_getclosest(rdataset, name, nsec, nsecsig) \
    602 	dns__rdataset_getclosest(rdataset, name, nsec, nsecsig DNS__DB_FILELINE)
    603 isc_result_t
    604 dns__rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
    605 			 dns_rdataset_t		*nsec,
    606 			 dns_rdataset_t *nsecsig DNS__DB_FLARG);
    607 /*%<
    608  * Return the closest encloser for this record.
    609  *
    610  * Requires:
    611  *\li	'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set.
    612  *\li	'name' to be valid.
    613  *\li	'nsec' and 'nsecsig' to be valid and not associated.
    614  */
    615 
    616 isc_result_t
    617 dns_rdataset_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name);
    618 /*%<
    619  * Associate a closest encloset proof with this record.
    620  * Sets #DNS_RDATASETATTR_CLOSEST if successful.
    621  * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and
    622  * the 'nsec' and 'rrsig(nsec)' ttl.
    623  *
    624  * Requires:
    625  *\li	'rdataset' to be valid and #DNS_RDATASETATTR_CLOSEST to be set.
    626  *\li	'name' to be valid and have NSEC3 and RRSIG(NSEC3) rdatasets.
    627  */
    628 
    629 void
    630 dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
    631 /*%<
    632  * Set the trust of the 'rdataset' to trust in any in the backing database.
    633  * The local trust level of 'rdataset' is also set.
    634  */
    635 
    636 #define dns_rdataset_expire(rdataset) \
    637 	dns__rdataset_expire(rdataset DNS__DB_FILELINE)
    638 void
    639 dns__rdataset_expire(dns_rdataset_t *rdataset DNS__DB_FLARG);
    640 /*%<
    641  * Mark the rdataset to be expired in the backing database.
    642  */
    643 
    644 void
    645 dns_rdataset_clearprefetch(dns_rdataset_t *rdataset);
    646 /*%<
    647  * Clear the PREFETCH attribute for the given rdataset in the
    648  * underlying database.
    649  *
    650  * In the cache database, this signals that the rdataset is not
    651  * eligible to be prefetched when the TTL is close to expiring.
    652  * It has no function in other databases.
    653  */
    654 
    655 void
    656 dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name);
    657 /*%<
    658  * Store the casing of 'name', the owner name of 'rdataset', into
    659  * a bitfield so that the name can be capitalized the same when when
    660  * the rdataset is used later. This sets the CASESET attribute.
    661  */
    662 
    663 void
    664 dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name);
    665 /*%<
    666  * If the CASESET attribute is set, retrieve the case bitfield that was
    667  * previously stored by dns_rdataset_getownername(), and capitalize 'name'
    668  * according to it. If CASESET is not set, do nothing.
    669  */
    670 
    671 void
    672 dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
    673 		     dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
    674 		     bool acceptexpired);
    675 /*%<
    676  * Trim the ttl of 'rdataset' and 'sigrdataset' so that they will expire
    677  * at or before 'rrsig->expiretime'.  If 'acceptexpired' is true and the
    678  * signature has expired or will expire in the next 120 seconds, limit
    679  * the ttl to be no more than 120 seconds.
    680  *
    681  * The ttl is further limited by the original ttl as stored in 'rrsig'
    682  * and the original ttl values of 'rdataset' and 'sigrdataset'.
    683  *
    684  * Requires:
    685  * \li	'rdataset' is a valid rdataset.
    686  * \li	'sigrdataset' is a valid rdataset.
    687  * \li	'rrsig' is non NULL.
    688  */
    689 
    690 const char *
    691 dns_trust_totext(dns_trust_t trust);
    692 /*%<
    693  * Display trust in textual form.
    694  */
    695 
    696 isc_stdtime_t
    697 dns_rdataset_minresign(dns_rdataset_t *rdataset);
    698 /*%<
    699  * Return the minimum resign time from an RRSIG rdataset.
    700  *
    701  * This function iterates through all RRSIG records in the rdataset
    702  * and returns the earliest expiration time, which indicates when
    703  * the signatures should be resigned.
    704  *
    705  * Requires:
    706  * \li	'rdataset' is a valid rdataset.
    707  */
    708 
    709 ISC_LANG_ENDDECLS
    710