summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2016-05-03 17:55:00 +0100
committerMatt Caswell <matt@openssl.org>2016-05-05 19:39:14 +0100
commitfc7f190c732729c1d0eb9dcdb7ff05ed6b06056f (patch)
treeb4b70753df865b62635b71b1ad177a1b0582a6d0 /ssl
parent0eadff033fea00f1b9abe0a83bf0d6637690f085 (diff)
Handle no async jobs in libssl
If the application has limited the size of the async pool using ASYNC_init_thread() then we could run out of jobs while trying to start a libssl io operation. However libssl was failing to handle this and treating it like a fatal error. It should not be fatal...we just need to retry when there are jobs available again. Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_lib.c102
1 files changed, 55 insertions, 47 deletions
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index e00c1191b5..e07fa07de7 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1516,6 +1516,9 @@ static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
case ASYNC_PAUSE:
s->rwstate = SSL_ASYNC_PAUSED;
return -1;
+ case ASYNC_NO_JOBS:
+ s->rwstate = SSL_ASYNC_NO_JOBS;
+ return -1;
case ASYNC_FINISH:
s->job = NULL;
return ret;
@@ -2939,56 +2942,61 @@ int SSL_get_error(const SSL *s, int i)
return (SSL_ERROR_SSL);
}
- if ((i < 0) && SSL_want_read(s)) {
- bio = SSL_get_rbio(s);
- if (BIO_should_read(bio))
- return (SSL_ERROR_WANT_READ);
- else if (BIO_should_write(bio))
- /*
- * This one doesn't make too much sense ... We never try to write
- * to the rbio, and an application program where rbio and wbio
- * are separate couldn't even know what it should wait for.
- * However if we ever set s->rwstate incorrectly (so that we have
- * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and
- * wbio *are* the same, this test works around that bug; so it
- * might be safer to keep it.
- */
- return (SSL_ERROR_WANT_WRITE);
- else if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT)
- return (SSL_ERROR_WANT_CONNECT);
- else if (reason == BIO_RR_ACCEPT)
- return (SSL_ERROR_WANT_ACCEPT);
- else
- return (SSL_ERROR_SYSCALL); /* unknown */
+ if (i < 0) {
+ if (SSL_want_read(s)) {
+ bio = SSL_get_rbio(s);
+ if (BIO_should_read(bio))
+ return (SSL_ERROR_WANT_READ);
+ else if (BIO_should_write(bio))
+ /*
+ * This one doesn't make too much sense ... We never try to write
+ * to the rbio, and an application program where rbio and wbio
+ * are separate couldn't even know what it should wait for.
+ * However if we ever set s->rwstate incorrectly (so that we have
+ * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and
+ * wbio *are* the same, this test works around that bug; so it
+ * might be safer to keep it.
+ */
+ return (SSL_ERROR_WANT_WRITE);
+ else if (BIO_should_io_special(bio)) {
+ reason = BIO_get_retry_reason(bio);
+ if (reason == BIO_RR_CONNECT)
+ return (SSL_ERROR_WANT_CONNECT);
+ else if (reason == BIO_RR_ACCEPT)
+ return (SSL_ERROR_WANT_ACCEPT);
+ else
+ return (SSL_ERROR_SYSCALL); /* unknown */
+ }
}
- }
- if ((i < 0) && SSL_want_write(s)) {
- bio = SSL_get_wbio(s);
- if (BIO_should_write(bio))
- return (SSL_ERROR_WANT_WRITE);
- else if (BIO_should_read(bio))
- /*
- * See above (SSL_want_read(s) with BIO_should_write(bio))
- */
- return (SSL_ERROR_WANT_READ);
- else if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT)
- return (SSL_ERROR_WANT_CONNECT);
- else if (reason == BIO_RR_ACCEPT)
- return (SSL_ERROR_WANT_ACCEPT);
- else
- return (SSL_ERROR_SYSCALL);
+ if (SSL_want_write(s)) {
+ bio = SSL_get_wbio(s);
+ if (BIO_should_write(bio))
+ return (SSL_ERROR_WANT_WRITE);
+ else if (BIO_should_read(bio))
+ /*
+ * See above (SSL_want_read(s) with BIO_should_write(bio))
+ */
+ return (SSL_ERROR_WANT_READ);
+ else if (BIO_should_io_special(bio)) {
+ reason = BIO_get_retry_reason(bio);
+ if (reason == BIO_RR_CONNECT)
+ return (SSL_ERROR_WANT_CONNECT);
+ else if (reason == BIO_RR_ACCEPT)
+ return (SSL_ERROR_WANT_ACCEPT);
+ else
+ return (SSL_ERROR_SYSCALL);
+ }
+ }
+ if (SSL_want_x509_lookup(s)) {
+ return (SSL_ERROR_WANT_X509_LOOKUP);
+ }
+ if (SSL_want_async(s)) {
+ return SSL_ERROR_WANT_ASYNC;
+ }
+ if (SSL_want_async_job(s)) {
+ return SSL_ERROR_WANT_ASYNC_JOB;
}
- }
- if ((i < 0) && SSL_want_x509_lookup(s)) {
- return (SSL_ERROR_WANT_X509_LOOKUP);
- }
- if ((i < 0) && SSL_want_async(s)) {
- return SSL_ERROR_WANT_ASYNC;
}
if (i == 0) {