@@ -53,10 +53,12 @@ public class SecureNio2Channel extends Nio2Channel {
53
53
private static final Log log = LogFactory .getLog (SecureNio2Channel .class );
54
54
private static final StringManager sm = StringManager .getManager (SecureNio2Channel .class );
55
55
56
- // Value determined by observation of what the SSL Engine requested in
57
- // various scenarios
56
+ // Value determined by observation of what the SSL Engine requested in various scenarios
58
57
private static final int DEFAULT_NET_BUFFER_SIZE = 16921 ;
59
58
59
+ // Much longer than it should ever need to be but short enough to trigger connection closure if something goes wrong
60
+ private static final int HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT = 100 ;
61
+
60
62
protected final Nio2Endpoint endpoint ;
61
63
62
64
protected ByteBuffer netInBuffer ;
@@ -67,6 +69,7 @@ public class SecureNio2Channel extends Nio2Channel {
67
69
protected volatile boolean sniComplete = false ;
68
70
69
71
private volatile boolean handshakeComplete = false ;
72
+ private volatile int handshakeWrapQueueLength = 0 ;
70
73
private volatile HandshakeStatus handshakeStatus ; //gets set by handshake
71
74
72
75
protected boolean closed ;
@@ -762,6 +765,11 @@ private Integer unwrap(int nRead, long timeout, TimeUnit unit) throws ExecutionE
762
765
//perform any tasks if needed
763
766
if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_TASK ) {
764
767
tasks ();
768
+ } else if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_WRAP ) {
769
+ if (++handshakeWrapQueueLength > HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT ) {
770
+ throw new ExecutionException (
771
+ new IOException (sm .getString ("channel.nio.ssl.handshakeWrapQueueTooLong" )));
772
+ }
765
773
}
766
774
//if we need more network data, then bail out for now.
767
775
if (unwrap .getStatus () == Status .BUFFER_UNDERFLOW ) {
@@ -892,6 +900,8 @@ protected void wrap() {
892
900
if (!netOutBuffer .hasRemaining ()) {
893
901
netOutBuffer .clear ();
894
902
SSLEngineResult result = sslEngine .wrap (src , netOutBuffer );
903
+ // Call to wrap() will have included any required handshake data
904
+ handshakeWrapQueueLength = 0 ;
895
905
written = result .bytesConsumed ();
896
906
netOutBuffer .flip ();
897
907
if (result .getStatus () == Status .OK ) {
@@ -957,6 +967,11 @@ public void completed(Integer nBytes, A attach) {
957
967
//perform any tasks if needed
958
968
if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_TASK ) {
959
969
tasks ();
970
+ } else if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_WRAP ) {
971
+ if (++handshakeWrapQueueLength > HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT ) {
972
+ throw new ExecutionException (new IOException (
973
+ sm .getString ("channel.nio.ssl.handshakeWrapQueueTooLong" )));
974
+ }
960
975
}
961
976
//if we need more network data, then bail out for now.
962
977
if (unwrap .getStatus () == Status .BUFFER_UNDERFLOW ) {
@@ -1070,6 +1085,11 @@ public void completed(Integer nBytes, A attach) {
1070
1085
//perform any tasks if needed
1071
1086
if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_TASK ) {
1072
1087
tasks ();
1088
+ } else if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_WRAP ) {
1089
+ if (++handshakeWrapQueueLength > HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT ) {
1090
+ throw new ExecutionException (new IOException (
1091
+ sm .getString ("channel.nio.ssl.handshakeWrapQueueTooLong" )));
1092
+ }
1073
1093
}
1074
1094
//if we need more network data, then bail out for now.
1075
1095
if (unwrap .getStatus () == Status .BUFFER_UNDERFLOW ) {
@@ -1179,6 +1199,8 @@ public <A> void write(final ByteBuffer src, final long timeout, final TimeUnit u
1179
1199
netOutBuffer .clear ();
1180
1200
// Wrap the source data into the internal buffer
1181
1201
SSLEngineResult result = sslEngine .wrap (src , netOutBuffer );
1202
+ // Call to wrap() will have included any required handshake data
1203
+ handshakeWrapQueueLength = 0 ;
1182
1204
final int written = result .bytesConsumed ();
1183
1205
netOutBuffer .flip ();
1184
1206
if (result .getStatus () == Status .OK ) {
0 commit comments