]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
iterate: avoid turning off qname minimization in a case
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 16 May 2018 11:59:06 +0000 (13:59 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 16 May 2018 15:17:52 +0000 (17:17 +0200)
Thanks to @ spakka for discovering this and authoring an earlier version
of this commit.

NEWS
lib/layer/iterate.c

diff --git a/NEWS b/NEWS
index 3b994abc83d61a2225fe0b7d330b736e2a1ec866..e40aeef700419f1c8d99c05b1fadb25396f2006e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ Security
 --------
 - fix a rare case of zones incorrectly dowgraded to insecure status
 
+Bugfixes
+--------
+- avoid turning off qname minimization in some cases, e.g. co.uk. (#339)
+
 
 Knot Resolver 2.3.0 (2018-04-23)
 ================================
index d5a65779163dc99185714dac0527733b1708cad7..d914921db9b72198d898faa688af4e93ba5af449 100644 (file)
@@ -650,17 +650,28 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
 {
        struct kr_query *query = req->current_query;
 
-       /* Response for minimized QNAME.
+       /* Response for minimized QNAME.  Note that current iterator's minimization
+        * is only able ask one label below a zone cut.
         * NODATA   => may be empty non-terminal, retry (found zone cut)
-        * NOERROR  => found zone cut, retry
+        * NOERROR  => found zone cut, retry, except the case described below
         * NXDOMAIN => parent is zone cut, retry as a workaround for bad authoritatives
         */
-       bool is_final = (query->parent == NULL);
-       int pkt_class = kr_response_classify(pkt);
-       if (!knot_dname_is_equal(knot_pkt_qname(pkt), query->sname) &&
+       const bool is_final = (query->parent == NULL);
+       const int pkt_class = kr_response_classify(pkt);
+       const knot_dname_t * pkt_qname = knot_pkt_qname(pkt);
+       if (!knot_dname_is_equal(pkt_qname, query->sname) &&
            (pkt_class & (PKT_NOERROR|PKT_NXDOMAIN|PKT_REFUSED|PKT_NODATA))) {
-               VERBOSE_MSG("<= found cut, retrying with non-minimized name\n");
-               query->flags.NO_MINIMIZE = true;
+               /* Check for parent server that is authoritative for child zone,
+                * several CCTLDs where the SLD and TLD have the same name servers */
+               const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER);
+               if ((pkt_class & (PKT_NOERROR)) && ans->count > 0 &&
+                    knot_dname_is_equal(pkt_qname, query->zone_cut.name)) {
+                       VERBOSE_MSG("<= continuing with qname minimization\n")
+               } else {
+                       /* fall back to disabling minimization */
+                       VERBOSE_MSG("<= retrying with non-minimized name\n");
+                       query->flags.NO_MINIMIZE = true;
+               }
                return KR_STATE_CONSUME;
        }