]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
nameserver: don't shadow positive zone record with module's NODATA
authorLibor Peltan <libor.peltan@nic.cz>
Tue, 29 Jun 2021 17:59:47 +0000 (19:59 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Wed, 30 Jun 2021 05:35:00 +0000 (07:35 +0200)
src/knot/nameserver/internet.c
tests-extra/tests/modules/geoip/data/example.com.zone
tests-extra/tests/modules/geoip/test.py

index dab1d7fe1cb22970eaf96fc504f62b61e8cebc33..a09776d8934cd4c1e4ed3634579a9227d51ceb6c 100644 (file)
@@ -431,14 +431,21 @@ static int solve_name(int state, knot_pkt_t *pkt, knotd_qdata_t *qdata)
 
 static int solve_answer(int state, knot_pkt_t *pkt, knotd_qdata_t *qdata, void *ctx)
 {
+       int old_state = state;
+
        /* Do not solve if already solved, e.g. in a module. */
-       if (state == KNOTD_IN_STATE_HIT || state == KNOTD_IN_STATE_NODATA) {
+       if (state == KNOTD_IN_STATE_HIT) {
                return state;
        }
 
        /* Get answer to QNAME. */
        state = solve_name(state, pkt, qdata);
 
+       /* Promote NODATA from a module if nothing found in zone. */
+       if (state == KNOTD_IN_STATE_MISS && old_state == KNOTD_IN_STATE_NODATA) {
+               state = old_state;
+       }
+
        /* Is authoritative answer unless referral.
         * Must check before we chase the CNAME chain. */
        if (state != KNOTD_IN_STATE_DELEG) {
index a88bde63f8e0f8e6a61fcb83ed977d2800aa74ef..a0aadebb9be8f6a86ce0cb53853009d6ed82f0d8 100644 (file)
@@ -6,4 +6,4 @@ dns1.example.com.       3600    AAAA    2001:db8::1
 foo.example.com.       3600    A       192.0.2.4
 mail.example.com.      3600    A       192.0.2.3
 mail.example.com.      3600    AAAA    2001:db8::3
-
+d1.example.com.                3600    AAAA    1::4
index b074261b719b1aba6acf99aff78707972b2c866d..b6fc74ceecdd7555eeb58183cd0a8b5f8c9220d3 100644 (file)
@@ -87,10 +87,14 @@ for i in range(1, 1000):
     resp.check(rcode="NOERROR", rdata=random_client)
 
     # check NODATA response when querying different type
-    resp = knot.dig("d" + str(random.randint(1, dname_count)) + ".example.com", "AAAA", source=random_client)
+    resp = knot.dig("d" + str(random.randint(2, dname_count)) + ".example.com", "AAAA", source=random_client)
     resp.check(rcode="NOERROR")
     resp.check_count(1, "SOA", section="authority")
 
+    # check that NODATA behaviour does not shadow existing RR in the zone
+    resp = knot.dig("d1.example.com", "AAAA", source=random_client)
+    resp.check(rcode="NOERROR", rdata="1::4")
+
 # Restart with subnet module.
 knot.clear_modules(zone)
 knot.add_module(zone, mod_subnet);
@@ -109,10 +113,13 @@ for i in range(1, 1000):
     resp = knot.dig("d" + str(random.randint(1, dname_count)) + ".example.com", "A", source=random_client)
     resp.check(rcode="NOERROR", rdata=random_client)
 
-    resp = knot.dig("d" + str(random.randint(1, dname_count)) + ".example.com", "AAAA", source=random_client)
+    resp = knot.dig("d" + str(random.randint(2, dname_count)) + ".example.com", "AAAA", source=random_client)
     resp.check(rcode="NOERROR")
     resp.check_count(1, "SOA", section="authority")
 
+    resp = knot.dig("d1.example.com", "AAAA", source=random_client)
+    resp.check(rcode="NOERROR", rdata="1::4")
+
 # Switch subnet file.
 shutil.move(subnet2_filename, subnet_filename)
 knot.ctl("-f zone-reload example.com.", wait=True)
@@ -125,6 +132,9 @@ for i in range(1, 1000):
     resp = knot.dig("d" + str(random.randint(1, dname_count)) + ".example.com", "A", source=random_client)
     resp.check(rcode="NOERROR", rdata=expected_rdata, nordata=random_client)
 
-    resp = knot.dig("d" + str(random.randint(1, dname_count)) + ".example.com", "AAAA", source=random_client)
+    resp = knot.dig("d" + str(random.randint(2, dname_count)) + ".example.com", "AAAA", source=random_client)
     resp.check(rcode="NOERROR")
     resp.check_count(1, "SOA", section="authority")
+
+    resp = knot.dig("d1.example.com", "AAAA", source=random_client)
+    resp.check(rcode="NOERROR", rdata="1::4")