You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We're setting -Djava.net.preferIPv6Addresses=system and we've found Netty doesn't honor the setting, because Netty implements IPv4/IPv6 loopback address/interface detection itself, causing different results from InetAddress.
In recent JDKs, LookupPolicy takes care how addresses are resolved, but the logic is essentially the same in all releases since JDK 9, but it's harder to follow in releases before LookupPolicy was added. In short:
If -Djava.net.preferIPv4Stack=true is set, IPv4 is forced
If the system is IPv4 or IPv6 only, the available protocol is used
Otherwise both IPv4 and v6 are enabled. The preferIPv6Addresses value determines the ordering of addresses:
For false IPv4 addresses are sorted first
For true IPv6 addresses are sorted first
For system addresses are provided in the order getaddrinfo returns them in
If no preference is specified via either flag, IPv4 addresses are ordered first. Equivalent to preferIPv6Addresses=false
The NetUtil implementation differs to this, and doesn't implement the system value. The real problem is the address reordering caused by the implicit preference:
The system value is required for mixed environments, because the combination of true/false for the two settings causes connectivity issues depending on the combination of source/destination being IPv4-only, IPv6-only or dualstack:
We chose system because it avoids the complexity of deciding whether it's safe to set -Djava.net.preferIPv6Addresses=true.
Expected behavior
Netty's selection of IP version, loopback address and name resolution order is identical to the JDK.
Actual behavior
The preferIPv6Addresses=system is not honored, causing addresses to be reordered based on the default preference, making it impossible to safely prefer IPv6 in mixed-protocol environments.
Steps to reproduce
Run with:
-Djava.net.preferIPv6Addresses=system
Note the failure:
io.netty.util.internal.SystemPropertyUtil: Unable to parse the boolean system property 'java.net.preferIPv6Addresses':system - using the default value: false
I don't quite follow why this is implemented explicitly, rather than calling io.netty.util.internal.SocketUtils#loopbackAddress and checking the instance of the returned address, that seems safer, with a check for the system value to determine if address reordering should be disabled.
Netty version
At least 4.1 and later.
JVM version
JDK 9 and later.
OS version
All operating systems.
The text was updated successfully, but these errors were encountered:
DanielThomas
changed the title
IPv6 disabled when -Djava.net.preferIPv6Addresses=system is set
IPv6 not preferred when -Djava.net.preferIPv6Addresses=system is set
May 25, 2023
We're setting
-Djava.net.preferIPv6Addresses=system
and we've found Netty doesn't honor the setting, because Netty implements IPv4/IPv6 loopback address/interface detection itself, causing different results fromInetAddress
.In recent JDKs, LookupPolicy takes care how addresses are resolved, but the logic is essentially the same in all releases since JDK 9, but it's harder to follow in releases before
LookupPolicy
was added. In short:-Djava.net.preferIPv4Stack=true
is set, IPv4 is forcedpreferIPv6Addresses
value determines the ordering of addresses:false
IPv4 addresses are sorted firsttrue
IPv6 addresses are sorted firstsystem
addresses are provided in the ordergetaddrinfo
returns them inpreferIPv6Addresses=false
The NetUtil implementation differs to this, and doesn't implement the
system
value. The real problem is the address reordering caused by the implicit preference:netty/resolver-dns/src/main/java/io/netty/resolver/dns/DnsAddressResolveContext.java
Lines 63 to 67 in 4eda913
netty/resolver-dns/src/main/java/io/netty/resolver/dns/PreferredAddressTypeComparator.java
Lines 30 to 39 in 4eda913
The
system
value is required for mixed environments, because the combination oftrue
/false
for the two settings causes connectivity issues depending on the combination of source/destination being IPv4-only, IPv6-only or dualstack:We chose
system
because it avoids the complexity of deciding whether it's safe to set-Djava.net.preferIPv6Addresses=true
.Expected behavior
Netty's selection of IP version, loopback address and name resolution order is identical to the JDK.
Actual behavior
The
preferIPv6Addresses=system
is not honored, causing addresses to be reordered based on the default preference, making it impossible to safely prefer IPv6 in mixed-protocol environments.Steps to reproduce
Run with:
Note the failure:
I don't quite follow why this is implemented explicitly, rather than calling
io.netty.util.internal.SocketUtils#loopbackAddress
and checking the instance of the returned address, that seems safer, with a check for thesystem
value to determine if address reordering should be disabled.Netty version
At least 4.1 and later.
JVM version
JDK 9 and later.
OS version
All operating systems.
The text was updated successfully, but these errors were encountered: