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

timoninmaxim pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new ad1bbcfabb1 IGNITE-22605 Add check for SSL errors on TcpDiscovery 
writing failures (#11415)
ad1bbcfabb1 is described below

commit ad1bbcfabb1bcbba4450d5d0cd613605e49b7830
Author: Maksim Timonin <[email protected]>
AuthorDate: Tue Jul 16 21:04:11 2024 +0300

    IGNITE-22605 Add check for SSL errors on TcpDiscovery writing failures 
(#11415)
---
 .../ignite/spi/discovery/tcp/TcpDiscoverySpi.java  | 45 ++++++++++++++++++++--
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
 
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index 6ae86f6c071..410611cc82f 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -1659,6 +1659,39 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter 
implements IgniteDiscovery
         }
     }
 
+    /**
+     * Writing to a socket might fail due to a broken connection. It might 
happen due to a recipient has closed the connection
+     * before, on SSL handshake, and doesn't accept new messages. In a such 
case it's possible to check the original error
+     * by reading the socket input stream.
+     *
+     * @param sock Socket to check.
+     * @param writeErr Error on writing a message to the socket.
+     * @return {@code SSLException} in case of SSL error, or {@code null} 
otherwise.
+     */
+    private @Nullable SSLException checkSslException(Socket sock, Exception 
writeErr) {
+        if (!sslEnable)
+            return null;
+
+        SSLException sslEx = X.cause(writeErr, SSLException.class);
+
+        if (sslEx != null)
+            return sslEx;
+
+        try {
+            // Set timeout to 1ms, in this case of closed socket it should 
return fast.
+            if (X.hasCause(writeErr, SocketException.class))
+                readReceipt(sock, 1);
+        }
+        catch (SSLException sslErr) {
+            return sslErr;
+        }
+        catch (Exception err) {
+            // Skip.
+        }
+
+        return null;
+    }
+
     /**
      * Creates socket binding it to a local host address. This operation is 
not blocking.
      *
@@ -1716,7 +1749,9 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter 
implements IgniteDiscovery
             out.flush();
         }
         catch (IOException e) {
-            err = e;
+            SSLException sslEx = checkSslException(sock, e);
+
+            err = sslEx == null ? e : sslEx;
         }
         finally {
             boolean cancelled = obj.cancel();
@@ -1824,7 +1859,9 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter 
implements IgniteDiscovery
             U.marshal(marshaller(), msg, out);
         }
         catch (IgniteCheckedException e) {
-            err = e;
+            SSLException sslEx = checkSslException(sock, e);
+
+            err = sslEx == null ? e : new IgniteCheckedException(sslEx);
         }
         finally {
             boolean cancelled = obj.cancel();
@@ -1869,7 +1906,9 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter 
implements IgniteDiscovery
             out.flush();
         }
         catch (IOException e) {
-            err = e;
+            SSLException sslEx = checkSslException(sock, e);
+
+            err = sslEx == null ? e : sslEx;
         }
         finally {
             boolean cancelled = obj.cancel();

Reply via email to