]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
net: split the EDNS buffer size into upstream and downstream
authorVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 9 Sep 2020 14:34:27 +0000 (16:34 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 9 Sep 2020 14:34:27 +0000 (16:34 +0200)
(Tiny nitpicks addressed by vcunat.)

NEWS
daemon/bindings/net.c
daemon/bindings/net_dns_tweaks.rst
daemon/engine.c
daemon/lua/kres-gen.lua
daemon/worker.c
lib/resolve.c
lib/resolve.h

diff --git a/NEWS b/NEWS
index ef1e9620af3d269398662b587d7b52d89c967197..4edaee16e253d6238710344fe3e5e3359a61a7f6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+Knot Resolver 5.2.0 (2020-1m-dd)
+================================
+
+- net: split the EDNS buffer size into upstream and downstream (!1026)
+
+
 Knot Resolver 5.1.3 (2020-09-08)
 ================================
 
index f888225349b710e7c427e048e257bf68ab6204f4..2131d16cbf9002afd9716302f7c673598b580ed9 100644 (file)
@@ -298,15 +298,30 @@ static int net_interfaces(lua_State *L)
 /** Set UDP maximum payload size. */
 static int net_bufsize(lua_State *L)
 {
-       knot_rrset_t *opt_rr = the_worker->engine->resolver.opt_rr;
-       if (!lua_isnumber(L, 1)) {
-               lua_pushinteger(L, knot_edns_get_payload(opt_rr));
-               return 1;
+       struct kr_context *ctx = &the_worker->engine->resolver;
+       const int argc = lua_gettop(L);
+       if (argc == 0) {
+               lua_pushinteger(L, knot_edns_get_payload(ctx->downstream_opt_rr));
+               lua_pushinteger(L, knot_edns_get_payload(ctx->upstream_opt_rr));
+               return 2;
+       }
+
+       if (argc == 1) {
+               int bufsize = lua_tointeger(L, 1);
+               if (bufsize < 512 || bufsize > UINT16_MAX)
+                       lua_error_p(L, "bufsize must be within <512, " STR(UINT16_MAX) ">");
+               knot_edns_set_payload(ctx->downstream_opt_rr, (uint16_t)bufsize);
+               knot_edns_set_payload(ctx->upstream_opt_rr, (uint16_t)bufsize);
+       } else if (argc == 2) {
+               int bufsize_downstream = lua_tointeger(L, 1);
+               int bufsize_upstream = lua_tointeger(L, 2);
+               if (bufsize_downstream < 512 || bufsize_upstream < 512
+                   || bufsize_downstream > UINT16_MAX || bufsize_upstream > UINT16_MAX) {
+                       lua_error_p(L, "bufsize must be within <512, " STR(UINT16_MAX) ">");
+               }
+               knot_edns_set_payload(ctx->downstream_opt_rr, (uint16_t)bufsize_downstream);
+               knot_edns_set_payload(ctx->upstream_opt_rr, (uint16_t)bufsize_upstream);
        }
-       int bufsize = lua_tointeger(L, 1);
-       if (bufsize < 512 || bufsize > UINT16_MAX)
-               lua_error_p(L, "bufsize must be within <512, " STR(UINT16_MAX) ">");
-       knot_edns_set_payload(opt_rr, (uint16_t) bufsize);
        return 0;
 }
 
index 0a08b8ed5d07464cc4c4c90eaabad7e4d3bdf31b..baac568b60826c2e476eee5d4386ed7778855da4 100644 (file)
@@ -6,19 +6,26 @@ DNS protocol tweaks
 Following settings change low-level details of DNS protocol implementation.
 Default values should not be changed except for very special cases.
 
-.. function:: net.bufsize([udp_bufsize])
+.. function:: net.bufsize([udp_downstream_bufsize][, udp_upstream_bufsize])
 
-   Get/set maximum EDNS payload size advertised in DNS packets. Default is 4096 bytes and the default will be lowered to value around 1220 bytes in future, once `DNS Flag Day 2020 <https://dnsflagday.net/>`_ becomes effective.
+   Get/set maximum EDNS payload size advertised in DNS packets. Default is 4096 bytes and the default will be lowered to value around 1232 bytes in future, once `DNS Flag Day 2020 <https://dnsflagday.net/2020/>`_ becomes effective.
 
-   Minimal value allowed by standard :rfc:`6891` is 512 bytes, which is equal to DNS packet size without Extension Mechanisms for DNS. Value 1220 bytes is minimum size required in DNSSEC standard :rfc:`4035`.
+   Minimal value allowed by standard :rfc:`6891` is 512 bytes, which is equal to DNS packet size without Extension Mechanisms for DNS. Value 1220 bytes is minimum size required by DNSSEC standard :rfc:`4035`.
 
    Example output:
 
    .. code-block:: lua
 
+       -- set downstream and upstream bufsize to value 4096
        > net.bufsize(4096)
-       nil
        > net.bufsize()
        4096
+       4096
+
+       -- set downstream bufsize to 4096 and upstream bufsize to 1232
+       > net.bufsize(4096, 1232)
+       > net.bufsize()
+       4096
+       1232
 
 .. include:: ../modules/workarounds/README.rst
index c45e99010bc9cde803b463c3a5cade8b80f899b5..52894f891c6a424ffa1e0e3af14d8dc96c959728 100644 (file)
@@ -441,11 +441,13 @@ static int init_resolver(struct engine *engine)
        engine->resolver.modules = &engine->modules;
        engine->resolver.cache_rtt_tout_retry_interval = KR_NS_TIMEOUT_RETRY_INTERVAL;
        /* Create OPT RR */
-       engine->resolver.opt_rr = mm_alloc(engine->pool, sizeof(knot_rrset_t));
-       if (!engine->resolver.opt_rr) {
+       engine->resolver.downstream_opt_rr = mm_alloc(engine->pool, sizeof(knot_rrset_t));
+       engine->resolver.upstream_opt_rr = mm_alloc(engine->pool, sizeof(knot_rrset_t));
+       if (!engine->resolver.downstream_opt_rr || !engine->resolver.upstream_opt_rr) {
                return kr_error(ENOMEM);
        }
-       knot_edns_init(engine->resolver.opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, engine->pool);
+       knot_edns_init(engine->resolver.downstream_opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, engine->pool);
+       knot_edns_init(engine->resolver.upstream_opt_rr, KR_EDNS_PAYLOAD, 0, KR_EDNS_VERSION, engine->pool);
        /* Use default TLS padding */
        engine->resolver.tls_padding = -1;
        /* Empty init; filled via ./lua/postconfig.lua */
index b72ba66dd5c1d8d2a043b63b44b251293d29de9f..7ba576f15002960011b7f82ed38a0d3fc5159c4c 100644 (file)
@@ -295,7 +295,8 @@ struct kr_query {
 };
 struct kr_context {
        struct kr_qflags options;
-       knot_rrset_t *opt_rr;
+       knot_rrset_t *downstream_opt_rr;
+       knot_rrset_t *upstream_opt_rr;
        map_t trust_anchors;
        map_t negative_anchors;
        struct kr_zonecut root_hints;
index d28c26befdd52a8d567534a5e7c560b2299aa358..d4ad9619f62de2b37cc8a8075b00d31cf87b6f1d 100644 (file)
@@ -379,7 +379,7 @@ static struct qr_task *qr_task_create(struct request_ctx *ctx)
         * for UDP answers from upstream *and* from cache
         * and for sending non-UDP queries upstream (?) */
        uint16_t pktbuf_max = KR_EDNS_PAYLOAD;
-       const knot_rrset_t *opt_our = ctx->worker->engine->resolver.opt_rr;
+       const knot_rrset_t *opt_our = ctx->worker->engine->resolver.upstream_opt_rr;
        if (opt_our) {
                pktbuf_max = MAX(pktbuf_max, knot_edns_get_payload(opt_our));
        }
@@ -1797,7 +1797,7 @@ knot_pkt_t * worker_resolve_mk_pkt(const char *qname_str, uint16_t qtype, uint16
 
        /* Add OPT RR, including wire format so modules can see both representations.
         * knot_pkt_put() copies the outside; we need to duplicate the inside manually. */
-       knot_rrset_t *opt = knot_rrset_copy(the_worker->engine->resolver.opt_rr, NULL);
+       knot_rrset_t *opt = knot_rrset_copy(the_worker->engine->resolver.downstream_opt_rr, NULL);
        if (!opt) {
                knot_pkt_free(pkt);
                return NULL;
index 146428855178e8e26370a3dbf8ac501efdc561f9..9828cbfa5e1fae3061c902a7a7a7b0de360c4654 100644 (file)
@@ -422,7 +422,7 @@ static int edns_erase_and_reserve(knot_pkt_t *pkt)
 
 static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template, struct kr_request *req)
 {
-       pkt->opt_rr = knot_rrset_copy(req->ctx->opt_rr, &pkt->mm);
+       pkt->opt_rr = knot_rrset_copy(req->ctx->upstream_opt_rr, &pkt->mm);
        size_t wire_size = knot_edns_wire_size(pkt->opt_rr);
 #if defined(ENABLE_COOKIES)
        if (req->ctx->cookie_ctx.clnt.enabled ||
@@ -450,7 +450,7 @@ static int answer_prepare(struct kr_request *req, knot_pkt_t *query)
        }
        /* Handle EDNS in the query */
        if (knot_pkt_has_edns(query)) {
-               answer->opt_rr = knot_rrset_copy(req->ctx->opt_rr, &answer->mm);
+               answer->opt_rr = knot_rrset_copy(req->ctx->downstream_opt_rr, &answer->mm);
                if (answer->opt_rr == NULL){
                        return kr_error(ENOMEM);
                }
index 17d16f1ae28a88d80262350c4a5e4697f7c38cdd..3a22430693e7d819519de79d3fbaf4bef2cd4a82 100644 (file)
@@ -140,7 +140,8 @@ struct kr_context
        /** Default EDNS towards *both* clients and upstream.
         * LATER: consider splitting the two, e.g. allow separately
         * configured limits for UDP packet size (say, LAN is under control). */
-       knot_rrset_t *opt_rr;
+       knot_rrset_t *downstream_opt_rr;
+       knot_rrset_t *upstream_opt_rr;
 
        map_t trust_anchors;
        map_t negative_anchors;