# HG changeset patch # User robm # Date 1443654591 -3600 # Node ID e630c3008f2ccbf03b5631e27fc05571dba5cdd0 # Parent 1861a8cd73ba87349847714c013f58baee48a3f9 8135305: InetAddress.isReachable reports true when loopback interface is specified Reviewed-by: michaelm diff -r 1861a8cd73ba -r e630c3008f2c jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c --- a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c Wed Sep 30 15:25:29 2015 -0700 +++ b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c Thu Oct 01 00:09:51 2015 +0100 @@ -283,8 +283,11 @@ * Returns true is an ECHO_REPLY is received, otherwise, false. */ static jboolean -ping4(JNIEnv *env, unsigned long ipaddr, jint timeout) { - +ping4(JNIEnv *env, + unsigned long src_addr, + unsigned long dest_addr, + jint timeout) +{ // See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx HANDLE hIcmpFile; @@ -307,14 +310,29 @@ return JNI_FALSE; } - dwRetVal = IcmpSendEcho(hIcmpFile, // HANDLE IcmpHandle, - ipaddr, // IPAddr DestinationAddress, - SendData, // LPVOID RequestData, - sizeof(SendData), // WORD RequestSize, - NULL, // PIP_OPTION_INFORMATION RequestOptions, - ReplyBuffer,// LPVOID ReplyBuffer, - ReplySize, // DWORD ReplySize, - timeout); // DWORD Timeout + if (src_addr == 0) { + dwRetVal = IcmpSendEcho(hIcmpFile, // HANDLE IcmpHandle, + dest_addr, // IPAddr DestinationAddress, + SendData, // LPVOID RequestData, + sizeof(SendData), // WORD RequestSize, + NULL, // PIP_OPTION_INFORMATION RequestOptions, + ReplyBuffer,// LPVOID ReplyBuffer, + ReplySize, // DWORD ReplySize, + timeout); // DWORD Timeout + } else { + dwRetVal = IcmpSendEcho2Ex(hIcmpFile, // HANDLE IcmpHandle, + NULL, // HANDLE Event + NULL, // PIO_APC_ROUTINE ApcRoutine + NULL, // ApcContext + src_addr, // IPAddr SourceAddress, + dest_addr, // IPAddr DestinationAddress, + SendData, // LPVOID RequestData, + sizeof(SendData), // WORD RequestSize, + NULL, // PIP_OPTION_INFORMATION RequestOptions, + ReplyBuffer,// LPVOID ReplyBuffer, + ReplySize, // DWORD ReplySize, + timeout); // DWORD Timeout + } free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); @@ -337,9 +355,9 @@ jint timeout, jbyteArray ifArray, jint ttl) { - jint addr; + jint src_addr = 0; + jint dest_addr = 0; jbyte caddr[4]; - struct sockaddr_in him; int sz; /** @@ -349,14 +367,28 @@ if (sz != 4) { return JNI_FALSE; } - memset((char *) &him, 0, sizeof(him)); memset((char *) caddr, 0, sizeof(caddr)); (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr); - addr = ((caddr[0]<<24) & 0xff000000); - addr |= ((caddr[1] <<16) & 0xff0000); - addr |= ((caddr[2] <<8) & 0xff00); - addr |= (caddr[3] & 0xff); - addr = htonl(addr); + dest_addr = ((caddr[0]<<24) & 0xff000000); + dest_addr |= ((caddr[1] <<16) & 0xff0000); + dest_addr |= ((caddr[2] <<8) & 0xff00); + dest_addr |= (caddr[3] & 0xff); + dest_addr = htonl(dest_addr); - return ping4(env, addr, timeout); + /** + * If a network interface was specified, let's convert its address + * as well. + */ + if (!(IS_NULL(ifArray))) { + memset((char *) caddr, 0, sizeof(caddr)); + (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr); + src_addr = ((caddr[0]<<24) & 0xff000000); + src_addr |= ((caddr[1] <<16) & 0xff0000); + src_addr |= ((caddr[2] <<8) & 0xff00); + src_addr |= (caddr[3] & 0xff); + src_addr = htonl(src_addr); + } + + return ping4(env, src_addr, dest_addr, timeout); } + diff -r 1861a8cd73ba -r e630c3008f2c jdk/test/java/net/InetAddress/IsReachableViaLoopbackTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/InetAddress/IsReachableViaLoopbackTest.java Thu Oct 01 00:09:51 2015 +0100 @@ -0,0 +1,40 @@ +import java.io.*; +import java.net.*; +import java.util.*; + +/** + * @test + * @bug 8135305 + * @summary ensure we can't ping external hosts via loopback if + */ + +public class IsReachableViaLoopbackTest { + public static void main(String[] args) { + try { + InetAddress addr = InetAddress.getByName("localhost"); + InetAddress remoteAddr = InetAddress.getByName("bugs.openjdk.java.net"); + if (!addr.isReachable(10000)) + throw new RuntimeException("Localhost should always be reachable"); + NetworkInterface inf = NetworkInterface.getByInetAddress(addr); + if (inf != null) { + if (!addr.isReachable(inf, 20, 10000)) { + throw new RuntimeException("Localhost should always be reachable"); + } else { + System.out.println(addr + " is reachable"); + } + if (remoteAddr.isReachable(inf, 20, 10000)) { + throw new RuntimeException(remoteAddr + " is reachable"); + } else { + System.out.println(remoteAddr + " is NOT reachable"); + } + } else { + System.out.println("inf == null"); + } + + } catch (IOException e) { + throw new RuntimeException("Unexpected exception:" + e); + } + System.out.println("IsReachableViaLoopbackTest EXIT"); + } +} +