From: Evan Hunt Date: Tue, 2 Aug 2011 20:36:13 +0000 (+0000) Subject: 3140. [func] New command "rndc flushtree " clears the X-Git-Tag: v9.9.0a1~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01279934803dd45c007a58b61fe20c2852135b52;p=thirdparty%2Fbind9.git 3140. [func] New command "rndc flushtree " clears the specified name from the server cache along with all names under it. [RT #19970] --- diff --git a/CHANGES b/CHANGES index 17a7d17ce3a..7260e9581aa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3140. [func] New command "rndc flushtree " clears the + specified name from the server cache along with + all names under it. [RT #19970] + 3139. [test] Added tests from RFC 6234, RFC 2202, and RFC 1321 for the hashing algorithms (md5, sha1 - sha512, and their hmac counterparts). [RT #25067] diff --git a/bin/named/control.c b/bin/named/control.c index e5295ca7227..3e5de3e7b46 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: control.c,v 1.43 2011/03/21 23:47:21 tbox Exp $ */ +/* $Id: control.c,v 1.44 2011/08/02 20:36:11 each Exp $ */ /*! \file */ @@ -169,7 +169,9 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { } else if (command_compare(command, NS_COMMAND_FLUSH)) { result = ns_server_flushcache(ns_g_server, command); } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) { - result = ns_server_flushname(ns_g_server, command); + result = ns_server_flushnode(ns_g_server, command, ISC_FALSE); + } else if (command_compare(command, NS_COMMAND_FLUSHTREE)) { + result = ns_server_flushnode(ns_g_server, command, ISC_TRUE); } else if (command_compare(command, NS_COMMAND_STATUS)) { result = ns_server_status(ns_g_server, text); } else if (command_compare(command, NS_COMMAND_TSIGLIST)) { diff --git a/bin/named/include/named/control.h b/bin/named/include/named/control.h index da680e1dcbc..3d451e95f77 100644 --- a/bin/named/include/named/control.h +++ b/bin/named/include/named/control.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: control.h,v 1.33 2011/03/21 23:47:21 tbox Exp $ */ +/* $Id: control.h,v 1.34 2011/08/02 20:36:12 each Exp $ */ #ifndef NAMED_CONTROL_H #define NAMED_CONTROL_H 1 @@ -47,6 +47,7 @@ #define NS_COMMAND_NOTRACE "notrace" #define NS_COMMAND_FLUSH "flush" #define NS_COMMAND_FLUSHNAME "flushname" +#define NS_COMMAND_FLUSHTREE "flushtree" #define NS_COMMAND_STATUS "status" #define NS_COMMAND_TSIGLIST "tsig-list" #define NS_COMMAND_TSIGDELETE "tsig-delete" diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 1346c7b9c58..92e6d22422d 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.h,v 1.112 2011/03/21 23:47:21 tbox Exp $ */ +/* $Id: server.h,v 1.113 2011/08/02 20:36:12 each Exp $ */ #ifndef NAMED_SERVER_H #define NAMED_SERVER_H 1 @@ -264,10 +264,12 @@ isc_result_t ns_server_flushcache(ns_server_t *server, char *args); /*% - * Flush a particular name from the server's cache(s) + * Flush a particular name from the server's cache. If 'tree' is false, + * also flush the name from the ADB and badcache. If 'tree' is true, also + * flush all the names under the specified name. */ isc_result_t -ns_server_flushname(ns_server_t *server, char *args); +ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree); /*% * Report the server's status. diff --git a/bin/named/server.c b/bin/named/server.c index c9a9ac6635a..bef3f8c95c0 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.615 2011/07/28 03:18:17 each Exp $ */ +/* $Id: server.c,v 1.616 2011/08/02 20:36:11 each Exp $ */ /*! \file */ @@ -6751,7 +6751,7 @@ ns_server_flushcache(ns_server_t *server, char *args) { } isc_result_t -ns_server_flushname(ns_server_t *server, char *args) { +ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree) { char *ptr, *target, *viewname; dns_view_t *view; isc_boolean_t flushed; @@ -6798,13 +6798,15 @@ ns_server_flushname(ns_server_t *server, char *args) { * if some of the views share a single cache. But since the * operation is lightweight we prefer simplicity here. */ - result = dns_view_flushname(view, name); + result = dns_view_flushnode(view, name, tree); if (result != ISC_R_SUCCESS) { flushed = ISC_FALSE; isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing name '%s' in cache view '%s' " - "failed: %s", target, view->name, + "flushing %s '%s' in cache view '%s' " + "failed: %s", + tree ? "tree" : "name", + target, view->name, isc_result_totext(result)); } } @@ -6812,21 +6814,26 @@ ns_server_flushname(ns_server_t *server, char *args) { if (viewname != NULL) isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing name '%s' in cache view '%s' " - "succeeded", target, viewname); + "flushing %s '%s' in cache view '%s' " + "succeeded", + tree ? "tree" : "name", + target, viewname); else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "flushing name '%s' in all cache views " - "succeeded", target); + "flushing %s '%s' in all cache views " + "succeeded", + tree ? "tree" : "name", + target); result = ISC_R_SUCCESS; } else { if (!found) isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "flushing name '%s' in cache view '%s' " - "failed: view not found", target, - viewname); + "flushing %s '%s' in cache view '%s' " + "failed: view not found", + tree ? "tree" : "name", + target, viewname); result = ISC_R_FAILURE; } isc_task_endexclusive(server->task); diff --git a/bin/tests/system/cacheclean/ns1/named.conf b/bin/tests/system/cacheclean/ns1/named.conf index 9f341486b04..9f3e37e69c8 100644 --- a/bin/tests/system/cacheclean/ns1/named.conf +++ b/bin/tests/system/cacheclean/ns1/named.conf @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.9 2007/06/19 23:47:01 tbox Exp $ */ +/* $Id: named.conf,v 1.10 2011/08/02 20:36:12 each Exp $ */ controls { /* empty */ }; @@ -36,3 +36,8 @@ zone "." { type master; file "example.db"; }; + +zone "flushtest.example" { + type master; + file "flushtest.db"; +}; diff --git a/bin/tests/system/cacheclean/ns2/named.conf b/bin/tests/system/cacheclean/ns2/named.conf index c0d9f4417f7..381ece7b54b 100644 --- a/bin/tests/system/cacheclean/ns2/named.conf +++ b/bin/tests/system/cacheclean/ns2/named.conf @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.8 2007/06/19 23:47:01 tbox Exp $ */ +/* $Id: named.conf,v 1.9 2011/08/02 20:36:12 each Exp $ */ controls { /* empty */ }; @@ -32,7 +32,21 @@ options { disable-empty-zone 127.IN-ADDR.ARPA; }; +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-md5; +}; + +controls { + inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; +}; + zone "." { type hint; file "../../common/root.hint"; }; + +zone "flushtest.example" { + type forward; + forwarders { 10.53.0.1; }; +}; diff --git a/bin/tests/system/cacheclean/tests.sh b/bin/tests/system/cacheclean/tests.sh index 7e1ba798969..61310a42271 100644 --- a/bin/tests/system/cacheclean/tests.sh +++ b/bin/tests/system/cacheclean/tests.sh @@ -15,18 +15,153 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.5 2007/06/19 23:47:00 tbox Exp $ +# $Id: tests.sh,v 1.6 2011/08/02 20:36:12 each Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh status=0 -$DIG +nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm +nostat \ - -f dig.batch -p 5300 @10.53.0.2 > dig.out.ns2 || status=1 +RNDCOPTS="-c ../common/rndc.conf -s 10.53.0.2 -p 9953" +DIGOPTS="+nosea +nocomm +nocmd +noquest +noadd +noauth +nocomm \ + +nostat @10.53.0.2 -p 5300" + +# fill the cache with nodes from flushtest.example zone +load_cache () { + # empty all existing cache data + $RNDC $RNDCOPTS flush + + # load the positive cache entries + $DIG $DIGOPTS txt top1.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second1.top1.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt third1.second1.top1.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt third2.second1.top1.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second2.top1.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second3.top1.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second1.top2.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second2.top2.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second3.top2.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt top3.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second1.top3.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt third1.second1.top3.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt third2.second1.top3.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt third1.second2.top3.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt third2.second2.top3.flushtest.example > /dev/null 2>1 + $DIG $DIGOPTS txt second3.top3.flushtest.example > /dev/null 2>1 + + # load the negative cache entries + # nxrrset: + $DIG $DIGOPTS a third1.second1.top1.flushtest.example > /dev/null + # nxdomain: + $DIG $DIGOPTS txt top4.flushtest.example > /dev/null + # empty nonterminal: + $DIG $DIGOPTS txt second2.top3.flushtest.example > /dev/null + + # sleep one second ensure the TTLs will be lower on cached data + sleep 1 +} + +dump_cache () { + rm -f ns2/named_dump.db + $RNDC $RNDCOPTS dumpdb -cache + sleep 1 +} + +clear_cache () { + $RNDC $RNDCOPTS flush +} + +in_cache () { + ttl=`$DIG $DIGOPTS "$@" | awk '{print $2}'` + [ -z "$ttl" ] && { + ttl=`$DIG $DIGOPTS +noanswer +auth "$@" | awk '{print $2}'` + [ "$ttl" -eq 3600 ] && return 1 + return 0 + } + [ "$ttl" -eq 3600 ] && return 1 + return 0 +} + +echo "I:check correctness of routine cache cleaning" +$DIG $DIGOPTS -f dig.batch > dig.out.ns2 || status=1 grep ";" dig.out.ns2 $PERL ../digcomp.pl dig.out.ns2 knowngood.dig.out || status=1 +echo "I:reset and check that records are correctly cached initially" +ret=0 +load_cache +dump_cache +nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l` +[ $nrecords -eq 20 ] || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:check flushing of the full cache" +ret=0 +clear_cache +dump_cache +nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l` +[ $nrecords -eq 0 ] || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:check flushing of individual nodes" +ret=0 +clear_cache +load_cache +# interior node +in_cache txt top1.flushtest.example || ret=1 +$RNDC $RNDCOPTS flushname top1.flushtest.example +in_cache txt top1.flushtest.example && ret=1 + +# leaf node, under the interior node (should still exist) +in_cache txt third2.second1.top1.flushtest.example || ret=1 +$RNDC $RNDCOPTS flushname third2.second1.top1.flushtest.example +in_cache txt third2.second1.top1.flushtest.example && ret=1 + +# another leaf node, with both positive and negative cache entries +in_cache a third1.second1.top1.flushtest.example || ret=1 +in_cache txt third1.second1.top1.flushtest.example || ret=1 +$RNDC $RNDCOPTS flushname third1.second1.top1.flushtest.example +in_cache a third1.second1.top1.flushtest.example && ret=1 +in_cache txt third1.second1.top1.flushtest.example && ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:check flushing of namespaces" +ret=0 +clear_cache +load_cache +# flushing leaf node should leave the interior node: +in_cache txt third1.second1.top1.flushtest.example || ret=1 +in_cache txt top1.flushtest.example || ret=1 +$RNDC $RNDCOPTS flushtree third1.second1.top1.flushtest.example +in_cache txt third1.second1.top1.flushtest.example && ret=1 +in_cache txt top1.flushtest.example || ret=1 +in_cache txt second1.top1.flushtest.example || ret=1 +in_cache txt third2.second1.top1.flushtest.example || ret=1 +$RNDC $RNDCOPTS flushtree second1.top1.flushtest.example +in_cache txt top1.flushtest.example || ret=1 +in_cache txt second1.top1.flushtest.example && ret=1 +in_cache txt third2.second1.top1.flushtest.example && ret=1 + +# flushing from an empty node should still remove all its children +in_cache txt second1.top2.flushtest.example || ret=1 +$RNDC $RNDCOPTS flushtree top2.flushtest.example +in_cache txt second1.top2.flushtest.example && ret=1 +in_cache txt second2.top2.flushtest.example && ret=1 +in_cache txt second3.top2.flushtest.example && ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:check the number of cached records remaining" +ret=0 +dump_cache +nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l` +[ $nrecords -eq 19 ] || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 59b73e4f83b..33a1fb54c98 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -1431,10 +1431,29 @@ zone "eng.example.com" { - flushname name + flushname + name + view + - Flushes the given name from the server's cache. + Flushes the given name from the server's DNS cache, + and from the server's nameserver address database + if applicable. + + + + + + flushtree + name + view + + + + Flushes the given name, and all of its subdomains, + from the server's DNS cache. (The server's + nameserver address database is not affected.) diff --git a/lib/dns/cache.c b/lib/dns/cache.c index 78119755164..a13a4aee52e 100644 --- a/lib/dns/cache.c +++ b/lib/dns/cache.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cache.c,v 1.89 2011/03/03 23:47:32 tbox Exp $ */ +/* $Id: cache.c,v 1.90 2011/08/02 20:36:12 each Exp $ */ /*! \file */ @@ -1153,31 +1153,14 @@ dns_cache_flush(dns_cache_t *cache) { return (ISC_R_SUCCESS); } -isc_result_t -dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { +static isc_result_t +clearnode(dns_db_t *db, dns_dbnode_t *node) { isc_result_t result; dns_rdatasetiter_t *iter = NULL; - dns_dbnode_t *node = NULL; - dns_db_t *db = NULL; - - LOCK(&cache->lock); - if (cache->db != NULL) - dns_db_attach(cache->db, &db); - UNLOCK(&cache->lock); - if (db == NULL) - return (ISC_R_SUCCESS); - result = dns_db_findnode(cache->db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_db; - } - if (result != ISC_R_SUCCESS) - goto cleanup_db; - result = dns_db_allrdatasets(cache->db, node, NULL, - (isc_stdtime_t)0, &iter); + result = dns_db_allrdatasets(db, node, NULL, (isc_stdtime_t)0, &iter); if (result != ISC_R_SUCCESS) - goto cleanup_node; + return (result); for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; @@ -1187,19 +1170,98 @@ dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { dns_rdataset_init(&rdataset); dns_rdatasetiter_current(iter, &rdataset); - result = dns_db_deleterdataset(cache->db, node, NULL, + result = dns_db_deleterdataset(db, node, NULL, rdataset.type, rdataset.covers); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) break; } + if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; dns_rdatasetiter_destroy(&iter); + return (result); +} - cleanup_node: - dns_db_detachnode(cache->db, &node); +static isc_result_t +cleartree(dns_db_t *db, dns_name_t *name) { + isc_result_t result; + dns_dbiterator_t *iter = NULL; + dns_dbnode_t *node = NULL; + dns_fixedname_t fnodename; + dns_name_t *nodename; + + dns_fixedname_init(&fnodename); + nodename = dns_fixedname_name(&fnodename); + + result = dns_db_createiterator(db, 0, &iter); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = dns_dbiterator_seek(iter, name); + if (result != ISC_R_SUCCESS) + goto cleanup; + + while (result == ISC_R_SUCCESS) { + result = dns_dbiterator_current(iter, &node, nodename); + if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) + goto cleanup; + if (! dns_name_issubdomain(nodename, name)) + goto cleanup; + + result = clearnode(db, node); + dns_db_detachnode(db, &node); + result = dns_dbiterator_next(iter); + } + + cleanup: + if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) + result = ISC_R_SUCCESS; + if (node != NULL) + dns_db_detachnode(db, &node); + if (iter != NULL) + dns_dbiterator_destroy(&iter); + + return (result); +} + +isc_result_t +dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { + return (dns_cache_flushnode(cache, name, ISC_FALSE)); +} + +isc_result_t +dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, + isc_boolean_t tree) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_db_t *db = NULL; + + if (dns_name_equal(name, dns_rootname)) + return (dns_cache_flush(cache)); + + LOCK(&cache->lock); + if (cache->db != NULL) + dns_db_attach(cache->db, &db); + UNLOCK(&cache->lock); + if (db == NULL) + return (ISC_R_SUCCESS); + + if (tree) { + result = cleartree(cache->db, name); + } else { + result = dns_db_findnode(cache->db, name, ISC_FALSE, &node); + if (result == ISC_R_NOTFOUND) { + result = ISC_R_SUCCESS; + goto cleanup_db; + } + if (result != ISC_R_SUCCESS) + goto cleanup_db; + result = clearnode(cache->db, node); + dns_db_detachnode(cache->db, &node); + } cleanup_db: dns_db_detach(&db); diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h index dd88760a725..931c47b0e39 100644 --- a/lib/dns/include/dns/cache.h +++ b/lib/dns/include/dns/cache.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cache.h,v 1.30 2011/03/03 23:47:32 tbox Exp $ */ +/* $Id: cache.h,v 1.31 2011/08/02 20:36:13 each Exp $ */ #ifndef DNS_CACHE_H #define DNS_CACHE_H 1 @@ -279,10 +279,28 @@ dns_cache_flush(dns_cache_t *cache); *\li #ISC_R_NOMEMORY */ +isc_result_t +dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, + isc_boolean_t tree); +/* + * Flush a given name from the cache. If 'tree' is true, then + * also flush all names under 'name'. + * + * Requires: + *\li 'cache' to be valid. + *\li 'name' to be valid. + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li other error returns. + */ + isc_result_t dns_cache_flushname(dns_cache_t *cache, dns_name_t *name); /* - * Flushes a given name from the cache. + * Flush a given name from the cache. Equivalent to + * dns_cache_flushpartial(cache, name, ISC_FALSE). * * Requires: *\li 'cache' to be valid. diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index f0cdc462f44..248835569e1 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.h,v 1.133 2011/02/23 03:08:11 marka Exp $ */ +/* $Id: view.h,v 1.134 2011/08/02 20:36:13 each Exp $ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 @@ -839,9 +839,31 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly); */ isc_result_t -dns_view_flushname(dns_view_t *view, dns_name_t *); +dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree); /*%< - * Flush the given name from the view's cache (and ADB). + * Flush the given name from the view's cache (and optionally ADB/badcache). + * + * If 'tree' is true, flush 'name' and all names below it + * from the cache, but do not flush ADB. + * + * If 'tree' is false, flush 'name' frmo both the cache and ADB, + * but do not touch any other nodes. + * + * Requires: + *\li 'view' is valid. + *\li 'name' is valid. + * + * Returns: + *\li #ISC_R_SUCCESS + * other returns are failures. + */ + +isc_result_t +dns_view_flushname(dns_view_t *view, dns_name_t *name); +/*%< + * Flush the given name from the view's cache, ADB and badcache. + * Equivalent to dns_view_flushnode(view, name, ISC_FALSE). + * * * Requires: *\li 'view' is valid. @@ -857,7 +879,6 @@ dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); /*%< * Add the given name to the delegation only table. * - * * Requires: *\li 'view' is valid. *\li 'name' is valid. diff --git a/lib/dns/view.c b/lib/dns/view.c index d9d93dba1f1..e2a9b88981d 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.180 2011/03/11 06:11:25 marka Exp $ */ +/* $Id: view.c,v 1.181 2011/08/02 20:36:12 each Exp $ */ /*! \file */ @@ -1529,16 +1529,23 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { isc_result_t dns_view_flushname(dns_view_t *view, dns_name_t *name) { + return (dns_view_flushnode(view, name, ISC_FALSE)); +} + +isc_result_t +dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) { REQUIRE(DNS_VIEW_VALID(view)); - if (view->adb != NULL) - dns_adb_flushname(view->adb, name); - if (view->cache == NULL) - return (ISC_R_SUCCESS); - if (view->resolver != NULL) - dns_resolver_flushbadcache(view->resolver, name); - return (dns_cache_flushname(view->cache, name)); + if (!tree) { + if (view->adb != NULL) + dns_adb_flushname(view->adb, name); + if (view->cache == NULL) + return (ISC_R_SUCCESS); + if (view->resolver != NULL) + dns_resolver_flushbadcache(view->resolver, name); + } + return (dns_cache_flushnode(view->cache, name, tree)); } isc_result_t