]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use NS rather than A records for qname-minimization relaxed
authorMark Andrews <marka@isc.org>
Tue, 23 May 2023 06:59:40 +0000 (16:59 +1000)
committerMark Andrews <marka@isc.org>
Wed, 28 Jun 2023 01:45:59 +0000 (11:45 +1000)
Remove all references to DNS_FETCHOPT_QMIN_USE_A and adjust
the expected tests results in the qmin system test.

bin/tests/system/digdelv/tests.sh
bin/tests/system/qmin/tests.sh
doc/arm/reference.rst
lib/dns/include/dns/resolver.h
lib/dns/resolver.c
lib/ns/query.c

index 6744c1aa78189eade7711250680f71f745e225c4..eb551f98b926f8e275b7c43cbb189cd46a7729f9 100644 (file)
@@ -1425,7 +1425,6 @@ if [ -x "$DELV" ] ; then
   ret=0
   delv_with_opts -i +ns +qmin +hint=../common/root.hint a a.example > delv.out.test$n || ret=1
   grep -q '; authoritative' delv.out.test$n || ret=1
-  grep -q '_.example' delv.out.test$n || ret=1
   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   status=$((status+ret))
 
@@ -1443,7 +1442,6 @@ if [ -x "$DELV" ] ; then
   ret=0
   delv_with_opts -a ns1/anchor.dnskey +root +ns +qmin +hint=../common/root.hint a a.example > delv.out.test$n || ret=1
   grep -q '; fully validated' delv.out.test$n || ret=1
-  grep -q '_.example' delv.out.test$n || ret=1
   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   status=$((status+ret))
 
index 26d3cb8946c4eb94473b8c3f645946ebdd695b6c..12d74518fcd80d28221ef579c7a4e6587265e8fa 100755 (executable)
@@ -154,20 +154,20 @@ grep "icky.icky.icky.ptang.zoop.boing.good. 1     IN A    192.0.2.1" dig.out.test$n > /
 sleep 1
 sort ans2/query.log > ans2/query.log.sorted
 cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
-ADDR _.boing.good.
-ADDR _.zoop.boing.good.
 ADDR a.bit.longer.ns.name.good.
 ADDR a.bit.longer.ns.name.good.
 ADDR ns2.good.
 ADDR ns3.good.
 ADDR ns3.good.
+NS boing.good.
+NS zoop.boing.good.
 __EOF
 cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
-ADDR _.ptang.zoop.boing.good.
-ADDR _.icky.ptang.zoop.boing.good.
+NS ptang.zoop.boing.good.
+NS icky.ptang.zoop.boing.good.
 __EOF
 cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
-ADDR _.icky.icky.ptang.zoop.boing.good.
+NS icky.icky.ptang.zoop.boing.good.
 ADDR icky.icky.icky.ptang.zoop.boing.good.
 __EOF
 for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
@@ -203,20 +203,18 @@ grep "icky.icky.icky.ptang.zoop.boing.bad. 1 IN A 192.0.2.1" dig.out.test$n > /d
 sleep 1
 sort ans2/query.log > ans2/query.log.sorted
 cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
-ADDR _.boing.bad.
-ADDR _.zoop.boing.bad.
 ADDR a.bit.longer.ns.name.bad.
 ADDR a.bit.longer.ns.name.bad.
+ADDR icky.icky.icky.ptang.zoop.boing.bad.
 ADDR ns2.bad.
 ADDR ns3.bad.
 ADDR ns3.bad.
+NS boing.bad.
 __EOF
 cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
-ADDR _.ptang.zoop.boing.bad.
-ADDR _.icky.ptang.zoop.boing.bad.
+ADDR icky.icky.icky.ptang.zoop.boing.bad.
 __EOF
 cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
-ADDR _.icky.icky.ptang.zoop.boing.bad.
 ADDR icky.icky.icky.ptang.zoop.boing.bad.
 __EOF
 for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
