This is an automated email from the ASF dual-hosted git repository.

jbertram pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new 2e5e491d85 ARTEMIS-6065 add SSL handshake timeout parameter
2e5e491d85 is described below

commit 2e5e491d8564b13d7fdace9c6f76d42bc4d6ec24
Author: Timofey Tikhomirov <[email protected]>
AuthorDate: Fri May 15 17:39:26 2026 +0300

    ARTEMIS-6065 add SSL handshake timeout parameter
---
 .../FederationDownstreamConfiguration.java         |  1 +
 .../remoting/impl/netty/TransportConstants.java    |  5 +++
 .../core/remoting/impl/netty/NettyAcceptor.java    | 11 +++++-
 docs/user-manual/configuring-transports.adoc       |  6 +++
 .../jms/server/config/JMSConfigurationTest.java    | 43 ++++++++++++++++++++++
 5 files changed, 65 insertions(+), 1 deletion(-)

diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationDownstreamConfiguration.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationDownstreamConfiguration.java
index ea7240ac76..6ca7676141 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationDownstreamConfiguration.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationDownstreamConfiguration.java
@@ -56,6 +56,7 @@ public class FederationDownstreamConfiguration extends 
FederationStreamConfigura
       //The federated server that creates the upstream back will rely on its 
config from the acceptor for TLS
       stripParam(params, TransportConstants.SSL_ENABLED_PROP_NAME);
       stripParam(params, TransportConstants.SSL_PROVIDER);
