diff --git a/scripts/ocsp-stapling-with-ca-as-responder.test b/scripts/ocsp-stapling-with-ca-as-responder.test index 4773ec104..b045e674c 100755 --- a/scripts/ocsp-stapling-with-ca-as-responder.test +++ b/scripts/ocsp-stapling-with-ca-as-responder.test @@ -1,6 +1,10 @@ #!/bin/bash -# ocsp-stapling.test +# ocsp-stapling-with-ca-as-responder.test + +if [[ -z "${RETRIES_REMAINING-}" ]]; then + export RETRIES_REMAINING=2 +fi ./examples/client/client -v 3 2>&1 | grep -- 'Bad SSL version' if [ $? -eq 0 ]; then @@ -9,50 +13,40 @@ if [ $? -eq 0 ]; then exit 0 fi +PARENTDIR=`pwd` + +# create a unique workspace directory ending in PID for the script instance ($$) +# to make this instance orthogonal to any others running, even on same repo. +# TCP ports are also carefully formed below from the PID, to minimize conflicts. + +WORKSPACE="${PARENTDIR}/workspace.pid$$" + +mkdir "${WORKSPACE}" || exit $? +cp -pR certs "${WORKSPACE}"/ || exit $? +cd "$WORKSPACE" || exit $? +ln -s ../examples + +CERT_DIR="certs/ocsp" + -WORKSPACE=`pwd` -CERT_DIR="./certs/ocsp" resume_port=0 -ready_file=`pwd`/wolf_ocsp_s1_readyF$$ -ready_file2=`pwd`/wolf_ocsp_s1_readyF2$$ -printf '%s\n' "ready file: $ready_file" +ready_file="${WORKSPACE}"/wolf_ocsp_s1_readyF$$ +ready_file2="${WORKSPACE}"/wolf_ocsp_s1_readyF2$$ +printf '%s\n' "ready files: $ready_file $ready_file2" test_cnf="ocsp_s_w_ca_a_r.cnf" -copy_originals() { - cd $CERT_DIR - cp intermediate1-ca-cert.pem bak-intermediate1-ca-cert.pem - cp intermediate2-ca-cert.pem bak-intermediate2-ca-cert.pem - cp intermediate3-ca-cert.pem bak-intermediate3-ca-cert.pem - cp ocsp-responder-cert.pem bak-ocsp-responder-cert.pem - cp root-ca-cert.pem bak-root-ca-cert.pem - cp server1-cert.pem bak-server1-cert.pem - cp server2-cert.pem bak-server2-cert.pem - cp server3-cert.pem bak-server3-cert.pem - cp server4-cert.pem bak-server4-cert.pem - cp server5-cert.pem bak-server5-cert.pem - cd $WORKSPACE -} - -restore_originals() { - cd $CERT_DIR - mv bak-intermediate1-ca-cert.pem intermediate1-ca-cert.pem - mv bak-intermediate2-ca-cert.pem intermediate2-ca-cert.pem - mv bak-intermediate3-ca-cert.pem intermediate3-ca-cert.pem - mv bak-ocsp-responder-cert.pem ocsp-responder-cert.pem - mv bak-root-ca-cert.pem root-ca-cert.pem - mv bak-server1-cert.pem server1-cert.pem - mv bak-server2-cert.pem server2-cert.pem - mv bak-server3-cert.pem server3-cert.pem - mv bak-server4-cert.pem server4-cert.pem - mv bak-server5-cert.pem server5-cert.pem -} - wait_for_readyFile(){ counter=0 while [ ! -s $1 -a "$counter" -lt 20 ]; do + if [[ -n "${2-}" ]]; then + if ! kill -0 $2 2>&-; then + echo "pid $2 for port ${3-} exited before creating ready file. bailing..." + exit 1 + fi + fi echo -e "waiting for ready file..." sleep 0.1 counter=$((counter+ 1)) @@ -61,7 +55,7 @@ wait_for_readyFile(){ if test -e $1; then echo -e "found ready file, starting client..." else - echo -e "NO ready file ending test..." + echo -e "NO ready file at $1 -- ending test..." exit 1 fi @@ -76,8 +70,6 @@ remove_single_rF(){ #create a configure file for cert generation with the port 0 solution create_new_cnf() { - copy_originals - printf '%s\n' "Random Port Selected: $RPORTSELECTED" printf '%s\n' "#" > $test_cnf @@ -145,13 +137,21 @@ remove_ready_file() { cleanup() { + exit_status=$? for i in $(jobs -pr) do kill -s HUP "$i" done remove_ready_file rm $CERT_DIR/$test_cnf - restore_originals + cd "$PARENTDIR" || return 1 + rm -r "$WORKSPACE" || return 1 + + if [[ ("$exit_status" == 1) && ($RETRIES_REMAINING -gt 0) ]]; then + echo "retrying..." + RETRIES_REMAINING=$((RETRIES_REMAINING - 1)) + exec $0 "$@" + fi } trap cleanup EXIT INT TERM HUP @@ -160,9 +160,34 @@ ca=certs/external/baltimore-cybertrust-root.pem [ ! -x ./examples/client/client ] && printf '\n\n%s\n' "Client doesn't exist" && exit 1 -# create a port 0 port to use with openssl ocsp responder -./examples/server/server -R $ready_file -p $resume_port & -wait_for_readyFile $ready_file + +# choose consecutive ports based on the PID, skipping any that are +# already bound, to avoid the birthday problem in case other +# instances are sharing this host. + +get_first_free_port() { + local ret="$1" + while :; do + if [[ "$ret" -ge 65536 ]]; then + ret=1024 + fi + if ! nc -z 127.0.0.1 "$ret"; then + break + fi + ret=$((ret+1)) + done + echo "$ret" + return 0 +} + +base_port=$((((($$ + $RETRIES_REMAINING) * 4) % (65536 - 2048)) + 1024)) +port1=$(get_first_free_port $base_port) + + +# create a port to use with openssl ocsp responder +./examples/server/server -R $ready_file -p $port1 & +wolf_pid=$! +wait_for_readyFile $ready_file $wolf_pid $port1 if [ ! -f $ready_file ]; then printf '%s\n' "Failed to create ready file: \"$ready_file\"" exit 1 @@ -173,7 +198,7 @@ else ./examples/client/client -p $RPORTSELECTED create_new_cnf $RPORTSELECTED fi -sleep 1 +sleep 0.1 # is our desired server there? - login.live.com doesn't answers PING #./scripts/ping.test $server 2 @@ -197,7 +222,7 @@ openssl ocsp -port $RPORTSELECTED -nmin 1 \ $@ \ & -sleep 1 +sleep 0.1 # "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.test b/scripts/ocsp-stapling.test index bc0a4e56f..073cb0352 100755 --- a/scripts/ocsp-stapling.test +++ b/scripts/ocsp-stapling.test @@ -3,6 +3,10 @@ # ocsp-stapling.test # Test requires HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST +if [[ -z "${RETRIES_REMAINING-}" ]]; then + export RETRIES_REMAINING=2 +fi + ./examples/client/client -v 3 2>&1 | grep -- 'Bad SSL version' if [ $? -eq 0 ]; then echo "TLS 1.2 or lower required" @@ -11,51 +15,38 @@ if [ $? -eq 0 ]; then fi -# create a unique ready file ending in PID for the script instance ($$) to take -# advantage of port zero solution -WORKSPACE=`pwd` +PARENTDIR=`pwd` + +# create a unique workspace directory ending in PID for the script instance ($$) +# to make this instance orthogonal to any others running, even on same repo. +# TCP ports are also carefully formed below from the PID, to minimize conflicts. + +WORKSPACE="${PARENTDIR}/workspace.pid$$" + +mkdir "${WORKSPACE}" || exit $? +cp -pR certs "${WORKSPACE}"/ || exit $? +cd "$WORKSPACE" || exit $? +ln -s ../examples + CERT_DIR="./certs/ocsp" resume_port=0 -ready_file=`pwd`/wolf_ocsp_s1_readyF$$ -ready_file2=`pwd`/wolf_ocsp_s1_readyF2$$ +ready_file="$WORKSPACE"/wolf_ocsp_s1_readyF$$ +ready_file2="$WORKSPACE"/wolf_ocsp_s1_readyF2$$ printf '%s\n' "ready file: $ready_file" test_cnf="ocsp_s1.cnf" -copy_originals() { - cd $CERT_DIR - cp intermediate1-ca-cert.pem bak-intermediate1-ca-cert.pem - cp intermediate2-ca-cert.pem bak-intermediate2-ca-cert.pem - cp intermediate3-ca-cert.pem bak-intermediate3-ca-cert.pem - cp ocsp-responder-cert.pem bak-ocsp-responder-cert.pem - cp root-ca-cert.pem bak-root-ca-cert.pem - cp server1-cert.pem bak-server1-cert.pem - cp server2-cert.pem bak-server2-cert.pem - cp server3-cert.pem bak-server3-cert.pem - cp server4-cert.pem bak-server4-cert.pem - cp server5-cert.pem bak-server5-cert.pem - cd $WORKSPACE -} - -restore_originals() { - cd $CERT_DIR - mv bak-intermediate1-ca-cert.pem intermediate1-ca-cert.pem - mv bak-intermediate2-ca-cert.pem intermediate2-ca-cert.pem - mv bak-intermediate3-ca-cert.pem intermediate3-ca-cert.pem - mv bak-ocsp-responder-cert.pem ocsp-responder-cert.pem - mv bak-root-ca-cert.pem root-ca-cert.pem - mv bak-server1-cert.pem server1-cert.pem - mv bak-server2-cert.pem server2-cert.pem - mv bak-server3-cert.pem server3-cert.pem - mv bak-server4-cert.pem server4-cert.pem - mv bak-server5-cert.pem server5-cert.pem -} - wait_for_readyFile(){ counter=0 while [ ! -s $1 -a "$counter" -lt 20 ]; do + if [[ -n "${2-}" ]]; then + if ! kill -0 $2 2>&-; then + echo "pid $2 for port ${3-} exited before creating ready file. bailing..." + exit 1 + fi + fi echo -e "waiting for ready file..." sleep 0.1 counter=$((counter+ 1)) @@ -64,7 +55,7 @@ wait_for_readyFile(){ if test -e $1; then echo -e "found ready file, starting client..." else - echo -e "NO ready file ending test..." + echo -e "NO ready file at $1 -- ending test..." exit 1 fi @@ -79,8 +70,6 @@ remove_single_rF(){ #create a configure file for cert generation with the port 0 solution create_new_cnf() { - copy_originals - printf '%s\n' "Random Port Selected: $RPORTSELECTED" printf '%s\n' "#" > $test_cnf @@ -147,13 +136,21 @@ remove_ready_file() { cleanup() { + exit_status=$? for i in $(jobs -pr) do kill -s HUP "$i" done remove_ready_file rm $CERT_DIR/$test_cnf - restore_originals + cd "$PARENTDIR" || return 1 + rm -r "$WORKSPACE" || return 1 + + if [[ ("$exit_status" == 1) && ($RETRIES_REMAINING -gt 0) ]]; then + echo "retrying..." + RETRIES_REMAINING=$((RETRIES_REMAINING - 1)) + exec $0 "$@" + fi } trap cleanup EXIT INT TERM HUP @@ -175,13 +172,37 @@ if [ ! -z "$size" ]; then printf 'OK\n' fi +# choose consecutive ports based on the PID, skipping any that are +# already bound, to avoid the birthday problem in case other +# instances are sharing this host. + +get_first_free_port() { + local ret="$1" + while :; do + if [[ "$ret" -ge 65536 ]]; then + ret=1024 + fi + if ! nc -z 127.0.0.1 "$ret"; then + break + fi + ret=$((ret+1)) + done + echo "$ret" + return 0 +} + +base_port=$((((($$ + $RETRIES_REMAINING) * 4) % (65536 - 2048)) + 1024)) +port1=$(get_first_free_port $base_port) +port2=$(get_first_free_port $((port1 + 1))) + + # test interop fail case ready_file=`pwd`/wolf_ocsp_readyF$$ printf '%s\n' "ready file: $ready_file" -# use random port and bind to any (allows use with IPv6) -./examples/server/server -b -p $resume_port -o -R $ready_file & +# bind to any (allows use with IPv6) +./examples/server/server -b -p $port1 -o -R $ready_file & wolf_pid=$! -wait_for_readyFile $ready_file +wait_for_readyFile $ready_file $wolf_pid $port1 if [ ! -f $ready_file ]; then printf '%s\n' "Failed to create ready file: \"$ready_file\"" exit 1 @@ -203,9 +224,10 @@ else fi -# create a port 0 port to use with openssl ocsp responder -./examples/server/server -b -p $resume_port -R $ready_file & -wait_for_readyFile $ready_file +# create a port to use with openssl ocsp responder +./examples/server/server -b -p $port2 -R $ready_file & +wolf_pid2=$! +wait_for_readyFile $ready_file $wolf_pid2 $port2 if [ ! -f $ready_file ]; then printf '%s\n' "Failed to create ready file: \"$ready_file\"" exit 1 diff --git a/scripts/ocsp-stapling2.test b/scripts/ocsp-stapling2.test index 58c02ce74..d3a5df214 100755 --- a/scripts/ocsp-stapling2.test +++ b/scripts/ocsp-stapling2.test @@ -3,6 +3,10 @@ # ocsp-stapling2.test # Test requires HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST_V2 +if [[ -z "${RETRIES_REMAINING-}" ]]; then + export RETRIES_REMAINING=2 +fi + ./examples/client/client -v 3 2>&1 | grep -- 'Bad SSL version' if [ $? -eq 0 ]; then echo "TLS 1.2 or lower required" @@ -10,17 +14,28 @@ if [ $? -eq 0 ]; then exit 0 fi -# create a unique ready file ending in PID for the script instance ($$) to take -# advantage of port zero solution -WORKSPACE=`pwd` +PARENTDIR=`pwd` + +# create a unique workspace directory ending in PID for the script instance ($$) +# to make this instance orthogonal to any others running, even on same repo. +# TCP ports are also carefully formed below from the PID, to minimize conflicts. + +WORKSPACE="${PARENTDIR}/workspace.pid$$" + +mkdir "${WORKSPACE}" || exit $? +cp -pR certs "${WORKSPACE}"/ || exit $? +cd "$WORKSPACE" || exit $? +ln -s ../examples + CERT_DIR="certs/ocsp" + resume_port=0 -ready_file1=`pwd`/wolf_ocsp_s2_readyF1$$ -ready_file2=`pwd`/wolf_ocsp_s2_readyF2$$ -ready_file3=`pwd`/wolf_ocsp_s2_readyF3$$ -ready_file4=`pwd`/wolf_ocsp_s2_readyF4$$ -ready_file5=`pwd`/wolf_ocsp_s2_readyF5$$ +ready_file1="$WORKSPACE"/wolf_ocsp_s2_readyF1$$ +ready_file2="$WORKSPACE"/wolf_ocsp_s2_readyF2$$ +ready_file3="$WORKSPACE"/wolf_ocsp_s2_readyF3$$ +ready_file4="$WORKSPACE"/wolf_ocsp_s2_readyF4$$ +ready_file5="$WORKSPACE"/wolf_ocsp_s2_readyF5$$ printf '%s\n' "ready file 1: $ready_file1" printf '%s\n' "ready file 2: $ready_file2" printf '%s\n' "ready file 3: $ready_file3" @@ -29,40 +44,17 @@ printf '%s\n' "ready file 5: $ready_file5" test_cnf="ocsp_s2.cnf" -copy_originals() { - cd $CERT_DIR - cp intermediate1-ca-cert.pem bak-intermediate1-ca-cert.pem - cp intermediate2-ca-cert.pem bak-intermediate2-ca-cert.pem - cp intermediate3-ca-cert.pem bak-intermediate3-ca-cert.pem - cp ocsp-responder-cert.pem bak-ocsp-responder-cert.pem - cp root-ca-cert.pem bak-root-ca-cert.pem - cp server1-cert.pem bak-server1-cert.pem - cp server2-cert.pem bak-server2-cert.pem - cp server3-cert.pem bak-server3-cert.pem - cp server4-cert.pem bak-server4-cert.pem - cp server5-cert.pem bak-server5-cert.pem - cd $WORKSPACE -} - -restore_originals() { - cd $CERT_DIR - mv bak-intermediate1-ca-cert.pem intermediate1-ca-cert.pem - mv bak-intermediate2-ca-cert.pem intermediate2-ca-cert.pem - mv bak-intermediate3-ca-cert.pem intermediate3-ca-cert.pem - mv bak-ocsp-responder-cert.pem ocsp-responder-cert.pem - mv bak-root-ca-cert.pem root-ca-cert.pem - mv bak-server1-cert.pem server1-cert.pem - mv bak-server2-cert.pem server2-cert.pem - mv bak-server3-cert.pem server3-cert.pem - mv bak-server4-cert.pem server4-cert.pem - mv bak-server5-cert.pem server5-cert.pem -} - wait_for_readyFile(){ counter=0 while [ ! -s $1 -a "$counter" -lt 20 ]; do + if [[ -n "${2-}" ]]; then + if ! kill -0 $2 2>&-; then + echo "pid $2 for port ${3-} exited before creating ready file. bailing..." + exit 1 + fi + fi echo -e "waiting for ready file..." sleep 0.1 counter=$((counter+ 1)) @@ -71,7 +63,7 @@ wait_for_readyFile(){ if test -e $1; then echo -e "found ready file, starting client..." else - echo -e "NO ready file ending test..." + echo -e "NO ready file at $1 -- ending test..." exit 1 fi @@ -86,8 +78,6 @@ remove_single_rF(){ #create a configure file for cert generation with the port 0 solution create_new_cnf() { - copy_originals - printf '%s\n' "Random Port Selected: $RPORTSELECTED" printf '%s\n' "#" > $test_cnf @@ -166,13 +156,21 @@ remove_ready_file(){ cleanup() { + exit_status=$? for i in $(jobs -pr) do kill -s HUP "$i" done remove_ready_file rm $CERT_DIR/$test_cnf - restore_originals + cd "$PARENTDIR" || return 1 + rm -r "$WORKSPACE" || return 1 + + if [[ ("$exit_status" == 1) && ($RETRIES_REMAINING -gt 0) ]]; then + echo "retrying..." + RETRIES_REMAINING=$((RETRIES_REMAINING - 1)) + exec $0 "$@" + fi } trap cleanup EXIT INT TERM HUP @@ -191,50 +189,81 @@ if [ ! -z "$size" ]; then fi #get four unique ports + +# choose consecutive ports based on the PID, skipping any that are +# already bound, to avoid the birthday problem in case other +# instances are sharing this host. + +get_first_free_port() { + local ret="$1" + while :; do + if [[ "$ret" -ge 65536 ]]; then + ret=1024 + fi + if ! nc -z 127.0.0.1 "$ret"; then + break + fi + ret=$((ret+1)) + done + echo "$ret" + return 0 +} + +base_port=$((((($$ + $RETRIES_REMAINING) * 4) % (65536 - 2048)) + 1024)) +port1=$(get_first_free_port $base_port) +port2=$(get_first_free_port $((port1 + 1))) +port3=$(get_first_free_port $((port2 + 1))) +port4=$(get_first_free_port $((port3 + 1))) + # 1: -./examples/server/server -R $ready_file1 -p $resume_port & -wait_for_readyFile $ready_file1 +./examples/server/server -R $ready_file1 -p $port1 & +server_pid1=$! +wait_for_readyFile $ready_file1 $server_pid1 $port1 if [ ! -f $ready_file1 ]; then printf '%s\n' "Failed to create ready file1: \"$ready_file1\"" exit 1 fi # 2: -./examples/server/server -R $ready_file2 -p $resume_port & -wait_for_readyFile $ready_file2 +./examples/server/server -R $ready_file2 -p $port2 & +server_pid2=$! +wait_for_readyFile $ready_file2 $server_pid2 $port2 if [ ! -f $ready_file2 ]; then printf '%s\n' "Failed to create ready file2: \"$ready_file2\"" exit 1 fi # 3: -./examples/server/server -R $ready_file3 -p $resume_port & -wait_for_readyFile $ready_file3 +./examples/server/server -R $ready_file3 -p $port3 & +server_pid3=$! +wait_for_readyFile $ready_file3 $server_pid3 $port3 if [ ! -f $ready_file3 ]; then printf '%s\n' "Failed to create ready file3: \"$ready_file3\"" exit 1 fi # 4: -./examples/server/server -R $ready_file4 -p $resume_port & -wait_for_readyFile $ready_file4 +./examples/server/server -R $ready_file4 -p $port4 & +server_pid4=$! +wait_for_readyFile $ready_file4 $server_pid4 $port4 if [ ! -f $ready_file4 ]; then printf '%s\n' "Failed to create ready file4: \"$ready_file4\"" exit 1 -else - RPORTSELECTED1=`cat $ready_file1` - RPORTSELECTED2=`cat $ready_file2` - RPORTSELECTED3=`cat $ready_file3` - RPORTSELECTED4=`cat $ready_file4` - printf '%s\n' "------------- PORTS ---------------" - printf '%s' "Random ports selected: $RPORTSELECTED1 $RPORTSELECTED2" - printf '%s\n' " $RPORTSELECTED3 $RPORTSELECTED4" - printf '%s\n' "-----------------------------------" - # Use client connections to cleanly shutdown the servers - ./examples/client/client -p $RPORTSELECTED1 - ./examples/client/client -p $RPORTSELECTED2 - ./examples/client/client -p $RPORTSELECTED3 - ./examples/client/client -p $RPORTSELECTED4 - create_new_cnf $RPORTSELECTED1 $RPORTSELECTED2 $RPORTSELECTED3 \ - $RPORTSELECTED4 fi + +RPORTSELECTED1=`cat $ready_file1` +RPORTSELECTED2=`cat $ready_file2` +RPORTSELECTED3=`cat $ready_file3` +RPORTSELECTED4=`cat $ready_file4` +printf '%s\n' "------------- PORTS ---------------" +printf '%s' "Random ports selected: $RPORTSELECTED1 $RPORTSELECTED2" +printf '%s\n' " $RPORTSELECTED3 $RPORTSELECTED4" +printf '%s\n' "-----------------------------------" +# Use client connections to cleanly shutdown the servers +./examples/client/client -p $RPORTSELECTED1 +./examples/client/client -p $RPORTSELECTED2 +./examples/client/client -p $RPORTSELECTED3 +./examples/client/client -p $RPORTSELECTED4 +create_new_cnf $RPORTSELECTED1 $RPORTSELECTED2 $RPORTSELECTED3 \ + $RPORTSELECTED4 + sleep 0.1 # setup ocsp responders diff --git a/wolfssl/test.h b/wolfssl/test.h index c3136894b..6904dcd6e 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -501,6 +501,34 @@ err_sys(const char* msg) } } +static WC_INLINE +#if defined(WOLFSSL_FORCE_MALLOC_FAIL_TEST) || defined(WOLFSSL_ZEPHYR) +THREAD_RETURN +#else +WC_NORETURN void +#endif +err_sys_with_errno(const char* msg) +{ +#if defined(HAVE_STRING_H) && defined(HAVE_ERRNO_H) + printf("wolfSSL error: %s: %s\n", msg, strerror(errno)); +#else + printf("wolfSSL error: %s\n", msg); +#endif + +#if !defined(__GNUC__) + /* scan-build (which pretends to be gnuc) can get confused and think the + * msg pointer can be null even when hardcoded and then it won't exit, + * making null pointer checks above the err_sys() call useless. + * We could just always exit() but some compilers will complain about no + * possible return, with gcc we know the attribute to handle that with + * WC_NORETURN. */ + if (msg) +#endif + { + XEXIT_T(EXIT_FAILURE); + } +} + extern int myoptind; extern char* myoptarg; @@ -948,7 +976,7 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) *sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP); if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) { - err_sys("socket failed\n"); + err_sys_with_errno("socket failed\n"); } #ifndef USE_WINDOWS_API @@ -958,7 +986,7 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) socklen_t len = sizeof(on); int res = setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); if (res < 0) - err_sys("setsockopt SO_NOSIGPIPE failed\n"); + err_sys_with_errno("setsockopt SO_NOSIGPIPE failed\n"); } #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\ defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR) @@ -974,7 +1002,7 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) socklen_t len = sizeof(on); int res = setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len); if (res < 0) - err_sys("setsockopt TCP_NODELAY failed\n"); + err_sys_with_errno("setsockopt TCP_NODELAY failed\n"); } #endif #endif /* USE_WINDOWS_API */ @@ -992,7 +1020,7 @@ static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, if (!udp) { if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) - err_sys("tcp connect failed"); + err_sys_with_errno("tcp connect failed"); } } @@ -1000,7 +1028,7 @@ static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz) { if (connect(*sockfd, (const struct sockaddr*)addr, addrSz) != 0) - err_sys("tcp connect failed"); + err_sys_with_errno("tcp connect failed"); } @@ -1098,12 +1126,21 @@ static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, socklen_t len = sizeof(on); res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); if (res < 0) - err_sys("setsockopt SO_REUSEADDR failed\n"); + err_sys_with_errno("setsockopt SO_REUSEADDR failed\n"); } +#ifdef SO_REUSEPORT + { + int res, on = 1; + socklen_t len = sizeof(on); + res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len); + if (res < 0) + err_sys_with_errno("setsockopt SO_REUSEPORT failed\n"); + } +#endif #endif if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) - err_sys("tcp bind failed"); + err_sys_with_errno("tcp bind failed"); if (!udp) { #ifdef WOLFSSL_KEIL_TCP_NET #define SOCK_LISTEN_MAX_QUEUE 1 @@ -1111,7 +1148,7 @@ static WC_INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr, #define SOCK_LISTEN_MAX_QUEUE 5 #endif if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0) - err_sys("tcp listen failed"); + err_sys_with_errno("tcp listen failed"); } #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) \ && !defined(WOLFSSL_ZEPHYR) @@ -1168,12 +1205,21 @@ static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, socklen_t len = sizeof(on); res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); if (res < 0) - err_sys("setsockopt SO_REUSEADDR failed\n"); + err_sys_with_errno("setsockopt SO_REUSEADDR failed\n"); } +#ifdef SO_REUSEPORT + { + int res, on = 1; + socklen_t len = sizeof(on); + res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEPORT, &on, len); + if (res < 0) + err_sys_with_errno("setsockopt SO_REUSEPORT failed\n"); + } +#endif #endif if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) - err_sys("tcp bind failed"); + err_sys_with_errno("tcp bind failed"); #if (defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API)) && !defined(WOLFSSL_TIRTOS) if (port == 0) { @@ -1275,7 +1321,7 @@ static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, *clientfd = accept(*sockfd, (struct sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) { - err_sys("tcp accept failed"); + err_sys_with_errno("tcp accept failed"); } } @@ -1286,7 +1332,7 @@ static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd) unsigned long blocking = 1; int ret = ioctlsocket(*sockfd, FIONBIO, &blocking); if (ret == SOCKET_ERROR) - err_sys("ioctlsocket failed"); + err_sys_with_errno("ioctlsocket failed"); #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \ || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \ || defined(WOLFSSL_ZEPHYR) @@ -1294,10 +1340,10 @@ static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd) #else int flags = fcntl(*sockfd, F_GETFL, 0); if (flags < 0) - err_sys("fcntl get failed"); + err_sys_with_errno("fcntl get failed"); flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK); if (flags < 0) - err_sys("fcntl set failed"); + err_sys_with_errno("fcntl set failed"); #endif } @@ -1972,7 +2018,7 @@ static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf) ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize); if (ret != 0 || myStack == NULL) - err_sys("posix_memalign failed\n"); + err_sys_with_errno("posix_memalign failed\n"); XMEMSET(myStack, STACK_CHECK_VAL, stackSize); @@ -2029,13 +2075,11 @@ static WC_INLINE void StackTrap(void) { struct rlimit rl; if (getrlimit(RLIMIT_STACK, &rl) != 0) - err_sys("getrlimit failed"); + err_sys_with_errno("getrlimit failed"); printf("rlim_cur = %llu\n", rl.rlim_cur); rl.rlim_cur = 1024*21; /* adjust trap size here */ - if (setrlimit(RLIMIT_STACK, &rl) != 0) { - perror("setrlimit"); - err_sys("setrlimit failed"); - } + if (setrlimit(RLIMIT_STACK, &rl) != 0) + err_sys_with_errno("setrlimit failed"); } #else /* STACK_TRAP */ @@ -2398,13 +2442,13 @@ static WC_INLINE void SetupAtomicUser(WOLFSSL_CTX* ctx, WOLFSSL* ssl) encCtx = (AtomicEncCtx*)malloc(sizeof(AtomicEncCtx)); if (encCtx == NULL) - err_sys("AtomicEncCtx malloc failed"); + err_sys_with_errno("AtomicEncCtx malloc failed"); XMEMSET(encCtx, 0, sizeof(AtomicEncCtx)); decCtx = (AtomicDecCtx*)malloc(sizeof(AtomicDecCtx)); if (decCtx == NULL) { free(encCtx); - err_sys("AtomicDecCtx malloc failed"); + err_sys_with_errno("AtomicDecCtx malloc failed"); } XMEMSET(decCtx, 0, sizeof(AtomicDecCtx));