xref: /netbsd-src/external/mpl/bind/dist/lib/dns/db_p.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: db_p.h,v 1.2 2025/01/26 16:25:22 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 #include <isc/heap.h>
19 #include <isc/lang.h>
20 #include <isc/urcu.h>
21 
22 #include <dns/nsec3.h>
23 #include <dns/rbt.h>
24 #include <dns/types.h>
25 
26 #define GLUETABLE_INIT_SIZE 1 << 2
27 #define GLUETABLE_MIN_SIZE  1 << 8
28 
29 #define RDATATYPE_NCACHEANY DNS_TYPEPAIR_VALUE(0, dns_rdatatype_any)
30 
31 #ifdef STRONG_RWLOCK_CHECK
32 #define STRONG_RWLOCK_CHECK(cond) REQUIRE(cond)
33 #else
34 #define STRONG_RWLOCK_CHECK(cond)
35 #endif
36 
37 #define NODE_INITLOCK(l)    isc_rwlock_init((l))
38 #define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l)
39 #define NODE_LOCK(l, t, tp)                                      \
40 	{                                                        \
41 		STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
42 		RWLOCK((l), (t));                                \
43 		*tp = t;                                         \
44 	}
45 #define NODE_UNLOCK(l, tp)                                       \
46 	{                                                        \
47 		STRONG_RWLOCK_CHECK(*tp != isc_rwlocktype_none); \
48 		RWUNLOCK(l, *tp);                                \
49 		*tp = isc_rwlocktype_none;                       \
50 	}
51 #define NODE_RDLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_read, tp);
52 #define NODE_WRLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_write, tp);
53 #define NODE_TRYLOCK(l, t, tp)                                   \
54 	({                                                       \
55 		STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
56 		isc_result_t _result = isc_rwlock_trylock(l, t); \
57 		if (_result == ISC_R_SUCCESS) {                  \
58 			*tp = t;                                 \
59 		};                                               \
60 		_result;                                         \
61 	})
62 #define NODE_TRYRDLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_read, tp)
63 #define NODE_TRYWRLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_write, tp)
64 #define NODE_TRYUPGRADE(l, tp)                                   \
65 	({                                                       \
66 		STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_read); \
67 		isc_result_t _result = isc_rwlock_tryupgrade(l); \
68 		if (_result == ISC_R_SUCCESS) {                  \
69 			*tp = isc_rwlocktype_write;              \
70 		};                                               \
71 		_result;                                         \
72 	})
73 #define NODE_FORCEUPGRADE(l, tp)                       \
74 	if (NODE_TRYUPGRADE(l, tp) != ISC_R_SUCCESS) { \
75 		NODE_UNLOCK(l, tp);                    \
76 		NODE_WRLOCK(l, tp);                    \
77 	}
78 
79 #define TREE_INITLOCK(l)    isc_rwlock_init(l)
80 #define TREE_DESTROYLOCK(l) isc_rwlock_destroy(l)
81 #define TREE_LOCK(l, t, tp)                                      \
82 	{                                                        \
83 		STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
84 		RWLOCK(l, t);                                    \
85 		*tp = t;                                         \
86 	}
87 #define TREE_UNLOCK(l, tp)                                       \
88 	{                                                        \
89 		STRONG_RWLOCK_CHECK(*tp != isc_rwlocktype_none); \
90 		RWUNLOCK(l, *tp);                                \
91 		*tp = isc_rwlocktype_none;                       \
92 	}
93 #define TREE_RDLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_read, tp);
94 #define TREE_WRLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_write, tp);
95 #define TREE_TRYLOCK(l, t, tp)                                   \
96 	({                                                       \
97 		STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_none); \
98 		isc_result_t _result = isc_rwlock_trylock(l, t); \
99 		if (_result == ISC_R_SUCCESS) {                  \
100 			*tp = t;                                 \
101 		};                                               \
102 		_result;                                         \
103 	})
104 #define TREE_TRYRDLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_read, tp)
105 #define TREE_TRYWRLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_write, tp)
106 #define TREE_TRYUPGRADE(l, tp)                                   \
107 	({                                                       \
108 		STRONG_RWLOCK_CHECK(*tp == isc_rwlocktype_read); \
109 		isc_result_t _result = isc_rwlock_tryupgrade(l); \
110 		if (_result == ISC_R_SUCCESS) {                  \
111 			*tp = isc_rwlocktype_write;              \
112 		};                                               \
113 		_result;                                         \
114 	})
115 #define TREE_FORCEUPGRADE(l, tp)                       \
116 	if (TREE_TRYUPGRADE(l, tp) != ISC_R_SUCCESS) { \
117 		TREE_UNLOCK(l, tp);                    \
118 		TREE_WRLOCK(l, tp);                    \
119 	}
120 
121 #define IS_STUB(db)  (((db)->common.attributes & DNS_DBATTR_STUB) != 0)
122 #define IS_CACHE(db) (((db)->common.attributes & DNS_DBATTR_CACHE) != 0)
123 
124 ISC_LANG_BEGINDECLS
125 
126 struct dns_glue {
127 	struct dns_glue *next;
128 	dns_fixedname_t fixedname;
129 	dns_rdataset_t rdataset_a;
130 	dns_rdataset_t sigrdataset_a;
131 	dns_rdataset_t rdataset_aaaa;
132 	dns_rdataset_t sigrdataset_aaaa;
133 };
134 
135 typedef struct {
136 	dns_glue_t *glue_list;
137 	dns_db_t *db;
138 	dns_dbversion_t *version;
139 	dns_name_t *nodename;
140 } dns_glue_additionaldata_ctx_t;
141 
142 typedef struct {
143 	isc_rwlock_t lock;
144 	/* Protected in the refcount routines. */
145 	isc_refcount_t references;
146 	/* Locked by lock. */
147 	bool exiting;
148 } db_nodelock_t;
149 
150 static inline bool
151 prio_type(dns_typepair_t type) {
152 	switch (type) {
153 	case dns_rdatatype_soa:
154 	case DNS_SIGTYPE(dns_rdatatype_soa):
155 	case dns_rdatatype_a:
156 	case DNS_SIGTYPE(dns_rdatatype_a):
157 	case dns_rdatatype_mx:
158 	case DNS_SIGTYPE(dns_rdatatype_mx):
159 	case dns_rdatatype_aaaa:
160 	case DNS_SIGTYPE(dns_rdatatype_aaaa):
161 	case dns_rdatatype_nsec:
162 	case DNS_SIGTYPE(dns_rdatatype_nsec):
163 	case dns_rdatatype_nsec3:
164 	case DNS_SIGTYPE(dns_rdatatype_nsec3):
165 	case dns_rdatatype_ns:
166 	case DNS_SIGTYPE(dns_rdatatype_ns):
167 	case dns_rdatatype_ds:
168 	case DNS_SIGTYPE(dns_rdatatype_ds):
169 	case dns_rdatatype_cname:
170 	case DNS_SIGTYPE(dns_rdatatype_cname):
171 	case dns_rdatatype_dname:
172 	case DNS_SIGTYPE(dns_rdatatype_dname):
173 	case dns_rdatatype_svcb:
174 	case DNS_SIGTYPE(dns_rdatatype_svcb):
175 	case dns_rdatatype_https:
176 	case DNS_SIGTYPE(dns_rdatatype_https):
177 	case dns_rdatatype_dnskey:
178 	case DNS_SIGTYPE(dns_rdatatype_dnskey):
179 	case dns_rdatatype_srv:
180 	case DNS_SIGTYPE(dns_rdatatype_srv):
181 	case dns_rdatatype_txt:
182 	case DNS_SIGTYPE(dns_rdatatype_txt):
183 	case dns_rdatatype_ptr:
184 	case DNS_SIGTYPE(dns_rdatatype_ptr):
185 	case dns_rdatatype_naptr:
186 	case DNS_SIGTYPE(dns_rdatatype_naptr):
187 		return true;
188 	}
189 	return false;
190 }
191 
192 void
193 dns__db_logtoomanyrecords(dns_db_t *db, const dns_name_t *name,
194 			  dns_rdatatype_t type, const char *op, uint32_t limit);
195 /*
196  * Emit a log message when adding an rdataset of name/type would exceed the
197  * 'maxrrperset' limit. 'op' is 'adding' or 'updating' depending on whether
198  * the addition is to create a new rdataset or to merge to an existing one.
199  */
200 
201 ISC_LANG_ENDDECLS
202