+      stripParam(params, TransportConstants.SSL_HANDSHAKE_TIMEOUT);
       stripParam(params, TransportConstants.KEYSTORE_PATH_PROP_NAME);
       stripParam(params, TransportConstants.KEYSTORE_PASSWORD_PROP_NAME);
       stripParam(params, TransportConstants.KEYSTORE_PROVIDER_PROP_NAME);
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
index b92947e97d..b1f3fe3420 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java
@@ -36,6 +36,10 @@ public class TransportConstants {
 
    public static final String SSL_ENABLED_PROP_NAME = "sslEnabled";
 
+   public static final String SSL_HANDSHAKE_TIMEOUT = "sslHandshakeTimeout";
+
+   public static final int DEFAULT_SSL_HANDSHAKE_TIMEOUT = 10;
+
    public static final String PROXY_PROTOCOL_ENABLED_PROP_NAME = 
"proxyProtocolEnabled";
 
    public static final String SSL_AUTO_RELOAD_PROP_NAME = "sslAutoReload";
@@ -436,6 +440,7 @@ public class TransportConstants {
       Set<String> allowableAcceptorKeys = new HashSet<>();
       allowableAcceptorKeys.add(TransportConstants.SSL_ENABLED_PROP_NAME);
       allowableAcceptorKeys.add(TransportConstants.SSL_AUTO_RELOAD_PROP_NAME);
+      allowableAcceptorKeys.add(TransportConstants.SSL_HANDSHAKE_TIMEOUT);
       
allowableAcceptorKeys.add(TransportConstants.HTTP_RESPONSE_TIME_PROP_NAME);
       
allowableAcceptorKeys.add(TransportConstants.HTTP_SERVER_SCAN_PERIOD_PROP_NAME);
       
allowableAcceptorKeys.add(TransportConstants.HTTP_UPGRADE_ENABLED_PROP_NAME);
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
index e07b34d789..cb06c6b032 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
@@ -150,6 +150,8 @@ public class NettyAcceptor extends AbstractAcceptor {
 
    private final boolean sslEnabled;
 
+   private final int sslHandshakeTimeout;
+
    private final boolean proxyProtocolEnabled;
 
    private final boolean useInvm;
@@ -301,6 +303,8 @@ public class NettyAcceptor extends AbstractAcceptor {
 
       sslEnabled = 
ConfigurationHelper.getBooleanProperty(TransportConstants.SSL_ENABLED_PROP_NAME,
 TransportConstants.DEFAULT_SSL_ENABLED, configuration);
 
+      sslHandshakeTimeout = 
ConfigurationHelper.getIntProperty(TransportConstants.SSL_HANDSHAKE_TIMEOUT, 
TransportConstants.DEFAULT_SSL_HANDSHAKE_TIMEOUT, configuration);
+
       proxyProtocolEnabled = 
ConfigurationHelper.getBooleanProperty(TransportConstants.PROXY_PROTOCOL_ENABLED_PROP_NAME,
 TransportConstants.DEFAULT_PROXY_PROTOCOL_ENABLED, configuration);
 
       remotingThreads = 
ConfigurationHelper.getIntProperty(TransportConstants.NIO_REMOTING_THREADS_PROPNAME,
 Runtime.getRuntime().availableProcessors() * 3, configuration);
@@ -738,7 +742,9 @@ public class NettyAcceptor extends AbstractAcceptor {
          engine.setSSLParameters(sslParameters);
       }
 
-      return new SslHandler(engine);
+      SslHandler sslHandler = new SslHandler(engine);
+      sslHandler.setHandshakeTimeout(sslHandshakeTimeout, TimeUnit.SECONDS);
+      return sslHandler;
    }
 
    private SSLEngine loadJdkSslEngine(String peerHost, int peerPort) throws 
Exception {
@@ -758,6 +764,9 @@ public class NettyAcceptor extends AbstractAcceptor {
       if (keyStorePath == null && keyStoreProvider == null) {
          throw new IllegalArgumentException("If \"" + 
TransportConstants.SSL_ENABLED_PROP_NAME + "\" is true then \"" + 
TransportConstants.KEYSTORE_PATH_PROP_NAME + "\" must be non-null unless an 
alternative \"" + TransportConstants.KEYSTORE_PROVIDER_PROP_NAME + "\" has been 
specified.");
       }
+      if (sslHandshakeTimeout < 0) {
+         throw new IllegalArgumentException("\"" + 
TransportConstants.SSL_HANDSHAKE_TIMEOUT + "\" value must be >= 0");
+      }
    }
 
    private SSLEngine loadOpenSslEngine(ByteBufAllocator alloc, String 
peerHost, int peerPort) throws Exception {
diff --git a/docs/user-manual/configuring-transports.adoc 
b/docs/user-manual/configuring-transports.adoc
index 9655f4158f..34292b6774 100644
--- a/docs/user-manual/configuring-transports.adoc
+++ b/docs/user-manual/configuring-transports.adoc
@@ -303,6 +303,12 @@ Must be `true` to have the broker 'watch' an acceptors 
keyStorePath and/or trust
 The watch period is controlled by 
xref:config-reload.adoc#configuration-reload[the configuration reload feature].
 Default is `false`.
 
+sslHandshakeTimeout::
+This is only valid for acceptors.
+It is the number of seconds the broker will wait for a client to complete the 
SSL handshake before closing the connection.
+Any non-negative integer value is valid, where `0` disables the timeout.
+Default is `10`.
+
 keyStorePath::
 When used on an `acceptor` this is the path to the SSL key store on the server 
which holds the server's certificates (whether self-signed or signed by an 
authority).
 +
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/config/JMSConfigurationTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/config/JMSConfigurationTest.java
index 04df1a2a1f..c89812ecf7 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/config/JMSConfigurationTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/config/JMSConfigurationTest.java
@@ -152,4 +152,47 @@ public class JMSConfigurationTest extends ActiveMQTestBase 
{
          server.stop();
       }
    }
+
+   @Test
+   public void testSslHandshakeTimeoutWithValueSet() throws Exception {
+      final int SSL_HANDSHAKE_TIMEOUT = 20;
+
+      String url = 
"tcp://127.0.0.1:61616?sslEnabled=true;keyStorePath=server-ca-truststore.p12;keyStorePassword=securepass;sslHandshakeTimeout=20;handshake-timeout=0";
+      ActiveMQServer server = 
addServer(ActiveMQServers.newActiveMQServer(createDefaultConfig(false)
+                                                                             
.clearAcceptorConfigurations()
+                                                                             
.addAcceptorConfiguration("netty", url)));
+      server.start();
+
+      TransportConfiguration tc = 
server.getConfiguration().getAcceptorConfigurations().iterator().next();
+      String host = (String) 
tc.getParams().get(TransportConstants.HOST_PROP_NAME);
+      String port = (String) 
tc.getParams().get(TransportConstants.PORT_PROP_NAME);
+      Object sslHandshakeTimeout = 
tc.getParams().get(TransportConstants.SSL_HANDSHAKE_TIMEOUT);
+      assertNotNull(sslHandshakeTimeout);
+      assertEquals(SSL_HANDSHAKE_TIMEOUT, 
Integer.parseInt(sslHandshakeTimeout.toString()));
+
+      NettyTransport transport = NettyTransportFactory.createTransport(new 
URI("tcp://" + host + ":" + port));
+      transport.setTransportListener(new NettyTransportListener() {
+         @Override
+         public void onData(ByteBuf incoming) {
+
+         }
+
+         @Override
+         public void onTransportClosed() {
+         }
+
+         @Override
+         public void onTransportError(Throwable cause) {
+         }
+
+      });
+
+      try {
+         transport.connect();
+         assertTrue(Wait.waitFor(() -> !transport.isConnected(), 
TimeUnit.SECONDS.toMillis(SSL_HANDSHAKE_TIMEOUT + 1)), "Connection should be 
closed now");
+      } finally {
+         transport.close();
+         server.stop();
+      }
+   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to