summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-03-27 18:03:03 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-03-27 18:03:03 +0200
commite538cb095f6290c40e8928e3813db6ac679740a2 (patch)
tree51f12fad5a2928fc1d398e7f45fc40c1c09e2512 /vio
parent356c149603285086d964c8a51107be97b981c15c (diff)
parent80459bcbd4ca2cfd149f58c41428882fcfc49e03 (diff)
downloadmariadb-git-e538cb095f6290c40e8928e3813db6ac679740a2.tar.gz
Merge 10.5 into 10.6
Diffstat (limited to 'vio')
-rw-r--r--vio/viossl.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/vio/viossl.c b/vio/viossl.c
index 590b78f24cd..94c4bcb46cf 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -83,13 +83,14 @@ static void ssl_set_sys_error(int ssl_error)
@param vio VIO object representing a SSL connection.
@param ret Value returned by a SSL I/O function.
@param event[out] The type of I/O event to wait/retry.
+ @param should_wait[out] whether to wait for 'event'
@return Whether a SSL I/O operation should be deferred.
@retval TRUE Temporary failure, retry operation.
@retval FALSE Indeterminate failure.
*/
-static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event)
+static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event, my_bool *should_wait)
{
int ssl_error;
SSL *ssl= vio->ssl_arg;
@@ -106,6 +107,7 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event
ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE)
{
ERR_clear_error();
+ *should_wait= FALSE;
return TRUE;
}
#endif
@@ -118,12 +120,15 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event
{
case SSL_ERROR_WANT_READ:
*event= VIO_IO_EVENT_READ;
+ *should_wait= TRUE;
break;
case SSL_ERROR_WANT_WRITE:
*event= VIO_IO_EVENT_WRITE;
+ *should_wait= TRUE;
break;
default:
should_retry= FALSE;
+ *should_wait= FALSE;
ssl_set_sys_error(ssl_error);
ERR_clear_error();
break;
@@ -133,6 +138,32 @@ static my_bool ssl_should_retry(Vio *vio, int ret, enum enum_vio_io_event *event
}
+/**
+ Handle SSL io error.
+
+ @param[in] vio Vio
+ @param[in] ret return from the failed IO operation
+
+ @return 0 - should retry last read/write operation
+ 1 - some error has occured
+*/
+static int handle_ssl_io_error(Vio *vio, int ret)
+{
+ enum enum_vio_io_event event;
+ my_bool should_wait;
+
+ /* Process the SSL I/O error. */
+ if (!ssl_should_retry(vio, ret, &event, &should_wait))
+ return 1;
+
+ if (!should_wait)
+ return 1;
+
+ /* Attempt to wait for an I/O event. */
+ return vio_socket_io_wait(vio, event);
+}
+
+
size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
{
int ret;
@@ -145,17 +176,11 @@ size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
while ((ret= SSL_read(ssl, buf, (int)size)) < 0)
{
- enum enum_vio_io_event event;
-
- /* Process the SSL I/O error. */
- if (!ssl_should_retry(vio, ret, &event))
- break;
- /* Attempt to wait for an I/O event. */
- if (vio_socket_io_wait(vio, event))
+ if (handle_ssl_io_error(vio, ret))
break;
}
- DBUG_PRINT("exit", ("%d", (int) ret));
+ DBUG_PRINT("exit", ("%d", ret));
DBUG_RETURN(ret < 0 ? -1 : ret);
}
@@ -171,14 +196,7 @@ size_t vio_ssl_write(Vio *vio, const uchar *buf, size_t size)
buf, size));
while ((ret= SSL_write(ssl, buf, (int)size)) < 0)
{
- enum enum_vio_io_event event;
-
- /* Process the SSL I/O error. */
- if (!ssl_should_retry(vio, ret, &event))
- break;
-
- /* Attempt to wait for an I/O event. */
- if (vio_socket_io_wait(vio, event))
+ if (handle_ssl_io_error(vio,ret))
break;
}
@@ -265,14 +283,7 @@ static int ssl_handshake_loop(Vio *vio, SSL *ssl, ssl_handshake_func_t func)
/* Initiate the SSL handshake. */
while ((ret= func(ssl)) < 1)
{
- enum enum_vio_io_event event;
-
- /* Process the SSL I/O error. */
- if (!ssl_should_retry(vio, ret, &event))
- break;
-
- /* Wait for I/O so that the handshake can proceed. */
- if (vio_socket_io_wait(vio, event))
+ if (handle_ssl_io_error(vio,ret))
break;
}