Fix a NoSuchElementException and out-of-order event problem caused by SslHandler
The fix prevents from reentering channelRead incorrectly. It also prevents from getting the inbound requests out of order.
This commit is contained in:
parent
d8479a04df
commit
c77ab7d092
@ -311,7 +311,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link #close()}
|
* See {@link #close()}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public ChannelFuture close(final ChannelPromise future) {
|
public ChannelFuture close(final ChannelPromise future) {
|
||||||
final ChannelHandlerContext ctx = this.ctx;
|
final ChannelHandlerContext ctx = this.ctx;
|
||||||
@ -473,9 +472,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
out = ctx.alloc().buffer();
|
out = ctx.alloc().buffer();
|
||||||
continue;
|
continue;
|
||||||
case NEED_UNWRAP:
|
case NEED_UNWRAP:
|
||||||
if (internalBuffer().isReadable()) {
|
unwrapLater = true;
|
||||||
unwrapLater = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NEED_TASK:
|
case NEED_TASK:
|
||||||
runDelegatedTasks();
|
runDelegatedTasks();
|
||||||
@ -486,9 +483,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
case NOT_HANDSHAKING:
|
case NOT_HANDSHAKING:
|
||||||
// Workaround for TLS False Start problem reported at:
|
// Workaround for TLS False Start problem reported at:
|
||||||
// https://github.com/netty/netty/issues/1108#issuecomment-14266970
|
// https://github.com/netty/netty/issues/1108#issuecomment-14266970
|
||||||
if (internalBuffer().isReadable()) {
|
unwrapLater = true;
|
||||||
unwrapLater = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
|
throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
|
||||||
@ -499,10 +494,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unwrapLater) {
|
|
||||||
unwrapLater(ctx);
|
|
||||||
}
|
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
setHandshakeFailure(e);
|
setHandshakeFailure(e);
|
||||||
throw e;
|
throw e;
|
||||||
@ -521,22 +512,13 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
out.release();
|
out.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void unwrapLater(ChannelHandlerContext ctx) throws SSLException {
|
if (unwrapLater) {
|
||||||
RecyclableArrayList out = RecyclableArrayList.newInstance();
|
unwrap(ctx);
|
||||||
try {
|
|
||||||
decode(ctx, internalBuffer(), out);
|
|
||||||
for (int i = 0; i < out.size(); i++) {
|
|
||||||
ctx.fireChannelRead(out.get(i));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
out.recycle();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushNonAppData0(ChannelHandlerContext ctx) throws SSLException {
|
private void flushNonAppData0(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
|
||||||
boolean unwrapLater = false;
|
|
||||||
ByteBuf out = null;
|
ByteBuf out = null;
|
||||||
try {
|
try {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -551,29 +533,25 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (result.getHandshakeStatus()) {
|
switch (result.getHandshakeStatus()) {
|
||||||
case NEED_WRAP:
|
case FINISHED:
|
||||||
continue;
|
setHandshakeSuccess();
|
||||||
case NEED_UNWRAP:
|
|
||||||
if (internalBuffer().isReadable()) {
|
|
||||||
unwrapLater = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NEED_TASK:
|
case NEED_TASK:
|
||||||
runDelegatedTasks();
|
runDelegatedTasks();
|
||||||
continue;
|
break;
|
||||||
case FINISHED:
|
case NEED_UNWRAP:
|
||||||
setHandshakeSuccess();
|
if (!inUnwrap) {
|
||||||
// try to flush now just in case as there may be pending write tasks
|
unwrap(ctx);
|
||||||
flush0(ctx);
|
}
|
||||||
return;
|
break;
|
||||||
|
case NEED_WRAP:
|
||||||
|
break;
|
||||||
case NOT_HANDSHAKING:
|
case NOT_HANDSHAKING:
|
||||||
// Workaround for TLS False Start problem reported at:
|
// Workaround for TLS False Start problem reported at:
|
||||||
// https://github.com/netty/netty/issues/1108#issuecomment-14266970
|
// https://github.com/netty/netty/issues/1108#issuecomment-14266970
|
||||||
if (internalBuffer().isReadable()) {
|
if (!inUnwrap) {
|
||||||
unwrapLater = true;
|
unwrap(ctx);
|
||||||
}
|
}
|
||||||
// try to flush now just in case as there may be pending write tasks
|
|
||||||
flush0(ctx);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
|
throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
|
||||||
@ -583,10 +561,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unwrapLater) {
|
|
||||||
unwrapLater(ctx);
|
|
||||||
}
|
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
setHandshakeFailure(e);
|
setHandshakeFailure(e);
|
||||||
throw e;
|
throw e;
|
||||||
@ -848,6 +822,18 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
unwrap(ctx, buffer, out);
|
unwrap(ctx, buffer, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void unwrap(ChannelHandlerContext ctx) throws SSLException {
|
||||||
|
RecyclableArrayList out = RecyclableArrayList.newInstance();
|
||||||
|
try {
|
||||||
|
unwrap(ctx, Unpooled.EMPTY_BUFFER.nioBuffer(), out);
|
||||||
|
for (int i = 0; i < out.size(); i++) {
|
||||||
|
ctx.fireChannelRead(out.get(i));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
out.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void unwrap(ChannelHandlerContext ctx, ByteBuffer packet, List<Object> out) throws SSLException {
|
private void unwrap(ChannelHandlerContext ctx, ByteBuffer packet, List<Object> out) throws SSLException {
|
||||||
boolean wrapLater = false;
|
boolean wrapLater = false;
|
||||||
int bytesProduced = 0;
|
int bytesProduced = 0;
|
||||||
@ -872,7 +858,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
case NEED_UNWRAP:
|
case NEED_UNWRAP:
|
||||||
break;
|
break;
|
||||||
case NEED_WRAP:
|
case NEED_WRAP:
|
||||||
wrapLater = true;
|
flushNonAppData0(ctx, true);
|
||||||
break;
|
break;
|
||||||
case NEED_TASK:
|
case NEED_TASK:
|
||||||
runDelegatedTasks();
|
runDelegatedTasks();
|
||||||
@ -894,7 +880,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wrapLater) {
|
if (wrapLater) {
|
||||||
flushNonAppData0(ctx);
|
flush0(ctx);
|
||||||
}
|
}
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
setHandshakeFailure(e);
|
setHandshakeFailure(e);
|
||||||
@ -1044,7 +1030,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
engine.beginHandshake();
|
engine.beginHandshake();
|
||||||
flushNonAppData0(ctx);
|
flushNonAppData0(ctx, false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
notifyHandshakeFailure(e);
|
notifyHandshakeFailure(e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user