diff --git a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java index 4222dacaad2..21132f82ff3 100644 --- a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java +++ b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java @@ -45,6 +45,7 @@ import io.grpc.netty.shaded.io.netty.handler.ssl.util.SelfSignedCertificate; import io.grpc.netty.shaded.io.netty.util.AsciiString; import io.grpc.netty.shaded.io.netty.util.CharsetUtil; +import io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil; import java.io.IOException; import java.io.InputStream; @@ -77,7 +78,7 @@ public class ProxyAndTlsProtocolNegotiator implements InternalProtocolNegotiator */ private static final int SSL_RECORD_HEADER_LENGTH = 5; - private static SslContext sslContext; + private static volatile SslContext sslContext; public ProxyAndTlsProtocolNegotiator() { try { @@ -113,9 +114,10 @@ public static void loadSslContext() throws CertificateException, IOException { provider = SslProvider.JDK; log.info("Using JDK SSL provider"); } + SslContext newSslContext; if (proxyConfig.isTlsTestModeEnable()) { SelfSignedCertificate selfSignedCertificate = new SelfSignedCertificate(); - sslContext = GrpcSslContexts.forServer(selfSignedCertificate.certificate(), selfSignedCertificate.privateKey()) + newSslContext = GrpcSslContexts.forServer(selfSignedCertificate.certificate(), selfSignedCertificate.privateKey()) .sslProvider(provider) .trustManager(InsecureTrustManagerFactory.INSTANCE) .clientAuth(ClientAuth.NONE) @@ -128,7 +130,7 @@ public static void loadSslContext() throws CertificateException, IOException { Paths.get(tlsKeyPath)); InputStream serverCertificateStream = Files.newInputStream( Paths.get(tlsCertPath))) { - sslContext = GrpcSslContexts.forServer(serverCertificateStream, + newSslContext = GrpcSslContexts.forServer(serverCertificateStream, serverKeyInputStream, StringUtils.isNotBlank(tlsKeyPassword) ? tlsKeyPassword : null) .trustManager(InsecureTrustManagerFactory.INSTANCE) @@ -136,6 +138,16 @@ public static void loadSslContext() throws CertificateException, IOException { .build(); } } + SslContext oldSslContext = sslContext; + sslContext = newSslContext; + if (oldSslContext != null) { + try { + ReferenceCountUtil.release(oldSslContext); + log.info("Old SslContext released for proxy server"); + } catch (Exception e) { + log.warn("Failed to release old SslContext for proxy server", e); + } + } } private class ProxyAndTlsProtocolHandler extends ByteToMessageDecoder { diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java index 578c102daa4..c059f5347f2 100644 --- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java +++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java @@ -45,6 +45,7 @@ import io.netty.handler.codec.haproxy.HAProxyMessageDecoder; import io.netty.handler.codec.haproxy.HAProxyProtocolVersion; import io.netty.handler.codec.haproxy.HAProxyTLV; +import io.netty.handler.ssl.SslContext; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleStateHandler; @@ -53,6 +54,7 @@ import io.netty.util.HashedWheelTimer; import io.netty.util.Timeout; import io.netty.util.TimerTask; +import io.netty.util.ReferenceCountUtil; import io.netty.util.concurrent.DefaultEventExecutorGroup; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -183,7 +185,17 @@ public void loadSslContext() { if (tlsMode != TlsMode.DISABLED) { try { - sslContext = TlsHelper.buildSslContext(false); + SslContext newSslContext = TlsHelper.buildSslContext(false); + SslContext oldSslContext = this.sslContext; + this.sslContext = newSslContext; + if (oldSslContext != null) { + try { + ReferenceCountUtil.release(oldSslContext); + log.info("Old SslContext released for server"); + } catch (Exception e) { + log.warn("Failed to release old SslContext for server", e); + } + } log.info("SslContext created for server"); } catch (CertificateException | IOException e) { log.error("Failed to create SslContext for server", e);