Potential fix for infinite loop in SslHandler.unwrap()

This commit is contained in:
Trustin Lee 2009-04-10 00:57:09 +00:00
parent f1b6534aaf
commit 7de2d0c0df

View File

@ -439,18 +439,25 @@ public class SslHandler extends FrameDecoder {
} }
ByteBuffer outAppBuf = pendingWrite.outAppBuf; ByteBuffer outAppBuf = pendingWrite.outAppBuf;
boolean outboundDone;
SSLEngineResult result; SSLEngineResult result = null;
try { try {
synchronized (handshakeLock) { synchronized (handshakeLock) {
result = engine.wrap(outAppBuf, outNetBuf); outboundDone = engine.isOutboundDone();
if (!outboundDone) {
result = engine.wrap(outAppBuf, outNetBuf);
}
} }
} finally { } finally {
if (!outAppBuf.hasRemaining()) { if (!outAppBuf.hasRemaining()) {
pendingUnencryptedWrites.remove(); pendingUnencryptedWrites.remove();
} }
} }
if (result.bytesProduced() > 0) {
if (outboundDone) {
success = false;
break;
} else if (result.bytesProduced() > 0) {
outNetBuf.flip(); outNetBuf.flip();
msg = ChannelBuffers.buffer(outNetBuf.remaining()); msg = ChannelBuffers.buffer(outNetBuf.remaining());
msg.writeBytes(outNetBuf.array(), 0, msg.capacity()); msg.writeBytes(outNetBuf.array(), 0, msg.capacity());
@ -468,7 +475,6 @@ public class SslHandler extends FrameDecoder {
channel, future, msg, channel.getRemoteAddress()); channel, future, msg, channel.getRemoteAddress());
if (Thread.holdsLock(pendingEncryptedWrites)) { if (Thread.holdsLock(pendingEncryptedWrites)) {
offered = pendingEncryptedWrites.offer(encryptedWrite); offered = pendingEncryptedWrites.offer(encryptedWrite);
} else { } else {
synchronized (pendingEncryptedWrites) { synchronized (pendingEncryptedWrites) {
offered = pendingEncryptedWrites.offer(encryptedWrite); offered = pendingEncryptedWrites.offer(encryptedWrite);
@ -519,6 +525,8 @@ public class SslHandler extends FrameDecoder {
} }
if (!success) { if (!success) {
IllegalStateException cause =
new IllegalStateException("SSLEngine already closed");
// Mark all remaining pending writes as failure if anything // Mark all remaining pending writes as failure if anything
// wrong happened before the write requests are wrapped. // wrong happened before the write requests are wrapped.
// Please note that we do not call setFailure while a lock is // Please note that we do not call setFailure while a lock is
@ -532,8 +540,7 @@ public class SslHandler extends FrameDecoder {
} }
} }
pendingWrite.future.setFailure( pendingWrite.future.setFailure(cause);
new IllegalStateException("SSLEngine already closed"));
} }
} }
} }
@ -578,6 +585,9 @@ public class SslHandler extends FrameDecoder {
try { try {
for (;;) { for (;;) {
synchronized (handshakeLock) { synchronized (handshakeLock) {
if (engine.isOutboundDone()) {
break;
}
result = engine.wrap(EMPTY_BUFFER, outNetBuf); result = engine.wrap(EMPTY_BUFFER, outNetBuf);
} }
@ -645,8 +655,14 @@ public class SslHandler extends FrameDecoder {
for (;;) { for (;;) {
SSLEngineResult result; SSLEngineResult result;
synchronized (handshakeLock) { synchronized (handshakeLock) {
boolean inboundDone = engine.isInboundDone();
if (inboundDone) {
break;
}
if (initialHandshake && !engine.getUseClientMode() && if (initialHandshake && !engine.getUseClientMode() &&
!engine.isInboundDone() && !engine.isOutboundDone()) { !inboundDone && !engine.isOutboundDone()) {
handshake(channel); handshake(channel);
initialHandshake = false; initialHandshake = false;
} }