a couple of points and observations * What is the platform's semantics when both java.net.preferIPv4Stack and java.net.preferIPv6Address are set simultaneously. * Should the EAFNOSUPPORT check be more pervasive within the native code? * IPv4 and IPv6 available doesn't mean that the stacks have been appropriately configured at the OS network level * It would seems worthwhile making access to the platforms perspective of stack duality directly available at the API level * It would seem worthwhile making the NetworkConfiguration abstraction available as util class in the API. * Is it possible at the OS level to dynamically turn on and off IPv6 support and IPv4 support? Thus a more dynamic test on on OS config is needed, rather than the onload config setting. * It may be useful to define the set of use case scenarios for the different possible IPv4 IPv6 combinations and descibe the expected behaviour
1. What is the platform's semantics when both java.net.preferIPv4Stack and java.net.preferIPv6Address are set simultaneously. The java.net.preferIPv4Stack precludes IPv6 usage, [ … However, in the case an application would rather use IPv4 only sockets, then this property can be set to true. ]. While java.net.preferIPv6Addresses, does not exclude IPv4, [ … This property can be set to true to change that preference and use IPv6 addresses over IPv4 ones where possible]. what should be the effect if an applications sets these properties during the course of its execution? afaik currently they are only accessed during startup and initialization and set the operational behaviour immutably thereafter. Thus, in IPv6_available is set on load. IPv6_available = IPv6_supported() & (!preferIPv4Stack); This doesn't take into account that an application might change it operational semantics dynamically ? 2. Should the EAFNOSUPPORT check be more pervasive within the native code? Is it not the case now, with the additional IPv6 support considerations, that the socket system call returns need to be augmented with an errno == EAFNOSUPPORT, also. Also as per the socket man pages description, the other errors are somewhat spurious and not indicative of no support, with exception of EPROTONOSUPPORT. So the generalised < 0 check should be refined with the additional check for errno == EAFNOSUPPORT . The other errno could considered exceptions and thrown as such. OR add EAFNOSUPPORT to handleSocketError ? so in IPv6_supported() if (fd < 0 && errno == EAFNOSUPPORT) { return JNI_FALSE; } else { // some approriate handling the others errors // are they indicative non availability or a transient // OS config error // could be run out of file descriptions! handleSocketError(...); } OR treat the other socket errors as spurious and proceed optimistically if (fd < 0 && errno == EAFNOSUPPORT) { return JNI_FALSE; } The java.net.preferIPv4Stack precludes IPv6 usage, so that is determined on load Thus in the case of Java_sun_nio_ch_Net_socket0 if the socket creation fails, should it be necessary to determine the semantics of the failure rather than just exiting … maybe the OS ran out of file descriptors ! which domain was the socket creation using ... it could be IPv6 was supported at startup and then got reconfigured and is not supported when the socket call is being made so then an attempted should be made for IPv4 AF_INET or IPv4 was configured and now IPv6 instead (some puppet or chef jobby decided to reconfigure the host network configuration) if (fd < 0 && errno != EAFNOSUPPORT) { // handle the error } else { // check the preferences and attempt a socket in AF_INET domain } 3. IPv4 and IPv6 available doesn't mean that the stacks have been appropriately configured at the OS network level 4. It would seem worthwhile making the NetworkConfiguration abstraction available as util class in the API. Also worth noting that availability of either IPv6 and IPv4 doesn't guarantee that they have been configured in the operating system at the network interface level. As such, while sockets may be created their proper functioning may be impaired. Thus, the usefulness of the utility class NetworkConfiguration for determining how various interfaces are configured. As a convenience at the application level it may be worth considering promoting the NetworkConfiguration from the test environment to the java.net API as a utility class. Similarly IPSupport abstract provides some convient functionality. An alternative implementation to this abstraction could be to make available the IPv6_available IPv4_available via IPv6supported and IPv4supported methods as part of an IPSupport API utility class. 5. Is it possible at the OS level to dynamically turn on and off IPv6 support and IPv4 support? Thus a more dynamic test on on OS config is needed, rather than the onload config setting. the global IPv6_available is set once on load, afaik - which may change during the execution of an application (happens a lot in the test environments) - as mentioned above the return from the socket call is augmented with errno check So there are a range of possible scenarios, which may be affected by dynamic configuration of a host while an application is executing. regards Mark ________________________________ From: net-dev <net-dev-boun...@openjdk.java.net> on behalf of Arthur Eubanks <aeuba...@google.com> Sent: Wednesday 17 April 2019 17:57 To: Chris Hegarty Cc: OpenJDK Network Dev list Subject: Re: [RFR]: 8222562: IPv6 only systems fail on setsockopt(IPV6_V6ONLY, 0) It turns out these patches only apply to a modified kernel which has patches to turn off IPv4. This specific patch doesn't make sense to submit if the kernel patches are not upstream. Maybe the entire call to setsockopt(IPV6_V6ONLY, 0) could be skipped if IPv4 is disabled. I'll look into Daniel's suggestion of a ipv4_available() utility. On Wed, Apr 17, 2019 at 7:01 AM Chris Hegarty <chris.hega...@oracle.com<mailto:chris.hega...@oracle.com>> wrote: Arthur, On 16/04/2019 22:34, Arthur Eubanks wrote: > Hi, > > Copied from the bug https://bugs.openjdk.java.net/browse/JDK-8222562: > Some of the networking code tries to support dual socket support. > However, it doesn't work with IPv6 only systems. > > setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, 0) returns a failure with > errno EAFNOSUPPORT, and then the networking code bails. It should not > bail when it sees that trying to set IPV6_V6ONLY fails. I assume that you are on Linux, right? If so, have you compiled the Kernel without IPv4 support? How have you configured your system without IPv4 support? I'm curious as I would like to try something similar, as well as on other platforms, macOS, etc. -Chris.