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

📄 query.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
		goto found;	if (dns_rdataset_isassociated(rdataset))		dns_rdataset_disassociate(rdataset);	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))		dns_rdataset_disassociate(sigrdataset);	if (node != NULL)		dns_db_detachnode(db, &node);	dns_db_detach(&db); try_glue:	/*	 * No cached data was found.  Glue is our last chance.	 * RFC1035 sayeth:	 *	 *	NS records cause both the usual additional section	 *	processing to locate a type A record, and, when used	 *	in a referral, a special search of the zone in which	 *	they reside for glue information.	 *	 * This is the "special search".  Note that we must search	 * the zone where the NS record resides, not the zone it	 * points to, and that we only do the search in the delegation	 * case (identified by client->query.gluedb being set).	 */	if (client->query.gluedb == NULL)		goto cleanup;	/*	 * Don't poision caches using the bailiwick protection model.	 */	if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb)))		goto cleanup;	dns_db_attach(client->query.gluedb, &db);	result = dns_db_find(db, name, version, type,			     client->query.dboptions | DNS_DBFIND_GLUEOK,			     client->now, &node, fname, rdataset,			     sigrdataset);	if (!(result == ISC_R_SUCCESS ||	      result == DNS_R_ZONECUT ||	      result == DNS_R_GLUE))		goto cleanup; found:	/*	 * We have found a potential additional data rdataset, or	 * at least a node to iterate over.	 */	query_keepname(client, fname, dbuf);	/*	 * If we have an rdataset, add it to the additional data	 * section.	 */	mname = NULL;	if (dns_rdataset_isassociated(rdataset) &&	    !query_isduplicate(client, fname, type, &mname)) {		if (mname != NULL) {			query_releasename(client, &fname);			fname = mname;		} else			need_addname = ISC_TRUE;		ISC_LIST_APPEND(fname->list, rdataset, link);		trdataset = rdataset;		rdataset = NULL;		added_something = ISC_TRUE;		/*		 * Note: we only add SIGs if we've added the type they cover,		 * so we do not need to check if the SIG rdataset is already		 * in the response.		 */		if (sigrdataset != NULL &&		    dns_rdataset_isassociated(sigrdataset))		{			ISC_LIST_APPEND(fname->list, sigrdataset, link);			sigrdataset = NULL;		}	}	if (qtype == dns_rdatatype_a) {		/*		 * We now go looking for A and AAAA records, along with		 * their signatures.		 *		 * XXXRTH  This code could be more efficient.		 */		if (rdataset != NULL) {			if (dns_rdataset_isassociated(rdataset))				dns_rdataset_disassociate(rdataset);		} else {			rdataset = query_newrdataset(client);			if (rdataset == NULL)				goto addname;		}		if (sigrdataset != NULL) {			if (dns_rdataset_isassociated(sigrdataset))				dns_rdataset_disassociate(sigrdataset);		} else if (WANTDNSSEC(client)) {			sigrdataset = query_newrdataset(client);			if (sigrdataset == NULL)				goto addname;		}		result = dns_db_findrdataset(db, node, version,					     dns_rdatatype_a, 0,					     client->now, rdataset,					     sigrdataset);		if (result == DNS_R_NCACHENXDOMAIN)			goto addname;		if (result == DNS_R_NCACHENXRRSET) {			dns_rdataset_disassociate(rdataset);			/*			 * Negative cache entries don't have sigrdatasets.			 */			INSIST(sigrdataset == NULL ||			       ! dns_rdataset_isassociated(sigrdataset));		}		if (result == ISC_R_SUCCESS) {			mname = NULL;			if (!query_isduplicate(client, fname,					       dns_rdatatype_a, &mname)) {				if (mname != NULL) {					query_releasename(client, &fname);					fname = mname;				} else					need_addname = ISC_TRUE;				ISC_LIST_APPEND(fname->list, rdataset, link);				added_something = ISC_TRUE;				if (sigrdataset != NULL &&				    dns_rdataset_isassociated(sigrdataset))				{					ISC_LIST_APPEND(fname->list,							sigrdataset, link);					sigrdataset =						query_newrdataset(client);				}				rdataset = query_newrdataset(client);				if (rdataset == NULL)					goto addname;				if (WANTDNSSEC(client) && sigrdataset == NULL)					goto addname;			} else {				dns_rdataset_disassociate(rdataset);				if (sigrdataset != NULL &&				    dns_rdataset_isassociated(sigrdataset))					dns_rdataset_disassociate(sigrdataset);			}		}		result = dns_db_findrdataset(db, node, version,					     dns_rdatatype_aaaa, 0,					     client->now, rdataset,					     sigrdataset);		if (result == DNS_R_NCACHENXDOMAIN)			goto addname;		if (result == DNS_R_NCACHENXRRSET) {			dns_rdataset_disassociate(rdataset);			INSIST(sigrdataset == NULL ||			       ! dns_rdataset_isassociated(sigrdataset));		}		if (result == ISC_R_SUCCESS) {			mname = NULL;			if (!query_isduplicate(client, fname,					       dns_rdatatype_aaaa, &mname)) {				if (mname != NULL) {					query_releasename(client, &fname);					fname = mname;				} else					need_addname = ISC_TRUE;				ISC_LIST_APPEND(fname->list, rdataset, link);				added_something = ISC_TRUE;				if (sigrdataset != NULL &&				    dns_rdataset_isassociated(sigrdataset))				{					ISC_LIST_APPEND(fname->list,							sigrdataset, link);					sigrdataset = NULL;				}				rdataset = NULL;			}		}	} addname:	CTRACE("query_addadditional: addname");	/*	 * If we haven't added anything, then we're done.	 */	if (!added_something)		goto cleanup;	/*	 * We may have added our rdatasets to an existing name, if so, then	 * need_addname will be ISC_FALSE.  Whether we used an existing name	 * or a new one, we must set fname to NULL to prevent cleanup.	 */	if (need_addname)		dns_message_addname(client->message, fname,				    DNS_SECTION_ADDITIONAL);	fname = NULL;	/*	 * In a few cases, we want to add additional data for additional	 * data.  It's simpler to just deal with special cases here than	 * to try to create a general purpose mechanism and allow the	 * rdata implementations to do it themselves.	 *	 * This involves recursion, but the depth is limited.  The	 * most complex case is adding a SRV rdataset, which involves	 * recursing to add address records, which in turn can cause	 * recursion to add KEYs.	 */	if (type == dns_rdatatype_a || type == dns_rdatatype_aaaa) {		/*		 * RFC 2535 section 3.5 says that when A or AAAA records are		 * retrieved as additional data, any KEY RRs for the owner name		 * should be added to the additional data section.		 *		 * XXXRTH  We should lower the priority here.  Alternatively,		 * we could raise the priority of glue records.		 */		eresult = query_addadditional(client, name, dns_rdatatype_dnskey); 	} else if (type == dns_rdatatype_srv && trdataset != NULL) {		/*		 * If we're adding SRV records to the additional data		 * section, it's helpful if we add the SRV additional data		 * as well.		 */		eresult = dns_rdataset_additionaldata(trdataset,						      query_addadditional,						      client);	} cleanup:	CTRACE("query_addadditional: cleanup");	query_putrdataset(client, &rdataset);	if (sigrdataset != NULL)		query_putrdataset(client, &sigrdataset);	if (fname != NULL)		query_releasename(client, &fname);	if (node != NULL)		dns_db_detachnode(db, &node);	if (db != NULL)		dns_db_detach(&db);	if (zone != NULL)		dns_zone_detach(&zone);	CTRACE("query_addadditional: done");	return (eresult);}static inline voidquery_addrdataset(ns_client_t *client, dns_name_t *fname,		  dns_rdataset_t *rdataset){	dns_rdatatype_t type = rdataset->type;	/*	 * Add 'rdataset' and any pertinent additional data to	 * 'fname', a name in the response message for 'client'.	 */	CTRACE("query_addrdataset");	ISC_LIST_APPEND(fname->list, rdataset, link);	if (client->view->order != NULL)		rdataset->attributes |= dns_order_find(client->view->order,						       fname, rdataset->type,						       rdataset->rdclass);	if (NOADDITIONAL(client))		return;	/*	 * Add additional data.	 *	 * We don't care if dns_rdataset_additionaldata() fails.	 */	(void)dns_rdataset_additionaldata(rdataset,					  query_addadditional, client);	/*	 * RFC 2535 section 3.5 says that when NS, SOA, A, or AAAA records	 * are retrieved, any KEY RRs for the owner name should be added	 * to the additional data section.  We treat A6 records the same way.	 *	 * We don't care if query_addadditional() fails.	 */	if (type == dns_rdatatype_ns || type == dns_rdatatype_soa ||	    type == dns_rdatatype_a || type == dns_rdatatype_aaaa ||	    type == dns_rdatatype_a6) {		/*		 * XXXRTH  We should lower the priority here.  Alternatively,		 * we could raise the priority of glue records.		 */		(void)query_addadditional(client, fname, dns_rdatatype_dnskey);	}	CTRACE("query_addrdataset: done");}static voidquery_addrrset(ns_client_t *client, dns_name_t **namep,	       dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,	       isc_buffer_t *dbuf, dns_section_t section){	dns_name_t *name, *mname;	dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;	isc_result_t result;	/*	 * To the current response for 'client', add the answer RRset	 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with	 * owner name '*namep', to section 'section', unless they are	 * already there.  Also add any pertinent additional data.	 *	 * If 'dbuf' is not NULL, then '*namep' is the name whose data is	 * stored in 'dbuf'.  In this case, query_addrrset() guarantees that	 * when it returns the name will either have been kept or released.	 */	CTRACE("query_addrrset");	name = *namep;	rdataset = *rdatasetp;	if (sigrdatasetp != NULL)		sigrdataset = *sigrdatasetp;	else		sigrdataset = NULL;	mname = NULL;	mrdataset = NULL;	result = dns_message_findname(client->message, section,				      name, rdataset->type, rdataset->covers,				      &mname, &mrdataset);	if (result == ISC_R_SUCCESS) {		/*		 * We've already got an RRset of the given name and type.		 * There's nothing else to do;		 */		CTRACE("query_addrrset: dns_message_findname succeeded: done");		if (dbuf != NULL)			query_releasename(client, namep);		return;	} else if (result == DNS_R_NXDOMAIN) {		/*		 * The name doesn't exist.		 */		if (dbuf != NULL)			query_keepname(client, name, dbuf);		dns_message_addname(client->message, name, section);		*namep = NULL;		mname = name;	} else {		RUNTIME_CHECK(result == DNS_R_NXRRSET);		if (dbuf != NULL)			query_releasename(client, namep);	}	if (rdataset->trust != dns_trust_secure &&	    (section == DNS_SECTION_ANSWER ||	     section == DNS_SECTION_AUTHORITY))		client->query.attributes &= ~NS_QUERYATTR_SECURE;	/*	 * Note: we only add SIGs if we've added the type they cover, so	 * we do not need to check if the SIG rdataset is already in the	 * response.	 */	query_addrdataset(client, mname, rdataset);	*rdatasetp = NULL;	if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {		/*		 * We have a signature.  Add it to the response.		 */		ISC_LIST_APPEND(mname->list, sigrdataset, link);		*sigrdatasetp = NULL;	}	CTRACE("query_addrrset: done");}static inline isc_result_tquery_addsoa(ns_client_t *client, dns_db_t *db, isc_boolean_t zero_ttl) {	dns_name_t *name, *fname;	dns_dbnode_t *node;	isc_result_t result, eresult;	dns_fixedname_t foundname;	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;	dns_rdataset_t **sigrdatasetp = NULL;	CTRACE("query_addsoa");	/*	 * Initialization.	 */	eresult = ISC_R_SUCCESS;	name = NULL;	rdataset = NULL;	node = NULL;	dns_fixedname_init(&foundname);	fname = dns_fixedname_name(&foundname);	/*	 * Get resources and make 'name' be the database origin.	 */	result = dns_message_gettempname(client->message, &name);	if (result != ISC_R_SUCCESS)		return (result);	dns_name_init(name, NULL);	dns_name_clone(dns_db_origin(db), name);	rdataset = query_newrdataset(client);	if (rdataset == NULL) {		eresult = DNS_R_SERVFAIL;		goto cleanup;	}	if (WANTDNSSEC(client)) {		sigrdataset = query_newrdataset(client);		if (sigrdataset == NULL) {			eresult = DNS_R_SERVFAIL;			goto cleanup;		}	}	/*	 * Find the SOA.	 */	result = dns_db_find(db, name, NULL, dns_rdatatype_soa,			     client->query.dboptions, 0, &node,			     fname, rdataset, sigrdataset);	if (result != ISC_R_SUCCESS) {		/*		 * This is bad.  We tried to get the SOA RR at the zone top		 * and it didn't work!		 */		eresult = DNS_R_SERVFAIL;	} else {		/*		 * Extract the SOA MINIMUM.		 */		dns_rdata_soa_t soa;		dns_rdata_t rdata = DNS_RDATA_INIT;		result = dns_rdataset_first(rdataset);		RUNTIME_CHECK(result == ISC_R_SUCCESS);		dns_rdataset_current(rdataset, &rdata);		result = dns_rdata_tostruct(&rdata, &soa, NULL);		if (result != ISC_R_SUCCESS)			goto cleanup;		if (zero_ttl) {			rdataset->ttl = 0;			if (sigrdataset != NULL)				sigrdataset->ttl = 0;		}		/*		 * Add the SOA and its SIG to the response, with the		 * TTLs adjusted per RFC2308 section 3.		 */		if (rdataset->ttl > soa.minimum)			rdataset->ttl = soa.minimum;		if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum)			sigrdataset->ttl = soa.minimum;		if (sigrdataset != NULL)			sigrdatasetp = &sigrdataset;		else			sigrdatasetp = NULL;		query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,			       DNS_SECTION_AUTHORITY);	} cleanup:	query_putrdataset(client, &rdataset);	if (sigrdataset != NULL)		query_putrdataset(client, &sigrdataset);	if (name != NULL)		query_releasename(client, &name);	if (node != NULL)		dns_db_detachnode(db, &node);	return (eresult);}static inline isc_result_tquery_addns(ns_client_t *client, dns_db_t *db) {	dns_name_t *name, *fname;	dns_dbnode_t *node;	isc_result_t result, eresult;	dns_fixedname_t foundname;	dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;	dns_rdataset_t **sigrdatasetp = NULL;	CTRACE("query_addns");	/*	 * Initialization.	 */	eresult = ISC_R_SUCCESS;	name = NULL;	rdataset = NULL;	node = NULL;	dns_fixedname_init(&foundname);

⌨️ 快捷键说明

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