コード例 #1
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
static void
test_context_teardown(test_context_t *ctx) {
	dns_rbt_destroy(&ctx->rbt);
	dns_rbt_destroy(&ctx->rbt_distances);

	isc_mem_put(mctx, ctx, sizeof(*ctx));
}
コード例 #2
0
void
dns_keytable_detach(dns_keytable_t **keytablep) {
	isc_boolean_t destroy = ISC_FALSE;
	dns_keytable_t *keytable;

	/*
	 * Detach *keytablep from its keytable.
	 */

	REQUIRE(keytablep != NULL && VALID_KEYTABLE(*keytablep));

	keytable = *keytablep;

	RWLOCK(&keytable->rwlock, isc_rwlocktype_write);

	INSIST(keytable->references > 0);
	keytable->references--;
	LOCK(&keytable->lock);
	if (keytable->references == 0 && keytable->active_nodes == 0)
		destroy = ISC_TRUE;
	UNLOCK(&keytable->lock);

	RWUNLOCK(&keytable->rwlock, isc_rwlocktype_write);

	if (destroy) {
		dns_rbt_destroy(&keytable->table);
		isc_rwlock_destroy(&keytable->rwlock);
		DESTROYLOCK(&keytable->lock);
		keytable->magic = 0;
		isc_mem_putanddetach(&keytable->mctx,
				     keytable, sizeof(*keytable));
	}

	*keytablep = NULL;
}
コード例 #3
0
isc_result_t
dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) {
	dns_fwdtable_t *fwdtable;
	isc_result_t result;

	REQUIRE(fwdtablep != NULL && *fwdtablep == NULL);

	fwdtable = isc_mem_get(mctx, sizeof(dns_fwdtable_t));
	if (fwdtable == NULL)
		return (ISC_R_NOMEMORY);

	fwdtable->table = NULL;
	result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table);
	if (result != ISC_R_SUCCESS)
		goto cleanup_fwdtable;

	result = isc_rwlock_init(&fwdtable->rwlock, 0, 0);
	if (result != ISC_R_SUCCESS)
		goto cleanup_rbt;

	fwdtable->mctx = NULL;
	isc_mem_attach(mctx, &fwdtable->mctx);
	fwdtable->magic = FWDTABLEMAGIC;
	*fwdtablep = fwdtable;

	return (ISC_R_SUCCESS);

   cleanup_rbt:
	dns_rbt_destroy(&fwdtable->table);

   cleanup_fwdtable:
	isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t));

	return (result);
}
コード例 #4
0
ファイル: zt.c プロジェクト: SylvestreG/bitrig
static void
zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) {
	isc_boolean_t destroy = ISC_FALSE;
	dns_zt_t *zt;

	REQUIRE(ztp != NULL && VALID_ZT(*ztp));

	zt = *ztp;

	RWLOCK(&zt->rwlock, isc_rwlocktype_write);

	INSIST(zt->references > 0);
	zt->references--;
	if (zt->references == 0)
		destroy = ISC_TRUE;

	RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);

	if (destroy) {
		if (need_flush)
			(void)dns_zt_apply(zt, ISC_FALSE, flush, NULL);
		dns_rbt_destroy(&zt->table);
		isc_rwlock_destroy(&zt->rwlock);
		zt->magic = 0;
		isc_mem_put(zt->mctx, zt, sizeof(*zt));
	}

	*ztp = NULL;
}
コード例 #5
0
ファイル: zt.c プロジェクト: crossbuild/bind
static void
zt_destroy(dns_zt_t *zt) {
	if (zt->flush)
		(void)dns_zt_apply(zt, ISC_FALSE, flush, NULL);
	dns_rbt_destroy(&zt->table);
	isc_rwlock_destroy(&zt->rwlock);
	zt->magic = 0;
	isc_mem_putanddetach(&zt->mctx, zt, sizeof(*zt));
}
コード例 #6
0
ファイル: tsig.c プロジェクト: miettal/armadillo420_standard
void
dns_tsigkeyring_destroy(dns_tsig_keyring_t **ringp) {
	dns_tsig_keyring_t *ring;

	REQUIRE(ringp != NULL);
	REQUIRE(*ringp != NULL);

	ring = *ringp;
	*ringp = NULL;

	dns_rbt_destroy(&ring->keys);
	isc_rwlock_destroy(&ring->lock);
	isc_mem_put(ring->mctx, ring, sizeof(dns_tsig_keyring_t));
}
コード例 #7
0
ファイル: dbtable.c プロジェクト: jaredmcneill/netbsd-src
isc_result_t
dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
		   dns_dbtable_t **dbtablep)
{
	dns_dbtable_t *dbtable;
	isc_result_t result;

	REQUIRE(mctx != NULL);
	REQUIRE(dbtablep != NULL && *dbtablep == NULL);

	dbtable = (dns_dbtable_t *)isc_mem_get(mctx, sizeof(*dbtable));
	if (dbtable == NULL)
		return (ISC_R_NOMEMORY);

	dbtable->rbt = NULL;
	result = dns_rbt_create(mctx, dbdetach, NULL, &dbtable->rbt);
	if (result != ISC_R_SUCCESS)
		goto clean1;

	result = isc_mutex_init(&dbtable->lock);
	if (result != ISC_R_SUCCESS)
		goto clean2;

	result = isc_rwlock_init(&dbtable->tree_lock, 0, 0);
	if (result != ISC_R_SUCCESS)
		goto clean3;

	dbtable->default_db = NULL;
	dbtable->mctx = NULL;
	isc_mem_attach(mctx, &dbtable->mctx);
	dbtable->rdclass = rdclass;
	dbtable->magic = DBTABLE_MAGIC;
	dbtable->references = 1;

	*dbtablep = dbtable;

	return (ISC_R_SUCCESS);

 clean3:
	DESTROYLOCK(&dbtable->lock);

 clean2:
	dns_rbt_destroy(&dbtable->rbt);

 clean1:
	isc_mem_putanddetach(&mctx, dbtable, sizeof(*dbtable));

	return (result);
}
コード例 #8
0
isc_result_t
dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) {
	dns_keytable_t *keytable;
	isc_result_t result;

	/*
	 * Create a keytable.
	 */

	REQUIRE(keytablep != NULL && *keytablep == NULL);

	keytable = isc_mem_get(mctx, sizeof(*keytable));
	if (keytable == NULL)
		return (ISC_R_NOMEMORY);

	keytable->table = NULL;
	result = dns_rbt_create(mctx, free_keynode, mctx, &keytable->table);
	if (result != ISC_R_SUCCESS)
		goto cleanup_keytable;

	result = isc_mutex_init(&keytable->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_rbt;

	result = isc_rwlock_init(&keytable->rwlock, 0, 0);
	if (result != ISC_R_SUCCESS)
		goto cleanup_lock;

	keytable->mctx = NULL;
	isc_mem_attach(mctx, &keytable->mctx);
	keytable->active_nodes = 0;
	keytable->references = 1;
	keytable->magic = KEYTABLE_MAGIC;
	*keytablep = keytable;

	return (ISC_R_SUCCESS);

   cleanup_lock:
	DESTROYLOCK(&keytable->lock);

   cleanup_rbt:
	dns_rbt_destroy(&keytable->table);

   cleanup_keytable:
	isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable));

	return (result);
}
コード例 #9
0
ファイル: t_rbt.c プロジェクト: pombredanne/NetBSD
/*
 * Initialize a database from filename.
 */
