]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
refresh: establish a new TCP connection for XFR if no-edns is set
authorDaniel Salzman <daniel.salzman@nic.cz>
Wed, 25 Jun 2025 12:51:16 +0000 (14:51 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Fri, 27 Jun 2025 12:29:19 +0000 (14:29 +0200)
doc/reference.rst
src/knot/events/handlers/refresh.c
src/knot/query/requestor.c
src/knot/query/requestor.h

index 35de9dcb769fb823f65a844f897a78c93947f846..b6b8f814f415942a503cbdb34020ef0988d913d8 100644 (file)
@@ -1614,7 +1614,11 @@ no-edns
 
 If enabled, no OPT record (EDNS) is inserted to outgoing requests to this
 remote server. This mode is necessary for communication with some broken
-implementations (e.g. Windows Server 2016).
+DNS implementations (e.g. Windows Server 2016).
+
+Additionally, if TCP is used for zone refresh, the SOA query and the subsequent
+AXFR/IXFR query do not share the same TCP connection. This mode allows
+transfers from some broken DNS implementations (e.g. ixfrdist).
 
 .. NOTE::
    This option effectively disables :ref:`zone expire<Zone expiration>` timer
index 745200e816596d03190077ecd4274449d5c7884c..5fc6f04b99ae337a8bf578c66168edd622612a63 100644 (file)
@@ -1388,6 +1388,9 @@ static int try_refresh(conf_t *conf, zone_t *zone, const conf_remote_t *master,
        }
 
        knot_request_flag_t flags = conf->cache.srv_tcp_fastopen ? KNOT_REQUEST_TFO : 0;
+       if (data.edns.no_edns) {
+               flags |= KNOT_REQUEST_NEW;
+       }
        knot_request_t *req = knot_request_make(NULL, master, pkt, zone->server->quic_creds,
                                                &data.edns, flags);
        if (req == NULL) {
index 433fafd81f699154d085f8b3f440df416bdcb11f..2a117162bd9aea4b80dd76c9a0a0fee8af5f4203 100644 (file)
@@ -397,6 +397,11 @@ static int request_produce(knot_requestor_t *req, knot_request_t *last,
        }
 
        if (req->layer.state == KNOT_STATE_CONSUME) {
+               if ((last->flags & KNOT_REQUEST_NEW) &&
+                   !(last->flags & (KNOT_REQUEST_UDP | KNOT_REQUEST_TLS))) {
+                       close(last->fd);
+                       last->fd = -1;
+               }
                bool reused_fd = false;
                ret = request_send(last, timeout_ms, &reused_fd);
                if (ret != KNOT_EOK) {
index 0adef1d974a29acef53da60a6a34d7f04185f45b..88f0ccaf76edde9738bf7e673466493652fd472f 100644 (file)
@@ -24,6 +24,7 @@ typedef enum {
        KNOT_REQUEST_QUIC = 1 << 3,  /*!< Use QUIC/UDP for requests. */
        KNOT_REQUEST_TLS  = 1 << 4,  /*!< Use DoT for requests. */
        KNOT_REQUEST_FWD  = 1 << 5,  /*!< Forwarded message, don't modify (TSIG, PADDING). */
+       KNOT_REQUEST_NEW  = 1 << 6,  /*!< Ensure a new TCP connection is established. */
 } knot_request_flag_t;
 
 typedef enum {