Skip to content

Commit ee3e5ea

Browse files
authored
[fix] Handle TLS close_notify to avoid SslClosedEngineException: SSLEngine closed already (#24986)
1 parent 8b28f42 commit ee3e5ea

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

pulsar-client/src/main/java/org/apache/pulsar/client/impl/ClientCnx.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import io.netty.channel.ChannelHandlerContext;
3030
import io.netty.channel.EventLoopGroup;
3131
import io.netty.channel.unix.Errors.NativeIoException;
32-
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
3332
import io.netty.util.concurrent.Promise;
3433
import io.opentelemetry.api.common.Attributes;
3534
import java.net.InetSocketAddress;
@@ -1442,18 +1441,6 @@ public void close() {
14421441
}
14431442
}
14441443

1445-
@Override
1446-
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
1447-
if (evt instanceof SslHandshakeCompletionEvent) {
1448-
SslHandshakeCompletionEvent sslHandshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
1449-
if (sslHandshakeCompletionEvent.cause() != null) {
1450-
log.warn("{} Got ssl handshake exception {}", ctx.channel(),
1451-
sslHandshakeCompletionEvent);
1452-
}
1453-
}
1454-
ctx.fireUserEventTriggered(evt);
1455-
}
1456-
14571444
protected void closeWithException(Throwable e) {
14581445
if (ctx != null) {
14591446
connectionFuture.completeExceptionally(e);

pulsar-common/src/main/java/org/apache/pulsar/common/protocol/PulsarDecoder.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import io.netty.channel.ChannelInboundHandlerAdapter;
2525
import io.netty.channel.ChannelOutboundInvoker;
2626
import io.netty.handler.codec.haproxy.HAProxyMessage;
27+
import io.netty.handler.ssl.SslCloseCompletionEvent;
28+
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
2729
import org.apache.pulsar.common.api.proto.BaseCommand;
2830
import org.apache.pulsar.common.api.proto.CommandAck;
2931
import org.apache.pulsar.common.api.proto.CommandAckResponse;
@@ -749,4 +751,26 @@ protected void handleCommandWatchTopicListClose(CommandWatchTopicListClose comma
749751
private void writeAndFlush(ChannelOutboundInvoker ctx, ByteBuf cmd) {
750752
NettyChannelUtil.writeAndFlushWithVoidPromise(ctx, cmd);
751753
}
754+
755+
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
756+
if (evt instanceof SslHandshakeCompletionEvent) {
757+
// log handshake failures
758+
SslHandshakeCompletionEvent sslHandshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
759+
if (!sslHandshakeCompletionEvent.isSuccess()) {
760+
log.warn("[{}] TLS handshake failed. {}", ctx.channel(), sslHandshakeCompletionEvent);
761+
}
762+
} else if (evt instanceof SslCloseCompletionEvent) {
763+
// handle TLS close_notify event and immediately close the channel
764+
// this is not handled by Netty by default
765+
// See https://datatracker.ietf.org/doc/html/rfc8446#section-6.1 for more details
766+
SslCloseCompletionEvent sslCloseCompletionEvent = (SslCloseCompletionEvent) evt;
767+
if (sslCloseCompletionEvent.isSuccess() && ctx.channel().isActive()) {
768+
if (log.isDebugEnabled()) {
769+
log.debug("[{}] Received a TLS close_notify, closing the channel.", ctx.channel());
770+
}
771+
ctx.close();
772+
}
773+
}
774+
ctx.fireUserEventTriggered(evt);
775+
}
752776
}

0 commit comments

Comments
 (0)