@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { handshakeDone = true; if(ctx.pipeline().context(this) != null){ ctx.pipeline().remove(this); } SslHandshakeCompletionEvent handshake = (SslHandshakeCompletionEvent) evt; if (handshake.isSuccess()) { ctx.fireChannelActive(); } else { sink.fireContextError(handshake.cause()); } } super.userEventTriggered(ctx, evt); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { LOG.info(">>> userEventTriggered " + evt); if (evt instanceof SslHandshakeCompletionEvent) { SslHandshakeCompletionEvent hce = (SslHandshakeCompletionEvent) evt; if (!hce.isSuccess() && hce.cause().getMessage().contains("unrecognized_name")) { LOG.info(">>> unrecognized_name"); ctx.close(); unrecognizedName = true; return; } } super.userEventTriggered(ctx, evt); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { LOG.info(">>> userEventTriggered " + evt); if (evt instanceof SslHandshakeCompletionEvent) { SslHandshakeCompletionEvent hce = (SslHandshakeCompletionEvent) evt; if (!hce.isSuccess() && hce.cause().getMessage() .contains("unrecognized_name")) { LOG.info(">>> unrecognized_name"); ctx.close(); unrecognizedName = true; return; } } super.userEventTriggered(ctx, evt); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt instanceof SslHandshakeCompletionEvent) { ctx.pipeline().remove(this); SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt; String peerIdentity = TlsAuthState.UNAUTHENTICATED; if (handshakeEvent.isSuccess()) { SslHandler sslHandler = ctx.pipeline().get(SslHandler.class); if (sslHandler == null) { throw new IllegalStateException( "cannot find a SslHandler in the pipeline (required for MutualAuthHandler)"); } peerIdentity = getPeerIdentity(sslHandler.engine()); } TlsAuthState.setPeerIdentity(ctx, peerIdentity); peerIdentityEstablished(ctx, peerIdentity); } ctx.fireUserEventTriggered(evt); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt; if (handshakeEvent.isSuccess()) { if (NEXT_PROTOCOL_VERSIONS.contains(sslHandler(ctx.pipeline()).applicationProtocol())) { // Successfully negotiated the protocol. // Notify about completion and pass down SSLSession in attributes. grpcHandler.handleProtocolNegotiationCompleted( Attributes.newBuilder() .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslHandler(ctx.pipeline()).engine().getSession()) .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, ctx.channel().remoteAddress()) .build()); // Replace this handler with the GRPC handler. ctx.pipeline().replace(this, null, grpcHandler); } else { fail(ctx, new Exception( "Failed protocol negotiation: Unable to find compatible protocol.")); } } else { fail(ctx, handshakeEvent.cause()); } } super.userEventTriggered(ctx, evt); }
@Test public void tlsHandler_userEventTriggeredSslEvent_unsupportedProtocol() throws Exception { SslHandler badSslHandler = new SslHandler(engine, false) { @Override public String applicationProtocol() { return "badprotocol"; } }; ChannelHandler handler = new ServerTlsHandler(sslContext, grpcHandler); pipeline.addLast(handler); pipeline.replace(SslHandler.class, null, badSslHandler); channelHandlerCtx = pipeline.context(handler); Object sslEvent = SslHandshakeCompletionEvent.SUCCESS; pipeline.fireUserEventTriggered(sslEvent); // No h2 protocol was specified, so this should be closed. assertFalse(channel.isOpen()); ChannelHandlerContext grpcHandlerCtx = pipeline.context(grpcHandler); assertNull(grpcHandlerCtx); }
@Test public void tlsHandler_userEventTriggeredSslEvent_supportedProtocolH2() throws Exception { SslHandler goodSslHandler = new SslHandler(engine, false) { @Override public String applicationProtocol() { return "h2"; } }; ChannelHandler handler = new ServerTlsHandler(sslContext, grpcHandler); pipeline.addLast(handler); pipeline.replace(SslHandler.class, null, goodSslHandler); channelHandlerCtx = pipeline.context(handler); Object sslEvent = SslHandshakeCompletionEvent.SUCCESS; pipeline.fireUserEventTriggered(sslEvent); assertTrue(channel.isOpen()); ChannelHandlerContext grpcHandlerCtx = pipeline.context(grpcHandler); assertNotNull(grpcHandlerCtx); }
@Test public void tlsHandler_userEventTriggeredSslEvent_supportedProtocolGrpcExp() throws Exception { SslHandler goodSslHandler = new SslHandler(engine, false) { @Override public String applicationProtocol() { return "grpc-exp"; } }; ChannelHandler handler = new ServerTlsHandler(sslContext, grpcHandler); pipeline.addLast(handler); pipeline.replace(SslHandler.class, null, goodSslHandler); channelHandlerCtx = pipeline.context(handler); Object sslEvent = SslHandshakeCompletionEvent.SUCCESS; pipeline.fireUserEventTriggered(sslEvent); assertTrue(channel.isOpen()); ChannelHandlerContext grpcHandlerCtx = pipeline.context(grpcHandler); assertNotNull(grpcHandlerCtx); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { LOGGER.trace("userEventTriggered: {}", evt.getClass().getName()); // if the channel has been idle, close it if (evt == IdleStateEvent.FIRST_READER_IDLE_STATE_EVENT) { LOGGER.warn("No data received on channel, closing"); ctx.close(); return; } else if (evt == SslHandshakeCompletionEvent.SUCCESS) { // If we require mutual authentication, extract the principal from // the client certificate and store it in the channel attributes. if (clientAuth) { final SSLSession session = ctx.pipeline().get(SslHandler.class) .engine().getSession(); final Optional<String> customerId = getCustomerId( session.getPeerPrincipal()); if (!customerId.isPresent()) { LOGGER.error( "No customer ID found in certificate, closing"); ctx.close(); return; } ctx.channel().attr(CUSTOMER_KEY).set(customerId.get()); // notify the BatchHandler that the channel is ready and to // create the empty batch ctx.fireChannelActive(); } } }
@Override public final void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { SslHandshakeCompletionEvent handshakeEvt = (SslHandshakeCompletionEvent) evt; if (handshakeEvt.cause() != null) { logger.warn("Handshake failed:", handshakeEvt.cause()); } assertSame(SslHandshakeCompletionEvent.SUCCESS, evt); negoCounter.incrementAndGet(); logStats("HANDSHAKEN"); } }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt; if (handshakeEvent.isSuccess()) { SslHandler handler = ctx.pipeline().get(SslHandler.class); if (NEXT_PROTOCOL_VERSIONS.contains(handler.applicationProtocol())) { // Successfully negotiated the protocol. logSslEngineDetails(Level.FINER, ctx, "TLS negotiation succeeded.", null); // Wait until negotiation is complete to add gRPC. If added too early, HTTP/2 writes // will fail before we see the userEvent, and the channel is closed down prematurely. ctx.pipeline().addBefore(ctx.name(), null, grpcHandler); // Successfully negotiated the protocol. // Notify about completion and pass down SSLSession in attributes. grpcHandler.handleProtocolNegotiationCompleted( Attributes.newBuilder() .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, handler.engine().getSession()) .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, ctx.channel().remoteAddress()) .build()); writeBufferedAndRemove(ctx); } else { Exception ex = new Exception( "Failed ALPN negotiation: Unable to find compatible protocol."); logSslEngineDetails(Level.FINE, ctx, "TLS negotiation failed.", ex); fail(ctx, ex); } } else { fail(ctx, handshakeEvent.cause()); } } super.userEventTriggered(ctx, evt); }
@Test public void tlsHandler_userEventTriggeredSslEvent_handshakeFailure() throws Exception { ChannelHandler handler = new ServerTlsHandler(sslContext, grpcHandler); pipeline.addLast(handler); channelHandlerCtx = pipeline.context(handler); Object sslEvent = new SslHandshakeCompletionEvent(new RuntimeException("bad")); pipeline.fireUserEventTriggered(sslEvent); // No h2 protocol was specified, so this should be closed. assertFalse(channel.isOpen()); ChannelHandlerContext grpcHandlerCtx = pipeline.context(grpcHandler); assertNull(grpcHandlerCtx); }
@Override public void userEventTriggered(final ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { logger.trace(format(ctx, "SslHandshakeCompletionEvent: "), ((SslHandshakeCompletionEvent) evt).cause()); } else if (evt instanceof Exception) { logger.trace(format(ctx, "Exception: "), (Exception) evt); } else { logger.trace(format(ctx, "USER_EVENT: " + evt)); } super.userEventTriggered(ctx, evt); }
@Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof SslHandshakeCompletionEvent) { if (((SslHandshakeCompletionEvent)evt).isSuccess()) { if (debug) { log.debug("SSL connection established [to={}]", id); } handshake(ctx); } super.userEventTriggered(ctx, evt); } else if (evt instanceof AutoReadChangeEvent) { if (evt == AutoReadChangeEvent.PAUSE) { // Completely ignore read timeouts. ignoreTimeouts = -1; } else { // Ignore next timeout. ignoreTimeouts = 1; } } else if (evt instanceof IdleStateEvent) { if (state == CONNECTING || state == CONNECTED) { IdleStateEvent idle = (IdleStateEvent)evt; if (idle.state() == IdleState.WRITER_IDLE) { if (hbFlushed) { // Make sure that we don't push multiple heartbeats to the network buffer simultaneously. // Need to perform this check since remote peer can hang and stop reading // while this channel will still be trying to put more and more heartbeats on its send buffer. hbFlushed = false; ctx.writeAndFlush(Heartbeat.INSTANCE).addListener(hbOnFlush); } } else { // Reader idle. // Ignore if auto-reading was disabled since in such case we will not read any heartbeats. if (ignoreTimeouts != -1 && ctx.channel().config().isAutoRead()) { // Check if timeout should be ignored. if (ignoreTimeouts > 0) { // Decrement the counter of ignored timeouts. ignoreTimeouts--; } else { if (state == CONNECTING) { ctx.fireExceptionCaught(new ConnectTimeoutException("Timeout while connecting to " + id)); } else if (state == CONNECTED) { ctx.fireExceptionCaught(new SocketTimeoutException("Timeout while reading data from " + id)); } } } } } } else { super.userEventTriggered(ctx, evt); } }