8201474: (so) Socket adaptor connect(InetAddress, timeout) succeeds when connection fails
Reviewed-by: bpb
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Apr 13 11:14:49 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Sat Apr 14 08:41:42 2018 +0100
@@ -1280,8 +1280,8 @@
boolean polled = false;
try {
beginRead(blocking, false);
- int n = Net.poll(fd, Net.POLLIN, timeout);
- polled = (n > 0);
+ int events = Net.poll(fd, Net.POLLIN, timeout);
+ polled = (events != 0);
} finally {
endRead(blocking, polled);
}
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Apr 13 11:14:49 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Sat Apr 14 08:41:42 2018 +0100
@@ -431,8 +431,8 @@
boolean polled = false;
try {
begin(true);
- int n = Net.poll(fd, Net.POLLIN, timeout);
- polled = (n > 0);
+ int events = Net.poll(fd, Net.POLLIN, timeout);
+ polled = (events != 0);
} finally {
end(true, polled);
}
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Apr 13 11:14:49 2018 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Sat Apr 14 08:41:42 2018 +0100
@@ -951,8 +951,8 @@
boolean polled = false;
try {
beginRead(blocking);
- int n = Net.poll(fd, Net.POLLIN, timeout);
- polled = (n > 0);
+ int events = Net.poll(fd, Net.POLLIN, timeout);
+ polled = (events != 0);
} finally {
endRead(blocking, polled);
}
@@ -977,10 +977,13 @@
boolean polled = false;
try {
beginFinishConnect(blocking);
- int n = Net.poll(fd, Net.POLLCONN, timeout);
- polled = (n > 0);
+ int events = Net.poll(fd, Net.POLLCONN, timeout);
+ polled = (events != 0);
} finally {
- endFinishConnect(blocking, polled);
+ // invoke endFinishConnect with completed = false so that
+ // the state is not changed to ST_CONNECTED. The socket
+ // adaptor will use finishConnect to finish.
+ endFinishConnect(blocking, /*completed*/false);
}
return polled;
} finally {
--- a/src/java.base/unix/native/libnio/ch/Net.c Fri Apr 13 11:14:49 2018 -0700
+++ b/src/java.base/unix/native/libnio/ch/Net.c Sat Apr 14 08:41:42 2018 +0100
@@ -700,7 +700,8 @@
if (rv >= 0) {
return pfd.revents;
} else if (errno == EINTR) {
- return IOS_INTERRUPTED;
+ // interrupted, no events to return
+ return 0;
} else {
handleSocketError(env, errno);
return IOS_THROWN;
--- a/test/jdk/java/nio/channels/SocketChannel/AdaptSocket.java Fri Apr 13 11:14:49 2018 -0700
+++ b/test/jdk/java/nio/channels/SocketChannel/AdaptSocket.java Sat Apr 14 08:41:42 2018 +0100
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 8156002
+ * @bug 8156002 8201474
* @summary Unit test for socket-channel adaptors
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
@@ -37,18 +37,16 @@
public class AdaptSocket {
- static java.io.PrintStream out = System.out;
+ static final java.io.PrintStream out = System.out;
- static void test(TestServers.DayTimeServer dayTimeServer,
+ static void test(TestServers.AbstractServer server,
int timeout,
boolean shouldTimeout)
throws Exception
{
out.println();
- InetSocketAddress isa
- = new InetSocketAddress(dayTimeServer.getAddress(),
- dayTimeServer.getPort());
+ InetSocketAddress isa = new InetSocketAddress(server.getAddress(), server.getPort());
SocketChannel sc = SocketChannel.open();
Socket so = sc.socket();
out.println("opened: " + so);
@@ -151,6 +149,30 @@
sc.close();
}
+ static void testConnect(TestServers.AbstractServer server,
+ int timeout,
+ boolean shouldFail)
+ throws Exception
+ {
+ SocketAddress sa = new InetSocketAddress(server.getAddress(), server.getPort());
+ try (SocketChannel sc = SocketChannel.open()) {
+ Socket s = sc.socket();
+ try {
+ if (timeout > 0) {
+ s.connect(sa, timeout);
+ } else {
+ s.connect(sa);
+ }
+ if (shouldFail)
+ throw new Exception("Connection should not be established");
+ } catch (SocketException se) {
+ if (!shouldFail)
+ throw se;
+ out.println("connect failed as expected: " + se);
+ }
+ }
+ }
+
public static void main(String[] args) throws Exception {
try (TestServers.DayTimeServer dayTimeServer
@@ -177,5 +199,9 @@
= TestServers.NoResponseServer.startNewServer()) {
testRead(noResponseServer, 10, true);
}
+
+ TestServers.RefusingServer refuser = TestServers.RefusingServer.newRefusingServer();
+ testConnect(refuser, 0, true);
+ testConnect(refuser, 2000, true);
}
}