From: Michał Kępień Date: Mon, 25 May 2020 12:34:56 +0000 (+0200) Subject: Ensure server-specific "edns-udp-size" is obeyed X-Git-Tag: v9.17.2~60^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d27f96cc98094cb44af0d03a2ed6d7238c9c2f8e;p=thirdparty%2Fbind9.git Ensure server-specific "edns-udp-size" is obeyed If "edns-udp-size" is set in a "server" block matching the queried server, it is accounted for in the process of determining the advertised UDP buffer size, but its value may still be overridden before the query is sent. This behavior contradicts the ARM which claims that when set, the server-specific "edns-udp-size" value is used for all EDNS queries sent to a given server. Furthermore, calling dns_peer_getudpsize() with the "udpsize" variable as an argument makes the code hard to follow as that call may either update the value of "udpsize" or leave it untouched. Ensure the code matches the documentation by moving the dns_peer_getudpsize() call below all other blocks of code potentially affecting the advertised UDP buffer size, which is where it was located when server-specific "edns-udp-size" support was first implemented [1]. Improve code readability by calling dns_peer_getudpsize() with a helper variable instead of "udpsize". [1] see commit 1c153afce556ff3c687986fb7c4a0b0a7f5e7cd8 --- diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 0ea798f90be..582a2c77b25 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -3412,6 +3412,9 @@ Tuning be sent without fragmentation at the minimum MTU sizes for Ethernet and IPv6 networks.) + Any server-specific ``edns-udp-size`` setting has precedence over all + the above rules. + ``max-udp-size`` Sets the maximum EDNS UDP message size ``named`` will send in bytes. Valid values are 512 to 4096 (values outside this range will be diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 77c6a99912c..99278a177ff 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2614,6 +2614,7 @@ resquery_send(resquery_t *query) { */ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { + uint16_t peerudpsize = 0; unsigned int version = DNS_EDNS_VERSION; unsigned int flags = query->addrinfo->flags; bool reqnsid = res->view->requestnsid; @@ -2641,14 +2642,6 @@ resquery_send(resquery_t *query) { } } - if (peer != NULL) { - (void)dns_peer_getudpsize(peer, &udpsize); - } - - if (udpsize == 0U && res->udpsize == 512U) { - udpsize = 512; - } - /* * We have talked to this server before. */ @@ -2667,6 +2660,17 @@ resquery_send(resquery_t *query) { udpsize = 512; } + /* + * If a fixed EDNS UDP buffer size is configured for + * this server, make sure we obey that. + */ + if (peer != NULL) { + (void)dns_peer_getudpsize(peer, &peerudpsize); + if (peerudpsize != 0) { + udpsize = peerudpsize; + } + } + if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) { version = flags & DNS_FETCHOPT_EDNSVERSIONMASK; version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;