Skip to content

Commit 644f617

Browse files
authored
Merge pull request #10290 from LinuxJedi/emnet
Fix emNET support and add tests
2 parents 9b11677 + 3720a94 commit 644f617

8 files changed

Lines changed: 520 additions & 7 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: emNET non-blocking handshake test
2+
3+
# START OF COMMON SECTION
4+
on:
5+
push:
6+
branches: [ 'master', 'main', 'release/**' ]
7+
pull_request:
8+
branches: [ '*' ]
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
# END OF COMMON SECTION
14+
15+
# Build wolfSSL with -DWOLFSSL_EMNET using the clean-room shim in
16+
# tests/emnet/ (IP/IP.h + emnet_shim.c), link a non-blocking TLS 1.3
17+
# handshake test, and run it. The test exercises the WOLFSSL_EMNET
18+
# path in wolfSSL_LastError() and asserts that would-block events
19+
# surface as WANT_READ/WANT_WRITE and the handshake completes,
20+
# guarding against regressions in the emNET error-translation logic.
21+
22+
jobs:
23+
emnet_nonblock:
24+
name: wolfSSL emNET non-blocking handshake
25+
if: github.repository_owner == 'wolfssl'
26+
runs-on: ubuntu-24.04
27+
timeout-minutes: 20
28+
steps:
29+
- name: Checkout wolfSSL
30+
uses: actions/checkout@v4
31+
32+
- name: Install build deps
33+
uses: ./.github/actions/install-apt-deps
34+
with:
35+
packages: autoconf automake libtool build-essential
36+
37+
- name: Bootstrap
38+
run: ./autogen.sh
39+
40+
- name: Configure wolfSSL (WOLFSSL_EMNET + emNET shim headers)
41+
run: |
42+
./configure \
43+
--enable-static --disable-shared \
44+
--enable-tls13 --disable-oldtls \
45+
--enable-ecc --disable-examples \
46+
--disable-benchmark --disable-crypttests \
47+
CFLAGS="-DWOLFSSL_EMNET -I$(pwd)/tests/emnet"
48+
49+
# The WOLFSSL_EMNET branch in src/wolfio.c calls IP_SOCK_getsockopt
50+
# which only resolves against the test shim. Build only the static
51+
# library; examples/benchmark/crypttests are disabled above, but
52+
# explicitly target the .a to avoid pulling in any residual link
53+
# targets that would fail with an undefined reference.
54+
- name: Build wolfSSL static library
55+
run: make -j$(nproc) src/libwolfssl.la
56+
57+
- name: Build emNET non-blocking test
58+
run: make -C tests/emnet
59+
60+
- name: Run emNET non-blocking test
61+
run: make -C tests/emnet run

.wolfssl_known_macro_extras

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,6 @@ WOLFSSL_ECDSA_SET_K_ONE_LOOP
761761
WOLFSSL_EC_POINT_CMP_JACOBIAN
762762
WOLFSSL_ED448_NO_LARGE_CODE
763763
WOLFSSL_EDDSA_CHECK_PRIV_ON_SIGN
764-
WOLFSSL_EMNET
765764
WOLFSSL_ESPWROOM32
766765
WOLFSSL_EVP_PRINT
767766
WOLFSSL_EXPORT_INT

src/wolfio.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,28 @@ static WC_INLINE int wolfSSL_LastError(int err, SOCKET_T sd)
151151
return WSAGetLastError();
152152
#elif defined(EBSNET)
153153
return xn_getlasterror();
154-
#elif defined(WOLFSSL_LINUXKM) || defined(WOLFSSL_EMNET)
154+
#elif defined(WOLFSSL_LINUXKM)
155155
return -err; /* Return provided error value with corrected sign. */
156+
#elif defined(WOLFSSL_EMNET)
157+
/* Any negative recv/send return is a SOCKET_ERROR sentinel under
158+
* emNET; the canonical IP_ERR_* lives in the socket SO_ERROR.
159+
* Retrieving it via IP_SOCK_getsockopt works across both emNET
160+
* integrator conventions (native: recv returns IP_ERR_* directly;
161+
* POSIX facade: recv returns -1 with errno set). If the lookup
162+
* itself fails, fall back to IP_ERR_FAULT rather than returning
163+
* the raw -1 sentinel - the latter matches no SOCKET_E* constant
164+
* and would regress into WOLFSSL_CBIO_ERR_GENERAL. */
165+
if (err < 0) {
166+
int sock_err = err;
167+
if (IP_SOCK_getsockopt(sd, SOL_SOCKET, SO_ERROR, &sock_err,
168+
(int)sizeof(sock_err)) == 0) {
169+
err = sock_err;
170+
}
171+
else if (err == -1) {
172+
err = IP_ERR_FAULT;
173+
}
174+
}
175+
return err;
156176
#elif defined(FUSION_RTOS)
157177
#include <fclerrno.h>
158178
return FCL_GET_ERRNO;
@@ -170,10 +190,6 @@ static WC_INLINE int wolfSSL_LastError(int err, SOCKET_T sd)
170190
}
171191
return err;
172192
}
173-
#elif defined(WOLFSSL_EMNET)
174-
/* Get the real socket error */
175-
IP_SOCK_getsockopt(sd, SOL_SOCKET, SO_ERROR, &err, (int)sizeof(old));
176-
return err;
177193
#else
178194
return errno;
179195
#endif

