mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-17 01:02:12 +00:00
FS-11362 FS could close client verto connection due to incorrect handling of SSL function return values (when SSL layer need to communicate with client on its own, f.e. keys re-negotiation)
This commit is contained in:
parent
2dcfc27963
commit
523db20068
@ -346,10 +346,12 @@ int ws_handshake(wsh_t *wsh)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SSL_WANT_READ_WRITE(err) (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
|
||||||
|
|
||||||
ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
|
ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
|
||||||
{
|
{
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
int err = 0;
|
int ssl_err = 0;
|
||||||
|
|
||||||
wsh->x++;
|
wsh->x++;
|
||||||
if (wsh->x > 250) ms_sleep(1);
|
if (wsh->x > 250) ms_sleep(1);
|
||||||
@ -358,10 +360,10 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
|
|||||||
do {
|
do {
|
||||||
r = SSL_read(wsh->ssl, data, bytes);
|
r = SSL_read(wsh->ssl, data, bytes);
|
||||||
|
|
||||||
if (r == -1) {
|
if (r < 0) {
|
||||||
err = SSL_get_error(wsh->ssl, r);
|
ssl_err = SSL_get_error(wsh->ssl, r);
|
||||||
|
|
||||||
if (err == SSL_ERROR_WANT_READ) {
|
if (SSL_WANT_READ_WRITE(ssl_err)) {
|
||||||
if (!block) {
|
if (!block) {
|
||||||
r = -2;
|
r = -2;
|
||||||
goto end;
|
goto end;
|
||||||
@ -374,7 +376,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 1000);
|
} while (r < 0 && SSL_WANT_READ_WRITE(ssl_err) && wsh->x < 1000);
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -446,10 +448,10 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
|
|||||||
ms_sleep(ms);
|
ms_sleep(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == -1) {
|
if (r < 0) {
|
||||||
ssl_err = SSL_get_error(wsh->ssl, r);
|
ssl_err = SSL_get_error(wsh->ssl, r);
|
||||||
|
|
||||||
if (ssl_err != SSL_ERROR_WANT_WRITE && ssl_err != SSL_ERROR_WANT_READ) {
|
if (!SSL_WANT_READ_WRITE(ssl_err)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ssl_err = 0;
|
ssl_err = 0;
|
||||||
@ -581,7 +583,8 @@ int establish_logical_layer(wsh_t *wsh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
if (code == -1 && SSL_get_error(wsh->ssl, code) != SSL_ERROR_WANT_READ) {
|
int ssl_err = SSL_get_error(wsh->ssl, code);
|
||||||
|
if (code < 0 && !SSL_WANT_READ_WRITE(ssl_err)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,10 +695,22 @@ void ws_destroy(wsh_t *wsh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wsh->ssl) {
|
if (wsh->ssl) {
|
||||||
int code;
|
int code, ssl_err, sanity = 100;
|
||||||
do {
|
do {
|
||||||
code = SSL_shutdown(wsh->ssl);
|
code = SSL_shutdown(wsh->ssl);
|
||||||
} while (code == -1 && SSL_get_error(wsh->ssl, code) == SSL_ERROR_WANT_READ);
|
if (code == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code < 0) {
|
||||||
|
ssl_err = SSL_get_error(wsh->ssl, code);
|
||||||
|
}
|
||||||
|
if (wsh->block) {
|
||||||
|
ms_sleep(10);
|
||||||
|
} else {
|
||||||
|
ms_sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while ((code == 0 || (code < 0 && SSL_WANT_READ_WRITE(ssl_err))) && --sanity > 0);
|
||||||
|
|
||||||
SSL_free(wsh->ssl);
|
SSL_free(wsh->ssl);
|
||||||
wsh->ssl = NULL;
|
wsh->ssl = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user