]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Added test for the proposed fix
authorDiego Fronza <diego@isc.org>
Fri, 28 Aug 2020 21:49:26 +0000 (18:49 -0300)
committerOndřej Surý <ondrej@isc.org>
Wed, 2 Sep 2020 14:52:39 +0000 (16:52 +0200)
The test works as follows:

1. Client wants to resolve unusual ip6.arpa. name:

   test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. IN TXT

2. Query is sent to ns7, a qmin enabled resolver.

3. ns7 do the first stage in query minimization for the name and send a new
   query to root (ns1):

  _.1.0.0.2.ip6.arpa.        IN  A

4. ns1 delegates ip6.arpa. to ns2.good.:

    ;; AUTHORITY SECTION:
    ;ip6.arpa.      20  IN  NS  ns2.good.

    ;; ADDITIONAL SECTION:
    ;ns2.good.      20  IN  A   10.53.0.2

5. ns7 do a second round in minimizing the name and send a new query
   to ns2.good. (10.53.0.2):

   _.8.2.6.0.1.0.0.2.ip6.arpa.    IN  A

6. ans2 delegates 8.2.6.0.1.0.0.2.ip6.arpa. to ns3.good.:

    ;; AUTHORITY SECTION:
    ;8.2.6.0.1.0.0.2.ip6.arpa. 60   IN  NS  ns3.good.

    ;; ADDITIONAL SECTION:
    ;ns3.good.      60  IN  A   10.53.0.3

7. ns7 do a third round in minimizing the name and send a new query to
   ns3.good.:

    _.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. IN A

8. ans3 delegates 1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. to ns4.good.:

    ;; AUTHORITY SECTION:
    ;1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. 60 IN    NS  ns4.good.

    ;; ADDITIONAL SECTION:
    ;ns4.good.      60  IN  A   10.53.0.4

9. ns7 do fourth round in minimizing the name and send a new query to
   ns4.good.:

_.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.    IN A

10. ns4.good. doesn't know such name, but answers stating it is authoritative for
    the domai:

;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id:  53815
...
;; AUTHORITY SECTION:
1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. 60 IN    SOA ns4.good.  ...

11. ns7 do another minimization on name:
   _.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa
   sends to ns4.good. and gets the same SOA response stated in item #10

12. ns7 do another minimization on name:
_.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa
sends to ns4.good. and gets the same SOA response stated in item #10.

13. ns7 do the last query minimization name for the ip6.arpa. QNAME.
After all IPv6 labels are exausted the algorithm falls back to the
original QNAME:
test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa

    ns7 sends a new query with the original QNAME to ans4.

14. Finally ans4 answers with the expected response:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:  40969
;; flags: qr aa; QUESTION: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 8192
;; QUESTION SECTION:
;test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. IN TXT

;; ANSWER SECTION:
;test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. 1    IN TXT "long_ip6_name"

(cherry picked from commit 11add6919855012fb8b41bb0ae6c15d6a6855f6d)

bin/tests/system/qmin/ans2/ans.py
bin/tests/system/qmin/ans3/ans.py
bin/tests/system/qmin/ans4/ans.py
bin/tests/system/qmin/tests.sh

index c4e98745374ca2dc33995692acfd9d0b09aafe7e..96e723986ac9f2824daf768b3671040477b517ec 100755 (executable)
@@ -48,6 +48,7 @@ def logquery(type, qname):
 #
 # For 1.0.0.2.ip6.arpa it serves
 # 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa. IN PTR nee.com.
+# 8.2.6.0.1.0.0.2.ip6.arpa IN NS ns3.good
 # 1.0.0.2.ip6.arpa. IN NS ns2.good
 # ip6.arpa. IN NS ns2.good
 ############################################################################
@@ -76,33 +77,37 @@ def create_response(msg):
 
     if lqname.endswith("1.0.0.2.ip6.arpa."):
         # Direct query - give direct answer
-        if lqname == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa." and rrtype == PTR:
+        if lqname.endswith("8.2.6.0.1.0.0.2.ip6.arpa."):
+            # Delegate to ns3
+            r.authority.append(dns.rrset.from_text("8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns3.good."))
+            r.additional.append(dns.rrset.from_text("ns3.good.", 60, IN, A, "10.53.0.3"))
+        elif lqname == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa." and rrtype == PTR:
             # Direct query - give direct answer
             r.answer.append(dns.rrset.from_text("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.", 1, IN, PTR, "nee.com."))
             r.flags |= dns.flags.AA
         elif lqname == "1.0.0.2.ip6.arpa." and rrtype == NS:
             # NS query at the apex
-            r.answer.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 1, IN, NS, "ns2.good."))
+            r.answer.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, NS, "ns2.good."))
             r.flags |= dns.flags.AA
         elif "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.".endswith(lqname):
             # NODATA answer
-            r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
         else:
             # NXDOMAIN
-            r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
             r.set_rcode(NXDOMAIN)
         return r
     elif lqname.endswith("ip6.arpa."):
         if lqname == "ip6.arpa." and rrtype == NS:
             # NS query at the apex
-            r.answer.append(dns.rrset.from_text("ip6.arpa.", 1, IN, NS, "ns2.good."))
+            r.answer.append(dns.rrset.from_text("ip6.arpa.", 30, IN, NS, "ns2.good."))
             r.flags |= dns.flags.AA
         elif "1.0.0.2.ip6.arpa.".endswith(lqname):
             # NODATA answer
