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

📄 adb.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
			isc_sockaddr_fromin(&sockaddr, &ina, 0);		} else {			INSIST(rdata.length == 16);			memcpy(in6a.s6_addr, rdata.data, 16);			isc_sockaddr_fromin6(&sockaddr, &in6a, 0);		}		INSIST(nh == NULL);		nh = new_adbnamehook(adb, NULL);		if (nh == NULL) {			adbname->partial_result |= findoptions;			result = ISC_R_NOMEMORY;			goto fail;		}		foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);		if (foundentry == NULL) {			dns_adbentry_t *entry;			entry = new_adbentry(adb);			if (entry == NULL) {				adbname->partial_result |= findoptions;				result = ISC_R_NOMEMORY;				goto fail;			}			entry->sockaddr = sockaddr;			entry->refcnt = 1;			nh->entry = entry;			link_entry(adb, addr_bucket, entry);		} else {			for (anh = ISC_LIST_HEAD(adbname->v4);			     anh != NULL;			     anh = ISC_LIST_NEXT(anh, plink))				if (anh->entry == foundentry)					break;			if (anh == NULL) {				foundentry->refcnt++;				nh->entry = foundentry;			} else				free_adbnamehook(adb, &nh);		}		new_addresses_added = ISC_TRUE;		if (nh != NULL) {			if (rdtype == dns_rdatatype_a)				ISC_LIST_APPEND(adbname->v4, nh, plink);			else				ISC_LIST_APPEND(adbname->v6, nh, plink);		}		nh = NULL;		result = dns_rdataset_next(rdataset);	} fail:	if (nh != NULL)		free_adbnamehook(adb, &nh);	if (addr_bucket != DNS_ADB_INVALIDBUCKET)		UNLOCK(&adb->entrylocks[addr_bucket]);	if (rdataset->trust == dns_trust_glue ||	    rdataset->trust == dns_trust_additional)		rdataset->ttl = ADB_CACHE_MINIMUM;	else		rdataset->ttl = ttlclamp(rdataset->ttl);	if (rdtype == dns_rdatatype_a) {		DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",		   adbname->expire_v4, now + rdataset->ttl);		adbname->expire_v4 = ISC_MIN(adbname->expire_v4,					     now + rdataset->ttl);	} else {		DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",		   adbname->expire_v6, now + rdataset->ttl);		adbname->expire_v6 = ISC_MIN(adbname->expire_v6,					     now + rdataset->ttl);	}	if (new_addresses_added) {		/*		 * Lie a little here.  This is more or less so code that cares		 * can find out if any new information was added or not.		 */		return (ISC_R_SUCCESS);	}	return (result);}/* * Requires the name's bucket be locked. */static isc_boolean_tkill_name(dns_adbname_t **n, isc_eventtype_t ev) {	dns_adbname_t *name;	isc_boolean_t result = ISC_FALSE;	isc_boolean_t result4, result6;	dns_adb_t *adb;	INSIST(n != NULL);	name = *n;	*n = NULL;	INSIST(DNS_ADBNAME_VALID(name));	adb = name->adb;	INSIST(DNS_ADB_VALID(adb));	DP(DEF_LEVEL, "killing name %p", name);	/*	 * If we're dead already, just check to see if we should go	 * away now or not.	 */	if (NAME_DEAD(name) && !NAME_FETCH(name)) {		result = unlink_name(adb, name);		free_adbname(adb, &name);		if (result)			result = dec_adb_irefcnt(adb);		return (result);	}	/*	 * Clean up the name's various lists.  These two are destructive	 * in that they will always empty the list.	 */	clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);	result4 = clean_namehooks(adb, &name->v4);	result6 = clean_namehooks(adb, &name->v6);	clean_target(adb, &name->target);	result = ISC_TF(result4 || result6);	/*	 * If fetches are running, cancel them.  If none are running, we can	 * just kill the name here.	 */	if (!NAME_FETCH(name)) {		INSIST(result == ISC_FALSE);		result = unlink_name(adb, name);		free_adbname(adb, &name);		if (result)			result = dec_adb_irefcnt(adb);	} else {		name->flags |= NAME_IS_DEAD;		cancel_fetches_at_name(name);	}	return (result);}/* * Requires the name's bucket be locked and no entry buckets be locked. */static isc_boolean_tcheck_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now,		       isc_boolean_t overmem){	dns_adb_t *adb;	isc_boolean_t expire;	isc_boolean_t result4 = ISC_FALSE;	isc_boolean_t result6 = ISC_FALSE;	INSIST(DNS_ADBNAME_VALID(name));	adb = name->adb;	INSIST(DNS_ADB_VALID(adb));	if (overmem) {		isc_uint32_t val;		isc_random_get(&val);		expire = ISC_TF((val % 4) == 0);	} else		expire = ISC_FALSE;	/*	 * Check to see if we need to remove the v4 addresses	 */	if (!NAME_FETCH_V4(name) &&	    (expire || EXPIRE_OK(name->expire_v4, now))) {		if (NAME_HAS_V4(name)) {			DP(DEF_LEVEL, "expiring v4 for name %p", name);			result4 = clean_namehooks(adb, &name->v4);			name->partial_result &= ~DNS_ADBFIND_INET;		}		name->expire_v4 = INT_MAX;		name->fetch_err = FIND_ERR_UNEXPECTED;	}	/*	 * Check to see if we need to remove the v6 addresses	 */	if (!NAME_FETCH_V6(name) &&	    (expire || EXPIRE_OK(name->expire_v6, now))) {		if (NAME_HAS_V6(name)) {			DP(DEF_LEVEL, "expiring v6 for name %p", name);			result6 = clean_namehooks(adb, &name->v6);			name->partial_result &= ~DNS_ADBFIND_INET6;		}		name->expire_v6 = INT_MAX;		name->fetch6_err = FIND_ERR_UNEXPECTED;	}	/*	 * Check to see if we need to remove the alias target.	 */	if (expire || EXPIRE_OK(name->expire_target, now)) {		clean_target(adb, &name->target);		name->expire_target = INT_MAX;	}	return (ISC_TF(result4 || result6));}/* * Requires the name's bucket be locked. */static inline voidlink_name(dns_adb_t *adb, int bucket, dns_adbname_t *name) {	INSIST(name->lock_bucket == DNS_ADB_INVALIDBUCKET);	ISC_LIST_PREPEND(adb->names[bucket], name, plink);	name->lock_bucket = bucket;	adb->name_refcnt[bucket]++;}/* * Requires the name's bucket be locked. */static inline isc_boolean_tunlink_name(dns_adb_t *adb, dns_adbname_t *name) {	int bucket;	isc_boolean_t result = ISC_FALSE;	bucket = name->lock_bucket;	INSIST(bucket != DNS_ADB_INVALIDBUCKET);	ISC_LIST_UNLINK(adb->names[bucket], name, plink);	name->lock_bucket = DNS_ADB_INVALIDBUCKET;	INSIST(adb->name_refcnt[bucket] > 0);	adb->name_refcnt[bucket]--;	if (adb->name_sd[bucket] && adb->name_refcnt[bucket] == 0)		result = ISC_TRUE;	return (result);}/* * Requires the entry's bucket be locked. */static inline voidlink_entry(dns_adb_t *adb, int bucket, dns_adbentry_t *entry) {	ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);	entry->lock_bucket = bucket;	adb->entry_refcnt[bucket]++;}/* * Requires the entry's bucket be locked. */static inline isc_boolean_tunlink_entry(dns_adb_t *adb, dns_adbentry_t *entry) {	int bucket;	isc_boolean_t result = ISC_FALSE;	bucket = entry->lock_bucket;	INSIST(bucket != DNS_ADB_INVALIDBUCKET);	ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);	entry->lock_bucket = DNS_ADB_INVALIDBUCKET;	INSIST(adb->entry_refcnt[bucket] > 0);	adb->entry_refcnt[bucket]--;	if (adb->entry_sd[bucket] && adb->entry_refcnt[bucket] == 0)		result = ISC_TRUE;	return (result);}static inline voidviolate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want) {	if (isc_mutex_trylock(want) != ISC_R_SUCCESS) {		UNLOCK(have);		LOCK(want);		LOCK(have);	}}/* * The ADB _MUST_ be locked before calling.  Also, exit conditions must be * checked after calling this function. */static isc_boolean_tshutdown_names(dns_adb_t *adb) {	int bucket;	isc_boolean_t result = ISC_FALSE;	dns_adbname_t *name;	dns_adbname_t *next_name;	for (bucket = 0; bucket < NBUCKETS; bucket++) {		LOCK(&adb->namelocks[bucket]);		adb->name_sd[bucket] = ISC_TRUE;		name = ISC_LIST_HEAD(adb->names[bucket]);		if (name == NULL) {			/*			 * This bucket has no names.  We must decrement the			 * irefcnt ourselves, since it will not be			 * automatically triggered by a name being unlinked.			 */			INSIST(result == ISC_FALSE);			result = dec_adb_irefcnt(adb);		} else {			/*			 * Run through the list.  For each name, clean up finds			 * found there, and cancel any fetches running.  When			 * all the fetches are canceled, the name will destroy			 * itself.			 */			while (name != NULL) {				next_name = ISC_LIST_NEXT(name, plink);				INSIST(result == ISC_FALSE);				result = kill_name(&name,						   DNS_EVENT_ADBSHUTDOWN);				name = next_name;			}		}		UNLOCK(&adb->namelocks[bucket]);	}	return (result);}/* * The ADB _MUST_ be locked before calling.  Also, exit conditions must be * checked after calling this function. */static isc_boolean_tshutdown_entries(dns_adb_t *adb) {	int bucket;	isc_boolean_t result = ISC_FALSE;	dns_adbentry_t *entry;	dns_adbentry_t *next_entry;	for (bucket = 0; bucket < NBUCKETS; bucket++) {		LOCK(&adb->entrylocks[bucket]);		adb->entry_sd[bucket] = ISC_TRUE;		entry = ISC_LIST_HEAD(adb->entries[bucket]);		if (entry == NULL) {			/*			 * This bucket has no entries.  We must decrement the			 * irefcnt ourselves, since it will not be			 * automatically triggered by an entry being unlinked.			 */			result = dec_adb_irefcnt(adb);		} else {			/*			 * Run through the list.  Cleanup any entries not			 * associated with names, and which are not in use.			 */			while (entry != NULL) {				next_entry = ISC_LIST_NEXT(entry, plink);				if (entry->refcnt == 0 &&				    entry->expires != 0) {					result = unlink_entry(adb, entry);					free_adbentry(adb, &entry);					if (result)						result = dec_adb_irefcnt(adb);				}				entry = next_entry;			}		}		UNLOCK(&adb->entrylocks[bucket]);	}	return (result);}/* * Name bucket must be locked */static voidcancel_fetches_at_name(dns_adbname_t *name) {	if (NAME_FETCH_A(name))	    dns_resolver_cancelfetch(name->fetch_a->fetch);	if (NAME_FETCH_AAAA(name))	    dns_resolver_cancelfetch(name->fetch_aaaa->fetch);}/* * Assumes the name bucket is locked. */static isc_boolean_tclean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {	dns_adbentry_t *entry;	dns_adbnamehook_t *namehook;	int addr_bucket;	isc_boolean_t result = ISC_FALSE;	addr_bucket = DNS_ADB_INVALIDBUCKET;	namehook = ISC_LIST_HEAD(*namehooks);	while (namehook != NULL) {		INSIST(DNS_ADBNAMEHOOK_VALID(namehook));		/*		 * Clean up the entry if needed.		 */		entry = namehook->entry;		if (entry != NULL) {			INSIST(DNS_ADBENTRY_VALID(entry));			if (addr_bucket != entry->lock_bucket) {				if (addr_bucket != DNS_ADB_INVALIDBUCKET)					UNLOCK(&adb->entrylocks[addr_bucket]);				addr_bucket = entry->lock_bucket;				LOCK(&adb->entrylocks[addr_bucket]);			}			result = dec_entry_refcnt(adb, entry, ISC_FALSE);		}		/*		 * Free the namehook		 */		namehook->entry = NULL;		ISC_LIST_UNLINK(*namehooks, namehook, plink);		free_adbnamehook(adb, &namehook);		namehook = ISC_LIST_HEAD(*namehooks);	}	if (addr_bucket != DNS_ADB_INVALIDBUCKET)		UNLOCK(&adb->entrylocks[addr_bucket]);	return (result);}static voidclean_target(dns_adb_t *adb, dns_name_t *target) {	if (dns_name_countlabels(target) > 0) {		dns_name_free(target, adb->mctx);		dns_name_init(target, NULL);	}}static isc_result_tset_target(dns_adb_t *adb, dns_name_t *name, dns_name_t *fname,	   dns_rdataset_t *rdataset, dns_name_t *target){	isc_result_t result;	dns_namereln_t namereln;	unsigned int nlabels;	int order;	dns_rdata_t rdata = DNS_RDATA_INIT;	dns_fixedname_t fixed1, fixed2;	dns_name_t *prefix, *new_target;	REQUIRE(dns_name_countlabels(target) == 0);	if (rdataset->type == dns_rdatatype_cname) {		dns_rdata_cname_t cname;		/*		 * Copy the CNAME's target into the target name.		 */		result = dns_rdataset_first(rdataset);		if (result != ISC_R_SUCCESS)			return (result);		dns_rdataset_current(rdataset, &rdata);		result = dns_rdata_tostruct(&rdata, &cname, NULL);		if (result != ISC_R_SUCCESS)			return (result);		result = dns_name_dup(&cname.cname, adb->mctx, target);		dns_rdata_freestruct(&cname);		if (result != ISC_R_SUCCESS)			return (result);	} else {		dns_rdata_dname_t dname;		INSIST(rdataset->type == dns_rdatatype_dname);		namereln = dns_name_fullcompare(name, fname, &order, &nlabels);		INSIST(namereln == dns_namereln_subdomain);		/*		 * Get the target name of the DNAME.		 */		result = dns_rdataset_first(rdataset);		if (result != ISC_R_SUCCESS)			return (result);		dns_rdataset_current(rdataset, &rdata);		result = dns_rdata_tostruct(&rdata, &dname, NULL);		if (result != ISC_R_SUCCESS)			return (result);		/*		 * Construct the new target name.		 */		dns_fixedname_init(&fixed1);		prefix = dns_fixedname_name(&fixed1);		dns_fixedname_init(&fixed2);		new_target = dns_fixedname_name(&fixed2);		dns_name_split(name, nlabels, prefix, NULL);		result = dns_name_concatenate(prefix, &dname.dname, new_target,					      NULL);		dns_rdata_freestruct(&dname);		if (result != ISC_R_SUCCESS)			return (result);		result = dns_name_dup(new_target, adb->mctx, target);		if (result != ISC_R_SUCCESS)			return (result);	}	return (ISC_R_SUCCESS);}/* * Assumes nothing is locked, since this is called by the client.

⌨️ 快捷键说明

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