]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
proxyv2_header_strip(): Operate correctly on malformed query packets
authorRobert Edmonds <redmonds@fastly.com>
Sat, 1 Oct 2022 02:23:07 +0000 (22:23 -0400)
committerDaniel Salzman <daniel.salzman@nic.cz>
Tue, 4 Oct 2022 09:21:18 +0000 (11:21 +0200)
Some DNS queries are malformed and generate a FORMERR response from
knot, but when those broken queries are encapsulated with a PROXY v2
header they are simply dropped with no response. This doesn't seem
correct; knot shouldn't be changing its behavior (response vs. no
response) when a PROXY v2 header is added to the query.

Previously, proxyv2_header_strip() was throwing away the knot_pkt_t
result of calling knot_pkt_parse() on the inner, decapsulated query
packet. It looks like this was what was causing the non-response issue,
because the caller couldn't distinguish between the failure of the
proxyv2_header_strip() function (e.g., PROXY v2 signature was wrong) vs.
the knot_pkt_parse() on the inner packet failing.

This commit instead makes sure that the knot_pkt_t result of
knot_pkt_parse() is returned to the caller regardless of the return code
from that function. This causes knot to respond to some kinds of broken
queries that are encapsulated with PROXY v2 in the same way when the
same query is sent as an unencapsulated, bare DNS query packet.

fixes #817

src/knot/server/proxyv2.c

index 1fc2c5adbc90f2ef0a0a413637b99181c0439ef5..a5212fa4b40ce37c8f11ed161e2e06231ba4586c 100644 (file)
@@ -46,31 +46,22 @@ int proxyv2_header_strip(knot_pkt_t **query,
        }
 
        /*
-        * Re-parse the query message using the data in the
-        * packet following the PROXY v2 payload.
-        */
-       knot_pkt_t *q = knot_pkt_new(pkt + offset, pkt_len - offset, &(*query)->mm);
-
-       /*
-        * Check if the calculated offset of the original DNS message is
-        * actually inside the packet received on the wire, and if so, parse
-        * the real DNS query message.
+        * Store the provided remote address.
         */
-       int ret = knot_pkt_parse(q, 0);
+       int ret = proxyv2_addr_store(pkt, pkt_len, new_remote);
        if (ret != KNOT_EOK) {
                return ret;
        }
 
        /*
-        * Store the provided remote address.
+        * Re-parse the query message using the data in the
+        * packet following the PROXY v2 payload.
         */
-       ret = proxyv2_addr_store(pkt, pkt_len, new_remote);
-       if (ret != KNOT_EOK && q->parsed > 0) {
-               return ret;
-       }
+       knot_pkt_t *q = knot_pkt_new(pkt + offset, pkt_len - offset, &(*query)->mm);
+       ret = knot_pkt_parse(q, 0);
 
        knot_pkt_free(*query);
        *query = q;
 
-       return KNOT_EOK;
+       return ret;
 }