コード例 #1
0
ファイル: t_rbt.c プロジェクト: pombredanne/NetBSD
/*
 * Adapted from the original rbt_test.c.
 */
static int
t1_add(char *name, dns_rbt_t *rbt, isc_mem_t *mctx, isc_result_t *dns_result) {
	int		nprobs;
	dns_name_t	*dns_name;

	nprobs = 0;
	if (name && dns_result) {
		if (create_name(name, mctx, &dns_name) == 0) {
			if (T_debug)
				t_info("dns_rbt_addname succeeded\n");
			*dns_result = dns_rbt_addname(rbt, dns_name, dns_name);
			if (*dns_result != ISC_R_SUCCESS) {
				delete_name(dns_name, mctx);
				t_info("dns_rbt_addname failed %s\n",
				       dns_result_totext(*dns_result));
				++nprobs;
			}
		} else {
			++nprobs;
		}
	} else {
		++nprobs;
	}
	return(nprobs);
}
コード例 #2
0
ファイル: tsig.c プロジェクト: execunix/vinos
/*
 * A supplemental routine just to add a key to ring.  Note that reference
 * counter should be counted separately because we may be adding the key
 * as part of creation of the key, in which case the reference counter was
 * already initialized.  Also note we don't need RWLOCK for the reference
 * counter: it's protected by a separate lock.
 */
static isc_result_t
keyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
	    dns_tsigkey_t *tkey)
{
	isc_result_t result;

	RWLOCK(&ring->lock, isc_rwlocktype_write);
	ring->writecount++;

	/*
	 * Do on the fly cleaning.  Find some nodes we might not
	 * want around any more.
	 */
	if (ring->writecount > 10) {
		cleanup_ring(ring);
		ring->writecount = 0;
	}

	result = dns_rbt_addname(ring->keys, name, tkey);
	if (result == ISC_R_SUCCESS && tkey->generated) {
		/*
		 * Add the new key to the LRU list and remove the least
		 * recently used key if there are too many keys on the list.
		 */
		ISC_LIST_APPEND(ring->lru, tkey, link);
		if (ring->generated++ > ring->maxgenerated)
			remove_fromring(ISC_LIST_HEAD(ring->lru));
	}
	RWUNLOCK(&ring->lock, isc_rwlocktype_write);

	return (result);
}
コード例 #3
0
/*
 * Load test data into the RBT.
 */
