bin/named/update.c
/*%
 * Find the next/previous name that has a NSEC record.
 * In other words, skip empty database nodes and names that
 * have had their NSECs removed because they are obscured by
 * a zone cut.
 */
%
Find the next/previous name that has a NSEC record.
In other words, skip empty database nodes and names that
have had their NSECs removed because they are obscured by
a zone cut.
% Find the next / previous name that has a NSEC record . In other words skip empty database nodes and names that have had their NSECs removed because they are obscured by a zone cut .
static isc_result_t
next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
	    dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname,
	    isc_boolean_t forward)
{
	isc_result_t result;
	dns_dbiterator_t *dbit = NULL;
	isc_boolean_t has_nsec = ISC_FALSE;
	unsigned int wraps = 0;
	isc_boolean_t secure = dns_db_issecure(db);
	CHECK(dns_db_createiterator(db, 0, &dbit));
	CHECK(dns_dbiterator_seek(dbit, oldname));
	do {
		dns_dbnode_t *node = NULL;
		if (forward)
			result = dns_dbiterator_next(dbit);
		else
			result = dns_dbiterator_prev(dbit);
		if (result == ISC_R_NOMORE) {
			if (forward)
				CHECK(dns_dbiterator_first(dbit));
			else
				CHECK(dns_dbiterator_last(dbit));
			wraps++;
			if (wraps == 2) {
				update_log(client, zone, ISC_LOG_ERROR,
					   "secure zone with no NSECs");
				result = DNS_R_BADZONE;
				goto failure;
			}
		}
		CHECK(dns_dbiterator_current(dbit, &node, newname));
		dns_db_detachnode(db, &node);
		CHECK(dns_dbiterator_pause(dbit));
		if (secure) {
			CHECK(rrset_exists(db, ver, newname,
					   dns_rdatatype_nsec, 0, &has_nsec));
		} else {
			dns_fixedname_t ffound;
			dns_name_t *found;
			dns_fixedname_init(&ffound);
			found = dns_fixedname_name(&ffound);
			result = dns_db_find(db, newname, ver,
					     dns_rdatatype_soa,
					     DNS_DBFIND_NOWILD, 0, NULL, found,
					     NULL, NULL);
			if (result == ISC_R_SUCCESS ||
			    result == DNS_R_EMPTYNAME ||
			    result == DNS_R_NXRRSET ||
			    result == DNS_R_CNAME ||
			    (result == DNS_R_DELEGATION &&
			     dns_name_equal(newname, found))) {
				has_nsec = ISC_TRUE;
				result = ISC_R_SUCCESS;
			} else if (result != DNS_R_NXDOMAIN)
				break;
		}
	} while (! has_nsec);
 failure:
	if (dbit != NULL)
		dns_dbiterator_destroy(&dbit);
	return (result);
}
static isc_result_t next_active ( ns_client_t * client , dns_zone_t * zone , dns_db_t * db , dns_dbversion_t * ver , dns_name_t * oldname , dns_name_t * newname , isc_boolean_t forward ) { isc_result_t result ; dns_dbiterator_t * dbit = NULL ; isc_boolean_t has_nsec = ISC_FALSE ; unsigned int wraps = 0 ; isc_boolean_t secure = dns_db_issecure ( db ) ; CHECK ( dns_db_createiterator ( db , 0 , & dbit ) ) ; CHECK ( dns_dbiterator_seek ( dbit , oldname ) ) ; do { dns_dbnode_t * node = NULL ; if ( forward ) result = dns_dbiterator_next ( dbit ) ; else result = dns_dbiterator_prev ( dbit ) ; if ( result == ISC_R_NOMORE ) { if ( forward ) CHECK ( dns_dbiterator_first ( dbit ) ) ; else CHECK ( dns_dbiterator_last ( dbit ) ) ; wraps ++ ; if ( wraps == 2 ) { update_log ( client , zone , ISC_LOG_ERROR , " " ) ; result = DNS_R_BADZONE ; goto failure ; } } CHECK ( dns_dbiterator_current ( dbit , & node , newname ) ) ; dns_db_detachnode ( db , & node ) ; CHECK ( dns_dbiterator_pause ( dbit ) ) ; if ( secure ) { CHECK ( rrset_exists ( db , ver , newname , dns_rdatatype_nsec , 0 , & has_nsec ) ) ; } else { dns_fixedname_t ffound ; dns_name_t * found ; dns_fixedname_init ( & ffound ) ; found = dns_fixedname_name ( & ffound ) ; result = dns_db_find ( db , newname , ver , dns_rdatatype_soa , DNS_DBFIND_NOWILD , 0 , NULL , found , NULL , NULL ) ; if ( result == ISC_R_SUCCESS || result == DNS_R_EMPTYNAME || result == DNS_R_NXRRSET || result == DNS_R_CNAME || ( result == DNS_R_DELEGATION && dns_name_equal ( newname , found ) ) ) { has_nsec = ISC_TRUE ; result = ISC_R_SUCCESS ; } else if ( result != DNS_R_NXDOMAIN ) break ; } } while ( ! has_nsec ) ; failure : if ( dbit != NULL ) dns_dbiterator_destroy ( & dbit ) ; return ( result ) ; }
%
 Find the next/previous name that has a NSEC record.
% Find the next / previous name that has a NSEC record .
/*
			 * Wrap around.
			 */ /*
		 * The iterator may hold the tree lock, and
		 * rrset_exists() calls dns_db_findnode() which
		 * may try to reacquire it.  To avoid deadlock
		 * we must pause the iterator first.
		 */