@@ -251,16 +249,15 @@ $DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.ugly. @10.53.0.7 > dig.out.test$n
 grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
 grep "icky.icky.icky.ptang.zoop.boing.ugly. 1  IN A    192.0.2.1" dig.out.test$n > /dev/null || ret=1
 sleep 1
-
 sort ans2/query.log > ans2/query.log.sorted
 cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
-ADDR _.boing.ugly.
 ADDR a.bit.longer.ns.name.ugly.
 ADDR a.bit.longer.ns.name.ugly.
 ADDR icky.icky.icky.ptang.zoop.boing.ugly.
 ADDR ns2.ugly.
 ADDR ns3.ugly.
 ADDR ns3.ugly.
+NS boing.ugly.
 __EOF
 echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans3/query.log - > /dev/null || ret=1
 echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans4/query.log - > /dev/null || ret=1
@@ -270,7 +267,7 @@ status=$((status+ret))
 $RNDCCMD 10.53.0.7 flush
 
 n=$((n+1))
-echo_i "information that minimization was unsuccessful for .ugly is logged ($n)"
+echo_i "information that minimization was unsuccessful for .ugly is logged in relaxed mode ($n)"
 ret=0
 wait_for_log 5 "success resolving 'icky.icky.icky.ptang.zoop.boing.ugly/A' after disabling qname minimization" ns7/named.run > /dev/null || ret=1
 if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -458,9 +455,9 @@ grep "a\.b\.stale\..*1.*IN.*TXT.*hooray" dig.out.test$n > /dev/null || ret=1
 sleep 1
 sort ans2/query.log > ans2/query.log.sorted
 cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
-ADDR _.b.stale.
 ADDR ns.b.stale.
 ADDR ns2.stale.
+NS b.stale.
 __EOF
 test -f  ans3/query.log && ret=1
 sort ans4/query.log > ans4/query.log.sorted
@@ -523,7 +520,7 @@ grep "a\.b\.stale\..*1.*IN.*TXT.*hooray" dig.out.test$n > /dev/null || ret=1
 sleep 1
 sort ans2/query.log > ans2/query.log.sorted
 cat << __EOF | diff ans2/query.log.sorted - > /dev/null || ret=1
-ADDR _.b.stale.
+NS b.stale.
 __EOF
 test -f  ans3/query.log && ret=1
 sort ans4/query.log > ans4/query.log.sorted
index ff400de38dde2a65d9ab9dec8db9ddf74648c200..f1a3c9e1916b63f1a336c84cbd53b2f3d19241af 100644 (file)
@@ -1392,21 +1392,22 @@ default is used.
    :tags: query
    :short: Controls QNAME minimization behavior in the BIND 9 resolver.
 
-   When this is set to ``strict``, BIND follows the QNAME
-   minimization algorithm to the letter, as specified in :rfc:`7816`.
+   When this is set to ``strict``, BIND follows the QNAME minimization
+   algorithm to the letter, as specified in :rfc:`7816`.
 
    Setting this option to ``relaxed`` causes BIND to fall back to
-   normal (non-minimized) query mode when it receives either NXDOMAIN or
-   other unexpected responses (e.g., SERVFAIL, improper zone cut,
-   REFUSED) to a minimized query. A resolver can use a leading
-   underscore, like ``_.example.com``, in an attempt to improve
-   interoperability. (See :rfc:`7816` section 3.)
+   normal (non-minimized) query mode when it receives either NXDOMAIN
+   or other unexpected responses (e.g., SERVFAIL, improper zone
+   cut, REFUSED) to a minimized query.
+
+   In ``relaxed`` mode ``named`` makes NS queries for ``<domain>`` as it
+   walks down the tree.
 
    ``disabled`` disables QNAME minimization completely.
    ``off`` is a synonym for ``disabled``.
 
-   The current default is ``relaxed``, but it
-   may be changed to ``strict`` in a future release.
+   The current default is ``relaxed``, but it may be changed to
+   ``strict`` in a future release.
 
 .. namedconf:statement:: tkey-gssapi-keytab
    :tags: security
