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

📄 dispatch.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
		disp->recv_pending = 0;	}	if (disp->shutting_down) {		/*		 * This dispatcher is shutting down.		 */		free_buffer(disp, ev->region.base, ev->region.length);		isc_event_free(&ev_in);		ev = NULL;		killit = destroy_disp_ok(disp);		UNLOCK(&disp->lock);		if (killit)			isc_task_send(disp->task, &disp->ctlevent);		return;	}	if (ev->result != ISC_R_SUCCESS) {		free_buffer(disp, ev->region.base, ev->region.length);		if (ev->result != ISC_R_CANCELED)			dispatch_log(disp, ISC_LOG_ERROR,				     "odd socket result in udp_recv(): %s",				     isc_result_totext(ev->result));		UNLOCK(&disp->lock);		isc_event_free(&ev_in);		return;	}	/*	 * If this is from a blackholed address, drop it.	 */	isc_netaddr_fromsockaddr(&netaddr, &ev->address);	if (disp->mgr->blackhole != NULL &&	    dns_acl_match(&netaddr, NULL, disp->mgr->blackhole,		    	  NULL, &match, NULL) == ISC_R_SUCCESS &&	    match > 0)	{		if (isc_log_wouldlog(dns_lctx, LVL(10))) {			char netaddrstr[ISC_NETADDR_FORMATSIZE];			isc_netaddr_format(&netaddr, netaddrstr,					   sizeof(netaddrstr));			dispatch_log(disp, LVL(10),				     "blackholed packet from %s",				     netaddrstr);		}		free_buffer(disp, ev->region.base, ev->region.length);		goto restart;	}	/*	 * Peek into the buffer to see what we can see.	 */	isc_buffer_init(&source, ev->region.base, ev->region.length);	isc_buffer_add(&source, ev->n);	dres = dns_message_peekheader(&source, &id, &flags);	if (dres != ISC_R_SUCCESS) {		free_buffer(disp, ev->region.base, ev->region.length);		dispatch_log(disp, LVL(10), "got garbage packet");		goto restart;	}	dispatch_log(disp, LVL(92),		     "got valid DNS message header, /QR %c, id %u",		     ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);	/*	 * Look at flags.  If query, drop it. If response,	 * look to see where it goes.	 */	queue_response = ISC_FALSE;	if ((flags & DNS_MESSAGEFLAG_QR) == 0) {		/* query */		free_buffer(disp, ev->region.base, ev->region.length);		goto restart;	}	/* response */	bucket = dns_hash(qid, &ev->address, id);	LOCK(&qid->lock);	resp = bucket_search(qid, &ev->address, id, bucket);	dispatch_log(disp, LVL(90),		     "search for response in bucket %d: %s",		     bucket, (resp == NULL ? "not found" : "found"));	if (resp == NULL) {		free_buffer(disp, ev->region.base, ev->region.length);		goto unlock;	} 	queue_response = resp->item_out;	rev = allocate_event(resp->disp);	if (rev == NULL) {		free_buffer(disp, ev->region.base, ev->region.length);		goto unlock;	}	/*	 * At this point, rev contains the event we want to fill in, and	 * resp contains the information on the place to send it to.	 * Send the event off.	 */	isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length);	isc_buffer_add(&rev->buffer, ev->n);	rev->result = ISC_R_SUCCESS;	rev->id = id;	rev->addr = ev->address;	rev->pktinfo = ev->pktinfo;	rev->attributes = ev->attributes;	if (queue_response) {		ISC_LIST_APPEND(resp->items, rev, ev_link);	} else {		ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL,			       DNS_EVENT_DISPATCH,			       resp->action, resp->arg, resp, NULL, NULL);		request_log(disp, resp, LVL(90),			    "[a] Sent event %p buffer %p len %d to task %p",			    rev, rev->buffer.base, rev->buffer.length,			    resp->task);		resp->item_out = ISC_TRUE;		isc_task_send(resp->task, ISC_EVENT_PTR(&rev));	} unlock:	UNLOCK(&qid->lock);	/*	 * Restart recv() to get the next packet.	 */ restart:	startrecv(disp);	UNLOCK(&disp->lock);	isc_event_free(&ev_in);}/* * General flow: * * If I/O result == CANCELED, EOF, or error, notify everyone as the * various queues drain. * * If query, restart. * * If response: *	Allocate event, fill in details. *		If cannot allocate, restart. *	find target.  If not found, restart. *	if event queue is not empty, queue.  else, send. *	restart. */static voidtcp_recv(isc_task_t *task, isc_event_t *ev_in) {	dns_dispatch_t *disp = ev_in->ev_arg;	dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;	dns_messageid_t id;	isc_result_t dres;	unsigned int flags;	dns_dispentry_t *resp;	dns_dispatchevent_t *rev;	unsigned int bucket;	isc_boolean_t killit;	isc_boolean_t queue_response;	dns_qid_t *qid;	int level;	char buf[ISC_SOCKADDR_FORMATSIZE];	UNUSED(task);	REQUIRE(VALID_DISPATCH(disp));	qid = disp->qid;	dispatch_log(disp, LVL(90),		     "got TCP packet: requests %d, buffers %d, recvs %d",		     disp->requests, disp->tcpbuffers, disp->recv_pending);	LOCK(&disp->lock);	INSIST(disp->recv_pending != 0);	disp->recv_pending = 0;	if (disp->refcount == 0) {		/*		 * This dispatcher is shutting down.  Force cancelation.		 */		tcpmsg->result = ISC_R_CANCELED;	}	if (tcpmsg->result != ISC_R_SUCCESS) {		switch (tcpmsg->result) {		case ISC_R_CANCELED:			break;					case ISC_R_EOF:			dispatch_log(disp, LVL(90), "shutting down on EOF");			do_cancel(disp);			break;		case ISC_R_CONNECTIONRESET:			level = ISC_LOG_INFO;			goto logit;		default:			level = ISC_LOG_ERROR;		logit:			isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf));			dispatch_log(disp, level, "shutting down due to TCP "				     "receive error: %s: %s", buf,				     isc_result_totext(tcpmsg->result));			do_cancel(disp);			break;		}		/*		 * The event is statically allocated in the tcpmsg		 * structure, and destroy_disp() frees the tcpmsg, so we must		 * free the event *before* calling destroy_disp().		 */		isc_event_free(&ev_in);		disp->shutting_down = 1;		disp->shutdown_why = tcpmsg->result;		/*		 * If the recv() was canceled pass the word on.		 */		killit = destroy_disp_ok(disp);		UNLOCK(&disp->lock);		if (killit)			isc_task_send(disp->task, &disp->ctlevent);		return;	}	dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p",		     tcpmsg->result,		     tcpmsg->buffer.length, tcpmsg->buffer.base);	/*	 * Peek into the buffer to see what we can see.	 */	dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags);	if (dres != ISC_R_SUCCESS) {		dispatch_log(disp, LVL(10), "got garbage packet");		goto restart;	}	dispatch_log(disp, LVL(92),		     "got valid DNS message header, /QR %c, id %u",		     ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id);	/*	 * Allocate an event to send to the query or response client, and	 * allocate a new buffer for our use.	 */	/*	 * Look at flags.  If query, drop it. If response,	 * look to see where it goes.	 */	queue_response = ISC_FALSE;	if ((flags & DNS_MESSAGEFLAG_QR) == 0) {		/*		 * Query.		 */		goto restart;	}	/*	 * Response.	 */	bucket = dns_hash(qid, &tcpmsg->address, id);	LOCK(&qid->lock);	resp = bucket_search(qid, &tcpmsg->address, id, bucket);	dispatch_log(disp, LVL(90),		     "search for response in bucket %d: %s",		     bucket, (resp == NULL ? "not found" : "found"));	if (resp == NULL)		goto unlock;	queue_response = resp->item_out;	rev = allocate_event(disp);	if (rev == NULL)		goto unlock;	/*	 * At this point, rev contains the event we want to fill in, and	 * resp contains the information on the place to send it to.	 * Send the event off.	 */	dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer);	disp->tcpbuffers++;	rev->result = ISC_R_SUCCESS;	rev->id = id;	rev->addr = tcpmsg->address;	if (queue_response) {		ISC_LIST_APPEND(resp->items, rev, ev_link);	} else {		ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH,			       resp->action, resp->arg, resp, NULL, NULL);		request_log(disp, resp, LVL(90),			    "[b] Sent event %p buffer %p len %d to task %p",			    rev, rev->buffer.base, rev->buffer.length,			    resp->task);		resp->item_out = ISC_TRUE;		isc_task_send(resp->task, ISC_EVENT_PTR(&rev));	} unlock:	UNLOCK(&qid->lock);	/*	 * Restart recv() to get the next packet.	 */ restart:	startrecv(disp);	UNLOCK(&disp->lock);	isc_event_free(&ev_in);}/* * disp must be locked. */static voidstartrecv(dns_dispatch_t *disp) {	isc_result_t res;	isc_region_t region;	if (disp->shutting_down == 1)		return;	if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0)		return;	if (disp->recv_pending != 0)		return;	if (disp->mgr->buffers >= disp->mgr->maxbuffers)		return;	switch (disp->socktype) {		/*		 * UDP reads are always maximal.		 */	case isc_sockettype_udp:		region.length = disp->mgr->buffersize;		region.base = allocate_udp_buffer(disp);		if (region.base == NULL)			return;		res = isc_socket_recv(disp->socket, &region, 1,				      disp->task, udp_recv, disp);		if (res != ISC_R_SUCCESS) {			free_buffer(disp, region.base, region.length);			disp->shutdown_why = res;			disp->shutting_down = 1;			do_cancel(disp);			return;		}		INSIST(disp->recv_pending == 0);		disp->recv_pending = 1;		break;	case isc_sockettype_tcp:		res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task,					     tcp_recv, disp);		if (res != ISC_R_SUCCESS) {			disp->shutdown_why = res;			disp->shutting_down = 1;			do_cancel(disp);			return;		}		INSIST(disp->recv_pending == 0);		disp->recv_pending = 1;		break;	}}/* * Mgr must be locked when calling this function. */static isc_boolean_tdestroy_mgr_ok(dns_dispatchmgr_t *mgr) {	mgr_log(mgr, LVL(90),		"destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, "		"epool=%d, rpool=%d, dpool=%d",		MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list),		isc_mempool_getallocated(mgr->epool),		isc_mempool_getallocated(mgr->rpool),		isc_mempool_getallocated(mgr->dpool));	if (!MGR_IS_SHUTTINGDOWN(mgr))		return (ISC_FALSE);	if (!ISC_LIST_EMPTY(mgr->list))		return (ISC_FALSE);	if (isc_mempool_getallocated(mgr->epool) != 0)		return (ISC_FALSE);	if (isc_mempool_getallocated(mgr->rpool) != 0)		return (ISC_FALSE);	if (isc_mempool_getallocated(mgr->dpool) != 0)		return (ISC_FALSE);	return (ISC_TRUE);}/* * Mgr must be unlocked when calling this function. */static voiddestroy_mgr(dns_dispatchmgr_t **mgrp) {	isc_mem_t *mctx;	dns_dispatchmgr_t *mgr;	mgr = *mgrp;	*mgrp = NULL;	mctx = mgr->mctx;	mgr->magic = 0;	mgr->mctx = NULL;	DESTROYLOCK(&mgr->lock);	mgr->state = 0;	isc_mempool_destroy(&mgr->epool);	isc_mempool_destroy(&mgr->rpool);	isc_mempool_destroy(&mgr->dpool);	isc_mempool_destroy(&mgr->bpool);	DESTROYLOCK(&mgr->pool_lock);	if (mgr->entropy != NULL)		isc_entropy_detach(&mgr->entropy);	if (mgr->qid != NULL)		qid_destroy(mctx, &mgr->qid);	DESTROYLOCK(&mgr->buffer_lock);	if (mgr->blackhole != NULL)		dns_acl_detach(&mgr->blackhole);	if (mgr->portlist != NULL)		dns_portlist_detach(&mgr->portlist);	isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));	isc_mem_detach(&mctx);}static isc_result_tcreate_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,	      isc_socket_t **sockp){	isc_socket_t *sock;	isc_result_t result;	sock = NULL;	result = isc_socket_create(mgr, isc_sockaddr_pf(local),				   isc_sockettype_udp, &sock);	if (result != ISC_R_SUCCESS)		return (result);#ifndef ISC_ALLOW_MAPPED	isc_socket_ipv6only(sock, ISC_TRUE);#endif	result = isc_socket_bind(sock, local);	if (result != ISC_R_SUCCESS) {		isc_socket_detach(&sock);		return (result);	}	*sockp = sock;	return (ISC_R_SUCCESS);}/* * Publics. */isc_result_tdns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,		       dns_dispatchmgr_t **mgrp){	dns_dispatchmgr_t *mgr;	isc_result_t result;	REQUIRE(mctx != NULL);	REQUIRE(mgrp != NULL && *mgrp == NULL);	mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t));	if (mgr == NULL)		return (ISC_R_NOMEMORY);	mgr->mctx = NULL;	isc_mem_attach(mctx, &mgr->mctx);	mgr->blackhole = NULL;	mgr->portlist = NULL;	result = isc_mutex_init(&mgr->lock);	if (result != ISC_R_SUCCESS)		goto deallocate;	result = isc_mutex_init(&mgr->buffer_lock);	if (result != ISC_R_SUCCESS)		goto kill_lock;	result = isc_mutex_init(&mgr->pool_lock);	if (result != ISC_R_SUCCESS)		goto kill_buffer_lock;	mgr->epool = NULL;	if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t),			       &mgr->epool) != ISC_R_SUCCESS) {		result = ISC_R_NOMEMORY;		goto kill_pool_lock;	}	mgr->rpool = NULL;	if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t),			       &mgr->rpool) != ISC_R_SUCCESS) {		result = ISC_R_NOMEMORY;		goto kill_epool;	}	mgr->dpool = NULL;	if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t),			       &mgr->dpool) != ISC_R_SUCCESS) {		result = ISC_R_NOMEMORY;		goto kill_rpool;	}	isc_mempool_setname(mgr->epool, "dispmgr_epool");	isc_mempool_setfreemax(mgr->epool, 1024);	isc_mempool_associatelock(mgr->epool, &mgr->pool_lock);	isc_mempool_setname(mgr->rpool, "dispmgr_rpool");	isc_mempool_setfreemax(mgr->rpool, 1024);	isc_mempool_associatelock(mgr->rpool, &mgr->pool_lock);	isc_mempool_setname(mgr->dpool, "dispmgr_dpool");	isc_mempool_setfreemax(mgr->dpool, 1024);	isc_mempool_associatelock(mgr->dpool, &mgr->pool_lock);	mgr->buffers = 0;	mgr->buffersize = 0;	mgr->maxbuffers = 0;	mgr->bpool = NULL;	mgr->entropy = NULL;	mgr->qid = NULL;

⌨️ 快捷键说明

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