diff --git a/jdk/src/java.base/share/classes/java/net/DatagramSocket.java b/jdk/src/java.base/share/classes/java/net/DatagramSocket.java index c047b3cf6a4..5d978e596e2 100644 --- a/jdk/src/java.base/share/classes/java/net/DatagramSocket.java +++ b/jdk/src/java.base/share/classes/java/net/DatagramSocket.java @@ -771,6 +771,7 @@ class DatagramSocket implements java.io.Closeable { } // end of while } } + DatagramPacket tmp = null; if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { // We have to do the filtering the old fashioned way since // the native impl doesn't support connect or the connect @@ -795,11 +796,13 @@ class DatagramSocket implements java.io.Closeable { if ((!connectedAddress.equals(peekAddress)) || (connectedPort != peekPort)) { // throw the packet away and silently continue - DatagramPacket tmp = new DatagramPacket( + tmp = new DatagramPacket( new byte[1024], 1024); getImpl().receive(tmp); if (explicitFilter) { - bytesLeftToFilter -= tmp.getLength(); + if (checkFiltering(tmp)) { + stop = true; + } } } else { stop = true; @@ -809,18 +812,22 @@ class DatagramSocket implements java.io.Closeable { // If the security check succeeds, or the datagram is // connected then receive the packet getImpl().receive(p); - if (explicitFilter) { - bytesLeftToFilter -= p.getLength(); - if (bytesLeftToFilter <= 0) { - explicitFilter = false; - } else { - // break out of filter, if there is no more data queued - explicitFilter = getImpl().dataAvailable() > 0; - } + if (explicitFilter && tmp == null) { + // packet was not filtered, account for it here + checkFiltering(p); } } } + private boolean checkFiltering(DatagramPacket p) throws SocketException { + bytesLeftToFilter -= p.getLength(); + if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) { + explicitFilter = false; + return true; + } + return false; + } + /** * Gets the local address to which the socket is bound. * diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index b9fd16eae29..e316facf491 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -752,7 +752,7 @@ class DatagramChannelImpl } do { tmpBuf.clear(); - } while (read(tmpBuf) > 0); + } while (receive(tmpBuf) != null); } finally { if (blocking) { configureBlocking(true); diff --git a/jdk/src/java.base/windows/native/libnet/AbstractPlainDatagramSocketImpl.c b/jdk/src/java.base/windows/native/libnet/AbstractPlainDatagramSocketImpl.c index 7244e664c9e..dd2c7e8a92f 100644 --- a/jdk/src/java.base/windows/native/libnet/AbstractPlainDatagramSocketImpl.c +++ b/jdk/src/java.base/windows/native/libnet/AbstractPlainDatagramSocketImpl.c @@ -32,9 +32,11 @@ #include "java_net_AbstractPlainDatagramSocketImpl.h" -static jfieldID IO_fd_fdID; +static jfieldID IO_fd_fdID = NULL; +static jfieldID apdsi_fdID = NULL; -static jfieldID apdsi_fdID; +static jfieldID apdsi_fd1ID = NULL; +static jclass two_stacks_clazz = NULL; /* @@ -48,10 +50,21 @@ Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", "Ljava/io/FileDescriptor;"); CHECK_NULL(apdsi_fdID); - IO_fd_fdID = NET_GetFileDescriptorID(env); CHECK_NULL(IO_fd_fdID); + two_stacks_clazz = (*env)->FindClass(env, "java/net/TwoStacksPlainDatagramSocketImpl"); + CHECK_NULL(two_stacks_clazz); + + /* Handle both TwoStacks and DualStack here */ + + if (JNU_Equals(env, cls, two_stacks_clazz)) { + /* fd1 present only in TwoStack.. */ + apdsi_fd1ID = (*env)->GetFieldID(env, cls, "fd1", + "Ljava/io/FileDescriptor;"); + CHECK_NULL(apdsi_fd1ID); + } + JNU_CHECK_EXCEPTION(env); } @@ -63,20 +76,38 @@ Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable (JNIEnv *env, jobject this) { SOCKET fd; - int retval; - + SOCKET fd1; + int rv = -1, rv1 = -1; jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID); - if (IS_NULL(fdObj)) { - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - "Socket closed"); - return -1; + if (!IS_NULL(fdObj)) { + int retval = 0; + fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); + rv = ioctlsocket(fd, FIONREAD, &retval); + if (retval > 0) { + return retval; + } } - fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); - if (ioctlsocket(fd, FIONREAD, &retval) < 0) { + if (!IS_NULL(apdsi_fd1ID)) { + /* TwoStacks */ + jobject fd1Obj = (*env)->GetObjectField(env, this, apdsi_fd1ID); + if (!IS_NULL(fd1Obj)) { + int retval = 0; + fd1 = (SOCKET)(*env)->GetIntField(env, fd1Obj, IO_fd_fdID); + rv1 = ioctlsocket(fd1, FIONREAD, &retval); + if (retval > 0) { + return retval; + } + } + } + + if (rv < 0 && rv1 < 0) { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "Socket closed"); return -1; } - return retval; + + return 0; }