static int
rbt_init(char *filename, dns_rbt_t **rbt, isc_mem_t *mctx) {
	int		rval;
	isc_result_t	dns_result;
	char		*p;
	FILE		*fp;

	fp = fopen(filename, "r");
	if (fp == NULL) {
		t_info("No such file %s\n", filename);
		return(1);
	}

	dns_result = dns_rbt_create(mctx, delete_name, mctx, rbt);
	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_rbt_create failed %s\n",
				dns_result_totext(dns_result));
		fclose(fp);
		return(1);
	}

	while ((p = t_fgetbs(fp)) != NULL) {

		/*
		 * Skip any comment lines.
		 */
		if ((*p == '#') || (*p == '\0') || (*p == ' ')) {
			(void)free(p);
			continue;
		}

		if (T_debug)
			t_info("adding name %s to the rbt\n", p);

		rval = t1_add(p, *rbt, mctx, &dns_result);
		if ((rval != 0) || (dns_result != ISC_R_SUCCESS)) {
			t_info("add of %s failed\n", p);
			dns_rbt_destroy(rbt);
			fclose(fp);
			return(1);
		}
		(void) free(p);
	}
	fclose(fp);
	return(0);
}
コード例 #10
0
void
dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) {
	dns_fwdtable_t *fwdtable;
	isc_mem_t *mctx;

	REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep));

	fwdtable = *fwdtablep;

	dns_rbt_destroy(&fwdtable->table);
	isc_rwlock_destroy(&fwdtable->rwlock);
	fwdtable->magic = 0;
	mctx = fwdtable->mctx;
	isc_mem_put(mctx, fwdtable, sizeof(dns_fwdtable_t));
	isc_mem_detach(&mctx);

	*fwdtablep = NULL;
}
コード例 #11
0
ファイル: zt.c プロジェクト: crossbuild/bind
isc_result_t
dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
	dns_zt_t *zt;
	isc_result_t result;

	REQUIRE(ztp != NULL && *ztp == NULL);

	zt = isc_mem_get(mctx, sizeof(*zt));
	if (zt == NULL)
		return (ISC_R_NOMEMORY);

	zt->table = NULL;
	result = dns_rbt_create(mctx, auto_detach, zt, &zt->table);
	if (result != ISC_R_SUCCESS)
		goto cleanup_zt;

	result = isc_rwlock_init(&zt->rwlock, 0, 0);
	if (result != ISC_R_SUCCESS)
		goto cleanup_rbt;

	zt->mctx = NULL;
	isc_mem_attach(mctx, &zt->mctx);
	zt->references = 1;
	zt->flush = ISC_FALSE;
	zt->rdclass = rdclass;
	zt->magic = ZTMAGIC;
	zt->loaddone = NULL;
	zt->loaddone_arg = NULL;
	zt->loads_pending = 0;
	*ztp = zt;

	return (ISC_R_SUCCESS);

   cleanup_rbt:
	dns_rbt_destroy(&zt->table);

   cleanup_zt:
	isc_mem_put(mctx, zt, sizeof(*zt));

	return (result);
}
コード例 #12
0
ファイル: zt.c プロジェクト: miettal/armadillo420_standard
isc_result_t
dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
	dns_zt_t *zt;
	isc_result_t result;

	REQUIRE(ztp != NULL && *ztp == NULL);

	zt = isc_mem_get(mctx, sizeof(*zt));
	if (zt == NULL)
		return (ISC_R_NOMEMORY);

	zt->table = NULL;
	result = dns_rbt_create(mctx, auto_detach, zt, &zt->table);
	if (result != ISC_R_SUCCESS)
		goto cleanup_zt;

	result = isc_rwlock_init(&zt->rwlock, 0, 0);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_rwlock_init() failed: %s",
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto cleanup_rbt;
	}

	zt->mctx = mctx;
	zt->references = 1;
	zt->rdclass = rdclass;
	zt->magic = ZTMAGIC;
	*ztp = zt;

	return (ISC_R_SUCCESS);

   cleanup_rbt:
	dns_rbt_destroy(&zt->table);

   cleanup_zt:
	isc_mem_put(mctx, zt, sizeof(*zt));

	return (result);
}
コード例 #13
0
ファイル: dbtable.c プロジェクト: jaredmcneill/netbsd-src
static inline void
dbtable_free(dns_dbtable_t *dbtable) {
	/*
	 * Caller must ensure that it is safe to call.
	 */

	RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);

	if (dbtable->default_db != NULL)
		dns_db_detach(&dbtable->default_db);

	dns_rbt_destroy(&dbtable->rbt);

	RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);

	isc_rwlock_destroy(&dbtable->tree_lock);

	dbtable->magic = 0;

	isc_mem_putanddetach(&dbtable->mctx, dbtable, sizeof(*dbtable));
}
コード例 #14
0
ファイル: cache.c プロジェクト: mnagy/bind-dyndb-ldap
void
destroy_ldap_cache(ldap_cache_t **cachep)
{
	ldap_cache_t *cache;
	int is_locked = 0;

	REQUIRE(cachep != NULL && *cachep != NULL);

	cache = *cachep;

	if (cache->rbt) {
		CONTROLED_LOCK(&cache->mutex);
		dns_rbt_destroy(&cache->rbt);
		cache->rbt = NULL;
		CONTROLED_UNLOCK(&cache->mutex);
		DESTROYLOCK(&cache->mutex);
	}

	MEM_PUT_AND_DETACH(cache);

	*cachep = NULL;
}
コード例 #15
0
ファイル: t_rbt.c プロジェクト: pombredanne/NetBSD
static int
test_rbt_gen(char *filename, char *command, char *testname,
	     isc_result_t exp_result)
{
	int		rval;
	int		result;
	dns_rbt_t	*rbt;
	isc_result_t	isc_result;
	isc_result_t	dns_result;
	isc_mem_t	*mctx;
	isc_entropy_t	*ectx;
	dns_name_t	*dns_name;

	result = T_UNRESOLVED;

	if (strcmp(command, "create") != 0)
		t_info("testing using name %s\n", testname);

	mctx = NULL;
	ectx = NULL;

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	rbt = NULL;
	if (rbt_init(filename, &rbt, mctx) != 0) {
		if (strcmp(command, "create") == 0)
			result = T_FAIL;
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	/*
	 * Now try the database command.
	 */
	if (strcmp(command, "create") == 0) {
		result = T_PASS;
	} else if (strcmp(command, "add") == 0) {
		if (create_name(testname, mctx, &dns_name) == 0) {
			dns_result = dns_rbt_addname(rbt, dns_name, dns_name);

			if (dns_result != ISC_R_SUCCESS)
				delete_name(dns_name, mctx);

			if (dns_result == exp_result) {
				if (dns_result == ISC_R_SUCCESS) {
					rval = t1_search(testname, rbt, mctx,
							 &dns_result);
					if (rval == 0) {
					     if (dns_result == ISC_R_SUCCESS) {
						     result = T_PASS;
					     } else {
						     result = T_FAIL;
					     }
					} else {
						t_info("t1_search failed\n");
						result = T_UNRESOLVED;
					}
				} else {
					result = T_PASS;
				}
			} else {
				t_info("dns_rbt_addname returned %s, "
				       "expected %s\n",
				       dns_result_totext(dns_result),
				       dns_result_totext(exp_result));
				result = T_FAIL;
			}
		} else {
			t_info("create_name failed\n");
			result = T_UNRESOLVED;
		}
	} else if ((strcmp(command, "delete") == 0) ||
		   (strcmp(command, "nuke") == 0)) {
		rval = t1_delete(testname, rbt, mctx, &dns_result);
		if (rval == 0) {
			if (dns_result == exp_result) {
				rval = t1_search(testname, rbt, mctx,
						 &dns_result);
				if (rval == 0) {
					if (dns_result == ISC_R_SUCCESS) {
						t_info("dns_rbt_deletename "
						       "didn't delete "
						       "the name");
						result = T_FAIL;
					} else {
						result = T_PASS;
					}
				}
			} else {
				t_info("delete returned %s, expected %s\n",
					dns_result_totext(dns_result),
					dns_result_totext(exp_result));
				result = T_FAIL;
			}
		}
	} else if (strcmp(command, "search") == 0) {
		rval = t1_search(testname, rbt, mctx, &dns_result);
		if (rval == 0) {
			if (dns_result == exp_result) {
				result = T_PASS;
			} else {
				t_info("find returned %s, expected %s\n",
					dns_result_totext(dns_result),
					dns_result_totext(exp_result));
				result = T_FAIL;
			}
		}
	}

	dns_rbt_destroy(&rbt);
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);
	return(result);
}
コード例 #16
0
ファイル: t_rbt.c プロジェクト: pombredanne/NetBSD
static int
t_dns_rbtnodechain_last(char *dbfile, char *expected_lastname,
			char *expected_lastorigin,
			char *expected_prevname,
			char *expected_prevorigin)
{

	int			result;
	int			nfails;
	dns_rbt_t		*rbt;
	dns_rbtnodechain_t	chain;
	isc_mem_t		*mctx;
	isc_entropy_t		*ectx;
	isc_result_t		isc_result;
	isc_result_t		dns_result;
	dns_fixedname_t		dns_name;
	dns_fixedname_t		dns_origin;
	isc_result_t		expected_result;

	result = T_UNRESOLVED;

	nfails = 0;
	mctx = NULL;
	ectx = NULL;

	dns_fixedname_init(&dns_name);
	dns_fixedname_init(&dns_origin);

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(result);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_rbtnodechain_init(&chain, mctx);

	rbt = NULL;
	if (rbt_init(dbfile, &rbt, mctx)) {
		t_info("rbt_init %s failed\n", dbfile);
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	t_info("testing for last name of %s, origin of %s\n",
	       expected_lastname, expected_lastorigin);

	dns_result = dns_rbtnodechain_last(&chain, rbt,
					   dns_fixedname_name(&dns_name),
					   dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_name, expected_lastname,
			    &dns_origin, expected_lastorigin, DNS_R_NEWORIGIN);

	t_info("testing for previous name of %s, origin of %s\n",
	       expected_prevname, expected_prevorigin);

	dns_fixedname_init(&dns_name);
	dns_result = dns_rbtnodechain_prev(&chain,
					   dns_fixedname_name(&dns_name),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	if (strcasecmp(expected_lastorigin, expected_prevorigin) == 0)
		expected_result = ISC_R_SUCCESS;
	else
		expected_result = DNS_R_NEWORIGIN;
	nfails += t_namechk(dns_result, &dns_name, expected_prevname,
			    &dns_origin, expected_prevorigin, expected_result);

	if (nfails)
		result = T_FAIL;
	else
		result = T_PASS;

	dns_rbtnodechain_invalidate(&chain);
	dns_rbt_destroy(&rbt);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);

	return(result);
}
コード例 #17
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
ATF_TC_BODY(rbt_insert_and_remove, tc) {
	/*
	 * What is the best way to test our red-black tree code? It is
	 * not a good method to test every case handled in the actual
	 * code itself. This is because our approach itself may be
	 * incorrect.
	 *
	 * We test our code at the interface level here by exercising the
	 * tree randomly multiple times, checking that red-black tree
	 * properties are valid, and all the nodes that are supposed to be
	 * in the tree exist and are in order.
	 *
	 * NOTE: These tests are run within a single tree level in the
	 * forest. The number of nodes in the tree level doesn't grow
	 * over 1024.
	 */
	isc_result_t result;
	dns_rbt_t *mytree = NULL;
	/*
	 * We use an array for storing names instead of a set
	 * structure. It's slow, but works and is good enough for tests.
	 */
	char *names[1024];
	size_t names_count;
	int i;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	result = dns_rbt_create(mctx, delete_data, NULL, &mytree);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	memset(names, 0, sizeof(names));
	names_count = 0;

	/* Repeat the insert/remove test some 4096 times */
	for (i = 0; i < 4096; i++) {
		isc_uint32_t num_names;
		isc_random_get(&num_names);

		if (names_count < 1024) {
			num_names %= 1024 - names_count;
			num_names++;
		} else {
			num_names = 0;
		}

		insert_nodes(mytree, names, &names_count, num_names);
		check_tree(mytree, names, names_count);

		isc_random_get(&num_names);
		if (names_count > 0) {
			num_names %= names_count;
			num_names++;
		} else {
			num_names = 0;
		}

		remove_nodes(mytree, names, &names_count, num_names);
		check_tree(mytree, names, names_count);
	}

	/* Remove the rest of the nodes */
	remove_nodes(mytree, names, &names_count, names_count);
	check_tree(mytree, names, names_count);

	for (i = 0; i < 1024; i++) {
		if (names[i] != NULL) {
			isc_mem_free(mctx, names[i]);
		}
	}

	dns_rbt_destroy(&mytree);

	dns_test_end();
}
コード例 #18
0
ファイル: rbt_test.c プロジェクト: enukane/netbsd-src
int
main(int argc, char **argv) {
	char *command, *arg, buffer[1024];
	const char *whitespace;
	dns_name_t *name, *foundname;
	dns_fixedname_t fixedname;
	dns_rbt_t *rbt = NULL;
	int length, ch;
	isc_boolean_t show_final_mem = ISC_FALSE;
	isc_result_t result;
	void *data;

	progname = strrchr(*argv, '/');
	if (progname != NULL)
		progname++;
	else
		progname = *argv;

	while ((ch = isc_commandline_parse(argc, argv, "m")) != -1) {
		switch (ch) {
		case 'm':
			show_final_mem = ISC_TRUE;
			break;
		}
	}

	argc -= isc_commandline_index;
	argv += isc_commandline_index;
	POST(argv);

	if (argc > 1) {
		printf("Usage: %s [-m]\n", progname);
		exit(1);
	}

	setbuf(stdout, NULL);

	/*
	 * So isc_mem_stats() can report any allocation leaks.
	 */
	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = isc_mem_create(0, 0, &mctx);
	if (result != ISC_R_SUCCESS) {
		printf("isc_mem_create: %s: exiting\n",
		       dns_result_totext(result));
		exit(1);
	}

	result = dns_rbt_create(mctx, delete_name, NULL, &rbt);
	if (result != ISC_R_SUCCESS) {
		printf("dns_rbt_create: %s: exiting\n",
		       dns_result_totext(result));
		exit(1);
	}

	whitespace = " \t";

	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
		length = strlen(buffer);

		if (buffer[length - 1] != '\n') {
			printf("line to long (%lu max), ignored\n",
			       (unsigned long)sizeof(buffer) - 2);
			continue;
		}

		buffer[length - 1] = '\0';

		command = buffer + strspn(buffer, whitespace);

		if (*command == '#')
			continue;

		arg = strpbrk(command, whitespace);
		if (arg != NULL) {
			*arg++ = '\0';
			arg += strspn(arg, whitespace);
		}

		length = strlen(command);
		if (*command != '\0') {
			if (CMDCHECK("add")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("adding name %s\n", arg);
					result = dns_rbt_addname(rbt,
								 name, name);
					PRINTERR(result);
				}

			} else if (CMDCHECK("delete")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("deleting name %s\n", arg);
					result = dns_rbt_deletename(rbt, name,
								    ISC_FALSE);
					PRINTERR(result);
					delete_name(name, NULL);
				}

			} else if (CMDCHECK("nuke")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("nuking name %s "
					       "and its descendants\n", arg);
					result = dns_rbt_deletename(rbt, name,
								    ISC_TRUE);
					PRINTERR(result);
					delete_name(name, NULL);
				}

			} else if (CMDCHECK("search")) {
				name = create_name(arg);
				if (name != NULL) {
					printf("searching for name %s ... ",
					       arg);

					dns_fixedname_init(&fixedname);
					foundname =
						dns_fixedname_name(&fixedname);
					data = NULL;

					result = dns_rbt_findname(rbt, name, 0,
								  foundname,
								  &data);
					switch (result) {
					case ISC_R_SUCCESS:
						printf("found exact: ");
						print_name(data);
						putchar('\n');
						break;
					case DNS_R_PARTIALMATCH:
						printf("found parent: ");
						print_name(data);
						printf("\n\t(foundname: ");
						print_name(foundname);
						printf(")\n");
						break;
					case ISC_R_NOTFOUND:
						printf("NOT FOUND!\n");
						break;
					case ISC_R_NOMEMORY:
						printf("OUT OF MEMORY!\n");
						break;
					default:
						printf("UNEXPECTED RESULT\n");
					}

					delete_name(name, NULL);
				}

			} else if (CMDCHECK("check")) {
				/*
				 * Or "chain".  I know, I know.  Lame name.
				 * I was having a hard time thinking of a
				 * name (especially one that did not have
				 * a conflicting first letter with another
				 * command) that would differentiate this
				 * from the search command.
				 *
				 * But it is just a test program, eh?
				 */
				name = create_name(arg);
				if (name != NULL) {
					detail(rbt, name);

					delete_name(name, NULL);
				}

			} else if (CMDCHECK("forward")) {
				iterate(rbt, ISC_TRUE);

			} else if (CMDCHECK("backward")) {
				iterate(rbt, ISC_FALSE);

			} else if (CMDCHECK("print")) {
				if (arg == NULL || *arg == '\0')
					dns_rbt_printall(rbt, NULL);
				else
					printf("usage: print\n");

			} else if (CMDCHECK("quit")) {
				if (arg == NULL || *arg == '\0')
					break;
				else
					printf("usage: quit\n");
			} else {
				printf("a(dd) NAME, d(elete) NAME, "
				       "s(earch) NAME, p(rint), or q(uit)\n");

			}
		}

	}

	dns_rbt_destroy(&rbt);

	if (show_final_mem)
		isc_mem_stats(mctx, stderr);

	return (0);
}
コード例 #19
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
ATF_TC_BODY(benchmark, tc) {
	isc_result_t result;
	char namestr[sizeof("name18446744073709551616.example.org.")];
	unsigned int r;
	dns_rbt_t *mytree;
	dns_rbtnode_t *node;
	unsigned int i;
	unsigned int maxvalue = 1000000;
	isc_time_t ts1, ts2;
	double t;
	unsigned int nthreads;
	isc_thread_t threads[32];

	UNUSED(tc);

	srandom(time(NULL));

	debug_mem_record = ISC_FALSE;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	fnames = (dns_fixedname_t *) malloc(4000000 * sizeof(dns_fixedname_t));
	names = (dns_name_t **) malloc(4000000 * sizeof(dns_name_t *));
	values = (int *) malloc(4000000 * sizeof(int));

	for (i = 0; i < 4000000; i++) {
		  r = ((unsigned long) random()) % maxvalue;
		  snprintf(namestr, sizeof(namestr), "name%u.example.org.", r);
		  build_name_from_str(namestr, &fnames[i]);
		  names[i] = dns_fixedname_name(&fnames[i]);
		  values[i] = r;
	}

	/* Create a tree. */
	mytree = NULL;
	result = dns_rbt_create(mctx, NULL, NULL, &mytree);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* Insert test data into the tree. */
	for (i = 0; i < maxvalue; i++) {
		snprintf(namestr, sizeof(namestr), "name%u.example.org.", i);
		node = NULL;
		result = insert_helper(mytree, namestr, &node);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
		node->data = (void *) (intptr_t) i;
	}

	result = isc_time_now(&ts1);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	nthreads = ISC_MIN(isc_os_ncpus(), 32);
	nthreads = ISC_MAX(nthreads, 1);
	for (i = 0; i < nthreads; i++) {
		result = isc_thread_create(find_thread, mytree, &threads[i]);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	}

	for (i = 0; i < nthreads; i++) {
		result = isc_thread_join(threads[i], NULL);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	}

	result = isc_time_now(&ts2);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	t = isc_time_microdiff(&ts2, &ts1);

	printf("%u findnode calls, %f seconds, %f calls/second\n",
	       nthreads * 8 * 4000000, t / 1000000.0,
	       (nthreads * 8 * 4000000) / (t / 1000000.0));

	free(values);
	free(names);
	free(fnames);

	dns_rbt_destroy(&mytree);

	dns_test_end();
}
コード例 #20
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
ATF_TC_BODY(rbt_check_distance_random, tc) {
	/* This test checks an important performance-related property of
	 * the red-black tree, which is important for us: the longest
	 * path from a sub-tree's root to a node is no more than
	 * 2log(n). This check verifies that the tree is balanced.
	 */
	dns_rbt_t *mytree = NULL;
	const unsigned int log_num_nodes = 16;

	int i;
	isc_result_t result;
	isc_boolean_t tree_ok;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	result = dns_rbt_create(mctx, delete_data, NULL, &mytree);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* Names are inserted in random order. */

	/* Make a large 65536 node top-level domain tree, i.e., the
	 * following code inserts names such as:
	 *
	 * savoucnsrkrqzpkqypbygwoiliawpbmz.
	 * wkadamcbbpjtundbxcmuayuycposvngx.
	 * wzbpznemtooxdpjecdxynsfztvnuyfao.
	 * yueojmhyffslpvfmgyfwioxegfhepnqq.
	 */
	for (i = 0; i < (1 << log_num_nodes); i++) {
		size_t *n;
		char namebuf[34];

		n = isc_mem_get(mctx, sizeof(size_t));
		*n = i + 1;

		while (1) {
			int j;
			dns_fixedname_t fname;
			dns_name_t *name;

			for (j = 0; j < 32; j++) {
				isc_uint32_t v;
				isc_random_get(&v);
				namebuf[j] = 'a' + (v % 26);
			}
			namebuf[32] = '.';
			namebuf[33] = 0;

			build_name_from_str(namebuf, &fname);
			name = dns_fixedname_name(&fname);

			result = dns_rbt_addname(mytree, name, n);
			if (result == ISC_R_SUCCESS)
				break;
		}
	}

	/* 1 (root . node) + (1 << log_num_nodes) */
	ATF_CHECK_EQ(1U + (1U << log_num_nodes), dns_rbt_nodecount(mytree));

	/* The distance from each node to its sub-tree root must be less
	 * than 2 * log(n).
	 */
	ATF_CHECK((2U * log_num_nodes) >= dns__rbt_getheight(mytree));

	/* Also check RB tree properties */
	tree_ok = dns__rbt_checkproperties(mytree);
	ATF_CHECK_EQ(tree_ok, ISC_TRUE);

	dns_rbt_destroy(&mytree);

	dns_test_end();
}
コード例 #21
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
ATF_TC_BODY(rbt_check_distance_ordered, tc) {
	/* This test checks an important performance-related property of
	 * the red-black tree, which is important for us: the longest
	 * path from a sub-tree's root to a node is no more than
	 * 2log(n). This check verifies that the tree is balanced.
	 */
	dns_rbt_t *mytree = NULL;
	const unsigned int log_num_nodes = 16;

	int i;
	isc_result_t result;
	isc_boolean_t tree_ok;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	result = dns_rbt_create(mctx, delete_data, NULL, &mytree);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* Names are inserted in sorted order. */

	/* Make a large 65536 node top-level domain tree, i.e., the
	 * following code inserts names such as:
	 *
	 *   name00000000.
	 *   name00000001.
	 *   name00000002.
	 *   name00000003.
	 */
	for (i = 0; i < (1 << log_num_nodes); i++) {
		size_t *n;
		char namebuf[14];
		dns_fixedname_t fname;
		dns_name_t *name;

		n = isc_mem_get(mctx, sizeof(size_t));
		*n = i + 1;

		snprintf(namebuf, sizeof(namebuf), "name%08x.", i);
		build_name_from_str(namebuf, &fname);
		name = dns_fixedname_name(&fname);

		result = dns_rbt_addname(mytree, name, n);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	}

	/* 1 (root . node) + (1 << log_num_nodes) */
	ATF_CHECK_EQ(1U + (1U << log_num_nodes), dns_rbt_nodecount(mytree));

	/* The distance from each node to its sub-tree root must be less
	 * than 2 * log(n).
	 */
	ATF_CHECK((2U * log_num_nodes) >= dns__rbt_getheight(mytree));

	/* Also check RB tree properties */
	tree_ok = dns__rbt_checkproperties(mytree);
	ATF_CHECK_EQ(tree_ok, ISC_TRUE);

	dns_rbt_destroy(&mytree);

	dns_test_end();
}
コード例 #22
0
ATF_TC_BODY(deserialize_corrupt, tc) {
	dns_rbt_t *rbt = NULL;
	isc_result_t result;
	FILE *rbtfile = NULL;
	off_t offset;
	int fd;
	off_t filesize = 0;
	char *base, *p, *q;
	isc_uint32_t r;
	int i;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* Set up map file */
	result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	add_test_data(mctx, rbt);
	rbtfile = fopen("./zone.bin", "w+b");
	ATF_REQUIRE(rbtfile != NULL);
	result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
					&offset);
	ATF_REQUIRE(result == ISC_R_SUCCESS);
	dns_rbt_destroy(&rbt);

	/* Read back with random fuzzing */
	for (i = 0; i < 256; i++) {
		dns_rbt_t *rbt_deserialized = NULL;

		fd = open("zone.bin", O_RDWR);
		isc_file_getsizefd(fd, &filesize);
		base = mmap(NULL, filesize,
			    PROT_READ|PROT_WRITE,
			    MAP_FILE|MAP_PRIVATE, fd, 0);
		ATF_REQUIRE(base != NULL && base != MAP_FAILED);
		close(fd);

		/* Randomly fuzz a portion of the memory */
		isc_random_get(&r);
		p = base + (r % filesize);
		q = base + filesize;
		isc_random_get(&r);
		q -= (r % (q - p));
		while (p++ < q) {
			isc_random_get(&r);
			*p = r & 0xff;
		}

		result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,
						  delete_data, NULL,
						  fix_data, NULL,
						  NULL, &rbt_deserialized);
		printf("%d: %s\n", i, isc_result_totext(result));

		/* Test to make sure we have a valid tree */
		ATF_REQUIRE(result == ISC_R_SUCCESS ||
			    result == ISC_R_INVALIDFILE);
		if (result != ISC_R_SUCCESS)
			ATF_REQUIRE(rbt_deserialized == NULL);

		if (rbt_deserialized != NULL)
			dns_rbt_destroy(&rbt_deserialized);

		munmap(base, filesize);
	}

	unlink("zone.bin");
	dns_test_end();
}
コード例 #23
0
ATF_TC_BODY(serialize, tc) {
	dns_rbt_t *rbt = NULL;
	isc_result_t result;
	FILE *rbtfile = NULL;
	dns_rbt_t *rbt_deserialized = NULL;
	off_t offset;
	int fd;
	off_t filesize = 0;
	char *base;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_CHECK_STREQ(dns_result_totext(result), "success");
	result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
	ATF_CHECK_STREQ(dns_result_totext(result), "success");

	add_test_data(mctx, rbt);

	dns_rbt_printtext(rbt, data_printer, stdout);

	/*
	 * Serialize the tree.
	 */
	printf("serialization begins.\n");
	rbtfile = fopen("./zone.bin", "w+b");
	ATF_REQUIRE(rbtfile != NULL);
	result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
					&offset);
	ATF_REQUIRE(result == ISC_R_SUCCESS);
	dns_rbt_destroy(&rbt);

	/*
	 * Deserialize the tree
	 */
	printf("deserialization begins.\n");

	/*
	 * Map in the whole file in one go
	 */
	fd = open("zone.bin", O_RDWR);
	isc_file_getsizefd(fd, &filesize);
	base = mmap(NULL, filesize,
		    PROT_READ|PROT_WRITE,
		    MAP_FILE|MAP_PRIVATE, fd, 0);
	ATF_REQUIRE(base != NULL && base != MAP_FAILED);
	close(fd);

	result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,
					  delete_data, NULL, fix_data, NULL,
					  NULL, &rbt_deserialized);

	/* Test to make sure we have a valid tree */
	ATF_REQUIRE(result == ISC_R_SUCCESS);
	if (rbt_deserialized == NULL)
		atf_tc_fail("deserialized rbt is null!"); /* Abort execution. */

	check_test_data(rbt_deserialized);

	dns_rbt_printtext(rbt_deserialized, data_printer, stdout);

	dns_rbt_destroy(&rbt_deserialized);
	munmap(base, filesize);
	unlink("zone.bin");
	dns_test_end();
}
コード例 #24
0
ファイル: t_rbt.c プロジェクト: pombredanne/NetBSD
static int
t_dns_rbtnodechain_init(char *dbfile, char *findname,
			char *nextname, char *nextorigin,
			char *prevname, char *prevorigin,
			char *firstname, char *firstorigin,
			char *lastname, char *lastorigin)
{
	int			result;
	int			len;
	int			nfails;
	dns_rbt_t		*rbt;
	dns_rbtnode_t		*node;
	dns_rbtnodechain_t	chain;
	isc_mem_t		*mctx;
	isc_entropy_t		*ectx;
	isc_result_t		isc_result;
	isc_result_t		dns_result;
	dns_fixedname_t		dns_findname;
	dns_fixedname_t		dns_foundname;
	dns_fixedname_t		dns_firstname;
	dns_fixedname_t		dns_lastname;
	dns_fixedname_t		dns_prevname;
	dns_fixedname_t		dns_nextname;
	dns_fixedname_t		dns_origin;
	isc_buffer_t		isc_buffer;

	result = T_UNRESOLVED;

	nfails = 0;
	mctx = NULL;
	ectx = NULL;

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(result);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_rbtnodechain_init(&chain, mctx);

	rbt = NULL;
	if (rbt_init(dbfile, &rbt, mctx)) {
		t_info("rbt_init %s failed\n", dbfile);
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	len = strlen(findname);
	isc_buffer_init(&isc_buffer, findname, len);
	isc_buffer_add(&isc_buffer, len);

	dns_fixedname_init(&dns_foundname);
	dns_fixedname_init(&dns_findname);
	dns_fixedname_init(&dns_firstname);
	dns_fixedname_init(&dns_origin);
	dns_fixedname_init(&dns_lastname);
	dns_fixedname_init(&dns_prevname);
	dns_fixedname_init(&dns_nextname);

	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
					&isc_buffer, NULL, 0, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_name_fromtext failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Set the starting node.
	 */
	node = NULL;
	dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname),
				      dns_fixedname_name(&dns_foundname),
				      &node, &chain, DNS_RBTFIND_EMPTYDATA,
				      NULL, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_rbt_findnode failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Check next.
	 */
	t_info("checking for next name of %s and new origin of %s\n",
	       nextname, nextorigin);
	dns_result = dns_rbtnodechain_next(&chain,
					   dns_fixedname_name(&dns_nextname),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}

	nfails += t_namechk(dns_result, &dns_nextname, nextname, &dns_origin,
			    nextorigin, DNS_R_NEWORIGIN);

	/*
	 * Set the starting node again.
	 */
	node = NULL;
	dns_fixedname_init(&dns_foundname);
	dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname),
				      dns_fixedname_name(&dns_foundname),
				      &node, &chain, DNS_RBTFIND_EMPTYDATA,
				      NULL, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("\tdns_rbt_findnode failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Check previous.
	 */
	t_info("checking for previous name of %s and new origin of %s\n",
	       prevname, prevorigin);
	dns_fixedname_init(&dns_origin);
	dns_result = dns_rbtnodechain_prev(&chain,
					   dns_fixedname_name(&dns_prevname),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_prevname, prevname, &dns_origin,
			    prevorigin, DNS_R_NEWORIGIN);

	/*
	 * Check first.
	 */
	t_info("checking for first name of %s and new origin of %s\n",
	       firstname, firstorigin);
	dns_result = dns_rbtnodechain_first(&chain, rbt,
					    dns_fixedname_name(&dns_firstname),
					    dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_first unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_firstname, firstname,
			    &dns_origin, firstorigin, DNS_R_NEWORIGIN);

	/*
	 * Check last.
	 */
	t_info("checking for last name of %s\n", lastname);
	dns_result = dns_rbtnodechain_last(&chain, rbt,
					   dns_fixedname_name(&dns_lastname),
					   dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_lastname, lastname, &dns_origin,
			    lastorigin, DNS_R_NEWORIGIN);

	/*
	 * Check node ordering.
	 */
	t_info("checking node ordering\n");
	nfails += t9_walkchain(&chain, rbt);

	if (nfails)
		result = T_FAIL;
	else
		result = T_PASS;

	dns_rbtnodechain_invalidate(&chain);
	dns_rbt_destroy(&rbt);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);

	return(result);
}
コード例 #25
0
ファイル: tsig.c プロジェクト: execunix/vinos
static void
destroyring(dns_tsig_keyring_t *ring) {
	dns_rbt_destroy(&ring->keys);
	isc_rwlock_destroy(&ring->lock);
	isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t));
}
コード例 #26
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
ATF_TC_BODY(rbt_remove, tc) {
	/*
	 * This testcase checks that after node removal, the
	 * binary-search tree is valid and all nodes that are supposed
	 * to exist are present in the correct order. It mainly tests
	 * DomainTree as a BST, and not particularly as a red-black
	 * tree. This test checks node deletion when upper nodes have
	 * data.
	 */
	isc_result_t result;
	size_t j;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/*
	 * Delete single nodes and check if the rest of the nodes exist.
	 */
	for (j = 0; j < ordered_names_count; j++) {
		dns_rbt_t *mytree = NULL;
		dns_rbtnode_t *node;
		size_t i;
		size_t *n;
		isc_boolean_t tree_ok;
		dns_rbtnodechain_t chain;
		size_t start_node;

		/* Create a tree. */
		result = dns_rbt_create(mctx, delete_data, NULL, &mytree);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

		/* Insert test data into the tree. */
		for (i = 0; i < domain_names_count; i++) {
			node = NULL;
			result = insert_helper(mytree, domain_names[i], &node);
			ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
		}

		/* Check that all names exist in order. */
		for (i = 0; i < ordered_names_count; i++) {
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[i], &fname);

			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, NULL,
						  DNS_RBTFIND_EMPTYDATA,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);

			/* Add node data */
			ATF_REQUIRE(node != NULL);
			ATF_REQUIRE_EQ(node->data, NULL);

			n = isc_mem_get(mctx, sizeof(size_t));
			*n = i;

			node->data = n;
		}

		/* Now, delete the j'th node from the tree. */
		{
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[j], &fname);

			name = dns_fixedname_name(&fname);

			result = dns_rbt_deletename(mytree, name, ISC_FALSE);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);
		}

		/* Check RB tree properties. */
		tree_ok = dns__rbt_checkproperties(mytree);
		ATF_CHECK_EQ(tree_ok, ISC_TRUE);

		dns_rbtnodechain_init(&chain, mctx);

		/* Now, walk through nodes in order. */
		if (j == 0) {
			/*
			 * Node for ordered_names[0] was already deleted
			 * above. We start from node 1.
			 */
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[0], &fname);
			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, NULL,
						  0,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_NOTFOUND);

			build_name_from_str(ordered_names[1], &fname);
			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, &chain,
						  0,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);
			start_node = 1;
		} else {
			/* Start from node 0. */
			dns_fixedname_t fname;
			dns_name_t *name;

			build_name_from_str(ordered_names[0], &fname);
			name = dns_fixedname_name(&fname);
			node = NULL;
			result = dns_rbt_findnode(mytree, name, NULL,
						  &node, &chain,
						  0,
						  NULL, NULL);
			ATF_CHECK_EQ(result, ISC_R_SUCCESS);
			start_node = 0;
		}

		/*
		 * node and chain have been set by the code above at
		 * this point.
		 */
		for (i = start_node; i < ordered_names_count; i++) {
			dns_fixedname_t fname_j, fname_i;
			dns_name_t *name_j, *name_i;

			build_name_from_str(ordered_names[j], &fname_j);
			name_j = dns_fixedname_name(&fname_j);
			build_name_from_str(ordered_names[i], &fname_i);
			name_i = dns_fixedname_name(&fname_i);

			if (dns_name_equal(name_i, name_j)) {
				/*
				 * This may be true for the last node if
				 * we seek ahead in the loop using
				 * dns_rbtnodechain_next() below.
				 */
				if (node == NULL) {
					break;
				}

				/* All ordered nodes have data
				 * initially. If any node is empty, it
				 * means it was removed, but an empty
				 * node exists because it is a
				 * super-domain. Just skip it.
				 */
				if (node->data == NULL) {
					result = dns_rbtnodechain_next(&chain,
								       NULL,
								       NULL);
					if (result == ISC_R_NOMORE) {
						node = NULL;
					} else {
						dns_rbtnodechain_current(&chain,
									 NULL,
									 NULL,
									 &node);
					}
				}
				continue;
			}

			ATF_REQUIRE(node != NULL);

			n = (size_t *) node->data;
			if (n != NULL) {
				/* printf("n=%zu, i=%zu\n", *n, i); */
				ATF_CHECK_EQ(*n, i);
			}

			result = dns_rbtnodechain_next(&chain, NULL, NULL);
			if (result == ISC_R_NOMORE) {
				node = NULL;
			} else {
				dns_rbtnodechain_current(&chain, NULL, NULL,
							 &node);
			}
		}

		/* We should have reached the end of the tree. */
		ATF_REQUIRE_EQ(node, NULL);

		dns_rbt_destroy(&mytree);
	}

	dns_test_end();
}