From 18d159e55a0700382d599f4376bb818cf92dc9f8 Mon Sep 17 00:00:00 2001 From: sebastian-carpenter Date: Mon, 23 Mar 2026 11:37:49 -0600 Subject: [PATCH] improved waits for ports/ready_files in ocsp tests --- .../ocsp-stapling-with-ca-as-responder.test | 30 ++++++++++++- .../ocsp-stapling-with-wolfssl-responder.test | 10 ++--- scripts/ocsp-stapling.test | 41 +++++++++++++---- scripts/ocsp-stapling2.test | 45 ++++++++++++++++--- scripts/ocsp-stapling_tls13multi.test | 45 ++++++++++++++++--- wolfssl/test.h | 17 ++++++- 6 files changed, 162 insertions(+), 26 deletions(-) diff --git a/scripts/ocsp-stapling-with-ca-as-responder.test b/scripts/ocsp-stapling-with-ca-as-responder.test index 74fd02e1966..15631c9dc5b 100755 --- a/scripts/ocsp-stapling-with-ca-as-responder.test +++ b/scripts/ocsp-stapling-with-ca-as-responder.test @@ -98,6 +98,32 @@ remove_single_rF(){ fi } +wait_for_port(){ + local port=$1 + local pid=${2-} + local counter=0 + while true; do + if command -v ss &>/dev/null; then + ss -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + elif command -v netstat &>/dev/null; then + netstat -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + else + # best effort! + sleep 4 && break + fi + if [[ -n "$pid" ]] && ! kill -0 "$pid" 2>/dev/null; then + echo "pid $pid for port $port exited before becoming ready. bailing..." + exit 1 + fi + sleep 0.1 + counter=$((counter + 1)) + if [ "$counter" -ge 40 ]; then + echo "timed out waiting for port $port" + exit 1 + fi + done +} + #create a configure file for cert generation with the port 0 solution create_new_cnf() { printf '%s\n' "Random Port Selected: $RPORTSELECTED" @@ -251,8 +277,8 @@ openssl ocsp -port $port1 -nmin 1 \ -CA certs/ocsp/intermediate1-ca-cert.pem \ "$@" \ & - -sleep 0.1 +ocsp_pid=$! +wait_for_port "$port1" "$ocsp_pid" # "jobs" is not portable for posix. Must use bash interpreter! [ $(jobs -r | wc -l) -ne 1 ] && printf '\n\n%s\n' "Setup ocsp responder failed, skipping" && exit 0 diff --git a/scripts/ocsp-stapling-with-wolfssl-responder.test b/scripts/ocsp-stapling-with-wolfssl-responder.test index f7ca8bafd5f..03c91830a6e 100755 --- a/scripts/ocsp-stapling-with-wolfssl-responder.test +++ b/scripts/ocsp-stapling-with-wolfssl-responder.test @@ -473,7 +473,6 @@ if [ "$stapling_v1" == "yes" ]; then -p $port5 & server_pid5=$! wait_for_readyFile $ready_file5 $server_pid5 $port5 - sleep 0.1 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -p $port5 RESULT=$? [ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection 2 succeeded $RESULT" \ @@ -537,7 +536,7 @@ if [ "$stapling_v1" == "yes" ]; then -k certs/ocsp/server1-key.pem -u -v 3 \ -p $port5 & server_pid5=$! - sleep 0.2 + wait_for_readyFile $ready_file5 $server_pid5 $port5 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -u -v 3 \ -W 1 -p $port5 RESULT=$? @@ -553,7 +552,7 @@ if [ "$stapling_v1" == "yes" ]; then -k certs/ocsp/server1-key.pem -u -v 4 \ -p $port5 & server_pid5=$! - sleep 0.2 + wait_for_readyFile $ready_file5 $server_pid5 $port5 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -u -v 4 \ -W 1 -p $port5 RESULT=$? @@ -619,7 +618,8 @@ if [ "$stapling_v2" == "yes" ]; then ./examples/server/server -c certs/ocsp/server4-cert.pem \ -k certs/ocsp/server4-key.pem -R $ready_file5 \ -p $port5 & - sleep 0.1 + server_pid5=$! + wait_for_readyFile $ready_file5 $server_pid5 $port5 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 3 -v 3 \ -p $port5 RESULT=$? @@ -663,7 +663,7 @@ if [ "$stapling_v2" == "yes" ]; then -k certs/ocsp/server3-key.pem -R $ready_file5 \ -p $port5 -u -v 3 & server_pid5=$! - sleep 0.2 + wait_for_readyFile $ready_file5 $server_pid5 $port5 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 2 -u -v 3 \ -p $port5 RESULT=$? diff --git a/scripts/ocsp-stapling.test b/scripts/ocsp-stapling.test index 85d02dec4b8..d92cc9b703b 100755 --- a/scripts/ocsp-stapling.test +++ b/scripts/ocsp-stapling.test @@ -134,6 +134,32 @@ remove_single_rF(){ fi } +wait_for_port(){ + local port=$1 + local pid=${2-} + local counter=0 + while true; do + if command -v ss &>/dev/null; then + ss -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + elif command -v netstat &>/dev/null; then + netstat -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + else + # best effort! + sleep 4 && break + fi + if [[ -n "$pid" ]] && ! kill -0 "$pid" 2>/dev/null; then + echo "pid $pid for port $port exited before becoming ready. bailing..." + exit 1 + fi + sleep 0.1 + counter=$((counter + 1)) + if [ "$counter" -ge 40 ]; then + echo "timed out waiting for port $port" + exit 1 + fi + done +} + retry_with_backoff() { local max_attempts=$1 shift @@ -365,8 +391,8 @@ openssl ocsp -port "$port2" -nmin 1 \ -rkey certs/ocsp/ocsp-responder-key.pem \ -CA certs/ocsp/intermediate1-ca-cert.pem \ "$@" & - -sleep 0.1 +ocsp_pid=$! +wait_for_port "$port2" "$ocsp_pid" # "jobs" is not portable for posix. Must use bash interpreter! [ "$(jobs -r | wc -l)" -ne 1 ] && \ printf '\n\n%s\n' "Setup ocsp responder failed, skipping" && exit 0 @@ -389,7 +415,6 @@ remove_single_rF "$ready_file2" -k certs/ocsp/server2-key.pem -p "$port3" & wolf_pid3=$! wait_for_readyFile "$ready_file2" "$wolf_pid3" "$port3" -sleep 0.1 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -p "$port3" RESULT=$? [ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection 2 succeeded $RESULT" \ @@ -449,13 +474,12 @@ fi if ./examples/client/client -? 2>&1 | grep -q 'DTLSv1.2'; then printf '%s\n\n' "------------- TEST CASE DTLS-1 SHOULD PASS -------------------" # client test against our own server, must staple - GOOD CERT - echo "$ready_file2" + remove_single_rF "$ready_file2" ./examples/server/server -c certs/ocsp/server1-cert.pem -R "$ready_file2" \ -k certs/ocsp/server1-key.pem -u -v 3 \ -p "$port3" & wolf_pid3=$! - - sleep 0.2 + wait_for_readyFile "$ready_file2" "$wolf_pid3" "$port3" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -u -v 3 \ -W 1 -p "$port3" RESULT=$? @@ -466,11 +490,12 @@ fi if [[ ("$dtls13" == "yes") && ("$tls13multi" == "no") ]]; then printf '%s\n\n' "------------- TEST CASE DTLS-2 SHOULD PASS -------------------" # client test against our own server, must staple - GOOD CERT + remove_single_rF "$ready_file2" ./examples/server/server -c certs/ocsp/server1-cert.pem -R "$ready_file2" \ -k certs/ocsp/server1-key.pem -u -v 4 \ -p "$port3" & wolf_pid3=$! - sleep 0.2 + wait_for_readyFile "$ready_file2" "$wolf_pid3" "$port3" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -u -v 4 \ -W 1 -p "$port3" RESULT=$? @@ -535,7 +560,7 @@ generate_port() { # Start OpenSSL server that has no OCSP responses to return generate_port openssl s_server "$V4V6_FLAG" -cert ./certs/server-cert.pem -key certs/server-key.pem -www -port "$port" & -MAX_TIMEOUT=10 +MAX_TIMEOUT=40 until nc -z localhost "$port" # Wait for openssl to be ready do sleep 0.05 diff --git a/scripts/ocsp-stapling2.test b/scripts/ocsp-stapling2.test index b3808e48e16..05a75195de9 100755 --- a/scripts/ocsp-stapling2.test +++ b/scripts/ocsp-stapling2.test @@ -129,6 +129,32 @@ remove_single_rF(){ fi } +wait_for_port(){ + local port=$1 + local pid=${2-} + local counter=0 + while true; do + if command -v ss &>/dev/null; then + ss -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + elif command -v netstat &>/dev/null; then + netstat -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + else + # best effort! + sleep 4 && break + fi + if [[ -n "$pid" ]] && ! kill -0 "$pid" 2>/dev/null; then + echo "pid $pid for port $port exited before becoming ready. bailing..." + exit 1 + fi + sleep 0.1 + counter=$((counter + 1)) + if [ "$counter" -ge 40 ]; then + echo "timed out waiting for port $port" + exit 1 + fi + done +} + #create a configure file for cert generation with the port 0 solution create_new_cnf() { printf '%s\n' "Random Ports Selected: $1 $2 $3 $4" @@ -329,6 +355,7 @@ openssl ocsp -port "$port1" -nmin 1 \ -CA certs/ocsp/root-ca-cert.pem \ "$@" \ & +ocsp_pid1=$! # OLD: ./certs/ocsp/ocspd-intermediate2-ca-issued-certs.sh & # NEW: openssl isn't being cleaned up, invoke directly in script for cleanup @@ -340,6 +367,7 @@ openssl ocsp -port "$port2" -nmin 1 \ -CA certs/ocsp/intermediate2-ca-cert.pem \ "$@" \ & +ocsp_pid2=$! # OLD: ./certs/ocsp/ocspd-intermediate3-ca-issued-certs.sh & # NEW: openssl isn't being cleaned up, invoke directly in script for cleanup @@ -351,6 +379,7 @@ openssl ocsp -port "$port3" -nmin 1 \ -CA certs/ocsp/intermediate3-ca-cert.pem \ "$@" \ & +ocsp_pid3=$! # NEW: openssl isn't being cleaned up, invoke directly in script for cleanup # purposes! @@ -361,8 +390,12 @@ openssl ocsp -port "$port4" -nmin 1 \ -CA certs/ocsp/root-ca-cert.pem \ "$@" \ & +ocsp_pid4=$! -sleep 0.1 +wait_for_port "$port1" "$ocsp_pid1" +wait_for_port "$port2" "$ocsp_pid2" +wait_for_port "$port3" "$ocsp_pid3" +wait_for_port "$port4" "$ocsp_pid4" # "jobs" is not portable for posix. Must use bash interpreter! [ "$(jobs -r | wc -l)" -ne 4 ] && printf '\n\n%s\n' "Setup ocsp responder failed, skipping" && exit 0 @@ -412,7 +445,8 @@ remove_single_rF "$ready_file5" ./examples/server/server -c certs/ocsp/server4-cert.pem \ -k certs/ocsp/server4-key.pem -R "$ready_file5" \ -p "$port5" & -sleep 0.1 +server_pid5=$! +wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 3 -v 3 \ -p "$port5" RESULT=$? @@ -466,7 +500,7 @@ remove_single_rF "$ready_file5" -k certs/ocsp/server4-key.pem -R "$ready_file5" \ -p "$port5" -H loadSSL & server_pid5=$! -sleep 0.1 +wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 3 -v 3 \ -p "$port5" RESULT=$? @@ -535,7 +569,7 @@ generate_port() { # Start OpenSSL server that has no OCSP responses to return generate_port openssl s_server -cert ./certs/server-cert.pem -key certs/server-key.pem -www -port "$port" & -MAX_TIMEOUT=10 +MAX_TIMEOUT=40 until nc -z localhost "$port" # Wait for openssl to be ready do sleep 0.05 @@ -567,11 +601,12 @@ printf '%s\n\n' "Test PASSED!" if ./examples/client/client -? 2>&1 | grep -q 'DTLS'; then printf '%s\n\n' "------------- TEST CASE DTLS-1 SHOULD PASS -------------------" # client test against our own server - GOOD CERTS +remove_single_rF "$ready_file5" ./examples/server/server -c certs/ocsp/server3-cert.pem \ -k certs/ocsp/server3-key.pem -R "$ready_file5" \ -p "$port5" -u -v 3 & server_pid5=$! -sleep 0.2 +wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 2 -u -v 3 \ -p "$port5" RESULT=$? diff --git a/scripts/ocsp-stapling_tls13multi.test b/scripts/ocsp-stapling_tls13multi.test index 4ae44cfc670..aae19f90ddd 100755 --- a/scripts/ocsp-stapling_tls13multi.test +++ b/scripts/ocsp-stapling_tls13multi.test @@ -147,6 +147,32 @@ remove_single_rF(){ rm "$1" fi } + +wait_for_port(){ + local port=$1 + local pid=${2-} + local counter=0 + while true; do + if command -v ss &>/dev/null; then + ss -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + elif command -v netstat &>/dev/null; then + netstat -lnt 2>/dev/null | grep -q ":${port}[[:space:]]" && break + else + # best effort! + sleep 4 && break + fi + if [[ -n "$pid" ]] && ! kill -0 "$pid" 2>/dev/null; then + echo "pid $pid for port $port exited before becoming ready. bailing..." + exit 1 + fi + sleep 0.1 + counter=$((counter + 1)) + if [ "$counter" -ge 40 ]; then + echo "timed out waiting for port $port" + exit 1 + fi + done +} #create a configure file for cert generation with the port 0 solution create_new_cnf() { echo "Random Ports Selected: $1 $2 $3 $4" @@ -347,6 +373,7 @@ openssl ocsp -port "$port1" -nmin 1 \ -CA certs/ocsp/root-ca-cert.pem \ "$@" \ & +ocsp_pid1=$! # OLD: ./certs/ocsp/ocspd-intermediate2-ca-issued-certs.sh & # NEW: openssl isn't being cleaned up, invoke directly in script for cleanup @@ -358,6 +385,7 @@ openssl ocsp -port "$port2" -nmin 1 \ -CA certs/ocsp/intermediate2-ca-cert.pem \ "$@" \ & +ocsp_pid2=$! # OLD: ./certs/ocsp/ocspd-intermediate3-ca-issued-certs.sh & # NEW: openssl isn't being cleaned up, invoke directly in script for cleanup @@ -369,6 +397,7 @@ openssl ocsp -port "$port3" -nmin 1 \ -CA certs/ocsp/intermediate3-ca-cert.pem \ "$@" \ & +ocsp_pid3=$! # NEW: openssl isn't being cleaned up, invoke directly in script for cleanup # purposes! @@ -379,8 +408,12 @@ openssl ocsp -port "$port4" -nmin 1 \ -CA certs/ocsp/root-ca-cert.pem \ "$@" \ & +ocsp_pid4=$! -sleep 0.1 +wait_for_port "$port1" "$ocsp_pid1" +wait_for_port "$port2" "$ocsp_pid2" +wait_for_port "$port3" "$ocsp_pid3" +wait_for_port "$port4" "$ocsp_pid4" # "jobs" is not portable for posix. Must use bash interpreter! [ "$(jobs -r | wc -l)" -ne 4 ] && printf '\n\n%s\n' "Setup ocsp responder failed, skipping" && exit 0 @@ -419,7 +452,8 @@ if [ "$tls13" == "yes" ]; then ./examples/server/server -c certs/ocsp/server4-cert.pem \ -k certs/ocsp/server4-key.pem -R "$ready_file5" \ -p "$port5" & - sleep 0.1 + server_pid5=$! + wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -v 4 \ -p "$port5" RESULT=$? @@ -474,7 +508,7 @@ if [ "$tls13" == "yes" ]; then -k certs/ocsp/server4-key.pem -R "$ready_file5" \ -p "$port5" -H loadSSL -v 4 & server_pid5=$! - sleep 0.1 + wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -v 4 \ -p "$port5" RESULT=$? @@ -490,11 +524,12 @@ fi if [ "$dtls13" == "yes" ]; then printf '%s\n\n' "------------- TEST CASE DTLS-1 SHOULD PASS ---------------" # client test against our own server - GOOD CERTS + remove_single_rF "$ready_file5" ./examples/server/server -c certs/ocsp/server3-cert.pem \ -k certs/ocsp/server3-key.pem -R "$ready_file5" \ -p "$port5" -u -v 4 & server_pid5=$! - sleep 0.2 + wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -u -v 4 \ -p "$port5" RESULT=$? @@ -508,7 +543,7 @@ if [ "$dtls13" == "yes" ]; then -k certs/ocsp/server4-key.pem -R "$ready_file5" \ -p "$port5" -v 4 & server_pid5=$! - sleep 0.2 + wait_for_readyFile "$ready_file5" "$server_pid5" "$port5" ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -v 4 \ -p "$port5" RESULT=$? diff --git a/wolfssl/test.h b/wolfssl/test.h index 41d7f4206dc..06b1034d9cc 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1814,6 +1814,21 @@ static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, if (udp) { udp_accept(sockfd, clientfd, useAnyAddr, port, args); + if (ready_file) { + #if (!defined(NO_FILESYSTEM) || defined(FORCE_BUFFER_TEST)) && \ + !defined(NETOS) + XFILE srf = (XFILE)NULL; + if (args) + ready = args->signal; + if (ready) { + srf = XFOPEN(ready->srfName, "w"); + if (srf) { + LIBCALL_CHECK_RET(fprintf(srf, "%d\n", (int)ready->port)); + fclose(srf); + } + } + #endif + } return; } @@ -1848,7 +1863,7 @@ static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, srf = XFOPEN(ready->srfName, "w"); if (srf) { - /* let's write port sever is listening on to ready file + /* let's write port server is listening on to ready file external monitor can then do ephemeral ports by passing -p 0 to server on supported platforms with -R ready_file client can then wait for existence of ready_file and see