}
+#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 r;
- int err = 0;
+ int ssl_err = 0;
wsh->x++;
if (wsh->x > 250) ms_sleep(1);
do {
r = SSL_read(wsh->ssl, data, bytes);
- if (r == -1) {
- err = SSL_get_error(wsh->ssl, r);
+ if (r < 0) {
+ ssl_err = SSL_get_error(wsh->ssl, r);
- if (err == SSL_ERROR_WANT_READ) {
+ if (SSL_WANT_READ_WRITE(ssl_err)) {
if (!block) {
r = -2;
goto end;
}
}
- } 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;
}
ms_sleep(ms);
}
- if (r == -1) {
+ if (r < 0) {
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;
}
ssl_err = 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;
}
}
}
if (wsh->ssl) {
- int code;
+ int code, ssl_err, sanity = 100;
do {
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);
wsh->ssl = NULL;