diff options
Diffstat (limited to 'resolv/res_mkquery.c')
-rw-r--r-- | resolv/res_mkquery.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index 4532b58..8279d15 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -69,7 +69,7 @@ #include <netinet/in.h> #include <arpa/nameser.h> #include <netdb.h> -#include <resolv.h> +#include <resolv/resolv-internal.h> #include <stdio.h> #include <string.h> #include <sys/time.h> @@ -225,7 +225,30 @@ __res_nopt(res_state statp, *cp++ = 0; /* "." */ NS_PUT16(T_OPT, cp); /* TYPE */ - NS_PUT16(MIN(anslen, 0xffff), cp); /* CLASS = UDP payload size */ + + /* Lowering the advertised buffer size based on the actual + answer buffer size is desirable because the server will + minimize the reply to fit into the UDP packet (and A + non-minimal response might not fit the buffer). + + The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP + fallback and a non-minimal response which has to be + hard-truncated in the stub resolver, but this is price to + pay for avoiding fragmentation. (This issue does not + affect the nss_dns functions because they use the stub + resolver in such a way that it allocates a properly sized + response buffer.) */ + { + uint16_t buffer_size; + if (anslen < 512) + buffer_size = 512; + else if (anslen > RESOLV_EDNS_BUFFER_SIZE) + buffer_size = RESOLV_EDNS_BUFFER_SIZE; + else + buffer_size = anslen; + NS_PUT16 (buffer_size, cp); + } + *cp++ = NOERROR; /* extended RCODE */ *cp++ = 0; /* EDNS version */ @@ -243,4 +266,3 @@ __res_nopt(res_state statp, return cp - buf; } -libresolv_hidden_def (__res_nopt) |