From: Michał Kępień Date: Mon, 25 May 2020 12:34:56 +0000 (+0200) Subject: Restore semantic meaning of DNS_FETCHOPT_EDNS512 X-Git-Tag: v9.17.2~60^2~4 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=d7583e7926e317c1eeacd695eca6fb3ad661a8af;p=thirdparty%2Fbind9.git Restore semantic meaning of DNS_FETCHOPT_EDNS512 When the DNS_FETCHOPT_EDNS512 flag was first introduced [1], it enforced advertising a 512-byte UDP buffer size in an outgoing query. Ever since EDNS processing code got updated [2], that flag has still been set upon detection of certain query timeout patterns, but it has no longer been affecting the calculations of the advertised UDP buffer size in outgoing queries. Restore original semantic meaning of DNS_FETCHOPT_EDNS512 by ensuring the advertised UDP buffer size is set to 512 bytes when that flag is set. Update existing comments and add new ones to improve code readability. [1] see commit 08c90261660649ca7d92065f6f13a61ec5a9a86d [2] see commit 8e15d5eb3a000f1341e6bea0ddbc28d6dd2a0591 --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index f73f8b70f6c..77c6a99912c 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2588,6 +2588,15 @@ resquery_send(resquery_t *query) { isc_sockaddr_t *sockaddr = &query->addrinfo->sockaddr; struct tried *tried; + /* + * If this is the first timeout for this server in this fetch + * context, try setting EDNS UDP buffer size to the largest UDP + * response size we have seen from this server so far. + * + * If this server has already timed out twice or more in this + * fetch context, force setting the advertised UDP buffer size + * to 512 bytes. + */ if ((tried = triededns(fctx, sockaddr)) != NULL) { if (tried->count == 1U) { hint = dns_adb_getudpsize(fctx->adb, @@ -2613,9 +2622,17 @@ resquery_send(resquery_t *query) { unsigned char cookie[64]; uint16_t padding = 0; - if ((flags & FCTX_ADDRINFO_EDNSOK) != 0 && - (query->options & DNS_FETCHOPT_EDNS512) == 0) - { + /* + * If we ever received an EDNS response from this + * server, initialize 'udpsize' with a value between + * 512 and 4096, based on any potential EDNS timeouts + * observed for this particular server in the past and + * the total number of query timeouts observed for this + * fetch context so far. Clamp 'udpsize' to the global + * 'edns-udp-size' value (if unset, the latter defaults + * to 4096 bytes). + */ + if ((flags & FCTX_ADDRINFO_EDNSOK) != 0) { udpsize = dns_adb_probesize(fctx->adb, query->addrinfo, fctx->timeouts); @@ -2632,13 +2649,6 @@ resquery_send(resquery_t *query) { udpsize = 512; } - /* - * Was the size forced to 512 in the configuration? - */ - if (udpsize == 512U) { - query->options |= DNS_FETCHOPT_EDNS512; - } - /* * We have talked to this server before. */ @@ -2647,10 +2657,13 @@ resquery_send(resquery_t *query) { } /* - * We know nothing about the peer's capabilities - * so start with minimal EDNS UDP size. + * If we have not received any responses from this + * server before or if this server has already timed + * out twice or more in this fetch context, use an EDNS + * UDP buffer size of 512 bytes. */ - if (udpsize == 0U) { + if (udpsize == 0U || + (query->options & DNS_FETCHOPT_EDNS512) != 0) { udpsize = 512; }