--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Mar 22 13:42:45 2019 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Fri Mar 22 11:35:35 2019 +0000
@@ -32,6 +32,7 @@
import java.net.ProtocolFamily;
import java.net.Socket;
import java.net.SocketAddress;
+import java.net.SocketException;
import java.net.SocketOption;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
@@ -52,6 +53,7 @@
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
+import sun.net.ConnectionResetException;
import sun.net.NetHooks;
import sun.net.ext.ExtendedSocketOptions;
import sun.net.util.SocketExceptions;
@@ -85,6 +87,9 @@
private volatile boolean isInputClosed;
private volatile boolean isOutputClosed;
+ // Connection reset protected by readLock
+ private boolean connectionReset;
+
// -- The following fields are protected by stateLock
// set true when exclusive binding is on and SO_REUSEADDR is emulated
@@ -230,7 +235,7 @@
}
// no options that require special handling
- Net.setSocketOption(fd, Net.UNSPEC, name, value);
+ Net.setSocketOption(fd, name, value);
return this;
}
}
@@ -260,7 +265,7 @@
}
// no options that require special handling
- return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
+ return (T) Net.getSocketOption(fd, name);
}
}
@@ -334,6 +339,10 @@
}
}
+ private void throwConnectionReset() throws SocketException {
+ throw new SocketException("Connection reset");
+ }
+
@Override
public int read(ByteBuffer buf) throws IOException {
Objects.requireNonNull(buf);
@@ -345,6 +354,10 @@
try {
beginRead(blocking);
+ // check if connection has been reset
+ if (connectionReset)
+ throwConnectionReset();
+
// check if input is shutdown
if (isInputClosed)
return IOStatus.EOF;
@@ -356,6 +369,9 @@
} else {
n = IOUtil.read(fd, buf, -1, nd);
}
+ } catch (ConnectionResetException e) {
+ connectionReset = true;
+ throwConnectionReset();
} finally {
endRead(blocking, n > 0);
if (n <= 0 && isInputClosed)
@@ -380,6 +396,10 @@
try {
beginRead(blocking);
+ // check if connection has been reset
+ if (connectionReset)
+ throwConnectionReset();
+
// check if input is shutdown
if (isInputClosed)
return IOStatus.EOF;
@@ -391,6 +411,9 @@
} else {
n = IOUtil.read(fd, dsts, offset, length, nd);
}
+ } catch (ConnectionResetException e) {
+ connectionReset = true;
+ throwConnectionReset();
} finally {
endRead(blocking, n > 0);
if (n <= 0 && isInputClosed)
@@ -769,15 +792,13 @@
boolean connected = false;
try {
beginFinishConnect(blocking);
- int n = 0;
if (blocking) {
do {
- n = Net.pollConnect(fd, -1);
- } while ((n == 0 || n == IOStatus.INTERRUPTED) && isOpen());
+ connected = Net.pollConnect(fd, -1);
+ } while (!connected && isOpen());
} else {
- n = Net.pollConnect(fd, 0);
+ connected = Net.pollConnect(fd, 0);
}
- connected = (n > 0);
} finally {
endFinishConnect(blocking, connected);
}
@@ -1007,6 +1028,20 @@
}
/**
+ * Return the number of bytes in the socket input buffer.
+ */
+ int available() throws IOException {
+ synchronized (stateLock) {
+ ensureOpenAndConnected();
+ if (isInputClosed) {
+ return 0;
+ } else {
+ return Net.available(fd);
+ }
+ }
+ }
+
+ /**
* Translates native poll revent ops into a ready operation ops
*/
public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {