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