-            r.authority.append(dns.rrset.from_text("ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(dns.rrset.from_text("ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
         else:
             # NXDOMAIN
-            r.authority.append(dns.rrset.from_text("ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(dns.rrset.from_text("ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
             r.set_rcode(NXDOMAIN)
         return r
     elif lqname.endswith("bad."):
@@ -134,19 +139,25 @@ def create_response(msg):
         r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
         r.flags |= dns.flags.AA
     elif lqname == "" and rrtype == NS:
-        r.answer.append(dns.rrset.from_text(suffix, 1, IN, NS, "ns2." + suffix))
+        r.answer.append(dns.rrset.from_text(suffix, 30, IN, NS, "ns2." + suffix))
         r.flags |= dns.flags.AA
     elif lqname == "ns2." and rrtype == A:
-        r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, A, "10.53.0.2"))
+        r.answer.append(dns.rrset.from_text("ns2."+suffix, 30, IN, A, "10.53.0.2"))
         r.flags |= dns.flags.AA
     elif lqname == "ns2." and rrtype == AAAA:
-        r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::2"))
+        r.answer.append(dns.rrset.from_text("ns2."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::2"))
         r.flags |= dns.flags.AA
     elif lqname == "ns3." and rrtype == A:
-        r.answer.append(dns.rrset.from_text("ns3."+suffix, 1, IN, A, "10.53.0.3"))
+        r.answer.append(dns.rrset.from_text("ns3."+suffix, 30, IN, A, "10.53.0.3"))
         r.flags |= dns.flags.AA
     elif lqname == "ns3." and rrtype == AAAA:
-        r.answer.append(dns.rrset.from_text("ns3."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::3"))
+        r.answer.append(dns.rrset.from_text("ns3."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::3"))
+        r.flags |= dns.flags.AA
+    elif lqname == "ns4." and rrtype == A:
+        r.answer.append(dns.rrset.from_text("ns4."+suffix, 30, IN, A, "10.53.0.4"))
+        r.flags |= dns.flags.AA
+    elif lqname == "ns4." and rrtype == AAAA:
+        r.answer.append(dns.rrset.from_text("ns4."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::4"))
         r.flags |= dns.flags.AA
     elif lqname == "a.bit.longer.ns.name." and rrtype == A:
         r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, A, "10.53.0.4"))
index e96d3971fa18c7b34f19a2ff8d0b271a787dddbb..9a459d78359edc8c194a08189b828c7b8bb6536d 100755 (executable)
@@ -67,6 +67,8 @@ def create_response(msg):
     r = dns.message.make_response(m)
     r.set_rcode(NOERROR)
 
+    ip6req = False
+
     if lqname.endswith("bad."):
         bad = True
         suffix = "bad."
@@ -82,6 +84,8 @@ def create_response(msg):
         slow = True
         suffix = "slow."
         lqname = lqname[:-5]
+    elif lqname.endswith("8.2.6.0.1.0.0.2.ip6.arpa."):
+        ip6req = True 
     else:
         r.set_rcode(REFUSED)
         return r
@@ -101,6 +105,9 @@ def create_response(msg):
     elif lqname.endswith("zoop.boing."):
         r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
         r.set_rcode(NXDOMAIN)
+    elif ip6req:
+        r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns4.good."))
+        r.additional.append(dns.rrset.from_text("ns4.good.", 60, IN, A, "10.53.0.4"))
     else:
         r.set_rcode(REFUSED)
 
index 15c256ba3233179d64e10252195cd6928bc365f2..a836af43fffb6a5819f7fae2d8d081c2f2dcfd9a 100755 (executable)
@@ -68,6 +68,8 @@ def create_response(msg):
     r = dns.message.make_response(m)
     r.set_rcode(NOERROR)
 
+    ip6req = False
+
     if lqname.endswith("bad."):
         bad = True
         suffix = "bad."
@@ -83,6 +85,8 @@ def create_response(msg):
         slow = True
         suffix = "slow."
         lqname = lqname[:-5]
+    elif lqname.endswith("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa."):
+        ip6req = True
     else:
         r.set_rcode(REFUSED)
         return r
@@ -103,6 +107,17 @@ def create_response(msg):
             r.set_rcode(NXDOMAIN)
         if ugly:
             r.set_rcode(FORMERR)
+    elif ip6req:
+        r.flags |= dns.flags.AA
+        if lqname == "test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa." and rrtype == TXT:
+            r.answer.append(dns.rrset.from_text("test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 1, IN, TXT, "long_ip6_name"))
+        elif "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.".endswith(lqname):
+            #NODATA answer
+            r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, SOA, "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16"))
+        else:
+            # NXDOMAIN
+            r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, SOA, "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16"))
+            r.set_rcode(NXDOMAIN)
     else:
         r.set_rcode(REFUSED)
 
index ecd2bc86e9e333a0ecf910dc29b008a8416dbfc4..f3e529bc1bd4549f34d2d0274071186eac467a78 100755 (executable)
@@ -384,5 +384,16 @@ for ans in ans2; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true;
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+n=`expr $n + 1`
+echo_i "qname minimization resolves unusual ip6.arpa. names ($n)"
+ret=0
+$CLEANQL
+$DIG $DIGOPTS test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. txt @10.53.0.7 > dig.out.test$n 2>&1
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+# Expected output in dig.out.test$n:
+# ;; ANSWER SECTION:
+# test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. 1 IN TXT "long_ip6_name"
+grep 'ip6\.arpa.*TXT.*long_ip6_name' dig.out.test$n > /dev/null || ret=1
+
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1