dnsrps.c revision 1.8 1 1.7 rillig /* $NetBSD: dnsrps.c,v 1.8 2022/09/23 12:15:29 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.8 christos * SPDX-License-Identifier: MPL-2.0
7 1.8 christos *
8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public
9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this
10 1.6 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 1.1 christos *
12 1.1 christos * See the COPYRIGHT file distributed with this work for additional
13 1.1 christos * information regarding copyright ownership.
14 1.1 christos */
15 1.1 christos
16 1.1 christos /*! \file */
17 1.1 christos
18 1.3 christos #include <inttypes.h>
19 1.3 christos #include <stdbool.h>
20 1.3 christos
21 1.1 christos #ifdef USE_DNSRPS
22 1.1 christos
23 1.5 christos #include <stdlib.h>
24 1.5 christos
25 1.1 christos #include <isc/mem.h>
26 1.1 christos #include <isc/string.h>
27 1.1 christos #include <isc/util.h>
28 1.1 christos
29 1.1 christos #include <dns/db.h>
30 1.1 christos #define LIBRPZ_LIB_OPEN DNSRPS_LIB_OPEN
31 1.1 christos #include <dns/dnsrps.h>
32 1.1 christos #include <dns/rdataset.h>
33 1.1 christos #include <dns/rdatasetiter.h>
34 1.1 christos #include <dns/result.h>
35 1.1 christos #include <dns/rpz.h>
36 1.1 christos
37 1.1 christos librpz_t *librpz;
38 1.1 christos librpz_emsg_t librpz_lib_open_emsg;
39 1.1 christos static void *librpz_handle;
40 1.1 christos
41 1.5 christos #define RPSDB_MAGIC ISC_MAGIC('R', 'P', 'Z', 'F')
42 1.1 christos #define VALID_RPSDB(rpsdb) ((rpsdb)->common.impmagic == RPSDB_MAGIC)
43 1.1 christos
44 1.5 christos #define RD_DB(r) ((r)->private1)
45 1.5 christos #define RD_CUR_RR(r) ((r)->private2)
46 1.5 christos #define RD_NEXT_RR(r) ((r)->resign)
47 1.5 christos #define RD_COUNT(r) ((r)->privateuint4)
48 1.1 christos
49 1.1 christos typedef struct {
50 1.5 christos dns_rdatasetiter_t common;
51 1.5 christos dns_rdatatype_t type;
52 1.5 christos dns_rdataclass_t class;
53 1.5 christos uint32_t ttl;
54 1.5 christos uint count;
55 1.5 christos librpz_idx_t next_rr;
56 1.1 christos } rpsdb_rdatasetiter_t;
57 1.1 christos
58 1.1 christos static dns_dbmethods_t rpsdb_db_methods;
59 1.1 christos static dns_rdatasetmethods_t rpsdb_rdataset_methods;
60 1.1 christos static dns_rdatasetitermethods_t rpsdb_rdatasetiter_methods;
61 1.1 christos
62 1.1 christos static librpz_clist_t *clist;
63 1.1 christos
64 1.1 christos static isc_mutex_t dnsrps_mutex;
65 1.1 christos
66 1.1 christos static void
67 1.1 christos dnsrps_lock(void *mutex0) {
68 1.1 christos isc_mutex_t *mutex = mutex0;
69 1.1 christos
70 1.1 christos LOCK(mutex);
71 1.1 christos }
72 1.1 christos
73 1.1 christos static void
74 1.1 christos dnsrps_unlock(void *mutex0) {
75 1.1 christos isc_mutex_t *mutex = mutex0;
76 1.1 christos
77 1.1 christos UNLOCK(mutex);
78 1.1 christos }
79 1.1 christos
80 1.1 christos static void
81 1.1 christos dnsrps_mutex_destroy(void *mutex0) {
82 1.1 christos isc_mutex_t *mutex = mutex0;
83 1.1 christos
84 1.3 christos isc_mutex_destroy(mutex);
85 1.1 christos }
86 1.1 christos
87 1.1 christos static void
88 1.1 christos dnsrps_log_fnc(librpz_log_level_t level, void *ctxt, const char *buf) {
89 1.1 christos int isc_level;
90 1.1 christos
91 1.1 christos UNUSED(ctxt);
92 1.1 christos
93 1.1 christos /* Setting librpz_log_level in the configuration overrides the
94 1.1 christos * BIND9 logging levels. */
95 1.1 christos if (level > LIBRPZ_LOG_TRACE1 &&
96 1.1 christos level <= librpz->log_level_val(LIBRPZ_LOG_INVALID))
97 1.5 christos {
98 1.1 christos level = LIBRPZ_LOG_TRACE1;
99 1.5 christos }
100 1.1 christos
101 1.5 christos switch (level) {
102 1.1 christos case LIBRPZ_LOG_FATAL:
103 1.5 christos case LIBRPZ_LOG_ERROR: /* errors */
104 1.1 christos default:
105 1.1 christos isc_level = DNS_RPZ_ERROR_LEVEL;
106 1.1 christos break;
107 1.1 christos
108 1.5 christos case LIBRPZ_LOG_TRACE1: /* big events such as dnsrpzd starts */
109 1.1 christos isc_level = DNS_RPZ_INFO_LEVEL;
110 1.1 christos break;
111 1.1 christos
112 1.5 christos case LIBRPZ_LOG_TRACE2: /* smaller dnsrpzd zone transfers */
113 1.1 christos isc_level = DNS_RPZ_DEBUG_LEVEL1;
114 1.1 christos break;
115 1.1 christos
116 1.5 christos case LIBRPZ_LOG_TRACE3: /* librpz hits */
117 1.1 christos isc_level = DNS_RPZ_DEBUG_LEVEL2;
118 1.1 christos break;
119 1.1 christos
120 1.5 christos case LIBRPZ_LOG_TRACE4: /* librpz lookups */
121 1.1 christos isc_level = DNS_RPZ_DEBUG_LEVEL3;
122 1.1 christos break;
123 1.1 christos }
124 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB,
125 1.1 christos isc_level, "dnsrps: %s", buf);
126 1.1 christos }
127 1.1 christos
128 1.1 christos /*
129 1.1 christos * Start dnsrps for the entire server.
130 1.1 christos * This is not thread safe, but it is called by a single thread.
131 1.1 christos */
132 1.1 christos isc_result_t
133 1.1 christos dns_dnsrps_server_create(void) {
134 1.1 christos librpz_emsg_t emsg;
135 1.1 christos
136 1.1 christos INSIST(clist == NULL);
137 1.1 christos INSIST(librpz == NULL);
138 1.1 christos INSIST(librpz_handle == NULL);
139 1.1 christos
140 1.1 christos /*
141 1.1 christos * Notice if librpz is available.
142 1.1 christos */
143 1.5 christos librpz = librpz_lib_open(&librpz_lib_open_emsg, &librpz_handle,
144 1.5 christos DNSRPS_LIBRPZ_PATH);
145 1.1 christos /*
146 1.1 christos * Stop now without complaining if librpz is not available.
147 1.1 christos * Complain later if and when librpz is needed for a view with
148 1.5 christos * "dnsrps-enable yes" (including the default view).
149 1.1 christos */
150 1.5 christos if (librpz == NULL) {
151 1.1 christos return (ISC_R_SUCCESS);
152 1.5 christos }
153 1.1 christos
154 1.3 christos isc_mutex_init(&dnsrps_mutex);
155 1.1 christos
156 1.5 christos librpz->set_log(dnsrps_log_fnc, NULL);
157 1.1 christos
158 1.1 christos clist = librpz->clist_create(&emsg, dnsrps_lock, dnsrps_unlock,
159 1.1 christos dnsrps_mutex_destroy, &dnsrps_mutex,
160 1.1 christos dns_lctx);
161 1.1 christos if (clist == NULL) {
162 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
163 1.1 christos DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
164 1.1 christos "dnsrps: %s", emsg.c);
165 1.1 christos return (ISC_R_NOMEMORY);
166 1.1 christos }
167 1.1 christos return (ISC_R_SUCCESS);
168 1.1 christos }
169 1.1 christos
170 1.1 christos /*
171 1.1 christos * Stop dnsrps for the entire server.
172 1.1 christos * This is not thread safe.
173 1.1 christos */
174 1.1 christos void
175 1.1 christos dns_dnsrps_server_destroy(void) {
176 1.5 christos if (clist != NULL) {
177 1.1 christos librpz->clist_detach(&clist);
178 1.5 christos }
179 1.1 christos
180 1.1 christos #ifdef LIBRPZ_USE_DLOPEN
181 1.1 christos if (librpz != NULL) {
182 1.1 christos INSIST(librpz_handle != NULL);
183 1.5 christos if (dlclose(librpz_handle) != 0) {
184 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
185 1.1 christos DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
186 1.1 christos "dnsrps: dlclose(): %s", dlerror());
187 1.5 christos }
188 1.1 christos librpz_handle = NULL;
189 1.1 christos }
190 1.5 christos #endif /* ifdef LIBRPZ_USE_DLOPEN */
191 1.1 christos }
192 1.1 christos
193 1.1 christos /*
194 1.1 christos * Ready dnsrps for a view.
195 1.1 christos */
196 1.1 christos isc_result_t
197 1.1 christos dns_dnsrps_view_init(dns_rpz_zones_t *new, char *rps_cstr) {
198 1.1 christos librpz_emsg_t emsg;
199 1.1 christos
200 1.5 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB,
201 1.5 christos DNS_RPZ_DEBUG_LEVEL3, "dnsrps configuration \"%s\"",
202 1.5 christos rps_cstr);
203 1.1 christos
204 1.5 christos new->rps_client = librpz->client_create(&emsg, clist, rps_cstr, false);
205 1.1 christos if (new->rps_client == NULL) {
206 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
207 1.1 christos DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
208 1.1 christos "librpz->client_create(): %s", emsg.c);
209 1.3 christos new->p.dnsrps_enabled = false;
210 1.1 christos return (ISC_R_FAILURE);
211 1.1 christos }
212 1.1 christos
213 1.3 christos new->p.dnsrps_enabled = true;
214 1.1 christos return (ISC_R_SUCCESS);
215 1.1 christos }
216 1.1 christos
217 1.1 christos /*
218 1.1 christos * Connect to and start the dnsrps daemon, dnsrpzd.
219 1.1 christos */
220 1.1 christos isc_result_t
221 1.1 christos dns_dnsrps_connect(dns_rpz_zones_t *rpzs) {
222 1.1 christos librpz_emsg_t emsg;
223 1.1 christos
224 1.5 christos if (rpzs == NULL || !rpzs->p.dnsrps_enabled) {
225 1.1 christos return (ISC_R_SUCCESS);
226 1.5 christos }
227 1.1 christos
228 1.1 christos /*
229 1.1 christos * Fail only if we failed to link to librpz.
230 1.1 christos */
231 1.1 christos if (librpz == NULL) {
232 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
233 1.1 christos DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
234 1.1 christos "librpz->connect(): %s", librpz_lib_open_emsg.c);
235 1.1 christos return (ISC_R_FAILURE);
236 1.1 christos }
237 1.1 christos
238 1.1 christos if (!librpz->connect(&emsg, rpzs->rps_client, true)) {
239 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
240 1.1 christos DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
241 1.1 christos "librpz->connect(): %s", emsg.c);
242 1.1 christos return (ISC_R_SUCCESS);
243 1.1 christos }
244 1.1 christos
245 1.1 christos isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB,
246 1.1 christos DNS_RPZ_INFO_LEVEL, "dnsrps: librpz version %s",
247 1.1 christos librpz->version);
248 1.1 christos
249 1.1 christos return (ISC_R_SUCCESS);
250 1.1 christos }
251 1.1 christos
252 1.1 christos /*
253 1.1 christos * Get ready to try RPZ rewriting.
254 1.1 christos */
255 1.1 christos isc_result_t
256 1.1 christos dns_dnsrps_rewrite_init(librpz_emsg_t *emsg, dns_rpz_st_t *st,
257 1.1 christos dns_rpz_zones_t *rpzs, const dns_name_t *qname,
258 1.5 christos isc_mem_t *mctx, bool have_rd) {
259 1.1 christos rpsdb_t *rpsdb;
260 1.1 christos
261 1.1 christos rpsdb = isc_mem_get(mctx, sizeof(*rpsdb));
262 1.1 christos memset(rpsdb, 0, sizeof(*rpsdb));
263 1.1 christos
264 1.5 christos if (!librpz->rsp_create(emsg, &rpsdb->rsp, NULL, rpzs->rps_client,
265 1.5 christos have_rd, false))
266 1.5 christos {
267 1.1 christos isc_mem_put(mctx, rpsdb, sizeof(*rpsdb));
268 1.1 christos return (DNS_R_SERVFAIL);
269 1.1 christos }
270 1.1 christos if (rpsdb->rsp == NULL) {
271 1.1 christos isc_mem_put(mctx, rpsdb, sizeof(*rpsdb));
272 1.1 christos return (DNS_R_DISALLOWED);
273 1.1 christos }
274 1.1 christos
275 1.1 christos rpsdb->common.magic = DNS_DB_MAGIC;
276 1.1 christos rpsdb->common.impmagic = RPSDB_MAGIC;
277 1.1 christos rpsdb->common.methods = &rpsdb_db_methods;
278 1.1 christos rpsdb->common.rdclass = dns_rdataclass_in;
279 1.1 christos dns_name_init(&rpsdb->common.origin, NULL);
280 1.1 christos isc_mem_attach(mctx, &rpsdb->common.mctx);
281 1.1 christos
282 1.1 christos rpsdb->ref_cnt = 1;
283 1.1 christos rpsdb->qname = qname;
284 1.1 christos
285 1.1 christos st->rpsdb = &rpsdb->common;
286 1.1 christos return (ISC_R_SUCCESS);
287 1.1 christos }
288 1.1 christos
289 1.1 christos /*
290 1.1 christos * Convert a dnsrps policy to a classic BIND9 RPZ policy.
291 1.1 christos */
292 1.1 christos dns_rpz_policy_t
293 1.1 christos dns_dnsrps_2policy(librpz_policy_t rps_policy) {
294 1.1 christos switch (rps_policy) {
295 1.1 christos case LIBRPZ_POLICY_UNDEFINED:
296 1.1 christos return (DNS_RPZ_POLICY_MISS);
297 1.1 christos case LIBRPZ_POLICY_PASSTHRU:
298 1.1 christos return (DNS_RPZ_POLICY_PASSTHRU);
299 1.1 christos case LIBRPZ_POLICY_DROP:
300 1.1 christos return (DNS_RPZ_POLICY_DROP);
301 1.1 christos case LIBRPZ_POLICY_TCP_ONLY:
302 1.1 christos return (DNS_RPZ_POLICY_TCP_ONLY);
303 1.1 christos case LIBRPZ_POLICY_NXDOMAIN:
304 1.1 christos return (DNS_RPZ_POLICY_NXDOMAIN);
305 1.1 christos case LIBRPZ_POLICY_NODATA:
306 1.1 christos return (DNS_RPZ_POLICY_NODATA);
307 1.1 christos case LIBRPZ_POLICY_RECORD:
308 1.1 christos case LIBRPZ_POLICY_CNAME:
309 1.1 christos return (DNS_RPZ_POLICY_RECORD);
310 1.1 christos
311 1.1 christos case LIBRPZ_POLICY_DELETED:
312 1.1 christos case LIBRPZ_POLICY_GIVEN:
313 1.1 christos case LIBRPZ_POLICY_DISABLED:
314 1.1 christos default:
315 1.8 christos UNREACHABLE();
316 1.1 christos }
317 1.1 christos }
318 1.1 christos
319 1.1 christos /*
320 1.1 christos * Convert a dnsrps trigger to a classic BIND9 RPZ rewrite or trigger type.
321 1.1 christos */
322 1.1 christos dns_rpz_type_t
323 1.1 christos dns_dnsrps_trig2type(librpz_trig_t trig) {
324 1.1 christos switch (trig) {
325 1.1 christos case LIBRPZ_TRIG_BAD:
326 1.1 christos default:
327 1.1 christos return (DNS_RPZ_TYPE_BAD);
328 1.1 christos case LIBRPZ_TRIG_CLIENT_IP:
329 1.1 christos return (DNS_RPZ_TYPE_CLIENT_IP);
330 1.1 christos case LIBRPZ_TRIG_QNAME:
331 1.1 christos return (DNS_RPZ_TYPE_QNAME);
332 1.1 christos case LIBRPZ_TRIG_IP:
333 1.1 christos return (DNS_RPZ_TYPE_IP);
334 1.1 christos case LIBRPZ_TRIG_NSDNAME:
335 1.1 christos return (DNS_RPZ_TYPE_NSDNAME);
336 1.1 christos case LIBRPZ_TRIG_NSIP:
337 1.1 christos return (DNS_RPZ_TYPE_NSIP);
338 1.1 christos }
339 1.1 christos }
340 1.1 christos
341 1.1 christos /*
342 1.1 christos * Convert a classic BIND9 RPZ rewrite or trigger type to a librpz trigger type.
343 1.1 christos */
344 1.1 christos librpz_trig_t
345 1.1 christos dns_dnsrps_type2trig(dns_rpz_type_t type) {
346 1.1 christos switch (type) {
347 1.1 christos case DNS_RPZ_TYPE_BAD:
348 1.1 christos default:
349 1.1 christos return (LIBRPZ_TRIG_BAD);
350 1.1 christos case DNS_RPZ_TYPE_CLIENT_IP:
351 1.1 christos return (LIBRPZ_TRIG_CLIENT_IP);
352 1.1 christos case DNS_RPZ_TYPE_QNAME:
353 1.1 christos return (LIBRPZ_TRIG_QNAME);
354 1.1 christos case DNS_RPZ_TYPE_IP:
355 1.1 christos return (LIBRPZ_TRIG_IP);
356 1.1 christos case DNS_RPZ_TYPE_NSDNAME:
357 1.1 christos return (LIBRPZ_TRIG_NSDNAME);
358 1.1 christos case DNS_RPZ_TYPE_NSIP:
359 1.1 christos return (LIBRPZ_TRIG_NSIP);
360 1.1 christos }
361 1.1 christos }
362 1.1 christos
363 1.1 christos static void
364 1.1 christos rpsdb_attach(dns_db_t *source, dns_db_t **targetp) {
365 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)source;
366 1.1 christos
367 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
368 1.1 christos
369 1.1 christos /*
370 1.1 christos * Use a simple count because only one thread uses any single rpsdb_t
371 1.1 christos */
372 1.1 christos ++rpsdb->ref_cnt;
373 1.1 christos *targetp = source;
374 1.1 christos }
375 1.1 christos
376 1.1 christos static void
377 1.1 christos rpsdb_detach(dns_db_t **dbp) {
378 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)*dbp;
379 1.1 christos
380 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
381 1.1 christos REQUIRE(rpsdb->ref_cnt > 0);
382 1.1 christos
383 1.1 christos *dbp = NULL;
384 1.1 christos
385 1.1 christos /*
386 1.1 christos * Simple count because only one thread uses a rpsdb_t.
387 1.1 christos */
388 1.5 christos if (--rpsdb->ref_cnt != 0) {
389 1.1 christos return;
390 1.5 christos }
391 1.1 christos
392 1.1 christos librpz->rsp_detach(&rpsdb->rsp);
393 1.1 christos rpsdb->common.impmagic = 0;
394 1.1 christos isc_mem_putanddetach(&rpsdb->common.mctx, rpsdb, sizeof(*rpsdb));
395 1.1 christos }
396 1.1 christos
397 1.1 christos static void
398 1.1 christos rpsdb_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
399 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)db;
400 1.1 christos
401 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
402 1.1 christos REQUIRE(targetp != NULL && *targetp == NULL);
403 1.5 christos REQUIRE(source == &rpsdb->origin_node || source == &rpsdb->data_node);
404 1.1 christos
405 1.1 christos /*
406 1.1 christos * Simple count because only one thread uses a rpsdb_t.
407 1.1 christos */
408 1.1 christos ++rpsdb->ref_cnt;
409 1.1 christos *targetp = source;
410 1.1 christos }
411 1.1 christos
412 1.1 christos static void
413 1.1 christos rpsdb_detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
414 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)db;
415 1.1 christos
416 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
417 1.1 christos REQUIRE(*targetp == &rpsdb->origin_node ||
418 1.1 christos *targetp == &rpsdb->data_node);
419 1.1 christos
420 1.1 christos *targetp = NULL;
421 1.1 christos rpsdb_detach(&db);
422 1.1 christos }
423 1.1 christos
424 1.1 christos static isc_result_t
425 1.3 christos rpsdb_findnode(dns_db_t *db, const dns_name_t *name, bool create,
426 1.5 christos dns_dbnode_t **nodep) {
427 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)db;
428 1.1 christos dns_db_t *dbp;
429 1.1 christos
430 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
431 1.1 christos REQUIRE(nodep != NULL && *nodep == NULL);
432 1.1 christos REQUIRE(!create);
433 1.1 christos
434 1.1 christos /*
435 1.1 christos * A fake/shim rpsdb has two nodes.
436 1.1 christos * One is the origin to support query_addsoa() in bin/named/query.c.
437 1.1 christos * The other contains rewritten RRs.
438 1.1 christos */
439 1.5 christos if (dns_name_equal(name, &db->origin)) {
440 1.1 christos *nodep = &rpsdb->origin_node;
441 1.5 christos } else {
442 1.1 christos *nodep = &rpsdb->data_node;
443 1.5 christos }
444 1.1 christos dbp = NULL;
445 1.1 christos rpsdb_attach(db, &dbp);
446 1.1 christos
447 1.1 christos return (ISC_R_SUCCESS);
448 1.1 christos }
449 1.1 christos
450 1.1 christos static void
451 1.1 christos rpsdb_bind_rdataset(dns_rdataset_t *rdataset, uint count, librpz_idx_t next_rr,
452 1.1 christos dns_rdatatype_t type, uint16_t class, uint32_t ttl,
453 1.5 christos rpsdb_t *rpsdb) {
454 1.1 christos dns_db_t *dbp;
455 1.1 christos
456 1.5 christos INSIST(rdataset->methods == NULL); /* We must be disassociated. */
457 1.1 christos REQUIRE(type != dns_rdatatype_none);
458 1.1 christos
459 1.1 christos rdataset->methods = &rpsdb_rdataset_methods;
460 1.1 christos rdataset->rdclass = class;
461 1.1 christos rdataset->type = type;
462 1.1 christos rdataset->ttl = ttl;
463 1.1 christos dbp = NULL;
464 1.1 christos dns_db_attach(&rpsdb->common, &dbp);
465 1.1 christos RD_DB(rdataset) = dbp;
466 1.1 christos RD_COUNT(rdataset) = count;
467 1.1 christos RD_NEXT_RR(rdataset) = next_rr;
468 1.1 christos RD_CUR_RR(rdataset) = NULL;
469 1.1 christos }
470 1.1 christos
471 1.1 christos static isc_result_t
472 1.1 christos rpsdb_bind_soa(dns_rdataset_t *rdataset, rpsdb_t *rpsdb) {
473 1.1 christos uint32_t ttl;
474 1.1 christos librpz_emsg_t emsg;
475 1.1 christos
476 1.5 christos if (!librpz->rsp_soa(&emsg, &ttl, NULL, NULL, &rpsdb->result,
477 1.5 christos rpsdb->rsp)) {
478 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
479 1.1 christos return (DNS_R_SERVFAIL);
480 1.1 christos }
481 1.1 christos rpsdb_bind_rdataset(rdataset, 1, LIBRPZ_IDX_BAD, dns_rdatatype_soa,
482 1.5 christos dns_rdataclass_in, ttl, rpsdb);
483 1.1 christos return (ISC_R_SUCCESS);
484 1.1 christos }
485 1.1 christos
486 1.1 christos /*
487 1.1 christos * Forge an rdataset of the desired type from a librpz result.
488 1.1 christos * This is written for simplicity instead of speed, because RPZ rewriting
489 1.1 christos * should be rare compared to normal BIND operations.
490 1.1 christos */
491 1.1 christos static isc_result_t
492 1.1 christos rpsdb_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
493 1.1 christos dns_rdatatype_t type, dns_rdatatype_t covers,
494 1.1 christos isc_stdtime_t now, dns_rdataset_t *rdataset,
495 1.5 christos dns_rdataset_t *sigrdataset) {
496 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)db;
497 1.1 christos dns_rdatatype_t foundtype;
498 1.1 christos dns_rdataclass_t class;
499 1.1 christos uint32_t ttl;
500 1.1 christos uint count;
501 1.1 christos librpz_emsg_t emsg;
502 1.1 christos
503 1.1 christos UNUSED(version);
504 1.1 christos UNUSED(covers);
505 1.1 christos UNUSED(now);
506 1.1 christos UNUSED(sigrdataset);
507 1.1 christos
508 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
509 1.1 christos
510 1.1 christos if (node == &rpsdb->origin_node) {
511 1.5 christos if (type == dns_rdatatype_any) {
512 1.1 christos return (ISC_R_SUCCESS);
513 1.5 christos }
514 1.5 christos if (type == dns_rdatatype_soa) {
515 1.1 christos return (rpsdb_bind_soa(rdataset, rpsdb));
516 1.5 christos }
517 1.1 christos return (DNS_R_NXRRSET);
518 1.1 christos }
519 1.1 christos
520 1.1 christos REQUIRE(node == &rpsdb->data_node);
521 1.1 christos
522 1.1 christos switch (rpsdb->result.policy) {
523 1.1 christos case LIBRPZ_POLICY_UNDEFINED:
524 1.1 christos case LIBRPZ_POLICY_DELETED:
525 1.1 christos case LIBRPZ_POLICY_PASSTHRU:
526 1.1 christos case LIBRPZ_POLICY_DROP:
527 1.1 christos case LIBRPZ_POLICY_TCP_ONLY:
528 1.1 christos case LIBRPZ_POLICY_GIVEN:
529 1.1 christos case LIBRPZ_POLICY_DISABLED:
530 1.1 christos default:
531 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL,
532 1.1 christos "impossible dnsrps policy %d at %s:%d",
533 1.1 christos rpsdb->result.policy, __FILE__, __LINE__);
534 1.1 christos return (DNS_R_SERVFAIL);
535 1.1 christos
536 1.1 christos case LIBRPZ_POLICY_NXDOMAIN:
537 1.1 christos return (DNS_R_NXDOMAIN);
538 1.1 christos
539 1.1 christos case LIBRPZ_POLICY_NODATA:
540 1.1 christos return (DNS_R_NXRRSET);
541 1.1 christos
542 1.1 christos case LIBRPZ_POLICY_RECORD:
543 1.1 christos case LIBRPZ_POLICY_CNAME:
544 1.1 christos break;
545 1.1 christos }
546 1.1 christos
547 1.5 christos if (type == dns_rdatatype_soa) {
548 1.1 christos return (rpsdb_bind_soa(rdataset, rpsdb));
549 1.5 christos }
550 1.1 christos
551 1.1 christos /*
552 1.1 christos * There is little to do for an ANY query.
553 1.1 christos */
554 1.5 christos if (type == dns_rdatatype_any) {
555 1.1 christos return (ISC_R_SUCCESS);
556 1.5 christos }
557 1.1 christos
558 1.1 christos /*
559 1.1 christos * Reset to the start of the RRs.
560 1.1 christos * This function is only used after a policy has been chosen,
561 1.1 christos * and so without caring whether it is after recursion.
562 1.1 christos */
563 1.1 christos if (!librpz->rsp_result(&emsg, &rpsdb->result, true, rpsdb->rsp)) {
564 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
565 1.1 christos return (DNS_R_SERVFAIL);
566 1.1 christos }
567 1.1 christos if (!librpz->rsp_rr(&emsg, &foundtype, &class, &ttl, NULL,
568 1.1 christos &rpsdb->result, rpsdb->qname->ndata,
569 1.5 christos rpsdb->qname->length, rpsdb->rsp))
570 1.5 christos {
571 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
572 1.1 christos return (DNS_R_SERVFAIL);
573 1.1 christos }
574 1.1 christos REQUIRE(foundtype != dns_rdatatype_none);
575 1.1 christos
576 1.1 christos /*
577 1.1 christos * Ho many of the target RR type are available?
578 1.1 christos */
579 1.1 christos count = 0;
580 1.1 christos do {
581 1.5 christos if (type == foundtype || type == dns_rdatatype_any) {
582 1.1 christos ++count;
583 1.5 christos }
584 1.1 christos
585 1.1 christos if (!librpz->rsp_rr(&emsg, &foundtype, NULL, NULL, NULL,
586 1.1 christos &rpsdb->result, rpsdb->qname->ndata,
587 1.5 christos rpsdb->qname->length, rpsdb->rsp))
588 1.5 christos {
589 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
590 1.1 christos return (DNS_R_SERVFAIL);
591 1.1 christos }
592 1.1 christos } while (foundtype != dns_rdatatype_none);
593 1.5 christos if (count == 0) {
594 1.1 christos return (DNS_R_NXRRSET);
595 1.5 christos }
596 1.5 christos rpsdb_bind_rdataset(rdataset, count, rpsdb->result.next_rr, type, class,
597 1.5 christos ttl, rpsdb);
598 1.1 christos return (ISC_R_SUCCESS);
599 1.1 christos }
600 1.1 christos
601 1.1 christos static isc_result_t
602 1.1 christos rpsdb_finddb(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
603 1.1 christos dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
604 1.1 christos dns_dbnode_t **nodep, dns_name_t *foundname,
605 1.5 christos dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
606 1.1 christos dns_dbnode_t *node;
607 1.1 christos
608 1.1 christos UNUSED(version);
609 1.1 christos UNUSED(options);
610 1.1 christos UNUSED(now);
611 1.1 christos UNUSED(sigrdataset);
612 1.1 christos
613 1.1 christos if (nodep == NULL) {
614 1.1 christos node = NULL;
615 1.1 christos nodep = &node;
616 1.1 christos }
617 1.1 christos rpsdb_findnode(db, name, false, nodep);
618 1.4 christos dns_name_copynf(name, foundname);
619 1.5 christos return (rpsdb_findrdataset(db, *nodep, NULL, type, 0, 0, rdataset,
620 1.5 christos sigrdataset));
621 1.1 christos }
622 1.1 christos
623 1.1 christos static isc_result_t
624 1.1 christos rpsdb_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
625 1.5 christos isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) {
626 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)db;
627 1.1 christos rpsdb_rdatasetiter_t *rpsdb_iter;
628 1.1 christos
629 1.1 christos UNUSED(version);
630 1.1 christos UNUSED(now);
631 1.1 christos
632 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
633 1.1 christos REQUIRE(node == &rpsdb->origin_node || node == &rpsdb->data_node);
634 1.1 christos
635 1.1 christos rpsdb_iter = isc_mem_get(rpsdb->common.mctx, sizeof(*rpsdb_iter));
636 1.1 christos
637 1.1 christos memset(rpsdb_iter, 0, sizeof(*rpsdb_iter));
638 1.1 christos rpsdb_iter->common.magic = DNS_RDATASETITER_MAGIC;
639 1.1 christos rpsdb_iter->common.methods = &rpsdb_rdatasetiter_methods;
640 1.1 christos rpsdb_iter->common.db = db;
641 1.1 christos rpsdb_attachnode(db, node, &rpsdb_iter->common.node);
642 1.1 christos
643 1.1 christos *iteratorp = &rpsdb_iter->common;
644 1.1 christos
645 1.1 christos return (ISC_R_SUCCESS);
646 1.1 christos }
647 1.1 christos
648 1.3 christos static bool
649 1.1 christos rpsdb_issecure(dns_db_t *db) {
650 1.1 christos UNUSED(db);
651 1.1 christos
652 1.3 christos return (false);
653 1.1 christos }
654 1.1 christos
655 1.1 christos static isc_result_t
656 1.1 christos rpsdb_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
657 1.1 christos rpsdb_t *rpsdb = (rpsdb_t *)db;
658 1.1 christos
659 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
660 1.1 christos REQUIRE(nodep != NULL && *nodep == NULL);
661 1.1 christos
662 1.1 christos rpsdb_attachnode(db, &rpsdb->origin_node, nodep);
663 1.1 christos return (ISC_R_SUCCESS);
664 1.1 christos }
665 1.1 christos
666 1.1 christos static void
667 1.1 christos rpsdb_rdataset_disassociate(dns_rdataset_t *rdataset) {
668 1.1 christos dns_db_t *db;
669 1.1 christos
670 1.1 christos /*
671 1.1 christos * Detach the last RR delivered.
672 1.1 christos */
673 1.1 christos if (RD_CUR_RR(rdataset) != NULL) {
674 1.1 christos free(RD_CUR_RR(rdataset));
675 1.1 christos RD_CUR_RR(rdataset) = NULL;
676 1.1 christos }
677 1.1 christos
678 1.1 christos db = RD_DB(rdataset);
679 1.1 christos RD_DB(rdataset) = NULL;
680 1.1 christos dns_db_detach(&db);
681 1.1 christos }
682 1.1 christos
683 1.1 christos static isc_result_t
684 1.1 christos rpsdb_rdataset_next(dns_rdataset_t *rdataset) {
685 1.1 christos rpsdb_t *rpsdb;
686 1.1 christos uint16_t type;
687 1.1 christos dns_rdataclass_t class;
688 1.1 christos librpz_rr_t *rr;
689 1.1 christos librpz_emsg_t emsg;
690 1.1 christos
691 1.1 christos rpsdb = RD_DB(rdataset);
692 1.1 christos
693 1.1 christos /*
694 1.1 christos * Detach the previous RR.
695 1.1 christos */
696 1.1 christos if (RD_CUR_RR(rdataset) != NULL) {
697 1.1 christos free(RD_CUR_RR(rdataset));
698 1.1 christos RD_CUR_RR(rdataset) = NULL;
699 1.1 christos }
700 1.1 christos
701 1.1 christos /*
702 1.1 christos * Get the next RR of the specified type.
703 1.1 christos * SOAs differ.
704 1.1 christos */
705 1.1 christos if (rdataset->type == dns_rdatatype_soa) {
706 1.5 christos if (RD_NEXT_RR(rdataset) == LIBRPZ_IDX_NULL) {
707 1.1 christos return (ISC_R_NOMORE);
708 1.5 christos }
709 1.1 christos RD_NEXT_RR(rdataset) = LIBRPZ_IDX_NULL;
710 1.5 christos if (!librpz->rsp_soa(&emsg, NULL, &rr, NULL, &rpsdb->result,
711 1.5 christos rpsdb->rsp)) {
712 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
713 1.1 christos return (DNS_R_SERVFAIL);
714 1.1 christos }
715 1.1 christos RD_CUR_RR(rdataset) = rr;
716 1.1 christos return (ISC_R_SUCCESS);
717 1.1 christos }
718 1.1 christos
719 1.1 christos rpsdb->result.next_rr = RD_NEXT_RR(rdataset);
720 1.1 christos for (;;) {
721 1.1 christos if (!librpz->rsp_rr(&emsg, &type, &class, NULL, &rr,
722 1.1 christos &rpsdb->result, rpsdb->qname->ndata,
723 1.5 christos rpsdb->qname->length, rpsdb->rsp))
724 1.5 christos {
725 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
726 1.1 christos return (DNS_R_SERVFAIL);
727 1.1 christos }
728 1.5 christos if (rdataset->type == type && rdataset->rdclass == class) {
729 1.1 christos RD_CUR_RR(rdataset) = rr;
730 1.1 christos RD_NEXT_RR(rdataset) = rpsdb->result.next_rr;
731 1.1 christos return (ISC_R_SUCCESS);
732 1.1 christos }
733 1.5 christos if (type == dns_rdatatype_none) {
734 1.1 christos return (ISC_R_NOMORE);
735 1.5 christos }
736 1.1 christos free(rr);
737 1.1 christos }
738 1.1 christos }
739 1.1 christos
740 1.1 christos static isc_result_t
741 1.1 christos rpsdb_rdataset_first(dns_rdataset_t *rdataset) {
742 1.1 christos rpsdb_t *rpsdb;
743 1.1 christos librpz_emsg_t emsg;
744 1.1 christos
745 1.1 christos rpsdb = RD_DB(rdataset);
746 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
747 1.1 christos
748 1.1 christos if (RD_CUR_RR(rdataset) != NULL) {
749 1.1 christos free(RD_CUR_RR(rdataset));
750 1.1 christos RD_CUR_RR(rdataset) = NULL;
751 1.1 christos }
752 1.1 christos
753 1.1 christos if (!librpz->rsp_result(&emsg, &rpsdb->result, true, rpsdb->rsp)) {
754 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
755 1.1 christos return (DNS_R_SERVFAIL);
756 1.1 christos }
757 1.5 christos if (rdataset->type == dns_rdatatype_soa) {
758 1.1 christos RD_NEXT_RR(rdataset) = LIBRPZ_IDX_BAD;
759 1.5 christos } else {
760 1.1 christos RD_NEXT_RR(rdataset) = rpsdb->result.next_rr;
761 1.5 christos }
762 1.1 christos
763 1.1 christos return (rpsdb_rdataset_next(rdataset));
764 1.1 christos }
765 1.1 christos
766 1.1 christos static void
767 1.1 christos rpsdb_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
768 1.1 christos rpsdb_t *rpsdb;
769 1.1 christos librpz_rr_t *rr;
770 1.1 christos isc_region_t r;
771 1.1 christos
772 1.1 christos rpsdb = RD_DB(rdataset);
773 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
774 1.1 christos rr = RD_CUR_RR(rdataset);
775 1.1 christos REQUIRE(rr != NULL);
776 1.1 christos
777 1.1 christos r.length = ntohs(rr->rdlength);
778 1.1 christos r.base = rr->rdata;
779 1.1 christos dns_rdata_fromregion(rdata, ntohs(rr->class), ntohs(rr->type), &r);
780 1.1 christos }
781 1.1 christos
782 1.1 christos static void
783 1.1 christos rpsdb_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
784 1.1 christos rpsdb_t *rpsdb;
785 1.1 christos dns_db_t *dbp;
786 1.1 christos
787 1.1 christos INSIST(!ISC_LINK_LINKED(target, link));
788 1.1 christos *target = *source;
789 1.1 christos ISC_LINK_INIT(target, link);
790 1.1 christos rpsdb = RD_DB(source);
791 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
792 1.1 christos dbp = NULL;
793 1.1 christos dns_db_attach(&rpsdb->common, &dbp);
794 1.1 christos RD_DB(target) = dbp;
795 1.1 christos RD_CUR_RR(target) = NULL;
796 1.1 christos RD_NEXT_RR(target) = LIBRPZ_IDX_NULL;
797 1.1 christos }
798 1.1 christos
799 1.1 christos static unsigned int
800 1.1 christos rpsdb_rdataset_count(dns_rdataset_t *rdataset) {
801 1.1 christos rpsdb_t *rpsdb;
802 1.1 christos
803 1.1 christos rpsdb = RD_DB(rdataset);
804 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
805 1.1 christos
806 1.1 christos return (RD_COUNT(rdataset));
807 1.1 christos }
808 1.1 christos
809 1.1 christos static void
810 1.1 christos rpsdb_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
811 1.1 christos rpsdb_t *rpsdb;
812 1.1 christos dns_rdatasetiter_t *iterator;
813 1.1 christos isc_mem_t *mctx;
814 1.1 christos
815 1.1 christos iterator = *iteratorp;
816 1.5 christos *iteratorp = NULL;
817 1.1 christos rpsdb = (rpsdb_t *)iterator->db;
818 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
819 1.1 christos
820 1.1 christos mctx = iterator->db->mctx;
821 1.1 christos dns_db_detachnode(iterator->db, &iterator->node);
822 1.1 christos isc_mem_put(mctx, iterator, sizeof(rpsdb_rdatasetiter_t));
823 1.1 christos }
824 1.1 christos
825 1.1 christos static isc_result_t
826 1.1 christos rpsdb_rdatasetiter_next(dns_rdatasetiter_t *iter) {
827 1.1 christos rpsdb_t *rpsdb;
828 1.1 christos rpsdb_rdatasetiter_t *rpsdb_iter;
829 1.1 christos dns_rdatatype_t next_type, type;
830 1.1 christos dns_rdataclass_t next_class, class;
831 1.1 christos uint32_t ttl;
832 1.1 christos librpz_emsg_t emsg;
833 1.1 christos
834 1.1 christos rpsdb = (rpsdb_t *)iter->db;
835 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
836 1.1 christos rpsdb_iter = (rpsdb_rdatasetiter_t *)iter;
837 1.1 christos
838 1.1 christos /*
839 1.1 christos * This function is only used after a policy has been chosen,
840 1.1 christos * and so without caring whether it is after recursion.
841 1.1 christos */
842 1.1 christos if (!librpz->rsp_result(&emsg, &rpsdb->result, true, rpsdb->rsp)) {
843 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
844 1.1 christos return (DNS_R_SERVFAIL);
845 1.1 christos }
846 1.1 christos /*
847 1.1 christos * Find the next class and type after the current class and type
848 1.1 christos * among the RRs in current result.
849 1.1 christos * As a side effect, count the number of those RRs.
850 1.1 christos */
851 1.1 christos rpsdb_iter->count = 0;
852 1.1 christos next_class = dns_rdataclass_reserved0;
853 1.1 christos next_type = dns_rdatatype_none;
854 1.1 christos for (;;) {
855 1.5 christos if (!librpz->rsp_rr(&emsg, &type, &class, &ttl, NULL,
856 1.5 christos &rpsdb->result, rpsdb->qname->ndata,
857 1.5 christos rpsdb->qname->length, rpsdb->rsp))
858 1.5 christos {
859 1.1 christos librpz->log(LIBRPZ_LOG_ERROR, NULL, "%s", emsg.c);
860 1.1 christos return (DNS_R_SERVFAIL);
861 1.1 christos }
862 1.1 christos if (type == dns_rdatatype_none) {
863 1.5 christos if (next_type == dns_rdatatype_none) {
864 1.1 christos return (ISC_R_NOMORE);
865 1.5 christos }
866 1.1 christos rpsdb_iter->type = next_type;
867 1.1 christos rpsdb_iter->class = next_class;
868 1.1 christos return (ISC_R_SUCCESS);
869 1.1 christos }
870 1.1 christos /*
871 1.1 christos * Skip RRs with the current class and type or before.
872 1.1 christos */
873 1.1 christos if (rpsdb_iter->class > class ||
874 1.1 christos (rpsdb_iter->class = class && rpsdb_iter->type >= type))
875 1.5 christos {
876 1.1 christos continue;
877 1.5 christos }
878 1.5 christos if (next_type == dns_rdatatype_none || next_class > class ||
879 1.5 christos (next_class == class && next_type > type))
880 1.5 christos {
881 1.1 christos /*
882 1.1 christos * This is the first of a subsequent class and type.
883 1.1 christos */
884 1.1 christos next_type = type;
885 1.1 christos next_class = class;
886 1.1 christos rpsdb_iter->ttl = ttl;
887 1.1 christos rpsdb_iter->count = 1;
888 1.1 christos rpsdb_iter->next_rr = rpsdb->result.next_rr;
889 1.1 christos } else if (next_type == type && next_class == class) {
890 1.1 christos ++rpsdb_iter->count;
891 1.1 christos }
892 1.1 christos }
893 1.1 christos }
894 1.1 christos
895 1.1 christos static isc_result_t
896 1.1 christos rpsdb_rdatasetiter_first(dns_rdatasetiter_t *iterator) {
897 1.1 christos rpsdb_t *rpsdb;
898 1.1 christos rpsdb_rdatasetiter_t *rpsdb_iter;
899 1.1 christos
900 1.1 christos rpsdb = (rpsdb_t *)iterator->db;
901 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
902 1.1 christos rpsdb_iter = (rpsdb_rdatasetiter_t *)iterator;
903 1.1 christos
904 1.1 christos rpsdb_iter->type = dns_rdatatype_none;
905 1.1 christos rpsdb_iter->class = dns_rdataclass_reserved0;
906 1.1 christos return (rpsdb_rdatasetiter_next(iterator));
907 1.1 christos }
908 1.1 christos
909 1.1 christos static void
910 1.1 christos rpsdb_rdatasetiter_current(dns_rdatasetiter_t *iterator,
911 1.5 christos dns_rdataset_t *rdataset) {
912 1.1 christos rpsdb_t *rpsdb;
913 1.1 christos rpsdb_rdatasetiter_t *rpsdb_iter;
914 1.1 christos
915 1.1 christos rpsdb = (rpsdb_t *)iterator->db;
916 1.1 christos REQUIRE(VALID_RPSDB(rpsdb));
917 1.1 christos rpsdb_iter = (rpsdb_rdatasetiter_t *)iterator;
918 1.1 christos REQUIRE(rpsdb_iter->type != dns_rdatatype_none);
919 1.1 christos
920 1.5 christos rpsdb_bind_rdataset(rdataset, rpsdb_iter->count, rpsdb_iter->next_rr,
921 1.5 christos rpsdb_iter->type, rpsdb_iter->class,
922 1.5 christos rpsdb_iter->ttl, rpsdb);
923 1.1 christos }
924 1.1 christos
925 1.1 christos static dns_dbmethods_t rpsdb_db_methods = {
926 1.1 christos rpsdb_attach,
927 1.1 christos rpsdb_detach,
928 1.5 christos NULL, /* beginload */
929 1.5 christos NULL, /* endload */
930 1.5 christos NULL, /* serialize */
931 1.5 christos NULL, /* dump */
932 1.5 christos NULL, /* currentversion */
933 1.5 christos NULL, /* newversion */
934 1.5 christos NULL, /* attachversion */
935 1.5 christos NULL, /* closeversion */
936 1.1 christos rpsdb_findnode,
937 1.1 christos rpsdb_finddb,
938 1.5 christos NULL, /* findzonecut*/
939 1.1 christos rpsdb_attachnode,
940 1.1 christos rpsdb_detachnode,
941 1.5 christos NULL, /* expirenode */
942 1.5 christos NULL, /* printnode */
943 1.5 christos NULL, /* createiterator */
944 1.1 christos rpsdb_findrdataset,
945 1.1 christos rpsdb_allrdatasets,
946 1.5 christos NULL, /* addrdataset */
947 1.5 christos NULL, /* subtractrdataset */
948 1.5 christos NULL, /* deleterdataset */
949 1.1 christos rpsdb_issecure,
950 1.5 christos NULL, /* nodecount */
951 1.5 christos NULL, /* ispersistent */
952 1.5 christos NULL, /* overmem */
953 1.5 christos NULL, /* settask */
954 1.1 christos rpsdb_getoriginnode,
955 1.5 christos NULL, /* transfernode */
956 1.5 christos NULL, /* getnsec3parameters */
957 1.5 christos NULL, /* findnsec3node */
958 1.5 christos NULL, /* setsigningtime */
959 1.5 christos NULL, /* getsigningtime */
960 1.5 christos NULL, /* resigned */
961 1.5 christos NULL, /* isdnssec */
962 1.5 christos NULL, /* getrrsetstats */
963 1.5 christos NULL, /* rpz_attach */
964 1.5 christos NULL, /* rpz_ready */
965 1.5 christos NULL, /* findnodeext */
966 1.5 christos NULL, /* findext */
967 1.5 christos NULL, /* setcachestats */
968 1.5 christos NULL, /* hashsize */
969 1.5 christos NULL, /* nodefullname */
970 1.5 christos NULL, /* getsize */
971 1.5 christos NULL, /* setservestalettl */
972 1.5 christos NULL, /* getservestalettl */
973 1.6 christos NULL, /* setservestalerefresh */
974 1.6 christos NULL, /* getservestalerefresh */
975 1.6 christos NULL, /* setgluecachestats */
976 1.6 christos NULL /* adjusthashsize */
977 1.1 christos };
978 1.1 christos
979 1.1 christos static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
980 1.1 christos rpsdb_rdataset_disassociate,
981 1.1 christos rpsdb_rdataset_first,
982 1.1 christos rpsdb_rdataset_next,
983 1.1 christos rpsdb_rdataset_current,
984 1.1 christos rpsdb_rdataset_clone,
985 1.1 christos rpsdb_rdataset_count,
986 1.1 christos NULL,
987 1.1 christos NULL,
988 1.1 christos NULL,
989 1.1 christos NULL,
990 1.1 christos NULL,
991 1.1 christos NULL,
992 1.1 christos NULL,
993 1.1 christos NULL,
994 1.1 christos NULL,
995 1.1 christos NULL
996 1.1 christos };
997 1.1 christos
998 1.1 christos static dns_rdatasetitermethods_t rpsdb_rdatasetiter_methods = {
999 1.5 christos rpsdb_rdatasetiter_destroy, rpsdb_rdatasetiter_first,
1000 1.5 christos rpsdb_rdatasetiter_next, rpsdb_rdatasetiter_current
1001 1.1 christos };
1002 1.1 christos
1003 1.1 christos #endif /* USE_DNSRPS */
1004