JDK-6718504 : IN6_IS_ADDR_ANY tests only 12 bytes of 16-byte address
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_2.5.1
  • CPU: sparc
  • Submitted: 2008-06-24
  • Updated: 2014-03-25
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u81Fixed 7 b94Fixed
Description
This is observed in Java 5 and Java 6.

When called with -Djava.net.preferIPv6Addresses=true the call to DatagramSocket getLocalSocketAddress returns an all-zero address, instead of ::1.

           InetAddress iNet = InetAddress.getByName("localhost");
            DatagramSocket soc = new DatagramSocket( 12345, iNet);
            SocketAddress sa = soc. getLocalSocketAddress();

            System.out.println("iNet: " + iNet);
            System.out.println("Expected: " + iNet + ":12345");
            System.out.println("Returned: " + ((InetSocketAddress)sa).getAddress());
workaround:  Here's a fix:
In net_util_md.h, the macro IN6_IS_ADDR_ANY is defined as:
#define IN6_IS_ADDR_ANY(a)      \
    (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) &&      \
    ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) &&       \
    ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0))

It should be:
#define IN6_IS_ADDR_ANY(a)      \
    (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) &&      \
    ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) &&       \
    ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && \
    ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0))

IPV6 addresses are 16 bytes long, the macros only tests 12 bytes.

Comments
This issue seems to be causing a WLS startup problem on JDK 1.6 if you bind a ServerSocket to 127.0.0.1 and then a second one to ::1 the second bind will fail because it sees the ::1 as ::0 in the macro above and tries to bind on both stacks. It works when the sequence is reversed.
21-03-2014

EVALUATION JDK7 changeset: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/0c27202d66c1
27-04-2010

SUGGESTED FIX --- a/src/windows/native/java/net/net_util_md.h Thu Apr 22 12:45:36 2010 +0800 +++ b/src/windows/native/java/net/net_util_md.h Tue Apr 27 09:42:51 2010 +0100 @@ -222,7 +222,8 @@ LPFN_GETNAMEINFO getnameinfo_ptr; #define IN6_IS_ADDR_ANY(a) \ (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \ ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && \ - ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0)) + ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && \ + ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0)) #endif #ifndef IPV6_V6ONLY --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/DatagramSocket/LocalSocketAddress.java Tue Apr 27 09:42:51 2010 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6718504 + * @summary IN6_IS_ADDR_ANY tests only 12 bytes of 16-byte address + */ + +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Inet6Address; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.*; + +public class LocalSocketAddress { + public static void main(String[] args) throws SocketException { + InetAddress IPv6LoopbackAddr = null; + DatagramSocket soc = null; + + try { + List<NetworkInterface> nics = Collections.list(NetworkInterface.getNetworkInterfaces()); + for (NetworkInterface nic : nics) { + if (!nic.isLoopback()) + continue; + + List<InetAddress> addrs = Collections.list(nic.getInetAddresses()); + for (InetAddress addr : addrs) { + if (addr instanceof Inet6Address) { + IPv6LoopbackAddr = addr; + break; + } + } + } + + if (IPv6LoopbackAddr == null) { + System.out.println("IPv6 is not available, exiting test."); + return; + } + + soc = new DatagramSocket(0, IPv6LoopbackAddr); + + if (!IPv6LoopbackAddr.equals(soc.getLocalAddress())) { + throw new RuntimeException("Bound address is " + soc.getLocalAddress() + + ", but should be " + IPv6LoopbackAddr); + } + } finally { + if (soc != null) { soc.close(); } + } + } +}
27-04-2010

EVALUATION see description
25-06-2008

WORK AROUND Here's a fix: In net_util_md.h, the macro IN6_IS_ADDR_ANY is defined as: #define IN6_IS_ADDR_ANY(a) (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0)) It should be: #define IN6_IS_ADDR_ANY(a) (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0)) IPV6 addresses are 16 bytes long, the macros only tests 12 bytes.
24-06-2008