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

rmaucher pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 87e233ece68aee4b7596330b40c1753ea649269d
Author: opencode <[email protected]>
AuthorDate: Sun Oct 11 15:58:08 2026 +0200

    Cap the NIO sender SO_TIMEOUT at Integer.MAX_VALUE
    
    NioSender.configureSocket() cast the long sender timeout directly to the
    int required by Socket.setSoTimeout(). Any timeout larger than
    Integer.MAX_VALUE milliseconds (about 24.8 days) therefore overflowed to
    a negative value, which the socket implementation rejects with
    IllegalArgumentException: timeout < 0.
    
    Because configureSocket() runs from connect(), this broke the UDP send
    path outright for such timeouts: UdpChannel.connect() threw before a
    single datagram was sent. TestUdpPackages.testSingleDataSendNO_ACK sets
    setTimeout(Long.MAX_VALUE) and failed deterministically on every run as
    a result; it now passes.
    
    Compute the SO_TIMEOUT value once, capped at Integer.MAX_VALUE, and use
    it for both the socket channel and the datagram channel. The cap keeps
    the effective wait as close as possible to the configured timeout while
    always producing a value the socket accepts.
---
 java/org/apache/catalina/tribes/transport/nio/NioSender.java | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/tribes/transport/nio/NioSender.java 
b/java/org/apache/catalina/tribes/transport/nio/NioSender.java
index 9ec53b4740..3aad23c287 100644
--- a/java/org/apache/catalina/tribes/transport/nio/NioSender.java
+++ b/java/org/apache/catalina/tribes/transport/nio/NioSender.java
@@ -181,11 +181,17 @@ public class NioSender extends AbstractSender {
     }
 
     private void configureSocket() throws IOException {
+        // The timeout is a long in milliseconds but SO_TIMEOUT is an int,
+        // so cap it at the largest value the socket option can represent.
+        // Casting directly would overflow to a negative value for timeouts
+        // larger than Integer.MAX_VALUE, which the socket then rejects with
+        // an IllegalArgumentException.
+        int soTimeout = (int) Math.min(getTimeout(), Integer.MAX_VALUE);
         if (socketChannel != null) {
             socketChannel.configureBlocking(false);
             socketChannel.socket().setSendBufferSize(getTxBufSize());
             socketChannel.socket().setReceiveBufferSize(getRxBufSize());
-            socketChannel.socket().setSoTimeout((int) getTimeout());
+            socketChannel.socket().setSoTimeout(soTimeout);
             socketChannel.socket().setTcpNoDelay(getTcpNoDelay());
             socketChannel.socket().setKeepAlive(getSoKeepAlive());
             socketChannel.socket().setReuseAddress(getSoReuseAddress());
@@ -196,7 +202,7 @@ public class NioSender extends AbstractSender {
             dataChannel.configureBlocking(false);
             dataChannel.socket().setSendBufferSize(getUdpTxBufSize());
             dataChannel.socket().setReceiveBufferSize(getUdpRxBufSize());
-            dataChannel.socket().setSoTimeout((int) getTimeout());
+            dataChannel.socket().setSoTimeout(soTimeout);
             dataChannel.socket().setReuseAddress(getSoReuseAddress());
             dataChannel.socket().setTrafficClass(getSoTrafficClass());
         }


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

Reply via email to