The constructor throws java.net.BindException: Cannot assign requested address: NET_Bind. The failure can be reproduced only on Windows2003 Server(amd64), with enabled IPv6 support, on Windows XP there is no such problem. The test code attached.
Initially the problem found by IBM. Their comments:
"The problem is caused by the fact that Java does not handle IPv6 link-local addresses correctly. The reason this problem is only seen on amd64 is to do with the IPv6 default setup on Windows 2003 Server - it maps link-local addresses to interfaces
so that a call to InetAddress.getAllByName() on W2003S will return link-local addresses. (No link-local addresses are returned on XP).
The InetAddress.getAllByName(hostname) call eventually results in a call to OS method getaddrinfo (or retrieves information from a cache which was originally filled in by a call to getaddrinfo()). This call returns a linked list of addrinfo structures, each of which contains a sockaddr structure, which will describe the socketaddress. The problem stems from Java (at the native level) only taking the address value from this sockaddr structure, and placing it into a byte array which is returned to Java code (to then be put into a InetAddress array which is what InetAddress.getAllByName() returns). This means the scope ID is not retreived from the linked list for each address, making the link-local addresses invalid. Worse, as the addresses are passed back in a byte array, there is no easy way to also pass back the scope ID to Java code.
The testcase in question selects one of the addresses returned from getAllByName() and tries to bind to it. However, due to the ordering of the returned addresses, it always seems to pick a link-local address, so the fact that Java isn't handling link-local address has come to light."
Initially the problem found by IBM. Their comments:
"The problem is caused by the fact that Java does not handle IPv6 link-local addresses correctly. The reason this problem is only seen on amd64 is to do with the IPv6 default setup on Windows 2003 Server - it maps link-local addresses to interfaces
so that a call to InetAddress.getAllByName() on W2003S will return link-local addresses. (No link-local addresses are returned on XP).
The InetAddress.getAllByName(hostname) call eventually results in a call to OS method getaddrinfo (or retrieves information from a cache which was originally filled in by a call to getaddrinfo()). This call returns a linked list of addrinfo structures, each of which contains a sockaddr structure, which will describe the socketaddress. The problem stems from Java (at the native level) only taking the address value from this sockaddr structure, and placing it into a byte array which is returned to Java code (to then be put into a InetAddress array which is what InetAddress.getAllByName() returns). This means the scope ID is not retreived from the linked list for each address, making the link-local addresses invalid. Worse, as the addresses are passed back in a byte array, there is no easy way to also pass back the scope ID to Java code.
The testcase in question selects one of the addresses returned from getAllByName() and tries to bind to it. However, due to the ordering of the returned addresses, it always seems to pick a link-local address, so the fact that Java isn't handling link-local address has come to light."