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

📄 query.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 5 页
字号:
		query_putrdataset(client, &csigrdataset);	if (fname != NULL)		query_releasename(client, &fname);}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 (NOADDITIONAL(client))		return;	/*	 * Add additional data.	 *	 * We don't care if dns_a6_foreach or dns_rdataset_additionaldata()	 * fail.	 */	if (type == dns_rdatatype_a6) {		dns_a6_reset(&client->query.a6ctx);		(void)dns_a6_foreach(&client->query.a6ctx, rdataset,				     client->now);	} else		(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_key);	}	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);	}	/*	 * 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);		dns_rdata_tostruct(&rdata, &soa, NULL);		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);	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) {		CTRACE("query_addns: dns_message_gettempname failed: done");		return (result);	}	dns_name_init(name, NULL);	dns_name_clone(dns_db_origin(db), name);	rdataset = query_newrdataset(client);	if (rdataset == NULL) {		CTRACE("query_addns: query_newrdataset failed");		eresult = DNS_R_SERVFAIL;		goto cleanup;	}	if (WANTDNSSEC(client)) {		sigrdataset = query_newrdataset(client);		if (sigrdataset == NULL) {			CTRACE("query_addns: query_newrdataset failed");			eresult = DNS_R_SERVFAIL;			goto cleanup;		}	}	/*	 * Find the NS rdataset.	 */	CTRACE("query_addns: calling dns_db_find");	result = dns_db_find(db, name, NULL, dns_rdatatype_ns,			     client->query.dboptions, 0, &node,			     fname, rdataset, sigrdataset);	CTRACE("query_addns: dns_db_find complete");	if (result != ISC_R_SUCCESS) {		CTRACE("query_addns: dns_db_find failed");		/*		 * This is bad.  We tried to get the NS rdataset at the zone		 * top and it didn't work!		 */		eresult = DNS_R_SERVFAIL;	} else {		if (sigrdataset != NULL)			sigrdatasetp = &sigrdataset;		else			sigrdatasetp = NULL;		query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL,			       DNS_SECTION_AUTHORITY);	} cleanup:	CTRACE("query_addns: 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);	CTRACE("query_addns: done");	return (eresult);}static inline isc_result_tquery_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname,		   dns_ttl_t ttl, dns_name_t **anamep, dns_rdatatype_t type){	dns_rdataset_t *rdataset;	dns_rdatalist_t *rdatalist;	dns_rdata_t *rdata;	isc_result_t result;	isc_region_t r;	/*	 * We assume the name data referred to by tname won't go away.	 */	REQUIRE(anamep != NULL);	rdatalist = NULL;	result = dns_message_gettemprdatalist(client->message, &rdatalist);	if (result != ISC_R_SUCCESS)		return (result);	rdata = NULL;	result = dns_message_gettemprdata(client->message, &rdata);	if (result != ISC_R_SUCCESS)		return (result);	rdataset = NULL;	result = dns_message_gettemprdataset(client->message, &rdataset);	if (result != ISC_R_SUCCESS)		return (result);	dns_rdataset_init(rdataset);	result = dns_name_dup(qname, client->mctx, *anamep);	if (result != ISC_R_SUCCESS) {		dns_message_puttemprdataset(client->message, &rdataset);		return (result);	}	rdatalist->type = type;	rdatalist->covers = 0;	rdatalist->rdclass = client->message->rdclass;	rdatalist->ttl = ttl;	dns_name_toregion(tname, &r);	rdata->data = r.base;	rdata->length = r.length;	rdata->rdclass = client->message->rdclass;	rdata->type = type;	ISC_LIST_INIT(rdatalist->rdata);	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);	dns_rdatalist_tordataset(rdatalist, rdataset);	query_addrrset(client, anamep, &rdataset, NULL, NULL,		       DNS_SECTION_ANSWER);	if (rdataset != NULL) {		if (dns_rdataset_isassociated(rdataset))			dns_rdataset_disassociate(rdataset);		dns_message_puttemprdataset(client->message, &rdataset);	}	return (ISC_R_SUCCESS);}static voidquery_addbestns(ns_client_t *client) {	dns_db_t *db, *zdb;	dns_dbnode_t *node;	dns_name_t *fname, *zfname;	dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset;	isc_boolean_t is_zone, use_zone;	isc_buffer_t *dbuf;	isc_result_t result;	dns_dbversion_t *version;	dns_zone_t *zone;	isc_buffer_t b;	CTRACE("query_addbestns");	fname = NULL;	zfname = NULL;	rdataset = NULL;	zrdataset = NULL;	sigrdataset = NULL;	zsigrdataset = NULL;	node = NULL;	db = NULL;	zdb = NULL;	version = NULL;	zone = NULL;	is_zone = ISC_FALSE;	use_zone = ISC_FALSE;	/*	 * Find the right database.	 */	result = query_getdb(client, client->query.qname, 0, &zone, &db,			     &version, &is_zone);	if (result != ISC_R_SUCCESS)		goto cleanup; db_find:	/*	 * We'll need some resources...	 */	dbuf = query_getnamebuf(client);	if (dbuf == NULL)		goto cleanup;	fname = query_newname(client, dbuf, &b);	rdataset = query_newrdataset(client);	if (fname == NULL || rdataset == NULL)		goto cleanup;	if (WANTDNSSEC(client)) {		sigrdataset = query_newrdataset(client);		if (sigrdataset == NULL)			goto cleanup;	}	/*	 * Now look for the zonecut.	 */	if (is_zone) {		result = dns_db_find(db, client->query.qname, version,				     dns_rdatatype_ns, client->query.dboptions,				     client->now, &node, fname,				     rdataset, sigrdataset);		if (result != DNS_R_DELEGATION)			goto cleanup;		if (USECACHE(client)) {			query_keepname(client, fname, dbuf);			zdb = db;			zfname = fname;			zrdataset = rdataset;			rdataset = NULL;			zsigrdataset = sigrdataset;			sigrdataset = NULL;			dns_db_detachnode(db, &node);			version = NULL;			db = NULL;			dns_db_attach(client->view->cachedb, &db);			is_zone = ISC_FALSE;			goto db_find;		}	} else {		result = dns_db_findzonecut(db, client->query.qname,					    client->query.dboptions,					    client->now, &node, fname,					    rdataset, sigrdataset);		if (result == ISC_R_SUCCESS) {			if (zfname != NULL &&			    !dns_name_issubdomain(fname, zfname)) {				/*				 * We found a zonecut in the cache, but our				 * zone delegation is better.				 */				use_zone = ISC_TRUE;			}		} else if (result == ISC_R_NOTFOUND && zfname != NULL) {			/*			 * We didn't find anything in the cache, but we			 * have a zone delegation, so use it.			 */			use_zone = ISC_TRUE;		} else			goto cleanup;	}	if (use_zone) {		query_releasename(client, &fname);		fname = zfname;		zfname = NULL;		/*		 * We've already done query_keepname() on		 * zfname, so we must set dbuf to NULL to		 * prevent query_addrrset() from trying to		 * call query_keepname() again.		 */		dbuf = NULL;		query_putrdataset(client, &rdataset);		if (sigrdataset != NULL)			query_putrdataset(client, &sigrdataset);		rdataset = zrdataset;		zrdataset = NULL;		sigrdataset = zsigrdataset;		zsigrdataset = NULL;	}	if ((client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0 &&	    (rdataset->trust == dns_trust_pending ||	     (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending)))		goto cleanup;	query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,		       DNS_SECTION_AUTHORITY);

⌨️ 快捷键说明

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