mirror of https://github.com/wolfSSL/wolfssl.git
BIO/wolfio: refactor TranslateReturnCode(), wolfSSL_LastError(), and TranslateIoError() into complete+consistent wolfSSL_LastError() and TranslateIoReturnCode(), handling all special cases correctly, and correctly returning WOLFSSL_CBIO_ERR_WANT_WRITE and WOLFSSL_CBIO_ERR_TIMEOUT. use TranslateIoReturnCode() directly in wolfIO_Recv(), wolfIO_Send(), wolfIO_RecvFrom(), wolfIO_SendTo(), and remove now-superfluous TranslateIoError() calls from EmbedReceive(), EmbedSend(), EmbedReceiveFrom(), EmbedSendTo(), EmbedReceiveFromMcast().
parent
5298039d09
commit
9023aeef75
16
src/bio.c
16
src/bio.c
|
@ -353,8 +353,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
|
|||
* (cannot be used with WOLFSSL_USER_IO) */
|
||||
bio->flags &= ~WOLFSSL_BIO_FLAG_RETRY;
|
||||
ret = wolfIO_Recv(bio->num, (char*)buf, len, 0);
|
||||
if (ret == WC_NO_ERR_TRACE(SOCKET_NODATA)) {
|
||||
if (ret == WOLFSSL_CBIO_ERR_WANT_READ) {
|
||||
bio->flags |= WOLFSSL_BIO_FLAG_RETRY;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
#else
|
||||
|
@ -374,8 +376,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
|
|||
wolfSSL_BIO_ADDR_clear(&bio->peer_addr);
|
||||
ret = wolfIO_RecvFrom(bio->num, &bio->peer_addr, (char*)buf, len, 0);
|
||||
}
|
||||
if (ret == WC_NO_ERR_TRACE(SOCKET_NODATA)) {
|
||||
if (ret == WOLFSSL_CBIO_ERR_WANT_READ) {
|
||||
bio->flags |= WOLFSSL_BIO_FLAG_RETRY;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
#else
|
||||
|
@ -772,8 +776,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
|
|||
* (cannot be used with WOLFSSL_USER_IO) */
|
||||
bio->flags &= ~WOLFSSL_BIO_FLAG_RETRY;
|
||||
ret = wolfIO_Send(bio->num, (char*)data, len, 0);
|
||||
if (ret == WC_NO_ERR_TRACE(SOCKET_NODATA)) {
|
||||
if (ret == WOLFSSL_CBIO_ERR_WANT_WRITE) {
|
||||
bio->flags |= WOLFSSL_BIO_FLAG_RETRY;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
#else
|
||||
|
@ -793,8 +799,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
|
|||
ret = SOCKET_ERROR_E;
|
||||
else
|
||||
ret = wolfIO_SendTo(bio->num, &bio->peer_addr, (char*)data, len, 0);
|
||||
if (ret == WC_NO_ERR_TRACE(SOCKET_NODATA)) {
|
||||
if (ret == WOLFSSL_CBIO_ERR_WANT_WRITE) {
|
||||
bio->flags |= WOLFSSL_BIO_FLAG_RETRY;
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
#else
|
||||
|
|
186
src/wolfio.c
186
src/wolfio.c
|
@ -136,70 +136,65 @@ Possible IO enable options:
|
|||
|
||||
#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT)
|
||||
|
||||
/* Translates return codes returned from
|
||||
* send() and recv() if need be.
|
||||
*/
|
||||
static WC_INLINE int TranslateReturnCode(int old, int sd)
|
||||
static WC_INLINE int wolfSSL_LastError(int err, SOCKET_T sd)
|
||||
{
|
||||
(void)sd;
|
||||
|
||||
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
||||
if (old == 0) {
|
||||
errno = SOCKET_EWOULDBLOCK;
|
||||
return -1; /* convert to BSD style wouldblock as error */
|
||||
}
|
||||
|
||||
if (old < 0) {
|
||||
errno = RTCS_geterror(sd);
|
||||
if (errno == RTCSERR_TCP_CONN_CLOSING)
|
||||
return 0; /* convert to BSD style closing */
|
||||
if (errno == RTCSERR_TCP_CONN_RLSD)
|
||||
errno = SOCKET_ECONNRESET;
|
||||
if (errno == RTCSERR_TCP_TIMED_OUT)
|
||||
errno = SOCKET_EAGAIN;
|
||||
}
|
||||
#elif defined(WOLFSSL_EMNET)
|
||||
if (old < 0) { /* SOCKET_ERROR */
|
||||
/* Get the real socket error */
|
||||
IP_SOCK_getsockopt(sd, SOL_SOCKET, SO_ERROR, &old, (int)sizeof(old));
|
||||
}
|
||||
#endif
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static WC_INLINE int wolfSSL_LastError(int err)
|
||||
{
|
||||
(void)err; /* Suppress unused arg */
|
||||
if (err > 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_API
|
||||
return WSAGetLastError();
|
||||
#elif defined(EBSNET)
|
||||
return xn_getlasterror();
|
||||
#elif defined(WOLFSSL_LINUXKM) || defined(WOLFSSL_EMNET)
|
||||
return -err; /* Return provided error value */
|
||||
return -err; /* Return provided error value with corrected sign. */
|
||||
#elif defined(FUSION_RTOS)
|
||||
#include <fclerrno.h>
|
||||
return FCL_GET_ERRNO;
|
||||
#elif defined(NUCLEUS_PLUS_2_3)
|
||||
return Nucleus_Net_Errno;
|
||||
#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
||||
if ((err == 0) || (err == -SOCKET_EWOULDBLOCK)) {
|
||||
return SOCKET_EWOULDBLOCK; /* convert to BSD style wouldblock */
|
||||
} else {
|
||||
err = RTCS_geterror(sd);
|
||||
if ((err == RTCSERR_TCP_CONN_CLOSING) ||
|
||||
(err == RTCSERR_TCP_CONN_RLSD))
|
||||
{
|
||||
err = SOCKET_ECONNRESET;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#elif defined(WOLFSSL_EMNET)
|
||||
/* Get the real socket error */
|
||||
IP_SOCK_getsockopt(sd, SOL_SOCKET, SO_ERROR, &err, (int)sizeof(old));
|
||||
return err;
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int TranslateIoError(int err)
|
||||
/* Translates return codes returned from
|
||||
* send(), recv(), and other network I/O calls.
|
||||
*/
|
||||
static int TranslateIoReturnCode(int err, SOCKET_T sd, int direction)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
size_t errstr_offset;
|
||||
char errstr[WOLFSSL_STRERROR_BUFFER_SIZE];
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
||||
if (err > 0)
|
||||
return err;
|
||||
#else
|
||||
if (err >= 0)
|
||||
return err;
|
||||
#endif
|
||||
|
||||
err = wolfSSL_LastError(err, sd);
|
||||
|
||||
err = wolfSSL_LastError(err);
|
||||
#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN
|
||||
if ((err == SOCKET_EWOULDBLOCK) || (err == SOCKET_EAGAIN))
|
||||
#else
|
||||
|
@ -207,8 +202,26 @@ static int TranslateIoError(int err)
|
|||
#endif
|
||||
{
|
||||
WOLFSSL_MSG("\tWould block");
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
if (direction == SOCKET_SENDING)
|
||||
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
else if (direction == SOCKET_RECEIVING)
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
else
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
}
|
||||
|
||||
#ifdef SOCKET_ETIMEDOUT
|
||||
else if (err == SOCKET_ETIMEDOUT) {
|
||||
WOLFSSL_MSG("\tTimed out");
|
||||
if (direction == SOCKET_SENDING)
|
||||
return WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
else if (direction == SOCKET_RECEIVING)
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
else
|
||||
return WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (err == SOCKET_ECONNRESET) {
|
||||
WOLFSSL_MSG("\tConnection reset");
|
||||
return WOLFSSL_CBIO_ERR_CONN_RST;
|
||||
|
@ -288,7 +301,7 @@ int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
|||
return WOLFSSL_CBIO_ERR_CONN_CLOSE;
|
||||
}
|
||||
#ifdef USE_WOLFSSL_IO
|
||||
recvd = TranslateIoError(recvd);
|
||||
recvd = TranslateIoReturnCode(recvd, ssl->biord->num, SOCKET_RECEIVING);
|
||||
#endif
|
||||
return recvd;
|
||||
}
|
||||
|
@ -333,7 +346,7 @@ int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
|||
if (sent <= 0) {
|
||||
if (ssl->biowr->type == WOLFSSL_BIO_SOCKET) {
|
||||
#ifdef USE_WOLFSSL_IO
|
||||
sent = TranslateIoError(sent);
|
||||
sent = TranslateIoReturnCode(sent, ssl->biowr->num, SOCKET_SENDING);
|
||||
#endif
|
||||
return sent;
|
||||
}
|
||||
|
@ -377,7 +390,6 @@ int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
recvd = wolfIO_Recv(sd, buf, sz, ssl->rflags);
|
||||
if (recvd < 0) {
|
||||
WOLFSSL_MSG("Embed Receive error");
|
||||
return TranslateIoError(recvd);
|
||||
}
|
||||
else if (recvd == 0) {
|
||||
WOLFSSL_MSG("Embed receive connection closed");
|
||||
|
@ -407,7 +419,6 @@ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
|||
sent = wolfIO_Send(sd, buf, sz, ssl->wflags);
|
||||
if (sent < 0) {
|
||||
WOLFSSL_MSG("Embed Send error");
|
||||
return TranslateIoError(sent);
|
||||
}
|
||||
|
||||
return sent;
|
||||
|
@ -746,11 +757,10 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
peerSz = (XSOCKLENT)dtlsCtx->peer.bufSz;
|
||||
}
|
||||
|
||||
recvd = TranslateReturnCode(recvd, sd);
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
|
||||
if (recvd < 0) {
|
||||
WOLFSSL_MSG("Embed Receive From error");
|
||||
recvd = TranslateIoError(recvd);
|
||||
if (recvd == WOLFSSL_CBIO_ERR_WANT_READ &&
|
||||
!wolfSSL_dtls_get_using_nonblock(ssl)) {
|
||||
recvd = WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
|
@ -835,11 +845,10 @@ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
|||
sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, ssl->wflags,
|
||||
(const SOCKADDR*)peer, peerSz);
|
||||
|
||||
sent = TranslateReturnCode(sent, sd);
|
||||
sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
|
||||
|
||||
if (sent < 0) {
|
||||
WOLFSSL_MSG("Embed Send To error");
|
||||
return TranslateIoError(sent);
|
||||
}
|
||||
|
||||
return sent;
|
||||
|
@ -861,16 +870,14 @@ int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, ssl->rflags, NULL, NULL);
|
||||
|
||||
recvd = TranslateReturnCode(recvd, sd);
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
|
||||
if (recvd < 0) {
|
||||
WOLFSSL_MSG("Embed Receive From error");
|
||||
recvd = TranslateIoError(recvd);
|
||||
if (recvd == WOLFSSL_CBIO_ERR_WANT_READ &&
|
||||
!wolfSSL_dtls_get_using_nonblock(ssl)) {
|
||||
recvd = WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
}
|
||||
return recvd;
|
||||
}
|
||||
|
||||
return recvd;
|
||||
|
@ -1098,22 +1105,7 @@ int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags)
|
|||
int recvd;
|
||||
|
||||
recvd = (int)RECV_FUNCTION(sd, buf, (size_t)sz, rdFlags);
|
||||
recvd = TranslateReturnCode(recvd, (int)sd);
|
||||
|
||||
if (recvd < 0) {
|
||||
int last_err = wolfSSL_LastError(recvd);
|
||||
if ((last_err == SOCKET_EWOULDBLOCK)
|
||||
#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN
|
||||
|| (last_err == SOCKET_EAGAIN)
|
||||
#endif
|
||||
#ifdef SOCKET_ETIMEDOUT
|
||||
|| (last_err == SOCKET_ETIMEDOUT)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return SOCKET_NODATA;
|
||||
}
|
||||
}
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
|
||||
return recvd;
|
||||
}
|
||||
|
@ -1123,22 +1115,7 @@ int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
|
|||
int sent;
|
||||
|
||||
sent = (int)SEND_FUNCTION(sd, buf, (size_t)sz, wrFlags);
|
||||
sent = TranslateReturnCode(sent, (int)sd);
|
||||
|
||||
if (sent < 0) {
|
||||
int last_err = wolfSSL_LastError(sent);
|
||||
if ((last_err == SOCKET_EWOULDBLOCK)
|
||||
#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN
|
||||
|| (last_err == SOCKET_EAGAIN)
|
||||
#endif
|
||||
#ifdef SOCKET_ETIMEDOUT
|
||||
|| (last_err == SOCKET_ETIMEDOUT)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return SOCKET_NODATA;
|
||||
}
|
||||
}
|
||||
sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
@ -1151,24 +1128,9 @@ int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int
|
|||
socklen_t addr_len = (socklen_t)sizeof(*addr);
|
||||
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, rdFlags,
|
||||
addr ? &addr->sa : NULL,
|
||||
addr ? &addr_len : 0);
|
||||
recvd = TranslateReturnCode(recvd, (int)sd);
|
||||
|
||||
if (recvd < 0) {
|
||||
int last_err = wolfSSL_LastError(recvd);
|
||||
if ((last_err == SOCKET_EWOULDBLOCK)
|
||||
#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN
|
||||
|| (last_err == SOCKET_EAGAIN)
|
||||
#endif
|
||||
#ifdef SOCKET_ETIMEDOUT
|
||||
|| (last_err == SOCKET_ETIMEDOUT)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return SOCKET_NODATA;
|
||||
}
|
||||
}
|
||||
addr ? &addr->sa : NULL,
|
||||
addr ? &addr_len : 0);
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
|
||||
return recvd;
|
||||
}
|
||||
|
@ -1176,26 +1138,12 @@ int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int
|
|||
int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wrFlags)
|
||||
{
|
||||
int sent;
|
||||
socklen_t addr_len = addr ? wolfSSL_BIO_ADDR_size(addr) : 0;
|
||||
|
||||
sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, wrFlags,
|
||||
addr ? &addr->sa : NULL,
|
||||
addr ? wolfSSL_BIO_ADDR_size(addr) : 0);
|
||||
sent = TranslateReturnCode(sent, (int)sd);
|
||||
|
||||
if (sent < 0) {
|
||||
int last_err = wolfSSL_LastError(sent);
|
||||
if ((last_err == SOCKET_EWOULDBLOCK)
|
||||
#if SOCKET_EWOULDBLOCK != SOCKET_EAGAIN
|
||||
|| (last_err == SOCKET_EAGAIN)
|
||||
#endif
|
||||
#ifdef SOCKET_ETIMEDOUT
|
||||
|| (last_err == SOCKET_ETIMEDOUT)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return SOCKET_NODATA;
|
||||
}
|
||||
}
|
||||
addr ? &addr->sa : NULL,
|
||||
addr_len);
|
||||
sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
@ -1513,7 +1461,7 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec)
|
|||
#ifdef HAVE_IO_TIMEOUT
|
||||
if ((ret != 0) && (to_sec > 0)) {
|
||||
#ifdef USE_WINDOWS_API
|
||||
if ((ret == SOCKET_ERROR) && (wolfSSL_LastError(ret) == WSAEWOULDBLOCK))
|
||||
if ((ret == SOCKET_ERROR) && (wolfSSL_LastError(ret, *sockfd) == SOCKET_EWOULDBLOCK))
|
||||
#else
|
||||
if (errno == EINPROGRESS)
|
||||
#endif
|
||||
|
@ -1824,9 +1772,7 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList,
|
|||
start[len] = 0;
|
||||
}
|
||||
else {
|
||||
result = TranslateReturnCode(result, sfd);
|
||||
result = wolfSSL_LastError(result);
|
||||
if (result == SOCKET_EWOULDBLOCK || result == SOCKET_EAGAIN) {
|
||||
if (result == WOLFSSL_CBIO_ERR_WANT_READ) {
|
||||
return OCSP_WANT_READ;
|
||||
}
|
||||
|
||||
|
|
|
@ -201,6 +201,9 @@
|
|||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#define SOCKET_RECEIVING 1
|
||||
#define SOCKET_SENDING 2
|
||||
|
||||
#ifdef USE_WINDOWS_API
|
||||
/* no epipe yet */
|
||||
#ifndef WSAEPIPE
|
||||
|
@ -228,6 +231,7 @@
|
|||
/* RTCS old I/O doesn't have an EWOULDBLOCK */
|
||||
#define SOCKET_EWOULDBLOCK EAGAIN
|
||||
#define SOCKET_EAGAIN EAGAIN
|
||||
#define SOCKET_ETIMEDOUT RTCSERR_TCP_TIMED_OUT
|
||||
#define SOCKET_ECONNRESET RTCSERR_TCP_CONN_RESET
|
||||
#define SOCKET_EINTR EINTR
|
||||
#define SOCKET_EPIPE EPIPE
|
||||
|
@ -236,6 +240,7 @@
|
|||
#else
|
||||
#define SOCKET_EWOULDBLOCK NIO_EWOULDBLOCK
|
||||
#define SOCKET_EAGAIN NIO_EAGAIN
|
||||
#define SOCKET_ETIMEDOUT NIO_ETIMEDOUT
|
||||
#define SOCKET_ECONNRESET NIO_ECONNRESET
|
||||
#define SOCKET_EINTR NIO_EINTR
|
||||
#define SOCKET_EPIPE NIO_EPIPE
|
||||
|
@ -253,6 +258,7 @@
|
|||
#elif defined(WOLFSSL_PICOTCP)
|
||||
#define SOCKET_EWOULDBLOCK PICO_ERR_EAGAIN
|
||||
#define SOCKET_EAGAIN PICO_ERR_EAGAIN
|
||||
#define SOCKET_ETIMEDOUT PICO_ERR_ETIMEDOUT
|
||||
#define SOCKET_ECONNRESET PICO_ERR_ECONNRESET
|
||||
#define SOCKET_EINTR PICO_ERR_EINTR
|
||||
#define SOCKET_EPIPE PICO_ERR_EIO
|
||||
|
@ -261,6 +267,7 @@
|
|||
#elif defined(FREERTOS_TCP)
|
||||
#define SOCKET_EWOULDBLOCK FREERTOS_EWOULDBLOCK
|
||||
#define SOCKET_EAGAIN FREERTOS_EWOULDBLOCK
|
||||
#define SOCKET_ETIMEDOUT (-pdFREERTOS_ERRNO_ETIMEDOUT)
|
||||
#define SOCKET_ECONNRESET FREERTOS_SOCKET_ERROR
|
||||
#define SOCKET_EINTR FREERTOS_SOCKET_ERROR
|
||||
#define SOCKET_EPIPE FREERTOS_SOCKET_ERROR
|
||||
|
|
Loading…
Reference in New Issue