mirror of https://github.com/grpc/grpc-java.git
Fixing erroneous server log when TLS nego fails
Only adding the server HTTP/2 handler after the TLS negotiation is successful. Fixes #974
This commit is contained in:
parent
31394aa9df
commit
ccf328f367
|
|
@ -38,6 +38,7 @@ import io.grpc.internal.ServerTransportListener;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.handler.codec.http2.DefaultHttp2Connection;
|
import io.netty.handler.codec.http2.DefaultHttp2Connection;
|
||||||
import io.netty.handler.codec.http2.DefaultHttp2FrameReader;
|
import io.netty.handler.codec.http2.DefaultHttp2FrameReader;
|
||||||
import io.netty.handler.codec.http2.DefaultHttp2FrameWriter;
|
import io.netty.handler.codec.http2.DefaultHttp2FrameWriter;
|
||||||
|
|
@ -84,19 +85,20 @@ class NettyServerTransport implements ServerTransport {
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
|
||||||
// Create the Netty handler for the pipeline.
|
// Create the Netty handler for the pipeline.
|
||||||
final NettyServerHandler handler = createHandler(listener);
|
final NettyServerHandler grpcHandler = createHandler(listener);
|
||||||
|
|
||||||
// Notify when the channel closes.
|
// Notify when the channel closes.
|
||||||
channel.closeFuture().addListener(new ChannelFutureListener() {
|
channel.closeFuture().addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
notifyTerminated(handler.connectionError());
|
notifyTerminated(grpcHandler.connectionError());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ChannelHandler handler = grpcHandler;
|
||||||
if (sslContext != null) {
|
if (sslContext != null) {
|
||||||
SSLEngine sslEngine = sslContext.newEngine(channel.alloc());
|
SSLEngine sslEngine = sslContext.newEngine(channel.alloc());
|
||||||
channel.pipeline().addLast(ProtocolNegotiators.serverTls(sslEngine));
|
handler = ProtocolNegotiators.serverTls(sslEngine, grpcHandler);
|
||||||
}
|
}
|
||||||
channel.pipeline().addLast(handler);
|
channel.pipeline().addLast(handler);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ public final class ProtocolNegotiators {
|
||||||
/**
|
/**
|
||||||
* Create a TLS handler for HTTP/2 capable of using ALPN/NPN.
|
* Create a TLS handler for HTTP/2 capable of using ALPN/NPN.
|
||||||
*/
|
*/
|
||||||
public static ChannelHandler serverTls(SSLEngine sslEngine) {
|
public static ChannelHandler serverTls(SSLEngine sslEngine, final ChannelHandler grpcHandler) {
|
||||||
Preconditions.checkNotNull(sslEngine, "sslEngine");
|
Preconditions.checkNotNull(sslEngine, "sslEngine");
|
||||||
|
|
||||||
final SslHandler sslHandler = new SslHandler(sslEngine, false);
|
final SslHandler sslHandler = new SslHandler(sslEngine, false);
|
||||||
|
|
@ -97,11 +97,11 @@ public final class ProtocolNegotiators {
|
||||||
if (evt instanceof SslHandshakeCompletionEvent) {
|
if (evt instanceof SslHandshakeCompletionEvent) {
|
||||||
SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;
|
SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;
|
||||||
if (handshakeEvent.isSuccess()) {
|
if (handshakeEvent.isSuccess()) {
|
||||||
if (applicationProtocol(ctx) != null) {
|
if (sslHandler(ctx).applicationProtocol() != null) {
|
||||||
// Successfully negotiated the protocol.
|
// Successfully negotiated the protocol. Replace this handler with
|
||||||
ctx.pipeline().remove(this);
|
// the GRPC handler.
|
||||||
|
ctx.pipeline().replace(this, null, grpcHandler);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fail(ctx, new Exception(
|
fail(ctx, new Exception(
|
||||||
"Failed protocol negotiation: Unable to find compatible protocol."));
|
"Failed protocol negotiation: Unable to find compatible protocol."));
|
||||||
}
|
}
|
||||||
|
|
@ -113,34 +113,16 @@ public final class ProtocolNegotiators {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fail(ChannelHandlerContext ctx, Throwable exception) {
|
private void fail(ChannelHandlerContext ctx, Throwable exception) {
|
||||||
log.log(Level.FINE, errorMessage(ctx), exception);
|
Level level = Level.FINE;
|
||||||
|
if (log.isLoggable(level)) {
|
||||||
|
log.log(level, errorMessage(ctx), exception);
|
||||||
|
}
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String errorMessage(ChannelHandlerContext ctx) {
|
private String errorMessage(ChannelHandlerContext ctx) {
|
||||||
StringBuilder builder = new StringBuilder("TLS negotiation failed for new client. ");
|
StringBuilder builder = new StringBuilder("TLS negotiation failed for new client.\n");
|
||||||
SSLEngine engine = sslHandler(ctx).engine();
|
return sslEngineDetails(sslHandler(ctx), builder).toString();
|
||||||
if (engine instanceof OpenSslEngine) {
|
|
||||||
builder.append("OpenSSL version: ");
|
|
||||||
builder.append("0x").append(Integer.toHexString(OpenSsl.version()));
|
|
||||||
builder.append(" [").append(OpenSsl.versionString()).append(']');
|
|
||||||
builder.append(". ALPN supported: ").append(OpenSsl.isAlpnSupported()).append(". ");
|
|
||||||
} else if (JettyTlsUtil.isJettyAlpnConfigured()) {
|
|
||||||
builder.append("Jetty ALPN configured. ");
|
|
||||||
} else if (JettyTlsUtil.isJettyNpnConfigured()) {
|
|
||||||
builder.append("Jetty NPN configured. ");
|
|
||||||
}
|
|
||||||
builder.append("Enabled ciphers=");
|
|
||||||
builder.append(Arrays.toString(enabledCiphers(ctx))).append(". ");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String applicationProtocol(ChannelHandlerContext ctx) {
|
|
||||||
return sslHandler(ctx).applicationProtocol();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] enabledCiphers(ChannelHandlerContext ctx) {
|
|
||||||
return sslHandler(ctx).engine().getEnabledCipherSuites();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SslHandler sslHandler(ChannelHandlerContext ctx) {
|
private SslHandler sslHandler(ChannelHandlerContext ctx) {
|
||||||
|
|
@ -213,6 +195,39 @@ public final class ProtocolNegotiators {
|
||||||
return Status.UNAVAILABLE.withDescription(msg).asRuntimeException();
|
return Status.UNAVAILABLE.withDescription(msg).asRuntimeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static StringBuilder sslEngineDetails(SslHandler sslHandler, StringBuilder builder) {
|
||||||
|
SSLEngine engine = sslHandler.engine();
|
||||||
|
builder.append("SSLEngine Details: [\n");
|
||||||
|
if (engine instanceof OpenSslEngine) {
|
||||||
|
builder.append(" OpenSSL, ");
|
||||||
|
builder.append("Version: 0x").append(Integer.toHexString(OpenSsl.version()));
|
||||||
|
builder.append(" (").append(OpenSsl.versionString()).append("), ");
|
||||||
|
builder.append("ALPN supported: ").append(OpenSsl.isAlpnSupported());
|
||||||
|
} else if (JettyTlsUtil.isJettyAlpnConfigured()) {
|
||||||
|
builder.append(" Jetty ALPN");
|
||||||
|
} else if (JettyTlsUtil.isJettyNpnConfigured()) {
|
||||||
|
builder.append(" Jetty NPN");
|
||||||
|
}
|
||||||
|
builder.append("\n TLS Protocol: ");
|
||||||
|
builder.append(engine.getSession().getProtocol());
|
||||||
|
builder.append("\n Application Protocol: ");
|
||||||
|
builder.append(sslHandler.applicationProtocol());
|
||||||
|
builder.append("\n Need Client Auth: " );
|
||||||
|
builder.append(engine.getNeedClientAuth());
|
||||||
|
builder.append("\n Want Client Auth: ");
|
||||||
|
builder.append(engine.getWantClientAuth());
|
||||||
|
builder.append("\n Supported protocols=");
|
||||||
|
builder.append(Arrays.toString(engine.getSupportedProtocols()));
|
||||||
|
builder.append("\n Enabled protocols=");
|
||||||
|
builder.append(Arrays.toString(engine.getEnabledProtocols()));
|
||||||
|
builder.append("\n Supported ciphers=");
|
||||||
|
builder.append(Arrays.toString(engine.getSupportedCipherSuites()));
|
||||||
|
builder.append("\n Enabled ciphers=");
|
||||||
|
builder.append(Arrays.toString(engine.getEnabledCipherSuites()));
|
||||||
|
builder.append("\n]");
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buffers all writes until either {@link #writeBufferedAndRemove(ChannelHandlerContext)} or
|
* Buffers all writes until either {@link #writeBufferedAndRemove(ChannelHandlerContext)} or
|
||||||
* {@link #fail(ChannelHandlerContext, Throwable)} is called. This handler allows us to
|
* {@link #fail(ChannelHandlerContext, Throwable)} is called. This handler allows us to
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue