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

📄 xfrout.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 1999-2001, 2003  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 INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM 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: xfrout.c,v 1.101.2.5 2003/07/22 04:03:35 marka Exp $ */#include <config.h>#include <isc/formatcheck.h>#include <isc/mem.h>#include <isc/timer.h>#include <isc/print.h>#include <isc/util.h>#include <dns/db.h>#include <dns/dbiterator.h>#include <dns/fixedname.h>#include <dns/journal.h>#include <dns/message.h>#include <dns/peer.h>#include <dns/rdataclass.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatasetiter.h>#include <dns/result.h>#include <dns/soa.h>#include <dns/timer.h>#include <dns/view.h>#include <dns/zone.h>#include <dns/zt.h>#include <named/client.h>#include <named/log.h>#include <named/server.h>#include <named/xfrout.h>/* * Outgoing AXFR and IXFR. *//* * TODO: *  - IXFR over UDP */#define XFROUT_COMMON_LOGARGS \	ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT#define XFROUT_PROTOCOL_LOGARGS \	XFROUT_COMMON_LOGARGS, ISC_LOG_INFO#define XFROUT_DEBUG_LOGARGS(n) \	XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n)#define XFROUT_RR_LOGARGS \	XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL#define XFROUT_RR_LOGLEVEL	ISC_LOG_DEBUG(8)/* * Fail unconditionally and log as a client error. * The test against ISC_R_SUCCESS is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". */#define FAILC(code, msg) \	do {							\		result = (code);				\		ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \			   NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \			   "bad zone transfer request: %s (%s)", \		      	   msg, isc_result_totext(code));	\		if (result != ISC_R_SUCCESS) goto failure;	\	} while (0)#define FAILQ(code, msg, question, rdclass) \	do {							\		char _buf1[DNS_NAME_FORMATSIZE];		\		char _buf2[DNS_RDATACLASS_FORMATSIZE]; 		\		result = (code);				\		dns_name_format(question, _buf1, sizeof(_buf1));  \		dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \		ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \			   NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \			   "bad zone transfer request: '%s/%s': %s (%s)", \		      	   _buf1, _buf2, msg, isc_result_totext(code));	\		if (result != ISC_R_SUCCESS) goto failure;	\	} while (0)#define CHECK(op) \     	do { result = (op); 					\		if (result != ISC_R_SUCCESS) goto failure; 	\	} while (0)/**************************************************************************//* * A db_rr_iterator_t is an iterator that iterates over an entire database, * returning one RR at a time, in some arbitrary order. */typedef struct db_rr_iterator db_rr_iterator_t;struct db_rr_iterator {	isc_result_t		result;	dns_db_t		*db;    	dns_dbiterator_t 	*dbit;	dns_dbversion_t 	*ver;	isc_stdtime_t		now;	dns_dbnode_t		*node;	dns_fixedname_t		fixedname;    	dns_rdatasetiter_t 	*rdatasetit;	dns_rdataset_t 		rdataset;	dns_rdata_t		rdata;};static isc_result_tdb_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,		    isc_stdtime_t now);static isc_result_tdb_rr_iterator_first(db_rr_iterator_t *it);static isc_result_tdb_rr_iterator_next(db_rr_iterator_t *it);static voiddb_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,		       isc_uint32_t *ttl, dns_rdata_t **rdata);static voiddb_rr_iterator_destroy(db_rr_iterator_t *it);static isc_result_tdb_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,		    isc_stdtime_t now){	isc_result_t result;	it->db = db;	it->dbit = NULL;	it->ver = ver;	it->now = now;	it->node = NULL;	result = dns_db_createiterator(it->db, ISC_FALSE, &it->dbit);	if (result != ISC_R_SUCCESS)		return (result);	it->rdatasetit = NULL;	dns_rdata_init(&it->rdata);	dns_rdataset_init(&it->rdataset);	dns_fixedname_init(&it->fixedname);	INSIST(! dns_rdataset_isassociated(&it->rdataset));	it->result = ISC_R_SUCCESS;	return (it->result);}static isc_result_tdb_rr_iterator_first(db_rr_iterator_t *it) {	it->result = dns_dbiterator_first(it->dbit);	/*	 * The top node may be empty when out of zone glue exists.	 * Walk the tree to find the first node with data.	 */	while (it->result == ISC_R_SUCCESS) {		it->result = dns_dbiterator_current(it->dbit, &it->node,				    dns_fixedname_name(&it->fixedname));		if (it->result != ISC_R_SUCCESS)			return (it->result);		it->result = dns_db_allrdatasets(it->db, it->node,						 it->ver, it->now,						 &it->rdatasetit);		if (it->result != ISC_R_SUCCESS)			return (it->result);		it->result = dns_rdatasetiter_first(it->rdatasetit);		if (it->result != ISC_R_SUCCESS) {			/*			 * This node is empty. Try next node.			 */			dns_rdatasetiter_destroy(&it->rdatasetit);			dns_db_detachnode(it->db, &it->node);			it->result = dns_dbiterator_next(it->dbit);			continue;		}		dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);		it->result = dns_rdataset_first(&it->rdataset);		return (it->result);	}	return (it->result);}static isc_result_tdb_rr_iterator_next(db_rr_iterator_t *it) {	if (it->result != ISC_R_SUCCESS)		return (it->result);	INSIST(it->dbit != NULL);	INSIST(it->node != NULL);	INSIST(it->rdatasetit != NULL);	it->result = dns_rdataset_next(&it->rdataset);	if (it->result == ISC_R_NOMORE) {		dns_rdataset_disassociate(&it->rdataset);		it->result = dns_rdatasetiter_next(it->rdatasetit);		/*		 * The while loop body is executed more than once		 * only when an empty dbnode needs to be skipped.		 */		while (it->result == ISC_R_NOMORE) {			dns_rdatasetiter_destroy(&it->rdatasetit);			dns_db_detachnode(it->db, &it->node);			it->result = dns_dbiterator_next(it->dbit);			if (it->result == ISC_R_NOMORE) {				/* We are at the end of the entire database. */				return (it->result);			}			if (it->result != ISC_R_SUCCESS)				return (it->result);			it->result = dns_dbiterator_current(it->dbit,				    &it->node,				    dns_fixedname_name(&it->fixedname));			if (it->result != ISC_R_SUCCESS)				return (it->result);			it->result = dns_db_allrdatasets(it->db, it->node,					 it->ver, it->now,					 &it->rdatasetit);			if (it->result != ISC_R_SUCCESS)				return (it->result);			it->result = dns_rdatasetiter_first(it->rdatasetit);		}		if (it->result != ISC_R_SUCCESS)			return (it->result);		dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);		it->result = dns_rdataset_first(&it->rdataset);		if (it->result != ISC_R_SUCCESS)			return (it->result);	}	return (it->result);}static voiddb_rr_iterator_pause(db_rr_iterator_t *it) {	dns_dbiterator_pause(it->dbit);}static voiddb_rr_iterator_destroy(db_rr_iterator_t *it) {	if (dns_rdataset_isassociated(&it->rdataset))		dns_rdataset_disassociate(&it->rdataset);	if (it->rdatasetit != NULL)		dns_rdatasetiter_destroy(&it->rdatasetit);	if (it->node != NULL)		dns_db_detachnode(it->db, &it->node);	dns_dbiterator_destroy(&it->dbit);}static voiddb_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,		      isc_uint32_t *ttl, dns_rdata_t **rdata){	REQUIRE(name != NULL && *name == NULL);	REQUIRE(it->result == ISC_R_SUCCESS);	*name = dns_fixedname_name(&it->fixedname);	*ttl = it->rdataset.ttl;	dns_rdata_reset(&it->rdata);	dns_rdataset_current(&it->rdataset, &it->rdata);	*rdata = &it->rdata;}/**************************************************************************//* Log an RR (for debugging) */static voidlog_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) {	isc_result_t result;	isc_buffer_t buf;	char mem[2000];	dns_rdatalist_t rdl;	dns_rdataset_t rds;	dns_rdata_t rd = DNS_RDATA_INIT;	rdl.type = rdata->type;	rdl.rdclass = rdata->rdclass;	rdl.ttl = ttl;	ISC_LIST_INIT(rdl.rdata);	ISC_LINK_INIT(&rdl, link);	dns_rdataset_init(&rds);	dns_rdata_init(&rd);	dns_rdata_clone(rdata, &rd);	ISC_LIST_APPEND(rdl.rdata, &rd, link);	RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS);	isc_buffer_init(&buf, mem, sizeof(mem));	result = dns_rdataset_totext(&rds, name,				     ISC_FALSE, ISC_FALSE, &buf);	/*	 * We could use xfrout_log(), but that would produce	 * very long lines with a repetitive prefix.	 */	if (result == ISC_R_SUCCESS) {		/*		 * Get rid of final newline.		 */		INSIST(buf.used >= 1 &&		       ((char *) buf.base)[buf.used - 1] == '\n');		buf.used--;				isc_log_write(XFROUT_RR_LOGARGS, "%.*s",			      (int)isc_buffer_usedlength(&buf),			      (char *)isc_buffer_base(&buf));	} else {		isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>");	}}/**************************************************************************//* * An 'rrstream_t' is a polymorphic iterator that returns * a stream of resource records.  There are multiple implementations, * e.g. for generating AXFR and IXFR records streams. */typedef struct rrstream_methods rrstream_methods_t;typedef struct rrstream {	isc_mem_t 		*mctx;	rrstream_methods_t	*methods;} rrstream_t;struct rrstream_methods {	isc_result_t 		(*first)(rrstream_t *);	isc_result_t 		(*next)(rrstream_t *);	void			(*current)(rrstream_t *,					   dns_name_t **,					   isc_uint32_t *,					   dns_rdata_t **);	void	 		(*pause)(rrstream_t *);	void 			(*destroy)(rrstream_t **);};static voidrrstream_noop_pause(rrstream_t *rs) {	UNUSED(rs);}/**************************************************************************//* * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns * an IXFR-like RR stream from a journal file. * * The SOA at the beginning of each sequence of additions * or deletions are included in the stream, but the extra * SOAs at the beginning and end of the entire transfer are * not included. */typedef struct ixfr_rrstream {	rrstream_t		common;	dns_journal_t 		*journal;} ixfr_rrstream_t;/* Forward declarations. */static voidixfr_rrstream_destroy(rrstream_t **sp);static rrstream_methods_t ixfr_rrstream_methods;/* * Returns: anything dns_journal_open() or dns_journal_iter_init() * may return. */static isc_result_tixfr_rrstream_create(isc_mem_t *mctx,		     const char *journal_filename,		     isc_uint32_t begin_serial,		     isc_uint32_t end_serial,		     rrstream_t **sp){	ixfr_rrstream_t *s;	isc_result_t result;	INSIST(sp != NULL && *sp == NULL);	s = isc_mem_get(mctx, sizeof(*s));	if (s == NULL)		return (ISC_R_NOMEMORY);	s->common.mctx = mctx;	s->common.methods = &ixfr_rrstream_methods;	s->journal = NULL;	CHECK(dns_journal_open(mctx, journal_filename,			       ISC_FALSE, &s->journal));	CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial));	*sp = (rrstream_t *) s;	return (ISC_R_SUCCESS); failure:	ixfr_rrstream_destroy((rrstream_t **) &s);	return (result);}static isc_result_tixfr_rrstream_first(rrstream_t *rs) {	ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs;	return (dns_journal_first_rr(s->journal));}static isc_result_t

⌨️ 快捷键说明

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