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

📄 client.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (TCP_CLIENT(client)) {		isc_buffer_usedregion(&buffer, &r);		isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length);		isc_buffer_add(&tcpbuffer, r.length);		result = client_sendpkg(client, &tcpbuffer);	} else		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;	}	if (cleanup_cctx)		dns_compress_invalidate(&cctx);	ns_client_next(client, result);}voidns_client_error(ns_client_t *client, isc_result_t result) {	dns_rcode_t rcode;	dns_message_t *message;	REQUIRE(NS_CLIENT_VALID(client));	CTRACE("error");	message = client->message;	rcode = dns_result_torcode(result);	/*	 * Message may be an in-progress reply that we had trouble	 * with, in which case QR will be set.  We need to clear QR before	 * calling dns_message_reply() to avoid triggering an assertion.	 */	message->flags &= ~DNS_MESSAGEFLAG_QR;	/*	 * AA and AD shouldn't be set.	 */	message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD);	result = dns_message_reply(message, ISC_TRUE);	if (result != ISC_R_SUCCESS) {		/*		 * It could be that we've got a query with a good header,		 * but a bad question section, so we try again with		 * want_question_section set to ISC_FALSE.		 */		result = dns_message_reply(message, ISC_FALSE);		if (result != ISC_R_SUCCESS) {			ns_client_next(client, result);			return;		}	}	message->rcode = rcode;	/*	 * FORMERR loop avoidance:  If we sent a FORMERR message	 * with the same ID to the same client less than two	 * seconds ago, assume that we are in an infinite error 	 * packet dialog with a server for some protocol whose 	 * error responses look enough like DNS queries to	 * elicit a FORMERR response.  Drop a packet to break	 * the loop.	 */	if (rcode == dns_rcode_formerr) {		if (isc_sockaddr_equal(&client->peeraddr,				       &client->formerrcache.addr) &&		    message->id == client->formerrcache.id &&		    client->requesttime - client->formerrcache.time < 2) {			/* Drop packet. */			ns_client_log(client, NS_LOGCATEGORY_CLIENT,				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),				      "possible error packet loop, "				      "FORMERR dropped");			ns_client_next(client, result);			return;		}		client->formerrcache.addr = client->peeraddr;		client->formerrcache.time = client->requesttime;		client->formerrcache.id = message->id;	}	ns_client_send(client);}static inline isc_result_tclient_addopt(ns_client_t *client) {	dns_rdataset_t *rdataset;	dns_rdatalist_t *rdatalist;	dns_rdata_t *rdata;	isc_result_t result;	dns_view_t *view;	dns_resolver_t *resolver;	isc_uint16_t udpsize;	REQUIRE(client->opt == NULL);	/* XXXRTH free old. */	rdatalist = NULL;	result = dns_message_gettemprdatalist(client->message, &rdatalist);	if (result != ISC_R_SUCCESS)		return (result);	rdata = NULL;	result = dns_message_gettemprdata(client->message, &rdata);	if (result != ISC_R_SUCCESS)		return (result);	rdataset = NULL;	result = dns_message_gettemprdataset(client->message, &rdataset);	if (result != ISC_R_SUCCESS)		return (result);	dns_rdataset_init(rdataset);	rdatalist->type = dns_rdatatype_opt;	rdatalist->covers = 0;	/*	 * Set the maximum UDP buffer size.	 */	view = client->view;	resolver = (view != NULL) ? view->resolver : NULL;	if (resolver != NULL)		udpsize = dns_resolver_getudpsize(resolver);	else		udpsize = ns_g_udpsize;	rdatalist->rdclass = udpsize;	/*	 * Set EXTENDED-RCODE, VERSION and Z to 0.	 */	rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE);	/*	 * No ENDS options in the default case.	 */	rdata->data = NULL;	rdata->length = 0;	rdata->rdclass = rdatalist->rdclass;	rdata->type = rdatalist->type;	rdata->flags = 0;	ISC_LIST_INIT(rdatalist->rdata);	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);	RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)		      == ISC_R_SUCCESS);	client->opt = rdataset;	return (ISC_R_SUCCESS);}static inline isc_boolean_tallowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl) {	int match;	isc_result_t result;	if (acl == NULL)		return (ISC_TRUE);	result = dns_acl_match(addr, signer, acl, &ns_g_server->aclenv,			       &match, NULL);	if (result == ISC_R_SUCCESS && match > 0)		return (ISC_TRUE);	return (ISC_FALSE);}/* * Handle an incoming request event from the socket (UDP case) * or tcpmsg (TCP case). */static voidclient_request(isc_task_t *task, isc_event_t *event) {	ns_client_t *client;	isc_socketevent_t *sevent;	isc_result_t result;	isc_result_t sigresult = ISC_R_SUCCESS;	isc_buffer_t *buffer;	isc_buffer_t tbuffer;	dns_view_t *view;	dns_rdataset_t *opt;	isc_boolean_t ra; 	/* Recursion available. */	isc_netaddr_t netaddr;	isc_netaddr_t destaddr;	int match;	dns_messageid_t id;	unsigned int flags;	isc_boolean_t notimp;	REQUIRE(event != NULL);	client = event->ev_arg;	REQUIRE(NS_CLIENT_VALID(client));	REQUIRE(task == client->task);	INSIST(client->recursionquota == NULL);	INSIST(client->state ==	       TCP_CLIENT(client) ?	       NS_CLIENTSTATE_READING :	       NS_CLIENTSTATE_READY);	if (event->ev_type == ISC_SOCKEVENT_RECVDONE) {		INSIST(!TCP_CLIENT(client));		sevent = (isc_socketevent_t *)event;		REQUIRE(sevent == client->recvevent);		isc_buffer_init(&tbuffer, sevent->region.base, sevent->n);		isc_buffer_add(&tbuffer, sevent->n);		buffer = &tbuffer;		result = sevent->result;		if (result == ISC_R_SUCCESS) {			client->peeraddr = sevent->address;			client->peeraddr_valid = ISC_TRUE;		}		if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) {			client->attributes |= NS_CLIENTATTR_PKTINFO;			client->pktinfo = sevent->pktinfo;		}		if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0)			client->attributes |= NS_CLIENTATTR_MULTICAST;		client->nrecvs--;	} else {		INSIST(TCP_CLIENT(client));		REQUIRE(event->ev_type == DNS_EVENT_TCPMSG);		REQUIRE(event->ev_sender == &client->tcpmsg);		buffer = &client->tcpmsg.buffer;		result = client->tcpmsg.result;		INSIST(client->nreads == 1);		/*		 * client->peeraddr was set when the connection was accepted.		 */		client->nreads--;	}	if (exit_check(client))		goto cleanup;	client->state = client->newstate = NS_CLIENTSTATE_WORKING;	isc_task_getcurrenttime(task, &client->requesttime);	client->now = client->requesttime;	if (result != ISC_R_SUCCESS) {		if (TCP_CLIENT(client)) {			ns_client_next(client, result);		} else {			if  (result != ISC_R_CANCELED)				isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,					      NS_LOGMODULE_CLIENT,					      ISC_LOG_ERROR,					      "UDP client handler shutting "					      "down due to fatal receive "					      "error: %s",					      isc_result_totext(result));			isc_task_shutdown(client->task);		}		goto cleanup;	}	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);	ns_client_log(client, NS_LOGCATEGORY_CLIENT,		      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),		      "%s request",		      TCP_CLIENT(client) ? "TCP" : "UDP");	/*	 * Check the blackhole ACL for UDP only, since TCP is done in	 * client_newconn.	 */	if (!TCP_CLIENT(client)) {		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)		{			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),				      "blackholed UDP datagram");			ns_client_next(client, ISC_R_SUCCESS);			goto cleanup;		}	}	/*	 * Silently drop multicast requests for the present.	 * XXXMPA look at when/if mDNS spec stabilizes.	 */	if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) {		ns_client_log(client, NS_LOGCATEGORY_CLIENT,			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),			      "dropping multicast request");		ns_client_next(client, DNS_R_REFUSED);	}	result = dns_message_peekheader(buffer, &id, &flags);	if (result != ISC_R_SUCCESS) {		/*		 * There isn't enough header to determine whether		 * this was a request or a response.  Drop it.		 */		ns_client_next(client, result);		goto cleanup;	}	/*	 * The client object handles requests, not responses.	 * If this is a UDP response, forward it to the dispatcher.	 * If it's a TCP response, discard it here.	 */	if ((flags & DNS_MESSAGEFLAG_QR) != 0) {		if (TCP_CLIENT(client)) {			CTRACE("unexpected response");			ns_client_next(client, DNS_R_FORMERR);			goto cleanup;		} else {			dns_dispatch_importrecv(client->dispatch, event);			ns_client_next(client, ISC_R_SUCCESS);			goto cleanup;		}	}	/*	 * It's a request.  Parse it.	 */	result = dns_message_parse(client->message, buffer, 0);	if (result != ISC_R_SUCCESS) {		/*		 * Parsing the request failed.  Send a response		 * (typically FORMERR or SERVFAIL).		 */		ns_client_error(client, result);		goto cleanup;	}	switch (client->message->opcode) {	case dns_opcode_query:	case dns_opcode_update:	case dns_opcode_notify:		notimp = ISC_FALSE;		break;	case dns_opcode_iquery:	default:		notimp = ISC_TRUE;		break;	}	client->message->rcode = dns_rcode_noerror;	/* RFC1123 section 6.1.3.2 */	if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0)		client->message->flags &= ~DNS_MESSAGEFLAG_RD;	/*	 * Deal with EDNS.	 */	opt = dns_message_getopt(client->message);	if (opt != NULL) {		unsigned int version;		/*		 * Set the client's UDP buffer size.		 */		client->udpsize = opt->rdclass;		/*		 * If the requested UDP buffer size is less than 512,		 * ignore it and use 512.		 */		if (client->udpsize < 512)			client->udpsize = 512;		/*		 * Get the flags out of the OPT record.		 */		client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF);		/*		 * Create an OPT for our reply.		 */		result = client_addopt(client);		if (result != ISC_R_SUCCESS) {			ns_client_error(client, result);			goto cleanup;		}		/*		 * Do we understand this version of ENDS?		 *		 * XXXRTH need library support for this!		 */		version = (opt->ttl & 0x00FF0000) >> 16;		if (version != 0) {			ns_client_error(client, DNS_R_BADVERS);			goto cleanup;		}	}	if (client->message->rdclass == 0) {		ns_client_log(client, NS_LOGCATEGORY_CLIENT,			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),			      "message class could not be determined");		ns_client_dumpmessage(client,				      "message class could not be determined");		ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);		goto cleanup;	}	/*	 * Determine the destination address.  If the receiving interface is	 * bound to a specific address, we simply use it regardless of the	 * address family.  All IPv4 queries should fall into this case.	 * Otherwise, if this is a TCP query, get the address from the	 * receiving socket (this needs a system call and can be heavy).	 * For IPv6 UDP queries, we get this from the pktinfo structure (if	 * supported).	 * If all the attempts fail (this can happen due to memory shortage,	 * etc), we regard this as an error for safety. 	 */	if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)		isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr);	else {		result = ISC_R_FAILURE;		if (TCP_CLIENT(client)) {			isc_sockaddr_t destsockaddr;			result = isc_socket_getsockname(client->tcpsocket,							&destsockaddr);			if (result == ISC_R_SUCCESS)				isc_netaddr_fromsockaddr(&destaddr,							 &destsockaddr);		}		if (result != ISC_R_SUCCESS &&		    client->interface->addr.type.sa.sa_family == AF_INET6 &&		    (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) {			isc_uint32_t zone = 0;			/*			 * XXXJT technically, we should convert the receiving			 * interface ID to a proper scope zone ID.  However,			 * due to the fact there is no standard API for this,			 * we only handle link-local addresses and use the			 * interface index as link ID.  Despite the assumption,			 * it should cover most typical cases.			 */			if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr))				zone = (isc_uint32_t)client->pktinfo.ipi6_ifindex;			isc_netaddr_fromin6(&destaddr,					    &client->pktinfo.ipi6_addr);			isc_netaddr_setzone(&destaddr, zone);			result = ISC_R_SUCCESS;		}		if (result != ISC_R_SUCCESS) {			UNEXPECTED_ERROR(__FILE__, __LINE__,					 "failed to get request's "					 "destination: %s",					 isc_result_totext(result));			goto cleanup;		}	}	/*	 * Find a view that matches the client's source address.	 */	for (view = ISC_LIST_HEAD(ns_g_server->viewlist);	     view != NULL;	     view = ISC_LIST_NEXT(view, link)) {		if (client->message->rdclass == view->rdclass ||		    client->message->rdclass == dns_rdataclass_any)		{			dns_name_t *tsig = NULL;			sigresult = dns_message_rechecksig(client->message,

⌨️ 快捷键说明

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