⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdlz.c

📁 非常好的dns解析软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Portions Copyright (C) 2005-2007  Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was * conceived and contributed by Rob Butler. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. *//* $Id: sdlz.c,v 1.2.2.9 2007/02/14 23:45:43 marka Exp $ *//*! \file */#include <config.h>#include <string.h>#include <isc/buffer.h>#include <isc/lex.h>#include <isc/log.h>#include <isc/rwlock.h>#include <isc/string.h>#include <isc/util.h>#include <isc/magic.h>#include <isc/mem.h>#include <isc/once.h>#include <isc/print.h>#include <isc/region.h>#include <dns/callbacks.h>#include <dns/db.h>#include <dns/dbiterator.h>#include <dns/dlz.h>#include <dns/fixedname.h>#include <dns/log.h>#include <dns/rdata.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatasetiter.h>#include <dns/rdatatype.h>#include <dns/result.h>#include <dns/master.h>#include <dns/sdlz.h>#include <dns/types.h>#include "rdatalist_p.h"/* * Private Types */struct dns_sdlzimplementation {	const dns_sdlzmethods_t		*methods;	isc_mem_t			*mctx;	void				*driverarg;	unsigned int			flags;	isc_mutex_t			driverlock;	dns_dlzimplementation_t		*dlz_imp;};struct dns_sdlz_db {	/* Unlocked */	dns_db_t			common;	void				*dbdata;	dns_sdlzimplementation_t	*dlzimp;	isc_mutex_t			refcnt_lock;	/* Locked */	unsigned int			references;};struct dns_sdlzlookup {	/* Unlocked */	unsigned int			magic;	dns_sdlz_db_t			*sdlz;	ISC_LIST(dns_rdatalist_t)	lists;	ISC_LIST(isc_buffer_t)		buffers;	dns_name_t			*name;	ISC_LINK(dns_sdlzlookup_t)	link;	isc_mutex_t			lock;	dns_rdatacallbacks_t		callbacks;	/* Locked */	unsigned int			references;};typedef struct dns_sdlzlookup dns_sdlznode_t;struct dns_sdlzallnodes {	dns_dbiterator_t		common;	ISC_LIST(dns_sdlznode_t)	nodelist;	dns_sdlznode_t			*current;	dns_sdlznode_t			*origin;};typedef dns_sdlzallnodes_t sdlz_dbiterator_t;typedef struct sdlz_rdatasetiter {	dns_rdatasetiter_t		common;	dns_rdatalist_t			*current;} sdlz_rdatasetiter_t;#define SDLZDB_MAGIC		ISC_MAGIC('D', 'L', 'Z', 'S')/* * Note that "impmagic" is not the first four bytes of the struct, so * ISC_MAGIC_VALID cannot be used. */#define VALID_SDLZDB(sdlzdb)	((sdlzdb) != NULL && \				 (sdlzdb)->common.impmagic == SDLZDB_MAGIC)#define SDLZLOOKUP_MAGIC	ISC_MAGIC('D','L','Z','L')#define VALID_SDLZLOOKUP(sdlzl)	ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC)#define VALID_SDLZNODE(sdlzn)	VALID_SDLZLOOKUP(sdlzn)/* These values are taken from RFC 1537 */#define SDLZ_DEFAULT_REFRESH	(60 * 60 * 8)#define SDLZ_DEFAULT_RETRY	(60 * 60 * 2)#define SDLZ_DEFAULT_EXPIRE	(60 * 60 * 24 * 7)#define SDLZ_DEFAULT_MINIMUM	(60 * 60 * 24)/* This is a reasonable value */#define SDLZ_DEFAULT_TTL	(60 * 60 * 24)static int dummy;#define MAYBE_LOCK(imp) \	do { \		unsigned int flags = imp->flags; \		if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \			LOCK(&imp->driverlock); \	} while (0)#define MAYBE_UNLOCK(imp) \	do { \		unsigned int flags = imp->flags; \		if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \			UNLOCK(&imp->driverlock); \	} while (0)/* * Forward references.  Try to keep these to a minimum. */static void list_tordataset(dns_rdatalist_t *rdatalist,			    dns_db_t *db, dns_dbnode_t *node,			    dns_rdataset_t *rdataset);static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);static void		dbiterator_destroy(dns_dbiterator_t **iteratorp);static isc_result_t	dbiterator_first(dns_dbiterator_t *iterator);static isc_result_t	dbiterator_last(dns_dbiterator_t *iterator);static isc_result_t	dbiterator_seek(dns_dbiterator_t *iterator,					dns_name_t *name);static isc_result_t	dbiterator_prev(dns_dbiterator_t *iterator);static isc_result_t	dbiterator_next(dns_dbiterator_t *iterator);static isc_result_t	dbiterator_current(dns_dbiterator_t *iterator,					   dns_dbnode_t **nodep,					   dns_name_t *name);static isc_result_t	dbiterator_pause(dns_dbiterator_t *iterator);static isc_result_t	dbiterator_origin(dns_dbiterator_t *iterator,					  dns_name_t *name);static dns_dbiteratormethods_t dbiterator_methods = {	dbiterator_destroy,	dbiterator_first,	dbiterator_last,	dbiterator_seek,	dbiterator_prev,	dbiterator_next,	dbiterator_current,	dbiterator_pause,	dbiterator_origin};/* * Utility functions *//*% Converts the input string to lowercase, in place. */static voiddns_sdlz_tolower(char *str) {	unsigned int len = strlen(str);	unsigned int i;	for (i = 0; i < len; i++) {		if (str[i] >= 'A' && str[i] <= 'Z')			str[i] += 32;	}}static inline unsigned intinitial_size(const char *data) {	unsigned int len = (strlen(data) / 64) + 1;	return (len * 64 + 64);}/* * Rdataset Iterator Methods. These methods were "borrowed" from the SDB * driver interface.  See the SDB driver interface documentation for more info. */static voidrdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {	sdlz_rdatasetiter_t *sdlziterator =		(sdlz_rdatasetiter_t *)(*iteratorp);	detachnode(sdlziterator->common.db, &sdlziterator->common.node);	isc_mem_put(sdlziterator->common.db->mctx, sdlziterator,		    sizeof(sdlz_rdatasetiter_t));	*iteratorp = NULL;}static isc_result_trdatasetiter_first(dns_rdatasetiter_t *iterator) {	sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;	dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node;	if (ISC_LIST_EMPTY(sdlznode->lists))		return (ISC_R_NOMORE);	sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists);	return (ISC_R_SUCCESS);}static isc_result_trdatasetiter_next(dns_rdatasetiter_t *iterator) {	sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;	sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link);	if (sdlziterator->current == NULL)		return (ISC_R_NOMORE);	else		return (ISC_R_SUCCESS);}static voidrdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {	sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;	list_tordataset(sdlziterator->current, iterator->db, iterator->node,			rdataset);}static dns_rdatasetitermethods_t rdatasetiter_methods = {	rdatasetiter_destroy,	rdatasetiter_first,	rdatasetiter_next,	rdatasetiter_current};/* * DB routines. These methods were "borrowed" from the SDB driver interface. * See the SDB driver interface documentation for more info. */static voidattach(dns_db_t *source, dns_db_t **targetp) {	dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source;	REQUIRE(VALID_SDLZDB(sdlz));	LOCK(&sdlz->refcnt_lock);	REQUIRE(sdlz->references > 0);	sdlz->references++;	UNLOCK(&sdlz->refcnt_lock);	*targetp = source;}static voiddestroy(dns_sdlz_db_t *sdlz) {	isc_mem_t *mctx;	mctx = sdlz->common.mctx;	sdlz->common.magic = 0;	sdlz->common.impmagic = 0;	isc_mutex_destroy(&sdlz->refcnt_lock);	dns_name_free(&sdlz->common.origin, mctx);	isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));	isc_mem_detach(&mctx);}static voiddetach(dns_db_t **dbp) {	dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);	isc_boolean_t need_destroy = ISC_FALSE;	REQUIRE(VALID_SDLZDB(sdlz));	LOCK(&sdlz->refcnt_lock);	REQUIRE(sdlz->references > 0);	sdlz->references--;	if (sdlz->references == 0)		need_destroy = ISC_TRUE;	UNLOCK(&sdlz->refcnt_lock);	if (need_destroy)		destroy(sdlz);	*dbp = NULL;}static isc_result_tbeginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) {	UNUSED(db);	UNUSED(addp);	UNUSED(dbloadp);	return (ISC_R_NOTIMPLEMENTED);}static isc_result_tendload(dns_db_t *db, dns_dbload_t **dbloadp) {	UNUSED(db);	UNUSED(dbloadp);	return (ISC_R_NOTIMPLEMENTED);}static isc_result_tdump(dns_db_t *db, dns_dbversion_t *version, const char *filename,     dns_masterformat_t masterformat){	UNUSED(db);	UNUSED(version);	UNUSED(filename);	UNUSED(masterformat);	return (ISC_R_NOTIMPLEMENTED);}static voidcurrentversion(dns_db_t *db, dns_dbversion_t **versionp) {	REQUIRE(versionp != NULL && *versionp == NULL);	UNUSED(db);	*versionp = (void *) &dummy;	return;}static isc_result_tnewversion(dns_db_t *db, dns_dbversion_t **versionp) {	UNUSED(db);	UNUSED(versionp);	return (ISC_R_NOTIMPLEMENTED);}static voidattachversion(dns_db_t *db, dns_dbversion_t *source,	      dns_dbversion_t **targetp){	REQUIRE(source != NULL && source == (void *) &dummy);	UNUSED(db);	UNUSED(source);	UNUSED(targetp);	*targetp = source;}static voidcloseversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {	REQUIRE(versionp != NULL && *versionp == (void *) &dummy);	REQUIRE(commit == ISC_FALSE);	UNUSED(db);	UNUSED(commit);	*versionp = NULL;}static isc_result_tcreatenode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) {	dns_sdlznode_t *node;	isc_result_t result;	node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t));	if (node == NULL)		return (ISC_R_NOMEMORY);	node->sdlz = NULL;	attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz);	ISC_LIST_INIT(node->lists);	ISC_LIST_INIT(node->buffers);	ISC_LINK_INIT(node, link);	node->name = NULL;	result = isc_mutex_init(&node->lock);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mutex_init() failed: %s",				 isc_result_totext(result));		isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t));		return (ISC_R_UNEXPECTED);	}	dns_rdatacallbacks_init(&node->callbacks);	node->references = 1;	node->magic = SDLZLOOKUP_MAGIC;	*nodep = node;	return (ISC_R_SUCCESS);}static voiddestroynode(dns_sdlznode_t *node) {	dns_rdatalist_t *list;	dns_rdata_t *rdata;	isc_buffer_t *b;	dns_sdlz_db_t *sdlz;	dns_db_t *db;	isc_mem_t *mctx;	sdlz = node->sdlz;	mctx = sdlz->common.mctx;	while (!ISC_LIST_EMPTY(node->lists)) {		list = ISC_LIST_HEAD(node->lists);		while (!ISC_LIST_EMPTY(list->rdata)) {			rdata = ISC_LIST_HEAD(list->rdata);			ISC_LIST_UNLINK(list->rdata, rdata, link);			isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));		}		ISC_LIST_UNLINK(node->lists, list, link);		isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));	}	while (!ISC_LIST_EMPTY(node->buffers)) {		b = ISC_LIST_HEAD(node->buffers);		ISC_LIST_UNLINK(node->buffers, b, link);		isc_buffer_free(&b);	}	if (node->name != NULL) {		dns_name_free(node->name, mctx);		isc_mem_put(mctx, node->name, sizeof(dns_name_t));	}	DESTROYLOCK(&node->lock);	node->magic = 0;	isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));	db = &sdlz->common;	detach(&db);}static isc_result_tfindnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,	 dns_dbnode_t **nodep){	dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;	dns_sdlznode_t *node = NULL;	isc_result_t result;	isc_buffer_t b;	char namestr[DNS_NAME_MAXTEXT + 1];	isc_buffer_t b2;	char zonestr[DNS_NAME_MAXTEXT + 1];	isc_boolean_t isorigin;	dns_sdlzauthorityfunc_t authority;	REQUIRE(VALID_SDLZDB(sdlz));	REQUIRE(create == ISC_FALSE);	REQUIRE(nodep != NULL && *nodep == NULL);	UNUSED(name);	UNUSED(create);	isc_buffer_init(&b, namestr, sizeof(namestr));	if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) {		dns_name_t relname;		unsigned int labels;		labels = dns_name_countlabels(name) -			 dns_name_countlabels(&db->origin);		dns_name_init(&relname, NULL);		dns_name_getlabelsequence(name, 0, labels, &relname);		result = dns_name_totext(&relname, ISC_TRUE, &b);		if (result != ISC_R_SUCCESS)			return (result);	} else {		result = dns_name_totext(name, ISC_TRUE, &b);		if (result != ISC_R_SUCCESS)			return (result);	}	isc_buffer_putuint8(&b, 0);	isc_buffer_init(&b2, zonestr, sizeof(zonestr));	result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2);	if (result != ISC_R_SUCCESS)		return (result);	isc_buffer_putuint8(&b2, 0);	result = createnode(sdlz, &node);	if (result != ISC_R_SUCCESS)		return (result);	isorigin = dns_name_equal(name, &sdlz->common.origin);	/* make sure strings are always lowercase */	dns_sdlz_tolower(zonestr);	dns_sdlz_tolower(namestr);	MAYBE_LOCK(sdlz->dlzimp);	/* try to lookup the host (namestr) */	result = sdlz->dlzimp->methods->lookup(zonestr, namestr,					       sdlz->dlzimp->driverarg,					       sdlz->dbdata, node);	/*	 * if the host (namestr) was not found, try to lookup a	 * "wildcard" host.	 */	if (result != ISC_R_SUCCESS) {		result = sdlz->dlzimp->methods->lookup(zonestr, "*",						       sdlz->dlzimp->driverarg,						       sdlz->dbdata, node);	}	MAYBE_UNLOCK(sdlz->dlzimp);	if (result != ISC_R_SUCCESS && !isorigin) {		destroynode(node);		return (result);	}	if (isorigin && sdlz->dlzimp->methods->authority != NULL) {		MAYBE_LOCK(sdlz->dlzimp);		authority = sdlz->dlzimp->methods->authority;		result = (*authority)(zonestr, sdlz->dlzimp->driverarg,				      sdlz->dbdata, node);		MAYBE_UNLOCK(sdlz->dlzimp);		if (result != ISC_R_SUCCESS &&		    result != ISC_R_NOTIMPLEMENTED) {			destroynode(node);			return (result);		}	}	*nodep = node;	return (ISC_R_SUCCESS);}static isc_result_tfindzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,	    isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,	    dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset){	UNUSED(db);	UNUSED(name);	UNUSED(options);	UNUSED(now);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -