lib/dns/validator.c
/*%
 * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
 * or we can determine whether there is data or not at the name.
 * If the name does not exist return the wildcard name.
 *
 * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
 */
%
Return ISC_R_SUCCESS if we can determine that the name doesn't exist
or we can determine whether there is data or not at the name.
If the name does not exist return the wildcard name.

Return ISC_R_IGNORE when the NSEC is not the appropriate one.
% Return ISC_R_SUCCESS if we can determine that the name doesn ' t exist or we can determine whether there is data or not at the name . If the name does not exist return the wildcard name . Return ISC_R_IGNORE when the NSEC is not the appropriate one .
static isc_result_t
nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname,
		  dns_rdataset_t *nsecset, isc_boolean_t *exists,
		  isc_boolean_t *data, dns_name_t *wild)
{
	int order;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_result_t result;
	dns_namereln_t relation;
	unsigned int olabels, nlabels, labels;
	dns_rdata_nsec_t nsec;
	isc_boolean_t atparent;
	isc_boolean_t ns;
	isc_boolean_t soa;
	REQUIRE(exists != NULL);
	REQUIRE(data != NULL);
	REQUIRE(nsecset != NULL &&
		nsecset->type == dns_rdatatype_nsec);
	result = dns_rdataset_first(nsecset);
	if (result != ISC_R_SUCCESS) {
		validator_log(val, ISC_LOG_DEBUG(3),
			"failure processing NSEC set");
		return (result);
	}
	dns_rdataset_current(nsecset, &rdata);
	validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");
	relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
	if (order < 0) {
		validator_log(val, ISC_LOG_DEBUG(3),
			      "NSEC does not cover name, before NSEC");
		return (ISC_R_IGNORE);
	}
	if (order == 0) {
		atparent = dns_rdatatype_atparent(val->event->type);
		ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
		soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa);
		if (ns && !soa) {
			if (!atparent) {
				validator_log(val, ISC_LOG_DEBUG(3),
					      "ignoring parent nsec");
				return (ISC_R_IGNORE);
			}
		} else if (atparent && ns && soa) {
			validator_log(val, ISC_LOG_DEBUG(3),
				      "ignoring child nsec");
			return (ISC_R_IGNORE);
		}
		if (val->event->type == dns_rdatatype_cname ||
		    val->event->type == dns_rdatatype_nxt ||
		    val->event->type == dns_rdatatype_nsec ||
		    val->event->type == dns_rdatatype_key ||
		    !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) {
			*exists = ISC_TRUE;
			*data = dns_nsec_typepresent(&rdata, val->event->type);
			validator_log(val, ISC_LOG_DEBUG(3),
				      "nsec proves name exists (owner) data=%d",
				      *data);
			return (ISC_R_SUCCESS);
		}
		validator_log(val, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");
		return (ISC_R_IGNORE);
	}
	if (relation == dns_namereln_subdomain &&
	    dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
	    !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
	{
		validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec");
		return (ISC_R_IGNORE);
	}
	result = dns_rdata_tostruct(&rdata, &nsec, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);
	relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
	if (order == 0) {
		dns_rdata_freestruct(&nsec);
		validator_log(val, ISC_LOG_DEBUG(3),
			      "ignoring nsec matches next name");
		return (ISC_R_IGNORE);
	}
	if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
		dns_rdata_freestruct(&nsec);
		validator_log(val, ISC_LOG_DEBUG(3),
			    "ignoring nsec because name is past end of range");
		return (ISC_R_IGNORE);
	}
	if (order > 0 && relation == dns_namereln_subdomain) {
		validator_log(val, ISC_LOG_DEBUG(3),
			      "nsec proves name exist (empty)");
		dns_rdata_freestruct(&nsec);
		*exists = ISC_TRUE;
		*data = ISC_FALSE;
		return (ISC_R_SUCCESS);
	}
	if (wild != NULL) {
		dns_name_t common;
		dns_name_init(&common, NULL);
		if (olabels > nlabels) {
			labels = dns_name_countlabels(nsecname);
			dns_name_getlabelsequence(nsecname, labels - olabels,
						  olabels, &common);
		} else {
			labels = dns_name_countlabels(&nsec.next);
			dns_name_getlabelsequence(&nsec.next, labels - nlabels,
						  nlabels, &common);
		}
		result = dns_name_concatenate(dns_wildcardname, &common,
					       wild, NULL);
		if (result != ISC_R_SUCCESS) {
			dns_rdata_freestruct(&nsec);
			validator_log(val, ISC_LOG_DEBUG(3),
				    "failure generating wildcard name");
			return (result);
		}
	}
	dns_rdata_freestruct(&nsec);
	validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");
	*exists = ISC_FALSE;
	return (ISC_R_SUCCESS);
}
static isc_result_t nsecnoexistnodata ( dns_validator_t * val , dns_name_t * name , dns_name_t * nsecname , dns_rdataset_t * nsecset , isc_boolean_t * exists , isc_boolean_t * data , dns_name_t * wild ) { int order ; dns_rdata_t rdata = DNS_RDATA_INIT ; isc_result_t result ; dns_namereln_t relation ; unsigned int olabels , nlabels , labels ; dns_rdata_nsec_t nsec ; isc_boolean_t atparent ; isc_boolean_t ns ; isc_boolean_t soa ; REQUIRE ( exists != NULL ) ; REQUIRE ( data != NULL ) ; REQUIRE ( nsecset != NULL && nsecset -> type == dns_rdatatype_nsec ) ; result = dns_rdataset_first ( nsecset ) ; if ( result != ISC_R_SUCCESS ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( result ) ; } dns_rdataset_current ( nsecset , & rdata ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; relation = dns_name_fullcompare ( name , nsecname , & order , & olabels ) ; if ( order < 0 ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } if ( order == 0 ) { atparent = dns_rdatatype_atparent ( val -> event -> type ) ; ns = dns_nsec_typepresent ( & rdata , dns_rdatatype_ns ) ; soa = dns_nsec_typepresent ( & rdata , dns_rdatatype_soa ) ; if ( ns && ! soa ) { if ( ! atparent ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } } else if ( atparent && ns && soa ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } if ( val -> event -> type == dns_rdatatype_cname || val -> event -> type == dns_rdatatype_nxt || val -> event -> type == dns_rdatatype_nsec || val -> event -> type == dns_rdatatype_key || ! dns_nsec_typepresent ( & rdata , dns_rdatatype_cname ) ) { * exists = ISC_TRUE ; * data = dns_nsec_typepresent ( & rdata , val -> event -> type ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " , * data ) ; return ( ISC_R_SUCCESS ) ; } validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } if ( relation == dns_namereln_subdomain && dns_nsec_typepresent ( & rdata , dns_rdatatype_ns ) && ! dns_nsec_typepresent ( & rdata , dns_rdatatype_soa ) ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } result = dns_rdata_tostruct ( & rdata , & nsec , NULL ) ; if ( result != ISC_R_SUCCESS ) return ( result ) ; relation = dns_name_fullcompare ( & nsec . next , name , & order , & nlabels ) ; if ( order == 0 ) { dns_rdata_freestruct ( & nsec ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } if ( order < 0 && ! dns_name_issubdomain ( nsecname , & nsec . next ) ) { dns_rdata_freestruct ( & nsec ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( ISC_R_IGNORE ) ; } if ( order > 0 && relation == dns_namereln_subdomain ) { validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; dns_rdata_freestruct ( & nsec ) ; * exists = ISC_TRUE ; * data = ISC_FALSE ; return ( ISC_R_SUCCESS ) ; } if ( wild != NULL ) { dns_name_t common ; dns_name_init ( & common , NULL ) ; if ( olabels > nlabels ) { labels = dns_name_countlabels ( nsecname ) ; dns_name_getlabelsequence ( nsecname , labels - olabels , olabels , & common ) ; } else { labels = dns_name_countlabels ( & nsec . next ) ; dns_name_getlabelsequence ( & nsec . next , labels - nlabels , nlabels , & common ) ; } result = dns_name_concatenate ( dns_wildcardname , & common , wild , NULL ) ; if ( result != ISC_R_SUCCESS ) { dns_rdata_freestruct ( & nsec ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; return ( result ) ; } } dns_rdata_freestruct ( & nsec ) ; validator_log ( val , ISC_LOG_DEBUG ( 3 ) , " " ) ; * exists = ISC_FALSE ; return ( ISC_R_SUCCESS ) ; }
%
 Return ISC_R_SUCCESS if we can determine that the name doesn't exist
 or we can determine whether there is data or not at the name.
% Return ISC_R_SUCCESS if we can determine that the name doesn ' t exist or we can determine whether there is data or not at the name .
/*
		 * The name is not within the NSEC range.
		 */ /*
		 * The names are the same.
		 */ /*
				 * This NSEC record is from somewhere higher in
				 * the DNS, and at the parent of a delegation.
				 * It can not be legitimately used here.
				 */ /*
			 * This NSEC record is from the child.
			 * It can not be legitimately used here.
			 */ /*
		 * This NSEC record is from somewhere higher in
		 * the DNS, and at the parent of a delegation.
		 * It can not be legitimately used here.
		 */ /*
		 * The name is not within the NSEC range.
		 */