vtls: change send/recv signatures of tls backends

Similar to connection filter changes, return a CURLcode and the
read/written amount as size_t *.

Closes #17593
This commit is contained in:
Stefan Eissing 2025-06-11 14:50:15 +02:00 committed by Daniel Stenberg
parent 17f8b1db5c
commit b7c676d13f
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
8 changed files with 310 additions and 348 deletions

View file

@ -1948,48 +1948,49 @@ static bool gtls_data_pending(struct Curl_cfilter *cf,
return FALSE;
}
static ssize_t gtls_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf,
size_t blen,
CURLcode *curlcode)
static CURLcode gtls_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf,
size_t blen,
size_t *pnwritten)
{
struct ssl_connect_data *connssl = cf->ctx;
struct gtls_ssl_backend_data *backend =
(struct gtls_ssl_backend_data *)connssl->backend;
ssize_t rc;
size_t nwritten, total_written = 0;
CURLcode result = CURLE_OK;
ssize_t nwritten;
size_t remain = blen;
(void)data;
DEBUGASSERT(backend);
*pnwritten = 0;
while(blen) {
while(remain) {
backend->gtls.io_result = CURLE_OK;
rc = gnutls_record_send(backend->gtls.session, buf, blen);
nwritten = gnutls_record_send(backend->gtls.session, buf, remain);
if(rc < 0) {
if(total_written && (rc == GNUTLS_E_AGAIN)) {
*curlcode = CURLE_OK;
rc = (ssize_t)total_written;
if(nwritten >= 0) {
*pnwritten += (size_t)nwritten;
DEBUGASSERT((size_t)nwritten <= remain);
buf = (char *)CURL_UNCONST(buf) + (size_t)nwritten;
remain -= (size_t)nwritten;
}
else {
if(*pnwritten && (nwritten == GNUTLS_E_AGAIN)) {
result = CURLE_OK;
goto out;
}
*curlcode = (rc == GNUTLS_E_AGAIN) ?
result = (nwritten == GNUTLS_E_AGAIN) ?
CURLE_AGAIN :
(backend->gtls.io_result ? backend->gtls.io_result : CURLE_SEND_ERROR);
rc = -1;
goto out;
}
nwritten = (size_t)rc;
total_written += nwritten;
DEBUGASSERT(nwritten <= blen);
buf = (char *)CURL_UNCONST(buf) + nwritten;
blen -= nwritten;
}
rc = total_written;
out:
return rc;
CURL_TRC_CF(data, cf, "gtls_send(len=%zu) -> %d, %zu",
blen, result, *pnwritten);
return result;
}
/*
@ -2095,50 +2096,49 @@ static void gtls_close(struct Curl_cfilter *cf,
#endif
}
static ssize_t gtls_recv(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf,
size_t buffersize,
CURLcode *curlcode)
static CURLcode gtls_recv(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread)
{
struct ssl_connect_data *connssl = cf->ctx;
struct gtls_ssl_backend_data *backend =
(struct gtls_ssl_backend_data *)connssl->backend;
ssize_t ret;
CURLcode result = CURLE_OK;
ssize_t nread;
(void)data;
DEBUGASSERT(backend);
ret = gnutls_record_recv(backend->gtls.session, buf, buffersize);
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
*curlcode = CURLE_AGAIN;
ret = -1;
goto out;
}
nread = gnutls_record_recv(backend->gtls.session, buf, blen);
if(ret == GNUTLS_E_REHANDSHAKE) {
/* BLOCKING call, this is bad but a work-around for now. Fixing this "the
proper way" takes a whole lot of work. */
CURLcode result = handshake(cf, data);
if(result)
*curlcode = result;
else
*curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
ret = -1;
goto out;
}
if(ret < 0) {
failf(data, "GnuTLS recv error (%d): %s",
(int)ret, gnutls_strerror((int)ret));
*curlcode = backend->gtls.io_result ?
backend->gtls.io_result : CURLE_RECV_ERROR;
ret = -1;
goto out;
if(nread >= 0)
*pnread = (size_t)nread;
else {
if((nread == GNUTLS_E_AGAIN) || (nread == GNUTLS_E_INTERRUPTED)) {
result = CURLE_AGAIN;
goto out;
}
else if(nread == GNUTLS_E_REHANDSHAKE) {
/* BLOCKING call, this is bad but a work-around for now. Fixing this "the
proper way" takes a whole lot of work. */
result = handshake(cf, data);
if(!result)
result = CURLE_AGAIN; /* then return as if this was a wouldblock */
goto out;
}
else {
failf(data, "GnuTLS recv error (%d): %s",
(int)nread, gnutls_strerror((int)nread));
result = backend->gtls.io_result ?
backend->gtls.io_result : CURLE_RECV_ERROR;
goto out;
}
}
out:
return ret;
CURL_TRC_CF(data, cf, "gtls_recv(len=%zu) -> 0, %zu", blen, *pnread);
return result;
}
size_t Curl_gtls_version(char *buffer, size_t size)

View file

@ -1203,16 +1203,18 @@ out:
return result;
}
static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len,
CURLcode *curlcode)
static CURLcode mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len,
size_t *pnwritten)
{
struct ssl_connect_data *connssl = cf->ctx;
struct mbed_ssl_backend_data *backend =
(struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
CURLcode result = CURLE_OK;
int nwritten;
(void)data;
*pnwritten = 0;
DEBUGASSERT(backend);
/* mbedtls is picky when a mbedtls_ssl_write) was previously blocked.
* It requires to be called with the same amount of bytes again, or it
@ -1225,28 +1227,29 @@ static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
len = backend->send_blocked_len;
}
ret = mbedtls_ssl_write(&backend->ssl, (const unsigned char *)mem, len);
nwritten = mbedtls_ssl_write(&backend->ssl, (const unsigned char *)mem, len);
if(ret < 0) {
if(nwritten >= 0) {
*pnwritten = (size_t)nwritten;
backend->send_blocked = FALSE;
}
else {
CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X",
len, -ret);
*curlcode = ((ret == MBEDTLS_ERR_SSL_WANT_WRITE)
len, -nwritten);
result = ((nwritten == MBEDTLS_ERR_SSL_WANT_WRITE)
#ifdef HAS_TLS13_SUPPORT
|| (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
|| (nwritten == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET)
#endif
) ? CURLE_AGAIN : CURLE_SEND_ERROR;
ret = -1;
if((*curlcode == CURLE_AGAIN) && !backend->send_blocked) {
if((result == CURLE_AGAIN) && !backend->send_blocked) {
backend->send_blocked = TRUE;
backend->send_blocked_len = len;
}
}
else {
CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d", len, ret);
backend->send_blocked = FALSE;
}
return ret;
CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> %d, %zu",
len, result, *pnwritten);
return result;
}
static CURLcode mbedtls_shutdown(struct Curl_cfilter *cf,
@ -1365,48 +1368,48 @@ static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
}
}
static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t buffersize,
CURLcode *curlcode)
static CURLcode mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t buffersize,
size_t *pnread)
{
struct ssl_connect_data *connssl = cf->ctx;
struct mbed_ssl_backend_data *backend =
(struct mbed_ssl_backend_data *)connssl->backend;
int ret = -1;
CURLcode result = CURLE_OK;
int nread;
(void)data;
DEBUGASSERT(backend);
*pnread = 0;
ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
buffersize);
if(ret <= 0) {
nread = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, buffersize);
if(nread > 0)
*pnread = (size_t)nread;
else {
CURL_TRC_CF(data, cf, "mbedtls_ssl_read(len=%zu) -> -0x%04X",
buffersize, -ret);
switch(ret) {
buffersize, -nread);
switch(nread) {
#ifdef HAS_SESSION_TICKETS
case MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET:
mbed_new_session(cf, data);
FALLTHROUGH();
#endif
case MBEDTLS_ERR_SSL_WANT_READ:
*curlcode = CURLE_AGAIN;
ret = -1;
result = CURLE_AGAIN;
break;
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
*curlcode = CURLE_OK;
ret = 0;
result = CURLE_OK;
break;
default: {
char errorbuf[128];
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "ssl_read returned: (-0x%04X) %s", -ret, errorbuf);
*curlcode = CURLE_RECV_ERROR;
ret = -1;
mbedtls_strerror(nread, errorbuf, sizeof(errorbuf));
failf(data, "ssl_read returned: (-0x%04X) %s", -nread, errorbuf);
result = CURLE_RECV_ERROR;
break;
}
}
}
return (ssize_t)ret;
return result;
}
static size_t mbedtls_version(char *buffer, size_t size)

View file

@ -2177,6 +2177,8 @@ static CURLcode ossl_shutdown(struct Curl_cfilter *cf,
out:
cf->shutdown = (result || *done);
if(cf->shutdown || (connssl->io_need != CURL_SSL_IO_NEED_NONE))
connssl->input_pending = FALSE;
return result;
}
@ -2188,6 +2190,7 @@ static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
(void)data;
DEBUGASSERT(octx);
connssl->input_pending = FALSE;
if(octx->ssl) {
SSL_free(octx->ssl);
octx->ssl = NULL;
@ -5227,11 +5230,11 @@ static bool ossl_data_pending(struct Curl_cfilter *cf,
return connssl->input_pending;
}
static ssize_t ossl_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *mem,
size_t len,
CURLcode *curlcode)
static CURLcode ossl_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *mem,
size_t len,
size_t *pnwritten)
{
/* SSL_write() is said to return 'int' while write() and send() returns
'size_t' */
@ -5239,39 +5242,39 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
char error_buffer[256];
sslerr_t sslerror;
int memlen;
int rc;
struct ssl_connect_data *connssl = cf->ctx;
struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
CURLcode result = CURLE_OK;
int nwritten;
(void)data;
DEBUGASSERT(octx);
*pnwritten = 0;
ERR_clear_error();
connssl->io_need = CURL_SSL_IO_NEED_NONE;
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
rc = SSL_write(octx->ssl, mem, memlen);
nwritten = SSL_write(octx->ssl, mem, memlen);
if(rc <= 0) {
err = SSL_get_error(octx->ssl, rc);
if(nwritten > 0)
*pnwritten = (size_t)nwritten;
else {
err = SSL_get_error(octx->ssl, nwritten);
switch(err) {
case SSL_ERROR_WANT_READ:
connssl->io_need = CURL_SSL_IO_NEED_RECV;
*curlcode = CURLE_AGAIN;
rc = -1;
result = CURLE_AGAIN;
goto out;
case SSL_ERROR_WANT_WRITE:
*curlcode = CURLE_AGAIN;
rc = -1;
result = CURLE_AGAIN;
goto out;
case SSL_ERROR_SYSCALL:
{
int sockerr = SOCKERRNO;
if(octx->io_result == CURLE_AGAIN) {
*curlcode = CURLE_AGAIN;
rc = -1;
result = CURLE_AGAIN;
goto out;
}
sslerror = ERR_get_error();
@ -5285,8 +5288,7 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_SEND_ERROR;
rc = -1;
result = CURLE_SEND_ERROR;
goto out;
}
case SSL_ERROR_SSL: {
@ -5295,49 +5297,50 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
sslerror = ERR_get_error();
failf(data, "SSL_write() error: %s",
ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
*curlcode = CURLE_SEND_ERROR;
rc = -1;
result = CURLE_SEND_ERROR;
goto out;
}
default:
/* a true error */
failf(data, OSSL_PACKAGE " SSL_write: %s, errno %d",
SSL_ERROR_to_str(err), SOCKERRNO);
*curlcode = CURLE_SEND_ERROR;
rc = -1;
result = CURLE_SEND_ERROR;
goto out;
}
}
*curlcode = CURLE_OK;
out:
return (ssize_t)rc; /* number of bytes */
return result;
}
static ssize_t ossl_recv(struct Curl_cfilter *cf,
struct Curl_easy *data, /* transfer */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
static CURLcode ossl_recv(struct Curl_cfilter *cf,
struct Curl_easy *data, /* transfer */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
size_t *pnread)
{
char error_buffer[256];
unsigned long sslerror;
ssize_t nread;
int buffsize;
struct connectdata *conn = cf->conn;
struct ssl_connect_data *connssl = cf->ctx;
struct ossl_ctx *octx = (struct ossl_ctx *)connssl->backend;
CURLcode result = CURLE_OK;
int nread;
(void)data;
DEBUGASSERT(octx);
*pnread = 0;
ERR_clear_error();
connssl->io_need = CURL_SSL_IO_NEED_NONE;
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
nread = (ssize_t)SSL_read(octx->ssl, buf, buffsize);
nread = SSL_read(octx->ssl, buf, buffsize);
if(nread <= 0) {
if(nread > 0)
*pnread = (size_t)nread;
else {
/* failed SSL_read */
int err = SSL_get_error(octx->ssl, (int)nread);
@ -5352,21 +5355,18 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
connclose(conn, "TLS close_notify");
break;
case SSL_ERROR_WANT_READ:
*curlcode = CURLE_AGAIN;
nread = -1;
result = CURLE_AGAIN;
goto out;
case SSL_ERROR_WANT_WRITE:
connssl->io_need = CURL_SSL_IO_NEED_SEND;
*curlcode = CURLE_AGAIN;
nread = -1;
result = CURLE_AGAIN;
goto out;
default:
/* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
value/errno" */
/* https://docs.openssl.org/master/man3/ERR_get_error/ */
if(octx->io_result == CURLE_AGAIN) {
*curlcode = CURLE_AGAIN;
nread = -1;
result = CURLE_AGAIN;
goto out;
}
sslerror = ERR_get_error();
@ -5383,18 +5383,17 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
SSL_ERROR_to_str(err));
failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_RECV_ERROR;
nread = -1;
result = CURLE_RECV_ERROR;
goto out;
}
else if(err == SSL_ERROR_SYSCALL) {
if(octx->io_result) {
/* logging handling in underlying filter already */
*curlcode = octx->io_result;
result = octx->io_result;
}
else if(connssl->peer_closed) {
failf(data, "Connection closed abruptly");
*curlcode = CURLE_RECV_ERROR;
result = CURLE_RECV_ERROR;
}
else {
/* We should no longer get here nowadays. But handle
@ -5408,16 +5407,15 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
}
failf(data, OSSL_PACKAGE " SSL_read: %s, errno %d",
error_buffer, sockerr);
*curlcode = CURLE_RECV_ERROR;
result = CURLE_RECV_ERROR;
}
nread = -1;
goto out;
}
}
}
out:
if(!nread || ((nread < 0) && (*curlcode == CURLE_AGAIN))) {
if((!result && !*pnread) || (result == CURLE_AGAIN)) {
/* This happens when:
* - we read an EOF
* - OpenSSLs buffers are empty, there is no more data
@ -5426,7 +5424,9 @@ out:
* until more data arrives */
connssl->input_pending = FALSE;
}
return nread;
CURL_TRC_CF(data, cf, "ossl_recv(len=%zu) -> %d, %zu (in_pending=%d)",
buffersize, result, *pnread, connssl->input_pending);
return result;
}
static CURLcode ossl_get_channel_binding(struct Curl_easy *data, int sockindex,

View file

@ -195,37 +195,37 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf,
* buffer, and process packets, but will not consume bytes from Rustls'
* plaintext output buffer.
*/
static ssize_t
static CURLcode
cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *plainbuf, size_t plainlen, CURLcode *err)
char *plainbuf, size_t plainlen, size_t *pnread)
{
const struct ssl_connect_data *const connssl = cf->ctx;
struct rustls_ssl_backend_data *const backend =
(struct rustls_ssl_backend_data *)connssl->backend;
struct rustls_connection *rconn = NULL;
CURLcode result = CURLE_OK;
size_t n = 0;
size_t plain_bytes_copied = 0;
rustls_result rresult = 0;
ssize_t nread;
bool eof = FALSE;
DEBUGASSERT(backend);
*pnread = 0;
rconn = backend->conn;
while(plain_bytes_copied < plainlen) {
while(*pnread < plainlen) {
if(!backend->data_in_pending) {
if(tls_recv_more(cf, data, err) < 0) {
if(*err != CURLE_AGAIN) {
nread = -1;
if(tls_recv_more(cf, data, &result) < 0) {
if(result != CURLE_AGAIN) {
goto out;
}
result = CURLE_OK;
break;
}
}
rresult = rustls_connection_read(rconn,
(uint8_t *)plainbuf + plain_bytes_copied,
plainlen - plain_bytes_copied,
(uint8_t *)plainbuf + *pnread,
plainlen - *pnread,
&n);
if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
backend->data_in_pending = FALSE;
@ -233,15 +233,13 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
else if(rresult == RUSTLS_RESULT_UNEXPECTED_EOF) {
failf(data, "rustls: peer closed TCP connection "
"without first closing TLS connection");
*err = CURLE_RECV_ERROR;
nread = -1;
result = CURLE_RECV_ERROR;
goto out;
}
else if(rresult != RUSTLS_RESULT_OK) {
/* n always equals 0 in this case, do not need to check it */
rustls_failf(data, rresult, "rustls_connection_read");
*err = CURLE_RECV_ERROR;
nread = -1;
result = CURLE_RECV_ERROR;
goto out;
}
else if(n == 0) {
@ -252,27 +250,18 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
break;
}
else {
plain_bytes_copied += n;
*pnread += n;
}
}
if(plain_bytes_copied) {
*err = CURLE_OK;
nread = (ssize_t)plain_bytes_copied;
}
else if(eof) {
*err = CURLE_OK;
nread = 0;
}
else {
*err = CURLE_AGAIN;
nread = -1;
if(!eof && !*pnread) {
result = CURLE_AGAIN;
}
out:
CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d",
plainlen, nread, *err);
return nread;
CURL_TRC_CF(data, cf, "rustls_recv(len=%zu) -> %d, %zu",
plainlen, result, *pnread);
return result;
}
static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data,
@ -320,9 +309,9 @@ static CURLcode cr_flush_out(struct Curl_cfilter *cf, struct Curl_easy *data,
* In that case, it will not read anything into Rustls' plaintext input buffer.
* It will only drain Rustls' plaintext output buffer into the socket.
*/
static ssize_t
static CURLcode
cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *plainbuf, size_t plainlen, CURLcode *err)
const void *plainbuf, size_t plainlen, size_t *pnwritten)
{
const struct ssl_connect_data *const connssl = cf->ctx;
struct rustls_ssl_backend_data *const backend =
@ -330,10 +319,11 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
struct rustls_connection *rconn = NULL;
size_t plainwritten = 0;
const unsigned char *buf = plainbuf;
CURLcode result = CURLE_OK;
size_t blen = plainlen;
ssize_t nwritten = 0;
DEBUGASSERT(backend);
*pnwritten = 0;
rconn = backend->conn;
DEBUGASSERT(rconn);
@ -344,18 +334,18 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
* if successful, deduct the previous plain bytes from the current
* send. */
if(backend->plain_out_buffered) {
*err = cr_flush_out(cf, data, rconn);
result = cr_flush_out(cf, data, rconn);
CURL_TRC_CF(data, cf, "cf_send: flushing %zu previously added bytes -> %d",
backend->plain_out_buffered, *err);
if(*err)
return -1;
backend->plain_out_buffered, result);
if(result)
return result;
if(blen > backend->plain_out_buffered) {
blen -= backend->plain_out_buffered;
buf += backend->plain_out_buffered;
}
else
blen = 0;
nwritten += (ssize_t)backend->plain_out_buffered;
*pnwritten += (ssize_t)backend->plain_out_buffered;
backend->plain_out_buffered = 0;
}
@ -365,37 +355,35 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
rresult = rustls_connection_write(rconn, buf, blen, &plainwritten);
if(rresult != RUSTLS_RESULT_OK) {
rustls_failf(data, rresult, "rustls_connection_write");
*err = CURLE_WRITE_ERROR;
return -1;
result = CURLE_WRITE_ERROR;
goto out;
}
else if(plainwritten == 0) {
failf(data, "rustls_connection_write: EOF");
*err = CURLE_WRITE_ERROR;
return -1;
result = CURLE_WRITE_ERROR;
goto out;
}
}
*err = cr_flush_out(cf, data, rconn);
if(*err) {
if(CURLE_AGAIN == *err) {
result = cr_flush_out(cf, data, rconn);
if(result) {
if(CURLE_AGAIN == result) {
/* The TLS bytes may have been partially written, but we fail the
* complete send() and remember how much we already added to Rustls. */
CURL_TRC_CF(data, cf, "cf_send: EAGAIN, remember we added %zu plain"
" bytes already to Rustls", blen);
backend->plain_out_buffered = plainwritten;
if(nwritten) {
*err = CURLE_OK;
return (ssize_t)nwritten;
if(*pnwritten) {
result = CURLE_OK;
}
}
return -1;
goto out;
}
else
nwritten += (ssize_t)plainwritten;
*pnwritten += (ssize_t)plainwritten;
CURL_TRC_CF(data, cf, "cf_send(len=%zu) -> %d, %zd",
plainlen, *err, nwritten);
return nwritten;
out:
CURL_TRC_CF(data, cf, "rustls_send(len=%zu) -> %d, %zd",
plainlen, result, *pnwritten);
return result;
}
/* A server certificate verify callback for Rustls that always returns
@ -1184,8 +1172,9 @@ cr_connect(struct Curl_cfilter *cf,
* send its FINISHED message off. We attempt to let it write
* one more time. Oh my.
*/
size_t nwritten;
cr_set_negotiated_alpn(cf, data, rconn);
cr_send(cf, data, NULL, 0, &tmperr);
tmperr = cr_send(cf, data, NULL, 0, &nwritten);
if(tmperr == CURLE_AGAIN) {
connssl->io_need = CURL_SSL_IO_NEED_SEND;
return CURLE_OK;
@ -1258,8 +1247,9 @@ cr_connect(struct Curl_cfilter *cf,
DEBUGASSERT(wants_read || wants_write);
if(wants_write) {
size_t nwritten;
CURL_TRC_CF(data, cf, "rustls_connection wants us to write_tls.");
cr_send(cf, data, NULL, 0, &tmperr);
tmperr = cr_send(cf, data, NULL, 0, &nwritten);
if(tmperr == CURLE_AGAIN) {
CURL_TRC_CF(data, cf, "writing would block");
connssl->io_need = CURL_SSL_IO_NEED_SEND;
@ -1312,8 +1302,7 @@ cr_shutdown(struct Curl_cfilter *cf,
struct rustls_ssl_backend_data *backend =
(struct rustls_ssl_backend_data *)connssl->backend;
CURLcode result = CURLE_OK;
ssize_t nwritten, nread;
size_t i;
size_t i, nread, nwritten;
DEBUGASSERT(backend);
if(!backend->conn || cf->shutdown) {
@ -1332,8 +1321,8 @@ cr_shutdown(struct Curl_cfilter *cf,
}
}
nwritten = cr_send(cf, data, NULL, 0, &result);
if(nwritten < 0) {
result = cr_send(cf, data, NULL, 0, &nwritten);
if(result) {
if(result == CURLE_AGAIN) {
connssl->io_need = CURL_SSL_IO_NEED_SEND;
result = CURLE_OK;
@ -1346,26 +1335,23 @@ cr_shutdown(struct Curl_cfilter *cf,
for(i = 0; i < 10; ++i) {
char buf[1024];
nread = cr_recv(cf, data, buf, (int)sizeof(buf), &result);
if(nread <= 0)
result = cr_recv(cf, data, buf, (int)sizeof(buf), &nread);
if(result)
break;
}
if(nread > 0) {
/* still data coming in? */
if(result == CURLE_AGAIN) {
connssl->io_need = CURL_SSL_IO_NEED_RECV;
result = CURLE_OK;
}
else if(result) {
DEBUGASSERT(result);
CURL_TRC_CF(data, cf, "shutdown, error: %d", result);
}
else if(nread == 0) {
/* We got the close notify alert and are done. */
*done = TRUE;
}
else if(result == CURLE_AGAIN) {
connssl->io_need = CURL_SSL_IO_NEED_RECV;
result = CURLE_OK;
}
else {
DEBUGASSERT(result);
CURL_TRC_CF(data, cf, "shutdown, error: %d", result);
}
out:
cf->shutdown = (result || *done);

View file

@ -1714,22 +1714,22 @@ static CURLcode schannel_connect(struct Curl_cfilter *cf,
return CURLE_OK;
}
static ssize_t
static CURLcode
schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
const void *buf, size_t len, size_t *pnwritten)
{
ssize_t written = -1;
size_t data_len = 0;
unsigned char *ptr = NULL;
struct ssl_connect_data *connssl = cf->ctx;
SecBuffer outbuf[4];
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
CURLcode result = CURLE_OK;
struct schannel_ssl_backend_data *backend =
(struct schannel_ssl_backend_data *)connssl->backend;
DEBUGASSERT(backend);
*pnwritten = 0;
/* check if the maximum stream sizes were queried */
if(backend->stream_sizes.cbMaximumMessage == 0) {
@ -1738,8 +1738,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
SECPKG_ATTR_STREAM_SIZES,
&backend->stream_sizes);
if(sspi_status != SEC_E_OK) {
*err = CURLE_SEND_ERROR;
return -1;
return CURLE_SEND_ERROR;
}
}
@ -1753,8 +1752,7 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
backend->stream_sizes.cbTrailer;
ptr = (unsigned char *) malloc(data_len);
if(!ptr) {
*err = CURLE_OUT_OF_MEMORY;
return -1;
return CURLE_OUT_OF_MEMORY;
}
/* setup output buffers (header, data, trailer, empty) */
@ -1777,7 +1775,6 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
/* check if the message was encrypted */
if(sspi_status == SEC_E_OK) {
written = 0;
/* send the encrypted message including header, data and trailer */
len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
@ -1799,16 +1796,15 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
*/
/* send entire message or fail */
while(len > (size_t)written) {
while(len > *pnwritten) {
size_t this_write = 0;
int what;
timediff_t timeout_ms = Curl_timeleft(data, NULL, FALSE);
if(timeout_ms < 0) {
/* we already got the timeout */
failf(data, "schannel: timed out sending data "
"(bytes sent: %zd)", written);
*err = CURLE_OPERATION_TIMEDOUT;
written = -1;
"(bytes sent: %zu)", *pnwritten);
result = CURLE_OPERATION_TIMEDOUT;
break;
}
else if(!timeout_ms)
@ -1817,53 +1813,49 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
*err = CURLE_SEND_ERROR;
written = -1;
result = CURLE_SEND_ERROR;
break;
}
else if(0 == what) {
failf(data, "schannel: timed out sending data "
"(bytes sent: %zd)", written);
*err = CURLE_OPERATION_TIMEDOUT;
written = -1;
"(bytes sent: %zu)", *pnwritten);
result = CURLE_OPERATION_TIMEDOUT;
break;
}
/* socket is writable */
result = Curl_conn_cf_send(cf->next, data,
ptr + written, len - written,
ptr + *pnwritten, len - *pnwritten,
FALSE, &this_write);
if(result == CURLE_AGAIN)
continue;
else if(result != CURLE_OK) {
*err = result;
written = -1;
break;
}
written += (ssize_t)this_write;
*pnwritten += this_write;
}
}
else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
*err = CURLE_OUT_OF_MEMORY;
result = CURLE_OUT_OF_MEMORY;
}
else{
*err = CURLE_SEND_ERROR;
result = CURLE_SEND_ERROR;
}
Curl_safefree(ptr);
if(len == (size_t)written)
if(len == *pnwritten)
/* Encrypted message including header, data and trailer entirely sent.
The return value is the number of unencrypted bytes that were sent. */
written = outbuf[1].cbBuffer;
*pnwritten = outbuf[1].cbBuffer;
return written;
return result;
}
static ssize_t
static CURLcode
schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
char *buf, size_t len, size_t *pnread)
{
size_t size = 0;
size_t nread = 0;
@ -1879,8 +1871,10 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
struct schannel_ssl_backend_data *backend =
(struct schannel_ssl_backend_data *)connssl->backend;
CURLcode result = CURLE_OK;
DEBUGASSERT(backend);
*pnread = 0;
/****************************************************************************
* Do not return or set backend->recv_unrecoverable_err unless in the
@ -1899,7 +1893,6 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
*/
SCH_DEV(infof(data, "schannel: client wants to read %zu bytes", len));
*err = CURLE_OK;
if(len && len <= backend->decdata_offset) {
SCH_DEV(infof(data,
@ -1907,7 +1900,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
goto cleanup;
}
else if(backend->recv_unrecoverable_err) {
*err = backend->recv_unrecoverable_err;
result = backend->recv_unrecoverable_err;
infof(data, "schannel: an unrecoverable error occurred in a prior call");
goto cleanup;
}
@ -1933,7 +1926,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
reallocated_buffer = realloc(backend->encdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
result = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
}
@ -1950,17 +1943,17 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
backend->encdata_offset, backend->encdata_length));
/* read encrypted data from socket */
*err = Curl_conn_cf_recv(cf->next, data,
result = Curl_conn_cf_recv(cf->next, data,
(char *)(backend->encdata_buffer +
backend->encdata_offset),
size, &nread);
if(*err) {
if(*err == CURLE_AGAIN)
if(result) {
if(result == CURLE_AGAIN)
SCH_DEV(infof(data, "schannel: recv returned CURLE_AGAIN"));
else if(*err == CURLE_RECV_ERROR)
else if(result == CURLE_RECV_ERROR)
infof(data, "schannel: recv returned CURLE_RECV_ERROR");
else
infof(data, "schannel: recv returned error %d", *err);
infof(data, "schannel: recv returned error %d", result);
}
else if(nread == 0) {
backend->recv_connection_closed = TRUE;
@ -2019,7 +2012,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
reallocated_buffer = realloc(backend->decdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
result = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
}
@ -2070,7 +2063,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
/* check if server wants to renegotiate the connection context */
if(sspi_status == SEC_I_RENEGOTIATE) {
infof(data, "schannel: remote party requests renegotiation");
if(*err && *err != CURLE_AGAIN) {
if(result && result != CURLE_AGAIN) {
infof(data, "schannel: cannot renegotiate, an error is pending");
goto cleanup;
}
@ -2081,9 +2074,9 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
connssl->connecting_state = ssl_connect_2;
connssl->io_need = CURL_SSL_IO_NEED_SEND;
backend->recv_renegotiating = TRUE;
*err = schannel_connect(cf, data, &done);
result = schannel_connect(cf, data, &done);
backend->recv_renegotiating = FALSE;
if(*err) {
if(result) {
infof(data, "schannel: renegotiation failed");
goto cleanup;
}
@ -2102,8 +2095,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
/* We received the close notify just fine, any error we got
* from the lower filters afterwards (e.g. the socket), is not
* an error on the TLS data stream. That one ended here. */
if(*err == CURLE_RECV_ERROR)
*err = CURLE_OK;
if(result == CURLE_RECV_ERROR)
result = CURLE_OK;
infof(data,
"schannel: server close notification received (close_notify)");
goto cleanup;
@ -2111,8 +2104,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
}
else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
backend->encdata_is_incomplete = TRUE;
if(!*err)
*err = CURLE_AGAIN;
if(!result)
result = CURLE_AGAIN;
SCH_DEV(infof(data, "schannel: failed to decrypt data, need more data"));
goto cleanup;
}
@ -2122,7 +2115,7 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
failf(data, "schannel: failed to read data from server: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
#endif
*err = CURLE_RECV_ERROR;
result = CURLE_RECV_ERROR;
goto cleanup;
}
}
@ -2145,13 +2138,13 @@ cleanup:
*/
if(len && !backend->decdata_offset && backend->recv_connection_closed &&
!backend->recv_sspi_close_notify) {
*err = CURLE_RECV_ERROR;
result = CURLE_RECV_ERROR;
failf(data, "schannel: server closed abruptly (missing close_notify)");
}
/* Any error other than CURLE_AGAIN is an unrecoverable error. */
if(*err && *err != CURLE_AGAIN)
backend->recv_unrecoverable_err = *err;
if(result && result != CURLE_AGAIN)
backend->recv_unrecoverable_err = result;
size = len < backend->decdata_offset ? len : backend->decdata_offset;
if(size) {
@ -2163,21 +2156,21 @@ cleanup:
SCH_DEV(infof(data,
"schannel: decrypted data buffer: offset %zu length %zu",
backend->decdata_offset, backend->decdata_length));
*err = CURLE_OK;
return (ssize_t)size;
*pnread = size;
return CURLE_OK;
}
if(!*err && !backend->recv_connection_closed)
*err = CURLE_AGAIN;
if(!result && !backend->recv_connection_closed)
result = CURLE_AGAIN;
/* it is debatable what to return when !len. We could return whatever error
we got from decryption but instead we override here so the return is
consistent.
*/
if(!len)
*err = CURLE_OK;
return CURLE_OK;
return *err ? -1 : 0;
return result;
}
static bool schannel_data_pending(struct Curl_cfilter *cf,
@ -2319,23 +2312,23 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf,
if(backend->cred && backend->ctxt &&
!backend->recv_sspi_close_notify && !backend->recv_connection_closed) {
char buffer[1024];
ssize_t nread;
size_t nread;
nread = schannel_recv(cf, data, buffer, sizeof(buffer), &result);
if(nread > 0) {
/* still data coming in? */
result = schannel_recv(cf, data, buffer, sizeof(buffer), &nread);
if(result == CURLE_AGAIN) {
connssl->io_need = CURL_SSL_IO_NEED_RECV;
}
else if(result) {
CURL_TRC_CF(data, cf, "SSL shutdown, error %d", result);
result = CURLE_RECV_ERROR;
}
else if(nread == 0) {
/* We got the close notify alert and are done. */
backend->recv_connection_closed = TRUE;
*done = TRUE;
}
else if(nread < 0 && result == CURLE_AGAIN) {
connssl->io_need = CURL_SSL_IO_NEED_RECV;
}
else {
CURL_TRC_CF(data, cf, "SSL shutdown, error %d", result);
result = CURLE_RECV_ERROR;
/* still data coming in? */
}
}

View file

@ -917,23 +917,23 @@ static void multissl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
Curl_ssl->close(cf, data);
}
static ssize_t multissl_recv_plain(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf, size_t len, CURLcode *code)
static CURLcode multissl_recv_plain(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf, size_t len, size_t *pnread)
{
if(multissl_setup(NULL))
return CURLE_FAILED_INIT;
return Curl_ssl->recv_plain(cf, data, buf, len, code);
return Curl_ssl->recv_plain(cf, data, buf, len, pnread);
}
static ssize_t multissl_send_plain(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *mem, size_t len,
CURLcode *code)
static CURLcode multissl_send_plain(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *mem, size_t len,
size_t *pnwritten)
{
if(multissl_setup(NULL))
return CURLE_FAILED_INIT;
return Curl_ssl->send_plain(cf, data, mem, len, code);
return Curl_ssl->send_plain(cf, data, mem, len, pnwritten);
}
static const struct Curl_ssl Curl_ssl_multi = {
@ -1474,10 +1474,10 @@ static CURLcode ssl_cf_send(struct Curl_cfilter *cf,
/* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */
if(blen > 0) {
ssize_t nwritten;
nwritten = connssl->ssl_impl->send_plain(cf, data, buf, blen, &result);
if(nwritten > 0)
*pnwritten += (size_t)nwritten;
size_t nwritten;
result = connssl->ssl_impl->send_plain(cf, data, buf, blen, &nwritten);
if(!result)
*pnwritten += nwritten;
}
out:
@ -1492,7 +1492,6 @@ static CURLcode ssl_cf_recv(struct Curl_cfilter *cf,
struct ssl_connect_data *connssl = cf->ctx;
struct cf_call_data save;
CURLcode result = CURLE_OK;
ssize_t nread;
CF_DATA_SAVE(save, cf, data);
*pnread = 0;
@ -1508,19 +1507,9 @@ static CURLcode ssl_cf_recv(struct Curl_cfilter *cf,
DEBUGASSERT(connssl->state == ssl_connection_complete);
}
nread = connssl->ssl_impl->recv_plain(cf, data, buf, len, &result);
if(nread > 0) {
DEBUGASSERT((size_t)nread <= len);
*pnread = (size_t)nread;
}
else if(nread == 0) {
/* eof */
result = CURLE_OK;
}
result = connssl->ssl_impl->recv_plain(cf, data, buf, len, pnread);
out:
CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %d, %zd", len,
result, *pnread);
CF_DATA_RESTORE(cf, save);
return result;
}

View file

@ -178,10 +178,10 @@ struct Curl_ssl {
CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen,
unsigned char *sha256sum, size_t sha256sumlen);
ssize_t (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *code);
ssize_t (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len, CURLcode *code);
CURLcode (*recv_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, size_t *pnread);
CURLcode (*send_plain)(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *mem, size_t len, size_t *pnwritten);
CURLcode (*get_channel_binding)(struct Curl_easy *data, int sockindex,
struct dynbuf *binding);

View file

@ -1789,49 +1789,48 @@ static CURLcode wssl_handshake(struct Curl_cfilter *cf,
}
}
static ssize_t wssl_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf, size_t blen,
CURLcode *curlcode)
static CURLcode wssl_send(struct Curl_cfilter *cf,
struct Curl_easy *data,
const void *buf, size_t blen,
size_t *pnwritten)
{
struct ssl_connect_data *connssl = cf->ctx;
struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend;
size_t total_written = 0;
ssize_t nwritten = -1;
DEBUGASSERT(wssl);
CURLcode result = CURLE_OK;
int nwritten;
DEBUGASSERT(wssl);
*pnwritten = 0;
wolfSSL_ERR_clear_error();
if(blen) {
int memlen = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
int rc;
rc = wolfSSL_write(wssl->ssl, buf, memlen);
if(rc <= 0) {
int err = wolfSSL_get_error(wssl->ssl, rc);
nwritten = wolfSSL_write(wssl->ssl, buf, memlen);
if(nwritten > 0)
*pnwritten += (size_t)nwritten;
else {
int err = wolfSSL_get_error(wssl->ssl, nwritten);
switch(err) {
case WOLFSSL_ERROR_WANT_READ:
case WOLFSSL_ERROR_WANT_WRITE:
/* there is data pending, re-invoke wolfSSL_write() */
if(total_written) {
*curlcode = CURLE_OK;
nwritten = total_written;
if(*pnwritten) {
result = CURLE_OK;
goto out;
}
*curlcode = CURLE_AGAIN;
nwritten = -1;
result = CURLE_AGAIN;
goto out;
default:
if(wssl->io_result == CURLE_AGAIN) {
if(total_written) {
*curlcode = CURLE_OK;
nwritten = total_written;
if(*pnwritten) {
result = CURLE_OK;
goto out;
}
*curlcode = CURLE_AGAIN;
nwritten = -1;
result = CURLE_AGAIN;
goto out;
}
{
@ -1841,21 +1840,16 @@ static ssize_t wssl_send(struct Curl_cfilter *cf,
sizeof(error_buffer)),
SOCKERRNO);
}
*curlcode = CURLE_SEND_ERROR;
nwritten = -1;
result = CURLE_SEND_ERROR;
goto out;
}
}
else
total_written += rc;
}
*curlcode = CURLE_OK;
nwritten = total_written;
out:
CURL_TRC_CF(data, cf, "wssl_send(len=%zu) -> %" FMT_OFF_T ", %d",
blen, nwritten, *curlcode);
return nwritten;
CURL_TRC_CF(data, cf, "wssl_send(len=%zu) -> %d, %zu",
blen, result, *pnwritten);
return result;
}
static CURLcode wssl_shutdown(struct Curl_cfilter *cf,
@ -1982,10 +1976,10 @@ static void wssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
}
}
static ssize_t wssl_recv(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf, size_t blen,
CURLcode *curlcode)
static CURLcode wssl_recv(struct Curl_cfilter *cf,
struct Curl_easy *data,
char *buf, size_t blen,
size_t *pnread)
{
struct ssl_connect_data *connssl = cf->ctx;
struct wssl_ctx *wssl = (struct wssl_ctx *)connssl->backend;
@ -1994,36 +1988,34 @@ static ssize_t wssl_recv(struct Curl_cfilter *cf,
DEBUGASSERT(wssl);
*pnread = 0;
wolfSSL_ERR_clear_error();
*curlcode = CURLE_OK;
nread = wolfSSL_read(wssl->ssl, buf, buffsize);
if(nread <= 0) {
if(nread > 0)
*pnread = (size_t)nread;
else {
int err = wolfSSL_get_error(wssl->ssl, nread);
switch(err) {
case WOLFSSL_ERROR_ZERO_RETURN: /* no more data */
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen);
*curlcode = CURLE_OK;
return 0;
return CURLE_OK;
case WOLFSSL_ERROR_NONE:
case WOLFSSL_ERROR_WANT_READ:
case WOLFSSL_ERROR_WANT_WRITE:
if(!wssl->io_result && connssl->peer_closed) {
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen);
*curlcode = CURLE_OK;
return 0;
return CURLE_OK;
}
/* there is data pending, re-invoke wolfSSL_read() */
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> AGAIN", blen);
*curlcode = CURLE_AGAIN;
return -1;
return CURLE_AGAIN;
default:
if(wssl->io_result == CURLE_AGAIN) {
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> AGAIN", blen);
*curlcode = CURLE_AGAIN;
return -1;
return CURLE_AGAIN;
}
else if(!wssl->io_result && connssl->peer_closed) {
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> CLOSED", blen);
@ -2036,13 +2028,12 @@ static ssize_t wssl_recv(struct Curl_cfilter *cf,
sizeof(error_buffer)),
SOCKERRNO);
}
*curlcode = CURLE_RECV_ERROR;
return -1;
return CURLE_RECV_ERROR;
}
}
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> %d", blen, nread);
return nread;
CURL_TRC_CF(data, cf, "wssl_recv(len=%zu) -> 0, %zu", blen, *pnread);
return CURLE_OK;
}
size_t Curl_wssl_version(char *buffer, size_t size)