maintainer-feedback requested: [Bug 274964] java/openjdk21 Dual-stack IPv4/IPv6 applications no longer work with sysctl net.inet6.ip6.v6only=1
Date: Wed, 08 Nov 2023 14:35:18 UTC
Bugzilla Automation <bugzilla@FreeBSD.org> has asked freebsd-java (Nobody) <java@FreeBSD.org> for maintainer-feedback: Bug 274964: java/openjdk21 Dual-stack IPv4/IPv6 applications no longer work with sysctl net.inet6.ip6.v6only=1 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274964 --- Description --- We have a Tomcat-based application (with Tomcat configured to use the Apache Portable Runtime) that listens on both IPv4 and IPv6. Java is invoked with -Djava.net.preferIPv4Stack=false to enable IPv6 support. This application works perfectly on FreeBSD with OpenJDK 17 and accepts both IPv4 and IPv6 connections, even though the FreeBSD 13.2-RELEASE-p3 host has the default sysctl net.inet6.ip6.v6only=1 setting. The exact same application and configuration fails to listen to IPv4 clients when deployed with OpenJDK 21. We have another JVM server application, this time created using Scala HTTP4s (https://http4s.org/), and thus not using the Apache Portable Runtime. This application (again run with -Djava.net.preferIPv4Stack=false) exhibits the exact same behaviour: with OpenJDK 17, both IPv4 and IPv6 clients can connect; with OpenJDK 21, only IPv6 clients can connect. The problem is thus not specific to the Apache Portable Runtime. Both applications work as expected with OpenJDK 21 if the FreeBSD host has sysctl net.inet6.ip6.v6only set to 0. However, setting sysctl net.inet6.ip6.v6only=0 is not required using OpenJDK 17. Both applications are running in FreeBSD jails, but I do not believe that is likely a factor. I am not sure whether I am looking at the relevant code or not, but the FreeBSD OpenJDK 17 port has BSD-specific code in src/java.base/unix/native/libnet/PlainSocketImpl.c that appears to set the IPV6_V6ONLY flag to 0 when opening a socket if IPv4 is available. See https://github.com/battleblow/jdk17u/blob/373026a81f5000e6df990eb9faec37f518ee7 11e/src/java.base/unix/native/libnet/PlainSocketImpl.c#L184 The networking code appears to have been re-arranged in OpenJDK 21 (relative to OpenJDK 17), so that particular source file no longer exists. However, a search for IPV6_V6ONLY in the jdk21u GitHub repository does not reveal any plausible direct equivalent code. This explicit enabling of IPV6_V6ONLY when opening a socket in OpenJDK 17 may perhaps be the reason why OpenJDK 17 works for us without sysctl net.inet6.ip6.v6only=0 but OpenJDK 21 doesn’t. Note that we also tested the FreeBSD OpenJDK 18, 19, and 20 ports. Like OpenJDK 21, these also fail to work with our dual-stack applications. This issue is almost certainly related to the old OpenJDK 11 bug #239890, but I am guessing that bug was obsolete as of OpenJDK 17, since the described scenario does seem to work there.