Ensure SslHandler.sslCloseFuture() is notified in all cases.
Motivation: The SslHandler.sslCloseFuture() may not be notified when the Channel is closed before a closify_notify is received. Modifications: Ensure we try to fail the sslCloseFuture() when the Channel is closed. Result: Correctly notify the ssl close future.
This commit is contained in:
parent
91951a51ad
commit
d37702aa69
@ -277,7 +277,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
private PendingWriteQueue pendingUnencryptedWrites;
|
private PendingWriteQueue pendingUnencryptedWrites;
|
||||||
|
|
||||||
private Promise<Channel> handshakePromise = new LazyChannelPromise();
|
private Promise<Channel> handshakePromise = new LazyChannelPromise();
|
||||||
private final LazyChannelPromise sslCloseFuture = new LazyChannelPromise();
|
private final LazyChannelPromise sslClosePromise = new LazyChannelPromise();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set by wrap*() methods when something is produced.
|
* Set by wrap*() methods when something is produced.
|
||||||
@ -456,7 +456,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
* @see SSLEngine
|
* @see SSLEngine
|
||||||
*/
|
*/
|
||||||
public Future<Channel> sslCloseFuture() {
|
public Future<Channel> sslCloseFuture() {
|
||||||
return sslCloseFuture;
|
return sslClosePromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -770,6 +770,9 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
// Make sure to release SSLEngine,
|
// Make sure to release SSLEngine,
|
||||||
// and notify the handshake future if the connection has been closed during handshake.
|
// and notify the handshake future if the connection has been closed during handshake.
|
||||||
setHandshakeFailure(ctx, CHANNEL_CLOSED, !outboundClosed);
|
setHandshakeFailure(ctx, CHANNEL_CLOSED, !outboundClosed);
|
||||||
|
|
||||||
|
// Ensure we always notify the sslClosePromise as well
|
||||||
|
sslClosePromise.tryFailure(CHANNEL_CLOSED);
|
||||||
super.channelInactive(ctx);
|
super.channelInactive(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,7 +807,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private boolean ignoreException(Throwable t) {
|
private boolean ignoreException(Throwable t) {
|
||||||
if (!(t instanceof SSLException) && t instanceof IOException && sslCloseFuture.isDone()) {
|
if (!(t instanceof SSLException) && t instanceof IOException && sslClosePromise.isDone()) {
|
||||||
String message = String.valueOf(t.getMessage()).toLowerCase();
|
String message = String.valueOf(t.getMessage()).toLowerCase();
|
||||||
|
|
||||||
// first try to match connection reset / broke peer based on the regex. This is the fastest way
|
// first try to match connection reset / broke peer based on the regex. This is the fastest way
|
||||||
@ -1129,7 +1132,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (notifyClosure) {
|
if (notifyClosure) {
|
||||||
sslCloseFuture.trySuccess(ctx.channel());
|
sslClosePromise.trySuccess(ctx.channel());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (decodeOut != null) {
|
if (decodeOut != null) {
|
||||||
|
@ -62,6 +62,7 @@ import io.netty.util.ReferenceCounted;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
@ -371,4 +372,16 @@ public class SslHandlerTest {
|
|||||||
ReferenceCountUtil.release(sslClientCtx);
|
ReferenceCountUtil.release(sslClientCtx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloseFutureNotified() throws Exception {
|
||||||
|
SslHandler handler = new SslHandler(SSLContext.getDefault().createSSLEngine());
|
||||||
|
EmbeddedChannel ch = new EmbeddedChannel(handler);
|
||||||
|
|
||||||
|
// Closing the Channel will also produce a close_notify so it is expected to return true.
|
||||||
|
assertTrue(ch.finishAndReleaseAll());
|
||||||
|
|
||||||
|
assertTrue(handler.handshakeFuture().cause() instanceof ClosedChannelException);
|
||||||
|
assertTrue(handler.sslCloseFuture().cause() instanceof ClosedChannelException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user