isc_result_t dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) { isc_result_t result; dns_rbtnodechain_t chain; dns_name_t foundname; dns_fixedname_t fixedorigin; dns_name_t *origin; isc_stdtime_t now; dns_rbtnode_t *node; dns_tsigkey_t *tkey; dns_tsig_keyring_t *ring; unsigned int references; REQUIRE(ringp != NULL && *ringp != NULL); ring = *ringp; *ringp = NULL; RWLOCK(&ring->lock, isc_rwlocktype_write); INSIST(ring->references > 0); ring->references--; references = ring->references; RWUNLOCK(&ring->lock, isc_rwlocktype_write); if (references != 0) return (DNS_R_CONTINUE); isc_stdtime_get(&now); dns_name_init(&foundname, NULL); dns_fixedname_init(&fixedorigin); origin = dns_fixedname_name(&fixedorigin); dns_rbtnodechain_init(&chain, ring->mctx); result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); goto destroy; } for (;;) { node = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &node); tkey = node->data; if (tkey != NULL && tkey->generated && tkey->expire >= now) dump_key(tkey, fp); result = dns_rbtnodechain_next(&chain, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; goto destroy; } } destroy: destroyring(ring); return (result); }
static void iterate(dns_rbt_t *rbt, isc_boolean_t forward) { dns_name_t foundname, *origin; dns_rbtnodechain_t chain; dns_fixedname_t fixedorigin; isc_result_t result; isc_result_t (*move)(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin); dns_rbtnodechain_init(&chain, mctx); dns_name_init(&foundname, NULL); dns_fixedname_init(&fixedorigin); origin = dns_fixedname_name(&fixedorigin); if (forward) { printf("iterating forward\n" ); move = dns_rbtnodechain_next; result = dns_rbtnodechain_first(&chain, rbt, &foundname, origin); } else { printf("iterating backward\n" ); move = dns_rbtnodechain_prev; result = dns_rbtnodechain_last(&chain, rbt, &foundname, origin); } if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) printf("start not found!\n"); else { for (;;) { if (result == DNS_R_NEWORIGIN) { printf(" new origin: "); print_name(origin); printf("\n"); } if (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) { print_name(&foundname); printf("\n"); } else { if (result != ISC_R_NOMORE) printf("UNEXEPCTED ITERATION ERROR: %s", dns_result_totext(result)); break; } result = move(&chain, &foundname, origin); } } }
/* * Find a few nodes to destroy if possible. */ static void cleanup_ring(dns_tsig_keyring_t *ring) { isc_result_t result; dns_rbtnodechain_t chain; dns_name_t foundname; dns_fixedname_t fixedorigin; dns_name_t *origin; isc_stdtime_t now; dns_rbtnode_t *node; dns_tsigkey_t *tkey; /* * Start up a new iterator each time. */ isc_stdtime_get(&now); dns_name_init(&foundname, NULL); dns_fixedname_init(&fixedorigin); origin = dns_fixedname_name(&fixedorigin); again: dns_rbtnodechain_init(&chain, ring->mctx); result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); return; } for (;;) { node = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &node); tkey = node->data; if (tkey != NULL) { if (tkey->generated && isc_refcount_current(&tkey->refs) == 1 && tkey->inception != tkey->expire && tkey->expire < now) { tsig_log(tkey, 2, "tsig expire: deleting"); /* delete the key */ dns_rbtnodechain_invalidate(&chain); remove_fromring(tkey); goto again; } } result = dns_rbtnodechain_next(&chain, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); return; } } }
isc_result_t dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub, isc_result_t (*action)(dns_zone_t *, void *), void *uap) { dns_rbtnode_t *node; dns_rbtnodechain_t chain; isc_result_t result, tresult = ISC_R_SUCCESS; dns_zone_t *zone; REQUIRE(VALID_ZT(zt)); REQUIRE(action != NULL); dns_rbtnodechain_init(&chain, zt->mctx); result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL); if (result == ISC_R_NOTFOUND) { /* * The tree is empty. */ tresult = result; result = ISC_R_NOMORE; } while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { result = dns_rbtnodechain_current(&chain, NULL, NULL, &node); if (result == ISC_R_SUCCESS) { zone = node->data; if (zone != NULL) result = (action)(zone, uap); if (result != ISC_R_SUCCESS && stop) { tresult = result; goto cleanup; /* don't break */ } else if (result != ISC_R_SUCCESS && tresult == ISC_R_SUCCESS) tresult = result; } result = dns_rbtnodechain_next(&chain, NULL, NULL); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: dns_rbtnodechain_invalidate(&chain); if (sub != NULL) *sub = tresult; return (result); }
ATF_TC_BODY(rbtnode_get_distance, tc) { isc_result_t result; test_context_t *ctx; const char *name_str = "a"; dns_fixedname_t fname; dns_name_t *name; dns_rbtnode_t *node = NULL; dns_rbtnodechain_t chain; UNUSED(tc); isc_mem_debugging = ISC_MEM_DEBUGRECORD; result = dns_test_begin(NULL, ISC_TRUE); ATF_CHECK_EQ(result, ISC_R_SUCCESS); ctx = test_context_setup(); build_name_from_str(name_str, &fname); name = dns_fixedname_name(&fname); dns_rbtnodechain_init(&chain, mctx); result = dns_rbt_findnode(ctx->rbt_distances, name, NULL, &node, &chain, 0, NULL, NULL); ATF_CHECK_EQ(result, ISC_R_SUCCESS); while (node != NULL) { const size_t *distance = (const size_t *) node->data; if (distance != NULL) ATF_CHECK_EQ(*distance, dns__rbtnode_getdistance(node)); result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result == ISC_R_NOMORE) break; dns_rbtnodechain_current(&chain, NULL, NULL, &node); } ATF_CHECK_EQ(result, ISC_R_NOMORE); dns_rbtnodechain_invalidate(&chain); test_context_teardown(ctx); dns_test_end(); }
isc_result_t dns_keytable_totext(dns_keytable_t *keytable, isc_buffer_t **text) { isc_result_t result; dns_keynode_t *knode; dns_rbtnode_t *node; dns_rbtnodechain_t chain; REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(text != NULL && *text != NULL); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); dns_rbtnodechain_init(&chain, keytable->mctx); result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; goto cleanup; } for (;;) { char pbuf[DST_KEY_FORMATSIZE]; dns_rbtnodechain_current(&chain, NULL, NULL, &node); for (knode = node->data; knode != NULL; knode = knode->next) { char obuf[DNS_NAME_FORMATSIZE + 200]; if (knode->key == NULL) continue; dst_key_format(knode->key, pbuf, sizeof(pbuf)); snprintf(obuf, sizeof(obuf), "%s ; %s\n", pbuf, knode->managed ? "managed" : "trusted"); result = putstr(text, obuf); if (result != ISC_R_SUCCESS) break; } result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; break; } } cleanup: dns_rbtnodechain_invalidate(&chain); RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); }
isc_result_t dns_keytable_dump(dns_keytable_t *keytable, FILE *fp) { isc_result_t result; dns_keynode_t *knode; dns_rbtnode_t *node; dns_rbtnodechain_t chain; REQUIRE(VALID_KEYTABLE(keytable)); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); dns_rbtnodechain_init(&chain, keytable->mctx); result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) goto cleanup; for (;;) { char pbuf[DST_KEY_FORMATSIZE]; dns_rbtnodechain_current(&chain, NULL, NULL, &node); for (knode = node->data; knode != NULL; knode = knode->next) { dst_key_format(knode->key, pbuf, sizeof(pbuf)); fprintf(fp, "%s ; %s\n", pbuf, knode->managed ? "managed" : "trusted"); } result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; break; } } cleanup: dns_rbtnodechain_invalidate(&chain); RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); }
isc_result_t dns_keytable_forall(dns_keytable_t *keytable, void (*func)(dns_keytable_t *, dns_keynode_t *, void *), void *arg) { isc_result_t result; dns_rbtnode_t *node; dns_rbtnodechain_t chain; REQUIRE(VALID_KEYTABLE(keytable)); RWLOCK(&keytable->rwlock, isc_rwlocktype_read); dns_rbtnodechain_init(&chain, keytable->mctx); result = dns_rbtnodechain_first(&chain, keytable->table, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; goto cleanup; } for (;;) { dns_rbtnodechain_current(&chain, NULL, NULL, &node); if (node->data != NULL) (*func)(keytable, node->data, arg); result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; break; } } cleanup: dns_rbtnodechain_invalidate(&chain); RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); }
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); }
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); }
static void detail(dns_rbt_t *rbt, dns_name_t *name) { dns_name_t *foundname, *origin, *fullname; dns_fixedname_t fixedfoundname, fixedorigin, fixedfullname; dns_rbtnode_t *node1, *node2; dns_rbtnodechain_t chain; isc_result_t result; isc_boolean_t nodes_should_match = ISC_FALSE; dns_rbtnodechain_init(&chain, mctx); dns_fixedname_init(&fixedorigin); dns_fixedname_init(&fixedfullname); dns_fixedname_init(&fixedfoundname); origin = dns_fixedname_name(&fixedorigin); fullname = dns_fixedname_name(&fixedfullname); foundname = dns_fixedname_name(&fixedfoundname); node1 = node2 = NULL; printf("checking chain information for "); print_name(name); printf("\n"); result = dns_rbt_findnode(rbt, name, foundname, &node1, &chain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); switch (result) { case ISC_R_SUCCESS: printf(" found exact."); nodes_should_match = ISC_TRUE; break; case DNS_R_PARTIALMATCH: printf(" found parent."); break; case ISC_R_NOTFOUND: printf(" name not found."); break; default: printf(" unexpected result: %s\n", dns_result_totext(result)); return; } if (node1 != NULL && node1->data != NULL) { printf(" data at node: "); print_name(node1->data); } else printf(" no data at node."); if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { printf("\n name from dns_rbt_findnode: "); print_name(foundname); } result = dns_rbtnodechain_current(&chain, foundname, origin, &node2); if (result == ISC_R_SUCCESS) { printf("\n name from dns_rbtnodechain_current: "); result = dns_name_concatenate(foundname, origin, fullname, NULL); if (result == ISC_R_SUCCESS) print_name(fullname); else printf("%s\n", dns_result_totext(result)); printf("\n (foundname = "); print_name(foundname); printf(", origin = "); print_name(origin); printf(")\n"); if (nodes_should_match && node1 != node2) printf(" nodes returned from each function " "DO NOT match!\n"); } else printf("\n result from dns_rbtnodechain_current: %s\n", dns_result_totext(result)); printf(" level_matches = %d, level_count = %d\n", chain.level_matches, chain.level_count); }
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(); }