sdlz.c revision 1.2.2.2 1 1.2.2.2 pgoyette /* $NetBSD: sdlz.c,v 1.2.2.2 2018/09/06 06:55:00 pgoyette Exp $ */
2 1.2.2.2 pgoyette
3 1.2.2.2 pgoyette /*
4 1.2.2.2 pgoyette * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 1.2.2.2 pgoyette *
6 1.2.2.2 pgoyette * This Source Code Form is subject to the terms of the Mozilla Public
7 1.2.2.2 pgoyette * License, v. 2.0. If a copy of the MPL was not distributed with this
8 1.2.2.2 pgoyette * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 1.2.2.2 pgoyette *
10 1.2.2.2 pgoyette * See the COPYRIGHT file distributed with this work for additional
11 1.2.2.2 pgoyette * information regarding copyright ownership.
12 1.2.2.2 pgoyette */
13 1.2.2.2 pgoyette
14 1.2.2.2 pgoyette /*
15 1.2.2.2 pgoyette * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting (at) nlnet.nl.
16 1.2.2.2 pgoyette *
17 1.2.2.2 pgoyette * Permission to use, copy, modify, and distribute this software for any
18 1.2.2.2 pgoyette * purpose with or without fee is hereby granted, provided that the
19 1.2.2.2 pgoyette * above copyright notice and this permission notice appear in all
20 1.2.2.2 pgoyette * copies.
21 1.2.2.2 pgoyette *
22 1.2.2.2 pgoyette * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
23 1.2.2.2 pgoyette * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
24 1.2.2.2 pgoyette * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
25 1.2.2.2 pgoyette * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
26 1.2.2.2 pgoyette * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
27 1.2.2.2 pgoyette * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
28 1.2.2.2 pgoyette * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
29 1.2.2.2 pgoyette * USE OR PERFORMANCE OF THIS SOFTWARE.
30 1.2.2.2 pgoyette *
31 1.2.2.2 pgoyette * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
32 1.2.2.2 pgoyette * conceived and contributed by Rob Butler.
33 1.2.2.2 pgoyette *
34 1.2.2.2 pgoyette * Permission to use, copy, modify, and distribute this software for any
35 1.2.2.2 pgoyette * purpose with or without fee is hereby granted, provided that the
36 1.2.2.2 pgoyette * above copyright notice and this permission notice appear in all
37 1.2.2.2 pgoyette * copies.
38 1.2.2.2 pgoyette *
39 1.2.2.2 pgoyette * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
40 1.2.2.2 pgoyette * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
41 1.2.2.2 pgoyette * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
42 1.2.2.2 pgoyette * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
43 1.2.2.2 pgoyette * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
44 1.2.2.2 pgoyette * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
45 1.2.2.2 pgoyette * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
46 1.2.2.2 pgoyette * USE OR PERFORMANCE OF THIS SOFTWARE.
47 1.2.2.2 pgoyette */
48 1.2.2.2 pgoyette
49 1.2.2.2 pgoyette /*! \file */
50 1.2.2.2 pgoyette
51 1.2.2.2 pgoyette #include <config.h>
52 1.2.2.2 pgoyette #include <string.h>
53 1.2.2.2 pgoyette
54 1.2.2.2 pgoyette #include <isc/buffer.h>
55 1.2.2.2 pgoyette #include <isc/lex.h>
56 1.2.2.2 pgoyette #include <isc/log.h>
57 1.2.2.2 pgoyette #include <isc/rwlock.h>
58 1.2.2.2 pgoyette #include <isc/string.h>
59 1.2.2.2 pgoyette #include <isc/util.h>
60 1.2.2.2 pgoyette #include <isc/magic.h>
61 1.2.2.2 pgoyette #include <isc/mem.h>
62 1.2.2.2 pgoyette #include <isc/once.h>
63 1.2.2.2 pgoyette #include <isc/print.h>
64 1.2.2.2 pgoyette #include <isc/region.h>
65 1.2.2.2 pgoyette
66 1.2.2.2 pgoyette #include <dns/callbacks.h>
67 1.2.2.2 pgoyette #include <dns/db.h>
68 1.2.2.2 pgoyette #include <dns/dbiterator.h>
69 1.2.2.2 pgoyette #include <dns/dlz.h>
70 1.2.2.2 pgoyette #include <dns/fixedname.h>
71 1.2.2.2 pgoyette #include <dns/log.h>
72 1.2.2.2 pgoyette #include <dns/rdata.h>
73 1.2.2.2 pgoyette #include <dns/rdatalist.h>
74 1.2.2.2 pgoyette #include <dns/rdataset.h>
75 1.2.2.2 pgoyette #include <dns/rdatasetiter.h>
76 1.2.2.2 pgoyette #include <dns/rdatatype.h>
77 1.2.2.2 pgoyette #include <dns/result.h>
78 1.2.2.2 pgoyette #include <dns/master.h>
79 1.2.2.2 pgoyette #include <dns/sdlz.h>
80 1.2.2.2 pgoyette #include <dns/types.h>
81 1.2.2.2 pgoyette
82 1.2.2.2 pgoyette #include "rdatalist_p.h"
83 1.2.2.2 pgoyette
84 1.2.2.2 pgoyette /*
85 1.2.2.2 pgoyette * Private Types
86 1.2.2.2 pgoyette */
87 1.2.2.2 pgoyette
88 1.2.2.2 pgoyette struct dns_sdlzimplementation {
89 1.2.2.2 pgoyette const dns_sdlzmethods_t *methods;
90 1.2.2.2 pgoyette isc_mem_t *mctx;
91 1.2.2.2 pgoyette void *driverarg;
92 1.2.2.2 pgoyette unsigned int flags;
93 1.2.2.2 pgoyette isc_mutex_t driverlock;
94 1.2.2.2 pgoyette dns_dlzimplementation_t *dlz_imp;
95 1.2.2.2 pgoyette };
96 1.2.2.2 pgoyette
97 1.2.2.2 pgoyette struct dns_sdlz_db {
98 1.2.2.2 pgoyette /* Unlocked */
99 1.2.2.2 pgoyette dns_db_t common;
100 1.2.2.2 pgoyette void *dbdata;
101 1.2.2.2 pgoyette dns_sdlzimplementation_t *dlzimp;
102 1.2.2.2 pgoyette isc_mutex_t refcnt_lock;
103 1.2.2.2 pgoyette /* Locked */
104 1.2.2.2 pgoyette unsigned int references;
105 1.2.2.2 pgoyette dns_dbversion_t *future_version;
106 1.2.2.2 pgoyette int dummy_version;
107 1.2.2.2 pgoyette };
108 1.2.2.2 pgoyette
109 1.2.2.2 pgoyette struct dns_sdlzlookup {
110 1.2.2.2 pgoyette /* Unlocked */
111 1.2.2.2 pgoyette unsigned int magic;
112 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz;
113 1.2.2.2 pgoyette ISC_LIST(dns_rdatalist_t) lists;
114 1.2.2.2 pgoyette ISC_LIST(isc_buffer_t) buffers;
115 1.2.2.2 pgoyette dns_name_t *name;
116 1.2.2.2 pgoyette ISC_LINK(dns_sdlzlookup_t) link;
117 1.2.2.2 pgoyette isc_mutex_t lock;
118 1.2.2.2 pgoyette dns_rdatacallbacks_t callbacks;
119 1.2.2.2 pgoyette /* Locked */
120 1.2.2.2 pgoyette unsigned int references;
121 1.2.2.2 pgoyette };
122 1.2.2.2 pgoyette
123 1.2.2.2 pgoyette typedef struct dns_sdlzlookup dns_sdlznode_t;
124 1.2.2.2 pgoyette
125 1.2.2.2 pgoyette struct dns_sdlzallnodes {
126 1.2.2.2 pgoyette dns_dbiterator_t common;
127 1.2.2.2 pgoyette ISC_LIST(dns_sdlznode_t) nodelist;
128 1.2.2.2 pgoyette dns_sdlznode_t *current;
129 1.2.2.2 pgoyette dns_sdlznode_t *origin;
130 1.2.2.2 pgoyette };
131 1.2.2.2 pgoyette
132 1.2.2.2 pgoyette typedef dns_sdlzallnodes_t sdlz_dbiterator_t;
133 1.2.2.2 pgoyette
134 1.2.2.2 pgoyette typedef struct sdlz_rdatasetiter {
135 1.2.2.2 pgoyette dns_rdatasetiter_t common;
136 1.2.2.2 pgoyette dns_rdatalist_t *current;
137 1.2.2.2 pgoyette } sdlz_rdatasetiter_t;
138 1.2.2.2 pgoyette
139 1.2.2.2 pgoyette
140 1.2.2.2 pgoyette #define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S')
141 1.2.2.2 pgoyette
142 1.2.2.2 pgoyette /*
143 1.2.2.2 pgoyette * Note that "impmagic" is not the first four bytes of the struct, so
144 1.2.2.2 pgoyette * ISC_MAGIC_VALID cannot be used.
145 1.2.2.2 pgoyette */
146 1.2.2.2 pgoyette
147 1.2.2.2 pgoyette #define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \
148 1.2.2.2 pgoyette (sdlzdb)->common.impmagic == SDLZDB_MAGIC)
149 1.2.2.2 pgoyette
150 1.2.2.2 pgoyette #define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L')
151 1.2.2.2 pgoyette #define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC)
152 1.2.2.2 pgoyette #define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn)
153 1.2.2.2 pgoyette
154 1.2.2.2 pgoyette /* These values are taken from RFC 1537 */
155 1.2.2.2 pgoyette #define SDLZ_DEFAULT_REFRESH 28800U /* 8 hours */
156 1.2.2.2 pgoyette #define SDLZ_DEFAULT_RETRY 7200U /* 2 hours */
157 1.2.2.2 pgoyette #define SDLZ_DEFAULT_EXPIRE 604800U /* 7 days */
158 1.2.2.2 pgoyette #define SDLZ_DEFAULT_MINIMUM 86400U /* 1 day */
159 1.2.2.2 pgoyette
160 1.2.2.2 pgoyette /* This is a reasonable value */
161 1.2.2.2 pgoyette #define SDLZ_DEFAULT_TTL (60 * 60 * 24)
162 1.2.2.2 pgoyette
163 1.2.2.2 pgoyette #ifdef __COVERITY__
164 1.2.2.2 pgoyette #define MAYBE_LOCK(imp) LOCK(&imp->driverlock)
165 1.2.2.2 pgoyette #define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock)
166 1.2.2.2 pgoyette #else
167 1.2.2.2 pgoyette #define MAYBE_LOCK(imp) \
168 1.2.2.2 pgoyette do { \
169 1.2.2.2 pgoyette unsigned int flags = imp->flags; \
170 1.2.2.2 pgoyette if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
171 1.2.2.2 pgoyette LOCK(&imp->driverlock); \
172 1.2.2.2 pgoyette } while (/*CONSTCOND*/0)
173 1.2.2.2 pgoyette
174 1.2.2.2 pgoyette #define MAYBE_UNLOCK(imp) \
175 1.2.2.2 pgoyette do { \
176 1.2.2.2 pgoyette unsigned int flags = imp->flags; \
177 1.2.2.2 pgoyette if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
178 1.2.2.2 pgoyette UNLOCK(&imp->driverlock); \
179 1.2.2.2 pgoyette } while (/*CONSTCOND*/0)
180 1.2.2.2 pgoyette #endif
181 1.2.2.2 pgoyette
182 1.2.2.2 pgoyette /*
183 1.2.2.2 pgoyette * Forward references.
184 1.2.2.2 pgoyette */
185 1.2.2.2 pgoyette static isc_result_t getnodedata(dns_db_t *db, const dns_name_t *name,
186 1.2.2.2 pgoyette isc_boolean_t create, unsigned int options,
187 1.2.2.2 pgoyette dns_clientinfomethods_t *methods,
188 1.2.2.2 pgoyette dns_clientinfo_t *clientinfo,
189 1.2.2.2 pgoyette dns_dbnode_t **nodep);
190 1.2.2.2 pgoyette
191 1.2.2.2 pgoyette static void list_tordataset(dns_rdatalist_t *rdatalist,
192 1.2.2.2 pgoyette dns_db_t *db, dns_dbnode_t *node,
193 1.2.2.2 pgoyette dns_rdataset_t *rdataset);
194 1.2.2.2 pgoyette
195 1.2.2.2 pgoyette static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
196 1.2.2.2 pgoyette
197 1.2.2.2 pgoyette static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
198 1.2.2.2 pgoyette static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
199 1.2.2.2 pgoyette static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
200 1.2.2.2 pgoyette static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
201 1.2.2.2 pgoyette const dns_name_t *name);
202 1.2.2.2 pgoyette static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
203 1.2.2.2 pgoyette static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
204 1.2.2.2 pgoyette static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
205 1.2.2.2 pgoyette dns_dbnode_t **nodep,
206 1.2.2.2 pgoyette dns_name_t *name);
207 1.2.2.2 pgoyette static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
208 1.2.2.2 pgoyette static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
209 1.2.2.2 pgoyette dns_name_t *name);
210 1.2.2.2 pgoyette
211 1.2.2.2 pgoyette static dns_dbiteratormethods_t dbiterator_methods = {
212 1.2.2.2 pgoyette dbiterator_destroy,
213 1.2.2.2 pgoyette dbiterator_first,
214 1.2.2.2 pgoyette dbiterator_last,
215 1.2.2.2 pgoyette dbiterator_seek,
216 1.2.2.2 pgoyette dbiterator_prev,
217 1.2.2.2 pgoyette dbiterator_next,
218 1.2.2.2 pgoyette dbiterator_current,
219 1.2.2.2 pgoyette dbiterator_pause,
220 1.2.2.2 pgoyette dbiterator_origin
221 1.2.2.2 pgoyette };
222 1.2.2.2 pgoyette
223 1.2.2.2 pgoyette /*
224 1.2.2.2 pgoyette * Utility functions
225 1.2.2.2 pgoyette */
226 1.2.2.2 pgoyette
227 1.2.2.2 pgoyette /*
228 1.2.2.2 pgoyette * Log a message at the given level
229 1.2.2.2 pgoyette */
230 1.2.2.2 pgoyette static void
231 1.2.2.2 pgoyette sdlz_log(int level, const char *fmt, ...) {
232 1.2.2.2 pgoyette va_list ap;
233 1.2.2.2 pgoyette va_start(ap, fmt);
234 1.2.2.2 pgoyette isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
235 1.2.2.2 pgoyette DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
236 1.2.2.2 pgoyette fmt, ap);
237 1.2.2.2 pgoyette va_end(ap);
238 1.2.2.2 pgoyette }
239 1.2.2.2 pgoyette
240 1.2.2.2 pgoyette /*% Converts the input string to lowercase, in place. */
241 1.2.2.2 pgoyette static void
242 1.2.2.2 pgoyette dns_sdlz_tolower(char *str) {
243 1.2.2.2 pgoyette unsigned int len = strlen(str);
244 1.2.2.2 pgoyette unsigned int i;
245 1.2.2.2 pgoyette
246 1.2.2.2 pgoyette for (i = 0; i < len; i++) {
247 1.2.2.2 pgoyette if (str[i] >= 'A' && str[i] <= 'Z')
248 1.2.2.2 pgoyette str[i] += 32;
249 1.2.2.2 pgoyette }
250 1.2.2.2 pgoyette }
251 1.2.2.2 pgoyette
252 1.2.2.2 pgoyette static inline unsigned int
253 1.2.2.2 pgoyette initial_size(const char *data) {
254 1.2.2.2 pgoyette unsigned int len = (strlen(data) / 64) + 1;
255 1.2.2.2 pgoyette return (len * 64 + 64);
256 1.2.2.2 pgoyette }
257 1.2.2.2 pgoyette
258 1.2.2.2 pgoyette /*
259 1.2.2.2 pgoyette * Rdataset Iterator Methods. These methods were "borrowed" from the SDB
260 1.2.2.2 pgoyette * driver interface. See the SDB driver interface documentation for more info.
261 1.2.2.2 pgoyette */
262 1.2.2.2 pgoyette
263 1.2.2.2 pgoyette static void
264 1.2.2.2 pgoyette rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
265 1.2.2.2 pgoyette sdlz_rdatasetiter_t *sdlziterator =
266 1.2.2.2 pgoyette (sdlz_rdatasetiter_t *)(*iteratorp);
267 1.2.2.2 pgoyette
268 1.2.2.2 pgoyette detachnode(sdlziterator->common.db, &sdlziterator->common.node);
269 1.2.2.2 pgoyette isc_mem_put(sdlziterator->common.db->mctx, sdlziterator,
270 1.2.2.2 pgoyette sizeof(sdlz_rdatasetiter_t));
271 1.2.2.2 pgoyette *iteratorp = NULL;
272 1.2.2.2 pgoyette }
273 1.2.2.2 pgoyette
274 1.2.2.2 pgoyette static isc_result_t
275 1.2.2.2 pgoyette rdatasetiter_first(dns_rdatasetiter_t *iterator) {
276 1.2.2.2 pgoyette sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
277 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node;
278 1.2.2.2 pgoyette
279 1.2.2.2 pgoyette if (ISC_LIST_EMPTY(sdlznode->lists))
280 1.2.2.2 pgoyette return (ISC_R_NOMORE);
281 1.2.2.2 pgoyette sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists);
282 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
283 1.2.2.2 pgoyette }
284 1.2.2.2 pgoyette
285 1.2.2.2 pgoyette static isc_result_t
286 1.2.2.2 pgoyette rdatasetiter_next(dns_rdatasetiter_t *iterator) {
287 1.2.2.2 pgoyette sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
288 1.2.2.2 pgoyette
289 1.2.2.2 pgoyette sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link);
290 1.2.2.2 pgoyette if (sdlziterator->current == NULL)
291 1.2.2.2 pgoyette return (ISC_R_NOMORE);
292 1.2.2.2 pgoyette else
293 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
294 1.2.2.2 pgoyette }
295 1.2.2.2 pgoyette
296 1.2.2.2 pgoyette static void
297 1.2.2.2 pgoyette rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
298 1.2.2.2 pgoyette sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
299 1.2.2.2 pgoyette
300 1.2.2.2 pgoyette list_tordataset(sdlziterator->current, iterator->db, iterator->node,
301 1.2.2.2 pgoyette rdataset);
302 1.2.2.2 pgoyette }
303 1.2.2.2 pgoyette
304 1.2.2.2 pgoyette static dns_rdatasetitermethods_t rdatasetiter_methods = {
305 1.2.2.2 pgoyette rdatasetiter_destroy,
306 1.2.2.2 pgoyette rdatasetiter_first,
307 1.2.2.2 pgoyette rdatasetiter_next,
308 1.2.2.2 pgoyette rdatasetiter_current
309 1.2.2.2 pgoyette };
310 1.2.2.2 pgoyette
311 1.2.2.2 pgoyette /*
312 1.2.2.2 pgoyette * DB routines. These methods were "borrowed" from the SDB driver interface.
313 1.2.2.2 pgoyette * See the SDB driver interface documentation for more info.
314 1.2.2.2 pgoyette */
315 1.2.2.2 pgoyette
316 1.2.2.2 pgoyette static void
317 1.2.2.2 pgoyette attach(dns_db_t *source, dns_db_t **targetp) {
318 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source;
319 1.2.2.2 pgoyette
320 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
321 1.2.2.2 pgoyette
322 1.2.2.2 pgoyette LOCK(&sdlz->refcnt_lock);
323 1.2.2.2 pgoyette REQUIRE(sdlz->references > 0);
324 1.2.2.2 pgoyette sdlz->references++;
325 1.2.2.2 pgoyette UNLOCK(&sdlz->refcnt_lock);
326 1.2.2.2 pgoyette
327 1.2.2.2 pgoyette *targetp = source;
328 1.2.2.2 pgoyette }
329 1.2.2.2 pgoyette
330 1.2.2.2 pgoyette static void
331 1.2.2.2 pgoyette destroy(dns_sdlz_db_t *sdlz) {
332 1.2.2.2 pgoyette isc_mem_t *mctx;
333 1.2.2.2 pgoyette mctx = sdlz->common.mctx;
334 1.2.2.2 pgoyette
335 1.2.2.2 pgoyette sdlz->common.magic = 0;
336 1.2.2.2 pgoyette sdlz->common.impmagic = 0;
337 1.2.2.2 pgoyette
338 1.2.2.2 pgoyette (void)isc_mutex_destroy(&sdlz->refcnt_lock);
339 1.2.2.2 pgoyette
340 1.2.2.2 pgoyette dns_name_free(&sdlz->common.origin, mctx);
341 1.2.2.2 pgoyette
342 1.2.2.2 pgoyette isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));
343 1.2.2.2 pgoyette isc_mem_detach(&mctx);
344 1.2.2.2 pgoyette }
345 1.2.2.2 pgoyette
346 1.2.2.2 pgoyette static void
347 1.2.2.2 pgoyette detach(dns_db_t **dbp) {
348 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);
349 1.2.2.2 pgoyette isc_boolean_t need_destroy = ISC_FALSE;
350 1.2.2.2 pgoyette
351 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
352 1.2.2.2 pgoyette LOCK(&sdlz->refcnt_lock);
353 1.2.2.2 pgoyette REQUIRE(sdlz->references > 0);
354 1.2.2.2 pgoyette sdlz->references--;
355 1.2.2.2 pgoyette if (sdlz->references == 0)
356 1.2.2.2 pgoyette need_destroy = ISC_TRUE;
357 1.2.2.2 pgoyette UNLOCK(&sdlz->refcnt_lock);
358 1.2.2.2 pgoyette
359 1.2.2.2 pgoyette if (need_destroy)
360 1.2.2.2 pgoyette destroy(sdlz);
361 1.2.2.2 pgoyette
362 1.2.2.2 pgoyette *dbp = NULL;
363 1.2.2.2 pgoyette }
364 1.2.2.2 pgoyette
365 1.2.2.2 pgoyette static isc_result_t
366 1.2.2.2 pgoyette beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
367 1.2.2.2 pgoyette UNUSED(db);
368 1.2.2.2 pgoyette UNUSED(callbacks);
369 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
370 1.2.2.2 pgoyette }
371 1.2.2.2 pgoyette
372 1.2.2.2 pgoyette static isc_result_t
373 1.2.2.2 pgoyette endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
374 1.2.2.2 pgoyette UNUSED(db);
375 1.2.2.2 pgoyette UNUSED(callbacks);
376 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
377 1.2.2.2 pgoyette }
378 1.2.2.2 pgoyette
379 1.2.2.2 pgoyette static isc_result_t
380 1.2.2.2 pgoyette dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
381 1.2.2.2 pgoyette dns_masterformat_t masterformat)
382 1.2.2.2 pgoyette {
383 1.2.2.2 pgoyette UNUSED(db);
384 1.2.2.2 pgoyette UNUSED(version);
385 1.2.2.2 pgoyette UNUSED(filename);
386 1.2.2.2 pgoyette UNUSED(masterformat);
387 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
388 1.2.2.2 pgoyette }
389 1.2.2.2 pgoyette
390 1.2.2.2 pgoyette static void
391 1.2.2.2 pgoyette currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
392 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
393 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
394 1.2.2.2 pgoyette REQUIRE(versionp != NULL && *versionp == NULL);
395 1.2.2.2 pgoyette
396 1.2.2.2 pgoyette *versionp = (void *) &sdlz->dummy_version;
397 1.2.2.2 pgoyette return;
398 1.2.2.2 pgoyette }
399 1.2.2.2 pgoyette
400 1.2.2.2 pgoyette static isc_result_t
401 1.2.2.2 pgoyette newversion(dns_db_t *db, dns_dbversion_t **versionp) {
402 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
403 1.2.2.2 pgoyette char origin[DNS_NAME_MAXTEXT + 1];
404 1.2.2.2 pgoyette isc_result_t result;
405 1.2.2.2 pgoyette
406 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
407 1.2.2.2 pgoyette
408 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->newversion == NULL)
409 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
410 1.2.2.2 pgoyette
411 1.2.2.2 pgoyette dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
412 1.2.2.2 pgoyette
413 1.2.2.2 pgoyette result = sdlz->dlzimp->methods->newversion(origin,
414 1.2.2.2 pgoyette sdlz->dlzimp->driverarg,
415 1.2.2.2 pgoyette sdlz->dbdata, versionp);
416 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
417 1.2.2.2 pgoyette sdlz_log(ISC_LOG_ERROR,
418 1.2.2.2 pgoyette "sdlz newversion on origin %s failed : %s",
419 1.2.2.2 pgoyette origin, isc_result_totext(result));
420 1.2.2.2 pgoyette return (result);
421 1.2.2.2 pgoyette }
422 1.2.2.2 pgoyette
423 1.2.2.2 pgoyette sdlz->future_version = *versionp;
424 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
425 1.2.2.2 pgoyette }
426 1.2.2.2 pgoyette
427 1.2.2.2 pgoyette static void
428 1.2.2.2 pgoyette attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp)
429 1.2.2.2 pgoyette {
430 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
431 1.2.2.2 pgoyette
432 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
433 1.2.2.2 pgoyette REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version);
434 1.2.2.2 pgoyette
435 1.2.2.2 pgoyette *targetp = source;
436 1.2.2.2 pgoyette }
437 1.2.2.2 pgoyette
438 1.2.2.2 pgoyette static void
439 1.2.2.2 pgoyette closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
440 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
441 1.2.2.2 pgoyette char origin[DNS_NAME_MAXTEXT + 1];
442 1.2.2.2 pgoyette
443 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
444 1.2.2.2 pgoyette REQUIRE(versionp != NULL);
445 1.2.2.2 pgoyette
446 1.2.2.2 pgoyette if (*versionp == (void *)&sdlz->dummy_version) {
447 1.2.2.2 pgoyette *versionp = NULL;
448 1.2.2.2 pgoyette return;
449 1.2.2.2 pgoyette }
450 1.2.2.2 pgoyette
451 1.2.2.2 pgoyette REQUIRE(*versionp == sdlz->future_version);
452 1.2.2.2 pgoyette REQUIRE(sdlz->dlzimp->methods->closeversion != NULL);
453 1.2.2.2 pgoyette
454 1.2.2.2 pgoyette dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
455 1.2.2.2 pgoyette
456 1.2.2.2 pgoyette sdlz->dlzimp->methods->closeversion(origin, commit,
457 1.2.2.2 pgoyette sdlz->dlzimp->driverarg,
458 1.2.2.2 pgoyette sdlz->dbdata, versionp);
459 1.2.2.2 pgoyette if (*versionp != NULL)
460 1.2.2.2 pgoyette sdlz_log(ISC_LOG_ERROR,
461 1.2.2.2 pgoyette "sdlz closeversion on origin %s failed", origin);
462 1.2.2.2 pgoyette
463 1.2.2.2 pgoyette sdlz->future_version = NULL;
464 1.2.2.2 pgoyette }
465 1.2.2.2 pgoyette
466 1.2.2.2 pgoyette static isc_result_t
467 1.2.2.2 pgoyette createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) {
468 1.2.2.2 pgoyette dns_sdlznode_t *node;
469 1.2.2.2 pgoyette isc_result_t result;
470 1.2.2.2 pgoyette void *sdlzv, *tdlzv;
471 1.2.2.2 pgoyette
472 1.2.2.2 pgoyette node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t));
473 1.2.2.2 pgoyette if (node == NULL)
474 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
475 1.2.2.2 pgoyette
476 1.2.2.2 pgoyette node->sdlz = NULL;
477 1.2.2.2 pgoyette sdlzv = sdlz;
478 1.2.2.2 pgoyette tdlzv = &node->sdlz;
479 1.2.2.2 pgoyette attach(sdlzv, tdlzv);
480 1.2.2.2 pgoyette ISC_LIST_INIT(node->lists);
481 1.2.2.2 pgoyette ISC_LIST_INIT(node->buffers);
482 1.2.2.2 pgoyette ISC_LINK_INIT(node, link);
483 1.2.2.2 pgoyette node->name = NULL;
484 1.2.2.2 pgoyette result = isc_mutex_init(&node->lock);
485 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
486 1.2.2.2 pgoyette UNEXPECTED_ERROR(__FILE__, __LINE__,
487 1.2.2.2 pgoyette "isc_mutex_init() failed: %s",
488 1.2.2.2 pgoyette isc_result_totext(result));
489 1.2.2.2 pgoyette isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t));
490 1.2.2.2 pgoyette return (ISC_R_UNEXPECTED);
491 1.2.2.2 pgoyette }
492 1.2.2.2 pgoyette dns_rdatacallbacks_init(&node->callbacks);
493 1.2.2.2 pgoyette node->references = 1;
494 1.2.2.2 pgoyette node->magic = SDLZLOOKUP_MAGIC;
495 1.2.2.2 pgoyette
496 1.2.2.2 pgoyette *nodep = node;
497 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
498 1.2.2.2 pgoyette }
499 1.2.2.2 pgoyette
500 1.2.2.2 pgoyette static void
501 1.2.2.2 pgoyette destroynode(dns_sdlznode_t *node) {
502 1.2.2.2 pgoyette dns_rdatalist_t *list;
503 1.2.2.2 pgoyette dns_rdata_t *rdata;
504 1.2.2.2 pgoyette isc_buffer_t *b;
505 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz;
506 1.2.2.2 pgoyette dns_db_t *db;
507 1.2.2.2 pgoyette isc_mem_t *mctx;
508 1.2.2.2 pgoyette
509 1.2.2.2 pgoyette sdlz = node->sdlz;
510 1.2.2.2 pgoyette mctx = sdlz->common.mctx;
511 1.2.2.2 pgoyette
512 1.2.2.2 pgoyette while (!ISC_LIST_EMPTY(node->lists)) {
513 1.2.2.2 pgoyette list = ISC_LIST_HEAD(node->lists);
514 1.2.2.2 pgoyette while (!ISC_LIST_EMPTY(list->rdata)) {
515 1.2.2.2 pgoyette rdata = ISC_LIST_HEAD(list->rdata);
516 1.2.2.2 pgoyette ISC_LIST_UNLINK(list->rdata, rdata, link);
517 1.2.2.2 pgoyette isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
518 1.2.2.2 pgoyette }
519 1.2.2.2 pgoyette ISC_LIST_UNLINK(node->lists, list, link);
520 1.2.2.2 pgoyette isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
521 1.2.2.2 pgoyette }
522 1.2.2.2 pgoyette
523 1.2.2.2 pgoyette while (!ISC_LIST_EMPTY(node->buffers)) {
524 1.2.2.2 pgoyette b = ISC_LIST_HEAD(node->buffers);
525 1.2.2.2 pgoyette ISC_LIST_UNLINK(node->buffers, b, link);
526 1.2.2.2 pgoyette isc_buffer_free(&b);
527 1.2.2.2 pgoyette }
528 1.2.2.2 pgoyette
529 1.2.2.2 pgoyette if (node->name != NULL) {
530 1.2.2.2 pgoyette dns_name_free(node->name, mctx);
531 1.2.2.2 pgoyette isc_mem_put(mctx, node->name, sizeof(dns_name_t));
532 1.2.2.2 pgoyette }
533 1.2.2.2 pgoyette DESTROYLOCK(&node->lock);
534 1.2.2.2 pgoyette node->magic = 0;
535 1.2.2.2 pgoyette isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
536 1.2.2.2 pgoyette db = &sdlz->common;
537 1.2.2.2 pgoyette detach(&db);
538 1.2.2.2 pgoyette }
539 1.2.2.2 pgoyette
540 1.2.2.2 pgoyette static isc_result_t
541 1.2.2.2 pgoyette getnodedata(dns_db_t *db, const dns_name_t *name, isc_boolean_t create,
542 1.2.2.2 pgoyette unsigned int options, dns_clientinfomethods_t *methods,
543 1.2.2.2 pgoyette dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
544 1.2.2.2 pgoyette {
545 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
546 1.2.2.2 pgoyette dns_sdlznode_t *node = NULL;
547 1.2.2.2 pgoyette isc_result_t result;
548 1.2.2.2 pgoyette isc_buffer_t b;
549 1.2.2.2 pgoyette char namestr[DNS_NAME_MAXTEXT + 1];
550 1.2.2.2 pgoyette isc_buffer_t b2;
551 1.2.2.2 pgoyette char zonestr[DNS_NAME_MAXTEXT + 1];
552 1.2.2.2 pgoyette isc_boolean_t isorigin;
553 1.2.2.2 pgoyette dns_sdlzauthorityfunc_t authority;
554 1.2.2.2 pgoyette
555 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
556 1.2.2.2 pgoyette REQUIRE(nodep != NULL && *nodep == NULL);
557 1.2.2.2 pgoyette
558 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->newversion == NULL) {
559 1.2.2.2 pgoyette REQUIRE(create == ISC_FALSE);
560 1.2.2.2 pgoyette }
561 1.2.2.2 pgoyette
562 1.2.2.2 pgoyette isc_buffer_init(&b, namestr, sizeof(namestr));
563 1.2.2.2 pgoyette if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) {
564 1.2.2.2 pgoyette dns_name_t relname;
565 1.2.2.2 pgoyette unsigned int labels;
566 1.2.2.2 pgoyette
567 1.2.2.2 pgoyette labels = dns_name_countlabels(name) -
568 1.2.2.2 pgoyette dns_name_countlabels(&sdlz->common.origin);
569 1.2.2.2 pgoyette dns_name_init(&relname, NULL);
570 1.2.2.2 pgoyette dns_name_getlabelsequence(name, 0, labels, &relname);
571 1.2.2.2 pgoyette result = dns_name_totext(&relname, ISC_TRUE, &b);
572 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
573 1.2.2.2 pgoyette return (result);
574 1.2.2.2 pgoyette } else {
575 1.2.2.2 pgoyette result = dns_name_totext(name, ISC_TRUE, &b);
576 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
577 1.2.2.2 pgoyette return (result);
578 1.2.2.2 pgoyette }
579 1.2.2.2 pgoyette isc_buffer_putuint8(&b, 0);
580 1.2.2.2 pgoyette
581 1.2.2.2 pgoyette isc_buffer_init(&b2, zonestr, sizeof(zonestr));
582 1.2.2.2 pgoyette result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2);
583 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
584 1.2.2.2 pgoyette return (result);
585 1.2.2.2 pgoyette isc_buffer_putuint8(&b2, 0);
586 1.2.2.2 pgoyette
587 1.2.2.2 pgoyette result = createnode(sdlz, &node);
588 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
589 1.2.2.2 pgoyette return (result);
590 1.2.2.2 pgoyette
591 1.2.2.2 pgoyette isorigin = dns_name_equal(name, &sdlz->common.origin);
592 1.2.2.2 pgoyette
593 1.2.2.2 pgoyette /* make sure strings are always lowercase */
594 1.2.2.2 pgoyette dns_sdlz_tolower(zonestr);
595 1.2.2.2 pgoyette dns_sdlz_tolower(namestr);
596 1.2.2.2 pgoyette
597 1.2.2.2 pgoyette MAYBE_LOCK(sdlz->dlzimp);
598 1.2.2.2 pgoyette
599 1.2.2.2 pgoyette /* try to lookup the host (namestr) */
600 1.2.2.2 pgoyette result = sdlz->dlzimp->methods->lookup(zonestr, namestr,
601 1.2.2.2 pgoyette sdlz->dlzimp->driverarg,
602 1.2.2.2 pgoyette sdlz->dbdata, node,
603 1.2.2.2 pgoyette methods, clientinfo);
604 1.2.2.2 pgoyette
605 1.2.2.2 pgoyette /*
606 1.2.2.2 pgoyette * If the name was not found and DNS_DBFIND_NOWILD is not
607 1.2.2.2 pgoyette * set, then we try to find a wildcard entry.
608 1.2.2.2 pgoyette *
609 1.2.2.2 pgoyette * If DNS_DBFIND_NOZONECUT is set and there are multiple
610 1.2.2.2 pgoyette * levels between the host and the zone origin, we also look
611 1.2.2.2 pgoyette * for wildcards at each level.
612 1.2.2.2 pgoyette */
613 1.2.2.2 pgoyette if (result == ISC_R_NOTFOUND && !create &&
614 1.2.2.2 pgoyette (options & DNS_DBFIND_NOWILD) == 0)
615 1.2.2.2 pgoyette {
616 1.2.2.2 pgoyette unsigned int i, dlabels, nlabels;
617 1.2.2.2 pgoyette
618 1.2.2.2 pgoyette nlabels = dns_name_countlabels(name);
619 1.2.2.2 pgoyette dlabels = nlabels - dns_name_countlabels(&sdlz->common.origin);
620 1.2.2.2 pgoyette for (i = 0; i < dlabels; i++) {
621 1.2.2.2 pgoyette char wildstr[DNS_NAME_MAXTEXT + 1];
622 1.2.2.2 pgoyette dns_fixedname_t fixed;
623 1.2.2.2 pgoyette const dns_name_t *wild;
624 1.2.2.2 pgoyette
625 1.2.2.2 pgoyette dns_fixedname_init(&fixed);
626 1.2.2.2 pgoyette if (i == dlabels)
627 1.2.2.2 pgoyette wild = dns_wildcardname;
628 1.2.2.2 pgoyette else {
629 1.2.2.2 pgoyette dns_name_t *fname;
630 1.2.2.2 pgoyette fname = dns_fixedname_name(&fixed);
631 1.2.2.2 pgoyette dns_name_getlabelsequence(name, i + 1,
632 1.2.2.2 pgoyette dlabels - i - 1,
633 1.2.2.2 pgoyette fname);
634 1.2.2.2 pgoyette result = dns_name_concatenate(dns_wildcardname,
635 1.2.2.2 pgoyette fname, fname,
636 1.2.2.2 pgoyette NULL);
637 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
638 1.2.2.2 pgoyette return (result);
639 1.2.2.2 pgoyette wild = fname;
640 1.2.2.2 pgoyette }
641 1.2.2.2 pgoyette
642 1.2.2.2 pgoyette isc_buffer_init(&b, wildstr, sizeof(wildstr));
643 1.2.2.2 pgoyette result = dns_name_totext(wild, ISC_TRUE, &b);
644 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
645 1.2.2.2 pgoyette return (result);
646 1.2.2.2 pgoyette isc_buffer_putuint8(&b, 0);
647 1.2.2.2 pgoyette
648 1.2.2.2 pgoyette result = sdlz->dlzimp->methods->lookup(zonestr, wildstr,
649 1.2.2.2 pgoyette sdlz->dlzimp->driverarg,
650 1.2.2.2 pgoyette sdlz->dbdata, node,
651 1.2.2.2 pgoyette methods, clientinfo);
652 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS)
653 1.2.2.2 pgoyette break;
654 1.2.2.2 pgoyette }
655 1.2.2.2 pgoyette }
656 1.2.2.2 pgoyette
657 1.2.2.2 pgoyette MAYBE_UNLOCK(sdlz->dlzimp);
658 1.2.2.2 pgoyette
659 1.2.2.2 pgoyette if (result == ISC_R_NOTFOUND && (isorigin || create))
660 1.2.2.2 pgoyette result = ISC_R_SUCCESS;
661 1.2.2.2 pgoyette
662 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
663 1.2.2.2 pgoyette destroynode(node);
664 1.2.2.2 pgoyette return (result);
665 1.2.2.2 pgoyette }
666 1.2.2.2 pgoyette
667 1.2.2.2 pgoyette if (isorigin && sdlz->dlzimp->methods->authority != NULL) {
668 1.2.2.2 pgoyette MAYBE_LOCK(sdlz->dlzimp);
669 1.2.2.2 pgoyette authority = sdlz->dlzimp->methods->authority;
670 1.2.2.2 pgoyette result = (*authority)(zonestr, sdlz->dlzimp->driverarg,
671 1.2.2.2 pgoyette sdlz->dbdata, node);
672 1.2.2.2 pgoyette MAYBE_UNLOCK(sdlz->dlzimp);
673 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS &&
674 1.2.2.2 pgoyette result != ISC_R_NOTIMPLEMENTED)
675 1.2.2.2 pgoyette {
676 1.2.2.2 pgoyette destroynode(node);
677 1.2.2.2 pgoyette return (result);
678 1.2.2.2 pgoyette }
679 1.2.2.2 pgoyette }
680 1.2.2.2 pgoyette
681 1.2.2.2 pgoyette if (node->name == NULL) {
682 1.2.2.2 pgoyette node->name = isc_mem_get(sdlz->common.mctx,
683 1.2.2.2 pgoyette sizeof(dns_name_t));
684 1.2.2.2 pgoyette if (node->name == NULL) {
685 1.2.2.2 pgoyette destroynode(node);
686 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
687 1.2.2.2 pgoyette }
688 1.2.2.2 pgoyette dns_name_init(node->name, NULL);
689 1.2.2.2 pgoyette result = dns_name_dup(name, sdlz->common.mctx, node->name);
690 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
691 1.2.2.2 pgoyette isc_mem_put(sdlz->common.mctx, node->name,
692 1.2.2.2 pgoyette sizeof(dns_name_t));
693 1.2.2.2 pgoyette destroynode(node);
694 1.2.2.2 pgoyette return (result);
695 1.2.2.2 pgoyette }
696 1.2.2.2 pgoyette }
697 1.2.2.2 pgoyette
698 1.2.2.2 pgoyette *nodep = node;
699 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
700 1.2.2.2 pgoyette }
701 1.2.2.2 pgoyette
702 1.2.2.2 pgoyette static isc_result_t
703 1.2.2.2 pgoyette findnodeext(dns_db_t *db, const dns_name_t *name, isc_boolean_t create,
704 1.2.2.2 pgoyette dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
705 1.2.2.2 pgoyette dns_dbnode_t **nodep)
706 1.2.2.2 pgoyette {
707 1.2.2.2 pgoyette return (getnodedata(db, name, create, 0, methods, clientinfo, nodep));
708 1.2.2.2 pgoyette }
709 1.2.2.2 pgoyette
710 1.2.2.2 pgoyette static isc_result_t
711 1.2.2.2 pgoyette findnode(dns_db_t *db, const dns_name_t *name, isc_boolean_t create,
712 1.2.2.2 pgoyette dns_dbnode_t **nodep)
713 1.2.2.2 pgoyette {
714 1.2.2.2 pgoyette return (getnodedata(db, name, create, 0, NULL, NULL, nodep));
715 1.2.2.2 pgoyette }
716 1.2.2.2 pgoyette
717 1.2.2.2 pgoyette static isc_result_t
718 1.2.2.2 pgoyette findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
719 1.2.2.2 pgoyette isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
720 1.2.2.2 pgoyette dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
721 1.2.2.2 pgoyette {
722 1.2.2.2 pgoyette UNUSED(db);
723 1.2.2.2 pgoyette UNUSED(name);
724 1.2.2.2 pgoyette UNUSED(options);
725 1.2.2.2 pgoyette UNUSED(now);
726 1.2.2.2 pgoyette UNUSED(nodep);
727 1.2.2.2 pgoyette UNUSED(foundname);
728 1.2.2.2 pgoyette UNUSED(rdataset);
729 1.2.2.2 pgoyette UNUSED(sigrdataset);
730 1.2.2.2 pgoyette
731 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
732 1.2.2.2 pgoyette }
733 1.2.2.2 pgoyette
734 1.2.2.2 pgoyette static void
735 1.2.2.2 pgoyette attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
736 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
737 1.2.2.2 pgoyette dns_sdlznode_t *node = (dns_sdlznode_t *)source;
738 1.2.2.2 pgoyette
739 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
740 1.2.2.2 pgoyette
741 1.2.2.2 pgoyette UNUSED(sdlz);
742 1.2.2.2 pgoyette
743 1.2.2.2 pgoyette LOCK(&node->lock);
744 1.2.2.2 pgoyette INSIST(node->references > 0);
745 1.2.2.2 pgoyette node->references++;
746 1.2.2.2 pgoyette INSIST(node->references != 0); /* Catch overflow. */
747 1.2.2.2 pgoyette UNLOCK(&node->lock);
748 1.2.2.2 pgoyette
749 1.2.2.2 pgoyette *targetp = source;
750 1.2.2.2 pgoyette }
751 1.2.2.2 pgoyette
752 1.2.2.2 pgoyette static void
753 1.2.2.2 pgoyette detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
754 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
755 1.2.2.2 pgoyette dns_sdlznode_t *node;
756 1.2.2.2 pgoyette isc_boolean_t need_destroy = ISC_FALSE;
757 1.2.2.2 pgoyette
758 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
759 1.2.2.2 pgoyette REQUIRE(targetp != NULL && *targetp != NULL);
760 1.2.2.2 pgoyette
761 1.2.2.2 pgoyette UNUSED(sdlz);
762 1.2.2.2 pgoyette
763 1.2.2.2 pgoyette node = (dns_sdlznode_t *)(*targetp);
764 1.2.2.2 pgoyette
765 1.2.2.2 pgoyette LOCK(&node->lock);
766 1.2.2.2 pgoyette INSIST(node->references > 0);
767 1.2.2.2 pgoyette node->references--;
768 1.2.2.2 pgoyette if (node->references == 0)
769 1.2.2.2 pgoyette need_destroy = ISC_TRUE;
770 1.2.2.2 pgoyette UNLOCK(&node->lock);
771 1.2.2.2 pgoyette
772 1.2.2.2 pgoyette if (need_destroy)
773 1.2.2.2 pgoyette destroynode(node);
774 1.2.2.2 pgoyette
775 1.2.2.2 pgoyette *targetp = NULL;
776 1.2.2.2 pgoyette }
777 1.2.2.2 pgoyette
778 1.2.2.2 pgoyette static isc_result_t
779 1.2.2.2 pgoyette expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
780 1.2.2.2 pgoyette UNUSED(db);
781 1.2.2.2 pgoyette UNUSED(node);
782 1.2.2.2 pgoyette UNUSED(now);
783 1.2.2.2 pgoyette INSIST(0);
784 1.2.2.2 pgoyette return (ISC_R_UNEXPECTED);
785 1.2.2.2 pgoyette }
786 1.2.2.2 pgoyette
787 1.2.2.2 pgoyette static void
788 1.2.2.2 pgoyette printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
789 1.2.2.2 pgoyette UNUSED(db);
790 1.2.2.2 pgoyette UNUSED(node);
791 1.2.2.2 pgoyette UNUSED(out);
792 1.2.2.2 pgoyette return;
793 1.2.2.2 pgoyette }
794 1.2.2.2 pgoyette
795 1.2.2.2 pgoyette static isc_result_t
796 1.2.2.2 pgoyette createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
797 1.2.2.2 pgoyette {
798 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
799 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter;
800 1.2.2.2 pgoyette isc_result_t result;
801 1.2.2.2 pgoyette isc_buffer_t b;
802 1.2.2.2 pgoyette char zonestr[DNS_NAME_MAXTEXT + 1];
803 1.2.2.2 pgoyette
804 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
805 1.2.2.2 pgoyette
806 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->allnodes == NULL)
807 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
808 1.2.2.2 pgoyette
809 1.2.2.2 pgoyette if ((options & DNS_DB_NSEC3ONLY) != 0 ||
810 1.2.2.2 pgoyette (options & DNS_DB_NONSEC3) != 0)
811 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
812 1.2.2.2 pgoyette
813 1.2.2.2 pgoyette isc_buffer_init(&b, zonestr, sizeof(zonestr));
814 1.2.2.2 pgoyette result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b);
815 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
816 1.2.2.2 pgoyette return (result);
817 1.2.2.2 pgoyette isc_buffer_putuint8(&b, 0);
818 1.2.2.2 pgoyette
819 1.2.2.2 pgoyette sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t));
820 1.2.2.2 pgoyette if (sdlziter == NULL)
821 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
822 1.2.2.2 pgoyette
823 1.2.2.2 pgoyette sdlziter->common.methods = &dbiterator_methods;
824 1.2.2.2 pgoyette sdlziter->common.db = NULL;
825 1.2.2.2 pgoyette dns_db_attach(db, &sdlziter->common.db);
826 1.2.2.2 pgoyette sdlziter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
827 1.2.2.2 pgoyette sdlziter->common.magic = DNS_DBITERATOR_MAGIC;
828 1.2.2.2 pgoyette ISC_LIST_INIT(sdlziter->nodelist);
829 1.2.2.2 pgoyette sdlziter->current = NULL;
830 1.2.2.2 pgoyette sdlziter->origin = NULL;
831 1.2.2.2 pgoyette
832 1.2.2.2 pgoyette /* make sure strings are always lowercase */
833 1.2.2.2 pgoyette dns_sdlz_tolower(zonestr);
834 1.2.2.2 pgoyette
835 1.2.2.2 pgoyette MAYBE_LOCK(sdlz->dlzimp);
836 1.2.2.2 pgoyette result = sdlz->dlzimp->methods->allnodes(zonestr,
837 1.2.2.2 pgoyette sdlz->dlzimp->driverarg,
838 1.2.2.2 pgoyette sdlz->dbdata, sdlziter);
839 1.2.2.2 pgoyette MAYBE_UNLOCK(sdlz->dlzimp);
840 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
841 1.2.2.2 pgoyette dns_dbiterator_t *iter = &sdlziter->common;
842 1.2.2.2 pgoyette dbiterator_destroy(&iter);
843 1.2.2.2 pgoyette return (result);
844 1.2.2.2 pgoyette }
845 1.2.2.2 pgoyette
846 1.2.2.2 pgoyette if (sdlziter->origin != NULL) {
847 1.2.2.2 pgoyette ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link);
848 1.2.2.2 pgoyette ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link);
849 1.2.2.2 pgoyette }
850 1.2.2.2 pgoyette
851 1.2.2.2 pgoyette *iteratorp = (dns_dbiterator_t *)sdlziter;
852 1.2.2.2 pgoyette
853 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
854 1.2.2.2 pgoyette }
855 1.2.2.2 pgoyette
856 1.2.2.2 pgoyette static isc_result_t
857 1.2.2.2 pgoyette findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
858 1.2.2.2 pgoyette dns_rdatatype_t type, dns_rdatatype_t covers,
859 1.2.2.2 pgoyette isc_stdtime_t now, dns_rdataset_t *rdataset,
860 1.2.2.2 pgoyette dns_rdataset_t *sigrdataset)
861 1.2.2.2 pgoyette {
862 1.2.2.2 pgoyette dns_rdatalist_t *list;
863 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node;
864 1.2.2.2 pgoyette
865 1.2.2.2 pgoyette REQUIRE(VALID_SDLZNODE(node));
866 1.2.2.2 pgoyette
867 1.2.2.2 pgoyette UNUSED(db);
868 1.2.2.2 pgoyette UNUSED(version);
869 1.2.2.2 pgoyette UNUSED(covers);
870 1.2.2.2 pgoyette UNUSED(now);
871 1.2.2.2 pgoyette UNUSED(sigrdataset);
872 1.2.2.2 pgoyette
873 1.2.2.2 pgoyette if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig)
874 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
875 1.2.2.2 pgoyette
876 1.2.2.2 pgoyette list = ISC_LIST_HEAD(sdlznode->lists);
877 1.2.2.2 pgoyette while (list != NULL) {
878 1.2.2.2 pgoyette if (list->type == type)
879 1.2.2.2 pgoyette break;
880 1.2.2.2 pgoyette list = ISC_LIST_NEXT(list, link);
881 1.2.2.2 pgoyette }
882 1.2.2.2 pgoyette if (list == NULL)
883 1.2.2.2 pgoyette return (ISC_R_NOTFOUND);
884 1.2.2.2 pgoyette
885 1.2.2.2 pgoyette list_tordataset(list, db, node, rdataset);
886 1.2.2.2 pgoyette
887 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
888 1.2.2.2 pgoyette }
889 1.2.2.2 pgoyette
890 1.2.2.2 pgoyette static isc_result_t
891 1.2.2.2 pgoyette findext(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
892 1.2.2.2 pgoyette dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
893 1.2.2.2 pgoyette dns_dbnode_t **nodep, dns_name_t *foundname,
894 1.2.2.2 pgoyette dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
895 1.2.2.2 pgoyette dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
896 1.2.2.2 pgoyette {
897 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
898 1.2.2.2 pgoyette dns_dbnode_t *node = NULL;
899 1.2.2.2 pgoyette dns_fixedname_t fname;
900 1.2.2.2 pgoyette dns_rdataset_t xrdataset;
901 1.2.2.2 pgoyette dns_name_t *xname;
902 1.2.2.2 pgoyette unsigned int nlabels, olabels;
903 1.2.2.2 pgoyette isc_result_t result;
904 1.2.2.2 pgoyette unsigned int i;
905 1.2.2.2 pgoyette
906 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
907 1.2.2.2 pgoyette REQUIRE(nodep == NULL || *nodep == NULL);
908 1.2.2.2 pgoyette REQUIRE(version == NULL ||
909 1.2.2.2 pgoyette version == (void*)&sdlz->dummy_version ||
910 1.2.2.2 pgoyette version == sdlz->future_version);
911 1.2.2.2 pgoyette
912 1.2.2.2 pgoyette UNUSED(sdlz);
913 1.2.2.2 pgoyette
914 1.2.2.2 pgoyette if (!dns_name_issubdomain(name, &db->origin))
915 1.2.2.2 pgoyette return (DNS_R_NXDOMAIN);
916 1.2.2.2 pgoyette
917 1.2.2.2 pgoyette olabels = dns_name_countlabels(&db->origin);
918 1.2.2.2 pgoyette nlabels = dns_name_countlabels(name);
919 1.2.2.2 pgoyette
920 1.2.2.2 pgoyette xname = dns_fixedname_initname(&fname);
921 1.2.2.2 pgoyette
922 1.2.2.2 pgoyette if (rdataset == NULL) {
923 1.2.2.2 pgoyette dns_rdataset_init(&xrdataset);
924 1.2.2.2 pgoyette rdataset = &xrdataset;
925 1.2.2.2 pgoyette }
926 1.2.2.2 pgoyette
927 1.2.2.2 pgoyette result = DNS_R_NXDOMAIN;
928 1.2.2.2 pgoyette
929 1.2.2.2 pgoyette /*
930 1.2.2.2 pgoyette * If we're not walking down searching for zone
931 1.2.2.2 pgoyette * cuts, we can cut straight to the chase
932 1.2.2.2 pgoyette */
933 1.2.2.2 pgoyette if ((options & DNS_DBFIND_NOZONECUT) != 0) {
934 1.2.2.2 pgoyette i = nlabels;
935 1.2.2.2 pgoyette goto search;
936 1.2.2.2 pgoyette }
937 1.2.2.2 pgoyette
938 1.2.2.2 pgoyette for (i = olabels; i <= nlabels; i++) {
939 1.2.2.2 pgoyette search:
940 1.2.2.2 pgoyette /*
941 1.2.2.2 pgoyette * Look up the next label.
942 1.2.2.2 pgoyette */
943 1.2.2.2 pgoyette dns_name_getlabelsequence(name, nlabels - i, i, xname);
944 1.2.2.2 pgoyette result = getnodedata(db, xname, ISC_FALSE, options,
945 1.2.2.2 pgoyette methods, clientinfo, &node);
946 1.2.2.2 pgoyette if (result == ISC_R_NOTFOUND) {
947 1.2.2.2 pgoyette result = DNS_R_NXDOMAIN;
948 1.2.2.2 pgoyette continue;
949 1.2.2.2 pgoyette } else if (result != ISC_R_SUCCESS)
950 1.2.2.2 pgoyette break;
951 1.2.2.2 pgoyette
952 1.2.2.2 pgoyette /*
953 1.2.2.2 pgoyette * Look for a DNAME at the current label, unless this is
954 1.2.2.2 pgoyette * the qname.
955 1.2.2.2 pgoyette */
956 1.2.2.2 pgoyette if (i < nlabels) {
957 1.2.2.2 pgoyette result = findrdataset(db, node, version,
958 1.2.2.2 pgoyette dns_rdatatype_dname, 0, now,
959 1.2.2.2 pgoyette rdataset, sigrdataset);
960 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS) {
961 1.2.2.2 pgoyette result = DNS_R_DNAME;
962 1.2.2.2 pgoyette break;
963 1.2.2.2 pgoyette }
964 1.2.2.2 pgoyette }
965 1.2.2.2 pgoyette
966 1.2.2.2 pgoyette /*
967 1.2.2.2 pgoyette * Look for an NS at the current label, unless this is the
968 1.2.2.2 pgoyette * origin, glue is ok, or there are known to be no zone cuts.
969 1.2.2.2 pgoyette */
970 1.2.2.2 pgoyette if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0 &&
971 1.2.2.2 pgoyette (options & DNS_DBFIND_NOZONECUT) == 0)
972 1.2.2.2 pgoyette {
973 1.2.2.2 pgoyette result = findrdataset(db, node, version,
974 1.2.2.2 pgoyette dns_rdatatype_ns, 0, now,
975 1.2.2.2 pgoyette rdataset, sigrdataset);
976 1.2.2.2 pgoyette
977 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS &&
978 1.2.2.2 pgoyette i == nlabels && type == dns_rdatatype_any)
979 1.2.2.2 pgoyette {
980 1.2.2.2 pgoyette result = DNS_R_ZONECUT;
981 1.2.2.2 pgoyette dns_rdataset_disassociate(rdataset);
982 1.2.2.2 pgoyette if (sigrdataset != NULL &&
983 1.2.2.2 pgoyette dns_rdataset_isassociated(sigrdataset))
984 1.2.2.2 pgoyette dns_rdataset_disassociate(sigrdataset);
985 1.2.2.2 pgoyette break;
986 1.2.2.2 pgoyette } else if (result == ISC_R_SUCCESS) {
987 1.2.2.2 pgoyette result = DNS_R_DELEGATION;
988 1.2.2.2 pgoyette break;
989 1.2.2.2 pgoyette }
990 1.2.2.2 pgoyette }
991 1.2.2.2 pgoyette
992 1.2.2.2 pgoyette /*
993 1.2.2.2 pgoyette * If the current name is not the qname, add another label
994 1.2.2.2 pgoyette * and try again.
995 1.2.2.2 pgoyette */
996 1.2.2.2 pgoyette if (i < nlabels) {
997 1.2.2.2 pgoyette destroynode(node);
998 1.2.2.2 pgoyette node = NULL;
999 1.2.2.2 pgoyette continue;
1000 1.2.2.2 pgoyette }
1001 1.2.2.2 pgoyette
1002 1.2.2.2 pgoyette /*
1003 1.2.2.2 pgoyette * If we're looking for ANY, we're done.
1004 1.2.2.2 pgoyette */
1005 1.2.2.2 pgoyette if (type == dns_rdatatype_any) {
1006 1.2.2.2 pgoyette result = ISC_R_SUCCESS;
1007 1.2.2.2 pgoyette break;
1008 1.2.2.2 pgoyette }
1009 1.2.2.2 pgoyette
1010 1.2.2.2 pgoyette /*
1011 1.2.2.2 pgoyette * Look for the qtype.
1012 1.2.2.2 pgoyette */
1013 1.2.2.2 pgoyette result = findrdataset(db, node, version, type, 0, now,
1014 1.2.2.2 pgoyette rdataset, sigrdataset);
1015 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS)
1016 1.2.2.2 pgoyette break;
1017 1.2.2.2 pgoyette
1018 1.2.2.2 pgoyette /*
1019 1.2.2.2 pgoyette * Look for a CNAME
1020 1.2.2.2 pgoyette */
1021 1.2.2.2 pgoyette if (type != dns_rdatatype_cname) {
1022 1.2.2.2 pgoyette result = findrdataset(db, node, version,
1023 1.2.2.2 pgoyette dns_rdatatype_cname, 0, now,
1024 1.2.2.2 pgoyette rdataset, sigrdataset);
1025 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS) {
1026 1.2.2.2 pgoyette result = DNS_R_CNAME;
1027 1.2.2.2 pgoyette break;
1028 1.2.2.2 pgoyette }
1029 1.2.2.2 pgoyette }
1030 1.2.2.2 pgoyette
1031 1.2.2.2 pgoyette result = DNS_R_NXRRSET;
1032 1.2.2.2 pgoyette break;
1033 1.2.2.2 pgoyette }
1034 1.2.2.2 pgoyette
1035 1.2.2.2 pgoyette if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
1036 1.2.2.2 pgoyette dns_rdataset_disassociate(rdataset);
1037 1.2.2.2 pgoyette
1038 1.2.2.2 pgoyette if (foundname != NULL) {
1039 1.2.2.2 pgoyette isc_result_t xresult;
1040 1.2.2.2 pgoyette
1041 1.2.2.2 pgoyette xresult = dns_name_copy(xname, foundname, NULL);
1042 1.2.2.2 pgoyette if (xresult != ISC_R_SUCCESS) {
1043 1.2.2.2 pgoyette if (node != NULL)
1044 1.2.2.2 pgoyette destroynode(node);
1045 1.2.2.2 pgoyette if (dns_rdataset_isassociated(rdataset))
1046 1.2.2.2 pgoyette dns_rdataset_disassociate(rdataset);
1047 1.2.2.2 pgoyette return (DNS_R_BADDB);
1048 1.2.2.2 pgoyette }
1049 1.2.2.2 pgoyette }
1050 1.2.2.2 pgoyette
1051 1.2.2.2 pgoyette if (nodep != NULL)
1052 1.2.2.2 pgoyette *nodep = node;
1053 1.2.2.2 pgoyette else if (node != NULL)
1054 1.2.2.2 pgoyette detachnode(db, &node);
1055 1.2.2.2 pgoyette
1056 1.2.2.2 pgoyette return (result);
1057 1.2.2.2 pgoyette }
1058 1.2.2.2 pgoyette
1059 1.2.2.2 pgoyette static isc_result_t
1060 1.2.2.2 pgoyette find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
1061 1.2.2.2 pgoyette dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
1062 1.2.2.2 pgoyette dns_dbnode_t **nodep, dns_name_t *foundname,
1063 1.2.2.2 pgoyette dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1064 1.2.2.2 pgoyette {
1065 1.2.2.2 pgoyette return (findext(db, name, version, type, options, now, nodep,
1066 1.2.2.2 pgoyette foundname, NULL, NULL, rdataset, sigrdataset));
1067 1.2.2.2 pgoyette }
1068 1.2.2.2 pgoyette
1069 1.2.2.2 pgoyette static isc_result_t
1070 1.2.2.2 pgoyette allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1071 1.2.2.2 pgoyette isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
1072 1.2.2.2 pgoyette {
1073 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db;
1074 1.2.2.2 pgoyette sdlz_rdatasetiter_t *iterator;
1075 1.2.2.2 pgoyette
1076 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
1077 1.2.2.2 pgoyette
1078 1.2.2.2 pgoyette REQUIRE(version == NULL ||
1079 1.2.2.2 pgoyette version == (void*)&sdlz->dummy_version ||
1080 1.2.2.2 pgoyette version == sdlz->future_version);
1081 1.2.2.2 pgoyette
1082 1.2.2.2 pgoyette UNUSED(version);
1083 1.2.2.2 pgoyette UNUSED(now);
1084 1.2.2.2 pgoyette
1085 1.2.2.2 pgoyette iterator = isc_mem_get(db->mctx, sizeof(sdlz_rdatasetiter_t));
1086 1.2.2.2 pgoyette if (iterator == NULL)
1087 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
1088 1.2.2.2 pgoyette
1089 1.2.2.2 pgoyette iterator->common.magic = DNS_RDATASETITER_MAGIC;
1090 1.2.2.2 pgoyette iterator->common.methods = &rdatasetiter_methods;
1091 1.2.2.2 pgoyette iterator->common.db = db;
1092 1.2.2.2 pgoyette iterator->common.node = NULL;
1093 1.2.2.2 pgoyette attachnode(db, node, &iterator->common.node);
1094 1.2.2.2 pgoyette iterator->common.version = version;
1095 1.2.2.2 pgoyette iterator->common.now = now;
1096 1.2.2.2 pgoyette
1097 1.2.2.2 pgoyette *iteratorp = (dns_rdatasetiter_t *)iterator;
1098 1.2.2.2 pgoyette
1099 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1100 1.2.2.2 pgoyette }
1101 1.2.2.2 pgoyette
1102 1.2.2.2 pgoyette static isc_result_t
1103 1.2.2.2 pgoyette modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1104 1.2.2.2 pgoyette dns_rdataset_t *rdataset, unsigned int options,
1105 1.2.2.2 pgoyette dns_sdlzmodrdataset_t mod_function)
1106 1.2.2.2 pgoyette {
1107 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1108 1.2.2.2 pgoyette dns_master_style_t *style = NULL;
1109 1.2.2.2 pgoyette isc_result_t result;
1110 1.2.2.2 pgoyette isc_buffer_t *buffer = NULL;
1111 1.2.2.2 pgoyette isc_mem_t *mctx;
1112 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode;
1113 1.2.2.2 pgoyette char *rdatastr = NULL;
1114 1.2.2.2 pgoyette char name[DNS_NAME_MAXTEXT + 1];
1115 1.2.2.2 pgoyette
1116 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
1117 1.2.2.2 pgoyette
1118 1.2.2.2 pgoyette if (mod_function == NULL)
1119 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
1120 1.2.2.2 pgoyette
1121 1.2.2.2 pgoyette sdlznode = (dns_sdlznode_t *)node;
1122 1.2.2.2 pgoyette
1123 1.2.2.2 pgoyette UNUSED(options);
1124 1.2.2.2 pgoyette
1125 1.2.2.2 pgoyette dns_name_format(sdlznode->name, name, sizeof(name));
1126 1.2.2.2 pgoyette
1127 1.2.2.2 pgoyette mctx = sdlz->common.mctx;
1128 1.2.2.2 pgoyette
1129 1.2.2.2 pgoyette result = isc_buffer_allocate(mctx, &buffer, 1024);
1130 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1131 1.2.2.2 pgoyette return (result);
1132 1.2.2.2 pgoyette
1133 1.2.2.2 pgoyette result = dns_master_stylecreate(&style, 0, 0, 0, 0, 0, 0, 1, mctx);
1134 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1135 1.2.2.2 pgoyette goto cleanup;
1136 1.2.2.2 pgoyette
1137 1.2.2.2 pgoyette result = dns_master_rdatasettotext(sdlznode->name, rdataset,
1138 1.2.2.2 pgoyette style, buffer);
1139 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1140 1.2.2.2 pgoyette goto cleanup;
1141 1.2.2.2 pgoyette
1142 1.2.2.2 pgoyette if (isc_buffer_usedlength(buffer) < 1) {
1143 1.2.2.2 pgoyette result = ISC_R_BADADDRESSFORM;
1144 1.2.2.2 pgoyette goto cleanup;
1145 1.2.2.2 pgoyette }
1146 1.2.2.2 pgoyette
1147 1.2.2.2 pgoyette rdatastr = isc_buffer_base(buffer);
1148 1.2.2.2 pgoyette if (rdatastr == NULL) {
1149 1.2.2.2 pgoyette result = ISC_R_NOMEMORY;
1150 1.2.2.2 pgoyette goto cleanup;
1151 1.2.2.2 pgoyette }
1152 1.2.2.2 pgoyette rdatastr[isc_buffer_usedlength(buffer) - 1] = 0;
1153 1.2.2.2 pgoyette
1154 1.2.2.2 pgoyette MAYBE_LOCK(sdlz->dlzimp);
1155 1.2.2.2 pgoyette result = mod_function(name, rdatastr, sdlz->dlzimp->driverarg,
1156 1.2.2.2 pgoyette sdlz->dbdata, version);
1157 1.2.2.2 pgoyette MAYBE_UNLOCK(sdlz->dlzimp);
1158 1.2.2.2 pgoyette
1159 1.2.2.2 pgoyette cleanup:
1160 1.2.2.2 pgoyette isc_buffer_free(&buffer);
1161 1.2.2.2 pgoyette if (style != NULL)
1162 1.2.2.2 pgoyette dns_master_styledestroy(&style, mctx);
1163 1.2.2.2 pgoyette
1164 1.2.2.2 pgoyette return (result);
1165 1.2.2.2 pgoyette }
1166 1.2.2.2 pgoyette
1167 1.2.2.2 pgoyette static isc_result_t
1168 1.2.2.2 pgoyette addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1169 1.2.2.2 pgoyette isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
1170 1.2.2.2 pgoyette dns_rdataset_t *addedrdataset)
1171 1.2.2.2 pgoyette {
1172 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1173 1.2.2.2 pgoyette isc_result_t result;
1174 1.2.2.2 pgoyette
1175 1.2.2.2 pgoyette UNUSED(now);
1176 1.2.2.2 pgoyette UNUSED(addedrdataset);
1177 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
1178 1.2.2.2 pgoyette
1179 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->addrdataset == NULL)
1180 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
1181 1.2.2.2 pgoyette
1182 1.2.2.2 pgoyette result = modrdataset(db, node, version, rdataset, options,
1183 1.2.2.2 pgoyette sdlz->dlzimp->methods->addrdataset);
1184 1.2.2.2 pgoyette return (result);
1185 1.2.2.2 pgoyette }
1186 1.2.2.2 pgoyette
1187 1.2.2.2 pgoyette
1188 1.2.2.2 pgoyette static isc_result_t
1189 1.2.2.2 pgoyette subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1190 1.2.2.2 pgoyette dns_rdataset_t *rdataset, unsigned int options,
1191 1.2.2.2 pgoyette dns_rdataset_t *newrdataset)
1192 1.2.2.2 pgoyette {
1193 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1194 1.2.2.2 pgoyette isc_result_t result;
1195 1.2.2.2 pgoyette
1196 1.2.2.2 pgoyette UNUSED(newrdataset);
1197 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
1198 1.2.2.2 pgoyette
1199 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->subtractrdataset == NULL) {
1200 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
1201 1.2.2.2 pgoyette }
1202 1.2.2.2 pgoyette
1203 1.2.2.2 pgoyette result = modrdataset(db, node, version, rdataset, options,
1204 1.2.2.2 pgoyette sdlz->dlzimp->methods->subtractrdataset);
1205 1.2.2.2 pgoyette return (result);
1206 1.2.2.2 pgoyette }
1207 1.2.2.2 pgoyette
1208 1.2.2.2 pgoyette static isc_result_t
1209 1.2.2.2 pgoyette deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1210 1.2.2.2 pgoyette dns_rdatatype_t type, dns_rdatatype_t covers)
1211 1.2.2.2 pgoyette {
1212 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1213 1.2.2.2 pgoyette char name[DNS_NAME_MAXTEXT + 1];
1214 1.2.2.2 pgoyette char b_type[DNS_RDATATYPE_FORMATSIZE];
1215 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode;
1216 1.2.2.2 pgoyette isc_result_t result;
1217 1.2.2.2 pgoyette
1218 1.2.2.2 pgoyette UNUSED(covers);
1219 1.2.2.2 pgoyette
1220 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
1221 1.2.2.2 pgoyette
1222 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->delrdataset == NULL)
1223 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
1224 1.2.2.2 pgoyette
1225 1.2.2.2 pgoyette sdlznode = (dns_sdlznode_t *)node;
1226 1.2.2.2 pgoyette dns_name_format(sdlznode->name, name, sizeof(name));
1227 1.2.2.2 pgoyette dns_rdatatype_format(type, b_type, sizeof(b_type));
1228 1.2.2.2 pgoyette
1229 1.2.2.2 pgoyette MAYBE_LOCK(sdlz->dlzimp);
1230 1.2.2.2 pgoyette result = sdlz->dlzimp->methods->delrdataset(name, b_type,
1231 1.2.2.2 pgoyette sdlz->dlzimp->driverarg,
1232 1.2.2.2 pgoyette sdlz->dbdata, version);
1233 1.2.2.2 pgoyette MAYBE_UNLOCK(sdlz->dlzimp);
1234 1.2.2.2 pgoyette
1235 1.2.2.2 pgoyette return (result);
1236 1.2.2.2 pgoyette }
1237 1.2.2.2 pgoyette
1238 1.2.2.2 pgoyette static isc_boolean_t
1239 1.2.2.2 pgoyette issecure(dns_db_t *db) {
1240 1.2.2.2 pgoyette UNUSED(db);
1241 1.2.2.2 pgoyette
1242 1.2.2.2 pgoyette return (ISC_FALSE);
1243 1.2.2.2 pgoyette }
1244 1.2.2.2 pgoyette
1245 1.2.2.2 pgoyette static unsigned int
1246 1.2.2.2 pgoyette nodecount(dns_db_t *db) {
1247 1.2.2.2 pgoyette UNUSED(db);
1248 1.2.2.2 pgoyette
1249 1.2.2.2 pgoyette return (0);
1250 1.2.2.2 pgoyette }
1251 1.2.2.2 pgoyette
1252 1.2.2.2 pgoyette static isc_boolean_t
1253 1.2.2.2 pgoyette ispersistent(dns_db_t *db) {
1254 1.2.2.2 pgoyette UNUSED(db);
1255 1.2.2.2 pgoyette return (ISC_TRUE);
1256 1.2.2.2 pgoyette }
1257 1.2.2.2 pgoyette
1258 1.2.2.2 pgoyette static void
1259 1.2.2.2 pgoyette overmem(dns_db_t *db, isc_boolean_t over) {
1260 1.2.2.2 pgoyette UNUSED(db);
1261 1.2.2.2 pgoyette UNUSED(over);
1262 1.2.2.2 pgoyette }
1263 1.2.2.2 pgoyette
1264 1.2.2.2 pgoyette static void
1265 1.2.2.2 pgoyette settask(dns_db_t *db, isc_task_t *task) {
1266 1.2.2.2 pgoyette UNUSED(db);
1267 1.2.2.2 pgoyette UNUSED(task);
1268 1.2.2.2 pgoyette }
1269 1.2.2.2 pgoyette
1270 1.2.2.2 pgoyette /*
1271 1.2.2.2 pgoyette * getoriginnode() is used by the update code to find the
1272 1.2.2.2 pgoyette * dns_rdatatype_dnskey record for a zone
1273 1.2.2.2 pgoyette */
1274 1.2.2.2 pgoyette static isc_result_t
1275 1.2.2.2 pgoyette getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
1276 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1277 1.2.2.2 pgoyette isc_result_t result;
1278 1.2.2.2 pgoyette
1279 1.2.2.2 pgoyette REQUIRE(VALID_SDLZDB(sdlz));
1280 1.2.2.2 pgoyette if (sdlz->dlzimp->methods->newversion == NULL)
1281 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
1282 1.2.2.2 pgoyette
1283 1.2.2.2 pgoyette result = getnodedata(db, &sdlz->common.origin, ISC_FALSE,
1284 1.2.2.2 pgoyette 0, NULL, NULL, nodep);
1285 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1286 1.2.2.2 pgoyette sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed: %s",
1287 1.2.2.2 pgoyette isc_result_totext(result));
1288 1.2.2.2 pgoyette return (result);
1289 1.2.2.2 pgoyette }
1290 1.2.2.2 pgoyette
1291 1.2.2.2 pgoyette static dns_dbmethods_t sdlzdb_methods = {
1292 1.2.2.2 pgoyette attach,
1293 1.2.2.2 pgoyette detach,
1294 1.2.2.2 pgoyette beginload,
1295 1.2.2.2 pgoyette endload,
1296 1.2.2.2 pgoyette NULL, /* serialize */
1297 1.2.2.2 pgoyette dump,
1298 1.2.2.2 pgoyette currentversion,
1299 1.2.2.2 pgoyette newversion,
1300 1.2.2.2 pgoyette attachversion,
1301 1.2.2.2 pgoyette closeversion,
1302 1.2.2.2 pgoyette findnode,
1303 1.2.2.2 pgoyette find,
1304 1.2.2.2 pgoyette findzonecut,
1305 1.2.2.2 pgoyette attachnode,
1306 1.2.2.2 pgoyette detachnode,
1307 1.2.2.2 pgoyette expirenode,
1308 1.2.2.2 pgoyette printnode,
1309 1.2.2.2 pgoyette createiterator,
1310 1.2.2.2 pgoyette findrdataset,
1311 1.2.2.2 pgoyette allrdatasets,
1312 1.2.2.2 pgoyette addrdataset,
1313 1.2.2.2 pgoyette subtractrdataset,
1314 1.2.2.2 pgoyette deleterdataset,
1315 1.2.2.2 pgoyette issecure,
1316 1.2.2.2 pgoyette nodecount,
1317 1.2.2.2 pgoyette ispersistent,
1318 1.2.2.2 pgoyette overmem,
1319 1.2.2.2 pgoyette settask,
1320 1.2.2.2 pgoyette getoriginnode,
1321 1.2.2.2 pgoyette NULL, /* transfernode */
1322 1.2.2.2 pgoyette NULL, /* getnsec3parameters */
1323 1.2.2.2 pgoyette NULL, /* findnsec3node */
1324 1.2.2.2 pgoyette NULL, /* setsigningtime */
1325 1.2.2.2 pgoyette NULL, /* getsigningtime */
1326 1.2.2.2 pgoyette NULL, /* resigned */
1327 1.2.2.2 pgoyette NULL, /* isdnssec */
1328 1.2.2.2 pgoyette NULL, /* getrrsetstats */
1329 1.2.2.2 pgoyette NULL, /* rpz_attach */
1330 1.2.2.2 pgoyette NULL, /* rpz_ready */
1331 1.2.2.2 pgoyette findnodeext,
1332 1.2.2.2 pgoyette findext,
1333 1.2.2.2 pgoyette NULL, /* setcachestats */
1334 1.2.2.2 pgoyette NULL, /* hashsize */
1335 1.2.2.2 pgoyette NULL, /* nodefullname */
1336 1.2.2.2 pgoyette NULL, /* getsize */
1337 1.2.2.2 pgoyette NULL, /* setservestalettl */
1338 1.2.2.2 pgoyette NULL, /* getservestalettl */
1339 1.2.2.2 pgoyette NULL /* setgluecachestats */
1340 1.2.2.2 pgoyette };
1341 1.2.2.2 pgoyette
1342 1.2.2.2 pgoyette /*
1343 1.2.2.2 pgoyette * Database Iterator Methods. These methods were "borrowed" from the SDB
1344 1.2.2.2 pgoyette * driver interface. See the SDB driver interface documentation for more info.
1345 1.2.2.2 pgoyette */
1346 1.2.2.2 pgoyette
1347 1.2.2.2 pgoyette static void
1348 1.2.2.2 pgoyette dbiterator_destroy(dns_dbiterator_t **iteratorp) {
1349 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp);
1350 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db;
1351 1.2.2.2 pgoyette
1352 1.2.2.2 pgoyette while (!ISC_LIST_EMPTY(sdlziter->nodelist)) {
1353 1.2.2.2 pgoyette dns_sdlznode_t *node;
1354 1.2.2.2 pgoyette node = ISC_LIST_HEAD(sdlziter->nodelist);
1355 1.2.2.2 pgoyette ISC_LIST_UNLINK(sdlziter->nodelist, node, link);
1356 1.2.2.2 pgoyette destroynode(node);
1357 1.2.2.2 pgoyette }
1358 1.2.2.2 pgoyette
1359 1.2.2.2 pgoyette dns_db_detach(&sdlziter->common.db);
1360 1.2.2.2 pgoyette isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t));
1361 1.2.2.2 pgoyette
1362 1.2.2.2 pgoyette *iteratorp = NULL;
1363 1.2.2.2 pgoyette }
1364 1.2.2.2 pgoyette
1365 1.2.2.2 pgoyette static isc_result_t
1366 1.2.2.2 pgoyette dbiterator_first(dns_dbiterator_t *iterator) {
1367 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1368 1.2.2.2 pgoyette
1369 1.2.2.2 pgoyette sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
1370 1.2.2.2 pgoyette if (sdlziter->current == NULL)
1371 1.2.2.2 pgoyette return (ISC_R_NOMORE);
1372 1.2.2.2 pgoyette else
1373 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1374 1.2.2.2 pgoyette }
1375 1.2.2.2 pgoyette
1376 1.2.2.2 pgoyette static isc_result_t
1377 1.2.2.2 pgoyette dbiterator_last(dns_dbiterator_t *iterator) {
1378 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1379 1.2.2.2 pgoyette
1380 1.2.2.2 pgoyette sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist);
1381 1.2.2.2 pgoyette if (sdlziter->current == NULL)
1382 1.2.2.2 pgoyette return (ISC_R_NOMORE);
1383 1.2.2.2 pgoyette else
1384 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1385 1.2.2.2 pgoyette }
1386 1.2.2.2 pgoyette
1387 1.2.2.2 pgoyette static isc_result_t
1388 1.2.2.2 pgoyette dbiterator_seek(dns_dbiterator_t *iterator, const dns_name_t *name) {
1389 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1390 1.2.2.2 pgoyette
1391 1.2.2.2 pgoyette sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
1392 1.2.2.2 pgoyette while (sdlziter->current != NULL) {
1393 1.2.2.2 pgoyette if (dns_name_equal(sdlziter->current->name, name))
1394 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1395 1.2.2.2 pgoyette sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
1396 1.2.2.2 pgoyette }
1397 1.2.2.2 pgoyette return (ISC_R_NOTFOUND);
1398 1.2.2.2 pgoyette }
1399 1.2.2.2 pgoyette
1400 1.2.2.2 pgoyette static isc_result_t
1401 1.2.2.2 pgoyette dbiterator_prev(dns_dbiterator_t *iterator) {
1402 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1403 1.2.2.2 pgoyette
1404 1.2.2.2 pgoyette sdlziter->current = ISC_LIST_PREV(sdlziter->current, link);
1405 1.2.2.2 pgoyette if (sdlziter->current == NULL)
1406 1.2.2.2 pgoyette return (ISC_R_NOMORE);
1407 1.2.2.2 pgoyette else
1408 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1409 1.2.2.2 pgoyette }
1410 1.2.2.2 pgoyette
1411 1.2.2.2 pgoyette static isc_result_t
1412 1.2.2.2 pgoyette dbiterator_next(dns_dbiterator_t *iterator) {
1413 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1414 1.2.2.2 pgoyette
1415 1.2.2.2 pgoyette sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
1416 1.2.2.2 pgoyette if (sdlziter->current == NULL)
1417 1.2.2.2 pgoyette return (ISC_R_NOMORE);
1418 1.2.2.2 pgoyette else
1419 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1420 1.2.2.2 pgoyette }
1421 1.2.2.2 pgoyette
1422 1.2.2.2 pgoyette static isc_result_t
1423 1.2.2.2 pgoyette dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
1424 1.2.2.2 pgoyette dns_name_t *name)
1425 1.2.2.2 pgoyette {
1426 1.2.2.2 pgoyette sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1427 1.2.2.2 pgoyette
1428 1.2.2.2 pgoyette attachnode(iterator->db, sdlziter->current, nodep);
1429 1.2.2.2 pgoyette if (name != NULL)
1430 1.2.2.2 pgoyette return (dns_name_copy(sdlziter->current->name, name, NULL));
1431 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1432 1.2.2.2 pgoyette }
1433 1.2.2.2 pgoyette
1434 1.2.2.2 pgoyette static isc_result_t
1435 1.2.2.2 pgoyette dbiterator_pause(dns_dbiterator_t *iterator) {
1436 1.2.2.2 pgoyette UNUSED(iterator);
1437 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1438 1.2.2.2 pgoyette }
1439 1.2.2.2 pgoyette
1440 1.2.2.2 pgoyette static isc_result_t
1441 1.2.2.2 pgoyette dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
1442 1.2.2.2 pgoyette UNUSED(iterator);
1443 1.2.2.2 pgoyette return (dns_name_copy(dns_rootname, name, NULL));
1444 1.2.2.2 pgoyette }
1445 1.2.2.2 pgoyette
1446 1.2.2.2 pgoyette /*
1447 1.2.2.2 pgoyette * Rdataset Methods. These methods were "borrowed" from the SDB driver
1448 1.2.2.2 pgoyette * interface. See the SDB driver interface documentation for more info.
1449 1.2.2.2 pgoyette */
1450 1.2.2.2 pgoyette
1451 1.2.2.2 pgoyette static void
1452 1.2.2.2 pgoyette disassociate(dns_rdataset_t *rdataset) {
1453 1.2.2.2 pgoyette dns_dbnode_t *node = rdataset->private5;
1454 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
1455 1.2.2.2 pgoyette dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
1456 1.2.2.2 pgoyette
1457 1.2.2.2 pgoyette detachnode(db, &node);
1458 1.2.2.2 pgoyette isc__rdatalist_disassociate(rdataset);
1459 1.2.2.2 pgoyette }
1460 1.2.2.2 pgoyette
1461 1.2.2.2 pgoyette static void
1462 1.2.2.2 pgoyette rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
1463 1.2.2.2 pgoyette dns_dbnode_t *node = source->private5;
1464 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
1465 1.2.2.2 pgoyette dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
1466 1.2.2.2 pgoyette dns_dbnode_t *tempdb = NULL;
1467 1.2.2.2 pgoyette
1468 1.2.2.2 pgoyette isc__rdatalist_clone(source, target);
1469 1.2.2.2 pgoyette attachnode(db, node, &tempdb);
1470 1.2.2.2 pgoyette source->private5 = tempdb;
1471 1.2.2.2 pgoyette }
1472 1.2.2.2 pgoyette
1473 1.2.2.2 pgoyette static dns_rdatasetmethods_t rdataset_methods = {
1474 1.2.2.2 pgoyette disassociate,
1475 1.2.2.2 pgoyette isc__rdatalist_first,
1476 1.2.2.2 pgoyette isc__rdatalist_next,
1477 1.2.2.2 pgoyette isc__rdatalist_current,
1478 1.2.2.2 pgoyette rdataset_clone,
1479 1.2.2.2 pgoyette isc__rdatalist_count,
1480 1.2.2.2 pgoyette isc__rdatalist_addnoqname,
1481 1.2.2.2 pgoyette isc__rdatalist_getnoqname,
1482 1.2.2.2 pgoyette NULL, /* addclosest */
1483 1.2.2.2 pgoyette NULL, /* getclosest */
1484 1.2.2.2 pgoyette NULL, /* settrust */
1485 1.2.2.2 pgoyette NULL, /* expire */
1486 1.2.2.2 pgoyette NULL, /* clearprefetch */
1487 1.2.2.2 pgoyette NULL, /* setownercase */
1488 1.2.2.2 pgoyette NULL, /* getownercase */
1489 1.2.2.2 pgoyette NULL /* addglue */
1490 1.2.2.2 pgoyette };
1491 1.2.2.2 pgoyette
1492 1.2.2.2 pgoyette static void
1493 1.2.2.2 pgoyette list_tordataset(dns_rdatalist_t *rdatalist,
1494 1.2.2.2 pgoyette dns_db_t *db, dns_dbnode_t *node,
1495 1.2.2.2 pgoyette dns_rdataset_t *rdataset)
1496 1.2.2.2 pgoyette {
1497 1.2.2.2 pgoyette /*
1498 1.2.2.2 pgoyette * The sdlz rdataset is an rdatalist with some additions.
1499 1.2.2.2 pgoyette * - private1 & private2 are used by the rdatalist.
1500 1.2.2.2 pgoyette * - private3 & private 4 are unused.
1501 1.2.2.2 pgoyette * - private5 is the node.
1502 1.2.2.2 pgoyette */
1503 1.2.2.2 pgoyette
1504 1.2.2.2 pgoyette /* This should never fail. */
1505 1.2.2.2 pgoyette RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
1506 1.2.2.2 pgoyette ISC_R_SUCCESS);
1507 1.2.2.2 pgoyette
1508 1.2.2.2 pgoyette rdataset->methods = &rdataset_methods;
1509 1.2.2.2 pgoyette dns_db_attachnode(db, node, &rdataset->private5);
1510 1.2.2.2 pgoyette }
1511 1.2.2.2 pgoyette
1512 1.2.2.2 pgoyette /*
1513 1.2.2.2 pgoyette * SDLZ core methods. This is the core of the new DLZ functionality.
1514 1.2.2.2 pgoyette */
1515 1.2.2.2 pgoyette
1516 1.2.2.2 pgoyette /*%
1517 1.2.2.2 pgoyette * Build a 'bind' database driver structure to be returned by
1518 1.2.2.2 pgoyette * either the find zone or the allow zone transfer method.
1519 1.2.2.2 pgoyette * This method is only available in this source file, it is
1520 1.2.2.2 pgoyette * not made available anywhere else.
1521 1.2.2.2 pgoyette */
1522 1.2.2.2 pgoyette
1523 1.2.2.2 pgoyette static isc_result_t
1524 1.2.2.2 pgoyette dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata,
1525 1.2.2.2 pgoyette const dns_name_t *name, dns_rdataclass_t rdclass,
1526 1.2.2.2 pgoyette dns_db_t **dbp)
1527 1.2.2.2 pgoyette {
1528 1.2.2.2 pgoyette isc_result_t result;
1529 1.2.2.2 pgoyette dns_sdlz_db_t *sdlzdb;
1530 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1531 1.2.2.2 pgoyette
1532 1.2.2.2 pgoyette /* check that things are as we expect */
1533 1.2.2.2 pgoyette REQUIRE(dbp != NULL && *dbp == NULL);
1534 1.2.2.2 pgoyette REQUIRE(name != NULL);
1535 1.2.2.2 pgoyette
1536 1.2.2.2 pgoyette imp = (dns_sdlzimplementation_t *) driverarg;
1537 1.2.2.2 pgoyette
1538 1.2.2.2 pgoyette /* allocate and zero memory for driver structure */
1539 1.2.2.2 pgoyette sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t));
1540 1.2.2.2 pgoyette if (sdlzdb == NULL)
1541 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
1542 1.2.2.2 pgoyette memset(sdlzdb, 0, sizeof(dns_sdlz_db_t));
1543 1.2.2.2 pgoyette
1544 1.2.2.2 pgoyette /* initialize and set origin */
1545 1.2.2.2 pgoyette dns_name_init(&sdlzdb->common.origin, NULL);
1546 1.2.2.2 pgoyette result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin);
1547 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1548 1.2.2.2 pgoyette goto mem_cleanup;
1549 1.2.2.2 pgoyette
1550 1.2.2.2 pgoyette /* initialize the reference count mutex */
1551 1.2.2.2 pgoyette result = isc_mutex_init(&sdlzdb->refcnt_lock);
1552 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1553 1.2.2.2 pgoyette goto name_cleanup;
1554 1.2.2.2 pgoyette
1555 1.2.2.2 pgoyette /* set the rest of the database structure attributes */
1556 1.2.2.2 pgoyette sdlzdb->dlzimp = imp;
1557 1.2.2.2 pgoyette sdlzdb->common.methods = &sdlzdb_methods;
1558 1.2.2.2 pgoyette sdlzdb->common.attributes = 0;
1559 1.2.2.2 pgoyette sdlzdb->common.rdclass = rdclass;
1560 1.2.2.2 pgoyette sdlzdb->common.mctx = NULL;
1561 1.2.2.2 pgoyette sdlzdb->dbdata = dbdata;
1562 1.2.2.2 pgoyette sdlzdb->references = 1;
1563 1.2.2.2 pgoyette
1564 1.2.2.2 pgoyette /* attach to the memory context */
1565 1.2.2.2 pgoyette isc_mem_attach(mctx, &sdlzdb->common.mctx);
1566 1.2.2.2 pgoyette
1567 1.2.2.2 pgoyette /* mark structure as valid */
1568 1.2.2.2 pgoyette sdlzdb->common.magic = DNS_DB_MAGIC;
1569 1.2.2.2 pgoyette sdlzdb->common.impmagic = SDLZDB_MAGIC;
1570 1.2.2.2 pgoyette *dbp = (dns_db_t *) sdlzdb;
1571 1.2.2.2 pgoyette
1572 1.2.2.2 pgoyette return (result);
1573 1.2.2.2 pgoyette
1574 1.2.2.2 pgoyette /*
1575 1.2.2.2 pgoyette * reference count mutex could not be initialized, clean up
1576 1.2.2.2 pgoyette * name memory
1577 1.2.2.2 pgoyette */
1578 1.2.2.2 pgoyette name_cleanup:
1579 1.2.2.2 pgoyette dns_name_free(&sdlzdb->common.origin, mctx);
1580 1.2.2.2 pgoyette mem_cleanup:
1581 1.2.2.2 pgoyette isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t));
1582 1.2.2.2 pgoyette return (result);
1583 1.2.2.2 pgoyette }
1584 1.2.2.2 pgoyette
1585 1.2.2.2 pgoyette static isc_result_t
1586 1.2.2.2 pgoyette dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx,
1587 1.2.2.2 pgoyette dns_rdataclass_t rdclass, const dns_name_t *name,
1588 1.2.2.2 pgoyette const isc_sockaddr_t *clientaddr, dns_db_t **dbp)
1589 1.2.2.2 pgoyette {
1590 1.2.2.2 pgoyette isc_buffer_t b;
1591 1.2.2.2 pgoyette isc_buffer_t b2;
1592 1.2.2.2 pgoyette char namestr[DNS_NAME_MAXTEXT + 1];
1593 1.2.2.2 pgoyette char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")
1594 1.2.2.2 pgoyette + 1];
1595 1.2.2.2 pgoyette isc_netaddr_t netaddr;
1596 1.2.2.2 pgoyette isc_result_t result;
1597 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1598 1.2.2.2 pgoyette
1599 1.2.2.2 pgoyette /*
1600 1.2.2.2 pgoyette * Perform checks to make sure data is as we expect it to be.
1601 1.2.2.2 pgoyette */
1602 1.2.2.2 pgoyette REQUIRE(driverarg != NULL);
1603 1.2.2.2 pgoyette REQUIRE(name != NULL);
1604 1.2.2.2 pgoyette REQUIRE(clientaddr != NULL);
1605 1.2.2.2 pgoyette REQUIRE(dbp != NULL && *dbp == NULL);
1606 1.2.2.2 pgoyette
1607 1.2.2.2 pgoyette imp = (dns_sdlzimplementation_t *) driverarg;
1608 1.2.2.2 pgoyette
1609 1.2.2.2 pgoyette /* Convert DNS name to ascii text */
1610 1.2.2.2 pgoyette isc_buffer_init(&b, namestr, sizeof(namestr));
1611 1.2.2.2 pgoyette result = dns_name_totext(name, ISC_TRUE, &b);
1612 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1613 1.2.2.2 pgoyette return (result);
1614 1.2.2.2 pgoyette isc_buffer_putuint8(&b, 0);
1615 1.2.2.2 pgoyette
1616 1.2.2.2 pgoyette /* convert client address to ascii text */
1617 1.2.2.2 pgoyette isc_buffer_init(&b2, clientstr, sizeof(clientstr));
1618 1.2.2.2 pgoyette isc_netaddr_fromsockaddr(&netaddr, clientaddr);
1619 1.2.2.2 pgoyette result = isc_netaddr_totext(&netaddr, &b2);
1620 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1621 1.2.2.2 pgoyette return (result);
1622 1.2.2.2 pgoyette isc_buffer_putuint8(&b2, 0);
1623 1.2.2.2 pgoyette
1624 1.2.2.2 pgoyette /* make sure strings are always lowercase */
1625 1.2.2.2 pgoyette dns_sdlz_tolower(namestr);
1626 1.2.2.2 pgoyette dns_sdlz_tolower(clientstr);
1627 1.2.2.2 pgoyette
1628 1.2.2.2 pgoyette /* Call SDLZ driver's find zone method */
1629 1.2.2.2 pgoyette if (imp->methods->allowzonexfr != NULL) {
1630 1.2.2.2 pgoyette MAYBE_LOCK(imp);
1631 1.2.2.2 pgoyette result = imp->methods->allowzonexfr(imp->driverarg, dbdata,
1632 1.2.2.2 pgoyette namestr, clientstr);
1633 1.2.2.2 pgoyette MAYBE_UNLOCK(imp);
1634 1.2.2.2 pgoyette /*
1635 1.2.2.2 pgoyette * if zone is supported and transfers allowed build a 'bind'
1636 1.2.2.2 pgoyette * database driver
1637 1.2.2.2 pgoyette */
1638 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS)
1639 1.2.2.2 pgoyette result = dns_sdlzcreateDBP(mctx, driverarg, dbdata,
1640 1.2.2.2 pgoyette name, rdclass, dbp);
1641 1.2.2.2 pgoyette return (result);
1642 1.2.2.2 pgoyette }
1643 1.2.2.2 pgoyette
1644 1.2.2.2 pgoyette return (ISC_R_NOTIMPLEMENTED);
1645 1.2.2.2 pgoyette }
1646 1.2.2.2 pgoyette
1647 1.2.2.2 pgoyette static isc_result_t
1648 1.2.2.2 pgoyette dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
1649 1.2.2.2 pgoyette char *argv[], void *driverarg, void **dbdata)
1650 1.2.2.2 pgoyette {
1651 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1652 1.2.2.2 pgoyette isc_result_t result = ISC_R_NOTFOUND;
1653 1.2.2.2 pgoyette
1654 1.2.2.2 pgoyette /* Write debugging message to log */
1655 1.2.2.2 pgoyette sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver.");
1656 1.2.2.2 pgoyette
1657 1.2.2.2 pgoyette /*
1658 1.2.2.2 pgoyette * Performs checks to make sure data is as we expect it to be.
1659 1.2.2.2 pgoyette */
1660 1.2.2.2 pgoyette REQUIRE(driverarg != NULL);
1661 1.2.2.2 pgoyette REQUIRE(dlzname != NULL);
1662 1.2.2.2 pgoyette REQUIRE(dbdata != NULL);
1663 1.2.2.2 pgoyette UNUSED(mctx);
1664 1.2.2.2 pgoyette
1665 1.2.2.2 pgoyette imp = driverarg;
1666 1.2.2.2 pgoyette
1667 1.2.2.2 pgoyette /* If the create method exists, call it. */
1668 1.2.2.2 pgoyette if (imp->methods->create != NULL) {
1669 1.2.2.2 pgoyette MAYBE_LOCK(imp);
1670 1.2.2.2 pgoyette result = imp->methods->create(dlzname, argc, argv,
1671 1.2.2.2 pgoyette imp->driverarg, dbdata);
1672 1.2.2.2 pgoyette MAYBE_UNLOCK(imp);
1673 1.2.2.2 pgoyette }
1674 1.2.2.2 pgoyette
1675 1.2.2.2 pgoyette /* Write debugging message to log */
1676 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS) {
1677 1.2.2.2 pgoyette sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully.");
1678 1.2.2.2 pgoyette } else {
1679 1.2.2.2 pgoyette sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load.");
1680 1.2.2.2 pgoyette }
1681 1.2.2.2 pgoyette
1682 1.2.2.2 pgoyette return (result);
1683 1.2.2.2 pgoyette }
1684 1.2.2.2 pgoyette
1685 1.2.2.2 pgoyette static void
1686 1.2.2.2 pgoyette dns_sdlzdestroy(void *driverdata, void **dbdata) {
1687 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1688 1.2.2.2 pgoyette
1689 1.2.2.2 pgoyette /* Write debugging message to log */
1690 1.2.2.2 pgoyette sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver.");
1691 1.2.2.2 pgoyette
1692 1.2.2.2 pgoyette imp = driverdata;
1693 1.2.2.2 pgoyette
1694 1.2.2.2 pgoyette /* If the destroy method exists, call it. */
1695 1.2.2.2 pgoyette if (imp->methods->destroy != NULL) {
1696 1.2.2.2 pgoyette MAYBE_LOCK(imp);
1697 1.2.2.2 pgoyette imp->methods->destroy(imp->driverarg, dbdata);
1698 1.2.2.2 pgoyette MAYBE_UNLOCK(imp);
1699 1.2.2.2 pgoyette }
1700 1.2.2.2 pgoyette }
1701 1.2.2.2 pgoyette
1702 1.2.2.2 pgoyette static isc_result_t
1703 1.2.2.2 pgoyette dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx,
1704 1.2.2.2 pgoyette dns_rdataclass_t rdclass, const dns_name_t *name,
1705 1.2.2.2 pgoyette dns_clientinfomethods_t *methods,
1706 1.2.2.2 pgoyette dns_clientinfo_t *clientinfo,
1707 1.2.2.2 pgoyette dns_db_t **dbp)
1708 1.2.2.2 pgoyette {
1709 1.2.2.2 pgoyette isc_buffer_t b;
1710 1.2.2.2 pgoyette char namestr[DNS_NAME_MAXTEXT + 1];
1711 1.2.2.2 pgoyette isc_result_t result;
1712 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1713 1.2.2.2 pgoyette
1714 1.2.2.2 pgoyette /*
1715 1.2.2.2 pgoyette * Perform checks to make sure data is as we expect it to be.
1716 1.2.2.2 pgoyette */
1717 1.2.2.2 pgoyette REQUIRE(driverarg != NULL);
1718 1.2.2.2 pgoyette REQUIRE(name != NULL);
1719 1.2.2.2 pgoyette REQUIRE(dbp != NULL && *dbp == NULL);
1720 1.2.2.2 pgoyette
1721 1.2.2.2 pgoyette imp = (dns_sdlzimplementation_t *) driverarg;
1722 1.2.2.2 pgoyette
1723 1.2.2.2 pgoyette /* Convert DNS name to ascii text */
1724 1.2.2.2 pgoyette isc_buffer_init(&b, namestr, sizeof(namestr));
1725 1.2.2.2 pgoyette result = dns_name_totext(name, ISC_TRUE, &b);
1726 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1727 1.2.2.2 pgoyette return (result);
1728 1.2.2.2 pgoyette isc_buffer_putuint8(&b, 0);
1729 1.2.2.2 pgoyette
1730 1.2.2.2 pgoyette /* make sure strings are always lowercase */
1731 1.2.2.2 pgoyette dns_sdlz_tolower(namestr);
1732 1.2.2.2 pgoyette
1733 1.2.2.2 pgoyette /* Call SDLZ driver's find zone method */
1734 1.2.2.2 pgoyette MAYBE_LOCK(imp);
1735 1.2.2.2 pgoyette result = imp->methods->findzone(imp->driverarg, dbdata, namestr,
1736 1.2.2.2 pgoyette methods, clientinfo);
1737 1.2.2.2 pgoyette MAYBE_UNLOCK(imp);
1738 1.2.2.2 pgoyette
1739 1.2.2.2 pgoyette /*
1740 1.2.2.2 pgoyette * if zone is supported build a 'bind' database driver
1741 1.2.2.2 pgoyette * structure to return
1742 1.2.2.2 pgoyette */
1743 1.2.2.2 pgoyette if (result == ISC_R_SUCCESS)
1744 1.2.2.2 pgoyette result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name,
1745 1.2.2.2 pgoyette rdclass, dbp);
1746 1.2.2.2 pgoyette
1747 1.2.2.2 pgoyette return (result);
1748 1.2.2.2 pgoyette }
1749 1.2.2.2 pgoyette
1750 1.2.2.2 pgoyette
1751 1.2.2.2 pgoyette static isc_result_t
1752 1.2.2.2 pgoyette dns_sdlzconfigure(void *driverarg, void *dbdata,
1753 1.2.2.2 pgoyette dns_view_t *view, dns_dlzdb_t *dlzdb)
1754 1.2.2.2 pgoyette {
1755 1.2.2.2 pgoyette isc_result_t result;
1756 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1757 1.2.2.2 pgoyette
1758 1.2.2.2 pgoyette REQUIRE(driverarg != NULL);
1759 1.2.2.2 pgoyette
1760 1.2.2.2 pgoyette imp = (dns_sdlzimplementation_t *) driverarg;
1761 1.2.2.2 pgoyette
1762 1.2.2.2 pgoyette /* Call SDLZ driver's configure method */
1763 1.2.2.2 pgoyette if (imp->methods->configure != NULL) {
1764 1.2.2.2 pgoyette MAYBE_LOCK(imp);
1765 1.2.2.2 pgoyette result = imp->methods->configure(view, dlzdb,
1766 1.2.2.2 pgoyette imp->driverarg, dbdata);
1767 1.2.2.2 pgoyette MAYBE_UNLOCK(imp);
1768 1.2.2.2 pgoyette } else {
1769 1.2.2.2 pgoyette result = ISC_R_SUCCESS;
1770 1.2.2.2 pgoyette }
1771 1.2.2.2 pgoyette
1772 1.2.2.2 pgoyette return (result);
1773 1.2.2.2 pgoyette }
1774 1.2.2.2 pgoyette
1775 1.2.2.2 pgoyette static isc_boolean_t
1776 1.2.2.2 pgoyette dns_sdlzssumatch(const dns_name_t *signer, const dns_name_t *name,
1777 1.2.2.2 pgoyette const isc_netaddr_t *tcpaddr, dns_rdatatype_t type,
1778 1.2.2.2 pgoyette const dst_key_t *key, void *driverarg, void *dbdata)
1779 1.2.2.2 pgoyette {
1780 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
1781 1.2.2.2 pgoyette char b_signer[DNS_NAME_FORMATSIZE];
1782 1.2.2.2 pgoyette char b_name[DNS_NAME_FORMATSIZE];
1783 1.2.2.2 pgoyette char b_addr[ISC_NETADDR_FORMATSIZE];
1784 1.2.2.2 pgoyette char b_type[DNS_RDATATYPE_FORMATSIZE];
1785 1.2.2.2 pgoyette char b_key[DST_KEY_FORMATSIZE];
1786 1.2.2.2 pgoyette isc_buffer_t *tkey_token = NULL;
1787 1.2.2.2 pgoyette isc_region_t token_region = { NULL, 0 };
1788 1.2.2.2 pgoyette isc_uint32_t token_len = 0;
1789 1.2.2.2 pgoyette isc_boolean_t ret;
1790 1.2.2.2 pgoyette
1791 1.2.2.2 pgoyette REQUIRE(driverarg != NULL);
1792 1.2.2.2 pgoyette
1793 1.2.2.2 pgoyette imp = (dns_sdlzimplementation_t *) driverarg;
1794 1.2.2.2 pgoyette if (imp->methods->ssumatch == NULL)
1795 1.2.2.2 pgoyette return (ISC_FALSE);
1796 1.2.2.2 pgoyette
1797 1.2.2.2 pgoyette /*
1798 1.2.2.2 pgoyette * Format the request elements. sdlz operates on strings, not
1799 1.2.2.2 pgoyette * structures
1800 1.2.2.2 pgoyette */
1801 1.2.2.2 pgoyette if (signer != NULL)
1802 1.2.2.2 pgoyette dns_name_format(signer, b_signer, sizeof(b_signer));
1803 1.2.2.2 pgoyette else
1804 1.2.2.2 pgoyette b_signer[0] = 0;
1805 1.2.2.2 pgoyette
1806 1.2.2.2 pgoyette dns_name_format(name, b_name, sizeof(b_name));
1807 1.2.2.2 pgoyette
1808 1.2.2.2 pgoyette if (tcpaddr != NULL)
1809 1.2.2.2 pgoyette isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr));
1810 1.2.2.2 pgoyette else
1811 1.2.2.2 pgoyette b_addr[0] = 0;
1812 1.2.2.2 pgoyette
1813 1.2.2.2 pgoyette dns_rdatatype_format(type, b_type, sizeof(b_type));
1814 1.2.2.2 pgoyette
1815 1.2.2.2 pgoyette if (key != NULL) {
1816 1.2.2.2 pgoyette dst_key_format(key, b_key, sizeof(b_key));
1817 1.2.2.2 pgoyette tkey_token = dst_key_tkeytoken(key);
1818 1.2.2.2 pgoyette } else
1819 1.2.2.2 pgoyette b_key[0] = 0;
1820 1.2.2.2 pgoyette
1821 1.2.2.2 pgoyette if (tkey_token != NULL) {
1822 1.2.2.2 pgoyette isc_buffer_region(tkey_token, &token_region);
1823 1.2.2.2 pgoyette token_len = token_region.length;
1824 1.2.2.2 pgoyette }
1825 1.2.2.2 pgoyette
1826 1.2.2.2 pgoyette MAYBE_LOCK(imp);
1827 1.2.2.2 pgoyette ret = imp->methods->ssumatch(b_signer, b_name, b_addr, b_type, b_key,
1828 1.2.2.2 pgoyette token_len,
1829 1.2.2.2 pgoyette token_len != 0 ? token_region.base : NULL,
1830 1.2.2.2 pgoyette imp->driverarg, dbdata);
1831 1.2.2.2 pgoyette MAYBE_UNLOCK(imp);
1832 1.2.2.2 pgoyette return (ret);
1833 1.2.2.2 pgoyette }
1834 1.2.2.2 pgoyette
1835 1.2.2.2 pgoyette static dns_dlzmethods_t sdlzmethods = {
1836 1.2.2.2 pgoyette dns_sdlzcreate,
1837 1.2.2.2 pgoyette dns_sdlzdestroy,
1838 1.2.2.2 pgoyette dns_sdlzfindzone,
1839 1.2.2.2 pgoyette dns_sdlzallowzonexfr,
1840 1.2.2.2 pgoyette dns_sdlzconfigure,
1841 1.2.2.2 pgoyette dns_sdlzssumatch
1842 1.2.2.2 pgoyette };
1843 1.2.2.2 pgoyette
1844 1.2.2.2 pgoyette /*
1845 1.2.2.2 pgoyette * Public functions.
1846 1.2.2.2 pgoyette */
1847 1.2.2.2 pgoyette
1848 1.2.2.2 pgoyette isc_result_t
1849 1.2.2.2 pgoyette dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
1850 1.2.2.2 pgoyette const char *data)
1851 1.2.2.2 pgoyette {
1852 1.2.2.2 pgoyette dns_rdatalist_t *rdatalist;
1853 1.2.2.2 pgoyette dns_rdata_t *rdata;
1854 1.2.2.2 pgoyette dns_rdatatype_t typeval;
1855 1.2.2.2 pgoyette isc_consttextregion_t r;
1856 1.2.2.2 pgoyette isc_buffer_t b;
1857 1.2.2.2 pgoyette isc_buffer_t *rdatabuf = NULL;
1858 1.2.2.2 pgoyette isc_lex_t *lex;
1859 1.2.2.2 pgoyette isc_result_t result;
1860 1.2.2.2 pgoyette unsigned int size;
1861 1.2.2.2 pgoyette isc_mem_t *mctx;
1862 1.2.2.2 pgoyette const dns_name_t *origin;
1863 1.2.2.2 pgoyette
1864 1.2.2.2 pgoyette REQUIRE(VALID_SDLZLOOKUP(lookup));
1865 1.2.2.2 pgoyette REQUIRE(type != NULL);
1866 1.2.2.2 pgoyette REQUIRE(data != NULL);
1867 1.2.2.2 pgoyette
1868 1.2.2.2 pgoyette mctx = lookup->sdlz->common.mctx;
1869 1.2.2.2 pgoyette
1870 1.2.2.2 pgoyette r.base = type;
1871 1.2.2.2 pgoyette r.length = strlen(type);
1872 1.2.2.2 pgoyette result = dns_rdatatype_fromtext(&typeval, (void *) &r);
1873 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1874 1.2.2.2 pgoyette return (result);
1875 1.2.2.2 pgoyette
1876 1.2.2.2 pgoyette rdatalist = ISC_LIST_HEAD(lookup->lists);
1877 1.2.2.2 pgoyette while (rdatalist != NULL) {
1878 1.2.2.2 pgoyette if (rdatalist->type == typeval)
1879 1.2.2.2 pgoyette break;
1880 1.2.2.2 pgoyette rdatalist = ISC_LIST_NEXT(rdatalist, link);
1881 1.2.2.2 pgoyette }
1882 1.2.2.2 pgoyette
1883 1.2.2.2 pgoyette if (rdatalist == NULL) {
1884 1.2.2.2 pgoyette rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
1885 1.2.2.2 pgoyette if (rdatalist == NULL)
1886 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
1887 1.2.2.2 pgoyette dns_rdatalist_init(rdatalist);
1888 1.2.2.2 pgoyette rdatalist->rdclass = lookup->sdlz->common.rdclass;
1889 1.2.2.2 pgoyette rdatalist->type = typeval;
1890 1.2.2.2 pgoyette rdatalist->ttl = ttl;
1891 1.2.2.2 pgoyette ISC_LIST_APPEND(lookup->lists, rdatalist, link);
1892 1.2.2.2 pgoyette } else
1893 1.2.2.2 pgoyette if (rdatalist->ttl > ttl) {
1894 1.2.2.2 pgoyette /*
1895 1.2.2.2 pgoyette * BIND9 doesn't enforce all RRs in an RRset
1896 1.2.2.2 pgoyette * having the same TTL, as per RFC 2136,
1897 1.2.2.2 pgoyette * section 7.12. If a DLZ backend has
1898 1.2.2.2 pgoyette * different TTLs, then the best
1899 1.2.2.2 pgoyette * we can do is return the lowest.
1900 1.2.2.2 pgoyette */
1901 1.2.2.2 pgoyette rdatalist->ttl = ttl;
1902 1.2.2.2 pgoyette }
1903 1.2.2.2 pgoyette
1904 1.2.2.2 pgoyette rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
1905 1.2.2.2 pgoyette if (rdata == NULL)
1906 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
1907 1.2.2.2 pgoyette dns_rdata_init(rdata);
1908 1.2.2.2 pgoyette
1909 1.2.2.2 pgoyette if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
1910 1.2.2.2 pgoyette origin = &lookup->sdlz->common.origin;
1911 1.2.2.2 pgoyette else
1912 1.2.2.2 pgoyette origin = dns_rootname;
1913 1.2.2.2 pgoyette
1914 1.2.2.2 pgoyette lex = NULL;
1915 1.2.2.2 pgoyette result = isc_lex_create(mctx, 64, &lex);
1916 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1917 1.2.2.2 pgoyette goto failure;
1918 1.2.2.2 pgoyette
1919 1.2.2.2 pgoyette size = initial_size(data);
1920 1.2.2.2 pgoyette do {
1921 1.2.2.2 pgoyette isc_buffer_constinit(&b, data, strlen(data));
1922 1.2.2.2 pgoyette isc_buffer_add(&b, strlen(data));
1923 1.2.2.2 pgoyette
1924 1.2.2.2 pgoyette result = isc_lex_openbuffer(lex, &b);
1925 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1926 1.2.2.2 pgoyette goto failure;
1927 1.2.2.2 pgoyette
1928 1.2.2.2 pgoyette rdatabuf = NULL;
1929 1.2.2.2 pgoyette result = isc_buffer_allocate(mctx, &rdatabuf, size);
1930 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1931 1.2.2.2 pgoyette goto failure;
1932 1.2.2.2 pgoyette
1933 1.2.2.2 pgoyette result = dns_rdata_fromtext(rdata, rdatalist->rdclass,
1934 1.2.2.2 pgoyette rdatalist->type, lex,
1935 1.2.2.2 pgoyette origin, ISC_FALSE,
1936 1.2.2.2 pgoyette mctx, rdatabuf,
1937 1.2.2.2 pgoyette &lookup->callbacks);
1938 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1939 1.2.2.2 pgoyette isc_buffer_free(&rdatabuf);
1940 1.2.2.2 pgoyette if (size >= 65535)
1941 1.2.2.2 pgoyette break;
1942 1.2.2.2 pgoyette size *= 2;
1943 1.2.2.2 pgoyette if (size >= 65535)
1944 1.2.2.2 pgoyette size = 65535;
1945 1.2.2.2 pgoyette } while (result == ISC_R_NOSPACE);
1946 1.2.2.2 pgoyette
1947 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1948 1.2.2.2 pgoyette goto failure;
1949 1.2.2.2 pgoyette
1950 1.2.2.2 pgoyette ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1951 1.2.2.2 pgoyette ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
1952 1.2.2.2 pgoyette
1953 1.2.2.2 pgoyette if (lex != NULL)
1954 1.2.2.2 pgoyette isc_lex_destroy(&lex);
1955 1.2.2.2 pgoyette
1956 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
1957 1.2.2.2 pgoyette
1958 1.2.2.2 pgoyette failure:
1959 1.2.2.2 pgoyette if (rdatabuf != NULL)
1960 1.2.2.2 pgoyette isc_buffer_free(&rdatabuf);
1961 1.2.2.2 pgoyette if (lex != NULL)
1962 1.2.2.2 pgoyette isc_lex_destroy(&lex);
1963 1.2.2.2 pgoyette isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
1964 1.2.2.2 pgoyette
1965 1.2.2.2 pgoyette return (result);
1966 1.2.2.2 pgoyette }
1967 1.2.2.2 pgoyette
1968 1.2.2.2 pgoyette isc_result_t
1969 1.2.2.2 pgoyette dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
1970 1.2.2.2 pgoyette const char *type, dns_ttl_t ttl, const char *data)
1971 1.2.2.2 pgoyette {
1972 1.2.2.2 pgoyette dns_name_t *newname;
1973 1.2.2.2 pgoyette const dns_name_t *origin;
1974 1.2.2.2 pgoyette dns_fixedname_t fnewname;
1975 1.2.2.2 pgoyette dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db;
1976 1.2.2.2 pgoyette dns_sdlznode_t *sdlznode;
1977 1.2.2.2 pgoyette isc_mem_t *mctx = sdlz->common.mctx;
1978 1.2.2.2 pgoyette isc_buffer_t b;
1979 1.2.2.2 pgoyette isc_result_t result;
1980 1.2.2.2 pgoyette
1981 1.2.2.2 pgoyette newname = dns_fixedname_initname(&fnewname);
1982 1.2.2.2 pgoyette
1983 1.2.2.2 pgoyette if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
1984 1.2.2.2 pgoyette origin = &sdlz->common.origin;
1985 1.2.2.2 pgoyette else
1986 1.2.2.2 pgoyette origin = dns_rootname;
1987 1.2.2.2 pgoyette isc_buffer_constinit(&b, name, strlen(name));
1988 1.2.2.2 pgoyette isc_buffer_add(&b, strlen(name));
1989 1.2.2.2 pgoyette
1990 1.2.2.2 pgoyette result = dns_name_fromtext(newname, &b, origin, 0, NULL);
1991 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
1992 1.2.2.2 pgoyette return (result);
1993 1.2.2.2 pgoyette
1994 1.2.2.2 pgoyette if (allnodes->common.relative_names) {
1995 1.2.2.2 pgoyette /* All names are relative to the root */
1996 1.2.2.2 pgoyette unsigned int nlabels = dns_name_countlabels(newname);
1997 1.2.2.2 pgoyette dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
1998 1.2.2.2 pgoyette }
1999 1.2.2.2 pgoyette
2000 1.2.2.2 pgoyette sdlznode = ISC_LIST_HEAD(allnodes->nodelist);
2001 1.2.2.2 pgoyette if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) {
2002 1.2.2.2 pgoyette sdlznode = NULL;
2003 1.2.2.2 pgoyette result = createnode(sdlz, &sdlznode);
2004 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
2005 1.2.2.2 pgoyette return (result);
2006 1.2.2.2 pgoyette sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t));
2007 1.2.2.2 pgoyette if (sdlznode->name == NULL) {
2008 1.2.2.2 pgoyette destroynode(sdlznode);
2009 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
2010 1.2.2.2 pgoyette }
2011 1.2.2.2 pgoyette dns_name_init(sdlznode->name, NULL);
2012 1.2.2.2 pgoyette result = dns_name_dup(newname, mctx, sdlznode->name);
2013 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
2014 1.2.2.2 pgoyette isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t));
2015 1.2.2.2 pgoyette destroynode(sdlznode);
2016 1.2.2.2 pgoyette return (result);
2017 1.2.2.2 pgoyette }
2018 1.2.2.2 pgoyette ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link);
2019 1.2.2.2 pgoyette if (allnodes->origin == NULL &&
2020 1.2.2.2 pgoyette dns_name_equal(newname, &sdlz->common.origin))
2021 1.2.2.2 pgoyette allnodes->origin = sdlznode;
2022 1.2.2.2 pgoyette }
2023 1.2.2.2 pgoyette return (dns_sdlz_putrr(sdlznode, type, ttl, data));
2024 1.2.2.2 pgoyette
2025 1.2.2.2 pgoyette }
2026 1.2.2.2 pgoyette
2027 1.2.2.2 pgoyette isc_result_t
2028 1.2.2.2 pgoyette dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname,
2029 1.2.2.2 pgoyette isc_uint32_t serial)
2030 1.2.2.2 pgoyette {
2031 1.2.2.2 pgoyette char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
2032 1.2.2.2 pgoyette int n;
2033 1.2.2.2 pgoyette
2034 1.2.2.2 pgoyette REQUIRE(mname != NULL);
2035 1.2.2.2 pgoyette REQUIRE(rname != NULL);
2036 1.2.2.2 pgoyette
2037 1.2.2.2 pgoyette n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u",
2038 1.2.2.2 pgoyette mname, rname, serial,
2039 1.2.2.2 pgoyette SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY,
2040 1.2.2.2 pgoyette SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM);
2041 1.2.2.2 pgoyette if (n >= (int)sizeof(str) || n < 0)
2042 1.2.2.2 pgoyette return (ISC_R_NOSPACE);
2043 1.2.2.2 pgoyette return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str));
2044 1.2.2.2 pgoyette }
2045 1.2.2.2 pgoyette
2046 1.2.2.2 pgoyette isc_result_t
2047 1.2.2.2 pgoyette dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods,
2048 1.2.2.2 pgoyette void *driverarg, unsigned int flags, isc_mem_t *mctx,
2049 1.2.2.2 pgoyette dns_sdlzimplementation_t **sdlzimp)
2050 1.2.2.2 pgoyette {
2051 1.2.2.2 pgoyette
2052 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
2053 1.2.2.2 pgoyette isc_result_t result;
2054 1.2.2.2 pgoyette
2055 1.2.2.2 pgoyette /*
2056 1.2.2.2 pgoyette * Performs checks to make sure data is as we expect it to be.
2057 1.2.2.2 pgoyette */
2058 1.2.2.2 pgoyette REQUIRE(drivername != NULL);
2059 1.2.2.2 pgoyette REQUIRE(methods != NULL);
2060 1.2.2.2 pgoyette REQUIRE(methods->findzone != NULL);
2061 1.2.2.2 pgoyette REQUIRE(methods->lookup != NULL);
2062 1.2.2.2 pgoyette REQUIRE(mctx != NULL);
2063 1.2.2.2 pgoyette REQUIRE(sdlzimp != NULL && *sdlzimp == NULL);
2064 1.2.2.2 pgoyette REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER |
2065 1.2.2.2 pgoyette DNS_SDLZFLAG_RELATIVERDATA |
2066 1.2.2.2 pgoyette DNS_SDLZFLAG_THREADSAFE)) == 0);
2067 1.2.2.2 pgoyette
2068 1.2.2.2 pgoyette /* Write debugging message to log */
2069 1.2.2.2 pgoyette sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername);
2070 1.2.2.2 pgoyette
2071 1.2.2.2 pgoyette /*
2072 1.2.2.2 pgoyette * Allocate memory for a sdlz_implementation object. Error if
2073 1.2.2.2 pgoyette * we cannot.
2074 1.2.2.2 pgoyette */
2075 1.2.2.2 pgoyette imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t));
2076 1.2.2.2 pgoyette if (imp == NULL)
2077 1.2.2.2 pgoyette return (ISC_R_NOMEMORY);
2078 1.2.2.2 pgoyette
2079 1.2.2.2 pgoyette /* Make sure memory region is set to all 0's */
2080 1.2.2.2 pgoyette memset(imp, 0, sizeof(dns_sdlzimplementation_t));
2081 1.2.2.2 pgoyette
2082 1.2.2.2 pgoyette /* Store the data passed into this method */
2083 1.2.2.2 pgoyette imp->methods = methods;
2084 1.2.2.2 pgoyette imp->driverarg = driverarg;
2085 1.2.2.2 pgoyette imp->flags = flags;
2086 1.2.2.2 pgoyette imp->mctx = NULL;
2087 1.2.2.2 pgoyette
2088 1.2.2.2 pgoyette /* attach the new sdlz_implementation object to a memory context */
2089 1.2.2.2 pgoyette isc_mem_attach(mctx, &imp->mctx);
2090 1.2.2.2 pgoyette
2091 1.2.2.2 pgoyette /*
2092 1.2.2.2 pgoyette * initialize the driver lock, error if we cannot
2093 1.2.2.2 pgoyette * (used if a driver does not support multiple threads)
2094 1.2.2.2 pgoyette */
2095 1.2.2.2 pgoyette result = isc_mutex_init(&imp->driverlock);
2096 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS) {
2097 1.2.2.2 pgoyette UNEXPECTED_ERROR(__FILE__, __LINE__,
2098 1.2.2.2 pgoyette "isc_mutex_init() failed: %s",
2099 1.2.2.2 pgoyette isc_result_totext(result));
2100 1.2.2.2 pgoyette goto cleanup_mctx;
2101 1.2.2.2 pgoyette }
2102 1.2.2.2 pgoyette
2103 1.2.2.2 pgoyette imp->dlz_imp = NULL;
2104 1.2.2.2 pgoyette
2105 1.2.2.2 pgoyette /*
2106 1.2.2.2 pgoyette * register the DLZ driver. Pass in our "extra" sdlz information as
2107 1.2.2.2 pgoyette * a driverarg. (that's why we stored the passed in driver arg in our
2108 1.2.2.2 pgoyette * sdlz_implementation structure) Also, store the dlz_implementation
2109 1.2.2.2 pgoyette * structure in our sdlz_implementation.
2110 1.2.2.2 pgoyette */
2111 1.2.2.2 pgoyette result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx,
2112 1.2.2.2 pgoyette &imp->dlz_imp);
2113 1.2.2.2 pgoyette
2114 1.2.2.2 pgoyette /* if registration fails, cleanup and get outta here. */
2115 1.2.2.2 pgoyette if (result != ISC_R_SUCCESS)
2116 1.2.2.2 pgoyette goto cleanup_mutex;
2117 1.2.2.2 pgoyette
2118 1.2.2.2 pgoyette *sdlzimp = imp;
2119 1.2.2.2 pgoyette
2120 1.2.2.2 pgoyette return (ISC_R_SUCCESS);
2121 1.2.2.2 pgoyette
2122 1.2.2.2 pgoyette cleanup_mutex:
2123 1.2.2.2 pgoyette /* destroy the driver lock, we don't need it anymore */
2124 1.2.2.2 pgoyette DESTROYLOCK(&imp->driverlock);
2125 1.2.2.2 pgoyette
2126 1.2.2.2 pgoyette cleanup_mctx:
2127 1.2.2.2 pgoyette /*
2128 1.2.2.2 pgoyette * return the memory back to the available memory pool and
2129 1.2.2.2 pgoyette * remove it from the memory context.
2130 1.2.2.2 pgoyette */
2131 1.2.2.2 pgoyette isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
2132 1.2.2.2 pgoyette isc_mem_detach(&mctx);
2133 1.2.2.2 pgoyette return (result);
2134 1.2.2.2 pgoyette }
2135 1.2.2.2 pgoyette
2136 1.2.2.2 pgoyette void
2137 1.2.2.2 pgoyette dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) {
2138 1.2.2.2 pgoyette dns_sdlzimplementation_t *imp;
2139 1.2.2.2 pgoyette isc_mem_t *mctx;
2140 1.2.2.2 pgoyette
2141 1.2.2.2 pgoyette /* Write debugging message to log */
2142 1.2.2.2 pgoyette sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver.");
2143 1.2.2.2 pgoyette
2144 1.2.2.2 pgoyette /*
2145 1.2.2.2 pgoyette * Performs checks to make sure data is as we expect it to be.
2146 1.2.2.2 pgoyette */
2147 1.2.2.2 pgoyette REQUIRE(sdlzimp != NULL && *sdlzimp != NULL);
2148 1.2.2.2 pgoyette
2149 1.2.2.2 pgoyette imp = *sdlzimp;
2150 1.2.2.2 pgoyette
2151 1.2.2.2 pgoyette /* Unregister the DLZ driver implementation */
2152 1.2.2.2 pgoyette dns_dlzunregister(&imp->dlz_imp);
2153 1.2.2.2 pgoyette
2154 1.2.2.2 pgoyette /* destroy the driver lock, we don't need it anymore */
2155 1.2.2.2 pgoyette DESTROYLOCK(&imp->driverlock);
2156 1.2.2.2 pgoyette
2157 1.2.2.2 pgoyette mctx = imp->mctx;
2158 1.2.2.2 pgoyette
2159 1.2.2.2 pgoyette /*
2160 1.2.2.2 pgoyette * return the memory back to the available memory pool and
2161 1.2.2.2 pgoyette * remove it from the memory context.
2162 1.2.2.2 pgoyette */
2163 1.2.2.2 pgoyette isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
2164 1.2.2.2 pgoyette isc_mem_detach(&mctx);
2165 1.2.2.2 pgoyette
2166 1.2.2.2 pgoyette *sdlzimp = NULL;
2167 1.2.2.2 pgoyette }
2168 1.2.2.2 pgoyette
2169 1.2.2.2 pgoyette
2170 1.2.2.2 pgoyette isc_result_t
2171 1.2.2.2 pgoyette dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass,
2172 1.2.2.2 pgoyette const dns_name_t *name, dns_db_t **dbp)
2173 1.2.2.2 pgoyette {
2174 1.2.2.2 pgoyette isc_result_t result;
2175 1.2.2.2 pgoyette
2176 1.2.2.2 pgoyette result = dns_sdlzcreateDBP(dlzdatabase->mctx,
2177 1.2.2.2 pgoyette dlzdatabase->implementation->driverarg,
2178 1.2.2.2 pgoyette dlzdatabase->dbdata, name, rdclass, dbp);
2179 1.2.2.2 pgoyette return (result);
2180 1.2.2.2 pgoyette }
2181