@@ -105,6 +105,12 @@ public class SSLSocketChannel2 implements ByteChannel, WrappedByteChannel, ISSLC
105105 **/
106106 protected int bufferallocations = 0 ;
107107
108+ /**
109+ * 2022-06-17 Handshake start time in WSS for the underlying channel.
110+ * If wss handshake is not completed in 10s, close this channel to prevent cpu overload or unexpected channel error. see #896.
111+ */
112+ protected long handshakeStartTime = System .currentTimeMillis () ;
113+
108114 public SSLSocketChannel2 (SocketChannel channel , SSLEngine sslEngine , ExecutorService exec ,
109115 SelectionKey key ) throws IOException {
110116 if (channel == null || sslEngine == null || exec == null ) {
@@ -385,19 +391,29 @@ public boolean isConnected() {
385391 public void close () throws IOException {
386392 sslEngine .closeOutbound ();
387393 sslEngine .getSession ().invalidate ();
388- try {
389- if (socketChannel .isOpen ()) {
390- socketChannel .write (wrap (emptybuffer ));
391- }
392- } finally { // in case socketChannel.write produce exception - channel will never close
393- socketChannel .close ();
394+ if (socketChannel .isOpen ()) {
395+ socketChannel .write (wrap (emptybuffer ));// FIXME what if not all bytes can be written
394396 }
397+ socketChannel .close ();
395398 }
396399
397400 private boolean isHandShakeComplete () {
398401 HandshakeStatus status = sslEngine .getHandshakeStatus ();
399- return status == SSLEngineResult .HandshakeStatus .FINISHED
400- || status == SSLEngineResult .HandshakeStatus .NOT_HANDSHAKING ;
402+
403+ // handshake status
404+ boolean ret = status == SSLEngineResult .HandshakeStatus .FINISHED
405+ || status == SSLEngineResult .HandshakeStatus .NOT_HANDSHAKING ;
406+
407+ if ( ret == false )
408+ {
409+ // 2022-06-17 If wss handshake is not completed in 10s, close this channel to prevent cpu overload or unexpected channel error. see #896.
410+ if ( handshakeStartTime > 0 && ( System .currentTimeMillis () - handshakeStartTime ) > 10000 )
411+ {
412+ try {close () ;}catch (Exception ex ){} ;
413+ }
414+ }
415+
416+ return ret ;
401417 }
402418
403419 public SelectableChannel configureBlocking (boolean b ) throws IOException {
@@ -498,4 +514,4 @@ private void tryRestoreCryptedData() {
498514 saveCryptData = null ;
499515 }
500516 }
501- }
517+ }
0 commit comments