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

📄 rbtdb.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
			} else if (found == NULL && foundsig == NULL) {				/*				 * This node is active, but has no NSEC or				 * RRSIG NSEC.  That means it's glue or				 * other obscured zone data that isn't				 * relevant for our search.  Treat the				 * node as if it were empty and keep looking.				 */				empty_node = ISC_TRUE;				result = dns_rbtnodechain_prev(&search->chain,							       NULL, NULL);			} else {				/*				 * We found an active node, but either the				 * NSEC or the RRSIG NSEC is missing.  This				 * shouldn't happen.				 */				result = DNS_R_BADDB;			}		} else {			/*			 * This node isn't active.  We've got to keep			 * looking.			 */			result = dns_rbtnodechain_prev(&search->chain, NULL,						       NULL);		}		UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock));	} while (empty_node && result == ISC_R_SUCCESS);	/*	 * If the result is ISC_R_NOMORE, then we got to the beginning of	 * the database and didn't find a NSEC record.  This shouldn't	 * happen.	 */	if (result == ISC_R_NOMORE)		result = DNS_R_BADDB;	return (result);}static isc_result_tzone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,	  dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,	  dns_dbnode_t **nodep, dns_name_t *foundname,	  dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset){	dns_rbtnode_t *node = NULL;	isc_result_t result;	rbtdb_search_t search;	isc_boolean_t cname_ok = ISC_TRUE;	isc_boolean_t close_version = ISC_FALSE;	isc_boolean_t maybe_zonecut = ISC_FALSE;	isc_boolean_t at_zonecut = ISC_FALSE;	isc_boolean_t wild;	isc_boolean_t empty_node;	isc_mutex_t *lock;	rdatasetheader_t *header, *header_next, *found, *nsecheader;	rdatasetheader_t *foundsig, *cnamesig, *nsecsig;	rbtdb_rdatatype_t sigtype;	isc_boolean_t active;	dns_rbtnodechain_t chain;	search.rbtdb = (dns_rbtdb_t *)db;	REQUIRE(VALID_RBTDB(search.rbtdb));	/*	 * We don't care about 'now'.	 */	UNUSED(now);	/*	 * If the caller didn't supply a version, attach to the current	 * version.	 */	if (version == NULL) {		currentversion(db, &version);		close_version = ISC_TRUE;	}	search.rbtversion = version;	search.serial = search.rbtversion->serial;	search.options = options;	search.copy_name = ISC_FALSE;	search.need_cleanup = ISC_FALSE;	search.wild = ISC_FALSE;	search.zonecut = NULL;	dns_fixedname_init(&search.zonecut_name);	dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx);	search.now = 0;	/*	 * 'wild' will be true iff. we've matched a wildcard.	 */	wild = ISC_FALSE;	RWLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);	/*	 * Search down from the root of the tree.  If, while going down, we	 * encounter a callback node, zone_zonecut_callback() will search the	 * rdatasets at the zone cut for active DNAME or NS rdatasets.	 */	result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node,				  &search.chain, DNS_RBTFIND_EMPTYDATA,				  zone_zonecut_callback, &search);	if (result == DNS_R_PARTIALMATCH) {	partial_match:		if (search.zonecut != NULL) {		    result = setup_delegation(&search, nodep, foundname,					      rdataset, sigrdataset);		    goto tree_exit;		}		if (search.wild) {			/*			 * At least one of the levels in the search chain			 * potentially has a wildcard.  For each such level,			 * we must see if there's a matching wildcard active			 * in the current version.			 */			result = find_wildcard(&search, &node, name);			if (result == ISC_R_SUCCESS) {				result = dns_name_copy(name, foundname, NULL);				if (result != ISC_R_SUCCESS)					goto tree_exit;				wild = ISC_TRUE;				goto found;			}			else if (result != ISC_R_NOTFOUND)				goto tree_exit;		}		chain = search.chain;		active = activeempty(&search, &chain, name);		/*		 * If we're here, then the name does not exist, is not		 * beneath a zonecut, and there's no matching wildcard.		 */		if (search.rbtdb->secure ||		    (search.options & DNS_DBFIND_FORCENSEC) != 0)		{			result = find_closest_nsec(&search, nodep, foundname,						  rdataset, sigrdataset,						  search.rbtdb->secure);			if (result == ISC_R_SUCCESS)				result = active ? DNS_R_EMPTYNAME :						  DNS_R_NXDOMAIN;		} else			result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN;		goto tree_exit;	} else if (result != ISC_R_SUCCESS)		goto tree_exit; found:	/*	 * We have found a node whose name is the desired name, or we	 * have matched a wildcard.	 */	if (search.zonecut != NULL) {		/*		 * If we're beneath a zone cut, we don't want to look for		 * CNAMEs because they're not legitimate zone glue.		 */		cname_ok = ISC_FALSE;	} else {		/*		 * The node may be a zone cut itself.  If it might be one,		 * make sure we check for it later.		 */		if (node->find_callback &&		    (node != search.rbtdb->origin_node ||		     IS_STUB(search.rbtdb)) &&		    !dns_rdatatype_atparent(type))			maybe_zonecut = ISC_TRUE;	}	/*	 * Certain DNSSEC types are not subject to CNAME matching	 * (RFC 2535, section 2.3.5).	 *	 * We don't check for RRSIG, because we don't store RRSIG records	 * directly.	 */	if (type == dns_rdatatype_dnskey || type == dns_rdatatype_nsec)		cname_ok = ISC_FALSE;	/*	 * We now go looking for rdata...	 */	LOCK(&(search.rbtdb->node_locks[node->locknum].lock));	found = NULL;	foundsig = NULL;	sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type);	nsecheader = NULL;	nsecsig = NULL;	cnamesig = NULL;	empty_node = ISC_TRUE;	for (header = node->data; header != NULL; header = header_next) {		header_next = header->next;		/*		 * Look for an active, extant rdataset.		 */		do {			if (header->serial <= search.serial &&			    !IGNORE(header)) {				/*				 * Is this a "this rdataset doesn't				 * exist" record?				 */				if (NONEXISTENT(header))					header = NULL;				break;			} else				header = header->down;		} while (header != NULL);		if (header != NULL) {			/*			 * We now know that there is at least one active			 * rdataset at this node.			 */			empty_node = ISC_FALSE;			/*			 * Do special zone cut handling, if requested.			 */			if (maybe_zonecut &&			    header->type == dns_rdatatype_ns) {				/*				 * We increment the reference count on node to				 * ensure that search->zonecut_rdataset will				 * still be valid later.				 */				new_reference(search.rbtdb, node);				search.zonecut = node;				search.zonecut_rdataset = header;				search.zonecut_sigrdataset = NULL;				search.need_cleanup = ISC_TRUE;				maybe_zonecut = ISC_FALSE;				at_zonecut = ISC_TRUE;				if ((search.options & DNS_DBFIND_GLUEOK) == 0				    && type != dns_rdatatype_nsec				    && type != dns_rdatatype_dnskey) {					/*					 * Glue is not OK, but any answer we					 * could return would be glue.  Return					 * the delegation.					 */					found = NULL;					break;				}				if (found != NULL && foundsig != NULL)					break;			}			/*			 * If we found a type we were looking for,			 * remember it.			 */			if (header->type == type ||			    type == dns_rdatatype_any ||			    (header->type == dns_rdatatype_cname &&			     cname_ok)) {				/*				 * We've found the answer!				 */				found = header;				if (header->type == dns_rdatatype_cname &&				    cname_ok) {					/*					 * We may be finding a CNAME instead					 * of the desired type.					 *					 * If we've already got the CNAME RRSIG,					 * use it, otherwise change sigtype					 * so that we find it.					 */					if (cnamesig != NULL)						foundsig = cnamesig;					else						sigtype =						    RBTDB_RDATATYPE_SIGCNAME;				}				/*				 * If we've got all we need, end the search.				 */				if (!maybe_zonecut && foundsig != NULL)					break;			} else if (header->type == sigtype) {				/*				 * We've found the RRSIG rdataset for our				 * target type.  Remember it.				 */				foundsig = header;				/*				 * If we've got all we need, end the search.				 */				if (!maybe_zonecut && found != NULL)					break;			} else if (header->type == dns_rdatatype_nsec) {				/*				 * Remember a NSEC rdataset even if we're				 * not specifically looking for it, because				 * we might need it later.				 */				nsecheader = header;			} else if (header->type == RBTDB_RDATATYPE_SIGNSEC) {				/*				 * If we need the NSEC rdataset, we'll also				 * need its signature.				 */				nsecsig = header;			} else if (cname_ok &&				   header->type == RBTDB_RDATATYPE_SIGCNAME) {				/*				 * If we get a CNAME match, we'll also need				 * its signature.				 */				cnamesig = header;			}		}	}	if (empty_node) {		/*		 * We have an exact match for the name, but there are no		 * active rdatasets in the desired version.  That means that		 * this node doesn't exist in the desired version, and that		 * we really have a partial match.		 */		if (!wild) {			UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));			goto partial_match;		}	}	/*	 * If we didn't find what we were looking for...	 */	if (found == NULL) {		if (search.zonecut != NULL) {		    /*		     * We were trying to find glue at a node beneath a		     * zone cut, but didn't.		     *		     * Return the delegation.		     */		    UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));		    result = setup_delegation(&search, nodep, foundname,					      rdataset, sigrdataset);		    goto tree_exit;		}		/*		 * The desired type doesn't exist.		 */		result = DNS_R_NXRRSET;		if (search.rbtdb->secure &&		    (nsecheader == NULL || nsecsig == NULL)) {			/*			 * The zone is secure but there's no NSEC,			 * or the NSEC has no signature!			 */			if (!wild) {				result = DNS_R_BADDB;				goto node_exit;			}						UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));			result = find_closest_nsec(&search, nodep, foundname,						  rdataset, sigrdataset,						  search.rbtdb->secure);			if (result == ISC_R_SUCCESS)				result = DNS_R_EMPTYWILD;			goto tree_exit;		}		if ((search.options & DNS_DBFIND_FORCENSEC) != 0 &&		    nsecheader == NULL)		{			/*			 * There's no NSEC record, and we were told			 * to find one.			 */			result = DNS_R_BADDB;			goto node_exit;		}		if (nodep != NULL) {			new_reference(search.rbtdb, node);			*nodep = node;		}		if (search.rbtdb->secure ||		    (search.options & DNS_DBFIND_FORCENSEC) != 0)		{			bind_rdataset(search.rbtdb, node, nsecheader,				      0, rdataset);			if (nsecsig != NULL)				bind_rdataset(search.rbtdb, node,					      nsecsig, 0, sigrdataset);		}		if (wild)			foundname->attributes |= DNS_NAMEATTR_WILDCARD;		goto node_exit;	}	/*	 * We found what we were looking for, or we found a CNAME.	 */	if (type != found->type &&	    type != dns_rdatatype_any &&	    found->type == dns_rdatatype_cname) {		/*		 * We weren't doing an ANY query and we found a CNAME instead		 * of the type we were looking for, so we need to indicate		 * that result to the caller.		 */		result = DNS_R_CNAME;	} else if (search.zonecut != NULL) {		/*		 * If we're beneath a zone cut, we must indicate that the		 * result is glue, unless we're actually at the zone cut		 * and the type is NSEC or KEY.		 */		if (search.zonecut == node) {			if (type == dns_rdatatype_nsec ||			    type == dns_rdatatype_dnskey)				result = ISC_R_SUCCESS;			else if (type == dns_rdatatype_any)				result = DNS_R_ZONECUT;			else				result = DNS_R_GLUE;		} else			result = DNS_R_GLUE;		/*		 * We might have found data that isn't glue, but was occluded		 * by a dynamic update.  If the caller cares about this, they		 * will have told us to validate glue.		 *		 * XXX We should cache the glue validity state!		 */		if (result == DNS_R_GLUE &&		    (search.options & DNS_DBFIND_VALIDATEGLUE) != 0 &&		    !valid_glue(&search, foundname, type, node)) {		    UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));		    result = setup_delegation(&search, nodep, foundname,					      rdataset, sigrdataset);		    goto tree_exit;		}	} else {		/*		 * An ordinary successful query!		 */		result = ISC_R_SUCCESS;	}	if (nodep != NULL) {		if (!at_zonecut)			new_reference(search.rbtdb, node);		else			search.need_cleanup = ISC_FALSE;		*nodep = node;	}	if (type != dns_rdatatype_any) {		bind_rdataset(search.rbtdb, node, found, 0, rdataset);		if (foundsig != NULL)			bind_rdataset(search.rbtdb, node, foundsig, 0,				      sigrdataset);	}	if (wild)		foundname->attributes |= DNS_NAMEATTR_WILDCARD; node_exit:	UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); tree_exit:	RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);	/*	 * If we found a zonecut but aren't going to use it, we have to	 * let go of it.	 */	if (search.need_cleanup) {		node = search.zonecut;		lock = &(search.rbtdb->node_locks[node->locknum].lock);		LOCK(lock);		INSIST(node->references > 0);		node->reference

⌨️ 快捷键说明

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