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

📄 update.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	dns_name_t *name;	dns_rdata_t *update_rr;} conditional_delete_ctx_t;/* * Predicate functions for delete_if(). *//* * Return true iff 'update_rr' is neither a SOA nor an NS RR. */static isc_boolean_ttype_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {	UNUSED(update_rr);	return ((db_rr->type != dns_rdatatype_soa &&		 db_rr->type != dns_rdatatype_ns) ?		ISC_TRUE : ISC_FALSE);}/* * Return true always. */static isc_boolean_ttrue_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {	UNUSED(update_rr);	UNUSED(db_rr);	return (ISC_TRUE);}/* * Return true iff the two RRs have identical rdata. */static isc_boolean_trr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {	/*	 * XXXRTH  This is not a problem, but we should consider creating	 *         dns_rdata_equal() (that used dns_name_equal()), since it	 *         would be faster.  Not a priority.	 */	return (dns_rdata_compare(update_rr, db_rr) == 0 ?		ISC_TRUE : ISC_FALSE);}/* * Return true iff 'update_rr' should replace 'db_rr' according * to the special RFC2136 rules for CNAME, SOA, and WKS records. * * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs * make little sense, so we replace those, too. */static isc_boolean_treplaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {	if (db_rr->type != update_rr->type)		return (ISC_FALSE);	if (db_rr->type == dns_rdatatype_cname)		return (ISC_TRUE);	if (db_rr->type == dns_rdatatype_dname)		return (ISC_TRUE);	if (db_rr->type == dns_rdatatype_soa)		return (ISC_TRUE);	if (db_rr->type == dns_rdatatype_nsec)		return (ISC_TRUE);	if (db_rr->type == dns_rdatatype_wks) {		/*		 * Compare the address and protocol fields only.  These		 * form the first five bytes of the RR data.  Do a		 * raw binary comparison; unpacking the WKS RRs using		 * dns_rdata_tostruct() might be cleaner in some ways,		 * but it would require us to pass around an mctx.		 */		INSIST(db_rr->length >= 5 && update_rr->length >= 5);		return (memcmp(db_rr->data, update_rr->data, 5) == 0 ?			ISC_TRUE : ISC_FALSE);	}	return (ISC_FALSE);}/* * Internal helper function for delete_if(). */static isc_result_tdelete_if_action(void *data, rr_t *rr) {	conditional_delete_ctx_t *ctx = data;	if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) {		isc_result_t result;		result = update_one_rr(ctx->db, ctx->ver, ctx->diff,				       DNS_DIFFOP_DEL, ctx->name,				       rr->ttl, &rr->rdata);		return (result);	} else {		return (ISC_R_SUCCESS);	}}/* * Conditionally delete RRs.  Apply 'predicate' to the RRs * specified by 'db', 'ver', 'name', and 'type' (which can * be dns_rdatatype_any to match any type).  Delete those * RRs for which the predicate returns true, and log the * deletions in 'diff'. */static isc_result_tdelete_if(rr_predicate *predicate,	  dns_db_t *db,	  dns_dbversion_t *ver,	  dns_name_t *name,	  dns_rdatatype_t type,	  dns_rdatatype_t covers,	  dns_rdata_t *update_rr,	  dns_diff_t *diff){	conditional_delete_ctx_t ctx;	ctx.predicate = predicate;	ctx.db = db;	ctx.ver = ver;	ctx.diff = diff;	ctx.name = name;	ctx.update_rr = update_rr;	return (foreach_rr(db, ver, name, type, covers,			   delete_if_action, &ctx));}/**************************************************************************//* * Prepare an RR for the addition of the new RR 'ctx->update_rr', * with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting * the RRs if it is replaced by the new RR or has a conflicting TTL. * The necessary changes are appended to ctx->del_diff and ctx->add_diff; * we need to do all deletions before any additions so that we don't run * into transient states with conflicting TTLs. */typedef struct {	dns_db_t *db;	dns_dbversion_t *ver;	dns_diff_t *diff;	dns_name_t *name;	dns_rdata_t *update_rr;	dns_ttl_t update_rr_ttl;	isc_boolean_t ignore_add;	dns_diff_t del_diff;	dns_diff_t add_diff;} add_rr_prepare_ctx_t;static isc_result_tadd_rr_prepare_action(void *data, rr_t *rr) {	isc_result_t result = ISC_R_SUCCESS;		add_rr_prepare_ctx_t *ctx = data;	dns_difftuple_t *tuple = NULL;	isc_boolean_t equal;	/*	 * If the update RR is a "duplicate" of the update RR,	 * the update should be silently ignored.	 */	equal = ISC_TF(dns_rdata_compare(&rr->rdata, ctx->update_rr) == 0);	if (equal && rr->ttl == ctx->update_rr_ttl) {		ctx->ignore_add = ISC_TRUE;		return (ISC_R_SUCCESS);	}	/*	 * If this RR is "equal" to the update RR, it should	 * be deleted before the update RR is added.	 */	if (replaces_p(ctx->update_rr, &rr->rdata)) {		CHECK(dns_difftuple_create(ctx->del_diff.mctx,					   DNS_DIFFOP_DEL, ctx->name,					   rr->ttl,					   &rr->rdata,					   &tuple));		dns_diff_append(&ctx->del_diff, &tuple);		return (ISC_R_SUCCESS);	}	/*	 * If this RR differs in TTL from the update RR,	 * its TTL must be adjusted.	 */	if (rr->ttl != ctx->update_rr_ttl) {		CHECK(dns_difftuple_create(ctx->del_diff.mctx,					   DNS_DIFFOP_DEL, ctx->name,					   rr->ttl,					   &rr->rdata,					   &tuple));		dns_diff_append(&ctx->del_diff, &tuple);		if (!equal) {			CHECK(dns_difftuple_create(ctx->add_diff.mctx,						   DNS_DIFFOP_ADD, ctx->name,						   ctx->update_rr_ttl,						   &rr->rdata,						   &tuple));			dns_diff_append(&ctx->add_diff, &tuple);		}	} failure:	return (result);}/**************************************************************************//* * Miscellaneous subroutines. *//* * Extract a single update RR from 'section' of dynamic update message * 'msg', with consistency checking. * * Stores the owner name, rdata, and TTL of the update RR at 'name', * 'rdata', and 'ttl', respectively. */static voidget_current_rr(dns_message_t *msg, dns_section_t section,	       dns_rdataclass_t zoneclass,	       dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers,	       dns_ttl_t *ttl,	       dns_rdataclass_t *update_class){	dns_rdataset_t *rdataset;	isc_result_t result;	dns_message_currentname(msg, section, name);	rdataset = ISC_LIST_HEAD((*name)->list);	INSIST(rdataset != NULL);	INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);	*covers = rdataset->covers;	*ttl = rdataset->ttl;	result = dns_rdataset_first(rdataset);	INSIST(result == ISC_R_SUCCESS);	dns_rdataset_current(rdataset, rdata);	INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE);	*update_class = rdata->rdclass;	rdata->rdclass = zoneclass;}/* * Increment the SOA serial number of database 'db', version 'ver'. * Replace the SOA record in the database, and log the * change in 'diff'. */	/*	 * XXXRTH  Failures in this routine will be worth logging, when	 *         we have a logging system.  Failure to find the zonename	 *	   or the SOA rdataset warrant at least an UNEXPECTED_ERROR().	 */static isc_result_tincrement_soa_serial(dns_db_t *db, dns_dbversion_t *ver,		     dns_diff_t *diff, isc_mem_t *mctx){	dns_difftuple_t *deltuple = NULL;	dns_difftuple_t *addtuple = NULL;	isc_uint32_t serial;	isc_result_t result;	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));	CHECK(dns_difftuple_copy(deltuple, &addtuple));	addtuple->op = DNS_DIFFOP_ADD;	serial = dns_soa_getserial(&addtuple->rdata);	/* RFC1982 */	serial = (serial + 1) & 0xFFFFFFFF;	if (serial == 0)		serial = 1;	dns_soa_setserial(serial, &addtuple->rdata);	CHECK(do_one_tuple(&deltuple, db, ver, diff));	CHECK(do_one_tuple(&addtuple, db, ver, diff));	result = ISC_R_SUCCESS; failure:	if (addtuple != NULL)		dns_difftuple_free(&addtuple);	if (deltuple != NULL)		dns_difftuple_free(&deltuple);	return (result);}/* * Check that the new SOA record at 'update_rdata' does not * illegally cause the SOA serial number to decrease or stay * unchanged relative to the existing SOA in 'db'. * * Sets '*ok' to ISC_TRUE if the update is legal, ISC_FALSE if not. * * William King points out that RFC2136 is inconsistent about * the case where the serial number stays unchanged: * *   section 3.4.2.2 requires a server to ignore a SOA update request *   if the serial number on the update SOA is less_than_or_equal to *   the zone SOA serial. * *   section 3.6 requires a server to ignore a SOA update request if *   the serial is less_than the zone SOA serial. * * Paul says 3.4.2.2 is correct. * */static isc_result_tcheck_soa_increment(dns_db_t *db, dns_dbversion_t *ver,		    dns_rdata_t *update_rdata,		    isc_boolean_t *ok){	isc_uint32_t db_serial;	isc_uint32_t update_serial;	isc_result_t result;	update_serial = dns_soa_getserial(update_rdata);	result = dns_db_getsoaserial(db, ver, &db_serial);	if (result != ISC_R_SUCCESS)		return (result);	if (DNS_SERIAL_GE(db_serial, update_serial)) {		*ok = ISC_FALSE;	} else {		*ok = ISC_TRUE;	}	return (ISC_R_SUCCESS);}/**************************************************************************//* * Incremental updating of NSECs and RRSIGs. */#define MAXZONEKEYS 32	/* Maximum number of zone keys supported. *//* * We abuse the dns_diff_t type to represent a set of domain names * affected by the update. */static isc_result_tnamelist_append_name(dns_diff_t *list, dns_name_t *name) {	isc_result_t result;	dns_difftuple_t *tuple = NULL;	static dns_rdata_t dummy_rdata = { NULL, 0, 0, 0, 0,					   { (void*)(-1), (void*)(-1) } };	CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0,				   &dummy_rdata, &tuple));	dns_diff_append(list, &tuple); failure:	return (result);}static isc_result_tnamelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected){	isc_result_t result;	dns_fixedname_t fixedname;	dns_name_t *child;	dns_dbiterator_t *dbit = NULL;	dns_fixedname_init(&fixedname);	child = dns_fixedname_name(&fixedname);	CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit));	for (result = dns_dbiterator_seek(dbit, name);	     result == ISC_R_SUCCESS;	     result = dns_dbiterator_next(dbit))	{		dns_dbnode_t *node = NULL;		CHECK(dns_dbiterator_current(dbit, &node, child));		dns_db_detachnode(db, &node);		if (! dns_name_issubdomain(child, name))			break;		CHECK(namelist_append_name(affected, child));	}	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS; failure:	if (dbit != NULL)		dns_dbiterator_destroy(&dbit);	return (result);}/* * Helper function for non_nsec_rrset_exists(). */static isc_result_tis_non_nsec_action(void *data, dns_rdataset_t *rrset) {	UNUSED(data);	if (!(rrset->type == dns_rdatatype_nsec ||	      (rrset->type == dns_rdatatype_rrsig &&	       rrset->covers == dns_rdatatype_nsec)))		return (ISC_R_EXISTS);	return (ISC_R_SUCCESS);}/* * Check whether there is an rrset other than a NSEC or RRSIG NSEC, * i.e., anything that justifies the continued existence of a name * after a secure update. * * If such an rrset exists, set '*exists' to ISC_TRUE. * Otherwise, set it to ISC_FALSE. */static isc_result_tnon_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver,		     dns_name_t *name, isc_boolean_t *exists){	isc_result_t result;	result = foreach_rrset(db, ver, name,			       is_non_nsec_action, NULL);	RETURN_EXISTENCE_FLAG;}/* * A comparison function for sorting dns_diff_t:s by name. */static intname_order(const void *av, const void *bv) {	dns_difftuple_t const * const *ap = av;	dns_difftuple_t const * const *bp = bv;	dns_difftuple_t const *a = *ap;	dns_difftuple_t const *b = *bp;	return (dns_name_compare(&a->name, &b->name));}static isc_result_tuniqify_name_list(dns_diff_t *list) {	isc_result_t result;	dns_difftuple_t *p, *q;	CHECK(dns_diff_sort(list, name_order));	p = ISC_LIST_HEAD(list->tuples);	while (p != NULL) {		do {			q = ISC_LIST_NEXT(p, link);			if (q == NULL || ! dns_name_equal(&p->name, &q->name))				break;			ISC_LIST_UNLINK(list->tuples, q, link);			dns_difftuple_free(&q);		} while (1);		p = ISC_LIST_NEXT(p, link);	} failure:	return (result);}static isc_result_tis_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,	isc_boolean_t *flag){	isc_result_t result;	dns_fixedname_t foundname;	dns_fixedname_init(&foundname);	result = dns_db_find(db, name, ver, dns_rdatatype_any,			     DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,			     (isc_stdtime_t) 0, NULL,			     dns_fixedname_name(&foundname),			     NULL, NULL);	if (result == ISC_R_SUCCESS) {		*flag = ISC_FALSE;		return (ISC_R_SUCCESS);	} else if (result == DNS_R_ZONECUT) {		/*		 * We are at the zonecut.  The name will have an NSEC, but		 * non-delegation will be omitted from the type bit map.		 */		*flag = ISC_FALSE;		return (ISC_R_SUCCESS);	} else if (result == DNS_R_GLUE || result == DNS_R_DNAME) {		*flag = ISC_TRUE;		return (ISC_R_SUCCESS);	} else {		return (result);	}}/*

⌨️ 快捷键说明

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