diff --git a/CHANGES b/CHANGES index 8279c5716b..2345d67040 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +6160. [bug] 'delv +ns' could print duplicate output. [GL #4020] + 6159. [bug] Fix use-after-free bug in TCP accept connection failure. [GL #4018] diff --git a/bin/delv/delv.c b/bin/delv/delv.c index 8d68782d10..fc10c7137c 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -1952,6 +1952,7 @@ recvresponse(void *arg) { dns_message_t *query = dns_request_getarg(request); isc_result_t result = dns_request_getresult(request); dns_message_t *response = NULL; + dns_name_t *prev = NULL; if (result != ISC_R_SUCCESS) { fatal("request event result: %s", isc_result_totext(result)); @@ -1977,8 +1978,10 @@ recvresponse(void *arg) { { dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; + dns_rdatatype_t prevtype = 0; dns_message_currentname(response, DNS_SECTION_ANSWER, &name); + for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { @@ -1988,16 +1991,32 @@ recvresponse(void *arg) { /* * The response message contains the answer the * resolver found, but it doesn't contain the - * trust status; so if we're displaying that, we - * need to look up each rdataset in the cache and - * print that version instead. but if not, we - * can just print the rdatasets from the message. + * trust status. if we're not displaying that, + * fine, we can just print that version. */ if (!showtrust) { printdata(rdataset, name); continue; } + /* + * ... but if we are printing the trust status + * (which is the default behavior)), we'll need + * to retrieve a copy of the rdataset from the cache. + * if we do that for ever record, it will produce + * duplicate output, so we check here whether we've + * already printed this name and type. + */ + if (prev != NULL && dns_name_equal(prev, name)) { + continue; + } + prev = name; + + if (prevtype == rdataset->type) { + continue; + } + prevtype = rdataset->type; + /* do the cache lookup */ if (rdataset->type == dns_rdatatype_rrsig) { continue; diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index d222e57d10..6744c1aa78 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -1404,6 +1404,13 @@ if [ -x "$DELV" ] ; then if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status+ret)) + n=$((n+1)) + echo_i "check NS output from delv +ns ($n)" + delv_with_opts -i +ns +nortrace +nostrace +nomtrace +novtrace +hint=../common/root.hint ns example > delv.out.test$n || ret=1 + lines=$(awk '$1 == "example." && $4 == "NS" {print}' delv.out.test$n | wc -l) + [ $lines -eq 2 ] || ret=1 + status=$((status+ret)) + n=$((n+1)) echo_i "checking delv +ns (no validation) ($n)" ret=0