static void
add_test_data(isc_mem_t *mymctx, dns_rbt_t *rbt) {
	char buffer[1024];
	isc_buffer_t b;
	isc_result_t result;
	dns_fixedname_t fname;
	dns_name_t *name;
	dns_compress_t cctx;
	rbt_testdata_t *testdatap = testdata;

	dns_compress_init(&cctx, -1, mymctx);

	while (testdatap->name != NULL && testdatap->data.data != NULL) {
		memmove(buffer, testdatap->name, testdatap->name_len);

		isc_buffer_init(&b, buffer, testdatap->name_len);
		isc_buffer_add(&b, testdatap->name_len);
		dns_fixedname_init(&fname);
		name = dns_fixedname_name(&fname);
		result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
		if (result != ISC_R_SUCCESS) {
			testdatap++;
			continue;
		}

		if (name != NULL) {
			result = dns_rbt_addname(rbt, name, &testdatap->data);
			ATF_CHECK_STREQ(dns_result_totext(result), "success");
		}
		testdatap++;
	}

	dns_compress_invalidate(&cctx);
}
コード例 #4
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
static test_context_t *
test_context_setup(void) {
	test_context_t *ctx;
	isc_result_t result;
	size_t i;

	ctx = isc_mem_get(mctx, sizeof(*ctx));
	ATF_REQUIRE(ctx != NULL);

	ctx->rbt = NULL;
	result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	ctx->rbt_distances = NULL;
	result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt_distances);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	for (i = 0; i < domain_names_count; i++) {
		size_t *n;
		dns_fixedname_t fname;
		dns_name_t *name;

		build_name_from_str(domain_names[i], &fname);

		name = dns_fixedname_name(&fname);

		n = isc_mem_get(mctx, sizeof(size_t));
		*n = i + 1;
		result = dns_rbt_addname(ctx->rbt, name, n);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

		n = isc_mem_get(mctx, sizeof(size_t));
		*n = node_distances[i];
		result = dns_rbt_addname(ctx->rbt_distances, name, n);
		ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	}

	return (ctx);
}
コード例 #5
0
ファイル: forward.c プロジェクト: each/bind9-collab
isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
		 isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy)
{
	isc_result_t result;
	dns_forwarders_t *forwarders;
	dns_forwarder_t *fwd;
	isc_sockaddr_t *sa;

	REQUIRE(VALID_FWDTABLE(fwdtable));

	forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t));
	if (forwarders == NULL)
		return (ISC_R_NOMEMORY);

	ISC_LIST_INIT(forwarders->fwdrs);
	for (sa = ISC_LIST_HEAD(*addrs);
	     sa != NULL;
	     sa = ISC_LIST_NEXT(sa, link))
	{
		fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
		if (fwd == NULL) {
			result = ISC_R_NOMEMORY;
			goto cleanup;
		}
		fwd->addr = *sa;
		fwd->dscp = -1;
		ISC_LINK_INIT(fwd, link);
		ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
	}
	forwarders->fwdpolicy = fwdpolicy;

	RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
	result = dns_rbt_addname(fwdtable->table, name, forwarders);
	RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);

	if (result != ISC_R_SUCCESS)
		goto cleanup;

	return (ISC_R_SUCCESS);

 cleanup:
	while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
		fwd = ISC_LIST_HEAD(forwarders->fwdrs);
		ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
		isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
	}
	isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
	return (result);
}
コード例 #6
0
ファイル: dbtable.c プロジェクト: jaredmcneill/netbsd-src
isc_result_t
dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db) {
	isc_result_t result;
	dns_db_t *dbclone;

	REQUIRE(VALID_DBTABLE(dbtable));
	REQUIRE(dns_db_class(db) == dbtable->rdclass);

	dbclone = NULL;
	dns_db_attach(db, &dbclone);

	RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write);
	result = dns_rbt_addname(dbtable->rbt, dns_db_origin(dbclone), dbclone);
	RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write);

	return (result);
}
コード例 #7
0
ファイル: rbt_test.c プロジェクト: fatman2021/netbsd-src
static void
insert_nodes(dns_rbt_t *mytree, char **names,
	     size_t *names_count, isc_uint32_t num_names)
{
	isc_uint32_t i;

	for (i = 0; i < num_names; i++) {
		size_t *n;
		char namebuf[34];

		n = isc_mem_get(mctx, sizeof(size_t));
		ATF_REQUIRE(n != NULL);

		*n = i; /* Unused value */

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

			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) {
				names[*names_count] = isc_mem_strdup(mctx,
								     namebuf);
				*names_count += 1;
				break;
			}
		}
	}
}
コード例 #8
0
ファイル: zt.c プロジェクト: SylvestreG/bitrig
isc_result_t
dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone) {
	isc_result_t result;
	dns_zone_t *dummy = NULL;
	dns_name_t *name;

	REQUIRE(VALID_ZT(zt));

	name = dns_zone_getorigin(zone);

	RWLOCK(&zt->rwlock, isc_rwlocktype_write);

	result = dns_rbt_addname(zt->table, name, zone);
	if (result == ISC_R_SUCCESS)
		dns_zone_attach(zone, &dummy);

	RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);

	return (result);
}
コード例 #9
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);
}
コード例 #10
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);
}
コード例 #11
0
ファイル: tsig.c プロジェクト: miettal/armadillo420_standard
isc_result_t
dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
			  dst_key_t *dstkey, isc_boolean_t generated,
			  dns_name_t *creator, isc_stdtime_t inception,
			  isc_stdtime_t expire, isc_mem_t *mctx,
			  dns_tsig_keyring_t *ring, dns_tsigkey_t **key)
{
	dns_tsigkey_t *tkey;
	isc_result_t ret;
	unsigned int refs = 0;

	REQUIRE(key == NULL || *key == NULL);
	REQUIRE(name != NULL);
	REQUIRE(algorithm != NULL);
	REQUIRE(mctx != NULL);

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

	dns_name_init(&tkey->name, NULL);
	ret = dns_name_dup(name, mctx, &tkey->name);
	if (ret != ISC_R_SUCCESS)
		goto cleanup_key;
	(void)dns_name_downcase(&tkey->name, &tkey->name, NULL);

	if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) {
		tkey->algorithm = DNS_TSIG_HMACMD5_NAME;
		if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) {
			ret = DNS_R_BADALG;
			goto cleanup_name;
		}
	} else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) {
		tkey->algorithm = DNS_TSIG_GSSAPI_NAME;
		if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) {
			ret = DNS_R_BADALG;
			goto cleanup_name;
		}
	} else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
		tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME;
		if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) {
			ret = DNS_R_BADALG;
			goto cleanup_name;
		}
	} else {
		if (key != NULL) {
			ret = DNS_R_BADALG;
			goto cleanup_name;
		}
		tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t));
		if (tkey->algorithm == NULL) {
			ret = ISC_R_NOMEMORY;
			goto cleanup_name;
		}
		dns_name_init(tkey->algorithm, NULL);
		ret = dns_name_dup(algorithm, mctx, tkey->algorithm);
		if (ret != ISC_R_SUCCESS)
			goto cleanup_algorithm;
		(void)dns_name_downcase(tkey->algorithm, tkey->algorithm,
					NULL);
	}

	if (creator != NULL) {
		tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t));
		if (tkey->creator == NULL) {
			ret = ISC_R_NOMEMORY;
			goto cleanup_algorithm;
		}
		dns_name_init(tkey->creator, NULL);
		ret = dns_name_dup(creator, mctx, tkey->creator);
		if (ret != ISC_R_SUCCESS) {
			isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
			goto cleanup_algorithm;
		}
	} else
		tkey->creator = NULL;

	tkey->key = dstkey;
	tkey->ring = ring;

	if (ring != NULL) {
		RWLOCK(&ring->lock, isc_rwlocktype_write);
		ret = dns_rbt_addname(ring->keys, name, tkey);
		if (ret != ISC_R_SUCCESS) {
			RWUNLOCK(&ring->lock, isc_rwlocktype_write);
			goto cleanup_algorithm;
		}
		refs++;
		RWUNLOCK(&ring->lock, isc_rwlocktype_write);
	}

	if (key != NULL)
		refs++;
	isc_refcount_init(&tkey->refs, refs);
	tkey->generated = generated;
	tkey->inception = inception;
	tkey->expire = expire;
	tkey->mctx = mctx;

	tkey->magic = TSIG_MAGIC;

	if (dstkey != NULL && dst_key_size(dstkey) < 64) {
		char namestr[DNS_NAME_FORMATSIZE];
		dns_name_format(name, namestr, sizeof(namestr));
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
			      DNS_LOGMODULE_TSIG, ISC_LOG_INFO,
			      "the key '%s' is too short to be secure",
			      namestr);
	}
	if (key != NULL)
		*key = tkey;

	return (ISC_R_SUCCESS);

 cleanup_algorithm:
	if (algname_is_allocated(tkey->algorithm)) {
		if (dns_name_dynamic(tkey->algorithm))
			dns_name_free(tkey->algorithm, mctx);
		isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t));
	}
 cleanup_name:
	dns_name_free(&tkey->name, mctx);
 cleanup_key:
	isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t));

	return (ret);
}
コード例 #12
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();
}
コード例 #13
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();
}
コード例 #14
0
ファイル: cache.c プロジェクト: mnagy/bind-dyndb-ldap
isc_result_t
cached_ldap_rdatalist_get(isc_mem_t *mctx, ldap_cache_t *cache,
			  ldap_db_t *ldap_db, dns_name_t *name,
			  dns_name_t *origin, ldapdb_rdatalist_t *rdatalist)
{
	isc_result_t result;
	ldapdb_rdatalist_t rdlist;
	cache_node_t *node = NULL;
	int in_cache = 0;
	int is_locked = 0;

	REQUIRE(cache != NULL);

	if (cache->rbt == NULL)
		return ldapdb_rdatalist_get(mctx, ldap_db, name, origin,
					    rdatalist);

	CONTROLED_LOCK(&cache->mutex);
	result = dns_rbt_findname(cache->rbt, name, 0, NULL, (void *)&node);
	if (result == ISC_R_SUCCESS) {
		isc_time_t now;

		CHECK(isc_time_now(&now));

		/* Check if the record is still valid. */
		if (isc_time_compare(&now, &node->valid_until) > 0) {
			CHECK(dns_rbt_deletename(cache->rbt, name, ISC_FALSE));
			in_cache = 0;
		} else {
			rdlist = node->rdatalist;
			in_cache = 1;
		}
	} else if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) {
		goto cleanup;
	}
	CONTROLED_UNLOCK(&cache->mutex);

	if (!in_cache) {
		INIT_LIST(rdlist);
		result = ldapdb_rdatalist_get(mctx, ldap_db, name, origin,
					      &rdlist);
		/* TODO: Cache entries that are not found. */
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		CONTROLED_LOCK(&cache->mutex);
		/* Check again to make sure. */
		node = NULL;
		result = dns_rbt_findname(cache->rbt, name, 0, NULL,
					  (void *)&node);
		if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
			node = NULL;
			CHECK(cache_node_create(cache, rdlist, &node));
			CHECK(dns_rbt_addname(cache->rbt, name, (void *)node));
		}
		CONTROLED_UNLOCK(&cache->mutex);
	}

	CHECK(ldap_rdatalist_copy(mctx, rdlist, rdatalist));

	if (EMPTY(*rdatalist))
		result = ISC_R_NOTFOUND;

cleanup:
	CONTROLED_UNLOCK(&cache->mutex);
	return result;
}