1999-01-27 08:44:10 +00:00
|
|
|
/*
|
2008-04-01 23:47:10 +00:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
1999-01-27 08:44:10 +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-27 08:44:10 +00:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
|
|
|
*/
|
|
|
|
|
2021-10-05 16:49:47 +02:00
|
|
|
#pragma once
|
1999-01-27 08:44:10 +00:00
|
|
|
|
2006-12-22 01:46:19 +00:00
|
|
|
/*! \file dns/rdataslab.h
|
2005-04-27 04:57:32 +00:00
|
|
|
* \brief
|
1999-01-27 08:44:10 +00:00
|
|
|
* Implements storage of rdatasets into slabs of memory.
|
|
|
|
*
|
|
|
|
* MP:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li Clients of this module must impose any required synchronization.
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Reliability:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li This module deals with low-level byte streams. Errors in any of
|
1999-01-27 08:44:10 +00:00
|
|
|
* the functions are likely to crash the server or corrupt memory.
|
|
|
|
*
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li If the caller passes invalid memory references, these functions are
|
1999-02-06 00:07:09 +00:00
|
|
|
* likely to crash the server or corrupt memory.
|
|
|
|
*
|
1999-01-27 08:44:10 +00:00
|
|
|
* Resources:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li None.
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Security:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li None.
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Standards:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li None.
|
1999-01-27 08:44:10 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/***
|
|
|
|
*** Imports
|
|
|
|
***/
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2023-07-19 08:50:17 +02:00
|
|
|
#include <isc/atomic.h>
|
2023-05-09 23:07:50 -07:00
|
|
|
#include <isc/heap.h>
|
2023-07-19 08:50:17 +02:00
|
|
|
#include <isc/stdtime.h>
|
2023-05-09 23:07:50 -07:00
|
|
|
#include <isc/urcu.h>
|
1999-01-27 08:44:10 +00:00
|
|
|
|
2023-07-19 08:50:17 +02:00
|
|
|
#include <dns/name.h>
|
|
|
|
#include <dns/rdataset.h>
|
1999-01-27 08:44:10 +00:00
|
|
|
#include <dns/types.h>
|
|
|
|
|
2000-11-30 13:19:09 +00:00
|
|
|
#define DNS_RDATASLAB_FORCE 0x1
|
|
|
|
#define DNS_RDATASLAB_EXACT 0x2
|
|
|
|
|
2008-04-01 01:37:25 +00:00
|
|
|
#define DNS_RDATASLAB_OFFLINE 0x01 /* RRSIG is for offline DNSKEY */
|
|
|
|
|
2023-10-01 01:06:49 -07:00
|
|
|
struct dns_slabheader_proof {
|
2023-05-09 23:07:50 -07:00
|
|
|
dns_name_t name;
|
|
|
|
void *neg;
|
|
|
|
void *negsig;
|
|
|
|
dns_rdatatype_t type;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct dns_slabheader {
|
2024-11-05 09:36:24 +01:00
|
|
|
_Atomic(uint16_t) attributes;
|
|
|
|
|
2023-05-09 23:07:50 -07:00
|
|
|
/*%
|
|
|
|
* Locked by the owning node's lock.
|
|
|
|
*/
|
2025-02-03 14:06:37 +01:00
|
|
|
dns_trust_t trust;
|
|
|
|
uint32_t serial;
|
|
|
|
union {
|
|
|
|
isc_stdtime_t expire;
|
|
|
|
dns_ttl_t ttl;
|
|
|
|
};
|
2025-08-06 19:34:35 +02:00
|
|
|
dns_typepair_t typepair;
|
2023-05-09 23:07:50 -07:00
|
|
|
|
2024-11-05 09:36:24 +01:00
|
|
|
_Atomic(uint16_t) count;
|
2023-05-09 23:07:50 -07:00
|
|
|
/*%<
|
2024-11-05 09:36:24 +01:00
|
|
|
* 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.
|
2023-05-09 23:07:50 -07:00
|
|
|
*/
|
|
|
|
|
2025-02-23 14:36:35 +01:00
|
|
|
/* resigning (zone) and TTL-cleaning (cache) */
|
|
|
|
uint16_t resign_lsb : 1;
|
2024-11-05 09:36:24 +01:00
|
|
|
isc_stdtime_t resign;
|
2025-02-23 14:36:35 +01:00
|
|
|
isc_heap_t *heap;
|
2024-11-05 09:36:24 +01:00
|
|
|
unsigned int heap_index;
|
2023-05-09 23:07:50 -07:00
|
|
|
|
2025-02-23 14:36:35 +01:00
|
|
|
/* Used for stale refresh */
|
2024-11-05 09:36:24 +01:00
|
|
|
_Atomic(uint32_t) last_refresh_fail_ts;
|
2023-05-09 23:07:50 -07:00
|
|
|
|
2023-10-01 01:06:49 -07:00
|
|
|
dns_slabheader_proof_t *noqname;
|
|
|
|
dns_slabheader_proof_t *closest;
|
2023-05-09 23:07:50 -07:00
|
|
|
/*%<
|
|
|
|
* We don't use the LIST macros, because the LIST structure has
|
|
|
|
* both head and tail pointers, and is doubly linked.
|
|
|
|
*/
|
|
|
|
|
2025-01-31 15:47:33 +01:00
|
|
|
union {
|
|
|
|
struct dns_slabheader *next;
|
|
|
|
struct dns_slabheader *up;
|
|
|
|
};
|
2023-05-09 23:07:50 -07:00
|
|
|
/*%<
|
|
|
|
* If this is the top header for an rdataset, 'next' points
|
|
|
|
* to the top header for the next rdataset (i.e., the next type).
|
2025-01-31 15:47:33 +01:00
|
|
|
*
|
|
|
|
* Otherwise 'up' points up to the header whose down pointer points at
|
|
|
|
* this header.
|
2023-05-09 23:07:50 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
struct dns_slabheader *down;
|
|
|
|
/*%<
|
|
|
|
* Points to the header for the next older version of
|
|
|
|
* this rdataset.
|
|
|
|
*/
|
|
|
|
|
|
|
|
dns_dbnode_t *node;
|
|
|
|
/*%<
|
|
|
|
* The database and database node objects containing
|
|
|
|
* this rdataset, if any.
|
|
|
|
*/
|
|
|
|
|
2025-02-23 14:36:35 +01:00
|
|
|
dns_gluelist_t *gluelist;
|
|
|
|
|
|
|
|
/*% Used for SIEVE-LRU (cache) and changed_list (zone) */
|
2023-05-09 23:07:50 -07:00
|
|
|
ISC_LINK(struct dns_slabheader) link;
|
2025-02-23 14:36:35 +01:00
|
|
|
/*% Used for SIEVE-LRU */
|
|
|
|
bool visited;
|
2023-05-09 23:07:50 -07:00
|
|
|
|
|
|
|
/*%
|
|
|
|
* Case vector. If the bit is set then the corresponding
|
|
|
|
* character in the owner name needs to be AND'd with 0x20,
|
|
|
|
* rendering that character upper case.
|
|
|
|
*/
|
|
|
|
unsigned char upper[32];
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
DNS_SLABHEADERATTR_NONEXISTENT = 1 << 0,
|
|
|
|
DNS_SLABHEADERATTR_STALE = 1 << 1,
|
|
|
|
DNS_SLABHEADERATTR_IGNORE = 1 << 2,
|
|
|
|
DNS_SLABHEADERATTR_NXDOMAIN = 1 << 3,
|
|
|
|
DNS_SLABHEADERATTR_RESIGN = 1 << 4,
|
|
|
|
DNS_SLABHEADERATTR_STATCOUNT = 1 << 5,
|
|
|
|
DNS_SLABHEADERATTR_OPTOUT = 1 << 6,
|
|
|
|
DNS_SLABHEADERATTR_NEGATIVE = 1 << 7,
|
|
|
|
DNS_SLABHEADERATTR_PREFETCH = 1 << 8,
|
|
|
|
DNS_SLABHEADERATTR_CASESET = 1 << 9,
|
|
|
|
DNS_SLABHEADERATTR_ZEROTTL = 1 << 10,
|
|
|
|
DNS_SLABHEADERATTR_CASEFULLYLOWER = 1 << 11,
|
|
|
|
DNS_SLABHEADERATTR_ANCIENT = 1 << 12,
|
|
|
|
DNS_SLABHEADERATTR_STALE_WINDOW = 1 << 13,
|
|
|
|
};
|
|
|
|
|
2025-06-18 12:01:31 +10:00
|
|
|
/* clang-format off : RemoveParentheses */
|
2023-05-09 23:07:50 -07:00
|
|
|
#define DNS_SLABHEADER_GETATTR(header, attribute) \
|
2025-06-18 12:01:31 +10:00
|
|
|
(atomic_load_acquire(&(header)->attributes) & (attribute))
|
|
|
|
/* clang-format on */
|
2023-05-09 23:07:50 -07:00
|
|
|
#define DNS_SLABHEADER_SETATTR(header, attribute) \
|
|
|
|
atomic_fetch_or_release(&(header)->attributes, attribute)
|
|
|
|
#define DNS_SLABHEADER_CLRATTR(header, attribute) \
|
|
|
|
atomic_fetch_and_release(&(header)->attributes, ~(attribute))
|
|
|
|
|
|
|
|
extern dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods;
|
|
|
|
|
1999-01-27 08:44:10 +00:00
|
|
|
/***
|
|
|
|
*** Functions
|
|
|
|
***/
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-01-27 08:44:10 +00:00
|
|
|
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
2025-02-07 20:07:53 -08:00
|
|
|
isc_region_t *region, uint32_t limit);
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%<
|
2025-02-07 20:07:53 -08:00
|
|
|
* Allocate space for a slab to hold the data in rdataset, and copy the
|
|
|
|
* data into it. The resulting slab will be returned in 'region'.
|
|
|
|
*
|
2025-02-19 13:59:23 +01:00
|
|
|
* dns_rdataslab_fromrdataset() allocates space for a dns_slabheader object
|
|
|
|
* and the memory needed for a raw slab, and partially initializes
|
2025-02-07 21:06:34 -08:00
|
|
|
* it, setting the type, trust, and TTL fields to match rdataset->type,
|
|
|
|
* rdataset->covers, rdataset->trust, and rdataset->ttl. (Note that the
|
|
|
|
* last field needs to be overridden when used in the cache database,
|
|
|
|
* since cache headers use an expire time instead of a TTL.)
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Requires:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li 'rdataset' is valid.
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Ensures:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li 'region' will have base pointing to the start of allocated memory,
|
1999-01-27 08:44:10 +00:00
|
|
|
* with the slabified region beginning at region->base + reservelen.
|
|
|
|
* region->length contains the total length allocated.
|
|
|
|
*
|
|
|
|
* Returns:
|
2005-04-27 04:57:32 +00:00
|
|
|
*\li ISC_R_SUCCESS - successful completion
|
2025-01-07 19:03:07 -08:00
|
|
|
*\li ISC_R_NOSPACE - more than 64k RRs
|
|
|
|
*\li DNS_R_TOOMANYRECORDS - more than max-records-per-rrset RRs
|
|
|
|
*\li DNS_R_SINGLETON - singleton type has more than one RR
|
1999-01-27 08:44:10 +00:00
|
|
|
*/
|
|
|
|
|
1999-02-06 00:07:09 +00:00
|
|
|
unsigned int
|
2025-02-07 21:21:52 -08:00
|
|
|
dns_rdataslab_size(dns_slabheader_t *header);
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%<
|
2025-02-07 21:21:52 -08:00
|
|
|
* Return the total size of the rdataslab following 'header'.
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Requires:
|
2025-02-07 21:21:52 -08:00
|
|
|
*\li 'header' points to a slabheader with an rdataslab following it.
|
1999-01-27 08:44:10 +00:00
|
|
|
*
|
|
|
|
* Returns:
|
2025-02-07 21:21:52 -08:00
|
|
|
*\li The number of bytes in the slab, plus the header.
|
1999-01-27 08:44:10 +00:00
|
|
|
*/
|
|
|
|
|
2016-11-02 17:31:27 +11:00
|
|
|
unsigned int
|
2025-02-07 21:21:52 -08:00
|
|
|
dns_rdataslab_count(dns_slabheader_t *header);
|
2016-11-02 17:31:27 +11:00
|
|
|
/*%<
|
2025-02-07 21:21:52 -08:00
|
|
|
* Return the number of records in the rdataslab following 'header'.
|
2016-11-02 17:31:27 +11:00
|
|
|
*
|
|
|
|
* Requires:
|
2025-02-07 21:21:52 -08:00
|
|
|
*\li 'header' points to a slabheader with an rdataslab following it.
|
2016-11-02 17:31:27 +11:00
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
*\li The number of records in the slab.
|
|
|
|
*/
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2025-02-07 21:21:52 -08:00
|
|
|
dns_rdataslab_merge(dns_slabheader_t *oheader, dns_slabheader_t *nheader,
|
|
|
|
isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|
|
|
dns_rdatatype_t type, unsigned int flags,
|
|
|
|
uint32_t maxrrperset, dns_slabheader_t **theaderp);
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%<
|
2025-02-07 21:21:52 -08:00
|
|
|
* Merge the slabs following 'oheader' and 'nheader'.
|
1999-04-01 04:00:39 +00:00
|
|
|
*/
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2025-02-07 21:21:52 -08:00
|
|
|
dns_rdataslab_subtract(dns_slabheader_t *mheader, dns_slabheader_t *sheader,
|
|
|
|
isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|
|
|
dns_rdatatype_t type, unsigned int flags,
|
|
|
|
dns_slabheader_t **theaderp);
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%<
|
2025-02-07 21:21:52 -08:00
|
|
|
* Subtract the slab following 'sheader' from the one following 'mheader'.
|
|
|
|
* If 'exact' is true then all elements from the 'sheader' slab must exist
|
|
|
|
* in the 'mheader' slab.
|
1999-06-16 21:03:07 +00:00
|
|
|
*
|
|
|
|
* XXX
|
2000-12-01 01:22:45 +00:00
|
|
|
* valid flags are DNS_RDATASLAB_EXACT
|
1999-06-16 21:03:07 +00:00
|
|
|
*/
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2025-02-07 21:21:52 -08:00
|
|
|
dns_rdataslab_equal(dns_slabheader_t *header1, dns_slabheader_t *header2);
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%<
|
2002-11-12 23:24:45 +00:00
|
|
|
* Compare two rdataslabs for equality. This does _not_ do a full
|
2000-09-01 01:35:21 +00:00
|
|
|
* DNSSEC comparison.
|
|
|
|
*
|
|
|
|
* Requires:
|
2025-02-07 21:21:52 -08:00
|
|
|
*\li 'header1' and 'header1' point to slab headers followed by slabs.
|
2000-09-01 01:35:21 +00:00
|
|
|
*
|
|
|
|
* Returns:
|
2018-04-17 08:29:14 -07:00
|
|
|
*\li true if the slabs are equal, false otherwise.
|
2000-09-01 01:35:21 +00:00
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2025-02-07 21:21:52 -08:00
|
|
|
dns_rdataslab_equalx(dns_slabheader_t *header1, dns_slabheader_t *header2,
|
2025-02-06 15:50:52 -08:00
|
|
|
dns_rdataclass_t rdclass, dns_rdatatype_t type);
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%<
|
2008-04-01 23:47:10 +00:00
|
|
|
* Compare two rdataslabs for DNSSEC equality.
|
2002-11-12 23:24:45 +00:00
|
|
|
*
|
|
|
|
* Requires:
|
2025-02-07 21:21:52 -08:00
|
|
|
*\li 'header1' and 'header2' point to slab headers followed by slabs.
|
2002-11-12 23:24:45 +00:00
|
|
|
*
|
|
|
|
* Returns:
|
2018-04-17 08:29:14 -07:00
|
|
|
*\li true if the slabs are equal, #false otherwise.
|
2002-11-12 23:24:45 +00:00
|
|
|
*/
|
|
|
|
|
2023-05-09 23:07:50 -07:00
|
|
|
void *
|
|
|
|
dns_slabheader_raw(dns_slabheader_t *header);
|
|
|
|
/*%
|
|
|
|
* Returns the address of the raw memory following a dns_slabheader.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_slabheader_setownercase(dns_slabheader_t *header, const dns_name_t *name);
|
|
|
|
/*%<
|
|
|
|
* Store the casing of 'name', into a bitfield in 'header'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_slabheader_copycase(dns_slabheader_t *dest, dns_slabheader_t *src);
|
|
|
|
/*%<
|
|
|
|
* Copy the casing of 'src', into 'dest'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
2025-07-15 12:16:39 +02:00
|
|
|
dns_slabheader_reset(dns_slabheader_t *h, dns_dbnode_t *node);
|
2023-05-09 23:07:50 -07:00
|
|
|
/*%<
|
|
|
|
* Reset an rdataslab header 'h' so it can be used to store data in
|
2025-08-05 18:05:52 +02:00
|
|
|
* database node 'node'.
|
2023-05-09 23:07:50 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
dns_slabheader_t *
|
2025-08-05 18:05:52 +02:00
|
|
|
dns_slabheader_new(isc_mem_t *mctx, dns_dbnode_t *node);
|
2023-05-09 23:07:50 -07:00
|
|
|
/*%<
|
|
|
|
* Allocate memory for an rdataslab header and initialize it for use
|
2025-08-05 18:05:52 +02:00
|
|
|
* in database node 'node'.
|
2023-05-09 23:07:50 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_slabheader_destroy(dns_slabheader_t **headerp);
|
|
|
|
/*%<
|
|
|
|
* Free all memory associated with '*headerp'.
|
|
|
|
*/
|
2023-10-01 01:06:49 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proof);
|
|
|
|
/*%<
|
|
|
|
* Free all memory associated with a nonexistence proof.
|
|
|
|
*/
|
2025-01-31 15:47:33 +01:00
|
|
|
|
|
|
|
dns_slabheader_t *
|
|
|
|
dns_slabheader_top(dns_slabheader_t *header);
|
|
|
|
/*%<
|
|
|
|
* Return the top header for the type or the negtype
|
|
|
|
*/
|