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

📄 request.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 3 页
字号:
			goto unlink;	}	req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: request %p",		request);	*requestp = request;	return (ISC_R_SUCCESS); unlink:	LOCK(&requestmgr->lock);	ISC_LIST_UNLINK(requestmgr->requests, request, link);	UNLOCK(&requestmgr->lock); cleanup:	if (tclone != NULL)		isc_task_detach(&tclone);	req_destroy(request);	req_log(ISC_LOG_DEBUG(3), "dns_request_createvia: failed %s",		dns_result_totext(result));	return (result);}static isc_result_treq_render(dns_message_t *message, isc_buffer_t **bufferp,	   unsigned int options, isc_mem_t *mctx){	isc_buffer_t *buf1 = NULL;	isc_buffer_t *buf2 = NULL;	isc_result_t result;	isc_region_t r;	isc_boolean_t tcp = ISC_FALSE;	dns_compress_t cctx;	isc_boolean_t cleanup_cctx = ISC_FALSE;	REQUIRE(bufferp != NULL && *bufferp == NULL);	req_log(ISC_LOG_DEBUG(3), "request_render");	/*	 * Create buffer able to hold largest possible message.	 */	result = isc_buffer_allocate(mctx, &buf1, 65535);	if (result != ISC_R_SUCCESS)		return (result);	result = dns_compress_init(&cctx, -1, mctx);	if (result != ISC_R_SUCCESS)		return (result);	cleanup_cctx = ISC_TRUE;	/*	 * Render message.	 */	result = dns_message_renderbegin(message, &cctx, buf1);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_message_renderend(message);	if (result != ISC_R_SUCCESS)		goto cleanup;	dns_compress_invalidate(&cctx);	cleanup_cctx = ISC_FALSE;	/*	 * Copy rendered message to exact sized buffer.	 */	isc_buffer_usedregion(buf1, &r);	if ((options & DNS_REQUESTOPT_TCP) != 0) {		tcp = ISC_TRUE;	} else if (r.length > 512) {		result = DNS_R_USETCP;		goto cleanup;	}	result = isc_buffer_allocate(mctx, &buf2, r.length + (tcp ? 2 : 0));	if (result != ISC_R_SUCCESS)		goto cleanup;	if (tcp)		isc_buffer_putuint16(buf2, (isc_uint16_t)r.length);	result = isc_buffer_copyregion(buf2, &r);	if (result != ISC_R_SUCCESS)		goto cleanup;	/*	 * Cleanup and return.	 */	isc_buffer_free(&buf1);	*bufferp = buf2;	return (ISC_R_SUCCESS); cleanup:	dns_message_renderreset(message);	if (buf1 != NULL)		isc_buffer_free(&buf1);	if (buf2 != NULL)		isc_buffer_free(&buf2);	if (cleanup_cctx)		dns_compress_invalidate(&cctx);	return (result);}/* * If this request is no longer waiting for events, * send the completion event.  This will ultimately * cause the request to be destroyed. * * Requires: *	'request' is locked by the caller. */static voidsend_if_done(dns_request_t *request, isc_result_t result) {	if (!DNS_REQUEST_CONNECTING(request) &&	    !DNS_REQUEST_SENDING(request) &&	    !request->canceling)		req_sendevent(request, result);}/* * Handle the control event. */static voiddo_cancel(isc_task_t *task, isc_event_t *event) {	dns_request_t *request = event->ev_arg;	UNUSED(task);	INSIST(event->ev_type == DNS_EVENT_REQUESTCONTROL);	LOCK(&request->requestmgr->locks[request->hash]);	request->canceling = ISC_FALSE;	if (!DNS_REQUEST_CANCELED(request))		req_cancel(request);	send_if_done(request, ISC_R_CANCELED);	UNLOCK(&request->requestmgr->locks[request->hash]);	}isc_result_tdns_request_cancel(dns_request_t *request) {	REQUIRE(VALID_REQUEST(request));	req_log(ISC_LOG_DEBUG(3), "dns_request_cancel: request %p", request);	REQUIRE(VALID_REQUEST(request));	LOCK(&request->requestmgr->locks[request->hash]);	if (!request->canceling && !DNS_REQUEST_CANCELED(request)) {		isc_event_t *ev =  &request->ctlevent;		isc_task_send(request->event->ev_sender, &ev);		request->canceling = ISC_TRUE;	}	UNLOCK(&request->requestmgr->locks[request->hash]);	return (ISC_R_SUCCESS);}isc_result_tdns_request_getresponse(dns_request_t *request, dns_message_t *message,			unsigned int options){	isc_result_t result;	REQUIRE(VALID_REQUEST(request));	REQUIRE(request->answer != NULL);	req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",		request);	dns_message_setquerytsig(message, request->tsig);	dns_message_settsigkey(message, request->tsigkey);	result = dns_message_parse(message, request->answer, options);	if (result != ISC_R_SUCCESS)		return (result);	if (request->tsigkey != NULL)		result = dns_tsig_verify(request->answer, message, NULL, NULL);	return (result);}isc_boolean_tdns_request_usedtcp(dns_request_t *request) {	REQUIRE(VALID_REQUEST(request));	return (ISC_TF((request->flags & DNS_REQUEST_F_TCP) != 0));}voiddns_request_destroy(dns_request_t **requestp) {	dns_request_t *request;	REQUIRE(requestp != NULL && VALID_REQUEST(*requestp));	request = *requestp;	req_log(ISC_LOG_DEBUG(3), "dns_request_destroy: request %p", request);	LOCK(&request->requestmgr->lock);	LOCK(&request->requestmgr->locks[request->hash]);	ISC_LIST_UNLINK(request->requestmgr->requests, request, link);	INSIST(!DNS_REQUEST_CONNECTING(request));	INSIST(!DNS_REQUEST_SENDING(request));	UNLOCK(&request->requestmgr->locks[request->hash]);	UNLOCK(&request->requestmgr->lock);	/*	 * These should have been cleaned up by req_cancel() before	 * the completion event was sent.	 */	INSIST(!ISC_LINK_LINKED(request, link));	INSIST(request->dispentry == NULL);	INSIST(request->dispatch == NULL);	INSIST(request->timer == NULL);	req_destroy(request);	*requestp = NULL;}/*** *** Private: request. ***/static voidreq_connected(isc_task_t *task, isc_event_t *event) {	isc_socketevent_t *sevent = (isc_socketevent_t *)event;	isc_result_t result;	dns_request_t *request = event->ev_arg;	REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);	REQUIRE(VALID_REQUEST(request));	REQUIRE(DNS_REQUEST_CONNECTING(request));	req_log(ISC_LOG_DEBUG(3), "req_connected: request %p", request);	LOCK(&request->requestmgr->locks[request->hash]);	request->flags &= ~DNS_REQUEST_F_CONNECTING;	if (DNS_REQUEST_CANCELED(request)) {		/*		 * Send delayed event.		 */		if (DNS_REQUEST_TIMEDOUT(request))			send_if_done(request, ISC_R_TIMEDOUT);		else			send_if_done(request, ISC_R_CANCELED);	} else {		dns_dispatch_starttcp(request->dispatch);		result = sevent->result;		if (result == ISC_R_SUCCESS)			result = req_send(request, task, NULL);		if (result != ISC_R_SUCCESS) {			req_cancel(request);			send_if_done(request, ISC_R_CANCELED);		}	}	UNLOCK(&request->requestmgr->locks[request->hash]);	isc_event_free(&event);}static voidreq_senddone(isc_task_t *task, isc_event_t *event) {	isc_socketevent_t *sevent = (isc_socketevent_t *)event;	dns_request_t *request = event->ev_arg;	REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);	REQUIRE(VALID_REQUEST(request));	REQUIRE(DNS_REQUEST_SENDING(request));	req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request);	UNUSED(task);	LOCK(&request->requestmgr->locks[request->hash]);	request->flags &= ~DNS_REQUEST_F_SENDING;	if (DNS_REQUEST_CANCELED(request)) {		/*		 * Send delayed event.		 */		if (DNS_REQUEST_TIMEDOUT(request))			send_if_done(request, ISC_R_TIMEDOUT);		else			send_if_done(request, ISC_R_CANCELED);	} else if (sevent->result != ISC_R_SUCCESS) {			req_cancel(request);			send_if_done(request, ISC_R_CANCELED);	}	UNLOCK(&request->requestmgr->locks[request->hash]);	isc_event_free(&event);}static voidreq_response(isc_task_t *task, isc_event_t *event) {	isc_result_t result;	dns_request_t *request = event->ev_arg;	dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;	isc_region_t r;	REQUIRE(VALID_REQUEST(request));	REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);	UNUSED(task);	req_log(ISC_LOG_DEBUG(3), "req_response: request %p: %s", request,		dns_result_totext(devent->result));	LOCK(&request->requestmgr->locks[request->hash]);	result = devent->result;	if (result != ISC_R_SUCCESS)		goto done;	/*	 * Copy buffer to request.	 */	isc_buffer_usedregion(&devent->buffer, &r);	result = isc_buffer_allocate(request->mctx, &request->answer,				     r.length);	if (result != ISC_R_SUCCESS)		goto done;	result = isc_buffer_copyregion(request->answer, &r);	if (result != ISC_R_SUCCESS)		isc_buffer_free(&request->answer); done:	/*	 * Cleanup.	 */	dns_dispatch_removeresponse(&request->dispentry, &devent);	req_cancel(request);	/*	 * Send completion event.	 */	send_if_done(request, result);	UNLOCK(&request->requestmgr->locks[request->hash]);}static voidreq_timeout(isc_task_t *task, isc_event_t *event) {	dns_request_t *request = event->ev_arg;	REQUIRE(VALID_REQUEST(request));	req_log(ISC_LOG_DEBUG(3), "req_timeout: request %p", request);	UNUSED(task);	LOCK(&request->requestmgr->locks[request->hash]);	request->flags |= DNS_REQUEST_F_TIMEDOUT;	req_cancel(request);	send_if_done(request, ISC_R_TIMEDOUT);	UNLOCK(&request->requestmgr->locks[request->hash]);	isc_event_free(&event);}static voidreq_sendevent(dns_request_t *request, isc_result_t result) {	isc_task_t *task;	REQUIRE(VALID_REQUEST(request));	req_log(ISC_LOG_DEBUG(3), "req_sendevent: request %p", request);	/*	 * Lock held by caller.	 */	task = request->event->ev_sender;	request->event->ev_sender = request;	request->event->result = result;	isc_task_sendanddetach(&task, (isc_event_t **)&request->event);}static voidreq_destroy(dns_request_t *request) {	isc_mem_t *mctx;	REQUIRE(VALID_REQUEST(request));	req_log(ISC_LOG_DEBUG(3), "req_destroy: request %p", request);	request->magic = 0;	if (request->query != NULL)		isc_buffer_free(&request->query);	if (request->answer != NULL)		isc_buffer_free(&request->answer);	if (request->event != NULL)		isc_event_free((isc_event_t **)&request->event);	if (request->dispentry != NULL)		dns_dispatch_removeresponse(&request->dispentry, NULL);	if (request->dispatch != NULL)		dns_dispatch_detach(&request->dispatch);	if (request->timer != NULL)		isc_timer_detach(&request->timer);	if (request->tsig != NULL)		isc_buffer_free(&request->tsig);	if (request->tsigkey != NULL)		dns_tsigkey_detach(&request->tsigkey);	if (request->requestmgr != NULL)		requestmgr_detach(&request->requestmgr);	mctx = request->mctx;	isc_mem_put(mctx, request, sizeof(*request));	isc_mem_detach(&mctx);}/* * Stop the current request.  Must be called from the request's task. */static voidreq_cancel(dns_request_t *request) {	isc_socket_t *socket;	REQUIRE(VALID_REQUEST(request));	req_log(ISC_LOG_DEBUG(3), "req_cancel: request %p", request);	/*	 * Lock held by caller.	 */	request->flags |= DNS_REQUEST_F_CANCELED;	if (request->timer != NULL)		isc_timer_detach(&request->timer);	if (request->dispentry != NULL)		dns_dispatch_removeresponse(&request->dispentry, NULL);	if (DNS_REQUEST_CONNECTING(request)) {		socket = dns_dispatch_getsocket(request->dispatch);		isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT);	}	if (DNS_REQUEST_SENDING(request)) {		socket = dns_dispatch_getsocket(request->dispatch);		isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);	}	dns_dispatch_detach(&request->dispatch);}static voidreq_log(int level, const char *fmt, ...) {	va_list ap;	va_start(ap, fmt);	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,		       DNS_LOGMODULE_REQUEST, level, fmt, ap);	va_end(ap);}

⌨️ 快捷键说明

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