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