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

📄 resolver.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: resolver.c,v 1.218.2.18.4.43 2004/08/28 06:25:19 marka Exp $ */#include <config.h>#include <isc/print.h>#include <isc/string.h>#include <isc/task.h>#include <isc/timer.h>#include <isc/util.h>#include <dns/acl.h>#include <dns/adb.h>#include <dns/db.h>#include <dns/dispatch.h>#include <dns/events.h>#include <dns/forward.h>#include <dns/keytable.h>#include <dns/log.h>#include <dns/message.h>#include <dns/ncache.h>#include <dns/opcode.h>#include <dns/peer.h>#include <dns/rbt.h>#include <dns/rcode.h>#include <dns/rdata.h>#include <dns/rdataclass.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatastruct.h>#include <dns/rdatatype.h>#include <dns/resolver.h>#include <dns/result.h>#include <dns/tsig.h>#include <dns/validator.h>#define DNS_RESOLVER_TRACE#ifdef DNS_RESOLVER_TRACE#define RTRACE(m)	isc_log_write(dns_lctx, \				      DNS_LOGCATEGORY_RESOLVER, \				      DNS_LOGMODULE_RESOLVER, \				      ISC_LOG_DEBUG(3), \				      "res %p: %s", res, (m))#define RRTRACE(r, m)	isc_log_write(dns_lctx, \				      DNS_LOGCATEGORY_RESOLVER, \				      DNS_LOGMODULE_RESOLVER, \				      ISC_LOG_DEBUG(3), \				      "res %p: %s", (r), (m))#define FCTXTRACE(m)	isc_log_write(dns_lctx, \				      DNS_LOGCATEGORY_RESOLVER, \				      DNS_LOGMODULE_RESOLVER, \				      ISC_LOG_DEBUG(3), \				      "fctx %p(%s'): %s", fctx, fctx->info, (m))#define FCTXTRACE2(m1, m2) \			isc_log_write(dns_lctx, \				      DNS_LOGCATEGORY_RESOLVER, \				      DNS_LOGMODULE_RESOLVER, \				      ISC_LOG_DEBUG(3), \				      "fctx %p(%s): %s %s", \				      fctx, fctx->info, (m1), (m2))#define FTRACE(m)	isc_log_write(dns_lctx, \				      DNS_LOGCATEGORY_RESOLVER, \				      DNS_LOGMODULE_RESOLVER, \				      ISC_LOG_DEBUG(3), \				      "fetch %p (fctx %p(%s)): %s", \				      fetch, fetch->private, \				      fetch->private->info, (m))#define QTRACE(m)	isc_log_write(dns_lctx, \				      DNS_LOGCATEGORY_RESOLVER, \				      DNS_LOGMODULE_RESOLVER, \				      ISC_LOG_DEBUG(3), \				      "resquery %p (fctx %p(%s)): %s", \				      query, query->fctx, \				      query->fctx->info, (m))#else#define RTRACE(m)#define RRTRACE(r, m)#define FCTXTRACE(m)#define FTRACE(m)#define QTRACE(m)#endif/* * Maximum EDNS0 input packet size. */#define RECV_BUFFER_SIZE		4096		/* XXXRTH  Constant. *//* * This defines the maximum number of timeouts we will permit before we * disable EDNS0 on the query. */#define MAX_EDNS0_TIMEOUTS	3typedef struct fetchctx fetchctx_t;typedef struct query {	/* Locked by task event serialization. */	unsigned int			magic;	fetchctx_t *			fctx;	isc_mem_t *			mctx;	dns_dispatchmgr_t *		dispatchmgr;	dns_dispatch_t *		dispatch;	dns_adbaddrinfo_t *		addrinfo;	isc_socket_t *			tcpsocket;	isc_time_t			start;	dns_messageid_t			id;	dns_dispentry_t *		dispentry;	ISC_LINK(struct query)		link;	isc_buffer_t			buffer;	isc_buffer_t			*tsig;	dns_tsigkey_t			*tsigkey;	unsigned int			options;	unsigned int			attributes;	unsigned int			sends;	unsigned int			connects;	unsigned char			data[512];} resquery_t;#define QUERY_MAGIC			ISC_MAGIC('Q', '!', '!', '!')#define VALID_QUERY(query)		ISC_MAGIC_VALID(query, QUERY_MAGIC)#define RESQUERY_ATTR_CANCELED		0x02#define RESQUERY_CONNECTING(q)		((q)->connects > 0)#define RESQUERY_CANCELED(q)		(((q)->attributes & \					  RESQUERY_ATTR_CANCELED) != 0)#define RESQUERY_SENDING(q)		((q)->sends > 0)typedef enum {	fetchstate_init = 0,		/* Start event has not run yet. */	fetchstate_active,	fetchstate_done			/* FETCHDONE events posted. */} fetchstate;struct fetchctx {	/* Not locked. */	unsigned int			magic;	dns_resolver_t *		res;	dns_name_t			name;	dns_rdatatype_t			type;	unsigned int			options;	unsigned int			bucketnum;	char *				info;	/* Locked by appropriate bucket lock. */	fetchstate			state;	isc_boolean_t			want_shutdown;	isc_boolean_t			cloned;	unsigned int			references;	isc_event_t			control_event;	ISC_LINK(struct fetchctx)	link;	ISC_LIST(dns_fetchevent_t)	events;	/* Locked by task event serialization. */	dns_name_t			domain;	dns_rdataset_t			nameservers;	unsigned int			attributes;	isc_timer_t *			timer;	isc_time_t			expires;	isc_interval_t			interval;	dns_message_t *			qmessage;	dns_message_t *			rmessage;	ISC_LIST(resquery_t)		queries;	dns_adbfindlist_t		finds;	dns_adbfind_t *			find;	dns_adbfindlist_t		altfinds;	dns_adbfind_t *			altfind;	dns_adbaddrinfolist_t		forwaddrs;	dns_adbaddrinfolist_t		altaddrs;	isc_sockaddrlist_t		forwarders;	dns_fwdpolicy_t			fwdpolicy;	isc_sockaddrlist_t		bad;	ISC_LIST(dns_validator_t)	validators;	dns_db_t *			cache;	dns_adb_t *			adb;	/*	 * The number of events we're waiting for.	 */	unsigned int			pending;	/*	 * The number of times we've "restarted" the current	 * nameserver set.  This acts as a failsafe to prevent	 * us from pounding constantly on a particular set of	 * servers that, for whatever reason, are not giving	 * us useful responses, but are responding in such a	 * way that they are not marked "bad".	 */	unsigned int			restarts;	/*	 * The number of timeouts that have occurred since we 	 * last successfully received a response packet.  This	 * is used for EDNS0 black hole detection.	 */	unsigned int			timeouts;	/*	 * Look aside state for DS lookups.	 */	dns_name_t 			nsname; 	dns_fetch_t *			nsfetch;	dns_rdataset_t			nsrrset;};#define FCTX_MAGIC			ISC_MAGIC('F', '!', '!', '!')#define VALID_FCTX(fctx)		ISC_MAGIC_VALID(fctx, FCTX_MAGIC)#define FCTX_ATTR_HAVEANSWER		0x0001#define FCTX_ATTR_GLUING		0x0002#define FCTX_ATTR_ADDRWAIT		0x0004#define FCTX_ATTR_SHUTTINGDOWN		0x0008#define FCTX_ATTR_WANTCACHE		0x0010#define FCTX_ATTR_WANTNCACHE		0x0020#define FCTX_ATTR_NEEDEDNS0		0x0040#define FCTX_ATTR_TRIEDFIND		0x0080#define FCTX_ATTR_TRIEDALT		0x0100#define HAVE_ANSWER(f)		(((f)->attributes & FCTX_ATTR_HAVEANSWER) != \				 0)#define GLUING(f)		(((f)->attributes & FCTX_ATTR_GLUING) != \				 0)#define ADDRWAIT(f)		(((f)->attributes & FCTX_ATTR_ADDRWAIT) != \				 0)#define SHUTTINGDOWN(f)		(((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \ 				 != 0)#define WANTCACHE(f)		(((f)->attributes & FCTX_ATTR_WANTCACHE) != 0)#define WANTNCACHE(f)		(((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0)#define NEEDEDNS0(f)		(((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0)#define TRIEDFIND(f)		(((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)#define TRIEDALT(f)		(((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)struct dns_fetch {	unsigned int			magic;	fetchctx_t *			private;};#define DNS_FETCH_MAGIC			ISC_MAGIC('F', 't', 'c', 'h')#define DNS_FETCH_VALID(fetch)		ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)typedef struct fctxbucket {	isc_task_t *			task;	isc_mutex_t			lock;	ISC_LIST(fetchctx_t)		fctxs;	isc_boolean_t			exiting;} fctxbucket_t;typedef struct alternate {	isc_boolean_t			isaddress;	union	{		isc_sockaddr_t		addr;		struct {			dns_name_t	name;			in_port_t	port;		} _n;	} _u;	ISC_LINK(struct alternate)	link;} alternate_t;struct dns_resolver {	/* Unlocked. */	unsigned int			magic;	isc_mem_t *			mctx;	isc_mutex_t			lock;	isc_mutex_t			nlock;		isc_mutex_t			primelock;		dns_rdataclass_t		rdclass;	isc_socketmgr_t *		socketmgr;	isc_timermgr_t *		timermgr;	isc_taskmgr_t *			taskmgr;	dns_view_t *			view;	isc_boolean_t			frozen;	unsigned int			options;	dns_dispatchmgr_t *		dispatchmgr;	dns_dispatch_t *		dispatchv4;	dns_dispatch_t *		dispatchv6;	unsigned int			nbuckets;	fctxbucket_t *			buckets;	isc_uint32_t			lame_ttl;	ISC_LIST(alternate_t)		alternates;	isc_uint16_t			udpsize;#if USE_ALGLOCK	isc_rwlock_t			alglock;#endif	dns_rbt_t *			algorithms;#if USE_MBSLOCK	isc_rwlock_t			mbslock;#endif	dns_rbt_t *			mustbesecure;	/* Locked by lock. */	unsigned int			references;	isc_boolean_t			exiting;	isc_eventlist_t			whenshutdown;	unsigned int			activebuckets;	isc_boolean_t			priming;	/* Locked by primelock. */	dns_fetch_t *			primefetch;	/* Locked by nlock. */	unsigned int			nfctx;};#define RES_MAGIC			ISC_MAGIC('R', 'e', 's', '!')#define VALID_RESOLVER(res)		ISC_MAGIC_VALID(res, RES_MAGIC)/* * Private addrinfo flags.  These must not conflict with DNS_FETCHOPT_NOEDNS0, * which we also use as an addrinfo flag. */#define FCTX_ADDRINFO_MARK		0x0001#define FCTX_ADDRINFO_FORWARDER		0x1000#define UNMARKED(a)			(((a)->flags & FCTX_ADDRINFO_MARK) \					 == 0)#define ISFORWARDER(a)			(((a)->flags & \					 FCTX_ADDRINFO_FORWARDER) != 0)#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)static void destroy(dns_resolver_t *res);static void empty_bucket(dns_resolver_t *res);static isc_result_t resquery_send(resquery_t *query);static void resquery_response(isc_task_t *task, isc_event_t *event);static void resquery_connected(isc_task_t *task, isc_event_t *event);static void fctx_try(fetchctx_t *fctx);static isc_boolean_t fctx_destroy(fetchctx_t *fctx);static isc_result_t ncache_adderesult(dns_message_t *message,				      dns_db_t *cache, dns_dbnode_t *node,				      dns_rdatatype_t covers,				      isc_stdtime_t now, dns_ttl_t maxttl,				      dns_rdataset_t *ardataset,				      isc_result_t *eresultp);static isc_boolean_tfix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {	dns_name_t *name;	dns_name_t *domain = &fctx->domain;	dns_rdataset_t *rdataset;	dns_rdatatype_t type;	isc_result_t result;	isc_boolean_t keep_auth = ISC_FALSE;	if (message->rcode == dns_rcode_nxdomain)		return (ISC_FALSE);	/*	 * Look for BIND 8 style delegations.	 * Also look for answers to ANY queries where the duplicate NS RRset	 * may have been stripped from the authority section.	 */	if (message->counts[DNS_SECTION_ANSWER] != 0 &&	    (fctx->type == dns_rdatatype_ns ||	     fctx->type == dns_rdatatype_any)) {		result = dns_message_firstname(message, DNS_SECTION_ANSWER);		while (result == ISC_R_SUCCESS) {			name = NULL;			dns_message_currentname(message, DNS_SECTION_ANSWER,						&name);			for (rdataset = ISC_LIST_HEAD(name->list);			     rdataset != NULL;			     rdataset = ISC_LIST_NEXT(rdataset, link)) {				type = rdataset->type;				if (type != dns_rdatatype_ns)					continue;				if (dns_name_issubdomain(name, domain))					return (ISC_FALSE);			}			result = dns_message_nextname(message,						      DNS_SECTION_ANSWER);		}	}	/* Look for referral. */	if (message->counts[DNS_SECTION_AUTHORITY] == 0)		goto munge;	result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);	while (result == ISC_R_SUCCESS) {		name = NULL;		dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);		for (rdataset = ISC_LIST_HEAD(name->list);		     rdataset != NULL;		     rdataset = ISC_LIST_NEXT(rdataset, link)) {			type = rdataset->type;			if (type == dns_rdatatype_soa &&			    dns_name_equal(name, domain))				keep_auth = ISC_TRUE;			if (type != dns_rdatatype_ns &&			    type != dns_rdatatype_soa)				continue;			if (dns_name_equal(name, domain))				goto munge;			if (dns_name_issubdomain(name, domain))				return (ISC_FALSE);		}		result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);	} munge:	message->rcode = dns_rcode_nxdomain;	message->counts[DNS_SECTION_ANSWER] = 0;	if (!keep_auth)		message->counts[DNS_SECTION_AUTHORITY] = 0;	message->counts[DNS_SECTION_ADDITIONAL] = 0;	return (ISC_TRUE);}static inline isc_result_tfctx_starttimer(fetchctx_t *fctx) {	/*	 * Start the lifetime timer for fctx.	 *	 * This is also used for stopping the idle timer; in that	 * case we must purge events already posted to ensure that	 * no further idle events are delivered.	 */	return (isc_timer_reset(fctx->timer, isc_timertype_once,				&fctx->expires, NULL,				ISC_TRUE));}static inline voidfctx_stoptimer(fetchctx_t *fctx) {	isc_result_t result;	/*	 * We don't return a result if resetting the timer to inactive fails	 * since there's nothing to be done about it.  Resetting to inactive	 * should never fail anyway, since the code as currently written	 * cannot fail in that case.	 */	result = isc_timer_reset(fctx->timer, isc_timertype_inactive,				  NULL, NULL, ISC_TRUE);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_timer_reset(): %s",				 isc_result_totext(result));	}}static inline isc_result_tfctx_startidletimer(fetchctx_t *fctx) {	/*	 * Start the idle timer for fctx.  The lifetime timer continues	 * to be in effect.	 */	return (isc_timer_reset(fctx->timer, isc_timertype_once,				&fctx->expires, &fctx->interval,				ISC_FALSE));}/* * Stopping the idle timer is equivalent to calling fctx_starttimer(), but * we use fctx_stopidletimer for readability in the code below. */#define fctx_stopidletimer	fctx_starttimerstatic inline voidresquery_destroy(resquery_t **queryp) {	resquery_t *query;	REQUIRE(queryp != NULL);	query = *queryp;	REQUIRE(!ISC_LINK_LINKED(query, link));	INSIST(query->tcpsocket == NULL);	query->magic = 0;	isc_mem_put(query->mctx, query, sizeof(*query));	*queryp = NULL;}static voidfctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,		 isc_time_t *finish, isc_boolean_t no_response){	fetchctx_t *fctx;	resquery_t *query;	unsigned int rtt;	unsigned int factor;	dns_adbfind_t *find;	dns_adbaddrinfo_t *addrinfo;	query = *queryp;	fctx = query->fctx;	FCTXTRACE("cancelquery");	REQUIRE(!RESQUERY_CANCELED(query));	query->attributes |= RESQUERY_ATTR_CANCELED;	/*	 * Should we update the RTT?	 */	if (finish != NULL || no_response) {		if (finish != NULL) {			/*			 * We have both the start and finish times for this			 * packet, so we can compute a real RTT.			 */			rtt = (unsigned int)isc_time_microdiff(finish,							       &query->start);

⌨️ 快捷键说明

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