diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerTransport.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerTransport.java index 3ef8b613394..2da041f571e 100644 --- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerTransport.java +++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerTransport.java @@ -50,6 +50,7 @@ import io.grpc.okhttp.internal.framed.Variant; import java.io.IOException; import java.net.Socket; +import java.net.SocketException; import java.util.List; import java.util.Locale; import java.util.Map; @@ -170,6 +171,13 @@ private void startIo(SerializingExecutor serializingExecutor) { HandshakerSocketFactory.HandshakeResult result = config.handshakerSocketFactory.handshake(socket, Attributes.EMPTY); synchronized (lock) { + if (socket.isClosed()) { + // The wrapped socket may not handle the underlying socket being closed by shutdown(). In + // particular, SSLSocket hangs future reads if the underlying socket is already closed at + // this point, even if you call sslSocket.close() later. + result.socket.close(); + throw new SocketException("Socket close raced with handshake"); + } this.socket = result.socket; } this.attributes = result.attributes;