7163874: InetAddress.isReachable should support pinging 0.0.0.0
Reviewed-by: alanb, chegar
--- a/jdk/src/share/native/java/net/net_util.h Thu May 10 11:19:22 2012 -0700
+++ b/jdk/src/share/native/java/net/net_util.h Fri May 11 16:20:46 2012 +0800
@@ -139,6 +139,9 @@
int
NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
+int
+NET_IsZeroAddr(jbyte* caddr);
+
/* Socket operations
*
* These work just like the JVM_* procedures, except that they may do some
--- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c Thu May 10 11:19:22 2012 -0700
+++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c Fri May 11 16:20:46 2012 +0800
@@ -671,12 +671,19 @@
* We did receive something, but is it what we were expecting?
* I.E.: A ICMP_ECHOREPLY packet with the proper PID.
*/
- if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY &&
- (ntohs(icmp->icmp_id) == pid) &&
- (him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
- close(fd);
- return JNI_TRUE;
- }
+ if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY
+ && (ntohs(icmp->icmp_id) == pid)) {
+ if ((him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
+ close(fd);
+ return JNI_TRUE;
+ }
+
+ if (him->sin_addr.s_addr == 0) {
+ close(fd);
+ return JNI_TRUE;
+ }
+ }
+
}
} while (tmout2 > 0);
timeout -= 1000;
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c Thu May 10 11:19:22 2012 -0700
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c Fri May 11 16:20:46 2012 +0800
@@ -532,10 +532,15 @@
* from the host that we are trying to determine is reachable.
*/
if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY &&
- (ntohs(icmp6->icmp6_id) == pid) &&
- NET_IsEqual(caddr, recv_caddr)) {
- close(fd);
- return JNI_TRUE;
+ (ntohs(icmp6->icmp6_id) == pid)) {
+ if (NET_IsEqual(caddr, recv_caddr)) {
+ close(fd);
+ return JNI_TRUE;
+ }
+ if (NET_IsZeroAddr(caddr)) {
+ close(fd);
+ return JNI_TRUE;
+ }
}
}
} while (tmout2 > 0);
--- a/jdk/src/solaris/native/java/net/net_util_md.c Thu May 10 11:19:22 2012 -0700
+++ b/jdk/src/solaris/native/java/net/net_util_md.c Fri May 11 16:20:46 2012 +0800
@@ -961,6 +961,16 @@
return 1;
}
+int NET_IsZeroAddr(jbyte* caddr) {
+ int i;
+ for (i = 0; i < 16; i++) {
+ if (caddr[i] != 0) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
/*
* Map the Java level socket option to the platform specific
* level and option name.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/Inet4Address/PingThis.java Fri May 11 16:20:46 2012 +0800
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7163874
+ * @summary InetAddress.isReachable is returning false
+ * for InetAdress 0.0.0.0 and ::0
+ * @run main PingThis
+ * @run main/othervm -Djava.net.preferIPv4Stack=true PingThis
+ */
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class PingThis {
+ private static boolean hasIPv6() throws Exception {
+ List<NetworkInterface> nics = Collections.list(NetworkInterface
+ .getNetworkInterfaces());
+ for (NetworkInterface nic : nics) {
+ List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
+ for (InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address)
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static void main(String args[]) throws Exception {
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ return;
+ }
+
+ boolean preferIPv4Stack = "true".equals(System
+ .getProperty("java.net.preferIPv4Stack"));
+ List<String> addrs = new ArrayList<String>();
+ InetAddress inetAddress = null;
+
+ addrs.add("0.0.0.0");
+ if (!preferIPv4Stack) {
+ if (hasIPv6()) {
+ addrs.add("::0");
+ }
+ }
+
+ for (String addr : addrs) {
+ inetAddress = InetAddress.getByName(addr);
+ System.out.println("The target ip is "
+ + inetAddress.getHostAddress());
+ boolean isReachable = inetAddress.isReachable(3000);
+ System.out.println("the target is reachable: " + isReachable);
+ if (isReachable) {
+ System.out.println("Test passed ");
+ } else {
+ System.out.println("Test failed ");
+ throw new Exception("address " + inetAddress.getHostAddress()
+ + " can not be reachable!");
+ }
+ }
+ }
+}