You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by lh...@apache.org on 2025/11/17 21:52:26 UTC
(pulsar) 01/03: [fix] Handle TLS close_notify to avoid SslClosedEngineException: SSLEngine closed already (#24986)
This is an automated email from the ASF dual-hosted git repository.
lhotari pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit e0d89a3f842933dfc9c3622c0e491445a024a2eb
Author: Lari Hotari <lh...@users.noreply.github.com>
AuthorDate: Sat Nov 15 10:11:13 2025 +0200
[fix] Handle TLS close_notify to avoid SslClosedEngineException: SSLEngine closed already (#24986)
(cherry picked from commit ee3e5eaa9f9364287061a70dbb41f9bc9c2adb0c)
---
.../org/apache/pulsar/client/impl/ClientCnx.java | 13 ------------
.../pulsar/common/protocol/PulsarDecoder.java | 24 ++++++++++++++++++++++
2 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java
index 9cccbecf3aa..07df92f501e 100644
--- a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java
+++ b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java
@@ -29,7 +29,6 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.unix.Errors.NativeIoException;
-import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.util.concurrent.Promise;
import io.opentelemetry.api.common.Attributes;
import java.net.InetSocketAddress;
@@ -1442,18 +1441,6 @@ public class ClientCnx extends PulsarHandler {
}
}
- @Override
- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
- if (evt instanceof SslHandshakeCompletionEvent) {
- SslHandshakeCompletionEvent sslHandshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
- if (sslHandshakeCompletionEvent.cause() != null) {
- log.warn("{} Got ssl handshake exception {}", ctx.channel(),
- sslHandshakeCompletionEvent);
- }
- }
- ctx.fireUserEventTriggered(evt);
- }
-
protected void closeWithException(Throwable e) {
if (ctx != null) {
connectionFuture.completeExceptionally(e);
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java b/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java
index 33307a8cacc..9017805c75b 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java
@@ -24,6 +24,8 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOutboundInvoker;
import io.netty.handler.codec.haproxy.HAProxyMessage;
+import io.netty.handler.ssl.SslCloseCompletionEvent;
+import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import org.apache.pulsar.common.api.proto.BaseCommand;
import org.apache.pulsar.common.api.proto.CommandAck;
import org.apache.pulsar.common.api.proto.CommandAckResponse;
@@ -749,4 +751,26 @@ public abstract class PulsarDecoder extends ChannelInboundHandlerAdapter {
private void writeAndFlush(ChannelOutboundInvoker ctx, ByteBuf cmd) {
NettyChannelUtil.writeAndFlushWithVoidPromise(ctx, cmd);
}
+
+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
+ if (evt instanceof SslHandshakeCompletionEvent) {
+ // log handshake failures
+ SslHandshakeCompletionEvent sslHandshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
+ if (!sslHandshakeCompletionEvent.isSuccess()) {
+ log.warn("[{}] TLS handshake failed. {}", ctx.channel(), sslHandshakeCompletionEvent);
+ }
+ } else if (evt instanceof SslCloseCompletionEvent) {
+ // handle TLS close_notify event and immediately close the channel
+ // this is not handled by Netty by default
+ // See https://datatracker.ietf.org/doc/html/rfc8446#section-6.1 for more details
+ SslCloseCompletionEvent sslCloseCompletionEvent = (SslCloseCompletionEvent) evt;
+ if (sslCloseCompletionEvent.isSuccess() && ctx.channel().isActive()) {
+ if (log.isDebugEnabled()) {
+ log.debug("[{}] Received a TLS close_notify, closing the channel.", ctx.channel());
+ }
+ ctx.close();
+ }
+ }
+ ctx.fireUserEventTriggered(evt);
+ }
}