@@ -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 ;
@@ -767,6 +770,11 @@ private Integer unwrap(int nRead, long timeout, TimeUnit unit) throws ExecutionE
767
770
//perform any tasks if needed
768
771
if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_TASK ) {
769
772
tasks ();
773
+ } else if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_WRAP ) {
774
+ if (++handshakeWrapQueueLength > HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT ) {
775
+ throw new ExecutionException (
776
+ new IOException (sm .getString ("channel.nio.ssl.handshakeWrapQueueTooLong" )));
777
+ }
770
778
}
771
779
//if we need more network data, then bail out for now.
772
780
if (unwrap .getStatus () == Status .BUFFER_UNDERFLOW ) {
@@ -897,6 +905,8 @@ protected void wrap() {
897
905
if (!netOutBuffer .hasRemaining ()) {
898
906
netOutBuffer .clear ();
899
907
SSLEngineResult result = sslEngine .wrap (src , netOutBuffer );
908
+ // Call to wrap() will have included any required handshake data
909
+ handshakeWrapQueueLength = 0 ;
900
910
written = result .bytesConsumed ();
901
911
netOutBuffer .flip ();
902
912
if (result .getStatus () == Status .OK ) {
@@ -962,6 +972,11 @@ public void completed(Integer nBytes, A attach) {
962
972
//perform any tasks if needed
963
973
if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_TASK ) {
964
974
tasks ();
975
+ } else if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_WRAP ) {
976
+ if (++handshakeWrapQueueLength > HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT ) {
977
+ throw new ExecutionException (new IOException (
978
+ sm .getString ("channel.nio.ssl.handshakeWrapQueueTooLong" )));
979
+ }
965
980
}
966
981
//if we need more network data, then bail out for now.
967
982
if (unwrap .getStatus () == Status .BUFFER_UNDERFLOW ) {
@@ -1075,6 +1090,11 @@ public void completed(Integer nBytes, A attach) {
1075
1090
//perform any tasks if needed
1076
1091
if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_TASK ) {
1077
1092
tasks ();
1093
+ } else if (unwrap .getHandshakeStatus () == HandshakeStatus .NEED_WRAP ) {
1094
+ if (++handshakeWrapQueueLength > HANDSHAKE_WRAP_QUEUE_LENGTH_LIMIT ) {
1095
+ throw new ExecutionException (new IOException (
1096
+ sm .getString ("channel.nio.ssl.handshakeWrapQueueTooLong" )));
1097
+ }
1078
1098
}
1079
1099
//if we need more network data, then bail out for now.
1080
1100
if (unwrap .getStatus () == Status .BUFFER_UNDERFLOW ) {
@@ -1184,6 +1204,8 @@ public <A> void write(final ByteBuffer src, final long timeout, final TimeUnit u
1184
1204
netOutBuffer .clear ();
1185
1205
// Wrap the source data into the internal buffer
1186
1206
SSLEngineResult result = sslEngine .wrap (src , netOutBuffer );
1207
+ // Call to wrap() will have included any required handshake data
1208
+ handshakeWrapQueueLength = 0 ;
1187
1209
final int written = result .bytesConsumed ();
1188
1210
netOutBuffer .flip ();
1189
1211
if (result .getStatus () == Status .OK ) {
0 commit comments