use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.
the class Http2MultiplexTransportTest method testFireChannelReadAfterHandshakeSuccess.
private void testFireChannelReadAfterHandshakeSuccess(SslProvider provider) throws Exception {
SelfSignedCertificate ssc = null;
try {
ssc = new SelfSignedCertificate();
final SslContext serverCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
ServerBootstrap sb = new ServerBootstrap();
sb.group(eventLoopGroup);
sb.channel(NioServerSocketChannel.class);
sb.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(serverCtx.newHandler(ch.alloc()));
ch.pipeline().addLast(new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_1_1) {
@Override
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
ctx.pipeline().addLast(new Http2FrameCodecBuilder(true).build());
ctx.pipeline().addLast(new Http2MultiplexHandler(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2HeadersFrame && ((Http2HeadersFrame) msg).isEndStream()) {
ctx.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false)).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ctx.writeAndFlush(new DefaultHttp2DataFrame(Unpooled.copiedBuffer("Hello World", CharsetUtil.US_ASCII), true));
}
});
}
ReferenceCountUtil.release(msg);
}
}));
}
});
}
});
serverChannel = sb.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).sync().channel();
final SslContext clientCtx = SslContextBuilder.forClient().sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).trustManager(InsecureTrustManagerFactory.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
final CountDownLatch latch = new CountDownLatch(1);
Bootstrap bs = new Bootstrap();
bs.group(eventLoopGroup);
bs.channel(NioSocketChannel.class);
bs.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(clientCtx.newHandler(ch.alloc()));
ch.pipeline().addLast(new Http2FrameCodecBuilder(false).build());
ch.pipeline().addLast(new Http2MultiplexHandler(DISCARD_HANDLER));
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof SslHandshakeCompletionEvent) {
SslHandshakeCompletionEvent handshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
if (handshakeCompletionEvent.isSuccess()) {
Http2StreamChannelBootstrap h2Bootstrap = new Http2StreamChannelBootstrap(clientChannel);
h2Bootstrap.handler(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof Http2DataFrame && ((Http2DataFrame) msg).isEndStream()) {
latch.countDown();
}
ReferenceCountUtil.release(msg);
}
});
h2Bootstrap.open().addListener(new FutureListener<Channel>() {
@Override
public void operationComplete(Future<Channel> future) {
if (future.isSuccess()) {
future.getNow().writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), true));
}
}
});
}
}
}
});
}
});
clientChannel = bs.connect(serverChannel.localAddress()).sync().channel();
latch.await();
} finally {
if (ssc != null) {
ssc.delete();
}
}
}
use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.
the class NettyBlockHoundIntegrationTest method testHandshake.
private static void testHandshake(SslContext sslClientCtx, SslHandler clientSslHandler, SslHandler serverSslHandler) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
Channel sc = null;
Channel cc = null;
try {
sc = new ServerBootstrap().group(group).channel(NioServerSocketChannel.class).childHandler(serverSslHandler).bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
ChannelFuture future = new Bootstrap().group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(clientSslHandler).addLast(new ChannelInboundHandlerAdapter() {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
if (evt instanceof SslHandshakeCompletionEvent && ((SslHandshakeCompletionEvent) evt).cause() != null) {
((SslHandshakeCompletionEvent) evt).cause().printStackTrace();
}
ctx.fireUserEventTriggered(evt);
}
});
}
}).connect(sc.localAddress());
cc = future.syncUninterruptibly().channel();
clientSslHandler.handshakeFuture().await().sync();
serverSslHandler.handshakeFuture().await().sync();
} finally {
if (cc != null) {
cc.close().syncUninterruptibly();
}
if (sc != null) {
sc.close().syncUninterruptibly();
}
group.shutdownGracefully();
ReferenceCountUtil.release(sslClientCtx);
}
}
use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project netty by netty.
the class NettyBlockHoundIntegrationTest method testSslHandlerWrapAllowsBlockingCalls.
@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<Throwable> 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<Channel>() {
@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);
}
}
use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project zuul by Netflix.
the class OriginResponseReceiver method userEventTriggered.
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof CompleteEvent) {
final CompleteReason reason = ((CompleteEvent) evt).getReason();
if ((reason != SESSION_COMPLETE) && (edgeProxy != null)) {
LOG.error("Origin request completed with reason other than COMPLETE: {}, {}", reason.name(), ChannelUtils.channelInfoForLogging(ctx.channel()));
final ZuulException ze = new ZuulException("CompleteEvent", reason.name(), true);
edgeProxy.errorFromOrigin(ze);
}
// See channelWrite() where these vars are first set onto the channel.
try {
super.userEventTriggered(ctx, evt);
} finally {
postCompleteHook(ctx, evt);
}
} else if (evt instanceof SslHandshakeCompletionEvent && !((SslHandshakeCompletionEvent) evt).isSuccess()) {
Throwable cause = ((SslHandshakeCompletionEvent) evt).cause();
ctx.channel().attr(SSL_HANDSHAKE_UNSUCCESS_FROM_ORIGIN_THROWABLE).set(cause);
} else if (evt instanceof IdleStateEvent) {
if (edgeProxy != null) {
LOG.error("Origin request received IDLE event: {}", ChannelUtils.channelInfoForLogging(ctx.channel()));
edgeProxy.errorFromOrigin(new OutboundException(READ_TIMEOUT, edgeProxy.getRequestAttempts()));
}
super.userEventTriggered(ctx, evt);
} else {
super.userEventTriggered(ctx, evt);
}
}
use of io.netty.handler.ssl.SslHandshakeCompletionEvent in project zuul by Netflix.
the class SslHandshakeInfoHandler method userEventTriggered.
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof SslHandshakeCompletionEvent) {
try {
SslHandshakeCompletionEvent sslEvent = (SslHandshakeCompletionEvent) evt;
if (sslEvent.isSuccess()) {
CurrentPassport.fromChannel(ctx.channel()).add(PassportState.SERVER_CH_SSL_HANDSHAKE_COMPLETE);
SslHandler sslhandler = ctx.channel().pipeline().get(SslHandler.class);
SSLSession session = sslhandler.engine().getSession();
ClientAuth clientAuth = whichClientAuthEnum(sslhandler);
Certificate serverCert = null;
X509Certificate peerCert = null;
if ((clientAuth == ClientAuth.REQUIRE || clientAuth == ClientAuth.OPTIONAL) && session.getPeerCertificates() != null && session.getPeerCertificates().length > 0) {
peerCert = (X509Certificate) session.getPeerCertificates()[0];
}
if (session.getLocalCertificates() != null && session.getLocalCertificates().length > 0) {
serverCert = session.getLocalCertificates()[0];
}
SslHandshakeInfo info = new SslHandshakeInfo(isSSlFromIntermediary, session.getProtocol(), session.getCipherSuite(), clientAuth, serverCert, peerCert);
ctx.channel().attr(ATTR_SSL_INFO).set(info);
// Metrics.
incrementCounters(sslEvent, info);
logger.debug("Successful SSL Handshake: {}", info);
} else {
String clientIP = ctx.channel().attr(SourceAddressChannelHandler.ATTR_SOURCE_ADDRESS).get();
Throwable cause = sslEvent.cause();
PassportState passportState = CurrentPassport.fromChannel(ctx.channel()).getState();
if (cause instanceof ClosedChannelException && (PassportState.SERVER_CH_INACTIVE.equals(passportState) || PassportState.SERVER_CH_IDLE_TIMEOUT.equals(passportState))) {
// Either client closed the connection without/before having completed a handshake, or
// the connection idle timed-out before handshake.
// NOTE: we were seeing a lot of these in prod and can repro by just telnetting to port and then closing terminal
// without sending anything.
// So don't treat these as SSL handshake failures.
logger.debug("Client closed connection or it idle timed-out without doing an ssl handshake. " + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
} else if (cause instanceof SSLException && cause.getMessage().contains("handshake timed out")) {
logger.debug("Client timed-out doing the ssl handshake. " + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
} else if (cause instanceof SSLException && cause.getMessage().contains("failure when writing TLS control frames")) {
// This can happen if the ClientHello is sent followed by a RST packet, before we can respond.
logger.debug("Client terminated handshake early." + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()));
} else {
String msg = "Unsuccessful SSL Handshake: " + sslEvent + ", client_ip = " + clientIP + ", channel_info = " + ChannelUtils.channelInfoForLogging(ctx.channel()) + ", error = " + cause;
if (cause instanceof ClosedChannelException) {
logger.debug(msg);
} else {
logger.debug(msg, cause);
}
incrementCounters(sslEvent, null);
}
}
} catch (Throwable e) {
logger.warn("Error getting the SSL handshake info.", e);
} finally {
// Now remove this handler from the pipeline as no longer needed once the ssl handshake has completed.
ctx.pipeline().remove(this);
}
} else if (evt instanceof SslCloseCompletionEvent) {
// TODO - increment a separate metric for this event?
} else if (evt instanceof SniCompletionEvent) {
logger.debug("SNI Parsing Complete: {}", evt);
SniCompletionEvent sniCompletionEvent = (SniCompletionEvent) evt;
if (sniCompletionEvent.isSuccess()) {
spectatorRegistry.counter("zuul.sni.parse.success").increment();
} else {
Throwable cause = sniCompletionEvent.cause();
spectatorRegistry.counter("zuul.sni.parse.failure", "cause", cause != null ? cause.getMessage() : "UNKNOWN").increment();
}
}
super.userEventTriggered(ctx, evt);
}
Aggregations