From 69c9eb550cdd97fcf480c0185788b364a15c0fdb Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 24 Jan 2025 15:54:27 +0100 Subject: [PATCH 01/51] Further improved readline.sh STDERR handling --- CHANGES | 6 ++++++ readline.sh | 22 ++++++++++++++++------ test.sh | 5 +++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 3b654aa..8e9467f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +Security: + readline.sh has new option -lf <logfile> for stderr. If this option is + not given it logs to a file in . (cwd) only when it is not writable by + other users. + ####################### V 1.8.0.2: Security: @@ -1410,6 +1415,7 @@ security: Socat security advisory 7 MSVR-1499 + CVE-2016-2217 In the OpenSSL address implementation the hard coded 1024 bit DH p parameter was not prime. The effective cryptographic strength of a key exchange using these parameters was weaker than the one one could get by diff --git a/readline.sh b/readline.sh index 1045303..2f08c04 100755 --- a/readline.sh +++ b/readline.sh @@ -4,15 +4,19 @@ # Published under the GNU General Public License V.2, see file COPYING # this is an attempt for a socat based readline wrapper -# usage: readline.sh <command> +# usage: readline.sh [options] <program> withhistfile=1 +STDERR= while true; do case "X$1" in - X-nh|X-nohist*) withhistfile=; shift; continue ;; - *) break;; + X-lf?*) STDERR="${1:3}" ;; + X-lf) shift; STDERR="$1" ;; + X-nh|X-nohist*) withhistfile= ;; + *) break;; esac + shift done PROGRAM="$@" @@ -25,12 +29,18 @@ fi # # -if test -w .; then +#if test -w .; then +if [ -z "$STDERR" ] && find . -maxdepth 0 -user $USER ! -perm /022 -print |grep ^ >/dev/null; then + # When cwd is owned by $USER and it is neither group nor world writable STDERR=./socat-readline.${1##*/}.log rm -f $STDERR -else + echo "$0: logs go to $STDERR" >&2 +elif [ -z "$STDERR" ]; then + echo "$0: insecure working directory, no logs are written" >&2 STDERR=/dev/null +else + echo "$0: logs go to $STDERR" >&2 fi -exec socat -d readline"$HISTOPT",noecho='[Pp]assword:' exec:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>$STDERR +exec socat -d READLINE"$HISTOPT",noecho='[Pp]assword:' EXEC:"$PROGRAM",sigint,pty,setsid,ctty,raw,echo=0,stderr 2>$STDERR diff --git a/test.sh b/test.sh index 5204ac7..55abd17 100755 --- a/test.sh +++ b/test.sh @@ -4925,8 +4925,9 @@ te="$td/test$N.stderr" tr="$td/test$N.ref" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -# the feature that we really want to test is in the readline.sh script: -CMD="$TRACE $SOCAT -lpwrapper $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" +# the feature that we really want to test is in the readline.sh script +READLINE_LOG=; if grep -e -lf ./readline.sh >/dev/null; then READLINE_LOG="-lf $td/test$N.rl-log"; fi +CMD="$TRACE $SOCAT -lpwrapper $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh $READLINE_LOG ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" #echo "$CMD" >"$ts" #chmod a+x "$ts" printf "test $F_n $TEST... " $N From 2e21396282d8c05f5b7a451b679a1f1976864a2b Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 24 Jan 2025 16:01:19 +0100 Subject: [PATCH 02/51] test.sh produces results.txt with numbers, names, results --- CHANGES | 4 + test.sh | 4091 +++++++++++++++++++------------------------------------ 2 files changed, 1375 insertions(+), 2720 deletions(-) diff --git a/CHANGES b/CHANGES index 8e9467f..4166168 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Security: not given it logs to a file in . (cwd) only when it is not writable by other users. +Testing: + test.sh produces file results.txt with columns of test numbers, names, + and results. + ####################### V 1.8.0.2: Security: diff --git a/test.sh b/test.sh index 55abd17..759e42b 100755 --- a/test.sh +++ b/test.sh @@ -92,7 +92,7 @@ debug=$DEBUG [ "$DEFS" ] && echo "BASH_VERSION=\"$BASH_VERSION\"" >&2 -[ "$DEFS" ] && echo "ECHO_E=\"$ECHO_E\"" >&2 +[ "$DEFS" ] && echo "ECHO=\"$ECHO\"" >&2 UNAME=`uname` [ "$DEFS" ] && echo "UNAME=\"$UNAME\"" >&2 @@ -744,6 +744,8 @@ mkdir -p "$TD" echo "Using temp directory $TD" +RESULTS="$TD/results.txt" # file for list of results + case "$TESTS" in *%consistency%*) # test if addresses are sorted alphabetically: @@ -796,16 +798,40 @@ listFAIL= listCANT= namesFAIL= +ok () { + numOK=$((numOK+1)) + listOK="$listOK $N" + do_result OK +} + +cant () { + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" + do_result CANT +} + +failed () { + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + do_result FAILED +} + +do_result () { + #echo "RESULTS=\"$RESULTS\"" >&2; exit + echo "$N $NAME $1" >>$RESULTS +} + #============================================================================== # test if selected socat features work ("FUNCTIONS") testecho () { local N="$1" - local title="$2" - local arg1="$3"; [ -z "$arg1" ] && arg1="-" - local arg2="$4"; [ -z "$arg2" ] && arg2="echo" - local opts="$5" - local T="$6"; [ -z "$T" ] && T=0 # fractional seconds + local NAME="$2" + local title="$3" + local arg1="$4"; [ -z "$arg1" ] && arg1="-" + local arg2="$5"; [ -z "$arg2" ] && arg2="echo" + local opts="$6" + local T="$7"; [ -z "$T" ] && T=0 # fractional seconds local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tdiff="$td/test$N.diff" @@ -825,22 +851,19 @@ testecho () { $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2 cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$SOCAT $opts $arg1 $arg2" >&2; fi if [ -n "$debug" ]; then cat $te >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2 cat "$te" >&2 echo diff: >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND } @@ -849,11 +872,12 @@ testecho () { # flush of od buffers testod () { local num="$1" - local title="$2" - local arg1="$3"; [ -z "$arg1" ] && arg1="-" - local arg2="$4"; [ -z "$arg2" ] && arg2="echo" - local opts="$5" - local T="$6"; [ -z "$T" ] && T=0 # fractional seconds + local NAME="$2" + local title="$3" + local arg1="$4"; [ -z "$arg1" ] && arg1="-" + local arg2="$5"; [ -z "$arg2" ] && arg2="echo" + local opts="$6" + local T="$7"; [ -z "$T" ] && T=0 # fractional seconds local tf="$td/test$N.stdout" local te="$td/test$N.stderr" local tr="$td/test$N.ref" @@ -868,21 +892,18 @@ testod () { $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $num" + failed # elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then elif diff "$tr" "$tf" >"$tdiff" 2>&1; then $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED: diff:\n" echo "$TRACE $SOCAT $opts $arg1 $arg2" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $num" + failed fi fi # NUMCOND } @@ -1937,7 +1958,7 @@ NAME=UNISTDIO case "$TESTS " in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: unidirectional throughput from stdin to stdout" -testecho "$N" "$TEST" "stdin" "stdout" "$opts -u" +testecho "$N" "$NAME" "$TEST" "stdin" "stdout" "$opts -u" esac N=$((N+1)) @@ -1948,7 +1969,7 @@ NAME=UNPIPESTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: stdio with simple echo via internal pipe" -testecho "$N" "$TEST" "stdio" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "stdio" "pipe" "$opts" esac N=$((N+1)) @@ -1957,7 +1978,7 @@ NAME=UNPIPESHORT case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: short form of stdio ('-') with simple echo via internal pipe" -testecho "$N" "$TEST" "-" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "-" "pipe" "$opts" esac N=$((N+1)) @@ -1966,7 +1987,7 @@ NAME=DUALSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe" -testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "stdin!!stdout" "pipe" "$opts" esac N=$((N+1)) @@ -1975,7 +1996,7 @@ NAME=DUALSHORTSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe" -testecho "$N" "$TEST" "-!!-" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "-!!-" "pipe" "$opts" esac N=$((N+1)) @@ -1984,7 +2005,7 @@ NAME=DUALFDS case "$TESTS" in *%$N%*|*%functions%*|*%fd%*|*%$NAME%*) TEST="$NAME: file descriptors with simple echo via internal pipe" -testecho "$N" "$TEST" "0!!1" "pipe" "$opts" +testecho "$N" "$NAME" "$TEST" "0!!1" "pipe" "$opts" esac N=$((N+1)) @@ -1996,7 +2017,7 @@ TEST="$NAME: simple echo via named pipe" # with MacOS, this test hangs if nonblock is not used. Is an OS bug. tp="$td/pipe$N" # note: the nonblock is required by MacOS 10.1(?), otherwise it hangs (OS bug?) -testecho "$N" "$TEST" "" "pipe:$tp,nonblock" "$opts" +testecho "$N" "$NAME" "$TEST" "" "pipe:$tp,nonblock" "$opts" esac N=$((N+1)) @@ -2006,7 +2027,7 @@ case "$TESTS" in *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via named pipe, specified twice" tp="$td/pipe$N" -testecho "$N" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts" +testecho "$N" "$NAME" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts" esac N=$((N+1)) @@ -2016,7 +2037,7 @@ case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: simple echo via file" tf="$td/file$N" -testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts" +testecho "$N" "$NAME" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts" esac N=$((N+1)) @@ -2025,7 +2046,7 @@ NAME=EXECSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with socketpair" -testecho "$N" "$TEST" "" "EXEC:$CAT" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT" "$opts" esac N=$((N+1)) @@ -2033,7 +2054,7 @@ NAME=SYSTEMSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with socketpair" -testecho "$N" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t" esac N=$((N+1)) @@ -2042,7 +2063,7 @@ NAME=EXECPIPES case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%pipe%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with pipes" -testecho "$N" "$TEST" "" "EXEC:$CAT,pipes" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pipes" "$opts" esac N=$((N+1)) @@ -2050,7 +2071,7 @@ NAME=SYSTEMPIPES case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pipes" -testecho "$N" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts" esac N=$((N+1)) @@ -2062,10 +2083,9 @@ TEST="$NAME: simple echo via exec of cat with pseudo terminal" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" fi esac N=$((N+1)) @@ -2077,10 +2097,9 @@ TEST="$NAME: simple echo via system() of cat with pseudo terminal" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" fi esac N=$((N+1)) @@ -2090,7 +2109,7 @@ NAME=SYSTEMPIPESFDS case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with pipes, non stdio" -testecho "$N" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts" esac N=$((N+1)) @@ -2099,7 +2118,7 @@ NAME=DUALSYSTEMFDS case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: echo via dual system() of cat" -testecho "$N" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t" +testecho "$N" "$NAME" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t" esac N=$((N+1)) @@ -2112,7 +2131,7 @@ NAME=EXECSOCKETPAIRFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: call to od via exec with socketpair" -testod "$N" "$TEST" "" "EXEC:$OD_C" "$opts" +testod "$N" "$NAME" "$TEST" "" "EXEC:$OD_C" "$opts" esac N=$((N+1)) @@ -2120,7 +2139,7 @@ NAME=SYSTEMSOCKETPAIRFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*) TEST="$NAME: call to od via system() with socketpair" -testod "$N" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t +testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t esac N=$((N+1)) @@ -2129,7 +2148,7 @@ NAME=EXECPIPESFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via EXEC with pipes" -testod "$N" "$TEST" "" "EXEC:$OD_C,pipes" "$opts" +testod "$N" "$NAME" "$TEST" "" "EXEC:$OD_C,pipes" "$opts" esac N=$((N+1)) @@ -2137,7 +2156,7 @@ NAME=SYSTEMPIPESFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via system() with pipes" -testod "$N" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t" +testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t" esac N=$((N+1)) @@ -2149,10 +2168,9 @@ N=$((N+1)) #TEST="$NAME: call to od via exec with pseudo terminal" #if ! testfeats pty >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant #else -#testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts" +#testod "$N" "$NAME" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts" #fi #esac #N=$((N+1)) @@ -2165,10 +2183,9 @@ N=$((N+1)) #TEST="$NAME: call to od via system() with pseudo terminal" #if ! testfeats pty >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant #else -#testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts" +#testod "$N" "$NAME" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts" #fi #esac #N=$((N+1)) @@ -2178,7 +2195,7 @@ NAME=SYSTEMPIPESFDSFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via system() with pipes, non stdio" -testod "$N" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t" +testod "$N" "$NAME" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t" esac N=$((N+1)) @@ -2186,7 +2203,7 @@ NAME=DUALSYSTEMFDSFLUSH case "$TESTS" in *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*) TEST="$NAME: call to od via dual system()" -testod "$N" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t" +testod "$N" "$NAME" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t" esac N=$((N+1)) @@ -2198,18 +2215,15 @@ TEST="$NAME: simple echo via self receiving raw IPv4 protocol" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts" fi esac N=$((N+1)) @@ -2221,18 +2235,15 @@ TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -2244,18 +2255,15 @@ TEST="$NAME: simple echo via self receiving raw IPv6 protocol" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts" fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -2267,18 +2275,15 @@ TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts" + testecho "$N" "$NAME" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts" fi esac N=$((N+1)) @@ -2297,12 +2302,11 @@ TEST="$NAME: echo via self connection of TCP IPv4 socket" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 # provide free port number in $PORT #ts="127.0.0.1:$tsl" - testecho "$N" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts" + testecho "$N" "$NAME" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts" fi esac N=$((N+1)) @@ -2315,11 +2319,10 @@ case "$TESTS" in TEST="$NAME: echo via self connection of UDP IPv4 socket" if [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT - testecho "$N" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" + testecho "$N" "$NAME" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" fi esac fi # NUMCOND @@ -2333,16 +2336,14 @@ TEST="$NAME: echo via self connection of UDP IPv6 socket" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats udp ip6 >/dev/null || ! runsudp6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/file$N" newport udp6 # provide free port number in $PORT - testecho "$N" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts" + testecho "$N" "$NAME" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts" fi esac N=$((N+1)) @@ -2356,7 +2357,7 @@ TEST="$NAME: echo via two unidirectional UDP IPv4 sockets" tf="$td/file$N" newport udp4; PORT1=$PORT # get free port newport udp4; PORT2=$PORT # get free port -testecho "$N" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts" +testecho "$N" "$NAME" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts" esac fi # NUMCOND N=$((N+1)) @@ -2392,8 +2393,7 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" echo "rc=$rc2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" @@ -2401,13 +2401,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $bg 2>/dev/null esac @@ -2426,8 +2424,7 @@ elif ! cond=$(checkconds "" "" "" \ "so-reuseaddr" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2448,9 +2445,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -2459,17 +2454,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -2486,20 +2478,16 @@ TEST="$NAME: echo via connection to TCP V6 socket" if ! eval $NUMCOND; then :; elif ! F=$(testfeats IP6 TCP LISTEN STDIO PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - TCP6-LISTEN PIPE STDIN STDOUT TCP6-CONNECT); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2520,8 +2508,7 @@ if [ $? -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" echo "$CMD1 &" @@ -2530,16 +2517,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2556,20 +2541,16 @@ TEST="$NAME: echo via connection to TCP socket, v4 by target" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pf) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2590,9 +2571,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" @@ -2600,17 +2579,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2626,20 +2602,16 @@ TEST="$NAME: echo via connection to TCP socket, v6 by target" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP6 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pf) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2660,9 +2632,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" @@ -2670,17 +2640,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2698,16 +2665,13 @@ TEST="$NAME: option ipv6-v6only=0 listens on IPv4" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2727,18 +2691,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi @@ -2755,16 +2716,13 @@ TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2782,17 +2740,14 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" if [ $? -eq 0 ]; then $PRINTF "$FAILED:\n" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED:\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid; wait wait @@ -2808,16 +2763,13 @@ TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runstcp6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2837,18 +2789,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -2862,12 +2811,10 @@ TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2888,8 +2835,7 @@ if [ $? -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff):\n" echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &" @@ -2898,16 +2844,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -2921,16 +2865,13 @@ TEST="$NAME: option -4 for IPv4 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -2950,18 +2891,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -2975,12 +2913,10 @@ TEST="$NAME: option -6 for IPv6 preference on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3000,18 +2936,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait wait @@ -3026,16 +2959,13 @@ TEST="$NAME: pf=4 overrides option -6 on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions ipv6-v6only); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3055,18 +2985,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi @@ -3080,12 +3007,10 @@ TEST="$NAME: pf=6 overrides option -4 on listen" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3105,18 +3030,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -3149,8 +3071,7 @@ if [ $rc2 -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -3158,13 +3079,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3178,8 +3097,7 @@ TEST="$NAME: echo via connection to UDP V6 socket" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3201,18 +3119,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # ! testfeats esac @@ -3237,18 +3152,15 @@ if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! diff "$tf1" "$tf2" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND esac @@ -3278,8 +3190,7 @@ if [ ! -p "$tp" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else #echo "$da" >"$tp" # might hang forever echo "$da" >"$tp" & export pid=$!; (relsleep 1; kill $pid 2>/dev/null) & @@ -3295,13 +3206,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -3336,8 +3245,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -3346,13 +3254,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi # NUMCOND @@ -3385,8 +3291,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -3395,13 +3300,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi # NUMCOND @@ -3435,8 +3338,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then $PRINTF "$FAILED:\n" echo "$SRV &" @@ -3444,13 +3346,11 @@ elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) kill "$pids" 2>/dev/null; wait fi ;; # NUMCOND @@ -3480,13 +3380,11 @@ kill $bg 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - listFAIL="$listFAIL $N" - numFAIL=$((numFAIL+1)) + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3514,13 +3412,11 @@ kill $bg 2>/dev/null if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - listFAIL="$listFAIL $N" - numFAIL=$((numFAIL+1)) + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait fi ;; # NUMCOND @@ -3543,13 +3439,11 @@ if [ -s "$te" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3563,8 +3457,7 @@ TEST="$NAME: generation of pty for other processes" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tt="$td/pty$N" tf="$td/test$N.stdout" @@ -3590,13 +3483,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -3625,13 +3516,11 @@ if ! [ $rc0 = 0 ] || echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3657,13 +3546,11 @@ if ! echo "$da" |$CMD >$tf 2>"$te" || echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3674,7 +3561,7 @@ NAME=RIGHTTOLEFT case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: unidirectional throughput from stdin to stdout, right to left" -testecho "$N" "$TEST" "stdout" "stdin" "$opts -U" +testecho "$N" "$NAME" "$TEST" "stdout" "stdin" "$opts -U" esac N=$((N+1)) @@ -3686,12 +3573,10 @@ case "$TESTS" in if ! eval $NUMCOND; then : elif ! F=$(testfeats STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else TEST="$NAME: child process default properties" tf="$td/test$N.stdout" @@ -3711,14 +3596,12 @@ then $PRINTF "$FAILED:\n" echo "$CMD" cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3747,12 +3630,10 @@ then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3781,12 +3662,10 @@ then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -3800,16 +3679,13 @@ TEST="$NAME: openssl connect" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -3835,13 +3711,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -3856,12 +3730,10 @@ TEST="$NAME: openssl listen" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -3883,13 +3755,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -3904,12 +3774,10 @@ TEST="$NAME: openssl listen" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -3931,13 +3799,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -3970,12 +3836,10 @@ TEST="$NAME: $TESTKEYW half close" if ! eval $NUMCOND; then :; elif [ "$FEAT" != ',' ] && ! testfeats "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $FEAT not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available on host${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3998,8 +3862,7 @@ if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then echo "$CMD" cat "${te}" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then @@ -4007,8 +3870,7 @@ else echo " $CMD" fi if [ -n "$debug" ]; then cat "${te}2" "${te}"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait fi ;; # NUMCOND, feats @@ -4038,12 +3900,10 @@ TEST="$NAME: OpenSSL server authentication (hostname)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -4066,13 +3926,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4087,12 +3945,10 @@ TEST="$NAME: openssl client authentication" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -4115,13 +3971,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4136,16 +3990,13 @@ TEST="$NAME: OpenSSL+FIPS client and server authentication" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions fips >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else OPENSSL_FIPS=1 gentestcert testsrvfips OPENSSL_FIPS=1 gentestcert testclifips @@ -4168,13 +4019,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4190,16 +4039,13 @@ TEST="$NAME: OpenSSL compression" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions openssl-compress >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL compression option not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv printf "test $F_n $TEST... " $N @@ -4231,13 +4077,11 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -4251,12 +4095,10 @@ TEST="$NAME: socks4 connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testfeats socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4278,13 +4120,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4299,12 +4139,10 @@ TEST="$NAME: socks4 connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats socks4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4327,16 +4165,14 @@ if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4352,12 +4188,10 @@ TEST="$NAME: socks4a connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testfeats socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4379,13 +4213,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4400,12 +4232,10 @@ TEST="$NAME: socks4a connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats socks4a >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -4427,13 +4257,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4449,12 +4277,10 @@ TEST="$NAME: proxy connect over TCP/IPv4" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sh" tf="$td/test$N.stdout" @@ -4477,13 +4303,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4498,12 +4322,10 @@ TEST="$NAME: proxy connect over TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sh" tf="$td/test$N.stdout" @@ -4526,13 +4348,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4566,18 +4386,15 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -4588,7 +4405,7 @@ NAME=EXECCATNOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec of cat with nofork" -testecho "$N" "$TEST" "" "EXEC:$CAT,nofork" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,nofork" "$opts" esac N=$((N+1)) @@ -4597,7 +4414,7 @@ NAME=SYSTEMCATNOFORK case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via system() of cat with nofork" -testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts" esac N=$((N+1)) @@ -4606,7 +4423,7 @@ NAME=NOFORKSETSID case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: simple echo via exec() of cat with nofork and setsid" -testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts" +testecho "$N" "$NAME" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts" esac N=$((N+1)) @@ -4622,12 +4439,10 @@ N=$((N+1)) #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then # $ECHO "... test $N succeeded" -# numOK=$((numOK+1)) -# listOK="$listOK $N" +# ok #else # $ECHO "*** test $N $FAILED" -# numFAIL=$((numFAIL+1)) -# listFAIL="$listFAIL $N" +# failed #fi #fi ;; # NUMCOND #N=$((N+1)) @@ -4642,12 +4457,10 @@ N=$((N+1)) #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf" #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then # $ECHO "... test $N succeeded" -# numOK=$((numOK+1)) -# listOK="$listOK $N" +# ok #else # $ECHO "*** test $N $FAILED" -# numFAIL=$((numFAIL+1)) -# listFAIL="$listFAIL $N" +# failed #fi #fi ;; # NUMCOND @@ -4678,13 +4491,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4724,13 +4535,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "$te" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait MICROS=$SAVEMICS @@ -4746,8 +4555,7 @@ TEST="$NAME: proxy connect accepts status with multiple spaces" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sh" tf="$td/test$N.stdout" @@ -4771,16 +4579,14 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "diff:" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$debug" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$debug" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -4804,19 +4610,16 @@ CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk" $CMD <"$ff" 2>"$te" if [ "$?" -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else if [ "$UNAME" = "Linux" ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "${YELLOW}failed (don't care)${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi fi fi ;; # NUMCOND @@ -4828,7 +4631,7 @@ NAME=SINGLEEXECOUTSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with socketpair" -testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "-!!exec:cat" "" "$opts" 1 esac N=$((N+1)) @@ -4836,7 +4639,7 @@ NAME=SINGLEEXECOUTPIPE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdout to single exec with pipe" -testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1 esac N=$((N+1)) @@ -4847,10 +4650,9 @@ TEST="$NAME: inheritance of stdout to single exec with pty" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4859,7 +4661,7 @@ NAME=SINGLEEXECINSOCKETPAIR case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with socketpair" -testecho "$N" "$TEST" "exec:cat!!-" "" "$opts" +testecho "$N" "$NAME" "$TEST" "exec:cat!!-" "" "$opts" esac N=$((N+1)) @@ -4867,7 +4669,7 @@ NAME=SINGLEEXECINPIPE case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: inheritance of stdin to single exec with pipe" -testecho "$N" "$TEST" "exec:cat,pipes!!-" "" "$opts" +testecho "$N" "$NAME" "$TEST" "exec:cat,pipes!!-" "" "$opts" esac N=$((N+1)) @@ -4878,10 +4680,9 @@ TEST="$NAME: inheritance of stdin to single exec with pty, with delay" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else -testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY +testecho "$N" "$NAME" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4893,11 +4694,10 @@ TEST="$NAME: inheritance of stdin to single exec with pty" if ! eval $NUMCOND; then :; elif ! testfeats pty >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # T value needed (only) by AIX -testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1 +testecho "$N" "$NAME" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1 fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4911,8 +4711,7 @@ TEST="$NAME: readline with password and sigint" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else SAVETERM="$TERM"; TERM= # 'cause console might print controls even in raw SAVEMICS=$MICROS @@ -4925,9 +4724,9 @@ te="$td/test$N.stderr" tr="$td/test$N.ref" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -# the feature that we really want to test is in the readline.sh script +# The feature that we really want to test is in the readline.sh script READLINE_LOG=; if grep -e -lf ./readline.sh >/dev/null; then READLINE_LOG="-lf $td/test$N.rl-log"; fi -CMD="$TRACE $SOCAT -lpwrapper $opts -t1 open:$tpi,nonblock!!open:$tpo exec:\"./readline.sh -nh $READLINE_LOG ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" +CMD="$TRACE $SOCAT -lpwrapper $opts -t1 OPEN:$tpi,nonblock!!OPEN:$tpo EXEC:\"./readline.sh -nh $READLINE_LOG ./readline-test.sh\",pty,ctty,setsid,raw,echo=0,isig" #echo "$CMD" >"$ts" #chmod a+x "$ts" printf "test $F_n $TEST... " $N @@ -4985,14 +4784,12 @@ if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" cat "$te" 2>&1 echo diff: 2>&1 cat "$tdiff" 2>&1 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait MICROS=$SAVEMICS @@ -5047,8 +4844,7 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}4" >&2 echo diff: >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi @@ -5059,8 +4855,7 @@ else if [ "$DEBUG" ]; then cat "${te}3" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD4"; fi if [ "$DEBUG" ]; then cat "${te}4" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -5074,8 +4869,7 @@ TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5135,13 +4929,11 @@ if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then echo "$CMD4 &" cat "${te}4" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" "${te}6"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait @@ -5166,8 +4958,7 @@ TEST="$NAME: gender changer via SSL through HTTP proxy, daemons" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl proxy); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5251,19 +5042,16 @@ if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then echo "$CMD6 &" cat "${te}6_3" cat "${tdiff}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null wait @@ -5307,8 +5095,7 @@ testserversec () { $PRINTF "$NO_RESULT (ph.1 server not working):\n" echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return fi # now use client @@ -5322,8 +5109,7 @@ testserversec () { cat "${te}1" echo "$TRACE $SOCAT $opts - \"$arg2\"" cat "${te}2" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then : # function without security is ok, go on @@ -5334,16 +5120,14 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}2" cat "$tdiff1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return fi # then: with security if [ "$port" ] && ! wait${proto}${ipvers}port $port 0; then $PRINTF "$NO_RESULT (ph.1 port remains in use)\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait; return fi wait @@ -5365,8 +5149,7 @@ testserversec () { wait echo "$CMD3" cat "${te}3" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant return fi # now use client @@ -5392,8 +5175,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ "X$expect" != 'X*' -a X$result != X$expect ]; then case X$result in X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n" @@ -5401,8 +5183,7 @@ testserversec () { cat "${te}3" echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant ;; X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n" echo "$TRACE $SOCAT $opts $arg echo" @@ -5410,8 +5191,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant ;; X1) $PRINTF "$FAILED: SECURITY BROKEN\n" echo "$TRACE $SOCAT $opts $arg echo" @@ -5419,8 +5199,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed ;; X2) $PRINTF "$FAILED: diff:\n" echo "$TRACE $SOCAT $opts $arg echo" @@ -5428,8 +5207,7 @@ testserversec () { echo "$TRACE $SOCAT $opts - $arg2" cat "${te}4" cat "$tdiff2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed ;; esac else @@ -5438,8 +5216,7 @@ testserversec () { [ "$debug" ] && cat ${te}3 [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts - $arg2" [ "$debug" ] && cat ${te}4 - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait #set +vx @@ -5454,8 +5231,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 @@ -5471,8 +5247,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR:255.255.255.255" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 @@ -5522,8 +5297,7 @@ TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5542,8 +5316,7 @@ TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5563,8 +5336,7 @@ TEST="$NAME: security of TCP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "range=[::2]/128" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 @@ -5579,8 +5351,7 @@ TEST="$NAME: security of TCP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 @@ -5595,8 +5366,7 @@ TEST="$NAME: security of TCP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 @@ -5611,8 +5381,7 @@ TEST="$NAME: security of TCP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runstcp6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5666,8 +5435,7 @@ TEST="$NAME: security of UDP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5687,8 +5455,7 @@ TEST="$NAME: security of UDP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0 @@ -5704,8 +5471,7 @@ TEST="$NAME: security of UDP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP6:[::1]:$PORT" 6 udp $PORT 0 @@ -5720,8 +5486,7 @@ TEST="$NAME: security of UDP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0 @@ -5736,8 +5501,7 @@ TEST="$NAME: security of UDP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -5756,8 +5520,7 @@ TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 # provide free port number in $PORT @@ -5773,8 +5536,7 @@ TEST="$NAME: security of SSL-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 # provide free port number in $PORT @@ -5790,8 +5552,7 @@ TEST="$NAME: security of SSL-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 # provide free port number in $PORT @@ -5807,8 +5568,7 @@ TEST="$NAME: security of SSL-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tcp libwrap openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ha="$td/hosts.allow" @@ -5828,8 +5588,7 @@ TEST="$NAME: security of SSL-L with client certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5846,8 +5605,7 @@ TEST="$NAME: security of SSL with server certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5865,12 +5623,10 @@ TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 newport tcp6 # provide free port number in $PORT @@ -5886,12 +5642,10 @@ TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 newport tcp6 # provide free port number in $PORT @@ -5907,12 +5661,10 @@ TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 newport tcp6 # provide free port number in $PORT @@ -5928,8 +5680,7 @@ TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 tcp libwrap openssl && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert6 testsrv6 ha="$td/hosts.allow" @@ -5953,12 +5704,10 @@ TEST="$NAME: security of client openssl-commonname option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -5979,12 +5728,10 @@ TEST="$NAME: security of server openssl-commonname option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -6002,16 +5749,13 @@ TEST="$NAME: OpenSSL restrictions by FIPS" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions fips >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestcert testcli @@ -6027,7 +5771,7 @@ NAME=UNIEXECEOF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: give exec'd write-only process a chance to flush (-u)" -testod "$N" "$TEST" "" EXEC:"$OD_C" "$opts -u" +testod "$N" "$NAME" "$TEST" "" EXEC:"$OD_C" "$opts -u" esac N=$((N+1)) @@ -6036,7 +5780,7 @@ NAME=REVEXECEOF case "$TESTS" in *%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: give exec'd write-only process a chance to flush (-U)" -testod "$N" "$TEST" EXEC:"$OD_C" "-" "$opts -U" +testod "$N" "$NAME" "$TEST" EXEC:"$OD_C" "-" "$opts -U" esac N=$((N+1)) @@ -6051,13 +5795,11 @@ printf "test $F_n $TEST... " $N type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}') if [ "$type" = "dir" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi ;; # NUMCOND esac @@ -6086,16 +5828,14 @@ if [ "$type" = "socket" ]; then echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" >&2 cat "$te1" echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" >&2 cat "$te2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi kill $spid 2>/dev/null wait @@ -6144,8 +5884,7 @@ if echo "$da" |diff - "$tf"> "$tdiff"; then echo " $TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link=\"$tp\" UNIX-LISTEN:\"$ts\"" >&2 echo " $TRACE $SOCAT -lpsocat3 $opts - file:\"$tp\",$PTYOPTS2" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "${YELLOW}FAILED${NORMAL}\n" cat "$te1" @@ -6153,8 +5892,7 @@ else cat "$te3" cat "$te4" cat "$tdiff" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi set +vx } @@ -6167,12 +5905,10 @@ TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" if ! eval $NUMCOND; then :; else if ! feat=$(testfeats pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi @@ -6188,12 +5924,10 @@ TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" fi ;; # NUMCOND, feats @@ -6209,12 +5943,10 @@ TEST="$NAME: test the connect-timeout option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions connect-timeout); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # We need a hanging connection attempt, guess an address for this case "$UNAME" in @@ -6236,8 +5968,7 @@ if ! kill $pid1 2>"$tk1"; then $PRINTF "${YELLOW}does not hang${NORMAL}\n" echo "$CMD" >&2 cat "$te1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Second, set connect-timeout and see if socat exits before kill CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1,connect-timeout=$(reltime 1)" @@ -6248,15 +5979,13 @@ if kill $pid2 2>"$tk2"; then $PRINTF "$FAILED (\n" echo "$CMD" >&2 cat "$te2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -6297,8 +6026,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" @@ -6307,13 +6035,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi ;; esac fi # NUMCOND @@ -6327,8 +6053,7 @@ TEST="$NAME: openssl listen with DSA certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else SRVCERT=testsrvdsa gentestdsacert $SRVCERT @@ -6351,13 +6076,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -6392,8 +6115,7 @@ TEST="$NAME: exit status when dying on SIG$signam" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else SIG="$(signum $signam)" te="$td/test$N.stderr" @@ -6419,14 +6141,12 @@ sleep 1; kill -INT $(cat $tp) wait if [ "$stat" -eq $((128+$SIG)) ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi wait fi ;; # NUMCOND, feats @@ -6443,8 +6163,7 @@ TEST="$NAME: restrict reading from file with bytes option" if ! eval $NUMCOND; then :; elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tr="$td/test$N.ref" ti="$td/test$N.in" @@ -6468,13 +6187,11 @@ if ! diff "$tr" "$to" >"$tdiff" 2>&1; then echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -6488,20 +6205,16 @@ TEST="$NAME: UDP socket rebinds after first connection" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO IP4 UDP PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO UDP4-CONNECT UDP4-LISTEN PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions bind so-reuseaddr fork) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -6526,8 +6239,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$NO_RESULT (first conn failed); diff:\n" @@ -6536,8 +6248,7 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD1" cat "${te}1" >&2 cat "$tdiff" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else relsleep 2 # UDP-LISTEN sleeps 1s echo "$da2" |eval "$CMD1" >"${tf}2" 2>"${te}2" @@ -6548,8 +6259,7 @@ if [ $rc -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then $PRINTF "$FAILED: diff\n" echo "$CMD0 &" @@ -6558,16 +6268,14 @@ elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then cat "${te}1" >&2 echo "diff:" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !( $? -ne 0) fi # !(rc -ne 0) wait @@ -6594,11 +6302,10 @@ TEST="$NAME: $PROTOV listen handles 2 concurrent connections" if ! eval $NUMCOND; then :; #elif ! feat=$(testfeats $PROTOV); then # $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) +# cant elif ! runs$protov >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sock" tref="$td/test$N.ref" @@ -6650,8 +6357,7 @@ if ! diff -u "$tref" "$tf" >"$tdiff"; then echo "$CMD1" cat "${te}2" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -6660,8 +6366,7 @@ else if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats @@ -6703,18 +6408,15 @@ if [ $? -ne 0 ]; then echo "$SRV &" echo "$CLI" cat "${te}s" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED; diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi ;; # NUMCOND @@ -6753,8 +6455,7 @@ if [ $rc -ne 0 ]; then cat "${te}s" echo "$CLI" cat "${te}1" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -6763,12 +6464,10 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CLI" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) fi ;; # NUMCOND esac @@ -6783,7 +6482,7 @@ TEST="$NAME: simple echo via exec of cat with pipes,stderr" # this test is known to fail when logging is enabled with OPTS/opts env var. SAVE_opts="$opts" opts="$(echo "$opts" |sed 's/-dd*//g')" -testecho "$N" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts" +testecho "$N" "$NAME" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts" opts="$SAVE_opts" esac N=$((N+1)) @@ -6800,7 +6499,7 @@ case "$opts" in *-d*) opts="$opts -d" ;; *) opts="-d -d" ;; esac -testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" +testecho "$N" "$NAME" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" opts="$SAVE_opts" esac N=$((N+1)) @@ -6811,7 +6510,7 @@ NAME=SIMPLEPARSE case "$TESTS" in *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*) TEST="$NAME: invoke socat from socat" -testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t" +testecho "$N" "$NAME" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t" esac N=$((N+1)) @@ -6836,20 +6535,17 @@ if [ "$rc" -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$TRACE $SOCAT" -u "exec:echo $da" - cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -s "$tdiff" ]; then $PRINTF "$FAILED:\n" echo diff: cat "$tdiff" if [ -n "$debug" ]; then cat $te; fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -6859,7 +6555,7 @@ NAME=NESTEDSOCATEXEC case "$TESTS" in *%parse%*|*%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: does lexical analysis work sensibly (exec)" -testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1 esac N=$((N+1)) @@ -6867,7 +6563,7 @@ NAME=NESTEDSOCATSYSTEM case "$TESTS" in *%parse%*|*%$N%*|*%functions%*|*%$NAME%*) TEST="$NAME: does lexical analysis work sensibly (system)" -testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1 +testecho "$N" "$NAME" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1 esac N=$((N+1)) @@ -6879,12 +6575,10 @@ TEST="$NAME: TCP4 mapped into TCP6 address space" if ! eval $NUMCOND; then :; elif true; then $PRINTF "test $F_n $TEST... ${YELLOW}Feature removed${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -6905,18 +6599,15 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null; wait fi ;; # NUMCOND, feats @@ -6956,8 +6647,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -6965,13 +6655,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -6986,8 +6674,7 @@ TEST="$NAME: UDP/IPv6 datagram" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7010,18 +6697,15 @@ if [ $? -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -7035,8 +6719,7 @@ TEST="$NAME: raw IPv4 datagram" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7062,18 +6745,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # root, NUMCOND esac @@ -7088,12 +6768,10 @@ TEST="$NAME: raw IPv6 datagram by self addressing" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7115,18 +6793,15 @@ if [ $? -ne 0 ]; then # cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # root, NUMCOND esac @@ -7160,8 +6835,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" @@ -7170,16 +6844,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -7216,8 +6888,7 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -7225,13 +6896,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -7246,8 +6915,7 @@ TEST="$NAME: UDP/IPv6 receive" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7273,18 +6941,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -7298,8 +6963,7 @@ TEST="$NAME: raw IPv4 receive" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7325,18 +6989,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, root esac @@ -7350,12 +7011,10 @@ TEST="$NAME: raw IPv6 receive" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -7380,18 +7039,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, root esac @@ -7425,18 +7081,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -7451,8 +7104,7 @@ TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 @@ -7467,8 +7119,7 @@ TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 @@ -7495,8 +7146,7 @@ TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 udp libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7517,8 +7167,7 @@ TEST="$NAME: security of UDP4-RECV with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7537,8 +7186,7 @@ TEST="$NAME: security of UDP4-RECV with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7556,8 +7204,7 @@ TEST="$NAME: security of UDP4-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7575,8 +7222,7 @@ TEST="$NAME: security of UDP4-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4; PORT1=$PORT newport udp4; PORT2=$PORT @@ -7599,8 +7245,7 @@ TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 @@ -7615,8 +7260,7 @@ TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 @@ -7631,8 +7275,7 @@ TEST="$NAME: security of UDP6-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 @@ -7648,8 +7291,7 @@ TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7669,8 +7311,7 @@ TEST="$NAME: security of UDP6-RECV with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6; PORT1=$PORT newport udp6; PORT2=$PORT @@ -7689,8 +7330,7 @@ TEST="$NAME: security of UDP6-RECV with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6; PORT1=$PORT newport udp6; PORT2=$PORT @@ -7708,8 +7348,7 @@ TEST="$NAME: security of UDP6-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6; PORT1=$PORT newport udp6; PORT2=$PORT @@ -7727,8 +7366,7 @@ TEST="$NAME: security of UDP6-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7751,12 +7389,10 @@ TEST="$NAME: security of IP4-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp4 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0 @@ -7773,12 +7409,10 @@ TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7801,12 +7435,10 @@ TEST="$NAME: security of IP4-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7827,12 +7459,10 @@ TEST="$NAME: security of IP4-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7856,12 +7486,10 @@ TEST="$NAME: security of IP6-RECVFROM with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport udp6 # provide free port number in $PORT #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=[::2]/128" "IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0 @@ -7878,12 +7506,10 @@ TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ha="$td/hosts.allow" hd="$td/hosts.deny" @@ -7905,12 +7531,10 @@ TEST="$NAME: security of IP6-RECV with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7929,12 +7553,10 @@ TEST="$NAME: security of IP6-RECV with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1)) IPPROTO2=$((IPPROTO+1)) @@ -7962,8 +7584,7 @@ TEST="$NAME: option O_NOATIME on file" if ! eval $NUMCOND; then :; elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.file" te="$td/test$N.stderr" @@ -7983,8 +7604,7 @@ if [ $? -ne 0 ]; then # command failed $PRINTF "${FAILED}:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else # check which file has a later atime stamp if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; @@ -7992,13 +7612,11 @@ then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # wrong time stamps fi # command ok fi ;; # NUMCOND, feats @@ -8016,8 +7634,7 @@ TEST="$NAME: option O_NOATIME on file descriptor" if ! eval $NUMCOND; then :; elif ! testoptions o-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.file" te="$td/test$N.stderr" @@ -8039,8 +7656,7 @@ if [ $rc -ne 0 ]; then # command failed $PRINTF "${FAILED} (rc=$rc):\n" echo "$CMD" cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else # check which file has a later atime stamp if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; @@ -8048,14 +7664,12 @@ then $PRINTF "$FAILED (bad order):\n" echo "$CMD" >&2 cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # wrong time stamps fi # command ok fi ;; # NUMCOND, feats @@ -8073,8 +7687,7 @@ TEST="$NAME: extended file system options using fs noatime option" if ! eval $NUMCOND; then :; elif ! testoptions fs-noatime >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}fs-noatime not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.socket" tf="$td/test$N.file" @@ -8089,8 +7702,7 @@ CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",fs-noatime" $CMD0 2>"${te}0" if [ $? -ne 0 ]; then $PRINTF "${YELLOW} cannot test${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # generate a file with noatime, len >= 1 $CMD 2>"$te" @@ -8098,8 +7710,7 @@ if [ $? -ne 0 ]; then # command failed $PRINTF "${YELLOW}impotent file system?${NORMAL}\n" echo "$CMD" cat "$te" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else sleep 1 # generate a reference file @@ -8114,13 +7725,11 @@ then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # not impotent fi # can test @@ -8136,8 +7745,7 @@ TEST="$NAME: option cool-write" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else #set -vx ti="$td/test$N.pipe" @@ -8159,13 +7767,11 @@ if [ $rc -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD &" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8187,8 +7793,7 @@ TEST="$NAME: option cool-write on bidirectional stdio" if ! eval $NUMCOND; then :; elif ! testoptions cool-write >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else #set -vx ti="$td/test$N.pipe" @@ -8212,13 +7817,11 @@ if [ $rc -ne 0 ]; then cat "${te}1" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8265,8 +7868,7 @@ if [ $rc2a -ne 0 -o $rc2b -ne 0 ]; then cat "${te}2a" >&2 echo "$CMD2" cat "${te}2b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -8278,8 +7880,7 @@ elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then echo "$CMD2" cat "${te}2b" >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -8290,8 +7891,7 @@ else if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -8326,19 +7926,16 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1a" "${te}1b" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" cat "${te}1a" "${te}1b" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -8372,14 +7969,12 @@ PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //') rc=$(cat "$td/test$N.rc0") if [ "$rc" = 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -8423,8 +8018,7 @@ if [ $rc1 != 0 -o $rc2 != 0 ]; then cat "${te}1" >&2 echo "$CMD1" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "${tf}" >"$tdiff"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -8433,8 +8027,7 @@ elif echo "$da" |diff - "${tf}" >"$tdiff"; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -8445,8 +8038,7 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "${tdiff}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -8463,8 +8055,7 @@ TEST="$NAME: UDP6-LISTEN with bind" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8486,18 +8077,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8513,8 +8101,7 @@ TEST="$NAME: use of multiple tcpwrapper enabling options" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8538,18 +8125,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8565,8 +8149,7 @@ TEST="$NAME: specification of TCP6 address in hosts.allow" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8592,18 +8175,15 @@ if [ $rc2 -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8617,8 +8197,7 @@ TEST="$NAME: UDP/IPv4 broadcast" if ! eval $NUMCOND; then :; elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8645,13 +8224,11 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$tut" ]; then @@ -8659,8 +8236,7 @@ else echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8677,12 +8253,10 @@ TEST="$NAME: raw IPv4 broadcast" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$BCADDR" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N else @@ -8715,8 +8289,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" @@ -8725,16 +8298,14 @@ elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8764,16 +8335,13 @@ TEST="$NAME: UDP/IPv4 multicast, send only" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 udp) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs UDP4-RECV UDP4-SENDTO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions ip-add-membership bind) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8798,8 +8366,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -8807,16 +8374,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8829,12 +8394,10 @@ TEST="$NAME: IPv4 multicast" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8861,18 +8424,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8889,24 +8449,19 @@ TEST="$NAME: UDP/IPv6 multicast" if ! eval $NUMCOND; then :; elif ! f=$(testfeats ip6 udp); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs - STDIO UDP6-RECV UDP6-SENDTO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions ipv6-join-group) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 does not work on $HOSTNAME${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo |$SOCAT -u -t 0.1 - UDP6-SENDTO:[ff02::1]:12002 >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 multicasting does not work${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -8932,14 +8487,11 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then # if ! [ "$UNAME" = Linux ] || ! [[ $(uname -r) =~ ^2\.* ]] || ! [[ ^3\.* ]] || ! [[ ^4\.[0-4]\.* ]]; then # $PRINTF "${YELLOW}works only on Linux up to about 4.4${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant # else $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -8947,8 +8499,7 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed # fi else $PRINTF "$OK\n" @@ -8956,8 +8507,7 @@ else if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -8994,8 +8544,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -9004,16 +8553,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo diff: >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9026,12 +8573,10 @@ TEST="$NAME: IPv4 multicast, with reply" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9057,13 +8602,11 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$tut" ]; then @@ -9071,8 +8614,7 @@ else echo "$CMD2" fi if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9090,12 +8632,10 @@ TEST="$NAME: reading data sent through tun interface" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tun) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9120,21 +8660,18 @@ if [ $? -ne 0 ]; then echo "$CMD &" echo "$CMD1" cat "${te}" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD &" echo "$CMD1" cat "$tdiff" cat "${te}" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9152,12 +8689,10 @@ TEST="$NAME: pass data through tun interface using INTERFACE" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tun interface) || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9184,8 +8719,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -9194,16 +8728,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9217,8 +8749,7 @@ TEST="$NAME: abstract UNIX stream socket, listen and connect" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.socket" tf="$td/test$N.stdout" @@ -9243,8 +8774,7 @@ if [ $? -ne 0 ]; then cat "${te}s" echo "$CMD" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then kill "$pids" 2>/dev/null $PRINTF "$FAILED:\n" @@ -9253,13 +8783,11 @@ elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then echo "$CMD" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats @@ -9274,8 +8802,7 @@ TEST="$NAME: abstract UNIX datagram" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9300,8 +8827,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -9309,16 +8835,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9332,8 +8856,7 @@ TEST="$NAME: abstract UNIX datagram receive" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.socket" tf="$td/test$N.stdout" @@ -9359,8 +8882,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -9368,16 +8890,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" >&2 cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9396,8 +8916,7 @@ TEST="$NAME: abstract bind" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9413,21 +8932,18 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" echo "rc=$rc1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff -q - $tf; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD1" >&2 cat "${te}1" >&2 echo "$da" |diff - "$tf" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -9454,8 +8970,7 @@ TEST="$NAME: socat handles data buffered by openssl" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.out" te="$td/test$N.err" @@ -9480,13 +8995,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD2" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi wait fi # NUMCOND, featsesac @@ -9510,8 +9023,7 @@ TEST="$NAME: trigger EOF after that many bytes, even when socket idle" if ! eval $NUMCOND; then :; elif false; then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tr="$td/test$N.ref" ti="$td/test$N.in" @@ -9525,13 +9037,11 @@ printf "test $F_n $TEST... " $N if test -s "$to"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -9575,18 +9085,15 @@ if [ $? -ne 0 ]; then echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -f "$tda" ]; then $PRINTF "$FAILED\n" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9626,18 +9133,15 @@ if [ $? -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -9671,15 +9175,13 @@ TEST="$NAME: more than FOPEN_MAX FDs in use" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else REDIR= #set -vx if [ -z "$FOPEN_MAX" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else if [ $FOPEN_MAX -lt 270 ]; then OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX @@ -9692,9 +9194,9 @@ i=3; while [ "$i" -lt "$OPEN_FILES" ]; do i=$((i+1)) done #echo "$REDIR" -#testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 +#testecho "$N" "$NAME" "$TEST" "" "pipe" "$opts -T 3" "" 1 #set -vx -eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR +eval testecho "\"$N\"" "\"$NAME\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR #set +vx fi # could determine FOPEN_MAX fi ;; # NUMCOND @@ -9733,24 +9235,20 @@ l="$(childprocess $pid1)" kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then $PRINTF "$NO_RESULT (client failed)\n" # already handled in test UDP4STREAM - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif $(isdefunct "$l"); then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" echo "$CMD2" cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9793,16 +9291,14 @@ if [ $rc2 -ne 0 ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif $(isdefunct "$l"); then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" @@ -9810,16 +9306,14 @@ elif $(isdefunct "$l"); then echo "$CMD2" cat "${te}2" >&2 cat "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9839,8 +9333,7 @@ TEST="$NAME: raw IPv4 receive with bind" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -9866,18 +9359,15 @@ if [ "$rc2" -ne 0 ]; then echo "$CMD2" cat "${te}1" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, root esac @@ -9916,8 +9406,7 @@ rc2b=$? kill $pid1 2>/dev/null; wait if [ $rc2b -ne 0 ]; then $PRINTF "$NO_RESULT\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" >&2 @@ -9925,13 +9414,11 @@ elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then echo "$CMD2" >&2 cat "${te}2b" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -9958,20 +9445,17 @@ echo "$da" |diff - "$tf" >"$tdiff" if [ "$rc" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -s "$tdiff" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo diff: cat "$tdiff" if [ -n "$debug" ]; then cat $te; fi - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10013,24 +9497,20 @@ fi kill $pid1 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$NO_RESULT\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $nsocks -eq 0 ]; then $PRINTF "$NO_RESULT\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $nsocks -ne 1 ]; then $PRINTF "$FAILED ($nsocks listening sockets)\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10061,19 +9541,16 @@ if [ $rc0 != 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >/dev/null; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi ;; # NUMCOND esac @@ -10099,18 +9576,15 @@ if [ $? -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10139,13 +9613,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10170,20 +9642,16 @@ if ! eval $NUMCOND; then :; #elif [[ "$PF" == "#*" ]]; then : elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats ${KEYW%[46]} IP${KEYW##*[A-Z]}); then $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs${proto} >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available on host${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions $SCM_RECV >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}option $SCM_RECV not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -10239,8 +9707,7 @@ if [ "$rc1" -ne 0 ]; then echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then $PRINTF "$FAILED\n" echo "variable $SCM_TYPE: $SCM_NAME not set" @@ -10248,8 +9715,7 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/null; then $PRINTF "$FAILED\n" badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')" @@ -10258,21 +9724,18 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/ echo "$CMD1" grep " $LEVELS " "${te}0" grep " $LEVELS " "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then grep " $LEVELS " "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "echo XYZ |$CMD1"; fi if [ "$DEBUG" ]; then grep " $LEVELS " "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi # option is not supported fi # NUMCOND, root, feats ;; @@ -10331,12 +9794,10 @@ TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats $FEAT); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs${protov} >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -10374,8 +9835,7 @@ if [ $rc1 != 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \ "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \ \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \ @@ -10388,8 +9848,7 @@ elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g" echo "$CMD1" cat "${te}1" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -10398,8 +9857,7 @@ else cat "${te}1" echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" | diff - "${tf}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND, feats ;; @@ -10438,12 +9896,10 @@ TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME" if ! eval $NUMCOND; then :; elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$PF" = "IP6" ] && ( ! feat=$(testfeats ip6) || ! runsip6 ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -10495,8 +9951,7 @@ if [ "$rc1" -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant #elif ! $GREP_E "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then #elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then @@ -10506,21 +9961,18 @@ elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "{ echo XYZ; sleep 0.1; } |$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi else # option is not supported $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi # option is not supported fi ;; # NUMCOND, feats esac @@ -10588,8 +10040,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10597,13 +10048,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -10619,8 +10068,7 @@ TEST="$NAME: socket connect with TCP/IPv6" if ! eval $NUMCOND; then :; elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # start a TCP6-LISTEN process that echoes data, and send test data using # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned. @@ -10649,8 +10097,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10658,13 +10105,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10699,8 +10144,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10708,13 +10152,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10755,8 +10197,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10764,13 +10205,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10809,8 +10248,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10818,13 +10256,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10864,8 +10300,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10873,13 +10308,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10921,8 +10354,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10930,13 +10362,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -10977,8 +10407,7 @@ if [ "$rc1" -ne 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" @@ -10986,13 +10415,11 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat $te; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -11006,8 +10433,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to more loopback addresses $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4; ts1p=$(printf "%04x" $PORT); testserversec "$N" "$TEST" "$opts" "SOCKET-LISTEN:2:6:x${ts1p}x00000000x0000000000000000,$REUSEADDR,fork,retry=1" "" "range=x0000x7f000000:x0000xffffffff" "SOCKET-CONNECT:2:6:x${ts1p}x${SECONDADDRHEX}x0000000000000000" 4 tcp $PORT 0 @@ -11031,8 +10457,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$TIOCEXCL" ]; then # we use the numeric value of TIOCEXL which is system dependent $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tp="$td/test$N.pty" tf="$td/test$N.stdout" @@ -11057,21 +10482,18 @@ if ! echo "$da" |diff - "$tf" >/dev/null; then echo "$CMD0 &" echo "$CMD1" echo "$da" |diff - "$tf" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc2 -eq 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" echo "$CMD1" echo "$CMD2" cat "${te}0" "${te}1" "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, TIOCEXCL ;; @@ -11096,8 +10518,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$TCP_MAXSEG" ]; then # we use the numeric value of TCP_MAXSEG which might be system dependent $PRINTF "test $F_n $TEST... ${YELLOW}value of TCPMAXSEG not known${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11124,29 +10545,25 @@ if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then echo "$CMD1" cat ${te}1 cat "$tdiff" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc1 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat ${te}0 echo "$CMD1" cat ${te}1 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ $rc2 -eq 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" cat ${te}0 echo "$CMD2" cat ${te}2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -11175,8 +10592,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$SO_REUSEADDR" ]; then # we use the numeric value of SO_REUSEADDR which might be system dependent $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11207,8 +10623,7 @@ if ! echo "$da" |diff - "${tf}1" >"${tdiff}1"; then echo "$CMD1" cat ${te}1 cat "${tdiff}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -11219,8 +10634,7 @@ elif [ $rc3 -ne 0 ]; then cat ${te}2 echo "$CMD3" cat ${te}3 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -11232,13 +10646,11 @@ elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then echo "$CMD3" cat ${te}3 cat "${tdiff}3" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, SO_REUSEADDR ;; @@ -11253,15 +10665,12 @@ TEST="$NAME: echo via connection to SCTP V4 socket" if ! eval $NUMCOND; then :; elif ! testfeats sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N - listCANT="$listCANT $N" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then # RHEL5 based systems became unusable when an sctp socket was created but # module sctp not loaded $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11283,18 +10692,15 @@ if [ $? -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -11310,12 +10716,10 @@ TEST="$NAME: echo via connection to SCTP V6 socket" if ! eval $NUMCOND; then :; elif ! testfeats sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11337,18 +10741,15 @@ if [ $? -ne 0 ]; then cat "${te}1" echo "$CMD2" cat "${te}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED: diff:\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null fi # NUMCOND, feats @@ -11381,21 +10782,17 @@ TEST="$NAME: OpenSSL connections survive renogotiation" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then # openssl s_client apparently provides renegotiation only up to version 1.2 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -11420,16 +10817,14 @@ if echo "$da" |diff - ${tf}1 >"$tdiff"; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif grep -i "Connection refused" "${te}1" >/dev/null; then $PRINTF "$CANT (conn failed)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -11438,8 +10833,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11461,21 +10855,17 @@ TEST="$NAME: OpenSSL connections do not block after renogotiation" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then # openssl s_client apparently provides renegotiation only up to version 1.2 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -11500,16 +10890,14 @@ if echo "$da" |diff - ${tf}1 >"$tdiff"; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif grep -i "Connection refused" "${te}1" >/dev/null; then $PRINTF "$CANT (conn failed)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -11518,8 +10906,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11550,14 +10937,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11585,14 +10970,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11621,14 +11004,12 @@ $CMD0 </dev/null 1>&0 2>"${te}0" rc0=$? if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11668,16 +11049,14 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif grep -q ' W ' "${te}1"; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -11685,12 +11064,10 @@ elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then cat "${te}0" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -11716,14 +11093,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 -a -f "$tf" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11748,14 +11123,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11795,26 +11168,21 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ ! -e "$tw" ]; then $PRINTF "$NO_RESULT (no wc -c output)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ "$bytes" -eq $(cat "$tw") ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (incomplete)\n" echo "transferred only $(cat $tw) of $bytes bytes" >&2 @@ -11822,9 +11190,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -11839,12 +11205,10 @@ TEST="$NAME: OpenSSL server with cipher aNULL " if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -11865,13 +11229,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then #cat "${te}1" #cat "${te}2" #cat "$tdiff" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -11898,12 +11260,10 @@ TEST="$NAME: max-children option" if ! eval $NUMCOND; then :; elif ! testfeats "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else case "X$IPPORT" in "XPORT") @@ -11935,8 +11295,7 @@ relsleep 2 kill $pid1 $pid2 $pid0 2>/dev/null; wait if echo -e "$da 1\n$da 2" |diff - $tf >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -11946,8 +11305,7 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -11986,12 +11344,10 @@ TEST="$NAME: max-children option" if ! eval $NUMCOND; then :; elif ! testfeats "$FEAT" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else case "X$IPPORT" in "XPORT") @@ -12025,8 +11381,7 @@ cpids="$(childpids $pid0)" kill $pid1 $pid2 $pid0 $cpids 2>/dev/null; wait if echo -e "$da 1" |diff - $tf >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -12036,8 +11391,7 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12067,8 +11421,7 @@ TEST="$NAME: test for buffer overflow in readline prompt handling" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats readline pty); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -12086,14 +11439,12 @@ if [ $rc -ne 0 ]; then $PRINTF "${YELLOW}framework failed${NORMAL}\n" elif [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" grep -v ^rc= "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12155,8 +11506,7 @@ if [ $rc2 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -12165,8 +11515,7 @@ elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -12175,8 +11524,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # ulimit -n fi # NUMCOND @@ -12216,19 +11564,16 @@ rc1=$? if [ $rc1 -lt 128 ]; then if [ "$EF" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n" - numCANT=$((num+1)) - listCANT="$listCANT $N" + cant fi else $PRINTF "$FAILED\n" echo "$CMD1" cat "${te}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12269,26 +11614,21 @@ if [ -z "$KEEPALIVE" ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ "$KEEPALIVE" = "1" ]; then $PRINTF "$OK\n"; if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (KEEPALIVE=$KEEPALIVE)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -12308,8 +11648,7 @@ TEST="$NAME: test OPENSSL-CONNECT with bind option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf0="$td/test$N.0.stdout" @@ -12334,8 +11673,7 @@ if [ "$rc1" -ne 0 ]; then echo "$CMD1" cat "$te0" cat "$te1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - $tf1 >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -12343,12 +11681,10 @@ elif ! echo "$da" |diff - $tf1 >"$tdiff"; then cat "${te}0" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -12366,8 +11702,7 @@ if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then # we need access to a second address $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -12387,24 +11722,20 @@ sleep 1 kill $pid0 2>/dev/null; wait if [ $rc1 != 0 ]; then $PRINTF "${YELLOW}invocation failed${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ -f "$tf" ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "${YELLOW}diff failed${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # $SECONDADDR, NUMCOND @@ -12430,8 +11761,7 @@ FEAT=$(echo "$ssldist" |tr a-z A-Z) if ! eval $NUMCOND; then :; elif ! testfeats $FEAT >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -12470,8 +11800,7 @@ if [ $rc1 != 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")"; [ "$effval" = "$VALUE" ]; then $PRINTF "$OK\n" @@ -12481,8 +11810,7 @@ elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=] echo "$CMD1" cat "${te}1" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "expected \"$VALUE\", got \"$effval\"" >&2 @@ -12490,8 +11818,7 @@ else cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND, feats ;; @@ -12553,18 +11880,15 @@ if [ "$ERRNOENT" ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed elif [ "$perms" != "600" ]; then $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok fi set +xv fi # NUMCOND @@ -12629,18 +11953,15 @@ if [ "$ERRNOENT" ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed elif [ "$perms" != "511" ]; then $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n" echo "$CMD0 &" cat "$te0" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok fi set +vx fi # NUMCOND @@ -12680,8 +12001,7 @@ TEST="$NAME: $ADDR applies option user" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tlog="$td/test$N.log" te0="$td/test$N.0.stderr" @@ -12705,20 +12025,17 @@ if [ "$ERRNOENT" ]; then echo "$CMD0 &" cat "$te0" >&2 cat "$tlog" >&2 - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed elif [ "$user" != "$SUBSTUSER" ]; then $PRINTF "${FAILD}(user \"$user\", expected \"$SUBSTUSER\")\n" echo "$CMD0 &" cat "$te0" >&2 - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi set +vx fi # NUMCOND @@ -12778,19 +12095,16 @@ if [ $rc1 != 0 ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ $crit $tsock ]; then $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12847,19 +12161,16 @@ if [ $rc1 != 0 ]; then echo "$CMD0 &" cat "$te0" cat "$tlog" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ $crit $tsock ]; then $PRINTF "$OK\n" - let numOK=numOK+1 - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "$te0" cat "$tlog" - let numFAIL=numFAIL+1 - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -12887,8 +12198,7 @@ TEST="$NAME: SYSTEM address does not shutdown its parents addresses" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -12912,8 +12222,7 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then $PRINTF "$FAILED\n" echo "diff:" @@ -12922,12 +12231,10 @@ elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -12959,19 +12266,16 @@ if [ ! -f "$t0rc" ]; then echo "no return code of CMD0 stored" >&2 echo "$CMD0 &" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo 1 |diff - "$t0rc" >"$tdiff"; then $PRINTF "$FAILED\n" echo "CMD0 exited with $(cat $t0rc), expected 1" echo "$CMD0 &" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -12999,12 +12303,10 @@ TEST="$NAME: test OpenSSL method $method" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -13017,8 +12319,7 @@ CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,opensslmethod=$method,veri printf "test $F_n $TEST... " $N if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $CMD0 >/dev/null 2>"${te}0" & pid0=$! @@ -13031,13 +12332,11 @@ fi echo "$da" |diff - "${tf}1" >"$tdiff" 2>/dev/null if [ $w0 -eq 0 ] && [ -f "${tf}1" ] && ! [ -s "$tdiff" ]; then $PRINTF "${YELLOW}WARN${NORMAL} (obsolete method succeeds)\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$OK (obsolete method fails)\n" cat "$tdiff" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi if [ "$VERBOSE" ]; then echo " $CMD0" @@ -13067,12 +12366,10 @@ TEST="$NAME: test OpenSSL method $method" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -13089,8 +12386,7 @@ CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,openssl-method=$method,ver printf "test $F_n $TEST... " $N if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $CMD0 >/dev/null 2>"${te}0" & pid0=$! @@ -13104,8 +12400,7 @@ rc1=$? kill $pid0 2>/dev/null; wait if echo "$da" |diff - "${tf}1" >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok if [ "$VERBOSE" ]; then echo " $CMD0" echo " echo \"$da\" |$CMD1" @@ -13117,8 +12412,7 @@ else echo "$CMD1" cat "${te}1" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed #esac fi fi # !DTLS1 hang @@ -13140,17 +12434,14 @@ TEST="$NAME: security of OpenSSL server with openssl-min-proto-version" if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions openssl-min-proto-version); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! [ "$OPENSSL_LATEST_PROTO_VERSION" -a "$OPENSSL_BEFORELAST_PROTO_VERSION" -a \ "$OPENSSL_LATEST_PROTO_VERSION" != "$OPENSSL_BEFORELAST_PROTO_VERSION" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}cannot determine two available SSL/TLS versions${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv newport tcp4 @@ -13178,15 +12469,13 @@ $CMD >/dev/null 2>"${te}" rc=$? if [ $rc -eq 1 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" echo "command did not terminate with error!" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13215,12 +12504,10 @@ if [ $rc0 -eq 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -13249,12 +12536,10 @@ if [ $rc0 -eq 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -13276,8 +12561,7 @@ TEST="$NAME: test the so-reuseaddr option" if ! eval $NUMCOND; then :; elif ! feat=$(testoptions so-reuseaddr); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4; tp="$PORT" tf="$td/test$N.stdout" @@ -13305,8 +12589,7 @@ if ! echo "$da" |diff - "$tf"; then $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" echo "$CMD0 &" echo "$CMD1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -13314,8 +12597,7 @@ elif [ $rc3 -ne 0 ]; then echo "$CMD2 &" echo "$CMD3" cat "${te}2" "${te}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}3"; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD0 &" @@ -13323,13 +12605,11 @@ elif ! echo "$da" |diff - "${tf}3"; then echo "$CMD2 &" echo "$CMD3" echo "$da" |diff - "${tf}3" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, SO_REUSEADDR ;; @@ -13350,8 +12630,7 @@ TEST="$NAME: test the so-reuseport option" if ! eval $NUMCOND; then :; elif ! feat=$(testoptions so-reuseport); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4; tp="$PORT" tf="$td/test$N.stdout" @@ -13382,8 +12661,7 @@ if ! echo "$da2" |diff - "${tf}2"; then cat "${te}1" echo "$CMD2" cat "${te}2" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc3 -ne 0 ]; then $PRINTF "$FAILED:\n" echo "$CMD0 &" @@ -13394,8 +12672,7 @@ elif [ $rc3 -ne 0 ]; then cat "${te}2" echo "$CMD3" cat "${te}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da2" |diff - "${tf}2"; then $PRINTF "$FAILED:\n" echo "$CMD0 &" @@ -13407,8 +12684,7 @@ elif ! echo "$da2" |diff - "${tf}2"; then echo "$CMD3" cat "${te}3" echo "$da2" |diff - "${tf}2" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da3" |diff - "${tf}3"; then $PRINTF "$FAILED:\n" echo "$CMD0 &" @@ -13420,13 +12696,11 @@ elif ! echo "$da3" |diff - "${tf}3"; then echo "$CMD3" cat "${te}3" echo "$da3" |diff - "${tf}3" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND, SO_REUSEPORT ;; @@ -13452,15 +12726,13 @@ eval "$CMD0" >"${tf}0" 2>"${te}0" rc1=$? if echo "$da" |diff - "${tf}0" >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13480,12 +12752,10 @@ TEST="$NAME: test OpenSSL ECDHE" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! openssl ciphers |grep -q '\<ECDHE\>'; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl: cipher ECDHE not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -13512,12 +12782,10 @@ if [ $rc1 -ne 0 ]; then echo "client and stderr:" >&2 echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "${tf}1" >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "server and stderr:" >&2 @@ -13526,8 +12794,7 @@ else echo "client and stderr:" >&2 echo "$CMD0 &" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13557,14 +12824,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13593,19 +12858,16 @@ if [ $rc0 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - ${tf}0 >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13625,13 +12887,11 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ "$rc0" = "1" ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi ;; # NUMCOND esac @@ -13662,16 +12922,14 @@ $CMD1 2>"${te}1" rc0=$? if [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" echo "$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13698,14 +12956,12 @@ printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" if ! grep -q "ai_socktype not supported" ${te}0; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13736,16 +12992,14 @@ rc1=$? kill $pid0 2>/dev/null; wait if [ $(grep "socket 2 (fd .*) is at EOF" ${te}0 |wc -l) -eq 1 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13781,19 +13035,16 @@ if [ $rc0 -eq 0 ]; then $PRINTF "$FAILED (rc=$rc0)\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif [ $rc0 -eq 1 ]; then if grep -q "buffer size option (-b) to big" "${te}0"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (rc=$rc0)\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi fi # NUMCOND @@ -13820,14 +13071,12 @@ if grep -q -i -e "syntax error" -e "unexpected end" "${te}0"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi if [ "$debug" ]; then cat ${te} >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13849,8 +13098,7 @@ TEST="$NAME: Service name resolution works with SCTP" if ! eval $NUMCOND; then :; elif ! runssctp4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -13860,18 +13108,15 @@ printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" if [ $? -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif grep -q "Connection refused" ${te}0; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -13889,8 +13134,7 @@ TEST="$NAME: echo via file with o-direct" if ! eval $NUMCOND; then :; elif ! testoptions o-direct >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}o-direct not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.file" to="$td/test$N.stdout" @@ -13908,29 +13152,24 @@ if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then $PRINTF "${FAILED}\n" echo "$CMD" >&2 cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" ;; + failed ;; *) $PRINTF "${YELLOW}inable file system${NORMAL}\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" ;; + cant ;; esac elif [ $rc -ne 0 ]; then $PRINTF "${FAILED}:\n" echo "$CMD" >&2 cat "$te" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$to" >$tdiff; then $PRINTF "${FAILED}\n" echo "$CMD" >&2 cat "$te" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi # command ok fi ;; # NUMCOND, feats esac @@ -13964,8 +13203,7 @@ rc1=$? kill $pid0 2>/dev/null; wait if test -S $uns && ! test -S $unc; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -13973,8 +13211,7 @@ else ls -ld $uns $unc cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14008,8 +13245,7 @@ rc1=$? kill $pid0 2>/dev/null; wait if test -S $uns && ! test -S $unc; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -14017,8 +13253,7 @@ else ls -ld $uns $unc cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14036,20 +13271,16 @@ TEST="$NAME: OpenSSL DTLS client" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-client); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -14074,13 +13305,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "$te"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -14096,25 +13325,20 @@ TEST="$NAME: OpenSSL DTLS server" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-server); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -14134,8 +13358,7 @@ rc=$? kill $pid1 2>/dev/null; wait if echo "$da" |diff - $tf >"$tdiff"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -14143,8 +13366,7 @@ else echo "$CMD" cat "$te" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14159,12 +13381,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (hostname)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestaltcert testalt tf="$td/test$N.stdout" @@ -14186,13 +13406,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14207,12 +13425,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv4 address)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 openssl >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestaltcert testalt tf="$td/test$N.stdout" @@ -14234,13 +13450,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14255,12 +13469,10 @@ TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv6 address)" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip6 openssl >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestaltcert testalt tf="$td/test$N.stdout" @@ -14282,13 +13494,11 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14308,8 +13518,7 @@ TEST="$NAME: raw dump of transferred data" if ! eval $NUMCOND; then :; elif [ $($SOCAT -h |grep -e ' -[rR] ' |wc -l) -lt 2 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Options -r, -R not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14339,12 +13548,10 @@ if ! echo "$da1" |diff - $tr1 >$tdiff1 || ! echo "$da2" |diff - $tr2 >$tdiff2; t cat $tdiff1 >&2 echo "Right-to-left:" >&2 cat $tdiff2 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -14364,16 +13571,13 @@ SNISERVER=badssl.com if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions openssl-snihost); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14385,14 +13589,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -eq 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14413,16 +13615,13 @@ SNISERVER=badssl.com if ! eval $NUMCOND; then :; elif ! testaddrs openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions openssl-no-sni); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14434,14 +13633,12 @@ $CMD0 >/dev/null 2>"${te}0" rc0=$? if [ $rc0 -ne 0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14457,12 +13654,10 @@ TEST="$NAME: test the accept-timeout option" if ! eval $NUMCOND; then :; elif ! feat=$(testaddrs tcp); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testoptions accept-timeout); then $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Just start a process with accept-timeout 1s and check if it still runs 2s later # but before this, we test if the process waits at all @@ -14482,8 +13677,7 @@ if ! kill $pid1 2>"$tk1"; then echo $CMD1 >&2 cat "$te1" >&2 cat "$tk1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Second, set accept-timeout and see if socat exits before kill CMD2="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,accept-timeout=$(reltime 1) PIPE" @@ -14495,12 +13689,10 @@ if kill $pid2 2>"$tk2"; then echo "$CMD2" >&2 cat "$te2" >&2 cat "$tk2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -14520,8 +13712,7 @@ TEST="$NAME: test UDP-DATAGRAM ignoring peerport" if ! eval $NUMCOND; then : elif [ $(echo $E "$SOCAT_VERSION\n1.7.3.4" |sort -n |tail -n 1) = 1.7.3.4 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only with Socat 1.7.4.0 or higher${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14542,8 +13733,7 @@ sleep 0.1 kill $pid0 2>/dev/null; wait if [ -f ${tf}0 ] && echo "$da" |diff - ${tf}0 >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14551,8 +13741,7 @@ else echo "$CMD1" >&2 cat "${te}1" >&2 cat "${tdiff}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14568,16 +13757,13 @@ TEST="$NAME: proxy-authorization-file option" if ! eval $NUMCOND; then :; elif ! testfeats proxy >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testoptions proxy-authorization-file >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option proxy-authorization-file not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ta="$td/test$N.auth" tf="$td/test$N.stdout" @@ -14603,8 +13789,7 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" >&2 cat "${te}1" >&2 cat "${tf}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then $PRINTF "$FAILED:\n" echo "$CMD0 &" >&2 @@ -14613,13 +13798,11 @@ elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then cat "${te}1" >&2 cat "${tf}0" >&2 echo "Authorization string not in client request" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -14638,8 +13821,7 @@ TEST="$NAME: test communication via VSOCK loopback socket" if ! eval $NUMCOND; then :; elif ! fea=$(testfeats VSOCK); then $PRINTF "test $F_n $TEST... ${YELLOW}$fea not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14657,36 +13839,30 @@ rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ] && [ "$UNAME" != Linux ]; then $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif grep -q "No such device" "${te}1"; then $PRINTF "${YELLOW}Loopback does not work${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $rc1 -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14708,16 +13884,13 @@ TEST="$NAME: OpenSSL stream from client to server" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 tcp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-listen openssl-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14743,12 +13916,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14758,8 +13929,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14780,16 +13950,13 @@ TEST="$NAME: OpenSSL stream from server to client" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 tcp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-listen openssl-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14815,12 +13982,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14830,8 +13995,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14851,21 +14015,17 @@ TEST="$NAME: OpenSSL DTLS transfer from client to server" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14891,12 +14051,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14906,8 +14064,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -14927,21 +14084,17 @@ TEST="$NAME: OpenSSL DTLS transfer from server to client" if ! eval $NUMCOND; then :; elif ! a=$(testfeats ip4 udp openssl); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv ti="$td/test$N.datain" @@ -14967,12 +14120,10 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif diff $ti $to >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 @@ -14982,8 +14133,7 @@ else echo "diff:" >&2 head -n 2 $tdiff >&2 echo ... >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15002,16 +14152,13 @@ TEST="$NAME: test diverse of socket,openssl params" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -15032,19 +14179,17 @@ sleep 0.5 kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ]; then $PRINTF "$CANT\n" - numCANT=$((numCANT+1)) + cant elif [ ! -e $trc0 ]; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15063,12 +14208,10 @@ TEST="$NAME: Test if OpenSSL server may be crashed by client cert with IPv6 addr if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else gentestcert testsrv gentestaltcert testalt @@ -15088,16 +14231,14 @@ rc1=$? kill $pid0 2>/dev/null; wait if [ $rc1 -eq 0 ] && echo "$da" |diff - "${tf}0" >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15128,14 +14269,12 @@ if [ $rc -ne 0 ]; then if [ "$VERBOSE" ]; then echo "$CMD &" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD &" >&2 cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15154,8 +14293,7 @@ TEST="$NAME: Is the fs related user option on ABSTRACT socket applied to FD" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15171,14 +14309,12 @@ if [ $rc -eq 0 ]; then if [ "$VERBOSE" ]; then echo "$CMD" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" >&2 cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15208,21 +14344,18 @@ if [ ! -f "$ts" ]; then echo "$CMD" >&2 cat "${te}" >&2 fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ ! -s "$ts" ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD &" >&2 cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15295,8 +14428,7 @@ if [ $rc1 != 1 ]; then fi echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then $PRINTF "$FAILED ($nerr error message(s) instead of 1)\n" if [ "$pid0" ]; then @@ -15305,16 +14437,14 @@ elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then fi echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then if [ "$pid0" ]; then echo "$CMD0 &" >&2; fi echo "$CMD1" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi set +vx fi # NUMCOND @@ -15390,24 +14520,21 @@ if [ $rc1 -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &" >&2 echo "$CMD1" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" >&2 cat "${te}0" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15437,14 +14564,12 @@ if [ $rc0 -eq 0 ]; then if [ "$VERBOSE" ]; then echo "$CMD0" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" >&2 cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15482,20 +14607,17 @@ if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then $PRINTF "$CANT (no SYCLS)\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15520,14 +14642,12 @@ printf "test $F_n $TEST... " $N $CMD0 </dev/null >/dev/null 2>"${te}0" if grep -q "missing numerical value" "${te}0"; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15553,14 +14673,12 @@ if grep -q "trailing garbage" "${te}0"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi if [ "$debug" ]; then cat ${te} >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15590,16 +14708,14 @@ if [ "$target" = "$tf" ]; then echo "ln -s \"$tf\" \"$tl\"" echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "touch \"$tf\"" >&2 echo "ln -s \"$tf\" \"$tl\"" >&2 echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" >&2 cat "$te" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi kill $spid 2>/dev/null wait @@ -15653,8 +14769,7 @@ for addr in exec system; do cat "${te}0" echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" >&2 @@ -15663,16 +14778,14 @@ for addr in exec system; do cat "${te}1" >&2 echo "diff:" >&2 cat $tdiff >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &" >&2 echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" >&2 fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi MICROS=$SAVEMICS fi # NUMCOND @@ -15693,12 +14806,10 @@ TEST="$NAME: Dalan syntax error does not raise SIGSEGV" if ! eval $NUMCOND; then : elif ! a=$(testfeats GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs - GOPEN SOCKET-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15712,21 +14823,18 @@ if [ $rc1 -eq 1 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif [ $rc1 -eq 139 ]; then $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else # soemthing unexpected happened $PRINTF "$CANT\n" echo "$CMD" cat "${te}" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant fi fi # NUMCOND ;; @@ -15746,20 +14854,16 @@ TEST="$NAME: filan -s displays TCP etc" if ! eval $NUMCOND; then : elif ! a=$(testfeats STDIO IP4 TCP LISTEN EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs STDIO TCP4 TCP4-LISTEN EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr nofork ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15781,8 +14885,7 @@ if [ $rc1 -eq 0 -a "$result" = tcp ]; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" if [ $rc1 -ne 0 ]; then @@ -15794,8 +14897,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15819,20 +14921,16 @@ TEST="$NAME: Restoring of terminal settings" if ! eval $NUMCOND; then : elif ! $(type stty >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}stty not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testfeats STDIO SYSTEM PTY GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! a=$(testaddrs - STDIO SYSTEM GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions cfmakeraw pty setsid ctty stderr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else te="$td/test$N.stderr" tx0="$td/test$N.stty0" @@ -15847,16 +14945,14 @@ if diff $tx0 $tx1 >$tdiff 2>&1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD &"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 cat "${te}.outer" >&2 cat $tdiff >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15876,12 +14972,10 @@ TEST="$NAME: Socat does not leak FDs to EXEC'd program" if ! eval $NUMCOND; then :; elif ! a=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions stderr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15895,15 +14989,13 @@ if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" >&2 cat "${te}" >&2 cat "${tf}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15923,12 +15015,10 @@ TEST="$NAME: Socat does not leak sniffing FDs" if ! eval $NUMCOND; then :; elif ! a=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions stderr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -15942,15 +15032,13 @@ if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" >&2 cat "${te}" >&2 cat "${tf}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -15976,20 +15064,16 @@ TEST="$NAME: ${KEYW}-RECVFROM with fork option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats $FEAT STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - STDIO SYSTEM $PROTO-RECVFROM $PROTO-SENDTO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runs$RUNS >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else case "X$IPPORT" in "XPORT") @@ -16029,8 +15113,7 @@ if $ECHO "$da 2\n$da 1" |diff -u - $tf >$tdiff; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -16041,9 +15124,7 @@ else cat "${te}2" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16066,16 +15147,13 @@ TEST="$NAME: Option -S can turn off logging of SIGTERM" if ! eval $NUMCOND; then :; elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16092,16 +15170,13 @@ if ! grep "exiting on signal" ${te}0 >/dev/null; then if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$DEBUG" ]; then echo "kill -TERM <pid>" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "kill -TERM <pid>" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16119,16 +15194,13 @@ TEST="$NAME: Option -S can turn on logging of signal 31" if ! eval $NUMCOND; then :; elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16145,16 +15217,13 @@ if grep "exiting on signal" ${te}0 >/dev/null; then if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$DEBUG" ]; then echo "kill -31 <pid>" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "kill -31 <pid>" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16170,24 +15239,19 @@ TEST="$NAME: PROXY-CONNECT with option http-version" if ! eval $NUMCOND; then :; elif ! $(type proxyecho.sh >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}proxyecho.sh not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 TCP LISTEN EXEC STDIO PROXY); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP4-LISTEN EXEC STDIO PROXY-CONNECT); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr crlf pf proxyport http-version) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sh" tf="$td/test$N.stdout" @@ -16209,16 +15273,14 @@ if ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$debug" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$debug" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid 2>/dev/null wait @@ -16236,20 +15298,16 @@ TEST="$NAME: test the so-rcvtimeo option with DTLS" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO OPENSSL); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO DTLS); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions verify so-rcvtimeo) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # We need a hanging connection attempt, guess an address for this HANGIP=0.0.0.1 @@ -16267,8 +15325,7 @@ if ! kill -0 $pid1 2>"$tk1"; then $PRINTF "${YELLOW}does not hang${NORMAL}\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant wait else # DTLS restarts read() a few times @@ -16283,16 +15340,14 @@ if kill $pid2 2>"$tk2"; then echo "$CMD2" >&2 cat "$te2" >&2 cat "$tk2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed while kill $pid2 2>/dev/null; do :; done wait else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi wait @@ -16314,20 +15369,16 @@ TEST="$NAME: sniff file names with variables" if ! eval $NUMCOND; then :; elif ! A=$(testfeats IP4 TCP LISTEN PIPE STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr fork) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16354,9 +15405,7 @@ if [ $rc1a != 0 -o $rc1b != 0 ]; then cat "${te}1a" >&2 echo "$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 && test $(ls $td/test$N.*.log |head -n 1 |wc -c) -ge 56; then # Are the names correct? @@ -16369,8 +15418,7 @@ elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 && if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.in.log; then $PRINTF "$FAILED (vars not resolved)\n" echo "$CMD0 &" @@ -16379,9 +15427,7 @@ elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$. cat "${te}1a" >&2 echo "$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$FAILED (unknown)\n" echo "$CMD0 &" @@ -16390,9 +15436,7 @@ else cat "${te}1a" >&2 echo "$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16410,20 +15454,16 @@ TEST="$NAME: Socat option --statistics" if ! eval $NUMCOND; then :; elif ! $(type >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats STATS STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16438,21 +15478,17 @@ if [ $rc0 -ne 0 ]; then $PRINTF "$CANT\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(grep STATISTICS "${te}0" |wc -l) -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16469,24 +15505,19 @@ TEST="$NAME: statistics on SIGUSR1" if ! eval $NUMCOND; then :; elif ! $(type tee >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type pkill >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}pkill not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats STATS STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16507,15 +15538,12 @@ if [ "$(grep STATISTICS "${te}0" |wc -l)" -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16534,16 +15562,13 @@ TEST="$NAME: test the children-shutup option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs UNIX-LISTEN TCP4 FILE UNIX-CONNECT); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork children-shutup) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else newport tcp4 ts="$td/test$N.sock" @@ -16567,17 +15592,14 @@ if grep -q " W connect" ${te}0; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16597,28 +15619,22 @@ TEST="$NAME: INTERFACE ignores outgoing packets" if ! eval $NUMCOND; then :; elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type ping >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}ping not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! feat=$(testfeats TUN STDIO INTERFACE); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - TUN STDIO INTERFACE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions iff-up tun-type tun-name ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16651,8 +15667,7 @@ if [ $? -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif test -s "${tf}1"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -16661,8 +15676,7 @@ elif test -s "${tf}1"; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -16671,8 +15685,7 @@ else if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND, feats esac @@ -16692,20 +15705,16 @@ TEST="$NAME: test if option reuseaddr's default is 1" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO PIPE TCP4 TCP4-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions accept-timeout) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16732,8 +15741,7 @@ if [ $rc0b -eq 0 ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0a &" @@ -16742,9 +15750,7 @@ else cat "${te}1" >&2 echo "$CMD0b" cat "${te}0b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16763,20 +15769,16 @@ TEST="$NAME: test if option reuseaddr's default is 1 with SSL-L" if ! eval $NUMCOND; then :; elif ! F=$(testfeats PIPE IP6 TCP OPENSSL LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs PIPE OPENSSL-CONNECT OPENSSL-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions verify cert key) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16807,8 +15809,7 @@ if [ $rc0b -eq 0 ]; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0a &" @@ -16817,9 +15818,7 @@ else cat "${te}1" >&2 echo "$CMD0b" cat "${te}0b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16838,20 +15837,16 @@ TEST="$NAME: test option reuseaddr without value" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO PIPE TCP4-CONNECT TCP4-LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions so-reuseaddr accept-timeout) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16878,8 +15873,7 @@ if [ $rc0b -eq 1 ] && grep -q -e "Address already in use" -e "Address in use" "$ if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok #elif grep -q "accept: \(Connection\|Operation\) timed out" "${te}0b"; then elif grep -q "accept: .* timed out" "${te}0b"; then # FreeBSD, Solaris do not seem to need SO_REUSEADDR with TCP at all @@ -16890,8 +15884,7 @@ elif grep -q "accept: .* timed out" "${te}0b"; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD0b"; fi if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$FAILED\n" echo "$CMD0a &" @@ -16900,9 +15893,7 @@ else cat "${te}1" >&2 echo "$CMD0b" cat "${te}0b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -16925,28 +15916,22 @@ TEST="$NAME: try all available TCP4 addresses" if ! eval $NUMCOND; then :; elif ! $(type nslookup >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then # $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant elif ! F=$(testfeats IP4 TCP GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP4-CONNECT GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -16980,15 +15965,12 @@ if [ $(grep " N opening connection to .*AF=2 " ${te} |wc -l) -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17009,32 +15991,25 @@ TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses" if ! eval $NUMCOND; then :; #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then # $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant elif ! F=$(testfeats IP4 IP6 TCP); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs TCP-CONNECT GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions ai-addrconfig) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ -z "$INTERNET" ]; then # only needs Internet DNS $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17082,15 +16057,12 @@ if [ $(grep " N opening connection to .*AF=[0-9]" ${te} |wc -l) -eq 2 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD"; fi if [ "$DEBUG" ]; then cat "${te}" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD" cat "${te}" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17110,32 +16082,25 @@ TEST="$NAME: option netns (net namespace $ns)" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type ip >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 TCP LISTEN NAMESPACES); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO TCP-LISTEN TCP EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions netns) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17167,9 +16132,7 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}1" >&2 echo "ip netns del $ns" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then @@ -17183,8 +16146,7 @@ elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "ip netns del $ns"; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (bad output)\n" echo "$CMD0 &" @@ -17193,9 +16155,7 @@ else cat "${te}1" >&2 diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17217,32 +16177,25 @@ TEST="$NAME: option netns with EXEC (net namespace $ns)" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! $(type ip >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 ABSTRACT_UNIXSOCKET UDP LISTEN NAMESPACES STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs ABSTRACT-RECV ABSTRACT-SENDTO CREATE EXEC UDP4-RECV STDIO UDP4); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions netns) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17275,9 +16228,7 @@ if [ $rc1 -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -17286,8 +16237,7 @@ elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED (bad output)\n" echo "$CMD0 &" @@ -17298,9 +16248,7 @@ else cat "${te}2" >&2 echo diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17321,11 +16269,9 @@ if ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else - testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts" + testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR" "$opts" fi esac N=$((N+1)) @@ -17343,11 +16289,9 @@ if ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else - testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts" + testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts" fi esac N=$((N+1)) @@ -17365,11 +16309,9 @@ if ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else - testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts" + testecho "$N" "$NAME" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts" fi esac N=$((N+1)) @@ -17387,20 +16329,16 @@ TEST="$NAME: Internal socketpair keeps packet boundaries" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO IP4 UDP SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - STDIO UDP4-DATAGRAM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions bind socktype ) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17425,8 +16363,7 @@ if [ "$rc2" -ne 0 ]; then cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD1 &" @@ -17435,16 +16372,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}2" >&2 echo diff: cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -17464,20 +16399,16 @@ TEST="$NAME: ACCEPT-FD address" if ! eval $NUMCOND; then :; elif ! $(type systemd-socket-activate >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats IP4 TCP LISTEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs ACCEPT-FD PIPE STDIO TCP4); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17499,8 +16430,7 @@ if echo "$da" |diff "${tf}1" - >$tdiff; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -17508,9 +16438,7 @@ else echo "$CMD1" cat "${te}1" >&2 cat $tdiff >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17531,20 +16459,16 @@ TEST="$NAME: POSIX-MQ (Linux) with prio" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats POSIXMQ STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions mq-prio unlink-early unlink-close) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17571,9 +16495,7 @@ if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then cat "${te}0b" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0a"; fi @@ -17582,8 +16504,7 @@ elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0a" @@ -17594,9 +16515,7 @@ else cat "${te}1" >&2 echo "difference:" >&2 cat ${tdiff}1 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17615,20 +16534,16 @@ TEST="$NAME: POSIX-MQ (Linux) RECV with fork" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats POSIXMQ STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork unlink-early unlink-close) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17656,9 +16571,7 @@ if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi @@ -17667,8 +16580,7 @@ elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1b"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" @@ -17679,9 +16591,7 @@ else cat "${te}1b" >&2 echo "difference:" >&2 cat ${tdiff}0 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17702,20 +16612,16 @@ TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork max-children unlink-early unlink-close) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17746,9 +16652,7 @@ if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi @@ -17757,8 +16661,7 @@ elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1b"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" @@ -17769,9 +16672,7 @@ else cat "${te}1b" >&2 echo "difference:" >&2 cat ${tdiff}0 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17794,24 +16695,19 @@ TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children" if ! eval $NUMCOND; then :; elif [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions fork max-children mq-prio unlink-early unlink-close) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant #elif ! runsposixmq >/dev/null; then # $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" +# cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17841,8 +16737,7 @@ if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0" @@ -17851,9 +16746,7 @@ else cat "${te}1" >&2 echo "difference:" >&2 cat ${tdiff}0 >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17872,16 +16765,13 @@ TEST="$NAME: sigint option with SHELL" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions setsid sigint) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -17902,15 +16792,12 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0" || $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -17927,14 +16814,12 @@ TEST="$NAME: simple echo via SHELL of cat with socketpair" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t" + testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t" fi esac N=$((N+1)) @@ -17948,14 +16833,12 @@ TEST="$NAME: simple echo via SHELL of cat with pipes" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t" + testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t" fi esac N=$((N+1)) @@ -17969,19 +16852,16 @@ TEST="$NAME: simple echo via SHELL of cat with pty" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL PTY); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PTY); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$SHELL" = /bin/ksh ]; then # on NetBSD-9.3 this test kills test.sh script... $PRINTF "test $F_n $TEST... ${YELLOW}/bin/ksh might kill test.sh${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testecho "$N" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t" + testecho "$N" "$NAME" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t" fi esac N=$((N+1)) @@ -17995,14 +16875,12 @@ TEST="$NAME: call od -c via SHELL using socketpair" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testod "$N" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t" + testod "$N" "$NAME" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t" fi esac N=$((N+1)) @@ -18016,14 +16894,12 @@ TEST="$NAME: call od -c via SHELL using pipes" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SHELL PIPE); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else - testod "$N" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t" + testod "$N" "$NAME" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t" fi esac N=$((N+1)) @@ -18043,20 +16919,16 @@ elif [ "$UNAME" = "NetBSD" ]; then # On NetBSD-4.0 and NetBSD-9.3 this test hangs (signal has no effect) # (other versions not tried) $PRINTF "test $F_n $TEST... ${YELLOW}might hang on $UNAME${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats SYCLS STDIO SYSTEM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO SYSTEM SOCKETPAIR); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions setsid sigint) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18078,15 +16950,12 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?${NORMAL}\n" echo "$CMD0 &" cat "${te}0" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant fi fi # NUMCOND ;; @@ -18106,20 +16975,16 @@ TEST="$NAME: test the res-nsaddr option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO IP4 UDP TCP); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO TCP4 UDP-RECVFROM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions res-nsaddr) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18142,26 +17007,21 @@ if grep "$da" "${tf}0" >/dev/null; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok elif pgrep -u root nscd >/dev/null 2>&1; then $PRINTF "${YELLOW}FAILED (due to nscd?)${NORMAL}\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCAnT="$namesCANT $NAME" + cant else $PRINTF "$FAILED (query not received)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed fi fi # NUMCOND ;; @@ -18190,16 +17050,13 @@ TEST="$NAME: restore of pwd after CREAT with chdir option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs - CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions chdir) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18224,31 +17081,24 @@ else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ "$tpwd" != "$td" ]; then $PRINTF "$FAILED (chdir failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then $PRINTF "$FAILED (bad pwd2)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18268,16 +17118,13 @@ TEST="$NAME: restore of pwd after SYSTEM with chdir option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions chdir) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18303,31 +17150,24 @@ else $PRINTF "$FAILED (rc=$rc0)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ "$tpwd" != "$td" ]; then $PRINTF "$FAILED (chdir failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then $PRINTF "$FAILED (bad pwd)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18348,16 +17188,13 @@ TEST="$NAME: test restore after CREAT with umask option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs CREAT SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions umask) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18387,30 +17224,23 @@ else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ $((tumask + tperms - 0666)) -ne 0 ]; then $PRINTF "$FAILED (umask failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! [ "$oumask" -eq $(cat "$tc") ]; then $PRINTF "$FAILED (bad umask)\n" echo "$CMD0 &" cat "${te}0" >&2 cat "$tdebug" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18430,16 +17260,13 @@ TEST="$NAME: test restore after SHELL with umask option" if ! eval $NUMCOND; then :; elif ! F=$(testfeats SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs SHELL SYSTEM); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions umask) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18469,30 +17296,23 @@ else $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ $((tumask + tperms - 0666)) -ne 0 ]; then $PRINTF "$FAILED (umask failed)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! [ "$oumask" -eq $(cat "$tc") ]; then $PRINTF "$FAILED (bad umask)\n" echo "$CMD0 &" cat "${te}0" >&2 cat "$tdebug" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18522,12 +17342,10 @@ TEST="$NAME: Option unix-bind-tempname" if ! eval $NUMCOND; then :; elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions unix-bind-tempname) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ts="$td/test$N.sock" tf="$td/test$N.stdout" @@ -18573,8 +17391,7 @@ if [ $rc2b -ne 0 ]; then cat "${te}2a" >&2 echo "$CMD2" cat "${te}2b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then $PRINTF "$FAILED (phase a)\n" echo "$CMD0 &" @@ -18585,8 +17402,7 @@ elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then cat "${te}2a" >&2 echo "diff a:" >&2 cat ${tdiff}2a >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -18599,8 +17415,7 @@ elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then cat "${te}2b" >&2 echo "diff b:" >&2 cat ${tdiff}2b >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -18611,8 +17426,7 @@ else if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18669,8 +17483,7 @@ if [ -e $ts3 ]; then cat "${te}0b" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! grep -q " E " ${te}1; then $PRINTF "$FAILED\n" echo "Socat did not fail" @@ -18680,8 +17493,7 @@ elif ! grep -q " E " ${te}1; then cat "${te}0b" >&2 echo "$CMD1" >&2 cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0a"; fi @@ -18690,8 +17502,7 @@ else if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18710,20 +17521,16 @@ TEST="$NAME: f-setpipe-sz on STDIN" if ! eval $NUMCOND; then :; elif ! $(type true >/dev/null 2>&1); then $PRINTF "test $F_n $TEST... ${YELLOW}true not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! F=$(testfeats STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions f-setpipe-sz nofork) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18742,24 +17549,19 @@ if [ "$rc0" -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18776,16 +17578,13 @@ TEST="$NAME: f-setpipe-sz on EXEC with pipes" if ! eval $NUMCOND; then :; elif ! F=$(testfeats STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! A=$(testaddrs STDIO EXEC); then $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif ! o=$(testoptions pipes f-setpipe-sz) >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18802,24 +17601,19 @@ if [ "$rc0" -ne 0 ]; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then $PRINTF "$FAILED\n" echo "$CMD0 &" cat "${te}0" >&2 echo "diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -18838,8 +17632,7 @@ elif ! cond=$(checkconds "" "" "" \ "so-reuseaddr" \ "dccp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18860,9 +17653,7 @@ if [ $? -ne 0 ]; then cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -18871,17 +17662,14 @@ elif ! echo "$da" |diff - "$tf" >"$tdiff"; then cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi kill $pid1 2>/dev/null wait @@ -18904,9 +17692,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udplite4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18929,8 +17715,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" >&2 @@ -18939,17 +17724,14 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -18971,9 +17753,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udplite4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -18996,8 +17776,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" >&2 @@ -19006,17 +17785,14 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -19038,9 +17814,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udplite4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19063,8 +17837,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" >&2 @@ -19073,17 +17846,14 @@ else cat "${te}2" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi ;; # NUMCOND esac @@ -19117,9 +17887,7 @@ elif ! cond=$(checkconds \ "$REUSEADDR bind" \ "$protov" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19157,8 +17925,7 @@ if [ $rc1 != 0 ]; then cat "${te}0" echo "$CMD1" cat "${te}1" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \ "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \ \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \ @@ -19171,8 +17938,7 @@ elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g" echo "$CMD1" cat "${te}1" fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -19181,8 +17947,7 @@ else cat "${te}1" echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" | diff - "${tf}" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND, feats ;; @@ -19222,9 +17987,7 @@ elif ! cond=$(checkconds \ "$REUSEADDR o-trunc o-creat o-append fork max-children $SHUT" \ "$RUNS" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else case "X$IPPORT" in "XPORT") @@ -19258,8 +18021,7 @@ cpids="$(childpids $pid0)" kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait if echo -e "$da 1" |diff - $tf >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" echo "$CMD0 &" @@ -19269,8 +18031,7 @@ else cat "${te}1" cat "${te}2" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi fi # NUMCOND ;; @@ -19298,8 +18059,7 @@ elif ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19312,24 +18072,19 @@ else $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! tty |diff - <(cat ${tf}0 |grep "controlling terminal" |grep -v -e '"/dev/tty"' -e none |head -n 1 |sed -e 's/controlling terminal by .*:[[:space:]]*//' -e 's/"//g') >$tdiff; then $PRINTF "$FAILED\n" echo "$CMD0" cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19354,9 +18109,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4 unix" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else ts="$td/test$N.sock" tf="$td/test$N.stdout" @@ -19379,9 +18132,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -19390,17 +18141,14 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19425,14 +18173,10 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [[ $BASH_VERSION =~ ^[1-3]\. ]]; then $PRINTF "test $F_n $TEST... ${YELLOW}requires bash 4 or higher${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else gentestcert testsrv tp="$td/test$N.pty" @@ -19457,9 +18201,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -19468,17 +18210,14 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19506,9 +18245,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4 unix" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19546,9 +18283,7 @@ else cat "${te}2a" >&2 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2" cat "${te}2b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2a" >${tdiff}_a; then $PRINTF "$FAILED (diff a)\n" echo "$CMD0 &" @@ -19561,9 +18296,7 @@ else cat "${te}2b" >&2 echo "// diff a:" >&2 cat "${tdiff}_a" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2b" >${tdiff}_b; then $PRINTF "$FAILED (diff b)\n" echo "$CMD0 &" @@ -19576,9 +18309,7 @@ else cat "${te}2b" >&2 echo "// diff b:" >&2 cat "${tdiff}_b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19589,8 +18320,7 @@ else if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"; fi if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19617,9 +18347,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "udp4 tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19648,9 +18376,7 @@ else cat "${te}1a" >&2 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1a" >${tdiff}_a; then $PRINTF "$FAILED (diff a)\n" echo "$CMD0 &" @@ -19661,9 +18387,7 @@ else cat "${te}1b" >&2 echo "// diff a:" >&2 cat "${tdiff}_a" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1b" >${tdiff}_b; then $PRINTF "$FAILED (diff b)\n" echo "$CMD0 &" @@ -19674,9 +18398,7 @@ else cat "${te}1b" >&2 echo "// diff b:" >&2 cat "${tdiff}_b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19685,8 +18407,7 @@ else if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10.; } |$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19716,9 +18437,7 @@ elif ! cond=$(checkconds \ "fork" \ "udp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19740,35 +18459,28 @@ else cat "${te}0" >&2 echo "echo \$da\" |$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ $(grep -c " E open(" "${te}0") -eq 0 ]; then $PRINTF "$CANT (no error)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "echo \$da\" |$CMD1" cat "${te}1" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ $(grep -c " E open(" "${te}0") -ge 2 ]; then $PRINTF "$FAILED (this bug)\n" echo "$CMD0 &" head -n 2 "${te}0" >&2 echo "echo \$da\" |$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19796,9 +18508,7 @@ elif ! cond=$(checkconds \ "fork" \ "udp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19823,9 +18533,7 @@ else cat "${te}1a" >&2 echo "echo \$da b\" |$CMD1" cat "${te}1b" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif [ $(grep -c " I socketpair(" "${te}0") -ne 2 ]; then $PRINTF "$CANT (not 2 socketpair())\n" echo "$CMD0 &" @@ -19834,9 +18542,7 @@ else cat "${te}1a" >&2 echo "echo \$da b\" |$CMD1" cat "${te}1b" >&2 - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif ! diff <(grep " I socketpair(" "${te}0" |head -n 1 |sed 's/.*\( I socketpair.*\)/\1/') <(grep " I socketpair(" "${te}0" |tail -n 1 |sed 's/.*\( I socketpair.*\)/\1/') >/dev/null 2>&1; then $PRINTF "$FAILED (this bug)\n" echo "$CMD0 &" @@ -19845,9 +18551,7 @@ else cat "${te}1a" >&2 echo "echo \$da b\" |$CMD1" cat "${te}1b" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19856,8 +18560,7 @@ else if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "echo \$da b\" |$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19886,9 +18589,7 @@ elif ! cond=$(checkconds \ "pf" \ "ip4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19902,15 +18603,12 @@ else $PRINTF "$FAILED (rc0=$rc0)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -19955,9 +18653,7 @@ TEST="$NAME: TCP-L with -0 accepts IPv4" if ! eval $NUMCOND; then : elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif ! cond=$(checkconds \ "" \ "" \ @@ -19967,9 +18663,7 @@ elif ! cond=$(checkconds \ "" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else opt0= if SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-0[[:space:]]' >/dev/null; then @@ -19997,21 +18691,17 @@ else if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) ;; + ok ;; Linux) $PRINTF "$FAILED (rc1=$rc1)\n" echo "$CMD0 &" cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" ;; + failed ;; *) $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" ;; + cant ;; esac else $PRINTF "$OK\n" @@ -20019,7 +18709,7 @@ else if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) + ok fi fi # NUMCOND ;; @@ -20036,9 +18726,7 @@ TEST="$NAME: TCP-L with -0 accepts IPv6" if ! eval $NUMCOND; then : elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant elif ! cond=$(checkconds \ "" \ "" \ @@ -20048,9 +18736,7 @@ elif ! cond=$(checkconds \ "" \ "tcp6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20072,16 +18758,14 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) + ok fi fi # NUMCOND ;; @@ -20125,9 +18809,7 @@ elif ! cond=$(checkconds \ "${option%%=*}" \ "$(tolower $PROTO)4 $(tolower $PROTO)6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20142,9 +18824,7 @@ else printf "test $F_n $TEST... " $N if [ -z "$ACCEPT_TIMEOUT" ] && [ -z "$BIN_TIMEOUT" ]; then $PRINTF "$CANT (would block)\n" - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else if [ "$BIN_TIMEOUT" ]; then $BIN_TIMEOUT 0.1 $CMD0 >/dev/null 2>"${te}0" @@ -20157,15 +18837,12 @@ else $PRINTF "$FAILED (rc0=$rc0)\n" echo "$CMD0 &" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # not would block fi # NUMCOND @@ -20225,9 +18902,7 @@ elif ! cond=$(checkconds \ "bind" \ "$protov" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20246,15 +18921,12 @@ else $PRINTF "$FAILED (rc0=$rc0)\n" echo "$CMD0" cat "${te}0" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -20295,9 +18967,7 @@ elif ! cond=$(checkconds \ "bind" \ "$protov" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20323,15 +18993,12 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -20368,9 +19035,7 @@ elif ! cond=$(checkconds \ "" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.file" te="$td/test$N.stderr" @@ -20386,9 +19051,7 @@ else # $PRINTF "$CANT (rc0=$rc0)\n" # echo "$CMD0" # cat "${te}0" >&2 -# numCANT=$((numCANT+1)) -# listCANT="$listCANT $N" -# namesCANT="$namesCANT $NAME" +# cant # elif ! echo "$da" |diff - "$tf" >$tdiff; then if ! echo "$da" |diff - "$tf" >$tdiff; then $PRINTF "$FAILED (diff)\n" @@ -20396,17 +19059,14 @@ else cat "${te}0" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi fi # NUMCOND ;; @@ -20463,17 +19123,14 @@ if [ $rc1 -ne 0 ]; then echo "$CMD1" cat "${te}0" cat "${te}1" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed elif echo "$da" |diff - "$tf" >$tdiff; then $PRINTF "$OK\n" - numOK=$((numOK+1)) - listOK="$listOK $N" + ok else $PRINTF "$FAILED\n" cat "$tdiff" - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" + failed fi if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n" @@ -20494,8 +19151,11 @@ set -- $listOK; while [ "$1" ]; do echo "$1"; shift; done >"$td/success.lst" ln -sf "$td/success.lst" . set -- $listFAIL; while [ "$1" ]; do echo "$1"; shift; done >"$td/failed.lst" ln -sf "$td/failed.lst" . -sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt" -ln -sf "$td/result.txt" . +#sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt" +#ln -sf "$td/result.txt" . + +ln -sf "$td/results.txt" . + if [ "$numCANT" -gt 0 ]; then echo "CANT: $listCANT" fi @@ -20508,8 +19168,6 @@ if [ -z "$OPT_EXPECT_FAIL" ]; then exit # with rc from above statement fi -#set -vx - if [ "$OPT_EXPECT_FAIL" ]; then diff <(set -- $(echo "$EXPECT_FAIL" |tr ',' ' '); while [ "$1" ]; do echo "$1"; shift; done) "$td/failed.lst" >"$td/failed.diff" ln -sf "$td/failed.diff" . @@ -20565,9 +19223,7 @@ elif ! cond=$(checkconds \ "so-reuseaddr" \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -20590,9 +19246,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -20601,9 +19255,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - numFAIL=$((numFAIL+1)) - listFAIL="$listFAIL $N" - namesFAIL="$namesFAIL $NAME" + failed elif [ ??? ]; then # The test could not run meaningfully $PRINTF "$CANT\n" @@ -20611,17 +19263,16 @@ else if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi - numOK=$((numOK+1)) - listOK="$listOK $N" + ok fi + result fi # NUMCOND ;; esac From f38b76f5c8e94dd998e437269e44fa23976e8d7c Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 24 Jan 2025 16:13:33 +0100 Subject: [PATCH 03/51] Fixed display of option phases in help output --- CHANGES | 3 +++ xiohelp.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4166168..a3629c4 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ Security: not given it logs to a file in . (cwd) only when it is not writable by other users. +Corrections: + Fixed display of option phases in help output. + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/xiohelp.c b/xiohelp.c index 1ba92a8..bc95ce5 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -53,7 +53,7 @@ static const char *addressgroupnames[] = { /* keep consistent with xioopts.h:enum ephase ! */ static char *optionphasenames[] = { - "ALL", "INIT", "EARLY", + "ALL", "OFFSET", "INIT", "EARLY", "PREOPEN", "OPEN", "PASTOPEN", "PRESOCKET", "SOCKET", "PASTSOCKET", "PREBIGEN", "BIGEN", "PASTBIGEN", From af7d44d7516d57adac3107d3139d6a234db782b4 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Tue, 28 Jan 2025 01:25:22 +0100 Subject: [PATCH 04/51] Fixed a few testing issues --- CHANGES | 2 + VERSION | 2 +- socat-broker.sh | 1 + socat-chain.sh | 1 + socat-mux.sh | 1 + test.sh | 267 +++++++++++++++++++++++++++++++++++++++--------- 6 files changed, 227 insertions(+), 47 deletions(-) diff --git a/CHANGES b/CHANGES index a3629c4..691e417 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,8 @@ Testing: test.sh produces file results.txt with columns of test numbers, names, and results. + Fixed a few testing issues + ####################### V 1.8.0.2: Security: diff --git a/VERSION b/VERSION index 2b16796..8a17980 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.8.0.2" +"1.8.0.2+" diff --git a/socat-broker.sh b/socat-broker.sh index ccdea6f..b4b6dd2 100755 --- a/socat-broker.sh +++ b/socat-broker.sh @@ -37,6 +37,7 @@ while [ "$1" ]; do X-q) QUIET=1; OPTS="-d0" ;; X-d*|X-l?*) OPTS="$OPTS $1" ;; X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;; + X--experimental) ;; X-) break ;; X-*) echo "Unknown option \"$1\"" >&2 usage >&2 diff --git a/socat-chain.sh b/socat-chain.sh index fa8e93e..357aff0 100755 --- a/socat-chain.sh +++ b/socat-chain.sh @@ -77,6 +77,7 @@ while [ "$1" ]; do X-q) QUIET=1; OPTS="-d0" ;; X-d*|X-l?*) OPTS="$OPTS $1" ;; X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;; + X--experimental) ;; X-) break ;; X-*) echo "$0: Unknown option \"$1\"" >&2 usage >&2 diff --git a/socat-mux.sh b/socat-mux.sh index 084c0e6..8cea73e 100755 --- a/socat-mux.sh +++ b/socat-mux.sh @@ -43,6 +43,7 @@ while [ "$1" ]; do X-q) QUIET=1; OPTS="-d0" ;; X-d*|X-l?*) OPTS="$OPTS $1" ;; X-b|X-S|X-t|X-T|X-l) OPT=$1; shift; OPTS="$OPTS $OPT $1" ;; + X--experimental) ;; X-) break ;; X-*) echo "$0: Unknown option \"$1\"" >&2 usage >&2 diff --git a/test.sh b/test.sh index 759e42b..bd8ea14 100755 --- a/test.sh +++ b/test.sh @@ -48,6 +48,7 @@ usage() { $ECHO "\t-d \t\tShow log output of commands, even when they did not fail (not yet completed)" $ECHO "\t-D \t\tOutput some platform/system specific defines (variables)" $ECHO "\t--internet \tAllow tests that send packets to Internet" + $ECHO "\t--experimental \tApply --experimental option to Socat" $ECHO "\t--expect-fail N1,N2,... \tIgnore failure of these tests" $ECHO "\ttest-spec \Number of test or name of test" $ECHO "Contents of environment variable OPTS are passed to Socat invocations, e.'g:" @@ -78,8 +79,9 @@ while [ "$1" ]; do X-n) shift; NUMCOND="test \$N -eq $1" ;; X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;; X-N) shift; NUMCOND="test \$N -ge $1" ;; - X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;; + X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* testalt.* ;; X--internet|X-internet) INTERNET=1 ;; # allow access to 3rd party Internet hosts + X--experimental) EXPERIMENTAL=1 ;; X--expect-fail|X-expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;; X-*) echo "Unknown option \"$1\"" >&2 usage >&2 @@ -129,16 +131,23 @@ if [ -z "$PROCAN" ]; then if test -x ./procan; then PROCAN="./procan"; elif type if [ -z "$FILAN" ]; then if test -x ./filan; then FILAN="./filan"; elif ! type filan >/dev/null 2>&1; then FILAN=filan; elif test -x ${SOCAT%/*}/filan; then FILAN=${SOCAT%/*}/filan; else FILAN=false; fi; fi [ "$DEFS" ] && echo "FILAN=\"$FILAN\"" >&2 +if ! sleep 0.1 2>/dev/null; then + sleep () { + $SOCAT -T $0 PIPE PIPE + } +fi + if [ -z "$val_t" ]; then # Determine the time Socat needs for an empty run $SOCAT /dev/null /dev/null # populate caches - MILLIs=$(bash -c 'time socat /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) + MILLIs=$(bash -c 'time $SOCAT /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done # strip leading '0' to avoid octal [ -z "$MILLIs" ] && MILLIs=1 [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2 # On my idle development computer this value flaps from 0.001 to 0.004 # 0.001 lets many tests fail, so we triple the result + #MILLIs=$((10*MILLIs)) MILLIs=$((3*MILLIs)) [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (2)" >&2 MICROS=${MILLIs}000 @@ -191,6 +200,7 @@ PATH=.:$PATH # for usleep,relsleep MISCDELAY=1 OPTS="$opt_t $OPTS" +[ "$EXPERIMENTAL" ] && OPTS="--experimental $OPTS" opts="$OPTS" [ "$DEFS" ] && echo "opts=\"$opts\"" >&2 @@ -356,12 +366,12 @@ IP.2 = ::1 EOF -# clean up from previous runs -rm -f testcli.{crt,key,pem} -rm -f testsrv.{crt,key,pem} -rm -f testcli6.{crt,key,pem} -rm -f testsrv6.{crt,key,pem} -rm -f testalt.{crt,key,pem} +# clean up from previous runs - no, only with -C +#rm -f testcli.{crt,key,pem} +#rm -f testsrv.{crt,key,pem} +#rm -f testcli6.{crt,key,pem} +#rm -f testsrv6.{crt,key,pem} +#rm -f testalt.{crt,key,pem} CAT="cat" OD_C="od -c" @@ -657,20 +667,12 @@ vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256col RED="\0033[31m" GREEN="\0033[32m" YELLOW="\0033[33m" -# if [ "$UNAME" = SunOS ]; then -# NORMAL="\0033[30m" -# else - NORMAL="\0033[39m" -# fi - else + NORMAL="\0033[39m" + else # "\101" RED="\033[31m" GREEN="\033[32m" YELLOW="\033[33m" -# if [ "$UNAME" = SunOS ]; then -# NORMAL="\033[30m" -# else - NORMAL="\033[39m" -# fi + NORMAL="\033[39m" fi OK="${GREEN}OK${NORMAL}" FAILED="${RED}FAILED${NORMAL}" @@ -787,6 +789,63 @@ fi /bin/rm "$TF-diff" esac +case "$TESTS" in +*%consistency%*) + # Test if help shows option types without inconsistency + $ECHO "testing if help shows option types correctly...\c" + TF="$TD/socat-hhh" + LINE="$($SOCAT -hhh |grep "^[[:space:]]*ip-add-source-membership\>")" + if [ -z "$LINE" ]; then + $ECHO $CANT + else + TYPE="$($ECHO "$LINE" |sed 's/^.*type=\([^[:space:]][^[:space:]]*\).*/\1/')" + if [ "$TYPE" != "IP-MREQ-SOURCE" ]; then + $ECHO "\n*** help does not show option types correctly" >&2 + exit 1 + else + echo " ok" + fi + fi +esac + +case "$TESTS" in +*%consistency%*) + # Test if help shows option phases without inconsistency + $ECHO "testing if help shows option phases correctly...\c" + TF="$TD/socat-hhh" + LINE="$($SOCAT -hhh |grep "^[[:space:]]*dash\>")" + if [ -z "$LINE" ]; then + $ECHO $CANT + else + PHASE="$($ECHO "$LINE" |sed 's/^.*phase=\([^[:space:]][^[:space:]]*\).*/\1/')" + if [ "$PHASE" != "PREEXEC" ]; then + $ECHO "\n*** help does not show option phases correctly" >&2 + exit 1 + else + echo " ok" + fi + fi +esac + +case "$TESTS" in +*%consistency%*) + # Test if help shows option groups without inconsistency + $ECHO "testing if help shows option groups correctly...\c" + TF="$TD/socat-hhh" + LINE="$($SOCAT -hhh |grep "^[[:space:]]*udplite-recv-cscov\>")" + if [ -z "$LINE" ]; then + $ECHO $CANT + else + GROUP="$($ECHO "$LINE" |sed 's/^.*groups=\([^[:space:]][^[:space:]]*\).*/\1/')" + if [ "$GROUP" != "UDPLITE" ]; then + $ECHO "\n*** help does not show option groups correctly" >&2 + exit 1 + else + echo " ok" + fi + fi +esac + #============================================================================== N=1 @@ -976,6 +1035,10 @@ testoptions () { # if not: prints ev.message to stderr, returns 1 childprocess () { local l + case "$1" in + [1-9]*) ;; + *) echo "childprocess \"$1\": not a number" >&2; exit 1 ;; + esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;; FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;; @@ -999,6 +1062,10 @@ childprocess () { childpids () { local recursive i if [ "X$1" = "X-r" ]; then recursive=1; shift; fi + case "$1" in + [1-9]*) ;; + *) echo "childpids \"$1\": not a number" >&2; exit 1 ;; + esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;; FreeBSD) l="$(ps -fl |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;; @@ -1204,7 +1271,7 @@ runsunix () { routesip6 () { runsip6 >/dev/null || { echo route6; return 1; } - ping -c 1 -s 0 -6 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; } + $PING6 -c 1 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; } return 0; } @@ -1236,13 +1303,6 @@ checkconds() { [ "$i" ] && { echo "Only on (one of) $unames"; return 255; } fi - if [ "$root" = "root" ]; then - if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then - echo "Must be root" - return 255 - fi - fi - if [ "$progs" ]; then for i in $progs; do if ! type >/dev/null 2>&1; then @@ -1283,11 +1343,20 @@ checkconds() { fi if [ "$inet" ]; then - if [ -z "$NTERNET" ]; then + if [ -z "$INTERNET" ]; then echo "Use test.sh option --internet" return 255 fi fi + + # Only at the end, so we get a better overview of missing features + if [ "$root" = "root" ]; then + if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then + echo "Must be root" + return 255 + fi + fi + return 0 } @@ -1319,7 +1388,7 @@ waitip4proto () { # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;; # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;; - *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;; + *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;; relsleep 5; return 0 ;; esac [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ @@ -1444,7 +1513,7 @@ waittcp4port () { OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; DragonFly) l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; - *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1525,7 +1594,7 @@ waitudp4port () { HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;; OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;; DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; - *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; + *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1586,7 +1655,7 @@ waitsctp4port () { while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) if [ "$SS" ]; then - l=$($SS -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>") + l=$($SS -4 -a -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>") else l=$(netstat -n -a |grep '^sctp .*[0-9*]:'$port' .* LISTEN') fi ;; @@ -1601,7 +1670,7 @@ waitsctp4port () { # HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; # OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; # CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; - *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1631,6 +1700,7 @@ waitudplite4port () { Linux) #if [ "$SS" ]; then #l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>") #else + # On Ubuntu-20 only netstat shows udplite ports if ! netstat -nU >/dev/null 2>&1; then return 0 # speculative fi @@ -1665,6 +1735,51 @@ waitudplite4port () { return 1 } +# wait until an DCCP4 listen port is ready +waitdccp4port () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening + local timeout="$3" + local l + local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here + [ "$logic" ] || logic=1 + [ "$timeout" ] || timeout=5 + while [ $timeout -gt 0 ]; do + case "$UNAME" in + Linux) + # On Ubuntu-20, only ss shows DCCP ports + if [ "$SS" ]; then + l=$($SS -4 -a -n 2>/dev/null |grep "^dccp.*LISTEN .*:$port\>") + else + l=$(netstat -n -a |grep '^dccp .*[0-9*]:'$port' .* LISTEN') + fi ;; +# FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; +# Darwin) case "$(uname -r)" in +# [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;; +# esac ;; +# AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; + SunOS) l=$(netstat -an -f inet -P dccp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;; +# HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;; +# OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;; +# CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;; + *) l=$(netstat -an |grep -i 'dccp .*[0-9*][:.]'$port' .* listen') ;; + esac + if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ + \( \( $logic -eq 0 \) -a -z "$l" \) ]; then + set ${vx}vx + return 0 + fi + sleep $val_t + timeout=$((timeout-1)) + done + + $ECHO "!port $port timed out! \c" >&2 + set ${vx}vx + return 1 +} + # check if a TCP6 port is in use # exits with 0 when it is not used checktcp6port () { @@ -1696,7 +1811,7 @@ waittcp6port () { SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; DragonFly) l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;; - *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1746,7 +1861,7 @@ waitudp6port () { #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;; #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;; DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; - *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; + *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1781,9 +1896,9 @@ waitsctp6port () { while [ $timeout -gt 0 ]; do case "$UNAME" in Linux) if [ "$SS" ]; then - l=$($SS -6 -n 2>/dev/null |grep "^LISTEN .*:$port\>") + l=$($SS -6 -a -n 2>/dev/null |grep "^sctp .*LISTEN .*:$port\>") else - l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') + l=$(netstat -an |grep '^sctp[6 ] .* \*:'$port' .* LISTEN') fi ;; # FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; # NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; @@ -1791,7 +1906,7 @@ waitsctp6port () { # AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; SunOS) l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; # #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; - *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; + *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; esac if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ \( \( $logic -eq 0 \) -a -z "$l" \) ]; then @@ -1852,6 +1967,45 @@ waitudplite6port () { return 1 } +# wait until a dccp6 listen port is ready +# not all (Linux) variants show this in netstat +waitdccp6port () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening + local timeout="$3" + local l + local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here + [ "$logic" ] || logic=1 + [ "$timeout" ] || timeout=5 + while [ $timeout -gt 0 ]; do + case "$UNAME" in + Linux) if [ "$SS" ]; then + l=$($SS -6 -a -n 2>/dev/null |grep "^dccp .*LISTEN .*:$port\>") + else + l=$(netstat -an |grep '^dccp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') + fi ;; +# FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;; +# NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; +# OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; +# AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; + SunOS) l=$(netstat -an -f inet6 -P dccp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;; +# #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;; + *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;; + esac + if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ + \( \( $logic -eq 0 \) -a -z "$l" \) ]; then + set ${vx}vx + return 0 + fi + sleep $val_t + timeout=$((timeout-1)) + done + + $ECHO "!port $port timed out! \c" >&2 + set ${vx}vx + return 1 +} + # we need this misleading function name for canonical reasons waitunixport () { waitfile "$1" "$2" "$3" @@ -1895,6 +2049,15 @@ case "$UNAME" in *) SOCK_SEQPACKET=5 ;; esac + +if [ "$INTERNET" ]; then + # No "-s 24" on Solaris + if ! ping -c 1 "server-4.dest-unreach.net" >/dev/null 2>&1; then + echo "$0: Option --internet but no connectivity or DNS" >&2 + #exit 1 + fi +fi + # generate a test certificate and key gentestcert () { local name="$1" @@ -5004,7 +5167,7 @@ waittcp4port $PORT3 1 50 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null # now we start the external daemon eval "$CMD5 2>\"${te}5\" &" pid5=$! -waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $5PORT\n" >&2 </dev/null +waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null # and this is the outside client: echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" & pid6_1=$! @@ -5014,7 +5177,7 @@ echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" & pid6_3=$! wait $pid6_1 $pid6_2 $pid6_3 kill $pid1 $pid2 $pid3 $pid4 $pid5 $(childpids $pid5) 2>/dev/null -# (On BSDs a child of pid5 loves to hang) +# (On BSDs a child of pid5 likes to hang) # (echo "$da1"; relsleep 2) |diff - "${tf}_1" >"${tdiff}1" (echo "$da2"; relsleep 2) |diff - "${tf}_2" >"${tdiff}2" @@ -12027,7 +12190,7 @@ if [ "$ERRNOENT" ]; then cat "$tlog" >&2 failed elif [ "$user" != "$SUBSTUSER" ]; then - $PRINTF "${FAILD}(user \"$user\", expected \"$SUBSTUSER\")\n" + $PRINTF "${FAILED}(user \"$user\", expected \"$SUBSTUSER\")\n" echo "$CMD0 &" cat "$te0" >&2 failed @@ -12812,7 +12975,20 @@ TEST="$NAME: is option ipv6-join-group used" # Terminate immediately, do not transfer data. # If socat exits with 0 the test succeeds. # Up to 1.7.3.1 it failed with "1 option(s) could not be used" -if ! eval $NUMCOND; then :; else +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP6 UDP GOPEN" \ + "UDP6-RECV GOPEN" \ + "ipv6-join-group" \ + "udp6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" + namesCANT="$namesCANT $NAME" +else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" @@ -16935,9 +17111,8 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" #CMD0="$TRACE $SOCAT $opts PIPE SYSTEM:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" -# -T is required on (only?) OpenBSD-4 -CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -lf\ ${te}1\ PIPE\ PIPE\",setsid,sigint" -#CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" +# Without -T process remains on OpenBSD-4, AIX, ? +CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" printf "test $F_n $TEST... " $N eval $CMD0 >/dev/null 2>"${te}0" & pid0=$! @@ -18733,7 +18908,7 @@ elif ! cond=$(checkconds \ "" \ "IP6 TCP LISTEN FILE" \ "TCP-LISTEN TCP6-CONNECT FILE" \ - "" \ + "ai-addrconfig" \ "tcp6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant From 7a90caade535b12efcb0a74d4f0a0bd716d7a0b2 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 21:49:16 +0100 Subject: [PATCH 05/51] Fixed build issues on disabled features --- CHANGES | 3 ++ fdname.c | 4 +-- sysutils.c | 16 +++++----- xio-ip.c | 7 ++++- xio-ip6.c | 2 +- xio-ipapp.c | 10 +++---- xio-progcall.c | 5 ++-- xio-socket.c | 77 ++++++++++++++++++++++++++++++------------------ xio-socket.h | 2 -- xio-socketpair.c | 23 +++++++++++++++ xio-socketpair.h | 2 ++ xio-socks.c | 11 +++++-- xio-udp.c | 4 +-- xio-unix.c | 21 +++++++++++-- xio-vsock.c | 2 +- xioconfig.h | 18 ++++++----- xioopen.c | 16 +++++----- xioopts.c | 47 +++++++++++++++++------------ xioopts.h | 2 +- xioshutdown.c | 3 +- xiowrite.c | 2 ++ 21 files changed, 182 insertions(+), 95 deletions(-) diff --git a/CHANGES b/CHANGES index 691e417..5a94938 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Security: Corrections: Fixed display of option phases in help output. +Building: + Disabling certain features during configure could break build process. + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/fdname.c b/fdname.c index e226bda..58aa509 100644 --- a/fdname.c +++ b/fdname.c @@ -226,7 +226,7 @@ int sockname(int fd, FILE *outfile, char style) { #define FDNAME_OPTLEN 256 #define FDNAME_NAMELEN 256 socklen_t optlen; -#if HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R +#if WITH_IP && ( HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R ) struct protoent protoent, *protoentp; #endif #define PROTONAMEMAX 1024 @@ -278,7 +278,7 @@ int sockname(int fd, FILE *outfile, char style) { Getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &optacceptconn, &optlen); #endif -#if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) +#if WITH_IP && ( defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) ) #if HAVE_GETPROTOBYNUMBER_R==1 /* Linux */ rc = getprotobynumber_r(proto, &protoent, protoname, sizeof(protoname), &protoentp); if (protoentp == NULL) { diff --git a/sysutils.c b/sysutils.c index ee24454..082e845 100644 --- a/sysutils.c +++ b/sysutils.c @@ -677,7 +677,7 @@ int xiopoll(struct pollfd fds[], unsigned long nfds, struct timeval *timeout) { } -#if WITH_TCP || WITH_UDP +#if WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE /* returns port in network byte order; ipproto==IPPROTO_UDP resolves as UDP service, every other value resolves as TCP */ @@ -702,10 +702,10 @@ int parseport(const char *portname, int ipproto) { return se->s_port; } -#endif /* WITH_TCP || WITH_UDP */ +#endif /* WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE */ -#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE +#if WITH_IP4 || WITH_IP6 || _WITH_INTERFACE /* check the systems interfaces for ifname and return its index or -1 if no interface with this name was found The system calls require an arbitrary socket; the calling program may @@ -729,8 +729,8 @@ int ifindexbyname(const char *ifname, int anysock) { } if (anysock >= 0) { s = anysock; - } else if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { - Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno)); + } else if ((s = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno)); return -1; } @@ -756,10 +756,10 @@ int ifindexbyname(const char *ifname, int anysock) { return -1; #endif /* !defined(HAVE_ STRUCT_IFREQ) && defined(SIOCGIFCONF) && defined(SIOCGIFINDEX) */ } -#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ +#endif /* WITH_IP4 || WITH_IP6 || _WITH_INTERFACE */ -#if WITH_IP4 || WITH_IP6 || WITH_INTERFACE +#if WITH_IP4 || WITH_IP6 || _WITH_INTERFACE /* like ifindexbyname(), but also allows the index number as input - in this case it does not lookup the index. writes the resulting index to *ifindex and returns 0, @@ -783,7 +783,7 @@ int ifindex(const char *ifname, unsigned int *ifindex, int anysock) { *ifindex = val; return 0; } -#endif /* WITH_IP4 || WITH_IP6 || WITH_INTERFACE */ +#endif /* WITH_IP4 || WITH_IP6 || _WITH_INTERFACE */ int _xiosetenv(const char *envname, const char *value, int overwrite, const char *sep) { diff --git a/xio-ip.c b/xio-ip.c index 6821571..3a136d0 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -68,7 +68,7 @@ const struct optdesc opt_ip_multicast_if ={"ip-multicast-if", "multicast-if", #ifdef IP_PKTOPTIONS const struct optdesc opt_ip_pktoptions = { "ip-pktoptions", "pktopts", OPT_IP_PKTOPTIONS, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_IP, IP_PKTOPTIONS }; #endif -#ifdef IP_ADD_MEMBERSHIP +#if defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) const struct optdesc opt_ip_add_membership = { "ip-add-membership", "membership",OPT_IP_ADD_MEMBERSHIP, GROUP_SOCK_IP, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IP, IP_ADD_MEMBERSHIP }; #endif #if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP) @@ -1128,6 +1128,9 @@ int xiotype_ip_add_membership( } #endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */ + +#if _WITH_IP4 + #if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) int xioapply_ip_add_membership( struct single *sfd, @@ -1386,6 +1389,8 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { #endif /* HAVE_STRUCT_IP_MREQ_SOURCE */ +#endif /* _WITH_IP4 */ + #if WITH_RESOLVE #if HAVE_RESOLV_H diff --git a/xio-ip6.c b/xio-ip6.c index 04eff08..8bd4a53 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -23,7 +23,7 @@ static char *inet6addr_info(const struct in6_addr *sa, char *buff, size_t blen); #ifdef IPV6_V6ONLY const struct optdesc opt_ipv6_v6only = { "ipv6-v6only", "ipv6only", OPT_IPV6_V6ONLY, GROUP_SOCK_IP6, PH_PREBIND, TYPE_INT, OFUNC_SOCKOPT, SOL_IPV6, IPV6_V6ONLY }; #endif -#ifdef IPV6_JOIN_GROUP +#if defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) const struct optdesc opt_ipv6_join_group = { "ipv6-join-group", "join-group", OPT_IPV6_JOIN_GROUP, GROUP_SOCK_IP6, PH_PASTSOCKET, TYPE_IP_MREQN, OFUNC_SPEC, SOL_IPV6, IPV6_JOIN_GROUP }; #endif #ifdef MCAST_JOIN_SOURCE_GROUP diff --git a/xio-ipapp.c b/xio-ipapp.c index 1cb1b64..fcc0d33 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -6,7 +6,7 @@ #include "xiosysincludes.h" -#if WITH_TCP || WITH_UDP +#if WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE #include "xioopen.h" #include "xio-socket.h" @@ -19,7 +19,7 @@ const struct optdesc opt_sourceport = { "sourceport", "sp", OPT_SOURCEPORT /*const struct optdesc opt_port = { "port", NULL, OPT_PORT, GROUP_IPAPP, PH_BIND, TYPE_USHORT, OFUNC_SPEC };*/ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; -#if WITH_IP4 +#if _WITH_IP4 || _WITH_IP6 /* we expect the form "host:port" */ int xioopen_ipapp_connect( int argc, @@ -276,7 +276,7 @@ int return STAT_OK; } -#endif /* WITH_IP4 */ +#endif /* _WITH_IP4 || _WITH_IP6 */ #if WITH_TCP && WITH_LISTEN @@ -382,6 +382,6 @@ int xioopen_ipapp_listen( return result; return 0; } -#endif /* WITH_IP4 && WITH_TCP && WITH_LISTEN */ +#endif /* WITH_TCP && WITH_LISTEN */ -#endif /* WITH_TCP || WITH_UDP */ +#endif /* WITH_TCP || WITH_UDP || WITH_SCTP || WITH_DCCP || WITH_UDPLITE */ diff --git a/xio-progcall.c b/xio-progcall.c index f980ef9..d0b8c1c 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -12,6 +12,7 @@ #include "xio-progcall.h" #include "xio-socket.h" +#include "xio-socketpair.h" /* these options are used by address pty too */ @@ -23,7 +24,7 @@ const struct optdesc opt_ptmx = { "ptmx", NULL, OPT_PTMX, GROUP_P #endif const struct optdesc opt_sitout_eio = { "sitout-eio", NULL, OPT_SITOUT_EIO, GROUP_PTY, PH_OFFSET, TYPE_TIMEVAL, OFUNC_OFFSET, XIO_OFFSETOF(para.exec.sitout_eio), XIO_SIZEOF(para.exec.sitout_eio) }; -#if WITH_EXEC || WITH_SYSTEM +#if WITH_EXEC || WITH_SYSTEM || WITH_SHELL #define MAXPTYNAMELEN 64 @@ -623,7 +624,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ *optsp = popts; return pid; /* indicate parent (main) process */ } -#endif /* WITH_EXEC || WITH_SYSTEM */ +#endif /* WITH_EXEC || WITH_SYSTEM || WITH_SHELL */ int setopt_path(struct opt *opts, char **path) { diff --git a/xio-socket.c b/xio-socket.c index 5a7782f..c2fb717 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -7,8 +7,6 @@ #include "xiosysincludes.h" -#if _WITH_SOCKET - #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" @@ -30,6 +28,8 @@ #include "xio-tcpwrap.h" +#if _WITH_SOCKET + static int xioopen_socket_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int xioopen_socket_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); static int xioopen_socket_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); @@ -263,7 +263,12 @@ static int xioopen_socket_connect( socket_init(0, &us); if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 || _WITH_IP6 */ + ) != STAT_NOACTION) { needbind = true; us.soa.sa_family = pf; @@ -540,7 +545,12 @@ int xioopen_socket_recvfrom( if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &sfd->para.socket.range, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 */ + ) < 0) { free(rangename); return STAT_NORETRY; @@ -626,7 +636,12 @@ int xioopen_socket_recv( if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &sfd->para.socket.range, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 */ + ) < 0) { free(rangename); return STAT_NORETRY; @@ -712,7 +727,12 @@ static int xioopen_socket_datagram( /* which reply sockets will accept - determine by range option */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, 0, &sfd->para.socket.range, - sfd->para.socket.ip.ai_flags) +#if _WITH_IP4 || _WITH_IP6 + sfd->para.socket.ip.ai_flags +#else + NULL +#endif /* _WITH_IP4 */ + ) < 0) { free(rangename); return STAT_NORETRY; @@ -1202,6 +1222,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, } #endif +#if WITH_IP4 /* for generic sockets, this has already been retrieved */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, @@ -1213,6 +1234,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, free(rangename); sfd->para.socket.dorange = true; } +#endif /* WITH_IP4 */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(sfd, opts); @@ -1424,6 +1446,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, } #endif +#if WITH_IP4 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, sfd->para.socket.ip.ai_flags) @@ -1434,6 +1457,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, free(rangename); sfd->para.socket.dorange = true; } +#endif /* WITH_IP4 */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(sfd, opts); @@ -1449,7 +1473,10 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, return STAT_OK; } +#endif /* _WITH_SOCKET */ + +#if _WITH_SOCKET || _WITH_SOCKETPAIR int retropt_socket_pf(struct opt *opts, int *pf) { char *pfname; @@ -1478,8 +1505,11 @@ int retropt_socket_pf(struct opt *opts, int *pf) { } return -1; } +#endif /* _WITH_SOCKET || _WITH_SOCKETPAIR */ +#if _WITH_SOCKET + /* This function calls recvmsg(..., MSG_PEEK, ...) to obtain information about the arriving packet, thus it does not "consume" the packet. In msgh the msg_name pointer must refer to an (empty) sockaddr storage. @@ -1651,7 +1681,7 @@ int xiocheckpeer(xiosingle_t *sfd, char infobuff[256]; int result; -#if WITH_IP4 +#if WITH_IP4 || WITH_IP6 if (sfd->para.socket.dorange) { if (pa == NULL) { return -1; } if (xiocheckrange(pa, &sfd->para.socket.range) < 0) { @@ -2055,9 +2085,7 @@ int xiosetsockaddrenv(const char *lr, # undef XIOSOCKADDRENVLEN } -#endif /* _WITH_SOCKET */ - -/* these do sockets internally */ +/* These do sockets internally */ /* retrieves options so-type and so-prototype from opts, calls socket, and ev. generates an appropriate error message. @@ -2080,24 +2108,6 @@ xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { return result; } -/* retrieves options so-type and so-prototype from opts, calls socketpair, and - ev. generates an appropriate error message. - returns 0 on success or -1 if an error occurred. */ -int -xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { - int result; - - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_int(opts, OPT_SO_PROTOTYPE, &proto); - result = Socketpair(pf, socktype, proto, sv); - if (result < 0) { - Error5("socketpair(%d, %d, %d, %p): %s", - pf, socktype, proto, sv, strerror(errno)); - return -1; - } - return result; -} - /* Binds a socket to a socket address. Handles IP (internet protocol), UNIX domain, Linux abstract UNIX domain. The bind address us may be NULL in which case no bind() happens, except with @@ -2206,8 +2216,12 @@ int xiobind( if (us) { sinp = us; } else { - if (pf == AF_INET) { + if (0) { + ; +#if WITH_IP4 + } else if (pf == AF_INET) { socket_in_init(&sin.ip4); +#endif #if WITH_IP6 } else { socket_in6_init(&sin.ip6); @@ -2307,10 +2321,12 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) val.u_int = 0; notnull.u_bool = false; +#if WITH_TCP if (ipproto == IPPROTO_TCP) { val.u_int = 1; notnull.u_bool = true; } +#endif /* WITH_TCP */ retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, ¬null); if (notnull.u_bool) { if (Setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val.u_int, sizeof(int)) @@ -2324,3 +2340,6 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) } return 0; } + +#endif /* _WITH_SOCKET */ + diff --git a/xio-socket.h b/xio-socket.h index 2064ed3..2af3367 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -135,8 +135,6 @@ extern int xioparserange(const char *rangename, int pf, struct xiorange *range, extern int xiosocket(struct opt *opts, int pf, int socktype, int proto, int level); -extern int -xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]); extern int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts); #endif /* !defined(__xio_socket_h_included) */ diff --git a/xio-socketpair.c b/xio-socketpair.c index 0da0c99..e062a44 100644 --- a/xio-socketpair.c +++ b/xio-socketpair.c @@ -95,3 +95,26 @@ static int xioopen_socketpair( } #endif /* WITH_SOCKETPAIR */ + + +#if _WITH_SOCKETPAIR + +/* retrieves options so-type and so-prototype from opts, calls socketpair, and + ev. generates an appropriate error message. + returns 0 on success or -1 if an error occurred. */ +int +xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) { + int result; + + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &proto); + result = Socketpair(pf, socktype, proto, sv); + if (result < 0) { + Error5("socketpair(%d, %d, %d, %p): %s", + pf, socktype, proto, sv, strerror(errno)); + return -1; + } + return result; +} + +#endif /* _WITH_SOCKETPAIR */ diff --git a/xio-socketpair.h b/xio-socketpair.h index 2f92f70..5822798 100644 --- a/xio-socketpair.h +++ b/xio-socketpair.h @@ -7,4 +7,6 @@ const extern struct addrdesc xioaddr_socketpair; +extern int xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]); + #endif /* !defined(__xio_socketpair_h_included) */ diff --git a/xio-socks.c b/xio-socks.c index d5234cb..2e9c224 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -6,14 +6,16 @@ #include "xiosysincludes.h" -#if WITH_SOCKS4 || WITH_SOCKS4A - #include "xioopen.h" #include "xio-ascii.h" #include "xio-socket.h" #include "xio-ip.h" #include "xio-ipapp.h" +#define SOCKSPORT "1080" + +#if WITH_SOCKS4 || WITH_SOCKS4A + #include "xio-socks.h" @@ -24,7 +26,6 @@ enum { SOCKS_CD_IDENTFAILED } ; -#define SOCKSPORT "1080" #define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512) static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); @@ -229,6 +230,8 @@ static int xioopen_socks4_connect( return 0; } +#endif /* WITH_SOCKS4 || WITH_SOCKS4A */ +#if WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5 int _xioopen_opt_socksport( struct opt *opts, @@ -253,6 +256,8 @@ int _xioopen_opt_socksport( return 0; } +#endif /* WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5 */ +#if WITH_SOCKS4 || WITH_SOCKS4A int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) { char *userid; diff --git a/xio-udp.c b/xio-udp.c index 10704e3..98c2ced 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -85,7 +85,7 @@ int _xioopen_ipdgram_listen(struct single *sfd, return STAT_NORETRY; } -#if WITH_IP4 /*|| WITH_IP6*/ +#if WITH_IP4 || WITH_IP6 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, sfd->para.socket.ip.ai_flags) @@ -646,7 +646,7 @@ int xioopen_udp_recv( } #endif -#if WITH_IP4 /*|| WITH_IP6*/ +#if WITH_IP4 || WITH_IP6 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &xfd->stream.para.socket.range, xfd->stream.para.socket.ip.ai_flags) diff --git a/xio-unix.c b/xio-unix.c index 42bb2a3..8468fa2 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -257,7 +257,12 @@ static int xioopen_unix_connect( if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, (addrdesc->arg1/*abstract*/<<1)|sfd->para.socket.un.tight, - sfd->para.socket.ip.ai_flags) +#if WITH_TCP + sfd->para.socket.ip.ai_flags +#else + 0 +#endif /* WITH_TCP */ +) == STAT_OK) { needbind = true; } @@ -426,7 +431,12 @@ static int xioopen_unix_sendto( if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, (addrdesc->arg1/*abstract*/<<1)| sfd->para.socket.un.tight, - sfd->para.socket.ip.ai_flags) +#if WITH_TCP + sfd->para.socket.ip.ai_flags +#else + 0 +#endif /* WITH_TCP */ + ) == STAT_OK) { needbind = true; } @@ -709,7 +719,12 @@ _xioopen_unix_client( if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, (abstract<<1)|sfd->para.socket.un.tight, - sfd->para.socket.ip.ai_flags) +#if WITH_TCP + sfd->para.socket.ip.ai_flags +#else + 0 +#endif /* WITH_TCP */ + ) != STAT_NOACTION) { needbind = true; } diff --git a/xio-vsock.c b/xio-vsock.c index fcd09bc..0531994 100644 --- a/xio-vsock.c +++ b/xio-vsock.c @@ -98,7 +98,7 @@ static int xioopen_vsock_connect( ret = retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&sa_local, &sa_len, 3, - sfd->para.socket.ip.ai_flags); + NULL); if (ret == STAT_NORETRY) return ret; if (ret == STAT_OK) diff --git a/xioconfig.h b/xioconfig.h index 1c12c1a..ab3d115 100644 --- a/xioconfig.h +++ b/xioconfig.h @@ -16,7 +16,13 @@ # define WITH_OPEN 1 #endif -#if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY +#if WITH_INTERFACE || WITH_TUN +# define _WITH_INTERFACE 1 +#else +# define _WITH_INTERFACE 0 +#endif + +#if WITH_OPEN || WITH_PIPE || WITH_UNIX || WITH_PTY || _WITH_INTERFACE # define WITH_NAMED 1 #endif @@ -34,7 +40,7 @@ with IP6 */ #endif -#if WITH_OPENSSL +#if WITH_OPENSSL || WITH_SOCKS5 # define WITH_TCP 1 # define WITH_IP4 1 #endif @@ -57,7 +63,7 @@ # define _WITH_UDP 1 #endif -#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_RAWIP || WITH_GENERICSOCKET +#if WITH_UNIX || WITH_IP4 || WITH_IP6 || WITH_SOCKS4 || WITH_SOCKS5 || WITH_RAWIP || WITH_GENERICSOCKET || WITH_SOCKETPAIR || WITH_VSOCK # define _WITH_SOCKET 1 #else # undef _WITH_SOCKET @@ -71,10 +77,8 @@ # undef WITH_LIBWRAP #endif -#if WITH_INTERFACE || WITH_TUN -# define _WITH_INTERFACE 1 -#else -# define _WITH_INTERFACE 0 +#if WITH_SOCKETPAIR || WITH_EXEC || WITH_SYSTEM || WITH_SHELL +# define _WITH_SOCKETPAIR 1 #endif #if WITH_GENERICSOCKET || _WITH_INTERFACE diff --git a/xioopen.c b/xioopen.c index be17e3b..8a29f21 100644 --- a/xioopen.c +++ b/xioopen.c @@ -471,14 +471,14 @@ static xiofile_t *xioallocfd(void) { fd->stream.escape = -1; /* fd->stream.para.exec.pid = 0; */ fd->stream.lineterm = LINETERM_RAW; -#if WITH_RESOLVE +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE #if HAVE_RES_RETRANS fd->stream.para.socket.ip.res.retrans = -1; #endif #if HAVE_RES_RETRY fd->stream.para.socket.ip.res.retry = -1; #endif -#endif /* WITH_RESOLVE */ +#endif /* ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE */ return fd; } @@ -701,10 +701,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { mode_t orig_umask, tmp_umask; int result; /* Values to be saved until xioopen() is finished */ -#if WITH_RESOLVE && HAVE_RESOLV_H +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H int do_res; struct __res_state save_res; -#endif /* WITH_RESOLVE && HAVE_RESOLV_H */ +#endif #if WITH_NAMESPACES int save_netfd = -1; #endif @@ -735,10 +735,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { return -1; #endif /* WITH_NAMESPACES */ -#if WITH_RESOLVE && HAVE_RESOLV_H +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H if ((do_res = xio_res_init(sfd, &save_res)) < 0) return STAT_NORETRY; -#endif /* WITH_RESOLVE && HAVE_RESOLV_H */ +#endif if (xio_chdir(sfd->opts, &orig_dir) < 0) return STAT_NORETRY; @@ -769,10 +769,10 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { free(orig_dir); } -#if WITH_RESOLVE && HAVE_RESOLV_H +#if ( _WITH_IP4 || _WITH_IP6 ) && WITH_RESOLVE && HAVE_RESOLV_H if (do_res) xio_res_restore(&save_res); -#endif /* WITH_RESOLVE && HAVE_RESOLV_H */ +#endif #if WITH_NAMESPACES if (save_netfd > 0) { diff --git a/xioopts.c b/xioopts.c index a751fd3..81f1e53 100644 --- a/xioopts.c +++ b/xioopts.c @@ -177,7 +177,7 @@ static int applyopt(struct single *sfd, int fd, struct opt *opt); binary search! */ /* NULL terminated */ const struct optname optionnames[] = { -#if HAVE_RESOLV_H && WITH_RES_AAONLY +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_AAONLY IF_RESOLVE("aaonly", &opt_res_aaonly) #endif #ifdef TCP_ABORT_THRESHOLD /* HP_UX */ @@ -421,7 +421,7 @@ const struct optname optionnames[] = { #ifdef TCP_DEFER_ACCEPT /* Linux 2.4.0 */ IF_TCP ("defer-accept", &opt_tcp_defer_accept) #endif -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("defnames", &opt_res_defnames) #endif /* HAVE_RESOLV_H */ #ifdef O_DELAY @@ -454,10 +454,10 @@ const struct optname optionnames[] = { #ifdef VDISCARD IF_TERMIOS("discard", &opt_vdiscard) #endif -#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST +#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST IF_IP ("dns", &opt_res_nsaddr) #endif -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("dnsrch", &opt_res_dnsrch) #endif /* HAVE_RESOLV_H */ #ifdef SO_DONTLINGER @@ -721,7 +721,7 @@ const struct optname optionnames[] = { IF_ANY ("ignoreeof", &opt_ignoreeof) IF_ANY ("ignoreof", &opt_ignoreeof) IF_TERMIOS("ignpar", &opt_ignpar) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("igntc", &opt_res_igntc) #endif /* HAVE_RESOLV_H */ IF_TERMIOS("imaxbel", &opt_imaxbel) @@ -1050,7 +1050,7 @@ const struct optname optionnames[] = { IF_IP ("multicast-ttl", &opt_ip_multicast_ttl) IF_IP ("multicastloop", &opt_ip_multicast_loop) IF_IP ("multicastttl", &opt_ip_multicast_ttl) -#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST +#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST IF_IP ("nameserver", &opt_res_nsaddr) #endif #if defined(O_NDELAY) && (!defined(O_NONBLOCK) || O_NDELAY != O_NONBLOCK) @@ -1118,7 +1118,7 @@ const struct optname optionnames[] = { IF_OPENSSL("nosni", &opt_openssl_no_sni) #endif IF_INTERFACE("notrailers", &opt_iff_notrailers) -#if WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST +#if (WITH_IP4 || WITH_IP6) && WITH_RESOLVE && HAVE_RESOLV_H && HAVE_RES_NSADDR_LIST IF_IP ("nsaddr", &opt_res_nsaddr) #endif #ifdef O_NSHARE @@ -1350,7 +1350,7 @@ const struct optname optionnames[] = { #if WITH_POSIXMQ IF_ANY ("posixmq-priority", &opt_posixmq_priority) #endif -#if HAVE_RESOLV_H && WITH_RES_PRIMARY +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_PRIMARY IF_RESOLVE("primary", &opt_res_primary) #endif #ifdef SO_PRIORITY @@ -1411,7 +1411,7 @@ const struct optname optionnames[] = { IF_OPEN ("rdonly", &opt_o_rdonly) IF_OPEN ("rdwr", &opt_o_rdwr) IF_ANY ("readbytes", &opt_readbytes) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("recurse", &opt_res_recurse) #endif /* HAVE_RESOLV_H */ #ifdef IP_RECVDSTADDR @@ -1451,7 +1451,7 @@ const struct optname optionnames[] = { #ifdef VREPRINT IF_TERMIOS("reprint", &opt_vreprint) #endif -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H # if WITH_AA_ONLY IF_RESOLVE("res-aaonly", &opt_res_aaonly) # endif @@ -1480,15 +1480,15 @@ const struct optname optionnames[] = { # endif IF_RESOLVE("res-stayopen", &opt_res_stayopen) IF_RESOLVE("res-usevc", &opt_res_usevc) -#endif /* HAVE_RESOLV_H */ +#endif /* (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H */ IF_PROXY ("resolv", &opt_proxy_resolve) IF_PROXY ("resolve", &opt_proxy_resolve) #ifdef IP_RETOPTS IF_IP ("retopts", &opt_ip_retopts) #endif -# if HAVE_RES_RETRANS +#if (WITH_IP4 || WITH_IP6) && HAVE_RES_RETRANS IF_RESOLVE("retrans", &opt_res_retrans) -# endif +#endif #if WITH_INTERFACE && defined(PACKET_AUXDATA) IF_SOCKET ("retrieve-vlan", &opt_retrieve_vlan) #endif @@ -1724,7 +1724,7 @@ const struct optname optionnames[] = { IF_IPAPP ("sourceport", &opt_sourceport) IF_IPAPP ("sp", &opt_sourceport) IF_TERMIOS("start", &opt_vstart) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("stayopen", &opt_res_stayopen) #endif /* HAVE_RESOLV_H */ IF_EXEC ("stderr", &opt_stderr) @@ -1930,7 +1930,7 @@ const struct optname optionnames[] = { IF_ANY ("user", &opt_user) IF_NAMED ("user-early", &opt_user_early) IF_ANY ("user-late", &opt_user_late) -#if HAVE_RESOLV_H +#if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H IF_RESOLVE("usevc", &opt_res_usevc) #endif /* HAVE_RESOLV_H */ #if defined(AI_V4MAPPED) @@ -2654,13 +2654,13 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts, (*opts)[i].value3.u_string); break; -#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) +#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) case TYPE_IP_MREQN: xiotype_ip_add_membership(token, ent, opt); break; -#endif /* defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) */ +#endif /* WITH_IP && defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) */ -#if defined(HAVE_STRUCT_IP_MREQ_SOURCE) && defined(IP_ADD_SOURCE_MEMBERSHIP) +#if _WITH_IP4 && defined(HAVE_STRUCT_IP_MREQ_SOURCE) case TYPE_IP_MREQ_SOURCE: xiotype_ip_add_source_membership(token, ent, opt); break; @@ -3323,6 +3323,7 @@ int retropt_bind(struct opt *opts, } } +# if WITH_IP4 || WITH_IP6 /* Set AI_PASSIVE, except when it is explicitely disabled */ ai_flags2[0] = ai_flags[0]; ai_flags2[1] = ai_flags[1]; @@ -3337,6 +3338,8 @@ int retropt_bind(struct opt *opts, Error("error resolving bind option"); return STAT_NORETRY; } +/*# else */ +# endif /* WITH_IP4 || WITH_IP6 */ break; #endif /* WITH_IP4 || WITH_IP6 || WITH_VSOCK */ @@ -3567,6 +3570,8 @@ int applyopt_ioctl_generic( return 0; } +#if _WITH_SOCKET + int applyopt_sockopt( int fd, struct opt *opt) @@ -3695,7 +3700,7 @@ int applyopt_sockopt( } break; #endif /* HAVE_STRUCT_LINGER */ -#if defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) +#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined (HAVE_STRUCT_IP_MREQN) ) case TYPE_IP_MREQN: /* handled in applyopts_single */ break; @@ -3815,6 +3820,8 @@ int applyopt_sockopt_generic( return 0; } +#endif /* _WITH_SOCKET */ + int applyopt_flock( int fd, struct opt *opt) @@ -4272,6 +4279,7 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) { case TYPE_CONST: *(int *)ptr = opt->desc->minor; break; +#if WITH_IP4 case TYPE_IP4NAME: memset(ptr, 0, sizeof(struct sockaddr_in)); ((struct sockaddr_in *)ptr)->sin_addr = opt->value.u_ip4addr; @@ -4281,6 +4289,7 @@ static int applyopt_offset(struct single *sfd, struct opt *opt) { memset(ptr, 0, sizeof(struct sockaddr_in)); *(struct sockaddr_in *)ptr = opt->value.u_ip4sock; break; +#endif /* WITH_IP4 */ default: Error2("applyopt_offset(opt:%s): type %s not implemented", opt->desc->defname, xiohelp_opttypename(opt->desc->type)); diff --git a/xioopts.h b/xioopts.h index ef3b31c..37545e1 100644 --- a/xioopts.h +++ b/xioopts.h @@ -72,7 +72,7 @@ enum e_types { #if HAVE_STRUCT_LINGER TYPE_LINGER, /* struct linger */ #endif /* HAVE_STRUCT_LINGER */ -#if HAVE_STRUCT_IP_MREQ || HAVE_STRUCT_IP_MREQN +#if (WITH_IP4 || WITH_IP6) && ( defined(HAVE_STRUCT_IP_MREQ) || defined(HAVE_STRUCT_IP_MREQN) ) TYPE_IP_MREQN, /* for struct ip_mreq or struct ip_mreqn */ #endif #if HAVE_STRUCT_IP_MREQ_SOURCE diff --git a/xioshutdown.c b/xioshutdown.c index c1ec796..6af190e 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -10,6 +10,7 @@ #include "xio-openssl.h" + static pid_t socat_kill_pid; /* here we pass the pid to be killed in sighandler */ static void signal_kill_pid(int dummy) { @@ -51,6 +52,7 @@ int xioshutdown(xiofile_t *sock, int how) { sock->stream.fd, strerror(errno)); } return 0; +#if _WITH_SOCKET case XIOSHUT_DOWN: result = Shutdown(sock->stream.fd, how); if (result < 0) { @@ -70,7 +72,6 @@ int xioshutdown(xiofile_t *sock, int how) { return -1; } return 0; -#if _WITH_SOCKET case XIOSHUT_NULL: writenull = '\0'; /* assign something to make gcc happy */ /* send an empty packet; only useful on datagram sockets? */ diff --git a/xiowrite.c b/xiowrite.c index 5388baf..a3e77ab 100644 --- a/xiowrite.c +++ b/xiowrite.c @@ -116,8 +116,10 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { case XIOWRITE_PIPE: if (pipe->para.bipipe.socktype == SOCK_STREAM) { writt = Write(pipe->para.bipipe.fdout, buff, bytes); +#if _WITH_SOCKET } else { writt = Send(pipe->para.bipipe.fdout, buff, bytes, 0); +#endif /* _WITH_SOCKET */ } _errno = errno; if (writt < 0) { From 9968ca4c5bf5c33393b6ac9786cec03b6a2c6174 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 21:51:58 +0100 Subject: [PATCH 06/51] Fixed filan -s displaying "(stream)" instead of "tcp" --- CHANGES | 3 +++ fdname.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 5a94938..cf9a110 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Security: Corrections: Fixed display of option phases in help output. + filan -s displayed "(stream)" instead of "tcp" with addresses + (regression). + Building: Disabling certain features during configure could break build process. diff --git a/fdname.c b/fdname.c index 58aa509..af7afc0 100644 --- a/fdname.c +++ b/fdname.c @@ -226,7 +226,7 @@ int sockname(int fd, FILE *outfile, char style) { #define FDNAME_OPTLEN 256 #define FDNAME_NAMELEN 256 socklen_t optlen; -#if WITH_IP && ( HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R ) +#if (WITH_IP4 || WITH_IP6) && ( HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R ) struct protoent protoent, *protoentp; #endif #define PROTONAMEMAX 1024 @@ -278,7 +278,7 @@ int sockname(int fd, FILE *outfile, char style) { Getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &optacceptconn, &optlen); #endif -#if WITH_IP && ( defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) ) +#if (WITH_IP4 || WITH_IP6) && ( defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) ) #if HAVE_GETPROTOBYNUMBER_R==1 /* Linux */ rc = getprotobynumber_r(proto, &protoent, protoname, sizeof(protoname), &protoentp); if (protoentp == NULL) { From fa67d7d380c2a9bbd348a86655974808ed510cfc Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 21:55:18 +0100 Subject: [PATCH 07/51] Corrected regression of ignoreeof --- CHANGES | 4 +++ socat.c | 2 +- test.sh | 88 ++++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index cf9a110..a03f5cc 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,10 @@ Corrections: filan -s displayed "(stream)" instead of "tcp" with addresses (regression). + Fixed a bug that made ignoreeof fail in 1.8.0.0 and 1.8.0.1; + corrected test IGNOREEOF. + Thanks to Rusty Bird for the precise problem report. + Building: Disabling certain features during configure could break build process. diff --git a/socat.c b/socat.c index cf1685d..6ffbd21 100644 --- a/socat.c +++ b/socat.c @@ -1013,7 +1013,7 @@ int _socat(void) { /* for ignoreeof */ if (polling) { if (!wasaction) { - if (socat_opts.total_timeout.tv_usec <= 1000000) { + if (socat_opts.total_timeout.tv_usec < 1000000) { if (total_timeout.tv_usec < socat_opts.pollintv.tv_usec) { total_timeout.tv_usec += 1000000; total_timeout.tv_sec -= 1; diff --git a/test.sh b/test.sh index bd8ea14..1357f1d 100755 --- a/test.sh +++ b/test.sh @@ -3521,67 +3521,110 @@ esac N=$((N+1)) +# Test the ignoreeof option in forward (left to right) direction NAME=IGNOREEOF case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file" -if ! eval $NUMCOND; then :; else +# Let Socat read from an empty file, this would terminate immediately due to +# EOF. Wait for more than one second, then append data to the file; when Socat +# transfers this data the test succeeded. +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "STDIO FILE" \ + "STDOUT FILE" \ + "ignoreeof" \ + "" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +else ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -" +# Note: the bug in 1.8.0.0 and 1.8.0.1 let Socat terminate in unidirectional +# mode after 1s, in bidirectional mode with traffic in reverse direction +# (var wasaction) immediately +CMD="$TRACE $SOCAT $opts -u FILE:\"$ti\",ignoreeof -" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! -sleep 0.1 +# Up to 1.8.0.1 this sleep was 0.1 and thus the test said OK despite the bug +sleep 1.1 echo "$da" >>"$ti" sleep 1 kill $bg 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: diff:\n" - cat "$tdiff" + $PRINTF "$FAILED (diff)\n" + echo "$CMD" + cat "$te" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 failed else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi - ok + $PRINTF "$OK\n" + if [ -n "$VERBOSE" ]; then echo "$CMD"; fi + if [ -n "$DEBUG" ]; then cat "$te" >&2; fi + ok fi fi ;; # NUMCOND esac N=$((N+1)) +# Test the ignoreeof option in reverse (right to left) direction NAME=IGNOREEOF_REV case "$TESTS" in *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) TEST="$NAME: ignoreeof on file right-to-left" -if ! eval $NUMCOND; then :; else +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "STDIO FILE" \ + "STDOUT FILE" \ + "ignoreeof" \ + "" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +else +# Let Socat read from an empty file, this would terminate immediately due to +# EOF. Wait for more than one second, then append data to the file; when Socat +# transfers this data the test succeeded. ti="$td/test$N.file" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD="$SOCAT $opts -U - file:\"$ti\",ignoreeof" +CMD="$SOCAT $opts -U - FILE:\"$ti\",ignoreeof" printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! -relsleep 1 +sleep 1.1 echo "$da" >>"$ti" sleep 1 -kill $bg 2>/dev/null +kill $bg 2>/dev/null; wait if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: diff:\n" - cat "$tdiff" + $PRINTF "$FAILED (diff)\n" + echo "$CMD" + cat "$te" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 failed else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi - ok + $PRINTF "$OK\n" + if [ -n "$VERBOSE" ]; then echo "$CMD"; fi + if [ -n "$DEBUG" ]; then cat "$te" >&2; fi + ok fi -wait fi ;; # NUMCOND esac N=$((N+1)) @@ -3601,12 +3644,13 @@ $CMD >"$tf" 2>"$te" if [ -s "$te" ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD" - cat "$te" + cat "$te" >&2 failed else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi - ok + $PRINTF "$OK\n" + if [ -n "$VERBOSE" ]; then echo "$CMD"; fi + if [ -n "$DEBUG" ]; then cat "$te" >&2; fi + ok fi fi ;; # NUMCOND esac From 5e56f252850db1e979354c3f6f91617955387401 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 21:58:08 +0100 Subject: [PATCH 08/51] Fix for old FreeBSD --- CHANGES | 5 ++++- compat.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index a03f5cc..b9ee5d5 100644 --- a/CHANGES +++ b/CHANGES @@ -17,11 +17,14 @@ Corrections: Building: Disabling certain features during configure could break build process. +Porting: + Fix for old FreeBSD. + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. - Fixed a few testing issues + Fixed a few testing issues. ####################### V 1.8.0.2: diff --git a/compat.h b/compat.h index 72e73c7..ecfa27c 100644 --- a/compat.h +++ b/compat.h @@ -98,6 +98,10 @@ typedef int sig_atomic_t; # define SOL_IPV6 IPPROTO_IPV6 #endif +#ifndef EAI_NODATA +# define EAI_NODATA 7 /* for old FreeBSD */ +#endif + #define F_uint8_t "%hu" #define F_uint8_x "%02hx" #define F_int8_t "%hd" From e7df880af5841c71b3644c2695ea0eb475e8c75a Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 21:59:56 +0100 Subject: [PATCH 09/51] Fixed ignoring of explicit socksport in socks5 addresses (regression) --- CHANGES | 4 ++++ doc/socat.yo | 2 ++ xio-socks.c | 3 ++- xio-socks5.c | 2 ++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b9ee5d5..274b8e6 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,10 @@ Corrections: corrected test IGNOREEOF. Thanks to Rusty Bird for the precise problem report. + Fixed the regression introduced with version 1.8.0.1 that in socks5 + addresses the explicit socksport (2nd address parameter) was ignored. + Thanks to Jakub Fišer for reporting this bug. + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index abfd991..2574a3f 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1103,6 +1103,7 @@ label(ADDRESS_SOCKS4A)dit(bf(tt(SOCKS4A:<socks-server>:<host>:<port>))) Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(SOCKS4)(GROUP_SOCKS),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port>:<target-host>:<target-port>))) +dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<target-host>:<target-port>))) Connects via <socks-server> [link(IP address)(TYPE_IP_ADDRESS)] to <target-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)] on <target-port> [link(TCP service)(TYPE_TCP_SERVICE)], @@ -1122,6 +1123,7 @@ label(ADDRESS_SOCKS5_CONNECT)dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<socks-port link(TCP)(ADDRESS_TCP_CONNECT) label(ADDRESS_SOCKS5_LISTEN)dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<socks-port>:<listen-host>:<listen-port>))) +dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<listen-host>:<listen-port>))) Connects to <socks-server> [link(IP address)(TYPE_IP_ADDRESS)] using socks version 5 protocol over TCP and makes it listen for incoming connections on <listen-port> [link(TCP service)(TYPE_TCP_SERVICE)], binding to <-listen-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)] diff --git a/xio-socks.c b/xio-socks.c index 2e9c224..089fd27 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -239,7 +239,8 @@ int _xioopen_opt_socksport( { struct servent *se; - if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) { + if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0 && + *socksport == NULL) { if ((se = getservbyname("socks", "tcp")) != NULL) { Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port)); if ((*socksport = Malloc(6)) == NULL) { diff --git a/xio-socks5.c b/xio-socks5.c index 8543881..8d8ffc5 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -533,6 +533,7 @@ static int xioopen_socks5( target_name = argv[3]; target_port = argv[4]; } else { + socks_port = NULL; target_name = argv[2]; target_port = argv[3]; } @@ -548,6 +549,7 @@ static int xioopen_socks5( if (_xioopen_opt_socksport(opts, (char **)&socks_port) < 0) { return STAT_NORETRY; } + /*! possible memory leak */ result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port, &pf, ipproto, From 29f9e4db921702fa8a88f865b299a9dcf76cd51a Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 22:21:19 +0100 Subject: [PATCH 10/51] Test script socks5server-echo.sh for new tests SOCKS5CONNECT_TCP4 and SOCKS5LISTEN_TCP4 --- CHANGES | 5 ++ Makefile.in | 2 +- doc/socat.yo | 3 +- socks4a-echo.sh | 12 ++-- socks4echo.sh | 8 +-- socks5server-echo.sh | 67 ++++++++++++++++++ test.sh | 163 ++++++++++++++++++++++++++++++++++--------- xio-socks5.c | 14 ++-- 8 files changed, 223 insertions(+), 51 deletions(-) create mode 100755 socks5server-echo.sh diff --git a/CHANGES b/CHANGES index 274b8e6..40d247a 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,11 @@ Testing: Fixed a few testing issues. + Added test script sock5server-echo.sh for SOCKS5-CONNECT and + SOCKS5-LISTEN, and appropriate tests. + SOCKS5 addresses are no longer experimental. + Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4 + ####################### V 1.8.0.2: Security: diff --git a/Makefile.in b/Makefile.in index 631d31d..6187393 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,7 +80,7 @@ SHFILES = socat-chain.sh socat-mux.sh socat-broker.sh \ daemon.sh mail.sh ftp.sh readline.sh \ socat_buildscript_for_android.sh TESTFILES = test.sh socks4echo.sh proxyecho.sh readline-test.sh \ - proxy.sh socks4a-echo.sh + proxy.sh socks4a-echo.sh socks5server-echo.sh all: progs doc diff --git a/doc/socat.yo b/doc/socat.yo index 2574a3f..747f915 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1108,7 +1108,6 @@ dit(bf(tt(SOCKS5-CONNECT:<socks-server>:<target-host>:<target-port>))) to <target-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)] on <target-port> [link(TCP service)(TYPE_TCP_SERVICE)], using socks version 5 protocol over TCP. Currently no authentication mechanism is provided.nl() - This address type is experimental.nl() Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl() Useful options: link(socksport)(OPTION_SOCKSPORT), @@ -1127,7 +1126,7 @@ dit(bf(tt(SOCKS5-LISTEN:<socks-server>:<listen-host>:<listen-port>))) Connects to <socks-server> [link(IP address)(TYPE_IP_ADDRESS)] using socks version 5 protocol over TCP and makes it listen for incoming connections on <listen-port> [link(TCP service)(TYPE_TCP_SERVICE)], binding to <-listen-host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)] - Currently not authentication mechanism is provided. This address type is experimental. + Currently not authentication mechanism is provided.nl() Option groups: link(FD)(GROUP_FD), link(SOCKET)(GROUP_SOCKET), link(IP4)(GROUP_IP4), link(IP6)(GROUP_IP6), link(TCP)(GROUP_TCP), link(CHILD)(GROUP_CHILD), link(RETRY)(GROUP_RETRY)nl() Useful options: link(sourceport)(OPTION_SOURCEPORT), diff --git a/socks4a-echo.sh b/socks4a-echo.sh index 7360366..91d255a 100755 --- a/socks4a-echo.sh +++ b/socks4a-echo.sh @@ -37,7 +37,7 @@ esac if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else - echo "cannot suppress trailing newline on echo" >&2 + echo "$0: cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" @@ -58,7 +58,7 @@ else fi if [ "$vn" != $($ECHO "\04") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks version requested" >&2 + echo "$0 invalid socks version requested" >&2 exit fi @@ -69,7 +69,7 @@ else fi if [ "$cd" != $($ECHO "\01") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks operation requested" >&2 + echo "$0: invalid socks operation requested" >&2 exit fi @@ -82,7 +82,7 @@ a=$(dd bs=1 count=6 2>/dev/null) if [ "$a" != "$($ECHO "}m\0\0\0\01")" ]; then sleep 1 $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks address or port requested" >&2 + echo "$0: wrong socks address or port requested" >&2 exit fi @@ -93,7 +93,7 @@ else fi if [ "$u" != "nobody" ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks user requested" >&2 + echo "$0: wrong socks user requested" >&2 exit fi @@ -104,7 +104,7 @@ else fi if [ "$h" != "localhost" ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks address requested" >&2 + echo "$0: wrong socks address requested" >&2 exit fi diff --git a/socks4echo.sh b/socks4echo.sh index 48ea536..a577b20 100755 --- a/socks4echo.sh +++ b/socks4echo.sh @@ -36,7 +36,7 @@ esac if [ $(echo "x\c") = "x" ]; then E="" elif [ $(echo -e "x\c") = "x" ]; then E="-e" else - echo "cannot suppress trailing newline on echo" >&2 + echo "$0: cannot suppress trailing newline on echo" >&2 exit 1 fi ECHO="echo $E" @@ -57,7 +57,7 @@ else fi if [ "$vn" != $($ECHO "\04") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks version requested" >&2 + echo "$0: invalid socks version requested" >&2 exit fi @@ -68,7 +68,7 @@ else fi if [ "$cd" != $($ECHO "\01") ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "invalid socks operation requested" >&2 + echo "$0: invalid socks operation requested" >&2 exit fi @@ -91,7 +91,7 @@ else fi if [ "$u" != "nobody" ]; then $ECHO "$SOCKSREPLY_FAILED" - echo "wrong socks user requested (expected \"nobody\")" >&2 + echo "$0: wrong socks user requested (expected \"nobody\")" >&2 exit fi diff --git a/socks5server-echo.sh b/socks5server-echo.sh new file mode 100755 index 0000000..04e562a --- /dev/null +++ b/socks5server-echo.sh @@ -0,0 +1,67 @@ +#! /usr/bin/env bash +# Source: socks5connect-echo.sh + +# Copyright Gerhard Rieger and contributors (see file CHANGES) +# Published under the GNU General Public License V.2, see file COPYING + +# Performs primitive simulation of a socks5 server with echo function via stdio. +# Accepts and answers SOCKS5 CONNECT request without authentication to +# 8.8.8.8:80, however is does not connect there but just echoes data. +# It is required for test.sh +# For TCP, use this script as: +# socat TCP-L:1080,reuseaddr EXEC:"socks5connect-echo.sh" + +#set -vx + +if [ "$SOCAT" ]; then + : +elif type socat >/dev/null 2>&1; then + SOCAT=socat +else + SOCAT=./socat +fi + +case `uname` in +HP-UX|OSF1) + CAT="$SOCAT -u STDIN STDOUT" + ;; +*) + CAT=cat + ;; +esac + +A="7f000001" +P="0050" + +# Read and parse SOCKS5 greeting +read _ v b c _ <<<"$($SOCAT -u -,readbytes=3 - |od -t x1)" +#echo "$v $b $c" >&2 +if [ "$v" != 05 ]; then echo "$0: Packet1: expected version x05, got \"$v\"" >&2; exit 1; fi +if [ "$b" != 01 ]; then echo "$0: Packet1: expected 01 auth methods, got \"$b\"" >&2; exit 1; fi +if [ "$c" != 00 ]; then echo "$0: Packet1: expected auth method 00, got \"$c\"" >&2; exit 1; fi +# Send answer +echo -en "\x05\x00" + +# Read and parse SOCKS5 connect request +read _ v b c d a1 a2 a3 a4 p1 p2 _ <<<"$($SOCAT -u -,readbytes=10 - |od -t x1)" +#echo "$v $b $c $d $a1 $a2 $a3 $a4 $p1 $p2" >&2 +a="$a1$a2$a3$a4" +p="$p1$p2" +if [ "$v" != 05 ]; then echo "$0: Packet2: expected version x05, got \"$v\"" >&2; exit 1; fi +if [ "$b" != 01 ] && [ "$b" != 02 ]; then echo "$0: Packet2: expected connect request 01 or bind request 02, got \"$b\"" >&2; exit 1; fi +if [ "$c" != 00 ]; then echo "$0: Packet2: expected reserved 00, got \"$c\"" >&2; exit 1; fi +if [ "$d" != 01 ]; then echo "$0: Packet2: expected address type 01, got \"$d\"" >&2; exit 1; fi +if [ "$a" != "$A" ]; then echo "$0: Packet2: expected address $A, got \"$a\"" >&2; exit 1; fi +if [ "$p" != "$P" ]; then echo "$0: Packet2: expected port $P, got \"$p\"" >&2; exit 1; fi +if [ "$z" != "" ]; then echo "$0: Packet2: trailing data \"$z\"" >&2; exit 1; fi +# Send answer +echo -en "\x05\x00\x00\x01\x10\x00\x1f\x64\x1f\x64" + +# Bind/listen/passive mode +if [ "$b" == 02 ]; then + sleep 1 # pretend to be waiting for connection + echo -en "\x05\x00\x00\x01\x10\xff\x1f\x64\x23\x28" +fi + +# perform echo function +$CAT diff --git a/test.sh b/test.sh index 1357f1d..9d08236 100755 --- a/test.sh +++ b/test.sh @@ -66,6 +66,7 @@ VERBOSE= DEBUG= DEFS= INTERNET= +EXPERIMENTAL= OPT_EXPECT_FAIL= EXPECT_FAIL= while [ "$1" ]; do case "X$1" in @@ -4295,46 +4296,62 @@ esac N=$((N+1)) +# Test the SOCKS address with IPv4 NAME=SOCKS4CONNECT_TCP4 case "$TESTS" in *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) TEST="$NAME: socks4 connect over TCP/IPv4" if ! eval $NUMCOND; then :; -elif ! testfeats socks4 >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N - cant -elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N +elif ! cond=$(checkconds \ + "" \ + "" \ + "socks4echo.sh" \ + "SOCKS4 IP4 TCP LISTEN STDIO" \ + "TCP4-LISTEN EXEC STDIN SOCKS4" \ + "so-reuseaddr" \ + "tcp4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else -tf="$td/test$N.stdout" -te="$td/test$N.stderr" -tdiff="$td/test$N.diff" -da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -# we have a normal tcp echo listening - so the socks header must appear in answer -newport tcp4 # provide free port number in $PORT -CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\"" -CMD="$TRACE $SOCAT $opts - SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody" -printf "test $F_n $TEST... " $N -eval "$CMD2 2>\"${te}1\" &" -pid=$! # background process id -waittcp4port $PORT 1 -echo "$da" |$CMD >$tf 2>"${te}2" -if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" - echo "$CMD2 &" - echo "$CMD" - cat "${te}1" - cat "${te}2" - cat "$tdiff" - failed -else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - ok -fi -kill $pid 2>/dev/null -wait + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp4 # provide free port number in $PORT + CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\"" + CMD1="$TRACE $SOCAT $opts STDIO SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid0=$! # background process id + waittcp4port $PORT 1 + echo "$da" |$CMD1 >${tf}1 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null + wait + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -19292,6 +19309,86 @@ fi # NUMCOND esac N=$((N+1)) + +# Above test introduced with 1.8.0.2 +# Below tests introduced with 1.8.0.3 (or later) + + +# Test the SOCKS5-CONNECT and SOCKS5-LISTEN addresses with IPv4 +for SUFFIX in CONNECT LISTEN; do + +suffix=$(tolower $SUFFIX) +if [ "$SUFFIX" = LISTEN ]; then + test=listen + LISTEN=LISTEN + listen=listen +else + test=dont + LISTEN= + listen= +fi +NAME=SOCKS5${SUFFIX}_TCP4 +case "$TESTS" in +*%$N%*|*%functions%*|*%socks%*|*%socks5%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$test%*|*%$NAME%*) +TEST="$NAME: SOCKS5-$SUFFIX over TCP/IPv4" +if ! eval $NUMCOND; then :; +elif ! cond=$(checkconds \ + "" \ + "" \ + "od ./socks5server-echo.sh" \ + "SOCKS5 IP4 TCP $LISTEN STDIO" \ + "TCP4-LISTEN EXEC STDIN SOCKS5-$SUFFIX" \ + "so-reuseaddr readbytes" \ + "tcp4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp4 # provide free port number in $PORT + CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR EXEC:\"./socks5server-echo.sh\"" + CMD1="$TRACE $SOCAT $opts STDIO SOCKS5-$SUFFIX:$LOCALHOST:127.0.0.1:80,pf=ip4,socksport=$PORT" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid0=$! # background process id + waittcp4port $PORT 1 + echo "$da" |$CMD1 >${tf}1 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null + wait + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi +fi ;; # NUMCOND, feats +esac +N=$((N+1)) + +done # CONNECT LISTEN + + # end of common tests ################################################################################## diff --git a/xio-socks5.c b/xio-socks5.c index 8d8ffc5..d931961 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -53,7 +53,7 @@ static int xioopen_socks5(int argc, const char *argv[], struct opt *opts, int xi const struct addrdesc xioaddr_socks5_connect = { "SOCKS5-CONNECT", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_CONNECT, 0, 0 HELP(":<socks-server>[:<socks-port>]:<target-host>:<target-port>") }; -const struct addrdesc xioaddr_socks5_listen = { "SOCKS5-LISTEN", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND, 0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") }; +const struct addrdesc xioaddr_socks5_listen = { "SOCKS5-LISTEN", 1+XIO_RDWR, xioopen_socks5, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_TCP|GROUP_IP_SOCKS|GROUP_CHILD|GROUP_RETRY, SOCKS5_COMMAND_BIND, 0, 0 HELP(":<socks-server>[:<socks-port>]:<listen-host>:<listen-port>") }; static const char * _xioopen_socks5_strerror(uint8_t r) { @@ -188,6 +188,8 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level) return STAT_RETRYLATER; } + Debug2("received SOCKS5 server hello %02x %02x", + server_hello_ptr[0], server_hello_ptr[1]); Info2("received SOCKS5 server hello version=%d method=%d", server_hello.version, server_hello.method); @@ -332,6 +334,12 @@ static int _xioopen_socks5_read_reply( } return STAT_RETRYLATER; } + Debug5("received SOCKS5 reply %02x %02x %02x %02x %02x", + ((unsigned char *)reply+bytes_read)[0], + ((unsigned char *)reply+bytes_read)[1], + ((unsigned char *)reply+bytes_read)[2], + ((unsigned char *)reply+bytes_read)[3], + ((unsigned char *)reply+bytes_read)[4]); bytes_read += result; /* Once we've read 5 bytes, figure out total message length and @@ -518,10 +526,6 @@ static int xioopen_socks5( bool lowport = false; char infobuff[256]; - if (!xioparms.experimental) { - Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); - return STAT_NORETRY; - } if (argc < 4 || argc > 5) { xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); return STAT_NORETRY; From 2dd1452f25ff42ca9b9be6a67c827feaf6b7082e Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Thu, 16 Jan 2025 11:59:01 +0100 Subject: [PATCH 11/51] Correct undesired logging of complete write() --- CHANGES | 2 ++ sysutils.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 40d247a..df3ae2b 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,8 @@ Corrections: addresses the explicit socksport (2nd address parameter) was ignored. Thanks to Jakub Fišer for reporting this bug. + Do not log simple successful write with NOTICE level. + Building: Disabling certain features during configure could break build process. diff --git a/sysutils.c b/sysutils.c index 082e845..777388f 100644 --- a/sysutils.c +++ b/sysutils.c @@ -27,6 +27,11 @@ const int one = 1; Returns <0 on unhandled error, errno valid Will only return <0 or bytes */ +/* Assuming your pipe size is 65536 - find out with: + filan -i 1 |grep F_GETPIPE_SZ |sed 's|.*\(F_GETPIPE_SZ=[1-9][0-9]*\).*|\1|' + Then we can test partial write with something like: + socat -d4 -lu -b 262144 -u /dev/zero,readbytes=262144 -,o-nonblock |{ sleep 3; wc -c; } +*/ ssize_t writefull(int fd, const void *buff, size_t bytes) { size_t writt = 0; ssize_t chk; @@ -40,16 +45,17 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) { case EWOULDBLOCK: #endif Warn4("write(%d, %p, "F_Zu"): %s", fd, (const char *)buff+writt, bytes-writt, strerror(errno)); - Sleep(1); continue; + Sleep(1); + continue; default: return -1; } } else if (writt+chk < bytes) { - Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (rev.direction is blocked)", + Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (meanwhile, other direction is blocked)", fd, (const char *)buff+writt, bytes-writt, chk); writt += chk; - } else { - writt = bytes; - break; + } else if (writt == 0) { + /* First attempt, write complete - no extra message */ + return chk; } } Notice3("write(%d, %p, "F_Zu") completed", fd, (const char *)buff, bytes); From 1878ae93fdb39a9eea36c9752a68202e30397099 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Thu, 9 Jan 2025 12:35:51 +0100 Subject: [PATCH 12/51] writefull() uses select()/poll() instead of sleep based polling --- CHANGES | 2 ++ sysutils.c | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index df3ae2b..f1efbcc 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,8 @@ Corrections: Do not log simple successful write with NOTICE level. + On partial write to not poll with sleep() but use select()/poll(). + Building: Disabling certain features during configure could break build process. diff --git a/sysutils.c b/sysutils.c index 777388f..a581a53 100644 --- a/sysutils.c +++ b/sysutils.c @@ -35,6 +35,9 @@ const int one = 1; ssize_t writefull(int fd, const void *buff, size_t bytes) { size_t writt = 0; ssize_t chk; + struct pollfd pfd; + int rc; + while (1) { chk = Write(fd, (const char *)buff + writt, bytes - writt); if (chk < 0) { @@ -45,10 +48,22 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) { case EWOULDBLOCK: #endif Warn4("write(%d, %p, "F_Zu"): %s", fd, (const char *)buff+writt, bytes-writt, strerror(errno)); - Sleep(1); + pfd.fd = fd; + pfd.events = POLLOUT; + pfd.revents = 0; + rc = xiopoll(&pfd, 1, NULL); + if (rc == 0) { + Notice("inactivity timeout triggered"); + errno = ETIMEDOUT; + return -1; + } continue; - default: return -1; + default: + return -1; } + } else if (chk == bytes) { + /* First attempt, complete write */ + return chk; } else if (writt+chk < bytes) { Warn4("write(%d, %p, "F_Zu"): only wrote "F_Zu" bytes, trying to continue (meanwhile, other direction is blocked)", fd, (const char *)buff+writt, bytes-writt, chk); @@ -56,6 +71,8 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) { } else if (writt == 0) { /* First attempt, write complete - no extra message */ return chk; + } else { /* write completed */ + break; } } Notice3("write(%d, %p, "F_Zu") completed", fd, (const char *)buff, bytes); From 1154e69d3e9b8ac259bf39bf0df9de6151c7d32e Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 10 Jan 2025 19:41:34 +0100 Subject: [PATCH 13/51] writefull() respects total inactivity timeout --- CHANGES | 4 ++++ socat.c | 2 ++ sysutils.c | 13 +++++++++++-- sysutils.h | 2 +- test.sh | 6 +++--- xio-proxy.c | 6 +++--- xio-readline.c | 2 +- xio-socks.c | 2 +- xio-socks5.c | 4 ++-- xio.h | 1 + xiolockfile.c | 2 +- xiowrite.c | 2 +- 12 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index f1efbcc..0588136 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,9 @@ Corrections: On partial write to not poll with sleep() but use select()/poll(). + Partial write situations respect total inactivity timeout when + nonblocking. + Building: Disabling certain features during configure could break build process. @@ -39,6 +42,7 @@ Testing: SOCKS5 addresses are no longer experimental. Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4 + ####################### V 1.8.0.2: Security: diff --git a/socat.c b/socat.c index 6ffbd21..c990f62 100644 --- a/socat.c +++ b/socat.c @@ -282,6 +282,8 @@ int main(int argc, const char *argv[]) { socat_opts.total_timeout.tv_usec = (rto-socat_opts.total_timeout.tv_sec) * 1000000; } + xioparms.total_timeout.tv_sec = socat_opts.total_timeout.tv_sec; + xioparms.total_timeout.tv_usec = socat_opts.total_timeout.tv_usec; break; case 'u': if (arg1[0][2]) { socat_opt_hint(stderr, arg1[0][1], arg1[0][2]); Exit(1); } socat_opts.lefttoright = true; break; diff --git a/sysutils.c b/sysutils.c index a581a53..f395e58 100644 --- a/sysutils.c +++ b/sysutils.c @@ -32,10 +32,15 @@ const int one = 1; Then we can test partial write with something like: socat -d4 -lu -b 262144 -u /dev/zero,readbytes=262144 -,o-nonblock |{ sleep 3; wc -c; } */ -ssize_t writefull(int fd, const void *buff, size_t bytes) { +ssize_t writefull( + int fd, + const void *buff, + size_t bytes, + const struct timeval *tmo0) { size_t writt = 0; ssize_t chk; struct pollfd pfd; + struct timeval tmo = { 0 }; int rc; while (1) { @@ -51,7 +56,11 @@ ssize_t writefull(int fd, const void *buff, size_t bytes) { pfd.fd = fd; pfd.events = POLLOUT; pfd.revents = 0; - rc = xiopoll(&pfd, 1, NULL); + if (tmo0 != NULL) { + tmo.tv_sec = tmo0->tv_sec; + tmo.tv_usec = tmo0->tv_usec; + } + rc = xiopoll(&pfd, 1, (tmo.tv_sec!=0 || tmo.tv_usec!=0) ? &tmo : NULL); if (rc == 0) { Notice("inactivity timeout triggered"); errno = ETIMEDOUT; diff --git a/sysutils.h b/sysutils.h index 5e8ae10..cfdff04 100644 --- a/sysutils.h +++ b/sysutils.h @@ -47,7 +47,7 @@ struct xiorange { extern const int one; #endif -extern ssize_t writefull(int fd, const void *buff, size_t bytes); +extern ssize_t writefull(int fd, const void *buff, size_t bytes, const struct timeval *tmo0); #if _WITH_SOCKET extern socklen_t socket_init(int af, union sockaddr_union *sa); diff --git a/test.sh b/test.sh index 9d08236..c16a839 100755 --- a/test.sh +++ b/test.sh @@ -19053,7 +19053,7 @@ else da="test$N $(date) $RANDOM" case X$IPPORT in XPORT) newport $(tolower $PROTO); _PORT=$PORT ;; - XPROTO) echo "IPPROTO=\"$IPPROTO\"" + XPROTO) #echo "IPPROTO=\"$IPPROTO\"" _PORT=$IPPROTO ;; esac CMD0="$TRACE $SOCAT $opts ${ADDR}:$_PORT,$option,$ACCEPT_TIMEOUT PIPE" @@ -19146,7 +19146,7 @@ else da="test$N $(date) $RANDOM" case X$IPPORT in XPORT) newport $(tolower $PROTO); _PORT=$PORT ;; - XPROTO) echo "IPPROTO=\"$IPPROTO\"" + XPROTO) #echo "IPPROTO=\"$IPPROTO\"" _PORT=$IPPROTO ;; esac CMD0="$TRACE $SOCAT $opts -u /dev/null $ADDR:localhost-6-4.dest-unreach.net:$_PORT,bind=127.0.0.1" @@ -19211,7 +19211,7 @@ else da="test$N $(date) $RANDOM" case X$IPPORT in XPORT) newport $(tolower $PROTO); _PORT=$PORT ;; - XPROTO) echo "IPPROTO=\"$IPPROTO\"" + XPROTO) #echo "IPPROTO=\"$IPPROTO\"" _PORT=$IPPROTO ;; esac CMD0="$TRACE $SOCAT $opts ${ADDR%%-*}-LISTEN:$_PORT,pf=ip4 PIPE" diff --git a/xio-proxy.c b/xio-proxy.c index 86d86e3..0a8d4e6 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -376,7 +376,7 @@ int _xioopen_proxy_connect(struct single *sfd, * xiosanitize(request, strlen(request), textbuff) = '\0'; Info1("sending \"%s\"", textbuff); /* write errors are assumed to always be hard errors, no retry */ - if (writefull(sfd->fd, request, strlen(request)) < 0) { + if (writefull(sfd->fd, request, strlen(request), NULL) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", sfd->fd, request, strlen(request), strerror(errno)); if (Close(sfd->fd) < 0) { @@ -406,7 +406,7 @@ int _xioopen_proxy_connect(struct single *sfd, *next = '\0'; Info1("sending \"%s\\r\\n\"", header); *next++ = '\r'; *next++ = '\n'; *next++ = '\0'; - if (writefull(sfd->fd, header, strlen(header)) < 0) { + if (writefull(sfd->fd, header, strlen(header), NULL) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", sfd->fd, header, strlen(header), strerror(errno)); if (Close(sfd->fd) < 0) { @@ -419,7 +419,7 @@ int _xioopen_proxy_connect(struct single *sfd, } Info("sending \"\\r\\n\""); - if (writefull(sfd->fd, "\r\n", 2) < 0) { + if (writefull(sfd->fd, "\r\n", 2, NULL) < 0) { Msg2(level, "write(%d, \"\\r\\n\", 2): %s", sfd->fd, strerror(errno)); if (Close(sfd->fd) < 0) { diff --git a/xio-readline.c b/xio-readline.c index 376cd26..2807379 100644 --- a/xio-readline.c +++ b/xio-readline.c @@ -184,7 +184,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { /* we must carriage return, because readline will first print the prompt */ ssize_t writt; - writt = writefull(pipe->fd, "\r", 1); + writt = writefull(pipe->fd, "\r", 1, NULL); if (writt < 0) { Warn2("write(%d, \"\\r\", 1): %s", pipe->fd, strerror(errno)); diff --git a/xio-socks.c b/xio-socks.c index 089fd27..fd064dd 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -370,7 +370,7 @@ int _xioopen_socks4_connect(struct single *sfd, } } #endif /* WITH_MSGLEVEL <= E_DEBUG */ - if (writefull(sfd->fd, sockhead, headlen) < 0) { + if (writefull(sfd->fd, sockhead, headlen, NULL) < 0) { Msg4(level, "write(%d, %p, "F_Zu"): %s", sfd->fd, sockhead, headlen, strerror(errno)); if (Close(sfd->fd) < 0) { diff --git a/xio-socks5.c b/xio-socks5.c index d931961..31aa1ca 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -136,7 +136,7 @@ static int _xioopen_socks5_handshake(struct single *sfd, int level) } #endif - if (writefull(sfd->fd, client_hello, client_hello_size) < 0) { + if (writefull(sfd->fd, client_hello, client_hello_size, NULL) < 0) { Msg4(level, "write(%d, %p, %d): %s", sfd->fd, client_hello, client_hello_size, strerror(errno)); @@ -426,7 +426,7 @@ static int _xioopen_socks5_request( } #endif - if (writefull(sfd->fd, req, bytes) < 0) { + if (writefull(sfd->fd, req, bytes, NULL) < 0) { Msg4(level, "write(%d, %p, %d): %s", sfd->fd, req, bytes, strerror(errno)); if (Close(sfd->fd) < 0) { diff --git a/xio.h b/xio.h index a276a56..ade2d0a 100644 --- a/xio.h +++ b/xio.h @@ -120,6 +120,7 @@ typedef struct xioparms { const char *sniffleft_name; /* file name with -r */ const char *sniffright_name; /* file name with -R */ size_t bufsiz; + struct timeval total_timeout;/* when nothing happens, die after seconds */ } xioparms_t; /* pack the description of a lock file */ diff --git a/xiolockfile.c b/xiolockfile.c index c6896d4..ff29c2f 100644 --- a/xiolockfile.c +++ b/xiolockfile.c @@ -52,7 +52,7 @@ int xiogetlock(const char *lockfile) { pid = Getpid(); bytes = sprintf(pidbuf, F_pid"\n", pid); - if (writefull(fd, pidbuf, bytes) < 0) { + if (writefull(fd, pidbuf, bytes, NULL) < 0) { Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno)); return -1; } diff --git a/xiowrite.c b/xiowrite.c index a3e77ab..c5885ad 100644 --- a/xiowrite.c +++ b/xiowrite.c @@ -50,7 +50,7 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) { switch (pipe->dtype & XIODATA_WRITEMASK) { case XIOWRITE_STREAM: - writt = writefull(pipe->fd, buff, bytes); + writt = writefull(pipe->fd, buff, bytes, NULL); if (writt < 0) { _errno = errno; switch (_errno) { From 9beffd3193a02d0454626f48f60c203229aa07c0 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Wed, 29 Jan 2025 22:41:25 +0100 Subject: [PATCH 14/51] Fixed: xiopoll(...) Bad file descriptor --- CHANGES | 4 ++++ socat.c | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 0588136..6c005c4 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,10 @@ Corrections: Partial write situations respect total inactivity timeout when nonblocking. + Fixed a bug that could lead to error "xiopoll(...): Bad file descriptor" + or to undefined behaviour before terminating Socat with addresses EXEC, + SYSTEM, or SHELL. + Building: Disabling certain features during configure could break build process. diff --git a/socat.c b/socat.c index c990f62..5886a00 100644 --- a/socat.c +++ b/socat.c @@ -865,11 +865,12 @@ int childleftdata(xiofile_t *xfd) { XIO_RDSTREAM(xfd)->para.exec.pid == 0) { struct timeval timeout = { 0, 0 }; - if (XIO_READABLE(xfd) && !(XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof)) { - in.fd = XIO_GETRDFD(xfd); - in.events = POLLIN/*|POLLRDBAND*/; - in.revents = 0; - } + if (XIO_RDSTREAM(xfd)->eof >= 2 && !XIO_RDSTREAM(xfd)->ignoreeof) + return 0; + + in.fd = XIO_GETRDFD(xfd); + in.events = POLLIN/*|POLLRDBAND*/; + in.revents = 0; do { int _errno; retval = xiopoll(&in, 1, &timeout); @@ -877,7 +878,7 @@ int childleftdata(xiofile_t *xfd) { } while (retval < 0 && errno == EINTR); if (retval < 0) { - Error5("xiopoll({%d,%0o}, 1, {"F_tv_sec"."F_tv_usec"}): %s", + Error5("xiopoll({%d,0%o}, 1, {"F_tv_sec"."F_tv_usec"}): %s", in.fd, in.events, timeout.tv_sec, timeout.tv_usec, strerror(errno)); return -1; @@ -1133,7 +1134,7 @@ int _socat(void) { */ if (retval < 0) { - Error11("xiopoll({%d,%0o}{%d,%0o}{%d,%0o}{%d,%0o}, 4, {"F_tv_sec"."F_tv_usec"}): %s", + Error11("xiopoll({%d,0%o}{%d,0%o}{%d,0%o}{%d,0%o}, 4, {"F_tv_sec"."F_tv_usec"}): %s", fds[0].fd, fds[0].events, fds[1].fd, fds[1].events, fds[2].fd, fds[2].events, fds[3].fd, fds[3].events, timeout.tv_sec, timeout.tv_usec, strerror(errno)); From bcca5a3b9a139b76c906e090e18f4dbfb02f4909 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 27 Dec 2024 13:00:22 +0100 Subject: [PATCH 15/51] Option ip-add-source-membership did not work --- CHANGES | 4 ++++ xio-ip.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 6c005c4..ee0315b 100644 --- a/CHANGES +++ b/CHANGES @@ -29,6 +29,10 @@ Corrections: or to undefined behaviour before terminating Socat with addresses EXEC, SYSTEM, or SHELL. + Option ip-add-source-membership did not work. + Thanks to Duncan Sands and others for reporting this issue and sending + the fix. + Building: Disabling certain features during configure could break build process. diff --git a/xio-ip.c b/xio-ip.c index 3a136d0..455ac47 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -1355,7 +1355,7 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { } ip4_mreq_src.imr_multiaddr = sockaddr1.ip4.sin_addr; /* second parameter is interface address */ - rc = xioresolve(opt->value.u_string/*ifaddr*/, NULL, + rc = xioresolve(opt->value2.u_string/*ifaddr*/, NULL, sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr2, &socklen2, sfd->para.socket.ip.ai_flags); @@ -1364,7 +1364,7 @@ int xioapply_ip_add_source_membership(struct single *sfd, struct opt *opt) { } ip4_mreq_src.imr_interface = sockaddr2.ip4.sin_addr; /* third parameter is source address */ - rc = xioresolve(opt->value.u_string/*srcaddr*/, NULL, + rc = xioresolve(opt->value3.u_string/*srcaddr*/, NULL, sfd->para.socket.la.soa.sa_family, SOCK_DGRAM, IPPROTO_IP, &sockaddr3, &socklen3, sfd->para.socket.ip.ai_flags); From 920ed1f0a3dd9f0e206e3db6a5e109f0f6bee9f8 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Thu, 16 Jan 2025 08:00:05 +0100 Subject: [PATCH 16/51] Fixed possible crash or fail of option ip-add-membership with two parameters --- CHANGES | 5 +++++ sycls.c | 15 +++++++++++++++ sycls.h | 2 ++ xio-exec.c | 3 ++- xio-ip.c | 3 ++- xiolayer.c | 3 ++- xioopts.c | 3 ++- 7 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index ee0315b..02e50c2 100644 --- a/CHANGES +++ b/CHANGES @@ -33,6 +33,10 @@ Corrections: Thanks to Duncan Sands and others for reporting this issue and sending the fix. + Option ip-add-membership with only two parameters crashed or failed + when malloc() does not initialize memory with zeros. + Thanks to Nicolas Cavallari for reporting and fixing this bug. + Building: Disabling certain features during configure could break build process. @@ -50,6 +54,7 @@ Testing: SOCKS5 addresses are no longer experimental. Tests: SOCKS5CONNECT_TCP4 SOCKS5LISTEN_TCP4 + Added a developer test that overwrites malloc'ed memory with non-zeros. ####################### V 1.8.0.2: diff --git a/sycls.c b/sycls.c index 900cee3..2fbed6f 100644 --- a/sycls.c +++ b/sycls.c @@ -1513,6 +1513,9 @@ void *Malloc(size_t size) { Error1("malloc("F_Zd"): out of memory", size); return NULL; } +#if WITH_DEVTESTS + memset(result, 0x55, size); +#endif /* WITH_DEVTESTS */ return result; } @@ -1540,6 +1543,18 @@ void *Realloc(void *ptr, size_t size) { return result; } +/* Like Realloc(), but gets info about old size for overwrite test */ +void *Realloc3(void *ptr, size_t size, size_t oldsize) { + void *result = Realloc(ptr, size); + if (result == NULL) + return result; +#if WITH_DEVTESTS + if (size > oldsize) + memset(result+oldsize, 0x55, size-oldsize); +#endif /* WITH_DEVTESTS */ + return result; +} + #if _WITH_TERMIOS int Tcgetattr(int fd, struct termios *termios_p) { int i, result, _errno; diff --git a/sycls.h b/sycls.h index 8f8ded5..fe9bb70 100644 --- a/sycls.h +++ b/sycls.h @@ -148,6 +148,7 @@ struct hostent *Getipnodebyname(const char *name, int af, int flags, void *Malloc(size_t size); void *Calloc(size_t nmemb, size_t size); void *Realloc(void *ptr, size_t size); +void *Realloc3(void *ptr, size_t size, size_t oldsize); int Tcgetattr(int fd, struct termios *termios_p); int Tcsetattr(int fd, int optional_actions, struct termios *termios_p); char *Ttyname(int fd); @@ -257,6 +258,7 @@ void Add_history(const char *string); #define Malloc(s) malloc(s) #define Calloc(n,s) calloc(n,s) #define Realloc(p,s) realloc(p,s) +#define Realloc3(p,s,o) realloc(p,s) #define Tcgetattr(f,t) tcgetattr(f,t) #define Tcsetattr(f,o,t) tcsetattr(f,o,t) #define Ttyname(f) ttyname(f) diff --git a/xio-exec.c b/xio-exec.c index bed513c..303d429 100644 --- a/xio-exec.c +++ b/xio-exec.c @@ -84,7 +84,8 @@ static int xioopen_exec( while (*strp == ' ') { while (*++strp == ' ') ; if ((pargc & 0x07) == 0) { - pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); + /*0 pargv = Realloc(pargv, (pargc+8)*sizeof(char *)); */ + pargv = Realloc3(pargv, (pargc+8)*sizeof(char *), pargc*sizeof(char *)); if (pargv == NULL) return STAT_RETRYLATER; } pargv[pargc++] = tokp; diff --git a/xio-ip.c b/xio-ip.c index 455ac47..308973b 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -1112,13 +1112,14 @@ int xiotype_ip_add_membership( opt->value2.u_string/*param2*/, opt->value3.u_string/*ifindex*/); } else { - /*0 opt->value3.u_string = NULL; / * is NULL from init */ + opt->value3.u_string = NULL; /* is not NULL from init! */ Info3("setting option \"%s\" to {\"%s\",\"%s\"}", ent->desc->defname, opt->value.u_string/*multiaddr*/, opt->value2.u_string/*param2*/); } #else /* !HAVE_STRUCT_IP_MREQN */ + opt->value3.u_string = NULL; Info3("setting option \"%s\" to {\"%s\",\"%s\"}", ent->desc->defname, opt->value.u_string/*multiaddr*/, diff --git a/xiolayer.c b/xiolayer.c index 83b8839..a378293 100644 --- a/xiolayer.c +++ b/xiolayer.c @@ -48,7 +48,8 @@ int xio_chdir( free(tmp_dir); return -1; } - *orig_dir = Realloc(*orig_dir, strlen(*orig_dir)+1); + /*0 *orig_dir = Realloc(*orig_dir, strlen(*orig_dir)+1); */ + *orig_dir = Realloc3(*orig_dir, strlen(*orig_dir)+1, PATH_MAX); if (Chdir(tmp_dir) < 0) { Error2("chdir(\"%s\"): %s", tmp_dir, strerror(errno)); diff --git a/xioopts.c b/xioopts.c index 81f1e53..a93a1b6 100644 --- a/xioopts.c +++ b/xioopts.c @@ -2768,7 +2768,8 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts, ++i; if ((i % 8) == 0) { - *opts = Realloc(*opts, (i+8) * sizeof(struct opt)); + /*0 *opts = Realloc(*opts, (i+8) * sizeof(struct opt)); */ + *opts = Realloc3(*opts, (i+8) * sizeof(struct opt), i * sizeof(struct opt)); if (*opts == NULL) { return -1; } From 68f0143f7bcdb2489a9c2a038675867f78972e7b Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 24 Jan 2025 16:54:50 +0100 Subject: [PATCH 17/51] READLINE now prints newline on empty input line --- CHANGES | 4 ++++ xio-readline.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/CHANGES b/CHANGES index 02e50c2..2950b31 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,10 @@ Corrections: when malloc() does not initialize memory with zeros. Thanks to Nicolas Cavallari for reporting and fixing this bug. + The readline() library function does not output the newline of empty + input lines. Changed Socat to explicitly print the newline in this + case. + Building: Disabling certain features during configure could break build process. diff --git a/xio-readline.c b/xio-readline.c index 2807379..69423c0 100644 --- a/xio-readline.c +++ b/xio-readline.c @@ -204,6 +204,9 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) { if (line == NULL) { return 0; /* EOF */ } + if (strlen(line) == 0) { + Write(STDOUT_FILENO, "\n", 1); + } #if _WITH_TERMIOS xiotermios_clrflag(pipe->fd, 3, ECHO); xiotermios_flush(pipe->fd); From 9bf5fc625ceef0709c336e0cdbf9764188de7ac1 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 24 Jan 2025 17:01:55 +0100 Subject: [PATCH 18/51] POSIXMQ-RECV takes option o-nonblock --- CHANGES | 4 ++++ doc/socat.yo | 17 +++++++++-------- xio-posixmq.c | 5 +++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 2950b31..aeeb398 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,10 @@ Corrections: input lines. Changed Socat to explicitly print the newline in this case. +Features: + POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, + makes it possible to terminate Socat in case the queue is empty. + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index 747f915..30c2bb0 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -332,7 +332,7 @@ label(ADDRESS_DCCP_CONNECT)dit(bf(tt(DCCP-CONNECT:<host>:<port>)) (bf(tt(DCCP:<h link(connect-timeout)(OPTION_CONNECT_TIMEOUT), link(tos)(OPTION_TOS), link(dccp-set-ccid)(OPTION_DCCP_SET_CCID), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), link(readbytes)(OPTION_READBYTES)nl() @@ -747,7 +747,7 @@ label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:<filename>))) Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() Useful options: link(rdonly)(OPTION_RDONLY), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(group)(OPTION_GROUP), link(user)(OPTION_USER), link(mode)(OPTION_MODE), @@ -784,7 +784,8 @@ label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>))) Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(unlink-early)(OPTION_UNLINK_EARLY), - link(unlink-close)(OPTION_UNLINK_CLOSE) + link(unlink-close)(OPTION_UNLINK_CLOSE), + link(o-nonblock)(OPTION_O_NONBLOCK) label(ADDRESS_POSIXMQ_RECEIVE)dit(bf(tt(POSIXMQ-RECEIVE:/<mqueue>))) dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) @@ -882,7 +883,7 @@ label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT:<host>:<port>))) link(mtudiscover)(OPTION_MTUDISCOVER), link(sctp-maxseg)(OPTION_SCTP_MAXSEG), link(sctp-nodelay)(OPTION_SCTP_NODELAY), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(sourceport)(OPTION_SOURCEPORT), link(retry)(OPTION_RETRY), link(readbytes)(OPTION_READBYTES)nl() @@ -1234,7 +1235,7 @@ label(ADDRESS_TCP_CONNECT)dit(bf(tt(TCP:<host>:<port>))) link(mtudiscover)(OPTION_MTUDISCOVER), link(mss)(OPTION_MSS), link(nodelay)(OPTION_TCP_NODELAY), - link(nonblock)(OPTION_NONBLOCK), + link(nonblock)(OPTION_O_NONBLOCK), link(readbytes)(OPTION_READBYTES)nl() See also: link(TCP4)(ADDRESS_TCP4_CONNECT), @@ -1853,7 +1854,7 @@ label(OPTION_APPEND)dit(bf(tt(append[=<bool>]))) socat() uses the code(O_APPEND) flag with the code(open()) system call (link(example)(EXAMPLE_OPTION_APPEND)). Otherwise, socat() applies the code(fcntl(fd, F_SETFL, O_APPEND)) call. -label(OPTION_NONBLOCK)dit(bf(tt(nonblock[=<bool>]))) +label(OPTION_O_NONBLOCK)dit(bf(tt(nonblock[=<bool>]))) Tries to open or use file in nonblocking mode. Its only effects are that the code(connect()) call of TCP addresses does not block, and that opening a named pipe for reading does not block. @@ -1988,7 +1989,7 @@ E.g., option `creat' sets the code(O_CREAT) flag. When the used address does not use code(open()) (e.g.STDIO), the code(fcntl(..., F_SETFL, ...)) call is used instead.nl() See also options link(append)(OPTION_APPEND) and -link(nonblock)(OPTION_NONBLOCK). +link(nonblock)(OPTION_O_NONBLOCK). startdit() label(OPTION_O_CREAT)dit(bf(tt(creat[=<bool>]))) Creates the file if it does not exist (link(example)(EXAMPLE_OPTION_CREAT)). @@ -3973,7 +3974,7 @@ prompts. label(EXAMPLE_ADDRESS_PTY) label(EXAMPLE_OPTION_SYMBOLIC_LINK) label(EXAMPLE_OPTION_WAIT_SLAVE) -label(EXAMPLE_OPTION_NONBLOCK) +label(EXAMPLE_OPTION_O_NONBLOCK) mancommand(\.LP) mancommand(\.nf) mancommand(\fBsocat \\) diff --git a/xio-posixmq.c b/xio-posixmq.c index 186e932..f80b303 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -45,6 +45,7 @@ static int xioopen_posixmq( int dirs = addrdesc->arg1; int oneshot = addrdesc->arg2; bool opt_unlink_early = false; + bool nonblock; int oflag; bool opt_o_excl = false; mode_t opt_mode = 0666; @@ -113,6 +114,8 @@ static int xioopen_posixmq( case XIO_RDONLY: oflag |= O_RDONLY; break; case XIO_WRONLY: oflag |= O_WRONLY; break; } + if (retropt_bool(opts, OPT_O_NONBLOCK, &nonblock) >= 0 && nonblock) + oflag |= O_NONBLOCK; /* Now open the message queue */ Debug3("mq_open(\"%s\", %d, "F_mode", NULL)", name, oflag, opt_mode); @@ -155,6 +158,8 @@ static int xioopen_posixmq( do { struct pollfd pollfd; + if (oflag & O_NONBLOCK) + break; pollfd.fd = sfd->fd; pollfd.events = (dirs==XIO_RDONLY?POLLIN:POLLOUT); if (xiopoll(&pollfd, 1, NULL) > 0) { From 663a6bb012afd423aeb8564cb5de33349018da92 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 6 Sep 2024 13:09:44 +0200 Subject: [PATCH 19/51] Added option posixmq-flush --- CHANGES | 4 ++ doc/socat.yo | 3 ++ test.sh | 92 +++++++++++++------------------------------- xio-posixmq.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++-- xio-posixmq.h | 1 + xioopts.c | 2 + xioopts.h | 1 + 7 files changed, 138 insertions(+), 69 deletions(-) diff --git a/CHANGES b/CHANGES index aeeb398..225a8cd 100644 --- a/CHANGES +++ b/CHANGES @@ -45,6 +45,10 @@ Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. + New option posixmq-flush (mq-flush) for POSIXMQ addresses empty the + queue before starting to transfer data. + Test: LINUX_POSIXMQ_FLUSH + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index 30c2bb0..a478fbb 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -3492,6 +3492,9 @@ startdit() label(OPTION_POSIXMQ_PRIORITY)dit(bf(tt(posixmq-priority (mq-prio)))) Sets the priority of messages (packets) written to the queue, or the minimal priority of packet read from the queue. +label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush)))) + "Consumes" (drops) all messages currently in the queue before starting + transfers. enddit() diff --git a/test.sh b/test.sh index c16a839..7dcb0da 100755 --- a/test.sh +++ b/test.sh @@ -16683,28 +16683,18 @@ esac N=$((N+1)) - # Test the POSIX MQ feature with continuous READ and priorization on Linux -NAME=LINUX_POSIXMQ_READ_PRIO +NAME=POSIXMQ_READ_PRIO case "$TESTS" in *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) with prio" +TEST="$NAME: POSIX-MQ with prio" # Run a client/sender that creates a POSIX-MQ and sends a normal message and # then a client/sender with a higher priority message. # Run a passive/listening/receiving/reading process and check if it receives # both messages and in the prioritized order if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - cant -elif ! F=$(testfeats POSIXMQ STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - cant -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - cant -elif ! o=$(testoptions mq-prio unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO" "POSIXMQ-SEND POSIXMQ-READ STDIO" "mq-prio unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else tf="$td/test$N.stdout" @@ -16725,7 +16715,7 @@ pid1=$! relsleep 1 kill $pid1; wait if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (rc0a=$rc0a, rc0b=$rc0b)\n" echo "$CMD0a" cat "${te}0a" >&2 echo "$CMD0b" @@ -16743,7 +16733,7 @@ elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then if [ "$DEBUG" ]; then cat "${te}1" >&2; fi ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD0a" cat "${te}0a" >&2 echo "$CMD0b" @@ -16759,27 +16749,18 @@ fi # NUMCOND esac N=$((N+1)) -# Test the POSIX MQ feature with RECV,fork on Linux -NAME=LINUX_POSIXMQ_RECV_FORK +# Test the POSIX MQ feature with RECV,fork +NAME=POSIXMQ_RECV_FORK case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) RECV with fork" +TEST="$NAME: POSIX-MQ RECV with fork" # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its # output. # Run two clients/senders each with a message. # Check if both messages are stored. if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - cant -elif ! F=$(testfeats POSIXMQ STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - cant -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - cant -elif ! o=$(testoptions fork unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO" "POSIXMQ-SEND POSIXMQ-READ STDIO" "fork unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else tf="$td/test$N.stdout" @@ -16801,7 +16782,7 @@ rc1b=$? relsleep 1 kill $pid0; wait if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" @@ -16819,7 +16800,7 @@ elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" @@ -16835,11 +16816,11 @@ fi # NUMCOND esac N=$((N+1)) -# Test the POSIX MQ feature with RECV,fork,max-children on Linux -NAME=LINUX_POSIXMQ_RECV_MAXCHILDREN +# Test the POSIX MQ feature with RECV,fork,max-children +NAME=POSIXMQ_RECV_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children" +TEST="$NAME: POSIX-MQ RECV with fork,max-children" # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its # output via sub processes that sleeps after writing. # Run a client/sender that sends message 1; @@ -16847,17 +16828,8 @@ TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children" # write message 2 directly into output file; # Check if the messages are stored in order of their numbers if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N - cant -elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - cant -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - cant -elif ! o=$(testoptions fork max-children unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SYSTEM" "POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM" "fork max-children unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else tf="$td/test$N.stdout" @@ -16882,7 +16854,7 @@ sleep 1 # as in SYSTEM kill $(childpids $pid0) $pid0 2>/dev/null wait 2>/dev/null if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" @@ -16900,7 +16872,7 @@ elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" @@ -16916,11 +16888,11 @@ fi # NUMCOND esac N=$((N+1)) -# Test the POSIX MQ feature with SEND,fork,max-children on Linux -NAME=LINUX_POSIXMQ_SEND_MAXCHILDREN +# Test the POSIX MQ feature with SEND,fork,max-children +NAME=POSIXMQ_SEND_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) -TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children" +TEST="$NAME: POSIX-MQ SEND with fork,max-children" # Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from # there to an output file # Run a POSIX-MQ sender that two times forks and invokes a data generator @@ -16930,21 +16902,9 @@ TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children" # Check if the messages are stored in order of their numbers. # The data generator is implemented as a receiver from an MQ with "1", "3" if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SYSTEM" "POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM" "fork max-children mq-prio unlink-early unlink-close"); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant -elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N - cant -elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM); then - $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N - cant -elif ! o=$(testoptions fork max-children mq-prio unlink-early unlink-close) >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N - cant -#elif ! runsposixmq >/dev/null; then -# $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N -# cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19252,6 +19212,8 @@ DCCP-CONNECT dccp4 PORT #ROXY::127.0.0.1 tcp4 PORT " +# Above tests introduced before or with 1.8.0.1 +# Below test introduced with 1.8.0.2 # Test the readline.sh file overwrite vulnerability NAME=READLINE_SH_OVERWRITE diff --git a/xio-posixmq.c b/xio-posixmq.c index f80b303..5168781 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -15,9 +15,8 @@ #if WITH_POSIXMQ -static int _posixmq_unlink( - const char *name, - int level); /* message level on error */ +static int _posixmq_flush(struct single *sfd); +static int _posixmq_unlink(const char *name, int level); static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); @@ -27,6 +26,7 @@ const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-pri", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; +const struct optdesc opt_posixmq_flush = { "posixmq-flush", "mq-flush", OPT_POSIXMQ_FLUSH, GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC, 0, 0, 0 }; /* _read(): open immediately, stay in transfer loop _recv(): wait until data (how we know there is??), oneshot, opt.fork @@ -45,11 +45,13 @@ static int xioopen_posixmq( int dirs = addrdesc->arg1; int oneshot = addrdesc->arg2; bool opt_unlink_early = false; - bool nonblock; + bool nonblock = 0; + bool flush = false; int oflag; bool opt_o_excl = false; mode_t opt_mode = 0666; mqd_t mqd; + struct mq_attr attr; int _errno; bool dofork = false; int maxchildren = 0; @@ -97,6 +99,7 @@ static int xioopen_posixmq( retropt_bool(opts, OPT_O_EXCL, &opt_o_excl); retropt_mode(opts, OPT_PERM, &opt_mode); + retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush); retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); if (opt_unlink_early) { @@ -117,6 +120,11 @@ static int xioopen_posixmq( if (retropt_bool(opts, OPT_O_NONBLOCK, &nonblock) >= 0 && nonblock) oflag |= O_NONBLOCK; + if (flush) { + if (_posixmq_flush(sfd) != STAT_OK) + return STAT_NORETRY; + } + /* Now open the message queue */ Debug3("mq_open(\"%s\", %d, "F_mode", NULL)", name, oflag, opt_mode); mqd = mq_open(name, oflag, opt_mode, NULL); @@ -129,6 +137,16 @@ static int xioopen_posixmq( } sfd->fd = mqd; + Debug1("mq_getattr(%d, ...)", mqd); + if (mq_getattr(mqd, &attr) < 0) { + Warn4("mq_getattr(%d[\"%s\"], %p): %s", + mqd, sfd->para.posixmq.name, &attr, strerror(errno)); + mq_close(mqd); + return STAT_NORETRY; + } + Info5("POSIXMQ queue \"%s\": flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld", + name, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); + if (!dofork && !oneshot) { return STAT_OK; } @@ -236,6 +254,81 @@ static int xioopen_posixmq( } +/* With option flush try to open the queue and "consume" its current contents */ +static int _posixmq_flush( + struct single *sfd) +{ + mqd_t mqd; + struct mq_attr attr; + void *buff; + size_t bufsiz; + int _errno; + int p = 0; /* number of messages flushed */ + size_t b = 0; /* number of bytes flushed */ + + Info1("flushing POSIXMQ queue \"%s\"", sfd->para.posixmq.name); + Debug1("mq_open(\"%s\", O_RDONLY|O_NONBLOCK, 0, NULL)", + sfd->para.posixmq.name); + mqd = mq_open(sfd->para.posixmq.name, O_RDONLY|O_NONBLOCK, 0, NULL); + _errno = errno; + Debug1("mq_open() -> %d", mqd); + if (mqd < 0 && _errno == ENOENT) { + Info("this queue does not exist, no need to flush it"); + return STAT_OK; + } + if (mqd < 0) { + Warn2("mq_open(\"%s\", ...): %s", sfd->para.posixmq.name, + strerror(_errno)); + return STAT_NORETRY; + } + + Debug1("mq_getattr(%d, ...)", mqd); + if (mq_getattr(mqd, &attr) < 0) { + Warn4("mq_getattr(%d[\"%s\"], %p): %s", + mqd, sfd->para.posixmq.name, &attr, strerror(errno)); + mq_close(mqd); + return STAT_NORETRY; + } + if (attr.mq_curmsgs == 0) { + Info1("POSIXMQ \"%s\" is empty", sfd->para.posixmq.name); + mq_close(mqd); + return STAT_OK; + } + bufsiz = attr.mq_msgsize; + if ((buff = Malloc(bufsiz)) == NULL) { + mq_close(mqd); + return STAT_RETRYLATER; + } + + /* Now read all messages to null */ + while (true) { + ssize_t bytes; + + Debug3("mq_receive(mqd=%d, %p, "F_Zu", {} )", mqd, buff, bufsiz); + bytes = mq_receive(mqd, buff, bufsiz, &sfd->para.posixmq.prio); + _errno = errno; + Debug1("mq_receive() -> "F_Zd, bytes); + errno = _errno; + if (bytes == 0 || (bytes < 0 && _errno == EAGAIN)) { + break; + } + if (bytes < 0) { + Warn2("flushing POSIXMQ \"%s\" failed: %s", + sfd->para.posixmq.name, strerror(_errno)); + free(buff); + mq_close(mqd); + return STAT_NORETRY; + } + ++p; + b += bytes; + } + Info3("flushed "F_Zu" bytes in %u packets from queue \"%s\"", b, p, + sfd->para.posixmq.name); + free(buff); + mq_close(mqd); + return STAT_OK; +} + ssize_t xiowrite_posixmq( struct single *sfd, const void *buff, @@ -288,6 +381,9 @@ ssize_t xioclose_posixmq( struct single *sfd) { int res; + + if (sfd->fd < 0) + return 0; Debug1("xioclose_posixmq(): mq_close(%d)", sfd->fd); res = mq_close(sfd->fd); if (res < 0) { diff --git a/xio-posixmq.h b/xio-posixmq.h index 8359696..b7242e0 100644 --- a/xio-posixmq.h +++ b/xio-posixmq.h @@ -11,6 +11,7 @@ extern const struct addrdesc xioaddr_posixmq_receive; extern const struct addrdesc xioaddr_posixmq_send; extern const struct optdesc opt_posixmq_priority; +extern const struct optdesc opt_posixmq_flush; extern ssize_t xioread_posixmq(struct single *file, void *buff, size_t bufsiz); extern ssize_t xiopending_posixmq(struct single *pipe); diff --git a/xioopts.c b/xioopts.c index a93a1b6..3824014 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1032,6 +1032,7 @@ const struct optname optionnames[] = { #endif IF_ANY ("mode", &opt_perm) #if WITH_POSIXMQ + IF_ANY ("mq-flush", &opt_posixmq_flush) IF_ANY ("mq-prio", &opt_posixmq_priority) #endif #ifdef TCP_MAXSEG @@ -1348,6 +1349,7 @@ const struct optname optionnames[] = { IF_INTERFACE("portsel", &opt_iff_portsel) #endif #if WITH_POSIXMQ + IF_ANY ("posixmq-flush", &opt_posixmq_flush) IF_ANY ("posixmq-priority", &opt_posixmq_priority) #endif #if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_PRIMARY diff --git a/xioopts.h b/xioopts.h index 37545e1..4796fb2 100644 --- a/xioopts.h +++ b/xioopts.h @@ -482,6 +482,7 @@ enum e_optcode { OPT_LOWPORT, OPT_MAX_CHILDREN, #if WITH_POSIXMQ + OPT_POSIXMQ_FLUSH, OPT_POSIXMQ_PRIORITY, #endif #ifdef NLDLY From 25d2f746d9ba0dbf590d75b54769307ef8d8c259 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Tue, 10 Sep 2024 20:16:36 +0200 Subject: [PATCH 20/51] Added options posixmq-maxmsg and posixmq-msgsize --- CHANGES | 3 +++ doc/socat.yo | 10 ++++++++- test.sh | 4 ++-- xio-posixmq.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++----- xio-posixmq.h | 2 ++ xioopts.c | 8 +++++-- xioopts.h | 2 ++ 7 files changed, 79 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 225a8cd..ac17961 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,9 @@ Features: queue before starting to transfer data. Test: LINUX_POSIXMQ_FLUSH + New options posixmq-maxmsg, posixmq-msgsize. + Tests: POSIXMQ_MAXMSG POSIXMQ_MSGSIZE + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index a478fbb..3786ebd 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -2168,7 +2168,7 @@ label(OPTION_NETNS)dit(bf(tt(netns=<net-namespace-name>))) Before opening the address it tries to switch to the named network namespace. After opening the address it switches back to the previous namespace. (link(Example with TCP forwarder)(EXAMPLE_OPTION_NETNS), - link(example with virtual network connection)(EXAMPLE_TUN_NETNS).nl() + link(example with virtual network connection)(EXAMPLE_TUN_NETNS)).nl() Only on Linux; requires root; use option tt(--experimental).nl() enddit() @@ -3495,6 +3495,14 @@ label(OPTION_POSIXMQ_PRIORITY)dit(bf(tt(posixmq-priority (mq-prio)))) label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush)))) "Consumes" (drops) all messages currently in the queue before starting transfers. +label(OPTION_POSIXMQ_MAXMSG)dit(bf(tt(posixmq-maxmsg (mq-maxmsg)))) + Sets the maxmsg parameter of the POSIX message queue when creating it. + Note: You need root or CAP_SYS_RESOURCE to exceed the default value + (<tt>/proc/sys/fs/mqueue/msg_default</tt>). +label(OPTION_POSIXMQ_MSGSIZE)dit(bf(tt(posixmq-msgsize (mq-msgsize)))) + Sets the msgsize parameter of the POSIX message queue when creating it. + Note: You need root or CAP_SYS_RESOURCE to exceed the default value + (<tt>/proc/sys/fs/mqueue/msgsize_default</tt>). enddit() diff --git a/test.sh b/test.sh index 7dcb0da..3bc44e8 100755 --- a/test.sh +++ b/test.sh @@ -15106,8 +15106,8 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork" -CMD1="$TRACE $SOCAT $opts -t $T4 - TCP4:localhost:$PORT" +CMD0="$TRACE $SOCAT $opts -t $T4 TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork" +CMD1="$TRACE $SOCAT $opts -t $T8 - TCP4:localhost:$PORT" printf "test $F_n $TEST... " $N eval "$CMD0" >/dev/null 2>"${te}0" & pid0=$! diff --git a/xio-posixmq.c b/xio-posixmq.c index 5168781..ff5842d 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -25,8 +25,10 @@ const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") }; const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; -const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-pri", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; +const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-prio", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; const struct optdesc opt_posixmq_flush = { "posixmq-flush", "mq-flush", OPT_POSIXMQ_FLUSH, GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_posixmq_maxmsg = { "posixmq-maxmsg", "mq-maxmsg", OPT_POSIXMQ_MAXMSG, GROUP_POSIXMQ, PH_OPEN, TYPE_LONG, OFUNC_SPEC, 0, 0, 0 }; +const struct optdesc opt_posixmq_msgsize = { "posixmq-msgsize", "mq-msgsize", OPT_POSIXMQ_MSGSIZE, GROUP_POSIXMQ, PH_OPEN, TYPE_LONG, OFUNC_SPEC, 0, 0, 0 }; /* _read(): open immediately, stay in transfer loop _recv(): wait until data (how we know there is??), oneshot, opt.fork @@ -47,11 +49,12 @@ static int xioopen_posixmq( bool opt_unlink_early = false; bool nonblock = 0; bool flush = false; + struct mq_attr attr = { 0 }; + bool setopts = false; int oflag; bool opt_o_excl = false; mode_t opt_mode = 0666; mqd_t mqd; - struct mq_attr attr; int _errno; bool dofork = false; int maxchildren = 0; @@ -100,6 +103,47 @@ static int xioopen_posixmq( retropt_bool(opts, OPT_O_EXCL, &opt_o_excl); retropt_mode(opts, OPT_PERM, &opt_mode); retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush); + retropt_long(opts, OPT_POSIXMQ_MAXMSG, &attr.mq_maxmsg) || + (setopts = true); + retropt_long(opts, OPT_POSIXMQ_MSGSIZE, &attr.mq_msgsize) || + (setopts = true); + + /* When only one of mq-maxmsg and mq-msgsize options has been provided, + we must nevertheless set the other option value in strucht mq_attr. + For this we have to find the default, read it from /proc fs */ + if (setopts) { + int pfd; + const static char *PROC_MAXMSG = "/proc/sys/fs/mqueue/msg_default"; + const static char *PROC_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default"; + char buff[21]; /* fit a 64bit num in decimal */ + ssize_t bytes; + + if (attr.mq_maxmsg == 0) { + if ((pfd = Open(PROC_MAXMSG, O_RDONLY, 0)) < 0) { + Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MAXMSG, strerror(errno)); + } else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) { + Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s", + pfd, PROC_MAXMSG, sizeof(buff)-1, strerror (errno)); + Close(pfd); + } else { + sscanf(buff, "%ld", &attr.mq_maxmsg); + Close(pfd); + } + } + + if (attr.mq_msgsize == 0) { + if ((pfd = Open(PROC_MSGSIZE, O_RDONLY, 0)) < 0) { + Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MSGSIZE, strerror(errno)); + } else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) { + Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s", + pfd, PROC_MSGSIZE, sizeof(buff)-1, strerror (errno)); + Close(pfd); + } else { + sscanf(buff, "%ld", &attr.mq_msgsize); + Close(pfd); + } + } + } retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early); if (opt_unlink_early) { @@ -126,12 +170,18 @@ static int xioopen_posixmq( } /* Now open the message queue */ - Debug3("mq_open(\"%s\", %d, "F_mode", NULL)", name, oflag, opt_mode); - mqd = mq_open(name, oflag, opt_mode, NULL); + if (setopts) + Debug8("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} )", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); + else + Debug4("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL)", argv[0], name, oflag, opt_mode); + mqd = mq_open(name, oflag, opt_mode, setopts ? &attr : NULL); _errno = errno; Debug1("mq_open() -> %d", mqd); if (mqd < 0) { - Error3("%s: mq_open(\"%s\"): %s", argv[0], name, strerror(errno)); + if (setopts) + Error9("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} ): %s", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs, strerror(errno)); + else + Error5("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL): %s", argv[0], name, oflag, opt_mode, strerror(errno)); errno = _errno; return STAT_RETRYLATER; } diff --git a/xio-posixmq.h b/xio-posixmq.h index b7242e0..4779f1a 100644 --- a/xio-posixmq.h +++ b/xio-posixmq.h @@ -10,6 +10,8 @@ extern const struct addrdesc xioaddr_posixmq_read; extern const struct addrdesc xioaddr_posixmq_receive; extern const struct addrdesc xioaddr_posixmq_send; +extern const struct optdesc opt_posixmq_maxmsg; +extern const struct optdesc opt_posixmq_msgsize; extern const struct optdesc opt_posixmq_priority; extern const struct optdesc opt_posixmq_flush; diff --git a/xioopts.c b/xioopts.c index 3824014..0f48c40 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1032,8 +1032,10 @@ const struct optname optionnames[] = { #endif IF_ANY ("mode", &opt_perm) #if WITH_POSIXMQ - IF_ANY ("mq-flush", &opt_posixmq_flush) - IF_ANY ("mq-prio", &opt_posixmq_priority) + IF_ANY ("mq-flush", &opt_posixmq_flush) + IF_ANY ("mq-maxmsg", &opt_posixmq_maxmsg) + IF_ANY ("mq-msgsize", &opt_posixmq_msgsize) + IF_ANY ("mq-prio", &opt_posixmq_priority) #endif #ifdef TCP_MAXSEG IF_TCP ("mss", &opt_tcp_maxseg) @@ -1350,6 +1352,8 @@ const struct optname optionnames[] = { #endif #if WITH_POSIXMQ IF_ANY ("posixmq-flush", &opt_posixmq_flush) + IF_ANY ("posixmq-maxmsg", &opt_posixmq_maxmsg) + IF_ANY ("posixmq-msgsize", &opt_posixmq_msgsize) IF_ANY ("posixmq-priority", &opt_posixmq_priority) #endif #if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_PRIMARY diff --git a/xioopts.h b/xioopts.h index 4796fb2..2cdd3ac 100644 --- a/xioopts.h +++ b/xioopts.h @@ -483,6 +483,8 @@ enum e_optcode { OPT_MAX_CHILDREN, #if WITH_POSIXMQ OPT_POSIXMQ_FLUSH, + OPT_POSIXMQ_MAXMSG, + OPT_POSIXMQ_MSGSIZE, OPT_POSIXMQ_PRIORITY, #endif #ifdef NLDLY From 1ea37d48c25c10abe12ecb1e53d8820ba9d49077 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Tue, 12 Nov 2024 22:28:02 +0100 Subject: [PATCH 21/51] Fixed o-creat, o-excl, and o-cloexec with POSIXMQ-* --- CHANGES | 4 ++++ doc/socat.yo | 12 ++++------ test.sh | 62 ++++++++++++++++++++++++++------------------------- xio-fd.c | 2 +- xio-file.c | 2 +- xio-file.h | 2 +- xio-posixmq.c | 38 ++++++++++++++++++++----------- xio-socket.c | 6 ++--- xio-udp.c | 2 +- xio-unix.c | 2 +- xioopts.c | 15 +++++++------ xioopts.h | 4 ++-- 12 files changed, 83 insertions(+), 68 deletions(-) diff --git a/CHANGES b/CHANGES index ac17961..fbedf85 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,10 @@ Corrections: input lines. Changed Socat to explicitly print the newline in this case. + Fixed implementation of options o-creat, o-excl, and o-cloexec with + POSIXMQ-* addresses. + POSIXMQ addresses are no longer experimental. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/doc/socat.yo b/doc/socat.yo index 3786ebd..2e97524 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -779,8 +779,6 @@ label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>))) link(-U)(option_U) and link(dual addresses)(ADDRESS_DUAL).nl() Socat() provides this address type only on Linux because POSIX MQ is based on UNIX filedescriptors there.nl() - This feature is new in version 1.8.0.0 and might change in the future, - therefore it is link(experimental)(option_experimental).nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(unlink-early)(OPTION_UNLINK_EARLY), @@ -793,7 +791,6 @@ dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) This is a read-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) for more info.nl() Example: link(POSIX MQ recv with fork)(EXAMPLE_POSIXMQ_RECV_FORK)nl() - This feature is link(experimental)(option_experimental).nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(fork)(OPTION_FORK), @@ -806,7 +803,6 @@ label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) This is a write-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) for more info.nl() (link(Example)(EXAMPLE_POSIXMQ_SEND))nl() - This feature is link(experimental)(option_experimental).nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(fork)(OPTION_FORK), @@ -4458,14 +4454,14 @@ both devices. Use pppd on device tt(/var/run/ppp) then. label(EXAMPLE_POSIXMQ_SEND) mancommand(\.LP) mancommand(\.nf) -mancommand(\fBsocat --experimental -u \\) +mancommand(\fBsocat -u \\) mancommand(\.RS) mancommand(\fBSTDIO \\ POSIXMQ-SEND:/queue1,unlink-early,mq-prio=10\fP) mancommand(\.RE) mancommand(\.fi) -htmlcommand(<hr><div class="shell">socat --experimental -u \ +htmlcommand(<hr><div class="shell">socat -u \ STDIO \ POSIXMQ-SEND:/queue1,unlink-early,mq-prio=10</div>) @@ -4477,7 +4473,7 @@ label(EXAMPLE_POSIXMQ_RECV_FORK) mancommand(\.LP) mancommand(\.nf) -mancommand(\fBsocat --experimental -u \\) +mancommand(\fBsocat -u \\) mancommand(\.RS) mancommand(\fBPOSIXMQ-RECV:/queue1,fork,max-children=3 \\ SYSTEM:"worker.sh"\fP) @@ -4485,7 +4481,7 @@ mancommand(\fBPOSIXMQ-RECV:/queue1,fork,max-children=3 \\ mancommand(\.RE) mancommand(\.fi) -htmlcommand(<hr><div class="shell">socat --experimental -u \ +htmlcommand(<hr><div class="shell">socat -u \ POSIXMQ-RECV:/queue1,fork,max-children=3 \ SYSTEM:"worker.sh"</div>) diff --git a/test.sh b/test.sh index 3bc44e8..f321bc0 100755 --- a/test.sh +++ b/test.sh @@ -1038,7 +1038,7 @@ childprocess () { local l case "$1" in [1-9]*) ;; - *) echo "childprocess \"$1\": not a number" >&2; exit 1 ;; + *) echo "childprocess \"$1\": not a number" >&2; exit -1 ;; esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;; @@ -1065,7 +1065,7 @@ childpids () { if [ "X$1" = "X-r" ]; then recursive=1; shift; fi case "$1" in [1-9]*) ;; - *) echo "childpids \"$1\": not a number" >&2; exit 1 ;; + *) echo "childpids \"$1\": not a number" >&2; exit -1 ;; esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;; @@ -16702,9 +16702,9 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early" -CMD0b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1" -CMD1="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-close STDIO" +CMD0a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early" +CMD0b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1" +CMD1="$TRACE $SOCAT $opts -u POSIXMQ-READ:$tq,unlink-close STDIO" printf "test $F_n $TEST... " $N echo "$da 0" |$CMD0a 2>"${te}0a" rc0a=$? @@ -16768,9 +16768,9 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO" -CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq" -CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" +CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO" +CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq" +CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" printf "test $F_n $TEST... " $N $CMD0 2>"${te}0" >"${tf}0" & pid0=$! @@ -16837,9 +16837,9 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\"" -CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq" -CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" +CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\"" +CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq" +CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" printf "test $F_n $TEST... " $N eval $CMD0 2>"${te}0" >"${tf}0" & pid0=$! @@ -16893,8 +16893,8 @@ NAME=POSIXMQ_SEND_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) TEST="$NAME: POSIX-MQ SEND with fork,max-children" -# Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from -# there to an output file +# Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from it +# to an output file # Run a POSIX-MQ sender that two times forks and invokes a data generator # for messages 1 and 3 in a shell process with some trailing sleep. # Afterwards write message 2 directly into output file; message 3 should be @@ -16911,38 +16911,40 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-early STDIO" -CMD1="$TRACE $SOCAT --experimental $opts -U POSIXMQ-SEND:$tq,fork,max-children=1,interval=0.1 SYSTEM:\"./socat\ --experimental\ -u\ POSIXMQ-RECV\:$tq-data\ -;\ sleep\ 1\"" +CMD1="$TRACE $SOCAT $opts -u POSIXMQ-READ:$tq,unlink-early STDIO" +CMD2="$TRACE $SOCAT $opts -U POSIXMQ-SEND:$tq,fork,max-children=1,interval=0.1 SYSTEM:\"./socat\ -u\ POSIXMQ-RECV\:$tq-data\ -;\ sleep\ 1\"" printf "test $F_n $TEST... " $N # create data for the generator -echo "$da 1" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data,unlink-early -echo "$da 3" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data -eval $CMD0 2>"${te}0" >>"${tf}0" & -pid0=$! -relsleep 1 -eval $CMD1 2>"${te}1" & +echo "$da 1" |$SOCAT -u - POSIXMQ-SEND:$tq-data,unlink-early 2>"${te}0a" +echo "$da 3" |$SOCAT -u - POSIXMQ-SEND:$tq-data 2>"${te}0b" +eval $CMD1 2>"${te}1" >>"${tf}1" & pid1=$! +relsleep 1 +eval $CMD2 2>"${te}2" & +pid2=$! sleep 0.5 -echo "$da 2" >>"${tf}0" +echo "$da 2" >>"${tf}1" sleep 1 # as in SYSTEM -kill $pid0 $(childpids $pid0) $pid1 $(childpids $pid1) 2>/dev/null +kill $pid1 $(childpids $pid1) $pid2 $(childpids $pid2) 2>/dev/null wait 2>/dev/null -$SOCAT -u --experimental /dev/null POSIXMQ-SEND:$tq-data,unlink-close -if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then +# remove the queues +$SOCAT -u /dev/null POSIXMQ-SEND:$tq-data,unlink-close 2>"${te}3a" +$SOCAT -u /dev/null POSIXMQ-SEND:$tq,unlink-close 2>"${te}3b" +if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}1 >${tdiff}1; then $PRINTF "$OK\n" - if [ "$VERBOSE" ]; then echo "$CMD0"; fi - if [ "$DEBUG" ]; then cat "${te}0" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD2"; fi + if [ "$DEBUG" ]; then cat "${te}2" >&2; fi ok else $PRINTF "$FAILED\n" - echo "$CMD0" - cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 + echo "$CMD2" + cat "${te}2" >&2 echo "difference:" >&2 - cat ${tdiff}0 >&2 + cat ${tdiff}1 >&2 failed fi fi # NUMCOND diff --git a/xio-fd.c b/xio-fd.c index 6f50629..70b8634 100644 --- a/xio-fd.c +++ b/xio-fd.c @@ -31,7 +31,7 @@ const struct optdesc opt_o_noinherit = { "o-noinherit", "noinherit", OPT_O_NOINH const struct optdesc opt_o_noatime = { "o-noatime", "noatime", OPT_O_NOATIME, GROUP_OPEN|GROUP_FD, PH_FD, TYPE_BOOL, OFUNC_FCNTL, F_SETFL, O_NOATIME }; #endif /****** for ALL addresses - with fcntl(F_SETFD) ******/ -const struct optdesc opt_cloexec = { "cloexec", NULL, OPT_CLOEXEC, GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC }; +const struct optdesc opt_cloexec = { "cloexec", NULL, OPT_O_CLOEXEC, GROUP_FD, PH_LATE, TYPE_BOOL, OFUNC_FCNTL, F_SETFD, FD_CLOEXEC }; /****** ftruncate() ******/ /* this record is good for ftruncate() or ftruncate64() if available */ #if HAVE_FTRUNCATE64 diff --git a/xio-file.c b/xio-file.c index c19be4b..cb61247 100644 --- a/xio-file.c +++ b/xio-file.c @@ -20,7 +20,7 @@ static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xiof const struct optdesc opt_o_rdonly = { "o-rdonly", "rdonly", OPT_O_RDONLY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDONLY, O_ACCMODE }; const struct optdesc opt_o_wronly = { "o-wronly", "wronly", OPT_O_WRONLY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_WRONLY, O_ACCMODE }; const struct optdesc opt_o_rdwr = { "o-rdwr", "rdwr", OPT_O_RDWR, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG_PATTERN, O_RDWR, O_ACCMODE }; -const struct optdesc opt_o_create = { "o-create", "creat", OPT_O_CREATE, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT }; +const struct optdesc opt_o_creat = { "o-creat", "creat", OPT_O_CREAT, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_CREAT }; const struct optdesc opt_o_excl = { "o-excl", "excl", OPT_O_EXCL, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_EXCL }; const struct optdesc opt_o_noctty = { "o-noctty", "noctty", OPT_O_NOCTTY, GROUP_OPEN, PH_OPEN, TYPE_BOOL, OFUNC_FLAG, O_NOCTTY }; #ifdef O_SYNC diff --git a/xio-file.h b/xio-file.h index f592d68..be01378 100644 --- a/xio-file.h +++ b/xio-file.h @@ -8,7 +8,7 @@ extern const struct optdesc opt_o_rdonly; extern const struct optdesc opt_o_wronly; extern const struct optdesc opt_o_rdwr; -extern const struct optdesc opt_o_create; +extern const struct optdesc opt_o_creat; extern const struct optdesc opt_o_excl; extern const struct optdesc opt_o_noctty; extern const struct optdesc opt_o_sync; diff --git a/xio-posixmq.c b/xio-posixmq.c index ff5842d..da3bdb3 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -20,10 +20,10 @@ static int _posixmq_unlink(const char *name, int level); static int xioopen_posixmq(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); -const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDWR, 0, 0 HELP(":<mqname>") }; -const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":<mqname>") }; -const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") }; -const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO_RDWR, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDWR, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-prio", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; const struct optdesc opt_posixmq_flush = { "posixmq-flush", "mq-flush", OPT_POSIXMQ_FLUSH, GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC, 0, 0, 0 }; @@ -52,7 +52,11 @@ static int xioopen_posixmq( struct mq_attr attr = { 0 }; bool setopts = false; int oflag; + bool opt_o_creat = true; bool opt_o_excl = false; +#ifdef O_CLOEXEC + bool opt_o_cloexec = true; +#endif mode_t opt_mode = 0666; mqd_t mqd; int _errno; @@ -61,10 +65,6 @@ static int xioopen_posixmq( bool with_intv = false; int result = 0; - if (!xioparms.experimental) { - Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); - return STAT_NORETRY; - } if (argc != 2) { xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); return STAT_NORETRY; @@ -83,7 +83,10 @@ static int xioopen_posixmq( with_intv = true; } } - + if (dirs == XIO_RDWR) { + /* Bidirectional ADDRESS in unidirectional mode? Adapt dirs */ + dirs = (xioflags & XIO_ACCMODE); + } retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); if (! dofork && maxchildren) { Error("option max-children not allowed without option fork"); @@ -100,8 +103,12 @@ static int xioopen_posixmq( Error1("strdup(\"%s\"): out of memory", name); } - retropt_bool(opts, OPT_O_EXCL, &opt_o_excl); - retropt_mode(opts, OPT_PERM, &opt_mode); + retropt_bool(opts, OPT_O_CREAT, &opt_o_creat); + retropt_bool(opts, OPT_O_EXCL, &opt_o_excl); +#ifdef O_CLOEXEC + retropt_bool(opts, OPT_O_CLOEXEC, &opt_o_cloexec); +#endif + retropt_mode(opts, OPT_PERM, &opt_mode); retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush); retropt_long(opts, OPT_POSIXMQ_MAXMSG, &attr.mq_maxmsg) || (setopts = true); @@ -154,8 +161,12 @@ static int xioopen_posixmq( sfd->howtoend = END_CLOSE; sfd->dtype = XIODATA_POSIXMQ | oneshot; - oflag = O_CREAT; - if (opt_o_excl) oflag |= O_EXCL; + oflag = 0; + if (opt_o_creat) oflag |= O_CREAT; + if (opt_o_excl) oflag |= O_EXCL; +#ifdef O_CLOEXEC + if (opt_o_cloexec) oflag |= O_CLOEXEC; /* does not seem to work (Ubuntu-20) */ +#endif switch (dirs) { case XIO_RDWR: oflag |= O_RDWR; break; case XIO_RDONLY: oflag |= O_RDONLY; break; @@ -185,6 +196,7 @@ static int xioopen_posixmq( errno = _errno; return STAT_RETRYLATER; } + /* applyopts_cloexec(mqd, opts); */ /* does not seem to work too (Ubuntu-20) */ sfd->fd = mqd; Debug1("mq_getattr(%d, ...)", mqd); diff --git a/xio-socket.c b/xio-socket.c index c2fb717..89045d1 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -799,7 +799,7 @@ int xiogetpacketinfo(struct single *sfd, int fd) PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, PH_CONNECTED, PH_LATE, OFUNC_OFFSET, - OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC Does not fork, does not retry. Alternate (alt) bind semantics are: with IP sockets: lowport (selects randomly a free port from 640 to 1023) @@ -972,7 +972,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT, PH_CONNECTED, PH_LATE, OFUNC_OFFSET, - OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC returns 0 on success. */ int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, @@ -1072,7 +1072,7 @@ int xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, applies and consumes the following option: PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET - OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC */ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */ union sockaddr_union *us, socklen_t uslen, diff --git a/xio-udp.c b/xio-udp.c index 98c2ced..ff5a9e1 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -349,7 +349,7 @@ int xioopen_udp_sendto( applies and consumes the following option: PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE OFUNC_OFFSET - OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC + OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_O_CLOEXEC */ int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, diff --git a/xio-unix.c b/xio-unix.c index 8468fa2..0febdc6 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -675,7 +675,7 @@ static int xioopen_unix_client( PH_CONNECTED, PH_LATE, ?PH_CONNECT OFUNC_OFFSET, OPT_PROTOCOL_FAMILY, OPT_UNIX_TIGHTSOCKLEN, OPT_UNLINK_CLOSE, OPT_BIND, - OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, + OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_O_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK, */ int _xioopen_unix_client( diff --git a/xioopts.c b/xioopts.c index 0f48c40..b11cdb5 100644 --- a/xioopts.c +++ b/xioopts.c @@ -352,7 +352,7 @@ const struct optname optionnames[] = { #endif /* SO_CKSUMRECV */ /*IF_NAMED ("cleanup", &opt_cleanup)*/ IF_TERMIOS("clocal", &opt_clocal) - IF_ANY ("cloexec", &opt_cloexec) + IF_ANY ("cloexec", &opt_cloexec) IF_ANY ("close", &opt_end_close) IF_OPENSSL("cn", &opt_openssl_commonname) IF_OPENSSL("commonname", &opt_openssl_commonname) @@ -390,8 +390,8 @@ const struct optname optionnames[] = { # endif #endif /* defined(CRDLY) */ IF_TERMIOS("cread", &opt_cread) - IF_OPEN ("creat", &opt_o_create) - IF_OPEN ("create", &opt_o_create) + IF_OPEN ("creat", &opt_o_creat) + IF_OPEN ("create", &opt_o_creat) IF_ANY ("crlf", &opt_crnl) IF_ANY ("crnl", &opt_crnl) IF_TERMIOS("crterase", &opt_echoe) @@ -1135,8 +1135,8 @@ const struct optname optionnames[] = { #ifdef O_BINARY IF_OPEN ("o-binary", &opt_o_binary) #endif - IF_OPEN ("o-creat", &opt_o_create) - IF_OPEN ("o-create", &opt_o_create) + IF_OPEN ("o-creat", &opt_o_creat) + IF_OPEN ("o-create", &opt_o_creat) #ifdef O_DEFER IF_OPEN ("o-defer", &opt_o_defer) #endif @@ -1194,7 +1194,8 @@ const struct optname optionnames[] = { #endif IF_OPEN ("o-trunc", &opt_o_trunc) IF_OPEN ("o-wronly", &opt_o_wronly) - IF_OPEN ("o_create", &opt_o_create) + IF_OPEN ("o_creat", &opt_o_creat) + IF_OPEN ("o_create", &opt_o_creat) #ifdef O_DEFER IF_OPEN ("o_defer", &opt_o_defer) #endif @@ -4230,7 +4231,7 @@ int applyopts_cloexec(int fd, struct opt *opts) { if (!opts) return 0; - retropt_bool(opts, OPT_CLOEXEC, &docloexec); + retropt_bool(opts, OPT_O_CLOEXEC, &docloexec); if (docloexec) { if (Fcntl_l(fd, F_SETFD, FD_CLOEXEC) < 0) { Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno)); diff --git a/xioopts.h b/xioopts.h index 2cdd3ac..5071cc4 100644 --- a/xioopts.h +++ b/xioopts.h @@ -272,7 +272,6 @@ enum e_optcode { OPT_CHROOT_EARLY, /* chroot() before file system access */ /*OPT_CIBAUD,*/ /* termios.c_cflag */ OPT_CLOCAL, /* termios.c_cflag */ - OPT_CLOEXEC, OPT_CONNECT_TIMEOUT, /* socket connect */ OPT_COOL_WRITE, OPT_CR, /* customized */ @@ -555,7 +554,8 @@ enum e_optcode { OPT_O_ASYNC, #endif OPT_O_BINARY, /* Cygwin */ - OPT_O_CREATE, + OPT_O_CLOEXEC, + OPT_O_CREAT, #ifdef O_DEFER OPT_O_DEFER, #endif From c4844692f3e922d4adedbf5f03dd3a91f66fbe38 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Tue, 26 Nov 2024 09:01:42 +0100 Subject: [PATCH 22/51] New alias POSIXMQ for POSIXMQ-BIDIRECTIONAL --- CHANGES | 5 ++++- doc/socat.yo | 40 ++++++++++++++++++++++++++++------------ xioopen.c | 1 + 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index fbedf85..ffaefe0 100644 --- a/CHANGES +++ b/CHANGES @@ -49,13 +49,16 @@ Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. - New option posixmq-flush (mq-flush) for POSIXMQ addresses empty the + New option posixmq-flush (mq-flush) for POSIXMQ addresses empties the queue before starting to transfer data. Test: LINUX_POSIXMQ_FLUSH New options posixmq-maxmsg, posixmq-msgsize. Tests: POSIXMQ_MAXMSG POSIXMQ_MSGSIZE + POSIXMQ is now an alias for POSIXMQ-BIDIRECTIONAL. It can also be used + in unidirectional context. + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index 2e97524..6695d28 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -313,6 +313,7 @@ label(ADDRESS_CREAT)dit(bf(tt(CREATE:<filename>))) if <filename> refers to a socket, this is an error.nl() Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED) nl() Useful options: + link(mode)(OPTION_UMASK), link(mode)(OPTION_MODE), link(user)(OPTION_USER), link(group)(OPTION_GROUP), @@ -583,7 +584,7 @@ label(ADDRESS_OPEN)dit(bf(tt(OPEN:<filename>))) Option groups: link(FD)(GROUP_FD),link(REG)(GROUP_REG),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN) nl() Useful options: link(creat)(OPTION_O_CREAT), - link(excl)(OPTION_EXCL), + link(excl)(OPTION_O_EXCL), link(noatime)(OPTION_O_NOATIME), link(nofollow)(OPTION_NOFOLLOW), link(append)(OPTION_APPEND), @@ -783,7 +784,10 @@ label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>))) link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), link(unlink-early)(OPTION_UNLINK_EARLY), link(unlink-close)(OPTION_UNLINK_CLOSE), - link(o-nonblock)(OPTION_O_NONBLOCK) + link(o-nonblock)(OPTION_O_NONBLOCK), + link(o-creat)(OPTION_O_CREAT), + link(o-excl)(OPTION_O_EXCL), + link(umask)(OPTION_UMASK) label(ADDRESS_POSIXMQ_RECEIVE)dit(bf(tt(POSIXMQ-RECEIVE:/<mqueue>))) dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) @@ -796,7 +800,10 @@ dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) link(fork)(OPTION_FORK), link(max-children)(OPTION_MAX_CHILDREN), link(unlink-early)(OPTION_UNLINK_EARLY), - link(unlink-close)(OPTION_UNLINK_CLOSE) + link(unlink-close)(OPTION_UNLINK_CLOSE), + link(o-creat)(OPTION_O_CREAT), + link(o-excl)(OPTION_O_EXCL), + link(umask)(OPTION_UMASK) label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) Opens the specified POSIX message queue and writes messages (packets).nl() @@ -808,12 +815,18 @@ label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) link(fork)(OPTION_FORK), link(max-children)(OPTION_MAX_CHILDREN), link(unlink-early)(OPTION_UNLINK_EARLY), - link(unlink-close)(OPTION_UNLINK_CLOSE) + link(unlink-close)(OPTION_UNLINK_CLOSE), + link(o-creat)(OPTION_O_CREAT), + link(o-excl)(OPTION_O_EXCL), + link(umask)(OPTION_UMASK) label(ADDRESS_POSIXMQ_BIDIRECTIONAL)dit(bf(tt(POSIXMQ-BIDIRECTIONAL:/mqueue))) - Opens the specified POSIX message queue and writes and reads messages - (packet). This is probably rarely useful but has been implemented for - functional completeness. +dit(bf(tt(POSIXMQ:/mqueue))) + Opens the specified POSIX message queue in read and/or write mode depending + on context, then reads and/or writes messages (packets). + In bidirectional mode this is just another echo service.nl() + See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) and + link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND) for more info. label(ADDRESS_PROXY_CONNECT)dit(bf(tt(PROXY:<proxy>:<hostname>:<port>))) Connects to an HTTP proxy server on port 8080 using TCP/IP version 4 or 6 @@ -1837,8 +1850,10 @@ label(OPTION_MODE)dit(bf(tt(mode=<mode>))) system calls, socat() uses the code(chmod()) system call after opening the filesystem entry or binding to the unixdomain() socket (race condition!). Otherwise, socat() sets the mode of the stream - using code(fchmod()). - These calls might require ownership or root privilege. + using code(fchmod()) which, btw, might not have any effect.nl() + These calls might require ownership or root privilege.nl() + Note: this option can only tighten the permissions implied by processes + umask. See option link(umask)(OPTION_UMASK) to loosen permissions. label(OPTION_PERM_LATE)dit(bf(tt(perm-late=<mode>))) Sets the permissions of the fd to value <mode> [link(mode_t)(TYPE_MODE_T)] using the code(fchmod()) system call after @@ -1991,7 +2006,7 @@ label(OPTION_O_CREAT)dit(bf(tt(creat[=<bool>]))) Creates the file if it does not exist (link(example)(EXAMPLE_OPTION_CREAT)). label(OPTION_DSYNC)dit(bf(tt(dsync[=<bool>]))) Blocks code(write()) calls until metainfo is physically written to media. -label(OPTION_EXCL)dit(bf(tt(excl[=<bool>]))) +label(OPTION_O_EXCL)dit(bf(tt(excl[=<bool>]))) With option creat, if file exists this is an error. label(OPTION_LARGEFILE)dit(bf(tt(largefile[=<bool>]))) On 32 bit systems, allows a file larger than 2^31 bytes. @@ -2106,8 +2121,9 @@ label(OPTION_CHDIR)dit(bf(tt(chdir=<filename>))) dit(bf(tt(cd=<filename>))) label(OPTION_UMASK)dit(bf(tt(umask=<mode>))) Sets the umask of the process to <mode> [link(mode_t)(TYPE_MODE_T)] before opening the address. Useful when file system entries are created or a shell - or program is invoked. Usually the value is specified as octal number.nl() - The processes tt(umask) value is inherited by child processes. + or program is invoked. Usually the value is specified as octal number with + leading '0'.nl() + The processes tt(umask) value is inherited by child processes.nl() Note: umask is an inverted value: creating a file with umask=0026 results in permissions 0640. enddit() diff --git a/xioopen.c b/xioopen.c index 8a29f21..45fe9fa 100644 --- a/xioopen.c +++ b/xioopen.c @@ -177,6 +177,7 @@ const struct addrname addressnames[] = { { "PIPE", &xioaddr_pipe }, #endif #if WITH_POSIXMQ + { "POSIXMQ", &xioaddr_posixmq_bidir }, { "POSIXMQ-BIDIRECTIONAL", &xioaddr_posixmq_bidir }, { "POSIXMQ-READ", &xioaddr_posixmq_read }, { "POSIXMQ-RECEIVE", &xioaddr_posixmq_receive }, From 0f1c5dd85a38450ad736572ae960fe9d74bca6e8 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Sat, 11 Jan 2025 08:09:40 +0100 Subject: [PATCH 23/51] Fixed UDP-LISTEN with bind to IPv4 address on option -0 --- CHANGES | 7 ++++ test.sh | 104 ++++++++++++++++++++++++++++++++++++++++++--------- xio-socket.c | 2 +- xio-udp.c | 23 +++++++++++- xioopts.c | 21 +++++++---- 5 files changed, 131 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index ffaefe0..28ab3e5 100644 --- a/CHANGES +++ b/CHANGES @@ -45,6 +45,13 @@ Corrections: POSIXMQ-* addresses. POSIXMQ addresses are no longer experimental. + With version 1.8.0.0, and with 1.8.0.1 and option -0, the following + command failed: + socat UDP-LISTEN:1234,fork,reuseaddr,bind=127.0.0.1 - + Message: "E xioopen_ipdgram_listen(): unknown address family 0": + Thanks to Brian Woo for reporting this issue. + Test: UDP_LISTEN_BIND4 + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/test.sh b/test.sh index f321bc0..d6ce591 100755 --- a/test.sh +++ b/test.sh @@ -3231,18 +3231,20 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" + $PRINTF "$FAILED (rc2=$rc2)\n" echo "$CMD1 &" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}1" "${te}2" + cat "${te}2" >&2 failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (diff)\n" echo "$CMD1 &" - cat "${te}1" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}2" - cat "$tdiff" + cat "${te}2" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 failed else $PRINTF "$OK\n" @@ -3279,14 +3281,20 @@ echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait if [ $rc2 -ne 0 ]; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" + $PRINTF "$FAILED (rc2=$rc2)\n" echo "$CMD1 &" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}1" "${te}2" + cat "${te}2" >&2 failed elif ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED\n" - cat "$tdiff" + $PRINTF "$FAILED (diff)\n" + echo "$CMD1 &" + cat "${te}1" >&2 + echo "$CMD2" + cat "${te}2" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 failed else $PRINTF "$OK\n" @@ -3540,8 +3548,7 @@ elif ! cond=$(checkconds \ "ignoreeof" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else ti="$td/test$N.file" tf="$td/test$N.stdout" @@ -3593,8 +3600,7 @@ elif ! cond=$(checkconds \ "ignoreeof" \ "" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" + cant else # Let Socat read from an empty file, this would terminate immediately due to # EOF. Wait for more than one second, then append data to the file; when Socat @@ -13046,9 +13052,7 @@ elif ! cond=$(checkconds \ "ipv6-join-group" \ "udp6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" - namesCANT="$namesCANT $NAME" + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19278,6 +19282,7 @@ N=$((N+1)) # Below tests introduced with 1.8.0.3 (or later) + # Test the SOCKS5-CONNECT and SOCKS5-LISTEN addresses with IPv4 for SUFFIX in CONNECT LISTEN; do @@ -19353,6 +19358,71 @@ N=$((N+1)) done # CONNECT LISTEN +# Test UDP-LISTEN with bind to IPv4 address; this failed with Socat version +# 1.8.0.0 +NAME=UDP_LISTEN_BIND4 +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%udp%*|*%udp4%*|*%listen%*|*%$NAME%*) +TEST="$NAME: Test UDP-LISTEN with bind to IPv4 addr" +# Start a listener with UDP-LISTEN and bind to 127.0.0.1; when it starts +# without error and even processes data the test succeeded +if ! eval $NUMCOND; then : +# Remove unneeded checks, adapt lists of the remaining ones +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP4 UDP LISTEN STDIO PIPE" \ + "UDP-LISTEN PIPE STDIO UDP" \ + "bind" \ + "udp4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + newport udp4 + CMD0="$TRACE $SOCAT $opts UDP-LISTEN:$PORT,bind=$LOCALHOST4 PIPE" + CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$LOCALHOST4:$PORT" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + waitudp4port $PORT 1 + echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + fail + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + fail + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + # end of common tests ################################################################################## diff --git a/xio-socket.c b/xio-socket.c index 89045d1..dbbde71 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -262,7 +262,7 @@ static int xioopen_socket_connect( sfd->dtype = XIOREAD_STREAM|XIOWRITE_STREAM; socket_init(0, &us); - if (retropt_bind(opts, 0 /*pf*/, socktype, proto, (struct sockaddr *)&us, &uslen, 3, + if (retropt_bind(opts, pf, socktype, proto, (struct sockaddr *)&us, &uslen, -1, #if _WITH_IP4 || _WITH_IP6 sfd->para.socket.ip.ai_flags #else diff --git a/xio-udp.c b/xio-udp.c index ff5a9e1..d74f670 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -277,8 +277,10 @@ int xioopen_ipdgram_listen( int pf = addrdesc->arg1; int ipproto = addrdesc->arg2; union sockaddr_union us; + int bind_rc; int socktype = SOCK_DGRAM; socklen_t uslen; + int result; if (argc != 2) { xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); @@ -295,12 +297,31 @@ int xioopen_ipdgram_listen( applyopts(sfd, -1, opts, PH_INIT); uslen = socket_init(pf, &us); - retropt_bind(opts, pf, socktype, ipproto, + bind_rc = retropt_bind(opts, pf, socktype, ipproto, (struct sockaddr *)&us, &uslen, 1, xfd->stream.para.socket.ip.ai_flags); + if (bind_rc == STAT_NORETRY) + return STAT_NORETRY; + if (pf == PF_UNSPEC && bind_rc == STAT_OK) + pf = us.soa.sa_family; if (false) { ; +#if WITH_IP4 || WITH_IP6 + } else if (pf == PF_UNSPEC && bind_rc == STAT_NOACTION) { + int ai_flags[2]; + ai_flags[0] = sfd->para.socket.ip.ai_flags[0]; + ai_flags[1] = sfd->para.socket.ip.ai_flags[1]; + if (!(ai_flags[1] & AI_PASSIVE)) + ai_flags[0] |= AI_PASSIVE; + result = + xioresolve(NULL, portname, pf, socktype, ipproto, &us, &uslen, ai_flags); + if (result != STAT_OK) { + Error("error resolving bind option"); + return STAT_NORETRY; + } + pf = us.soa.sa_family; +#endif /* WITH_IP4 || WITH_IP6*/ #if WITH_IP4 } else if (pf == PF_INET) { us.ip4.sin_port = parseport(portname, ipproto); diff --git a/xioopts.c b/xioopts.c index b11cdb5..3781529 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3258,7 +3258,8 @@ int retropt_bind(struct opt *opts, int ipproto, struct sockaddr *sa, socklen_t *salen, - int feats, /* TCP etc: 1..address allowed, + int feats, /* -1..generic addr spec + TCP etc: 1..address allowed, 3..address and port allowed UNIX (or'd): 1..tight 2..abstract @@ -3282,10 +3283,13 @@ int retropt_bind(struct opt *opts, } bindp = bindname; - switch (af) { +#if WITH_IP4 && WITH_IP6 + /* Try to derive address family from string */ + if (af == AF_UNSPEC && bindname[0] == '[') + af = AF_INET6; +#endif /* WITH_IP4 && WITH_IP6 */ - case AF_UNSPEC: - { + if (feats == -1) { size_t p = 0; dalan(bindname, (uint8_t *)sa->sa_data, &p, *salen-sizeof(sa->sa_family), 'i'); *salen = p + sizeof(sa->sa_family); @@ -3297,10 +3301,13 @@ int retropt_bind(struct opt *opts, #if HAVE_STRUCT_SOCKADDR_SALEN sa->sa_len = *salen; #endif - } - break; + return STAT_OK; + } + + switch (af) { #if WITH_IP4 || WITH_IP6 || WITH_VSOCK + case AF_UNSPEC: #if WITH_VSOCK case AF_VSOCK: #endif @@ -3336,7 +3343,7 @@ int retropt_bind(struct opt *opts, ai_flags2[0] = ai_flags[0]; ai_flags2[1] = ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) - ai_flags2[0] |= AI_PASSIVE; + ai_flags2[0] |= AI_PASSIVE; if ((result = xioresolve(hostname[0]!='\0'?hostname:NULL, portp, From 19d488a14fb3cc13987e6d43897b3843faf8a166 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Sat, 11 Jan 2025 14:48:26 +0100 Subject: [PATCH 24/51] Fixes for old Debian --- CHANGES | 2 + config.h.in | 3 + configure.ac | 7 ++ sysincludes.h | 2 +- test.sh | 316 ++++++++++++++++++++++++++++---------------------- xio-unix.c | 2 +- 6 files changed, 194 insertions(+), 138 deletions(-) diff --git a/CHANGES b/CHANGES index 28ab3e5..d43b4f4 100644 --- a/CHANGES +++ b/CHANGES @@ -72,6 +72,8 @@ Building: Porting: Fix for old FreeBSD. + Fixes for old Debian + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/config.h.in b/config.h.in index 682913e..410576b 100644 --- a/config.h.in +++ b/config.h.in @@ -333,6 +333,9 @@ /* Define if you have the <readline/history.h> header file. */ #undef HAVE_READLINE_HISTORY_H +/* Define if you have the <mqueue.h> header file. */ +#undef HAVE_MQUEUE_H + /* Define if you have the readline library. */ #undef HAVE_LIBREADLINE diff --git a/configure.ac b/configure.ac index b0227ec..0b35dd1 100644 --- a/configure.ac +++ b/configure.ac @@ -489,6 +489,13 @@ AC_ARG_ENABLE(posixmq, [ --disable-posixmq disable POSIX MQ support], *) WITH_POSIXMQ=1; AC_MSG_RESULT(yes);; esac], [WITH_POSIXMQ=1; AC_MSG_RESULT(yes)]) +if test "$WITH_POSIXMQ"; then + AC_CHECK_HEADERS(mqueue.h) + if test "x$ac_cv_header_mqueue_h" != xyes; then + AC_MSG_WARN([Header mqueue.h not found, disabling POSIX MQ]) + WITH_POSIXMQ= + fi +fi if test "$WITH_POSIXMQ"; then case "`uname`" in Linux) AC_DEFINE(WITH_POSIXMQ) diff --git a/sysincludes.h b/sysincludes.h index f51e368..25a2309 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -182,7 +182,7 @@ #if WITH_NAMESPACES && HAVE_SCHED_H #include <sched.h> #endif -#if WITH_POSIXMQ +#if WITH_POSIXMQ && HAVE_MQUEUE_H #include <mqueue.h> /* POSIX MQ */ #endif #if WITH_READLINE diff --git a/test.sh b/test.sh index d6ce591..272e1d8 100755 --- a/test.sh +++ b/test.sh @@ -291,89 +291,6 @@ SIZE_T=$($PROCAN |grep "^[^[:space:]]*size_t" |awk '{print($3);}') #AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi #[ "$DEFS" ] && echo "AI_ADDRCONFIG=\"$AI_ADDRCONFIG\"" >&2 -# SSL certificate contents -TESTCERT_CONF=testcert.conf -TESTCERT6_CONF=testcert6.conf -TESTALT_CONF=testalt.conf -# -TESTCERT_COMMONNAME="$LOCALHOST" -TESTCERT_COMMONNAME6="$LOCALHOST6" -TESTCERT_COUNTRYNAME="XY" -TESTCERT_LOCALITYNAME="Lunar Base" -TESTCERT_ORGANIZATIONALUNITNAME="socat" -TESTCERT_ORGANIZATIONNAME="dest-unreach" -TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" -TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" -RSABITS=2048 # Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536 -DSABITS=2048 -cat >$TESTCERT_CONF <<EOF -prompt=no - -[ req ] -default_bits = $RSABITS -distinguished_name=Test - -[ Test ] -countryName=$TESTCERT_COUNTRYNAME -commonName=$TESTCERT_COMMONNAME -O=$TESTCERT_ORGANIZATIONNAME -OU=$TESTCERT_ORGANIZATIONALUNITNAME -L=$TESTCERT_LOCALITYNAME - -EOF - -cat >$TESTCERT6_CONF <<EOF -prompt=no - -[ req ] -default_bits = $RESBITS -distinguished_name=Test - -[ Test ] -countryName=$TESTCERT_COUNTRYNAME -commonName=$TESTCERT_COMMONNAME6 -O=$TESTCERT_ORGANIZATIONNAME -OU=$TESTCERT_ORGANIZATIONALUNITNAME -L=$TESTCERT_LOCALITYNAME - -EOF - -cat >$TESTALT_CONF <<EOF -# config for generation of self signed certificate with IP addresses in -# SubjectAltNames -prompt=no - -[ req ] -default_bits = $RSABITS -distinguished_name = subject -x509_extensions = x509_ext - -[ subject ] -countryName=$TESTCERT_COUNTRYNAME -commonName=servername -O=$TESTCERT_ORGANIZATIONNAME -OU=$TESTCERT_ORGANIZATIONALUNITNAME -L=$TESTCERT_LOCALITYNAME - -[ x509_ext ] -subjectAltName = @alternate_names - -[ alternate_names ] -DNS.1 = localhost -DNS.2 = localhost4 -DNS.3 = localhost6 -IP.1 = 127.0.0.1 -IP.2 = ::1 - -EOF - -# clean up from previous runs - no, only with -C -#rm -f testcli.{crt,key,pem} -#rm -f testsrv.{crt,key,pem} -#rm -f testcli6.{crt,key,pem} -#rm -f testsrv6.{crt,key,pem} -#rm -f testalt.{crt,key,pem} - CAT="cat" OD_C="od -c" @@ -554,7 +471,7 @@ fi # need output like "644" case "$UNAME" in - Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;; + #Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;; FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;; *) fileperms() { local p s=0 c @@ -692,42 +609,6 @@ if [ -x /usr/xpg4/bin/id ]; then PATH="/usr/xpg4/bin:$PATH" fi -OPENSSL_S_CLIENT_4= -OPENSSL_S_CLIENT_DTLS= -init_openssl_s_client () { - if openssl s_client -help 2>&1 |grep -q ' -4 '; then - OPENSSL_S_CLIENT_4="-4" - else - OPENSSL_S_CLIENT_4=" " - fi - if openssl s_client -help 2>&1 | grep -q ' -dtls '; then - OPENSSL_S_CLIENT_DTLS=-dtls - else - OPENSSL_S_CLIENT_DTLS=-dtls1 - fi -} - -OPENSSL_S_SERVER_4= -OPENSSL_S_SERVER_DTLS= -OPENSSL_S_SERVER_NO_IGN_EOF= -init_openssl_s_server () { - if openssl s_server -help 2>&1 |grep -q ' -4 '; then - OPENSSL_S_SERVER_4="-4" - else - OPENSSL_S_SERVER_4=" " - fi - if openssl s_server -help 2>&1 | grep -q ' -dtls '; then - OPENSSL_S_SERVER_DTLS="-dtls" - else - OPENSSL_S_SERVER_DTLS="-dtls1" - fi - if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then - OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof" - else - OPENSSL_S_SERVER_NO_IGN_EOF=" " - fi -} - [ -z "$TESTS" ] && TESTS="consistency functions filan" # use '%' as separation char @@ -968,6 +849,20 @@ testod () { fi # NUMCOND } +# bash before version 3 aborts scripts that contain unquoted '=~' +# Therefore we create a shell script and quotedly fill it with '=~' for newer +# bashes +mkdir -p $td/bin +rm -f $td/bin/re_match +if [ "${BASH_VERSION%%[.]*}" -le 2 ]; then + echo '[ -n "$(echo "$1" |sed -n "/$2/ p")" ]' >$td/bin/re_match +else + echo '[[ "$1" =~ $2 ]]' >$td/bin/re_match +fi +chmod a+x $td/bin/re_match +PATH=$PATH:$td/bin + + # test if the socat executable has these features compiled in # print the first missing address type testfeats () { @@ -985,7 +880,8 @@ testfeats () { fi fi if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then - if [[ "$A" =~ OPENSSL.* ]]; then +# if [[ "$A" =~ OPENSSL.* ]]; then + if re_match "$A" "OPENSSL.*"; then gentestcert testsrv gentestcert testcli fi @@ -1165,9 +1061,9 @@ runsip6 () { AIX) l=$($IFCONFIG lo0 |grep 'inet6 ::1[/%]') ;; HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;; Linux) if [ "$IP" ]; then - l=$($IP address |$GREP_E 'inet6 ::1/128') + l="$($IP address |$GREP_E 'inet6 ::1/128')" else - l=$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?') + l="$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?')" fi ;; NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1\>');; OSF1) l=$($IFCONFIG -a |grep ' inet6 ') ;; @@ -1277,6 +1173,141 @@ routesip6 () { } +# SSL needs runsip6(), thus moved down + +# SSL certificate contents +TESTCERT_CONF=testcert.conf +TESTCERT6_CONF=testcert6.conf +TESTALT_CONF=testalt.conf +# +TESTCERT_COMMONNAME="$LOCALHOST" +TESTCERT_COMMONNAME6="$LOCALHOST6" +TESTCERT_COUNTRYNAME="XY" +TESTCERT_LOCALITYNAME="Lunar Base" +TESTCERT_ORGANIZATIONALUNITNAME="socat" +TESTCERT_ORGANIZATIONNAME="dest-unreach" +TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" +TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME" +RSABITS=2048 # Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536 +DSABITS=2048 +cat >$TESTCERT_CONF <<EOF +prompt=no + +[ req ] +default_bits = $RSABITS +distinguished_name=Test + +[ Test ] +countryName=$TESTCERT_COUNTRYNAME +commonName=$TESTCERT_COMMONNAME +O=$TESTCERT_ORGANIZATIONNAME +OU=$TESTCERT_ORGANIZATIONALUNITNAME +L=$TESTCERT_LOCALITYNAME + +EOF + +cat >$TESTCERT6_CONF <<EOF +prompt=no + +[ req ] +default_bits = $RESBITS +distinguished_name=Test + +[ Test ] +countryName=$TESTCERT_COUNTRYNAME +commonName=$TESTCERT_COMMONNAME6 +O=$TESTCERT_ORGANIZATIONNAME +OU=$TESTCERT_ORGANIZATIONALUNITNAME +L=$TESTCERT_LOCALITYNAME + +EOF + +cat >$TESTALT_CONF <<EOF +# config for generation of self signed certificate with IP addresses in +# SubjectAltNames +prompt=no + +[ req ] +default_bits = $RSABITS +distinguished_name = subject +x509_extensions = x509_ext + +[ subject ] +countryName=$TESTCERT_COUNTRYNAME +commonName=servername +O=$TESTCERT_ORGANIZATIONNAME +OU=$TESTCERT_ORGANIZATIONALUNITNAME +L=$TESTCERT_LOCALITYNAME + +[ x509_ext ] +subjectAltName = @alternate_names + +[ alternate_names ] +DNS.1 = localhost +DNS.2 = localhost4 +DNS.3 = localhost6 +IP.1 = 127.0.0.1 +EOF + +if runsip6; then + cat >>$TESTALT_CONF <<EOF +IP.2 = ::1 +EOF +fi + + +# clean up from previous runs +rm -f testcli.{crt,key,pem} +rm -f testsrv.{crt,key,pem} +rm -f testcli6.{crt,key,pem} +rm -f testsrv6.{crt,key,pem} +rm -f testalt.{crt,key,pem} + +OPENSSL_S_CLIENT_4= +OPENSSL_S_CLIENT_DTLS= +init_openssl_s_client () { + if openssl s_client -help 2>&1 |grep -q ' -4 '; then + OPENSSL_S_CLIENT_4="-4" + else + OPENSSL_S_CLIENT_4=" " + fi + if openssl s_client -help 2>&1 | grep -q ' -dtls1_2 '; then + OPENSSL_S_CLIENT_DTLS="-dtls1_2" + elif openssl s_client -help 2>&1 | grep -q ' -dtls1 '; then + OPENSSL_S_CLIENT_DTLS="-dtls1" + elif openssl s_client -help 2>&1 | grep -q ' -dtls '; then + OPENSSL_S_CLIENT_DTLS="-dtls" + else + OPENSSL_S_CLIENT_DTLS= + fi +} + +OPENSSL_S_SERVER_4= +OPENSSL_S_SERVER_DTLS= +OPENSSL_S_SERVER_NO_IGN_EOF= +init_openssl_s_server () { + if openssl s_server -help 2>&1 |grep -q ' -4 '; then + OPENSSL_S_SERVER_4="-4" + else + OPENSSL_S_SERVER_4=" " + fi + if openssl s_server -help 2>&1 | grep -q ' -dtls1_2 '; then + OPENSSL_S_SERVER_DTLS="-dtls1_2" + elif openssl s_server -help 2>&1 | grep -q ' -dtls1 '; then + OPENSSL_S_SERVER_DTLS="-dtls1" + elif openssl s_server -help 2>&1 | grep -q ' -dtls '; then + OPENSSL_S_SERVER_DTLS="-dtls" + else + OPENSSL_S_SERVER_DTLS= + fi + if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then + OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof" + else + OPENSSL_S_SERVER_NO_IGN_EOF=" " + fi +} + + # Perform a couple of checks to make sure the test has a chance of a useful # result: # platform is supported, features compiled in, addresses and options @@ -11016,7 +11047,7 @@ elif ! testfeats openssl >/dev/null; then elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N cant -elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then +elif ! re_match "$(echo $OPENSSL_VERSION |awk '{print($2);}')" '[01].*'; then # openssl s_client apparently provides renegotiation only up to version 1.2 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N cant @@ -11029,7 +11060,6 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -init_openssl_s_client newport tcp4 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g @@ -11089,7 +11119,7 @@ elif ! testfeats openssl >/dev/null; then elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N cant -elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then +elif ! re_match "$(echo $OPENSSL_VERSION |awk '{print($2);}')" '[01].*'; then # openssl s_client apparently provides renegotiation only up to version 1.2 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N cant @@ -11704,7 +11734,8 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" RLIMIT_NOFILE="$(ulimit -n)" -if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then +#if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then +if ! re_match "$RLIMIT_NOFILE" '^[0-9][0-9]*$'; then $PRINTF "${YELLOW}cannot determine ulimit -n${NORMAL}" else if [ $RLIMIT_NOFILE -gt 1024 ]; then @@ -12606,7 +12637,8 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -if [[ "$method" =~ DTLS* ]]; then +#if [[ "$method" =~ DTLS* ]]; then +if re_match "$method" '^DTLS.*'; then newport udp4 else newport tcp4 @@ -12620,7 +12652,8 @@ if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1) else $CMD0 >/dev/null 2>"${te}0" & pid0=$! -if [[ "$method" =~ DTLS* ]]; then +#if [[ "$method" =~ DTLS* ]]; then +if re_match "$method" '^DTLS.*'; then waitudp4port $PORT 1 else waittcp4port $PORT 1 @@ -13522,6 +13555,9 @@ elif ! runsip4 >/dev/null; then elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N cant +elif init_openssl_s_server; re_match "$method" '^DTLS.*' && [ -z "$OPENSSL_S_SERVER_DTLS" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}DTLS not available in s_server${NORMAL}\n" $N + cant else gentestcert testsrv tf="$td/test$N.stdout" @@ -13576,7 +13612,10 @@ elif ! runsip4 >/dev/null; then elif ! type openssl >/dev/null 2>&1; then $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N cant -elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then +elif init_openssl_s_client; re_match "$method" '^DTLS.*' && [ -z "$OPENSSL_S_CLIENT_DTLS" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}DTLS not available in s_client${NORMAL}\n" $N + cant +elif re_match "$(openssl version |awk '{print($2);}')" '^0\.9\.8[a-ce]'; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N cant @@ -14081,7 +14120,7 @@ kill $pid0 2>/dev/null; wait if [ $rc1 -ne 0 ] && [ "$UNAME" != Linux ]; then $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N cant -elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then +elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! re_match "$UNAME_R" '^[6-9]\..*' && ! re_match "$UNAME_R" '^5\.[6-]\..*' && ! re_match "$UNAME_R" '^5\.[1-9][0-9].*'; then $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N cant elif grep -q "No such device" "${te}1"; then @@ -14263,7 +14302,7 @@ elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N cant -elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then +elif re_match "$(openssl version |awk '{print($2);}')" '^0.9.8[a-ce]'; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N cant @@ -14332,7 +14371,7 @@ elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then elif ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N cant -elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then +elif re_match "$(openssl version |awk '{print($2);}')" '^0.9.8[a-ce]'; then # also on NetBSD-4 with openssl-0.9.8e $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N cant @@ -14453,6 +14492,9 @@ elif ! testfeats openssl >/dev/null; then elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N cant +elif ! runsip6 >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Cannot generate cert with IPv6 address${NORMAL}\n" $N + cant else gentestcert testsrv gentestaltcert testalt @@ -14844,7 +14886,8 @@ rc1=$? LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head -n 1) #echo "LOWPORT=\"$LOWPORT\"" >&2 #type socat >&2 -if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then +#if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then +if re_match "$LOWPORT" '^[0-9][0-9]*' ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi @@ -17542,7 +17585,8 @@ TEST="$NAME: Option unix-bind-tempname" # log "Transport endpoint is not connected" and the TCP service does not fail # with "Address already in use"), the test succeeded. if ! eval $NUMCOND; then :; -elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then +#elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then +elif re_match "$CLI_" 'ABSTRACT-*' && ! feat=$(testfeats abstract-unixsocket); then $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N cant elif ! o=$(testoptions unix-bind-tempname) >/dev/null; then @@ -18376,7 +18420,7 @@ elif ! cond=$(checkconds \ "tcp4" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant -elif [[ $BASH_VERSION =~ ^[1-3]\. ]]; then +elif re_match "$BASH_VERSION" '^[1-3]\.'; then $PRINTF "test $F_n $TEST... ${YELLOW}requires bash 4 or higher${NORMAL}\n" $N cant else diff --git a/xio-unix.c b/xio-unix.c index 0febdc6..67d2b7a 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -788,7 +788,7 @@ _xioopen_unix_client( opts, pf, SOCK_SEQPACKET, protocol, needtemp, E_INFO)) == 0) break; - if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/ + if (errno != EPROTOTYPE && errno != EPROTONOSUPPORT/*AIX*/ && errno != ESOCKTNOSUPPORT/*Debian3*/ #if WITH_ABSTRACT_UNIXSOCKET && !(abstract && errno == ECONNREFUSED) #endif From 24392766510ecb887b579b580b88731e3d7415db Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 24 Jan 2025 17:28:07 +0100 Subject: [PATCH 25/51] Fixes for old Scientific/RHEL --- CHANGES | 2 ++ configure.ac | 29 +++++++++++------------------ test.sh | 4 ++-- xio-ip.c | 12 ++++++++---- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index d43b4f4..66c0c65 100644 --- a/CHANGES +++ b/CHANGES @@ -74,6 +74,8 @@ Porting: Fixes for old Debian + Fixes for old Scientific/RHEL + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/configure.ac b/configure.ac index 0b35dd1..bdc2fd0 100644 --- a/configure.ac +++ b/configure.ac @@ -659,23 +659,16 @@ if test -n "$WITH_OPENSSL"; then AC_CACHE_VAL(sc_cv_have_openssl_ssl_h, [AC_TRY_COMPILE([#include <openssl/ssl.h>],[;], [sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE=""; ], - [sc_cv_have_openssl_ssl_h=no - if test "$OPENSSL_BASE"; then - Ds="$OPENSSL_BASE" - else - Ds="/sw /usr/local /opt/freeware /usr/sfw /usr/local/ssl" - fi - for D in $Ds; do - I="$D/include" - i="$I/openssl/ssl.h" - if test -r "$i"; then - #V_INCL="$V_INCL -I$I" - CPPFLAGS="$CPPFLAGS -I$I" - AC_MSG_NOTICE(found $i) - sc_cv_have_openssl_ssl_h=yes; OPENSSL_BASE="$D" - break; - fi - done]) + [ + # Another attempt to compile with OPENSSL_NO_KRB5 + AC_MSG_NOTICE(trying with -DOPENSSL_NO_KRB5) + CFLAGS_ORIG="$CFLAGS" + CFLAGS="$CFLAGS -DOPENSSL_NO_KRB5" + AC_TRY_COMPILE([#include <openssl/ssl.h>],[;], + [sc_cv_have_openssl_ssl_h=yes], + [sc_cv_have_openssl_ssl_h=no + CFLAGS="$CFLAGS_ORIG"]) + ]) ]) if test "$sc_cv_have_openssl_ssl_h" = "yes"; then AC_DEFINE(HAVE_OPENSSL_SSL_H) @@ -2310,7 +2303,7 @@ int allow_severity,deny_severity;],[hosts_access(0)], AC_TRY_LINK([#include <sys/types.h> #include <tcpd.h> int allow_severity,deny_severity;],[hosts_access(0)], - [sc_cv_have_libwrap='yes'], + [sc_cv_have_libwrap='yes'], [sc_cv_have_libwrap='no']) ] ) diff --git a/test.sh b/test.sh index 272e1d8..6475a7b 100755 --- a/test.sh +++ b/test.sh @@ -851,7 +851,7 @@ testod () { # bash before version 3 aborts scripts that contain unquoted '=~' # Therefore we create a shell script and quotedly fill it with '=~' for newer -# bashes +# bashes [regexp regular expressions] mkdir -p $td/bin rm -f $td/bin/re_match if [ "${BASH_VERSION%%[.]*}" -le 2 ]; then @@ -1886,7 +1886,7 @@ waitudp6port () { fi ;; FreeBSD) l=$(netstat -an |$GREP_E '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; - OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; + OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; Darwin) l=$(netstat -an |$GREP_E '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;; AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; diff --git a/xio-ip.c b/xio-ip.c index 308973b..c6b14df 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -902,16 +902,20 @@ int xiolog_ancillary_ip( '\0', inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); +#if HAVE_PKTINFO_IPI_SPEC_DST Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s", xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), -#if HAVE_PKTINFO_IPI_SPEC_DST inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr), scratch2, sizeof(scratch2)), -#else - "", -#endif inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), scratch3, sizeof(scratch3))); +#else + Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s", + xiogetifname(pktinfo->ipi_ifindex, scratch1, -1), + "", + inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr), + scratch3, sizeof(scratch3))); +#endif } return STAT_OK; #endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */ From 3f4b1715239022d89c792d823026fef51fc9e459 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Sat, 11 Jan 2025 18:48:58 +0100 Subject: [PATCH 26/51] Fixed flock() on AIX, Solaris --- CHANGES | 3 +++ xioopts.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 66c0c65..5fb94ee 100644 --- a/CHANGES +++ b/CHANGES @@ -76,6 +76,9 @@ Porting: Fixes for old Scientific/RHEL + Socat failed to build on platforms without flock() function (AIX, + Solaris) due to a missing guard. + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/xioopts.c b/xioopts.c index 3781529..d36179c 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3837,6 +3837,7 @@ int applyopt_sockopt_generic( #endif /* _WITH_SOCKET */ +#if HAVE_FLOCK int applyopt_flock( int fd, struct opt *opt) @@ -3848,6 +3849,7 @@ int applyopt_flock( } return 0; } +#endif /* defined(HAVE_FLOCK) */ /* Applies an option that needs handling specific to its OPT_* setting. Does not overwrite the option instance with ODESC_DONE or ODESC_ERROR, From 416fe38e3321f79c13ed1168d018a25a1a066d54 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Fri, 17 Jan 2025 14:43:35 +0100 Subject: [PATCH 27/51] Satisfy some deprecation warnings of newer Linux distributions --- CHANGES | 10 +++++++++ test.sh | 59 +++++++++++++-------------------------------------- xio-openssl.c | 16 +++++++------- xio-socket.c | 2 ++ 4 files changed, 35 insertions(+), 52 deletions(-) diff --git a/CHANGES b/CHANGES index 5fb94ee..9fdec1b 100644 --- a/CHANGES +++ b/CHANGES @@ -79,6 +79,14 @@ Porting: Socat failed to build on platforms without flock() function (AIX, Solaris) due to a missing guard. + Newer Linux distributions do not provide libwrap: do not leave unused + variable. + + Newer Linux distributions deprecate usleep, replace it. + + OpenSSL-3 loudly deprecates some functions or macros, replace a first + bunch of them. + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. @@ -92,6 +100,8 @@ Testing: Added a developer test that overwrites malloc'ed memory with non-zeros. + Newer Linux distributions now deprecate usleep; replaced it in test.sh + ####################### V 1.8.0.2: Security: diff --git a/test.sh b/test.sh index 6475a7b..f1500e6 100755 --- a/test.sh +++ b/test.sh @@ -112,6 +112,17 @@ MICROS=${S}${uS} MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0} # changed below again +divide_uint_by_1000000 () { + x=$1 + if [ ${#x} -ge 7 ]; then + echo ${x%??????}.${x: -6}; + else + y=000000$x; + f=${y: -6}; + echo 0.$f; + fi +} + _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}" [ -z "$SECONDs" ] && SECONDs=0 [ "$DEFS" ] && echo "SECONDs=\"$SECONDs\"" >&2 @@ -193,7 +204,7 @@ PATH=$PATH:/sbin # RHEL6:ip case "$0" in */*) PATH="${0%/*}:$PATH" esac -PATH=.:$PATH # for usleep,relsleep +PATH=.:$PATH # for relsleep [ "$DEFS" ] && echo "PATH=\"$PATH\"" >&2 #OPENSSL_RAND="-rand /dev/egd-pool" @@ -308,47 +319,6 @@ tolower () { esac } -if ! which usleep >/dev/null 2>&1; then -cat >usleep <<EOF -#! /usr/bin/env bash -# temporary script from Socat test.sh: -# sleep for a number of µs -u=\$1 -l=\${#u} -i=0 -[ "\$l" -gt 6 ] && i=\${u%??????} -u0=000000\$u -s=\${i}.\${u0: -6:6}; -#echo \$s -sleep \$s -EOF -chmod a+x usleep -fi - -# precision sleep; takes seconds with fractional part; sleep does this on all test platforms -if false; then -psleep () { - local T="$1" - [ "$T" = 0 ] && T=0.000002 - #$SOCAT -T "$T" PIPE PIPE 2>/dev/null - sleep "$T" -} -# time in microseconds to wait in some situations -if ! type usleep >/dev/null 2>&1 || - usleep 0 2>&1 |grep -q deprecated; then - usleep () { - local n="$1" - case "$n" in - *???????) S="${n%??????}"; uS="${n:${#n}-6}" ;; - *) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;; - esac - #$SOCAT -T "$S.$uS" PIPE PIPE 2>/dev/null - sleep "$S.$uS" - } -fi -#USLEEP=usleep -fi - # calculate the time i*MICROS, output as float number for us with -t reltime () { local n="$1" @@ -361,11 +331,12 @@ reltime () { echo "$S.$uS" } -# A sleep with configurable clocking ($vat_t) +# A sleep with configurable clocking ($val_t) # val_t should be at least the time that a Socat invocation, no action, and # termination takes relsleep () { - usleep $(($1*MICROS)) + #sleep $(($1*MICROS/1000000)) + sleep $(divide_uint_by_1000000 $(($1*MICROS)) ) } cat >relsleep <<-'EOF' diff --git a/xio-openssl.c b/xio-openssl.c index 1278bf4..006e378 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -702,7 +702,7 @@ int _xioopen_openssl_listen(struct single *sfd, const char *opt_commonname, SSL_CTX *ctx, int level) { - char error_string[120]; + char error_string[256]; unsigned long err; int errint, ret; @@ -764,7 +764,7 @@ int _xioopen_openssl_listen(struct single *sfd, while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Msg4(level, "SSL_accept(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } /* Msg1(level, "SSL_accept(): %s", ERR_error_string(e, buf));*/ @@ -1976,7 +1976,7 @@ static int xioSSL_set_fd(struct single *sfd, int level) { should not retry for any reason. */ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, bool opt_ver, int level) { - char error_string[120]; + char error_string[256]; int errint, status, ret; unsigned long err; @@ -2012,7 +2012,7 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Msg4(level, "SSL_connect(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } } @@ -2037,7 +2037,7 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, /* on result < 0: errno is set (at least to EIO) */ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) { unsigned long err; - char error_string[120]; + char error_string[256]; int _errno = EIO; /* if we have no better idea about nature of error */ int errint, ret; @@ -2072,7 +2072,7 @@ ssize_t xioread_openssl(struct single *pipe, void *buff, size_t bufsiz) { while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Error4("SSL_read(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } } @@ -2098,7 +2098,7 @@ ssize_t xiopending_openssl(struct single *pipe) { /* on result < 0: errno is set (at least to EIO) */ ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) { unsigned long err; - char error_string[120]; + char error_string[256]; int _errno = EIO; /* if we have no better idea about nature of error */ int errint, ret; @@ -2131,7 +2131,7 @@ ssize_t xiowrite_openssl(struct single *pipe, const void *buff, size_t bufsiz) { while (err = ERR_get_error()) { ERR_error_string_n(err, error_string, sizeof(error_string)); Error4("SSL_write(): %s / %s / %s / %s", error_string, - ERR_lib_error_string(err), ERR_func_error_string(err), + ERR_lib_error_string(err), error_string, ERR_reason_error_string(err)); } } diff --git a/xio-socket.c b/xio-socket.c index dbbde71..c798598 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1679,7 +1679,9 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { int xiocheckpeer(xiosingle_t *sfd, union sockaddr_union *pa, union sockaddr_union *la) { char infobuff[256]; +#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP int result; +#endif #if WITH_IP4 || WITH_IP6 if (sfd->para.socket.dorange) { From ed11b3d2c537c1b471b84fa892882f3ce5cb909d Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Sat, 8 Feb 2025 20:53:35 +0100 Subject: [PATCH 28/51] Protect SSL_connect(); Nanosleep() with decimal output --- CHANGES | 4 ++++ sslcls.c | 1 + sycls.c | 4 ++-- test.sh | 32 ++++++++++++++++++++------------ xio-openssl.c | 15 +++++++++++---- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index 9fdec1b..80512b4 100644 --- a/CHANGES +++ b/CHANGES @@ -52,6 +52,10 @@ Corrections: Thanks to Brian Woo for reporting this issue. Test: UDP_LISTEN_BIND4 + Protected SSL_connect() from SIGCHLD,SIGUSR1. + + Nanosleep() trace output now in decimal form. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/sslcls.c b/sslcls.c index 4e29d71..700b2a3 100644 --- a/sslcls.c +++ b/sslcls.c @@ -368,6 +368,7 @@ int sycSSL_connect(SSL *ssl) { int result; Debug1("SSL_connect(%p)", ssl); result = SSL_connect(ssl); + if (!diag_in_handler) diag_flush(); Debug1("SSL_connect() -> %d", result); return result; } diff --git a/sycls.c b/sycls.c index 2fbed6f..3eb0058 100644 --- a/sycls.c +++ b/sycls.c @@ -1421,11 +1421,11 @@ unsigned int Sleep(unsigned int seconds) { #if HAVE_NANOSLEEP unsigned int Nanosleep(const struct timespec *req, struct timespec *rem) { int retval, _errno; - Debug3("nanosleep({"F_time",%ld},%p)", req->tv_sec, req->tv_nsec, rem); + Debug3("nanosleep({"F_time".%09ld}, %p)", req->tv_sec, req->tv_nsec, rem); retval = nanosleep(req, rem); _errno = errno; if (rem) { - Debug3("nanosleep(,{"F_time",%ld}) -> %d", + Debug3("nanosleep(,{"F_time".%09ld}) -> %d", rem->tv_sec, rem->tv_nsec, retval); } else { Debug1("nanosleep() -> %d", retval); diff --git a/test.sh b/test.sh index f1500e6..05208ec 100755 --- a/test.sh +++ b/test.sh @@ -152,7 +152,7 @@ fi if [ -z "$val_t" ]; then # Determine the time Socat needs for an empty run $SOCAT /dev/null /dev/null # populate caches - MILLIs=$(bash -c 'time $SOCAT /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) + MILLIs=$(bash -c 'time $SOCAT $opts /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done # strip leading '0' to avoid octal [ -z "$MILLIs" ] && MILLIs=1 [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2 @@ -5206,11 +5206,12 @@ newport tcp4; PORT3=$PORT newport tcp4; PORT4=$PORT newport tcp4; PORT5=$PORT # this is the server in the protected network that we want to reach -CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 10) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO" +CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 100) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO" # this is the proxy in the protected network that provides a way out # note: the proxy.sh script starts one or two more socat processes without # setting the program name -CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 10) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh" +export SOCAT_OPTS="$OPTS" # for proxy.sh +CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 100) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh" # this is our proxy connect wrapper in the protected network CMD3="$TRACE $SOCAT $opts -lpwrapper -t$(reltime 30) TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve" # this is our double client in the protected network using SSL @@ -5238,19 +5239,21 @@ eval "$CMD5 2>\"${te}5\" &" pid5=$! waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null # and this is the outside client: -echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" & +{ echo "$da1"; relsleep 100; } |$CMD6 >${tf}_1 2>"${te}6_1" & pid6_1=$! -echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" & +relsleep 20 +{ echo "$da2"; relsleep 100; } |$CMD6 >${tf}_2 2>"${te}6_2" & pid6_2=$! -echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" & +relsleep 20 +{ echo "$da3"; relsleep 100; } |$CMD6 >${tf}_3 2>"${te}6_3" & pid6_3=$! wait $pid6_1 $pid6_2 $pid6_3 kill $pid1 $pid2 $pid3 $pid4 $pid5 $(childpids $pid5) 2>/dev/null # (On BSDs a child of pid5 likes to hang) # -(echo "$da1"; relsleep 2) |diff - "${tf}_1" >"${tdiff}1" -(echo "$da2"; relsleep 2) |diff - "${tf}_2" >"${tdiff}2" -(echo "$da3"; relsleep 2) |diff - "${tf}_3" >"${tdiff}3" +echo "$da1" |diff - "${tf}_1" >"${tdiff}1" +echo "$da2" |diff - "${tf}_2" >"${tdiff}2" +echo "$da3" |diff - "${tf}_3" >"${tdiff}3" if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then # FAILED only when none of the three transfers succeeded if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then @@ -15565,7 +15568,8 @@ elif ! runsip4 >/dev/null; then cant else # We need a hanging connection attempt, guess an address for this -HANGIP=0.0.0.1 +#HANGIP=0.0.0.1 # some OSes refuse to end to this address +HANGIP=8.8.8.9 # 2025 this hangs... te1="$td/test$N.stderr1" tk1="$td/test$N.kill1" te2="$td/test$N.stderr2" @@ -15590,8 +15594,12 @@ CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=$(reltime 1)" $CMD2 >"$te1" 2>$te2 </dev/null & pid2=$! relsleep 8 # in OpenSSL 1.1.1f DTLS takes two timeouts -if kill $pid2 2>"$tk2"; then - $PRINTF "$FAILED\n" +sleep 0.02 # in OpenSSL 3.0.13 SSL_CTX_clear_mode() needs e.g. 0.02s +kill $pid2 2>"$tk2" +prc2=$? +wait +if [ $prc2 -eq 0 ]; then + $PRINTF "$FAILED (not timeout)\n" echo "$CMD2" >&2 cat "$te2" >&2 cat "$tk2" >&2 diff --git a/xio-openssl.c b/xio-openssl.c index 006e378..c333ca3 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -26,7 +26,6 @@ (not only tcp, but also pipes, stdin, files...) for tcp we want to provide support for socks and proxy. read and write functions must use the openssl crypt versions. - but currently only plain tcp4 is implemented. */ /* Linux: "man 3 ssl" */ @@ -1976,12 +1975,20 @@ static int xioSSL_set_fd(struct single *sfd, int level) { should not retry for any reason. */ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, bool opt_ver, int level) { + sigset_t masksigs, oldsigs; char error_string[256]; - int errint, status, ret; + int errint, status, _errno, ret; unsigned long err; + sigemptyset(&masksigs); + sigaddset(&masksigs, SIGCHLD); + sigaddset(&masksigs, SIGUSR1); + Sigprocmask(SIG_BLOCK, &masksigs, &oldsigs); /* connect via SSL by performing handshake */ - if ((ret = sycSSL_connect(sfd->para.openssl.ssl)) <= 0) { + ret = sycSSL_connect(sfd->para.openssl.ssl); + _errno = errno; + Sigprocmask(SIG_SETMASK, &oldsigs, NULL); + if (ret <= 0) { /*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/ errint = SSL_get_error(sfd->para.openssl.ssl, ret); switch (errint) { @@ -2005,7 +2012,7 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname, if (ret == 0) { Msg(level, "SSL_connect(): socket closed by peer"); } else if (ret == -1) { - Msg1(level, "SSL_connect(): %s", strerror(errno)); + Msg1(level, "SSL_connect(): %s", strerror(_errno)); } } else { Msg(level, "I/O error"); /*!*/ From 676888e8ccee306b9d816536738db0afe4cbdb16 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Sat, 8 Feb 2025 20:55:03 +0100 Subject: [PATCH 29/51] UNIX-L with bind option logged INTERNAL error --- CHANGES | 4 ++++ test.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ xio-unix.c | 7 +++++++ 3 files changed, 62 insertions(+) diff --git a/CHANGES b/CHANGES index 80512b4..8bef34f 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,10 @@ Corrections: Nanosleep() trace output now in decimal form. + UNIX-LISTEN with bind option terminated with INTERNAL error, this is + now handled properly. + Test: UNIX_L_BIND + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/test.sh b/test.sh index 05208ec..64e2158 100755 --- a/test.sh +++ b/test.sh @@ -19446,6 +19446,57 @@ esac N=$((N+1)) +# Test for useful error message on UNIX-L with bind option +NAME=UNIX_L_BIND +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%listen%*|*%unix%*|*%bind%*|*%$NAME%*) +TEST="$NAME: Test if UNIX-L with bind does not fail INTERNAL" +# Invoke Socat with a UNIX-LISTEN address with bind option. +# When there is no INTERNAL error the test succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "UNIX LISTEN PIPE" \ + "UNIX-LISTEN PIPE" \ + "bind,accept-timeout" \ + "" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else + ts="$td/test$N.sock" + tb="$td/test$N.bind" + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,accept-timeout=0.001,bind=$tb PIPE" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" + rc0=$? + if [ "$rc0" -eq 0 ]; then + $PRINTF "$CANT (rc0=$rc0)\n" + echo "$CMD0" + cat "${te}0" >&2 + cant + elif grep " E .* INTERNAL " "${te}0" >/dev/null; then + $PRINTF "$FAILED (INTERNAL)\n" + echo "$CMD0" + cat "${te}0" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + ok + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + # end of common tests ################################################################################## diff --git a/xio-unix.c b/xio-unix.c index 67d2b7a..b1bc04f 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -123,6 +123,7 @@ static int xioopen_unix_listen( /* we expect the form: filename */ const char *name; xiosingle_t *sfd = &xxfd->stream; + char *bindstring = NULL; int pf = PF_UNIX; int socktype = SOCK_STREAM; int protocol = 0; @@ -140,6 +141,12 @@ static int xioopen_unix_listen( } name = argv[1]; + if (retropt_string(opts, OPT_BIND, &bindstring) == 0) { + Error2("%s:%s: binds implicitly, bind option not allowed", + addrdesc->defname, argv[1]); + free(bindstring); + } + sfd->para.socket.un.tight = UNIX_TIGHTSOCKLEN; retropt_socket_pf(opts, &pf); if (sfd->howtoend == END_UNSPEC) From 63f67101f4b77e0037630ccbb1f0a248d809bacc Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 10 Feb 2025 12:46:57 +0100 Subject: [PATCH 30/51] Corrections for Ubuntu-24 with newer compilers --- CHANGES | 4 ++++ socat.c | 8 +++----- test.sh | 26 +++++++++++++++++--------- xio-ip.c | 2 +- xio-socks.h | 4 ++-- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index 8bef34f..6c264e4 100644 --- a/CHANGES +++ b/CHANGES @@ -60,6 +60,10 @@ Corrections: now handled properly. Test: UNIX_L_BIND + Removed unused bytes variable from gettimestamp(), corrected #elsif and + socks4 record length. + Thanks to clang-18 and gcc-13. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/socat.c b/socat.c index 5886a00..567cd29 100644 --- a/socat.c +++ b/socat.c @@ -1339,7 +1339,6 @@ int _socat(void) { should be at least MAXTIMESTAMPLEN bytes long. returns 0 on success or -1 if an error occurred */ int gettimestamp(char *timestamp) { - size_t bytes; #if HAVE_CLOCK_GETTIME struct timespec now; #elif HAVE_PROTOTYPE_LIB_gettimeofday @@ -1367,17 +1366,16 @@ int gettimestamp(char *timestamp) { } #endif #if HAVE_STRFTIME - bytes = strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); + strftime(timestamp, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); #if HAVE_CLOCK_GETTIME - bytes += sprintf(timestamp+19, "."F_tv_nsec" ", now.tv_nsec/1000); + sprintf(timestamp+19, "."F_tv_nsec" ", now.tv_nsec/1000); #elif HAVE_PROTOTYPE_LIB_gettimeofday - bytes += sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec); + sprintf(timestamp+19, "."F_tv_usec" ", now.tv_usec); #else strncpy(×tamp[bytes++], " ", 2); #endif #else strcpy(timestamp, ctime(&nowt)); - bytes = strlen(timestamp); #endif return 0; } diff --git a/test.sh b/test.sh index 64e2158..0ed9584 100755 --- a/test.sh +++ b/test.sh @@ -15787,25 +15787,33 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" CMD0="$TRACE $SOCAT $opts STDIO SYSTEM:'tee /dev/stdout 2>/dev/null',pty,cfmakeraw" -#set -vx -printf "test $F_n $TEST... " $N -{ echo "$da"; relsleep 10; } |eval "$CMD0" >"${tf}0" 2>"${te}0" & -pid0=$! -relsleep 2 TTY=$(tty |sed 's|/dev/||') -pkill -USR1 -t $TTY socat || { echo "pkill -t $TTY -USR1 socat"; } +CMD1="pkill -USR1 -t $TTY socat" +printf "test $F_n $TEST... " $N +# On Fedora-41 pkill can be slow (eg.20ms) +{ echo "$da"; relsleep 20; } |eval "$CMD0" >"${tf}0" 2>"${te}0" & +pid0=$! +#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1" relsleep 2 -pkill -t $TTY socat +#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1" +$CMD1 2>"${te}1" +relsleep 2 +#date +'%Y-%m-%dT%H:%M:%S.%N' >>"${te}1" wait +pkill -t $TTY socat >>"${te}1" if [ "$(grep STATISTICS "${te}0" |wc -l)" -eq 2 ]; then $PRINTF "$OK\n" - if [ "$VERBOSE" ]; then echo "$CMD0"; fi + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi ok else - $PRINTF "$FAILED\n" + $PRINTF "$FAILED (no stats)\n" echo "$CMD0 &" cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 failed fi fi # NUMCOND diff --git a/xio-ip.c b/xio-ip.c index c6b14df..a0c12c9 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -592,7 +592,7 @@ int _xiogetaddrinfo(const char *node, const char *service, freehostent(host); } -#elsif 0 /* !HAVE_PROTOTYPE_LIB_getipnodebyname */ +#elif 0 /* !HAVE_PROTOTYPE_LIB_getipnodebyname */ if (node != NULL) { /* this is not a typical IP6 resolver function - but Linux diff --git a/xio-socks.h b/xio-socks.h index b089ec2..f9a1131 100644 --- a/xio-socks.h +++ b/xio-socks.h @@ -10,9 +10,9 @@ struct socks4 { uint8_t action; uint16_t port; uint32_t dest; - char userid[1]; /* just to have access via this struct */ + char userid[0]; /* just to have access via this struct */ } ; -#define SIZEOF_STRUCT_SOCKS4 8 +#define SIZEOF_STRUCT_SOCKS4 ((size_t)&((struct socks4 *)0)->userid) extern const struct optdesc opt_socksport; extern const struct optdesc opt_socksuser; From 7b26406d96f6456b0137cf2272ea06952fd3a342 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 10 Feb 2025 12:48:04 +0100 Subject: [PATCH 31/51] Reworked IPAPP clients --- CHANGES | 18 +- socks4echo.sh | 1 + test.sh | 926 ++++++++++++++++++++++++++++++++++++++++---------- xio-ip.c | 80 ++++- xio-ip.h | 1 + xio-ipapp.c | 427 +++++++++++++++-------- xio-ipapp.h | 8 +- xio-openssl.c | 162 +++++---- xio-proxy.c | 231 ++++++++----- xio-proxy.h | 5 +- xio-socket.c | 40 ++- xio-socks.c | 205 ++++++----- xio-socks.h | 11 +- xio-socks5.c | 184 ++++++---- xioopts.c | 9 +- xioopts.h | 1 + 16 files changed, 1660 insertions(+), 649 deletions(-) diff --git a/CHANGES b/CHANGES index 6c264e4..69f091b 100644 --- a/CHANGES +++ b/CHANGES @@ -60,10 +60,24 @@ Corrections: now handled properly. Test: UNIX_L_BIND - Removed unused bytes variable from gettimestamp(), corrected #elsif and - socks4 record length. + Removed unused bytes variable from gettimestamp(), corrected #elsif, + and socks4 record length. Thanks to clang-18 and gcc-13. + Address TCP-CONNECT, when target address resolves to both IPv4 and + IPv6, now tries to take into account bind address for protocol + selection. + + Reworked and harmonized ipapp client addresses. + Tests: TCP_CONNECT_RETRY SCTP_CONNECT_RETRY DCCP_CONNECT_RETRY + OPENSSL_CONNECT_RETRY SOCKS4_RETRY SOCKS5_CONNECT_RETRY + PROXY_CONNECT_RETRY + + Socks and proxy clients now also support option max-children. + Tests: TCP_CONNECT_MAXCHILDREN SCTP_CONNECT_MAXCHILDREN + DCCP_CONNECT_MAXCHILDREN OPENSSL_CONNECT_MAXCHILDREN + SOCKS4_MAXCHILDREN SOCKS5_CONNECT_MAXCHILDREN PROXY_CONNECT_MAXCHILDREN + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/socks4echo.sh b/socks4echo.sh index a577b20..44c631a 100755 --- a/socks4echo.sh +++ b/socks4echo.sh @@ -9,6 +9,7 @@ # it is required for test.sh # for TCP, use this script as: # socat tcp-l:1080,reuseaddr,crlf system:"socks4echo.sh" +# Then connect with a socks4 request for 32.98.76.54:32109 and user nobody # older bash and ksh do not have -n option to read command; we try dd then #if echo a |read -n 1 null >/dev/null 2>&1; then diff --git a/test.sh b/test.sh index 0ed9584..5829e63 100755 --- a/test.sh +++ b/test.sh @@ -39,7 +39,7 @@ usage() { $ECHO "Usage: $0 <options> [<test-spec> ...]" $ECHO "options:" $ECHO "\t-h \t\tShow this help" - $ECHO "\t-t <sec> \tBase for timeouts in seconds, default: 0.1" + $ECHO "\t-t <sec> \tBase for timeouts in seconds, default is automatically determined" $ECHO "\t-v \t\tBe more verbose, show failed commands" $ECHO "\t-n <num> \tOnly perform test with given number" $ECHO "\t-N <num> \tOnly perform tests starting with given number" @@ -123,6 +123,13 @@ divide_uint_by_1000000 () { fi } + +# output the value in seconds for n * val_t +relsecs () { + local n="$1" + divide_uint_by_1000000 $((n*MICROS)) +} + _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}" [ -z "$SECONDs" ] && SECONDs=0 [ "$DEFS" ] && echo "SECONDs=\"$SECONDs\"" >&2 @@ -145,26 +152,20 @@ if [ -z "$FILAN" ]; then if test -x ./filan; then FILAN="./filan"; elif ! type f if ! sleep 0.1 2>/dev/null; then sleep () { - $SOCAT -T $0 PIPE PIPE + $SOCAT -T "$1" PIPE PIPE } fi if [ -z "$val_t" ]; then - # Determine the time Socat needs for an empty run + # Estimate the time Socat needs for an empty run + sleep 0.5 # immediately after build the first runs are extremely fast $SOCAT /dev/null /dev/null # populate caches - MILLIs=$(bash -c 'time $SOCAT $opts /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) + MILLIs=$(bash -c "time for _ in {1..3}; do $SOCAT -d0 $opts /dev/null /dev/null; done" 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.) while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done # strip leading '0' to avoid octal [ -z "$MILLIs" ] && MILLIs=1 - [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2 - - # On my idle development computer this value flaps from 0.001 to 0.004 - # 0.001 lets many tests fail, so we triple the result - #MILLIs=$((10*MILLIs)) - MILLIs=$((3*MILLIs)) - [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (2)" >&2 + [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\"" >&2 MICROS=${MILLIs}000 - #set -vx case $MICROS in ???????*) val_t=${MICROS%??????}.${MICROS: -6} ;; *) x=000000$MICROS; val_t=0.${x: -6} ;; @@ -212,7 +213,13 @@ PATH=.:$PATH # for relsleep MISCDELAY=1 OPTS="$opt_t $OPTS" -[ "$EXPERIMENTAL" ] && OPTS="--experimental $OPTS" + +if [ "$EXPERIMENTAL" ]; then + if $SOCAT -h |grep -e --experimental >/dev/null; then + OPTS="$OPTS --experimental" + fi +fi + opts="$OPTS" [ "$DEFS" ] && echo "opts=\"$opts\"" >&2 @@ -1009,7 +1016,7 @@ runsip4 () { CYGWIN*) l=$(ipconfig |grep IPv4);; *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac - [ -z "$l" ] && return 1 + [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in Darwin) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;; @@ -1043,7 +1050,7 @@ runsip6 () { CYGWIN*) l=$(ipconfig |grep IPv6);; *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; esac - [ -z "$l" ] && return 1 + [ -z "$l" ] && return 1 # existence of interface might not suffice, check for routeability: case "$UNAME" in Darwin) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;; @@ -1484,6 +1491,24 @@ checktcpport () { return 1 } +waittcpport () { + local port="$1" + local logic="$2" # 0..wait until free; 1..wait until listening (default) + local timeout="$3" + while true; do +#echo "timeout=\"$timeout\"" >&2 + if [ "$logic" = 0 ]; then + if checktcpport $1; then break; fi + else + if ! checktcpport $1; then break; fi + fi + if [ $timeout -le 0 ]; then return 1; fi + sleep 1 + let --timeout; + done + return 0; +} + checktcp4port () { checktcpport $1 } @@ -2289,7 +2314,7 @@ esac N=$((N+1)) -# test: send EOF to exec'ed sub process, let it finish its operation, and +# test: send EOF to exec'ed sub process, let it finish its operation, and # check if the sub process returns its data before terminating. NAME=EXECSOCKETPAIRFLUSH # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data @@ -2455,8 +2480,9 @@ esac N=$((N+1)) newport() { - _PORT=$((_PORT+1)) + _PORT=$((_PORT+1)) while eval wait${1}port $_PORT 1 0 2>/dev/null; do _PORT=$((_PORT+1)); done + #while ! eval check${1}port $_PORT 2>/dev/null; do sleep 1; _PORT=$((_PORT+1)); done #echo "PORT=$_PORT" >&2 PORT=$_PORT } @@ -3565,7 +3591,7 @@ printf "test $F_n $TEST... " $N touch "$ti" $CMD >"$tf" 2>"$te" & bg=$! -# Up to 1.8.0.1 this sleep was 0.1 and thus the test said OK despite the bug +# Up to 1.8.0.1 this sleep was 0.1 and thus the test said OK despite the bug sleep 1.1 echo "$da" >>"$ti" sleep 1 @@ -4028,8 +4054,6 @@ esac N=$((N+1)) -newport $RUNS # in case it has not yet been invoked - while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi @@ -4514,35 +4538,47 @@ elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N cant else -ts="$td/test$N.sh" -tf="$td/test$N.stdout" -te="$td/test$N.stderr" -tdiff="$td/test$N.diff" -da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -newport tcp4 # provide free port number in $PORT -#CMD2="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" -CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" -CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" -printf "test $F_n $TEST... " $N -eval "$CMD2 2>\"${te}2\" &" -pid=$! # background process id -waittcp4port $PORT 1 -echo "$da" |$CMD >"$tf" 2>"${te}1" -if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" - echo "$CMD2 &" - echo "$CMD" - cat "${te}1" - cat "${te}2" - cat "$tdiff" - failed -else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - ok -fi -kill $pid 2>/dev/null -wait + ts="$td/test$N.sh" + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp4 # provide free port number in $PORT + #CMD0="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" + CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" + CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid=$! # background process id + waittcp4port $PORT 1 + echo "$da" |$CMD1 >"$tf" 2>"${te}1" + rc1=$? + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + fail + elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + fail + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi + kill $pid 2>/dev/null + wait fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -4559,35 +4595,47 @@ elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N cant else -ts="$td/test$N.sh" -tf="$td/test$N.stdout" -te="$td/test$N.stderr" -tdiff="$td/test$N.diff" -da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" -newport tcp6 # provide free port number in $PORT -#CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" -CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" -CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT" -printf "test $F_n $TEST... " $N -eval "$CMD2 2>\"${te}2\" &" -pid=$! # background process id -waittcp6port $PORT 1 -echo "$da" |$CMD >"$tf" 2>"${te}1" -if ! echo "$da" |diff - "$tf" >"$tdiff"; then - $PRINTF "$FAILED: $TRACE $SOCAT:\n" - echo "$CMD2 &" - echo "$CMD" - cat "${te}1" - cat "${te}2" - cat "$tdiff" - failed -else - $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi - ok -fi -kill $pid 2>/dev/null -wait + ts="$td/test$N.sh" + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" + newport tcp6 # provide free port number in $PORT + #CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\"" + CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\"" + CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT" + printf "test $F_n $TEST... " $N + eval "$CMD0 2>\"${te}0\" &" + pid=$! # background process id + waittcp6port $PORT 1 + echo "$da" |$CMD1 >"$tf" 2>"${te}1" + rc1=$? + if [ "$rc1" -ne 0 ]; then + $PRINTF "$FAILED (rc1=$rc1)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif ! echo "$da" |diff - "$tf" >"$tdiff"; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff: " >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + fi + kill $pid 2>/dev/null + wait fi ;; # NUMCOND, feats esac N=$((N+1)) @@ -5033,7 +5081,7 @@ N=$((N+1)) NAME=GENDERCHANGER case "$TESTS" in -*%$N%*|*%functions%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: TCP4 \"gender changer\"" if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -5096,7 +5144,7 @@ N=$((N+1)) NAME=OUTBOUNDIN case "$TESTS" in -*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl proxy); then @@ -5185,7 +5233,7 @@ N=$((N+1)) #! NAME=INTRANETRIPPER case "$TESTS" in -*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: gender changer via SSL through HTTP proxy, daemons" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats openssl proxy); then @@ -5460,7 +5508,7 @@ testserversec () { NAME=TCP4RANGEBITS case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then @@ -5476,7 +5524,7 @@ N=$((N+1)) NAME=TCP4RANGEMASK case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then @@ -5493,7 +5541,7 @@ N=$((N+1)) # like TCP4RANGEMASK, but the "bad" address is within the same class A network NAME=TCP4RANGEMASKHAIRY case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" if ! eval $NUMCOND; then :; else newport tcp4 # provide free port number in $PORT @@ -5505,7 +5553,7 @@ N=$((N+1)) NAME=TCP4SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with SOURCEPORT option" if ! eval $NUMCOND; then :; else newport tcp4 # provide free port number in $PORT @@ -5516,7 +5564,7 @@ N=$((N+1)) NAME=TCP4LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with LOWPORT option" if ! eval $NUMCOND; then :; else newport tcp4 # provide free port number in $PORT @@ -5527,7 +5575,7 @@ N=$((N+1)) NAME=TCP4WRAPPERS_ADDR case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then @@ -5546,7 +5594,7 @@ N=$((N+1)) NAME=TCP4WRAPPERS_NAME case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then @@ -5566,7 +5614,7 @@ N=$((N+1)) NAME=TCP6RANGE case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with RANGE option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then @@ -5581,7 +5629,7 @@ N=$((N+1)) NAME=TCP6SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%**|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then @@ -5596,7 +5644,7 @@ N=$((N+1)) NAME=TCP6LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then @@ -5611,7 +5659,7 @@ N=$((N+1)) NAME=TCP6TCPWRAP case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of TCP6-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats tcp ip6 libwrap && runstcp6); then @@ -5750,7 +5798,7 @@ N=$((N+1)) NAME=OPENSSLTCP4_RANGE case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5766,7 +5814,7 @@ N=$((N+1)) NAME=OPENSSLTCP4_SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5782,7 +5830,7 @@ N=$((N+1)) NAME=OPENSSLTCP4_LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5798,7 +5846,7 @@ N=$((N+1)) NAME=OPENSSLTCP4_TCPWRAP case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip4 tcp libwrap openssl); then @@ -5818,7 +5866,7 @@ N=$((N+1)) NAME=OPENSSLCERTSERVER case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L with client certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5835,7 +5883,7 @@ N=$((N+1)) NAME=OPENSSLCERTCLIENT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL with server certificate" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5853,7 +5901,7 @@ N=$((N+1)) NAME=OPENSSLTCP6_RANGE case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5872,7 +5920,7 @@ N=$((N+1)) NAME=OPENSSLTCP6_SOURCEPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5891,7 +5939,7 @@ N=$((N+1)) NAME=OPENSSLTCP6_LOWPORT case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -5910,7 +5958,7 @@ N=$((N+1)) NAME=OPENSSLTCP6_TCPWRAP case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats ip6 tcp libwrap openssl && runsip6); then @@ -5932,7 +5980,7 @@ N=$((N+1)) # test security with the openssl-commonname option on client side NAME=OPENSSL_CN_CLIENT_SECURITY case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of client openssl-commonname option" # connect using non matching server name/address with commonname # options, this should succeed. Then without this option, should fail @@ -5979,7 +6027,7 @@ N=$((N+1)) NAME=OPENSSL_FIPS_SECURITY case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: OpenSSL restrictions by FIPS" if ! eval $NUMCOND; then :; elif ! testfeats openssl >/dev/null; then @@ -6556,7 +6604,7 @@ case "$MAJADDR" in tca="$ts" waitproto="file" waitfor="$ts" ;; -esac +esac case "$MINADDR" in "PORT") newport $protov # provide free port number in $PORT @@ -6564,7 +6612,7 @@ case "$MINADDR" in tca="$MAJADDR:$PORT" waitproto="${protov}port" waitfor="$PORT" ;; -esac +esac #set -xv echo -e "$da1a\n$da2\n$da1b" >"$tref" # establish a listening and forking listen socket in background @@ -10662,7 +10710,7 @@ N=$((N+1)) NAME=SOCKETRANGEMASK case "$TESTS" in -*%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) +*%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%retry%*|*%$NAME%*) TEST="$NAME: security of generic socket-listen with RANGE option" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then @@ -11483,10 +11531,10 @@ PROTO=$KEYW proto="$(tolower "$PROTO")" feat="$(tolower "$FEAT")" # test the max-children option on really connection oriented sockets -NAME=${KEYW}MAXCHILDREN +NAME=${KEYW}_L_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$feat%*|*%$proto%*|*%socket%*|*%listen%*|*%$NAME%*) -TEST="$NAME: max-children option" +TEST="$NAME: max-children option with $PROTO-LISTEN" # start a listen process with max-children=1; connect with a client, let it # sleep some time before sending data; connect with second client that sends # data immediately. If max-children is working correctly the first data should @@ -11566,10 +11614,10 @@ RUNS=$(tolower $KEYW) PROTO=$KEYW proto="$(tolower "$PROTO")" # test the max-children option on pseudo connected sockets -NAME=${KEYW}MAXCHILDREN +NAME=${KEYW}_L_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*) -TEST="$NAME: max-children option" +TEST="$NAME: max-children option with $PROTO-LISTEN" # start a listen process with max-children=1; connect with a client, let it # send data and then sleep; connect with second client that wants to send # data immediately, but keep first client active until server terminates. @@ -11931,7 +11979,7 @@ N=$((N+1)) # had a bug that converted a bit mask of 0 internally to 0xffffffff NAME=TCP4RANGE_0BITS case "$TESTS" in -*%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: correct evaluation of range mask 0" if ! eval $NUMCOND; then :; elif [ -z "$SECONDADDR" ]; then @@ -14617,7 +14665,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Socats access to different types of file system entries using various kinds @@ -14752,7 +14799,7 @@ orphaned gopen # Up to 1.7.4.3 this terminated immediately on connection refused NAME=TCP_TIMEOUT_RETRY case "$TESTS" in -*%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*) +*%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%retry%*|*%$NAME%*) TEST="$NAME: TCP with options connect-timeout and retry" # In background run a delayed echo server # In foreground start TCP with connect-timeout and retry. On first attempt the @@ -14831,7 +14878,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Up to 1.7.4.3 there was a bug with the lowport option: @@ -14880,7 +14926,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Test if trailing garbage in integer type options gives error @@ -15160,7 +15205,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15215,7 +15259,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15258,7 +15301,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) # Test if Socat makes the sniffing file descriptos (-r, -R) CLOEXEC to not leak @@ -15301,7 +15343,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15544,7 +15585,6 @@ kill $pid 2>/dev/null wait fi ;; # NUMCOND, feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -15857,7 +15897,7 @@ waitunixport $ts 1 rc1=$? kill $pid0 2>/dev/null; wait relsleep 1 # child process might need more time -if grep -q " W connect" ${te}0; then +if ! grep -q " E " ${te}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi @@ -15960,7 +16000,6 @@ else fi fi ;; # NUMCOND, feats esac -PORT=$((PORT+1)) N=$((N+1)) @@ -16614,8 +16653,8 @@ else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -ts1p=$PORT; PORT=$((PORT+1)) -ts2p=$PORT; PORT=$((PORT+1)) +newport udp; ts1p=$PORT +newport udp; ts2p=$PORT da="test$N $(date) $RANDOM" CMD1="$TRACE $SOCAT $opts -T 0.2 UDP4-DATAGRAM:$LOCALHOST:$ts2p,bind=$LOCALHOST:$ts1p SOCKETPAIR,socktype=$SOCK_DGRAM" CMD2="$TRACE $SOCAT $opts -b 24 -t 0.2 -T 0.3 - UDP4-DATAGRAM:$LOCALHOST:$ts1p,bind=$LOCALHOST:$ts2p" @@ -16655,7 +16694,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -16856,13 +16894,14 @@ case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) TEST="$NAME: POSIX-MQ RECV with fork,max-children" # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its -# output via sub processes that sleeps after writing. +# output via sub processes that sleep after writing. # Run a client/sender that sends message 1; -# run a client/sender that sends message 3, has to wait; -# write message 2 directly into output file; +# run a client/sender that sends message 2; +# run a client/sender that sends message 4, has to wait; +# write message 3 directly into output file; # Check if the messages are stored in order of their numbers if ! eval $NUMCOND; then :; -elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SYSTEM" "POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM" "fork max-children unlink-early unlink-close"); then +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SHELL" "POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SHELL" "fork max-children unlink-early unlink-close"); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else @@ -16871,7 +16910,7 @@ te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" tq=/test$N -CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\"" +CMD0="$TRACE $SOCAT $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=2 SHELL:\"cat\ >>${tf}0;\ relsleep\ 5\"" CMD1a="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq" CMD1b="$TRACE $SOCAT $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close" printf "test $F_n $TEST... " $N @@ -16880,23 +16919,28 @@ pid0=$! relsleep 1 echo "$da 1" |$CMD1a >/dev/null 2>"${te}1a" rc1a=$? -echo "$da 3" |$CMD1b >/dev/null 2>"${te}1b" +echo "$da 2" |$CMD1a >/dev/null 2>"${te}1b" rc1b=$? -sleep 0.5 -echo "$da 2" >>"${tf}0" -sleep 1 # as in SYSTEM +echo "$da 4" |$CMD1b >/dev/null 2>"${te}1c" +rc1c=$? +#sleep 0.5 +relsleep 2 +echo "$da 3" >>"${tf}0" +relsleep 5 # as in SHELL kill $(childpids $pid0) $pid0 2>/dev/null wait 2>/dev/null if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then - $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b)\n" + $PRINTF "$FAILED (rc1a=$rc1a, rc1b=$rc1b, rc1c=$rc1c)\n" echo "$CMD0" cat "${te}0" >&2 echo "$CMD1a" cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 + echo "$CMD1c" + cat "${te}1c" >&2 failed -elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then +elif $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}0 >${tdiff}0; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0"; fi if [ "$DEBUG" ]; then cat "${te}0" >&2; fi @@ -16904,6 +16948,8 @@ elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi if [ "$VERBOSE" ]; then echo "$CMD1b"; fi if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1c"; fi + if [ "$DEBUG" ]; then cat "${te}1c" >&2; fi ok else $PRINTF "$FAILED (diff)\n" @@ -16913,7 +16959,9 @@ else cat "${te}1a" >&2 echo "$CMD1b" cat "${te}1b" >&2 - echo "difference:" >&2 + echo "$CMD1c" + cat "${te}1c" >&2 + echo "// diff:" >&2 cat ${tdiff}0 >&2 failed fi @@ -16927,44 +16975,49 @@ NAME=POSIXMQ_SEND_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) TEST="$NAME: POSIX-MQ SEND with fork,max-children" -# Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from it +# Start a POSIX-MQ receiver that creates the MQ and transfers data from it # to an output file -# Run a POSIX-MQ sender that two times forks and invokes a data generator -# for messages 1 and 3 in a shell process with some trailing sleep. -# Afterwards write message 2 directly into output file; message 3 should be +# Run a POSIX-MQ sender that forks two child shell processes that get data from +# a file queue with messages 1, 2, and 4, transfer it to the receiver and sleep +# afterwards to delay the third child by option max-children=2 +# Afterwards write message 3 directly into output file; message 4 should be # delayed due to max-children option # Check if the messages are stored in order of their numbers. -# The data generator is implemented as a receiver from an MQ with "1", "3" +# The data generator is implemented with just a directory containing files +# "1", "2", "4" if ! eval $NUMCOND; then :; -elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SYSTEM" "POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM" "fork max-children mq-prio unlink-early unlink-close"); then +elif ! cond=$(checkconds "" "" "" "POSIXMQ STDIO SHELL" "POSIXMQ-SEND POSIXMQ-READ STDIO SHELL" "fork max-children mq-prio unlink-early unlink-close"); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" +tq="/test$N" +tQ="$td/test$N.q" da="test$N $(date) $RANDOM" -tq=/test$N -CMD1="$TRACE $SOCAT $opts -u POSIXMQ-READ:$tq,unlink-early STDIO" -CMD2="$TRACE $SOCAT $opts -U POSIXMQ-SEND:$tq,fork,max-children=1,interval=0.1 SYSTEM:\"./socat\ -u\ POSIXMQ-RECV\:$tq-data\ -;\ sleep\ 1\"" +CMD1="$TRACE $SOCAT $opts -lp reader -u POSIXMQ-READ:$tq,unlink-early STDIO" +#CMD2="$TRACE $SOCAT $opts -lp worker -U POSIXMQ-SEND:$tq,fork,max-children=2,interval=$(relsecs 2) SHELL:'f=\$(ls -1 $tQ|head -n 1);\ test\ -f\ "$tQ/\$f"\ ||\ exit\ 1;\ {\ cat\ $tQ/\$f;\ rm\ $tQ/\$f;\ };\ sleep\ $(relsecs 5)'" +CMD2="$TRACE $SOCAT $opts -lp worker -U POSIXMQ-SEND:$tq,fork,max-children=2,interval=$(relsecs 2) SHELL:'shopt\ -s\ nullglob;\ f=\$(ls -1 $tQ|head -n 1);\ test\ -z\ "\$f"\ &&\ exit;\ {\ cat\ $tQ/\$f;\ rm\ $tQ/\$f;\ };\ sleep\ $(relsecs 5)'" printf "test $F_n $TEST... " $N # create data for the generator -echo "$da 1" |$SOCAT -u - POSIXMQ-SEND:$tq-data,unlink-early 2>"${te}0a" -echo "$da 3" |$SOCAT -u - POSIXMQ-SEND:$tq-data 2>"${te}0b" +mkdir -p $tQ +echo "$da 1" >$tQ/01 +echo "$da 2" >$tQ/02 +echo "$da 4" >$tQ/04 eval $CMD1 2>"${te}1" >>"${tf}1" & pid1=$! relsleep 1 eval $CMD2 2>"${te}2" & pid2=$! -sleep 0.5 -echo "$da 2" >>"${tf}1" -sleep 1 # as in SYSTEM -kill $pid1 $(childpids $pid1) $pid2 $(childpids $pid2) 2>/dev/null +relsleep 4 +echo "$da 3" >>"${tf}1" +relsleep 10 +kill $(childpids -r $pid1) $pid1 $(childpids -r $pid2) $pid2 2>/dev/null wait 2>/dev/null -# remove the queues -$SOCAT -u /dev/null POSIXMQ-SEND:$tq-data,unlink-close 2>"${te}3a" +# remove the MQ $SOCAT -u /dev/null POSIXMQ-SEND:$tq,unlink-close 2>"${te}3b" -if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}1 >${tdiff}1; then +if $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}1 >${tdiff}1; then $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD1"; fi if [ "$DEBUG" ]; then cat "${te}1" >&2; fi @@ -16977,7 +17030,7 @@ else cat "${te}1" >&2 echo "$CMD2" cat "${te}2" >&2 - echo "difference:" >&2 + echo "// diff:" >&2 cat ${tdiff}1 >&2 failed fi @@ -16985,6 +17038,7 @@ fi # NUMCOND ;; esac N=$((N+1)) +date "+%Y/%m/%d %H:%M:%S.%N" # Test the sigint option with SHELL address @@ -17184,7 +17238,7 @@ if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then if [ "$DEBUG" ]; then cat "${te}0" >&2; fi ok else - $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?${NORMAL}\n" + $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?)${NORMAL}\n" echo "$CMD0 &" cat "${te}0" >&2 cant @@ -17664,7 +17718,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) done <<<" @@ -17740,7 +17793,6 @@ fi fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) @@ -17769,7 +17821,7 @@ tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -newport tcp4 # or whatever proto, or drop this line +newport tcp4 # Find the default pipe size PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')" PIPESZ2=$((2*PIPESZ)) @@ -17968,7 +18020,6 @@ else fi fi ;; # NUMCOND esac -PORT=$((PORT+1)) N=$((N+1)) @@ -18029,7 +18080,6 @@ else fi fi ;; # NUMCOND esac -PORT=$((PORT+1)) N=$((N+1)) @@ -18090,7 +18140,6 @@ else fi fi ;; # NUMCOND esac -PORT=$((PORT+1)) N=$((N+1)) @@ -18201,10 +18250,10 @@ RUNS=$(tolower $KEYW) PROTO=$KEYW proto="$(tolower "$PROTO")" # test the max-children option on pseudo connected sockets -NAME=${KEYW}MAXCHILDREN +NAME=${KEYW}_L_MAXCHILDREN case "$TESTS" in *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*) -TEST="$NAME: max-children option" +TEST="$NAME: max-children option with $PROTO-LISTEN" # start a listen process with max-children=1; connect with a client, let it # send data and then sleep; connect with second client that wants to send # data immediately, but keep first client active until server terminates. @@ -19005,7 +19054,6 @@ fi # NUMCOND esac N=$((N+1)) - BIN_TIMEOUT= if type timeout >/dev/null 2>&1; then BIN_TIMEOUT=timeout @@ -19164,7 +19212,6 @@ else fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) done <<<" UDP-SENDTO udp4 PORT @@ -19236,7 +19283,6 @@ else fi # NUMCOND ;; esac -PORT=$((PORT+1)) N=$((N+1)) done <<<" TCP-CONNECT tcp4 PORT @@ -19249,7 +19295,9 @@ DCCP-CONNECT dccp4 PORT #ROXY::127.0.0.1 tcp4 PORT " + # Above tests introduced before or with 1.8.0.1 +#============================================================================== # Below test introduced with 1.8.0.2 # Test the readline.sh file overwrite vulnerability @@ -19310,10 +19358,9 @@ N=$((N+1)) # Above test introduced with 1.8.0.2 +#============================================================================== # Below tests introduced with 1.8.0.3 (or later) - - # Test the SOCKS5-CONNECT and SOCKS5-LISTEN addresses with IPv4 for SUFFIX in CONNECT LISTEN; do @@ -19430,7 +19477,7 @@ else cat "${te}0" >&2 echo "$CMD1" cat "${te}1" >&2 - fail + failed elif ! echo "$da" |diff - "${tf}1" >$tdiff; then $PRINTF "$FAILED (diff)\n" echo "$CMD0 &" @@ -19439,7 +19486,7 @@ else cat "${te}1" >&2 echo "// diff:" >&2 cat "$tdiff" >&2 - fail + failed else $PRINTF "$OK\n" if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi @@ -19505,6 +19552,535 @@ esac N=$((N+1)) +while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE; do +if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi + +if [ "X$CSUFF" != "X-" ]; then + CADDR=$ADDR-$CSUFF +else + CADDR=$ADDR +fi +CNAME=$(echo $CADDR |tr - _) +PROTO=$(toupper $proto) +FEAT=$ADDR +runs=$proto +case "$CPARMS" in + PORT) newport $proto; CPARMS=$PORT ;; + *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;; +esac +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 +case "X$COPTS" in + X-) COPTS= ;; + *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;; +esac +case "X$SOPTS" in + X-) SOPTS= ;; +esac + +# Test if bind on *-CONNECT selects the matching IP version +NAME=${CNAME}_BIND_6_4 +case "$TESTS" in +*%$N%*|*%functions%*|*%$proto%*|*%${proto}4%*|*%${proto}6%*|*%ip4%*|*%ip6%*|*%listen%*|*%bind%*|*%socket%*|*%$NAME%*) +TEST="$NAME: $ADDR bind chooses matching IPv" +# Have an IPv4 listener +# Host name localhost-4-6.dest-unreach.net resolves to both 127.0.0.1 and [::1], +# consequently; with option -6 we have Socat try IPv6 first, and on failure try +# IPv4 +# Start Socat TCP-CONNECT with -6 and binding and connecting to this host name; +# Up to version 1.8.0.0 Socat only tries IPv6 and fails +# With version 1.8.0.1 Socat first connects using IPv6, and due to ECONNREFUSED +# tries to connect using IPv4 but still binds to IPv6 which fails with +# EAFNOSUPPORT "Address family not supported by protocol"; +# With 1.8.0.3 the connection attempt with IPv4 correctly binds to IPv4 and +# succeeds +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "$FEAT IP4 IP6 TCP LISTEN STDIO PIPE" \ + "$CADDR $SADDR STDIO PIPE" \ + "bind pf" \ + "${runs}4 ${runs}6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts $SADDR:$PORT,$SOPTS,pf=2 $PIPE" + CMD1="$TRACE $SOCAT $opts -6 STDIO $CADDR:localhost-4-6.dest-unreach.net:$CPARMS,bind=localhost-4-6.dest-unreach.net,$COPTS" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + wait${proto}4port $PORT 1 + { echo "$da"; relsleep 10; } |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family not supported by protocol" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +done <<<" +TCP tcp CONNECT PORT - TCP-L - PIPE +SCTP sctp CONNECT PORT - SCTP-L - PIPE +DCCP dccp CONNECT PORT - DCCP-L - PIPE +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE +SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh +SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh +PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh +" + + +# Test if TCP-CONNECT with host name resolving to IPv6 first and IPv4 second +# (due to option -6) chooses IPv4 when bind option is specific. +# This works only since version 1.8.0.3 +NAME=TCP_BIND_4 +case "$TESTS" in +*%$N%*|*%functions%*|*%internet%*|*%tcp4%*|*%tcp6%*|*%ip4%*|*%ip6%*|*%listen%*|*%socket%*|*%$NAME%*) +TEST="$NAME: TCP-CONNECT chooses IPv4 from bind" +# Start a TCP4 listener with echo function +# Start Socat TCP-CONNECT with host name resolving to IPv6 first and IPv4 +# second, and bind to IPv4 explicitly. +# When connection and data transfer work the test succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP4 IP6 TCP LISTEN STDIO PIPE" \ + "TCP-CONNECT TCP4-LISTEN STDIO PIPE" \ + "" \ + "tcp4 tcp6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + newport tcp4 + CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT PIPE" + CMD1="$TRACE $SOCAT $opts -6 - TCP-CONNECT:localhost-4-6.dest-unreach.net:$PORT,bind=127.0.0.1" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + waittcp4port $PORT 1 + echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family for hostname not supported" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +# Test if TCP-CONNECT with host name resolving to IPv4 first and IPv6 second +# (due to option -4) chooses IPv6 when bind option is specific. +# This works only since version 1.8.0.3 +NAME=TCP_BIND_6 +case "$TESTS" in +*%$N%*|*%functions%*|*%internet%*|*%tcp4%*|*%tcp6%*|*%ip4%*|*%ip6%*|*%listen%*|*%socket%*|*%$NAME%*) +TEST="$NAME: TCP-CONNECT chooses IPv6 from bind" +# Start a TCP6 listener with echo function +# Start Socat TCP-CONNECT with host name resolving to IPv4 first and IPv6 +# second, and bind to IPv6 explicitly. +# When connection and data transfer work the test succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "IP4 IP6 TCP LISTEN STDIO PIPE" \ + "TCP-CONNECT TCP4-LISTEN STDIO PIPE" \ + "" \ + "tcp4 tcp6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-4[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +else + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + newport tcp4 + CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT PIPE" + CMD1="$TRACE $SOCAT $opt -4 - TCP-CONNECT:localhost-4-6.dest-unreach.net:$PORT,bind=[::1]" + printf "test $F_n $TEST... " $N + $CMD0 >/dev/null 2>"${te}0" & + pid0=$! + waittcp4port $PORT 1 + echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family for hostname not supported" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + +while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE; do +if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi + +if [ "X$CSUFF" != "X-" ]; then + CADDR=$ADDR-$CSUFF +else + CADDR=$ADDR +fi +CNAME=$(echo $CADDR |tr - _) +PROTO=$(toupper $proto) +FEAT=$ADDR +runs=$proto +case "$CPARMS" in + PORT) newport $proto; CPARMS=$PORT ;; + *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;; +esac +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 +case "X$COPTS" in + X-) COPTS= ;; + *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;; +esac +case "X$SOPTS" in + X-) SOPTS= ;; +esac + +# Test the retry option with *-CONNECT addresses +NAME=${CNAME}_RETRY +case "$TESTS" in +*%$N%*|*%functions%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%retry%*|*%$NAME%*) +TEST="$NAME: $ADDR can retry" +# Have an IPv4 listener with delay +# Start a connector whose first attempt must fail; check if the second attempt +# succeeds. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "$FEAT IP4 TCP LISTEN STDIO" \ + "$CADDR $SADDR STDIO PIPE" \ + "pf retry interval" \ + "${runs}4 ${runs}6" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N + cant +else +# newport $proto +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + da="test$N $(date) $RANDOM" + CMD0="relsleep 5; $TRACE $SOCAT $opts $SADDR:$PORT,$SOPTS,pf=2 $PIPE" + CMD1="$TRACE $SOCAT $opts -4 STDIO $CADDR:$LOCALHOST:$CPARMS,retry=1,interval=$(relsecs 10),$COPTS" + printf "test $F_n $TEST... " $N +#date +%Y/%m/%d" "%H:%M:%S.%N + eval "$CMD0" >/dev/null 2>"${te}0" & + pid0=$! + { echo "$da"; relsleep 15; } |$CMD1 >"${tf}1" 2>"${te}1" + rc1=$? + kill $pid0 2>/dev/null; wait + if echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + elif [ "$rc1" -ne 0 ] && grep "Address family not supported by protocol" "${te}1" >/dev/null; then + $PRINTF "$FAILED (EAFNOSUPPORT)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif [ "$rc1" -ne 0 ]; then + $PRINTF "$CANT (unexpected error)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + cant + elif ! echo "$da" |diff - "${tf}1" >$tdiff; then + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + else + $PRINTF "$CANT (unexpected problem)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + cant + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +done <<<" +TCP tcp CONNECT PORT - TCP-L - PIPE +SCTP sctp CONNECT PORT - SCTP-L - PIPE +DCCP dccp CONNECT PORT - DCCP-L - PIPE +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE +SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh +SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh +PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh +" + +#------------------------------------------------------------------------------ + +while read ADDR proto CSUFF CPARMS COPTS SADDR SOPTS PIPE SLOW; do +if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi + +if [ "X$CSUFF" != "X-" ]; then + CADDR=$ADDR-$CSUFF +else + CADDR=$ADDR +fi +CNAME=$(echo $CADDR |tr - _) +PROTO=$(toupper $proto) +FEAT=$ADDR +runs=$proto +case "$CPARMS" in + PORT) newport $proto; CPARMS=$PORT ;; + *'$PORT'*) newport $proto; CPARMS=$(eval echo "$CPARMS") ;; +esac +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 +case "X$COPTS" in + X-) COPTS= ;; + *'$PORT'*) newport $proto; COPTS=$(eval echo "$COPTS") ;; +esac +case "X$SOPTS" in + X-) SOPTS= ;; +esac + +# Test the fork and max-children options with CONNECT addresses +NAME=${CNAME}_MAXCHILDREN +case "$TESTS" in +*%$N%*|*%functions%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%fork%*|*%maxchildren%*|*%$NAME%*) +TEST="$NAME: $ADDR with fork,max-children" +# Start a reader process that transfers received data to an output file; +# run a sending client that forks at most 2 parallel child processes that +# transfer data from a simple directory queue to the reader but afterwards +# hang some time to prevent more child process. +# After the first two transfers write the third record directly to the file; +# a little later the Socat mechanism puts a 4th record. +# When the 4 records in the output file have the expected order the test +# succeeded. +if ! eval $NUMCOND; then : +elif ! cond=$(checkconds \ + "" \ + "" \ + "" \ + "$FEAT IP4 TCP LISTEN STDIO PIPE" \ + "$CADDR $SADDR STDIO PIPE" \ + "pf" \ + "${runs}4" ); then + $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N + cant +else +# newport $proto +#echo "PORT=$PORT CPARMS=$CPARMS" >&2 + tf="$td/test$N.stdout" + te="$td/test$N.stderr" + tdiff="$td/test$N.diff" + tQ="$td/test$N.q" + ext=q.y.f. # some unusual extension to prevent from deleting wrong file + da="test$N $(date) $RANDOM" + CMD0="$TRACE $SOCAT $opts -lp reader $SADDR:$PORT,$SOPTS,pf=2,reuseaddr,fork $PIPE" + CMD1="$TRACE $SOCAT $opts -4 $CADDR:$LOCALHOST:$CPARMS,fork,max-children=2,interval=$(relsecs $((2*SLOW))),$COPTS SHELL:'shopt\ -s\ nullglob;\ F=\$(ls -1 $tQ|grep .$ext\\\$|head -n 1);\ test\ \"\$F\"\ ||\ exit;\ cat\ $tQ/\$F;\ mv\ -i\ $tQ/\$F\ $tQ/.\$F;\ sleep\ $(relsecs $((5*SLOW)) )'!!-" + printf "test $F_n $TEST... " $N + # create data for the generator + mkdir -p $tQ + echo "$da 1" >$tQ/01.$ext + echo "$da 2" >$tQ/02.$ext + echo "$da 4" >$tQ/04.$ext + eval "$CMD0" 2>"${te}0" & + pid0=$! + relsleep $((1*SLOW)) + eval $CMD1 2>"${te}1" >>"${tf}0" & + pid1=$! + relsleep $((4*SLOW)) +#date +%Y/%m/%d" "%H:%M:%S.%N + echo "$da 3" >>"${tf}0" + relsleep $((4*SLOW)) + kill $(childpids -r $pid0) $pid0 $(childpids -r $pid1) $pid1 2>/dev/null + wait 2>/dev/null + if ! test -e "${tf}0" || ! test -s "${tf}0"; then + $PRINTF "$FAILED\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + failed + elif $ECHO "$da 1\n$da 2\n$da 3\n$da 4" |diff - ${tf}0 >$tdiff; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD1"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + ok + else + $PRINTF "$FAILED (diff)\n" + echo "$CMD0 &" + cat "${te}0" >&2 + echo "$CMD1" + cat "${te}1" >&2 + echo "// diff:" >&2 + cat "$tdiff" >&2 + failed + fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + +done <<<" +TCP tcp CONNECT PORT - TCP-L - PIPE 1 +SCTP sctp CONNECT PORT - SCTP-L - PIPE 1 +DCCP dccp CONNECT PORT - DCCP-L - PIPE 1 +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE 6 +SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh 6 +SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh 5 +PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh 4 +" +# detto IP6 + + +# test combined 4_6/6_4 with retry and fork + + # end of common tests ################################################################################## @@ -19519,7 +20095,7 @@ case "$TESTS" in TEST="$NAME: pty with group-late works on pty" # up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of # the pty with options user-late, group-late, or perm-late. -# here we check for correct behaviour. +# here we check for correct behaviour. # ATTENTION: in case of failure of this test the # group of /dev/ptmx might be changed! if ! eval $NUMCOND; then :; else @@ -19626,7 +20202,7 @@ rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips* # end # too dangerous - run as root and having a shell problem, it might purge your -# file systems +# file systems #rm -r "$td" # sometimes subprocesses hang; we want to see this diff --git a/xio-ip.c b/xio-ip.c index a0c12c9..7b1c56e 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -161,6 +161,79 @@ int Res_init(void) { #endif /* HAVE_RESOLV_H */ +/* Looks for a bind option and, if found, passes it to resolver; + for IP (v4, v6) and raw (PF_UNSPEC); + returns list of addrinfo results; + returns STAT_OK if option exists and could be resolved, + STAT_NORETRY if option exists but had error, + or STAT_NOACTION if it does not exist */ +int retropt_bind_ip( + struct opt *opts, + int af, + int socktype, + int ipproto, + struct addrinfo ***bindlist, + int feats, /* TCP etc: 1..address allowed, + 3..address and port allowed + */ + const int ai_flags[2]) +{ + const char portsep[] = ":"; + const char *ends[] = { portsep, NULL }; + const char *nests[] = { "[", "]", NULL }; + bool portallowed; + char *bindname, *bindp; + char hostname[512], *hostp = hostname, *portp = NULL; + size_t hostlen = sizeof(hostname)-1; + int parsres; + int ai_flags2[2]; + int result; + + if (retropt_string(opts, OPT_BIND, &bindname) < 0) { + return STAT_NOACTION; + } + bindp = bindname; + + portallowed = (feats>=2); + parsres = + nestlex((const char **)&bindp, &hostp, &hostlen, ends, NULL, NULL, nests, + true, false, false); + if (parsres < 0) { + Error1("option too long: \"%s\"", bindp); + return STAT_NORETRY; + } else if (parsres > 0) { + Error1("syntax error in \"%s\"", bindp); + return STAT_NORETRY; + } + *hostp++ = '\0'; + if (!strncmp(bindp, portsep, strlen(portsep))) { + if (!portallowed) { + Error("port specification not allowed in this bind option"); + return STAT_NORETRY; + } else { + portp = bindp + strlen(portsep); + } + } + + /* Set AI_PASSIVE, except when it is explicitely disabled */ + ai_flags2[0] = ai_flags[0]; + ai_flags2[1] = ai_flags[1]; + if (!(ai_flags2[1] & AI_PASSIVE)) + ai_flags2[0] |= AI_PASSIVE; + + if ((result = + xiogetaddrinfo(hostname[0]!='\0'?hostname:NULL, portp, + af, socktype, ipproto, + bindlist, ai_flags2)) + != STAT_OK) { + Error2("error resolving bind option \"%s\" with af=%d", bindname, af); + return STAT_NORETRY; + } + + return STAT_OK; +} + + #if WITH_DEVTESTS /* Have a couple of hard coded sockaddr records, to be copied and adapted when @@ -516,11 +589,11 @@ int _xiogetaddrinfo(const char *node, const char *service, continue; } if ((error_num = Getaddrinfo(node, service, &hints, res)) != 0) { - Warn7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %d", + Warn7("getaddrinfo(\"%s\", \"%s\", {0x%02x,%d,%d,%d}, {}): %s", node?node:"NULL", service?service:"NULL", hints.ai_flags, hints.ai_family, hints.ai_socktype, hints.ai_protocol, - error_num); + gai_strerror(error_num)); if (numnode) free(numnode); @@ -760,6 +833,9 @@ void xiofreeaddrinfo(struct addrinfo **ai_sorted) { int ain; struct addrinfo *res; + if (ai_sorted == NULL) + return; + /* Find the original *res from getaddrinfo past NULL */ ain = 0; while (ai_sorted[ain] != NULL) diff --git a/xio-ip.h b/xio-ip.h index ec94e16..c6c0355 100644 --- a/xio-ip.h +++ b/xio-ip.h @@ -49,6 +49,7 @@ extern const struct optdesc opt_res_nsaddr; extern int xioinit_ip(int *pf, char ipv); +extern int retropt_bind_ip(struct opt *opts, int af, int socktype, int ipproto, struct addrinfo ***bindlist, int feats, const int ai_flags[2]); extern int xiogetaddrinfo(const char *node, const char *service, int family, int socktype, int protocol, struct addrinfo ***ai_sorted, const int ai_flags[2]); extern void xiofreeaddrinfo(struct addrinfo **ai_sorted); extern int _xio_sort_ip_addresses(struct addrinfo *themlist, struct addrinfo **ai_sorted); diff --git a/xio-ipapp.c b/xio-ipapp.c index fcc0d33..53c505d 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -19,6 +19,7 @@ const struct optdesc opt_sourceport = { "sourceport", "sp", OPT_SOURCEPORT /*const struct optdesc opt_port = { "port", NULL, OPT_PORT, GROUP_IPAPP, PH_BIND, TYPE_USHORT, OFUNC_SPEC };*/ const struct optdesc opt_lowport = { "lowport", NULL, OPT_LOWPORT, GROUP_IPAPP, PH_LATE, TYPE_BOOL, OFUNC_SPEC }; + #if _WITH_IP4 || _WITH_IP6 /* we expect the form "host:port" */ int xioopen_ipapp_connect( @@ -31,20 +32,18 @@ int xioopen_ipapp_connect( { struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; + const char *hostname = argv[1], *portname = argv[2]; + int pf = addrdesc->arg3; int socktype = addrdesc->arg1; int ipproto = addrdesc->arg2; - int pf = addrdesc->arg3; - const char *hostname = argv[1], *portname = argv[2]; bool dofork = false; int maxchildren = 0; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; - char infobuff[256]; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; - int level; - int i; + int level = E_ERROR; int result; if (argc != 3) { @@ -52,97 +51,84 @@ int xioopen_ipapp_connect( return STAT_NORETRY; } - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); + if (result != STAT_OK) + return result; - if (applyopts_single(sfd, opts, PH_INIT) < 0) - return -1; - applyopts(sfd, -1, opts, PH_INIT); + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; - retropt_bool(opts, OPT_FORK, &dofork); - if (dofork) { - if (!(xioflags & XIO_MAYFORK)) { - Error("option fork not allowed here"); - return STAT_NORETRY; - } - sfd->flags |= XIO_DOESFORK; - } + Notice2("opening connection to %s:%s", hostname, portname); - retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren); - - if (! dofork && maxchildren) { - Error("option max-children not allowed without option fork"); - return STAT_NORETRY; - } - - if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, &needbind, &lowport, - socktype) != STAT_OK) { - return STAT_NORETRY; - } - - if (dofork) { - xiosetchilddied(); /* set SIGCHLD handler */ - } - - if (xioparms.logopt == 'm') { - Info("starting connect loop, switching to syslog"); - diag_set('y', xioparms.syslogfac); xioparms.logopt = 'y'; - } else { - Info("starting connect loop"); - } - - do { /* loop over retries, and forks */ - - /* Loop over themarr (which had been "ai_sorted") */ - result = STAT_RETRYLATER; - i = 0; - themp = themarr[i++]; - while (themp != NULL) { - Notice1("opening connection to %s", - sockaddr_info(themp->ai_addr, themp->ai_addrlen, - infobuff, sizeof(infobuff))); + do { /* loop over retries and/or forks */ + int _errno; #if WITH_RETRY - if (sfd->forever || sfd->retry) { - level = E_INFO; - } else if (themarr[i] != NULL) { - level = E_WARN; - } else + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else #endif /* WITH_RETRY */ - level = E_ERROR; + level = E_WARN; - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, ipproto, - lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) { - result = STAT_RETRYLATER; - } - } + opts = copyopts(opts0, GROUP_ALL); + + result = + _xioopen_ipapp_prepare(&opts, opts0, hostname, portname, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - --sfd->retry; - if (result == STAT_RETRYLATER) { + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); - } - dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ - default: + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); - free(opts0);free(opts); + freeopts(opts); + freeopts(opts0); + return result; + } + + result = + _xioopen_ipapp_connect(sfd, hostname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) + xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error4("%s:%s:%s: %s", argv[0], argv[1], argv[2], + _errno?strerror(_errno):"(See above)"); + freeopts(opts); + freeopts(opts0); return result; } @@ -155,16 +141,18 @@ int xioopen_ipapp_connect( so Notice is too weak */ } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { - Nanosleep(&sfd->intervall, NULL); continue; + if (sfd->forever || sfd->retry--) { + Nanosleep(&sfd->intervall, NULL); + continue; } - xiofreeaddrinfo(themarr); - free(opts0); + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - sfd->forever = false; sfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } @@ -176,109 +164,266 @@ int xioopen_ipapp_connect( Info1("all %d allowed children are active, waiting", maxchildren); Nanosleep(&sfd->intervall, NULL); } - dropopts(opts, PH_ALL); free(opts); opts = copyopts(opts0, GROUP_ALL); + freeopts(opts); continue; /* with next socket() bind() connect() */ } else #endif /* WITH_RETRY */ { break; } - } while (true); + } while (true); /* end of loop over retries and/or forks */ /* only "active" process breaks (master without fork, or child) */ - xiofreeaddrinfo(themarr); - if ((result = _xio_openlate(sfd, opts)) < 0) { - free(opts0);free(opts); - return result; - } - free(opts0); free(opts); - return 0; + Notice2("successfully connected to %s:%s", hostname, portname); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } -/* returns STAT_OK on success or some other value on failure +/* This function performs static initializations for addresses like TCP-CONNECT + before start of the outer loop: + it retrieves some options + returns STAT_OK on success or some other value on failure; + applies and consumes the following options: + PH_INIT, OPT_FORK, OPT_MAX_CHILDREN, OPT_PROTOCOL_FAMILY, OPT_SO_TYPE, + OPT_SO_PROTOTYPE +*/ +int _xioopen_ipapp_init( + struct single *sfd, + int xioflags, + struct opt *opts, + bool *dofork, + int *maxchildren, + int *pf, + int *socktype, + int *ipproto) +{ + if (sfd->howtoend == END_UNSPEC) + sfd->howtoend = END_SHUTDOWN; + + if (applyopts_single(sfd, opts, PH_INIT) < 0) + return -1; + if (applyopts(sfd, -1, opts, PH_INIT) < 0) + return -1; + + retropt_bool(opts, OPT_FORK, dofork); + if (dofork) { + if (!(xioflags & XIO_MAYFORK)) { + Error1("%s: option fork not allowed here", sfd->addr->defname); + return STAT_NORETRY; + } + sfd->flags |= XIO_DOESFORK; + } + + retropt_int(opts, OPT_MAX_CHILDREN, maxchildren); + if (! dofork && maxchildren) { + Error1("%s: option max-children not allowed without option fork", sfd->addr->defname); + return STAT_NORETRY; + } + + retropt_socket_pf(opts, pf); + retropt_int(opts, OPT_SO_TYPE, socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, ipproto); + + if (dofork) { + xiosetchilddied(); /* set SIGCHLD handler */ + } + + if (xioparms.logopt == 'm') { + Info("starting connect loop, switching to syslog"); + diag_set('y', xioparms.syslogfac); + xioparms.logopt = 'y'; + } else { + Info("starting connect loop"); + } + + return STAT_OK; +} + + +/* This function performs preparations for addresses like TCP-CONNECT + at the beginning of the outer (retry/fork) loop: + it evaluates some options and performs name resolution of both server + (target, "them") address and bind ("us") address. + It is intended to be invoked before the connect loop starts; + returns STAT_OK on success or some other value on failure; applies and consumes the following options: PH_EARLY - OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT - */ -int - _xioopen_ipapp_prepare( - struct opt *opts, - struct opt **opts0, - const char *hostname, - const char *portname, - int *pf, - int protocol, - const int ai_flags[2], - struct addrinfo ***themarr, - union sockaddr_union *us, - socklen_t *uslen, - bool *needbind, - bool *lowport, - int socktype) { + OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT + returns STAT_OK, STAT_RETRYLATER, or STAT_NORETRY (+errno) +*/ +int _xioopen_ipapp_prepare( + struct opt **opts, + struct opt *opts0, + const char *hostname, + const char *portname, + int pf, + int socktype, + int protocol, + const int ai_flags[2], + struct addrinfo ***themarr, /* always from getaddrinfo(); xiofreeaddrinfo()! */ + struct addrinfo ***bindarr, /* on bind from getaddrinfo(); xiofreeaddrinfo()! */ + uint16_t *bindport, /* for bind without address */ + bool *needbind, + bool *lowport) +{ uint16_t port; int rc; - retropt_socket_pf(opts, pf); + *opts = copyopts(opts0, GROUP_ALL); if (hostname != NULL || portname != NULL) { - rc = xiogetaddrinfo(hostname, portname, *pf, socktype, protocol, + rc = xiogetaddrinfo(hostname, portname, pf, socktype, protocol, themarr, ai_flags); if (rc == EAI_AGAIN) { Warn4("_xioopen_ipapp_prepare(node=\"%s\", service=\"%s\", pf=%d, ...): %s", hostname?hostname:"NULL", portname?portname:"NULL", - *pf, gai_strerror(rc)); + pf, gai_strerror(rc)); + errno = EAGAIN; return STAT_RETRYLATER; } else if (rc != 0) { Error4("_xioopen_ipapp_prepare(node=\"%s\", service=\"%s\", pf=%d, ...): %s", hostname?hostname:"NULL", portname?portname:"NULL", - *pf, (rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc)); + pf, (rc == EAI_SYSTEM)?strerror(errno):gai_strerror(rc)); + errno = 0; /* unspecified */ return STAT_NORETRY; /*! STAT_RETRYLATER? */ } } - applyopts(NULL, -1, opts, PH_EARLY); + applyopts(NULL, -1, *opts, PH_EARLY); /* 3 means: IP address AND port accepted */ - if (retropt_bind(opts, (*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family, - socktype, protocol, (struct sockaddr *)us, uslen, 3, - ai_flags) + if (retropt_bind_ip(*opts, pf, socktype, protocol, bindarr, 3, ai_flags) != STAT_NOACTION) { *needbind = true; - } else { - switch ((*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family) { -#if WITH_IP4 - case PF_INET: socket_in_init(&us->ip4); *uslen = sizeof(us->ip4); break; -#endif /* WITH_IP4 */ -#if WITH_IP6 - case PF_INET6: socket_in6_init(&us->ip6); *uslen = sizeof(us->ip6); break; -#endif /* WITH_IP6 */ - default: Error("unsupported protocol family"); - } } - - if (retropt_2bytes(opts, OPT_SOURCEPORT, &port) >= 0) { - switch ((*pf!=PF_UNSPEC)?*pf:(**themarr)->ai_family) { + if (retropt_2bytes(*opts, OPT_SOURCEPORT, &port) >= 0) { + if (*bindarr) { + struct addrinfo **bindp; + bindp = *bindarr; + switch ((*bindp)->ai_family) { #if WITH_IP4 - case PF_INET: us->ip4.sin_port = htons(port); break; + case PF_INET: ((struct sockaddr_in *)(*bindp)->ai_addr)->sin_port = htons(port); break; #endif /* WITH_IP4 */ #if WITH_IP6 - case PF_INET6: us->ip6.sin6_port = htons(port); break; + case PF_INET6: ((struct sockaddr_in6 *)(*bindp)->ai_addr)->sin6_port = htons(port); break; #endif /* WITH_IP6 */ - default: Error("unsupported protocol family"); + default: + Error("unsupported protocol family"); + errno = EPROTONOSUPPORT; + return STAT_NORETRY; + } + } else { + *bindport = port; } *needbind = true; } - retropt_bool(opts, OPT_LOWPORT, lowport); - - *opts0 = copyopts(opts, GROUP_ALL); + retropt_bool(*opts, OPT_LOWPORT, lowport); return STAT_OK; } #endif /* _WITH_IP4 || _WITH_IP6 */ +/* Tries to connect to the addresses in themarr, for each one it tries to bind + to the addresses in bindarr. + Ends on success or when all attempts failed. + Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure. */ +int _xioopen_ipapp_connect(struct single *sfd, + const char *hostname, + struct opt *opts, + struct addrinfo **themarr, + bool needbind, + struct addrinfo **bindarr, + uint16_t bindport, + bool lowport, + int level) +{ + struct addrinfo **themp; + struct addrinfo **bindp; + union sockaddr_union bindaddr = {0}; + union sockaddr_union *bindaddrp = NULL; + socklen_t bindlen = 0; + char infobuff[256]; + int _errno; + int result = STAT_OK; + + --level; + + /* Loop over server addresses (themarr) */ + themp = themarr; + while (*themp != NULL) { + Notice1("opening connection to %s", + sockaddr_info((*themp)->ai_addr, (*themp)->ai_addrlen, + infobuff, sizeof(infobuff))); + + if (*(themp+1) == NULL) { + ++level; /* last attempt */ + } + + /* Loop over array (list) of bind addresses */ + if (needbind && bindarr != NULL) { + /* Bind by hostname, use resolvers results list */ + bindp = bindarr; + while (*bindp != NULL) { + if ((*bindp)->ai_family == (*themp)->ai_family) + break; + ++bindp; + } + if (*bindp == NULL) { + Warn3("%s: No bind address with matching address family (%d) of %s available", + sfd->addr->defname, (*themp)->ai_family, hostname); + ++themp; + if ((*themp) == NULL) { + result = STAT_RETRYLATER; + } + _errno = ENOPROTOOPT; + continue; + } + bindaddrp = (union sockaddr_union *)(*bindp)->ai_addr; + bindlen = (*bindp)->ai_addrlen; + } else if (needbind && bindport) { + /* Bind by sourceport option */ + switch ((*themp)->ai_family) { + case PF_INET: + bindaddr.ip4.sin_family = (*themp)->ai_family; + bindaddr.ip4.sin_port = htons(bindport); + bindaddrp = &bindaddr; + bindlen = sizeof(bindaddr.ip4); + break; + case PF_INET6: + bindaddr.ip6.sin6_family = (*themp)->ai_family; + bindaddr.ip6.sin6_port = htons(bindport); + bindaddrp = &bindaddr; + bindlen = sizeof(bindaddr.ip6); + break; + } + } + + result = + _xioopen_connect(sfd, + bindaddrp, bindlen, + (*themp)->ai_addr, (*themp)->ai_addrlen, + opts, /*pf?pf:*/(*themp)->ai_family, (*themp)->ai_socktype, (*themp)->ai_protocol, + lowport, level); + if (result == STAT_OK) + break; + _errno = errno; + ++themp; + if (*themp == NULL) + result = STAT_RETRYLATER; + } /* end of loop over target addresses */ + + if (result != STAT_OK) + errno = _errno; + return result; +} + + #if WITH_TCP && WITH_LISTEN /* applies and consumes the following options: diff --git a/xio-ipapp.h b/xio-ipapp.h index af9e7b4..e190e36 100644 --- a/xio-ipapp.h +++ b/xio-ipapp.h @@ -15,11 +15,9 @@ extern const struct optdesc opt_sourceport; extern const struct optdesc opt_lowport; extern int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); -extern int _xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0, const char *hostname, const char *portname, int *pf, int protocol, const int ai_flags[2], struct addrinfo ***themlist, union sockaddr_union *us, socklen_t *uslen, bool *needbind, bool *lowport, int socktype); -extern int _xioopen_ip4app_connect(const char *hostname, const char *portname, - struct single *xfd, - int socktype, int ipproto, void *protname, - struct opt *opts); +extern int _xioopen_ipapp_init(struct single *sfd, int xioflags, struct opt *opts, bool *dofork, int *maxchildren, int *pf, int *socktype, int *protocol); +extern int _xioopen_ipapp_prepare(struct opt **opts, struct opt *opts0, const char *hostname, const char *portname, int pf, int socktype, int protocol, const int ai_flags[2], struct addrinfo ***themarr, struct addrinfo ***bindarr, uint16_t *bindport, bool *needbind, bool *lowport); +extern int _xioopen_ipapp_connect(struct single *sfd, const char *hostname, struct opt *opts, struct addrinfo **themarr, bool needbind, struct addrinfo **bindarr, uint16_t bindport, bool lowport, int level); extern int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc); extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0, const char *portname, int *pf, int ipproto, const int ai_flags[2], union sockaddr_union *us, socklen_t *uslen, int socktype); diff --git a/xio-openssl.c b/xio-openssl.c index c333ca3..21a571a 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -238,13 +238,13 @@ static int xioopen_openssl_connect( int socktype = SOCK_STREAM; int ipproto = IPPROTO_TCP; bool dofork = false; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; + int maxchildren = 0; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; int level = E_ERROR; - int i; SSL_CTX* ctx; bool opt_ver = true; /* verify peer certificate */ char *opt_cert = NULL; /* file name of client certificate */ @@ -254,7 +254,7 @@ static int xioopen_openssl_connect( int result; if (!(xioflags & XIO_MAYCONVERT)) { - Error("address with data processing not allowed here"); + Error1("%s: address with data processing not allowed here", argv[0]); return STAT_NORETRY; } sfd->flags |= XIO_DOESCONVERT; @@ -272,14 +272,6 @@ static int xioopen_openssl_connect( return STAT_NORETRY; } - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) - return -1; - applyopts(sfd, -1, opts, PH_INIT); - - retropt_bool(opts, OPT_FORK, &dofork); - retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert); retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname); #if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name) @@ -315,73 +307,83 @@ static int xioopen_openssl_connect( socktype = SOCK_DGRAM; ipproto = IPPROTO_UDP; } - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto); - result = - _xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); - if (result != STAT_OK) return STAT_NORETRY; + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); + if (result != STAT_OK) + return result; - if (xioparms.logopt == 'm') { - Info("starting connect loop, switching to syslog"); - diag_set('y', xioparms.syslogfac); xioparms.logopt = 'y'; - } else { - Info("starting connect loop"); - } + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; - do { /* loop over failed connect and SSL handshake attempts */ + Notice2("opening OpenSSL connection to %s:%s", hostname, portname); - /* Loop over themarr (which had been "ai_sorted") */ - i = 0; - themp = themarr[i++]; - while (themp != NULL) { + do { /* loop over retries (failed connect and SSL handshake attempts) and/or forks */ + int _errno; #if WITH_RETRY - if (sfd->forever || sfd->retry || themarr[i] != NULL) { - level = E_INFO; - } else + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else #endif /* WITH_RETRY */ - level = E_ERROR; + level = E_WARN; - /* This cannot fork because we retrieved fork option above */ - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) { - result = STAT_RETRYLATER; - } - } + opts = copyopts(opts0, GROUP_ALL); + + result = + _xioopen_ipapp_prepare(&opts, opts0, hostname, portname, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); + return result; + } + + Notice2("opening connection to server %s:%s", hostname, portname); + result = + _xioopen_ipapp_connect(sfd, hostname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) { Nanosleep(&sfd->intervall, NULL); } - --sfd->retry; + freeopts(opts); continue; } - xiofreeaddrinfo(themarr); - return STAT_NORETRY; #endif /* WITH_RETRY */ default: - xiofreeaddrinfo(themarr); - return result; - } - /*! isn't this too early? */ - if ((result = _xio_openlate(sfd, opts)) < 0) { - xiofreeaddrinfo(themarr); + Error4("%s:%s:%s: %s", argv[0], hostname, portname, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); return result; } @@ -392,19 +394,19 @@ static int xioopen_openssl_connect( #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - Close(sfd->fd); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) { Nanosleep(&sfd->intervall, NULL); } - --sfd->retry; + freeopts(opts); + Close(sfd->fd); continue; } #endif /* WITH_RETRY */ default: - xiofreeaddrinfo(themarr); - return STAT_NORETRY; + freeopts(opts); + freeopts(opts0); + return result; } if (dofork) { @@ -419,15 +421,19 @@ static int xioopen_openssl_connect( level = E_WARN; } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { - Nanosleep(&sfd->intervall, NULL); continue; + if (sfd->forever || sfd->retry--) { + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); + continue; } - xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - sfd->forever = false; sfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } @@ -437,21 +443,29 @@ static int xioopen_openssl_connect( sfd->para.openssl.ssl = NULL; /* with and without retry */ Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; /* with next socket() bind() connect() */ } #endif /* WITH_RETRY */ break; + } while (true); /* drop out on success */ - xiofreeaddrinfo(themarr); openssl_conn_loginfo(sfd->para.openssl.ssl); free((void *)opt_commonname); free((void *)opt_snihost); - /* fill in the fd structure */ - return STAT_OK; + Notice2("successfully connected to SSL server %s:%s", hostname, portname); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } diff --git a/xio-proxy.c b/xio-proxy.c index 0a8d4e6..ba82d5d 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -83,18 +83,18 @@ static int xioopen_proxy_connect( xiofile_t *xxfd, const struct addrdesc *addrdesc) { - /* we expect the form: host:host:port */ + /* we expect the form: host:host:port */ struct single *sfd = &xxfd->stream; struct opt *opts0 = NULL; struct proxyvars struct_proxyvars = { 0 }, *proxyvars = &struct_proxyvars; /* variables to be filled with address option values */ bool dofork = false; + int maxchildren = 0; /* */ int pf = PF_UNSPEC; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; - int i; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; const char *proxyname; char *proxyport = NULL; const char *targetname, *targetport; int ipproto = IPPROTO_TCP; @@ -112,90 +112,123 @@ static int xioopen_proxy_connect( targetname = argv[2]; targetport = argv[3]; - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) - return -1; - applyopts(sfd, 1, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - retropt_bool(opts, OPT_FORK, &dofork); - if (retropt_string(opts, OPT_PROXYPORT, &proxyport) < 0) { if ((proxyport = strdup(PROXYPORT)) == NULL) { errno = ENOMEM; return -1; } } - result = _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport, - sfd->para.socket.ip.ai_flags); - if (result != STAT_OK) - return result; - - Notice4("opening connection to %s:%u via proxy %s:%s", - proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); - - i = 0; - do { /* loop over retries (failed connect and proxy-request attempts) */ - - level = E_INFO; - - result = - _xioopen_ipapp_prepare(opts, &opts0, proxyname, proxyport, - &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); + result = + _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); if (result != STAT_OK) return result; - /* Loop over themlist */ - i = 0; - themp = themarr[i++]; - while (themp != NULL) { - Notice4("opening connection to %s:%u via proxy %s:%s", - proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); -#if WITH_RETRY - if (sfd->forever || sfd->retry || themarr[i] != NULL) { - level = E_INFO; - } else -#endif /* WITH_RETRY */ - level = E_ERROR; + result = _xioopen_proxy_init(proxyvars, opts, targetname, targetport); + if (result != STAT_OK) + return result; - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) { - result = STAT_RETRYLATER; - } + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; + + Notice4("opening connection to %s:%s via proxy %s:%s", + targetname, targetport, proxyname, proxyport); + + do { /* loop over retries (failed connect and proxy-request attempts) + and/or forks */ + int _errno; + +#if WITH_RETRY + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else +#endif /* WITH_RETRY */ + level = E_WARN; + + opts = copyopts(opts0, GROUP_ALL); + + result = + _xioopen_ipapp_prepare(&opts, opts0, proxyname, proxyport, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - --sfd->retry; + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ - default: + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; } - } - xiofreeaddrinfo(themarr); - applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(sfd, opts)) < 0) + result = + _xioopen_proxy_prepare(proxyvars, opts, targetname, targetport, + sfd->para.socket.ip.ai_flags); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; + } + + Notice2("opening connection to proxy %s:%s", proxyname, proxyport); + result = + _xioopen_ipapp_connect(sfd, proxyname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error4("%s:%s:...,proxyport=%s: %s", argv[0], proxyname, proxyport, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); + return result; + } result = _xioopen_proxy_connect(sfd, proxyvars, level); switch (result) { @@ -204,11 +237,16 @@ static int xioopen_proxy_connect( case STAT_RETRYLATER: case STAT_RETRYNOW: if (sfd->forever || sfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } #endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + freeopts(opts); + freeopts(opts0); return result; } @@ -225,21 +263,32 @@ static int xioopen_proxy_connect( } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { if (sfd->forever || --sfd->retry) { - Nanosleep(&sfd->intervall, NULL); continue; + if (sfd->retry > 0) + --sfd->retry; + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); + continue; } + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } if (pid == 0) { /* child process */ - sfd->forever = false; sfd->retry = 0; + sfd->forever = false; + sfd->retry = 0; break; } /* parent process */ Close(sfd->fd); + /* With and without retry */ Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); - opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; } else #endif /* WITH_RETRY */ @@ -248,25 +297,25 @@ static int xioopen_proxy_connect( } } while (true); /* end of complete open loop - drop out on success */ + /* Only "active" process breaks (master without fork, or child) */ Notice4("successfully connected to %s:%u via proxy %s:%s", proxyvars->targetaddr, proxyvars->targetport, proxyname, proxyport); - return 0; + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } -int _xioopen_proxy_prepare( +int _xioopen_proxy_init( struct proxyvars *proxyvars, struct opt *opts, const char *targetname, - const char *targetport, - const int ai_flags[2]) { - union sockaddr_union host; - socklen_t socklen = sizeof(host); - int rc; - + const char *targetport) +{ retropt_bool(opts, OPT_IGNORECR, &proxyvars->ignorecr); retropt_bool(opts, OPT_PROXY_RESOLVE, &proxyvars->doresolve); retropt_string(opts, OPT_HTTP_VERSION, &proxyvars->version); @@ -316,6 +365,28 @@ int _xioopen_proxy_prepare( Close(authfd); } + if (!proxyvars->doresolve) { + proxyvars->targetaddr = strdup(targetname); + if (proxyvars->targetaddr == NULL) { + Error1("strdup(\"%s\"): out of memory", targetname); + return STAT_RETRYLATER; + } + } + + return STAT_OK; +} + +int _xioopen_proxy_prepare( + struct proxyvars *proxyvars, + struct opt *opts, + const char *targetname, + const char *targetport, + const int ai_flags[2]) +{ + union sockaddr_union host; + socklen_t socklen = sizeof(host); + int rc; + if (proxyvars->doresolve) { /* currently we only resolve to IPv4 addresses. This is in accordance to RFC 2396; however once it becomes clear how IPv6 addresses should be @@ -325,6 +396,10 @@ int _xioopen_proxy_prepare( &host, &socklen, ai_flags); if (rc != STAT_OK) { proxyvars->targetaddr = strdup(targetname); + if (proxyvars->targetaddr == NULL) { + Error1("strdup(\"%s\"): out of memory", targetname); + return STAT_RETRYLATER; + } } else { #define LEN 16 /* www.xxx.yyy.zzz\0 */ if ((proxyvars->targetaddr = Malloc(LEN)) == NULL) { @@ -337,8 +412,6 @@ int _xioopen_proxy_prepare( ((unsigned char *)&host.ip4.sin_addr.s_addr)[3]); #undef LEN } - } else { - proxyvars->targetaddr = strdup(targetname); } proxyvars->targetport = htons(parseport(targetport, IPPROTO_TCP)); diff --git a/xio-proxy.h b/xio-proxy.h index fee18b7..f7fb2b8 100644 --- a/xio-proxy.h +++ b/xio-proxy.h @@ -25,9 +25,8 @@ extern const struct optdesc opt_proxy_authorization_file; extern const struct addrdesc xioaddr_proxy_connect; +extern int _xioopen_proxy_init(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport); extern int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport, const int ai_flags[2]); -int _xioopen_proxy_connect(struct single *xfd, - struct proxyvars *proxyvars, - int level); +extern int _xioopen_proxy_connect(struct single *xfd, struct proxyvars *proxyvars, int level); #endif /* !defined(__xio_proxy_h_included) */ diff --git a/xio-socket.c b/xio-socket.c index c798598..96e9893 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -805,7 +805,7 @@ int xiogetpacketinfo(struct single *sfd, int fd) with IP sockets: lowport (selects randomly a free port from 640 to 1023) with UNIX and abstract sockets: uses tmpname() to find a free file system entry. - returns 0 on success. + Returns STAT_OK on success, or STAT_RETRYLATER (+errno) on failure. */ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, struct sockaddr *them, size_t themlen, @@ -835,7 +835,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, applyopts_cloexec(sfd->fd, opts); if (xiobind(sfd, us, uslen, opts, pf, alt, level) < 0) { - return -1; + return STAT_RETRYLATER; } applyopts(sfd, -1, opts, PH_CONNECT); @@ -875,6 +875,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s", sfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } if (result == 0) { @@ -882,6 +883,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), strerror(ETIMEDOUT)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } if (writefd.revents & POLLERR) { @@ -897,15 +899,19 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); #endif + _errno = errno; Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } /* otherwise OK or network error */ result = Getsockopt(sfd->fd, SOL_SOCKET, SO_ERROR, &err, &errlen); if (result != 0) { + _errno = errno; Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s", sfd->fd, strerror(err)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0", @@ -915,6 +921,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(err)); Close(sfd->fd); + errno = err; return STAT_RETRYLATER; } Fcntl_l(sfd->fd, F_SETFL, fcntl_flags); @@ -945,6 +952,7 @@ int _xioopen_connect(struct single *sfd, union sockaddr_union *us, size_t uslen, sfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } else { /* result >= 0 */ @@ -1679,9 +1687,7 @@ int xiocheckrange(union sockaddr_union *sa, struct xiorange *range) { int xiocheckpeer(xiosingle_t *sfd, union sockaddr_union *pa, union sockaddr_union *la) { char infobuff[256]; -#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP int result; -#endif #if WITH_IP4 || WITH_IP6 if (sfd->para.socket.dorange) { @@ -2091,9 +2097,8 @@ int xiosetsockaddrenv(const char *lr, /* retrieves options so-type and so-prototype from opts, calls socket, and ev. generates an appropriate error message. - returns 0 on success or -1 if an error occurred. */ -int -xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { + returns 0 on success or -1 (and errno) if an error occurred. */ +int xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { int result; retropt_int(opts, OPT_SO_TYPE, &socktype); @@ -2118,6 +2123,7 @@ xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) { with IP sockets: lowport (selects randomly a free port from 640 to 1023) with UNIX and abstract sockets: uses a method similar to tmpname() to find a free file system entry. + On success returns STAT_OK, otherwise errno is set. */ int xiobind( struct single *sfd, @@ -2154,18 +2160,20 @@ int xiobind( usrname = strndup(us->un.sun_path, sizeof(us->un.sun_path)); if (usrname == NULL) { int _errno = errno; - Error2("strndup(\"%s\", "F_Zu"): out of memory", + Msg2(level, "strndup(\"%s\", "F_Zu"): out of memory", us->un.sun_path, sizeof(us->un.sun_path)); errno = _errno; - return -1; + return STAT_RETRYLATER; } } do { /* loop over tempnam bind() attempts */ sockname = xio_tempnam(usrname, abstract); if (sockname == NULL) { + int _errno = errno; Error2("tempnam(\"%s\"): %s", usrname, strerror(errno)); free(usrname); + errno = _errno; return -1; } strncpy(us->un.sun_path+(abstract?1:0), sockname, sizeof(us->un.sun_path)); @@ -2179,8 +2187,10 @@ int xiobind( infobuff, sizeof(infobuff)), uslen, strerror(errno)); if (errno != EADDRINUSE) { + int _errno = errno; free(usrname); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } else { @@ -2193,10 +2203,12 @@ int xiobind( if (us != NULL) { if (Bind(sfd->fd, &us->soa, uslen) < 0) { + int _errno = errno; Msg4(level, "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } applyopts_named(us->un.sun_path, opts, PH_PREOPEN); @@ -2268,12 +2280,14 @@ int xiobind( do { /* loop over lowport bind() attempts */ *port = htons(i); if (Bind(sfd->fd, &sinp->soa, sizeof(*sinp)) < 0) { + int _errno = errno; Msg4(errno==EADDRINUSE?E_INFO:level, "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&sinp->soa, sizeof(*sinp), infobuff, sizeof(infobuff)), sizeof(*sinp), strerror(errno)); - if (errno != EADDRINUSE) { + if (_errno != EADDRINUSE) { Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } else { @@ -2282,8 +2296,8 @@ int xiobind( --i; if (i < XIO_IPPORT_LOWER) i = IPPORT_RESERVED-1; if (i == N) { Msg(level, "no low port available"); - /*errno = EADDRINUSE; still assigned */ Close(sfd->fd); + errno = EADDRINUSE; return STAT_RETRYLATER; } } while (i != N); @@ -2294,17 +2308,19 @@ int xiobind( if (us) { applyopts(sfd, sfd->fd, opts, PH_BIND); if (Bind(sfd->fd, &us->soa, uslen) < 0) { + int _errno = errno; Msg4(level, "bind(%d, {%s}, "F_Zd"): %s", sfd->fd, sockaddr_info(&us->soa, uslen, infobuff, sizeof(infobuff)), uslen, strerror(errno)); Close(sfd->fd); + errno = _errno; return STAT_RETRYLATER; } } } applyopts(sfd, -1, opts, PH_PASTBIND); - return 0; + return STAT_OK; } /* Handles the SO_REUSEADDR socket option for TCP LISTEN addresses depending on diff --git a/xio-socks.c b/xio-socks.c index fd064dd..ea0805c 100644 --- a/xio-socks.c +++ b/xio-socks.c @@ -54,13 +54,12 @@ static int xioopen_socks4_connect( int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; bool dofork = false; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; - int i; + int maxchildren = 0; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; - char infobuff[256]; unsigned char buff[BUFF_LEN]; struct socks4 *sockhead = (struct socks4 *)buff; size_t buflen = sizeof(buff); @@ -76,41 +75,43 @@ static int xioopen_socks4_connect( targetname = argv[2]; targetport = argv[3]; - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - applyopts(sfd, 1, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - retropt_bool(opts, OPT_FORK, &dofork); - - result = _xioopen_socks4_prepare(targetport, opts, &socksport, sockhead, &buflen); + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); if (result != STAT_OK) return result; + result = _xioopen_socks4_init(targetport, opts, &socksport, sockhead, + &buflen); + if (result != STAT_OK) + return result; + + opts0 = opts; /* save remaining options for each loop */ + opts = NULL; + Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"", - targetname, - ntohs(sockhead->port), + targetname, ntohs(sockhead->port), sockdname, socksport, sockhead->userid); - i = 0; - do { /* loop over retries (failed connect and socks-request attempts) */ + do { /* loop over retries (failed connect and socks-request attempts) + and/or forks */ + int _errno; - level = E_INFO; +#if WITH_RETRY + if (sfd->forever || sfd->retry) { + level = E_NOTICE; + } else +#endif /* WITH_RETRY */ + level = E_WARN; + + opts = copyopts(opts0, GROUP_ALL); result = - _xioopen_ipapp_prepare(opts, &opts0, sockdname, socksport, - &pf, ipproto, + _xioopen_ipapp_prepare(&opts, opts0, sockdname, socksport, + pf, socktype, ipproto, sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); - - /* we try to resolve the target address _before_ connecting to the socks - server: this avoids unnecessary socks connects and timeouts */ - result = - _xioopen_socks4_connect0(sfd, targetname, socks4a, sockhead, - (ssize_t *)&buflen, level); + &themarr, &bindarr, &bindport, &needbind, &lowport); switch (result) { case STAT_OK: break; #if WITH_RETRY @@ -119,60 +120,78 @@ static int xioopen_socks4_connect( if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ - default: + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; } - /* loop over themarr */ - i = 0; - themp = themarr[i++]; - while (themp != NULL) { - Notice1("opening connection to %s", - sockaddr_info(themp->ai_addr, themp->ai_addrlen, - infobuff, sizeof(infobuff))); -#if WITH_RETRY - if (sfd->forever || sfd->retry || themarr[i] != NULL) { - level = E_INFO; - } else -#endif /* WITH_RETRY */ - level = E_ERROR; - - /* this cannot fork because we retrieved fork option above */ - result = - _xioopen_connect(sfd, - needbind?us:NULL, uslen, - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, IPPROTO_TCP, lowport, level); - if (result == STAT_OK) - break; - themp = themarr[i++]; - if (themp == NULL) - result = STAT_RETRYLATER; - } + /* we try to resolve the target address _before_ connecting to the socks + server: this may avoid unnecessary connects and timeouts */ + result = + _xioopen_socks4_prepare(sfd, targetname, socks4a, sockhead, + (ssize_t *)&buflen, level); switch (result) { case STAT_OK: break; #if WITH_RETRY case STAT_RETRYLATER: case STAT_RETRYNOW: - if (sfd->forever || sfd->retry) { - --sfd->retry; + if (sfd->forever || sfd->retry--) { if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); continue; } #endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; } - xiofreeaddrinfo(themarr); - applyopts(sfd, -1, opts, PH_ALL); - if ((result = _xio_openlate(sfd, opts)) < 0) + Notice2("opening connection to sockd %s:%s", sockdname, socksport); + result = + _xioopen_ipapp_connect(sfd, sockdname, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + errno = _errno; + Error4("%s:%s:...,socksport=%s: %s", argv[0], sockdname, socksport, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); return result; + } result = _xioopen_socks4_connect(sfd, sockhead, buflen, level); switch (result) { @@ -181,11 +200,16 @@ static int xioopen_socks4_connect( case STAT_RETRYLATER: case STAT_RETRYNOW: if (sfd->forever || sfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } #endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + freeopts(opts); + freeopts(opts0); return result; } @@ -202,10 +226,13 @@ static int xioopen_socks4_connect( so Notice is too weak */ } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { + if (sfd->forever || sfd->retry--) { Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } @@ -217,8 +244,13 @@ static int xioopen_socks4_connect( /* parent process */ Close(sfd->fd); + /* with and without retry */ Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; } else #endif /* WITH_RETRY */ @@ -227,7 +259,15 @@ static int xioopen_socks4_connect( } } while (true); /* end of complete open loop - drop out on success */ - return 0; + /* only "active" process breaks (master without fork, or child) */ + + Notice4("successfully connected to %s:%s via sockd %s:%s", + targetname, targetport, sockdname, socksport); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return result; } #endif /* WITH_SOCKS4 || WITH_SOCKS4A */ @@ -260,7 +300,13 @@ int _xioopen_opt_socksport( #endif /* WITH_SOCKS4 || WITH_SOCKS4A || WITH_SOCKS5 */ #if WITH_SOCKS4 || WITH_SOCKS4A -int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) { +int _xioopen_socks4_init( + const char *targetport, + struct opt *opts, + char **socksport, + struct socks4 *sockhead, + size_t *headlen) +{ char *userid; /* generate socks header - points to final target */ @@ -286,14 +332,14 @@ int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **soc /* called within retry/fork loop, before connect() */ -int - _xioopen_socks4_connect0(struct single *sfd, - const char *hostname, /* socks target host */ - int socks4a, - struct socks4 *sockhead, - ssize_t *headlen, /* get available space, - return used length*/ - int level) { +int _xioopen_socks4_prepare( + struct single *sfd, + const char *hostname, /* socks target host */ + int socks4a, + struct socks4 *sockhead, + ssize_t *headlen, /* get available space, return used length*/ + int level) +{ int result; if (!socks4a) { @@ -435,16 +481,7 @@ int _xioopen_socks4_connect(struct single *sfd, switch (replyhead->action) { case SOCKS_CD_GRANTED: /* Notice("socks: connect request succeeded"); */ -#if 0 - if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) { - Warn4("getsockname(%d, %p, {%d}): %s", - sfd->fd, &us, uslen, strerror(errno)); - } - Notice1("successfully connected from %s via socks4", - sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); -#else Notice("successfully connected via socks4"); -#endif break; case SOCKS_CD_FAILED: diff --git a/xio-socks.h b/xio-socks.h index f9a1131..f5abfb9 100644 --- a/xio-socks.h +++ b/xio-socks.h @@ -21,15 +21,8 @@ extern const struct addrdesc xioaddr_socks4_connect; extern const struct addrdesc xioaddr_socks4a_connect; extern int _xioopen_opt_socksport(struct opt *opts, char **socksport); -extern int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen); -extern int - _xioopen_socks4_connect0(struct single *xfd, - const char *hostname, /* socks target host */ - int socks4a, - struct socks4 *sockhead, - ssize_t *headlen, /* get available space, - return used length*/ - int level); +extern int _xioopen_socks4_init(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen); +extern int _xioopen_socks4_prepare(struct single *xfd, const char *hostname, int socks4a, struct socks4 *sockhead, ssize_t *headlen, int level); extern int _xioopen_socks4_connect(struct single *xfd, struct socks4 *sockhead, size_t headlen, diff --git a/xio-socks5.c b/xio-socks5.c index 31aa1ca..27ae1b1 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -512,6 +512,7 @@ static int xioopen_socks5( { int socks_command = addrdesc->arg1; bool dofork = false; + int maxchildren = 0; int socktype = SOCK_STREAM; int pf = PF_UNSPEC; int ipproto = IPPROTO_TCP; @@ -519,12 +520,11 @@ static int xioopen_socks5( struct opt *opts0 = NULL; struct single *sfd = &xxfd->stream; const char *socks_server, *target_name, *target_port, *socks_port; - union sockaddr_union us_sa, *us = &us_sa; - socklen_t uslen = sizeof(us_sa); - struct addrinfo **themarr, *themp; + struct addrinfo **bindarr = NULL; + struct addrinfo **themarr = NULL; + uint16_t bindport = 0; bool needbind = false; bool lowport = false; - char infobuff[256]; if (argc < 4 || argc > 5) { xio_syntax(argv[0], 4, argc-1, addrdesc->syntax); @@ -542,75 +542,115 @@ static int xioopen_socks5( target_port = argv[3]; } - if (sfd->howtoend == END_UNSPEC) - sfd->howtoend = END_SHUTDOWN; - if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; - applyopts(sfd, -1, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - retropt_bool(opts, OPT_FORK, &dofork); + /* Apply and retrieve some options */ + result = _xioopen_ipapp_init(sfd, xioflags, opts, + &dofork, &maxchildren, + &pf, &socktype, &ipproto); + if (result != STAT_OK) + return result; if (_xioopen_opt_socksport(opts, (char **)&socks_port) < 0) { return STAT_NORETRY; } /*! possible memory leak */ - result = _xioopen_ipapp_prepare(opts, &opts0, socks_server, socks_port, - &pf, ipproto, - sfd->para.socket.ip.ai_flags, - &themarr, us, &uslen, - &needbind, &lowport, socktype); + opts0 = opts; + opts = NULL; - Notice2("connecting to socks5 server %s:%s", - socks_server, socks_port); + Notice4("opening connection to %s:%s vis socks5 server %s:%s", + target_name, target_port, socks_server, socks_port); - do { + do { /* loop over retries (failed connect and socks-request attempts) + and/or forks */ + int _errno; #if WITH_RETRY if (sfd->forever || sfd->retry) { - level = E_INFO; - } else { - level = E_ERROR; - } + level = E_NOTICE; + } else #endif + level = E_WARN; - /* loop over themarr */ - themp = themarr[0]; - while (themp != NULL) { - Notice1("opening connection to %s", - sockaddr_info(themp->ai_addr, themp->ai_addrlen, - infobuff, sizeof(infobuff))); - result = _xioopen_connect(sfd, needbind?us:NULL, sizeof(*us), - themp->ai_addr, themp->ai_addrlen, - opts, pf?pf:themp->ai_family, socktype, - IPPROTO_TCP, lowport, level); - if (result == STAT_OK) - break; - themp = themp->ai_next; - if (themp == NULL) - result = STAT_RETRYLATER; + opts = copyopts(opts0, GROUP_ALL); - switch(result){ - break; + result = + _xioopen_ipapp_prepare(&opts, opts0, socks_server, socks_port, + pf, socktype, ipproto, + sfd->para.socket.ip.ai_flags, + &themarr, &bindarr, &bindport, &needbind, + &lowport); + switch (result) { + case STAT_OK: break; #if WITH_RETRY - case STAT_RETRYLATER: - case STAT_RETRYNOW: - if (sfd->forever || sfd->retry-- ) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); - continue; - } -#endif - default: + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + if (bindarr != NULL) xiofreeaddrinfo(bindarr); xiofreeaddrinfo(themarr); - return result; + freeopts(opts); + continue; } - } - xiofreeaddrinfo(themarr); - applyopts(sfd, -1, opts, PH_ALL); - - if ((result = _xio_openlate(sfd, opts)) < 0) +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + case STAT_NORETRY: + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + freeopts(opts); + freeopts(opts0); return result; + } - if ((result = _xioopen_socks5_handshake(sfd, level)) != STAT_OK) { + Notice2("opening connection to socks5 server %s:%s", + socks_server, socks_port); + result = + _xioopen_ipapp_connect(sfd, socks_server, opts, themarr, + needbind, bindarr, bindport, lowport, level); + _errno = errno; + if (bindarr != NULL) xiofreeaddrinfo(bindarr); + xiofreeaddrinfo(themarr); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error4("%s:%s:%s:...: %s", + argv[0], socks_server, socks_port, + _errno?strerror(_errno):"(See above)"); + freeopts(opts0); + freeopts(opts); + return result; + } + + result = _xioopen_socks5_handshake(sfd, level); + switch (result) { + case STAT_OK: break; +#if WITH_RETRY + case STAT_RETRYLATER: + case STAT_RETRYNOW: + if (sfd->forever || sfd->retry--) { + if (result == STAT_RETRYLATER) { + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); + continue; + } +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ + default: + Error3("%s:%s:%s: Connection failed", argv[0], socks_server, socks_port); + freeopts(opts0); + freeopts(opts); return result; } @@ -622,11 +662,16 @@ static int xioopen_socks5( case STAT_RETRYLATER: case STAT_RETRYNOW: if ( sfd->forever || sfd->retry-- ) { - if (result == STAT_RETRYLATER) Nanosleep(&sfd->intervall, NULL); + if (result == STAT_RETRYLATER) + Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } -#endif +#endif /* WITH_RETRY */ + /* FALLTHROUGH */ default: + freeopts(opts); + freeopts(opts0); return result; } @@ -642,12 +687,18 @@ static int xioopen_socks5( level = E_WARN; } while ((pid = xio_fork(false, level, sfd->shutup)) < 0) { - if (sfd->forever || --sfd->retry) { + if (sfd->forever || sfd->retry) { + if (sfd->retry > 0) + --sfd->retry; Nanosleep(&sfd->intervall, NULL); + freeopts(opts); continue; } + freeopts(opts); + freeopts(opts0); return STAT_RETRYLATER; } + if ( pid == 0 ) { sfd->forever = false; sfd->retry = 0; @@ -656,17 +707,26 @@ static int xioopen_socks5( Close(sfd->fd); Nanosleep(&sfd->intervall, NULL); - dropopts(opts, PH_ALL); - opts = copyopts(opts0, GROUP_ALL); + while (maxchildren > 0 && num_child >= maxchildren) { + Info1("all %d allowed children are active, waiting", maxchildren); + Nanosleep(&sfd->intervall, NULL); + } + freeopts(opts); continue; } else -#endif +#endif /* WITH_RETRY */ { break; } } while (true); - return 0; + Notice4("successfully connected to %s:%s via socks5 server %s:%s", + target_name, target_port, socks_server, socks_port); + + result = _xio_openlate(sfd, opts); + freeopts(opts); + freeopts(opts0); + return STAT_OK; } #endif /* WITH_SOCKS5 */ diff --git a/xioopts.c b/xioopts.c index d36179c..71d5cf4 100644 --- a/xioopts.c +++ b/xioopts.c @@ -2912,7 +2912,6 @@ int showleft(const struct opt *opts) { return 0; } - /* determines the address group from mode_t */ /* does not set GROUP_FD; cannot determine GROUP_TERMIOS ! */ groups_t _groupbits(mode_t mode) { @@ -4690,3 +4689,11 @@ int dumpopts(struct opt *opts) } return 0; } + +/* Better with type specific free function */ +void freeopts( + struct opt *opts) +{ + free(opts); + return; +} diff --git a/xioopts.h b/xioopts.h index 5071cc4..d40e34d 100644 --- a/xioopts.h +++ b/xioopts.h @@ -1031,6 +1031,7 @@ extern groups_t _groupbits(mode_t mode); extern int dropopts(struct opt *opts, unsigned int phase); extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to); extern int dumpopts(struct opt *opts); +extern void freeopts(struct opt *opts); #if HAVE_BASIC_UID_T==1 # define retropt_uid(o,c,r) retropt_short(o,c,r) From 264b21c1a99822690b49c09458eaee0e554ea878 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 10 Feb 2025 19:42:22 +0100 Subject: [PATCH 32/51] getpwuid() errno --- CHANGES | 3 +++ xioopts.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 69f091b..7e02db2 100644 --- a/CHANGES +++ b/CHANGES @@ -78,6 +78,9 @@ Corrections: DCCP_CONNECT_MAXCHILDREN OPENSSL_CONNECT_MAXCHILDREN SOCKS4_MAXCHILDREN SOCKS5_CONNECT_MAXCHILDREN PROXY_CONNECT_MAXCHILDREN + On failure of getpwuid() (used in options su and su-d) now consider + errno. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/xioopts.c b/xioopts.c index 71d5cf4..505305d 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3944,8 +3944,12 @@ int applyopt_spec( { struct passwd *pwd; if ((pwd = getpwuid(opt->value.u_uidt)) == NULL) { - Error1("getpwuid("F_uid"): no such user", - opt->value.u_uidt); + if (errno != 0) + Error2("getpwuid("F_uid"): %s", + opt->value.u_uidt, strerror(errno)); + else + Error1("getpwuid("F_uid"): no such user", + opt->value.u_uidt); return -1; } if (Initgroups(pwd->pw_name, pwd->pw_gid) < 0) { From 08d01c19ff1378cc3cbd25a5591eebbb39c6b6e4 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 10 Feb 2025 21:06:22 +0100 Subject: [PATCH 33/51] Fixed UDP6-RECVFROM with range --- CHANGES | 3 +++ test.sh | 2 +- xio-ipapp.c | 1 + xio-socket.c | 8 ++++---- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 7e02db2..22574fe 100644 --- a/CHANGES +++ b/CHANGES @@ -81,6 +81,9 @@ Corrections: On failure of getpwuid() (used in options su and su-d) now consider errno. + When IP4 was completed deconfigured, UDP6-RECVFROM with range option + failed. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/test.sh b/test.sh index 5829e63..9b7bf0f 100755 --- a/test.sh +++ b/test.sh @@ -20070,7 +20070,7 @@ done <<<" TCP tcp CONNECT PORT - TCP-L - PIPE 1 SCTP sctp CONNECT PORT - SCTP-L - PIPE 1 DCCP dccp CONNECT PORT - DCCP-L - PIPE 1 -OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE 6 +OPENSSL tcp CONNECT PORT cafile=testsrv.pem,verify=0 SSL-L cert=testsrv.pem,key=testsrv.key,verify=0 PIPE 7 SOCKS4 tcp - 32.98.76.54:32109 socksport=\$PORT,socksuser=nobody TCP-L - EXEC:./socks4echo.sh 6 SOCKS5 tcp CONNECT \$PORT:127.0.0.1:80 - TCP-L - EXEC:./socks5server-echo.sh 5 PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf EXEC:./proxyecho.sh 4 diff --git a/xio-ipapp.c b/xio-ipapp.c index 53c505d..77c449e 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -326,6 +326,7 @@ int _xioopen_ipapp_prepare( return STAT_OK; } + #endif /* _WITH_IP4 || _WITH_IP6 */ diff --git a/xio-socket.c b/xio-socket.c index 96e9893..2e7a42d 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1230,7 +1230,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, } #endif -#if WITH_IP4 +#if WITH_IP4 || WITH_IP6 /* for generic sockets, this has already been retrieved */ if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, @@ -1242,7 +1242,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags, free(rangename); sfd->para.socket.dorange = true; } -#endif /* WITH_IP4 */ +#endif /* WITH_IP4 || WITH_IP6 */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(sfd, opts); @@ -1454,7 +1454,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, } #endif -#if WITH_IP4 +#if WITH_IP4 || WITH_IP6 if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) { if (xioparserange(rangename, pf, &sfd->para.socket.range, sfd->para.socket.ip.ai_flags) @@ -1465,7 +1465,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags, free(rangename); sfd->para.socket.dorange = true; } -#endif /* WITH_IP4 */ +#endif /* WITH_IP4 || WITH_IP6 */ #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP xio_retropt_tcpwrap(sfd, opts); From 568c26861b47a3f1b7138bf4cbfb37bf0d43896d Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Sun, 26 Nov 2023 14:08:33 +0100 Subject: [PATCH 34/51] Procan: print saved set-user-ID --- CHANGES | 3 +++ config.h.in | 6 ++++++ configure.ac | 2 ++ procan.c | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/CHANGES b/CHANGES index 22574fe..a68fa3b 100644 --- a/CHANGES +++ b/CHANGES @@ -98,6 +98,9 @@ Features: POSIXMQ is now an alias for POSIXMQ-BIDIRECTIONAL. It can also be used in unidirectional context. + Procan uses getresuid() and getresgid() when available, to determine + the saved set-user-ID. + Building: Disabling certain features during configure could break build process. diff --git a/config.h.in b/config.h.in index 410576b..39061f1 100644 --- a/config.h.in +++ b/config.h.in @@ -162,6 +162,12 @@ /* Define if you have the clock_gettime function */ #undef HAVE_CLOCK_GETTIME +/* Define if you have the getresuid function */ +#undef HAVE_GETRESUID + +/* Define if you have the getresgid function */ +#undef HAVE_GETRESGID + /* Define if you have the strtoll function */ #undef HAVE_STRTOLL diff --git a/configure.ac b/configure.ac index bdc2fd0..da5d4e3 100644 --- a/configure.ac +++ b/configure.ac @@ -1722,6 +1722,8 @@ AC_CHECK_PROTOTYPE_LIB(gettimeofday) AC_CHECK_FUNC(clock_gettime, AC_DEFINE(HAVE_CLOCK_GETTIME), AC_CHECK_LIB(rt, clock_gettime, [LIBS="-lrt $LIBS"; AC_DEFINE(HAVE_CLOCK_GETTIME)])) +AC_CHECK_FUNCS(getresuid getresgid) + dnl Search for flock() # with Linux it's in libc, with AIX in libbsd AC_CHECK_FUNC(flock, AC_DEFINE(HAVE_FLOCK), diff --git a/procan.c b/procan.c index 22dd5e4..f51751c 100644 --- a/procan.c +++ b/procan.c @@ -187,10 +187,30 @@ int procan(FILE *outfile) { fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2)); /* process owner, groups */ +#if HAVE_GETRESUID + { + uid_t ruid, euid, suid; + getresuid(&ruid, &euid, &suid); + fprintf(outfile, "user id = "F_uid"\n", ruid); + fprintf(outfile, "effective user id = "F_uid"\n", euid); + fprintf(outfile, "saved set-user id = "F_uid"\n", suid); + } +#else /* !HAVE_GETRESUID */ fprintf(outfile, "user id = "F_uid"\n", Getuid()); fprintf(outfile, "effective user id = "F_uid"\n", Geteuid()); +#endif /* !HAVE_GETRESUID */ +#if HAVE_GETRESGID + { + gid_t rgid, egid, sgid; + getresgid(&rgid, &egid, &sgid); + fprintf(outfile, "group id = "F_gid"\n", rgid); + fprintf(outfile, "effective group id = "F_gid"\n", egid); + fprintf(outfile, "saved set-group id = "F_gid"\n", sgid); + } +#else /* !HAVE_GETRESGID */ fprintf(outfile, "group id = "F_gid"\n", Getgid()); fprintf(outfile, "effective group id = "F_gid"\n", Getegid()); +#endif /* !HAVE_GETRESGID */ /* Simple process features */ fprintf(outfile, "\n"); From 200ccb24cdbd037f3494a47f2b0f7ed63143ac6a Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Sun, 8 Sep 2024 13:15:49 +0200 Subject: [PATCH 35/51] Procan -V; more C-defines (__GLIBC__, O_*, AI_*, EAI_*) --- CHANGES | 3 + procan-cdefs.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++--- procan_main.c | 28 ++++++++- 3 files changed, 171 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index a68fa3b..7b888f4 100644 --- a/CHANGES +++ b/CHANGES @@ -101,6 +101,9 @@ Features: Procan uses getresuid() and getresgid() when available, to determine the saved set-user-ID. + Procan prints more C-defines, esp.O_*, AI_*, EAI_*; __GLIBC__; + added option -V + Building: Disabling certain features during configure could break build process. diff --git a/procan-cdefs.c b/procan-cdefs.c index d9587f8..ae98a09 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -15,30 +15,91 @@ #include "procan.h" int procan_cdefs(FILE *outfile) { - /* basic C/system constants */ + /* System constants */ +#ifdef __KERNEL__ + fprintf(outfile, "__KERNEL__ = \"%s\"\n", __KERNEL__); +#endif +#ifdef __GLIBC__ + fprintf(outfile, "__GLIBC__ = %d\n", __GLIBC__); +#endif + /* Basic C/system constants */ #ifdef FD_SETSIZE - fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); + fprintf(outfile, "#define FD_SETSIZE %u\n", FD_SETSIZE); #endif #ifdef NFDBITS - fprintf(outfile, "#define NFDBITS %d\n", (int)NFDBITS); + fprintf(outfile, "#define NFDBITS %d\n", (int)NFDBITS); #endif #ifdef O_RDONLY - fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); + fprintf(outfile, "#define O_RDONLY %u\n", O_RDONLY); #endif #ifdef O_WRONLY - fprintf(outfile, "#define O_WRONLY %u\n", O_WRONLY); + fprintf(outfile, "#define O_WRONLY %u\n", O_WRONLY); #endif #ifdef O_RDWR - fprintf(outfile, "#define O_RDWR %u\n", O_RDWR); + fprintf(outfile, "#define O_RDWR %u\n", O_RDWR); +#endif +#ifdef O_CREAT + fprintf(outfile, "#define O_CREAT 0x%06x\n", O_CREAT); +#endif +#ifdef O_EXCL + fprintf(outfile, "#define O_EXCL 0x%06x\n", O_EXCL); +#endif +#ifdef O_NOCTTY + fprintf(outfile, "#define O_NOCTTY 0x%06x\n", O_NOCTTY); +#endif +#ifdef O_TRUNC + fprintf(outfile, "#define O_TRUNC 0x%06x\n", O_TRUNC); +#endif +#ifdef O_APPEND + fprintf(outfile, "#define O_APPEND 0x%06x\n", O_APPEND); +#endif +#ifdef O_NONBLOCK + fprintf(outfile, "#define O_NONBLOCK 0x%06x\n", O_NONBLOCK); +#endif +#ifdef O_NDELAY + fprintf(outfile, "#define O_NDELAY 0x%06x\n", O_NDELAY); +#endif +#ifdef O_SYNC + fprintf(outfile, "#define O_SYNC 0x%06x\n", O_SYNC); +#endif +#ifdef O_FSYNC + fprintf(outfile, "#define O_FSYNC 0x%06x\n", O_FSYNC); +#endif +#ifdef O_LARGEFILE + fprintf(outfile, "#define O_LARGEFILE 0x%06x\n", O_LARGEFILE); +#endif +#ifdef O_DIRECTORY + fprintf(outfile, "#define O_DIRECTORY 0x%06x\n", O_DIRECTORY); +#endif +#ifdef O_NOFOLLOW + fprintf(outfile, "#define O_NOFOLLOW 0x%06x\n", O_NOFOLLOW); +#endif +#ifdef O_CLOEXEC + fprintf(outfile, "#define O_CLOEXEC 0x%06x\n", O_CLOEXEC); +#endif +#ifdef O_DIRECT + fprintf(outfile, "#define O_DIRECT 0x%06x\n", O_DIRECT); +#endif +#ifdef O_NOATIME + fprintf(outfile, "#define O_NOATIME 0x%06x\n", O_NOATIME); +#endif +#ifdef O_PATH + fprintf(outfile, "#define O_PATH 0x%06x\n", O_PATH); +#endif +#ifdef O_DSYNC + fprintf(outfile, "#define O_DSYNC 0x%06x\n", O_SYNC); +#endif +#ifdef O_TMPFILE + fprintf(outfile, "#define O_TMPFILE 0x%06x\n", O_TMPFILE); #endif #ifdef SHUT_RD - fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD); + fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD); #endif #ifdef SHUT_WR - fprintf(outfile, "#define SHUT_WR %u\n", SHUT_WR); + fprintf(outfile, "#define SHUT_WR %u\n", SHUT_WR); #endif #ifdef SHUT_RDWR - fprintf(outfile, "#define SHUT_RDWR %u\n", SHUT_RDWR); + fprintf(outfile, "#define SHUT_RDWR %u\n", SHUT_RDWR); #endif /* Compile time controls */ @@ -188,5 +249,78 @@ int procan_cdefs(FILE *outfile) { #ifdef TCP_MAXSEG fprintf(outfile, "#define TCP_MAXSEG %d\n", TCP_MAXSEG); #endif +#ifdef AI_PASSIVE + fprintf(outfile, "#define AI_PASSIVE 0x%02x\n", AI_PASSIVE); +#endif +#ifdef AI_CANONNAME + fprintf(outfile, "#define AI_CANONNAME 0x%02x\n", AI_CANONNAME); +#endif +#ifdef AI_NUMERICHOST + fprintf(outfile, "#define AI_NUMERICHOST 0x%02x\n", AI_NUMERICHOST); +#endif +#ifdef AI_V4MAPPED + fprintf(outfile, "#define AI_V4MAPPED 0x%02x\n", AI_V4MAPPED); +#endif +#ifdef AI_ALL + fprintf(outfile, "#define AI_ALL 0x%02x\n", AI_ALL); +#endif +#ifdef AI_ADDRCONFIG + fprintf(outfile, "#define AI_ADDRCONFIG 0x%02x\n", AI_ADDRCONFIG); +#endif +#ifdef EAI_BADFLAGS + fprintf(outfile, "#define EAI_BADFLAGS %d\n", EAI_BADFLAGS); +#endif +#ifdef EAI_NONAME + fprintf(outfile, "#define EAI_NONAME %d\n", EAI_NONAME); +#endif +#ifdef EAI_AGAIN + fprintf(outfile, "#define EAI_AGAIN %d\n", EAI_AGAIN); +#endif +#ifdef EAI_FAIL + fprintf(outfile, "#define EAI_FAIL %d\n", EAI_FAIL); +#endif +#ifdef EAI_FAMILY + fprintf(outfile, "#define EAI_FAMILY %d\n", EAI_FAMILY); +#endif +#ifdef EAI_SOCKTYPE + fprintf(outfile, "#define EAI_SOCKTYPE %d\n", EAI_SOCKTYPE); +#endif +#ifdef EAI_SERVICE + fprintf(outfile, "#define EAI_SERVICE %d\n", EAI_SERVICE); +#endif +#ifdef EAI_MEMORY + fprintf(outfile, "#define EAI_MEMORY %d\n", EAI_MEMORY); +#endif +#ifdef EAI_SYSTEM + fprintf(outfile, "#define EAI_SYSTEM %d\n", EAI_SYSTEM); +#endif +#ifdef EAI_OVERFLOW + fprintf(outfile, "#define EAI_OVERFLOW %d\n", EAI_OVERFLOW); +#endif +#ifdef EAI_NODATA + fprintf(outfile, "#define EAI_NODATA %d\n", EAI_NODATA); +#endif +#ifdef EAI_ADDRFAMILY + fprintf(outfile, "#define EAI_ADDRFAMILY %d\n", EAI_ADDRFAMILY); +#endif +#ifdef EAI_INPROGRESS + fprintf(outfile, "#define EAI_INPROGRESS %d\n", EAI_INPROGRESS); +#endif +#ifdef EAI_CANCELED + fprintf(outfile, "#define EAI_CANCELED %d\n", EAI_CANCELED); +#endif +#ifdef EAI_NOTCANCELED + fprintf(outfile, "#define EAI_NOTCANCELED %d\n", EAI_NOTCANCELED); +#endif +#ifdef EAI_ALLDONE + fprintf(outfile, "#define EAI_ALLDONE %d\n", EAI_ALLDONE); +#endif +#ifdef EAI_INTR + fprintf(outfile, "#define EAI_INTR %d\n", EAI_INTR); +#endif +#ifdef EAI_IDN_ENCODE + fprintf(outfile, "#define EAI_IDN_ENCODE %d\n", EAI_IDN_ENCODE); +#endif + return 0; } diff --git a/procan_main.c b/procan_main.c index 7f70402..18b33de 100644 --- a/procan_main.c +++ b/procan_main.c @@ -13,6 +13,9 @@ const char copyright[] = "procan by Gerhard Rieger and contributors - send bug r #if HAVE_SYS_SELECT_H #include <sys/select.h> /* select(), fdset on FreeBSD */ #endif +#if HAVE_SYS_UTSNAME_H +#include <sys/utsname.h> /* uname(), struct utsname */ +#endif #include "mytypes.h" #include "error.h" #include "procan.h" @@ -22,6 +25,13 @@ const char copyright[] = "procan by Gerhard Rieger and contributors - send bug r #define WITH_HELP 1 static void procan_usage(FILE *fd); +static void procan_version(FILE *fd); + +const char copyright_procan[] = "procan by Gerhard Rieger and contributors - see www.dest-unreach.org"; +static const char procanversion[] = +#include "./VERSION" + ; +static const char timestamp[] = BUILD_DATE; int main(int argc, const char *argv[]) { @@ -39,8 +49,8 @@ int main(int argc, const char *argv[]) { case '?': case 'h': procan_usage(stdout); exit(0); #endif /* WITH_HELP */ case 'c': procan_cdefs(stdout); exit(0); -#if LATER case 'V': procan_version(stdout); exit(0); +#if LATER case 'l': diag_set(arg1[0][2], &arg1[0][3]); break; case 'd': diag_set('d', NULL); break; #endif @@ -80,9 +90,7 @@ static void procan_usage(FILE *fd) { fputs("Usage:\n", fd); fputs("procan [options]\n", fd); fputs(" options:\n", fd); -#if LATER fputs(" -V print version information to stdout, and exit\n", fd); -#endif #if WITH_HELP fputs(" -?|-h print a help text describing command line options\n", fd); #endif @@ -100,3 +108,17 @@ static void procan_usage(FILE *fd) { #endif } #endif /* WITH_HELP */ + + +void procan_version( + FILE *fd) +{ + struct utsname ubuf; + + fputs(copyright_procan, fd); fputc('\n', fd); + fprintf(fd, "procan version %s on %s\n", procanversion, timestamp); + uname(&ubuf); + fprintf(fd, " running on %s version %s, release %s, machine %s\n", + ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine); + return; +} From 699da5f52217ae1631f4472cf58af515d0bfc161 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger <gerhard@dest-unreach.org> Date: Thu, 31 Oct 2024 10:39:29 +0100 Subject: [PATCH 36/51] Procan tells if char is signed or unsigned --- CHANGES | 2 ++ hostan.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/CHANGES b/CHANGES index 7b888f4..6793b35 100644 --- a/CHANGES +++ b/CHANGES @@ -104,6 +104,8 @@ Features: Procan prints more C-defines, esp.O_*, AI_*, EAI_*; __GLIBC__; added option -V + Procan tells if char is signed or unsigned + Building: Disabling certain features during configure could break build process. diff --git a/hostan.c b/hostan.c index 80ea569..4258d3c 100644 --- a/hostan.c +++ b/hostan.c @@ -33,6 +33,11 @@ int hostan(FILE *outfile) { #endif fprintf(outfile, "sizeof(size_t) = %u\n", (unsigned int)sizeof(size_t)); + if ((char)-1 > 0) + fprintf(outfile, "typedef unsigned char char;\n"); + else + fprintf(outfile, "typedef signed char char;\n"); + # if HAVE_BASIC_SIZE_T==2 fprintf(outfile, "typedef unsigned short size_t; /* sizeof(size_t) = %u */\n", (unsigned int)sizeof(size_t)); #elif HAVE_BASIC_SIZE_T==4 From 3339885f5b5eff4eb3fef1add9c20848449a74e0 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 10 Feb 2025 22:24:56 +0100 Subject: [PATCH 37/51] Procan prints some C-defines in oct and hex --- CHANGES | 1 + procan-cdefs.c | 60 +++++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/CHANGES b/CHANGES index 6793b35..e2eea62 100644 --- a/CHANGES +++ b/CHANGES @@ -102,6 +102,7 @@ Features: the saved set-user-ID. Procan prints more C-defines, esp.O_*, AI_*, EAI_*; __GLIBC__; + prints some C-defines in oct and hex; added option -V Procan tells if char is signed or unsigned diff --git a/procan-cdefs.c b/procan-cdefs.c index ae98a09..af56e69 100644 --- a/procan-cdefs.c +++ b/procan-cdefs.c @@ -39,58 +39,58 @@ int procan_cdefs(FILE *outfile) { fprintf(outfile, "#define O_RDWR %u\n", O_RDWR); #endif #ifdef O_CREAT - fprintf(outfile, "#define O_CREAT 0x%06x\n", O_CREAT); + fprintf(outfile, "#define O_CREAT 0x%06x /* 0%08o */\n", O_CREAT, O_CREAT); #endif #ifdef O_EXCL - fprintf(outfile, "#define O_EXCL 0x%06x\n", O_EXCL); + fprintf(outfile, "#define O_EXCL 0x%06x /* 0%08o */\n", O_EXCL, O_EXCL); #endif #ifdef O_NOCTTY - fprintf(outfile, "#define O_NOCTTY 0x%06x\n", O_NOCTTY); + fprintf(outfile, "#define O_NOCTTY 0x%06x /* 0%08o */\n", O_NOCTTY, O_NOCTTY); #endif #ifdef O_TRUNC - fprintf(outfile, "#define O_TRUNC 0x%06x\n", O_TRUNC); + fprintf(outfile, "#define O_TRUNC 0x%06x /* 0%08o */\n", O_TRUNC, O_TRUNC); #endif #ifdef O_APPEND - fprintf(outfile, "#define O_APPEND 0x%06x\n", O_APPEND); + fprintf(outfile, "#define O_APPEND 0x%06x /* 0%08o */\n", O_APPEND, O_APPEND); #endif #ifdef O_NONBLOCK - fprintf(outfile, "#define O_NONBLOCK 0x%06x\n", O_NONBLOCK); + fprintf(outfile, "#define O_NONBLOCK 0x%06x /* 0%08o */\n", O_NONBLOCK, O_NONBLOCK); #endif #ifdef O_NDELAY - fprintf(outfile, "#define O_NDELAY 0x%06x\n", O_NDELAY); + fprintf(outfile, "#define O_NDELAY 0x%06x /* 0%08o */\n", O_NDELAY, O_NDELAY); #endif #ifdef O_SYNC - fprintf(outfile, "#define O_SYNC 0x%06x\n", O_SYNC); + fprintf(outfile, "#define O_SYNC 0x%06x /* 0%08o */\n", O_SYNC, O_SYNC); #endif #ifdef O_FSYNC - fprintf(outfile, "#define O_FSYNC 0x%06x\n", O_FSYNC); + fprintf(outfile, "#define O_FSYNC 0x%06x /* 0%08o */\n", O_FSYNC, O_FSYNC); #endif #ifdef O_LARGEFILE - fprintf(outfile, "#define O_LARGEFILE 0x%06x\n", O_LARGEFILE); + fprintf(outfile, "#define O_LARGEFILE 0x%06x /* 0%08o */\n", O_LARGEFILE, O_LARGEFILE); #endif #ifdef O_DIRECTORY - fprintf(outfile, "#define O_DIRECTORY 0x%06x\n", O_DIRECTORY); + fprintf(outfile, "#define O_DIRECTORY 0x%06x /* 0%08o */\n", O_DIRECTORY, O_DIRECTORY); #endif #ifdef O_NOFOLLOW - fprintf(outfile, "#define O_NOFOLLOW 0x%06x\n", O_NOFOLLOW); + fprintf(outfile, "#define O_NOFOLLOW 0x%06x /* 0%08o */\n", O_NOFOLLOW, O_NOFOLLOW); #endif #ifdef O_CLOEXEC - fprintf(outfile, "#define O_CLOEXEC 0x%06x\n", O_CLOEXEC); + fprintf(outfile, "#define O_CLOEXEC 0x%06x /* 0%08o */\n", O_CLOEXEC, O_CLOEXEC); #endif #ifdef O_DIRECT - fprintf(outfile, "#define O_DIRECT 0x%06x\n", O_DIRECT); + fprintf(outfile, "#define O_DIRECT 0x%06x /* 0%08o */\n", O_DIRECT, O_DIRECT); #endif #ifdef O_NOATIME - fprintf(outfile, "#define O_NOATIME 0x%06x\n", O_NOATIME); + fprintf(outfile, "#define O_NOATIME 0x%06x /* 0%08o */\n", O_NOATIME, O_NOATIME); #endif #ifdef O_PATH - fprintf(outfile, "#define O_PATH 0x%06x\n", O_PATH); + fprintf(outfile, "#define O_PATH 0x%06x /* 0%08o */\n", O_PATH, O_PATH); #endif #ifdef O_DSYNC - fprintf(outfile, "#define O_DSYNC 0x%06x\n", O_SYNC); + fprintf(outfile, "#define O_DSYNC 0x%06x /* 0%08o */\n", O_SYNC, O_SYNC); #endif #ifdef O_TMPFILE - fprintf(outfile, "#define O_TMPFILE 0x%06x\n", O_TMPFILE); + fprintf(outfile, "#define O_TMPFILE 0x%06x /* 0%08o */\n", O_TMPFILE, O_TMPFILE); #endif #ifdef SHUT_RD fprintf(outfile, "#define SHUT_RD %u\n", SHUT_RD); @@ -112,40 +112,40 @@ int procan_cdefs(FILE *outfile) { /* termios constants */ #ifdef CRDLY - fprintf(outfile, "#define CRDLY 0%011o\n", CRDLY); + fprintf(outfile, "#define CRDLY 0x%08x /* 0%011o */\n", CRDLY, CRDLY); #endif #ifdef CR0 - fprintf(outfile, "#define CR0 0%011o\n", CR0); + fprintf(outfile, "#define CR0 0x%08x /* 0%011o */\n", CR0, CR0); #endif #ifdef CR1 - fprintf(outfile, "#define CR1 0%011o\n", CR1); + fprintf(outfile, "#define CR1 0x%08x /* 0%011o */\n", CR1, CR1); #endif #ifdef CR2 - fprintf(outfile, "#define CR2 0%011o\n", CR2); + fprintf(outfile, "#define CR2 0x%08x /* 0%011o */\n", CR2, CR2); #endif #ifdef CR3 - fprintf(outfile, "#define CR3 0%011o\n", CR3); + fprintf(outfile, "#define CR3 0x%08x /* 0%011o */\n", CR3, CR3); #endif #ifdef TABDLY - fprintf(outfile, "#define TABDLY 0%011o\n", TABDLY); + fprintf(outfile, "#define TABDLY 0x%08x /* 0%011o */\n", TABDLY, TABDLY); #endif #ifdef TAB0 - fprintf(outfile, "#define TAB0 0%011o\n", TAB0); + fprintf(outfile, "#define TAB0 0x%08x /* 0%011o */\n", TAB0, TAB0); #endif #ifdef TAB1 - fprintf(outfile, "#define TAB1 0%011o\n", TAB1); + fprintf(outfile, "#define TAB1 0x%08x /* 0%011o */\n", TAB1, TAB1); #endif #ifdef TAB2 - fprintf(outfile, "#define TAB2 0%011o\n", TAB2); + fprintf(outfile, "#define TAB2 0x%08x /* 0%011o */\n", TAB2, TAB2); #endif #ifdef TAB3 - fprintf(outfile, "#define TAB3 0%011o\n", TAB3); + fprintf(outfile, "#define TAB3 0x%08x /* 0%011o */\n", TAB3, TAB3); #endif #ifdef CSIZE - fprintf(outfile, "#define CSIZE 0%011o\n", CSIZE); + fprintf(outfile, "#define CSIZE 0x%08x /* 0%011o */\n", CSIZE, CSIZE); #endif #ifdef TIOCEXCL - fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL); + fprintf(outfile, "#define TIOCEXCL 0x%lx\n", (unsigned long)TIOCEXCL); #endif /* stdio constants */ From e6aa3d17873e402a8615c07184f9be649725af83 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Tue, 11 Feb 2025 12:31:59 +0100 Subject: [PATCH 38/51] Print info on implicit SO_REUSEADDR --- CHANGES | 3 +++ xio-socket.c | 10 ++++++++-- xioopts.c | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index e2eea62..83ed6f0 100644 --- a/CHANGES +++ b/CHANGES @@ -107,6 +107,9 @@ Features: Procan tells if char is signed or unsigned + Socat now prints an info message when implicitely setting SO_REUSEADDR. + Thanks to Michael Renner for this suggestion. + Building: Disabling certain features during configure could break build process. diff --git a/xio-socket.c b/xio-socket.c index 2e7a42d..2eaed08 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -2327,7 +2327,7 @@ int xiobind( Socat option so-reuseaddr: Option not applied: set it to 1 Option applied with a value: set it to the value - Option applied eith empty value "so-reuseaddr=": do not call setsockopt() for + Option applied with empty value "so-reuseaddr=": do not call setsockopt() for SO_REUSEADDR Return 0 on success, or -1 with errno when an error occurred. */ @@ -2335,6 +2335,7 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) { union integral val; union integral notnull; + int result; int _errno; val.u_int = 0; @@ -2345,7 +2346,12 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) notnull.u_bool = true; } #endif /* WITH_TCP */ - retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, ¬null); + result = retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, ¬null); + if (ipproto == IPPROTO_TCP && result < 0) { + Info("Setting SO_REUSADDR on TCP listen socket implicitly"); + val.u_int = 1; + notnull.u_bool = true; + } if (notnull.u_bool) { if (Setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val.u_int, sizeof(int)) != 0) { diff --git a/xioopts.c b/xioopts.c index 505305d..db77499 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3107,7 +3107,7 @@ int retropt_int(struct opt *opts, int optcode, int *result) { /* Looks for the first option of type <optcode>. If the option is found, this function stores its int value in *result, "consumes" the option, and returns 0. - If the option is not found, *result is not modified, and -1 is returned. */ + If the option is not found, values are not modified, and -1 is returned. */ int retropt_2integrals(struct opt *opts, int optcode, union integral *value1, union integral *value2) { From c8aec28b821656417e8b676e51635bdad5eb3971 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Thu, 13 Feb 2025 11:25:09 +0100 Subject: [PATCH 39/51] Added options setsockopt-socket and setsockopt-connected --- CHANGES | 3 +++ doc/socat.yo | 6 ++++++ xio-socket.c | 2 ++ xio-socket.h | 2 ++ xioopts.c | 4 ++++ xioopts.h | 2 ++ 6 files changed, 19 insertions(+) diff --git a/CHANGES b/CHANGES index 83ed6f0..8d8a30b 100644 --- a/CHANGES +++ b/CHANGES @@ -110,6 +110,9 @@ Features: Socat now prints an info message when implicitely setting SO_REUSEADDR. Thanks to Michael Renner for this suggestion. + Added generic options setsockopt-socket and setsockopt-connected that + are applied after socket() or when connected. + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index 6695d28..6cfd907 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -2408,6 +2408,12 @@ label(OPTION_SETSOCKOPT_STRING)dit(bf(tt(setsockopt-string=<level>:<optname>:<op Like tt(setsockopt), but <optval> is a link(string)(TYPE_STRING). This string is passed to the function with trailing null character, and the length parameter is automatically derived from the data. +label(OPTION_SETSOCKOPT_SOCKET)dit(bf(tt(setsockopt-socket=<level>:<optname>:<optval>))) + Like tt(setsockopt), but is applied to the socket before other operations + (code(bind()), code(connect()), code(accept()), ...) +label(OPTION_SETSOCKOPT_CONNECTED)dit(bf(tt(setsockopt-connected=<level>:<optname>:<optval>))) + Like tt(setsockopt), but is applied only when the socket has been connected + by a code(connect()) or code(listen()) call. enddit() startdit()enddit()nl() diff --git a/xio-socket.c b/xio-socket.c index 2eaed08..6400c01 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -191,6 +191,8 @@ const struct optdesc opt_setsockopt_int = { "setsockopt-int", "sockopt-int const struct optdesc opt_setsockopt_bin = { "setsockopt-bin", "sockopt-bin", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_string = { "setsockopt-string", "sockopt-string", OPT_SETSOCKOPT_STRING, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_STRING, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_setsockopt_listen = { "setsockopt-listen", "sockopt-listen", OPT_SETSOCKOPT_LISTEN, GROUP_SOCKET,PH_PREBIND, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +const struct optdesc opt_setsockopt_socket = { "setsockopt-socket", "sockopt-sock", OPT_SETSOCKOPT_SOCKET, GROUP_SOCKET,PH_PASTSOCKET, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; +const struct optdesc opt_setsockopt_connected = { "setsockopt-connected", "sockopt-conn", OPT_SETSOCKOPT_CONNECTED, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 }; const struct optdesc opt_null_eof = { "null-eof", NULL, OPT_NULL_EOF, GROUP_SOCKET, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.null_eof) }; diff --git a/xio-socket.h b/xio-socket.h index 2af3367..2ecb28b 100644 --- a/xio-socket.h +++ b/xio-socket.h @@ -83,6 +83,8 @@ extern const struct optdesc opt_setsockopt_bin; extern const struct optdesc opt_setsockopt_string; extern const struct optdesc opt_setsockopt_listen; extern const struct optdesc opt_null_eof; +extern const struct optdesc opt_setsockopt_socket; +extern const struct optdesc opt_setsockopt_connected; extern diff --git a/xioopts.c b/xioopts.c index db77499..aa2f525 100644 --- a/xioopts.c +++ b/xioopts.c @@ -1583,8 +1583,10 @@ const struct optname optionnames[] = { #endif IF_SOCKET ("setsockopt", &opt_setsockopt) IF_SOCKET ("setsockopt-bin", &opt_setsockopt_bin) + IF_SOCKET ("setsockopt-connected", &opt_setsockopt_connected) IF_SOCKET ("setsockopt-int", &opt_setsockopt_int) IF_SOCKET ("setsockopt-listen", &opt_setsockopt_listen) + IF_SOCKET ("setsockopt-socket", &opt_setsockopt_socket) IF_SOCKET ("setsockopt-string", &opt_setsockopt_string) IF_ANY ("setuid", &opt_setuid) IF_ANY ("setuid-early", &opt_setuid_early) @@ -1719,8 +1721,10 @@ const struct optname optionnames[] = { #endif /* SO_USELOOPBACK */ IF_SOCKET ("sockopt", &opt_setsockopt) IF_SOCKET ("sockopt-bin", &opt_setsockopt_bin) + IF_SOCKET ("sockopt-conn", &opt_setsockopt_connected) IF_SOCKET ("sockopt-int", &opt_setsockopt_int) IF_SOCKET ("sockopt-listen", &opt_setsockopt_listen) + IF_SOCKET ("sockopt-sock", &opt_setsockopt_socket) IF_SOCKET ("sockopt-string", &opt_setsockopt_string) IF_SOCKS4 ("socksport", &opt_socksport) IF_SOCKS4 ("socksuser", &opt_socksuser) diff --git a/xioopts.h b/xioopts.h index d40e34d..593fc5d 100644 --- a/xioopts.h +++ b/xioopts.h @@ -663,8 +663,10 @@ enum e_optcode { OPT_SETPGID, OPT_SETSID, OPT_SETSOCKOPT_BIN, + OPT_SETSOCKOPT_CONNECTED, OPT_SETSOCKOPT_INT, OPT_SETSOCKOPT_LISTEN, + OPT_SETSOCKOPT_SOCKET, OPT_SETSOCKOPT_STRING, OPT_SETUID, OPT_SETUID_EARLY, From d9d06eb58750b42fca6a13610e8d8b58445eb702 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Thu, 13 Feb 2025 14:29:15 +0100 Subject: [PATCH 40/51] Fixed preprocessor directives in macro invocation --- CHANGES | 3 +++ filan.c | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 8d8a30b..4885be8 100644 --- a/CHANGES +++ b/CHANGES @@ -84,6 +84,9 @@ Corrections: When IP4 was completed deconfigured, UDP6-RECVFROM with range option failed. + Fixed preprocessor directives in macro invocation. + Thanks to Mario de Weerd for reporting this issue. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/filan.c b/filan.c index 36def50..fb9229c 100644 --- a/filan.c +++ b/filan.c @@ -393,7 +393,7 @@ int filan_stat( break; #ifdef S_IFLNK case (S_IFLNK): /* 10, symbolic link */ - /* we wait for freadlink() sytem call */ + /* we wait for freadlink() system call */ break; #endif /* S_IFLNK */ break; @@ -804,13 +804,13 @@ int ipan(int fd, FILE *outfile) { } /* want to pass the fd to the next layer protocol. */ #if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) - if (Getsockopt(fd, SOL_SOCKET, + if ( #ifdef SO_PROTOCOL - SO_PROTOCOL, + Getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &optproto, &optlen) #elif defined(SO_PROTOTYPE) - SO_PROTOTYPE, + Getsockopt(fd, SOL_SOCKET, SO_PROTOTYPE, &optproto, &optlen) #endif - &optproto, &optlen) >= 0) { + >= 0) { switch (optproto) { #if WITH_TCP case IPPROTO_TCP: tcpan(fd, outfile); break; From 52e2e5a277eb8f510829470442ed88619b8794c7 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Thu, 13 Feb 2025 14:33:06 +0100 Subject: [PATCH 41/51] Corrected lots of misspellings etc. --- CHANGES | 59 +- CHANGES.ISO-8859-1 | 1800 ---------------------------------- EXAMPLES | 8 +- FAQ | 2 +- PORTING | 2 +- README.FIPS | 2 +- SECURITY | 2 +- configure.ac | 4 +- doc/socat-genericsocket.html | 6 +- doc/socat.yo | 14 +- error.h | 2 +- filan_main.c | 2 +- readline-test.sh | 2 +- socat.c | 4 +- sysutils.c | 2 +- test.sh | 37 +- xio-ascii.c | 2 +- xio-fs.c | 2 +- xio-interface.c | 4 +- xio-ip.c | 2 +- xio-ip6.c | 2 +- xio-ipapp.c | 2 +- xio-openssl.c | 6 +- xio-openssl.h | 2 +- xio-socket.c | 4 +- xio-stdio.c | 2 +- xio-streams.c | 2 +- xio-tcpwrap.c | 2 +- xio-termios.c | 2 +- xio-tun.c | 4 +- xio-udp.c | 4 +- xio-unix.c | 4 +- xio.h | 2 +- xioinitialize.c | 4 +- xioopts.c | 2 +- xioopts.h | 2 +- 36 files changed, 108 insertions(+), 1896 deletions(-) delete mode 100644 CHANGES.ISO-8859-1 diff --git a/CHANGES b/CHANGES index 4885be8..53ef92e 100644 --- a/CHANGES +++ b/CHANGES @@ -110,7 +110,7 @@ Features: Procan tells if char is signed or unsigned - Socat now prints an info message when implicitely setting SO_REUSEADDR. + Socat now prints an info message when implicitly setting SO_REUSEADDR. Thanks to Michael Renner for this suggestion. Added generic options setsockopt-socket and setsockopt-connected that @@ -152,6 +152,12 @@ Testing: Newer Linux distributions now deprecate usleep; replaced it in test.sh +Documentation: + Removed obsolete CHANGES.ISO-8859-1 file. + + Corrected lots of misspelling and typos. + Thanks to Mario de Weerd for reporting these issues. + ####################### V 1.8.0.2: Security: @@ -223,6 +229,9 @@ Corrections: Print warning about not checking CRLs in OpenSSL only in the first child process. + Fixed preprocessor directives in macro invocation. + Thanks to Mario de Weerd for reporting this issue. + Features: Total inactivity timeout option -T 0 now means 0.0 seconds; up to version 1.8.0.0 it meant no total inactivity timeout. @@ -390,11 +399,11 @@ Features: no IP version is preferred by build, environment, option, or address type, Socat chooses IPv6 because this might activate both versions (but check option ipv6-v6only). - Added option ai-passive to control this flag explicitely. + Added option ai-passive to control this flag explicitly. New option ai-v4mapped (v4mapped) sets or unsets the AI_V4MAPPED flag of the resolver. For Socat addresses requiring IPv6 addresses, this - resolves IPv4 addresses to the approriate IPv6 address [::ffff:*:*]. + resolves IPv4 addresses to the appropriate IPv6 address [::ffff:*:*]. DNS resolver Options (res-*) are now set for the complete open phase of the address, not per getaddrinfo() invocation. @@ -587,14 +596,14 @@ Porting: Some corrections for better 32bit systems support. Testing: - Removed obselete parts from test.sh + Removed obsolete parts from test.sh test.sh: Introduced function checkcond Renamed test.sh option -foreign to -internet Documentation: - Removed obselete file doc/xio.help + Removed obsolete file doc/xio.help Added doc for option ipv6-join-group (ipv6-add-membership) Thanks to Martin Buck for sending the patch. @@ -607,7 +616,7 @@ Documentation: Corrections: On connect() failure and in some other situations Socat tries to get - detailled information about the error with recvmsg(). Error return of + detailed information about the error with recvmsg(). Error return of this function is now logged as Info instead of Warn. Tests of the correction of the "IP_ADD_SOURCE_MEMBERSHIP but not struct @@ -651,7 +660,7 @@ Corrections: Thanks to Gordon W.Ross for reporting and fixing this issue. Test: RESTORE_TTY - The OpenSSL client SNI parameter, when not explicitely specified, is + The OpenSSL client SNI parameter, when not explicitly specified, is derived from option commonname or rom target server name. This is not useful with IP addresses, which Socat now checks and avoids. @@ -682,7 +691,7 @@ Coding: fcntl() trace prints flags now in hexadecimal. - Stream dump options -r and -R now open their pathes with CLOEXEC to + Stream dump options -r and -R now open their paths with CLOEXEC to prevent leaking into sub processes. Test: EXEC_SNIFF @@ -981,7 +990,7 @@ Corrections: Print a message when readbytes option causes EOF The ip-recverr option had no effect. Corrected and improved its - handling of ancilliary messages, so it is able to analyze ICMP error + handling of ancillary messages, so it is able to analyze ICMP error packets (Linux only?) Setgui(), Setuid() calls in xio-progcall.c were useless. @@ -1119,7 +1128,7 @@ Porting: ai_protocol=0 and try again Test: SCTP_SERVICENAME - Per file filesystem options were still named ext2-* and depended on + Per file filesystem options were still named ext2-* and dependent on <linux/ext2_fs.h>. Now they are called fs-* and depend on <linux/fs.h>. These fs-* options are also available on old systems with ext2_fs.h @@ -1132,14 +1141,14 @@ Porting: SSL_library_init. With OPENSSL_API_COMPAT=0x10000000L the files openssl/dh.h, openssl/bn.h - must explicitely be included. + must explicitly be included. Thanks to Rosen Penev for reporting and sending a patch. Testing: test.sh now produces a list of tests that could not be performed for any reason. This helps to analyse these cases. - OpenSSL s_server appearently started to neglect TCPs half close feature. + OpenSSL s_server apparently started to neglect TCPs half close feature. Test OPENSSL_TCP4 has been changed to tolerate this. OpenSSL changed its behaviour when connection is rejected. Tests @@ -1333,7 +1342,7 @@ Corrections: Porting: OpenSSL functions TLS1_client_method() and similar are deprecated. Socat now uses recommended TLS_client_method(). The old - functions and dependend option openssl-method can still be + functions and dependent option openssl-method can still be used when configuring socat with --enable-openssl-method Shell scripts in socat distribution are now headed with: @@ -1375,7 +1384,7 @@ Testing: More corrections to test.sh: Language settings could still influence test results netstat was still required - Suppress usleep deprecated messag + Suppress usleep deprecated message Force use of IPv4 with some certificates Set timeout for UDPxMAXCHILDREN tests @@ -1528,7 +1537,7 @@ testing: docu: Corrected source of socat man page to correctly show man references - like socket(2); removed obseolete entries from See Also + like socket(2); removed obsolete entries from See Also Docu and some comments mentioned addresses SSL-LISTEN and SSL-CONNECT that do not exist (OPENSSL-LISTEN, SSL-L; and OPENNSSL-CONNECT, SSL @@ -1571,7 +1580,7 @@ security: parameters were chosen, the existence of a trapdoor that makes possible for an eavesdropper to recover the shared secret from a key exchange that uses them cannot be ruled out. - Futhermore, 1024bit is not considered sufficiently secure. + Furthermore, 1024bit is not considered sufficiently secure. Fix: generated a new 2048bit prime. Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability Research (MSVR) for finding and reporting this issue. @@ -1585,7 +1594,7 @@ security: safe functions in signal handlers that could freeze socat, allowing denial of service attacks. Many changes in signal handling and the diagnostic messages system were - applied to make the code async signal safe but still provide detailled + applied to make the code async signal safe but still provide detailed logging from signal handlers: Coded function vsnprintf_r() as async signal safe incomplete substitute of libc vsnprintf() @@ -1673,7 +1682,7 @@ corrections: Issue reported by Hendrik. Added option termios-cfmakeraw that calls cfmakeraw() and is preferred - over option raw which is now obsolote. On SysV systems this call is + over option raw which is now obsolete. On SysV systems this call is simulated by appropriate setting. Thanks to Youfu Zhang for reporting issue with option raw. @@ -1686,7 +1695,7 @@ porting: Thanks to Ross Burton and Danomi Manchego for reporting this issue. Debian Bug#764251: Set the build timestamp to a deterministic time: - support external BUILD_DATE env var to allow to build reproducable + support external BUILD_DATE env var to allow to build reproducible binaries Joachim Fenkes provided an new adapted spec file. @@ -1807,7 +1816,7 @@ porting: autoconf now prefers configure.ac over configure.in Thanks to Michael Vastola for sending a patch. - type of struct cmsghdr.cmsg is system dependend, determine it with + type of struct cmsghdr.cmsg is system dependent, determine it with configure; some more print format corrections docu: @@ -1861,7 +1870,7 @@ corrections: socket using address GOPEN. Thanks to Martin Forssen for bug report and patch. - UDP-LISTEN would alway set SO_REUSEADDR even without fork option and + UDP-LISTEN would always set SO_REUSEADDR even without fork option and when user set it to 0. Thanks to Michal Svoboda for reporting this bug. UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who @@ -2094,7 +2103,7 @@ new features: added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow - protocol independent socket handling; all parameters are explicitely + protocol independent socket handling; all parameters are explicitly specified as numbers or hex data added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, @@ -2167,7 +2176,7 @@ corrections: this bug). test: EXECSPACES in ignoreeof polling mode socat also blocked data transfer in the other - direction during the 1s wait intervalls (thanks to Jorgen Cederlof for + direction during the 1s wait intervals (thanks to Jorgen Cederlof for reporting this bug) corrected alphabetical order of options (proxy-auth) @@ -2593,7 +2602,7 @@ corrections: check for /proc at runtime, even if configure found it - src.rpm accidently supported SuSE instead of RedHat + src.rpm accidentally supported SuSE instead of RedHat ####################### V 1.3.2.0: @@ -2869,7 +2878,7 @@ solved problems and bugs: SOLVED: now uses common TCP service resolver PROBLEM: with PIPE, wrong FDs were shown for data transfer loop - SOLVED: retrieval of FDs now pays respect to PIPE pecularities + SOLVED: retrieval of FDs now pays respect to PIPE peculiarities PROBLEM: using address EXEC against an address with IGNOREEOF, socat never terminated diff --git a/CHANGES.ISO-8859-1 b/CHANGES.ISO-8859-1 deleted file mode 100644 index 9509e36..0000000 --- a/CHANGES.ISO-8859-1 +++ /dev/null @@ -1,1800 +0,0 @@ - -####################### V 1.7.3.4: - -Corrections: - Header of xiotermios_speed() declared parameter unsigned int instead of - speed_t, thus compiling failed on MacOS - Thanks to Joe Strout and others for reporting this bug. - Thanks to Andrew Childs and others for sending a patch. - - Under certain circumstances, termios options of the first address were - applied to the second address, resulting in error - "Inappropriate ioctl for device" - This affected version 1.7.3.3 only. - Test: TERMIOS_PH_ALL - Thanks to Ivan J. for reporting this issue. - - Socat failed to compile when no poll() system call was found by - configure. - Thanks to Jason White for sending a patch. - - Due to use of SSL_CTX_clear_mode() Socat failed to compile on old - systems with, e.g., OpenSSL-0.9.8. Thanks to Simon Matter and Moritz B. - for reporting this problem and sending initial patches. - - getaddrinfo() in IP4-SENDTO and IP6-SENDTO addresses failed with - "ai_socktype not supported" when protocol 6 was addressed. - The fix removes the possibility to use service names with SCTP. - Test: IP_SENDTO_6 - Thanks to S�ren for sending an initial patch. - - Under certain circumstances, Socat printed the "socket ... is at EOF" - multiple times. - Test: MULTIPLE_EOF - - Newer parts of test.sh used substitutions ${x,,*} or ${x^^*} that are - not implemented in older bash versions. - -####################### V 1.7.3.3: - -Corrections: - Makefile.in did not specify dependencies of filan on vsnprintf_r.o - and snprinterr.o - Added definition of FILAN_OBJS - Thanks to Craig Leres, Clayton Shotwell, and Chris Packham for - providing patches. - - configure option --enable-msglevel did not work with numbers - - The autoconf mechanism for determining SHIFT_OFFSET did not work when - cross compiling. - Thanks to Max Freisinger from Gentoo for sending a patch. - - Socat still depended on obsolete gethostbyname() function, thus - compiling with MUSL libc failed. - Problem reported by Kennedy33. - - The async signal safe diagnostic system used FDs 3 and 4 internally, so - use of appropriate fdin or fdout led to failures. - Test: DIAG_FDIN - Problem reported by Onur Sent�rk. - - The socket based mechanism for passing messages and signal information - from signal handler to process could reach and kill the wrong process. - Introduces functions diag_sock_pair(), diag_fork() - Thanks to Darren Zhao for analysing and reporting this problem. - - Option ipv6-join-group did not work because it was applied in the wrong - phase - Test: UDP6MULTICAST_UNIDIR - Thanks to Angus Gratton for sending a patch. - - Setting ispeed and ospeed failed for some serial devices because the - two settings were applied with two different get/set cycles, Thanks to - Alexandre Fenyo for providing an initial patch. - However, the actual fix is part of a conceptual change of the termios - module that aims for applying all changes in a single tcsetaddr call. - Fixes FreeBSD Bug 198441 - - Termios options TAB0,TAB1,TAB2,TAB3, and XTABS did not have an effect. - Thanks to Alan Walters for reporting this bug. - - Substituted cumbersom ISPEED_OFFSET mechanism for cfsetispeed() calls - - With TCP6-LISTEN and the other passive IPv6 addresses the range option - just failed: due to a bug in the syntax parser and two more bugs in - the xiocheckrange_ip6() function. - The syntax has now been changed from "[::1/128]" to "[::1]/128"! - Thanks Leah Neukirchen for sending an initial fix. - - For name resolution Socat only checked the first character of the host - name to decide if it is an IPv4 address. This was not RFC conform. This - fix removes the possibility for use of IPv4 addresses with IPv6, e.g. - TCP6:127.0.0.1:80 - Debian issue 695885 - Thanks to Nicolas Fournil for reporting this issue. - - Print a useful error message when single character options appear to be - merged in Socat invocation - Test: SOCCAT_OPT_HINT - - Fixed some docu typos. - Thanks to Travis Wellman, Thomas <tjps636>, Dan Kenigsberg, - Julian Zinn, and Simon Matter - -Porting: - OpenSSL functions TLS1_client_method() and similar are - deprecated. Socat now uses recommended TLS_client_method(). The old - functions and dependend option openssl-method can still be - used when configuring socat with --enable-openssl-method - - Shell scripts in socat distribution are now headed with: - #! /usr/bin/env bash - to make them better portable to systems without /bin/bash - Thanks to Maya Rashish for sending a patch - - RES_AAONLY, RES_PRIMARY are deprecated. You can still enable them with - configure option --enable-res-deprecated. - - New versions of OpenSSL preset SSL_MODE_AUTO_RETRY which may hang socat. - Solution: clear SSL_MODE_AUTO_RETRY when it is set. - - Renamed configure.in to configure.ac and set an appropriate symlink for - older environments. - Related Gentoo bug 426262: Warning on configure.in - Thanks to Francesco Turco for reporting that warning. - - Fixed new IPv6 range code for platforms without s6_addr32 component. - -Testing: - test.sh: Show a warning when phase-1 (insecure phase) of a security - test fails - - OpenSSL tests failed on actual Linux distributions. Measures: - Increased key lengths from 768 to 1024 bits - Added test.sh option -C to delete temp certs from prevsious runs - Provide DH-parameter in certificate in PEM - OpenSSL s_server option -verify 0 must be omitted - OpenSSL authentication method aNULL no longer works - Failure of cipher aNULL is not a failure - Failure of methods SSL3 and SSL23 is desired - - test.sh depended on ifconfig and netstat utilities which are no longer - availabie in some distributions. test.sh now checks for and prefers - ip and ss. - Thanks to Ruediger Meier for reporting this problem. - - More corrections to test.sh: - Language settings could still influence test results - netstat was still required - Suppress usleep deprecated messag - Force use of IPv4 with some certificates - Set timeout for UDPxMAXCHILDREN tests - -Git: - Added missing Config/Makefile.DragonFly-2-8-2, - Config/config.DragonFly-2-8-2.h - Removed testcert.conf (to be generated by test.sh) - -Cosmetics: - Simplified handling of missing termios defines. - -New features: - Permit combined -d options as -dd etc. - -####################### V 1.7.3.2: - -corrections: - SIGSEGV and other signals could lead to a 100% CPU loop - - Failing name resolution could lead to SIGSEGV - Thanks to Max for reporting this issue. - - Include <stddef.h> for ptrdiff_t - Thanks to Jeroen Roovers for reporting this issue. - - Building with --disable-sycls failed due to missing sslcls.h defines - - Socat hung when configured with --disable-sycls. - - Some minor corrections with includes etc. - - Option so-reuseport did not work. Thanks to Some Raghavendra Prabhu - for sending a patch. - - Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout - incorrectly assigned - Test: EXEC_NOFORK_UNIDIR - Thanks to David Reiss for reporting this problem. - - Socat exited with status 0 even when a program invoked with SYSTEM or - EXEC failed. - Tests: SYSTEM_RC EXEC_RC - Issue reported by Felix Winkelmann. - - AddressSanitizer reported a few buffer overflows (false positives). - Nevertheless fixed Socat source. - Issue reported by Hanno B�ck. - - Socat did not use option ipv6-join-group. - Test: USE_IPV6_JOIN_GROUP - Thanks to Linus L�ssing for sending a patch. - - UDP-LISTEN did not honor the max-children option. - Test: UDP4MAXCHILDREN UDP6MAXCHILDREN - Thanks to Leander Berwers for reporting this issue. - - Options so-rcvtimeo and so-sndtimeo do not work with poll()/select() - and therefore were useless. - Thanks to Steve Borenstein for reporting this issue. - - Option dhparam was documented as dhparams. Added the alias name - dhparams to fix this. - Thanks to Alexander Neumann for sending a patch. - - Options shut-down and shut-close did not work. - Thanks to Stefan Schimanski for providing a patch. - - There was a bug in printing readline log message caused by a misleading - indentation. - Thanks to Paul Wouters for reporting. - - The internal vsnprintf_r function looped or crashed on size parameter - with hexadecimal output. - - Ignore exit code of child process when it was killed by master due to - EOF - - Corrected byte order on read of IPV6_TCLASS value from ancillary - message - - Fixed type of the bool element in options. This had bug caused failures - e.g. of ignoreeof on big-endian systems when bool was not based on int. - - On systems with predefined bool type whose size differs from int some - IPv6 and TCP options (per setsockopt()) failed. - - Length of integral data in ancillary messages varies (TOS: 1 byte, - TTL: 4 bytes), the old implementation failed for TTL on big-endian - hosts. - - Fixed an issue in options processing: TUN and DNS flags had failed on - big-endian systems and the NO- forms had probable never worked. - -porting: - Type conflict between int and sig_atomic_t between declaration and - definition of diag_immediate_type and diag_immediate_exit broke - compilation on FreeBSD 10.1 with clang. Thanks to Emanuel Haupt for - reporting this bug. - - Socat failed to compile on platforms with OpenSSL without - DTLSv1_client_method or DTLSv1_server_method. - Thanks to Simon Matter for sending a patch. - - NuttX OS headers do not provide struct ip, thus socat did not compile. - Made struct ip subject to configure. - Thanks to SP for reporting this issue. - - Socat failed to compile with OpenSSL version 1.0.2d where - SSLv3_server_method and SSLv3_client_method are no longer defined. - Thanks to Mischa ter Smitten for reporting this issue and providing - a patch. - - configure checked for OpenSSL EC_KEY assuming it is a define but it - is a type, thus OpenSSL ECDHE ciphers failed even on Linux. - Thanks to Andrey Arapov for reporting this bug. - - Changes to make socat compile with OpenSSL 1.1. - Thanks to Sebastian Andrzej Siewior e.a. from the Debian team for - providing the base patch. - Debian Bug#828550 - - Make Socat compatible with BoringSSL. - Thanks to Matt Braithwaite for providing a patch. - - OpenSSL: Use RAND_status to determine PRNG state - Thanks to Adam Langley for providing a patch - - AIX-7 uses an extended O_ACCMODE that does not fit socat's internal - requirements. Thanks to Garrick Trowsdale for providing a patch - - LibreSSL support: check for OPENSSL_NO_COMP - Thanks to Bernard Spil for providing a patch - -testing: - socks4echo.sh and socks4a-echo.sh hung with new bash with read -n - - test.sh: stderr; option -v (verbose); FDOUT_ERROR description - - improved proxy.sh - it now also takes hostnames - - A few corrections in test.sh - - DTLS1 test hangs on some distributions. Test is now only performed - with OpenSSL 1.0.2 or higher. - - More corrections to test.sh that reveal a mistake with IPV6_TCLASS - -docu: - Corrected source of socat man page to correctly show man references - like socket(2); removed obseolete entries from See Also - - Docu and some comments mentioned addresses SSL-LISTEN and SSL-CONNECT - that do not exist (OPENSSL-LISTEN, SSL-L; and OPENNSSL-CONNECT, SSL - are correct). - Thanks to Zhigang Wang for reporting this issue. - - Fixed a couple of English spelling and grammar mistakes. - Thanks to Jakub Wild for sending the patches. - - NOEXPAND() was not resolved 2 times. - - More minor docu corrections - -legal: - Added contributors to copyright notices. Suggested by Matt Braithwaite. - -####################### V 1.7.3.1: - -security: - Socat security advisory 8 - A stack overflow in vulnerability was found that can be triggered when - command line arguments (complete address specifications, host names, - file names) are longer than 512 bytes. - Successful exploitation might allow an attacker to execute arbitrary - code with the privileges of the socat process. - This vulnerability can only be exploited when an attacker is able to - inject data into socat's command line. - A vulnerable scenario would be a CGI script that reads data from clients - and uses (parts of) this data as hostname for a Socat invocation. - Test: NESTEDOVFL - Credits to Takumi Akiyama for finding and reporting this issue. - - Socat security advisory 7 - MSVR-1499 - In the OpenSSL address implementation the hard coded 1024 bit DH p - parameter was not prime. The effective cryptographic strength of a key - exchange using these parameters was weaker than the one one could get by - using a prime p. Moreover, since there is no indication of how these - parameters were chosen, the existence of a trapdoor that makes possible - for an eavesdropper to recover the shared secret from a key exchange - that uses them cannot be ruled out. - Futhermore, 1024bit is not considered sufficiently secure. - Fix: generated a new 2048bit prime. - Thanks to Santiago Zanella-Beguelin and Microsoft Vulnerability - Research (MSVR) for finding and reporting this issue. - -####################### V 1.7.3.0: - -security: - Socat security advisory 6 - CVE-2015-1379: Possible DoS with fork - Fixed problems with signal handling caused by use of not async signal - safe functions in signal handlers that could freeze socat, allowing - denial of service attacks. - Many changes in signal handling and the diagnostic messages system were - applied to make the code async signal safe but still provide detailled - logging from signal handlers: - Coded function vsnprintf_r() as async signal safe incomplete substitute - of libc vsnprintf() - Coded function snprinterr() to replace %m in strings with a system error - message - Instead of gettimeofday() use clock_gettime() when available - Pass Diagnostic messages from signal handler per unix socket to the main - program flow - Use sigaction() instead of signal() for better control - Turn off nested signal handler invocations - Thanks to Peter Lobsinger for reporting and explaining this issue. - - Red Hat issue 1019975: add TLS host name checks - OpenSSL client checks if the server certificates names in - extensions/subjectAltName/DNS or in subject/commonName match the name - used to connect or the value of the openssl-commonname option. - Test: OPENSSL_CN_CLIENT_SECURITY - - OpenSSL server checks if the client certificates names in - extensions/subjectAltNames/DNS or subject/commonName match the value of - the openssl-commonname option when it is used. - Test: OPENSSL_CN_SERVER_SECURITY - - Red Hat issue 1019964: socat now uses the system certificate store with - OPENSSL when neither options cafile nor capath are used - - Red Hat issue 1019972: needs to specify OpenSSL cipher suites - Default cipherlist is now "HIGH:-NULL:-PSK:-aNULL" instead of empty to - prevent downgrade attacks - -new features: - OpenSSL addresses set couple of environment variables from values in - peer certificate, e.g.: - SOCAT_OPENSSL_X509_SUBJECT, SOCAT_OPENSSL_X509_ISSUER, - SOCAT_OPENSSL_X509_COMMONNAME, - SOCAT_OPENSSL_X509V3_SUBJECTALTNAME_DNS - Tests: ENV_OPENSSL_{CLIENT,SERVER}_X509_* - - Added support for methods TLSv1, TLSv1.1, TLSv1.2, and DTLS1 - Tests: OPENSSL_METHOD_* - - Enabled OpenSSL server side use of ECDHE ciphers. Feature suggested - by Andrey Arapov. - - Added a new option termios-rawer for ptys. - Thanks to Christian Vogelgsang for pointing me to this requirement - -corrections: - Bind with ABSTRACT commands used non-abstract namespace (Linux). - Test: ABSTRACT_BIND - Thanks to Denis Shatov for reporting this bug. - - Fixed return value of nestlex() - - Option ignoreeof on the right address hung. - Test: IGNOREEOF_REV - Thanks to Franz Fasching for reporting this bug. - - Address SYSTEM, when terminating, shut down its parent addresses, - e.g. an SSL connection which the parent assumed to still be active. - Test: SYSTEM_SHUTDOWN - - Passive (listening or receiving) addresses with empty port field bound - to a random port instead of terminating with error. - Test: TCP4_NOPORT - - configure with some combination of disable options produced config - files that failed to compile due to missing IPPROTO_TCP. - Thanks to Thierry Fournier for report and patch. - - fixed a few minor bugs with OpenSSL in configure and with messages - - Socat did not work in FIPS mode because 1024 instead of 512 bit DH prime - is required. Thanks to Zhigang Wang for reporting and sending a patch. - - Christophe Leroy provided a patch that fixes memory leaks reported by - valgrind - - Help for filan -L was bad, is now corrected to: - "follow symbolic links instead of showing their properties" - - Address options fdin and fdout were silently ignored when not applicable - due to -u or -U option. Now these combinations are caught as errors. - Test: FDOUT_ERROR - Issue reported by Hendrik. - - Added option termios-cfmakeraw that calls cfmakeraw() and is preferred - over option raw which is now obsolote. On SysV systems this call is - simulated by appropriate setting. - Thanks to Youfu Zhang for reporting issue with option raw. - -porting: - Socat included <sys/poll.h> instead of POSIX <poll.h> - Thanks to John Spencer for reporting this issue. - - Version 1.7.2.4 changed the check for gcc in configure.ac; this - broke cross compiling. The particular check gets reverted. - Thanks to Ross Burton and Danomi Manchego for reporting this issue. - - Debian Bug#764251: Set the build timestamp to a deterministic time: - support external BUILD_DATE env var to allow to build reproducable - binaries - - Joachim Fenkes provided an new adapted spec file. - - Type bool and macros Min and Max are defined by socat which led to - compile errors when they were already provided by build framework. - Thanks to Liyu Liu for providing a patch. - - David Arnstein contributed a patch for NetBSD 5.1 including stdbool.h - support and appropriate files in Config/ - - Lauri Tirkkonen contributed a patch regarding netinet/if_ether.h - on Illumos - - Changes for Openindiana: define _XPG4_2, __EXTENSIONS__, - _POSIX_PTHREAD_SEMANTICS; and minor changes - - Red Hat issue 1182005: socat 1.7.2.4 build failure missing - linux/errqueue.h - Socat failed to compile on on PPC due to new requirements for - including <linux/errqueue.h> and a weakness in the conditional code. - Thanks to Michel Normand for reporting this issue. - -doc: - In the man page the PTY example was badly formatted. Thanks to - J.F.Sebastian for sending a patch. - - Added missing CVE ids to security issues in CHANGES - -testing: - Do not distribute testcert.conf with socat source but generate it - (and new testcert6.conf) during test.sh run. - -####################### V 1.7.2.4: - -corrections: - LISTEN based addresses applied some address options, e.g. so-keepalive, - to the listening file descriptor instead of the connected file - descriptor - Thanks to Ulises Alonso for reporting this bug - - make failed after configure with non gcc compiler due to missing - include. Thanks to Horacio Mijail for reporting this problem - - configure checked for --disable-rawsocket but printed - --disable-genericsocket in the help text. Thanks to Ben Gardiner for - reporting and patching this bug - - In xioshutdown() a wrong branch was chosen after RECVFROM type addresses. - Probably no impact. - Thanks to David Binderman for reporting this issue. - - procan could not cleanly format ulimit values longer than 16 decimal - digits. Thanks to Frank Dana for providing a patch that increases field - width to 24 digits. - - OPENSSL-CONNECT with bind option failed on some systems, eg.FreeBSD, with - "Invalid argument" - Thanks to Emile den Tex for reporting this bug. - - Changed some variable definitions to make gcc -O2 aliasing checker happy - Thanks to Ilya Gordeev for reporting these warnings - - On big endian platforms with type long >32bit the range option applied a - bad base address. Thanks to hejia hejia for reporting and fixing this bug. - - Red Hat issue 1022070: missing length check in xiolog_ancillary_socket() - - Red Hat issue 1022063: out-of-range shifts on net mask bits - - Red Hat issue 1022062: strcpy misuse in xiosetsockaddrenv_ip4() - - Red Hat issue 1022048: strncpy hardening: corrected suspicious strncpy() - uses - - Red Hat issue 1021958: fixed a bug with faulty buffer/data length - calculation in xio-ascii.c:_xiodump() - - Red Hat issue 1021972: fixed a missing NUL termination in return string - of sysutils.c:sockaddr_info() for the AF_UNIX case - - fixed some typos and minor issues, including: - Red Hat issue 1021967: formatting error in manual page - - UNIX-LISTEN with fork option did not remove the socket file system entry - when exiting. Other file system based passive address types had similar - issues or failed to apply options umask, user e.a. - Thanks to Lorenzo Monti for pointing me to this issue - -porting: - Red Hat issue 1020203: configure checks fail with some compilers. - Use case: clang - - Performed changes for Fedora release 19 - - Adapted, improved test.sh script - - Red Hat issue 1021429: getgroupent fails with large number of groups; - use getgrouplist() when available instead of sequence of calls to - getgrent() - - Red Hat issue 1021948: snprintf API change; - Implemented xio_snprintf() function as wrapper that tries to emulate C99 - behaviour on old glibc systems, and adapted all affected calls - appropriately - - Mike Frysinger provided a patch that supports long long for time_t, - socklen_t and a few other libc types. - - Artem Mygaiev extended Cedril Priscals Android build script with pty code - - The check for fips.h required stddef.h - Thanks to Matt Hilt for reporting this issue and sending a patch - - Check for linux/errqueue.h failed on some systems due to lack of - linux/types.h inclusion. Thanks to Michael Vastola for sending a patch. - - autoconf now prefers configure.ac over configure.in - Thanks to Michael Vastola for sending a patch. - - type of struct cmsghdr.cmsg is system dependend, determine it with - configure; some more print format corrections - -docu: - libwrap always logs to syslog - - added actual text version of GPLv2 - -####################### V 1.7.2.3: - -security: - Socat security advisory 5 - CVE-2014-0019: socats PROXY-CONNECT address was vulnerable to a buffer - overflow with data from command line (see socat-secadv5.txt) - Credits to Florian Weimer of the Red Hat Product Security Team - -####################### V 1.7.2.2: - -security: - Socat security advisory 4 - CVE-2013-3571: - after refusing a client connection due to bad source address or source - port socat shutdown() the socket but did not close() it, resulting in - a file descriptor leak in the listening process, visible with lsof and - possibly resulting in EMFILE Too many open files. This issue could be - misused for a denial of service attack. - Full credits to Catalin Mitrofan for finding and reporting this issue. - -####################### V 1.7.2.1: - -security: - Socat security advisory 3 - CVE-2012-0219: - fixed a possible heap buffer overflow in the readline address. This bug - could be exploited when all of the following conditions were met: - 1) one of the addresses is READLINE without the noprompt and without the - prompt options. - 2) the other (almost arbitrary address) reads malicious data (which is - then transferred by socat to READLINE). - Workaround: when using the READLINE address apply option prompt or - noprompt. - Full credits to Johan Thillemann for finding and reporting this issue. - -####################### V 1.7.2.0: - -corrections: - when UNIX-LISTEN was applied to an existing file it failed as expected - but removed the file. Thanks to Bjoern Bosselmann for reporting this - problem - - fixed a bug where socat might crash when connecting to a unix domain - socket using address GOPEN. Thanks to Martin Forssen for bug report and - patch. - - UDP-LISTEN would alway set SO_REUSEADDR even without fork option and - when user set it to 0. Thanks to Michal Svoboda for reporting this bug. - - UNIX-CONNECT did not support half-close. Thanks to Greg Hughes who - pointed me to that bug - - TCP-CONNECT with option nonblock reported successful connect even when - it was still pending - - address option ioctl-intp failed with "unimplemented type 26". Thanks - to Jeremy W. Sherman for reporting and fixing that bug - - socat option -x did not print packet direction, timestamp etc; thanks - to Anthony Sharobaiko for sending a patch - - address PTY does not take any parameters but did not report an error - when some were given - - Marcus Meissner provided a patch that fixes invalid output and possible - process crash when socat prints info about an unnamed unix domain - socket - - Michal Soltys reported the following problem and provided an initial - patch: when socat was interrupted, e.g. by SIGSTOP, and resumed during - data transfer only parts of the data might have been written. - - Option o-nonblock in combination with large transfer block sizes - may result in partial writes and/or EAGAIN errors that were not handled - properly but resulted in data loss or process termination. - - Fixed a bug that could freeze socat when during assembly of a log - message a signal was handled that also printed a log message. socat - development had been aware that localtime() is not thread safe but had - only expected broken messages, not corrupted stack (glibc 2.11.1, - Ubuntu 10.4) - - an internal store for child pids was susceptible to pid reuse which - could lead to sporadic data loss when both fork option and exec address - were used. Thanks to Tetsuya Sodo for reporting this problem and - sending a patch - - OpenSSL server failed with "no shared cipher" when using cipher aNULL. - Fixed by providing temporary DH parameters. Thanks to Philip Rowlands - for drawing my attention to this issue. - - UDP-LISTEN slept 1s after accepting a connection. This is not required. - Thanks to Peter Valdemar Morch for reporting this issue - - fixed a bug that could lead to error or socat crash after a client - connection with option retry had been established - - fixed configure.in bug on net/if.h check that caused IF_NAMESIZE to be - undefined - - improved dev_t print format definition - -porting: - Cedril Priscal ported socat to Android (using Googles cross compiler). - The port includes the socat_buildscript_for_android.sh script - - added check for component ipi_spec_dst in struct in_pktinfo so - compilation does not fail on Cygwin (thanks to Peter Wagemans for - reporting this problem) - - build failed on RHEL6 due to presence of fips.h; configure now checks - for fipsld too. Thanks to Andreas Gruenbacher for reporting this - problem - - check for netinet6/in6.h only when IPv6 is available and enabled - - don't fail to compile when the following defines are missing: - IPV6_PKTINFO IPV6_RTHDR IPV6_DSTOPTS IPV6_HOPOPTS IPV6_HOPLIMIT - Thanks to Jerry Jacobs for reporting this problem (Mac OS X Lion 10.7) - - check if define __APPLE_USE_RFC_2292 helps to enable IPV6_* (MacOSX - Lion 7.1); thanks to Jerry Jacobs to reporting this problem and - proposing a solution - - fixed compiler warnings on Mac OS X 64bit. Thanks to Guy Harris for - providing the patch. - - corrections for OpenEmbedded, especially termios SHIFT values and - ISPEED/OSPEED. Thanks to John Faith for providing the patch - - minor corrections to docu and test.sh resulting from local compilation - on Openmoko SHR - - fixed sa_family_t compile error on DragonFly. Thanks to Tony Young for - reporting this issue and sending a patch. - - Ubuntu Oneiric: OpenSSL no longer provides SSLv2 functions; libutil.sh - is now bsd/libutil.h; compiler warns on vars that is only written to - -new features: - added option max-children that limits the number of concurrent child - processes. Thanks to Sam Liddicott for providing the patch. - - Till Maas added support for tun/tap addresses without IP address - - added an option openssl-compress that allows to disable the compression - feature of newer OpenSSL versions. Thanks to Michael Hanselmann for - providing this contribution (sponsored by Google Inc.) - -docu: - minor corrections in docu (thanks to Paggas) - - client process -> child process - -####################### V 1.7.1.3: - -security: - Socat security advisory 2 - CVE-2010-2799: - fixed a stack overflow vulnerability that occurred when command - line arguments (whole addresses, host names, file names) were longer - than 512 bytes. - Note that this could only be exploited when an attacker was able to - inject data into socat's command line. - Full credits to Felix Gr�bert, Google Security Team, for finding and - reporting this issue - -####################### V 1.7.1.2: - -corrections: - user-late and group-late, when applied to a pty, affected the system - device /dev/ptmx instead of the pty (thanks to Matthew Cloke for - pointing me to this bug) - - socats openssl addresses failed with "nonblocking operation did not - complete" when the peer performed a renegotiation. Thanks to Benjamin - Delpy for reporting this bug. - - info message during socks connect showed bad port number on little - endian systems due to wrong byte order (thanks to Peter M. Galbavy for - bug report and patch) - - Debian bug 531078: socat execs children with SIGCHLD ignored; corrected - to default. Thanks to Martin Dorey for reporting this bug. - -porting: - building socat on systems that predefined the CFLAGS environment to - contain -Wall failed (esp.RedHat). Thanks to Paul Wouters for reporting - this problem and to Simon Matter for providing the patch - - support for Solaris 8 and Sun Studio support (thanks to Sebastian - Kayser for providing the patches) - - on some 64bit systems a compiler warning "cast from pointer to integer - of different size" was issued on some option definitions - - added struct sockaddr_ll to union sockaddr_union to avoid "strict - aliasing" warnings (problem reported by Paul Wouters) - -docu: - minor corrections in docu - -####################### V 1.7.1.1: - -corrections: - corrected the "fixed possible SIGSEGV" fix because SIGSEGV still might - occur under those conditions. Thanks to Toni Mattila for first - reporting this problem. - - ftruncate64 cut its argument to 32 bits on systems with 32 bit long type - - socat crashed on systems without setenv() (esp. SunOS up to Solaris 9); - thanks to Todd Stansell for reporting this bug - - with unidirectional EXEC and SYSTEM a close() operation was performed - on a random number which could result in hanging e.a. - - fixed a compile problem caused by size_t/socklen_t mismatch on 64bit - systems - - docu mentioned option so-bindtodev but correct name is so-bindtodevice. - Thanks to Jim Zimmerman for reporting. - -docu changes: - added environment variables example to doc/socat-multicast.html - -####################### V 1.7.1.0: - -new features: - address options shut-none, shut-down, and shut-close allow to control - socat's half close behaviour - - with address option shut-null socat sends an empty packet to the peer - to indicate EOF - - option null-eof changes the behaviour of sockets that receive an empty - packet to see EOF instead of ignoring it - - introduced option names substuser-early and su-e, currently equivalent - to option substuser (thanks to Mike Perry for providing the patch) - -corrections: - fixed some typos and improved some comments - -####################### V 1.7.0.1: - -corrections: - fixed possible SIGSEGV in listening addresses when a new connection was - reset by peer before the socket addresses could be retrieved. Thanks to - Mike Perry for sending a patch. - - fixed a bug, introduced with version 1.7.0.0, that let client - connections with option connect-timeout fail when the connections - succeeded. Thanks to Bruno De Fraine for reporting this bug. - - option end-close "did not apply" to addresses PTY, SOCKET-CONNECT, - and most UNIX-* and ABSTRACT-* - - half close of EXEC and SYSTEM addresses did not work for pipes and - sometimes socketpair - - help displayed for some option a wrong type - - under some circumstances shutdown was called multiple times for the - same fd - -####################### V 1.7.0.0: - -new features: - new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream - mode for IPv4 and IPv6; new address options sctp-maxseg and - sctp-nodelay (suggested by David A. Madore; thanks to Jonathan Brannan - for providing an initial patch) - - new address "INTERFACE" for transparent network interface handling - (suggested by Stuart Nicholson) - - added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN, - SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow - protocol independent socket handling; all parameters are explicitely - specified as numbers or hex data - - added address options ioctl-void, ioctl-int, ioctl-intp, ioctl-string, - ioctl-bin for generic ioctl() calls. - - added address options setsockopt-int, setsockopt-bin, and - setsockopt-string for generic setsockopt() calls - - option so-type now only affects the socket() and socketpair() calls, - not the name resolution. so-type and so-prototype can now be applied to - all socket based addresses. - - new address option "escape" allows to break a socat instance even when - raw terminal mode prevents ^C etc. (feature suggested by Guido Trotter) - - socat sets environment variables SOCAT_VERSION, SOCAT_PID, SOCAT_PPID - for use in executed scripts - - socat sets environment variables SOCAT_SOCKADDR, SOCAT_SOCKPORT, - SOCAT_PEERADDR, SOCAT_PEERPORT in LISTEN type addresses (feature - suggested by Ed Sawicki) - - socat receives all ancillary messages with each received packet on - datagram related addresses. The messages are logged in raw form with - debug level, and broken down with info level. note: each type of - ancillary message must be enabled by appropriate address options. - - socat provides the contents of ancillary messages received on RECVFROM - addresses in appropriate environment variables: - SOCAT_TIMESTAMP, SOCAT_IP_DSTADDR, SOCAT_IP_IF, SOCAT_IP_LOCADDR, - SOCAT_IP_OPTIONS, SOCAT_IP_TOS, SOCAT_IP_TTL, SOCAT_IPV6_DSTADDR, - SOCAT_IPV6_HOPLIMIT, SOCAT_IPV6_TCLASS - - the following address options were added to enable ancillary messages: - so-timestamp, ip-pktinfo (not BSD), ip-recvdstaddr (BSD), ip-recverr, - ip-recvif (BSD), ip-recvopts, ip-recvtos, ip-recvttl, ipv6-recvdstopts, - ipv6-recverr, ipv6-recvhoplimit, ipv6-recvhopopts, ipv6-recvpathmtu, - ipv6-recvpktinfo, ipv6-recvrthdr, ipv6-recvtclass - - new address options ipv6-tclass and ipv6-unicast-hops set the related - socket options. - - STREAMS (UNIX System V STREAMS) can be configured with the new address - options i-pop-all and i-push (thanks to Michal Rysavy for providing a - patch) - -corrections: - some raw IP and UNIX datagram modes failed on BSD systems - - when UDP-LISTEN continued to listen after packet dropped by, e.g., - range option, the old listen socket would not be closed but a new one - created. open sockets could accumulate. - - there was a bug in ip*-recv with bind option: it did not bind, and - with the first received packet an error occurred: - socket_init(): unknown address family 0 - test: RAWIP4RECVBIND - - RECVFROM addresses with FORK option hung after processing the first - packet. test: UDP4RECVFROM_FORK - - corrected a few mistakes that caused compiler warnings on 64bit hosts - (thanks to Jonathan Brannan e.a. for providing a patch) - - EXEC and SYSTEM with stderr injected socat messages into the data - stream. test: EXECSTDERRLOG - - when the EXEC address got a string with consecutive spaces it created - additional empty arguments (thanks to Olivier Hervieu for reporting - this bug). test: EXECSPACES - - in ignoreeof polling mode socat also blocked data transfer in the other - direction during the 1s wait intervalls (thanks to Jorgen Cederlof for - reporting this bug) - - corrected alphabetical order of options (proxy-auth) - - some minor corrections - - improved test.sh script: more stable timing, corrections for BSD - - replaced the select() calls by poll() to cleanly fix the problems with - many file descriptors already open - - socat option -lf did not log to file but to stderr - - socat did not compile on Solaris when configured without termios - feature (thanks to Pavan Gadi for reporting this bug) - -porting: - socat compiles and runs on AIX with gcc (thanks to Andi Mather for his - help) - - socat compiles and runs on Cygwin (thanks to Jan Just Keijser for his - help) - - socat compiles and runs on HP-UX with gcc (thanks to Michal Rysavy for - his help) - - socat compiles and runs on MacOS X (thanks to Camillo Lugaresi for his - help) - -further changes: - filan -s prefixes output with FD number if more than one FD - - Makefile now supports datarootdir (thanks to Camillo Lugaresi for - providing the patch) - - cleanup in xio-unix.c - -####################### V 1.6.0.1: - -new features: - new make target "gitclean" - - docu source doc/socat.yo released - -corrections: - exec:...,pty did not kill child process under some circumstances; fixed - by correcting typo in xio-progcall.c (thanks to Ralph Forsythe for - reporting this problem) - - service name resolution failed due to byte order mistake - (thanks to James Sainsbury for reporting this problem) - - socat would hang when invoked with many file descriptors already opened - fix: replaced FOPEN_MAX with FD_SETSIZE - thanks to Daniel Lucq for reporting this problem. - - fixed bugs where sub processes would become zombies because the master - process did not catch SIGCHLD. this affected addresses UDP-LISTEN, - UDP-CONNECT, TCP-CONNECT, OPENSSL, PROXY, UNIX-CONNECT, UNIX-CLIENT, - ABSTRACT-CONNECT, ABSTRACT-CLIENT, SOCKSA, SOCKS4A - (thanks to Fernanda G Weiden for reporting this problem) - - fixed a bug where sub processes would become zombies because the master - process caught SIGCHLD but did not wait(). this affected addresses - UDP-RECVFROM, IP-RECVFROM, UNIX-RECVFROM, ABSTRACT-RECVFROM - (thanks to Evan Borgstrom for reporting this problem) - - corrected option handling with STDIO; usecase: cool-write - - configure --disable-pty also disabled option waitlock - - fixed small bugs on systems with struct ip_mreq without struct ip_mreqn - (thanks to Roland Illig for sending a patch) - - corrected name of option intervall to interval (old form still valid - for us German speaking guys) - - corrected some print statements and variable names - - make uninstall did not uninstall procan - - fixed lots of weaknesses in test.sh - - corrected some bugs and typos in doc/socat.yo, EXAMPLES, C comments - -further changes: - procan -c prints C defines important for socat - - added test OPENSSLEOF for OpenSSL half close - -####################### V 1.6.0.0: - -new features: - new addresses IP-DATAGRAM and UDP-DATAGRAM allow versatile broadcast - and multicast modes - - new option ip-add-membership for control of multicast group membership - - new address TUN for generation of Linux TUN/TAP pseudo network - interfaces (suggested by Mat Caughron); associated options tun-device, - tun-name, tun-type; iff-up, iff-promisc, iff-noarp, iff-no-pi etc. - - new addresses ABSTRACT-CONNECT, ABSTRACT-LISTEN, ABSTRACT-SENDTO, - ABSTRACT-RECV, and ABSTRACT-RECVFROM for abstract UNIX domain addresses - on Linux (requested by Zeeshan Ali); option unix-tightsocklen controls - socklen parameter on system calls. - - option end-close for control of connection closing allows FD sharing - by sub processes - - range option supports form address:mask with IPv4 - - changed behaviour of OPENSSL-LISTEN to require and verify client - certificate per default - - options f-setlkw-rd, f-setlkw-wr, f-setlk-rd, f-setlk-wr allow finer - grained locking on regular files - - uninstall target in Makefile (lack reported by Zeeshan Ali) - -corrections: - fixed bug where only first tcpwrap option was applied; fixed bug where - tcpwrap IPv6 check always failed (thanks to Rudolf Cejka for reporting - and fixing this bug) - - filan (and socat -D) could hang when a socket was involved - - corrected PTYs on HP-UX (and maybe others) using STREAMS (inspired by - Roberto Mackun) - - correct bind with udp6-listen (thanks to Jan Horak for reporting this - bug) - - corrected filan.c peekbuff[0] which did not compile with Sun Studio Pro - (thanks to Leo Zhadanovsky for reporting this problem) - - corrected problem with read data buffered in OpenSSL layer (thanks to - Jon Nelson for reporting this bug) - - corrected problem with option readbytes when input stream stayed idle - after so many bytes - - fixed a bug where a datagram receiver with option fork could fork two - sub processes per packet - -further changes: - moved documentation to new doc/ subdir - - new documents (kind of mini tutorials) are provided in doc/ - -####################### V 1.5.0.0: - -new features: - new datagram modes for udp, rawip, unix domain sockets - - socat option -T specifies inactivity timeout - - rewrote lexical analysis to allow nested socat calls - - addresses tcp, udp, tcp-l, udp-l, and rawip now support IPv4 and IPv6 - - socat options -4, -6 and environment variables SOCAT_DEFAULT_LISTEN_IP, - SOCAT_PREFERRED_RESOLVE_IP for control of protocol selection - - addresses ssl, ssl-l, socks, proxy now support IPv4 and IPv6 - - option protocol-family (pf), esp. for openssl-listen - - range option supports IPv6 - syntax: range=[::1/128] - - option ipv6-v6only (ipv6only) - - new tcp-wrappers options allow-table, deny-table, tcpwrap-etc - - FIPS version of OpenSSL can be integrated - initial patch provided by - David Acker. See README.FIPS - - support for resolver options res-debug, aaonly, usevc, primary, igntc, - recurse, defnames, stayopen, dnsrch - - options for file attributes on advanced filesystems (ext2, ext3, - reiser): secrm, unrm, compr, ext2-sync, immutable, ext2-append, nodump, - ext2-noatime, journal-data etc. - - option cool-write controls severeness of write failure (EPIPE, - ECONNRESET) - - option o-noatime - - socat option -lh for hostname in log output - - traffic dumping provides packet headers - - configure.in became part of distribution - - socats unpack directory now has full version, e.g. socat-1.5.0.0/ - - corrected docu of option verify - -corrections: - fixed tcpwrappers integration - initial fix provided by Rudolf Cejka - - exec with pipes,stderr produced error - - setuid-early was ignored with many address types - - some minor corrections - -####################### V 1.4.3.1: - -corrections: - PROBLEM: UNIX socket listen accepted only one (or a few) connections. - FIX: do not remove listening UNIX socket in child process - - PROBLEM: SIGSEGV when TCP part of SSL connect failed - FIX: check ssl pointer before calling SSL_shutdown - - In debug mode, show connect client port even when connect fails - -####################### V 1.4.3.0: - -new features: - socat options -L, -W for application level locking - - options "lockfile", "waitlock" for address level locking - (Stefan Luethje) - - option "readbytes" limits read length (Adam Osuchowski) - - option "retry" for unix-connect, unix-listen, tcp6-listen (Dale Dude) - - pty symlink, unix listen socket, and named pipe are per default removed - after use; option unlink-close overrides this new behaviour and also - controls removal of other socat generated files (Stefan Luethje) - -corrections: - option "retry" did not work with tcp-listen - - EPIPE condition could result in a 100% CPU loop - -further changes: - support systems without SHUT_RD etc. - handle more size_t types - try to find makedepend options with gcc 3 (richard/OpenMacNews) - -####################### V 1.4.2.0: - -new features: - option "connect-timeout" limits wait time for connect operations - (requested by Giulio Orsero) - - option "dhparam" for explicit Diffie-Hellman parameter file - -corrections: - support for OpenSSL DSA certificates (Miika Komu) - - create install directories before copying files (Miika Komu) - - when exiting on signal, return status 128+signum instead of 1 - - on EPIPE and ECONNRESET, only issue a warning (Santiago Garcia - Mantinan) - - -lu could cause a core dump on long messages - -further changes: - modifications to simplify using socats features in applications - -####################### V 1.4.1.0: - -new features: - option "wait-slave" blocks open of pty master side until a client - connects, "pty-intervall" controls polling - - option -h as synonym to -? for help (contributed by Christian - Lademann) - - filan prints formatted time stamps and rdev (disable with -r) - - redirect filan's output, so stdout is not affected (contributed by - Luigi Iotti) - - filan option -L to follow symbolic links - - filan shows termios control characters - -corrections: - proxy address no longer performs unsolicited retries - - filan -f no longer needs read permission to analyze a file (but still - needs access permission to directory, of course) - -porting: - Option dsusp - FreeBSD options noopt, nopush, md5sig - OpenBSD options sack-disable, signature-enable - HP-UX, Solaris options abort-threshold, conn-abort-threshold - HP-UX options b900, b3600, b7200 - Tru64/OSF1 options keepinit, paws, sackena, tsoptena - -further corrections: - address pty now uses ptmx as default if openpty is also available - -####################### V 1.4.0.3: - -security: - Socat security advisory 1 - CVE-2004-1484: - fix to a syslog() based format string vulnerability that can lead to - remote code execution. See advisory socat-adv-1.txt - -####################### V 1.4.0.2: - -corrections: - exec'd write-only addresses get a chance to flush before being killed - - error handler: print notice on error-exit - - filan printed wrong file type information - -####################### V 1.4.0.1: - -corrections: - socks4a constructed invalid header. Problem found, reported, and fixed - by Thomas Themel, by Peter Palfrader, and by rik - - with nofork, don't forget to apply some process related options - (chroot, setsid, setpgid, ...) - -####################### V 1.4.0.0: - -new features: - simple openssl server (ssl-l), experimental openssl trust - - new options "cafile", "capath", "key", "cert", "egd", and "pseudo" for - openssl - - new options "retry", "forever", and "intervall" - - option "fork" for address TCP improves `gender changer� - - options "sigint", "sigquit", and "sighup" control passing of signals to - sub process (thanks to David Shea who contributed to this issue) - - readline takes respect to the prompt issued by the peer address - - options "prompt" and "noprompt" allow to override readline's new - default behaviour - - readline supports invisible password with option "noecho" - - socat option -lp allows to set hostname in log output - - socat option -lu turns on microsecond resolution in log output - - -corrections: - before reading available data, check if writing on other channel is - possible - - tcp6, udp6: support hostname specification (not only IP address), and - map IP4 names to IP6 addresses - - openssl client checks server certificate per default - - support unidirectional communication with exec/system subprocess - - try to restore original terminal settings when terminating - - test.sh uses tmp dir /tmp/$USER/$$ instead of /tmp/$$ - - socks4 failed on platforms where long does not have 32 bits - (thanks to Peter Palfrader and Thomas Seyrat) - - hstrerror substitute wrote wrong messages (HP-UX, Solaris) - - proxy error message was truncated when answer contained multiple spaces - - -porting: - compiles with AIX xlc, HP-UX cc, Tru64 cc (but might not link) - -####################### V 1.3.2.2: - -corrections: - PROXY CONNECT failed when the status reply from the proxy server - contained more than one consecutive spaces. Problem reported by - Alexandre Bezroutchko - - do not SIGSEGV when proxy address fails to resolve server name - - udp-listen failed on systems where AF_INET != SOCK_DGRAM (e.g. SunOS). - Problem reported by Christoph Schittel - - test.sh only tests available features - - added missing IP and TCP options in filan analyzer - - do not apply stdio address options to both directions when in - unidirectional mode - - on systems lacking /dev/*random and egd, provide (weak) entropy from - libc random() - - -porting: - changes for HP-UX (VREPRINT, h_NETDB_INTERNAL) - - compiles on True64, FreeBSD (again), NetBSD, OpenBSD - - support for long long as st_ino type (Cygwin 1.5) - - compile on systems where pty can not be featured - -####################### V 1.3.2.1: - -corrections: - "final" solution for the ENOCHLD problem - - corrected "make strip" - - default gcc debug/opt is "-O" again - - check for /proc at runtime, even if configure found it - - src.rpm accidently supported SuSE instead of RedHat - -####################### V 1.3.2.0: - -new features: - option "nofork" connects an exec'd script or program directly - to the file descriptors of the other address, circumventing the socat - transfer engine - - support for files >2GB, using ftruncate64(), lseek64(), stat64() - - filan has new "simple" output style (filan -s) - - -porting: - options "binary" and "text" for controlling line termination on Cygwin - file system access (hint from Yang Wu-Zhou) - - fix by Yang Wu-Zhou for the Cygwin "No Children" problem - - improved support for OSR: _SVID3; no IS_SOCK, no F_GETOWN (thanks to - John DuBois) - - minor corrections to avoid warnings with gcc 3 - - -further corrections and minor improvements: - configure script is generated with autoconf 2.57 (no longer 2.52) - - configure passes CFLAGS to Makefile - - option -??? for complete list of address options and their short forms - - program name in syslog messages is derived from argv[0] - - SIGHUP now prints notice instead of error - - EIO during read of pty now gives Notice instead of Error, and - triggers EOF - - use of hstrerror() for printing resolver error messages - - setgrent() got required endgrent() - -####################### V 1.3.1.0: - -new features: - integration of Wietse Venema's tcpwrapper library (libwrap) - - with "proxy" address, option "resolve" controls if hostname or IP - address is sent in request - - option "lowport" establishes limited authorization for TCP and UDP - connections - - improvement of .spec file for RPM creation (thanks to Gerd v. Egidy) - An accompanying change in the numbering scheme results in an - incompatibility with earlier socat RPMs! - - -solved problems and bugs: - PROBLEM: socat daemon terminated when the address of a connecting - client did not match range option value instead of continue listening - SOLVED: in this case, print warning instead of error to keep daemon - active - - PROBLEM: tcp-listen with fork sometimes left excessive number of zombie - processes - SOLVED: dont assume that each exiting child process generates SIGCHLD - - when converting CRNL to CR, socat converted to NL - - -further corrections: - configure script now disables features that depend on missing files - making it more robust in "unsupported" environments - - server.pem permissions corrected to 600 - - "make install" now does not strip; use "make strip; make install" - if you like strip (suggested by Peter Bray) - -####################### V 1.3.0.1: - -solved problems and bugs: - PROBLEM: OPENSSL did not apply tcp, ip, and socket options - SOLVED: OPENSSL now correctly handles the options list - - PROBLEM: CRNL to NL and CRNL to CR conversions failed when CRNL crossed - block boundary - SOLVED: these conversions now simply strip all CR's or NL's from input - stream - - -porting: - SunOS ptys now work on x86, too (thanks to Peter Bray) - - configure looks for freeware libs in /pkgs/lib/ (thanks to Peter Bray) - - -further corrections: - added WITH_PROXY value to -V output - - added compile dependencies of WITH_PTY and WITH_PROXY - - -?? did not print option group of proxy options - - corrected syntax for bind option in docu - - corrected an issue with stdio in unidirectional mode - - options socksport and proxyport support service names - - ftp.sh script supports proxy address - - man page no longer installed with execute permissions (thanks to Peter - Bray) - - fixed a malloc call bug that could cause SIGSEGV or false "out of - memory" errors on EXEC and SYSTEM, depending on program name length and - libc. - -####################### V 1.3.0.0: - -new features: - proxy connect with optional proxy authentication - - combined hex and text dump mode, credits to Gregory Margo - - address pty applies options user, group, and perm to device - - -solved problems and bugs: - PROBLEM: option reuseport was not applied (BSD, AIX) - SOLVED: option reuseport now in phase PASTSOCKET instead of PREBIND, - credits to Jean-Baptiste Marchand - - PROBLEM: ignoreeof with stdio was ignored - SOLVED: ignoreeof now works correctly with address stdio - - PROBLEM: ftp.sh did not use user supplied password - SOLVED: ftp.sh now correctly passes password from command line - - PROBLEM: server.pem had expired - SOLVED: new server.pem valid for ten years - - PROBLEM: socks notice printed wrong port on some platforms - SOLVED: socks now uses correct byte-order for port number in notice - - -further corrections: - option name o_trunc corrected to o-trunc - - combined use of -u and -U is now detected and prevented - - made message system a little more robust against format string attacks - - -####################### V 1.2.0.0: - -new features: - address pty for putting socat behind a new pseudo terminal that may - fake a serial line, modem etc. - - experimental openssl integration - (it does not provide any trust between the peers because is does not - check certificates!) - - options flock-ex, flock-ex-nb, flock-sh, flock-sh-nb to control all - locking mechanism provided by flock() - - options setsid and setpgid now available with all address types - - option ctty (controlling terminal) now available for all TERMIOS - addresses - - option truncate (a hybrid of open(.., O_TRUNC) and ftruncate()) is - replaced by options o-trunc and ftruncate=offset - - option sourceport now available with TCP and UDP listen addresses to - restrict incoming client connections - - unidirectional mode right-to-left (-U) - - -solved problems and bugs: - PROBLEM: addresses without required parameters but an option containing - a '/' were incorrectly interpreted as implicit GOPEN address - SOLVED: if an address does not have ':' separator but contains '/', - check if the slash is before the first ',' before assuming - implicit GOPEN. - - -porting: - ptys under SunOS work now due to use of stream options - - -further corrections: - with -d -d -d -d -D, don't print debug info during file analysis - - -####################### V 1.1.0.1: - -new features: - .spec file for RPM generation - - -solved problems and bugs: - PROBLEM: GOPEN on socket did not apply option unlink-late - SOLUTION: GOPEN for socket now applies group NAMED, phase PASTOPEN - options - - PROBLEM: with unidirectional mode, an unnecessary close timeout was - applied - SOLUTION: in unidirectional mode, terminate without wait time - - PROBLEM: using GOPEN on a unix domain socket failed for datagram - sockets - SOLUTION: when connect() fails with EPROTOTYPE, use a datagram socket - - -further corrections: - - open() flag options had names starting with "o_", now corrected to "o-" - - in docu, *-listen addresses were called *_listen - - address unix now called unix-connect because it does not handle unix - datagram sockets - - in test.sh, apply global command line options with all tests - - -####################### V 1.1.0.0: - -new features: - regular man page and html doc - thanks to kromJx for prototype - - new address type "readline", utilizing GNU readline and history libs - - address option "history-file" for readline - - new option "dash" to "exec" address that allows to start login shells - - syslog facility can be set per command line option - - new address option "tcp-quickack", found in Linux 2.4 - - option -g prevents option group checking - - filan and procan can print usage - - procan prints rlimit infos - - -solved problems and bugs: - PROBLEM: raw IP socket SIGSEGV'ed when it had been shut down. - SOLVED: set eof flag of channel on shutdown. - - PROBLEM: if channel 2 uses a single non-socket FD in bidirectional mode - and has data available while channel 1 reaches EOF, the data is - lost. - SOLVED: during one loop run, first handle all data transfers and - _afterwards_ handle EOF. - - PROBLEM: despite to option NONBLOCK, the connect() call blocked - SOLVED: option NONBLOCK is now applied in phase FD instead of LATE - - PROBLEM: UNLINK options issued error when file did not exist, - terminating socat - SOLVED: failure of unlink() is only warning if errno==ENOENT - - PROBLEM: TCP6-LISTEN required numeric port specification - SOLVED: now uses common TCP service resolver - - PROBLEM: with PIPE, wrong FDs were shown for data transfer loop - SOLVED: retrieval of FDs now pays respect to PIPE pecularities - - PROBLEM: using address EXEC against an address with IGNOREEOF, socat - never terminated - SOLVED: corrected EOF handling of sigchld - - -porting: - MacOS and old AIX versions now have pty - - flock() now available on Linux (configure check was wrong) - - named pipe were generated using mknod(), which requires root under BSD - now they are generated using mkfifo - - -further corrections: - lots of address options that were "forgotten" at runtime are now - available - - option BINDTODEVICE now also called SO-BINDTODEVICE, IF - - "make install" now installs binaries with ownership 0:0 - - -####################### V 1.0.4.2: - -solved problems and bugs: - PROBLEM: EOF of one stream caused close of other stream, giving it no - chance to go down regularly - SOLVED: EOF of one stream now causes shutdown of write part of other - stream - - PROBLEM: sending mail via socks address to qmail showed that crlf - option does not work - SOLVED: socks address applies PH_LATE options - - PROBLEM: in debug mode, no info about socat and platform was issued - SOLVED: print socat version and uname output in debug mode - - PROBLEM: invoking socat with -t and no following parameters caused - SIGSEGV - SOLVED: -t and -b now check next argv entry - - PROBLEM: when opening of logfile (-lf) failed, no error was reported - and no further messages were printed - SOLVED: check result of fopen and print error message if it failed - -new features: - address type UDP-LISTEN now supports option fork: it internally applies - socket option SO_REUSEADDR so a new UDP socket can bind to port after - `accepting� a connection (child processes might live forever though) - (suggestion from Damjan Lango) - - -####################### V 1.0.4.1: - -solved problems and bugs: - PROB: assert in libc caused an endless recursion - SOLVED: no longer catch SIGABRT - - PROB: socat printed wrong verbose prefix for "right to left" packets - SOLVED: new parameter for xiotransfer() passes correct prefix - -new features: - in debug mode, socat prints its command line arguments - in verbose mode, escape special characters and replace unprintables - with '.'. Patch from Adrian Thurston. - - -####################### V 1.0.4.0: - -solved problems and bugs: - Debug output for lstat and fstat said "stat" - -further corrections: - FreeBSD now includes libutil.h - -new features: - option setsid with exec/pty - option setpgid with exec/pty - option ctty with exec/pty - TCP V6 connect test - gettimeofday in sycls.c (no use yet) - -porting: - before Gethostbyname, invoke inet_aton for MacOSX - - -####################### V 1.0.3.0: - -solved problems and bugs: - - PROB: test 9 of test.sh (echo via file) failed on some platforms, - socat exited without error message - SOLVED: _xioopen_named_early(): preset statbuf.st_mode with 0 - - PROB: test 17 hung forever - REASON: child death before select loop did not result in EOF - SOLVED: check of existence of children before starting select loop - - PROB: test 17 failed - REASON: child dead triggered EOF before last data was read - SOLVED: after child death, read last data before setting EOF - - PROB: filan showed that exec processes incorrectly had fd3 open - REASON: inherited open fd3 from main process - SOLVED: set CLOEXEC flag on pty fd in main process - - PROB: help printed "undef" instead of group "FORK" - SOLVED: added "FORK" to group name array - - PROB: fatal messages did not include severity classifier - SOLVED: added "F" to severity classifier array - - PROB: IP6 addresses where printed incorrectly - SOLVED: removed type casts to unsigned short * - -further corrections: - socat catches illegal -l modes - corrected error message on setsockopt(linger) - option tabdly is of type uint - correction for UDP over IP6 - more cpp conditionals, esp. for IP6 situations - better handling of group NAMED options with listening UNIX sockets - applyopts2 now includes last given phase - corrected option group handling for most address types - introduce dropping of unappliable options (dropopts, dropopts2) - gopen now accepts socket and unix-socket options - exec and system now accept all socket and termios options - child process for exec and system addresses with option pty - improved descriptions and options for EXAMPLES - printf format for file mode changed to "0%03o" with length spec. - added va_end() in branch of msg() - changed phase of lock options from PASTOPEN to FD - support up to four early dying processes - -structural changes: - xiosysincludes now includes sysincludes.h for non xio files - -new features: - option umask - CHANGES file - TYPE_DOUBLE, u_double - OFUNC_OFFSET - added getsid(), setsid(), send() to sycls - procan prints sid (session id) - mail.sh gets -f (from) option - new EXAMPLEs for file creation - gatherinfo.sh now tells about failures - test.sh can check for much more address/option combinations - -porting: - ispeed, ospeed for termios on FreeBSD - getpgid() conditional for MacOS 10 - added ranlib in Makefile.in for MacOS 10 - disable pty option if no pty mechanism is available (MacOS 10) - now compiles and runs on MacOS 10 (still some tests fail) - setgroups() conditional for cygwin - sighandler_t defined conditionally - use gcc option -D_GNU_SOURCE diff --git a/EXAMPLES b/EXAMPLES index 51b10ff..9ace4c4 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -67,7 +67,7 @@ $ socat \ TCP-LISTEN:8000,crlf \ SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; cat" -// A less primitive HTTP echo server that sends back not only the reqest but +// A less primitive HTTP echo server that sends back not only the request but // also server and client address and port. Might have portability issues with // echo $ socat -T 1 -d -d \ @@ -131,7 +131,7 @@ $ socat \ /////////////////////////////////////////////////////////////////////////////// // Intrusion testing -// Found an XWindow Server behind IP filters with FTP data hole? (you are +// Found an X-Window Server behind IP filters with FTP data hole? (you are // lucky!) // prepare your host: # rm -f /tmp/.X11-unix/X1 @@ -241,7 +241,7 @@ $ socat - /tmp/postoffice // Uses of filan // See what your operating system opens for you $ filan -// or if that was too detailled +// or if that was too detailed $ filan -s // See what file descriptors are passed via exec function $ socat - EXEC:"filan -s",nofork @@ -342,7 +342,7 @@ socat \ // three main versions for entering password: // 1) from your TTY; have 10 seconds to enter password: (sleep 10; echo "ls"; sleep 1) |socat - EXEC:'ssh server',pty -// 2) from XWindows (DISPLAY !); again 10 seconds +// 2) from X-Windows (DISPLAY !); again 10 seconds (sleep 10; echo "ls"; sleep 1) |socat - EXEC:'ssh server',pty,setsid // 3) from script (sleep 5; echo PASSWORD; echo ls; sleep 1) |./socat - EXEC:'ssh server',pty,setsid,ctty diff --git a/FAQ b/FAQ index 51d8c1b..d3845eb 100644 --- a/FAQ +++ b/FAQ @@ -60,7 +60,7 @@ Q: When I specify a dual address (two partial addresses linked with "!!") on the command line, I get some message "event not found", and my shell history has the line truncated. Not even protecting the '!'s with '\' helps. -A: '!' is appearently used by your shell as history expansion character. Say +A: '!' is apparently used by your shell as history expansion character. Say "set +H" and add this line to your (bash) profile. diff --git a/PORTING b/PORTING index 0571bf7..2cbb8f1 100644 --- a/PORTING +++ b/PORTING @@ -51,7 +51,7 @@ ACTIVE PHASE: . xioopts.h: enum e_optcode (sorted numerically/alphabetically by name) . xio-*.c: select the appropriate address file (e.g., xio-tcp.c for TCP-options) and make a record of type struct optdesc: opt_newoption - . xio-*.h: the declation of struct optdesc + . xio-*.h: the declaration of struct optdesc . xioopts.c: add records to struct optname optionnames for all appropriate names (sorted strictly ASCII for binary search) . filan.c: add the option to the appropriate array (sockopts, ipopts, diff --git a/README.FIPS b/README.FIPS index 0452844..2b92ea0 100644 --- a/README.FIPS +++ b/README.FIPS @@ -29,7 +29,7 @@ initializes things so after a fork, the child must reinitialize. When the ssl code detects a forks occur and if FIPS mode was enabled, it reinitializes FIPS by disabling and then enabling it again. -To produce Davids enviroment, do the following: +To produce Davids environment, do the following: To build openssl download OpenSSL 0.9.7j-fips-dev from http://www.openssl.org/source/OpenSSL-fips-1.0.tar.gz diff --git a/SECURITY b/SECURITY index 0e10075..27f295a 100644 --- a/SECURITY +++ b/SECURITY @@ -24,7 +24,7 @@ avoid accessing files in world-writable directories like /tmp * When using socat with system, exec, or in a shell script, know what you do -* With system and exec, use absolute pathes or set the path option +* With system and exec, use absolute paths or set the path option * When starting programs with socat, consider using the chroot option (this requires root, so use the substuser option too). diff --git a/configure.ac b/configure.ac index da5d4e3..3c5cc5b 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,7 @@ AC_PROG_RANLIB AC_SUBST(AR) AC_CHECK_PROG(AR, ar, ar, gar) # -# we need to explicitely call this here; otherwise, with --disable-libwrap we +# we need to explicitly call this here; otherwise, with --disable-libwrap we # fail AC_LANG_COMPILER_REQUIRE() @@ -2250,7 +2250,7 @@ AC_TRY_COMPILE([#include <resolv.h>], dnl "tcpd" "tcpwrappers" # on some platforms, raw linking with libwrap fails because allow_severity and -# deny_severity are not explicitely defined. Thus we put the libwrap part to +# deny_severity are not explicitly defined. Thus we put the libwrap part to # the end AC_MSG_CHECKING(whether to include libwrap support) AC_ARG_ENABLE(libwrap, [ --disable-libwrap disable libwrap support], diff --git a/doc/socat-genericsocket.html b/doc/socat-genericsocket.html index 0525696..2ad1440 100644 --- a/doc/socat-genericsocket.html +++ b/doc/socat-genericsocket.html @@ -10,7 +10,7 @@ <h2>Introduction</h2> <p>Beginning with version 1.7.0 socat provides means to freely control important aspects of socket handling. This allows to experiment with socket - types and protocols that are not explicitely implemented in socat. + types and protocols that are not explicitly implemented in socat. </p> <p>The related socat features fall into three major categories:<p> @@ -216,7 +216,7 @@ struct sockaddr_at { </p> <p>The address family component must be omitted from the socket address because - it is added by socat implicitely. The resulting hexadecimal representation of + it is added by socat implicitly. The resulting hexadecimal representation of the target socket address is therefore: </p> <tt>x40x00xff00xf3x00x0000000000000000</tt> @@ -287,7 +287,7 @@ struct sockaddr_at { and for bind and range options. The basis is the <tt>struct sockaddr_*</tt> for the respective address family that should be declared in the C include files. Please keep in mind that their first two bytes (<tt>sa_family</tt> and - on BSD -- <tt>sa_len</tt>) are implicitely prepended by socat.</p> +- <tt>sa_len</tt>) are implicitly prepended by socat.</p> <h4>Linux on 32bit Intel:</h4> diff --git a/doc/socat.yo b/doc/socat.yo index 6cfd907..4690543 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1301,7 +1301,7 @@ label(ADDRESS_TCP6_LISTEN)dit(bf(tt(TCP6-LISTEN:<port>))) link(ipv6only)(OPTION_IPV6_V6ONLY)nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl() label(ADDRESS_TUN)dit(bf(tt(TUN[:<if-addr>/<bits>]))) - Creates a Linux TUN/TAP device and optionally assignes it the address and + Creates a Linux TUN/TAP device and optionally assigns it the address and netmask given by the parameters. The resulting network interface is almost ready for use by other processes; socat serves its "wire side". This address requires read and write access to the tunnel cloning device, usually @@ -2150,7 +2150,7 @@ label(OPTION_SETGID)dit(bf(tt(setgid=<group>))) processing the address. This call might require root privilege. Please note that this option does not drop other group related privileges. label(OPTION_SETGID_EARLY)dit(bf(tt(setgid-early=<group>))) - Like link(setgit)(OPTION_SETGID) but is performed before opening the address. + Like link(setgid)(OPTION_SETGID) but is performed before opening the address. label(OPTION_SETUID)dit(bf(tt(setuid=<user>))) Changes the link(<user>)(TYPE_USER) (owner) of the process after processing the address. This call might require root privilege. Please note that this @@ -2203,7 +2203,7 @@ label(OPTION_NOECHO)dit(bf(tt(noecho=<pattern>))) Specifies a regular pattern for a prompt that prevents the following input line from being displayed on the screen and from being added to the history. The prompt is defined as the text that was output to the readline address - after the lastest newline character and before an input character was + after the last newline character and before an input character was typed. The pattern is a regular expression, e.g. "^[Pp]assword:.*$" or "([Uu]ser:|[Pp]assword:)". See NOEXPAND(regex(7)) for details. (link(example)(EXAMPLE_OPTION_NOECHO)) @@ -2382,7 +2382,7 @@ COMMENT(label(OPTION_SECURITYENCRYPTIONNETWORK)dit(bf(tt(securityencryptionnetwo COMMENT(label(OPTION_SECURITYENCRYPTIONTRANSPORT)dit(bf(tt(securityencryptiontransport))) Set the code(SO_SECURITY_ENCRYPTION_TRANSPORT) socket option.) COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=<pid_t>))) - Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.) + Set the SIOCSPGRP with code(ioctl()) to enable SIGIO.) COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs))) Set the code(SO_USE_IFBUFS) socket option.) label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp))) @@ -3365,7 +3365,7 @@ label(OPTION_OPENSSL_PSEUDO)dit(bf(tt(pseudo))) gathering daemon can be utilized, this option activates a mechanism for providing pseudo entropy. This is achieved by taking the current time in microseconds for feeding the libc pseudo random number generator with an - initial value. openssl is then feeded with output from NOEXPAND(random()) calls.nl() + initial value. openssl is then fed with output from NOEXPAND(random()) calls.nl() NOTE:This mechanism is not sufficient for generation of secure keys! label(OPTION_OPENSSL_COMPRESS)dit(bf(tt(compress))) Enable or disable the use of compression for a connection. Setting this to @@ -3612,10 +3612,10 @@ label(TYPE_LONG)dit(long) label(TYPE_LONGLONG)dit(long long) A number read with code(strtoll()). The value must fit into a C long long. label(TYPE_OFF)dit(off_t) - An implementation dependend signed number, usually 32 bits, read with strtol + An implementation dependent signed number, usually 32 bits, read with strtol or strtoll. label(TYPE_OFF64)dit(off64_t) - An implementation dependend signed number, usually 64 bits, read with strtol + An implementation dependent signed number, usually 64 bits, read with strtol or strtoll. label(TYPE_MODE_T)dit(mode_t) An unsigned integer, read with code(strtoul()), specifying mode (permission) diff --git a/error.h b/error.h index 9853f8a..0cc4fac 100644 --- a/error.h +++ b/error.h @@ -183,7 +183,7 @@ #define Debug18(m,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) #endif /* !(WITH_MSGLEVEL <= E_DEBUG) */ -/* message with software controlled serverity */ +/* message with software controlled severity */ #if WITH_MSGLEVEL <= E_FATAL #define Msg(l,m) msg(l,"%s",m) #define Msg1(l,m,a1) msg(l,m,a1) diff --git a/filan_main.c b/filan_main.c index 24dd5e9..d90432f 100644 --- a/filan_main.c +++ b/filan_main.c @@ -167,7 +167,7 @@ int main(int argc, const char *argv[]) { Nanosleep(&waittime, NULL); if (style == 0) { - /* this style gives detailled infos, but requires a file descriptor */ + /* This style gives detailed infos, but requires a file descriptor */ if (filename) { #if LATER /* this is just in case that S_ISSOCK does not work */ struct stat buf; diff --git a/readline-test.sh b/readline-test.sh index 26f392f..569bde6 100755 --- a/readline-test.sh +++ b/readline-test.sh @@ -36,7 +36,7 @@ $ECHO if [ "$USERNAME" != "$CREDUSER" -o "$PASSWORD" != "$CREDPASS" ]; then $ECHO "Authentication failed" >&2 - exit -1 + exit 1 fi while $ECHO "$PROMPT\c"; read -r COMMAND; do diff --git a/socat.c b/socat.c index 567cd29..3e9cc91 100644 --- a/socat.c +++ b/socat.c @@ -785,7 +785,7 @@ int socat(const char *address1, const char *address2) { int i; for (i = 0; i < NUMUNKNOWN; ++i) { if (XIO_RDSTREAM(sock1)->para.exec.pid == diedunknown[i]) { - /* child has alread died... but it might have put regular data into + /* Child has already died... but it might have put regular data into the communication channel, so continue */ Info2("child "F_pid" has already died with status %d", XIO_RDSTREAM(sock1)->para.exec.pid, statunknown[i]); @@ -828,7 +828,7 @@ int socat(const char *address1, const char *address2) { int i; for (i = 0; i < NUMUNKNOWN; ++i) { if (XIO_RDSTREAM(sock2)->para.exec.pid == diedunknown[i]) { - /* child has alread died... but it might have put regular data into + /* Child has already died... but it might have put regular data into the communication channel, so continue */ Info2("child "F_pid" has already died with status %d", XIO_RDSTREAM(sock2)->para.exec.pid, statunknown[i]); diff --git a/sysutils.c b/sysutils.c index f395e58..f25531a 100644 --- a/sysutils.c +++ b/sysutils.c @@ -580,7 +580,7 @@ int getusergroups(const char *user, gid_t *list, int *ngroups) { /* we prefer getgrouplist because it may be much faster with many groups, but it is not standard */ gid_t grp, twogrps[2]; int two = 2; - /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an abitrary supplementary group id that we then pass in a second call to getgrouplist. */ + /* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an arbitrary supplementary group id that we then pass in a second call to getgrouplist. */ grp = 0; Getgrouplist(user, grp, twogrps, &two); if (two == 1) { diff --git a/test.sh b/test.sh index 9b7bf0f..d97a850 100755 --- a/test.sh +++ b/test.sh @@ -616,7 +616,7 @@ TF="$TD/socat-q" IFS="$($ECHO ' \n\t')" if ! $SOCAT -hhh >/dev/null; then echo "Failed: $SOCAT -hhh" >&2 - exit -1 + exit 2 fi $SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF" $SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' |LC_ALL=C sort |diff "$TF" - >"$TF-diff" @@ -912,7 +912,7 @@ childprocess () { local l case "$1" in [1-9]*) ;; - *) echo "childprocess \"$1\": not a number" >&2; exit -1 ;; + *) echo "childprocess \"$1\": not a number" >&2; exit 2 ;; esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;; @@ -939,7 +939,7 @@ childpids () { if [ "X$1" = "X-r" ]; then recursive=1; shift; fi case "$1" in [1-9]*) ;; - *) echo "childpids \"$1\": not a number" >&2; exit -1 ;; + *) echo "childpids \"$1\": not a number" >&2; exit 2 ;; esac case "$UNAME" in AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;; @@ -2177,7 +2177,7 @@ N=$((N+1)) NAME=DUALSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) -TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe" +TEST="$NAME: split form of stdio ('stdin!!stdout') with simple echo via internal pipe" testecho "$N" "$NAME" "$TEST" "stdin!!stdout" "pipe" "$opts" esac N=$((N+1)) @@ -2186,7 +2186,7 @@ N=$((N+1)) NAME=DUALSHORTSTDIO case "$TESTS" in *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) -TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe" +TEST="$NAME: short split form of stdio ('-!!-') with simple echo via internal pipe" testecho "$N" "$NAME" "$TEST" "-!!-" "pipe" "$opts" esac N=$((N+1)) @@ -9292,7 +9292,7 @@ N=$((N+1)) # test: there is a bug with the readbytes option: when the socket delivered -# exacly that many bytes as specified with readbytes and the stays idle (no +# exactly that many bytes as specified with readbytes and the stays idle (no # more data, no EOF), socat waits for more data instead of generating EOF on # this in put stream. NAME=READBYTES_EOF @@ -9336,7 +9336,7 @@ N=$((N+1)) NAME=EXECPTYKILL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%pty%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*) -TEST="$NAME: exec:...,pty explicitely kills sub process" +TEST="$NAME: exec:...,pty explicitly kills sub process" # we want to check if the exec'd sub process is killed in time # for this we have a shell script that generates a file after two seconds; # it should be killed after one second, so if the file was generated the test @@ -11817,7 +11817,9 @@ N=$((N+1)) if false; then # this overflow is not reliably reproducable -# socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command line paramters when copying them into the HTTP request buffer. This could lead to a buffer overflow. +# Socat up to 2.0.0-b6 did not check the length of the PROXY-CONNECT command +# line parameters when copying them into the HTTP request buffer. This could +# lead to a buffer overflow. NAME=PROXY_ADDR_OVFL case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*) @@ -12475,7 +12477,7 @@ case "$TESTS" in TEST="$NAME: SYSTEM address does not shutdown its parents addresses" # start an OpenSSL echo server using SYSTEM:cat # start an OpenSSL client that sends data -# when the client recieves its data and terminates without error the test succeeded +# when the client receives its data and terminates without error the test succeeded # in case of the bug the client issues an error like: # SSL_connect(): error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac if ! eval $NUMCOND; then :; @@ -13139,7 +13141,7 @@ NAME=DIAG_FDIN case "$TESTS" in *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*) TEST="$NAME: test use of fdin=3" -# Use FD 3 explicitely with fdin and test if Socat passes data to executed +# Use FD 3 explicitly with fdin and test if Socat passes data to executed # program if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" @@ -13449,7 +13451,9 @@ if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then echo "$CMD" >&2 cat "$te" >&2 failed ;; - *) $PRINTF "${YELLOW}inable file system${NORMAL}\n" + *) $PRINTF "${YELLOW}unsupported file system${NORMAL}\n" + if [ "$VERBOSE" ]; then echo "$CMD"; fi + if [ "$DEBUG" ]; then cat "${te}" >&2; fi cant ;; esac elif [ $rc -ne 0 ]; then @@ -15133,7 +15137,7 @@ elif [ $rc1 -eq 139 ]; then cat "${te}" >&2 failed else - # soemthing unexpected happened + # Something unexpected happened $PRINTF "$CANT\n" echo "$CMD" cat "${te}" >&2 @@ -16755,7 +16759,7 @@ esac N=$((N+1)) -# Test the POSIX MQ feature with continuous READ and priorization on Linux +# Test the POSIX MQ feature with continuous READ and prioritization on Linux NAME=POSIXMQ_READ_PRIO case "$TESTS" in *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*) @@ -17038,7 +17042,6 @@ fi # NUMCOND ;; esac N=$((N+1)) -date "+%Y/%m/%d %H:%M:%S.%N" # Test the sigint option with SHELL address @@ -17650,7 +17653,7 @@ CMD0="$TRACE $SOCAT $opts -lp server $SRV:${ts}0,fork PIPE" # The following command is the solution: option unix-bind-tempname generates # random names (like tempnam(2)) for binding the datagram client socket; # creating the XXXXXX file makes sure that the (non abstract) clients cannot -# erronously bind there (part of the test) +# erroneously bind there (part of the test) CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind=${ts}1" touch ${ts}1.XXXXXX; CMD1="$TRACE $SOCAT $opts -lp tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind-tempname=${ts}1.XXXXXX" CMD2="$TRACE $SOCAT $opts -lp client - TCP4-CONNECT:$LOCALHOST:$PORT" @@ -20085,9 +20088,9 @@ PROXY tcp CONNECT 127.0.0.1:80 proxyport=\$PORT,crlf TCP-L crlf ################################################################################## #================================================================================= -# here come tests that might affect your systems integrity. Put normal tests +# Here come tests that might affect your systems integrity. Put normal tests # before this paragraph. -# tests must be explicitely selected by roottough or name (not number) +# Tests must be explicitly selected by roottough or name (not number) NAME=PTYGROUPLATE case "$TESTS" in diff --git a/xio-ascii.c b/xio-ascii.c index 2fb61b9..9493103 100644 --- a/xio-ascii.c +++ b/xio-ascii.c @@ -11,7 +11,7 @@ #include "xio-ascii.h" -/* for each 6 bit pattern we have an ASCII character in the arry */ +/* For each 6 bit pattern we have an ASCII character in the array */ const static int base64chars[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', diff --git a/xio-fs.c b/xio-fs.c index 1678828..5630f23 100644 --- a/xio-fs.c +++ b/xio-fs.c @@ -87,7 +87,7 @@ const struct optdesc opt_fs_noatime = { "fs-noatime", "noatime", #endif /* FS_NOATIME_FL */ /* FS_DIRTY_FL ??? */ -/* FS_COMPRBLK_FL one ore more compress clusters */ +/* FS_COMPRBLK_FL one or more compress clusters */ /* FS_NOCOMPR_FL access raw compressed data */ /* FS_ECOMPR_FL compression error */ /* FS_BTREE_FL btree format dir */ diff --git a/xio-interface.c b/xio-interface.c index d870f87..c09aec5 100644 --- a/xio-interface.c +++ b/xio-interface.c @@ -71,7 +71,7 @@ int _xioopen_interface(const char *ifname, if (ifindex(ifname, &ifidx, -1) < 0) { Error1("unknown interface \"%s\"", ifname); - ifidx = 0; /* desparate attempt to continue */ + ifidx = 0; /* desperate attempt to continue */ } if (sfd->howtoend == END_UNSPEC) @@ -276,7 +276,7 @@ int _xiointerface_apply_iff( #if HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA -/* Converts the ancillary message in *cmsg into a form useable for further +/* Converts the ancillary message in *cmsg into a form usable for further processing. Knows the specifics of common message types. On PACKET_AUXDATA it stored the ancillary data in the XFD. For other types: diff --git a/xio-ip.c b/xio-ip.c index 7b1c56e..dcc8c45 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -919,7 +919,7 @@ int xioresolve(const char *node, const char *service, } #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) -/* Converts the ancillary message in *cmsg into a form useable for further +/* Converts the ancillary message in *cmsg into a form usable for further processing. knows the specifics of common message types. These are valid for IPv4 and IPv6 Returns the number of resulting syntax elements in *num diff --git a/xio-ip6.c b/xio-ip6.c index 8bd4a53..221f01f 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -249,7 +249,7 @@ int xiocheckrange_ip6(struct sockaddr_in6 *pa, struct xiorange *range) { #if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA) /* provides info about the ancillary message: - converts the ancillary message in *cmsg into a form useable for further + converts the ancillary message in *cmsg into a form usable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff diff --git a/xio-ipapp.c b/xio-ipapp.c index 77c449e..d0c1871 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -449,7 +449,7 @@ int _xioopen_ipapp_listen_prepare( retropt_string(opts, OPT_BIND, &bindname); - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = ai_flags[0]; ai_flags2[1] = ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) diff --git a/xio-openssl.c b/xio-openssl.c index 21a571a..9a2ca62 100644 --- a/xio-openssl.c +++ b/xio-openssl.c @@ -5,7 +5,7 @@ /* this file contains the implementation of the openssl addresses */ #include "xiosysincludes.h" -#if WITH_OPENSSL /* make this address configure dependend */ +#if WITH_OPENSSL /* make this address configure dependent */ #include <openssl/conf.h> #include <openssl/x509v3.h> @@ -266,7 +266,7 @@ static int xioopen_openssl_connect( hostname = argv[1]; portname = argv[2]; if (hostname[0] == '\0') { - /* we catch this explicitely because empty commonname (peername) disables + /* We catch this explicitly because empty commonname (peername) disables commonName check of peer certificate */ Error1("%s: empty host name", argv[0]); return STAT_NORETRY; @@ -806,7 +806,7 @@ int _xioopen_openssl_listen(struct single *sfd, #if OPENSSL_VERSION_NUMBER >= 0x00908000L /* In OpenSSL 0.9.7 compression methods could be added using - * SSL_COMP_add_compression_method(3), but the implemntation is not compatible + * SSL_COMP_add_compression_method(3), but the implementation is not compatible * with the standard (RFC3749). */ static int openssl_setup_compression(SSL_CTX *ctx, char *method) diff --git a/xio-openssl.h b/xio-openssl.h index 204aca6..3570856 100644 --- a/xio-openssl.h +++ b/xio-openssl.h @@ -5,7 +5,7 @@ #ifndef __xio_openssl_included #define __xio_openssl_included 1 -#if WITH_OPENSSL /* make this address configure dependend */ +#if WITH_OPENSSL /* make this address configure dependent */ #define SSLIO_BASE 0x53530000 /* "SSxx" */ #define SSLIO_MASK 0xffff0000 diff --git a/xio-socket.c b/xio-socket.c index 6400c01..8c0b3db 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1776,7 +1776,7 @@ int xiocheckpeer(xiosingle_t *sfd, #if HAVE_STRUCT_CMSGHDR -/* converts the ancillary message in *cmsg into a form useable for further +/* Converts the ancillary message in *cmsg into a form usable for further processing. knows the specifics of common message types. returns the number of resulting syntax elements in *num returns a sequence of \0 terminated type strings in *typbuff @@ -1997,7 +1997,7 @@ int xioparserange( return -1; } /* we have parsed the address and mask; now we make sure that the stored - address has 0 where mask is 0, to simplify comparisions */ + address has 0 where mask is 0, to simplify comparisons */ switch (pf) { #if WITH_IP4 case PF_INET: diff --git a/xio-stdio.c b/xio-stdio.c index 9f8aac9..a84c61e 100644 --- a/xio-stdio.c +++ b/xio-stdio.c @@ -17,7 +17,7 @@ static int xioopen_stdio(int argc, const char *argv[], struct opt *opts, int xio static int xioopen_stdfd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); -/* we specify all option groups that we can imagine for a FD, becasue the +/* We specify all option groups that we can imagine for a FD, because the changed parsing mechanism does not allow us to check the type of FD before applying the options */ const struct addrdesc xioaddr_stdio = { "STDIO", 3, xioopen_stdio, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(NULL) }; diff --git a/xio-streams.c b/xio-streams.c index e470f3e..3be956e 100644 --- a/xio-streams.c +++ b/xio-streams.c @@ -65,7 +65,7 @@ void dummy(void) { #else /* !defined(ENABLE_APPLYOPT) */ #include "xiosysincludes.h" -#if WITH_STREAMS /* make this address configure dependend */ +#if WITH_STREAMS /* make this address configure dependent */ #include "xioopen.h" #include "xio-fd.h" diff --git a/xio-tcpwrap.c b/xio-tcpwrap.c index 26a3a1f..b8d2797 100644 --- a/xio-tcpwrap.c +++ b/xio-tcpwrap.c @@ -79,7 +79,7 @@ int xio_retropt_tcpwrap( } -/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed +/* Returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitly allowed */ int xio_tcpwrap_check( struct single *sfd, diff --git a/xio-termios.c b/xio-termios.c index 60209f7..976165d 100644 --- a/xio-termios.c +++ b/xio-termios.c @@ -501,7 +501,7 @@ int xiotermios_spec(int fd, int optcode) { #if HAVE_CFMAKERAW cfmakeraw(&_xiotermios_data.termarg); #else - /* these setting follow the Linux documenation of cfmakeraw */ + /* These settings follow the Linux documentation of cfmakeraw */ _xiotermios_data.termarg.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); _xiotermios_data.termarg.c_oflag &= ~(OPOST); diff --git a/xio-tun.c b/xio-tun.c index f66be7e..4618da4 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -120,7 +120,7 @@ static int xioopen_tun( if (retropt_bool(opts, OPT_IFF_NO_PI, &no_pi) == 0) { if (no_pi) { ifr.ifr_flags |= IFF_NO_PI; -#if 0 /* not neccessary for now */ +#if 0 /* not necessary for now */ } else { ifr.ifr_flags &= ~IFF_NO_PI; #endif @@ -139,7 +139,7 @@ static int xioopen_tun( /* we seem to need a socket for manipulating the interface */ if ((sockfd = Socket(PF_INET, SOCK_DGRAM, 0)) < 0) { Error1("socket(PF_INET, SOCK_DGRAM, 0): %s", strerror(errno)); - sockfd = sfd->fd; /* desparate fallback attempt */ + sockfd = sfd->fd; /* desperate fallback attempt */ } /*--------------------- setting interface address and netmask ------------*/ diff --git a/xio-udp.c b/xio-udp.c index d74f670..94a8947 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -550,7 +550,7 @@ int xioopen_udp_recvfrom( if (sfd->howtoend == END_UNSPEC) sfd->howtoend = END_NONE; - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0]; ai_flags2[1] = xfd->stream.para.socket.ip.ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) @@ -626,7 +626,7 @@ int xioopen_udp_recv( xioinit_ip(&pf, xioparms.default_ip); retropt_socket_pf(opts, &pf); - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = xfd->stream.para.socket.ip.ai_flags[0]; ai_flags2[1] = xfd->stream.para.socket.ip.ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) diff --git a/xio-unix.c b/xio-unix.c index b1bc04f..735b4af 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -15,7 +15,7 @@ #if WITH_UNIX -/* to avoid unneccessary runtime if () conditionals when no abstract support is +/* To avoid unnecessary runtime if () conditionals when no abstract support is compiled in (or at least to give optimizing compilers a good chance) we need a constant that can be used in C expressions */ #if WITH_ABSTRACT_UNIXSOCKET @@ -33,7 +33,7 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i /* the first free parameter is 0 for "normal" unix domain sockets, or 1 for abstract unix sockets (Linux); the second and third free parameter are - unsused */ + unused */ const struct addrdesc xioaddr_unix_connect = { "UNIX-CONNECT", 1+XIO_RDWR, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") }; #if WITH_LISTEN const struct addrdesc xioaddr_unix_listen = { "UNIX-LISTEN", 1+XIO_RDWR, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") }; diff --git a/xio.h b/xio.h index ade2d0a..05bef49 100644 --- a/xio.h +++ b/xio.h @@ -126,7 +126,7 @@ typedef struct xioparms { /* pack the description of a lock file */ typedef struct { const char *lockfile; /* name of lockfile; NULL if no locking */ - bool waitlock; /* dont't exit when already locked */ + bool waitlock; /* don't exit when already locked */ struct timespec intervall; /* polling intervall */ } xiolock_t; diff --git a/xioinitialize.c b/xioinitialize.c index b06915e..3abc8e2 100644 --- a/xioinitialize.c +++ b/xioinitialize.c @@ -175,8 +175,8 @@ static int xio_nokill(xiofile_t *sock) { return result; } -/* call this function immediately after fork() in child process */ -/* it performs some neccessary actions +/* Call this function immediately after fork() in child process */ +/* It performs some necessary actions returns 0 on success or != 0 if an error occurred */ int xio_forked_inchild(void) { int result = 0; diff --git a/xioopts.c b/xioopts.c index aa2f525..901a82b 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3342,7 +3342,7 @@ int retropt_bind(struct opt *opts, } # if WITH_IP4 || WITH_IP6 - /* Set AI_PASSIVE, except when it is explicitely disabled */ + /* Set AI_PASSIVE, except when it is explicitly disabled */ ai_flags2[0] = ai_flags[0]; ai_flags2[1] = ai_flags[1]; if (!(ai_flags2[1] & AI_PASSIVE)) diff --git a/xioopts.h b/xioopts.h index 593fc5d..1f32161 100644 --- a/xioopts.h +++ b/xioopts.h @@ -150,7 +150,7 @@ enum e_func { #define GROUP_NONE 0x00000000 #define GROUP_ADDR 0x00000000 /* options that apply to all addresses */ -#define GROUP_FD 0x00000001 /* everything applyable to a fd */ +#define GROUP_FD 0x00000001 /* everything applicable to a fd */ #define GROUP_FIFO 0x00000002 #define GROUP_CHR 0x00000004 /* not yet used? */ #define GROUP_BLK 0x00000008 From 186a323c2df59c2335088b12ab29b77b2c37ad36 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Thu, 13 Feb 2025 14:40:24 +0100 Subject: [PATCH 42/51] Improved README; explained benefit of UDP-DATAGRAM --- CHANGES | 4 ++++ README | 13 ++++++++++--- doc/socat.yo | 15 ++++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 53ef92e..1742439 100644 --- a/CHANGES +++ b/CHANGES @@ -158,6 +158,10 @@ Documentation: Corrected lots of misspelling and typos. Thanks to Mario de Weerd for reporting these issues. + Improved README file. + + Better explained benefit of UDP-DATAGRAM address type. + ####################### V 1.8.0.2: Security: diff --git a/README b/README index c48c095..0605138 100644 --- a/README +++ b/README @@ -58,8 +58,15 @@ Rocky 9 Cygwin 10.0 -install -------- +build +----- + +You need at least gcc and make. +A few libraries are required for full features: +Debian: libssl-dev libreadline-dev libwrap0-dev +Red Hat: openssl-devel readline-devel tcp_wrappers-libs +Arch Linux: openssl readline + Get the tarball and extract it: tar xzf socat.tar.gz @@ -69,7 +76,7 @@ Get the tarball and extract it: su make install # installs socat, filan, and procan in /usr/local/bin -For compiling socat, gcc (or clang) is recommended. +For compiling socat, gcc or a compatible compiler (e.g. clang) is recommended. If gcc (or a compiler with similar front end) is not available, the configure script might fail to determine some features diff --git a/doc/socat.yo b/doc/socat.yo index 4690543..9994e99 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -1429,7 +1429,8 @@ label(ADDRESS_UDP_SENDTO)dit(bf(tt(UDP-SENDTO:<host>:<port>))) link(pf)(OPTION_PROTOCOL_FAMILY). It sends packets to and receives packets from that peer socket only. This address effectively implements a datagram client. - It works well with socat UDP-RECVFROM and UDP-RECV address peers.nl() + It works well with socat UDP-RECVFROM and UDP-RECV address peers. + When the peer might send data first, link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) is preferable.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6) nl() Useful options: link(ttl)(OPTION_TTL), @@ -1467,7 +1468,8 @@ label(ADDRESS_UDP_RECVFROM)dit(bf(tt(UDP-RECVFROM:<port>))) label(NOTE_RECVFROM)Note: When the second address fails before entering the transfer loop the packet is dropped. Use option link(retry)(OPTION_RETRY) or link(forever)(OPTION_FOREVER) on the second address to avoid data loss. - nl() + When you know the peer address, link(UDP-DATAGRAM)(ADDRESS_UDP_DATAGRAM) is + preferable.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE) nl() Useful options: link(fork)(OPTION_FORK), @@ -2996,6 +2998,8 @@ label(OPTION_NOFORK)dit(bf(tt(nofork))) it() the first socat address cannot be OPENSSL or READLINE it() socat options -b, -t, -D, -l, -v, -x become useless it() for both addresses, options ignoreeof, cr, and crnl become useless + it() for both addresses, address specific end/shutdown handling (e.g., + graceful socket shutdown) and related options become useless it() for the second address (the one with option nofork), options append, metaCOMMENT(async,) cloexec, flock, user, group, mode, nonblock, perm-late, setlk, and setpgid cannot be applied. Some of these could be @@ -3543,7 +3547,8 @@ label(TYPE_COMMAND_LINE)dit(command-line) A string specifying a program name and its arguments, separated by single spaces. label(TYPE_DATA)dit(data) - This is a more general data specification. The given text string contains + This is a more general data specification, "dalan" (low level data + description language). The given text string contains information about the target data type and value. Generally a leading character specifies the type of the following data item. In its specific context a default data type may exist.nl() @@ -3559,12 +3564,12 @@ label(TYPE_DATA)dit(data) dit(b) A signed byte (signed char).nl() dit(B) An unsigned byte (unsigned char).nl() dit(x) Following is an even number of hex digits, stored as sequence of - bytes.nl() + bytes, the data length is the resulting number of bytes.nl() Example: bf(x7f000001) (IP address 127.0.0.1) dit(") Following is a string that is used with the common conversions \n \r \t \f \b \a \e \0; the string must be closed with '"'. Please note that the quotes and backslashes need to be escaped from shell and socat() - conversion.nl() + conversion. No implicit \0 is appended.nl() Example: bf("Hello world!\n") dit(') A single char, with the usual conversions. Please note that the quotes and backslashes need to be escaped from shell and socat() conversion. From 48f3341d8208264f38889702edde846f2178e61f Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 17 Feb 2025 20:30:26 +0100 Subject: [PATCH 43/51] Use correct IPPROTO with CONNECT --- CHANGES | 3 +++ xio-ip.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGES b/CHANGES index 1742439..92995e6 100644 --- a/CHANGES +++ b/CHANGES @@ -87,6 +87,9 @@ Corrections: Fixed preprocessor directives in macro invocation. Thanks to Mario de Weerd for reporting this issue. + CONNECT addresses could use a wrong IPPROTO when getaddrinfo() does not + support the selected one (at least on Debian-4 with SCTP). + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/xio-ip.c b/xio-ip.c index dcc8c45..a2ca953 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -459,6 +459,7 @@ int _xiogetaddrinfo(const char *node, const char *service, #else /* HAVE_PROTOTYPE_LIB_getipnodebyname || nothing */ struct hostent *host; #endif + bool restore_proto = false; int error_num; Debug8("_xiogetaddrinfo(node=\"%s\", service=\"%s\", family=%d, socktype=%d, protoco=%d, ai_flags={0x%04x/0x%04x} }, res=%p", @@ -585,6 +586,7 @@ int _xiogetaddrinfo(const char *node, const char *service, return EAI_SERVICE; } /* Probably unsupported protocol (e.g. UDP-Lite), fallback to 0 */ + restore_proto = true; hints.ai_protocol = 0; continue; } @@ -613,6 +615,14 @@ int _xiogetaddrinfo(const char *node, const char *service, #endif /* WITH_MSGLEVEL <= E_DEBUG */ } + if (restore_proto) { + struct addrinfo *record = *res; + while (record) { + record->ai_protocol = protocol; + record = record->ai_next; + } + } + #elif HAVE_PROTOTYPE_LIB_getipnodebyname /* !HAVE_GETADDRINFO */ if (node != NULL) { From f0b30f38596ef9b4d33b74fce4dcaf914e651f14 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 17 Feb 2025 20:32:06 +0100 Subject: [PATCH 44/51] Fixes for FreeBSD-15 (DCCP) --- CHANGES | 2 ++ config.h.in | 3 +++ configure.ac | 36 ++++++++++++++++++++++++------------ sysincludes.h | 3 +++ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 92995e6..26bdd28 100644 --- a/CHANGES +++ b/CHANGES @@ -140,6 +140,8 @@ Porting: OpenSSL-3 loudly deprecates some functions or macros, replace a first bunch of them. + Fixes for FreeBSD-15 (DCCP) + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/config.h.in b/config.h.in index 39061f1..cd2fdeb 100644 --- a/config.h.in +++ b/config.h.in @@ -288,6 +288,9 @@ /* Define if you have the <linux/if_tun.h> header file. */ #undef HAVE_LINUX_IF_TUN_H +/* Define if you have the <netinet/dccp.h> header file. */ +#undef HAVE_NETINET_DCCP_H + /* Define if you have the <linux/dccp.h> header file. */ #undef HAVE_LINUX_DCCP_H diff --git a/configure.ac b/configure.ac index 3c5cc5b..f36a27b 100644 --- a/configure.ac +++ b/configure.ac @@ -409,21 +409,33 @@ AC_ARG_ENABLE(dccp, [ --disable-dccp disable DCCP support], [AC_MSG_RESULT(yes); WITH_DCCP=1 ]) if test -n "$WITH_DCCP"; then -AC_MSG_CHECKING(for IPPROTO_DCCP) -AC_CACHE_VAL(sc_cv_define_ipproto_dccp, -[AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], -[IPPROTO_DCCP;], -[sc_cv_define_ipproto_dccp=yes], -[sc_cv_define_ipproto_dccp=no])]) -AC_MSG_RESULT($sc_cv_define_ipproto_dccp) -if test $sc_cv_define_ipproto_dccp = yes; then - AC_DEFINE(WITH_DCCP) + AC_CHECK_HEADER(netinet/dccp.h, + AC_DEFINE(HAVE_NETINET_DCCP_H)) AC_CHECK_HEADER(linux/dccp.h, AC_DEFINE(HAVE_LINUX_DCCP_H)) -else - AC_MSG_WARN([IPPROTO_DCCP undefined, disabling DCCP support]) fi +if test -n "$WITH_DCCP"; then + AC_MSG_CHECKING(for IPPROTO_DCCP) + AC_CACHE_VAL(sc_cv_define_ipproto_dccp, + [AC_TRY_COMPILE([#include <sys/types.h> + #include <netinet/in.h>], + [IPPROTO_DCCP;], + [sc_cv_define_ipproto_dccp=yes], + [sc_cv_define_ipproto_dccp=no; WITH_DCCP=])]) + AC_MSG_RESULT($sc_cv_define_ipproto_dccp) +fi +if test -n "$WITH_DCCP"; then + AC_MSG_CHECKING(for SOCK_DCCP) + AC_CACHE_VAL(sc_cv_define_sock_dccp, + [AC_TRY_COMPILE([#include <sys/types.h> + #include <netinet/in.h>], + [SOCK_DCCP;], + [sc_cv_define_sock_dccp=yes], + [sc_cv_define_sock_dccp=no; WITH_DCCP=])]) + AC_MSG_RESULT($sc_cv_define_sock_dccp) +fi +if test -n "$WITH_DCCP"; then + AC_DEFINE(WITH_DCCP) fi AC_MSG_CHECKING(whether to include vsock support) diff --git a/sysincludes.h b/sysincludes.h index 25a2309..a8e60be 100644 --- a/sysincludes.h +++ b/sysincludes.h @@ -150,6 +150,9 @@ #if HAVE_LINUX_IF_TUN_H #include <linux/if_tun.h> #endif +#if HAVE_NETINET_DCCP_H +#include <netinet/dccp.h> +#endif #if HAVE_LINUX_DCCP_H #include <linux/dccp.h> #endif From 9269897babb8158bd948929b575837c75ea06bdc Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 17 Feb 2025 20:33:18 +0100 Subject: [PATCH 45/51] Fix for compiling on Solaris-11 --- CHANGES | 2 ++ xio-ip.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 26bdd28..24ae7d5 100644 --- a/CHANGES +++ b/CHANGES @@ -142,6 +142,8 @@ Porting: Fixes for FreeBSD-15 (DCCP) + Fix for compiling on Solaris-11 + Testing: test.sh produces file results.txt with columns of test numbers, names, and results. diff --git a/xio-ip.c b/xio-ip.c index a2ca953..2b7deaf 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -1091,7 +1091,7 @@ int xiolog_ancillary_ip( cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1; /*!!!*/ break; -#if XIO_ANCILLARY_TYPE_SOLARIS +#if defined(IP_RECVTOS) && XIO_ANCILLARY_TYPE_SOLARIS case IP_RECVTOS: #else case IP_TOS: From 436d764029abf32cdf57f07e0b3af2986fc0c312 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Mon, 17 Feb 2025 20:39:06 +0100 Subject: [PATCH 46/51] Small fixes with tests, logs, comments, and doc --- CHANGES | 6 ++++-- doc/socat.yo | 26 +++++++++++++++----------- socat-mux.sh | 2 +- test.sh | 29 ++++++++++++++--------------- xio-shell.c | 2 +- xioopen.c | 2 +- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/CHANGES b/CHANGES index 24ae7d5..81a78a4 100644 --- a/CHANGES +++ b/CHANGES @@ -159,6 +159,8 @@ Testing: Newer Linux distributions now deprecate usleep; replaced it in test.sh + UDPLITE4STREAM was trice, changed one of them to UDPLITE6STREAM. + Documentation: Removed obsolete CHANGES.ISO-8859-1 file. @@ -1035,11 +1037,11 @@ Corrections: Under certain conditions OpenSSL stream connections, in particular bulk data transfer in unidirectional mode, failed during transfer or near - its with Connection reset by peer on receiver side. + its end with Connection reset by peer on receiver side. This happened with Socat versions 1.7.3.3 to 1.7.4.0. Reasons were lazy SSL shutdown handling on the sender side in combination with SSL_MODE_AUTO_RETRY turned off. - Fix: After SSH_shutdown but before socket shutdown call SSL_read() + Fix: After SSL_shutdown() but before socket shutdown call SSL_read() Test: OPENSSL_STREAM_TO_SERVER Fixes Red Hat issue 1870279. diff --git a/doc/socat.yo b/doc/socat.yo index 9994e99..3482e2a 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -774,8 +774,8 @@ label(ADDRESS_SOCKETPAIR)dit(bf(tt(SOCKETPAIR))) See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE) label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>))) - Opens the specified POSIX message queue and reads messages (packets). It - keeps the boundaries.nl() + Opens or creates the specified POSIX message queue and reads messages + (packets). It keeps the packet boundaries.nl() This is a read-only address, see options link(-u)(option_u) and link(-U)(option_U) and link(dual addresses)(ADDRESS_DUAL).nl() Socat() provides this address type only on Linux because POSIX MQ is based @@ -791,7 +791,8 @@ label(ADDRESS_POSIXMQ_READ)dit(bf(tt(POSIXMQ-READ:/<mqueue>))) label(ADDRESS_POSIXMQ_RECEIVE)dit(bf(tt(POSIXMQ-RECEIVE:/<mqueue>))) dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) - Opens the specified POSIX message queue and reads one message (packet).nl() + Opens or creates the specified POSIX message queue and reads one message + (packet).nl() This is a read-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) for more info.nl() Example: link(POSIX MQ recv with fork)(EXAMPLE_POSIXMQ_RECV_FORK)nl() @@ -806,12 +807,14 @@ dit(bf(tt(POSIXMQ-RECV:/<mqueue>))) link(umask)(OPTION_UMASK) label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) - Opens the specified POSIX message queue and writes messages (packets).nl() + Opens or creates the specified POSIX message queue and writes messages + (packets).nl() This is a write-only address. See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) for more info.nl() (link(Example)(EXAMPLE_POSIXMQ_SEND))nl() Useful options: link(posixmq-priority)(OPTION_POSIXMQ_PRIORITY), + link(posixmq-flush)(OPTION_POSIXMQ_FLUSH), link(fork)(OPTION_FORK), link(max-children)(OPTION_MAX_CHILDREN), link(unlink-early)(OPTION_UNLINK_EARLY), @@ -822,8 +825,8 @@ label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) label(ADDRESS_POSIXMQ_BIDIRECTIONAL)dit(bf(tt(POSIXMQ-BIDIRECTIONAL:/mqueue))) dit(bf(tt(POSIXMQ:/mqueue))) - Opens the specified POSIX message queue in read and/or write mode depending - on context, then reads and/or writes messages (packets). + Opens or creates the specified POSIX message queue in read and/or write mode + depending on context, then reads and/or writes messages (packets). In bidirectional mode this is just another echo service.nl() See link(POSIXMQ-READ)(ADDRESS_POSIXMQ_READ) and link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND) for more info. @@ -2180,8 +2183,8 @@ label(OPTION_SETSID)dit(bf(tt(setsid))) Makes the process the leader of a new session (link(example)(EXAMPLE_OPTION_SETSID)). label(OPTION_NETNS)dit(bf(tt(netns=<net-namespace-name>))) Before opening the address it tries to switch to the named network namespace. - After opening the address it switches back to the previous namespace. - (link(Example with TCP forwarder)(EXAMPLE_OPTION_NETNS), + After opening the address it switches back to the previous namespace + (link(example with TCP forwarder)(EXAMPLE_OPTION_NETNS), link(example with virtual network connection)(EXAMPLE_TUN_NETNS)).nl() Only on Linux; requires root; use option tt(--experimental).nl() enddit() @@ -2547,7 +2550,8 @@ dit(bf(tt(ipv6-join-source-group=<multicast-address:interface-index:source-addre IPv4 variant. The option takes the IP address of the multicast group, info about the desired network interface and the source IP address of the multicast traffic. The indices of active network interfaces can be shown - using the utility procan(). + using the utility procan().nl() + This feature is experimental. label(OPTION_IP_MULTICAST_IF) dit(bf(tt(ip-multicast-if=<hostname>))) Specifies hostname or address of the network interface to be used for @@ -3520,11 +3524,11 @@ label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush)))) label(OPTION_POSIXMQ_MAXMSG)dit(bf(tt(posixmq-maxmsg (mq-maxmsg)))) Sets the maxmsg parameter of the POSIX message queue when creating it. Note: You need root or CAP_SYS_RESOURCE to exceed the default value - (<tt>/proc/sys/fs/mqueue/msg_default</tt>). + (code(/proc/sys/fs/mqueue/msg_default)). label(OPTION_POSIXMQ_MSGSIZE)dit(bf(tt(posixmq-msgsize (mq-msgsize)))) Sets the msgsize parameter of the POSIX message queue when creating it. Note: You need root or CAP_SYS_RESOURCE to exceed the default value - (<tt>/proc/sys/fs/mqueue/msgsize_default</tt>). + (code(/proc/sys/fs/mqueue/msgsize_default)). enddit() diff --git a/socat-mux.sh b/socat-mux.sh index 8cea73e..204cd89 100755 --- a/socat-mux.sh +++ b/socat-mux.sh @@ -2,7 +2,7 @@ # Copyright Gerhard Rieger and contributors (see file CHANGES) # Published under the GNU General Public License V.2, see file COPYING -# Shell script to build a many-to-one, one-to-all communication +# Shell script to establish many-to-one, one-to-all communications. # It starts two Socat instances that communicate via IPv4 broadcast, # the first of which forks a child process for each connected client. diff --git a/test.sh b/test.sh index d97a850..448f18e 100755 --- a/test.sh +++ b/test.sh @@ -296,7 +296,7 @@ FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print [ "$DEFS" ] && echo "FOPEN_MAX=\"$FOPEN_MAX\"" >&2 PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)" [ "$DEFS" ] && echo "PF_INET6=\"$PF_INET6\"" >&2 -TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)" +TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |{ read _ _ v; echo "$v"; })" [ "$DEFS" ] && echo "TIOCEXCL=\"$TIOCEXCL\"" >&2 SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)" [ "$DEFS" ] && echo "SOL_SOCKET=\"$SOL_SOCKET\"" >&2 @@ -715,7 +715,6 @@ numCANT=0 listOK= listFAIL= listCANT= -namesFAIL= ok () { numOK=$((numOK+1)) @@ -762,7 +761,7 @@ testecho () { #echo "$da" |$cmd >"$tf" 2>"$te" { sleep $T; echo "$da"; sleep $T; } | { $TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc"; } & pid1=$! - #sleep 5 && kill $rc1 2>/dev/null & + #sleep 5 && kill $pid1 2>/dev/null & # rc2=$! wait $pid1 # kill $rc2 2>/dev/null @@ -17969,7 +17968,7 @@ N=$((N+1)) NAME=UDPLITE4STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*) -TEST="$NAME: echo via connection to UDP-Lite V4 socket" +TEST="$NAME: echo via connection to UDP-Lite IPv4 socket" if ! eval $NUMCOND; then :; elif ! cond=$(checkconds \ "" \ @@ -18029,7 +18028,7 @@ N=$((N+1)) NAME=UDPLITE4STREAM case "$TESTS" in *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*) -TEST="$NAME: echo via connection to UDP-Lite V4 socket" +TEST="$NAME: echo via connection to UDP-Lite IPv4 socket" if ! eval $NUMCOND; then :; elif ! cond=$(checkconds \ "" \ @@ -18086,19 +18085,19 @@ esac N=$((N+1)) -NAME=UDPLITE4STREAM +NAME=UDPLITE6STREAM case "$TESTS" in -*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*) -TEST="$NAME: echo via connection to UDP-Lite V4 socket" +*%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udplite%*|*%$NAME%*) +TEST="$NAME: echo via connection to UDP-Lite IPv6 socket" if ! eval $NUMCOND; then :; elif ! cond=$(checkconds \ "" \ "" \ "" \ - "IP4 UDPLITE LISTEN STDIO PIPE" \ - "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \ + "IP6 UDPLITE LISTEN STDIO PIPE" \ + "UDPLITE6-LISTEN PIPE STDIO UDPLITE6" \ "so-reuseaddr" \ - "udplite4" ); then + "udplite6" ); then $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N cant else @@ -18106,14 +18105,14 @@ else te="$td/test$N.stderr" tdiff="$td/test$N.diff" tsl=$PORT - ts="$LOCALHOST:$tsl" + ts="$LOCALHOST6:$tsl" da="test$N $(date) $RANDOM" - CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE" - CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts" + CMD1="$TRACE $SOCAT $opts UDPLITE6-LISTEN:$tsl,$REUSEADDR PIPE" + CMD2="$TRACE $SOCAT $opts - UDPLITE6:$ts" printf "test $F_n $TEST... " $N $CMD1 >"$tf" 2>"${te}1" & pid1=$! - waitudplite4port $tsl 1 + waitudplite6port $tsl 1 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" rc2=$? kill $pid1 2>/dev/null; wait diff --git a/xio-shell.c b/xio-shell.c index 8a41e21..a06358b 100644 --- a/xio-shell.c +++ b/xio-shell.c @@ -81,7 +81,7 @@ static int xioopen_shell( Setenv("SHELL", shellpath, 1); Info1("executing shell command \"%s\"", string); - Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL", + Debug3("execl(\"%s\", \"%s\", \"-c\", \"%s\", NULL)", shellpath, shellname, string); result = execl(shellpath, shellname, "-c", string, (char *)NULL); if (result != 0) { diff --git a/xioopen.c b/xioopen.c index 45fe9fa..c83455c 100644 --- a/xioopen.c +++ b/xioopen.c @@ -731,7 +731,7 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { if (applyopts_single(sfd, sfd->opts, PH_OFFSET) < 0) return -1; -#if WITH_NAMESPACES +#if WITH_NAMESPACES /* netns */ if ((save_netfd = xio_apply_namespace(sfd->opts)) < 0) return -1; #endif /* WITH_NAMESPACES */ From b57d8668ec95eb0a0c84675a7238f89fb1a9d2fd Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Tue, 18 Feb 2025 12:34:15 +0100 Subject: [PATCH 47/51] Added POSIXMQ-WRITE; warn on maxmsg,msgsize failure; doc --- CHANGES | 6 ++++++ doc/socat.yo | 13 +++++++------ xio-posixmq.c | 36 +++++++++++++++++++++++++----------- xio-posixmq.h | 1 + xioopen.c | 1 + 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index 81a78a4..a563018 100644 --- a/CHANGES +++ b/CHANGES @@ -119,6 +119,12 @@ Features: Added generic options setsockopt-socket and setsockopt-connected that are applied after socket() or when connected. + POSIXMQ addresses now print a warning when options posixmq-maxmsg or + posixmq-msgsize were not applied. + + New address POSIXMQ-WRITE does the same as POSIXMQ-SEND, as counterpart + of POSIXMQ-READ. + Building: Disabling certain features during configure could break build process. diff --git a/doc/socat.yo b/doc/socat.yo index 3482e2a..106686a 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -823,6 +823,9 @@ label(ADDRESS_POSIXMQ_SEND)dit(bf(tt(POSIXMQ-SEND:/<mqueue>))) link(o-excl)(OPTION_O_EXCL), link(umask)(OPTION_UMASK) +label(ADDRESS_POSIXMQ_WRITE)dit(bf(tt(POSIXMQ-WRITE:/<mqueue>))) + Does the same as link(POSIXMQ-SEND)(ADDRESS_POSIXMQ_SEND). + label(ADDRESS_POSIXMQ_BIDIRECTIONAL)dit(bf(tt(POSIXMQ-BIDIRECTIONAL:/mqueue))) dit(bf(tt(POSIXMQ:/mqueue))) Opens or creates the specified POSIX message queue in read and/or write mode @@ -3522,13 +3525,11 @@ label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush)))) "Consumes" (drops) all messages currently in the queue before starting transfers. label(OPTION_POSIXMQ_MAXMSG)dit(bf(tt(posixmq-maxmsg (mq-maxmsg)))) - Sets the maxmsg parameter of the POSIX message queue when creating it. - Note: You need root or CAP_SYS_RESOURCE to exceed the default value - (code(/proc/sys/fs/mqueue/msg_default)). + Sets the maxmsg parameter of the POSIX message queue when creating it.nl() + Note: This option applies only when the queue does not already exist. label(OPTION_POSIXMQ_MSGSIZE)dit(bf(tt(posixmq-msgsize (mq-msgsize)))) - Sets the msgsize parameter of the POSIX message queue when creating it. - Note: You need root or CAP_SYS_RESOURCE to exceed the default value - (code(/proc/sys/fs/mqueue/msgsize_default)). + Sets the msgsize parameter of the POSIX message queue when creating it.nl() + Note: This option applies only when the queue does not already exist. enddit() diff --git a/xio-posixmq.c b/xio-posixmq.c index da3bdb3..6fb969f 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -24,6 +24,7 @@ const struct addrdesc xioaddr_posixmq_bidir = { "POSIXMQ-BIDIRECTIONAL", 1+XIO const struct addrdesc xioaddr_posixmq_read = { "POSIXMQ-READ", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY, XIO_RDONLY, 0, 0 HELP(":<mqname>") }; const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE", 1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") }; const struct addrdesc xioaddr_posixmq_send = { "POSIXMQ-SEND", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; +const struct addrdesc xioaddr_posixmq_write = { "POSIXMQ-WRITE", 1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_OPEN|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD, XIO_WRONLY, 0, 0 HELP(":<mqname>") }; const struct optdesc opt_posixmq_priority = { "posixmq-priority", "mq-prio", OPT_POSIXMQ_PRIORITY, GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 }; const struct optdesc opt_posixmq_flush = { "posixmq-flush", "mq-flush", OPT_POSIXMQ_FLUSH, GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC, 0, 0, 0 }; @@ -49,6 +50,8 @@ static int xioopen_posixmq( bool opt_unlink_early = false; bool nonblock = 0; bool flush = false; + long maxmsg; + long msgsize; struct mq_attr attr = { 0 }; bool setopts = false; int oflag; @@ -110,13 +113,13 @@ static int xioopen_posixmq( #endif retropt_mode(opts, OPT_PERM, &opt_mode); retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush); - retropt_long(opts, OPT_POSIXMQ_MAXMSG, &attr.mq_maxmsg) || + retropt_long(opts, OPT_POSIXMQ_MAXMSG, &maxmsg) || (setopts = true); - retropt_long(opts, OPT_POSIXMQ_MSGSIZE, &attr.mq_msgsize) || + retropt_long(opts, OPT_POSIXMQ_MSGSIZE, &msgsize) || (setopts = true); - /* When only one of mq-maxmsg and mq-msgsize options has been provided, - we must nevertheless set the other option value in strucht mq_attr. + /* When just one of mq-maxmsg and mq-msgsize options has been provided, + we must nevertheless set the other option value in struct mq_attr. For this we have to find the default, read it from /proc fs */ if (setopts) { int pfd; @@ -125,7 +128,7 @@ static int xioopen_posixmq( char buff[21]; /* fit a 64bit num in decimal */ ssize_t bytes; - if (attr.mq_maxmsg == 0) { + if (maxmsg == 0) { if ((pfd = Open(PROC_MAXMSG, O_RDONLY, 0)) < 0) { Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MAXMSG, strerror(errno)); } else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) { @@ -133,12 +136,12 @@ static int xioopen_posixmq( pfd, PROC_MAXMSG, sizeof(buff)-1, strerror (errno)); Close(pfd); } else { - sscanf(buff, "%ld", &attr.mq_maxmsg); + sscanf(buff, "%ld", &maxmsg); Close(pfd); } } - if (attr.mq_msgsize == 0) { + if (msgsize == 0) { if ((pfd = Open(PROC_MSGSIZE, O_RDONLY, 0)) < 0) { Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MSGSIZE, strerror(errno)); } else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) { @@ -146,7 +149,7 @@ static int xioopen_posixmq( pfd, PROC_MSGSIZE, sizeof(buff)-1, strerror (errno)); Close(pfd); } else { - sscanf(buff, "%ld", &attr.mq_msgsize); + sscanf(buff, "%ld", &msgsize); Close(pfd); } } @@ -181,10 +184,13 @@ static int xioopen_posixmq( } /* Now open the message queue */ - if (setopts) + if (setopts) { + attr.mq_maxmsg = maxmsg; + attr.mq_msgsize = msgsize; Debug8("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} )", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); - else + } else { Debug4("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL)", argv[0], name, oflag, opt_mode); + } mqd = mq_open(name, oflag, opt_mode, setopts ? &attr : NULL); _errno = errno; Debug1("mq_open() -> %d", mqd); @@ -206,8 +212,16 @@ static int xioopen_posixmq( mq_close(mqd); return STAT_NORETRY; } - Info5("POSIXMQ queue \"%s\": flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld", + Info5("POSIXMQ queue \"%s\" attrs: { flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld }", name, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); + if (setopts) { + if (attr.mq_maxmsg != maxmsg) + Warn2("mq_open(): requested maxmsg=%ld, but result is %ld", + maxmsg, attr.mq_maxmsg); + if (attr.mq_msgsize != msgsize) + Warn2("mq_open(): requested msgsize=%ld, but result is %ld", + msgsize, attr.mq_msgsize); + } if (!dofork && !oneshot) { return STAT_OK; diff --git a/xio-posixmq.h b/xio-posixmq.h index 4779f1a..adf827b 100644 --- a/xio-posixmq.h +++ b/xio-posixmq.h @@ -9,6 +9,7 @@ extern const struct addrdesc xioaddr_posixmq_bidir; extern const struct addrdesc xioaddr_posixmq_read; extern const struct addrdesc xioaddr_posixmq_receive; extern const struct addrdesc xioaddr_posixmq_send; +extern const struct addrdesc xioaddr_posixmq_write; extern const struct optdesc opt_posixmq_maxmsg; extern const struct optdesc opt_posixmq_msgsize; diff --git a/xioopen.c b/xioopen.c index c83455c..30ec859 100644 --- a/xioopen.c +++ b/xioopen.c @@ -183,6 +183,7 @@ const struct addrname addressnames[] = { { "POSIXMQ-RECEIVE", &xioaddr_posixmq_receive }, { "POSIXMQ-RECV", &xioaddr_posixmq_receive }, { "POSIXMQ-SEND", &xioaddr_posixmq_send }, + { "POSIXMQ-WRITE", &xioaddr_posixmq_write }, #endif #if WITH_PROXY { "PROXY", &xioaddr_proxy_connect }, From 6a53c955d39282b631a89fdb80e020ecd785da68 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Thu, 20 Feb 2025 10:26:37 +0100 Subject: [PATCH 48/51] Help shows option groups beyond 32 bits --- CHANGES | 3 +++ xiohelp.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index a563018..7f2af5d 100644 --- a/CHANGES +++ b/CHANGES @@ -90,6 +90,9 @@ Corrections: CONNECT addresses could use a wrong IPPROTO when getaddrinfo() does not support the selected one (at least on Debian-4 with SCTP). + socat -h (help) did not show option groups POSIXMQ, SCTP, DCCP, and + UDPLITE of addresses. + Features: POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T, makes it possible to terminate Socat in case the queue is empty. diff --git a/xiohelp.c b/xiohelp.c index bc95ce5..fae8cfb 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -87,6 +87,8 @@ static int xiohelp_option(FILE *of, const struct optname *on, const char *name) groups = on->desc->group; occurred = false; chars = 7; + if (groups == 0) + fputs("(all)", of); for (j = 0; j < 8*sizeof(groups_t); ++j) { if (groups & 1) { if (occurred) { @@ -150,8 +152,9 @@ int xioopenhelp(FILE *of, i = (40 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fputs("\tgroups=", of); - groups = an->desc->groups; occurred = false; - for (j = 0; j < 32; ++j) { + groups = an->desc->groups; + occurred = false; + for (j = 0; j < sizeof(groups_t)*8; ++j) { if (groups & 1) { if (occurred) { fputc(',', of); } fprintf(of, "%s", addressgroupnames[j]); From 34b09a44eeddd6261d5cd7ee4bdcd9dbb93d8d1d Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Thu, 20 Feb 2025 10:29:49 +0100 Subject: [PATCH 49/51] Again fixes a few disable problems --- CHANGES | 2 ++ xio-ipapp.c | 4 ++++ xio-socket.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index 7f2af5d..d3b8a64 100644 --- a/CHANGES +++ b/CHANGES @@ -131,6 +131,8 @@ Features: Building: Disabling certain features during configure could break build process. + Again fixes a few disable problems. + Porting: Fix for old FreeBSD. diff --git a/xio-ipapp.c b/xio-ipapp.c index d0c1871..eab2078 100644 --- a/xio-ipapp.c +++ b/xio-ipapp.c @@ -390,18 +390,22 @@ int _xioopen_ipapp_connect(struct single *sfd, } else if (needbind && bindport) { /* Bind by sourceport option */ switch ((*themp)->ai_family) { +#if WITH_IP4 case PF_INET: bindaddr.ip4.sin_family = (*themp)->ai_family; bindaddr.ip4.sin_port = htons(bindport); bindaddrp = &bindaddr; bindlen = sizeof(bindaddr.ip4); break; +#endif +#if WITH_IP6 case PF_INET6: bindaddr.ip6.sin6_family = (*themp)->ai_family; bindaddr.ip6.sin6_port = htons(bindport); bindaddrp = &bindaddr; bindlen = sizeof(bindaddr.ip6); break; +#endif } } diff --git a/xio-socket.c b/xio-socket.c index 8c0b3db..e2c0ab2 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -2349,11 +2349,13 @@ int xiosock_reuseaddr(int fd, int ipproto, struct opt *opts) } #endif /* WITH_TCP */ result = retropt_2integrals(opts, OPT_SO_REUSEADDR, &val, ¬null); +#if WITH_TCP if (ipproto == IPPROTO_TCP && result < 0) { Info("Setting SO_REUSADDR on TCP listen socket implicitly"); val.u_int = 1; notnull.u_bool = true; } +#endif /* WITH_TCP */ if (notnull.u_bool) { if (Setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val.u_int, sizeof(int)) != 0) { From 245f5e657f66a84c5145a3ef530601a3c09a0d5c Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Fri, 21 Feb 2025 12:37:53 +0100 Subject: [PATCH 50/51] Catch problems caused by ISPs DNS --- CHANGES | 4 ++- test.sh | 75 +++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/CHANGES b/CHANGES index d3b8a64..2dfc706 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,7 @@ Security: readline.sh has new option -lf <logfile> for stderr. If this option is - not given it logs to a file in . (cwd) only when it is not writable by + not given it logs to a file in . (cwd) only when . is not writable by other users. Corrections: @@ -172,6 +172,8 @@ Testing: UDPLITE4STREAM was trice, changed one of them to UDPLITE6STREAM. + Catch problems caused by ISPs that filter *.dest-unreach.net records. + Documentation: Removed obsolete CHANGES.ISO-8859-1 file. diff --git a/test.sh b/test.sh index 448f18e..62df2e8 100755 --- a/test.sh +++ b/test.sh @@ -93,6 +93,9 @@ while [ "$1" ]; do done debug=$DEBUG +# Applying patch 1.8.0.3 to 1.8.0.2 generates this non executably +[ -f ./socks5server-echo.sh ] && chmod a+x ./socks5server-echo.sh + [ "$DEFS" ] && echo "BASH_VERSION=\"$BASH_VERSION\"" >&2 [ "$DEFS" ] && echo "ECHO=\"$ECHO\"" >&2 @@ -259,12 +262,12 @@ fi # for some tests we need a network interface if type ip >/dev/null 2>&1; then - INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") + INTERFACE=$(ip r get 9.9.9.9 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") else case "$UNAME" in Linux) if [ "$IP" ]; then - INTERFACE="$($IP route get 8.8.8.8 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')" + INTERFACE="$($IP route get 9.9.9.9 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')" else INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($8);}')" fi ;; @@ -489,7 +492,7 @@ if2bc4() { case "$UNAME" in Linux) if [ "$IP" ]; then - BROADCASTIF=$($IP r get 8.8.8.8 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/') + BROADCASTIF=$($IP r get 9.9.9.9 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/') else BROADCASTIF=$(route -n |grep '^0.0.0.0 ' |awk '{print($8);}') fi @@ -2077,11 +2080,22 @@ case "$UNAME" in esac +HAVEDNS=1 if [ "$INTERNET" ]; then # No "-s 24" on Solaris - if ! ping -c 1 "server-4.dest-unreach.net" >/dev/null 2>&1; then - echo "$0: Option --internet but no connectivity or DNS" >&2 - #exit 1 + if ! ping -c 1 "9.9.9.9" >/dev/null 2>&1; then + echo "$0: Option --internet but no connectivity" >&2 + HAVEDNS= + elif type nslookup >/dev/null 2>&1; then + if ! nslookup server-4.dest-unreach.net. |grep '^Name:' >/dev/null 2>&1; then + echo "$0: Option --internet but broken DNS (cannot resolve server-4.dest-unreach.net)" >&2 + HAVEDNS= + fi + elif type host >/dev/null 2>&1; then + if ! host server-4.dest-unreach.net. |grep "has address" >/dev/null 2>&1; then + echo "$0: Option --internet but broken DNS (cannot resolve server-4.dest-unreach.net)" >&2 + HAVEDNS= + fi fi fi @@ -16227,12 +16241,6 @@ TEST="$NAME: try all available TCP4 addresses" # that is closed on both addresses. # The test succeeded when the log shows that Socat tried to connect two times. if ! eval $NUMCOND; then :; -elif ! $(type nslookup >/dev/null 2>&1); then - $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N - cant -#elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then -# $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N -# cant elif ! F=$(testfeats IP4 TCP GOPEN); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N cant @@ -16245,16 +16253,14 @@ elif ! runsip4 >/dev/null; then elif [ -z "$INTERNET" ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N cant +elif [ -z "$HAVEDNS" ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" da="test$N $(date) $RANDOM" -if type nslookup >/dev/null 2>&1; then - ADDRS=$(nslookup server-4.dest-unreach.net. |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}') -elif type host >/dev/null 2>&1; then - ADDRS=$(host server-4.dest-unreach.net. |sed 's/.*address //') -fi while true; do newport tcp4 OPEN= @@ -16302,9 +16308,6 @@ TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses" # neither IPv4 nor IPv6 # Check the log if Socat tried both addresses if ! eval $NUMCOND; then :; -#elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then -# $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N -# cant elif ! F=$(testfeats IP4 IP6 TCP); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N cant @@ -16320,9 +16323,12 @@ elif ! runsip4 >/dev/null; then elif ! runsip6 >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N cant -elif [ -z "$INTERNET" ]; then # only needs Internet DNS +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19565,6 +19571,7 @@ fi CNAME=$(echo $CADDR |tr - _) PROTO=$(toupper $proto) FEAT=$ADDR +addr=$(tolower $ADDR) runs=$proto case "$CPARMS" in PORT) newport $proto; CPARMS=$PORT ;; @@ -19582,7 +19589,7 @@ esac # Test if bind on *-CONNECT selects the matching IP version NAME=${CNAME}_BIND_6_4 case "$TESTS" in -*%$N%*|*%functions%*|*%$proto%*|*%${proto}4%*|*%${proto}6%*|*%ip4%*|*%ip6%*|*%listen%*|*%bind%*|*%socket%*|*%$NAME%*) +*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%${proto}6%*|*%ip4%*|*%ip6%*|*%listen%*|*%bind%*|*%socket%*|*%$NAME%*) TEST="$NAME: $ADDR bind chooses matching IPv" # Have an IPv4 listener # Host name localhost-4-6.dest-unreach.net resolves to both 127.0.0.1 and [::1], @@ -19609,6 +19616,12 @@ elif ! cond=$(checkconds \ elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19702,6 +19715,12 @@ elif ! cond=$(checkconds \ elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-6[[:space:]]' >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19785,6 +19804,12 @@ elif ! cond=$(checkconds \ elif ! SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-4[[:space:]]' >/dev/null; then $PRINTF "test $F_n $TEST... ${YELLOW}no option -0${NORMAL}\n" $N cant +elif [ -z "$INTERNET" -a "$RES" != 'DEVTESTS' ]; then + $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N + cant +elif [ -z "$HAVEDNS" ] && ! testfeats DEVTESTS >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Broken DNS${NORMAL}\n" $N + cant else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -19855,6 +19880,7 @@ fi CNAME=$(echo $CADDR |tr - _) PROTO=$(toupper $proto) FEAT=$ADDR +addr=$(tolower $ADDR) runs=$proto case "$CPARMS" in PORT) newport $proto; CPARMS=$PORT ;; @@ -19872,7 +19898,7 @@ esac # Test the retry option with *-CONNECT addresses NAME=${CNAME}_RETRY case "$TESTS" in -*%$N%*|*%functions%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%retry%*|*%$NAME%*) +*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%retry%*|*%$NAME%*) TEST="$NAME: $ADDR can retry" # Have an IPv4 listener with delay # Start a connector whose first attempt must fail; check if the second attempt @@ -19973,6 +19999,7 @@ fi CNAME=$(echo $CADDR |tr - _) PROTO=$(toupper $proto) FEAT=$ADDR +addr=$(tolower $ADDR) runs=$proto case "$CPARMS" in PORT) newport $proto; CPARMS=$PORT ;; @@ -19990,7 +20017,7 @@ esac # Test the fork and max-children options with CONNECT addresses NAME=${CNAME}_MAXCHILDREN case "$TESTS" in -*%$N%*|*%functions%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%fork%*|*%maxchildren%*|*%$NAME%*) +*%$N%*|*%functions%*|*%$addr%*|*%$proto%*|*%${proto}4%*|*%ip4%*|*%listen%*|*%socket%*|*%fork%*|*%maxchildren%*|*%$NAME%*) TEST="$NAME: $ADDR with fork,max-children" # Start a reader process that transfers received data to an output file; # run a sending client that forks at most 2 parallel child processes that From 78cc5ae1a57470b1978c14ff8b65729f1bb6a719 Mon Sep 17 00:00:00 2001 From: Gerhard <Gerhard> Date: Fri, 21 Feb 2025 12:38:14 +0100 Subject: [PATCH 51/51] Version 1.8.0.3 --- CHANGES | 2 ++ README | 2 +- VERSION | 2 +- socat.spec | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 2dfc706..b64fb4c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ +####################### V 1.8.0.3: + Security: readline.sh has new option -lf <logfile> for stderr. If this option is not given it logs to a file in . (cwd) only when . is not writable by diff --git a/README b/README index 0605138..da6f64a 100644 --- a/README +++ b/README @@ -70,7 +70,7 @@ Arch Linux: openssl readline Get the tarball and extract it: tar xzf socat.tar.gz - cd socat-1.8.0.2 + cd socat-1.8.0.3 ./configure make su diff --git a/VERSION b/VERSION index 8a17980..12355b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.8.0.2+" +"1.8.0.3" diff --git a/socat.spec b/socat.spec index 3d2b7a1..55e1d70 100644 --- a/socat.spec +++ b/socat.spec @@ -1,6 +1,6 @@ %define majorver 1.8 -%define minorver 0.2 +%define minorver 0.3 Summary: socat - multipurpose relay Name: socat