From: Evan Hunt Date: Thu, 6 Dec 2012 20:41:58 +0000 (-0800) Subject: [master] handle ISC_R_NOMORE correctly X-Git-Tag: v9.10.0a1~677^2~4 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=177be355d4ccf0ce6308e3e6c0f5404eaf13e9a0;p=thirdparty%2Fbind9.git [master] handle ISC_R_NOMORE correctly 3433. [bug] dlz_findzone() did not correctly handle ISC_R_NOMORE. [RT #31172] --- diff --git a/CHANGES b/CHANGES index 67cf262c4af..0a88c20f1fd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3433. [bug] dlz_findzone() did not correctly handle + ISC_R_NOMORE. [RT #31172] + 3432. [func] Multiple DLZ databases can now be configured. DLZ databases are searched in the order configured, unless set to "search no", in which case a diff --git a/bin/tests/system/dlzexternal/driver.c b/bin/tests/system/dlzexternal/driver.c index 1faf07f149b..cdda7c406e2 100644 --- a/bin/tests/system/dlzexternal/driver.c +++ b/bin/tests/system/dlzexternal/driver.c @@ -321,6 +321,20 @@ isc_result_t dlz_findzonedb(void *dbdata, const char *name) { struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + state->log(ISC_LOG_INFO, + "dlz_example: dlz_findzonedb called with name '%s'" + "in zone DB '%s'", name, state->zone_name); + + /* + * Returning ISC_R_NOTFOUND will cause the query logic to + * check the database for parent names, looking for zone cuts. + * + * Returning ISC_R_NOMORE prevents the query logic from doing + * this; it will move onto the next database after a single query. + */ + if (strcasecmp(name, "test.example.com") == 0) + return (ISC_R_NOMORE); + if (strcasecmp(state->zone_name, name) == 0) return (ISC_R_SUCCESS); diff --git a/bin/tests/system/dlzexternal/tests.sh b/bin/tests/system/dlzexternal/tests.sh index 04d9196ddc8..38327d4dab2 100644 --- a/bin/tests/system/dlzexternal/tests.sh +++ b/bin/tests/system/dlzexternal/tests.sh @@ -101,4 +101,22 @@ grep "3600.IN.NS.zone.nil." dig.out.ns1.4 > /dev/null || ret=1 [ "$ret" -eq 0 ] || echo "I:failed" status=`expr $status + $ret` +ret=0 +echo "I:testing unsearched/registered DLZ zone is found" +$DIG $DIGOPTS +noall +answer ns zone.nil > dig.out.ns1.5 +grep "3600.IN.NS.zone.nil." dig.out.ns1.5 > /dev/null || ret=1 +[ "$ret" -eq 0 ] || echo "I:failed" +status=`expr $status + $ret` + +ret=0 +echo "I:testing correct behavior with findzone returning ISC_R_NOMORE" +$DIG $DIGOPTS +noall a test.example.com > /dev/null 2>&1 || ret=1 +# we should only find one logged lookup per searched DLZ database +lines=`grep "dlz_findzonedb.*example\.com.*example.nil" ns1/named.run | wc -l` +[ $lines -eq 1 ] || ret=1 +lines=`grep "dlz_findzonedb.*example\.com.*alternate.nil" ns1/named.run | wc -l` +[ $lines -eq 1 ] || ret=1 +[ "$ret" -eq 0 ] || echo "I:failed" +status=`expr $status + $ret` + exit $status diff --git a/lib/dns/dlz.c b/lib/dns/dlz.c index 482f484a1a9..f8066baac6e 100644 --- a/lib/dns/dlz.c +++ b/lib/dns/dlz.c @@ -335,9 +335,16 @@ dns_dlzfindzone(dns_view_t *view, dns_name_t *name, if (result != ISC_R_NOTFOUND) { if (best != NULL) dns_db_detach(&best); - dns_db_attach(db, &best); - dns_db_detach(&db); - minlabels = i; + if (result == ISC_R_SUCCESS) { + INSIST(db != NULL); + dns_db_attach(db, &best); + dns_db_detach(&db); + minlabels = i; + } else { + if (db != NULL) + dns_db_detach(&db); + break; + } } else if (db != NULL) dns_db_detach(&db); }