From e441e2803a9a2051589f172c3acfbae6abbdf199 Mon Sep 17 00:00:00 2001 From: Teo Jia Jiun Date: Sat, 7 Oct 2017 15:04:44 +0800 Subject: [PATCH 1/5] jdk9 ALPN: use java ALPN if available --- .../java/io/grpc/netty/GrpcSslContexts.java | 3 ++ .../main/java/io/grpc/netty/JettyTlsUtil.java | 42 +++++++++++++++++++ .../io/grpc/netty/ProtocolNegotiators.java | 7 ++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java b/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java index 96a1bf6f451..200b287e360 100644 --- a/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java +++ b/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java @@ -156,6 +156,9 @@ private static ApplicationProtocolConfig selectApplicationProtocolConfig(SslProv if (JettyTlsUtil.isJettyNpnConfigured()) { return NPN; } + if (JettyTlsUtil.isNettyJava9AlpnAvailable()) { + return ALPN; + } // Use the ALPN cause since it is prefered. throw new IllegalArgumentException( "Jetty ALPN/NPN has not been properly configured.", diff --git a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java index 53bdc6e9f38..92188fe25b1 100644 --- a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java +++ b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java @@ -16,10 +16,39 @@ package io.grpc.netty; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; + /** * Utility class for determining support for Jetty TLS ALPN/NPN. */ final class JettyTlsUtil { + private static final boolean HAS_JAVA9_ALPN; + + static { + Method getApplicationProtocol; + try { + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, null, null); + SSLEngine engine = context.createSSLEngine(); + getApplicationProtocol = + AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public Method run() throws Exception { + return SSLEngine.class.getMethod("getApplicationProtocol"); + } + }); + getApplicationProtocol.invoke(engine); + } catch (Throwable t) { + getApplicationProtocol = null; + } + HAS_JAVA9_ALPN = getApplicationProtocol != null; + } + private JettyTlsUtil() { } @@ -67,4 +96,17 @@ static synchronized Throwable getJettyNpnUnavailabilityCause() { } return jettyNpnUnavailabilityCause; } + + /** + * Indicates whether Netty Java 9 ALPN is available. + */ + static boolean isNettyJava9AlpnAvailable() { + try { + Class.forName("io.netty.handler.ssl.Java9SslEngine"); + return HAS_JAVA9_ALPN; + } catch (ClassNotFoundException e) { + return false; + } + } + } diff --git a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java index c7dc2f3e66c..faec0b6cdc4 100644 --- a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java +++ b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java @@ -61,7 +61,6 @@ import java.util.logging.Logger; import javax.annotation.Nullable; import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLParameters; /** * Common {@link ProtocolNegotiator}s used by gRPC. @@ -304,9 +303,7 @@ public Handler newHandler(GrpcHttp2ConnectionHandler handler) { @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { SSLEngine sslEngine = sslContext.newEngine(ctx.alloc(), host, port); - SSLParameters sslParams = new SSLParameters(); - sslParams.setEndpointIdentificationAlgorithm("HTTPS"); - sslEngine.setSSLParameters(sslParams); + sslEngine.getSSLParameters().setEndpointIdentificationAlgorithm("HTTPS"); ctx.pipeline().replace(this, null, new SslHandler(sslEngine, false)); } }; @@ -374,6 +371,8 @@ static void logSslEngineDetails(Level level, ChannelHandlerContext ctx, String m builder.append(" Jetty ALPN"); } else if (JettyTlsUtil.isJettyNpnConfigured()) { builder.append(" Jetty NPN"); + } else if (JettyTlsUtil.isNettyJava9AlpnAvailable()) { + builder.append(" JDK9 ALPN"); } builder.append("\n TLS Protocol: "); builder.append(engine.getSession().getProtocol()); From 68d8a450f87dfe2638f89209ffe762c7313de12f Mon Sep 17 00:00:00 2001 From: Teo Jia Jiun Date: Sat, 7 Oct 2017 15:17:34 +0800 Subject: [PATCH 2/5] jdk9 ALPN: fix SSL parameters not set properly --- netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java index faec0b6cdc4..1f15716cadb 100644 --- a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java +++ b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java @@ -61,6 +61,7 @@ import java.util.logging.Logger; import javax.annotation.Nullable; import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; /** * Common {@link ProtocolNegotiator}s used by gRPC. @@ -303,7 +304,9 @@ public Handler newHandler(GrpcHttp2ConnectionHandler handler) { @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { SSLEngine sslEngine = sslContext.newEngine(ctx.alloc(), host, port); - sslEngine.getSSLParameters().setEndpointIdentificationAlgorithm("HTTPS"); + SSLParameters sslParams = sslEngine.getSSLParameters(); + sslParams.setEndpointIdentificationAlgorithm("HTTPS"); + sslEngine.setSSLParameters(sslParams); ctx.pipeline().replace(this, null, new SslHandler(sslEngine, false)); } }; From 9840ad27a55d32aa60c18c760c55ea186f38a14b Mon Sep 17 00:00:00 2001 From: Teo Jia Jiun Date: Tue, 10 Oct 2017 13:02:47 +0800 Subject: [PATCH 3/5] jdk9 ALPN: keep JDK ALPN detection failure * assume bundled Netty version supports JDK ALPN --- .../java/io/grpc/netty/GrpcSslContexts.java | 2 +- .../main/java/io/grpc/netty/JettyTlsUtil.java | 54 ++++++++++--------- .../io/grpc/netty/ProtocolNegotiators.java | 2 +- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java b/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java index 200b287e360..94f8d274a4d 100644 --- a/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java +++ b/netty/src/main/java/io/grpc/netty/GrpcSslContexts.java @@ -156,7 +156,7 @@ private static ApplicationProtocolConfig selectApplicationProtocolConfig(SslProv if (JettyTlsUtil.isJettyNpnConfigured()) { return NPN; } - if (JettyTlsUtil.isNettyJava9AlpnAvailable()) { + if (JettyTlsUtil.isJava9AlpnAvailable()) { return ALPN; } // Use the ALPN cause since it is prefered. diff --git a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java index 92188fe25b1..7ec9dbe3ae1 100644 --- a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java +++ b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java @@ -27,26 +27,29 @@ * Utility class for determining support for Jetty TLS ALPN/NPN. */ final class JettyTlsUtil { - private static final boolean HAS_JAVA9_ALPN; - static { - Method getApplicationProtocol; - try { - SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, null, null); - SSLEngine engine = context.createSSLEngine(); - getApplicationProtocol = - AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Method run() throws Exception { - return SSLEngine.class.getMethod("getApplicationProtocol"); - } - }); - getApplicationProtocol.invoke(engine); - } catch (Throwable t) { - getApplicationProtocol = null; + private static class Java9AlpnUnavailabilityCauseHolder { + + static { + try { + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, null, null); + SSLEngine engine = context.createSSLEngine(); + Method getApplicationProtocol = + AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public Method run() throws Exception { + return SSLEngine.class.getMethod("getApplicationProtocol"); + } + }); + getApplicationProtocol.invoke(engine); + cause = null; + } catch (Throwable t) { + cause = t; + } } - HAS_JAVA9_ALPN = getApplicationProtocol != null; + + private static Throwable cause; } private JettyTlsUtil() { @@ -98,15 +101,14 @@ static synchronized Throwable getJettyNpnUnavailabilityCause() { } /** - * Indicates whether Netty Java 9 ALPN is available. + * Indicates whether Java 9 ALPN is available. */ - static boolean isNettyJava9AlpnAvailable() { - try { - Class.forName("io.netty.handler.ssl.Java9SslEngine"); - return HAS_JAVA9_ALPN; - } catch (ClassNotFoundException e) { - return false; - } + static boolean isJava9AlpnAvailable() { + return getJava9AlpnUnavailabilityCause() == null; + } + + static Throwable getJava9AlpnUnavailabilityCause() { + return Java9AlpnUnavailabilityCauseHolder.cause; } } diff --git a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java index 1f15716cadb..52c9a717424 100644 --- a/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java +++ b/netty/src/main/java/io/grpc/netty/ProtocolNegotiators.java @@ -374,7 +374,7 @@ static void logSslEngineDetails(Level level, ChannelHandlerContext ctx, String m builder.append(" Jetty ALPN"); } else if (JettyTlsUtil.isJettyNpnConfigured()) { builder.append(" Jetty NPN"); - } else if (JettyTlsUtil.isNettyJava9AlpnAvailable()) { + } else if (JettyTlsUtil.isJava9AlpnAvailable()) { builder.append(" JDK9 ALPN"); } builder.append("\n TLS Protocol: "); From 849e367190c2a9d025d9ba812f910dacf7cd623d Mon Sep 17 00:00:00 2001 From: Teo Jia Jiun Date: Tue, 10 Oct 2017 15:53:12 +0800 Subject: [PATCH 4/5] jdk9 ALPN: use standard form on-demand lazy init --- .../main/java/io/grpc/netty/JettyTlsUtil.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java index 7ec9dbe3ae1..04b1aa2f4cc 100644 --- a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java +++ b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java @@ -28,9 +28,17 @@ */ final class JettyTlsUtil { + private JettyTlsUtil() { + } + + private static Throwable jettyAlpnUnavailabilityCause; + private static Throwable jettyNpnUnavailabilityCause; + private static class Java9AlpnUnavailabilityCauseHolder { - static { + static final Throwable cause = checkAlpnAvailability(); + + static Throwable checkAlpnAvailability() { try { SSLContext context = SSLContext.getInstance("TLS"); context.init(null, null, null); @@ -43,21 +51,14 @@ public Method run() throws Exception { } }); getApplicationProtocol.invoke(engine); - cause = null; + return null; } catch (Throwable t) { - cause = t; + return t; } } - private static Throwable cause; } - private JettyTlsUtil() { - } - - private static Throwable jettyAlpnUnavailabilityCause; - private static Throwable jettyNpnUnavailabilityCause; - /** * Indicates whether or not the Jetty ALPN jar is installed in the boot classloader. */ From 18f1ae66fa32138ddbddf46edb74c09811a133d3 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Thu, 21 Dec 2017 13:44:21 -0800 Subject: [PATCH 5/5] Tweak style and remove an unnecessary change. --- netty/src/main/java/io/grpc/netty/JettyTlsUtil.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java index 04b1aa2f4cc..c83c55c38c5 100644 --- a/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java +++ b/netty/src/main/java/io/grpc/netty/JettyTlsUtil.java @@ -19,7 +19,6 @@ import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedExceptionAction; - import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; @@ -27,7 +26,6 @@ * Utility class for determining support for Jetty TLS ALPN/NPN. */ final class JettyTlsUtil { - private JettyTlsUtil() { } @@ -56,7 +54,6 @@ public Method run() throws Exception { return t; } } - } /** @@ -111,5 +108,4 @@ static boolean isJava9AlpnAvailable() { static Throwable getJava9AlpnUnavailabilityCause() { return Java9AlpnUnavailabilityCauseHolder.cause; } - }