Commit bb990030 authored by Ondřej Surý's avatar Ondřej Surý

Simplify the EDNS buffer size logic for DNS Flag Day 2020

The DNS Flag Day 2020 aims to remove the IP fragmentation problem from
the UDP DNS communication.  In this commit, we implement the required
changes and simplify the logic for picking the EDNS Buffer Size.

1. The defaults for `edns-udp-size`, `max-udp-size` and
   `nocookie-udp-size` have been changed to `1232` (the value picked by
   DNS Flag Day 2020).

2. The probing heuristics that would try 512->4096->1432->1232 buffer
   sizes has been removed and the resolver will always use just the
   `edns-udp-size` value.

3. Instead of just disabling the PMTUD mechanism on the UDP sockets, we
   now set IP_DONTFRAG (IPV6_DONTFRAG) flag.  That means that the UDP
   packets won't get ever fragmented.  If the ICMP packets are lost the
   UDP will just timeout and eventually be retried over TCP.
parent d51f09a8
......@@ -59,7 +59,7 @@ options {\n\
# directory <none>\n\
dnssec-policy \"none\";\n\
dump-file \"named_dump.db\";\n\
edns-udp-size 4096;\n\
edns-udp-size 1232;\n\
# fake-iquery <obsolete>;\n"
#ifndef WIN32
" files unlimited;\n"
......@@ -83,11 +83,11 @@ options {\n\
match-mapped-addresses no;\n\
max-ixfr-ratio 100%;\n\
max-rsa-exponent-size 0; /* no limit */\n\
max-udp-size 4096;\n\
max-udp-size 1232;\n\
memstatistics-file \"named.memstats\";\n\
# multiple-cnames <obsolete>;\n\
# named-xfer <obsolete>;\n\
nocookie-udp-size 4096;\n\
nocookie-udp-size 1232;\n\
notify-rate 20;\n\
nta-lifetime 3600;\n\
nta-recheck 300;\n\
......
......@@ -1842,7 +1842,7 @@ Boolean Options
``nocookie-udp-size``
This sets the maximum size of UDP responses that are sent to queries
without a valid server COOKIE. A value below 128 is silently
raised to 128. The default value is 4096, but the ``max-udp-size``
raised to 128. The default value is 1232, but the ``max-udp-size``
option may further limit the response size.
``sit-secret``
......@@ -3399,7 +3399,7 @@ Tuning
the size of packets received from authoritative servers in response
to recursive queries. Valid values are 512 to 4096; values outside
this range are silently adjusted to the nearest value within it.
The default value is 4096.
The default value is 1232.
The usual reason for setting ``edns-udp-size`` to a non-default value
is to get UDP answers to pass through broken firewalls that block
......@@ -3407,26 +3407,12 @@ Tuning
512 bytes.
When ``named`` first queries a remote server, it advertises a UDP
buffer size of 512, as this has the greatest chance of success on the
first try.
If the initial query is successful with EDNS advertising a buffer
size of 512, then ``named`` switches to advertising a buffer size
of 4096 bytes (unless ``edns-udp-size`` is lower, in which case the
latter will be used).
Query timeouts observed for any given server affect the buffer
size advertised in queries sent to that server. Depending on
observed packet dropping patterns, the advertised buffer size is
lowered to 1432 bytes, 1232 bytes, 512 bytes, or the size of the
largest UDP response ever received from a given server, and then
clamped to the ``<512, edns-udp-size>`` range. Per-server EDNS
statistics are only retained in memory for the lifetime of a given
server's ADB entry.
(The values 1232 and 1432 are chosen to allow for an
IPv4-/IPv6-encapsulated UDP message to be sent without fragmentation at the
minimum MTU sizes for Ethernet and IPv6 networks.)
buffer size of 1232.
Query timeouts observed for any given server affect the buffer size
advertised in queries sent to that server. Depending on observed packet
dropping patterns, the query is retried over TCP. Per-server EDNS statistics
are only retained in memory for the lifetime of a given server's ADB entry.
Any server-specific ``edns-udp-size`` setting has precedence over all
the above rules.
......@@ -3435,7 +3421,7 @@ Tuning
This sets the maximum EDNS UDP message size that ``named`` sends, in bytes.
Valid values are 512 to 4096; values outside this range are
silently adjusted to the nearest value within it. The default value
is 4096.
is 1232.
This value applies to responses sent by a server; to set the
advertised buffer size in queries, see ``edns-udp-size``.
......
......@@ -249,20 +249,13 @@ struct dns_adbentry {
unsigned char plain;
unsigned char plainto;
unsigned char edns;
unsigned char to4096; /* Our max. */
unsigned char ednsto;
uint8_t mode;
atomic_uint_fast32_t quota;
atomic_uint_fast32_t active;
double atr;
/*
* Allow for encapsulated IPv4/IPv6 UDP packet over ethernet.
* Ethernet 1500 - IP(20) - IP6(40) - UDP(8) = 1432.
*/
unsigned char to1432; /* Ethernet */
unsigned char to1232; /* IPv6 nofrag */
unsigned char to512; /* plain DNS */
isc_sockaddr_t sockaddr;
unsigned char *cookie;
uint16_t cookielen;
......@@ -1893,14 +1886,11 @@ new_adbentry(dns_adb_t *adb) {
e->flags = 0;
e->udpsize = 0;
e->edns = 0;
e->ednsto = 0;
e->completed = 0;
e->timeouts = 0;
e->plain = 0;
e->plainto = 0;
e->to4096 = 0;
e->to1432 = 0;
e->to1232 = 0;
e->to512 = 0;
e->cookie = NULL;
e->cookielen = 0;
e->srtt = (isc_random_uniform(0x1f)) + 1;
......@@ -3529,8 +3519,7 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
dns_adbentry_t *entry;
fprintf(f, ";\n; Address database dump\n;\n");
fprintf(f, "; [edns success/4096 timeout/1432 timeout/1232 timeout/"
"512 timeout]\n");
fprintf(f, "; [edns success/timeout]\n");
fprintf(f, "; [plain success/timeout]\n;\n");
if (debug) {
LOCK(&adb->reflock);
......@@ -3656,11 +3645,10 @@ dump_entry(FILE *f, dns_adb_t *adb, dns_adbentry_t *entry, bool debug,
}
fprintf(f,
";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] "
";\t%s [srtt %u] [flags %08x] [edns %u/%u] "
"[plain %u/%u]",
addrbuf, entry->srtt, entry->flags, entry->edns, entry->to4096,
entry->to1432, entry->to1232, entry->to512, entry->plain,
entry->plainto);
addrbuf, entry->srtt, entry->flags, entry->edns, entry->ednsto,
entry->plain, entry->plainto);
if (entry->udpsize != 0U) {
fprintf(f, " [udpsize %u]", entry->udpsize);
}
......@@ -4437,41 +4425,6 @@ maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) {
}
#define EDNSTOS 3U
bool
dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
int bucket;
bool noedns = false;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
if (addr->entry->edns == 0U &&
(addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS))
{
if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) {
noedns = true;
} else {
/*
* Increment plain so we don't get stuck.
*/
addr->entry->plain++;
if (addr->entry->plain == 0xff) {
addr->entry->edns >>= 1;
addr->entry->to4096 >>= 1;
addr->entry->to1432 >>= 1;
addr->entry->to1232 >>= 1;
addr->entry->to512 >>= 1;
addr->entry->plain >>= 1;
addr->entry->plainto >>= 1;
}
}
}
UNLOCK(&adb->entrylocks[bucket]);
return (noedns);
}
void
dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
......@@ -4488,10 +4441,7 @@ dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
addr->entry->plain++;
if (addr->entry->plain == 0xff) {
addr->entry->edns >>= 1;
addr->entry->to4096 >>= 1;
addr->entry->to1432 >>= 1;
addr->entry->to1232 >>= 1;
addr->entry->to512 >>= 1;
addr->entry->ednsto >>= 1;
addr->entry->plain >>= 1;
addr->entry->plainto >>= 1;
}
......@@ -4510,25 +4460,10 @@ dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
maybe_adjust_quota(adb, addr, true);
/*
* If we have not had a successful query then clear all
* edns timeout information.
*/
if (addr->entry->edns == 0 && addr->entry->plain == 0) {
addr->entry->to512 = 0;
addr->entry->to1232 = 0;
addr->entry->to1432 = 0;
addr->entry->to4096 = 0;
} else {
addr->entry->to512 >>= 1;
addr->entry->to1232 >>= 1;
addr->entry->to1432 >>= 1;
addr->entry->to4096 >>= 1;
}
addr->entry->plainto++;
if (addr->entry->plainto == 0xff) {
addr->entry->edns >>= 1;
addr->entry->ednsto >>= 1;
addr->entry->plain >>= 1;
addr->entry->plainto >>= 1;
}
......@@ -4536,7 +4471,7 @@ dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
}
void
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
int bucket;
REQUIRE(DNS_ADB_VALID(adb));
......@@ -4547,36 +4482,10 @@ dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
maybe_adjust_quota(adb, addr, true);
if (size <= 512U) {
if (addr->entry->to512 <= EDNSTOS) {
addr->entry->to512++;
addr->entry->to1232++;
addr->entry->to1432++;
addr->entry->to4096++;
}
} else if (size <= 1232U) {
if (addr->entry->to1232 <= EDNSTOS) {
addr->entry->to1232++;
addr->entry->to1432++;
addr->entry->to4096++;
}
} else if (size <= 1432U) {
if (addr->entry->to1432 <= EDNSTOS) {
addr->entry->to1432++;
addr->entry->to4096++;
}
} else {
if (addr->entry->to4096 <= EDNSTOS) {
addr->entry->to4096++;
}
}
if (addr->entry->to4096 == 0xff) {
addr->entry->ednsto++;
if (addr->entry->ednsto == 0xff) {
addr->entry->edns >>= 1;
addr->entry->to4096 >>= 1;
addr->entry->to1432 >>= 1;
addr->entry->to1232 >>= 1;
addr->entry->to512 >>= 1;
addr->entry->ednsto >>= 1;
addr->entry->plain >>= 1;
addr->entry->plainto >>= 1;
}
......@@ -4604,10 +4513,7 @@ dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
addr->entry->edns++;
if (addr->entry->edns == 0xff) {
addr->entry->edns >>= 1;
addr->entry->to4096 >>= 1;
addr->entry->to1432 >>= 1;
addr->entry->to1232 >>= 1;
addr->entry->to512 >>= 1;
addr->entry->ednsto >>= 1;
addr->entry->plain >>= 1;
addr->entry->plainto >>= 1;
}
......@@ -4630,38 +4536,6 @@ dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
return (size);
}
unsigned int
dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups) {
int bucket;
unsigned int size;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
if (addr->entry->to1232 > EDNSTOS || lookups >= 2) {
size = 512;
} else if (addr->entry->to1432 > EDNSTOS || lookups >= 1) {
size = 1232;
} else if (addr->entry->to4096 > EDNSTOS) {
size = 1432;
} else {
size = 4096;
}
/*
* Don't shrink probe size below what we have seen due to multiple
* lookups.
*/
if (lookups > 0 && size < addr->entry->udpsize &&
addr->entry->udpsize < 4096) {
size = addr->entry->udpsize;
}
UNLOCK(&adb->entrylocks[bucket]);
return (size);
}
void
dns_adb_setcookie(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
const unsigned char *cookie, size_t len) {
......
......@@ -606,19 +606,6 @@ dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
*\li addr be valid.
*/
unsigned int
dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, int lookups);
/*%
* Return suggested EDNS UDP size based on observed responses / failures.
* 'lookups' is the number of times the current lookup has been attempted.
*
* Requires:
*
*\li adb be valid.
*
*\li addr be valid.
*/
void
dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
/*%
......@@ -644,22 +631,9 @@ dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
*/
void
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size);
/*%
* Record a failed EDNS UDP response and the advertised EDNS UDP buffer size
* used.
*
* Requires:
*
*\li adb be valid.
*
*\li addr be valid.
*/
bool
dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
/*%
* Return whether EDNS should be disabled for this server.
* Record a EDNS UDP query failed.
*
* Requires:
*
......
......@@ -94,13 +94,11 @@ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t;
#define DNS_FETCHOPT_NOEDNS0 0x00000008 /*%< Do not use EDNS. */
#define DNS_FETCHOPT_FORWARDONLY 0x00000010 /*%< Only use forwarders. */
#define DNS_FETCHOPT_NOVALIDATE 0x00000020 /*%< Disable validation. */
#define DNS_FETCHOPT_EDNS512 \
0x00000040 /*%< Advertise a 512 byte \
* UDP buffer. */
#define DNS_FETCHOPT_WANTNSID 0x00000080 /*%< Request NSID */
#define DNS_FETCHOPT_PREFETCH 0x00000100 /*%< Do prefetch */
#define DNS_FETCHOPT_NOCDFLAG 0x00000200 /*%< Don't set CD flag. */
#define DNS_FETCHOPT_NONTA 0x00000400 /*%< Ignore NTA table. */
#define DNS_FETCHOPT_OBSOLETE1 0x00000040 /*%< Obsolete */
#define DNS_FETCHOPT_WANTNSID 0x00000080 /*%< Request NSID */
#define DNS_FETCHOPT_PREFETCH 0x00000100 /*%< Do prefetch */
#define DNS_FETCHOPT_NOCDFLAG 0x00000200 /*%< Don't set CD flag. */
#define DNS_FETCHOPT_NONTA 0x00000400 /*%< Ignore NTA table. */
/* RESERVED ECS 0x00000000 */
/* RESERVED ECS 0x00001000 */
/* RESERVED ECS 0x00002000 */
......
......@@ -203,6 +203,11 @@
*/
#define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */
/*%
* Default EDNS0 buffer size
*/
#define DEFAULT_EDNS_BUFSIZE 1232
/*%
* This defines the maximum number of timeouts we will permit before we
* disable EDNS0 on the query.
......@@ -316,7 +321,6 @@ struct fetchctx {
dns_fwdpolicy_t fwdpolicy;
isc_sockaddrlist_t bad;
ISC_LIST(struct tried) edns;
ISC_LIST(struct tried) edns512;
isc_sockaddrlist_t bad_edns;
dns_validator_t *validator;
ISC_LIST(dns_validator_t) validators;
......@@ -1215,7 +1219,7 @@ update_edns_stats(resquery_t *query) {
}
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
dns_adb_ednsto(fctx->adb, query->addrinfo, query->udpsize);
dns_adb_ednsto(fctx->adb, query->addrinfo);
} else {
dns_adb_timeout(fctx->adb, query->addrinfo);
}
......@@ -2321,38 +2325,6 @@ add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
ISC_LIST_INITANDAPPEND(fctx->edns, tried, link);
}
static struct tried *
triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
struct tried *tried;
for (tried = ISC_LIST_HEAD(fctx->edns512); tried != NULL;
tried = ISC_LIST_NEXT(tried, link))
{
if (isc_sockaddr_equal(&tried->addr, address)) {
return (tried);
}
}
return (NULL);
}
static void
add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
struct tried *tried;
tried = triededns512(fctx, address);
if (tried != NULL) {
tried->count++;
return;
}
tried = isc_mem_get(fctx->mctx, sizeof(*tried));
tried->addr = *address;
tried->count = 1;
ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link);
}
static inline size_t
addr2buf(void *buf, const size_t bufsize, const isc_sockaddr_t *sockaddr) {
isc_netaddr_t netaddr;
......@@ -2607,15 +2579,14 @@ resquery_send(resquery_t *query) {
* 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.
* fetch context, force TCP.
*/
if ((tried = triededns(fctx, sockaddr)) != NULL) {
if (tried->count == 1U) {
hint = dns_adb_getudpsize(fctx->adb,
query->addrinfo);
} else if (tried->count >= 2U) {
query->options |= DNS_FETCHOPT_EDNS512;
query->options |= DNS_FETCHOPT_TCP;
}
}
}
......@@ -2637,23 +2608,10 @@ resquery_send(resquery_t *query) {
uint16_t padding = 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).
* Set the default UDP size to what was configured as
* 'edns-buffer-size'
*/
if ((flags & FCTX_ADDRINFO_EDNSOK) != 0) {
udpsize = dns_adb_probesize(fctx->adb,
query->addrinfo,
fctx->timeouts);
if (udpsize > res->udpsize) {
udpsize = res->udpsize;
}
}
udpsize = res->udpsize;
/*
* This server timed out for the first time in this
......@@ -2667,17 +2625,6 @@ resquery_send(resquery_t *query) {
udpsize = hint;
}
/*
* 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 ||
(query->options & DNS_FETCHOPT_EDNS512) != 0) {
udpsize = 512;
}
/*
* If a fixed EDNS UDP buffer size is configured for
* this server, make sure we obey that.
......@@ -2805,13 +2752,7 @@ resquery_send(resquery_t *query) {
goto cleanup_message;
}
if (udpsize > 512U) {
add_triededns(fctx, &query->addrinfo->sockaddr);
}
if (udpsize == 512U) {
add_triededns512(fctx, &query->addrinfo->sockaddr);
}
add_triededns(fctx, &query->addrinfo->sockaddr);
/*
* Clear CD if EDNS is not in use.
......@@ -3101,17 +3042,10 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
isc_socket_detach(&query->tcpsocket);
/*
* Do not query this server again in this fetch context
* if we already tried reducing the advertised EDNS UDP
* payload size to 512 bytes and the server is
* unavailable over TCP. This prevents query loops
* lasting until the fetch context restart limit is
* reached when attempting to get answers whose size
* exceeds 512 bytes from broken servers.
* if the server is unavailable over TCP.
*/
if ((query->options & DNS_FETCHOPT_EDNS512) != 0) {
add_bad(fctx, query->rmessage, query->addrinfo,
sevent->result, badns_unreachable);
}
add_bad(fctx, query->rmessage, query->addrinfo,
sevent->result, badns_unreachable);
fctx_cancelquery(&query, NULL, NULL, true, false);
retry = true;
break;
......@@ -4556,13 +4490,6 @@ fctx_destroy(fetchctx_t *fctx) {
isc_mem_put(fctx->mctx, tried, sizeof(*tried));
}
for (tried = ISC_LIST_HEAD(fctx->edns512); tried != NULL;
tried = ISC_LIST_HEAD(fctx->edns512))
{
ISC_LIST_UNLINK(fctx->edns512, tried, link);
isc_mem_put(fctx->mctx, tried, sizeof(*tried));
}
for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL; sa = next_sa) {
next_sa = ISC_LIST_NEXT(sa, link);
ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
......@@ -4993,7 +4920,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
fctx->fwdpolicy = dns_fwdpolicy_none;
ISC_LIST_INIT(fctx->bad);
ISC_LIST_INIT(fctx->edns);
ISC_LIST_INIT(fctx->edns512);
ISC_LIST_INIT(fctx->bad_edns);
ISC_LIST_INIT(fctx->validators);
fctx->validator = NULL;
......@@ -10190,7 +10116,7 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
res->options = options;
res->lame_ttl = 0;
ISC_LIST_INIT(res->alternates);
res->udpsize = RECV_BUFFER_SIZE;
res->udpsize = DEFAULT_EDNS_BUFSIZE;
res->algorithms = NULL;
res->digests = NULL;
res->badcache = NULL;
......
......@@ -49,9 +49,7 @@ dns_adb_freeaddrinfo
dns_adb_getcookie
dns_adb_getudpsize
dns_adb_marklame
dns_adb_noedns
dns_adb_plainresponse
dns_adb_probesize
dns_adb_setadbsize
dns_adb_setcookie
dns_adb_setquota
......
......@@ -2102,6 +2102,32 @@ set_tcp_maxseg(isc__socket_t *sock, int size) {
#endif /* ifdef TCP_MAXSEG */
}
static void
set_ip_dontfrag(isc__socket_t *sock) {
/*
* Set the Don't Fragment flag on IP packets
*/
if (sock->pf == AF_INET6) {
#if defined(IPV6_DONTFRAG)
(void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_DONTFRAG,
&(int){ 1 }, sizeof(int));
#endif
#if defined(IPV6_MTU_DISCOVER)
(void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
&(int){ IP_PMTUDISC_DO }, sizeof(int));
#endif
} else if (sock->pf == AF_INET) {
#if defined(IP_DONTFRAG)
(void)setsockopt(sock->fd, IPPROTO_IP, IP_DONTFRAG, &(int){ 1 },
sizeof(int));
#endif
#if defined(IP_MTU_DISCOVER)
(void)setsockopt(sock->fd, IPPROTO_IP, IP_MTU_DISCOVER,
&(int){ IP_PMTUDISC_DO }, sizeof(int));
#endif
}
}
static isc_result_t
opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
isc__socket_t *dup_socket) {
......@@ -2320,52 +2346,9 @@ again:
sock->fd, strbuf);
}
#endif /* IPV6_RECVPKTINFO */
#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
/*
* Turn off Path MTU discovery on IPv6/UDP sockets.
*/
if (sock->pf == AF_INET6) {
int action = IPV6_PMTUDISC_DONT;
(void)setsockopt(sock->fd, IPPROTO_IPV6,
IPV6_MTU_DISCOVER, &action,
sizeof(action));
}
#endif /* if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT) */