Skip to content

Commit c44cbdf

Browse files
BUG#25444075 - YASSL REQUIRES FROM READ FUNCTION TO RETURN
EWOULDBLOCK, VIO RETURNS ETIMEOUT. Connection is invalidated when read timeout occurs and application uses YaSSL. The root cause is that yassl_recv emulates a blocking recv using the vio_read. vio_read returns ETIMEOUT in case of a timeout. YaSSL considers ETIMEOUT as a critical error causing subsequent read and writes to fail. The fix remaps ETIMEOUT to EWOULDBLOCK in yassl_recv. This fix is provided by Lukasz Kotula.
1 parent 4e5c590 commit c44cbdf

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

vio/viossl.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,13 @@ static my_bool ssl_should_retry(Vio *vio, int ret,
167167
return should_retry;
168168
}
169169

170-
170+
#ifdef HAVE_YASSL
171+
size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
172+
{
173+
// YASSL maps ETIMEOUT to EWOULDBLOCK and hence no need for retry here.
174+
return SSL_read(static_cast<SSL*>(vio->ssl_arg), buf, (int)size);
175+
}
176+
#else
171177
size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
172178
{
173179
int ret;
@@ -180,14 +186,12 @@ size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
180186
{
181187
enum enum_vio_io_event event;
182188

183-
#ifndef HAVE_YASSL
184189
/*
185190
OpenSSL: check that the SSL thread's error queue is cleared. Otherwise
186191
SSL_read() returns an error from the error queue, when SSL_read() failed
187192
because it would block.
188193
*/
189194
DBUG_ASSERT(ERR_peek_error() == 0);
190-
#endif
191195

192196
ret= SSL_read(ssl, buf, (int)size);
193197

@@ -205,7 +209,7 @@ size_t vio_ssl_read(Vio *vio, uchar *buf, size_t size)
205209

206210
DBUG_RETURN(ret < 0 ? -1 : ret);
207211
}
208-
212+
#endif
209213

210214
size_t vio_ssl_write(Vio *vio, const uchar *buf, size_t size)
211215
{
@@ -251,8 +255,15 @@ extern "C" {
251255
/* Emulate a blocking recv() call with vio_read(). */
252256
static long yassl_recv(void *ptr, void *buf, size_t len)
253257
{
254-
return static_cast<long>(vio_read(static_cast<Vio*>(ptr),
258+
long result= static_cast<long>(vio_read(static_cast<Vio*>(ptr),
255259
static_cast<uchar*>(buf), len));
260+
/*
261+
YASSL considers ETIMEOUT as critical error. This causes
262+
the connection to be invalidated.
263+
*/
264+
if (result == -1 && vio_was_timeout(static_cast<Vio*>(ptr)))
265+
errno= SOCKET_EWOULDBLOCK;
266+
return result;
256267
}
257268

258269

0 commit comments

Comments
 (0)