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

📄 update.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Find the next/previous name that has a NSEC record. * In other words, skip empty database nodes and names that * have had their NSECs removed because they are obscured by * a zone cut. */static isc_result_tnext_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,	    dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname,	    isc_boolean_t forward){	isc_result_t result;	dns_dbiterator_t *dbit = NULL;	isc_boolean_t has_nsec;	unsigned int wraps = 0;	CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit));	CHECK(dns_dbiterator_seek(dbit, oldname));	do {		dns_dbnode_t *node = NULL;		if (forward)			result = dns_dbiterator_next(dbit);		else			result = dns_dbiterator_prev(dbit);		if (result == ISC_R_NOMORE) {			/*			 * Wrap around.			 */			if (forward)				CHECK(dns_dbiterator_first(dbit));			else				CHECK(dns_dbiterator_last(dbit));			wraps++;			if (wraps == 2) {				update_log(client, zone, ISC_LOG_ERROR,					   "secure zone with no NSECs");				result = DNS_R_BADZONE;				goto failure;			}		}		CHECK(dns_dbiterator_current(dbit, &node, newname));		dns_db_detachnode(db, &node);		/*		 * The iterator may hold the tree lock, and		 * rrset_exists() calls dns_db_findnode() which		 * may try to reacquire it.  To avoid deadlock		 * we must pause the iterator first.		 */		CHECK(dns_dbiterator_pause(dbit));		CHECK(rrset_exists(db, ver, newname,				   dns_rdatatype_nsec, 0, &has_nsec));	} while (! has_nsec); failure:	if (dbit != NULL)		dns_dbiterator_destroy(&dbit);	return (result);}/* * Add a NSEC record for "name", recording the change in "diff". * The existing NSEC is removed. */static isc_result_tadd_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,	dns_dbversion_t *ver, dns_name_t *name, dns_diff_t *diff){	isc_result_t result;	dns_dbnode_t *node = NULL;	unsigned char buffer[DNS_NSEC_BUFFERSIZE];	dns_rdata_t rdata = DNS_RDATA_INIT;	dns_difftuple_t *tuple = NULL;	dns_fixedname_t fixedname;	dns_name_t *target;	dns_fixedname_init(&fixedname);	target = dns_fixedname_name(&fixedname);	/*	 * Find the successor name, aka NSEC target.	 */	CHECK(next_active(client, zone, db, ver, name, target, ISC_TRUE));	/*	 * Create the NSEC RDATA.	 */	CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));	dns_rdata_init(&rdata);	CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata));	dns_db_detachnode(db, &node);	/*	 * Delete the old NSEC and record the change.	 */	CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0,			NULL, diff));	/*	 * Add the new NSEC and record the change.	 */	CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,				   3600,	/* XXXRTH */				   &rdata, &tuple));	CHECK(do_one_tuple(&tuple, db, ver, diff));	INSIST(tuple == NULL); failure:	if (node != NULL)		dns_db_detachnode(db, &node);	return (result);}/* * Add a placeholder NSEC record for "name", recording the change in "diff". */static isc_result_tadd_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,		    dns_diff_t *diff) {	isc_result_t result;	dns_difftuple_t *tuple = NULL;	isc_region_t r;	unsigned char data[1] = { 0 }; /* The root domain, no bits. */	dns_rdata_t rdata = DNS_RDATA_INIT;	r.base = data;	r.length = sizeof(data);	dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r);	CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0,				   &rdata, &tuple));	CHECK(do_one_tuple(&tuple, db, ver, diff)); failure:	return (result);}static isc_result_tfind_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,	       isc_mem_t *mctx, unsigned int maxkeys,	       dst_key_t **keys, unsigned int *nkeys){	isc_result_t result;	dns_dbnode_t *node = NULL;	const char *directory = dns_zone_getkeydirectory(zone);	CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));	CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),				       directory, mctx, maxkeys, keys, nkeys)); failure:	if (node != NULL)		dns_db_detachnode(db, &node);	return (result);}/* * Add RRSIG records for an RRset, recording the change in "diff". */static isc_result_tadd_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,	 isc_stdtime_t expire){	isc_result_t result;	dns_dbnode_t *node = NULL;	dns_rdataset_t rdataset;	dns_rdata_t sig_rdata = DNS_RDATA_INIT;	isc_buffer_t buffer;	unsigned char data[1024]; /* XXX */	unsigned int i;	dns_rdataset_init(&rdataset);	isc_buffer_init(&buffer, data, sizeof(data));	/* Get the rdataset to sign. */	CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));	CHECK(dns_db_findrdataset(db, node, ver, type, 0,				  (isc_stdtime_t) 0,				  &rdataset, NULL));	dns_db_detachnode(db, &node);	for (i = 0; i < nkeys; i++) {		/* Calculate the signature, creating a RRSIG RDATA. */		CHECK(dns_dnssec_sign(name, &rdataset, keys[i],				      &inception, &expire,				      mctx, &buffer, &sig_rdata));		/* Update the database and journal with the RRSIG. */		/* XXX inefficient - will cause dataset merging */		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name,				    rdataset.ttl, &sig_rdata));		dns_rdata_reset(&sig_rdata);	} failure:	if (dns_rdataset_isassociated(&rdataset))		dns_rdataset_disassociate(&rdataset);	if (node != NULL)		dns_db_detachnode(db, &node);	return (result);}/* * Update RRSIG and NSEC records affected by an update.  The original * update, including the SOA serial update but exluding the RRSIG & NSEC * changes, is in "diff" and has already been applied to "newver" of "db". * The database version prior to the update is "oldver". * * The necessary RRSIG and NSEC changes will be applied to "newver" * and added (as a minimal diff) to "diff". * * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds. */static isc_result_tupdate_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,		  dns_dbversion_t *oldver, dns_dbversion_t *newver,		  dns_diff_t *diff, isc_uint32_t sigvalidityinterval){	isc_result_t result;	dns_difftuple_t *t;	dns_diff_t diffnames;	dns_diff_t affected;	dns_diff_t sig_diff;	dns_diff_t nsec_diff;	dns_diff_t nsec_mindiff;	isc_boolean_t flag;	dst_key_t *zone_keys[MAXZONEKEYS];	unsigned int nkeys = 0;	unsigned int i;	isc_stdtime_t now, inception, expire;	dns_diff_init(client->mctx, &diffnames);	dns_diff_init(client->mctx, &affected);	dns_diff_init(client->mctx, &sig_diff);	dns_diff_init(client->mctx, &nsec_diff);	dns_diff_init(client->mctx, &nsec_mindiff);	result = find_zone_keys(zone, db, newver, client->mctx,				MAXZONEKEYS, zone_keys, &nkeys);	if (result != ISC_R_SUCCESS) {		update_log(client, zone, ISC_LOG_ERROR,			   "could not get zone keys for secure dynamic update");		goto failure;	}	isc_stdtime_get(&now);	inception = now - 3600; /* Allow for some clock skew. */	expire = now + sigvalidityinterval;	/*	 * Find all RRsets directly affected by the update, and	 * update their RRSIGs.  Also build a list of names affected	 * by the update in "diffnames".	 */	CHECK(dns_diff_sort(diff, temp_order));	t = ISC_LIST_HEAD(diff->tuples);	while (t != NULL) {		dns_name_t *name = &t->name;		/* Now "name" is a new, unique name affected by the update. */		CHECK(namelist_append_name(&diffnames, name));		while (t != NULL && dns_name_equal(&t->name, name)) {			dns_rdatatype_t type;			type = t->rdata.type;			/*			 * Now "name" and "type" denote a new unique RRset			 * affected by the update.			 */			/* Don't sign RRSIGs. */			if (type == dns_rdatatype_rrsig)				goto skip;			/*			 * Delete all old RRSIGs covering this type, since they			 * are all invalid when the signed RRset has changed.			 * We may not be able to recreate all of them - tough.			 */			CHECK(delete_if(true_p, db, newver, name,					dns_rdatatype_rrsig, type,					NULL, &sig_diff));			/*			 * If this RRset still exists after the update,			 * add a new signature for it.			 */			CHECK(rrset_exists(db, newver, name, type, 0, &flag));			if (flag) {				CHECK(add_sigs(db, newver, name, type,					       &sig_diff, zone_keys, nkeys,					       client->mctx, inception,					       expire));			}		skip:			/* Skip any other updates to the same RRset. */			while (t != NULL &&			       dns_name_equal(&t->name, name) &&			       t->rdata.type == type)			{				t = ISC_LIST_NEXT(t, link);			}		}	}	/* Remove orphaned NSECs and RRSIG NSECs. */	for (t = ISC_LIST_HEAD(diffnames.tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag));		if (! flag) {			CHECK(delete_if(true_p, db, newver, &t->name,					dns_rdatatype_any, 0,					NULL, &sig_diff));		}	}	/*	 * When a name is created or deleted, its predecessor needs to	 * have its NSEC updated.	 */	for (t = ISC_LIST_HEAD(diffnames.tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		isc_boolean_t existed, exists;		dns_fixedname_t fixedname;		dns_name_t *prevname;		dns_fixedname_init(&fixedname);		prevname = dns_fixedname_name(&fixedname);		CHECK(name_exists(db, oldver, &t->name, &existed));		CHECK(name_exists(db, newver, &t->name, &exists));		if (exists == existed)			continue;		/*		 * Find the predecessor.		 * When names become obscured or unobscured in this update		 * transaction, we may find the wrong predecessor because		 * the NSECs have not yet been updated to reflect the delegation		 * change.  This should not matter because in this case,		 * the correct predecessor is either the delegation node or		 * a newly unobscured node, and those nodes are on the		 * "affected" list in any case.		 */		CHECK(next_active(client, zone, db, newver,				  &t->name, prevname, ISC_FALSE));		CHECK(namelist_append_name(&affected, prevname));	}	/*	 * Find names potentially affected by delegation changes	 * (obscured by adding an NS or DNAME, or unobscured by	 * removing one).	 */	for (t = ISC_LIST_HEAD(diffnames.tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		isc_boolean_t ns_existed, dname_existed;		isc_boolean_t ns_exists, dname_exists;		CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0,				   &ns_existed));		CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_dname, 0,				   &dname_existed));		CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0,				   &ns_exists));		CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0,				   &dname_exists));		if ((ns_exists || dname_exists) == (ns_existed || dname_existed))			continue;		/*		 * There was a delegation change.  Mark all subdomains		 * of t->name as potentially needing a NSEC update.		 */		CHECK(namelist_append_subdomain(db, &t->name, &affected));	}	ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link);	INSIST(ISC_LIST_EMPTY(diffnames.tuples));	CHECK(uniqify_name_list(&affected));	/*	 * Determine which names should have NSECs, and delete/create	 * NSECs to make it so.  We don't know the final NSEC targets yet,	 * so we just create placeholder NSECs with arbitrary contents	 * to indicate that their respective owner names should be part of	 * the NSEC chain.	 */	for (t = ISC_LIST_HEAD(affected.tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		isc_boolean_t exists;		CHECK(name_exists(db, newver, &t->name, &exists));		if (! exists)			continue;		CHECK(is_glue(db, newver, &t->name, &flag));		if (flag) {			/*			 * This name is obscured.  Delete any			 * existing NSEC record.			 */			CHECK(delete_if(true_p, db, newver, &t->name,					dns_rdatatype_nsec, 0,					NULL, &nsec_diff));		} else {			/*			 * This name is not obscured.  It should have a NSEC.			 */			CHECK(rrset_exists(db, newver, &t->name,					   dns_rdatatype_nsec, 0, &flag));			if (! flag)				CHECK(add_placeholder_nsec(db, newver, &t->name,							  diff));		}	}	/*	 * Now we know which names are part of the NSEC chain.	 * Make them all point at their correct targets.	 */	for (t = ISC_LIST_HEAD(affected.tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		CHECK(rrset_exists(db, newver, &t->name,				   dns_rdatatype_nsec, 0, &flag));		if (flag) {			/*			 * There is a NSEC, but we don't know if it is correct.			 * Delete it and create a correct one to be sure.			 * If the update was unnecessary, the diff minimization			 * will take care of eliminating it from the journal,			 * IXFRs, etc.			 *			 * The RRSIG bit should always be set in the NSECs			 * we generate, because they will all get RRSIG NSECs.			 * (XXX what if the zone keys are missing?).			 * Because the RRSIG NSECs have not necessarily been			 * created yet, the correctness of the bit mask relies			 * on the assumption that NSECs are only created if			 * there is other data, and if there is other data,			 * there are other RRSIGs.			 */			CHECK(add_nsec(client, zone, db, newver,				      &t->name, &nsec_diff));		}	}	/*	 * Minimize the set of NSEC updates so that we don't	 * have to regenerate the RRSIG NSECs for NSECs that were	 * replaced with identical ones.	 */	while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) {		ISC_LIST_UNLINK(nsec_diff.tuples, t, link);		dns_diff_appendminimal(&nsec_mindiff, &t);	}	/* Update RRSIG NSECs. */	for (t = ISC_LIST_HEAD(nsec_mindiff.tuples);	     t != NULL;	     t = ISC_LIST_NEXT(t, link))	{		if (t->op == DNS_DIFFOP_DEL) {			CHECK(delete_if(true_p, db, newver, &t->name,					dns_rdatatype_rrsig, dns_rdatatype_nsec,					NULL, &sig_diff));		} else if (t->op == DNS_DIFFOP_ADD) {			CHECK(add_sigs(db, newver, &t->name, dns_rdatatype_nsec,				       &sig_diff, zone_keys, nkeys,

⌨️ 快捷键说明

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