diff --git a/common/src/main/java/io/netty/util/internal/Hidden.java b/common/src/main/java/io/netty/util/internal/Hidden.java index 5ce0491865..ac97323573 100644 --- a/common/src/main/java/io/netty/util/internal/Hidden.java +++ b/common/src/main/java/io/netty/util/internal/Hidden.java @@ -111,6 +111,10 @@ class Hidden { "sun.security.ssl.SSLEngineImpl", "unwrap"); + builder.allowBlockingCallsInside( + "sun.security.ssl.SSLEngineImpl", + "wrap"); + builder.nonBlockingThreadPredicate(new Function, Predicate>() { @Override public Predicate apply(final Predicate p) { diff --git a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java b/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java index 68858b127d..ade2def470 100644 --- a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java +++ b/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java @@ -20,6 +20,7 @@ import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.UnpooledByteBufAllocator; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInitializer; @@ -63,9 +64,13 @@ import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; +import static io.netty.buffer.Unpooled.wrappedBuffer; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -238,6 +243,77 @@ public class NettyBlockHoundIntegrationTest { testTrustManagerVerify("TLSv1.3"); } + @Test + public void testSslHandlerWrapAllowsBlockingCalls() throws Exception { + final SslContext sslClientCtx = + SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE) + .sslProvider(SslProvider.JDK) + .build(); + final SslHandler sslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT); + final EventLoopGroup group = new NioEventLoopGroup(); + final CountDownLatch activeLatch = new CountDownLatch(1); + final AtomicReference error = new AtomicReference<>(); + + Channel sc = null; + Channel cc = null; + try { + sc = new ServerBootstrap() + .group(group) + .channel(NioServerSocketChannel.class) + .childHandler(new ChannelInboundHandlerAdapter()) + .bind(new InetSocketAddress(0)) + .syncUninterruptibly() + .channel(); + + cc = new Bootstrap() + .group(group) + .channel(NioSocketChannel.class) + .handler(new ChannelInitializer() { + + @Override + protected void initChannel(Channel ch) { + ch.pipeline().addLast(sslHandler); + ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { + + @Override + public void channelActive(ChannelHandlerContext ctx) { + activeLatch.countDown(); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { + if (evt instanceof SslHandshakeCompletionEvent && + ((SslHandshakeCompletionEvent) evt).cause() != null) { + Throwable cause = ((SslHandshakeCompletionEvent) evt).cause(); + cause.printStackTrace(); + error.set(cause); + } + ctx.fireUserEventTriggered(evt); + } + }); + } + }) + .connect(sc.localAddress()) + .addListener((ChannelFutureListener) future -> + future.channel().writeAndFlush(wrappedBuffer(new byte [] { 1, 2, 3, 4 }))) + .syncUninterruptibly() + .channel(); + + assertTrue(activeLatch.await(5, TimeUnit.SECONDS)); + assertNull(error.get()); + } finally { + if (cc != null) { + cc.close().syncUninterruptibly(); + } + if (sc != null) { + sc.close().syncUninterruptibly(); + } + group.shutdownGracefully(); + ReferenceCountUtil.release(sslClientCtx); + } + } + private static void testTrustManagerVerify(String tlsVersion) throws Exception { final SslContext sslClientCtx = SslContextBuilder.forClient()