8143397: It looks like InetAddress.isReachable(timeout) works incorrectly
authorrobm
Wed, 09 Dec 2015 15:16:00 +0000
changeset 34529 3a49a6c8b989
parent 34528 279258fb670b
child 34530 364376f150cf
8143397: It looks like InetAddress.isReachable(timeout) works incorrectly Reviewed-by: xuelei, msheppar
jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c
--- a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c	Wed Dec 09 10:36:33 2015 +0000
+++ b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c	Wed Dec 09 15:16:00 2015 +0000
@@ -295,6 +295,7 @@
     char SendData[32] = {0};
     LPVOID ReplyBuffer = NULL;
     DWORD ReplySize = 0;
+    jboolean ret = JNI_FALSE;
 
     hIcmpFile = IcmpCreateFile();
     if (hIcmpFile == INVALID_HANDLE_VALUE) {
@@ -318,7 +319,11 @@
                                 NULL,       // PIP_OPTION_INFORMATION RequestOptions,
                                 ReplyBuffer,// LPVOID ReplyBuffer,
                                 ReplySize,  // DWORD ReplySize,
-                                timeout);   // DWORD Timeout
+                                // Note: IcmpSendEcho and its derivatives
+                                // seem to have an undocumented minimum
+                                // timeout of 1000ms below which the
+                                // api behaves inconsistently.
+                                (timeout < 1000) ? 1000 : timeout);   // DWORD Timeout
     } else {
         dwRetVal = IcmpSendEcho2Ex(hIcmpFile,  // HANDLE IcmpHandle,
                                    NULL,       // HANDLE Event
@@ -331,17 +336,19 @@
                                    NULL,       // PIP_OPTION_INFORMATION RequestOptions,
                                    ReplyBuffer,// LPVOID ReplyBuffer,
                                    ReplySize,  // DWORD ReplySize,
-                                   timeout);   // DWORD Timeout
+                                   (timeout < 1000) ? 1000 : timeout);   // DWORD Timeout
+    }
+
+    if (dwRetVal != 0) {
+        PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
+        if ((int)pEchoReply->RoundTripTime <= timeout)
+            ret = JNI_TRUE;
     }
 
     free(ReplyBuffer);
     IcmpCloseHandle(hIcmpFile);
 
-    if (dwRetVal != 0) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
+    return ret;
 }
 
 /*