[haiku-commits] Change in haiku[master]: SecureSocket: Handle interrupted reads and writes

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 28 May 2020 06:39:46 +0000

From Kyle Ambroff-Kao <kyle@xxxxxxxxxxxxxx>:

Kyle Ambroff-Kao has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/2825 ;)


Change subject: SecureSocket: Handle interrupted reads and writes
......................................................................

SecureSocket: Handle interrupted reads and writes

If a system call performed by SSL_read is interrupted by a signal, it
seems to set its error to SSL_ERROR_WANT_READ. This triggers logic
added in hrev53853 which assumes the caller is doing async reads and
returns B_WOULD_BLOCK.

This breaks uses of BSecureSocket that do blocking reads.

* Detect interrupted signal by chcking for EINTR in errno.
* Adding this retry loop to BScureSocket::Write as well since it can
  have the same problem.

Resolves issue #15853.
---
M src/kits/network/libnetapi/SecureSocket.cpp
1 file changed, 26 insertions(+), 6 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/25/2825/1

diff --git a/src/kits/network/libnetapi/SecureSocket.cpp 
b/src/kits/network/libnetapi/SecureSocket.cpp
index 5e1539c..9c13c2e 100644
--- a/src/kits/network/libnetapi/SecureSocket.cpp
+++ b/src/kits/network/libnetapi/SecureSocket.cpp
@@ -549,10 +549,14 @@
                bytesRead = SSL_read(fPrivate->fSSL, buffer, size);
                if (bytesRead >= 0)
                        return bytesRead;
+
                // Don't retry in cases of "no data available" for non-blocking 
sockets
-               int error = SSL_get_error(fPrivate->fSSL, bytesRead);
-               if (error == SSL_ERROR_WANT_READ || error == 
SSL_ERROR_WANT_WRITE)
-                       return B_WOULD_BLOCK;
+               if (errno != EINTR) {
+                       int error = SSL_get_error(fPrivate->fSSL, bytesRead);
+                       if (error == SSL_ERROR_WANT_READ || error == 
SSL_ERROR_WANT_WRITE)
+                               return B_WOULD_BLOCK;
+               }
+
                // Otherwise, check if we should retry (maybe we were 
interrupted by
                // a signal, for example)
                retry = BIO_should_retry(SSL_get_rbio(fPrivate->fSSL));
@@ -568,9 +572,25 @@
        if (!IsConnected())
                return B_ERROR;

-       int bytesWritten = SSL_write(fPrivate->fSSL, buffer, size);
-       if (bytesWritten >= 0)
-               return bytesWritten;
+       int bytesWritten;
+       int retry;
+       do {
+               bytesWritten = SSL_write(fPrivate->fSSL, buffer, size);
+               if (bytesWritten >= 0)
+                       return bytesWritten;
+
+               // Don't retry in cases of "no data available" for non-blocking
+               // sockets
+               if (errno != EINTR) {
+                       int error = SSL_get_error(fPrivate->fSSL, bytesWritten);
+                       if (error == SSL_ERROR_WANT_READ || error == 
SSL_ERROR_WANT_WRITE)
+                               return B_WOULD_BLOCK;
+               }
+
+               // Otherwise, check if we should retry (maybe we were
+               // interrupted by a signal, for example)
+               retry = BIO_should_retry(SSL_get_wbio(fPrivate->fSSL));
+       } while (retry != 0);

        return fPrivate->ErrorCode(bytesWritten);
 }

--
To view, visit https://review.haiku-os.org/c/haiku/+/2825
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I8198a8496fa3a2ccee00bda87375a482a0d4ba3d
Gerrit-Change-Number: 2825
Gerrit-PatchSet: 1
Gerrit-Owner: Kyle Ambroff-Kao <kyle@xxxxxxxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: SecureSocket: Handle interrupted reads and writes - Gerrit