Integrated: 8290349: IP_DONTFRAGMENT doesn't set DF bit in IPv4 header

Daniel Jeliński djelinski at openjdk.org
Thu Aug 4 10:55:36 UTC 2022


On Wed, 20 Jul 2022 17:19:50 GMT, Daniel Jeliński <djelinski at openjdk.org> wrote:

> This patch partially fixes the issue where IPv6 sockets were fragmenting outgoing IPv4 datagrams even when IP_DONTFRAGMENT flag was set. Specifically, it fixes the issue on Linux and Windows. As far as I could tell, the issue is unfixable on Mac OS X.
> 
> All systems have a separate DONTFRAGMENT flag for IPv4 and IPv6. Each flag only affects packets from its address family; if we want to disable fragmentation of both IPv4 and IPv6 packets sent by an IPv6 socket, we need to set both IPv4 and IPv6 flags. This is similar to other already existing options like IP_TOS or IP_MULTICAST_*.
> 
> On Mac OS X it's impossible to set an IPv4 socket option on an IPv6 socket; attempting to do so results in an error. This is a known issue with Mac OS X; on that system we return false from [Net#shouldSetBothIPv4AndIPv6Options](https://github.com/openjdk/jdk/blob/2342684f2cd91a2e5f43dd271e95836aa78e7d0a/src/java.base/unix/native/libnio/ch/Net.c#L159) to avoid setting IPv4 options.
> 
> As far as I can tell, non-privileged users have no way to check if the DF flag was set or if the packet was fragmented. I implemented a test that attempted to send a large packet over a physical interface and expected SocketException / EMSGSIZE; the test frequently failed for unrelated reasons, so I decided against including it. Loopback interface has infinite MTU on some systems, so can not be used for this test.
> 
> Testing performed (with IP_DONTFRAGMENT flag):
> Windows 10:
> With this patch, IPv4 packets sent from IPv6 socket have the DF flag; sending an IPv4 packet larger than the interface MTU results in EMSGSIZE and no packet is sent. Without this patch, the packet is fragmented and sent without DF flag.
> Sending IPv6 packets larger than the interface MTU usually results in EMSGSIZE. It may succeed if the destination address is non-routable.
> 
> For other systems I could not capture packets, so I can only report the observed behavior of sending packets.
> Windows 2012 and 2016 (IP_MTU_DISCOVER not supported):
> With this patch, sending any packet exceeding MTU size fails with EMSGSIZE. Without this patch sending a large IPv6 packet succeeds.
> If a packet is sent to a non-routable address, send succeeds, no error is reported.
> 
> Linux:
> With this patch, sending any packet exceeding MTU size fails with EMSGSIZE. Without this patch, sending large IPv4 packets from IPv6 sockets succeeds.
> 
> Mac OS X 12:
> Sending an IPv6 packet exceeding MTU size fails with EMSGSIZE. Sending large IPv4 packets from IPv4 sockets also fails with EMSGSIZE. Sending large IPv4 packets from IPv6 sockets succeeds. The patch does not change the observed behavior.

This pull request has now been integrated.

Changeset: ce61eb6f
Author:    Daniel Jeliński <djelinski at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/ce61eb6ff99eaaece463091b8481e27f84f80684
Stats:     140 lines in 9 files changed: 6 ins; 66 del; 68 mod

8290349: IP_DONTFRAGMENT doesn't set DF bit in IPv4 header

Reviewed-by: michaelm, alanb

-------------

PR: https://git.openjdk.org/jdk/pull/9575


More information about the nio-dev mailing list