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