BSecureSocket: retry reads after interrupted syscalls.

SSL_AUTO_RETRY does not cover this case (it only covers SSL errors, not
underlying socket ones), so we still need to retry reads manually here.

Fixes #14638.
This commit is contained in:
Adrien Destugues 2020-02-03 21:43:01 +01:00
parent 9762e2fe45
commit 3bea15adca

View File

@ -224,11 +224,11 @@ BSecureSocket::Private::ErrorCode(int returnValue)
if (returnValue == -1) if (returnValue == -1)
{ {
fprintf(stderr, "SSL %s\n", ERR_error_string(error, NULL)); fprintf(stderr, "SSL rv -1 %s\n", ERR_error_string(error, NULL));
return errno; return errno;
} }
fprintf(stderr, "SSL %s\n", ERR_error_string(error, NULL)); fprintf(stderr, "SSL rv other %s\n", ERR_error_string(error, NULL));
return B_ERROR; return B_ERROR;
} }
@ -239,7 +239,7 @@ BSecureSocket::Private::ErrorCode(int returnValue)
case SSL_ERROR_WANT_X509_LOOKUP: case SSL_ERROR_WANT_X509_LOOKUP:
default: default:
// TODO: translate SSL error codes! // TODO: translate SSL error codes!
fprintf(stderr, "SSL %s\n", ERR_error_string(error, NULL)); fprintf(stderr, "SSL other %s\n", ERR_error_string(error, NULL));
return B_ERROR; return B_ERROR;
} }
} }
@ -545,9 +545,15 @@ BSecureSocket::Read(void* buffer, size_t size)
if (!IsConnected()) if (!IsConnected())
return B_ERROR; return B_ERROR;
int bytesRead = SSL_read(fPrivate->fSSL, buffer, size); int bytesRead;
int error;
int retry;
do {
bytesRead = SSL_read(fPrivate->fSSL, buffer, size);
if (bytesRead >= 0) if (bytesRead >= 0)
return bytesRead; return bytesRead;
retry = BIO_should_retry(SSL_get_rbio(fPrivate->fSSL));
} while(retry != 0);
return fPrivate->ErrorCode(bytesRead); return fPrivate->ErrorCode(bytesRead);
} }