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

Reply via email to