From 800853049814e751d9194bcb7d1a5947a870215a Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Fri, 18 Apr 2014 17:59:48 +0900 Subject: [PATCH] Work around an Android SSLEngine issue Motivation: Some Android SSLEngine implementations skip FINISHED handshake status and go straightly into NOT_HANDSHAKING. This behavior blocks SslHandler from notifying its handshakeFuture, because we do the notification when SSLEngine enters the FINISHED state. Modification: When the current handshake state is NOT_HANDSHAKING and the handshakeFuture is not fulfilled yet, treat NOT_HANDSHAKING as FINISHED. Result: Better Android compatibility - fixes #1823 --- .../java/io/netty/handler/ssl/SslHandler.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index fd89c19a96..3296be54bb 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -470,6 +470,8 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH setHandshakeSuccess(); // deliberate fall-through case NOT_HANDSHAKING: + setHandshakeSuccessIfStillHandshaking(); + // deliberate fall-through case NEED_WRAP: finishWrap(ctx, out, promise, inUnwrap); promise = null; @@ -541,6 +543,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH case NEED_WRAP: break; case NOT_HANDSHAKING: + setHandshakeSuccessIfStillHandshaking(); // Workaround for TLS False Start problem reported at: // https://github.com/netty/netty/issues/1108#issuecomment-14266970 if (!inUnwrap) { @@ -895,6 +898,10 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH wrapLater = true; continue; case NOT_HANDSHAKING: + if (setHandshakeSuccessIfStillHandshaking()) { + wrapLater = true; + continue; + } break; default: throw new IllegalStateException("Unknown handshake status: " + handshakeStatus); @@ -1006,6 +1013,21 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH } } + /** + * Works around some Android {@link SSLEngine} implementations that skip {@link HandshakeStatus#FINISHED} and + * go straight into {@link HandshakeStatus#NOT_HANDSHAKING} when handshake is finished. + * + * @return {@code true} if and only if the workaround has been applied and thus {@link #handshakeFuture} has been + * marked as success by this method + */ + private boolean setHandshakeSuccessIfStillHandshaking() { + if (!handshakePromise.isDone()) { + setHandshakeSuccess(); + return true; + } + return false; + } + /** * Notify all the handshake futures about the successfully handshake */