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

📄 rbtdb.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	 * If we have to set foundname, we do it before anything else.	 * If we were to set foundname after we had set nodep or bound the	 * rdataset, then we'd have to undo that work if dns_name_copy()	 * failed.  By setting foundname first, there's nothing to undo if	 * we have trouble.	 */	if (foundname != NULL && search->copy_name) {		zcname = dns_fixedname_name(&search->zonecut_name);		result = dns_name_copy(zcname, foundname, NULL);		if (result != ISC_R_SUCCESS)			return (result);	}	if (nodep != NULL) {		/*		 * Note that we don't have to increment the node's reference		 * count here because we're going to use the reference we		 * already have in the search block.		 */		*nodep = node;		search->need_cleanup = ISC_FALSE;	}	if (rdataset != NULL) {		LOCK(&(search->rbtdb->node_locks[node->locknum].lock));		bind_rdataset(search->rbtdb, node, search->zonecut_rdataset,			      search->now, rdataset);		if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL)			bind_rdataset(search->rbtdb, node,				      search->zonecut_sigrdataset,				      search->now, sigrdataset);		UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock));	}	if (type == dns_rdatatype_dname)		return (DNS_R_DNAME);	return (DNS_R_DELEGATION);}static inline isc_boolean_tvalid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type,	   dns_rbtnode_t *node){	unsigned char *raw;	unsigned int count, size;	dns_name_t ns_name;	isc_boolean_t valid = ISC_FALSE;	dns_offsets_t offsets;	isc_region_t region;	rdatasetheader_t *header;	/*	 * No additional locking is required.	 */	/*	 * Valid glue types are A, AAAA, A6.  NS is also a valid glue type	 * if it occurs at a zone cut, but is not valid below it.	 */	if (type == dns_rdatatype_ns) {		if (node != search->zonecut) {			return (ISC_FALSE);		}	} else if (type != dns_rdatatype_a &&		   type != dns_rdatatype_aaaa &&		   type != dns_rdatatype_a6) {		return (ISC_FALSE);	}	header = search->zonecut_rdataset;	raw = (unsigned char *)header + sizeof(*header);	count = raw[0] * 256 + raw[1];	raw += 2;	while (count > 0) {		count--;		size = raw[0] * 256 + raw[1];		raw += 2;		region.base = raw;		region.length = size;		raw += size;		/*		 * XXX Until we have rdata structures, we have no choice but		 * to directly access the rdata format.		 */		dns_name_init(&ns_name, offsets);		dns_name_fromregion(&ns_name, &region);		if (dns_name_compare(&ns_name, name) == 0) {			valid = ISC_TRUE;			break;		}	}	return (valid);}static inline isc_boolean_tactiveempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain,	    dns_name_t *name){	dns_fixedname_t fnext;	dns_fixedname_t forigin;	dns_name_t *next;	dns_name_t *origin;	dns_name_t prefix;	dns_rbtdb_t *rbtdb;	dns_rbtnode_t *node;	isc_result_t result;	isc_boolean_t answer = ISC_FALSE;	rdatasetheader_t *header;	rbtdb = search->rbtdb;	dns_name_init(&prefix, NULL);	dns_fixedname_init(&fnext);	next = dns_fixedname_name(&fnext);	dns_fixedname_init(&forigin);	origin = dns_fixedname_name(&forigin);	result = dns_rbtnodechain_next(chain, NULL, NULL);	while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {		node = NULL;		result = dns_rbtnodechain_current(chain, &prefix,						  origin, &node);		if (result != ISC_R_SUCCESS)			break;		LOCK(&(rbtdb->node_locks[node->locknum].lock));		for (header = node->data;		     header != NULL;		     header = header->next) {			if (header->serial <= search->serial &&			    !IGNORE(header) && EXISTS(header))				break;		}		UNLOCK(&(rbtdb->node_locks[node->locknum].lock));		if (header != NULL)			break;		result = dns_rbtnodechain_next(chain, NULL, NULL);	}	if (result == ISC_R_SUCCESS)		result = dns_name_concatenate(&prefix, origin, next, NULL);	if (result == ISC_R_SUCCESS && dns_name_issubdomain(next, name))		answer = ISC_TRUE;	return (answer);}static inline isc_boolean_tactiveemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) {	dns_fixedname_t fnext;	dns_fixedname_t forigin;	dns_fixedname_t fprev;	dns_name_t *next;	dns_name_t *origin;	dns_name_t *prev;	dns_name_t name;	dns_name_t rname;	dns_name_t tname;	dns_rbtdb_t *rbtdb;	dns_rbtnode_t *node;	dns_rbtnodechain_t chain;	isc_boolean_t check_next = ISC_TRUE;	isc_boolean_t check_prev = ISC_TRUE;	isc_boolean_t answer = ISC_FALSE;	isc_result_t result;	rdatasetheader_t *header;	unsigned int n;	rbtdb = search->rbtdb;	dns_name_init(&name, NULL);	dns_name_init(&tname, NULL);	dns_name_init(&rname, NULL);	dns_fixedname_init(&fnext);	next = dns_fixedname_name(&fnext);	dns_fixedname_init(&fprev);	prev = dns_fixedname_name(&fprev);	dns_fixedname_init(&forigin);	origin = dns_fixedname_name(&forigin);	/*	 * Find if qname is at or below a empty node.	 * Use our own copy of the chain.	 */	chain = search->chain;	do {		node = NULL;		result = dns_rbtnodechain_current(&chain, &name,						  origin, &node);		if (result != ISC_R_SUCCESS)			break;		LOCK(&(rbtdb->node_locks[node->locknum].lock));		for (header = node->data;		     header != NULL;		     header = header->next) {			if (header->serial <= search->serial &&			    !IGNORE(header) && EXISTS(header))				break;		}		UNLOCK(&(rbtdb->node_locks[node->locknum].lock));		if (header != NULL)			break;		result = dns_rbtnodechain_prev(&chain, NULL, NULL);	} while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN);	if (result == ISC_R_SUCCESS)		result = dns_name_concatenate(&name, origin, prev, NULL);	if (result != ISC_R_SUCCESS)		check_prev = ISC_FALSE;	result = dns_rbtnodechain_next(&chain, NULL, NULL);	while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {		node = NULL;		result = dns_rbtnodechain_current(&chain, &name,						  origin, &node);		if (result != ISC_R_SUCCESS)			break;		LOCK(&(rbtdb->node_locks[node->locknum].lock));		for (header = node->data;		     header != NULL;		     header = header->next) {			if (header->serial <= search->serial &&			    !IGNORE(header) && EXISTS(header))				break;		}		UNLOCK(&(rbtdb->node_locks[node->locknum].lock));		if (header != NULL)			break;		result = dns_rbtnodechain_next(&chain, NULL, NULL);	}	if (result == ISC_R_SUCCESS)		result = dns_name_concatenate(&name, origin, next, NULL);	if (result != ISC_R_SUCCESS)		check_next = ISC_FALSE;	dns_name_clone(qname, &rname);	/*	 * Remove the wildcard label to find the terminal name.	 */	n = dns_name_countlabels(wname);	dns_name_getlabelsequence(wname, 1, n - 1, &tname);	do {		if ((check_prev && dns_name_issubdomain(prev, &rname)) ||		    (check_next && dns_name_issubdomain(next, &rname))) {			answer = ISC_TRUE;			break;		}		/*		 * Remove the left hand label.		 */		n = dns_name_countlabels(&rname);		dns_name_getlabelsequence(&rname, 1, n - 1, &rname);	} while (!dns_name_equal(&rname, &tname));	return (answer);}static inline isc_result_tfind_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep,	      dns_name_t *qname){	unsigned int i, j;	dns_rbtnode_t *node, *level_node, *wnode;	rdatasetheader_t *header;	isc_result_t result = ISC_R_NOTFOUND;	dns_name_t name;	dns_name_t *wname;	dns_fixedname_t fwname;	dns_rbtdb_t *rbtdb;	isc_boolean_t done, wild, active;	dns_rbtnodechain_t wchain;	/*	 * Caller must be holding the tree lock and MUST NOT be holding	 * any node locks.	 */	/*	 * Examine each ancestor level.  If the level's wild bit	 * is set, then construct the corresponding wildcard name and	 * search for it.  If the wildcard node exists, and is active in	 * this version, we're done.  If not, then we next check to see	 * if the ancestor is active in this version.  If so, then there	 * can be no possible wildcard match and again we're done.  If not,	 * continue the search.	 */	rbtdb = search->rbtdb;	i = search->chain.level_matches;	done = ISC_FALSE;	node = *nodep;	do {		LOCK(&(rbtdb->node_locks[node->locknum].lock));		/*		 * First we try to figure out if this node is active in		 * the search's version.  We do this now, even though we		 * may not need the information, because it simplifies the		 * locking and code flow.		 */		for (header = node->data;		     header != NULL;		     header = header->next) {			if (header->serial <= search->serial &&			    !IGNORE(header) && EXISTS(header))				break;		}		if (header != NULL)			active = ISC_TRUE;		else			active = ISC_FALSE;		if (node->wild)			wild = ISC_TRUE;		else			wild = ISC_FALSE;		UNLOCK(&(rbtdb->node_locks[node->locknum].lock));		if (wild) {			/*			 * Construct the wildcard name for this level.			 */			dns_name_init(&name, NULL);			dns_rbt_namefromnode(node, &name);			dns_fixedname_init(&fwname);			wname = dns_fixedname_name(&fwname);			result = dns_name_concatenate(dns_wildcardname, &name,						      wname, NULL);			j = i;			while (result == ISC_R_SUCCESS && j != 0) {				j--;				level_node = search->chain.levels[j];				dns_name_init(&name, NULL);				dns_rbt_namefromnode(level_node, &name);				result = dns_name_concatenate(wname,							      &name,							      wname,							      NULL);			}			if (result != ISC_R_SUCCESS)				break;			wnode = NULL;			dns_rbtnodechain_init(&wchain, NULL);			result = dns_rbt_findnode(rbtdb->tree, wname,						  NULL, &wnode, &wchain,						  DNS_RBTFIND_EMPTYDATA,						  NULL, NULL);			if (result == ISC_R_SUCCESS) {			    /*			     * We have found the wildcard node.  If it			     * is active in the search's version, we're			     * done.			     */			    LOCK(&(rbtdb->node_locks[wnode->locknum].lock));			    for (header = wnode->data;				 header != NULL;				 header = header->next) {				    if (header->serial <= search->serial &&					!IGNORE(header) && EXISTS(header))					    break;			    }			    UNLOCK(&(rbtdb->node_locks[wnode->locknum].lock));			    if (header != NULL ||				activeempty(search, &wchain, wname)) {				    if (activeemtpynode(search, qname, wname))						return (ISC_R_NOTFOUND);				    /*				     * The wildcard node is active!				     *				     * Note: result is still ISC_R_SUCCESS				     * so we don't have to set it.				     */				    *nodep = wnode;				    break;			    }			} else if (result != ISC_R_NOTFOUND &&				   result != DNS_R_PARTIALMATCH) {				/*				 * An error has occurred.  Bail out.				 */				break;			}		}		if (active) {			/*			 * The level node is active.  Any wildcarding			 * present at higher levels has no			 * effect and we're done.			 */			result = ISC_R_NOTFOUND;			break;		}		if (i > 0) {			i--;			node = search->chain.levels[i];		} else			done = ISC_TRUE;	} while (!done);	return (result);}static inline isc_result_tfind_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,		  dns_name_t *foundname, dns_rdataset_t *rdataset,		  dns_rdataset_t *sigrdataset, isc_boolean_t need_sig){	dns_rbtnode_t *node;	rdatasetheader_t *header, *header_next, *found, *foundsig;	isc_boolean_t empty_node;	isc_result_t result;	dns_fixedname_t fname, forigin;	dns_name_t *name, *origin;	do {		node = NULL;		dns_fixedname_init(&fname);		name = dns_fixedname_name(&fname);		dns_fixedname_init(&forigin);		origin = dns_fixedname_name(&forigin);		result = dns_rbtnodechain_current(&search->chain, name,						  origin, &node);		if (result != ISC_R_SUCCESS)			return (result);		LOCK(&(search->rbtdb->node_locks[node->locknum].lock));		found = NULL;		foundsig = NULL;		empty_node = ISC_TRUE;		for (header = node->data;		     header != NULL;		     header = header_next) {			header_next = header->next;			/*			 * Look for an active, extant NSEC or RRSIG NSEC.			 */			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;				if (header->type == dns_rdatatype_nsec) {					found = header;					if (foundsig != NULL)						break;				} else if (header->type ==					   RBTDB_RDATATYPE_SIGNSEC) {					foundsig = header;					if (found != NULL)						break;				}			}		}		if (!empty_node) {			if (found != NULL &&			    (foundsig != NULL || !need_sig))			{				/*				 * We've found the right NSEC record.				 *				 * Note: for this to really be the right				 * NSEC record, it's essential that the NSEC				 * records of any nodes obscured by a zone				 * cut have been removed; we assume this is				 * the case.				 */				result = dns_name_concatenate(name, origin,							      foundname, NULL);				if (result == ISC_R_SUCCESS) {					if (nodep != NULL) {						new_reference(search->rbtdb,							      node);						*nodep = node;					}					bind_rdataset(search->rbtdb, node,						      found, search->now,						      rdataset);					if (foundsig != NULL)						bind_rdataset(search->rbtdb,							      node,							      foundsig,							      search->now,							      sigrdataset);				}

⌨️ 快捷键说明

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