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

📄 resolver.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
			factor = DNS_ADB_RTTADJDEFAULT;		} else {			/*			 * We don't have an RTT for this query.  Maybe the			 * packet was lost, or maybe this server is very			 * slow.  We don't know.  Increase the RTT.			 */			INSIST(no_response);			rtt = query->addrinfo->srtt +				(100000 * fctx->restarts);			if (rtt > 10000000)				rtt = 10000000;			/*			 * Replace the current RTT with our value.			 */			factor = DNS_ADB_RTTADJREPLACE;		}		dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);	}	/*	 * Age RTTs of servers not tried.	 */	factor = DNS_ADB_RTTADJAGE;	if (finish != NULL)		for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);		     addrinfo != NULL;		     addrinfo = ISC_LIST_NEXT(addrinfo, publink))			if (UNMARKED(addrinfo))				dns_adb_adjustsrtt(fctx->adb, addrinfo,						   0, factor);	if (finish != NULL && TRIEDFIND(fctx))		for (find = ISC_LIST_HEAD(fctx->finds);		     find != NULL;		     find = ISC_LIST_NEXT(find, publink))			for (addrinfo = ISC_LIST_HEAD(find->list);			     addrinfo != NULL;			     addrinfo = ISC_LIST_NEXT(addrinfo, publink))				if (UNMARKED(addrinfo))					dns_adb_adjustsrtt(fctx->adb, addrinfo,							   0, factor);	if (finish != NULL && TRIEDALT(fctx)) {		for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);		     addrinfo != NULL;		     addrinfo = ISC_LIST_NEXT(addrinfo, publink))			if (UNMARKED(addrinfo))				dns_adb_adjustsrtt(fctx->adb, addrinfo,						   0, factor);		for (find = ISC_LIST_HEAD(fctx->altfinds);		     find != NULL;		     find = ISC_LIST_NEXT(find, publink))			for (addrinfo = ISC_LIST_HEAD(find->list);			     addrinfo != NULL;			     addrinfo = ISC_LIST_NEXT(addrinfo, publink))				if (UNMARKED(addrinfo))					dns_adb_adjustsrtt(fctx->adb, addrinfo,							   0, factor);	}	if (query->dispentry != NULL)		dns_dispatch_removeresponse(&query->dispentry, deventp);	ISC_LIST_UNLINK(fctx->queries, query, link);	if (query->tsig != NULL)		isc_buffer_free(&query->tsig);	if (query->tsigkey != NULL)		dns_tsigkey_detach(&query->tsigkey);	/*	 * Check for any outstanding socket events.  If they exist, cancel	 * them and let the event handlers finish the cleanup.  The resolver	 * only needs to worry about managing the connect and send events;	 * the dispatcher manages the recv events.	 */	if (RESQUERY_CONNECTING(query))		/*		 * Cancel the connect.		 */		isc_socket_cancel(query->tcpsocket, NULL,				  ISC_SOCKCANCEL_CONNECT);	else if (RESQUERY_SENDING(query))		/*		 * Cancel the pending send.		 */		isc_socket_cancel(dns_dispatch_getsocket(query->dispatch),				  NULL, ISC_SOCKCANCEL_SEND);	if (query->dispatch != NULL)		dns_dispatch_detach(&query->dispatch);	if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query)))		/*		 * It's safe to destroy the query now.		 */		resquery_destroy(&query);}static voidfctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {	resquery_t *query, *next_query;	FCTXTRACE("cancelqueries");	for (query = ISC_LIST_HEAD(fctx->queries);	     query != NULL;	     query = next_query) {		next_query = ISC_LIST_NEXT(query, link);		fctx_cancelquery(&query, NULL, NULL, no_response);	}}static voidfctx_cleanupfinds(fetchctx_t *fctx) {	dns_adbfind_t *find, *next_find;	REQUIRE(ISC_LIST_EMPTY(fctx->queries));	for (find = ISC_LIST_HEAD(fctx->finds);	     find != NULL;	     find = next_find) {		next_find = ISC_LIST_NEXT(find, publink);		ISC_LIST_UNLINK(fctx->finds, find, publink);		dns_adb_destroyfind(&find);	}	fctx->find = NULL;}static voidfctx_cleanupaltfinds(fetchctx_t *fctx) {	dns_adbfind_t *find, *next_find;	REQUIRE(ISC_LIST_EMPTY(fctx->queries));	for (find = ISC_LIST_HEAD(fctx->altfinds);	     find != NULL;	     find = next_find) {		next_find = ISC_LIST_NEXT(find, publink);		ISC_LIST_UNLINK(fctx->altfinds, find, publink);		dns_adb_destroyfind(&find);	}	fctx->altfind = NULL;}static voidfctx_cleanupforwaddrs(fetchctx_t *fctx) {	dns_adbaddrinfo_t *addr, *next_addr;	REQUIRE(ISC_LIST_EMPTY(fctx->queries));	for (addr = ISC_LIST_HEAD(fctx->forwaddrs);	     addr != NULL;	     addr = next_addr) {		next_addr = ISC_LIST_NEXT(addr, publink);		ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);		dns_adb_freeaddrinfo(fctx->adb, &addr);	}}static voidfctx_cleanupaltaddrs(fetchctx_t *fctx) {	dns_adbaddrinfo_t *addr, *next_addr;	REQUIRE(ISC_LIST_EMPTY(fctx->queries));	for (addr = ISC_LIST_HEAD(fctx->altaddrs);	     addr != NULL;	     addr = next_addr) {		next_addr = ISC_LIST_NEXT(addr, publink);		ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);		dns_adb_freeaddrinfo(fctx->adb, &addr);	}}static inline voidfctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) {	FCTXTRACE("stopeverything");	fctx_cancelqueries(fctx, no_response);	fctx_cleanupfinds(fctx);	fctx_cleanupaltfinds(fctx);	fctx_cleanupforwaddrs(fctx);	fctx_cleanupaltaddrs(fctx);	fctx_stoptimer(fctx);}static inline voidfctx_sendevents(fetchctx_t *fctx, isc_result_t result) {	dns_fetchevent_t *event, *next_event;	isc_task_t *task;	/*	 * Caller must be holding the appropriate bucket lock.	 */	REQUIRE(fctx->state == fetchstate_done);	FCTXTRACE("sendevents");	for (event = ISC_LIST_HEAD(fctx->events);	     event != NULL;	     event = next_event) {		next_event = ISC_LIST_NEXT(event, ev_link);		ISC_LIST_UNLINK(fctx->events, event, ev_link);		task = event->ev_sender;		event->ev_sender = fctx;		if (!HAVE_ANSWER(fctx))			event->result = result;		INSIST(result != ISC_R_SUCCESS ||		       dns_rdataset_isassociated(event->rdataset) ||		       fctx->type == dns_rdatatype_any ||		       fctx->type == dns_rdatatype_rrsig);		isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event));	}}static voidfctx_done(fetchctx_t *fctx, isc_result_t result) {	dns_resolver_t *res;	isc_boolean_t no_response;	FCTXTRACE("done");	res = fctx->res;	if (result == ISC_R_SUCCESS)		no_response = ISC_TRUE;	else		no_response = ISC_FALSE;	fctx_stopeverything(fctx, no_response);	LOCK(&res->buckets[fctx->bucketnum].lock);	fctx->state = fetchstate_done;	fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;	fctx_sendevents(fctx, result);	UNLOCK(&res->buckets[fctx->bucketnum].lock);}static voidresquery_senddone(isc_task_t *task, isc_event_t *event) {	isc_socketevent_t *sevent = (isc_socketevent_t *)event;	resquery_t *query = event->ev_arg;	REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);	QTRACE("senddone");	/*	 * XXXRTH	 *	 * Currently we don't wait for the senddone event before retrying	 * a query.  This means that if we get really behind, we may end	 * up doing extra work!	 */	UNUSED(task);	INSIST(RESQUERY_SENDING(query));	query->sends--;	if (RESQUERY_CANCELED(query)) {		if (query->sends == 0) {			/*			 * This query was canceled while the			 * isc_socket_sendto() was in progress.			 */			if (query->tcpsocket != NULL)				isc_socket_detach(&query->tcpsocket);			resquery_destroy(&query);		}	} else if (sevent->result != ISC_R_SUCCESS)		fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);	isc_event_free(&event);}static inline isc_result_tfctx_addopt(dns_message_t *message, dns_resolver_t *res) {	dns_rdataset_t *rdataset;	dns_rdatalist_t *rdatalist;	dns_rdata_t *rdata;	isc_result_t result;	rdatalist = NULL;	result = dns_message_gettemprdatalist(message, &rdatalist);	if (result != ISC_R_SUCCESS)		return (result);	rdata = NULL;	result = dns_message_gettemprdata(message, &rdata);	if (result != ISC_R_SUCCESS)		return (result);	rdataset = NULL;	result = dns_message_gettemprdataset(message, &rdataset);	if (result != ISC_R_SUCCESS)		return (result);	dns_rdataset_init(rdataset);	rdatalist->type = dns_rdatatype_opt;	rdatalist->covers = 0;	/*	 * Set Maximum UDP buffer size.	 */	rdatalist->rdclass = res->udpsize;	/*	 * Set EXTENDED-RCODE, VERSION, and Z to 0, and the DO bit to 1.	 */	rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO;	/*	 * No EDNS options.	 */	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);	return (dns_message_setopt(message, rdataset));}static inline voidfctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {	unsigned int seconds;	/*	 * We retry every 2 seconds the first two times through the address	 * list, and then we do exponential back-off.	 */	if (fctx->restarts < 3)		seconds = 2;	else		seconds = (2 << (fctx->restarts - 1));	/*	 * Double the round-trip time and convert to seconds.	 */	rtt /= 500000;	/*	 * Always wait for at least the doubled round-trip time.	 */	if (seconds < rtt)		seconds = rtt;	/*	 * But don't ever wait for more than 30 seconds.	 */	if (seconds > 30)		seconds = 30;	isc_interval_set(&fctx->interval, seconds, 0);}static isc_result_tfctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,	   unsigned int options){	dns_resolver_t *res;	isc_task_t *task;	isc_result_t result;	resquery_t *query;	FCTXTRACE("query");	res = fctx->res;	task = res->buckets[fctx->bucketnum].task;	fctx_setretryinterval(fctx, addrinfo->srtt);	result = fctx_startidletimer(fctx);	if (result != ISC_R_SUCCESS)		return (result);	dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);	query = isc_mem_get(res->mctx, sizeof(*query));	if (query == NULL) {		result = ISC_R_NOMEMORY;		goto stop_idle_timer;	}	query->mctx = res->mctx;	query->options = options;	query->attributes = 0;	query->sends = 0;	query->connects = 0;	/*	 * Note that the caller MUST guarantee that 'addrinfo' will remain	 * valid until this query is canceled.	 */	query->addrinfo = addrinfo;	TIME_NOW(&query->start);	/*	 * If this is a TCP query, then we need to make a socket and	 * a dispatch for it here.  Otherwise we use the resolver's	 * shared dispatch.	 */	query->dispatchmgr = res->dispatchmgr;	query->dispatch = NULL;	query->tcpsocket = NULL;	if ((query->options & DNS_FETCHOPT_TCP) != 0) {		isc_sockaddr_t addr;		int pf;		pf = isc_sockaddr_pf(&addrinfo->sockaddr);		switch (pf) {		case PF_INET:			result = dns_dispatch_getlocaladdress(res->dispatchv4,							      &addr);			break;		case PF_INET6:			result = dns_dispatch_getlocaladdress(res->dispatchv6,							      &addr);			break;		default:			result = ISC_R_NOTIMPLEMENTED;			break;		}		if (result != ISC_R_SUCCESS)			goto cleanup_query;		isc_sockaddr_setport(&addr, 0);		result = isc_socket_create(res->socketmgr, pf,					   isc_sockettype_tcp,					   &query->tcpsocket);		if (result != ISC_R_SUCCESS)			goto cleanup_query;		result = isc_socket_bind(query->tcpsocket, &addr);		if (result != ISC_R_SUCCESS)			goto cleanup_socket;		/*		 * A dispatch will be created once the connect succeeds.		 */	} else {		switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {		case PF_INET:			dns_dispatch_attach(res->dispatchv4, &query->dispatch);			break;		case PF_INET6:			dns_dispatch_attach(res->dispatchv6, &query->dispatch);			break;		default:			result = ISC_R_NOTIMPLEMENTED;			goto cleanup_query;		}		/*		 * We should always have a valid dispatcher here.  If we		 * don't support a protocol family, then its dispatcher		 * will be NULL, but we shouldn't be finding addresses for		 * protocol types we don't support, so the dispatcher		 * we found should never be NULL.		 */		INSIST(query->dispatch != NULL);	}	query->dispentry = NULL;	query->fctx = fctx;	query->tsig = NULL;	query->tsigkey = NULL;	ISC_LINK_INIT(query, link);	query->magic = QUERY_MAGIC;	if ((query->options & DNS_FETCHOPT_TCP) != 0) {		/*		 * Connect to the remote server.		 *		 * XXXRTH  Should we attach to the socket?		 */		result = isc_socket_connect(query->tcpsocket,					    &addrinfo->sockaddr, task,					    resquery_connected, query);		if (result != ISC_R_SUCCESS)			goto cleanup_socket;		query->connects++;		QTRACE("connecting via TCP");	} else {		result = resquery_send(query);		if (result != ISC_R_SUCCESS)			goto cleanup_dispatch;	}	ISC_LIST_APPEND(fctx->queries, query, link);	return (ISC_R_SUCCESS); cleanup_socket:	isc_socket_detach(&query->tcpsocket); cleanup_dispatch:	if (query->dispatch != NULL)		dns_dispatch_detach(&query->dispatch); cleanup_query:	query->magic = 0;	isc_mem_put(res->mctx, query, sizeof(*query)); stop_idle_timer:	RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS);	return (result);}

⌨️ 快捷键说明

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