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

📄 adb.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 5 页
字号:
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, nbits;	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, &nbits);		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);		result = dns_name_split(name, nlabels, nbits, prefix, NULL);		if (result != ISC_R_SUCCESS) {			dns_rdata_freestruct(&dname);			return (result);		}		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. */static voidevent_free(isc_event_t *event) {	dns_adbfind_t *find;	INSIST(event != NULL);	find = event->ev_destroy_arg;	INSIST(DNS_ADBFIND_VALID(find));	LOCK(&find->lock);	find->flags |= FIND_EVENT_FREED;	event->ev_destroy_arg = NULL;	UNLOCK(&find->lock);}/* * Assumes the name bucket is locked. */static voidclean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,		    unsigned int addrs){	isc_event_t *ev;	isc_task_t *task;	dns_adbfind_t *find;	dns_adbfind_t *next_find;	isc_boolean_t process;	unsigned int wanted, notify;	DP(ENTER_LEVEL,	   "ENTER clean_finds_at_name, name %p, evtype %08x, addrs %08x",	   name, evtype, addrs);	find = ISC_LIST_HEAD(name->finds);	while (find != NULL) {		LOCK(&find->lock);		next_find = ISC_LIST_NEXT(find, plink);		process = ISC_FALSE;		wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;		notify = wanted & addrs;		switch (evtype) {		case DNS_EVENT_ADBMOREADDRESSES:			DP(3, "DNS_EVENT_ADBMOREADDRESSES");			if ((notify) != 0) {				find->flags &= ~addrs;				process = ISC_TRUE;			}			break;		case DNS_EVENT_ADBNOMOREADDRESSES:			DP(3, "DNS_EVENT_ADBNOMOREADDRESSES");			find->flags &= ~addrs;			wanted = find->flags & DNS_ADBFIND_ADDRESSMASK;			if (wanted == 0)				process = ISC_TRUE;			break;		default:			find->flags &= ~addrs;			process = ISC_TRUE;		}		if (process) {			DP(DEF_LEVEL, "cfan: processing find %p", find);			/*			 * Unlink the find from the name, letting the caller			 * call dns_adb_destroyfind() on it to clean it up			 * later.			 */			ISC_LIST_UNLINK(name->finds, find, plink);			find->adbname = NULL;			find->name_bucket = DNS_ADB_INVALIDBUCKET;			INSIST(!FIND_EVENTSENT(find));			ev = &find->event;			task = ev->ev_sender;			ev->ev_sender = find;			find->result_v4 = find_err_map[name->fetch_err];			find->result_v6 = find_err_map[name->fetch6_err];			ev->ev_type = evtype;			ev->ev_destroy = event_free;			ev->ev_destroy_arg = find;			DP(DEF_LEVEL,			   "Sending event %p to task %p for find %p",			   ev, task, find);			isc_task_sendanddetach(&task, (isc_event_t **)&ev);		} else {			DP(DEF_LEVEL, "cfan: skipping find %p", find);		}		UNLOCK(&find->lock);		find = next_find;	}	DP(ENTER_LEVEL, "EXIT clean_finds_at_name, name %p", name);}static inline voidcheck_exit(dns_adb_t *adb) {	isc_event_t *event;	/*	 * The caller must be holding the adb lock.	 */	if (adb->shutting_down) {		/*		 * If there aren't any external references either, we're		 * done.  Send the control event to initiate shutdown.		 */		INSIST(!adb->cevent_sent);	/* Sanity check. */		event = &adb->cevent;		isc_task_send(adb->task, &event);		adb->cevent_sent = ISC_TRUE;	}}static inline isc_boolean_tdec_adb_irefcnt(dns_adb_t *adb) {	isc_event_t *event;	isc_task_t *etask;	isc_boolean_t result = ISC_FALSE;	LOCK(&adb->reflock);	INSIST(adb->irefcnt > 0);	adb->irefcnt--;	if (adb->irefcnt == 0) {		event = ISC_LIST_HEAD(adb->whenshutdown);		while (event != NULL) {			ISC_LIST_UNLINK(adb->whenshutdown, event, ev_link);			etask = event->ev_sender;			event->ev_sender = adb;			isc_task_sendanddetach(&etask, &event);			event = ISC_LIST_HEAD(adb->whenshutdown);		}	}	if (adb->irefcnt == 0 && adb->erefcnt == 0)		result = ISC_TRUE;	UNLOCK(&adb->reflock);	return (result);}static inline voidinc_adb_irefcnt(dns_adb_t *adb) {	LOCK(&adb->reflock);	adb->irefcnt++;	UNLOCK(&adb->reflock);}static inline voidinc_adb_erefcnt(dns_adb_t *adb) {	LOCK(&adb->reflock);	adb->erefcnt++;	UNLOCK(&adb->reflock);}static inline voidinc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {	int bucket;	bucket = entry->lock_bucket;	if (lock)		LOCK(&adb->entrylocks[bucket]);	entry->refcnt++;	if (lock)		UNLOCK(&adb->entrylocks[bucket]);}static inline isc_boolean_tdec_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) {	int bucket;	isc_boolean_t destroy_entry;	isc_boolean_t result = ISC_FALSE;	bucket = entry->lock_bucket;	if (lock)		LOCK(&adb->entrylocks[bucket]);	INSIST(entry->refcnt > 0);	entry->refcnt--;	destroy_entry = ISC_FALSE;	if (entry->refcnt == 0 &&	    (adb->entry_sd[bucket] || entry->expires == 0)) {		destroy_entry = ISC_TRUE;		result = unlink_entry(adb, entry);	}	if (lock)		UNLOCK(&adb->entrylocks[bucket]);	if (!destroy_entry)		return (result);	entry->lock_bucket = DNS_ADB_INVALIDBUCKET;	free_adbentry(adb, &entry);	if (result)		result =dec_adb_irefcnt(adb);		return (result);}static inline dns_adbname_t *new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {	dns_adbname_t *name;	name = isc_mempool_get(adb->nmp);	if (name == NULL)		return (NULL);	dns_name_init(&name->name, NULL);	if (dns_name_dup(dnsname, adb->mctx, &name->name) != ISC_R_SUCCESS) {		isc_mempool_put(adb->nmp, name);		return (NULL);	}	dns_name_init(&name->target, NULL);	name->magic = DNS_ADBNAME_MAGIC;	name->adb = adb;	name->partial_result = 0;	name->flags = 0;	name->expire_v4 = INT_MAX;	name->expire_v6 = INT_MAX;	name->expire_target = INT_MAX;	name->chains = 0;	name->lock_bucket = DNS_ADB_INVALIDBUCKET;	ISC_LIST_INIT(name->v4);	ISC_LIST_INIT(name->v6);	name->fetch_a = NULL;	name->fetch_aaaa = NULL;	ISC_LIST_INIT(name->fetches_a6);	name->fetch_err = FIND_ERR_UNEXPECTED;	name->fetch6_err = FIND_ERR_UNEXPECTED;	ISC_LIST_INIT(name->finds);	ISC_LINK_INIT(name, plink);	return (name);}static inline voidfree_adbname(dns_adb_t *adb, dns_adbname_t **name) {	dns_adbname_t *n;	INSIST(name != NULL && DNS_ADBNAME_VALID(*name));	n = *name;	*name = NULL;	INSIST(!NAME_HAS_V4(n));	INSIST(!NAME_HAS_V6(n));	INSIST(!NAME_FETCH(n));	INSIST(ISC_LIST_EMPTY(n->finds));	INSIST(!ISC_LINK_LINKED(n, plink));	INSIST(n->lock_bucket == DNS_ADB_INVALIDBUCKET);	INSIST(n->adb == adb);	n->magic = 0;	dns_name_free(&n->name, adb->mctx);	isc_mempool_put(adb->nmp, n);}static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *adb, dns_adbentry_t *entry) {	dns_adbnamehook_t *nh;	nh = isc_mempool_get(adb->nhmp);	if (nh == NULL)		return (NULL);	nh->magic = DNS_ADBNAMEHOOK_MAGIC;	nh->entry = entry;	ISC_LINK_INIT(nh, plink);	return (nh);}static inline voidfree_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) {	dns_adbnamehook_t *nh;	INSIST(namehook != NULL && DNS_ADBNAMEHOOK_VALID(*namehook));	nh = *namehook;	*namehook = NULL;	INSIST(nh->entry == NULL);	INSIST(!ISC_LINK_LINKED(nh, plink));	nh->magic = 0;	isc_mempool_put(adb->nhmp, nh);}static inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *adb, dns_name_t *zone) {	dns_adbzoneinfo_t *zi;	zi = isc_mempool_get(adb->zimp);	if (zi == NULL)		return (NULL);	dns_name_init(&zi->zone, NULL);	if (dns_name_dup(zone, adb->mctx, &zi->zone) != ISC_R_SUCCESS) {		isc_mempool_put(adb->zimp, zi);		return (NULL);	}	zi->magic = DNS_ADBZONEINFO_MAGIC;	zi->lame_timer = 0;	ISC_LINK_INIT(zi, plink);	return (zi);}static inline voidfree_adbzoneinfo(dns_adb_t *adb, dns_adbzoneinfo_t **zoneinfo) {	dns_adbzoneinfo_t *zi;	INSIST(zoneinfo != NULL && DNS_ADBZONEINFO_VALID(*zoneinfo));	zi = *zoneinfo;	*zoneinfo = NULL;	INSIST(!ISC_LINK_LINKED(zi, plink));	dns_name_free(&zi->zone, adb->mctx);	zi->magic = 0;	isc_mempool_put(adb->zimp, zi);}static inline dns_adbentry_t *new_adbentry(dns_adb_t *adb) {	dns_adbentry_t *e;	isc_uint32_t r;	e = isc_mempool_get(adb->emp);	if (e == NULL)		return (NULL);	e->magic = DNS_ADBENTRY_MAGIC;	e->lock_bucket = DNS_ADB_INVALIDBUCKET;	e->refcnt = 0;	e->flags = 0;	isc_random_get(&r);	e->srtt = (r & 0x1f) + 1;	e->expires = 0;	ISC_LIST_INIT(e->zoneinfo);	ISC_LINK_INIT(e, plink);	return (e);}static inline voidfree_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {	dns_adbentry_t *e;	dns_adbzoneinfo_t *zi;	INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry));	e = *entry;	*entry = NULL;	INSIST(e->lock_bucket == DNS_ADB_INVALIDBUCKET);	INSIST(e->refcnt == 0);	INSIST(!ISC_LINK_LINKED(e, plink));	e->magic = 0;	zi = ISC_LIST_HEAD(e->zoneinfo);	while (zi != NULL) {		ISC_LIST_UNLINK(e->zoneinfo, zi, plink);		free_adbzoneinfo(adb, &zi);		zi = ISC_LIST_HEAD(e->zoneinfo);	}	isc_mempool_put(adb->emp, e);}static inline dns_adbfind_t *new_adbfind(dns_adb_t *adb) {	dns_adbfind_t *h;	isc_result_t result;	h = isc_mempool_get(adb->ahmp);	if (h == NULL)		return (NULL);	/*	 * Public members.	 */	h->magic = 0;	h->adb = adb;	h->partial_result = 0;	h->options = 0;	h->flags = 0;	h->result_v4 = ISC_R_UNEXPECTED;	h->result_v6 = ISC_R_UNEXPECTED;	ISC_LINK_INIT(h, publink);	ISC_LINK_INIT(h, plink);	ISC_LIST_INIT(h->list);	h->adbname = NULL;	h->name_bucket = DNS_ADB_INVALIDBUCKET;	/*	 * private members	 */	result = isc_mutex_init(&h->lock);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_mutex_init failed in new_adbfind()");		isc_mempool_put(adb->ahmp, h);		return (NULL);	}	ISC_EVENT_INIT(&h->event, sizeof (isc_event_t), 0, 0, 0, NULL, NULL,		       NULL, NULL, h);	inc_adb_irefcnt(adb);	h->magic = DNS_ADBFIND_MAGIC;	return (h);}static inline dns_adbfetch_t *new_adbfetch(dns_adb_t *adb) {	dns_adbfetch_t *f;	f = isc_mempool_get(adb->afmp);	if (f == NULL)		return (NULL);	f->magic = 0;	f->namehook = NULL;	f->entry = NULL;

⌨️ 快捷键说明

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