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

📄 query.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: query.c,v 1.198.2.13.4.30 2004/06/30 14:13:05 marka Exp $ */#include <config.h>#include <string.h>#include <isc/mem.h>#include <isc/util.h>#include <dns/adb.h>#include <dns/byaddr.h>#include <dns/db.h>#include <dns/events.h>#include <dns/message.h>#include <dns/order.h>#include <dns/rdata.h>#include <dns/rdataclass.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatasetiter.h>#include <dns/rdatastruct.h>#include <dns/rdatatype.h>#include <dns/resolver.h>#include <dns/result.h>#include <dns/stats.h>#include <dns/tkey.h>#include <dns/view.h>#include <dns/zone.h>#include <dns/zt.h>#include <named/client.h>#include <named/log.h>#include <named/server.h>#include <named/sortlist.h>#include <named/xfrout.h>#define PARTIALANSWER(c)	(((c)->query.attributes & \				  NS_QUERYATTR_PARTIALANSWER) != 0)#define USECACHE(c)		(((c)->query.attributes & \				  NS_QUERYATTR_CACHEOK) != 0)#define RECURSIONOK(c)		(((c)->query.attributes & \				  NS_QUERYATTR_RECURSIONOK) != 0)#define RECURSING(c)		(((c)->query.attributes & \				  NS_QUERYATTR_RECURSING) != 0)#define CACHEGLUEOK(c)		(((c)->query.attributes & \				  NS_QUERYATTR_CACHEGLUEOK) != 0)#define WANTRECURSION(c)	(((c)->query.attributes & \				  NS_QUERYATTR_WANTRECURSION) != 0)#define WANTDNSSEC(c)		(((c)->attributes & \				  NS_CLIENTATTR_WANTDNSSEC) != 0)#define NOAUTHORITY(c)		(((c)->query.attributes & \				  NS_QUERYATTR_NOAUTHORITY) != 0)#define NOADDITIONAL(c)		(((c)->query.attributes & \				  NS_QUERYATTR_NOADDITIONAL) != 0)#define SECURE(c)		(((c)->query.attributes & \				  NS_QUERYATTR_SECURE) != 0)#if 0#define CTRACE(m)       isc_log_write(ns_g_lctx, \				      NS_LOGCATEGORY_CLIENT, \				      NS_LOGMODULE_QUERY, \				      ISC_LOG_DEBUG(3), \				      "client %p: %s", client, (m))#define QTRACE(m)       isc_log_write(ns_g_lctx, \				      NS_LOGCATEGORY_GENERAL, \				      NS_LOGMODULE_QUERY, \				      ISC_LOG_DEBUG(3), \				      "query %p: %s", query, (m))#else#define CTRACE(m) ((void)m)#define QTRACE(m) ((void)m)#endif#define DNS_GETDB_NOEXACT 0x01U#define DNS_GETDB_NOLOG 0x02U#define DNS_GETDB_PARTIAL 0x04Ustatic voidquery_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);/* * Increment query statistics counters. */static inline voidinc_stats(ns_client_t *client, dns_statscounter_t counter) {	dns_zone_t *zone = client->query.authzone;	REQUIRE(counter < DNS_STATS_NCOUNTERS);	ns_g_server->querystats[counter]++;	if (zone != NULL) {		isc_uint64_t *zonestats = dns_zone_getstatscounters(zone);		if (zonestats != NULL)			zonestats[counter]++;	}}static voidquery_send(ns_client_t *client) {	dns_statscounter_t counter;	if (client->message->rcode == dns_rcode_noerror) {		if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER])) {			if (client->query.isreferral) {				counter = dns_statscounter_referral;			} else {				counter = dns_statscounter_nxrrset;			}		} else {			counter = dns_statscounter_success;		}	} else if (client->message->rcode == dns_rcode_nxdomain) {		counter = dns_statscounter_nxdomain;	} else {		/* We end up here in case of YXDOMAIN, and maybe others */		counter = dns_statscounter_failure;	}	inc_stats(client, counter);	ns_client_send(client);}static voidquery_error(ns_client_t *client, isc_result_t result) {	inc_stats(client, dns_statscounter_failure);	ns_client_error(client, result);}static voidquery_next(ns_client_t *client, isc_result_t result) {	inc_stats(client, dns_statscounter_failure);	ns_client_next(client, result);}static inline voidquery_maybeputqname(ns_client_t *client) {	if (client->query.restarts > 0) {		/*		 * client->query.qname was dynamically allocated.		 */		dns_message_puttempname(client->message,					&client->query.qname);		client->query.qname = NULL;	}}static inline voidquery_freefreeversions(ns_client_t *client, isc_boolean_t everything) {	ns_dbversion_t *dbversion, *dbversion_next;	unsigned int i;	for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;	     dbversion != NULL;	     dbversion = dbversion_next, i++)	{		dbversion_next = ISC_LIST_NEXT(dbversion, link);		/*		 * If we're not freeing everything, we keep the first three		 * dbversions structures around.		 */		if (i > 3 || everything) {			ISC_LIST_UNLINK(client->query.freeversions, dbversion,					link);			isc_mem_put(client->mctx, dbversion,				    sizeof(*dbversion));		}	}}voidns_query_cancel(ns_client_t *client) {	LOCK(&client->query.fetchlock);	if (client->query.fetch != NULL) {		dns_resolver_cancelfetch(client->query.fetch);		client->query.fetch = NULL;	}	UNLOCK(&client->query.fetchlock);}static inline voidquery_reset(ns_client_t *client, isc_boolean_t everything) {	isc_buffer_t *dbuf, *dbuf_next;	ns_dbversion_t *dbversion, *dbversion_next;	/*	 * Reset the query state of a client to its default state.	 */	/*	 * Cancel the fetch if it's running.	 */	ns_query_cancel(client);	/*	 * Cleanup any active versions.	 */	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);	     dbversion != NULL;	     dbversion = dbversion_next) {		dbversion_next = ISC_LIST_NEXT(dbversion, link);		dns_db_closeversion(dbversion->db, &dbversion->version,				    ISC_FALSE);		dns_db_detach(&dbversion->db);		ISC_LIST_INITANDAPPEND(client->query.freeversions,				      dbversion, link);	}	ISC_LIST_INIT(client->query.activeversions);	if (client->query.authdb != NULL)		dns_db_detach(&client->query.authdb);	if (client->query.authzone != NULL)		dns_zone_detach(&client->query.authzone);	query_freefreeversions(client, everything);	for (dbuf = ISC_LIST_HEAD(client->query.namebufs);	     dbuf != NULL;	     dbuf = dbuf_next) {		dbuf_next = ISC_LIST_NEXT(dbuf, link);		if (dbuf_next != NULL || everything) {			ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);			isc_buffer_free(&dbuf);		}	}	query_maybeputqname(client);	client->query.attributes = (NS_QUERYATTR_RECURSIONOK |				    NS_QUERYATTR_CACHEOK |				    NS_QUERYATTR_SECURE);	client->query.restarts = 0;	client->query.timerset = ISC_FALSE;	client->query.origqname = NULL;	client->query.qname = NULL;	client->query.dboptions = 0;	client->query.fetchoptions = 0;	client->query.gluedb = NULL;	client->query.authdbset = ISC_FALSE;	client->query.isreferral = ISC_FALSE;}static voidquery_next_callback(ns_client_t *client) {	query_reset(client, ISC_FALSE);}voidns_query_free(ns_client_t *client) {	query_reset(client, ISC_TRUE);}static inline isc_result_tquery_newnamebuf(ns_client_t *client) {	isc_buffer_t *dbuf;	isc_result_t result;	CTRACE("query_newnamebuf");	/*	 * Allocate a name buffer.	 */	dbuf = NULL;	result = isc_buffer_allocate(client->mctx, &dbuf, 1024);	if (result != ISC_R_SUCCESS) {		CTRACE("query_newnamebuf: isc_buffer_allocate failed: done");		return (result);	}	ISC_LIST_APPEND(client->query.namebufs, dbuf, link);	CTRACE("query_newnamebuf: done");	return (ISC_R_SUCCESS);}static inline isc_buffer_t *query_getnamebuf(ns_client_t *client) {	isc_buffer_t *dbuf;	isc_result_t result;	isc_region_t r;	CTRACE("query_getnamebuf");	/*	 * Return a name buffer with space for a maximal name, allocating	 * a new one if necessary.	 */	if (ISC_LIST_EMPTY(client->query.namebufs)) {		result = query_newnamebuf(client);		if (result != ISC_R_SUCCESS) {		    CTRACE("query_getnamebuf: query_newnamebuf failed: done");			return (NULL);		}	}	dbuf = ISC_LIST_TAIL(client->query.namebufs);	INSIST(dbuf != NULL);	isc_buffer_availableregion(dbuf, &r);	if (r.length < 255) {		result = query_newnamebuf(client);		if (result != ISC_R_SUCCESS) {		    CTRACE("query_getnamebuf: query_newnamebuf failed: done");			return (NULL);		}		dbuf = ISC_LIST_TAIL(client->query.namebufs);		isc_buffer_availableregion(dbuf, &r);		INSIST(r.length >= 255);	}	CTRACE("query_getnamebuf: done");	return (dbuf);}static inline voidquery_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {	isc_region_t r;	CTRACE("query_keepname");	/*	 * 'name' is using space in 'dbuf', but 'dbuf' has not yet been	 * adjusted to take account of that.  We do the adjustment.	 */	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);	dns_name_toregion(name, &r);	isc_buffer_add(dbuf, r.length);	dns_name_setbuffer(name, NULL);	client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;}static inline voidquery_releasename(ns_client_t *client, dns_name_t **namep) {	dns_name_t *name = *namep;	/*	 * 'name' is no longer needed.  Return it to our pool of temporary	 * names.  If it is using a name buffer, relinquish its exclusive	 * rights on the buffer.	 */	CTRACE("query_releasename");	if (dns_name_hasbuffer(name)) {		INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)		       != 0);		client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;	}	dns_message_puttempname(client->message, namep);	CTRACE("query_releasename: done");}static inline dns_name_t *query_newname(ns_client_t *client, isc_buffer_t *dbuf,	      isc_buffer_t *nbuf){	dns_name_t *name;	isc_region_t r;	isc_result_t result;	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);	CTRACE("query_newname");	name = NULL;	result = dns_message_gettempname(client->message, &name);	if (result != ISC_R_SUCCESS) {		CTRACE("query_newname: dns_message_gettempname failed: done");		return (NULL);	}	isc_buffer_availableregion(dbuf, &r);	isc_buffer_init(nbuf, r.base, r.length);	dns_name_init(name, NULL);	dns_name_setbuffer(name, nbuf);	client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;	CTRACE("query_newname: done");	return (name);}static inline dns_rdataset_t *query_newrdataset(ns_client_t *client) {	dns_rdataset_t *rdataset;	isc_result_t result;	CTRACE("query_newrdataset");	rdataset = NULL;	result = dns_message_gettemprdataset(client->message, &rdataset);	if (result != ISC_R_SUCCESS) {	  CTRACE("query_newrdataset: "		 "dns_message_gettemprdataset failed: done");		return (NULL);	}	dns_rdataset_init(rdataset);	CTRACE("query_newrdataset: done");	return (rdataset);}static inline voidquery_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {	dns_rdataset_t *rdataset = *rdatasetp;	CTRACE("query_putrdataset");	if (rdataset != NULL) {		if (dns_rdataset_isassociated(rdataset))			dns_rdataset_disassociate(rdataset);		dns_message_puttemprdataset(client->message, rdatasetp);	}	CTRACE("query_putrdataset: done");}static inline isc_result_tquery_newdbversion(ns_client_t *client, unsigned int n) {	unsigned int i;	ns_dbversion_t *dbversion;	for (i = 0; i < n; i++) {		dbversion = isc_mem_get(client->mctx, sizeof(*dbversion));		if (dbversion != NULL) {			dbversion->db = NULL;			dbversion->version = NULL;			ISC_LIST_INITANDAPPEND(client->query.freeversions,					      dbversion, link);		} else {			/*			 * We only return ISC_R_NOMEMORY if we couldn't			 * allocate anything.			 */			if (i == 0)				return (ISC_R_NOMEMORY);			else				return (ISC_R_SUCCESS);		}	}	return (ISC_R_SUCCESS);}static inline ns_dbversion_t *query_getdbversion(ns_client_t *client) {	isc_result_t result;	ns_dbversion_t *dbversion;	if (ISC_LIST_EMPTY(client->query.freeversions)) {		result = query_newdbversion(client, 1);		if (result != ISC_R_SUCCESS)			return (NULL);	}	dbversion = ISC_LIST_HEAD(client->query.freeversions);	INSIST(dbversion != NULL);	ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);	return (dbversion);}isc_result_tns_query_init(ns_client_t *client) {	isc_result_t result;	ISC_LIST_INIT(client->query.namebufs);	ISC_LIST_INIT(client->query.activeversions);	ISC_LIST_INIT(client->query.freeversions);	client->query.restarts = 0;	client->query.timerset = ISC_FALSE;	client->query.qname = NULL;	result = isc_mutex_init(&client->query.fetchlock);	if (result != ISC_R_SUCCESS)		return (result);	client->query.fetch = NULL;	client->query.authdb = NULL;	client->query.authzone = NULL;	client->query.authdbset = ISC_FALSE;	client->query.isreferral = ISC_FALSE;		query_reset(client, ISC_FALSE);	result = query_newdbversion(client, 3);	if (result != ISC_R_SUCCESS) {		DESTROYLOCK(&client->query.fetchlock);		return (result);	}

⌨️ 快捷键说明

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