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

📄 dispatch.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
	mgr->state = 0;	ISC_LIST_INIT(mgr->list);	mgr->magic = DNS_DISPATCHMGR_MAGIC;	if (entropy != NULL)		isc_entropy_attach(entropy, &mgr->entropy);	*mgrp = mgr;	return (ISC_R_SUCCESS); kill_rpool:	isc_mempool_destroy(&mgr->rpool); kill_epool:	isc_mempool_destroy(&mgr->epool); kill_pool_lock:	DESTROYLOCK(&mgr->pool_lock); kill_buffer_lock:	DESTROYLOCK(&mgr->buffer_lock); kill_lock:	DESTROYLOCK(&mgr->lock); deallocate:	isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));	isc_mem_detach(&mctx);	return (result);}voiddns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) {	REQUIRE(VALID_DISPATCHMGR(mgr));	if (mgr->blackhole != NULL)		dns_acl_detach(&mgr->blackhole);	dns_acl_attach(blackhole, &mgr->blackhole);}dns_acl_t *dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) {	REQUIRE(VALID_DISPATCHMGR(mgr));	return (mgr->blackhole);}voiddns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,				 dns_portlist_t *portlist){	REQUIRE(VALID_DISPATCHMGR(mgr));	if (mgr->portlist != NULL)		dns_portlist_detach(&mgr->portlist);	if (portlist != NULL)		dns_portlist_attach(portlist, &mgr->portlist);}dns_portlist_t *dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) {	REQUIRE(VALID_DISPATCHMGR(mgr));	return (mgr->portlist);}static isc_result_tdns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,			unsigned int buffersize, unsigned int maxbuffers,			unsigned int buckets, unsigned int increment){	isc_result_t result;	REQUIRE(VALID_DISPATCHMGR(mgr));	REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));	REQUIRE(maxbuffers > 0);	REQUIRE(buckets < 2097169);  /* next prime > 65536 * 32 */	REQUIRE(increment > buckets);	/*	 * Keep some number of items around.  This should be a config	 * option.  For now, keep 8, but later keep at least two even	 * if the caller wants less.  This allows us to ensure certain	 * things, like an event can be "freed" and the next allocation	 * will always succeed.	 *	 * Note that if limits are placed on anything here, we use one	 * event internally, so the actual limit should be "wanted + 1."	 *	 * XXXMLG	 */	if (maxbuffers < 8)		maxbuffers = 8;	LOCK(&mgr->buffer_lock);	if (mgr->bpool != NULL) {		isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);		mgr->maxbuffers = maxbuffers;		UNLOCK(&mgr->buffer_lock);		return (ISC_R_SUCCESS);	}	if (isc_mempool_create(mgr->mctx, buffersize,			       &mgr->bpool) != ISC_R_SUCCESS) {		return (ISC_R_NOMEMORY);	}	isc_mempool_setname(mgr->bpool, "dispmgr_bpool");	isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);	isc_mempool_associatelock(mgr->bpool, &mgr->pool_lock);	result = qid_allocate(mgr, buckets, increment, &mgr->qid);	if (result != ISC_R_SUCCESS)		goto cleanup;	mgr->buffersize = buffersize;	mgr->maxbuffers = maxbuffers;	UNLOCK(&mgr->buffer_lock);	return (ISC_R_SUCCESS); cleanup:	isc_mempool_destroy(&mgr->bpool);	UNLOCK(&mgr->buffer_lock);	return (ISC_R_NOMEMORY);}voiddns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {	dns_dispatchmgr_t *mgr;	isc_boolean_t killit;	REQUIRE(mgrp != NULL);	REQUIRE(VALID_DISPATCHMGR(*mgrp));	mgr = *mgrp;	*mgrp = NULL;	LOCK(&mgr->lock);	mgr->state |= MGR_SHUTTINGDOWN;	killit = destroy_mgr_ok(mgr);	UNLOCK(&mgr->lock);	mgr_log(mgr, LVL(90), "destroy: killit=%d", killit);	if (killit)		destroy_mgr(&mgr);}static isc_boolean_tblacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock) {	isc_sockaddr_t sockaddr;	isc_result_t result;	if (mgr->portlist == NULL)		return (ISC_FALSE);	result = isc_socket_getsockname(sock, &sockaddr);	if (result != ISC_R_SUCCESS)		return (ISC_FALSE);	if (mgr->portlist != NULL &&	    dns_portlist_match(mgr->portlist, isc_sockaddr_pf(&sockaddr),			       isc_sockaddr_getport(&sockaddr)))		return (ISC_TRUE);	return (ISC_FALSE);}#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask)))static isc_boolean_tlocal_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {	isc_sockaddr_t sockaddr;	isc_result_t result;	if (addr == NULL)		return (ISC_TRUE);	/*	 * Don't match wildcard ports against newly blacklisted ports.	 */	if (disp->mgr->portlist != NULL &&	    isc_sockaddr_getport(addr) == 0 &&	    isc_sockaddr_getport(&disp->local) == 0 &&	    blacklisted(disp->mgr, disp->socket))		return (ISC_FALSE);	/*	 * Check if we match the binding <address,port>.	 * Wildcard ports match/fail here.	 */	if (isc_sockaddr_equal(&disp->local, addr))		return (ISC_TRUE);	if (isc_sockaddr_getport(addr) == 0)		return (ISC_FALSE);	/*	 * Check if we match a bound wildcard port <address,port>.	 */	if (!isc_sockaddr_eqaddr(&disp->local, addr))		return (ISC_FALSE);	result = isc_socket_getsockname(disp->socket, &sockaddr);	if (result != ISC_R_SUCCESS)		return (ISC_FALSE);	return (isc_sockaddr_equal(&sockaddr, addr));}/* * Requires mgr be locked. * * No dispatcher can be locked by this thread when calling this function. * * * NOTE: *	If a matching dispatcher is found, it is locked after this function *	returns, and must be unlocked by the caller. */static isc_result_tdispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local,	      unsigned int attributes, unsigned int mask,	      dns_dispatch_t **dispp){	dns_dispatch_t *disp;	isc_result_t result;	/*	 * Make certain that we will not match a private dispatch.	 */	attributes &= ~DNS_DISPATCHATTR_PRIVATE;	mask |= DNS_DISPATCHATTR_PRIVATE;	disp = ISC_LIST_HEAD(mgr->list);	while (disp != NULL) {		LOCK(&disp->lock);		if ((disp->shutting_down == 0)		    && ATTRMATCH(disp->attributes, attributes, mask)		    && local_addr_match(disp, local))			break;		UNLOCK(&disp->lock);		disp = ISC_LIST_NEXT(disp, link);	}	if (disp == NULL) {		result = ISC_R_NOTFOUND;		goto out;	}	*dispp = disp;	result = ISC_R_SUCCESS; out:	return (result);}static isc_result_tqid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets,	     unsigned int increment, dns_qid_t **qidp){	dns_qid_t *qid;	unsigned int i;	REQUIRE(VALID_DISPATCHMGR(mgr));	REQUIRE(buckets < 2097169);  /* next prime > 65536 * 32 */	REQUIRE(increment > buckets);	REQUIRE(qidp != NULL && *qidp == NULL);	qid = isc_mem_get(mgr->mctx, sizeof(*qid));	if (qid == NULL)		return (ISC_R_NOMEMORY);	qid->qid_table = isc_mem_get(mgr->mctx,				     buckets * sizeof(dns_displist_t));	if (qid->qid_table == NULL) {		isc_mem_put(mgr->mctx, qid, sizeof(*qid));		return (ISC_R_NOMEMORY);	}	if (isc_mutex_init(&qid->lock) != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init failed");		isc_mem_put(mgr->mctx, qid->qid_table,			    buckets * sizeof(dns_displist_t));		isc_mem_put(mgr->mctx, qid, sizeof(*qid));		return (ISC_R_UNEXPECTED);	}	for (i = 0; i < buckets; i++)		ISC_LIST_INIT(qid->qid_table[i]);	qid->qid_nbuckets = buckets;	qid->qid_increment = increment;	qid->magic = QID_MAGIC;	/*	 * Initialize to a 32-bit LFSR.  Both of these are from Applied	 * Cryptography.	 *	 * lfsr1:	 *	x^32 + x^7 + x^5 + x^3 + x^2 + x + 1	 *	 * lfsr2:	 *	x^32 + x^7 + x^6 + x^2 + 1	 */	isc_lfsr_init(&qid->qid_lfsr1, 0, 32, 0x80000057U,		      0, reseed_lfsr, mgr);	isc_lfsr_init(&qid->qid_lfsr2, 0, 32, 0x80000062U,		      0, reseed_lfsr, mgr);	*qidp = qid;	return (ISC_R_SUCCESS);}static voidqid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) {	dns_qid_t *qid;	REQUIRE(qidp != NULL);	qid = *qidp;	REQUIRE(VALID_QID(qid));	*qidp = NULL;	qid->magic = 0;	isc_mem_put(mctx, qid->qid_table,		    qid->qid_nbuckets * sizeof(dns_displist_t));	DESTROYLOCK(&qid->lock);	isc_mem_put(mctx, qid, sizeof(*qid));}/* * Allocate and set important limits. */static isc_result_tdispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,		  dns_dispatch_t **dispp){	dns_dispatch_t *disp;	isc_result_t res;	REQUIRE(VALID_DISPATCHMGR(mgr));	REQUIRE(dispp != NULL && *dispp == NULL);	/*	 * Set up the dispatcher, mostly.  Don't bother setting some of	 * the options that are controlled by tcp vs. udp, etc.	 */	disp = isc_mempool_get(mgr->dpool);	if (disp == NULL)		return (ISC_R_NOMEMORY);	disp->magic = 0;	disp->mgr = mgr;	disp->maxrequests = maxrequests;	disp->attributes = 0;	ISC_LINK_INIT(disp, link);	disp->refcount = 1;	disp->recv_pending = 0;	memset(&disp->local, 0, sizeof(disp->local));	disp->shutting_down = 0;	disp->shutdown_out = 0;	disp->connected = 0;	disp->tcpmsg_valid = 0;	disp->shutdown_why = ISC_R_UNEXPECTED;	disp->requests = 0;	disp->tcpbuffers = 0;	disp->qid = NULL;	if (isc_mutex_init(&disp->lock) != ISC_R_SUCCESS) {		res = ISC_R_UNEXPECTED;		UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init failed");		goto deallocate;	}	disp->failsafe_ev = allocate_event(disp);	if (disp->failsafe_ev == NULL) {		res = ISC_R_NOMEMORY;		goto kill_lock;	}	disp->magic = DISPATCH_MAGIC;	*dispp = disp;	return (ISC_R_SUCCESS);	/*	 * error returns	 */ kill_lock:	DESTROYLOCK(&disp->lock); deallocate:	isc_mempool_put(mgr->dpool, disp);	return (res);}/* * MUST be unlocked, and not used by anthing. */static voiddispatch_free(dns_dispatch_t **dispp){	dns_dispatch_t *disp;	dns_dispatchmgr_t *mgr;	REQUIRE(VALID_DISPATCH(*dispp));	disp = *dispp;	*dispp = NULL;	mgr = disp->mgr;	REQUIRE(VALID_DISPATCHMGR(mgr));	if (disp->tcpmsg_valid) {		dns_tcpmsg_invalidate(&disp->tcpmsg);		disp->tcpmsg_valid = 0;	}	INSIST(disp->tcpbuffers == 0);	INSIST(disp->requests == 0);	INSIST(disp->recv_pending == 0);	isc_mempool_put(mgr->epool, disp->failsafe_ev);	disp->failsafe_ev = NULL;	if (disp->qid != NULL)		qid_destroy(mgr->mctx, &disp->qid);	disp->mgr = NULL;	DESTROYLOCK(&disp->lock);	disp->magic = 0;	isc_mempool_put(mgr->dpool, disp);}isc_result_tdns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,		       isc_taskmgr_t *taskmgr, unsigned int buffersize,		       unsigned int maxbuffers, unsigned int maxrequests,		       unsigned int buckets, unsigned int increment,		       unsigned int attributes, dns_dispatch_t **dispp){	isc_result_t result;	dns_dispatch_t *disp;	UNUSED(maxbuffers);	UNUSED(buffersize);	REQUIRE(VALID_DISPATCHMGR(mgr));	REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp);	REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0);	REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0);	attributes |= DNS_DISPATCHATTR_PRIVATE;  /* XXXMLG */	LOCK(&mgr->lock);	/*	 * dispatch_allocate() checks mgr for us.	 * qid_allocate() checks buckets and increment for us.	 */	disp = NULL;	result = dispatch_allocate(mgr, maxrequests, &disp);	if (result != ISC_R_SUCCESS) {		UNLOCK(&mgr->lock);		return (result);	}	result = qid_allocate(mgr, buckets, increment, &disp->qid);	if (result != ISC_R_SUCCESS)		goto deallocate_dispatch;	disp->socktype = isc_sockettype_tcp;	disp->socket = NULL;	isc_socket_attach(sock, &disp->socket);	disp->task = NULL;	result = isc_task_create(taskmgr, 0, &disp->task);	if (result != ISC_R_SUCCESS)		goto kill_socket;	disp->ctlevent = isc_event_allocate(mgr->mctx, disp,					    DNS_EVENT_DISPATCHCONTROL,					    destroy_disp, disp,					    sizeof(isc_event_t));	if (disp->ctlevent == NULL)		goto kill_task;	isc_task_setname(disp->task, "tcpdispatch", disp);	dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg);	disp->tcpmsg_valid = 1;	disp->attributes = attributes;	/*	 * Append it to the dispatcher list.	 */	ISC_LIST_APPEND(mgr->list, disp, link);	UNLOCK(&mgr->lock);	mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp);	dispatch_log(disp, LVL(90), "created task %p", disp->task);	*dispp = disp;	return (ISC_R_SUCCESS);	/*	 * Error returns.	 */ kill_task:	isc_task_detach(&disp->task); kill_socket:	isc_socket_detach(&disp->socket); deallocate_dispatch:	dispatch_free(&disp);	UNLOCK(&mgr->lock);	return (result);}isc_result_tdns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,		    isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,		    unsigned int buffersize,		    unsigned int maxbuffers, unsigned int maxrequests,		    unsigned int buckets, unsigned int increment,		    unsigned int attributes, unsigned int mask,		    dns_dispatch_t **dispp){	isc_result_t result;	dns_dispatch_t *disp;	REQUIRE(VALID_DISPATCHMGR(mgr));	REQUIRE(sockmgr != NULL);	REQUIRE(localaddr != NULL);	REQUIRE(taskmgr != NULL);	REQUIRE(buffersize >= 512 && buffersize < (64 * 1024));	REQUIRE(maxbuffers > 0);	REQUIRE(buckets < 2097169);  /* next prime > 65536 * 32 */	REQUIRE(increment > buckets);	REQUIRE(dispp != NULL && *dispp == NULL);	REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0);	result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers,					buckets, increment);	if (result != ISC_R_SUCCESS)		return (result);	LOCK(&mgr->lock);	/*	 * First, see if we have a dispatcher that matches.	 */	disp = NULL;	result = dispatch_find(mgr, localaddr, attributes, mask, &disp);	if (result == ISC_R_SUCCESS) {		disp->refcount++;

⌨️ 快捷键说明

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