From 5db48e5268980e093345fe5ac5d297454ef7255c Mon Sep 17 00:00:00 2001 From: hmohide Date: Wed, 6 May 2026 20:10:31 +0530 Subject: [PATCH 01/12] Add UDP support to NetX sockets for DTLS sessions --- src/internal.c | 12 +++- src/wolfio.c | 138 +++++++++++++++++++++++++++++++++++++++++---- wolfssl/internal.h | 5 +- wolfssl/wolfio.h | 6 ++ 4 files changed, 149 insertions(+), 12 deletions(-) diff --git a/src/internal.c b/src/internal.c index af7a695f413..ec386c76615 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2668,6 +2668,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef HAVE_NETX ctx->CBIORecv = NetX_Receive; ctx->CBIOSend = NetX_Send; + #ifdef WOLFSSL_DTLS + if (method->version.major == DTLS_MAJOR) { + ctx->CBIORecv = NetX_ReceiveFrom; + ctx->CBIOSend = NetX_SendTo; + } + #endif #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) ctx->CBIORecv = Mynewt_Receive; ctx->CBIOSend = Mynewt_Send; @@ -7907,9 +7913,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) if (wc_InitRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0) return BAD_MUTEX_E; #endif - +#ifdef HAVE_NETX + ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */ + ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */ +#else ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx; /* prevent invalid pointer access if not */ ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx; /* correctly set */ +#endif #else #ifdef HAVE_NETX ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */ diff --git a/src/wolfio.c b/src/wolfio.c index 4ebff95c696..313ad6b3353 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2530,7 +2530,7 @@ void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb) #ifdef HAVE_NETX -/* The NetX receive callback +/* The NetX receive callback for TLS * return : bytes read, or error */ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) @@ -2543,13 +2543,13 @@ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) (void)ssl; - if (nxCtx == NULL || nxCtx->nxSocket == NULL) { + if (nxCtx == NULL || nxCtx->nxTcpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } if (nxCtx->nxPacket == NULL) { - status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket, + status = nx_tcp_socket_receive(nxCtx->nxTcpSocket, &nxCtx->nxPacket, nxCtx->nxWait); if (status != NX_SUCCESS) { WOLFSSL_MSG("NetX Recv receive error"); @@ -2586,7 +2586,7 @@ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) } -/* The NetX send callback +/* The NetX send callback for TLS * return : bytes sent, or error */ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) @@ -2598,12 +2598,12 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) (void)ssl; - if (nxCtx == NULL || nxCtx->nxSocket == NULL) { + if (nxCtx == NULL || nxCtx->nxTcpSocket == NULL) { WOLFSSL_MSG("NetX Send NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } - pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool; + pool = nxCtx->nxTcpSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool; status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET, nxCtx->nxWait); if (status != NX_SUCCESS) { @@ -2618,7 +2618,7 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait); + 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"); @@ -2628,13 +2628,131 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) return sz; } +/* The NetX receive callback for DTLS + * return : bytes read, or error + */ +int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; + ULONG left; + ULONG total; + ULONG copied = 0; + UINT status; + + (void)ssl; + + if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { + WOLFSSL_MSG("NetX Recv NULL parameters"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + if (nxCtx->nxPacket == NULL) { + status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, + nxCtx->nxWait); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Recv receive error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + + if (nxCtx->nxPacket) { + status = nx_packet_length_get(nxCtx->nxPacket, &total); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Recv length get error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + left = total - nxCtx->nxOffset; + status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset, + buf, sz, &copied); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Recv data extract offset error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + nxCtx->nxOffset += copied; + + if (copied == left) { + WOLFSSL_MSG("NetX Recv Drained packet"); + nx_packet_release(nxCtx->nxPacket); + nxCtx->nxPacket = NULL; + nxCtx->nxOffset = 0; + } + } + + return copied; +} + +/* The NetX send callback for DTLS + * return : bytes sent, or error + */ +int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) +{ + NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; + NX_PACKET* packet; + NX_PACKET_POOL* pool; /* shorthand */ + UINT status; + + (void)ssl; + + if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL + || nxCtx->nxdIp == NULL || nxCtx->nxPort == NULL) { + WOLFSSL_MSG("NetX Send NULL parameters"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + pool = nxCtx->nxUdpSocket->nx_udp_socket_ip_ptr->nx_ip_default_packet_pool; + status = nx_packet_allocate(pool, &packet, NX_UDP_PACKET, + nxCtx->nxWait); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Send packet alloc error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + 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; + } + + if(nxCtx->nxdIp->nxd_ip_version == NX_IP_VERSION_V4) + { + status = nx_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp->nxd_ip_address.v4, (UINT)(*nxCtx->nxPort)); + if (status != NX_SUCCESS) { + nx_packet_release(packet); + WOLFSSL_MSG("NetX Send socket send error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + }else + { + status = nxd_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp, (UINT)(*nxCtx->nxPort)); + if (status != NX_SUCCESS) { + nx_packet_release(packet); + WOLFSSL_MSG("NetX Send socket send error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + + return sz; +} /* like set_fd, but for default NetX context */ -void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption) +void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) +{ + if (ssl) { + ssl->nxCtx.nxTcpSocket = nxsocket; + ssl->nxCtx.nxWait = waitoption; + } +} + +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT *nxport, ULONG waitoption) { if (ssl) { - ssl->nxCtx.nxSocket = nxSocket; - ssl->nxCtx.nxWait = waitOption; + ssl->nxCtx.nxUdpSocket = nxsocket; + ssl->nxCtx.nxdIp = nxdip; + ssl->nxCtx.nxPort = nxport; + ssl->nxCtx.nxWait = waitoption; } } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index f48de685cc2..7f530a0c25e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5711,10 +5711,13 @@ typedef struct DtlsMsg { /* NETX I/O Callback default */ typedef struct NetX_Ctx { - NX_TCP_SOCKET* nxSocket; /* send/recv socket handle */ + NX_TCP_SOCKET* nxTcpSocket; /* send/recv tcp socket handle */ + NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ NX_PACKET* nxPacket; /* incoming packet handle for short reads */ ULONG nxOffset; /* offset already read from nxPacket */ ULONG nxWait; /* wait option flag */ + NXD_ADDRESS* nxdIp; /* IP address for udp send*/ + USHORT* nxPort; /* Port number for udp recv*/ } NetX_Ctx; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 10c6f1a7bb5..18e728c1764 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -790,9 +790,15 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #ifdef HAVE_NETX WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); + WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS *nxdip, + USHORT* nxport, + ULONG waitoption); #endif /* HAVE_NETX */ #ifdef MICRIUM From 38d62bb86ee761e21a66c925fef1ebfa7e0b6ba4 Mon Sep 17 00:00:00 2001 From: hmohide Date: Wed, 10 Jun 2026 21:04:21 +0530 Subject: [PATCH 02/12] Added the guard with WOLFSSL_DTLS --- src/wolfio.c | 21 ++++++++++++--------- wolfssl/internal.h | 4 +++- wolfssl/wolfio.h | 7 ++++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/wolfio.c b/src/wolfio.c index 313ad6b3353..82888e37c7e 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2628,6 +2628,16 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) return sz; } +/* like set_fd, but for default NetX context */ +void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) +{ + if (ssl) { + ssl->nxCtx.nxTcpSocket = nxsocket; + ssl->nxCtx.nxWait = waitoption; + } +} + +#ifdef WOLFSSL_DTLS /* The NetX receive callback for DTLS * return : bytes read, or error */ @@ -2737,15 +2747,7 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) return sz; } -/* like set_fd, but for default NetX context */ -void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) -{ - if (ssl) { - ssl->nxCtx.nxTcpSocket = nxsocket; - ssl->nxCtx.nxWait = waitoption; - } -} - +/* like set_fd, but for default NetX UDP context */ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT *nxport, ULONG waitoption) { if (ssl) { @@ -2755,6 +2757,7 @@ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS ssl->nxCtx.nxWait = waitoption; } } +#endif /* WOLFSSL_DTLS */ #endif /* HAVE_NETX */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 7f530a0c25e..3f4cb558716 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5712,12 +5712,14 @@ typedef struct DtlsMsg { /* NETX I/O Callback default */ typedef struct NetX_Ctx { NX_TCP_SOCKET* nxTcpSocket; /* send/recv tcp socket handle */ - NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ NX_PACKET* nxPacket; /* incoming packet handle for short reads */ ULONG nxOffset; /* offset already read from nxPacket */ ULONG nxWait; /* wait option flag */ +#ifdef WOLFSSL_DTLS + NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ NXD_ADDRESS* nxdIp; /* IP address for udp send*/ USHORT* nxPort; /* Port number for udp recv*/ +#endif } NetX_Ctx; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 18e728c1764..43f16a2ab4c 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -790,15 +790,16 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #ifdef HAVE_NETX WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); +#ifdef WOLFSSL_DTLS + WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT* nxport, ULONG waitoption); +#endif #endif /* HAVE_NETX */ #ifdef MICRIUM From 730cdccc975d9845863ab8f08fd891fe6455feac Mon Sep 17 00:00:00 2001 From: hmohide Date: Fri, 12 Jun 2026 14:45:54 +0530 Subject: [PATCH 03/12] updated the review comments --- doc/dox_comments/header_files-ja/wolfio.h | 39 ++++++++++- doc/dox_comments/header_files/wolfio.h | 40 +++++++++++- src/internal.c | 4 +- src/wolfio.c | 80 +++++++++++++++-------- wolfssl/internal.h | 9 +-- wolfssl/wolfio.h | 11 ++-- 6 files changed, 139 insertions(+), 44 deletions(-) diff --git a/doc/dox_comments/header_files-ja/wolfio.h b/doc/dox_comments/header_files-ja/wolfio.h index cae11f81ee5..dedd128dd06 100644 --- a/doc/dox_comments/header_files-ja/wolfio.h +++ b/doc/dox_comments/header_files-ja/wolfio.h @@ -404,12 +404,12 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); /*! \ingroup IO - \brief この関数は、WOLFSSL構造体内のnxCtx構造体のnxSocketおよびnxWaitメンバーを設定します。 + \brief この関数は、WOLFSSL構造体内のnxCtx構造体のnxTcpSocketおよびnxWaitメンバーを設定します。 \return none 戻り値なし。 \param ssl wolfSSL_new()を使用して作成されたWOLFSSL構造体へのポインタ。 - \param nxSocket nxCTX構造体のnxSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 + \param nxSocket nxCtx構造体のnxTcpSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 \param waitOption nxCtx構造体のnxWaitメンバーに設定されるULONG型。 _Example_ @@ -432,6 +432,41 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); +/*! + \ingroup IO + + \brief この関数は、DTLSセッション用のNetX Duo UDPコンテキストを設定します。 + UDPソケット、送信先IPアドレス(値渡し)、送信先ポート、待機オプションを + WOLFSSL nxCtx構造体に格納します。WOLFSSL_NETX_DUOの定義が必要です(ThreadX NetX Duo SDK)。 + + \return none 戻り値なし。 + + \param ssl wolfSSL_new()を使用して作成されたWOLFSSL構造体へのポインタ。 + \param nxsocket 作成・バインド済みのNX_UDP_SOCKETへのポインタ。 + \param nxdip 送信先NXD_ADDRESS(値渡し;IPv4またはIPv6)。 + \param nxport 送信先UDPポート番号。 + \param waitoption NetX待機オプション(例:NX_WAIT_FOREVERまたはティック数)。 + + _Example_ + \code + WOLFSSL* ssl = wolfSSL_new(ctx); + NX_UDP_SOCKET udpSocket; + NXD_ADDRESS peerAddr; + USHORT peerPort = 4433; + ULONG wait = NX_WAIT_FOREVER; + // … udpSocketとpeerAddrを初期化 … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + \endcode + + \sa wolfSSL_SetIO_NetX + \sa NetX_SendTo + \sa NetX_ReceiveFrom +*/ +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, USHORT nxport, + ULONG waitoption); + + /*! \brief この関数は、WOLFSSL_CTX構造体のCBIOCookieメンバーのコールバックを設定します。 CallbackGenCookie型は関数ポインタで、次のシグネチャを持ちます: diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index 2ec951563e4..c685eb8d89a 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -450,14 +450,14 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); /*! \ingroup IO - \brief This function sets the nxSocket and nxWait members of the nxCtx + \brief This function sets the nxTcpSocket and nxWait members of the nxCtx struct within the WOLFSSL structure. \return none No returns. \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). \param nxSocket a pointer to type NX_TCP_SOCKET that is set to the - nxSocket member of the nxCTX structure. + nxTcpSocket member of the nxCtx structure. \param waitOption a ULONG type that is set to the nxWait member of the nxCtx structure. @@ -481,6 +481,42 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); +/*! + \ingroup IO + + \brief This function configures the NetX Duo UDP context for a DTLS + session. It stores the UDP socket, destination IP address (by value), + destination port, and wait option into the WOLFSSL nxCtx structure. + Requires WOLFSSL_NETX_DUO to be defined (ThreadX NetX Duo SDK). + + \return none No returns. + + \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). + \param nxsocket a pointer to an NX_UDP_SOCKET already created and bound. + \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). + + _Example_ + \code + WOLFSSL* ssl = wolfSSL_new(ctx); + NX_UDP_SOCKET udpSocket; + NXD_ADDRESS peerAddr; + USHORT peerPort = 4433; + ULONG wait = NX_WAIT_FOREVER; + // … initialise udpSocket and peerAddr … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + \endcode + + \sa wolfSSL_SetIO_NetX + \sa NetX_SendTo + \sa NetX_ReceiveFrom +*/ +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, USHORT nxport, + ULONG waitoption); + + /*! \brief This function sets the callback for the CBIOCookie member of the WOLFSSL_CTX structure. The CallbackGenCookie type is a function pointer diff --git a/src/internal.c b/src/internal.c index ec386c76615..86ea352d56b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2668,12 +2668,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef HAVE_NETX ctx->CBIORecv = NetX_Receive; ctx->CBIOSend = NetX_Send; - #ifdef WOLFSSL_DTLS + #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) if (method->version.major == DTLS_MAJOR) { ctx->CBIORecv = NetX_ReceiveFrom; ctx->CBIOSend = NetX_SendTo; } - #endif + #endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) ctx->CBIORecv = Mynewt_Receive; ctx->CBIOSend = Mynewt_Send; diff --git a/src/wolfio.c b/src/wolfio.c index 82888e37c7e..0765e457198 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2637,7 +2637,8 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) } } -#ifdef WOLFSSL_DTLS +/* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) /* The NetX receive callback for DTLS * return : bytes read, or error */ @@ -2648,8 +2649,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) ULONG total; ULONG copied = 0; UINT status; - - (void)ssl; + ULONG waitOption; if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); @@ -2657,9 +2657,33 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) } if (nxCtx->nxPacket == NULL) { + /* Compute wait ticks from the current DTLS retransmit timeout so the + * DTLS state machine can drive retransmission on packet loss. */ + if (!wolfSSL_dtls_get_using_nonblock(ssl)) { + int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); + #ifdef WOLFSSL_DTLS13 + if (wolfSSL_dtls13_use_quick_timeout(ssl) && + IsAtLeastTLSv1_3(ssl->version)) + dtls_timeout = dtls_timeout / 4; + #endif + waitOption = (dtls_timeout > 0) + ? (ULONG)dtls_timeout * NX_IP_PERIODIC_RATE + : nxCtx->nxWait; + } + else { + waitOption = NX_NO_WAIT; /* non-blocking */ + } + status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, - nxCtx->nxWait); + waitOption); if (status != NX_SUCCESS) { + if (status == NX_NO_PACKET) { + /* Normal receive timeout — allow DTLS to retransmit */ + WOLFSSL_MSG("NetX Recv timeout"); + return wolfSSL_dtls_get_using_nonblock(ssl) + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } WOLFSSL_MSG("NetX Recv receive error"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -2705,8 +2729,7 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) (void)ssl; - if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL - || nxCtx->nxdIp == NULL || nxCtx->nxPort == NULL) { + if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Send NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -2726,38 +2749,37 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - if(nxCtx->nxdIp->nxd_ip_version == NX_IP_VERSION_V4) - { - status = nx_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp->nxd_ip_address.v4, (UINT)(*nxCtx->nxPort)); - if (status != NX_SUCCESS) { - nx_packet_release(packet); - WOLFSSL_MSG("NetX Send socket send error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - }else - { - status = nxd_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp, (UINT)(*nxCtx->nxPort)); - if (status != NX_SUCCESS) { - nx_packet_release(packet); - WOLFSSL_MSG("NetX Send socket send error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } + if (nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V4) { + status = nx_udp_socket_send(nxCtx->nxUdpSocket, packet, + nxCtx->nxdIp.nxd_ip_address.v4, + (UINT)nxCtx->nxPort); + } + else { + status = nxd_udp_socket_send(nxCtx->nxUdpSocket, packet, + &nxCtx->nxdIp, (UINT)nxCtx->nxPort); + } + if (status != NX_SUCCESS) { + nx_packet_release(packet); + WOLFSSL_MSG("NetX Send socket send error"); + return WOLFSSL_CBIO_ERR_GENERAL; } return sz; } -/* like set_fd, but for default NetX UDP context */ -void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT *nxport, ULONG waitoption) +/* like set_fd, but for default NetX Duo UDP context */ +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, USHORT nxport, + ULONG waitoption) { if (ssl) { - ssl->nxCtx.nxUdpSocket = nxsocket; - ssl->nxCtx.nxdIp = nxdip; - ssl->nxCtx.nxPort = nxport; - ssl->nxCtx.nxWait = waitoption; + ssl->nxCtx.nxUdpSocket = nxsocket; + ssl->nxCtx.nxdIp = nxdip; + ssl->nxCtx.nxPort = nxport; + ssl->nxCtx.nxWait = waitoption; } } -#endif /* WOLFSSL_DTLS */ +#endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ #endif /* HAVE_NETX */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 3f4cb558716..892dcadfb09 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5715,11 +5715,12 @@ typedef struct DtlsMsg { NX_PACKET* nxPacket; /* incoming packet handle for short reads */ ULONG nxOffset; /* offset already read from nxPacket */ ULONG nxWait; /* wait option flag */ -#ifdef WOLFSSL_DTLS +/* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ - NXD_ADDRESS* nxdIp; /* IP address for udp send*/ - USHORT* nxPort; /* Port number for udp recv*/ -#endif + NXD_ADDRESS nxdIp; /* destination IP address for udp send */ + USHORT nxPort; /* destination port for udp send */ +#endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ } NetX_Ctx; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 43f16a2ab4c..771c041f9e5 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -792,14 +792,15 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); -#ifdef WOLFSSL_DTLS +/* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, - NXD_ADDRESS *nxdip, - USHORT* nxport, + WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, + USHORT nxport, ULONG waitoption); -#endif +#endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ #endif /* HAVE_NETX */ #ifdef MICRIUM From e59b7cdaf5c8c57846c5e97dbea54e8c1681dff5 Mon Sep 17 00:00:00 2001 From: hmohide Date: Mon, 15 Jun 2026 11:49:29 +0530 Subject: [PATCH 04/12] wolfio: fix review comments for DTLS NetX UDP support - Replace non-ASCII em-dash with ASCII hyphen in NetX_ReceiveFrom comment to pass wolfSSL encoding/whitespace CI check - Add WOLFSSL_NETX_DUO to .wolfssl_known_macro_extras so the macro checker no longer flags it as unrecognized --- .wolfssl_known_macro_extras | 1 + src/wolfio.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index a93473f0679..e223cd778c0 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -820,6 +820,7 @@ WOLFSSL_MONT_RED_CT WOLFSSL_MP_COND_COPY WOLFSSL_MP_INVMOD_CONSTANT_TIME WOLFSSL_MULTICIRCULATE_ALTNAMELIST +WOLFSSL_NETX_DUO WOLFSSL_NEW_PRIME_CHECK WOLFSSL_NOSHA3_384 WOLFSSL_NOT_WINDOWS_API diff --git a/src/wolfio.c b/src/wolfio.c index 0765e457198..5071435af35 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2678,7 +2678,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) waitOption); if (status != NX_SUCCESS) { if (status == NX_NO_PACKET) { - /* Normal receive timeout — allow DTLS to retransmit */ + /* Normal receive timeout - allow DTLS to retransmit */ WOLFSSL_MSG("NetX Recv timeout"); return wolfSSL_dtls_get_using_nonblock(ssl) ? WOLFSSL_CBIO_ERR_WANT_READ From 542f30ce5b57724f20362f383c1f25da5abe4f25 Mon Sep 17 00:00:00 2001 From: hmohide Date: Tue, 16 Jun 2026 10:56:02 +0530 Subject: [PATCH 05/12] updated review comments --- doc/dox_comments/header_files-ja/wolfio.h | 22 ++-- doc/dox_comments/header_files/wolfio.h | 22 ++-- src/wolfio.c | 145 ++++++++++++++++------ 3 files changed, 132 insertions(+), 57 deletions(-) diff --git a/doc/dox_comments/header_files-ja/wolfio.h b/doc/dox_comments/header_files-ja/wolfio.h index dedd128dd06..8813cd719ad 100644 --- a/doc/dox_comments/header_files-ja/wolfio.h +++ b/doc/dox_comments/header_files-ja/wolfio.h @@ -409,17 +409,17 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); \return none 戻り値なし。 \param ssl wolfSSL_new()を使用して作成されたWOLFSSL構造体へのポインタ。 - \param nxSocket nxCtx構造体のnxTcpSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 - \param waitOption nxCtx構造体のnxWaitメンバーに設定されるULONG型。 + \param nxsocket nxCtx構造体のnxTcpSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 + \param waitoption nxCtx構造体のnxWaitメンバーに設定されるULONG型。 _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_TCP_SOCKET* nxSocket; - ULONG waitOption; + NX_TCP_SOCKET* nxsocket; + ULONG waitoption; … - if(ssl != NULL || nxSocket != NULL || waitOption <= 0){ - wolfSSL_SetIO_NetX(ssl, nxSocket, waitOption); + if(ssl != NULL || nxsocket != NULL || waitoption <= 0){ + wolfSSL_SetIO_NetX(ssl, nxsocket, waitoption); } else { // 適切なパラメータを渡す必要があります。 } @@ -450,12 +450,12 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_UDP_SOCKET udpSocket; - NXD_ADDRESS peerAddr; - USHORT peerPort = 4433; + NX_UDP_SOCKET udpsocket; + NXD_ADDRESS peeraddr; + USHORT peerport = 4433; ULONG wait = NX_WAIT_FOREVER; - // … udpSocketとpeerAddrを初期化 … - wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + // … udpsocketとpeeraddrを初期化 … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpsocket, peeraddr, peerport, wait); \endcode \sa wolfSSL_SetIO_NetX diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index c685eb8d89a..86f176d5730 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -456,19 +456,19 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); \return none No returns. \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). - \param nxSocket a pointer to type NX_TCP_SOCKET that is set to the + \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 + \param waitoption a ULONG type that is set to the nxWait member of the nxCtx structure. _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_TCP_SOCKET* nxSocket; - ULONG waitOption; + NX_TCP_SOCKET* nxsocket; + ULONG waitoption; … - if(ssl != NULL || nxSocket != NULL || waitOption <= 0){ - wolfSSL_SetIO_NetX(ssl, nxSocket, waitOption); + if(ssl != NULL || nxsocket != NULL || waitoption <= 0){ + wolfSSL_SetIO_NetX(ssl, nxsocket, waitoption); } else { // You need to pass in good parameters. } @@ -500,12 +500,12 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_UDP_SOCKET udpSocket; - NXD_ADDRESS peerAddr; - USHORT peerPort = 4433; + NX_UDP_SOCKET udpsocket; + NXD_ADDRESS peeraddr; + USHORT peerport = 4433; ULONG wait = NX_WAIT_FOREVER; - // … initialise udpSocket and peerAddr … - wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + // … initialise udpsocket and peeraddr … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpsocket, peeraddr, peerport, wait); \endcode \sa wolfSSL_SetIO_NetX diff --git a/src/wolfio.c b/src/wolfio.c index 5071435af35..73e4f0aa0b4 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2639,67 +2639,142 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) /* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) +static void NetX_ResetPacket(NetX_Ctx* nxCtx) +{ + if (nxCtx->nxPacket != NULL) { + nx_packet_release(nxCtx->nxPacket); + nxCtx->nxPacket = NULL; + } + nxCtx->nxOffset = 0; +} + +static int NetX_PeerAddrEqual(const NXD_ADDRESS* left, const NXD_ADDRESS* right) +{ + if (left->nxd_ip_version != right->nxd_ip_version) + return 0; + + if (left->nxd_ip_version == NX_IP_VERSION_V4) + return left->nxd_ip_address.v4 == right->nxd_ip_address.v4; + + return left->nxd_ip_address.v6[0] == right->nxd_ip_address.v6[0] && + left->nxd_ip_address.v6[1] == right->nxd_ip_address.v6[1] && + left->nxd_ip_address.v6[2] == right->nxd_ip_address.v6[2] && + left->nxd_ip_address.v6[3] == right->nxd_ip_address.v6[3]; +} + /* The NetX receive callback for DTLS * return : bytes read, or error */ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) { NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; + NXD_ADDRESS srcIp; ULONG left; ULONG total; ULONG copied = 0; + UINT srcPort; UINT status; ULONG waitOption; + int dtls_timeout; + int usingNonblock; + byte doDtlsTimeout; if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } - if (nxCtx->nxPacket == NULL) { - /* Compute wait ticks from the current DTLS retransmit timeout so the - * DTLS state machine can drive retransmission on packet loss. */ - if (!wolfSSL_dtls_get_using_nonblock(ssl)) { - int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); - #ifdef WOLFSSL_DTLS13 - if (wolfSSL_dtls13_use_quick_timeout(ssl) && - IsAtLeastTLSv1_3(ssl->version)) - dtls_timeout = dtls_timeout / 4; - #endif - waitOption = (dtls_timeout > 0) - ? (ULONG)dtls_timeout * NX_IP_PERIODIC_RATE - : nxCtx->nxWait; - } - else { - waitOption = NX_NO_WAIT; /* non-blocking */ - } + usingNonblock = wolfSSL_dtls_get_using_nonblock(ssl); - status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, - waitOption); - if (status != NX_SUCCESS) { - if (status == NX_NO_PACKET) { - /* Normal receive timeout - allow DTLS to retransmit */ - WOLFSSL_MSG("NetX Recv timeout"); - return wolfSSL_dtls_get_using_nonblock(ssl) - ? WOLFSSL_CBIO_ERR_WANT_READ - : WOLFSSL_CBIO_ERR_TIMEOUT; + /* Don't use ssl->options.handShakeDone since it is true even if + * we are in the process of renegotiation. */ + doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE; +#ifdef WOLFSSL_DTLS13 + if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) { + doDtlsTimeout = + doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL || + (ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL); + } +#endif /* WOLFSSL_DTLS13 */ + + do { + if (nxCtx->nxPacket == NULL) { + /* Compute wait ticks from the DTLS retransmit timeout while a + * handshake/RTX timer is active, otherwise honor nxWait. */ + if (!usingNonblock) { + dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); + if (!doDtlsTimeout) + dtls_timeout = 0; +#ifdef WOLFSSL_DTLS13 + if (dtls_timeout > 0 && wolfSSL_dtls13_use_quick_timeout(ssl) && + IsAtLeastTLSv1_3(ssl->version)) { + if (dtls_timeout > 4) + dtls_timeout /= 4; + else + dtls_timeout = 1; + } +#endif /* WOLFSSL_DTLS13 */ + waitOption = (dtls_timeout > 0) + ? (ULONG)dtls_timeout * NX_IP_PERIODIC_RATE + : nxCtx->nxWait; + } + else { + waitOption = NX_NO_WAIT; /* non-blocking */ + } + + status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, + waitOption); + if (status != NX_SUCCESS) { + if (status == NX_NO_PACKET) { + /* Normal receive timeout - allow DTLS to retransmit */ + WOLFSSL_MSG("NetX Recv timeout"); + return usingNonblock + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } + WOLFSSL_MSG("NetX Recv receive error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + status = nxd_udp_source_extract(nxCtx->nxPacket, &srcIp, &srcPort); + if (status != NX_SUCCESS) { + NetX_ResetPacket(nxCtx); + WOLFSSL_MSG("NetX Recv source extract error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + if ((USHORT)srcPort != nxCtx->nxPort || + !NetX_PeerAddrEqual(&srcIp, &nxCtx->nxdIp)) { + WOLFSSL_MSG("NetX Recv ignored packet from invalid peer"); + NetX_ResetPacket(nxCtx); + continue; } - WOLFSSL_MSG("NetX Recv receive error"); - return WOLFSSL_CBIO_ERR_GENERAL; } - } - if (nxCtx->nxPacket) { status = nx_packet_length_get(nxCtx->nxPacket, &total); if (status != NX_SUCCESS) { + NetX_ResetPacket(nxCtx); WOLFSSL_MSG("NetX Recv length get error"); return WOLFSSL_CBIO_ERR_GENERAL; } + if (total == 0) { + WOLFSSL_MSG("Ignoring 0-length datagram"); + NetX_ResetPacket(nxCtx); + continue; + } + + if (nxCtx->nxOffset > total) { + NetX_ResetPacket(nxCtx); + WOLFSSL_MSG("NetX Recv invalid packet offset"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + left = total - nxCtx->nxOffset; status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset, buf, sz, &copied); if (status != NX_SUCCESS) { + NetX_ResetPacket(nxCtx); WOLFSSL_MSG("NetX Recv data extract offset error"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -2708,13 +2783,13 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) if (copied == left) { WOLFSSL_MSG("NetX Recv Drained packet"); - nx_packet_release(nxCtx->nxPacket); - nxCtx->nxPacket = NULL; - nxCtx->nxOffset = 0; + NetX_ResetPacket(nxCtx); } - } - return copied; + return copied; + } while (1); + + /* unreachable */ } /* The NetX send callback for DTLS From 0ca15afa32a7d153689a8f6aa0756cf834e07022 Mon Sep 17 00:00:00 2001 From: hmohide Date: Thu, 18 Jun 2026 20:10:35 +0530 Subject: [PATCH 06/12] Updated the review comments --- doc/dox_comments/header_files-ja/wolfio.h | 1 - doc/dox_comments/header_files/wolfio.h | 1 - src/wolfio.c | 43 +++++++++++++++++++---- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/doc/dox_comments/header_files-ja/wolfio.h b/doc/dox_comments/header_files-ja/wolfio.h index 8813cd719ad..d21eed171eb 100644 --- a/doc/dox_comments/header_files-ja/wolfio.h +++ b/doc/dox_comments/header_files-ja/wolfio.h @@ -466,7 +466,6 @@ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS nxdip, USHORT nxport, ULONG waitoption); - /*! \brief この関数は、WOLFSSL_CTX構造体のCBIOCookieメンバーのコールバックを設定します。 CallbackGenCookie型は関数ポインタで、次のシグネチャを持ちます: diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index 86f176d5730..42a39dfe67b 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -516,7 +516,6 @@ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS nxdip, USHORT nxport, ULONG waitoption); - /*! \brief This function sets the callback for the CBIOCookie member of the WOLFSSL_CTX structure. The CallbackGenCookie type is a function pointer diff --git a/src/wolfio.c b/src/wolfio.c index 73e4f0aa0b4..116d7abf9ed 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2678,6 +2678,12 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) int dtls_timeout; int usingNonblock; byte doDtlsTimeout; + word32 invalidPeerPackets = 0; +#if defined(DTLS_RECEIVEFROM_MAX_INVALID_PEER) + const word32 maxInvalidPeerPackets = DTLS_RECEIVEFROM_MAX_INVALID_PEER; +#else + const word32 maxInvalidPeerPackets = 10; +#endif if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); @@ -2743,11 +2749,28 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - if ((USHORT)srcPort != nxCtx->nxPort || - !NetX_PeerAddrEqual(&srcIp, &nxCtx->nxdIp)) { - WOLFSSL_MSG("NetX Recv ignored packet from invalid peer"); - NetX_ResetPacket(nxCtx); - continue; + if (nxCtx->nxPort != 0 && + (nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V4 || + nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V6)) { + if ((USHORT)srcPort != nxCtx->nxPort || + !NetX_PeerAddrEqual(&srcIp, &nxCtx->nxdIp)) { + WOLFSSL_MSG("NetX Recv ignored packet from invalid peer"); + NetX_ResetPacket(nxCtx); + if (doDtlsTimeout) { + invalidPeerPackets++; + if (invalidPeerPackets > maxInvalidPeerPackets) { + return usingNonblock + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } + } + continue; + } + } + else { + /* No peer preset: accept first datagram and lock onto source. */ + nxCtx->nxdIp = srcIp; + nxCtx->nxPort = (USHORT)srcPort; } } @@ -2761,6 +2784,14 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) if (total == 0) { WOLFSSL_MSG("Ignoring 0-length datagram"); NetX_ResetPacket(nxCtx); + if (doDtlsTimeout) { + invalidPeerPackets++; + if (invalidPeerPackets > maxInvalidPeerPackets) { + return usingNonblock + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } + } continue; } @@ -2789,7 +2820,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) return copied; } while (1); - /* unreachable */ + return (int)copied; } /* The NetX send callback for DTLS From 64ce37e626edb2cb76aefbff283e361da6399ffb Mon Sep 17 00:00:00 2001 From: hmohide Date: Wed, 6 May 2026 20:10:31 +0530 Subject: [PATCH 07/12] Add UDP support to NetX sockets for DTLS sessions --- src/internal.c | 12 +++- src/wolfio.c | 138 +++++++++++++++++++++++++++++++++++++++++---- wolfssl/internal.h | 5 +- wolfssl/wolfio.h | 6 ++ 4 files changed, 149 insertions(+), 12 deletions(-) diff --git a/src/internal.c b/src/internal.c index 16869c0bcc0..54975ed4318 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2707,6 +2707,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef HAVE_NETX ctx->CBIORecv = NetX_Receive; ctx->CBIOSend = NetX_Send; + #ifdef WOLFSSL_DTLS + if (method->version.major == DTLS_MAJOR) { + ctx->CBIORecv = NetX_ReceiveFrom; + ctx->CBIOSend = NetX_SendTo; + } + #endif #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) ctx->CBIORecv = Mynewt_Receive; ctx->CBIOSend = Mynewt_Send; @@ -7950,9 +7956,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) if (wc_InitRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0) return BAD_MUTEX_E; #endif - +#ifdef HAVE_NETX + ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */ + ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */ +#else ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx; /* prevent invalid pointer access if not */ ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx; /* correctly set */ +#endif #else #ifdef HAVE_NETX ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */ diff --git a/src/wolfio.c b/src/wolfio.c index 4ebff95c696..313ad6b3353 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2530,7 +2530,7 @@ void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb) #ifdef HAVE_NETX -/* The NetX receive callback +/* The NetX receive callback for TLS * return : bytes read, or error */ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) @@ -2543,13 +2543,13 @@ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) (void)ssl; - if (nxCtx == NULL || nxCtx->nxSocket == NULL) { + if (nxCtx == NULL || nxCtx->nxTcpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } if (nxCtx->nxPacket == NULL) { - status = nx_tcp_socket_receive(nxCtx->nxSocket, &nxCtx->nxPacket, + status = nx_tcp_socket_receive(nxCtx->nxTcpSocket, &nxCtx->nxPacket, nxCtx->nxWait); if (status != NX_SUCCESS) { WOLFSSL_MSG("NetX Recv receive error"); @@ -2586,7 +2586,7 @@ int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx) } -/* The NetX send callback +/* The NetX send callback for TLS * return : bytes sent, or error */ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) @@ -2598,12 +2598,12 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) (void)ssl; - if (nxCtx == NULL || nxCtx->nxSocket == NULL) { + if (nxCtx == NULL || nxCtx->nxTcpSocket == NULL) { WOLFSSL_MSG("NetX Send NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } - pool = nxCtx->nxSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool; + pool = nxCtx->nxTcpSocket->nx_tcp_socket_ip_ptr->nx_ip_default_packet_pool; status = nx_packet_allocate(pool, &packet, NX_TCP_PACKET, nxCtx->nxWait); if (status != NX_SUCCESS) { @@ -2618,7 +2618,7 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - status = nx_tcp_socket_send(nxCtx->nxSocket, packet, nxCtx->nxWait); + 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"); @@ -2628,13 +2628,131 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) return sz; } +/* The NetX receive callback for DTLS + * return : bytes read, or error + */ +int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; + ULONG left; + ULONG total; + ULONG copied = 0; + UINT status; + + (void)ssl; + + if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { + WOLFSSL_MSG("NetX Recv NULL parameters"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + if (nxCtx->nxPacket == NULL) { + status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, + nxCtx->nxWait); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Recv receive error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + + if (nxCtx->nxPacket) { + status = nx_packet_length_get(nxCtx->nxPacket, &total); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Recv length get error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + left = total - nxCtx->nxOffset; + status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset, + buf, sz, &copied); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Recv data extract offset error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + nxCtx->nxOffset += copied; + + if (copied == left) { + WOLFSSL_MSG("NetX Recv Drained packet"); + nx_packet_release(nxCtx->nxPacket); + nxCtx->nxPacket = NULL; + nxCtx->nxOffset = 0; + } + } + + return copied; +} + +/* The NetX send callback for DTLS + * return : bytes sent, or error + */ +int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) +{ + NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; + NX_PACKET* packet; + NX_PACKET_POOL* pool; /* shorthand */ + UINT status; + + (void)ssl; + + if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL + || nxCtx->nxdIp == NULL || nxCtx->nxPort == NULL) { + WOLFSSL_MSG("NetX Send NULL parameters"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + pool = nxCtx->nxUdpSocket->nx_udp_socket_ip_ptr->nx_ip_default_packet_pool; + status = nx_packet_allocate(pool, &packet, NX_UDP_PACKET, + nxCtx->nxWait); + if (status != NX_SUCCESS) { + WOLFSSL_MSG("NetX Send packet alloc error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + 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; + } + + if(nxCtx->nxdIp->nxd_ip_version == NX_IP_VERSION_V4) + { + status = nx_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp->nxd_ip_address.v4, (UINT)(*nxCtx->nxPort)); + if (status != NX_SUCCESS) { + nx_packet_release(packet); + WOLFSSL_MSG("NetX Send socket send error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + }else + { + status = nxd_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp, (UINT)(*nxCtx->nxPort)); + if (status != NX_SUCCESS) { + nx_packet_release(packet); + WOLFSSL_MSG("NetX Send socket send error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + + return sz; +} /* like set_fd, but for default NetX context */ -void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxSocket, ULONG waitOption) +void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) +{ + if (ssl) { + ssl->nxCtx.nxTcpSocket = nxsocket; + ssl->nxCtx.nxWait = waitoption; + } +} + +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT *nxport, ULONG waitoption) { if (ssl) { - ssl->nxCtx.nxSocket = nxSocket; - ssl->nxCtx.nxWait = waitOption; + ssl->nxCtx.nxUdpSocket = nxsocket; + ssl->nxCtx.nxdIp = nxdip; + ssl->nxCtx.nxPort = nxport; + ssl->nxCtx.nxWait = waitoption; } } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0480491e719..50ef42272b6 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5772,10 +5772,13 @@ typedef struct DtlsMsg { /* NETX I/O Callback default */ typedef struct NetX_Ctx { - NX_TCP_SOCKET* nxSocket; /* send/recv socket handle */ + NX_TCP_SOCKET* nxTcpSocket; /* send/recv tcp socket handle */ + NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ NX_PACKET* nxPacket; /* incoming packet handle for short reads */ ULONG nxOffset; /* offset already read from nxPacket */ ULONG nxWait; /* wait option flag */ + NXD_ADDRESS* nxdIp; /* IP address for udp send*/ + USHORT* nxPort; /* Port number for udp recv*/ } NetX_Ctx; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index eb609235d7c..3b6040d15cf 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -790,9 +790,15 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #ifdef HAVE_NETX WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); + WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS *nxdip, + USHORT* nxport, + ULONG waitoption); #endif /* HAVE_NETX */ #ifdef MICRIUM From d7e5b9091837079d198761fbc2746f1f0b1963e4 Mon Sep 17 00:00:00 2001 From: hmohide Date: Wed, 10 Jun 2026 21:04:21 +0530 Subject: [PATCH 08/12] Added the guard with WOLFSSL_DTLS --- src/wolfio.c | 21 ++++++++++++--------- wolfssl/internal.h | 4 +++- wolfssl/wolfio.h | 7 ++++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/wolfio.c b/src/wolfio.c index 313ad6b3353..82888e37c7e 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2628,6 +2628,16 @@ int NetX_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) return sz; } +/* like set_fd, but for default NetX context */ +void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) +{ + if (ssl) { + ssl->nxCtx.nxTcpSocket = nxsocket; + ssl->nxCtx.nxWait = waitoption; + } +} + +#ifdef WOLFSSL_DTLS /* The NetX receive callback for DTLS * return : bytes read, or error */ @@ -2737,15 +2747,7 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) return sz; } -/* like set_fd, but for default NetX context */ -void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) -{ - if (ssl) { - ssl->nxCtx.nxTcpSocket = nxsocket; - ssl->nxCtx.nxWait = waitoption; - } -} - +/* like set_fd, but for default NetX UDP context */ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT *nxport, ULONG waitoption) { if (ssl) { @@ -2755,6 +2757,7 @@ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS ssl->nxCtx.nxWait = waitoption; } } +#endif /* WOLFSSL_DTLS */ #endif /* HAVE_NETX */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 50ef42272b6..92f3920279c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5773,12 +5773,14 @@ typedef struct DtlsMsg { /* NETX I/O Callback default */ typedef struct NetX_Ctx { NX_TCP_SOCKET* nxTcpSocket; /* send/recv tcp socket handle */ - NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ NX_PACKET* nxPacket; /* incoming packet handle for short reads */ ULONG nxOffset; /* offset already read from nxPacket */ ULONG nxWait; /* wait option flag */ +#ifdef WOLFSSL_DTLS + NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ NXD_ADDRESS* nxdIp; /* IP address for udp send*/ USHORT* nxPort; /* Port number for udp recv*/ +#endif } NetX_Ctx; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 3b6040d15cf..16dddb417d9 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -790,15 +790,16 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #ifdef HAVE_NETX WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); +#ifdef WOLFSSL_DTLS + WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); + WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT* nxport, ULONG waitoption); +#endif #endif /* HAVE_NETX */ #ifdef MICRIUM From 50e13f8f1bd3c70fbab7f108ce61162139be5363 Mon Sep 17 00:00:00 2001 From: hmohide Date: Fri, 12 Jun 2026 14:45:54 +0530 Subject: [PATCH 09/12] updated the review comments --- doc/dox_comments/header_files-ja/wolfio.h | 39 ++++++++++- doc/dox_comments/header_files/wolfio.h | 40 +++++++++++- src/internal.c | 4 +- src/wolfio.c | 80 +++++++++++++++-------- wolfssl/internal.h | 9 +-- wolfssl/wolfio.h | 11 ++-- 6 files changed, 139 insertions(+), 44 deletions(-) diff --git a/doc/dox_comments/header_files-ja/wolfio.h b/doc/dox_comments/header_files-ja/wolfio.h index cae11f81ee5..dedd128dd06 100644 --- a/doc/dox_comments/header_files-ja/wolfio.h +++ b/doc/dox_comments/header_files-ja/wolfio.h @@ -404,12 +404,12 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); /*! \ingroup IO - \brief この関数は、WOLFSSL構造体内のnxCtx構造体のnxSocketおよびnxWaitメンバーを設定します。 + \brief この関数は、WOLFSSL構造体内のnxCtx構造体のnxTcpSocketおよびnxWaitメンバーを設定します。 \return none 戻り値なし。 \param ssl wolfSSL_new()を使用して作成されたWOLFSSL構造体へのポインタ。 - \param nxSocket nxCTX構造体のnxSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 + \param nxSocket nxCtx構造体のnxTcpSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 \param waitOption nxCtx構造体のnxWaitメンバーに設定されるULONG型。 _Example_ @@ -432,6 +432,41 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); +/*! + \ingroup IO + + \brief この関数は、DTLSセッション用のNetX Duo UDPコンテキストを設定します。 + UDPソケット、送信先IPアドレス(値渡し)、送信先ポート、待機オプションを + WOLFSSL nxCtx構造体に格納します。WOLFSSL_NETX_DUOの定義が必要です(ThreadX NetX Duo SDK)。 + + \return none 戻り値なし。 + + \param ssl wolfSSL_new()を使用して作成されたWOLFSSL構造体へのポインタ。 + \param nxsocket 作成・バインド済みのNX_UDP_SOCKETへのポインタ。 + \param nxdip 送信先NXD_ADDRESS(値渡し;IPv4またはIPv6)。 + \param nxport 送信先UDPポート番号。 + \param waitoption NetX待機オプション(例:NX_WAIT_FOREVERまたはティック数)。 + + _Example_ + \code + WOLFSSL* ssl = wolfSSL_new(ctx); + NX_UDP_SOCKET udpSocket; + NXD_ADDRESS peerAddr; + USHORT peerPort = 4433; + ULONG wait = NX_WAIT_FOREVER; + // … udpSocketとpeerAddrを初期化 … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + \endcode + + \sa wolfSSL_SetIO_NetX + \sa NetX_SendTo + \sa NetX_ReceiveFrom +*/ +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, USHORT nxport, + ULONG waitoption); + + /*! \brief この関数は、WOLFSSL_CTX構造体のCBIOCookieメンバーのコールバックを設定します。 CallbackGenCookie型は関数ポインタで、次のシグネチャを持ちます: diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index 2ec951563e4..c685eb8d89a 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -450,14 +450,14 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); /*! \ingroup IO - \brief This function sets the nxSocket and nxWait members of the nxCtx + \brief This function sets the nxTcpSocket and nxWait members of the nxCtx struct within the WOLFSSL structure. \return none No returns. \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). \param nxSocket a pointer to type NX_TCP_SOCKET that is set to the - nxSocket member of the nxCTX structure. + nxTcpSocket member of the nxCtx structure. \param waitOption a ULONG type that is set to the nxWait member of the nxCtx structure. @@ -481,6 +481,42 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); +/*! + \ingroup IO + + \brief This function configures the NetX Duo UDP context for a DTLS + session. It stores the UDP socket, destination IP address (by value), + destination port, and wait option into the WOLFSSL nxCtx structure. + Requires WOLFSSL_NETX_DUO to be defined (ThreadX NetX Duo SDK). + + \return none No returns. + + \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). + \param nxsocket a pointer to an NX_UDP_SOCKET already created and bound. + \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). + + _Example_ + \code + WOLFSSL* ssl = wolfSSL_new(ctx); + NX_UDP_SOCKET udpSocket; + NXD_ADDRESS peerAddr; + USHORT peerPort = 4433; + ULONG wait = NX_WAIT_FOREVER; + // … initialise udpSocket and peerAddr … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + \endcode + + \sa wolfSSL_SetIO_NetX + \sa NetX_SendTo + \sa NetX_ReceiveFrom +*/ +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, USHORT nxport, + ULONG waitoption); + + /*! \brief This function sets the callback for the CBIOCookie member of the WOLFSSL_CTX structure. The CallbackGenCookie type is a function pointer diff --git a/src/internal.c b/src/internal.c index 54975ed4318..6c2dd886ffb 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2707,12 +2707,12 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifdef HAVE_NETX ctx->CBIORecv = NetX_Receive; ctx->CBIOSend = NetX_Send; - #ifdef WOLFSSL_DTLS + #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) if (method->version.major == DTLS_MAJOR) { ctx->CBIORecv = NetX_ReceiveFrom; ctx->CBIOSend = NetX_SendTo; } - #endif + #endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ #elif defined(WOLFSSL_APACHE_MYNEWT) && !defined(WOLFSSL_LWIP) ctx->CBIORecv = Mynewt_Receive; ctx->CBIOSend = Mynewt_Send; diff --git a/src/wolfio.c b/src/wolfio.c index 82888e37c7e..0765e457198 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2637,7 +2637,8 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) } } -#ifdef WOLFSSL_DTLS +/* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) /* The NetX receive callback for DTLS * return : bytes read, or error */ @@ -2648,8 +2649,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) ULONG total; ULONG copied = 0; UINT status; - - (void)ssl; + ULONG waitOption; if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); @@ -2657,9 +2657,33 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) } if (nxCtx->nxPacket == NULL) { + /* Compute wait ticks from the current DTLS retransmit timeout so the + * DTLS state machine can drive retransmission on packet loss. */ + if (!wolfSSL_dtls_get_using_nonblock(ssl)) { + int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); + #ifdef WOLFSSL_DTLS13 + if (wolfSSL_dtls13_use_quick_timeout(ssl) && + IsAtLeastTLSv1_3(ssl->version)) + dtls_timeout = dtls_timeout / 4; + #endif + waitOption = (dtls_timeout > 0) + ? (ULONG)dtls_timeout * NX_IP_PERIODIC_RATE + : nxCtx->nxWait; + } + else { + waitOption = NX_NO_WAIT; /* non-blocking */ + } + status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, - nxCtx->nxWait); + waitOption); if (status != NX_SUCCESS) { + if (status == NX_NO_PACKET) { + /* Normal receive timeout — allow DTLS to retransmit */ + WOLFSSL_MSG("NetX Recv timeout"); + return wolfSSL_dtls_get_using_nonblock(ssl) + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } WOLFSSL_MSG("NetX Recv receive error"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -2705,8 +2729,7 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) (void)ssl; - if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL - || nxCtx->nxdIp == NULL || nxCtx->nxPort == NULL) { + if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Send NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -2726,38 +2749,37 @@ int NetX_SendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - if(nxCtx->nxdIp->nxd_ip_version == NX_IP_VERSION_V4) - { - status = nx_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp->nxd_ip_address.v4, (UINT)(*nxCtx->nxPort)); - if (status != NX_SUCCESS) { - nx_packet_release(packet); - WOLFSSL_MSG("NetX Send socket send error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } - }else - { - status = nxd_udp_socket_send(nxCtx->nxUdpSocket, packet, nxCtx->nxdIp, (UINT)(*nxCtx->nxPort)); - if (status != NX_SUCCESS) { - nx_packet_release(packet); - WOLFSSL_MSG("NetX Send socket send error"); - return WOLFSSL_CBIO_ERR_GENERAL; - } + if (nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V4) { + status = nx_udp_socket_send(nxCtx->nxUdpSocket, packet, + nxCtx->nxdIp.nxd_ip_address.v4, + (UINT)nxCtx->nxPort); + } + else { + status = nxd_udp_socket_send(nxCtx->nxUdpSocket, packet, + &nxCtx->nxdIp, (UINT)nxCtx->nxPort); + } + if (status != NX_SUCCESS) { + nx_packet_release(packet); + WOLFSSL_MSG("NetX Send socket send error"); + return WOLFSSL_CBIO_ERR_GENERAL; } return sz; } -/* like set_fd, but for default NetX UDP context */ -void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS *nxdip, USHORT *nxport, ULONG waitoption) +/* like set_fd, but for default NetX Duo UDP context */ +void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, USHORT nxport, + ULONG waitoption) { if (ssl) { - ssl->nxCtx.nxUdpSocket = nxsocket; - ssl->nxCtx.nxdIp = nxdip; - ssl->nxCtx.nxPort = nxport; - ssl->nxCtx.nxWait = waitoption; + ssl->nxCtx.nxUdpSocket = nxsocket; + ssl->nxCtx.nxdIp = nxdip; + ssl->nxCtx.nxPort = nxport; + ssl->nxCtx.nxWait = waitoption; } } -#endif /* WOLFSSL_DTLS */ +#endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ #endif /* HAVE_NETX */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 92f3920279c..40a760eeca9 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5776,11 +5776,12 @@ typedef struct DtlsMsg { NX_PACKET* nxPacket; /* incoming packet handle for short reads */ ULONG nxOffset; /* offset already read from nxPacket */ ULONG nxWait; /* wait option flag */ -#ifdef WOLFSSL_DTLS +/* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) NX_UDP_SOCKET* nxUdpSocket; /* send/recv udp socket handle */ - NXD_ADDRESS* nxdIp; /* IP address for udp send*/ - USHORT* nxPort; /* Port number for udp recv*/ -#endif + NXD_ADDRESS nxdIp; /* destination IP address for udp send */ + USHORT nxPort; /* destination port for udp send */ +#endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ } NetX_Ctx; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 16dddb417d9..fd0652f3499 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -792,14 +792,15 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption); -#ifdef WOLFSSL_DTLS +/* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) WOLFSSL_LOCAL int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_SendTo(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, - NXD_ADDRESS *nxdip, - USHORT* nxport, + WOLFSSL_API void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, + NXD_ADDRESS nxdip, + USHORT nxport, ULONG waitoption); -#endif +#endif /* WOLFSSL_DTLS && WOLFSSL_NETX_DUO */ #endif /* HAVE_NETX */ #ifdef MICRIUM From f0f7ea664685cd8cf15539e24f7cd330e515d937 Mon Sep 17 00:00:00 2001 From: hmohide Date: Mon, 15 Jun 2026 11:49:29 +0530 Subject: [PATCH 10/12] wolfio: fix review comments for DTLS NetX UDP support - Replace non-ASCII em-dash with ASCII hyphen in NetX_ReceiveFrom comment to pass wolfSSL encoding/whitespace CI check - Add WOLFSSL_NETX_DUO to .wolfssl_known_macro_extras so the macro checker no longer flags it as unrecognized --- .wolfssl_known_macro_extras | 1 + src/wolfio.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index c23fd8949e5..380c8886d41 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -814,6 +814,7 @@ WOLFSSL_MONT_RED_CT WOLFSSL_MP_COND_COPY WOLFSSL_MP_INVMOD_CONSTANT_TIME WOLFSSL_MULTICIRCULATE_ALTNAMELIST +WOLFSSL_NETX_DUO WOLFSSL_NEW_PRIME_CHECK WOLFSSL_NOSHA3_384 WOLFSSL_NOT_WINDOWS_API diff --git a/src/wolfio.c b/src/wolfio.c index 0765e457198..5071435af35 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2678,7 +2678,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) waitOption); if (status != NX_SUCCESS) { if (status == NX_NO_PACKET) { - /* Normal receive timeout — allow DTLS to retransmit */ + /* Normal receive timeout - allow DTLS to retransmit */ WOLFSSL_MSG("NetX Recv timeout"); return wolfSSL_dtls_get_using_nonblock(ssl) ? WOLFSSL_CBIO_ERR_WANT_READ From 918ed462d35c0878cbe117d8bac98b8efed9dffc Mon Sep 17 00:00:00 2001 From: hmohide Date: Tue, 16 Jun 2026 10:56:02 +0530 Subject: [PATCH 11/12] updated review comments --- doc/dox_comments/header_files-ja/wolfio.h | 22 ++-- doc/dox_comments/header_files/wolfio.h | 22 ++-- src/wolfio.c | 145 ++++++++++++++++------ 3 files changed, 132 insertions(+), 57 deletions(-) diff --git a/doc/dox_comments/header_files-ja/wolfio.h b/doc/dox_comments/header_files-ja/wolfio.h index dedd128dd06..8813cd719ad 100644 --- a/doc/dox_comments/header_files-ja/wolfio.h +++ b/doc/dox_comments/header_files-ja/wolfio.h @@ -409,17 +409,17 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); \return none 戻り値なし。 \param ssl wolfSSL_new()を使用して作成されたWOLFSSL構造体へのポインタ。 - \param nxSocket nxCtx構造体のnxTcpSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 - \param waitOption nxCtx構造体のnxWaitメンバーに設定されるULONG型。 + \param nxsocket nxCtx構造体のnxTcpSocketメンバーに設定されるNX_TCP_SOCKET型へのポインタ。 + \param waitoption nxCtx構造体のnxWaitメンバーに設定されるULONG型。 _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_TCP_SOCKET* nxSocket; - ULONG waitOption; + NX_TCP_SOCKET* nxsocket; + ULONG waitoption; … - if(ssl != NULL || nxSocket != NULL || waitOption <= 0){ - wolfSSL_SetIO_NetX(ssl, nxSocket, waitOption); + if(ssl != NULL || nxsocket != NULL || waitoption <= 0){ + wolfSSL_SetIO_NetX(ssl, nxsocket, waitoption); } else { // 適切なパラメータを渡す必要があります。 } @@ -450,12 +450,12 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_UDP_SOCKET udpSocket; - NXD_ADDRESS peerAddr; - USHORT peerPort = 4433; + NX_UDP_SOCKET udpsocket; + NXD_ADDRESS peeraddr; + USHORT peerport = 4433; ULONG wait = NX_WAIT_FOREVER; - // … udpSocketとpeerAddrを初期化 … - wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + // … udpsocketとpeeraddrを初期化 … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpsocket, peeraddr, peerport, wait); \endcode \sa wolfSSL_SetIO_NetX diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index c685eb8d89a..86f176d5730 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -456,19 +456,19 @@ void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); \return none No returns. \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). - \param nxSocket a pointer to type NX_TCP_SOCKET that is set to the + \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 + \param waitoption a ULONG type that is set to the nxWait member of the nxCtx structure. _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_TCP_SOCKET* nxSocket; - ULONG waitOption; + NX_TCP_SOCKET* nxsocket; + ULONG waitoption; … - if(ssl != NULL || nxSocket != NULL || waitOption <= 0){ - wolfSSL_SetIO_NetX(ssl, nxSocket, waitOption); + if(ssl != NULL || nxsocket != NULL || waitoption <= 0){ + wolfSSL_SetIO_NetX(ssl, nxsocket, waitoption); } else { // You need to pass in good parameters. } @@ -500,12 +500,12 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, _Example_ \code WOLFSSL* ssl = wolfSSL_new(ctx); - NX_UDP_SOCKET udpSocket; - NXD_ADDRESS peerAddr; - USHORT peerPort = 4433; + NX_UDP_SOCKET udpsocket; + NXD_ADDRESS peeraddr; + USHORT peerport = 4433; ULONG wait = NX_WAIT_FOREVER; - // … initialise udpSocket and peerAddr … - wolfSSL_SetIO_NetX_Dtls(ssl, &udpSocket, peerAddr, peerPort, wait); + // … initialise udpsocket and peeraddr … + wolfSSL_SetIO_NetX_Dtls(ssl, &udpsocket, peeraddr, peerport, wait); \endcode \sa wolfSSL_SetIO_NetX diff --git a/src/wolfio.c b/src/wolfio.c index 5071435af35..73e4f0aa0b4 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2639,67 +2639,142 @@ void wolfSSL_SetIO_NetX(WOLFSSL* ssl, NX_TCP_SOCKET* nxsocket, ULONG waitoption) /* WOLFSSL_NETX_DUO: requires ThreadX NetX Duo (NXD_ADDRESS, nxd_udp_socket_send) */ #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_NETX_DUO) +static void NetX_ResetPacket(NetX_Ctx* nxCtx) +{ + if (nxCtx->nxPacket != NULL) { + nx_packet_release(nxCtx->nxPacket); + nxCtx->nxPacket = NULL; + } + nxCtx->nxOffset = 0; +} + +static int NetX_PeerAddrEqual(const NXD_ADDRESS* left, const NXD_ADDRESS* right) +{ + if (left->nxd_ip_version != right->nxd_ip_version) + return 0; + + if (left->nxd_ip_version == NX_IP_VERSION_V4) + return left->nxd_ip_address.v4 == right->nxd_ip_address.v4; + + return left->nxd_ip_address.v6[0] == right->nxd_ip_address.v6[0] && + left->nxd_ip_address.v6[1] == right->nxd_ip_address.v6[1] && + left->nxd_ip_address.v6[2] == right->nxd_ip_address.v6[2] && + left->nxd_ip_address.v6[3] == right->nxd_ip_address.v6[3]; +} + /* The NetX receive callback for DTLS * return : bytes read, or error */ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) { NetX_Ctx* nxCtx = (NetX_Ctx*)ctx; + NXD_ADDRESS srcIp; ULONG left; ULONG total; ULONG copied = 0; + UINT srcPort; UINT status; ULONG waitOption; + int dtls_timeout; + int usingNonblock; + byte doDtlsTimeout; if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); return WOLFSSL_CBIO_ERR_GENERAL; } - if (nxCtx->nxPacket == NULL) { - /* Compute wait ticks from the current DTLS retransmit timeout so the - * DTLS state machine can drive retransmission on packet loss. */ - if (!wolfSSL_dtls_get_using_nonblock(ssl)) { - int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); - #ifdef WOLFSSL_DTLS13 - if (wolfSSL_dtls13_use_quick_timeout(ssl) && - IsAtLeastTLSv1_3(ssl->version)) - dtls_timeout = dtls_timeout / 4; - #endif - waitOption = (dtls_timeout > 0) - ? (ULONG)dtls_timeout * NX_IP_PERIODIC_RATE - : nxCtx->nxWait; - } - else { - waitOption = NX_NO_WAIT; /* non-blocking */ - } + usingNonblock = wolfSSL_dtls_get_using_nonblock(ssl); - status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, - waitOption); - if (status != NX_SUCCESS) { - if (status == NX_NO_PACKET) { - /* Normal receive timeout - allow DTLS to retransmit */ - WOLFSSL_MSG("NetX Recv timeout"); - return wolfSSL_dtls_get_using_nonblock(ssl) - ? WOLFSSL_CBIO_ERR_WANT_READ - : WOLFSSL_CBIO_ERR_TIMEOUT; + /* Don't use ssl->options.handShakeDone since it is true even if + * we are in the process of renegotiation. */ + doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE; +#ifdef WOLFSSL_DTLS13 + if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) { + doDtlsTimeout = + doDtlsTimeout || ssl->dtls13Rtx.rtxRecords != NULL || + (ssl->dtls13FastTimeout && ssl->dtls13Rtx.seenRecords != NULL); + } +#endif /* WOLFSSL_DTLS13 */ + + do { + if (nxCtx->nxPacket == NULL) { + /* Compute wait ticks from the DTLS retransmit timeout while a + * handshake/RTX timer is active, otherwise honor nxWait. */ + if (!usingNonblock) { + dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); + if (!doDtlsTimeout) + dtls_timeout = 0; +#ifdef WOLFSSL_DTLS13 + if (dtls_timeout > 0 && wolfSSL_dtls13_use_quick_timeout(ssl) && + IsAtLeastTLSv1_3(ssl->version)) { + if (dtls_timeout > 4) + dtls_timeout /= 4; + else + dtls_timeout = 1; + } +#endif /* WOLFSSL_DTLS13 */ + waitOption = (dtls_timeout > 0) + ? (ULONG)dtls_timeout * NX_IP_PERIODIC_RATE + : nxCtx->nxWait; + } + else { + waitOption = NX_NO_WAIT; /* non-blocking */ + } + + status = nx_udp_socket_receive(nxCtx->nxUdpSocket, &nxCtx->nxPacket, + waitOption); + if (status != NX_SUCCESS) { + if (status == NX_NO_PACKET) { + /* Normal receive timeout - allow DTLS to retransmit */ + WOLFSSL_MSG("NetX Recv timeout"); + return usingNonblock + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } + WOLFSSL_MSG("NetX Recv receive error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + status = nxd_udp_source_extract(nxCtx->nxPacket, &srcIp, &srcPort); + if (status != NX_SUCCESS) { + NetX_ResetPacket(nxCtx); + WOLFSSL_MSG("NetX Recv source extract error"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + + if ((USHORT)srcPort != nxCtx->nxPort || + !NetX_PeerAddrEqual(&srcIp, &nxCtx->nxdIp)) { + WOLFSSL_MSG("NetX Recv ignored packet from invalid peer"); + NetX_ResetPacket(nxCtx); + continue; } - WOLFSSL_MSG("NetX Recv receive error"); - return WOLFSSL_CBIO_ERR_GENERAL; } - } - if (nxCtx->nxPacket) { status = nx_packet_length_get(nxCtx->nxPacket, &total); if (status != NX_SUCCESS) { + NetX_ResetPacket(nxCtx); WOLFSSL_MSG("NetX Recv length get error"); return WOLFSSL_CBIO_ERR_GENERAL; } + if (total == 0) { + WOLFSSL_MSG("Ignoring 0-length datagram"); + NetX_ResetPacket(nxCtx); + continue; + } + + if (nxCtx->nxOffset > total) { + NetX_ResetPacket(nxCtx); + WOLFSSL_MSG("NetX Recv invalid packet offset"); + return WOLFSSL_CBIO_ERR_GENERAL; + } + left = total - nxCtx->nxOffset; status = nx_packet_data_extract_offset(nxCtx->nxPacket, nxCtx->nxOffset, buf, sz, &copied); if (status != NX_SUCCESS) { + NetX_ResetPacket(nxCtx); WOLFSSL_MSG("NetX Recv data extract offset error"); return WOLFSSL_CBIO_ERR_GENERAL; } @@ -2708,13 +2783,13 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) if (copied == left) { WOLFSSL_MSG("NetX Recv Drained packet"); - nx_packet_release(nxCtx->nxPacket); - nxCtx->nxPacket = NULL; - nxCtx->nxOffset = 0; + NetX_ResetPacket(nxCtx); } - } - return copied; + return copied; + } while (1); + + /* unreachable */ } /* The NetX send callback for DTLS From d6d55a60b75933f14da1c9f7fa4f3693f3a874e0 Mon Sep 17 00:00:00 2001 From: hmohide Date: Thu, 18 Jun 2026 20:10:35 +0530 Subject: [PATCH 12/12] Updated the review comments --- doc/dox_comments/header_files-ja/wolfio.h | 1 - doc/dox_comments/header_files/wolfio.h | 1 - src/wolfio.c | 43 +++++++++++++++++++---- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/doc/dox_comments/header_files-ja/wolfio.h b/doc/dox_comments/header_files-ja/wolfio.h index 8813cd719ad..d21eed171eb 100644 --- a/doc/dox_comments/header_files-ja/wolfio.h +++ b/doc/dox_comments/header_files-ja/wolfio.h @@ -466,7 +466,6 @@ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS nxdip, USHORT nxport, ULONG waitoption); - /*! \brief この関数は、WOLFSSL_CTX構造体のCBIOCookieメンバーのコールバックを設定します。 CallbackGenCookie型は関数ポインタで、次のシグネチャを持ちます: diff --git a/doc/dox_comments/header_files/wolfio.h b/doc/dox_comments/header_files/wolfio.h index 86f176d5730..42a39dfe67b 100644 --- a/doc/dox_comments/header_files/wolfio.h +++ b/doc/dox_comments/header_files/wolfio.h @@ -516,7 +516,6 @@ void wolfSSL_SetIO_NetX_Dtls(WOLFSSL* ssl, NX_UDP_SOCKET* nxsocket, NXD_ADDRESS nxdip, USHORT nxport, ULONG waitoption); - /*! \brief This function sets the callback for the CBIOCookie member of the WOLFSSL_CTX structure. The CallbackGenCookie type is a function pointer diff --git a/src/wolfio.c b/src/wolfio.c index 73e4f0aa0b4..116d7abf9ed 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -2678,6 +2678,12 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) int dtls_timeout; int usingNonblock; byte doDtlsTimeout; + word32 invalidPeerPackets = 0; +#if defined(DTLS_RECEIVEFROM_MAX_INVALID_PEER) + const word32 maxInvalidPeerPackets = DTLS_RECEIVEFROM_MAX_INVALID_PEER; +#else + const word32 maxInvalidPeerPackets = 10; +#endif if (nxCtx == NULL || nxCtx->nxUdpSocket == NULL) { WOLFSSL_MSG("NetX Recv NULL parameters"); @@ -2743,11 +2749,28 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - if ((USHORT)srcPort != nxCtx->nxPort || - !NetX_PeerAddrEqual(&srcIp, &nxCtx->nxdIp)) { - WOLFSSL_MSG("NetX Recv ignored packet from invalid peer"); - NetX_ResetPacket(nxCtx); - continue; + if (nxCtx->nxPort != 0 && + (nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V4 || + nxCtx->nxdIp.nxd_ip_version == NX_IP_VERSION_V6)) { + if ((USHORT)srcPort != nxCtx->nxPort || + !NetX_PeerAddrEqual(&srcIp, &nxCtx->nxdIp)) { + WOLFSSL_MSG("NetX Recv ignored packet from invalid peer"); + NetX_ResetPacket(nxCtx); + if (doDtlsTimeout) { + invalidPeerPackets++; + if (invalidPeerPackets > maxInvalidPeerPackets) { + return usingNonblock + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } + } + continue; + } + } + else { + /* No peer preset: accept first datagram and lock onto source. */ + nxCtx->nxdIp = srcIp; + nxCtx->nxPort = (USHORT)srcPort; } } @@ -2761,6 +2784,14 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) if (total == 0) { WOLFSSL_MSG("Ignoring 0-length datagram"); NetX_ResetPacket(nxCtx); + if (doDtlsTimeout) { + invalidPeerPackets++; + if (invalidPeerPackets > maxInvalidPeerPackets) { + return usingNonblock + ? WOLFSSL_CBIO_ERR_WANT_READ + : WOLFSSL_CBIO_ERR_TIMEOUT; + } + } continue; } @@ -2789,7 +2820,7 @@ int NetX_ReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) return copied; } while (1); - /* unreachable */ + return (int)copied; } /* The NetX send callback for DTLS