From a670604f67d6fd9526fc371120312a0a296d6f7a Mon Sep 17 00:00:00 2001 From: Marcin Date: Wed, 7 Oct 2026 08:49:12 +0200 Subject: [PATCH 1/5] SSL race condition when sending multiple larger data chunks --- .../apache/mina/filter/ssl/SSLHandlerG1.java | 14 +- .../mina/filter/ssl/SslEnd2EndTest.java | 341 ++++++++++++++++++ 2 files changed, 348 insertions(+), 7 deletions(-) create mode 100644 mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG1.java b/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG1.java index 78a8cdbbb..b2eae3fc2 100644 --- a/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG1.java +++ b/mina-core/src/main/java/org/apache/mina/filter/ssl/SSLHandlerG1.java @@ -760,7 +760,7 @@ synchronized protected void store_pending_error(SSLException sslException) { } protected void forward_received(NextFilter next) { - //synchronized (mReceiveQueue) { + synchronized (mReceiveQueue) { IoBuffer x; while ((x = mReceiveQueue.poll()) != null) { if (LOGGER.isDebugEnabled()) { @@ -768,11 +768,11 @@ protected void forward_received(NextFilter next) { } next.messageReceived(mSession, x); } - //} + } } protected void forward_writes(NextFilter next) { - //synchronized (mWriteQueue) { + synchronized (mWriteQueue) { EncryptedWriteRequest x; while ((x = mWriteQueue.poll()) != null) { if (LOGGER.isDebugEnabled()) { @@ -781,19 +781,19 @@ protected void forward_writes(NextFilter next) { mAckQueue.add(x); next.filterWrite(mSession, x); } - //} + } } protected void forward_events(NextFilter next) { - //synchronized (mEventQueue) { + synchronized(mEventQueue) { FilterEvent x; - while((x = mEventQueue.poll()) != null) { + while ((x = mEventQueue.poll()) != null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} forward_events() - dispatching event {}", toString(), x); } next.event(mSession, x); } - //} + } } /** diff --git a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java new file mode 100644 index 000000000..3b0d42c92 --- /dev/null +++ b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java @@ -0,0 +1,341 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.mina.filter.ssl; + +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; +import org.apache.mina.core.future.ConnectFuture; +import org.apache.mina.core.future.WriteFuture; +import org.apache.mina.core.service.IoAcceptor; +import org.apache.mina.core.service.IoConnector; +import org.apache.mina.core.service.IoHandler; +import org.apache.mina.core.service.IoHandlerAdapter; +import org.apache.mina.core.session.IoSession; +import org.apache.mina.transport.socket.nio.NioSocketAcceptor; +import org.apache.mina.transport.socket.nio.NioSocketConnector; +import org.apache.mina.util.AcceptorBindUtil; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.Security; +import java.util.Arrays; +import java.util.Collection; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; + +@RunWith(Parameterized.class) +public class SslEnd2EndTest { + + private static final String KEY_MANAGER_FACTORY_ALGORITHM; + private static final int MAX_LENGTH = 1024 * 1024 * 8; + + static { + String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); + if (algorithm == null) { + algorithm = KeyManagerFactory.getDefaultAlgorithm(); + } + + KEY_MANAGER_FACTORY_ALGORITHM = algorithm; + } + + @Parameterized.Parameters(name = "{index}: {0} / {1} / {2} / {3}") + public static Collection data() { + return Arrays.asList(new Object[][]{ + {"TLSv1.2", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 2048, 0}, + {"TLSv1.2", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 2048, 4}, + {"TLSv1.3", "TLS_AES_256_GCM_SHA384", 2048, 0}, + {"TLSv1.3", "TLS_AES_256_GCM_SHA384", 2048, 4}, + }); + } + + private final String protocol; + private final String[] cipherSuites; + private final int messageCount; + private final int messageLengthDelta; + + public SslEnd2EndTest(String protocol, String cipherSuites, int messageCount, int messageLengthDelta) { + this.protocol = protocol; + this.cipherSuites = cipherSuites.split(","); + this.messageCount = messageCount; + this.messageLengthDelta = messageLengthDelta; + } + + @Test + public void shouldSendLargeMessages() throws Exception { + ByteBuffer acceptorReceiveBuffer = ByteBuffer.allocate(MAX_LENGTH); + AcceptorHandler acceptorHandler = new AcceptorHandler(acceptorReceiveBuffer); + IoAcceptor acceptor = createAcceptor(acceptorHandler); + + try { + AcceptorBindUtil.tryBind(acceptor); + + ByteBuffer connectorReceiveBuffer = ByteBuffer.allocate(MAX_LENGTH); + ConnectorIoHandler connectorHandler = new ConnectorIoHandler(connectorReceiveBuffer); + IoConnector connector = createConnector(connectorHandler); + + try { + ConnectFuture connectFuture = connector.connect(acceptor.getLocalAddress()); + boolean connected = connectFuture.awaitUninterruptibly(4L, TimeUnit.SECONDS); + + if (!connected) { + throw new RuntimeException("Failed to connect"); + } + + IoBuffer connectorSendBuffer = IoBuffer.wrap(ByteBuffer.allocate(MAX_LENGTH)); + + for (int i = 0; i < connectorSendBuffer.limit(); i += 4) { + connectorSendBuffer.putInt(i); + } + + connectorSendBuffer.flip(); + + IoSession session = connectFuture.getSession(); + int messageLength = 65_536; + + for (int i = 0; i < messageCount; i++) { + if (messageLength > MAX_LENGTH) { + throw new RuntimeException("Message length exceeds send buffer capacity. Increase send buffer capacity"); + } + + connectorSendBuffer.limit(messageLength); + connectorSendBuffer.rewind(); + + CountDownLatch acceptorMessageReceivedLatch = new CountDownLatch(1); + acceptorHandler.reset(acceptorMessageReceivedLatch, messageLength); + + CountDownLatch connectorMessageReceivedLatch = new CountDownLatch(1); + connectorHandler.reset(connectorMessageReceivedLatch, messageLength); + + WriteFuture writeFuture = session.write(connectorSendBuffer); + boolean written = writeFuture.awaitUninterruptibly(4L, TimeUnit.SECONDS); + + if (!written) { + throw new RuntimeException("Failed to write data"); + } + + boolean messageReceived = acceptorMessageReceivedLatch.await(4L, TimeUnit.SECONDS); + + if (!messageReceived) { + throw new RuntimeException("Failed to receive from connector"); + } + + acceptorReceiveBuffer.flip(); + + for (int j = 0; j < acceptorReceiveBuffer.limit(); j += 4) { + assertEquals(j, acceptorReceiveBuffer.getInt()); + } + + boolean connectorMessageReceived = connectorMessageReceivedLatch.await(4L, TimeUnit.SECONDS); + + if (!connectorMessageReceived) { + throw new RuntimeException("Failed to receive from acceptor"); + } + + connectorReceiveBuffer.flip(); + + for (int j = 0; j < connectorReceiveBuffer.limit(); j += 4) { + assertEquals(j, connectorReceiveBuffer.getInt()); + } + + messageLength += messageLengthDelta; + } + } finally { + connector.dispose(); + } + } finally { + acceptor.unbind(); + acceptor.dispose(); + } + } + + private IoAcceptor createAcceptor(IoHandler handler) throws Exception { + NioSocketAcceptor acceptor = new NioSocketAcceptor(); + acceptor.setReuseAddress(true); + acceptor.setHandler(handler); + + DefaultIoFilterChainBuilder filters = acceptor.getFilterChain(); + + SSLContext sslContext = createAcceptorSSLContext(); + + SslFilter sslFilter = new SslFilter(sslContext); + sslFilter.setEnabledCipherSuites(cipherSuites); + sslFilter.setEnabledProtocols(protocol); + + filters.addLast("sslFilter", sslFilter); + + return acceptor; + } + + private IoConnector createConnector(IoHandler ioHandler) throws GeneralSecurityException, IOException { + NioSocketConnector connector = new NioSocketConnector(); + connector.setHandler(ioHandler); + + DefaultIoFilterChainBuilder filters = connector.getFilterChain(); + + SSLContext sslContext = createConnectorSslContext(); + + SslFilter sslFilter = new SslFilter(sslContext); + sslFilter.setEnabledCipherSuites(cipherSuites); + sslFilter.setEnabledProtocols(protocol); + + filters.addLast("sslFilter", sslFilter); + + return connector; + } + + private SSLContext createAcceptorSSLContext() throws IOException, GeneralSecurityException { + char[] passphrase = "password".toCharArray(); + + SSLContext ctx = SSLContext.getInstance(protocol); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM); + + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(SslEnd2EndTest.class.getResourceAsStream("keystore.jks"), passphrase); + + KeyStore ts = KeyStore.getInstance("JKS"); + ts.load(SslEnd2EndTest.class.getResourceAsStream("emptykeystore.sslTest"), passphrase); + + kmf.init(ks, passphrase); + tmf.init(ts); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + return ctx; + } + + private SSLContext createConnectorSslContext() throws IOException, GeneralSecurityException { + char[] passphrase = "password".toCharArray(); + + SSLContext ctx = SSLContext.getInstance(protocol); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM); + + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(SslEnd2EndTest.class.getResourceAsStream("emptykeystore.sslTest"), passphrase); + + KeyStore ts = KeyStore.getInstance("JKS"); + ts.load(SslEnd2EndTest.class.getResourceAsStream("truststore.jks"), passphrase); + + kmf.init(ks, passphrase); + tmf.init(ts); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + return ctx; + } + + private static final class AcceptorHandler extends IoHandlerAdapter { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcceptorHandler.class); + private final ByteBuffer receiveBuffer; + private CountDownLatch messageReceivedLatch; + private int expectedLength; + + private AcceptorHandler(ByteBuffer receiveBuffer) { + this.receiveBuffer = receiveBuffer; + } + + public void reset(CountDownLatch messageReceivedLatch, int expectedLength) { + this.messageReceivedLatch = messageReceivedLatch; + this.receiveBuffer.clear(); + + // zero data + for (int i = 0; i < receiveBuffer.capacity(); i++) { + receiveBuffer.put(i, (byte) 0); + } + + this.expectedLength = expectedLength; + } + + @Override + public void exceptionCaught(IoSession session, Throwable cause) { + LOGGER.error("Exception caught", cause); + } + + @Override + public void messageReceived(IoSession session, Object message) { + IoBuffer messageBuffer = (IoBuffer) message; + receiveBuffer.put(messageBuffer.buf()); + + if (receiveBuffer.position() == expectedLength) { + receiveBuffer.flip(); + + // respond with the same message + IoBuffer buffer = IoBuffer.wrap(receiveBuffer); + session.write(buffer); + + messageReceivedLatch.countDown(); + } + } + } + + private static final class ConnectorIoHandler extends IoHandlerAdapter { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConnectorIoHandler.class); + + private final ByteBuffer receiveBuffer; + private CountDownLatch messageReceivedLatch; + private int expectedLength; + + private ConnectorIoHandler(ByteBuffer receiveBuffer) { + this.receiveBuffer = receiveBuffer; + } + + public void reset(CountDownLatch messageReceivedLatch, int expectedLength) { + this.messageReceivedLatch = messageReceivedLatch; + this.receiveBuffer.clear(); + + // zero data + for (int i = 0; i < receiveBuffer.capacity(); i++) { + receiveBuffer.put(i, (byte) 0); + } + + this.expectedLength = expectedLength; + } + + @Override + public void exceptionCaught(IoSession session, Throwable cause) { + LOGGER.error("Exception caught", cause); + } + + @Override + public void messageReceived(IoSession session, Object message) { + IoBuffer messageBuffer = (IoBuffer) message; + receiveBuffer.put(messageBuffer.buf()); + + if (receiveBuffer.position() == expectedLength) { + messageReceivedLatch.countDown(); + } + } + } +} From 47726886747735ba30d81ce5313927f5b754e707 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 9 Oct 2026 08:00:06 +0200 Subject: [PATCH 2/5] Post review fixes --- .../mina/filter/ssl/SslEnd2EndTest.java | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java index 3b0d42c92..0c6a3b91a 100644 --- a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java +++ b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java @@ -49,8 +49,11 @@ import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; @RunWith(Parameterized.class) public class SslEnd2EndTest { @@ -90,7 +93,7 @@ public SslEnd2EndTest(String protocol, String cipherSuites, int messageCount, in } @Test - public void shouldSendLargeMessages() throws Exception { + public void shouldSendLargeMessages() throws Throwable { ByteBuffer acceptorReceiveBuffer = ByteBuffer.allocate(MAX_LENGTH); AcceptorHandler acceptorHandler = new AcceptorHandler(acceptorReceiveBuffer); IoAcceptor acceptor = createAcceptor(acceptorHandler); @@ -104,11 +107,7 @@ public void shouldSendLargeMessages() throws Exception { try { ConnectFuture connectFuture = connector.connect(acceptor.getLocalAddress()); - boolean connected = connectFuture.awaitUninterruptibly(4L, TimeUnit.SECONDS); - - if (!connected) { - throw new RuntimeException("Failed to connect"); - } + assertTrue("Failed to connect", connectFuture.awaitUninterruptibly(4L, TimeUnit.SECONDS)); IoBuffer connectorSendBuffer = IoBuffer.wrap(ByteBuffer.allocate(MAX_LENGTH)); @@ -136,16 +135,13 @@ public void shouldSendLargeMessages() throws Exception { connectorHandler.reset(connectorMessageReceivedLatch, messageLength); WriteFuture writeFuture = session.write(connectorSendBuffer); - boolean written = writeFuture.awaitUninterruptibly(4L, TimeUnit.SECONDS); - - if (!written) { - throw new RuntimeException("Failed to write data"); - } + assertTrue("Connector write failed", writeFuture.awaitUninterruptibly(4L, TimeUnit.SECONDS)); boolean messageReceived = acceptorMessageReceivedLatch.await(4L, TimeUnit.SECONDS); if (!messageReceived) { - throw new RuntimeException("Failed to receive from connector"); + assertNoException(acceptorHandler.getFailure()); + fail("Failed to receive from connector"); } acceptorReceiveBuffer.flip(); @@ -157,7 +153,8 @@ public void shouldSendLargeMessages() throws Exception { boolean connectorMessageReceived = connectorMessageReceivedLatch.await(4L, TimeUnit.SECONDS); if (!connectorMessageReceived) { - throw new RuntimeException("Failed to receive from acceptor"); + assertNoException(connectorHandler.getFailure()); + fail("Failed to receive from acceptor"); } connectorReceiveBuffer.flip(); @@ -177,6 +174,12 @@ public void shouldSendLargeMessages() throws Exception { } } + private void assertNoException(Throwable exception) throws Throwable { + if (exception != null) { + throw exception; + } + } + private IoAcceptor createAcceptor(IoHandler handler) throws Exception { NioSocketAcceptor acceptor = new NioSocketAcceptor(); acceptor.setReuseAddress(true); @@ -258,11 +261,13 @@ private static final class AcceptorHandler extends IoHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(AcceptorHandler.class); private final ByteBuffer receiveBuffer; + private final AtomicReference exception; private CountDownLatch messageReceivedLatch; private int expectedLength; private AcceptorHandler(ByteBuffer receiveBuffer) { this.receiveBuffer = receiveBuffer; + this.exception = new AtomicReference<>(); } public void reset(CountDownLatch messageReceivedLatch, int expectedLength) { @@ -277,9 +282,17 @@ public void reset(CountDownLatch messageReceivedLatch, int expectedLength) { this.expectedLength = expectedLength; } + public Throwable getFailure() { + return exception.get(); + } + @Override public void exceptionCaught(IoSession session, Throwable cause) { - LOGGER.error("Exception caught", cause); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Exception caught: {}", session, cause); + } + + exception.set(cause); } @Override @@ -304,11 +317,17 @@ private static final class ConnectorIoHandler extends IoHandlerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(ConnectorIoHandler.class); private final ByteBuffer receiveBuffer; + private final AtomicReference exception; private CountDownLatch messageReceivedLatch; private int expectedLength; private ConnectorIoHandler(ByteBuffer receiveBuffer) { this.receiveBuffer = receiveBuffer; + this.exception = new AtomicReference<>(); + } + + public Throwable getFailure() { + return exception.get(); } public void reset(CountDownLatch messageReceivedLatch, int expectedLength) { @@ -325,7 +344,11 @@ public void reset(CountDownLatch messageReceivedLatch, int expectedLength) { @Override public void exceptionCaught(IoSession session, Throwable cause) { - LOGGER.error("Exception caught", cause); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Exception caught: {}", session, cause); + } + + exception.set(cause); } @Override From ef36f0b7f90e5c0859c267468ff6ee0d5959b397 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 9 Oct 2026 09:45:46 +0200 Subject: [PATCH 3/5] Post review fixes #2 --- .../org/apache/mina/filter/ssl/SslEnd2EndTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java index 0c6a3b91a..895a1dcfb 100644 --- a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java +++ b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java @@ -93,7 +93,7 @@ public SslEnd2EndTest(String protocol, String cipherSuites, int messageCount, in } @Test - public void shouldSendLargeMessages() throws Throwable { + public void shouldSendLargeMessages() throws Exception { ByteBuffer acceptorReceiveBuffer = ByteBuffer.allocate(MAX_LENGTH); AcceptorHandler acceptorHandler = new AcceptorHandler(acceptorReceiveBuffer); IoAcceptor acceptor = createAcceptor(acceptorHandler); @@ -174,9 +174,9 @@ public void shouldSendLargeMessages() throws Throwable { } } - private void assertNoException(Throwable exception) throws Throwable { + private void assertNoException(Throwable exception) { if (exception != null) { - throw exception; + throw new AssertionError(exception); } } @@ -292,7 +292,7 @@ public void exceptionCaught(IoSession session, Throwable cause) { LOGGER.debug("Exception caught: {}", session, cause); } - exception.set(cause); + exception.compareAndSet(null, cause); } @Override @@ -347,8 +347,8 @@ public void exceptionCaught(IoSession session, Throwable cause) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Exception caught: {}", session, cause); } - - exception.set(cause); + + exception.compareAndSet(null, cause); } @Override From 5ca2e25c04a44b2352e77175c847ef8021af2c43 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 9 Oct 2026 12:16:22 +0200 Subject: [PATCH 4/5] Changing test parameters, increasing number of messages, adding more cipher suites --- .../java/org/apache/mina/filter/ssl/SslEnd2EndTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java index 895a1dcfb..914aba206 100644 --- a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java +++ b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java @@ -73,10 +73,8 @@ public class SslEnd2EndTest { @Parameterized.Parameters(name = "{index}: {0} / {1} / {2} / {3}") public static Collection data() { return Arrays.asList(new Object[][]{ - {"TLSv1.2", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 2048, 0}, - {"TLSv1.2", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 2048, 4}, - {"TLSv1.3", "TLS_AES_256_GCM_SHA384", 2048, 0}, - {"TLSv1.3", "TLS_AES_256_GCM_SHA384", 2048, 4}, + {"TLSv1.2", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 4096, 4}, + {"TLSv1.3", "TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384", 4096, 4}, }); } From 12a6d034e433d4e1015c881152c59d6c14e4f329 Mon Sep 17 00:00:00 2001 From: Marcin Date: Fri, 9 Oct 2026 17:52:21 +0200 Subject: [PATCH 5/5] Add explicit useNonBlockingPipeline setting to SslFilter --- .../test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java index 914aba206..8f4d95927 100644 --- a/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java +++ b/mina-core/src/test/java/org/apache/mina/filter/ssl/SslEnd2EndTest.java @@ -188,6 +188,7 @@ private IoAcceptor createAcceptor(IoHandler handler) throws Exception { SSLContext sslContext = createAcceptorSSLContext(); SslFilter sslFilter = new SslFilter(sslContext); + sslFilter.setUseNonBlockingPipeline(true); sslFilter.setEnabledCipherSuites(cipherSuites); sslFilter.setEnabledProtocols(protocol); @@ -205,6 +206,7 @@ private IoConnector createConnector(IoHandler ioHandler) throws GeneralSecurityE SSLContext sslContext = createConnectorSslContext(); SslFilter sslFilter = new SslFilter(sslContext); + sslFilter.setUseNonBlockingPipeline(true); sslFilter.setEnabledCipherSuites(cipherSuites); sslFilter.setEnabledProtocols(protocol);