index 83ea6bb40627c729ac37f569820b8bc3172fa33d..d094f58d846bfae3affef9d009d152f3fadd0221 100644 (file)
@@ -120,31 +120,21 @@ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t;
 /* RESERVED ECS                                0x00001000 */
 /* RESERVED ECS                                0x00002000 */
 /* RESERVED TCPCLIENT                  0x00004000 */
-#define DNS_FETCHOPT_NOCACHED 0x00008000 /*%< Force cache update. */
-#define DNS_FETCHOPT_QMINIMIZE    \
-       0x00010000 /*%< Use qname \
-                   *    minimization. */
-#define DNS_FETCHOPT_NOFOLLOW        \
-       0x00020000 /*%< Don't follow \
-                   *   delegations */
-#define DNS_FETCHOPT_QMIN_STRICT            \
-       0x00040000 /*%< Do not work around  \
-                   *   servers that return \
-                   *   errors on non-empty \
-                   *   terminals. */
-#define DNS_FETCHOPT_QMIN_USE_A            \
-       0x00080000 /*%< Use A type queries \
-                   *   instead of NS when \
-                   *   doing minimization */
-#define DNS_FETCHOPT_QMIN_SKIP_IP6A      \
-       0x00100000 /*%< Skip some labels \
-                   *   when doing qname \
-                   *   minimization on  \
+#define DNS_FETCHOPT_NOCACHED  0x00008000 /*%< Force cache update. */
+#define DNS_FETCHOPT_QMINIMIZE 0x00010000 /*%< Use qname minimization. */
+#define DNS_FETCHOPT_NOFOLLOW                                                  \
+       0x00020000 /*%< Don't retrieve the NS RRset from the child zone when a \
+                   *   delegation is returned in response to a NS query. */
+#define DNS_FETCHOPT_QMIN_STRICT                                         \
+       0x00040000 /*%< Do not work around servers that return errors on \
+                   *   non-empty terminals. */
+#define DNS_FETCHOPT_QMIN_SKIP_IP6A                                        \
+       0x00080000 /*%< Skip some labels when doing qname  minimization on \
                    *   ip6.arpa. */
-#define DNS_FETCHOPT_NOFORWARD                \
-       0x00200000 /*%< Do not use forwarders \
-                   *   if possible. */
+#define DNS_FETCHOPT_NOFORWARD \
+       0x00100000 /*%< Do not use forwarders if possible. */
 
+/* UNUSED                      0x00200000 */
 /* Reserved in use by adb.c            0x00400000 */
 #define DNS_FETCHOPT_EDNSVERSIONSET    0x00800000
 #define DNS_FETCHOPT_EDNSVERSIONMASK   0xff000000
index 28561e3ca12eac957c5c712270cd53095d7b9cf6..c747551881cc551f5000e4eba8f3082a6f706246 100644 (file)
@@ -635,11 +635,6 @@ static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
 static const dns_name_t ip6_arpa = DNS_NAME_INITABSOLUTE(ip6_arpa_data,
                                                         ip6_arpa_offsets);
 
-static unsigned char underscore_data[] = "\001_";
-static unsigned char underscore_offsets[] = { 0 };
-static const dns_name_t underscore_name =
-       DNS_NAME_INITNONABSOLUTE(underscore_data, underscore_offsets);
-
 static void
 dns_resolver__destroy(dns_resolver_t *res);
 static isc_result_t
@@ -4056,11 +4051,14 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
                }
 
                /*
-                * In "_ A" mode we're asking for _.domain -
-                * resolver by default will follow delegations
-                * then, we don't want that.
+                * Turn on NOFOLLOW in relaxed mode so that QNAME minimisation
+                * doesn't cause additional queries to resolve the target of the
+                * QNAME minimisation request when a referral is returned.  This
+                * will also reduce the impact of mis-matched NS RRsets where
+                * the child's NS RRset is garbage.  If a delegation is
+                * discovered DNS_R_DELEGATION will be returned to resume_qmin.
                 */
