]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Disable the PMTUD also on the old socket UDP code
authorOndřej Surý <ondrej@sury.org>
Wed, 23 Sep 2020 12:47:26 +0000 (14:47 +0200)
committerOndřej Surý <ondrej@sury.org>
Wed, 23 Jun 2021 19:06:05 +0000 (21:06 +0200)
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.

doc/arm/reference.rst
lib/isc/unix/socket.c

index 76a83e5e85d197f8de4f8c98331f3ee8da6fbc8c..6ad8b71e4f78a20403ca5206a71d66158b580cef 100644 (file)
@@ -1886,7 +1886,7 @@ Boolean Options
    without a valid server COOKIE. A value below 128 is silently
    raised to 128. The default value is 4096, but the ``max-udp-size``
    option may further limit the response size as the default for
-   ``max-udp-size`` is 1232.
+   ``max-udp-size`` is 4096.
 
 ``sit-secret``
    This experimental option is obsolete.
index 4ccf58852a2db0ccea2ff432d4bfacfb902415f6..bc260d222f13844c969f6a8202d2868a8ce2f065 100644 (file)
@@ -2099,6 +2099,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) {
@@ -2317,53 +2343,8 @@ 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) */
 #endif /* defined(USE_CMSG) */
 
-#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
-               /*
-                * Turn off Path MTU discovery on IPv4/UDP sockets.
-                * Prefer IP_PMTUDISC_OMIT over IP_PMTUDISC_DONT
-                * if it available.
-                */
-               if (sock->pf == AF_INET) {
-                       int action;
-#if defined(IP_PMTUDISC_OMIT)
-                       action = IP_PMTUDISC_OMIT;
-                       if (setsockopt(sock->fd, IPPROTO_IP, IP_MTU_DISCOVER,
-                                      &action, sizeof(action)) < 0)
-                       {
-#endif /* if defined(IP_PMTUDISC_OMIT) */
-                               action = IP_PMTUDISC_DONT;
-                               (void)setsockopt(sock->fd, IPPROTO_IP,
-                                                IP_MTU_DISCOVER, &action,
-                                                sizeof(action));
-#if defined(IP_PMTUDISC_OMIT)
-                       }
-#endif /* if defined(IP_PMTUDISC_OMIT) */
-               }
-#endif /* if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) */
-#if defined(IP_DONTFRAG)
-               /*
-                * Turn off Path MTU discovery on IPv4/UDP sockets.
-                */
-               if (sock->pf == AF_INET) {
-                       int off = 0;
-                       (void)setsockopt(sock->fd, IPPROTO_IP, IP_DONTFRAG,
-                                        &off, sizeof(off));
-               }
-#endif /* if defined(IP_DONTFRAG) */
-
 #if defined(SET_RCVBUF)
                optlen = sizeof(size);
                if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF, (void *)&size,
@@ -2430,6 +2411,8 @@ again:
 #endif /* ifdef IP_RECVTOS */
 #endif /* defined(USE_CMSG) || defined(SET_RCVBUF) || defined(SET_SNDBUF) */
 
+       set_ip_dontfrag(sock);
+
 setup_done:
        inc_stats(manager->stats, sock->statsindex[STATID_OPEN]);
        if (sock->active == 0) {