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

📄 client.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	} unlock:	if (locked_manager != NULL) {		UNLOCK(&locked_manager->lock);		locked_manager = NULL;	}	/*	 * Only now is it safe to destroy the client manager (if needed),	 * because we have accessed its lock for the last time.	 */	if (destroy_manager != NULL)		clientmgr_destroy(destroy_manager);	return (ISC_TRUE);}/* * The client's task has received the client's control event * as part of the startup process. */static voidclient_start(isc_task_t *task, isc_event_t *event) {	ns_client_t *client = (ns_client_t *) event->ev_arg;	INSIST(task == client->task);	UNUSED(task);	INSIST(client->nctls == 1);	client->nctls--;	if (exit_check(client))		return;	if (TCP_CLIENT(client)) {		client_accept(client);	} else {		client_udprecv(client);	}}/* * The client's task has received a shutdown event. */static voidclient_shutdown(isc_task_t *task, isc_event_t *event) {	ns_client_t *client;	REQUIRE(event != NULL);	REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN);	client = event->ev_arg;	REQUIRE(NS_CLIENT_VALID(client));	REQUIRE(task == client->task);	UNUSED(task);	CTRACE("shutdown");	isc_event_free(&event);	if (client->shutdown != NULL) {		(client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN);		client->shutdown = NULL;		client->shutdown_arg = NULL;	}	client->newstate = NS_CLIENTSTATE_FREED;	(void)exit_check(client);}static voidns_client_endrequest(ns_client_t *client) {	INSIST(client->naccepts == 0);	INSIST(client->nreads == 0);	INSIST(client->nsends == 0);	INSIST(client->nrecvs == 0);	INSIST(client->nupdates == 0);	INSIST(client->state == NS_CLIENTSTATE_WORKING);	CTRACE("endrequest");	if (client->next != NULL) {		(client->next)(client);		client->next = NULL;	}	if (client->view != NULL)		dns_view_detach(&client->view);	if (client->opt != NULL) {		INSIST(dns_rdataset_isassociated(client->opt));		dns_rdataset_disassociate(client->opt);		dns_message_puttemprdataset(client->message, &client->opt);	}	client->udpsize = 512;	client->extflags = 0;	dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);	if (client->recursionquota != NULL)		isc_quota_detach(&client->recursionquota);	/*	 * Clear all client attributes that are specific to	 * the request; that's all except the TCP flag.	 */	client->attributes &= NS_CLIENTATTR_TCP;}static voidns_client_checkactive(ns_client_t *client) {	if (client->mortal) {		/*		 * This client object should normally go inactive		 * at this point, but if we have fewer active client		 * objects than  desired due to earlier quota exhaustion,		 * keep it active to make up for the shortage.		 */		isc_boolean_t need_another_client = ISC_FALSE;		if (TCP_CLIENT(client)) {			LOCK(&client->interface->lock);			if (client->interface->ntcpcurrent <			    client->interface->ntcptarget)				need_another_client = ISC_TRUE;			UNLOCK(&client->interface->lock);		} else {			/*			 * The UDP client quota is enforced by making			 * requests fail rather than by not listening			 * for new ones.  Therefore, there is always a			 * full set of UDP clients listening.			 */		}		if (! need_another_client) {			/*			 * We don't need this client object.  Recycle it.			 */			if (client->newstate >= NS_CLIENTSTATE_INACTIVE)				client->newstate = NS_CLIENTSTATE_INACTIVE;		}	}}voidns_client_next(ns_client_t *client, isc_result_t result) {	int newstate;	REQUIRE(NS_CLIENT_VALID(client));	REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||		client->state == NS_CLIENTSTATE_READING);	CTRACE("next");	if (result != ISC_R_SUCCESS)		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),			      "request failed: %s", isc_result_totext(result));	/*	 * An error processing a TCP request may have left	 * the connection out of sync.  To be safe, we always	 * sever the connection when result != ISC_R_SUCCESS.	 */	if (result == ISC_R_SUCCESS && TCP_CLIENT(client))		newstate = NS_CLIENTSTATE_READING;	else		newstate = NS_CLIENTSTATE_READY;	if (client->newstate > newstate)		client->newstate = newstate;	(void)exit_check(client);}static voidclient_senddone(isc_task_t *task, isc_event_t *event) {	ns_client_t *client;	isc_socketevent_t *sevent = (isc_socketevent_t *) event;	REQUIRE(sevent != NULL);	REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);	client = sevent->ev_arg;	REQUIRE(NS_CLIENT_VALID(client));	REQUIRE(task == client->task);	REQUIRE(sevent == client->sendevent);	UNUSED(task);	CTRACE("senddone");	if (sevent->result != ISC_R_SUCCESS)		ns_client_log(client, NS_LOGCATEGORY_CLIENT,			      NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,			      "error sending response: %s",			      isc_result_totext(sevent->result));	INSIST(client->nsends > 0);	client->nsends--;	if (client->tcpbuf != NULL) {		INSIST(TCP_CLIENT(client));		isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);		client->tcpbuf = NULL;	}	if (exit_check(client))		return;	ns_client_next(client, ISC_R_SUCCESS);}/* * We only want to fail with ISC_R_NOSPACE when called from * ns_client_sendraw() and not when called from ns_client_send(), * tcpbuffer is NULL when called from ns_client_sendraw() and * length != 0.  tcpbuffer != NULL when called from ns_client_send() * and length == 0. */static isc_result_tclient_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,		    isc_buffer_t *tcpbuffer, isc_uint32_t length,		    unsigned char *sendbuf, unsigned char **datap){	unsigned char *data;	isc_uint32_t bufsize;	isc_result_t result;	INSIST(datap != NULL);	INSIST((tcpbuffer == NULL && length != 0) ||	       (tcpbuffer != NULL && length == 0));	if (TCP_CLIENT(client)) {		INSIST(client->tcpbuf == NULL);		if (length + 2 > TCP_BUFFER_SIZE) {			result = ISC_R_NOSPACE;			goto done;		}		client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE);		if (client->tcpbuf == NULL) {			result = ISC_R_NOMEMORY;			goto done;		}		data = client->tcpbuf;		if (tcpbuffer != NULL) {			isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE);			isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2);		} else {			isc_buffer_init(buffer, data, TCP_BUFFER_SIZE);			INSIST(length <= 0xffff);			isc_buffer_putuint16(buffer, (isc_uint16_t)length);		}	} else {		data = sendbuf;		if (client->udpsize < SEND_BUFFER_SIZE)			bufsize = client->udpsize;		else			bufsize = SEND_BUFFER_SIZE;		if (length > bufsize) {			result = ISC_R_NOSPACE;			goto done;		}		isc_buffer_init(buffer, data, bufsize);	}	*datap = data;	result = ISC_R_SUCCESS; done:	return (result);}static isc_result_tclient_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {	struct in6_pktinfo *pktinfo;	isc_result_t result;	isc_region_t r;	isc_sockaddr_t *address;	isc_socket_t *socket;	isc_netaddr_t netaddr;	int match;	unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE;	if (TCP_CLIENT(client)) {		socket = client->tcpsocket;		address = NULL;	} else {		socket = client->udpsocket;		address = &client->peeraddr;		isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);		if (ns_g_server->blackholeacl != NULL &&		    dns_acl_match(&netaddr, NULL,			    	  ns_g_server->blackholeacl,				  &ns_g_server->aclenv,				  &match, NULL) == ISC_R_SUCCESS &&		    match > 0)			return (DNS_R_BLACKHOLED);		sockflags |= ISC_SOCKFLAG_NORETRY;	}	if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 &&	    (client->attributes & NS_CLIENTATTR_MULTICAST) == 0)		pktinfo = &client->pktinfo;	else		pktinfo = NULL;	isc_buffer_usedregion(buffer, &r);	CTRACE("sendto");		result = isc_socket_sendto2(socket, &r, client->task,				    address, pktinfo,				    client->sendevent, sockflags);	if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) {		client->nsends++;		if (result == ISC_R_SUCCESS)			client_senddone(client->task,					(isc_event_t *)client->sendevent);		result = ISC_R_SUCCESS;	}	return (result);}voidns_client_sendraw(ns_client_t *client, dns_message_t *message) {	isc_result_t result;	unsigned char *data;	isc_buffer_t buffer;	isc_region_t r;	isc_region_t *mr;	unsigned char sendbuf[SEND_BUFFER_SIZE];	REQUIRE(NS_CLIENT_VALID(client));	CTRACE("sendraw");	mr = dns_message_getrawmessage(message);	if (mr == NULL) {		result = ISC_R_UNEXPECTEDEND;		goto done;	}	result = client_allocsendbuf(client, &buffer, NULL, mr->length,				     sendbuf, &data);	if (result != ISC_R_SUCCESS)		goto done;	/*	 * Copy message to buffer and fixup id.	 */	isc_buffer_availableregion(&buffer, &r);	result = isc_buffer_copyregion(&buffer, mr);	if (result != ISC_R_SUCCESS)		goto done;	r.base[0] = (client->message->id >> 8) & 0xff;	r.base[1] = client->message->id & 0xff;	result = client_sendpkg(client, &buffer);	if (result == ISC_R_SUCCESS)		return; done:	if (client->tcpbuf != NULL) {		isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);		client->tcpbuf = NULL;	}	ns_client_next(client, result);}voidns_client_send(ns_client_t *client) {	isc_result_t result;	unsigned char *data;	isc_buffer_t buffer;	isc_buffer_t tcpbuffer;	isc_region_t r;	dns_compress_t cctx;	isc_boolean_t cleanup_cctx = ISC_FALSE;	unsigned char sendbuf[SEND_BUFFER_SIZE];	unsigned int dnssec_opts;	unsigned int preferred_glue;	REQUIRE(NS_CLIENT_VALID(client));	CTRACE("send");	if ((client->attributes & NS_CLIENTATTR_RA) != 0)		client->message->flags |= DNS_MESSAGEFLAG_RA;	if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)		dnssec_opts = 0;	else		dnssec_opts = DNS_MESSAGERENDER_OMITDNSSEC;	preferred_glue = 0;	if (client->view != NULL) {		if (client->view->preferred_glue == dns_rdatatype_a)			preferred_glue = DNS_MESSAGERENDER_PREFER_A;		else if (client->view->preferred_glue == dns_rdatatype_aaaa)			preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;	}	/*	 * XXXRTH  The following doesn't deal with TCP buffer resizing.	 */	result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0,				     sendbuf, &data);	if (result != ISC_R_SUCCESS)		goto done;	result = dns_compress_init(&cctx, -1, client->mctx);	if (result != ISC_R_SUCCESS)		goto done;	cleanup_cctx = ISC_TRUE;	result = dns_message_renderbegin(client->message, &cctx, &buffer);	if (result != ISC_R_SUCCESS)		goto done;	if (client->opt != NULL) {		result = dns_message_setopt(client->message, client->opt);		/*		 * XXXRTH dns_message_setopt() should probably do this...		 */		client->opt = NULL;		if (result != ISC_R_SUCCESS)			goto done;	}	result = dns_message_rendersection(client->message,					   DNS_SECTION_QUESTION, 0);	if (result == ISC_R_NOSPACE) {		client->message->flags |= DNS_MESSAGEFLAG_TC;		goto renderend;	}	if (result != ISC_R_SUCCESS)		goto done;	result = dns_message_rendersection(client->message,					   DNS_SECTION_ANSWER,					   DNS_MESSAGERENDER_PARTIAL |					   dnssec_opts);	if (result == ISC_R_NOSPACE) {		client->message->flags |= DNS_MESSAGEFLAG_TC;		goto renderend;	}	if (result != ISC_R_SUCCESS)		goto done;	result = dns_message_rendersection(client->message,					   DNS_SECTION_AUTHORITY,					   DNS_MESSAGERENDER_PARTIAL |					   dnssec_opts);	if (result == ISC_R_NOSPACE) {		client->message->flags |= DNS_MESSAGEFLAG_TC;		goto renderend;	}	if (result != ISC_R_SUCCESS)		goto done;	result = dns_message_rendersection(client->message,					   DNS_SECTION_ADDITIONAL,					   preferred_glue | dnssec_opts);	if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)		goto done; renderend:	result = dns_message_renderend(client->message);	if (result != ISC_R_SUCCESS)		goto done;	if (cleanup_cctx) {		dns_compress_invalidate(&cctx);		cleanup_cctx = ISC_FALSE;	}

⌨️ 快捷键说明

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