-               if ((options & DNS_FETCHOPT_QMIN_USE_A) != 0) {
+               if ((options & DNS_FETCHOPT_QMIN_STRICT) == 0) {
                        options |= DNS_FETCHOPT_NOFOLLOW;
                }
 
@@ -4154,14 +4152,6 @@ resume_qmin(void *arg) {
                goto cleanup;
        case DNS_R_NXDOMAIN:
        case DNS_R_NCACHENXDOMAIN:
-               /*
-                * If we're doing "_ A"-style minimization we can get
-                * NX answer to minimized query - we need to continue then.
-                */
-               if ((fctx->options & DNS_FETCHOPT_QMIN_USE_A) != 0) {
-                       break;
-               }
-               FALLTHROUGH;
        case DNS_R_FORMERR:
        case DNS_R_REMOTEFORMERR:
        case ISC_R_FAILURE:
@@ -4180,6 +4170,11 @@ resume_qmin(void *arg) {
                }
                break;
        default:
+               /*
+                * When DNS_FETCHOPT_NOFOLLOW is set and a delegation
+                * was discovered, DNS_R_DELEGATION is returned and is
+                * processed here.
+                */
                break;
        }
 
@@ -7630,7 +7625,8 @@ resquery_response(isc_result_t eresult, isc_region_t *region, void *arg) {
                case DNS_R_CHASEDSSERVERS:
                        break;
                case DNS_R_DELEGATION:
-                       /* With NOFOLLOW we want to pass the result code
+                       /*
+                        * With NOFOLLOW we want to pass the result code.
                         */
                        if ((fctx->options & DNS_FETCHOPT_NOFOLLOW) == 0) {
                                result = ISC_R_SUCCESS;
@@ -10200,24 +10196,8 @@ fctx_minimize_qname(fetchctx_t *fctx) {
                dns_fixedname_t fname;
                dns_name_t *name = dns_fixedname_initname(&fname);
                dns_name_split(fctx->name, fctx->qmin_labels, NULL, name);
-               if ((fctx->options & DNS_FETCHOPT_QMIN_USE_A) != 0) {
-                       isc_buffer_t dbuf;
-                       dns_fixedname_t tmpname;
-                       dns_name_t *tname = dns_fixedname_initname(&tmpname);
-                       char ndata[DNS_NAME_MAXWIRE];
-
-                       isc_buffer_init(&dbuf, ndata, DNS_NAME_MAXWIRE);
-                       dns_fixedname_init(&tmpname);
-                       result = dns_name_concatenate(&underscore_name, name,
-                                                     tname, &dbuf);
-                       if (result == ISC_R_SUCCESS) {
-                               dns_name_copy(tname, fctx->qminname);
-                       }
-                       fctx->qmintype = dns_rdatatype_a;
-               } else {
-                       dns_name_copy(name, fctx->qminname);
-                       fctx->qmintype = dns_rdatatype_ns;
-               }
+               dns_name_copy(name, fctx->qminname);
+               fctx->qmintype = dns_rdatatype_ns;
                fctx->minimized = true;
        } else {
                /* Minimization is done, we'll ask for whole qname */
index 3d5752c8e5cd2d799817000d987edf44020f48c8..18c34b6968cdab81e9af6cdd6b3084bd5de419fe 100644 (file)
@@ -12072,8 +12072,6 @@ ns_query_start(ns_client_t *client, isc_nmhandle_t *handle) {
                                              DNS_FETCHOPT_QMIN_SKIP_IP6A;
                if (client->view->qmin_strict) {
                        client->query.fetchoptions |= DNS_FETCHOPT_QMIN_STRICT;
-               } else {
-                       client->query.fetchoptions |= DNS_FETCHOPT_QMIN_USE_A;
                }
        }