This is, AFAICT, expected based on the differences between the socket layers of the various operating systems involved and their handling of closed sockets. If you write a similar test program in C using OS specific APIs, I believe you will see similar results. I don't think this is a problem with the JDK, nor is it likely to be something that can be fixed in the JDK (since the error reported by the OS is, as far as I know, unlikely to be universally sufficient to extrapolate the exact cause of failure).
On Thu, Jan 2, 2020 at 9:14 AM Sean Mullan <sean.mul...@oracle.com> wrote: > Cross-posting to security-dev as SSL is involved. > > --Sean > > On 12/29/19 4:01 PM, Dawid Weiss wrote: > > Hello, > > > > I am a committer to the Apache Lucene project. We have been looking > > into a problem in which SSL connections were handled differently in > > tests on different operating systems and narrowed it down to > > essentially the following scenario (full repro code at [1]): > > > > Server side: > > > > try (ServerSocketChannel serverChannel = ServerSocketChannel.open()) { > > SocketChannel clientChannel = serverChannel.accept(); > > clientChannel.close(); > > } > > > > Client side: > > > > Socket socket = new Socket(); > > socket.connect(target); > > // ... server closes the socket here. > > // Queue some data for writing to the closed socket. This succeeds. > > socket.getOutputStream().write("will succeed?!".getBytes("UTF-8")); > > // Try to read something from the closed socket. > > socket.getInputStream().read(new byte[100]); > > > > The last line of the client results in different behavior between > > operating systems. > > > > 1) Linux, JDK 11, 13, 14: succeeds with -1 (EOF). > > 2) Windows, JDK 11: SocketException ("recv failed") is thrown > > 3) Windows, JDK 13, 14: SocketException (localized message) is thrown > > 4) FreeBSD: SocketException (connection reset) is thrown > > 5) Mac OS X: SocketException (connection reset) is thrown > > > > I admit my original thinking on the Lucene issue (see full discussion > > at [2]) was that it was Windows that was off here (due to > > WSAECONNRESET not being handled at all in SocketInputStream.c [3]. > > Since then (JDK11) the underlying socket implementation has changed > > due to JEP 353 [4] (which Alan Bateman kindly pointed out to me). > > > > But the difference in runtime behavior between Linux and other > > operating systems still exists on both the old and the new > > implementation. I don't know whether it's something that should be > > qualified as platform-specific but it causes additional problems when > > it triggers somewhere deep inside the SSL handling layer -- then the > > application-level code receives a different exception depending on > > where it's run (an SSLException with a suppressed SocketException or a > > SocketException directly). > > > > I don't have any ideas about what a "good" fix for this is but I'm > > curious what others think. > > > > Dawid > > > > [1] > https://issues.apache.org/jira/secure/attachment/12989538/RecvRepro.java > > [2] https://issues.apache.org/jira/browse/SOLR-13778 > > [3] > https://github.com/openjdk/jdk14/blob/f58a8cbed2ba984ceeb9a1ea59f917e3f9530f1e/src/java.base/windows/native/libnet/SocketInputStream.c#L120-L154 > > [4] https://openjdk.java.net/jeps/353 > > > > -- - DML