]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
knotd: add configurable answer rrset rotation determined by a query ID
authorDaniel Salzman <daniel.salzman@nic.cz>
Fri, 5 Oct 2018 11:47:25 +0000 (13:47 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Sun, 7 Oct 2018 19:25:52 +0000 (21:25 +0200)
close #612

doc/man/knot.conf.5in
doc/reference.rst
src/knot/conf/base.c
src/knot/conf/base.h
src/knot/conf/schema.c
src/knot/conf/schema.h
src/knot/nameserver/process_query.c
tests/knot/test_confio.c

index 4ee408092106bef2d11ddd1adccea127a9a05a55..048f79719f0ab6b30e0fd2ec869fcd39bb7c0dde 100644 (file)
@@ -191,6 +191,7 @@ server:
     max\-ipv4\-udp\-payload: SIZE
     max\-ipv6\-udp\-payload: SIZE
     edns\-client\-subnet: BOOL
+    answer\-rotation: BOOL
     listen: ADDR[@INT] ...
 .ft P
 .fi
@@ -298,10 +299,17 @@ Maximum EDNS0 UDP payload size for IPv6.
 \fIDefault:\fP 4096
 .SS edns\-client\-subnet
 .sp
-Enable or disable EDNS Client Subnet support. If enabled, responses to queries containing the EDNS Client Subnet option
+Enable or disable EDNS Client Subnet support. If enabled, responses to queries
+containing the EDNS Client Subnet option
 always contain a valid EDNS Client Subnet option according to \fI\%RFC 7871\fP\&.
 .sp
 \fIDefault:\fP off
+.SS answer\-rotation
+.sp
+Enable or disable sorted\-rrset rotation in the answer section of normal replies.
+The rotation shift is simply determined by a query ID.
+.sp
+\fIDefault:\fP off
 .SS listen
 .sp
 One or more IP addresses where the server listens for incoming queries.
index 37f194edbff5c86c2009c7c790c5f195b28f9b0d..76277f37d5a916a60a0bdff6c1181b90bd9902ae 100644 (file)
@@ -142,6 +142,7 @@ General options related to the server.
      max-ipv4-udp-payload: SIZE
      max-ipv6-udp-payload: SIZE
      edns-client-subnet: BOOL
+     answer-rotation: BOOL
      listen: ADDR[@INT] ...
 
 .. _server_identity:
@@ -317,11 +318,22 @@ Maximum EDNS0 UDP payload size for IPv6.
 edns-client-subnet
 ------------------
 
-Enable or disable EDNS Client Subnet support. If enabled, responses to queries containing the EDNS Client Subnet option
+Enable or disable EDNS Client Subnet support. If enabled, responses to queries
+containing the EDNS Client Subnet option
 always contain a valid EDNS Client Subnet option according to :rfc:`7871`.
 
 *Default:* off
 
+.. _server_answer-rotation:
+
+answer-rotation
+---------------
+
+Enable or disable sorted-rrset rotation in the answer section of normal replies.
+The rotation shift is simply determined by a query ID.
+
+*Default:* off
+
 .. _server_listen:
 
 listen
index 29e83205d0ad7324c1ba4244e710b8d66bbd0556..4fee4afa82d4cf952c86648b50c18930e33c6bda 100644 (file)
@@ -140,6 +140,9 @@ static void init_cache(
 
        val = conf_get(conf, C_SRV, C_ECS);
        conf->cache.use_ecs = conf_bool(&val);
+
+       val = conf_get(conf, C_SRV, C_ANS_ROTATION);
+       conf->cache.srv_ans_rotate = conf_bool(&val);
 }
 
 int conf_new(
index aae7d76598f3ac338e30bd36a1a1f89ecab8858f..09a332f94437265c82a92511e4df3766ae2a683b 100644 (file)
@@ -115,6 +115,7 @@ typedef struct {
                int32_t ctl_timeout;
                conf_val_t srv_nsid;
                bool use_ecs;
+               bool srv_ans_rotate;
        } cache;
 
        /*! List of dynamically loaded modules. */
index 95cfa1fe8023c5a5f748f5342b5e592cef90a42e..d903d7504379da5beb31b26edbf78c3d322903b3 100644 (file)
@@ -158,6 +158,7 @@ static const yp_item_t desc_server[] = {
        { C_LISTEN,               YP_TADDR, YP_VADDR = { 53 }, YP_FMULTI },
        { C_COMMENT,              YP_TSTR,  YP_VNONE },
        { C_ECS,                  YP_TBOOL, YP_VNONE },
+       { C_ANS_ROTATION,         YP_TBOOL, YP_VNONE },
        { NULL }
 };
 
index 63066c785772f58318b9264ca938c5301c0ab5cd..5725ad8146307130f277cf22c78ede8bc33ad6c5 100644 (file)
@@ -23,6 +23,7 @@
 #define C_ACTION               "\x06""action"
 #define C_ADDR                 "\x07""address"
 #define C_ALG                  "\x09""algorithm"
+#define C_ANS_ROTATION         "\x0F""answer-rotation"
 #define C_ANY                  "\x03""any"
 #define C_APPEND               "\x06""append"
 #define C_ASYNC_START          "\x0B""async-start"
index 4d3641c6670b1aaa952e4f35c7f368a6b61c2393..4114c6aca4e04111677984037c803ddfe803cc81 100644 (file)
@@ -858,8 +858,9 @@ int process_query_put_rr(knot_pkt_t *pkt, knotd_qdata_t *qdata,
                to_add = *rr;
        }
 
+       uint16_t rotate = conf()->cache.srv_ans_rotate ? knot_wire_get_id(qdata->query->wire) : 0;
        uint16_t prev_count = pkt->rrset_count;
-       ret = knot_pkt_put(pkt, compr_hint, &to_add, flags);
+       ret = knot_pkt_put_rotate(pkt, compr_hint, &to_add, rotate, flags);
        if (ret != KNOT_EOK && (flags & KNOT_PF_FREE)) {
                knot_rrset_clear(&to_add, &pkt->mm);
                return ret;
index ef67bbdf9088fdb7b3730eb31269cbb214c29621..00af7956e22289d23f32786d66d3c794c3f736e1 100644 (file)
@@ -909,7 +909,8 @@ static void test_conf_io_list(void)
              "server.max-udp-payload\n"
              "server.max-ipv4-udp-payload\n"
              "server.max-ipv6-udp-payload\n"
-             "server.edns-client-subnet";
+             "server.edns-client-subnet\n"
+             "server.answer-rotation";
        ok(strcmp(ref, out) == 0, "compare result");
 }
 
@@ -926,6 +927,7 @@ static const yp_item_t desc_server[] = {
        { C_MAX_IPV4_UDP_PAYLOAD, YP_TINT,  YP_VNONE },
        { C_MAX_IPV6_UDP_PAYLOAD, YP_TINT,  YP_VNONE },
        { C_ECS,                  YP_TBOOL, YP_VNONE },
+       { C_ANS_ROTATION,         YP_TBOOL, YP_VNONE },
        { NULL }
 };