From: Daniel Salzman Date: Fri, 5 Oct 2018 11:47:25 +0000 (+0200) Subject: knotd: add configurable answer rrset rotation determined by a query ID X-Git-Tag: v2.8.0~227 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de7d217d317265cf0fcfdce0431d41c127e689bc;p=thirdparty%2Fknot-dns.git knotd: add configurable answer rrset rotation determined by a query ID close #612 --- diff --git a/doc/man/knot.conf.5in b/doc/man/knot.conf.5in index 4ee4080921..048f79719f 100644 --- a/doc/man/knot.conf.5in +++ b/doc/man/knot.conf.5in @@ -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. diff --git a/doc/reference.rst b/doc/reference.rst index 37f194edbf..76277f37d5 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -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 diff --git a/src/knot/conf/base.c b/src/knot/conf/base.c index 29e83205d0..4fee4afa82 100644 --- a/src/knot/conf/base.c +++ b/src/knot/conf/base.c @@ -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( diff --git a/src/knot/conf/base.h b/src/knot/conf/base.h index aae7d76598..09a332f944 100644 --- a/src/knot/conf/base.h +++ b/src/knot/conf/base.h @@ -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. */ diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c index 95cfa1fe80..d903d75043 100644 --- a/src/knot/conf/schema.c +++ b/src/knot/conf/schema.c @@ -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 } }; diff --git a/src/knot/conf/schema.h b/src/knot/conf/schema.h index 63066c7857..5725ad8146 100644 --- a/src/knot/conf/schema.h +++ b/src/knot/conf/schema.h @@ -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" diff --git a/src/knot/nameserver/process_query.c b/src/knot/nameserver/process_query.c index 4d3641c667..4114c6aca4 100644 --- a/src/knot/nameserver/process_query.c +++ b/src/knot/nameserver/process_query.c @@ -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; diff --git a/tests/knot/test_confio.c b/tests/knot/test_confio.c index ef67bbdf90..00af7956e2 100644 --- a/tests/knot/test_confio.c +++ b/tests/knot/test_confio.c @@ -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 } };