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

📄 resolver.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	FCTXTRACE("add_bad");	sa = isc_mem_get(fctx->res->mctx, sizeof(*sa));	if (sa == NULL)		return;	*sa = *address;	ISC_LIST_INITANDAPPEND(fctx->bad, sa, link);	if (reason == DNS_R_LAME)	/* already logged */		return;	if (reason == DNS_R_UNEXPECTEDRCODE) {		isc_buffer_init(&b, code, sizeof(code) - 1);		dns_rcode_totext(fctx->rmessage->rcode, &b);		code[isc_buffer_usedlength(&b)] = '\0';		sep1 = "(";		sep2 = ") ";	} else if (reason == DNS_R_UNEXPECTEDOPCODE) {		isc_buffer_init(&b, code, sizeof(code) - 1);		dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b);		code[isc_buffer_usedlength(&b)] = '\0';		sep1 = "(";		sep2 = ") ";	} else {		code[0] = '\0';		sep1 = "";		sep2 = "";	}	dns_name_format(&fctx->name, namebuf, sizeof(namebuf));	dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));	dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf));	isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));	isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,		      DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,		      "%s %s%s%sresolving '%s/%s/%s': %s",		      dns_result_totext(reason), sep1, code, sep2,		      namebuf, typebuf, classbuf, addrbuf);}static voidsort_adbfind(dns_adbfind_t *find) {	dns_adbaddrinfo_t *best, *curr;	dns_adbaddrinfolist_t sorted;	/*	 * Lame N^2 bubble sort.	 */	ISC_LIST_INIT(sorted);	while (!ISC_LIST_EMPTY(find->list)) {		best = ISC_LIST_HEAD(find->list);		curr = ISC_LIST_NEXT(best, publink);		while (curr != NULL) {			if (curr->srtt < best->srtt)				best = curr;			curr = ISC_LIST_NEXT(curr, publink);		}		ISC_LIST_UNLINK(find->list, best, publink);		ISC_LIST_APPEND(sorted, best, publink);	}	find->list = sorted;}static voidsort_finds(fetchctx_t *fctx) {	dns_adbfind_t *best, *curr;	dns_adbfindlist_t sorted;	dns_adbaddrinfo_t *addrinfo, *bestaddrinfo;	/*	 * Lame N^2 bubble sort.	 */	ISC_LIST_INIT(sorted);	while (!ISC_LIST_EMPTY(fctx->finds)) {		best = ISC_LIST_HEAD(fctx->finds);		bestaddrinfo = ISC_LIST_HEAD(best->list);		INSIST(bestaddrinfo != NULL);		curr = ISC_LIST_NEXT(best, publink);		while (curr != NULL) {			addrinfo = ISC_LIST_HEAD(curr->list);			INSIST(addrinfo != NULL);			if (addrinfo->srtt < bestaddrinfo->srtt) {				best = curr;				bestaddrinfo = addrinfo;			}			curr = ISC_LIST_NEXT(curr, publink);		}		ISC_LIST_UNLINK(fctx->finds, best, publink);		ISC_LIST_APPEND(sorted, best, publink);	}	fctx->finds = sorted;	ISC_LIST_INIT(sorted);	while (!ISC_LIST_EMPTY(fctx->altfinds)) {		best = ISC_LIST_HEAD(fctx->altfinds);		bestaddrinfo = ISC_LIST_HEAD(best->list);		INSIST(bestaddrinfo != NULL);		curr = ISC_LIST_NEXT(best, publink);		while (curr != NULL) {			addrinfo = ISC_LIST_HEAD(curr->list);			INSIST(addrinfo != NULL);			if (addrinfo->srtt < bestaddrinfo->srtt) {				best = curr;				bestaddrinfo = addrinfo;			}			curr = ISC_LIST_NEXT(curr, publink);		}		ISC_LIST_UNLINK(fctx->altfinds, best, publink);		ISC_LIST_APPEND(sorted, best, publink);	}	fctx->altfinds = sorted;}static voidfindname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,	 unsigned int options, unsigned int flags, isc_stdtime_t now,	 isc_boolean_t *pruned, isc_boolean_t *need_alternate){	dns_adbaddrinfo_t *ai;	dns_adbfind_t *find;	dns_resolver_t *res;	isc_boolean_t unshared;	isc_result_t result;	res = fctx->res;	unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);	/*	 * If this name is a subdomain of the query domain, tell	 * the ADB to start looking using zone/hint data. This keeps us	 * from getting stuck if the nameserver is beneath the zone cut	 * and we don't know its address (e.g. because the A record has	 * expired).	 */	if (dns_name_issubdomain(name, &fctx->domain))		options |= DNS_ADBFIND_STARTATZONE;	options |= DNS_ADBFIND_GLUEOK;	options |= DNS_ADBFIND_HINTOK;	/*	 * See what we know about this address.	 */	find = NULL;	result = dns_adb_createfind(fctx->adb,				    res->buckets[fctx->bucketnum].task,				    fctx_finddone, fctx, name,				    &fctx->domain, options, now, NULL,				    res->view->dstport, &find);	if (result != ISC_R_SUCCESS) {		if (result == DNS_R_ALIAS) {			/*			 * XXXRTH  Follow the CNAME/DNAME chain?			 */			dns_adb_destroyfind(&find);		}	} else if (!ISC_LIST_EMPTY(find->list)) {		/*		 * We have at least some of the addresses for the		 * name.		 */		INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0);		sort_adbfind(find);		if (flags != 0 || port != 0) {			for (ai = ISC_LIST_HEAD(find->list);			     ai != NULL;			     ai = ISC_LIST_NEXT(ai, publink)) {				ai->flags |= flags;				if (port != 0)					isc_sockaddr_setport(&ai->sockaddr,							     port);			}		}		if ((flags & FCTX_ADDRINFO_FORWARDER) != 0)			ISC_LIST_APPEND(fctx->altfinds, find, publink);		else			ISC_LIST_APPEND(fctx->finds, find, publink);	} else {		/*		 * We don't know any of the addresses for this		 * name.		 */		if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) {			/*			 * We're looking for them and will get an			 * event about it later.			 */			fctx->pending++;			/*			 * Bootstrap.			 */			if (need_alternate != NULL &&			    !*need_alternate && unshared &&			    ((res->dispatchv4 == NULL &&			      find->result_v6 != DNS_R_NXDOMAIN) ||			     (res->dispatchv6 == NULL &&			      find->result_v4 != DNS_R_NXDOMAIN)))				*need_alternate = ISC_TRUE;		} else {			/*			 * If we know there are no addresses for			 * the family we are using then try to add			 * an alternative server.			 */			if (need_alternate != NULL && !*need_alternate &&			    ((res->dispatchv4 == NULL &&			      find->result_v6 == DNS_R_NXRRSET) ||			     (res->dispatchv6 == NULL &&			      find->result_v4 == DNS_R_NXRRSET)))				*need_alternate = ISC_TRUE;			/*			 * And ADB isn't going to send us any events			 * either.  This find loses.			 */			if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0) {				/*				 * The ADB pruned lame servers for				 * this name.  Remember that in case				 * we get desperate later on.				 */				*pruned = ISC_TRUE;			}			dns_adb_destroyfind(&find);		}	}}static isc_result_tfctx_getaddresses(fetchctx_t *fctx) {	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_result_t result;	dns_resolver_t *res;	isc_stdtime_t now;	unsigned int stdoptions;	isc_sockaddr_t *sa;	dns_adbaddrinfo_t *ai;	isc_boolean_t pruned, all_bad;	dns_rdata_ns_t ns;	isc_boolean_t need_alternate = ISC_FALSE;	isc_boolean_t unshared;	FCTXTRACE("getaddresses");	/*	 * Don't pound on remote servers.  (Failsafe!)	 */	fctx->restarts++;	if (fctx->restarts > 10) {		FCTXTRACE("too many restarts");		return (DNS_R_SERVFAIL);	}	res = fctx->res;	pruned = ISC_FALSE;	stdoptions = 0;		/* Keep compiler happy. */	unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);	/*	 * Forwarders.	 */	INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));	INSIST(ISC_LIST_EMPTY(fctx->altaddrs));	/*	 * If this fctx has forwarders, use them; otherwise use any	 * selective forwarders specified in the view; otherwise use the	 * resolver's forwarders (if any).	 */	sa = ISC_LIST_HEAD(fctx->forwarders);	if (sa == NULL) {		dns_forwarders_t *forwarders = NULL;		dns_name_t *name = &fctx->name;		dns_name_t suffix;		unsigned int labels;		/*		 * DS records are found in the parent server.		 * Strip label to get the correct forwarder (if any).		 */		if (fctx->type == dns_rdatatype_ds &&		    dns_name_countlabels(name) > 1) {			dns_name_init(&suffix, NULL);			labels = dns_name_countlabels(name);			dns_name_getlabelsequence(name, 1, labels - 1, &suffix);			name = &suffix;		}		result = dns_fwdtable_find(fctx->res->view->fwdtable, name,					   &forwarders);		if (result == ISC_R_SUCCESS) {			sa = ISC_LIST_HEAD(forwarders->addrs);			fctx->fwdpolicy = forwarders->fwdpolicy;		}	}	while (sa != NULL) {		ai = NULL;		result = dns_adb_findaddrinfo(fctx->adb,					      sa, &ai, 0);  /* XXXMLG */		if (result == ISC_R_SUCCESS) {			dns_adbaddrinfo_t *cur;			ai->flags |= FCTX_ADDRINFO_FORWARDER;			cur = ISC_LIST_HEAD(fctx->forwaddrs);			while (cur != NULL && cur->srtt < ai->srtt)				cur = ISC_LIST_NEXT(cur, publink);			if (cur != NULL)				ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur,						      ai, publink);			else				ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);		}		sa = ISC_LIST_NEXT(sa, link);	}	/*	 * If the forwarding policy is "only", we don't need the addresses	 * of the nameservers.	 */	if (fctx->fwdpolicy == dns_fwdpolicy_only)		goto out;	/*	 * Normal nameservers.	 */	stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;	if (fctx->restarts == 1) {		/*		 * To avoid sending out a flood of queries likely to		 * result in NXRRSET, we suppress fetches for address		 * families we don't have the first time through,		 * provided that we have addresses in some family we		 * can use.		 *		 * We don't want to set this option all the time, since		 * if fctx->restarts > 1, we've clearly been having trouble		 * with the addresses we had, so getting more could help.		 */		stdoptions |= DNS_ADBFIND_AVOIDFETCHES;	}	if (res->dispatchv4 != NULL)		stdoptions |= DNS_ADBFIND_INET;	if (res->dispatchv6 != NULL)		stdoptions |= DNS_ADBFIND_INET6;	isc_stdtime_get(&now); restart:	INSIST(ISC_LIST_EMPTY(fctx->finds));	INSIST(ISC_LIST_EMPTY(fctx->altfinds));	for (result = dns_rdataset_first(&fctx->nameservers);	     result == ISC_R_SUCCESS;	     result = dns_rdataset_next(&fctx->nameservers))	{		dns_rdataset_current(&fctx->nameservers, &rdata);		/*		 * Extract the name from the NS record.		 */		result = dns_rdata_tostruct(&rdata, &ns, NULL);		if (result != ISC_R_SUCCESS)			continue;		findname(fctx, &ns.name, 0, stdoptions, 0, now,			 &pruned, &need_alternate);		dns_rdata_reset(&rdata);		dns_rdata_freestruct(&ns);	}	if (result != ISC_R_NOMORE)		return (result);	/*	 * Do we need to use 6 to 4?	 */	if (need_alternate) {		int family;		alternate_t *a;		family = (res->dispatchv6 != NULL) ? AF_INET6 : AF_INET;		for (a = ISC_LIST_HEAD(fctx->res->alternates);		     a != NULL;		     a = ISC_LIST_NEXT(a, link)) {			if (!a->isaddress) {				findname(fctx, &a->_u._n.name, a->_u._n.port,					 stdoptions, FCTX_ADDRINFO_FORWARDER,					 now, &pruned, NULL);				continue;			}			if (isc_sockaddr_pf(&a->_u.addr) != family)				continue;			ai = NULL;			result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr,						      &ai, 0);			if (result == ISC_R_SUCCESS) {				dns_adbaddrinfo_t *cur;				ai->flags |= FCTX_ADDRINFO_FORWARDER;				cur = ISC_LIST_HEAD(fctx->altaddrs);				while (cur != NULL && cur->srtt < ai->srtt)					cur = ISC_LIST_NEXT(cur, publink);				if (cur != NULL)					ISC_LIST_INSERTBEFORE(fctx->altaddrs,							      cur, ai, publink);				else					ISC_LIST_APPEND(fctx->altaddrs, ai,							publink);			}		}	} out:	/*	 * Mark all known bad servers.	 */	all_bad = mark_bad(fctx);	/*	 * How are we doing?	 */	if (all_bad) {		/*		 * We've got no addresses.		 */		if (fctx->pending > 0) {			/*			 * We're fetching the addresses, but don't have any			 * yet.   Tell the caller to wait for an answer.			 */			result = DNS_R_WAIT;		} else if (pruned) {			/*			 * Some addresses were removed by lame pruning.			 * Turn pruning off and try again.			 */			FCTXTRACE("restarting with returnlame");			INSIST((stdoptions & DNS_ADBFIND_RETURNLAME) == 0);			stdoptions |= DNS_ADBFIND_RETURNLAME;			pruned = ISC_FALSE;			fctx_cleanupaltfinds(fctx);			fctx_cleanupfinds(fctx);			goto restart;		} else {			/*			 * We've lost completely.  We don't know any			 * addresses, and the ADB has told us it can't get			 * them.			 */			FCTXTRACE("no addresses");			result = ISC_R_FAILURE;		}	} else {		/*		 * We've found some addresses.  We might still be looking		 * for more addresses.		 */		sort_finds(fctx);		result = ISC_R_SUCCESS;	}	return (result);}static inline voidpossibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr){	isc_netaddr_t na;	char buf[ISC_NETADDR_FORMATSIZE];	isc_sockaddr_t *sa;	isc_boolean_t aborted = ISC_FALSE;	isc_boolean_t bogus;	dns_acl_t *blackhole;	isc_netaddr_t ipaddr;	dns_peer_t *peer = NULL;	dns_resolver_t *res;	const char *msg = NULL;	sa = &addr->sockaddr;	res = fctx->res;	isc_netaddr_fromsockaddr(&ipaddr, sa);	blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr);	(void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer);		if (blackhole != NULL) {		int match;		if (dns_acl_match(&ipaddr, NULL, blackhole,				  &res->view->aclenv,				  &match, NULL) == ISC_R_SUCCESS &&		    match > 0)			aborted = ISC_TRUE;	}	if (peer != NULL &&	    dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS &&	    bogus)		aborted = ISC_TRUE;	if (aborted) {		addr->flags |= FCTX_ADDRINFO_MARK;		msg = "ignoring blackholed / bogus server: ";	} else if (isc_sockaddr_ismulticast(sa)) {		addr->flags |= FCTX_ADDRINFO_MARK;		msg = "ignoring multicast address: ";	} else if (isc_sockaddr_isexperimental(sa)) {		addr->flags |= FCTX_ADDRINFO_MARK;		msg = "ignoring experimental address: ";	} else if (sa->type.sa.sa_family != AF_INET6) {		return;	} else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) {		addr->flags |= FCTX_ADDRINFO_MARK;		msg = "ignoring IPv6 mapped IPV4 address: ";	} else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) {		addr->flags |= FCTX_ADDRINFO_MARK;		msg = "ignoring IPv6 compatibility IPV4 address: ";	} else		return;	if (!isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3)))

⌨️ 快捷键说明

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