diff --git a/bin/tests/compress_test.c b/bin/tests/compress_test.c index c1cd21f604..d06f018bab 100644 --- a/bin/tests/compress_test.c +++ b/bin/tests/compress_test.c @@ -150,6 +150,7 @@ test(unsigned int allowed, dns_name_t *name1, dns_name_t *name2, RUNTIME_CHECK(dns_name_towire(name3, &cctx, &source) == DNS_R_SUCCESS); dns_compress_localinvalidate(&cctx); + dns_compress_rollback(&cctx, 0); /* testing only */ dns_compress_invalidate(&cctx); if (raw) { diff --git a/lib/dns/compress.c b/lib/dns/compress.c index a687031f47..4f7ed2390f 100644 --- a/lib/dns/compress.c +++ b/lib/dns/compress.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: compress.c,v 1.14 1999/04/28 03:16:50 marka Exp $ */ + /* $Id: compress.c,v 1.15 1999/05/03 03:07:16 marka Exp $ */ #include #include @@ -340,12 +340,65 @@ dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix, } void -dns_compress_backout(dns_compress_t *cctx, isc_uint16_t offset) { +dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) { + dns_rbtnode_t *node; + dns_fixedname_t foundfixed; + dns_fixedname_t fullfixed; + dns_fixedname_t originfixed; + dns_name_t *foundname; + dns_name_t *fullname; + dns_name_t *origin; + dns_rbtnodechain_t chain; + dns_result_t result; + REQUIRE(VALID_CCTX(cctx)); - /* XXX MPA need tree walking code */ - /* Remove all nodes in cctx->global that have *data >= offset. */ + /* + * Initalise things. + */ + dns_fixedname_init(&foundfixed); + foundname = dns_fixedname_name(&foundfixed); + dns_fixedname_init(&fullfixed); + fullname = dns_fixedname_name(&fullfixed); + dns_fixedname_init(&originfixed); + origin = dns_fixedname_name(&originfixed); + dns_rbtnodechain_init(&chain, cctx->mctx); + again: + result = dns_rbtnodechain_first(&chain, cctx->global, foundname, + origin); + + while (result == DNS_R_NEWORIGIN || result == DNS_R_SUCCESS) { + result = dns_rbtnodechain_current(&chain, foundname, + origin, &node); + + if (result != DNS_R_SUCCESS) + break; + + if (node->data != NULL && + (*(isc_uint16_t*)node->data >= offset)) { + result = dns_name_concatenate(foundname, + dns_name_isabsolute(foundname) ? + NULL : origin, + fullname, NULL); + + if (result != DNS_R_SUCCESS) + break; + + result = dns_rbt_deletename(cctx->global, fullname, + ISC_FALSE); + if (result != DNS_R_SUCCESS) + break; + /* + * If the delete is successful the chain is broken. + */ + dns_rbtnodechain_reset(&chain); + goto again; + } + + result = dns_rbtnodechain_next(&chain, foundname, origin); + } + dns_rbtnodechain_invalidate(&chain); } /*** @@ -375,7 +428,7 @@ dns_decompress_localinit(dns_decompress_t *dctx, dns_name_t *name, REQUIRE(dns_name_isabsolute(name) == ISC_TRUE); REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_BINARY); - dctx->rdata = source->current; + dctx->rdata = source->current; /* XXX layer violation */ dctx->owner_name = *name; } diff --git a/lib/dns/include/dns/compress.h b/lib/dns/include/dns/compress.h index 9ca23b1cd5..bc727d65c2 100644 --- a/lib/dns/include/dns/compress.h +++ b/lib/dns/include/dns/compress.h @@ -224,7 +224,7 @@ dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix, */ void -dns_compress_backout(dns_compress_t *cctx, isc_uint16_t offset); +dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset); /* * Remove any compression pointers from global RBT >= offset. diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 31f01b4dab..631e06e796 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: rdata.c,v 1.38 1999/03/11 00:29:10 marka Exp $ */ + /* $Id: rdata.c,v 1.39 1999/05/03 03:07:15 marka Exp $ */ #include @@ -37,6 +37,8 @@ #include #include #include +#include +#include #define RETERR(x) do { \ dns_result_t __r = (x); \ @@ -317,7 +319,7 @@ dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, } if (result != DNS_R_SUCCESS) { *target = st; - dns_compress_backout(cctx, target->used); + dns_compress_rollback(cctx, target->used); } return (result); } @@ -472,7 +474,6 @@ dns_rdata_tostruct(dns_rdata_t *rdata, void *target) { isc_boolean_t use_default = ISC_FALSE; REQUIRE(rdata != NULL); - REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY); TOSTRUCTSWITCH diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index 64e8b60ce5..9db9feb365 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -319,7 +319,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, st = *target; result = dns_name_towire(owner_name, cctx, target); if (result != DNS_R_SUCCESS) { - dns_compress_backout(cctx, st.used); + dns_compress_rollback(cctx, st.used); + *countp += count; *target = st; return (result); } @@ -329,7 +330,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, + 2; /* XXX 2 for rdata len */ isc_buffer_available(target, &r); if (r.length < headlen) { - dns_compress_backout(cctx, st.used); + dns_compress_rollback(cctx, st.used); + *countp += count; *target = st; return (DNS_R_NOSPACE); } @@ -351,14 +353,16 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, result = dns_compress_localinit(cctx, owner_name, target); if (result != DNS_R_SUCCESS) { - dns_compress_backout(cctx, st.used); + dns_compress_rollback(cctx, st.used); + *countp += count; *target = st; return (result); } result = dns_rdata_towire(&rdata, cctx, target); dns_compress_localinvalidate(cctx); if (result != DNS_R_SUCCESS) { - dns_compress_backout(cctx, st.used); + dns_compress_rollback(cctx, st.used); + *countp += count; *target = st; return (result); }