Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion doc/dox_comments/header_files/wolfio.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,9 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags);
\param nxsocket a pointer to type NX_TCP_SOCKET that is set to the
nxTcpSocket member of the nxCtx structure.
\param waitoption a ULONG type that is set to the nxWait member of
the nxCtx structure.
the nxCtx structure. With NX_NO_WAIT, or any wait option that can expire,
the callbacks report WANT_READ/WANT_WRITE instead of a fatal error, so
the wolfSSL call can be retried.

_Example_
\code
Expand Down Expand Up @@ -496,6 +498,10 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket,
\param nxdip the destination NXD_ADDRESS (passed by value; IPv4 or IPv6).
\param nxport the destination UDP port number.
\param waitoption a ULONG NetX wait option (e.g. NX_WAIT_FOREVER or ticks).
With NX_NO_WAIT, or any wait option that can expire, NetX_SendTo reports
WANT_WRITE instead of a fatal error. A receive that expires reports
WANT_READ when the session is set non blocking, and a timeout otherwise so
that DTLS can retransmit.

_Example_
\code
Expand Down
56 changes: 48 additions & 8 deletions src/wolfio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2807,6 +2807,46 @@ void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb)

#ifdef HAVE_NETX

/* Map a failing NetX status onto a wolfSSL CBIO error code.
* Transient conditions must not be reported as fatal, otherwise a non
* blocking (or short wait option) setup cannot retry the operation. */
static int NetX_TranslateReturnCode(UINT status, int direction)
Comment thread
embhorn marked this conversation as resolved.
{
int ret;

switch (status) {
/* Receive queue empty, packet pool exhausted, peer receive window
* full or transmit queue at max depth. All clear on their own. */
case NX_NO_PACKET:
case NX_WINDOW_OVERFLOW:
case NX_TX_QUEUE_DEPTH:
WOLFSSL_MSG("\tWould block");
ret = (direction == SOCKET_SENDING) ? WOLFSSL_CBIO_ERR_WANT_WRITE
: WOLFSSL_CBIO_ERR_WANT_READ;
Comment thread
embhorn marked this conversation as resolved.
break;

/* A suspended wait was aborted, treated like an interrupted call. */
case NX_WAIT_ABORTED:
WOLFSSL_MSG("\tSocket interrupted");
ret = WOLFSSL_CBIO_ERR_ISR;
break;

/* NetX has no separate reset status, so a peer reset also lands
* here and is reported as a close. */
case NX_NOT_CONNECTED:
WOLFSSL_MSG("\tConnection closed");
ret = WOLFSSL_CBIO_ERR_CONN_CLOSE;
break;

default:
WOLFSSL_MSG_EX("\tGeneral error: %u", (unsigned int)status);
ret = WOLFSSL_CBIO_ERR_GENERAL;
break;
}

return ret;
}

/* The NetX receive callback for TLS
* return : bytes read, or error
*/
Expand All @@ -2830,7 +2870,7 @@ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx)
nxCtx->nxWait);
if (status != NX_SUCCESS) {
WOLFSSL_MSG("NetX Recv receive error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_RECEIVING);
}
}

Expand Down Expand Up @@ -2885,21 +2925,21 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx)
nxCtx->nxWait);
if (status != NX_SUCCESS) {
WOLFSSL_MSG("NetX Send packet alloc error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_SENDING);
}

status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
if (status != NX_SUCCESS) {
nx_packet_release(packet);
WOLFSSL_MSG("NetX Send data append error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_SENDING);
}

status = nx_tcp_socket_send(nxCtx->nxTcpSocket, packet, nxCtx->nxWait);
if (status != NX_SUCCESS) {
nx_packet_release(packet);
WOLFSSL_MSG("NetX Send socket send error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_SENDING);
}

return sz;
Expand Down Expand Up @@ -3019,7 +3059,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
: WOLFSSL_CBIO_ERR_TIMEOUT;
}
WOLFSSL_MSG("NetX Recv receive error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_RECEIVING);
Comment thread
embhorn marked this conversation as resolved.
}

status = nxd_udp_source_extract(nxCtx->nxPacket, &srcIp, &srcPort);
Expand Down Expand Up @@ -3137,14 +3177,14 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
nxCtx->nxWait);
if (status != NX_SUCCESS) {
WOLFSSL_MSG("NetX Send packet alloc error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_SENDING);
}

status = nx_packet_data_append(packet, buf, sz, pool, nxCtx->nxWait);
if (status != NX_SUCCESS) {
nx_packet_release(packet);
WOLFSSL_MSG("NetX Send data append error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_SENDING);
}

if (nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V4) {
Expand All @@ -3159,7 +3199,7 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
if (status != NX_SUCCESS) {
nx_packet_release(packet);
WOLFSSL_MSG("NetX Send socket send error");
return WOLFSSL_CBIO_ERR_GENERAL;
return NetX_TranslateReturnCode(status, SOCKET_SENDING);
}

return sz;
Expand Down
10 changes: 7 additions & 3 deletions wolfssl/wolfio.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,14 @@
#define SOCKET_ECONNREFUSED SOCKET_ERROR
#define SOCKET_ECONNABORTED SOCKET_ERROR
#elif defined(HAVE_NETX)
#define SOCKET_EWOULDBLOCK NX_NOT_CONNECTED
#define SOCKET_EAGAIN NX_NOT_CONNECTED
/* NetX has no errno, these map onto the closest nx_api.h status codes.
* A send can also block as NX_WINDOW_OVERFLOW or NX_TX_QUEUE_DEPTH, so
* use the WANT_READ/WANT_WRITE the callbacks return rather than testing
* a NetX status against these. */
#define SOCKET_EWOULDBLOCK NX_NO_PACKET
#define SOCKET_EAGAIN NX_NO_PACKET
#define SOCKET_ECONNRESET NX_NOT_CONNECTED
#define SOCKET_EINTR NX_NOT_CONNECTED
#define SOCKET_EINTR NX_WAIT_ABORTED
#define SOCKET_EPIPE NX_NOT_CONNECTED
#define SOCKET_ECONNREFUSED NX_NOT_CONNECTED
#define SOCKET_ECONNABORTED NX_NOT_CONNECTED
Expand Down
Loading