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