diff --git a/test.sh b/test.sh index 208f834..ef16675 100755 --- a/test.sh +++ b/test.sh @@ -88,6 +88,7 @@ if ! type usleep >/dev/null 2>&1; then fi #USLEEP=usleep F_n="%3d" # format string for test numbers +LC_ALL=C # for timestamps format... LANG=C LANGUAGE=C # knoppix UNAME=`uname` @@ -138,7 +139,8 @@ esac case "$UNAME" in Linux) BROADCASTIF=eth0 - SECONDADDR=127.0.0.2 + SECONDADDR=127.1.0.1 + SECONDMASK=255.255.0.0 BCADDR=127.255.255.255 BCIFADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}' |cut -d: -f2) ;; FreeBSD|NetBSD|OpenBSD) @@ -1618,6 +1620,7 @@ ifprocess () { OpenBSD) l="$(ps -kaj |grep "^........ $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ $(printf %5u $1)")" ;; DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*$(printf %5u $1)")" ;; + CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*$1[ ]")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*$(printf %5u $1) ")" ;; esac if [ -z "$l" ]; then @@ -1642,6 +1645,7 @@ childprocess () { OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)")" ;; SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;; + CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]")" ;; *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]**[ ][ ]*$(printf %5u $1) ")" ;; esac if [ -z "$l" ]; then return 1; @@ -1667,6 +1671,16 @@ isdefunct () { [ -n "$l" ]; } +# check if UNIX socket protocol is available on host +runsunix () { + return 0; + $SOCAT /dev/null UNIX-LISTEN:"$td/unix.socket" 2>"$td/unix.stderr" & + pid=$! + usleep $MICROS + kill "$pid" 2>/dev/null + test ! -s "$td/unix.stderr" +} + unset HAVENOT_IP4 # check if an IP4 loopback interface exists runsip4 () { @@ -1722,22 +1736,66 @@ runsip6 () { return $l; } +# check if TCP on IPv4 is available on host +runstcp4 () { + return 0; +# PORT="$1" + $SOCAT /dev/null TCP4-LISTEN:$PORT 2>"$td/tcp4.stderr" & + pid=$! + usleep $MICROS + kill "$pid" 2>/dev/null + test ! -s "$td/tcp4.stderr" +} + +# check if TCP on IPv6 is available on host +runstcp6 () { + return 0; +# PORT="$1" + $SOCAT /dev/null TCP6-LISTEN:$PORT 2>"$td/tcp6.stderr" & + pid=$! + usleep $MICROS + kill "$pid" 2>/dev/null + test ! -s "$td/tcp6.stderr" +} + +# check if UDP on IPv4 is available on host +runsudp4 () { + return 0; +# PORT="$1" + $SOCAT /dev/null UDP4-LISTEN:$PORT 2>"$td/udp4.stderr" & + pid=$! + usleep $MICROS + kill "$pid" 2>/dev/null + test ! -s "$td/udp4.stderr" +} + +# check if UDP on IPv6 is available on host +runsudp6 () { + return 0; +# PORT="$1" + $SOCAT /dev/null UDP6-LISTEN:$PORT 2>"$td/udp6.stderr" & + pid=$! + usleep $MICROS + kill "$pid" 2>/dev/null + test ! -s "$td/udp6.stderr" +} + # check if SCTP on IPv4 is available on host runssctp4 () { - PORT="$1" +# PORT="$1" $SOCAT /dev/null SCTP4-LISTEN:$PORT 2>"$td/sctp4.stderr" & pid=$! - sleep 1 + usleep $MICROS kill "$pid" 2>/dev/null test ! -s "$td/sctp4.stderr" } # check if SCTP on IPv6 is available on host runssctp6 () { - PORT="$1" + #PORT="$1" $SOCAT /dev/null SCTP6-LISTEN:$PORT 2>"$td/sctp6.stderr" & pid=$! - sleep 1 + usleep $MICROS kill "$pid" 2>/dev/null test ! -s "$td/sctp6.stderr" } @@ -2446,12 +2504,11 @@ case "$TESTS" in 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 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N numCANT=$((numCANT+1)) else #ts="127.0.0.1:$tsl" - testecho "$N" "$TEST" "" "tcp:127.100.0.1:$PORT,sp=$PORT,bind=127.100.0.1,reuseaddr" "$opts" + testecho "$N" "$TEST" "" "tcp:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts" fi esac PORT=$((PORT+1)) @@ -2467,7 +2524,7 @@ if [ "$UNAME" != Linux ]; then $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N numCANT=$((numCANT+1)) else - testecho "$N" "$TEST" "" "udp:127.100.0.1:$PORT,sp=$PORT,bind=127.100.0.1" "$opts" + testecho "$N" "$TEST" "" "udp:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" fi esac fi # NUMCOND @@ -3792,7 +3849,7 @@ PORT=$((PORT+1)) N=$((N+1)) -while read NAMEKEYW TESTTMPL PEERTMPL WAITTMPL; do +while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi export ts="$td/test$N.socket" @@ -3810,9 +3867,12 @@ TEST="$NAME: $TESTKEYW half close" # have a "peer" socat "peer" that executes "$OD_C" and see if EOF on the # connecting socat brings the result of od if ! eval $NUMCOND; then :; -#elif ! testaddrs unix >/dev/null; then -# $PRINTF "test $F_n $TEST... ${YELLOW}UNIX not available${NORMAL}\n" $N -# numCANT=$((numCANT+1)) +elif [ "$FEAT" != ';' -a ! testaddrs "$FEAT" >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) +elif ! runs$RUNS; then + $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -3846,18 +3906,18 @@ PORT=$((PORT+1)) N=$((N+1)) done <<<" -UNIXCONNECT UNIX-CONNECT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts -UNIXCLIENT UNIX-CLIENT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts -GOPEN_UNIXSTREAM GOPEN:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts -UNIXLISTEN UNIX-LISTEN:\$ts UNIX-CONNECT:\$ts,retry=3 sleep\040\1 -TCP4CONNECT TCP4-CONNECT:\$LOCALHOST:\$PORT TCP4-LISTEN:\$PORT waittcp4port\040\$PORT -TCP4LISTEN TCP4-LISTEN:\$PORT TCP4-CONNECT:\$LOCALHOST:\$PORT,retry=3 -TCP6CONNECT TCP6-CONNECT:\$LOCALHOST6:\$PORT TCP6-LISTEN:\$PORT waittcp6port\040\$PORT -TCP6LISTEN TCP6-LISTEN:\$PORT TCP6-CONNECT:\$LOCALHOST6:\$PORT,retry=3 -OPENSSL4CLIENT OPENSSL:\$LOCALHOST:\$PORT,verify=0 OPENSSL-LISTEN:\$PORT,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp4port\040\$PORT -OPENSSL4SERVER OPENSSL-LISTEN:\$PORT,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST:\$PORT,verify=0,retry=3 -OPENSSL6CLIENT OPENSSL:\$LOCALHOST6:\$PORT,pf=ip6,verify=0 OPENSSL-LISTEN:\$PORT,pf=ip6,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp6port\040\$PORT -OPENSSL6SERVER OPENSSL-LISTEN:\$PORT,pf=ip6,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST:\$PORT,pf=ip6,verify=0,retry=3 +UNIXCONNECT , unix UNIX-CONNECT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts +UNIXCLIENT , unix UNIX-CLIENT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts +GOPEN_UNIXSTREAM , unix GOPEN:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts +UNIXLISTEN , unix UNIX-LISTEN:\$ts UNIX-CONNECT:\$ts,retry=3 sleep\040\1 +TCP4CONNECT , tcp4 TCP4-CONNECT:\$LOCALHOST:\$PORT TCP4-LISTEN:\$PORT waittcp4port\040\$PORT +TCP4LISTEN , tcp4 TCP4-LISTEN:\$PORT TCP4-CONNECT:\$LOCALHOST:\$PORT,retry=3 +TCP6CONNECT , tcp6 TCP6-CONNECT:\$LOCALHOST6:\$PORT TCP6-LISTEN:\$PORT waittcp6port\040\$PORT +TCP6LISTEN , tcp6 TCP6-LISTEN:\$PORT TCP6-CONNECT:\$LOCALHOST6:\$PORT,retry=3 +OPENSSL4CLIENT OPENSSL tcp4 OPENSSL:\$LOCALHOST:\$PORT,verify=0 OPENSSL-LISTEN:\$PORT,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp4port\040\$PORT +OPENSSL4SERVER OPENSSL tcp4 OPENSSL-LISTEN:\$PORT,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST:\$PORT,verify=0,retry=3 +OPENSSL6CLIENT OPENSSL tcp6 OPENSSL:\$LOCALHOST6:\$PORT,pf=ip6,verify=0 OPENSSL-LISTEN:\$PORT,pf=ip6,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp6port\040\$PORT +OPENSSL6SERVER OPENSSL tcp6 OPENSSL-LISTEN:\$PORT,pf=ip6,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST6:\$PORT,pf=ip6,verify=0,retry=3 " @@ -5177,13 +5237,8 @@ NAME=TCP4RANGEMASKHAIRY case "$TESTS" in *%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%$NAME%*) TEST="$NAME: security of TCP4-L with RANGE option" -if ! eval $NUMCOND; then :; -elif [ "$UNAME" != Linux ]; then - # we need access to more loopback addresses - $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N - numCANT=$((numCANT+1)) -else -testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=127.0.0.0:255.255.0.0" "tcp4:127.1.0.0:$PORT" 4 tcp $PORT 0 +if ! eval $NUMCOND; then :; else +testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=127.0.0.0:255.255.0.0" "tcp4:$SECONDADDR:$PORT,bind=$SECONDADDR" 4 tcp $PORT 0 fi ;; # Linux, NUMCOND esac PORT=$((PORT+1)) @@ -5244,7 +5299,7 @@ ha="$td/hosts.allow" hd="$td/hosts.deny" $ECHO "socat: $LOCALHOST" >"$ha" $ECHO "ALL: ALL" >"$hd" -testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp4:$SECONDADDR:$PORT" 4 tcp $PORT 0 +testserversec "$N" "$TEST" "$opts -s" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "tcp4:$SECONDADDR:$PORT,bind=$SECONDADDR" 4 tcp $PORT 0 fi ;; # NUMCOND, feats esac PORT=$((PORT+1)) @@ -6053,7 +6108,8 @@ tdiff="$td/test$N.diff" da1="test$N $(date) $RANDOM" da2="test$N $(date) $RANDOM" #establish a listening and forking udp socket in background -SRV="$SOCAT $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,fork PIPE" +#processes hang forever without -T +SRV="$SOCAT -T 5 $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,fork PIPE" #make a first and a second connection CLI="$SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT" $PRINTF "test $F_n $TEST... " $N @@ -6099,60 +6155,93 @@ PORT=$((PORT+1)) N=$((N+1)) -NAME=UNIXLISTENFORK +# is a listen address capable of forking to child processes and have both +# active? +while read PROTOV MAJADDR MINADDR; do +if [ -z "$PROTOV" ] || [[ "$PROTOV" == \#* ]]; then continue; fi +protov="$(echo "$PROTOV" |tr A-Z a-z)" +proto="${protov%%[0-9]}" +NAME=${PROTOV}LISTENFORK case "$TESTS" in -*%functions%*|*%unix%*|*%listen%*|*%fork%*|*%$NAME%*) -TEST="$NAME: UNIX socket keeps listening after child died" -if ! eval $NUMCOND; then :; else -ts="$td/test$N.socket" +*%functions%*|*%$protov%*|*%$proto%*|*%listen%*|*%fork%*|*%$NAME%*) +TEST="$NAME: $PROTOV listen handles 2 concurrent connections" +# have a listening address with fork option. connect with client1, send a piece +# of data, wait 1s, connect with client2, send another piece of data, wait 1s, +# and send another piece of data with client1. The server processes append all +# data to the same file. Check all data are written to the file in correct +# order. +if ! eval $NUMCOND; then :; +#elif ! feat=$(testaddrs $PROTOV); then +# $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N +# numCANT=$((numCANT+1)) +elif ! runs$protov; then + $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N + numCANT=$((numCANT+1)) +else +ts="$td/test$N.sock" +tref="$td/test$N.ref" tf="$td/test$N.stdout" te="$td/test$N.stderr" tdiff="$td/test$N.diff" -da1="test$N $(date) $RANDOM" -da2="test$N $(date) $RANDOM" -#establish a listening and forking unix socket in background -SRV="$SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\",fork PIPE" -#make a first and a second connection -CLI="$SOCAT $opts -lpclient - UNIX-CONNECT:\"$ts\"" +da1a="test$N $(date) 1a $RANDOM" +da1b="test$N $(date) 1b $RANDOM" +da2="test$N $(date) 2 $RANDOM" +case "$MAJADDR" in + "FILE") + tla="$ts" + tca="$ts" + waitproto="file" + waitfor="$ts" ;; +esac +case "$MINADDR" in + "PORT") + tla="$PORT,bind=$MAJADDR" + tca="$MAJADDR:$PORT" + waitproto="${protov}port" + waitfor="$PORT" ;; +esac +#set -xv +echo -e "$da1a\n$da2\n$da1b" >"$tref" +# establish a listening and forking listen socket in background +# UDP processes hang forever without -T +CMD0="$SOCAT -T 5 $opts -lpserver $PROTOV-LISTEN:$tla,fork PIPE" +# make a first and a second connection +CMD1="$SOCAT $opts -lpclient - $PROTOV-CONNECT:$tca" $PRINTF "test $F_n $TEST... " $N -eval "$SRV 2>${te}s &" -pids=$! -waitfile "$ts" -echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1" -if [ $? -ne 0 ]; then - kill "$pids" 2>/dev/null - $PRINTF "$NO_RESULT (first conn failed):\n" - echo "$SRV &" - echo "$CLI" - cat "${te}s" "${te}1" - numCANT=$((numCANT+1)) -elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then - kill "$pids" 2>/dev/null - $PRINTF "$NO_RESULT (first conn failed); diff:\n" - cat "$tdiff" - numCANT=$((numCANT+1)) -else -echo "$da2" |eval "$CLI" >"${tf}2" 2>"${te}2" -rc="$?"; kill "$pids" 2>/dev/null -if [ $rc -ne 0 ]; then - $PRINTF "$FAILED:\n" - echo "$SRV &" - echo "$CLI" - cat "${te}s" "${te}2" - numFAIL=$((numFAIL+1)) -elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then - $PRINTF "$FAILED: diff\n" +eval "$CMD0 2>${te}0 &" +pid0=$! +wait$waitproto "$waitfor" 1 2 +(echo "$da1a"; sleep 2; echo "$da1b") |eval "$CMD1" >>"${tf}" 2>"${te}1" & +sleep 1 +# trailing sleep req for sctp because no half close +(echo "$da2"; sleep 1) |eval "$CMD1" >>"${tf}" 2>"${te}2" & +sleep 2 +kill $pid0 2>/dev/null +wait +if ! diff "$tref" "$tf" >"$tdiff"; then + $PRINTF "$FAILED\n" + cat "${te}0" "${te}1" "${te}2" cat "$tdiff" numFAIL=$((numFAIL+1)) else $PRINTF "$OK\n" numOK=$((numOK+1)) -fi # !( $? -ne 0) fi # !(rc -ne 0) wait fi ;; # NUMCOND, feats esac +PORT=$((PORT+1)) N=$((N+1)) +done <<<" +TCP4 $LOCALHOST PORT +TCP6 $LOCALHOST6 PORT +UDP4 $LOCALHOST PORT +UDP6 $LOCALHOST6 PORT +SCTP4 $LOCALHOST PORT +SCTP6 $LOCALHOST6 PORT +UNIX FILE , +" +set +vx NAME=UNIXTOSTREAM @@ -8321,7 +8410,7 @@ $CMD 2>"${te}" |tail -c $dalen >"${tf}" & sleep 1 echo "$da" |$CMD1 2>"${te}1" sleep 1 -kill "$(cat $tl)" 2>/dev/null +kill "$(cat $tl 2>/dev/null)" 2>/dev/null wait if [ $? -ne 0 ]; then $PRINTF "$FAILED: $SOCAT:\n" @@ -9330,7 +9419,7 @@ IP6 UDP6 [::1] PORT , so-timestamp SCM_TIMESTAMP IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_PKTINFO dstaddr user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit user 35 IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass user xaa000000 -IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP timestamp root $(date '+%a %b %e %H:%M:.. %Y') +IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_PKTINFO dstaddr root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit root 35 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass root xaa000000