tests/emnet/IP/IP.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* IP.h -- clean-room shim for the subset of SEGGER emNET (embOS/IP) API
2+
* that wolfSSL's WOLFSSL_EMNET port compiles against. Written from the
3+
* public API surface documented in SEGGER UM07001; contains no SEGGER
4+
* source.
5+
*
6+
* Scope: enough to build wolfSSL with -DWOLFSSL_EMNET on a POSIX host
7+
* for CI test purposes. Only error constants and IP_SOCK_getsockopt
8+
* are provided here; send/recv fall through to glibc's POSIX
9+
* implementation, and the canonical IP_ERR_* lookup is emulated by
10+
* IP_SOCK_getsockopt in emnet_shim.c.
11+
*/
12+
13+
#ifndef WOLFSSL_EMNET_SHIM_IP_H
14+
#define WOLFSSL_EMNET_SHIM_IP_H
15+
16+
#include <sys/types.h>
17+
#include <sys/socket.h>
18+
#include <netinet/in.h>
19+
#include <arpa/inet.h>
20+
#include <unistd.h>
21+
#include <fcntl.h>
22+
#include <errno.h>
23+
24+
#ifdef __cplusplus
25+
extern "C" {
26+
#endif
27+
28+
/* emNET error codes (UM07001). Values match the public ABI. */
29+
#define IP_ERR_CONN_ABORTED (-5)
30+
#define IP_ERR_WOULD_BLOCK (-6)
31+
#define IP_ERR_CONN_REFUSED (-7)
32+
#define IP_ERR_CONN_RESET (-8)
33+
#define IP_ERR_PIPE (-13)
34+
#define IP_ERR_FAULT (-25)
35+
36+
/* BSD-style socket option retrieval. Signature matches the SEGGER
37+
* emNET API (UM07001, IP_Socket.h): the length is passed by value as
38+
* a plain int, not a POSIX socklen_t* / int*. */
39+
int IP_SOCK_getsockopt(int hSock, int Level, int Name,
40+
void *pVal, int ValLen);
41+
42+
#ifdef __cplusplus
43+
}
44+
#endif
45+
46+
#endif /* WOLFSSL_EMNET_SHIM_IP_H */

tests/emnet/Makefile

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Build the emNET non-blocking handshake test.
2+
# Requires wolfSSL already configured + built at the repo root with
3+
# WOLFSSL_EMNET and the emnet IP include path, e.g.:
4+
#
5+
# cd $(repo_root)
6+
# ./autogen.sh
7+
# ./configure --enable-static --disable-shared --enable-tls13 \
8+
# --disable-oldtls CFLAGS="-DWOLFSSL_EMNET \
9+
# -I$$(pwd)/tests/emnet"
10+
# make
11+
# make -C tests/emnet run
12+
#
13+
# recv/send fall through to glibc's POSIX implementation (-1 + errno
14+
# on would-block); wolfSSL_LastError then retrieves the canonical
15+
# IP_ERR_* via IP_SOCK_getsockopt in the shim. This is the integrator
16+
# convention that reproduces ticket #21673 and the one wolfSSL's
17+
# WOLFSSL_EMNET error path must handle correctly.
18+
19+
CURDIR := $(shell pwd)
20+
WOLFSSL_ROOT := $(abspath $(CURDIR)/../..)
21+
WOLFSSL_LIB := $(WOLFSSL_ROOT)/src/.libs/libwolfssl.a
22+
23+
CC ?= cc
24+
CFLAGS_TEST := -Wall -Wextra -O2 -g \
25+
-DWOLFSSL_EMNET \
26+
-I$(CURDIR) \
27+
-I$(WOLFSSL_ROOT)
28+
LIBS_TEST := $(WOLFSSL_LIB) -lpthread -lm
29+
30+
TEST_BIN := emnet_nonblock_test
31+
32+
.PHONY: all run clean check-lib
33+
34+
all: $(TEST_BIN)
35+
36+
check-lib:
37+
@if [ ! -f "$(WOLFSSL_LIB)" ]; then \
38+
echo "error: $(WOLFSSL_LIB) not found."; \
39+
echo "Build wolfSSL first (see header of this Makefile)."; \
40+
exit 1; \
41+
fi
42+
43+
# check-lib is an order-only dependency (after |) so its phony status
44+
# does not force the binary to relink on every `make` invocation.
45+
$(TEST_BIN): emnet_nonblock_test.o emnet_shim.o | check-lib
46+
$(CC) -o $@ emnet_nonblock_test.o emnet_shim.o $(LIBS_TEST)
47+
48+
emnet_nonblock_test.o: emnet_nonblock_test.c
49+
$(CC) $(CFLAGS_TEST) -c $< -o $@
50+
51+
emnet_shim.o: emnet_shim.c IP/IP.h
52+
$(CC) $(CFLAGS_TEST) -c $< -o $@
53+
54+
# Run from the repo root so the relative cert paths resolve.
55+
run: $(TEST_BIN)
56+
cd $(WOLFSSL_ROOT) && ./tests/emnet/$(TEST_BIN)
57+
58+
clean:
59+
rm -f *.o $(TEST_BIN)

0 commit comments

Comments
 (0)