| #! /usr/bin/env bash |
| # source: test.sh |
| # Copyright Gerhard Rieger and contributors (see file CHANGES) |
| # Published under the GNU General Public License V.2, see file COPYING |
| |
| # perform lots of tests on socat |
| |
| # this script uses functions; you need a shell that supports them |
| |
| # you can pass general options to socat: export OPTS="-d -d -d -d -lu" |
| # you can eg strace socat with: export TRACE="strace -v -tt -ff -D -x -s 1024 -o /tmp/$USER/socat.strace" |
| #set -vx |
| |
| #TODO: Add options for interface, broadcast-interface |
| |
| [ -z "$USER" ] && USER="$LOGNAME" # HP-UX |
| if [ -z "$TMPDIR" ]; then |
| if [ -z "$TMP" ]; then |
| TMP=/tmp |
| fi |
| TMPDIR="$TMP" |
| fi |
| #E=-e # Linux |
| 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 |
| exit 1 |
| fi |
| ECHO="echo $E" |
| PRINTF="printf" |
| |
| 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-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" |
| $ECHO "\t-C \t\tClear/remove left over certificates from previous runs" |
| $ECHO "\t-x \t\tShow commands executed, even when test succeeded" |
| #$ECHO "\t-d \t\tShow log output of commands, even when they did not fail" |
| $ECHO "\t-foreign \tAllow tests that send packets to Internet" |
| $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:" |
| $ECHO "OPTS=\"-d -d -d -d -lu\" ./test.sh" |
| $ECHO "TRACE=\"strace -tt -v\" Use trace,valgrind etc.on socat" |
| $ECHO "SOCAT=/path/to/socat \tselect socat executable for test" |
| $ECHO "FILAN=... PROCAN=..." |
| $ECHO "Find the tests' stdout,stderr,diff in $TMPDIR/$USER/\$PID" |
| } |
| |
| val_t=0.1 |
| NUMCOND=true |
| #NUMCOND="test \$N -gt 70" |
| VERBOSE= |
| DEBUG= |
| FOREIGN= |
| OPT_EXPECT_FAIL= EXPECT_FAIL= |
| while [ "$1" ]; do |
| case "X$1" in |
| X-h) usage; exit 0 ;; |
| X-d) DEBUG="1" ;; |
| X-t?*) val_t="${1#-t}" ;; |
| X-t) shift; val_t="$1" ;; |
| X-v) VERBOSE=1 ;; # show commands |
| X-n?*) NUMCOND="test \$N -eq ${1#-n}" ;; |
| 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-foreign|X--foreign) FOREIGN=1 ;; # allow access to 3rd party Internet hosts |
| X-expect-fail|X--expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;; |
| X-*) echo "Unknown option \"$1\"" >&2 |
| usage >&2 |
| exit 1 ;; |
| *) break; |
| esac |
| shift |
| done |
| debug=$DEBUG |
| |
| opt_t="-t $val_t" |
| |
| UNAME=`uname` |
| UNAME_R=`uname -r` |
| |
| #MICROS=100000 |
| case "X$val_t" in |
| X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;; |
| X*.*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS}000000"; uS="${uS:0:6}" ;; |
| X*) S="${val_t}"; uS="000000" ;; |
| esac |
| MICROS=${S}${uS} |
| MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0} |
| #echo MICROS=$MICROS >&2 |
| # |
| _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}" |
| [ -z "$SECONDs" ] && SECONDs=0 |
| |
| withroot=0 # perform privileged tests even if not run by root |
| |
| [ -z "$SOCAT" ] && SOCAT="./socat" |
| if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then |
| echo "$SOCAT does not exist" >&2; exit 1; |
| fi |
| if [ "$SOCAT" = socat ]; then |
| SOCAT=$(type -p socat) || SOCAT=$(which socat) |
| fi |
| #echo $SOCAT |
| if [ -z "$PROCAN" ]; then if test -x ./procan; then PROCAN="./procan"; elif type procan >/dev/null 2>&1; then PROCAN=procan; elif test -x ${SOCAT%/*}/procan; then PROCAN=${SOCAT%/*}/procan; else PROCAN=false; fi; fi |
| 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 |
| |
| #PATH=$PATH:/opt/freeware/bin |
| #PATH=$PATH:/usr/local/ssl/bin |
| PATH=$PATH:/sbin # RHEL6:ip |
| case "$0" in |
| */*) PATH="${0%/*}:$PATH" |
| esac |
| #OPENSSL_RAND="-rand /dev/egd-pool" |
| #SOCAT_EGD="egd=/dev/egd-pool" |
| MISCDELAY=1 |
| |
| opts="$opt_t $OPTS" |
| export SOCAT_OPTS="$opts" |
| TESTS="$*"; export TESTS |
| if ! SOCAT_MAIN_WAIT= $SOCAT -V >/dev/null 2>&1; then |
| echo "Failed to execute $SOCAT, exiting" >&2 |
| exit 1 |
| fi |
| |
| SOCAT_VERSION=$(SOCAT_MAIN_WAIT= $SOCAT -V |head -n 2 |tail -n 1 |sed 's/.* \([0-9][1-9]*\.[0-9][0-9]*\.[0-9][^[:space:]]*\).*/\1/') |
| if [ -z "$SOCAT_VERSION" ]; then |
| echo "Warning: failed to retrieve Socat version" >&2 |
| fi |
| |
| if type ip >/dev/null 2>&1; then |
| if ip -V |grep -q -i -e "^ip utility, iproute2-" -e BusyBox; then |
| IP=$(type -p ip) |
| else |
| unset IP |
| fi |
| fi |
| |
| if type ss >/dev/null 2>&1; then |
| if ss -V |grep -q "^ss utility, iproute2-"; then |
| SS=$(type -p ss) |
| else |
| unset SS |
| fi |
| 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/") |
| else |
| case "$UNAME" in |
| Linux) |
| if [ "$IP" ]; then |
| INTERFACE="$($IP route get 8.8.8.8 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')" |
| else |
| INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($8);}')" |
| fi ;; |
| FreeBSD) INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($4);}')" ;; |
| *) INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($4);}')" ;; |
| esac |
| fi |
| MCINTERFACE=$INTERFACE |
| [ -z "$MCINTERFACE" ] && MCINTERFACE=lo # !!! Linux only - and not always |
| #LOCALHOST=192.168.58.1 |
| LOCALHOST=localhost # attention: on FreeBSD-10 localhost resolves primarily to IPv6 |
| LOCALHOST4=127.0.0.1 |
| LOCALHOST6="[::1]" |
| #PROTO=$(awk '{print($2);}' /etc/protocols |sort -n |tail -n 1) |
| #PROTO=$(($PROTO+1)) |
| PROTO=$((144+RANDOM/2048)) |
| _PORT=12001 |
| SOURCEPORT=2002 |
| REUSEADDR=reuseaddr # use this with LISTEN addresses and bind options |
| |
| # get some system constants for use in tests |
| SOCK_DGRAM="$($PROCAN -c |grep "^#define[[:space:]]*SOCK_DGRAM[[:space:]]" |cut -d' ' -f3)" |
| FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print($3);}') |
| PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)" |
| TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)" |
| SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)" |
| SO_REUSEADDR="$($PROCAN -c |grep "^#define[[:space:]]*SO_REUSEADDR[[:space:]]" |cut -d' ' -f3)" |
| TCP_MAXSEG="$($PROCAN -c |grep "^#define[[:space:]]*TCP_MAXSEG[[:space:]]" |cut -d' ' -f3)" |
| SIZE_T=$($PROCAN |grep size_t |awk '{print($3);}') |
| #AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi |
| |
| # 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 |
| 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" |
| |
| toupper () { |
| case ${BASH_VERSION:0:1} in |
| [1-3]) echo "$@" |tr a-z A-Z ;; |
| [4-9]) echo "${@^^*}" ;; |
| esac |
| } |
| |
| tolower () { |
| case ${BASH_VERSION:0:1} in |
| [1-3]) echo "$@" |tr A-Z a-z ;; |
| [4-9]) echo "${@,,*}" ;; |
| esac |
| } |
| |
| # precision sleep; takes seconds with fractional part |
| psleep () { |
| local T="$1" |
| [ "$T" = 0 ] && T=0.000002 |
| $SOCAT -T "$T" pipe pipe 2>/dev/null |
| } |
| # 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 |
| } |
| fi |
| #USLEEP=usleep |
| |
| # A sleep with configurable clocking ($vat_t) |
| # val_t should be at least the time that a Socat invocation, no action, and |
| # termination takes |
| relsleep () { |
| usleep $(($1*MICROS)) |
| } |
| |
| if type ping6 >/dev/null 2>&1; then |
| PING6=ping6 |
| else |
| PING6="ping -6" |
| fi |
| |
| F_n="%3d" # format string for test numbers |
| export LC_ALL=C # for timestamps format... |
| export LANG=C |
| export LANGUAGE=C # knoppix |
| case "$UNAME" in |
| HP-UX|OSF1) |
| echo "$SOCAT -u stdin stdout" >cat.sh |
| chmod a+x cat.sh |
| CAT=./cat.sh |
| ;; |
| SunOS) |
| # /usr/bin/tr doesn't handle the a-z range syntax (needs [a-z]), use |
| # /usr/xpg4/bin/tr instead |
| alias tr=/usr/xpg4/bin/tr |
| ;; |
| *) |
| CAT="cat" |
| ;; |
| esac |
| |
| # some OSes need special options |
| case "$UNAME" in |
| #HP-UX) |
| # # on HP-UX, the default options (below) hang some tests (former 14, 15) |
| # PTYOPTS= |
| # PTYOPTS2= |
| # ;; |
| SunOS) |
| PTYOPTS="perm=600" |
| PTYOPTS2="echo=0,opost=0" |
| ;; |
| *) |
| PTYOPTS="echo=0,opost=0" |
| #PTYOPTS2="raw,echo=0" |
| PTYOPTS2="cfmakeraw" |
| #PTYOPTS2="rawer" |
| ;; |
| esac |
| |
| # for some tests we need an unprivileged user id to su to |
| if [ "$SUDO_USER" ]; then |
| SUBSTUSER="$SUDO_USER" |
| else |
| SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)" |
| fi |
| |
| if [ -z "$SS" ]; then |
| # non-root users might miss ifconfig in their path |
| case "$UNAME" in |
| AIX) IFCONFIG=/usr/sbin/ifconfig ;; |
| FreeBSD) IFCONFIG=/sbin/ifconfig ;; |
| HP-UX) IFCONFIG=/usr/sbin/ifconfig ;; |
| Linux) IFCONFIG=/sbin/ifconfig ;; |
| NetBSD)IFCONFIG=/sbin/ifconfig ;; |
| OpenBSD)IFCONFIG=/sbin/ifconfig ;; |
| OSF1) IFCONFIG=/sbin/ifconfig ;; |
| SunOS) IFCONFIG=/sbin/ifconfig ;; |
| Darwin)IFCONFIG=/sbin/ifconfig ;; |
| DragonFly) IFCONFIG=/sbin/ifconfig ;; |
| *) IFCONFIG=/sbin/ifconfig ;; |
| esac |
| fi |
| |
| # need output like "644" |
| case "$UNAME" in |
| 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 |
| p="$(ls -l -L "$1" |awk '{print($1);}')" |
| p="${p:1:9}" |
| while [ "$p" ]; do c=${p:0:1}; p=${p:1}; [ "x$c" == x- ]; let "s=2*s+$?"; done |
| printf "%03o\n" $s; |
| } ;; |
| esac |
| |
| # need user (owner) of filesystem entry |
| case "$UNAME" in |
| Linux) fileuser() { stat -L --print "%U\n" "$1" 2>/dev/null; } ;; |
| FreeBSD) fileuser() { ls -l "$1" |awk '{print($3);}'; } ;; |
| *) fileuser() { ls -l "$1" |awk '{print($3);}'; } ;; |
| esac |
| |
| if2addr4() { |
| local IF="$1" |
| if [ "$IP" ]; then |
| $IP address show dev "$IF" |grep "inet " |sed -e "s/.*inet //" -e "s/ .*//" |
| else |
| $IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}' |cut -d: -f2 |
| fi |
| } |
| |
| if2bc4() { |
| local IF="$1" |
| if [ "$IP" ]; then |
| $IP address show dev "$IF" |grep ' inet .* brd ' |awk '{print($4);}' |
| else |
| $IFCONFIG "$IF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}' |
| fi |
| } |
| |
| # for some tests we need a second local IPv4 address |
| 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/') |
| else |
| BROADCASTIF=$(route -n |grep '^0.0.0.0 ' |awk '{print($8);}') |
| fi |
| [ -z "$BROADCASTIF" ] && BROADCASTIF=eth0 |
| SECONDADDR=127.1.0.1 |
| SECONDMASK=255.255.0.0 |
| BCADDR=127.255.255.255 |
| BCIFADDR=$(if2addr4 $BROADCASTIF) ;; |
| FreeBSD|NetBSD|OpenBSD) |
| MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1) |
| BROADCASTIF="$MAINIF" |
| SECONDADDR=$($IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}') |
| BCIFADDR="$SECONDADDR" |
| BCADDR=$($IFCONFIG "$BROADCASTIF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;; |
| HP-UX) |
| MAINIF=lan0 # might use "netstat -ni" for this |
| BROADCASTIF="$MAINIF" |
| SECONDADDR=$($IFCONFIG $MAINIF |tail -n 1 |awk '{print($2);}') |
| BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;; |
| SunOS) |
| MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1) |
| BROADCASTIF="$MAINIF" |
| #BROADCASTIF=hme0 |
| #BROADCASTIF=eri0 |
| #SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}') |
| SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 '| head -n 1)" : '.*inet \([0-9.]*\) .*') |
| #BCIFADDR="$SECONDADDR" |
| #BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') |
| ;; |
| DragonFly) |
| MAINIF=$($IFCONFIG -a |grep -v ^lp |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1) |
| BROADCASTIF="$MAINIF" |
| SECONDADDR=$($IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}') |
| BCIFADDR="$SECONDADDR" |
| BCADDR=$($IFCONFIG "$BROADCASTIF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;; |
| #AIX|FreeBSD|Solaris) |
| *) |
| SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 ' |head -n 1)" : '.*inet \([0-9.]*\) .*') |
| ;; |
| esac |
| # for generic sockets we need this address in hex form |
| if [ "$SECONDADDR" ]; then |
| SECONDADDRHEX="$(printf "%02x%02x%02x%02x\n" $(echo "$SECONDADDR" |tr '.' ' '))" |
| fi |
| |
| # for some tests we need a second local IPv6 address |
| case "$UNAME" in |
| Linux) if [ "$IP" ]; then |
| SECONDIP6ADDR=$(expr "$($IP address |grep 'inet6 ' |fgrep -v ' ::1/128 '| head -n 1)" : '.*inet6 \([0-9a-f:][0-9a-f:]*\)/.*') |
| else |
| SECONDIP6ADDR=$(expr "$($IFCONFIG -a |grep 'inet6 ' |fgrep -v ' ::1/128 '| head -n 1)" : '.*inet \([0-9.]*\) .*') |
| fi ;; |
| *) |
| SECONDIP6ADDR=$(expr "$($IFCONFIG -a |grep 'inet6 ' |fgrep -v ' ::1/128 '| head -n 1)" : '.*inet \([0-9.]*\) .*') |
| ;; |
| esac |
| if [ -z "$SECONDIP6ADDR" ]; then |
| # case "$TESTS" in |
| # *%root2%*) $IFCONFIG eth0 ::2/128 |
| # esac |
| SECONDIP6ADDR="$LOCALHOST6" |
| else |
| SECONDIP6ADDR="[$SECONDIP6ADDR]" |
| fi |
| |
| TRUE=$(which true) |
| #E=-e # Linux |
| 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 |
| exit 1 |
| fi |
| ECHO="echo $E" |
| PRINTF="printf" |
| |
| case "$TERM" in |
| vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256color|screen) |
| # there are different behaviours of printf (and echo) |
| # on some systems, echo behaves different than printf... |
| if [ "$($PRINTF "\0101")" = "A" ]; then |
| RED="\0033[31m" |
| GREEN="\0033[32m" |
| YELLOW="\0033[33m" |
| # if [ "$UNAME" = SunOS ]; then |
| # NORMAL="\0033[30m" |
| # else |
| NORMAL="\0033[39m" |
| # fi |
| else |
| RED="\033[31m" |
| GREEN="\033[32m" |
| YELLOW="\033[33m" |
| # if [ "$UNAME" = SunOS ]; then |
| # NORMAL="\033[30m" |
| # else |
| NORMAL="\033[39m" |
| # fi |
| fi |
| OK="${GREEN}OK${NORMAL}" |
| FAILED="${RED}FAILED${NORMAL}" |
| NO_RESULT="${YELLOW}NO RESULT${NORMAL}" |
| CANT="$NO_RESULT" |
| ;; |
| *) OK="OK" |
| FAILED="FAILED" |
| NO_RESULT="NO RESULT" |
| CANT="$NO_RESULT" |
| ;; |
| esac |
| |
| if [ -x /usr/xpg4/bin/id ]; then |
| # SunOS has rather useless tools in its default path |
| 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 |
| TESTS="%$(echo " $TESTS " |tr ' ' '%')%" |
| |
| [ -z "$USER" ] && USER="$LOGNAME" # HP-UX |
| if [ -z "$TMPDIR" ]; then |
| if [ -z "$TMP" ]; then |
| TMP=/tmp |
| fi |
| TMPDIR="$TMP" |
| fi |
| TD="$TMPDIR/$USER/$$"; td="$TD" |
| rm -rf "$TD" || (echo "cannot rm $TD" >&2; exit 1) |
| mkdir -p "$TD" |
| #trap "rm -r $TD" 0 3 |
| |
| echo "Using temp directory $TD" |
| |
| case "$TESTS" in |
| *%consistency%*) |
| # test if addresses are sorted alphabetically: |
| $ECHO "testing if address array is sorted...\c" |
| TF="$TD/socat-q" |
| IFS="$($ECHO ' \n\t')" |
| $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" |
| if [ -s "$TF-diff" ]; then |
| $ECHO "\n*** address array is not sorted. Wrong entries:" >&2 |
| cat "$TD/socat-q-diff" >&2 |
| exit 1 |
| else |
| echo " ok" |
| fi |
| #/bin/rm "$TF" |
| #/bin/rm "$TF-diff" |
| esac |
| |
| case "$TESTS" in |
| *%consistency%*) |
| # test if address options array ("optionnames") is sorted alphabetically: |
| $ECHO "testing if address options are sorted...\c" |
| TF="$TD/socat-qq" |
| $SOCAT -hhh |sed '1,/opt:/ d' |awk '{print($1);}' >"$TF" |
| LC_ALL=C sort "$TF" |diff "$TF" - >"$TF-diff" |
| if [ -s "$TF-diff" ]; then |
| $ECHO "\n*** option array is not sorted. Wrong entries:" >&2 |
| cat "$TD/socat-qq-diff" >&2 |
| exit 1 |
| else |
| echo " ok" |
| fi |
| /bin/rm "$TF" |
| /bin/rm "$TF-diff" |
| esac |
| |
| #============================================================================== |
| |
| N=1 |
| numOK=0 |
| numFAIL=0 |
| numCANT=0 |
| listFAIL= |
| listCANT= |
| namesFAIL= |
| |
| #============================================================================== |
| # 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 |
| local tf="$td/test$N.stdout" |
| local te="$td/test$N.stderr" |
| local tdiff="$td/test$N.diff" |
| local da="test$N $(date) $RANDOM" |
| if ! eval $NUMCOND; then :; else |
| #local cmd="$TRACE $SOCAT $opts $arg1 $arg2" |
| #$ECHO "testing $title (test $N)... \c" |
| $PRINTF "test $F_n %s... " $N "$title" |
| #echo "$da" |$cmd >"$tf" 2>"$te" |
| (psleep $T; echo "$da"; psleep $T) |($TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") & |
| export rc1=$! |
| #sleep 5 && kill $rc1 2>/dev/null & |
| # rc2=$! |
| wait $rc1 |
| # kill $rc2 2>/dev/null |
| if [ "$(cat "$td/test$N.rc")" != 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2 |
| cat "$te" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| 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" |
| fi |
| fi # NUMCOND |
| } |
| |
| # test if call to od and throughput of data works - with graceful shutdown and |
| # 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 |
| local tf="$td/test$N.stdout" |
| local te="$td/test$N.stderr" |
| local tr="$td/test$N.ref" |
| local tdiff="$td/test$N.diff" |
| local dain="$(date) $RANDOM" |
| if ! eval $NUMCOND; then :; else |
| echo "$dain" |$OD_C >"$tr" |
| # local daout="$(echo "$dain" |$OD_C)" |
| $PRINTF "test $F_n %s... " $num "$title" |
| (psleep $T; echo "$dain"; psleep $T) |$TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te" |
| if [ "$?" != 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$TRACE $SOCAT $opts $arg1 $arg2" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $num" |
| # 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)) |
| else |
| $PRINTF "$FAILED: diff:\n" |
| echo "$TRACE $SOCAT $opts $arg1 $arg2" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $num" |
| fi |
| fi # NUMCOND |
| } |
| |
| # test if the socat executable has these features compiled in |
| # print the first missing address type |
| testfeats () { |
| local a A; |
| for a in $@; do |
| A=$(echo "$a" |tr 'a-z-' 'A-Z_') |
| if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then |
| if [[ "$A" =~ OPENSSL.* ]]; then |
| gentestcert testsrv |
| gentestcert testcli |
| fi |
| shift |
| continue |
| fi |
| echo "$a" |
| return 1 |
| done |
| return 0 |
| } |
| |
| # test if the socat executable has these address types compiled in |
| # print the first missing address type |
| testaddrs () { |
| local a A; |
| for a in $@; do |
| A=$(echo "$a" |tr 'a-z' 'A-Z') |
| # the ::::: forces syntax errer and prevents the address from doing anything |
| if ! $SOCAT $A::::: /dev/null 2>&1 </dev/null |grep -q "E unknown device/address"; then |
| shift |
| continue |
| fi |
| echo "$a" |
| return 1 |
| done |
| return 0 |
| } |
| |
| # test if the socat executable has these options compiled in |
| # print the first missing option |
| testoptions () { |
| local a A; |
| for a in $@; do |
| A=$(echo "$a" |tr 'a-z' 'A-Z') |
| if $SOCAT -hhh |grep "[^a-z0-9-]$a[^a-z0-9-]" >/dev/null; then |
| shift |
| continue |
| fi |
| echo "$a" |
| return 1 |
| done |
| return 0 |
| } |
| |
| # check if the given pid exists and has child processes |
| # if yes: prints child process lines to stdout, returns 0 |
| # if not: prints ev.message to stderr, returns 1 |
| childprocess () { |
| local l |
| case "$UNAME" in |
| AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;; |
| FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;; |
| HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; |
| Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;; |
| # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;; |
| NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;; |
| 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; |
| fi |
| echo "$l" |
| return 0 |
| } |
| |
| # return a list of child process pids [killchild] |
| childpids () { |
| 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);}')" ;; |
| HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;; |
| # Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;; |
| Linux) l="$(ps -fade |grep "^[^[:space:]][^[:space:]]*[[:space:]][[:space:]]*[^[:space:]][^[:space:]]*[[:space:]][[:space:]]*$1 " |awk '{print($2);}')" ;; |
| # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)" |awk '{print($2);}')" ;; |
| NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)" |awk '{print($2);}')" ;; |
| OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;; |
| SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;; |
| DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)" |awk '{print($2);}')" ;; |
| CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;; |
| *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$(printf %5u $1) " |awk '{print($2);}')" ;; esac |
| if [ -z "$l" ]; then |
| return 1; |
| fi |
| echo "$l" |
| return 0 |
| } |
| |
| # check if the given process line refers to a defunct (zombie) process |
| # yes: returns 0 |
| # no: returns 1 |
| isdefunct () { |
| local l |
| case "$UNAME" in |
| AIX) l="$(echo "$1" |grep ' <defunct>$')" ;; |
| FreeBSD) l="$(echo "$1" |grep ' <defunct>$')" ;; |
| HP-UX) l="$(echo "$1" |grep ' <defunct>$')" ;; |
| Linux) l="$(echo "$1" |grep ' <defunct>$')" ;; |
| SunOS) l="$(echo "$1" |grep ' <defunct>$')" ;; |
| DragonFly)l="$(echo "$1" |grep ' <defunct>$')" ;; |
| *) l="$(echo "$1" |grep ' <defunct>$')" ;; |
| esac |
| [ -n "$l" ]; |
| } |
| |
| # check if UNIX socket protocol is available on host |
| runsunix () { |
| return 0; |
| $TRACE $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 () { |
| [ -n "$HAVENOT_IP4" ] && return $HAVENOT_IP4 |
| local l |
| case "$UNAME" in |
| AIX) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; |
| FreeBSD) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; |
| HP-UX) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; |
| Linux) if [ "$IP" ]; then |
| l=$($IP address |egrep ' inet 127.0.0.1/') |
| else |
| l=$($IFCONFIG |egrep 'inet (addr:)?127\.0\.0\.1 ') |
| fi ;; |
| NetBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; |
| OpenBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; |
| OSF1) l=$($IFCONFIG -a |grep ' inet ') ;; |
| SunOS) l=$($IFCONFIG -a |grep 'inet ') ;; |
| Darwin)l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;; |
| DragonFly)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');; |
| CYGWIN*) l=$(ipconfig |grep IPv4);; |
| *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; |
| esac |
| [ -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="$?" ;; |
| Linux) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;; |
| *) if [ -n "$l" ]; then l=0; else l=1; fi ;; |
| esac |
| HAVENOT_IP4=$l |
| if [ "$HAVENOT_IP4" -ne 0 ]; then |
| echo IP4 |
| fi |
| return $l; |
| } |
| |
| unset HAVENOT_IP6 |
| # check if an IP6 loopback interface exists |
| runsip6 () { |
| [ -n "$HAVENOT_IP6" ] && return $HAVENOT_IP6 |
| local l |
| case "$UNAME" in |
| AIX) l=$($IFCONFIG lo0 |grep 'inet6 ::1[/%]') ;; |
| HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;; |
| Linux) if [ "$IP" ]; then |
| l=$($IP address |egrep 'inet6 ::1/128') |
| else |
| l=$($IFCONFIG |egrep 'inet6 (addr: )?::1/?') |
| fi ;; |
| NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1 ');; |
| OSF1) l=$($IFCONFIG -a |grep ' inet6 ') ;; |
| SunOS) l=$($IFCONFIG -a |grep 'inet6 ') ;; |
| Darwin)l=$($IFCONFIG lo0 |grep 'inet6 ::1 ') ;; |
| CYGWIN*) l=$(ipconfig |grep IPv6);; |
| *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;; |
| esac |
| [ -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="$?" ;; |
| Linux) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;; |
| *) if [ -n "$l" ]; then l=0; else l=1; fi ;; |
| esac |
| HAVENOT_IP6=$l |
| if [ "$HAVENOT_IP6" -ne 0 ]; then |
| echo IP6 |
| fi |
| return "$HAVENOT_IP6" |
| } |
| |
| # check if TCP on IPv4 is available on host |
| runstcp4 () { |
| runsip4 >/dev/null || { echo TCP4; return 1; } |
| $SOCAT -h |grep -i ' TCP4-' >/dev/null || return 1 |
| return 0; |
| } |
| |
| # check if TCP on IPv6 is available on host |
| runstcp6 () { |
| runsip6 >/dev/null || { echo TCP6; return 1; } |
| $SOCAT -h |grep -i ' TCP6-' >/dev/null || return 1 |
| return 0; |
| } |
| |
| # check if UDP on IPv4 is available on host |
| runsudp4 () { |
| runsip4 >/dev/null || { echo UDP4; return 1; } |
| $SOCAT -h |grep -i ' UDP4-' >/dev/null || return 1 |
| return 0; |
| } |
| |
| # check if UDP on IPv6 is available on host |
| runsudp6 () { |
| runsip6 >/dev/null || { echo UDP6; return 1; } |
| $SOCAT -h |grep -i ' UDP6-' >/dev/null || return 1 |
| return 0; |
| } |
| |
| # check if SCTP on IPv4 is available on host |
| runssctp4 () { |
| runsip4 >/dev/null || { echo SCTP4; return 1; } |
| $SOCAT -h |grep -i ' SCTP4-' >/dev/null || return 1 |
| $SOCAT /dev/null SCTP4-L:0,accept-timeout=0.001 2>/dev/null || return 1; |
| return 0; |
| } |
| |
| # check if SCTP on IPv6 is available on host |
| runssctp6 () { |
| runsip6 >/dev/null || { echo SCTP6; return 1; } |
| $SOCAT -h |grep -i ' SCTP6-' >/dev/null || return 1 |
| $SOCAT /dev/null SCTP6-L:0,accept-timeout=0.001 2>/dev/null || return 1; |
| return 0; |
| } |
| |
| 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; } |
| return 0; |
| } |
| |
| 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; } |
| return 0; |
| } |
| |
| # wait until an IP4 protocol is ready |
| waitip4proto () { |
| local proto="$1" |
| local logic="$2" # 0..wait until free; 1..wait until listening |
| local timeout="$3" |
| local l |
| [ "$logic" ] || logic=1 |
| [ "$timeout" ] || timeout=5 |
| while [ $timeout -gt 0 ]; do |
| case "$UNAME" in |
| Linux) if [ "$SS" ]; then |
| l=$($SS -n -w -l |grep '^\(raw\|UNCONN\) .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*') |
| else |
| l=$(netstat -n -w -l |grep '^raw .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*') |
| fi ;; |
| # FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;; |
| # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; |
| # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; |
| # Darwin) case "$(uname -r)" in |
| # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;; |
| # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;; |
| # esac ;; |
| AIX) # does not seem to show raw sockets in netstat |
| sleep 1; return 0 ;; |
| # 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' ') ;; |
| sleep 1; return 0 ;; |
| esac |
| [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ |
| \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0 |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| $ECHO "!protocol $proto timed out! \c" >&2 |
| return 1 |
| } |
| |
| # we need this misleading function name for canonical reasons |
| waitip4port () { |
| waitip4proto "$1" "$2" "$3" |
| } |
| |
| # wait until an IP6 protocol is ready |
| waitip6proto () { |
| local proto="$1" |
| local logic="$2" # 0..wait until free; 1..wait until listening |
| local timeout="$3" |
| local l |
| [ "$logic" ] || logic=1 |
| [ "$timeout" ] || timeout=5 |
| while [ $timeout -gt 0 ]; do |
| case "$UNAME" in |
| Linux) |
| if [ "$SS" ]; then |
| l=$($SS -n -w -l |grep '^\(raw\|UNCONN\) .* \*:'$proto' [ ]*\*:\*') |
| else |
| l=$(netstat -n -w -l |grep '^raw[6 ] .* .*:[0-9*]*:'$proto' [ ]*:::\*') |
| fi ;; |
| # FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;; |
| # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; |
| # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;; |
| # Darwin) case "$(uname -r)" in |
| # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;; |
| # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;; |
| # esac ;; |
| AIX) # does not seem to show raw sockets in netstat |
| sleep 1; return 0 ;; |
| # 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 |egrep -i 'raw6? .*[0-9*][:.]'$proto' ') ;; |
| sleep 1; return 0 ;; |
| esac |
| [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ |
| \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0 |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| $ECHO "!protocol $proto timed out! \c" >&2 |
| return 1 |
| } |
| |
| # we need this misleading function name for canonical reasons |
| waitip6port () { |
| waitip6proto "$1" "$2" "$3" |
| } |
| |
| # Check if a TCP port is in use |
| # exits with 0 when it is not used |
| checktcpport () { |
| local port="$1" |
| local l |
| case "$UNAME" in |
| Linux) if [ "$SS" ]; then |
| l=$($SS -a -n -t |grep ".*:$port\>") |
| else |
| l=$(netstat -a -n -t |grep '^tcp.* .*[0-9*]:'$port' .*') |
| fi ;; |
| FreeBSD) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .*') ;; |
| NetBSD) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' [ ]* .* [ ]*.*') ;; |
| Darwin) case "$(uname -r)" in |
| [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .* .*') ;; |
| *) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .* .*') ;; |
| esac ;; |
| AIX) l=$(netstat -an |grep '^tcp.* 0 0 .*[*0-9]\.'$port' .*') ;; |
| SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;; |
| HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .*') ;; |
| OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;; |
| CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .*') ;; |
| DragonFly)l=$(netstat -ant |grep '^tcp.* .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; |
| *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .*') ;; |
| esac |
| [ -z "$l" ] && return 0 |
| return 1 |
| } |
| |
| checktcp4port () { |
| checktcpport $1 |
| } |
| |
| # wait until a TCP4 listen port is ready |
| waittcp4port () { |
| local port="$1" |
| local logic="$2" # 0..wait until free; 1..wait until listening (default) |
| local timeout="$3" |
| local l |
| local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here |
| [ "$logic" ] || logic=1 |
| [ "$timeout" ] || timeout=5 |
| while true; do |
| case "$UNAME" in |
| Linux) if [ "$SS" ]; then |
| l=$($SS -l -n -t |grep "^LISTEN .*:$port\>") |
| else |
| l=$(netstat -a -n -t |grep '^tcp .* .*[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 tcp |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') ;; |
| DragonFly) l=$(netstat -ant |grep '^tcp4 .* .*[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 |
| set ${vx}vx |
| return 0 |
| fi |
| if [ $timeout -le 0 ]; then |
| set ${vx}vx |
| return 1 |
| fi |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| $ECHO "!port $port timed out! \c" >&2 |
| set ${vx}vx |
| return 1 |
| } |
| |
| # Check if a UDP4 port is in use |
| # exits with 0 when it is not used |
| checkudpport () { |
| local port="$1" |
| local l |
| case "$UNAME" in |
| Linux) if [ "$SS" ]; then |
| l=$($SS -a -n -u |grep ".*:$port\>") |
| else |
| l=$(netstat -a -n -u |grep '^udp.* .*[0-9*]:'$port' .*') |
| fi ;; |
| FreeBSD) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| NetBSD) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*.*') ;; |
| Darwin) case "$(uname -r)" in |
| [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| *) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| esac ;; |
| AIX) l=$(netstat -an |grep '^udp.* 0 0 .*[*0-9]\.'$port' .*') ;; |
| SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;; |
| 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' [ ]*\*\.\* [ ]*') ;; |
| CYGWIN*) l=$(netstat -an -p UDP |grep '^ UDP [0-9.]*:'$port' .*') ;; |
| DragonFly)l=$(netstat -ant |grep '^udp.* .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; |
| *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' .*') ;; |
| esac |
| [ -z "$l" ] && return 0 |
| return 1 |
| } |
| |
| checkudp4port () { |
| checkudpport $1 |
| } |
| |
| # wait until a UDP4 port is ready |
| waitudp4port () { |
| 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 -4 -l -n -u |grep "^UNCONN .*:$port\>") |
| else |
| l=$(netstat -a -n -u -l |grep '^udp .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*') |
| fi ;; |
| FreeBSD) l=$(netstat -an |egrep '^udp46? .*[0-9*]\.'$port' .* \*\.\*') ;; |
| NetBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;; |
| OpenBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;; |
| Darwin) case "$(uname -r)" in |
| [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;; |
| *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| esac ;; |
| AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;; |
| SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;; |
| 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' ') ;; |
| esac |
| if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ |
| \( \( $logic -eq 0 \) -a -z "$l" \) ]; then |
| set ${vx}vx |
| return 0 |
| fi |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| $ECHO "!port $port timed out! \c" >&2 |
| set ${vx}vx |
| return 1 |
| } |
| |
| # Check if a SCTP port is in use |
| # exits with 0 when it is not used |
| checksctpport () { |
| local port="$1" |
| local l |
| case "$UNAME" in |
| Linux) if [ "$SS" ]; then |
| l=$($SS -a -n |grep "^sctp.*:$port\>") |
| else |
| l=$(netstat -a -n |grep '^sctp.* .*[0-9*]:'$port' .*') |
| fi ;; |
| FreeBSD) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| NetBSD) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*.*') ;; |
| Darwin) case "$(uname -r)" in |
| [1-5]*) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| *) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;; |
| esac ;; |
| AIX) l=$(netstat -an |grep '^sctp.* 0 0 .*[*0-9]\.'$port' .*') ;; |
| SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;; |
| HP-UX) l=$(netstat -an |grep '^sctp 0 0 .*[0-9*]\.'$port' .*') ;; |
| OSF1) l=$(/usr/sbin/netstat -an |grep '^sctp.* 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;; |
| CYGWIN*) l=$(netstat -an -p SCTP |grep '^ SCTP [0-9.]*:'$port' .*') ;; |
| DragonFly)l=$(netstat -ant |grep '^sctp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;; |
| *) l=$(netstat -an |grep -i 'sctp.*[0-9*][:.]'$port' .*') ;; |
| esac |
| [ -z "$l" ] && return 0 |
| return 1 |
| } |
| |
| checksctp4port () { |
| checksctpport $1 |
| } |
| |
| # wait until an SCTP4 listen port is ready |
| waitsctp4port () { |
| 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 -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>") |
| else |
| l=$(netstat -n -a |grep '^sctp .*[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 sctp |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 'sctp .*[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 |
| psleep $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 () { |
| checktcpport $1 |
| } |
| |
| # wait until a tcp6 listen port is ready |
| waittcp6port () { |
| 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 -n -t -l |grep "^LISTEN .*:$port\>") |
| #l=$($SS -6 -n -t -l |grep "^tcp6* .*:$port\>") |
| else |
| l=$(netstat -an |grep -E '^tcp6? .* [0-9a-f:%]*:'$port' .* LISTEN') |
| fi ;; |
| FreeBSD) l=$(netstat -an |egrep -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;; |
| NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; |
| OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;; |
| Darwin) l=$(netstat -an |egrep '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN') ;; |
| AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;; |
| 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') ;; |
| esac |
| if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ |
| \( \( $logic -eq 0 \) -a -z "$l" \) ]; then |
| set ${vx}vx |
| return 0 |
| fi |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| $ECHO "!port $port timed out! \c" >&2 |
| #echo set ${vx}vx >&2 |
| set ${vx}vx |
| return 1 |
| } |
| |
| # Check if a UDP6 port is in use |
| # exits with 0 when it is not used |
| checkudp6port () { |
| checkudpport $1 |
| } |
| |
| # wait until a UDP6 port is ready |
| waitudp6port () { |
| 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 |
| # CAUTION!!! ss from iproute2 4.15.0-2ubuntu on 18-04 changes |
| # the output format when writing to pipe |
| l=$($SS -6 -u -l -n |grep "^UNCONN.*:$port\>") |
| else |
| l=$(netstat -an |grep -E '^udp6? .* .*[0-9*:%]:'$port' [ ]*:::\*') |
| fi ;; |
| FreeBSD) l=$(netstat -an |egrep '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;; |
| NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;; |
| OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;; |
| Darwin) l=$(netstat -an |egrep '^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') ;; |
| #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' ') ;; |
| esac |
| if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ |
| \( \( $logic -eq 0 \) -a -z "$l" \) ]; then |
| set ${vx}vx |
| return 0 |
| fi |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| $ECHO "!port $port timed out! \c" >&2 |
| set ${vx}vx |
| return 1 |
| } |
| |
| # Check if a SCTP6 port is in use |
| # exits with 0 when it is not used |
| checksctp6port () { |
| checksctpport $1 |
| } |
| |
| # wait until a sctp6 listen port is ready |
| # not all (Linux) variants show this in netstat |
| waitsctp6port () { |
| 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 -n 2>/dev/null |grep "^LISTEN .*:$port\>") |
| else |
| l=$(netstat -an |grep '^sctp[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 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') ;; |
| esac |
| if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \ |
| \( \( $logic -eq 0 \) -a -z "$l" \) ]; then |
| set ${vx}vx |
| return 0 |
| fi |
| psleep $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" |
| } |
| |
| # wait until a filesystem entry exists |
| waitfile () { |
| local crit=-e |
| case "X$1" in X-*) crit="$1"; shift ;; esac |
| local file="$1" |
| local logic="$2" # 0..wait until gone; 1..wait until exists (default); |
| # 2..wait until not empty |
| local timeout="$3" |
| local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here |
| [ "$logic" ] || logic=1 |
| [ "$logic" -eq 2 ] && crit=-s |
| [ "$timeout" ] || timeout=5 |
| while [ $timeout -gt 0 ]; do |
| if [ \( $logic -ne 0 -a $crit "$file" \) -o \ |
| \( $logic -eq 0 -a ! $crit "$file" \) ]; then |
| set ${vx}vx |
| return 0 |
| fi |
| psleep $val_t |
| timeout=$((timeout-1)) |
| done |
| |
| echo "file $file timed out" >&2 |
| set ${vx}vx |
| return 1 |
| } |
| |
| # system dependent values |
| case "$UNAME" in |
| SunOS) SOCK_SEQPACKET=6 ;; |
| *) SOCK_SEQPACKET=5 ;; |
| esac |
| |
| # generate a test certificate and key |
| gentestcert () { |
| local name="$1" |
| if ! [ -f testcert.dh ]; then |
| openssl dhparam -out testcert.dh $RSABITS |
| fi |
| if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi |
| openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1 |
| #openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 -extensions v3_ca >/dev/null 2>&1 |
| openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1 |
| cat $name.key $name.crt testcert.dh >$name.pem |
| } |
| |
| # generate a test DSA key and certificate |
| gentestdsacert () { |
| local name="$1" |
| if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi |
| openssl dsaparam -out $name-dsa.pem $DSABITS >/dev/null 2>&1 |
| openssl dhparam -dsaparam -out $name-dh.pem $DSABITS >/dev/null 2>&1 |
| openssl req -newkey dsa:$name-dsa.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1 |
| cat $name-dsa.pem $name-dh.pem $name.key $name.crt >$name.pem |
| } |
| |
| # generate a test EC key and certificate |
| gentesteccert () { |
| local name="$1" |
| if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi |
| openssl ecparam -name secp521r1 -out $name-ec.pem >/dev/null 2>&1 |
| chmod 0400 $name-ec.pem |
| openssl req -newkey ec:$name-ec.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1 |
| cat $name-ec.pem $name.key $name.crt >$name.pem |
| } |
| |
| gentestcert6 () { |
| local name="$1" |
| if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi |
| cat $TESTCERT_CONF | |
| { echo "# automatically generated by $0"; cat; } | |
| sed 's/\(commonName\s*=\s*\).*/\1[::1]/' >$TESTCERT6_CONF |
| openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1 |
| openssl req -new -config $TESTCERT6_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1 |
| cat $name.key $name.crt >$name.pem |
| } |
| |
| # generate a server certificate and key with SubjectAltName |
| gentestaltcert () { |
| local name="$1" |
| if ! [ -f testcert.dh ]; then |
| openssl dhparam -out testcert.dh $RSABITS |
| fi |
| if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi |
| openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1 |
| openssl req -new -config $TESTALT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1 |
| cat $name.key $name.crt testcert.dh >$name.pem |
| } |
| |
| #------------------------------------------------------------------------------ |
| # Begin of functional tests |
| |
| NAME=UNISTDIO |
| case "$TESTS " in |
| *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) |
| TEST="$NAME: unidirectional throughput from stdin to stdout" |
| testecho "$N" "$TEST" "stdin" "stdout" "$opts -u" |
| esac |
| N=$((N+1)) |
| |
| #------------------------------------------------------------------------------ |
| # Begin of common tests |
| |
| NAME=UNPIPESTDIO |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*) |
| TEST="$NAME: stdio with simple echo via internal pipe" |
| testecho "$N" "$TEST" "stdio" "pipe" "$opts" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| 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" |
| testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts" |
| esac |
| 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" |
| testecho "$N" "$TEST" "-!!-" "pipe" "$opts" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=NAMEDPIPE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*) |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=DUALPIPE |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=FILE |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=EXECPTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*) |
| 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" |
| else |
| testecho "$N" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" |
| fi |
| esac |
| N=$((N+1)) |
| |
| NAME=SYSTEMPTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*) |
| 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" |
| else |
| testecho "$N" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" |
| fi |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| # 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 |
| # arrives. |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*) |
| TEST="$NAME: call to od via exec with socketpair" |
| testod "$N" "$TEST" "" "EXEC:$OD_C" "$opts" |
| esac |
| N=$((N+1)) |
| |
| 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 |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| ## LATER: |
| #NAME=EXECPTYFLUSH |
| #case "$TESTS" in |
| #*%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*) |
| #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" |
| #else |
| #testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts" |
| #fi |
| #esac |
| #N=$((N+1)) |
| |
| |
| ## LATER: |
| #NAME=SYSTEMPTYFLUSH |
| #case "$TESTS" in |
| #*%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*) |
| #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" |
| #else |
| #testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts" |
| #fi |
| #esac |
| #N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| case "$UNAME" in |
| Linux) IPPROTO=254 ;; |
| Darwin) IPPROTO=255 ;; |
| *) IPPROTO=254 ;; # just a guess |
| esac |
| |
| NAME=RAWIP4SELF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "ip4:127.0.0.1:$IPPROTO" "$opts" |
| fi |
| esac |
| N=$((N+1)) |
| |
| NAME=RAWIPX4SELF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "ip:127.0.0.1:$IPPROTO" "$opts" |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=RAWIP6SELF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%rawip%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "ip6:[::1]:$IPPROTO" "$opts" |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=RAWIPX6SELF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "ip:[::1]:$IPPROTO" "$opts" |
| fi |
| esac |
| N=$((N+1)) |
| |
| newport() { |
| _PORT=$((_PORT+1)) |
| while eval wait${1}port $_PORT 1 0 2>/dev/null; do _PORT=$((_PORT+1)); done |
| #echo "PORT=$_PORT" >&2 |
| PORT=$_PORT |
| } |
| |
| NAME=TCPSELF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| 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" |
| 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" |
| fi |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDPSELF |
| if ! eval $NUMCOND; then :; else |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| 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" |
| else |
| newport udp4 # provide free port number in $PORT |
| testecho "$N" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts" |
| fi |
| esac |
| fi # NUMCOND |
| N=$((N+1)) |
| |
| |
| NAME=UDP6SELF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/file$N" |
| newport udp6 # provide free port number in $PORT |
| testecho "$N" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts" |
| fi |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=DUALUDPSELF |
| if ! eval $NUMCOND; then :; else |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| 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" |
| esac |
| fi # NUMCOND |
| N=$((N+1)) |
| |
| |
| #function testdual { |
| # local |
| #} |
| |
| |
| NAME=UNIXSTREAM |
| if ! eval $NUMCOND; then :; else |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: echo via connection to UNIX domain socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ts="$td/test$N.socket" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE" |
| CMD2="$TRACE $SOCAT $opts -!!- UNIX-CONNECT:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 </dev/null >$tf 2>"${te}1" & |
| bg=$! # background process id |
| waitfile "$ts" |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| echo "rc=$rc2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $bg 2>/dev/null |
| esac |
| fi # NUMCOND |
| N=$((N+1)) |
| |
| |
| NAME=TCP4 |
| if ! eval $NUMCOND; then :; else |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: echo via connection to TCP V4 socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid1 2>/dev/null |
| wait ;; |
| esac |
| fi # NUMCOND |
| N=$((N+1)) |
| |
| |
| #et -xv |
| NAME=TCP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| elif ! runsip6 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="[::1]:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo diff: |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| kill $pid 2>/dev/null |
| fi |
| esac |
| N=$((N+1)) |
| #set +vx |
| |
| |
| # Test if TCP client with IPv4 address connects to IPv4 port |
| NAME=TCPX4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE" |
| CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >"$tf" 2>"${te}0" & |
| pid=$! # background process id |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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)) |
| fi |
| kill $pid 2>/dev/null |
| fi |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if TCP client with IPv6 address connects to IPv6 port |
| NAME=TCPX6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| elif ! runsip6 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="[::1]:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE" |
| CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >"$tf" 2>"${te}0" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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)) |
| fi |
| kill $pid 2>/dev/null |
| fi |
| esac |
| N=$((N+1)) |
| |
| # TCP6-LISTEN may also listen for IPv4 connections. Test if option |
| # ipv6-v6only=0 shows this behaviour. |
| NAME=IPV6ONLY0 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: option ipv6-v6only=0 listens on IPv4" |
| # create a listening TCP6 socket and try to connect to the port using TCP4 |
| 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" |
| 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" |
| elif ! feat=$(testoptions ipv6-v6only); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=0,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| fi |
| esac |
| N=$((N+1)) |
| |
| #set -vx |
| # TCP6-LISTEN may also listen for IPv4 connections. Test if option |
| # ipv6-v6only=1 turns off this behaviour. |
| NAME=IPV6ONLY1 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| elif ! feat=$(testoptions ipv6-v6only); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=1,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| 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" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| kill $pid; wait |
| wait |
| fi |
| esac |
| N=$((N+1)) |
| #set +vx |
| |
| NAME=ENV_LISTEN_4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| elif ! feat=$(testoptions ipv6-v6only); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi |
| esac |
| N=$((N+1)) |
| |
| NAME=ENV_LISTEN_6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="[::1]:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts" |
| printf "test $F_n $TEST... " $N |
| SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED (diff):\n" |
| echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo "// diff:" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi |
| esac |
| N=$((N+1)) |
| |
| NAME=LISTEN_OPTION_4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| elif ! feat=$(testoptions ipv6-v6only); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -4 TCP-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi |
| esac |
| N=$((N+1)) |
| |
| NAME=LISTEN_OPTION_6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="[::1]:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -6 TCP-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts" |
| printf "test $F_n $TEST... " $N |
| SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| wait |
| fi # feats |
| esac |
| N=$((N+1)) |
| |
| NAME=LISTEN_PF_IP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| elif ! feat=$(testoptions ipv6-v6only); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -6 TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi |
| esac |
| N=$((N+1)) |
| |
| NAME=LISTEN_PF_IP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="[::1]:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -4 TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts" |
| printf "test $F_n $TEST... " $N |
| SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP4STREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: echo via connection to UDP V4 socket" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; tsl=$PORT |
| ts="$LOCALHOST:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP4-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waitudp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6STREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udp%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp6; tsl=$PORT |
| ts="$LOCALHOST6:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP6:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waitudp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # ! testfeats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=GOPENFILE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: file opening with gopen" |
| if ! eval $NUMCOND; then :; else |
| tf1="$td/test$N.1.stdout" |
| tf2="$td/test$N.2.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| echo "$da" >$tf1 |
| CMD="$TRACE $SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-" |
| printf "test $F_n $TEST... " $N |
| $CMD >"$tf2" 2>"$te" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! diff "$tf1" "$tf2" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=GOPENPIPE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: pipe opening with gopen for reading" |
| if ! eval $NUMCOND; then :; else |
| tp="$td/pipe$N" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf" |
| printf "test $F_n $TEST... " $N |
| #mknod $tp p # no mknod p on FreeBSD |
| mkfifo $tp |
| $CMD >$tf 2>"$te" & |
| #($CMD >$tf 2>"$te" || rm -f "$tp") 2>/dev/null & |
| bg=$! # background process id |
| usleep $MICROS |
| if [ ! -p "$tp" ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| #echo "$da" >"$tp" # might hang forever |
| echo "$da" >"$tp" & export pid=$!; (sleep 1; kill $pid 2>/dev/null) & |
| # Solaris needs more time: |
| sleep 1 |
| kill "$bg" 2>/dev/null; wait |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| if [ -s "$te" ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| else |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| fi |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi |
| wait |
| fi # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=GOPENUNIXSTREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: GOPEN on UNIX stream socket" |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N $(date) $RANDOM" |
| #establish a listening unix socket in background |
| SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE" |
| #make a connection |
| CMD="$TRACE $SOCAT $opts - $ts" |
| $PRINTF "test $F_n $TEST... " $N |
| eval "$SRV 2>${te}s &" |
| pids=$! |
| waitfile "$ts" |
| echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1" |
| if [ $? -ne 0 ]; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| wait |
| fi # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=GOPENUNIXSEQPACKET |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%seqpacket%*|*%$NAME%*) |
| TEST="$NAME: GOPEN on UNIX seqpacket socket" |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N $(date) $RANDOM" |
| #establish a listening unix socket in background |
| SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\",so-type=$SOCK_SEQPACKET PIPE" |
| #make a connection |
| CMD="$TRACE $SOCAT $opts - $ts" |
| $PRINTF "test $F_n $TEST... " $N |
| eval "$SRV 2>${te}s &" |
| pids=$! |
| waitfile "$ts" |
| echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1" |
| if [ $? -ne 0 ]; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| wait |
| fi # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=GOPENUNIXDGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: GOPEN on UNIX datagram socket" |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N $(date) $RANDOM" |
| #establish a receiving unix socket in background |
| SRV="$TRACE $SOCAT $opts -u -lpserver UNIX-RECV:\"$ts\" file:\"$tf\",create" |
| #make a connection |
| CMD="$TRACE $SOCAT $opts -u - $ts" |
| $PRINTF "test $F_n $TEST... " $N |
| eval "$SRV 2>${te}s &" |
| pids=$! |
| waitfile "$ts" |
| echo "$da1" |eval "$CMD" 2>"${te}1" |
| waitfile -s "$tf" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| kill "$pids" 2>/dev/null; wait |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=IGNOREEOF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: ignoreeof on file" |
| if ! eval $NUMCOND; then :; 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 -" |
| printf "test $F_n $TEST... " $N |
| touch "$ti" |
| $CMD >"$tf" 2>"$te" & |
| bg=$! |
| usleep 500000 |
| echo "$da" >>"$ti" |
| sleep 1 |
| 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)) |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=IGNOREEOF_REV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: ignoreeof on file right-to-left" |
| if ! eval $NUMCOND; then :; 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="$SOCAT $opts -U - file:\"$ti\",ignoreeof" |
| printf "test $F_n $TEST... " $N |
| touch "$ti" |
| $CMD >"$tf" 2>"$te" & |
| bg=$! |
| usleep 500000 |
| echo "$da" >>"$ti" |
| sleep 1 |
| kill $bg 2>/dev/null |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| listFAIL="$listFAIL $N" |
| numFAIL=$((numFAIL+1)) |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| wait |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=EXECIGNOREEOF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: exec against address with ignoreeof" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| # remark: diagnostics to null, no good style |
| CMD="$TRACE $SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof" |
| printf "test $F_n $TEST... " $N |
| $CMD >"$tf" 2>"$te" |
| if [ -s "$te" ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=FAKEPTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) |
| 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" |
| else |
| tt="$td/pty$N" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts PTY,$PTYOPTS,link=$tt PIPE" |
| CMD2="$TRACE $SOCAT $opts - $tt,$PTYOPTS2" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid=$! # background process id |
| waitfile "$tt" |
| # this hangs on HP-UX, so we use a timeout |
| (echo "$da"; sleep 1) |$CMD2 >$tf 2>"${te}2" & |
| pid2=$! |
| #sleep 5 && kill $rc2 2>/dev/null & |
| wait $pid2 |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| sleep 1 |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=O_TRUNC |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: option o-trunc" |
| if ! eval $NUMCOND; then :; else |
| ff="$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 -u $opts - open:$ff,append,o-trunc" |
| printf "test $F_n $TEST... " $N |
| rm -f $ff; $ECHO "prefix-\c" >$ff |
| echo "$da" |$CMD >$tf 2>"$te" |
| rc0=$? |
| if ! [ $rc0 = 0 ] || |
| ! echo "$da" |diff - $ff >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=FTRUNCATE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: option ftruncate" |
| if ! eval $NUMCOND; then :; else |
| ff="$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 -u $opts - open:$ff,append,ftruncate=0" |
| printf "test $F_n $TEST... " $N |
| rm -f $ff; $ECHO "prefix-\c" >$ff |
| if ! echo "$da" |$CMD >$tf 2>"$te" || |
| ! echo "$da" |diff - $ff >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| # I cannot remember the clou of this test, seems rather useless |
| NAME=CHILDDEFAULT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| TEST="$NAME: child process default properties" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| CMD="$TRACE $SOCAT $opts -u EXEC:$PROCAN -" |
| printf "test $F_n $TEST... " $N |
| $CMD >$tf 2>$te |
| MYPID=`expr "\`grep "process id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` |
| MYPPID=`expr "\`grep "process parent id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` |
| MYPGID=`expr "\`grep "process group id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` |
| MYSID=`expr "\`grep "process session id =" $tf\`" : '[^0-9]*\([0-9]*\).*'` |
| #echo "PID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID" |
| #if [ "$MYPID" = "$MYPPID" -o "$MYPID" = "$MYPGID" -o "$MYPID" = "$MYSID" -o \ |
| # "$MYPPID" = "$MYPGID" -o "$MYPPID" = "$MYSID" -o "$MYPGID" = "$MYSID" ]; |
| if [ "$MYPID" = "$MYPPID" ]; |
| then |
| $PRINTF "$FAILED:\n" |
| echo "$CMD" |
| cat "$te" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD"; fi |
| if [ "$DEBUG" ]; then cat "${te}" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=CHILDSETSID |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: child process with setsid" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| CMD="$TRACE $SOCAT $opts -u exec:$PROCAN,setsid -" |
| printf "test $F_n $TEST... " $N |
| $CMD >$tf 2>$te |
| MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID" |
| # PID, PGID, and SID must be the same |
| if [ "$MYPID" = "$MYPPID" -o \ |
| "$MYPID" != "$MYPGID" -o "$MYPID" != "$MYSID" ]; |
| then |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=MAINSETSID |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: main process with setsid" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| CMD="$TRACE $SOCAT $opts -U -,setsid exec:$PROCAN" |
| printf "test $F_n $TEST... " $N |
| $CMD >$tf 2>$te |
| MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')` |
| #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID" |
| # PPID, PGID, and SID must be the same |
| if [ "$MYPID" = "$MYPPID" -o \ |
| "$MYPPID" != "$MYPGID" -o "$MYPPID" != "$MYSID" ]; |
| then |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSL_TCP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 # provide free port number in $PORT |
| init_openssl_s_server |
| CMD2="$TRACE $SOCAT $opts exec:'openssl s_server $OPENSSL_S_SERVER_4 -accept "$PORT" -quiet -cert testsrv.pem' pipe" |
| CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| # this might timeout when openssl opens tcp46 port like " :::$PORT" |
| waittcp4port $PORT |
| #echo "$da" |$CMD >$tf 2>"${te}2" |
| #note: with about OpenSSL 1.1 s_server lost the half close feature, thus: |
| (echo "$da"; psleep 0.1) |$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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSLLISTEN_TCP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" |
| CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLLISTEN_TCP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp6 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" |
| CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp6port $PORT |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| 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 |
| |
| export ts="$td/test$N.socket" |
| case $RUNS in tcp4|tcp6) newport $RUNS;; esac |
| WAITTMPL="$(echo "$WAITTMPL" |sed -e 's/\040/ /g')" |
| TESTADDR=$(eval echo $TESTTMPL) |
| PEERADDR=$(eval echo $PEERTMPL) |
| WAITCMD=$(eval echo $WAITTMPL) |
| TESTKEYW=${TESTADDR%%:*} |
| feat=$(tolower $FEAT) |
| |
| # does our address implementation support halfclose? |
| NAME=${NAMEKEYW}_HALFCLOSE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$feat%*|*%socket%*|*%halfclose%*|*%listen%*|*%$NAME%*) |
| 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 [ "$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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| case $RUNS in tcp4|tcp6) newport $RUNS;; esac |
| CMD2="$TRACE $SOCAT $opts \"$PEERADDR\" EXEC:'$OD_C'" |
| CMD="$TRACE $SOCAT -T1 $opts -t 1 - $TESTADDR" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}2\" &" |
| pid2=$! # background process id |
| $WAITCMD |
| echo "$da" |$CMD >$tf 2>"${te}" |
| kill $pid2 2>/dev/null |
| wait |
| if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD2 &" |
| cat "${te}2" |
| echo "$CMD" |
| cat "${te}" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo " $CMD2 &" |
| echo " $CMD" |
| fi |
| if [ -n "$debug" ]; then cat "${te}2" "${te}"; fi |
| numOK=$((numOK+1)) |
| fi |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| done <<<" |
| 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,$REUSEADDR waittcp4port\040\$PORT |
| TCP4LISTEN , tcp4 TCP4-LISTEN:\$PORT,$REUSEADDR TCP4-CONNECT:\$LOCALHOST:\$PORT,retry=3 |
| TCP6CONNECT , tcp6 TCP6-CONNECT:\$LOCALHOST6:\$PORT TCP6-LISTEN:\$PORT,$REUSEADDR waittcp6port\040\$PORT |
| TCP6LISTEN , tcp6 TCP6-LISTEN:\$PORT,$REUSEADDR TCP6-CONNECT:\$LOCALHOST6:\$PORT,retry=3 |
| OPENSSL4CLIENT OPENSSL tcp4 OPENSSL:\$LOCALHOST:\$PORT,pf=ip4,verify=0 OPENSSL-LISTEN:\$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 waittcp4port\040\$PORT |
| OPENSSL4SERVER OPENSSL tcp4 OPENSSL-LISTEN:\$PORT,pf=ip4,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 OPENSSL:\$LOCALHOST:\$PORT,pf=ip4,$REUSEADDR,verify=0,retry=3 |
| OPENSSL6CLIENT OPENSSL tcp6 OPENSSL:\$LOCALHOST6:\$PORT,pf=ip6,verify=0 OPENSSL-LISTEN:\$PORT,pf=ip6,$REUSEADDR,$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,$REUSEADDR,verify=0,retry=3 |
| " |
| |
| |
| NAME=OPENSSL_SERVERAUTH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 # provide free port number in $PORT |
| CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe" |
| CMD1="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=1,cafile=testsrv.crt,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| echo "$da" |$CMD1 >$tf 2>"${te}1" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSL_CLIENTAUTH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD PIPE" |
| CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSL_FIPS_BOTHAUTH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| OPENSSL_FIPS=1 gentestcert testsrvfips |
| OPENSSL_FIPS=1 gentestcert testclifips |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe" |
| CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSL_COMPRESS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| printf "test $F_n $TEST... " $N |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| success=yes |
| for srccompr in '' compress=auto compress=none; do |
| for dstcompr in '' compress=auto compress=none; do |
| newport tcp4 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0,$dstcompr PIPE" |
| CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,$srccompr" |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| echo "$da" | $CMD >$tf 2>"${te}2" |
| kill $pid 2>/dev/null |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| success= |
| break |
| fi |
| done |
| done |
| if test -z "$success"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD2 &" |
| echo "$CMD" |
| cat "${te}1" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| 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 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=SOCKS4CONNECT_TCP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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 tcp6 # provide free port number in $PORT |
| CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR exec:\"./socks4echo.sh\"" |
| CMD1="$TRACE $SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" &" |
| pid=$! # background process id |
| waittcp6port $PORT 1 |
| echo "$da" |$CMD1 >${tf}1 2>"${te}1" |
| if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "// diff:" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=SOCKS4ACONNECT_TCP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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:\"./socks4a-echo.sh\"" |
| CMD="$TRACE $SOCAT $opts - SOCKS4A:$LOCALHOST:localhost: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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=SOCKS4ACONNECT_TCP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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 tcp6 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR EXEC:\"./socks4a-echo.sh\"" |
| CMD="$TRACE $SOCAT $opts - SOCKS4A:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp6port $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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=PROXYCONNECT_TCP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=PROXYCONNECT_TCP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=TCP4NOFORK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%exec%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: echo via connection to TCP V4 socket with nofork'ed exec" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR EXEC:$CAT,nofork" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| #$CMD1 >"$tf" 2>"${te}1" & |
| $CMD1 >/dev/null 2>"${te}1" & |
| waittcp4port $tsl |
| #usleep $MICROS |
| echo "$da" |$CMD2 >"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| #============================================================================== |
| #TEST="$NAME: echo via 'connection' to UDP V4 socket" |
| #if ! eval $NUMCOND; then :; else |
| #tf="$td/file$N" |
| #tsl=65534 |
| #ts="127.0.0.1:$tsl" |
| #da="test$N $(date) $RANDOM" |
| #$TRACE $SOCAT UDP-LISTEN:$tsl,$REUSEADDR PIPE & |
| #sleep 2 |
| #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf" |
| #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then |
| # $ECHO "... test $N succeeded" |
| # numOK=$((numOK+1)) |
| #else |
| # $ECHO "*** test $N $FAILED" |
| # numFAIL=$((numFAIL+1)) |
| # listFAIL="$listFAIL $N" |
| #fi |
| #fi ;; # NUMCOND |
| #N=$((N+1)) |
| #============================================================================== |
| # TEST 4 - simple echo via new file |
| #if ! eval $NUMCOND; then :; else |
| #N=4 |
| #tf="$td/file$N" |
| #tp="$td/pipe$N" |
| #da="test$N $(date) $RANDOM" |
| #rm -f "$tf.tmp" |
| #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf" |
| #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then |
| # $ECHO "... test $N succeeded" |
| # numOK=$((numOK+1)) |
| #else |
| # $ECHO "*** test $N $FAILED" |
| # numFAIL=$((numFAIL+1)) |
| # listFAIL="$listFAIL $N" |
| #fi |
| #fi ;; # NUMCOND |
| |
| #============================================================================== |
| |
| NAME=TOTALTIMEOUT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: socat inactivity timeout" |
| if ! eval $NUMCOND; then :; else |
| #set -vx |
| 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 $opts -T 1 TCP4-LISTEN:$PORT,$REUSEADDR pipe" |
| CMD="$TRACE $SOCAT $opts - TCP4-CONNECT:$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>${te}1 &" |
| pid=$! # background process id |
| waittcp4port $PORT 1 |
| (echo "$da"; sleep 2; echo X) |$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" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| #set +vx |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=IGNOREEOF+TOTALTIMEOUT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: ignoreeof and inactivity timeout" |
| if ! eval $NUMCOND; then :; else |
| #set -vx |
| 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 -T 2 -u file:\"$ti\",ignoreeof -" |
| printf "test $F_n $TEST... " $N |
| touch "$ti" |
| $CMD >"$tf" 2>"$te" & |
| bg=$! # background process id |
| psleep 0.5 |
| echo "$da" >>"$ti" |
| sleep 4 |
| echo X >>"$ti" |
| sleep 1 |
| kill $bg 2>/dev/null |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD &" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=PROXY2SPACES |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%proxy%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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 $opts TCP-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 -w 2\"" |
| 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}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 >"$tf" 2>"${te}0" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "diff:" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=BUG-UNISTDIO |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: for bug with address options on both stdin/out in unidirectional mode" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ff="$td/test$N.file" |
| printf "test $F_n $TEST... " $N |
| >"$ff" |
| #$TRACE $SOCAT $opts -u /dev/null -,setlk <"$ff" 2>"$te" |
| CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk" |
| $CMD <"$ff" 2>"$te" |
| if [ "$?" -eq 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| if [ "$UNAME" = "Linux" ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "${YELLOW}failed (don't care)${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| fi |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| 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 |
| esac |
| N=$((N+1)) |
| |
| 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 |
| esac |
| N=$((N+1)) |
| |
| NAME=SINGLEEXECOUTPTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) |
| 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" |
| else |
| testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=SINGLEEXECINSOCKETPAIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: inheritance of stdin to single exec with socketpair" |
| testecho "$N" "$TEST" "exec:cat!!-" "" "$opts" |
| esac |
| N=$((N+1)) |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| NAME=SINGLEEXECINPTYDELAY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) |
| 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" |
| else |
| testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=SINGLEEXECINPTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) |
| 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" |
| else |
| # T value needed (only) by AIX |
| testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=READLINE |
| #set -vx |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%readline%*|*%sigint%*|*%$NAME%*) |
| 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" |
| else |
| SAVETERM="$TERM"; TERM= # 'cause console might print controls even in raw |
| SAVEMICS=$MICROS |
| #MICROS=2000000 |
| ts="$td/test$N.sh" |
| to="$td/test$N.stdout" |
| tpi="$td/test$N.inpipe" |
| tpo="$td/test$N.outpipe" |
| 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" |
| #echo "$CMD" >"$ts" |
| #chmod a+x "$ts" |
| printf "test $F_n $TEST... " $N |
| rm -f "$tpi" "$tpo" |
| mkfifo "$tpi" |
| touch "$tpo" |
| # |
| # during development of this test, the following command line succeeded: |
| # ECHO="echo -e" SOCAT=./socat |
| # (sleep 1; $ECHO "user\n\c"; sleep 1; $ECHO "password\c"; sleep 1; $ECHO "\n\c"; sleep 1; $ECHO "test 1\n\c"; sleep 1; $ECHO "\003\c"; sleep 1; $ECHO "test 2\n\c"; sleep 1; $ECHO "exit\n\c"; sleep 1) |$TRACE $SOCAT -d -d -d -d -lf/tmp/$USER/debug1 -v -x - exec:'./readline.sh ./readline-test.sh',pty,ctty,setsid,raw,echo=0,isig |
| # |
| # the following cat, in case of socat failure, reads the pipe to prevent below writer from hanging |
| PATH=${SOCAT%socat}:$PATH eval "$CMD 2>$te || cat $tpi >/dev/null &" |
| pid=$! # background process id |
| usleep $MICROS |
| |
| ( |
| usleep $((3*MICROS)) |
| $ECHO "user\n\c" |
| usleep $MICROS |
| $ECHO "password\c" |
| usleep $MICROS |
| $ECHO "\n\c" |
| usleep $MICROS |
| $ECHO "test 1\n\c" |
| usleep $MICROS |
| $ECHO "\003\c" |
| usleep $MICROS |
| $ECHO "test 2\n\c" |
| usleep $MICROS |
| $ECHO "exit\n\c" |
| usleep $MICROS |
| ) >"$tpi" |
| |
| cat >$tr <<EOF |
| readline feature test program |
| Authentication required |
| Username: user |
| Password: |
| prog> test 1 |
| executing test 1 |
| prog> ./readline-test.sh got SIGINT |
| test 2 |
| executing test 2 |
| prog> exit |
| EOF |
| |
| #0 if ! sed 's/.*\r//g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then |
| #0 if ! sed 's/.*'"$($ECHO '\r\c')"'/</g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then |
| wait |
| if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" - >"$tdiff" 2>&1; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" 2>&1 |
| cat "$te" 2>&1 |
| echo diff: 2>&1 |
| cat "$tdiff" 2>&1 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null # necc on OpenBSD |
| wait |
| MICROS=$SAVEMICS |
| TERM="$SAVETERM" |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=GENDERCHANGER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: TCP4 \"gender changer\"" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4; PORT1=$PORT |
| newport tcp4; PORT2=$PORT |
| newport tcp4; PORT3=$PORT |
| # this is the server in the protected network that we want to reach |
| CMD1="$TRACE $SOCAT -lpserver $opts TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST ECHO" |
| # this is the double client in the protected network |
| CMD2="$TRACE $SOCAT -lp2client $opts TCP4:$LOCALHOST:$PORT2,retry=10,interval=1 TCP4:$LOCALHOST:$PORT1" |
| # this is the double server in the outside network |
| CMD3="$TRACE $SOCAT -lp2server $opts TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST" |
| # this is the outside client that wants to use the protected server |
| CMD4="$TRACE $SOCAT -lpclient $opts -t1 - tcp4:$LOCALHOST:$PORT3" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD1 2>${te}1 &" |
| pid1=$! |
| eval "$CMD2 2>${te}2 &" |
| pid2=$! |
| eval "$CMD3 2>${te}3 &" |
| pid3=$! |
| waittcp4port $PORT1 1 && |
| waittcp4port $PORT3 1 |
| sleep 1 |
| echo "$da" |$CMD4 >$tf 2>"${te}4" |
| kill $pid1 $pid2 $pid3 $pid4 2>/dev/null |
| wait |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2 &" |
| cat "${te}2" >&2 |
| echo "$CMD3 &" |
| cat "${te}3" >&2 |
| echo "$CMD4" |
| cat "${te}4" >&2 |
| echo diff: >&2 |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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 |
| if [ "$VERBOSE" ]; then echo "$CMD3 &"; fi |
| 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)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OUTBOUNDIN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4; PORT1=$PORT |
| newport tcp4; PORT2=$PORT |
| 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 TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST ECHO" |
| # this is the proxy in the protected network that provides a way out |
| CMD2="$TRACE $SOCAT $opts -lpproxy 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 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 |
| #CMD4="$TRACE $SOCAT $opts -lp2client SSL:$LOCALHOST:$PORT3,pf=ip4,retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD TCP4:$LOCALHOST:$PORT1" |
| CMD4="$TRACE $SOCAT $opts -lp2client SSL:$LOCALHOST:$PORT3,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD TCP4:$LOCALHOST:$PORT1" |
| # this is the double server in the outside network |
| CMD5="$TRACE $SOCAT $opts -lp2server -t1 tcp4-l:$PORT5,reuseaddr,bind=$LOCALHOST ssl-l:$PORT4,pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt" |
| # this is the outside client that wants to use the protected server |
| CMD6="$TRACE $SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$PORT5" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD1 2>${te}1 &" |
| pid1=$! |
| eval "$CMD2 2>${te}2 &" |
| pid2=$! |
| eval "$CMD3 2>${te}3 &" |
| pid3=$! |
| waittcp4port $PORT1 1 || $PRINTF "$FAILED: port $PORT1\n" >&2 </dev/null |
| waittcp4port $PORT2 1 || $PRINTF "$FAILED: port $PORT2\n" >&2 </dev/null |
| waittcp4port $PORT3 1 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null |
| eval "$CMD5 2>${te}5 &" |
| pid5=$! |
| waittcp4port $PORT5 1 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null |
| echo "$da" |$CMD6 >$tf 2>"${te}6" & |
| pid6=$! |
| waittcp4port $PORT4 1 || $PRINTF "$FAILED: port $PORT4\n" >&2 </dev/null |
| eval "$CMD4 2>${te}4 &" |
| pid4=$! |
| wait $pid6 |
| if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2 &" |
| cat "${te}2" |
| echo "$CMD3 &" |
| cat "${te}3" |
| echo "$CMD5 &" |
| cat "${te}5" |
| echo "$CMD6" |
| cat "${te}6" |
| echo "$CMD4 &" |
| cat "${te}4" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # test the TCP gender changer with almost production requirements: a double |
| # client repeatedly tries to connect to a double server via SSL through an HTTP |
| # proxy. the double servers SSL port becomes active for one connection only |
| # after a (real) client has connected to its TCP port. when the double client |
| # succeeded to establish an SSL connection, it connects with its second client |
| # side to the specified (protected) server. all three consecutive connections |
| # must function for full success of this test. |
| #PORT=$((RANDOM+16184)) |
| #! |
| NAME=INTRANETRIPPER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N.1 $(date) $RANDOM" |
| da2="test$N.2 $(date) $RANDOM" |
| da3="test$N.3 $(date) $RANDOM" |
| newport tcp4; PORT1=$PORT |
| newport tcp4; PORT2=$PORT |
| 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 -t1 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 -t1 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 -t3 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 |
| CMD4="$TRACE $SOCAT $opts -lp2client -t3 ssl:$LOCALHOST:$PORT3,retry=10,interval=1,cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD tcp4:$LOCALHOST:$PORT1,forever,interval=0.1" |
| # this is the double server in the outside network |
| CMD5="$TRACE $SOCAT $opts -lp2server -t4 tcp4-l:$PORT5,reuseaddr,bind=$LOCALHOST,backlog=3,fork ssl-l:$PORT4,pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=20,interval=0.5" |
| # this is the outside client that wants to use the protected server |
| CMD6="$TRACE $SOCAT $opts -lpclient -t6 - tcp4:$LOCALHOST:$PORT5,retry=3" |
| printf "test $F_n $TEST... " $N |
| # start the intranet infrastructure |
| eval "$CMD1 2>\"${te}1\" &" |
| pid1=$! |
| eval "$CMD2 2>\"${te}2\" &" |
| pid2=$! |
| waittcp4port $PORT1 1 || $PRINTF "$FAILED: port $PORT1\n" >&2 </dev/null |
| waittcp4port $PORT2 1 || $PRINTF "$FAILED: port $PORT2\n" >&2 </dev/null |
| # initiate our internal measures |
| eval "$CMD3 2>\"${te}3\" &" |
| pid3=$! |
| eval "$CMD4 2>\"${te}4\" &" |
| pid4=$! |
| waittcp4port $PORT3 1 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null |
| # now we start the external daemon |
| eval "$CMD5 2>\"${te}5\" &" |
| pid5=$! |
| waittcp4port $PORT5 1 || $PRINTF "$FAILED: port $5PORT\n" >&2 </dev/null |
| # and this is the outside client: |
| echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" & |
| pid6_1=$! |
| echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" & |
| pid6_2=$! |
| echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" & |
| pid6_3=$! |
| wait $pid6_1 $pid6_2 $pid6_3 |
| kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null |
| # |
| (echo "$da1"; sleep 2) |diff - "${tf}_1" >"${tdiff}1" |
| (echo "$da2"; sleep 2) |diff - "${tf}_2" >"${tdiff}2" |
| (echo "$da3"; sleep 2) |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 |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2 &" |
| cat "${te}2" |
| echo "$CMD3 &" |
| cat "${te}3" |
| echo "$CMD4 &" |
| cat "${te}4" |
| echo "$CMD5 &" |
| cat "${te}5" |
| echo "$CMD6 &" |
| cat "${te}6_1" |
| cat "${tdiff}1" |
| echo "$CMD6 &" |
| cat "${te}6_2" |
| cat "${tdiff}2" |
| echo "$CMD6 &" |
| cat "${te}6_3" |
| cat "${tdiff}3" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| 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)) |
| fi |
| kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # let us test the security features with -s, retry, and fork |
| # method: first test without security feature if it works |
| # then try with security feature, must fail |
| |
| # test the security features of a server address |
| testserversec () { |
| local N="$1" |
| local title="$2" |
| local opts="$3" |
| local arg1="$4" # the server address |
| local secopt0="$5" # option without security for server, mostly empty |
| local secopt1="$6" # the security option for server, to be tested |
| local arg2="$7" # the client address |
| local ipvers="$8" # IP version, for check of listen port |
| local proto="$9" # protocol, for check of listen port |
| local port="${10}" # start client when this port is listening |
| local expect="${11}" # expected behaviour of client: 0..empty output; -1..error; *: any of these |
| local T="${12}"; [ -z "$T" ] && T=0 |
| local tf="$td/test$N.stdout" |
| local te="$td/test$N.stderr" |
| local tdiff1="$td/test$N.diff1" |
| local tdiff2="$td/test$N.diff2" |
| local da="test$N.1 $(date) $RANDOM" |
| local stat result |
| |
| $PRINTF "test $F_n %s... " $N "$title" |
| # first: without security |
| # start server |
| $TRACE $SOCAT $opts "$arg1,$secopt0" echo 2>"${te}1" & |
| spid=$! |
| if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then |
| kill $spid 2>/dev/null |
| $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" |
| wait; return |
| fi |
| # now use client |
| (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}2" |
| stat="$?" |
| kill $spid 2>/dev/null |
| #killall $TRACE $SOCAT 2>/dev/null |
| if [ "$stat" != 0 ]; then |
| $PRINTF "$NO_RESULT (ph.1 function fails): $TRACE $SOCAT:\n" |
| echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &" |
| cat "${te}1" |
| echo "$TRACE $SOCAT $opts - \"$arg2\"" |
| cat "${te}2" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| wait; return |
| elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then |
| : # function without security is ok, go on |
| else |
| $PRINTF "$NO_RESULT (ph.1 function fails): diff:\n" |
| echo "$TRACE $SOCAT $opts $arg1,$secopt0 echo &" |
| cat "${te}1" |
| echo "$TRACE $SOCAT $opts - $arg2" |
| cat "${te}2" |
| cat "$tdiff1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| wait; return |
| fi |
| wait |
| |
| #set -vx |
| # assemble address w/ security option; on dual, take read part: |
| case "$arg1" in |
| *!!*) arg="${arg1%!!*},$secopt1!!${arg1#*!!}" ;; |
| *) arg="$arg1,$secopt1" ;; |
| esac |
| # start server |
| # use -s to make sure that it fails due to a sec violation, not some other failure |
| CMD3="$TRACE $SOCAT $opts -s $arg echo" |
| $CMD3 2>"${te}3" & |
| spid=$! |
| if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then |
| kill $spid 2>/dev/null |
| $PRINTF "$NO_RESULT (ph.2 server not working)\n" |
| wait |
| echo "$CMD3" |
| cat "${te}3" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| return |
| fi |
| # now use client |
| da="test$N.2 $(date) $RANDOM" |
| (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}4" |
| stat=$? |
| kill $spid 2>/dev/null |
| #set +vx |
| #killall $TRACE $SOCAT 2>/dev/null |
| if [ "$stat" != 0 ]; then |
| result=-1; # socat had error |
| elif [ ! -s "$tf" ]; then |
| result=0; # empty output |
| elif echo "$da" |diff - "$tf" >"$tdiff2" 2>&1; then |
| result=1; # output is copy of input |
| else |
| result=2; # output differs from input |
| fi |
| if [ "$expect" != '1' -a "$result" -eq 1 ]; then |
| $PRINTF "$FAILED: SECURITY BROKEN\n" |
| echo "$TRACE $SOCAT $opts $arg echo" |
| cat "${te}3" |
| echo "$TRACE $SOCAT $opts - $arg2" |
| cat "${te}4" |
| cat "$tdiff2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| echo "$TRACE $SOCAT $opts $arg echo" |
| cat "${te}3" |
| echo "$TRACE $SOCAT $opts - $arg2" |
| cat "${te}4" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| ;; |
| X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n" |
| echo "$TRACE $SOCAT $opts $arg echo" |
| cat "${te}3" |
| echo "$TRACE $SOCAT $opts - $arg2" |
| cat "${te}4" |
| cat "$tdiff2" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| ;; |
| X1) $PRINTF "$FAILED: SECURITY BROKEN\n" |
| echo "$TRACE $SOCAT $opts $arg echo" |
| cat "${te}3" |
| echo "$TRACE $SOCAT $opts - $arg2" |
| cat "${te}4" |
| cat "$tdiff2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| ;; |
| X2) $PRINTF "$FAILED: diff:\n" |
| echo "$TRACE $SOCAT $opts $arg echo" |
| cat "${te}3" |
| echo "$TRACE $SOCAT $opts - $arg2" |
| cat "${te}4" |
| cat "$tdiff2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| ;; |
| esac |
| else |
| $PRINTF "$OK\n" |
| [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts $arg echo" |
| [ "$debug" ] && cat ${te}3 |
| [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts - $arg2" |
| [ "$debug" ] && cat ${te}4 |
| numOK=$((numOK+1)) |
| fi |
| wait |
| #set +vx |
| } |
| |
| |
| NAME=TCP4RANGEBITS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: security of TCP4-L with RANGE option" |
| 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" |
| 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 |
| fi ;; # $SECONDADDR, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP4RANGEMASK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: security of TCP4-L with RANGE option" |
| 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" |
| 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 |
| fi ;; # $SECONDADDR, NUMCOND |
| esac |
| 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%*) |
| TEST="$NAME: security of TCP4-L with RANGE option" |
| if ! eval $NUMCOND; then :; else |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "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 |
| N=$((N+1)) |
| |
| |
| NAME=TCP4SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: security of TCP4-L with SOURCEPORT option" |
| if ! eval $NUMCOND; then :; else |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP4LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: security of TCP4-L with LOWPORT option" |
| if ! eval $NUMCOND; then :; else |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP4WRAPPERS_ADDR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP4WRAPPERS_NAME |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $LOCALHOST" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "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 |
| N=$((N+1)) |
| |
| |
| NAME=TCP6RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP6SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%**|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP6LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=TCP6TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport tcp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "TCP6:[::1]:$PORT" 6 tcp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP4RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: security of UDP4-L with RANGE option" |
| if ! eval $NUMCOND; then :; else |
| newport udp4 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0 |
| testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0 |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: security of UDP4-L with SOURCEPORT option" |
| if ! eval $NUMCOND; then :; else |
| newport udp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0 |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: security of UDP4-L with LOWPORT option" |
| if ! eval $NUMCOND; then :; else |
| newport udp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "lowport" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0 |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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 |
| testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP4_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "range=$SECONDADDR/32" "SSL:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP4_SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "sp=$PORT" "SSL:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP4_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "lowport" "SSL:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP4_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "tcpwrap-etc=$td" "SSL:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt,$SOCAT_EGD" 4 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLCERTSERVER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts -4" "SSL-L:$PORT,pf=ip4,reuseaddr,fork,retry=1,$SOCAT_EGD,verify,cert=testsrv.crt,key=testsrv.key" "cafile=testcli.crt" "cafile=testsrv.crt" "SSL:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt,cert=testcli.pem,$SOCAT_EGD" 4 tcp $PORT '*' |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLCERTCLIENT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts -t 0.5 -lu -d" "SSL:$LOCALHOST:$PORT,pf=ip4,fork,retry=2,verify,cert=testcli.pem,$SOCAT_EGD" "cafile=testsrv.crt" "cafile=testcli.crt" "SSL-L:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,cafile=testcli.crt,cert=testsrv.crt,key=testsrv.key" 4 tcp "" -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSLTCP6_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert6 testsrv6 |
| newport tcp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "range=[::2]/128" "SSL:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP6_SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert6 testsrv6 |
| newport tcp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "sp=$PORT" "SSL:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP6_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestcert6 testsrv6 |
| newport tcp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "lowport" "SSL:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSLTCP6_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$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 |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert6 testsrv6 |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport tcp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "SSL-L:$PORT,pf=ip6,reuseaddr,fork,retry=1,$SOCAT_EGD,verify=0,cert=testsrv6.crt,key=testsrv6.key" "" "tcpwrap-etc=$td" "SSL:[::1]:$PORT,cafile=testsrv6.crt,$SOCAT_EGD" 6 tcp $PORT -1 |
| fi ;; # NUMCOND, feats |
| esac |
| 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%*) |
| 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 |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts -t 0.5 -4" "SSL:127.0.0.1:$PORT,fork,retry=2,verify,cafile=testsrv.crt" "commonname=$LOCALHOST" "" "SSL-L:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0" 4 tcp "" '*' |
| fi ;; # testfeats, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test security with the openssl-commonname option on server side |
| NAME=OPENSSL_CN_SERVER_SECURITY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: security of server openssl-commonname option" |
| # connect using with client certificate to server, this should succeed. |
| # Then use the server with a non matching openssl-commonname option, |
| # this must fail |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| newport tcp4 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts -4" "SSL-L:$PORT,pf=ip4,reuseaddr,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt" "" "commonname=onlyyou" "SSL:$LOCALHOST:$PORT,pf=ip4,$REUSEADDR,verify=0,cafile=testsrv.crt,cert=testcli.crt,key=testcli.key" 4 tcp "$PORT" '*' |
| fi ;; # testfeats, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSL_FIPS_SECURITY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| gentestcert testcli |
| newport tcp4 # provide free port number in $PORT |
| # openssl client accepts a "normal" certificate only when not in fips mode |
| testserversec "$N" "$TEST" "$opts" "SSL:$LOCALHOST:$PORT,fork,retry=2,verify,cafile=testsrv.crt" "" "fips" "SSL-L:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key" 4 tcp "" -1 |
| fi ;; # testfeats, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| 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" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=FILANDIR |
| case "$TESTS" in |
| *%$N%*|*%filan%*|*%$NAME%*) |
| TEST="$NAME: check type printed for directories" |
| if ! eval $NUMCOND; then :; else |
| te="$td/test$N.stderr" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if Filan can determine UNIX domain socket in file system |
| NAME=FILANSOCKET |
| case "$TESTS" in |
| *%$N%*|*%filan%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: capability to analyze named unix socket" |
| # Run Filan on a listening UNIX domain socket. |
| # When its output gives "socket" as type (2nd column), the test succeeded |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| te1="$td/test$N.stderr1" # socat |
| te2="$td/test$N.stderr2" # filan |
| printf "test $F_n $TEST... " $N |
| $TRACE $SOCAT $opts UNIX-LISTEN:"$ts" /dev/null </dev/null 2>"$te1" & |
| spid=$! |
| waitfile "$ts" 1 |
| type=$($FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print($2);}') |
| if [ "$type" = "socket" ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; 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)) |
| 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" |
| fi |
| kill $spid 2>/dev/null |
| wait |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| testptywaitslave () { |
| local N="$1" |
| local TEST="$2" |
| local PTYTYPE="$3" # ptmx or openpty |
| local opts="$4" |
| |
| local tp="$td/test$N.pty" |
| local ts="$td/test$N.socket" |
| local tf="$td/test$N.file" |
| local tdiff="$td/test$N.diff" |
| local te1="$td/test$N.stderr1" |
| local te2="$td/test$N.stderr2" |
| local te3="$td/test$N.stderr3" |
| local te4="$td/test$N.stderr4" |
| local da="test$N $(date) $RANDOM" |
| printf "test $F_n $TEST... " $N |
| # first generate a pty, then a socket |
| ($TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link="$tp" UNIX-LISTEN:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null & |
| pid=$! |
| waitfile "$tp" |
| # if pty was non-blocking, the socket is active, and socat1 will term |
| $TRACE $SOCAT $opts -T 10 -lpsocat2 FILE:/dev/null UNIX-CONNECT:"$ts" 2>"$te2" |
| # if pty is blocking, first socat is still active and we get a connection now |
| #((echo "$da"; sleep 2) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") & |
| ( (waitfile "$ts" 1 20; echo "$da"; sleep 1) |$TRACE $SOCAT -lpsocat3 $opts - FILE:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") & |
| waitfile "$ts" 1 20 |
| # but we need an echoer on the socket |
| $TRACE $SOCAT $opts -lpsocat4 UNIX:"$ts" ECHO 2>"$te4" |
| # now $tf file should contain $da |
| #kill $pid 2>/dev/null |
| wait |
| # |
| if echo "$da" |diff - "$tf"> "$tdiff"; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo " $TRACE $SOCAT $opts -T 10 -lpsocat2 FILE:/dev/null UNIX-CONNECT:\"$ts\"" 2>"$te2" |
| 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)) |
| else |
| $PRINTF "${YELLOW}FAILED${NORMAL}\n" |
| cat "$te1" |
| #cat "$te2" # not of interest |
| cat "$te3" |
| cat "$te4" |
| cat "$tdiff" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| fi |
| } |
| |
| NAME=PTMXWAITSLAVE |
| PTYTYPE=ptmx |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENPTYWAITSLAVE |
| PTYTYPE=openpty |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts" |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the connect-timeout address option |
| NAME=CONNECTTIMEOUT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| # We need a hanging connection attempt, guess an address for this |
| case "$UNAME" in |
| Linux) HANGIP=1.0.0.1 ;; |
| *) HANGIP=255.255.255.254 ;; |
| esac |
| te1="$td/test$N.stderr1" |
| tk1="$td/test$N.kill1" |
| te2="$td/test$N.stderr2" |
| tk2="$td/test$N.kill2" |
| $PRINTF "test $F_n $TEST... " $N |
| # First, try to make socat hang and see if it can be killed |
| #$TRACE $SOCAT $opts - TCP:$HANGIP:1 >"$te1" 2>&1 </dev/null & |
| CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1" |
| $CMD >"$te1" 2>$te1 </dev/null & |
| pid1=$! |
| sleep 2 |
| 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" |
| else |
| # Second, set connect-timeout and see if socat exits before kill |
| CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1,connect-timeout=1.0" |
| $CMD >"$te1" 2>$te2 </dev/null & |
| pid2=$! |
| sleep 2 |
| if kill $pid2 2>"$tk2"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD" >&2 |
| cat "$te2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD" >&2 |
| fi |
| numOK=$((numOK+1)) |
| fi |
| fi |
| wait |
| fi ;; # testfeats, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # version 1.7.0.0 had a bug with the connect-timeout option: while it correctly |
| # terminated a hanging connect attempt, it prevented a successful connection |
| # establishment from being recognized by socat, instead the timeout occurred |
| NAME=CONNECTTIMEOUT_CONN |
| if ! eval $NUMCOND; then :; else |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: TCP4 connect-timeout option when server replies" |
| # just try a connection that is expected to succeed with the usual data |
| # transfer; with the bug it will fail |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIO TCP4:$ts,connect-timeout=1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid1 2>/dev/null |
| wait ;; |
| esac |
| fi # NUMCOND |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSLLISTENDSA |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| SRVCERT=testsrvdsa |
| gentestdsacert $SRVCERT |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 # provide free port number in $PORT |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe" |
| CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" |
| $PRINTF "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| echo "$da" |$CMD >$tf 2>"${te}2" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD2 &" |
| echo "$CMD" |
| cat "${te}1" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # testfeats, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # derive signal number from signal name |
| # kill -l should provide the info |
| signum () { |
| if [ ! "$BASH_VERSION" -o -o posix ]; then |
| # we expect: |
| for i in $(POSIXLY_CORRECT=1 kill -l); do echo "$i"; done |grep -n -i "^$1$" |cut -d: -f1 |
| else |
| # expect: |
| # " 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL" |
| signam="$1" |
| kill -l </dev/null | |
| while read l; do printf "%s %s\n%s %s\n%s %s\n%s %s\n" $l; done | |
| grep -e "SIG$signam\$" | |
| cut -d ')' -f 1 |
| fi |
| } |
| |
| # problems with QUIT, INT (are blocked in system() ) |
| for signam in TERM ILL; do |
| NAME=EXITCODESIG$signam |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%signal%*|*%$NAME%*) |
| 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" |
| else |
| SIG="$(signum $signam)" |
| te="$td/test$N.stderr" |
| tpp="$td/test$N.ppid" |
| tp="$td/test$N.pid" |
| $PRINTF "test $F_n $TEST... " $N |
| (sleep 1; kill -"$SIG" "$(cat "$tpp")") & |
| # a simple "system:echo $PPID..." does not work on NetBSD, OpenBSD |
| #$TRACE $SOCAT $opts echo SYSTEM:'exec /usr/bin/env bash -c "echo \$PPID '">$tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$? |
| tsh="$td/test$N.sh" |
| cat <<EOF >"$tsh" |
| #! /usr/bin/env bash |
| echo \$PPID >"$tpp" |
| echo \$\$ >"$tp" |
| read x |
| EOF |
| chmod a+x "$tsh" |
| #$TRACE $SOCAT $opts echo SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"; stat=$? |
| CMD="$TRACE $SOCAT $opts ECHO SYSTEM:\"exec\\\ \\\"$tsh\\\"\",pty,setsid,nofork" |
| $TRACE $SOCAT $opts ECHO SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te" |
| stat=$? |
| sleep 1; kill -INT $(cat $tp) |
| wait |
| if [ "$stat" -eq $((128+$SIG)) ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| done |
| |
| |
| NAME=READBYTES |
| #set -vx |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| 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" |
| else |
| tr="$td/test$N.ref" |
| ti="$td/test$N.in" |
| to="$td/test$N.out" |
| te="$td/test$N.err" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" |
| # |
| CMD="$TRACE $SOCAT $opts -u open:$ti,readbytes=100 -" |
| printf "test $F_n $TEST... " $N |
| rm -f "$tf" "$ti" "$to" |
| # |
| echo "AAAAAAAAAAAAAAAAAAAAAAAA |
| AAAAAAAAAAAAAAAAAAAAAAAA |
| AAAAAAAAAAAAAAAAAAAAAAAA |
| AAAAAAAAAAAAAAAAAAAAAAAA" >"$tr" # 100 bytes |
| cat "$tr" "$tr" >"$ti" # 200 bytes |
| $CMD >"$to" 2>"$te" |
| if ! diff "$tr" "$to" >"$tdiff" 2>&1; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDPLISTENFORK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%listen%*|*%fork%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| 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 udp socket in background |
| #processes hang forever without -T |
| newport udp4 # provide free port number in $PORT |
| CMD0="$TRACE $SOCAT -T 5 $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,$REUSEADDR,fork PIPE" |
| #make a first and a second connection |
| CMD1="$TRACE $SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT" |
| $PRINTF "test $F_n $TEST... " $N |
| eval "$CMD0 2>${te}0 &" |
| pids=$! |
| waitudp4port "$PORT" |
| echo "$da1" |eval "$CMD1" >"${tf}1" 2>"${te}1" |
| if [ $? -ne 0 ]; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$NO_RESULT (first conn failed):\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$NO_RESULT (first conn failed); diff:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| cat "$tdiff" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| sleep 2 # UDP-LISTEN sleeps 1s |
| echo "$da2" |eval "$CMD1" >"${tf}2" 2>"${te}2" |
| rc="$?"; kill "$pids" 2>/dev/null |
| if [ $rc -ne 0 ]; then |
| $PRINTF "$FAILED:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then |
| $PRINTF "$FAILED: diff\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "diff:" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi # !( $? -ne 0) |
| fi # !(rc -ne 0) |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # Is a listen address capable of forking two 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 |
| *%$N%*|*%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=$(testfeats $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 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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") |
| newport $protov # provide free port number 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="$TRACE $SOCAT -T 5 $opts -lpserver $PROTOV-LISTEN:$tla,$REUSEADDR,fork PIPE" |
| # make a first and a second connection |
| CMD1="$TRACE $SOCAT $opts -lpclient - $PROTOV-CONNECT:$tca" |
| $PRINTF "test $F_n $TEST... " $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" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD1" |
| cat "${te}2" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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 |
| if [ "$VERBOSE" ]; then echo "$CMD1"; fi |
| if [ "$DEBUG" ]; then cat "${te}2" >&2; fi |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| done <<<" |
| TCP4 $LOCALHOST PORT |
| TCP6 $LOCALHOST6 PORT |
| UDP4 $LOCALHOST PORT |
| UDP6 $LOCALHOST6 PORT |
| SCTP4 $LOCALHOST PORT |
| SCTP6 $LOCALHOST6 PORT |
| UNIX FILE , |
| " |
| |
| |
| NAME=UNIXTOSTREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: generic UNIX client connects to stream socket" |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N $(date) $RANDOM" |
| #establish a listening unix socket in background |
| SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE" |
| #make a connection |
| CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts\"" |
| $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 "$FAILED:\n" |
| echo "$SRV &" |
| echo "$CLI" |
| cat "${te}s" "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| wait |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UNIXTODGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%recv%*|*%$NAME%*) |
| TEST="$NAME: generic UNIX client connects to datagram socket" |
| if ! eval $NUMCOND; then :; else |
| ts1="$td/test$N.socket1" |
| ts2="$td/test$N.socket2" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N $(date) $RANDOM" |
| #establish a receiving unix datagram socket in background |
| SRV="$TRACE $SOCAT $opts -lpserver UNIX-RECVFROM:\"$ts1\" PIPE" |
| #make a connection |
| CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\",bind=\"$ts2\"" |
| #CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\"" |
| $PRINTF "test $F_n $TEST... " $N |
| eval "$SRV 2>${te}s &" |
| pids=$! |
| waitfile "$ts1" |
| echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1" |
| rc=$? |
| kill $pids 2>/dev/null |
| wait |
| if [ $rc -ne 0 ]; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CLI" |
| cat "${te}1" "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CLI" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # there was an error in address EXEC with options pipes,stderr |
| NAME=EXECPIPESSTDERR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| 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" |
| opts="$SAVE_opts" |
| esac |
| N=$((N+1)) |
| |
| # EXEC and SYSTEM with stderr injected socat messages into the data stream. |
| NAME=EXECSTDERRLOG |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: simple echo via exec of cat with pipes,stderr" |
| SAVE_opts="$opts" |
| # make sure at least two -d are there |
| case "$opts" in |
| *-d*-d*) ;; |
| *-d*) opts="$opts -d" ;; |
| *) opts="-d -d" ;; |
| esac |
| testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts" |
| opts="$SAVE_opts" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=SIMPLEPARSE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*) |
| TEST="$NAME: invoke socat from socat" |
| testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=FULLPARSE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%parse%*|*%$NAME%*) |
| TEST="$NAME: correctly parse special chars" |
| if ! eval $NUMCOND; then :; else |
| $PRINTF "test $F_n $TEST... " $N |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| # a string where commas are hidden in nesting lexical constructs |
| # if they are scanned incorrectly, socat will see an "unknown option" |
| dain='(,)[,]{,}","([),])hugo' |
| daout='(,)[,]{,},([),])hugo' |
| $TRACE "$SOCAT" $opts -u "exec:echo $dain" - >"$tf" 2>"$te" |
| rc=$? |
| echo "$daout" |diff "$tf" - >"$tdiff" |
| if [ "$rc" -ne 0 ]; then |
| $PRINTF "$FAILED:\n" |
| echo "$TRACE $SOCAT" -u "exec:echo $da" - |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif [ -s "$tdiff" ]; then |
| $PRINTF "$FAILED:\n" |
| echo diff: |
| cat "$tdiff" |
| if [ -n "$debug" ]; then cat $te; fi |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| 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 |
| esac |
| N=$((N+1)) |
| |
| 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 |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=TCP6BYTCP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waittcp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null; wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # test the UDP4-SENDTO and UDP4-RECVFROM addresses together |
| NAME=UDP4DGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: UDP/IPv4 sendto and recvfrom" |
| # start a UDP4-RECVFROM process that echoes data, and send test data using |
| # UDP4-SENDTO. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| ts1a="127.0.0.1" |
| ts1="$ts1a:$ts1p" |
| newport udp4; ts2p=$PORT |
| ts2="127.0.0.1:$ts2p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| waitudp4port $ts1p 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2="$?" |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6DGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp6; ts1p=$PORT |
| tsa="[::1]" |
| ts1="$tsa:$ts1p" |
| newport udp6; ts2p=$PORT |
| ts2="$tsa:$ts2p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| waitudp6port $ts1p 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=RAWIP4RECVFROM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%rawip%*|*%rawip4%*|*%dgram%*|*%root%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO; PROTO=$((PROTO+1)) |
| ts1a="127.0.0.1" |
| ts1="$ts1a:$ts1p" |
| ts2a="$SECONDADDR" |
| ts2="$ts2a:$ts2p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE" |
| CMD2="$TRACE $SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1=$! |
| waitip4proto $ts1p 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # root, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| if false; then |
| NAME=RAWIP6RECVFROM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%dgram%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO; PROTO=$((PROTO+1)) |
| tsa="[::1]" |
| ts1="$tsa:$ts1p" |
| ts2="$tsa" |
| da="test$N $(date) $RANDOM" |
| #CMD1="$TRACE $SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE" |
| CMD2="$TRACE $SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2" |
| printf "test $F_n $TEST... " $N |
| #$CMD1 2>"${te}1" & |
| waitip6proto $ts1p 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| # echo "$CMD1 &" |
| # cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # root, NUMCOND |
| esac |
| N=$((N+1)) |
| fi #false |
| |
| |
| NAME=UNIXDGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: UNIX datagram" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1="$td/test$N.socket1" |
| ts2="$td/test$N.socket2" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE" |
| CMD2="$TRACE $SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| waitfile $ts1 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| kill "$pid1" 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP4RECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*) |
| TEST="$NAME: UDP/IPv4 receive" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| ts1a="127.0.0.1" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| waitudp4port $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| #ls -l $tf |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6RECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%udp%*|*%udp6%*|*%recv%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp6; ts1p=$PORT |
| ts1a="[::1]" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - UDP6-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| waitudp6port $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| #ls -l $tf |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=RAWIP4RECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO; PROTO=$((PROTO+1)) |
| ts1a="127.0.0.1" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| waitip4proto $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| #ls -l $tf |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, root |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=RAWIP6RECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%rawip%*|*%rawip6%*|*%recv%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO; PROTO=$((PROTO+1)) |
| ts1a="[::1]" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - IP6-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| waitip6proto $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, root |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UNIXRECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%unix%*|*%dgram%*|*%recv%*|*%$NAME%*) |
| TEST="$NAME: UNIX receive" |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1="$ts" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| waitfile $ts1 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP4RECVFROM_SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4RECVFROM_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4RECVFROM_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) |
| TEST="$NAME: security of UDP4-RECVFROM with RANGE option" |
| newport udp4 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 |
| if ! eval $NUMCOND; then :; else |
| testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4RECVFROM_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp4 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr,fork" "" "tcpwrap=$d" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 |
| testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP4RECV_SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*) |
| 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" |
| else |
| newport udp4; PORT1=$PORT |
| newport udp4; PORT2=$PORT |
| newport udp4; PORT3=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP4-RECV:$PORT1,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT2" "" "sp=$PORT3" "UDP4-RECV:$PORT2!!UDP4-SENDTO:127.0.0.1:$PORT1" 4 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4RECV_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*) |
| 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" |
| else |
| newport udp4; PORT1=$PORT |
| newport udp4; PORT2=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP4-RECV:$PORT1,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT2" "" "lowport" "UDP4-RECV:$PORT2!!UDP4-SENDTO:127.0.0.1:$PORT1" 4 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4RECV_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*) |
| 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" |
| else |
| newport udp4; PORT1=$PORT |
| newport udp4; PORT2=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP4-RECV:$PORT1,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT2" "" "range=$SECONDADDR/32" "UDP4-RECV:$PORT2!!UDP4-SENDTO:127.0.0.1:$PORT1" 4 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP4RECV_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*) |
| 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" |
| else |
| newport udp4; PORT1=$PORT |
| newport udp4; PORT2=$PORT |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP4-RECV:$PORT1,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT2" "" "tcpwrap-etc=$td" "UDP4-RECV:$PORT2!!UDP4-SENDTO:127.0.0.1:$PORT1" 4 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6RECVFROM_SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6RECVFROM_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) |
| 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" |
| 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 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6RECVFROM_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) |
| 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" |
| 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 |
| testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6RECVFROM_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp6 # provide free port number in $PORT |
| testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6RECV_SOURCEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*) |
| 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" |
| else |
| newport udp6; PORT1=$PORT |
| newport udp6; PORT2=$PORT |
| newport udp6; PORT3=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP6-RECV:$PORT1,reuseaddr!!UDP6-SENDTO:[::1]:$PORT2" "" "sp=$PORT3" "UDP6-RECV:$PORT2!!UDP6-SENDTO:[::1]:$PORT1" 6 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6RECV_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*) |
| 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" |
| else |
| newport udp6; PORT1=$PORT |
| newport udp6; PORT2=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP6-RECV:$PORT1,reuseaddr!!UDP6-SENDTO:[::1]:$PORT2" "" "lowport" "UDP6-RECV:$PORT2!!UDP6-SENDTO:[::1]:$PORT1" 6 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6RECV_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*) |
| 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" |
| else |
| newport udp6; PORT1=$PORT |
| newport udp6; PORT2=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP6-RECV:$PORT1,reuseaddr!!UDP6-SENDTO:[::1]:$PORT2" "" "range=[::2]/128" "UDP6-RECV:$PORT2!!UDP6-SENDTO:[::1]:$PORT1" 6 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=UDP6RECV_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*) |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp6; PORT1=$PORT |
| newport udp6; PORT2=$PORT |
| # we use the forward channel (PORT1) for testing, and have a backward channel |
| # (PORT2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "UDP6-RECV:$PORT1,reuseaddr!!UDP6-SENDTO:[::1]:$PORT2" "" "tcpwrap-etc=$td" "UDP6-RECV:$PORT2!!UDP6-SENDTO:[::1]:$PORT1" 6 udp $PORT1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=IP4RECVFROM_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| newport udp4 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$PROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "IP4-SENDTO:127.0.0.1:$PROTO" 4 ip $PROTO 0 |
| testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$PROTO,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT" "" "range=$SECONDADDR/32" "UDP4-RECV:$PORT!!IP4-SENDTO:127.0.0.1:$PROTO" 4 ip $PROTO 0 |
| fi ;; # NUMCOND, feats, root |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| NAME=IP4RECVFROM_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp4 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "IP4-SENDTO:127.0.0.1:$PROTO" 4 ip $PROTO 0 |
| testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$PROTO,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT" "" "tcpwrap-etc=$td" "UDP4-RECV:$PORT!!IP4-SENDTO:127.0.0.1:$PROTO" 4 ip $PROTO 0 |
| fi # NUMCOND, feats, root |
| ;; |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| NAME=IP4RECV_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| PROTO1=$PROTO; PROTO=$((PROTO+1)) |
| PROTO2=$PROTO |
| # we use the forward channel (PROTO1) for testing, and have a backward channel |
| # (PROTO2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "ip4-recv:$PROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$PROTO2" "" "range=$SECONDADDR/32" "ip4-recv:$PROTO2!!ip4-sendto:127.0.0.1:$PROTO1" 4 ip $PROTO1 0 |
| fi ;; # NUMCOND, feats, root |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| |
| NAME=IP4RECV_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| PROTO1=$PROTO; PROTO=$((PROTO+1)) |
| PROTO2=$PROTO |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: $SECONDADDR" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| # we use the forward channel (PROTO1) for testing, and have a backward channel |
| # (PROTO2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "ip4-recv:$PROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$PROTO2" "" "tcpwrap-etc=$td" "ip4-recv:$PROTO2!!ip4-sendto:127.0.0.1:$PROTO1" 4 ip $PROTO1 0 |
| fi ;; # NUMCOND, feats, root |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| NAME=IP6RECVFROM_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| newport udp6 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$PROTO,reuseaddr,fork" "" "range=[::2]/128" "IP6-SENDTO:[::1]:$PROTO" 6 ip $PROTO 0 |
| testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$PROTO,reuseaddr!!UDP6-SENDTO:[::1]:$PORT" "" "range=[::2]/128" "UDP6-RECV:$PORT!!IP6-SENDTO:[::1]:$PROTO" 6 ip $PROTO 0 |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| NAME=IP6RECVFROM_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| newport udp6 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "IP6-SENDTO:[::1]:$PROTO" 6 ip $PROTO 0 |
| testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$PROTO,reuseaddr!!UDP6-SENDTO:[::1]:$PORT" "" "tcpwrap-etc=$td" "UDP6-RECV:$PORT!!IP6-SENDTO:[::1]:$PROTO" 6 ip $PROTO 0 |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| NAME=IP6RECV_RANGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| PROTO1=$PROTO; PROTO=$((PROTO+1)) |
| PROTO2=$PROTO |
| # we use the forward channel (PROTO1) for testing, and have a backward channel |
| # (PROTO2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "ip6-recv:$PROTO1,reuseaddr!!ip6-sendto:[::1]:$PROTO2" "" "range=[::2]/128" "ip6-recv:$PROTO2!!ip6-sendto:[::1]:$PROTO1" 6 ip $PROTO1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| NAME=IP6RECV_TCPWRAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| PROTO1=$PROTO; PROTO=$((PROTO+1)) |
| PROTO2=$PROTO |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat: [::2]" >"$ha" |
| $ECHO "ALL: ALL" >"$hd" |
| # we use the forward channel (PROTO1) for testing, and have a backward channel |
| # (PROTO2) to get the data back, so we get the classical echo behaviour |
| testserversec "$N" "$TEST" "$opts" "ip6-recv:$PROTO1,reuseaddr!!ip6-sendto:[::1]:$PROTO2" "" "tcpwrap-etc=$td" "ip6-recv:$PROTO2!!ip6-sendto:[::1]:$PROTO1" 6 ip $PROTO1 0 |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| NAME=O_NOATIME_FILE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%open%*|*%noatime%*|*%$NAME%*) |
| TEST="$NAME: option O_NOATIME on file" |
| # idea: create a file with o-noatime option; one second later create a file |
| # without this option (using touch); one second later read from the first file. |
| # Then we check which file has the later ATIME stamp. For this check we use |
| # "ls -ltu" because it is more portable than "test ... -nt ..." |
| 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" |
| else |
| tf="$td/test$N.file" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| $PRINTF "test $F_n $TEST... " $N |
| CMD="$TRACE $SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null" |
| # generate a file |
| touch "${tf}1" |
| sleep 1 |
| # generate a reference file |
| touch "${tf}2" |
| sleep 1 |
| # read from the first file |
| $CMD 2>"$te" |
| if [ $? -ne 0 ]; then # command failed |
| $PRINTF "${FAILED}:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| # check which file has a later atime stamp |
| if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; |
| then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi # wrong time stamps |
| fi # command ok |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=O_NOATIME_FD |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%noatime%*|*%$NAME%*) |
| TEST="$NAME: option O_NOATIME on file descriptor" |
| # idea: use a fd of a file with o-noatime option; one second later create a file |
| # without this option (using touch); one second later read from the first file. |
| # Then we check which file has the later ATIME stamp. For this check we use |
| # "ls -ltu" because it is more portable than "test ... -nt ..." |
| 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" |
| else |
| tf="$td/test$N.file" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| $PRINTF "test $F_n $TEST... " $N |
| touch ${tf}1 |
| CMD="$TRACE $SOCAT $opts -u -,o-noatime /dev/null <${tf}1" |
| # generate a file, len >= 1 |
| touch "${tf}1" |
| sleep 1 |
| # generate a reference file |
| touch "${tf}2" |
| sleep 1 |
| # read from the first file |
| sh -c "$CMD" 2>"$te" |
| if [ $? -ne 0 ]; then # command failed |
| $PRINTF "${FAILED}:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| # check which file has a later atime stamp |
| if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ]; |
| then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi # wrong time stamps |
| fi # command ok |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=FS_NOATIME |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fs%*|*%noatime%*|*%$NAME%*) |
| TEST="$NAME: extended file system options using fs noatime option" |
| # idea: create a file with fs-noatime option; one second later create a file |
| # without this option (using touch); one second later read from the first file. |
| # Then we check which file has the later ATIME stamp. For this check we use |
| # "ls -ltu" because it is more portable than "test ... -nt ..." |
| 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" |
| else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.file" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1="$ts" |
| da="test$N $(date) $RANDOM" |
| $PRINTF "test $F_n $TEST... " $N |
| CMD0="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\"" |
| CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",fs-noatime" |
| # check if this is a capable FS; lsattr does other things on AIX, thus socat |
| $CMD0 2>"${te}0" |
| if [ $? -ne 0 ]; then |
| $PRINTF "${YELLOW} cannot test${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| # generate a file with noatime, len >= 1 |
| $CMD 2>"$te" |
| if [ $? -ne 0 ]; then # command failed |
| $PRINTF "${YELLOW}impotent file system?${NORMAL}\n" |
| echo "$CMD" |
| cat "$te" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| sleep 1 |
| # generate a reference file |
| touch "${tf}2" |
| sleep 1 |
| # read from the first file |
| cat "${tf}1" >/dev/null |
| # check which file has a later atime stamp |
| #if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |awk '{print($8);}') != "${tf}2" ]; |
| if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |sed "s|.*\\($td.*\\)|\1|g") != "${tf}2" ]; |
| then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # not impotent |
| fi # can test |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=COOLWRITE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*) |
| 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" |
| else |
| #set -vx |
| ti="$td/test$N.pipe" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # a reader that will terminate after 1 byte |
| CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null" |
| CMD="$TRACE $SOCAT $opts -u - file:\"$ti\",cool-write" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| bg=$! # background process id |
| sleep 1 |
| (echo .; sleep 1; echo) |$CMD 2>"$te" |
| rc=$? |
| kill $bg 2>/dev/null; wait |
| if [ $rc -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD &" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # test if option coolwrite can be applied to bidirectional address stdio |
| # this failed up to socat 1.6.0.0 |
| NAME=COOLSTDIO |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*) |
| TEST="$NAME: option cool-write on bidirectional stdio" |
| # this test starts a socat reader that terminates after receiving one+ |
| # bytes (option readbytes); and a test process that sends two bytes via |
| # named pipe to the receiving process and, a second later, sends another |
| # byte. The last write will fail with "broken pipe"; if option coolwrite |
| # has been applied successfully, socat will terminate with 0 (OK), |
| # otherwise with error. |
| 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" |
| else |
| #set -vx |
| ti="$td/test$N.pipe" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # a reader that will terminate after 1 byte |
| CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null" |
| CMD="$TRACE $SOCAT $opts -,cool-write pipe >\"$ti\"" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| bg=$! # background process id |
| sleep 1 |
| (echo .; sleep 1; echo) |eval "$CMD" 2>"$te" |
| rc=$? |
| kill $bg 2>/dev/null; wait |
| if [ $rc -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "$te"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=TCP4ENDCLOSE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: end-close keeps TCP V4 socket open" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; p0=$PORT |
| newport tcp4; p1=$PORT |
| da2a="$(date) $RANDOM" |
| da2b="$(date) $RANDOM" |
| CMD0="$TRACE $SOCAT -lp collector $opts -u TCP4-LISTEN:$p0,$REUSEADDR,bind=$LOCALHOST -" |
| CMD1="$TRACE $SOCAT -lp forker $opts -U TCP4:$LOCALHOST:$p0,end-close TCP4-LISTEN:$p1,bind=$LOCALHOST,$REUSEADDR,fork" |
| CMD2="$TRACE $SOCAT -lp client $opts -u - TCP4-CONNECT:$LOCALHOST:$p1" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >"${tf}0" 2>"${te}0" & |
| pid0=$! |
| waittcp4port $p0 1 |
| $CMD1 2>"${te}1" & |
| pid1=$! |
| usleep $MICROS |
| waittcp4port $p1 1 |
| echo "$da2a" |$CMD2 2>>"${te}2a" |
| rc2a=$? |
| echo "$da2b" |$CMD2 2>>"${te}2b" |
| rc2b=$? |
| sleep 1 |
| kill "$pid0" "$pid1" 2>/dev/null |
| wait |
| if [ $rc2a -ne 0 -o $rc2b -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2a" >&2 |
| echo "$CMD2" |
| cat "${te}2b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then |
| $PRINTF "$FAILED (diff)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2a" >&2 |
| echo "$CMD2" |
| cat "${te}2b" >&2 |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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 |
| if [ "$VERBOSE" ]; then echo "$CMD2"; fi |
| 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)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=EXECENDCLOSE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: end-close keeps EXEC child running" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ts="$td/test$N.sock" |
| tdiff="$td/test$N.diff" |
| da1a="$(date) $RANDOM" |
| da1b="$(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$ts" |
| CMD="$TRACE $SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork" |
| printf "test $F_n $TEST... " $N |
| $CMD 2>"${te}2" & |
| pid2=$! |
| waitfile $ts 1 |
| echo "$da1a" |$CMD1 2>>"${te}1a" >"$tf" |
| usleep $MICROS |
| echo "$da1b" |$CMD1 2>>"${te}1b" >>"$tf" |
| #usleep $MICROS |
| kill "$pid2" 2>/dev/null |
| wait |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1a" "${te}1b" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # up to 1.7.0.0 option end-close led to an error with some address types due to |
| # bad internal handling. here we check it for address PTY |
| NAME=PTYENDCLOSE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*) |
| TEST="$NAME: PTY handles option end-close" |
| # with the bug, socat exits with error. we invoke socat in a no-op mode and |
| # check its return status. |
| if ! eval $NUMCOND; then :; |
| else |
| tf="$td/test$N.stout" |
| te="$td/test$N.stderr" |
| # -t must be longer than 0.1 on OpenBSD |
| CMD="$TRACE $SOCAT $opts -d -d -t 0.5 /dev/null pty,end-close" |
| printf "test $F_n $TEST... " $N |
| # AIX reports the pty writeable for select() only when its slave side has been |
| # opened, therefore we run this process in background and check its NOTICE |
| # output for the PTY name |
| { $CMD 2>"${te}"; echo $? >"$td/test$N.rc0"; } & |
| waitfile "${te}" |
| psleep 0.1 |
| PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //') |
| [ -e "$PTY" ] && cat $PTY >/dev/null 2>/dev/null |
| rc=$(cat "$td/test$N.rc0") |
| if [ "$rc" = 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the shut-null and null-eof options |
| NAME=SHUTNULLEOF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: options shut-null and null-eof" |
| # Run a receiving background process with option null-eof. |
| # Start a sending process with option shut-null that sends a test record to the |
| # receiving process and then terminates. |
| # Send another test record. |
| # When the receiving process only received and stored the first test record the |
| # test succeeded |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport udp4 # provide free port number in $PORT |
| CMD0="$TRACE $SOCAT $opts -u UDP-RECV:$PORT,null-eof CREAT:$tf" |
| CMD1="$TRACE $SOCAT $opts -u - UDP-SENDTO:127.0.0.1:$PORT,shut-null" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitudp4port $PORT 1 |
| { echo "$da"; psleep 0.1; } |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| { echo "xyz"; psleep 0.1; } |$CMD1 >"${tf}2" 2>"${te}2" |
| rc2=$? |
| kill $pid0 2>/dev/null; wait |
| if [ $rc1 != 0 -o $rc2 != 0 ]; then |
| $PRINTF "$FAILED (client(s) failed)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD1" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif echo "$da" |diff - "${tf}" >"$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 |
| if [ "$VERBOSE" ]; then echo "$CMD2"; fi |
| if [ "$DEBUG" ]; then cat "${te}2" >&2; fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED (diff)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo "// diff:" >&2 |
| cat "${tdiff}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP6LISTENBIND |
| # this tests for a bug in (up to) 1.5.0.0: |
| # with udp*-listen, the bind option supported only IPv4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%ip6%*|*%ipapp%*|*%udp%*|*%udp6%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp6; tsl=$PORT |
| ts="$LOCALHOST6:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,$REUSEADDR,bind=$LOCALHOST6 PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP6:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waitudp6port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=TCPWRAPPERS_MULTIOPTS |
| # this tests for a bug in 1.5.0.0 that let socat fail when more than one |
| # tcp-wrappers related option was specified in one address |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| ha="$td/hosts.allow" |
| $ECHO "test : ALL : allow" >"$ha" |
| newport tcp4 # provide free port number in $PORT |
| CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR,hosts-allow=$ha,tcpwrap=test pipe" |
| CMD2="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1=$! |
| waittcp4port $PORT |
| echo "$da" |$CMD2 >"$tf" 2>"${te}2" |
| rc2=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=TCPWRAPPERS_TCP6ADDR |
| # this tests for a bug in 1.5.0.0 that brought false results with tcp-wrappers |
| # and IPv6 when |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| ha="$td/hosts.allow" |
| hd="$td/hosts.deny" |
| $ECHO "socat : [::1] : allow" >"$ha" |
| $ECHO "ALL : ALL : deny" >"$hd" |
| newport tcp6 # provide free port number in $PORT |
| CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT,$REUSEADDR,tcpwrap-etc=$td,tcpwrappers=socat pipe" |
| CMD2="$TRACE $SOCAT $opts - TCP6:[::1]:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1=$! |
| waittcp6port $PORT |
| echo "$da" |$CMD2 >"$tf" 2>"${te}2" |
| rc2=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=UDP4BROADCAST |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| #ts1="$BCADDR/8:$ts1p" |
| ts1="$BCADDR:$ts1p" |
| newport udp4; ts2p=$PORT |
| ts2="$BCIFADDR:$ts2p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE" |
| #CMD2="$TRACE $SOCAT $opts - UDP4-BROADCAST:$ts1" |
| CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| waitudp4port $ts1p 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2="$?" |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$tut" ]; then |
| echo "$CMD1 &" |
| echo "$CMD2" |
| fi |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=IP4BROADCAST |
| # test a local broadcast of a raw IPv4 protocol. |
| # because we receive - in addition to the regular reply - our own broadcast, |
| # we use a token XXXX that is changed to YYYY in the regular reply packet. |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| elif [ -z "$BCADDR" ]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO |
| #ts1="$BCADDR/8:$ts1p" |
| ts1="$BCADDR:$ts1p" |
| ts2p=$ts1p |
| ts2="$BCIFADDR" |
| da="test$N $(date) $RANDOM XXXX" |
| sh="$td/test$N-sed.sh" |
| echo 'sed s/XXXX/YYYY/' >"$sh" |
| chmod a+x "$sh" |
| # EXEC need not work with script (musl libc), so use SYSTEM |
| CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,broadcast SYSTEM:$sh" |
| #CMD2="$TRACE $SOCAT $opts - IP4-BROADCAST:$ts1" |
| CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:$ts1,broadcast" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| waitip4port $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |grep -v XXXX >>"$tf" |
| rc2="$?" |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| #NAME=UDP4BROADCAST_RANGE |
| #case "$TESTS" in |
| #*%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%range%*|*%$NAME%*) |
| #TEST="$NAME: security of UDP4-BROADCAST with RANGE option" |
| #if ! eval $NUMCOND; then :; |
| #elif [ -z "$BCADDR" ]; then |
| # $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N |
| #else |
| #newport udp4 # provide free port number in $PORT |
| #testserversec "$N" "$TEST" "$opts" "UDP4-BROADCAST:$BCADDR/8:$PORT" "" "range=127.1.0.0:255.255.0.0" "udp4:127.1.0.0:$PORT" 4 udp $PORT 0 |
| #fi ;; # NUMCOND, feats |
| #esac |
| #N=$((N+1)) |
| |
| |
| NAME=UDP4MULTICAST_UNIDIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| ts1a="$SECONDADDR" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -" |
| CMD2="$TRACE $SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" >"${tf}" & |
| pid1="$!" |
| waitudp4port $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| usleep $MICROS |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=IP4MULTICAST_UNIDIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO |
| ts1a="$SECONDADDR" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -" |
| CMD2="$TRACE $SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" >"${tf}" & |
| pid1="$!" |
| waitip4proto $ts1p 1 |
| usleep $MICROS |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| #usleep $MICROS |
| sleep 1 |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| if true; then |
| # This test succeeds, e.g., on CentOS-7 with kernel 3.10.0, Ubuntu-16.04 with 4.4.0 |
| # but fails, e.g., on Ubuntu-18.04 with kernel 4.15.0, CentOS-8 with 4.10.0 |
| NAME=UDP6MULTICAST_UNIDIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%multicast%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| 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" |
| elif ! echo |$SOCAT -u -t 0.1 - UDP6-SENDTO:[ff02::2]: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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp6; ts1p=$PORT |
| if1="$MCINTERFACE" |
| ts1a="[::1]" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,$REUSEADDR,ipv6-join-group=[ff02::2]:$if1 -" |
| #CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a" |
| CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" >"${tf}" & |
| pid1="$!" |
| waitudp6port $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| usleep $MICROS |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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" |
| # else |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| # fi |
| 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)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| fi # false |
| |
| NAME=UDP4MULTICAST_BIDIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*) |
| TEST="$NAME: UDP/IPv4 multicast, with reply" |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| ts1a="$SECONDADDR" |
| ts1="$ts1a:$ts1p" |
| newport udp4; ts2p=$PORT |
| ts2="$BCIFADDR:$ts2p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE" |
| #CMD2="$TRACE $SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a" |
| CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| waitudp4port $ts1p 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2="$?" |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo diff: >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=IP4MULTICAST_BIDIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO |
| ts1a="$SECONDADDR" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE" |
| #CMD2="$TRACE $SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a" |
| CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| waitip4port $ts1p 1 |
| usleep 100000 # give process a chance to add multicast membership |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2="$?" |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$tut" ]; then |
| echo "$CMD1 &" |
| echo "$CMD2" |
| fi |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| NAME=TUNREAD |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%tun%*|*%root%*|*%$NAME%*) |
| TEST="$NAME: reading data sent through tun interface" |
| #idea: create a TUN interface and send a datagram to one of the addresses of |
| # its virtual network. On the tunnel side, read the packet and compare its last |
| # bytes with the datagram payload |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| tl="$td/test$N.lock" |
| da="test$N $(date) $RANDOM" |
| dalen=$((${#da}+1)) |
| TUNNET=10.255.255 |
| newport udp4 # provide free port number in $PORT |
| CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT" |
| #CMD="$TRACE $SOCAT $opts -u -L $tl TUN,ifaddr=$TUNNET.1,netmask=255.255.255.0,iff-up=1 -" |
| CMD="$TRACE $SOCAT $opts -u -L $tl TUN:$TUNNET.1/24,iff-up=1 -" |
| printf "test $F_n $TEST... " $N |
| $CMD 2>"${te}" |tail -c $dalen >"${tf}" & |
| sleep 1 |
| echo "$da" |$CMD1 2>"${te}1" |
| sleep 1 |
| kill "$(cat $tl 2>/dev/null)" 2>/dev/null |
| wait |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD &" |
| echo "$CMD1" |
| cat "${te}" "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # use the INTERFACE address on a tun/tap device and transfer data fully |
| # transparent |
| NAME=TUNINTERFACE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%tun%*|*%interface%*|*%root%*|*%$NAME%*) |
| TEST="$NAME: pass data through tun interface using INTERFACE" |
| #idea: create a TUN interface and send a raw packet on the interface side. |
| # It should arrive unmodified on the tunnel side. |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| tl="$td/test$N.lock" |
| da="$(date) $RANDOM" |
| TUNNET=10.255.255 |
| TUNNAME=tun9 |
| CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME PIPE" |
| CMD1="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}1" & |
| pid0="$!" |
| #waitinterface "$TUNNAME" |
| usleep $MICROS |
| { echo "$da"; usleep $MICROS ; } |$CMD1 >"$tf" 2>"${te}" |
| rc1=$? |
| usleep $MICROS |
| 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 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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:" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=ABSTRACTSTREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%connect%*|*%listen%*|*%$NAME%*) |
| 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" |
| else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da1="test$N $(date) $RANDOM" |
| #establish a listening abstract unix socket |
| SRV="$TRACE $SOCAT $opts -lpserver ABSTRACT-LISTEN:\"$ts\",$REUSEADDR PIPE" |
| #make a connection |
| CMD="$TRACE $SOCAT $opts - ABSTRACT-CONNECT:$ts" |
| $PRINTF "test $F_n $TEST... " $N |
| touch "$ts" # make a file with same name, so non-abstract fails |
| eval "$SRV 2>${te}s &" |
| pids=$! |
| #waitfile "$ts" |
| sleep 1 |
| echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1" |
| if [ $? -ne 0 ]; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then |
| kill "$pids" 2>/dev/null |
| $PRINTF "$FAILED:\n" |
| echo "$SRV &" |
| cat "${te}s" |
| echo "$CMD" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi # !(rc -ne 0) |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=ABSTRACTDGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%$NAME%*) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1="$td/test$N.socket1" |
| ts2="$td/test$N.socket2" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE" |
| #CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2" |
| CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2" |
| printf "test $F_n $TEST... " $N |
| touch "$ts1" # make a file with same name, so non-abstract fails |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| sleep 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| kill "$pid1" 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=ABSTRACTRECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%recv%*|*%$NAME%*) |
| 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" |
| else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1="$ts" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - ABSTRACT-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| touch "$ts1" # make a file with same name, so non-abstract fails |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| #waitfile $ts1 1 |
| sleep 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # bind with Linux abstract UNIX domain addresses bound to filesystem socket |
| # instead of abstract namespace |
| NAME=ABSTRACT_BIND |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%$NAME%*) |
| TEST="$NAME: abstract bind" |
| # open an abstract client address with bind option, bind to the target socket. |
| # send a datagram. |
| # when socat outputs the datagram it got the test succeeded |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1="$td/test$N.sock1" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts1" |
| printf "test $F_n $TEST... " $N |
| echo "$da" |$CMD1 >$tf 2>"${te}1" |
| rc1=$? |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1" |
| echo "rc=$rc1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| echo "$da" |diff - "$tf" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSLREAD |
| # socat determined availability of data using select(). With openssl, the |
| # following situation might occur: |
| # a SSL data block with more than 8192 bytes (socats default blocksize) |
| # arrives; socat calls SSL_read, and the SSL routine reads the complete block. |
| # socat then reads 8192 bytes from the SSL layer, the rest remains buffered. |
| # If the TCP connection stays idle for some time, the data in the SSL layer |
| # keeps there and is not transferred by socat until the socket indicates more |
| # data or EOF. |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: socat handles data buffered by openssl" |
| #idea: have a socat process (server) that gets an SSL block that is larger than |
| # socat transfer block size; keep the socket connection open and kill the |
| # server process after a short time; if not the whole data block has been |
| # transferred, the test has failed. |
| 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" |
| else |
| tf="$td/test$N.out" |
| te="$td/test$N.err" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| SRVCERT=testsrv |
| gentestcert "$SRVCERT" |
| newport tcp4 # provide free port number in $PORT |
| CMD1="$TRACE $SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=$SRVCERT.pem,verify=0 -" |
| CMD2="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0" |
| printf "test $F_n $TEST... " $N |
| # |
| $CMD1 2>"${te}1" >"$tf" & |
| pid=$! # background process id |
| waittcp4port $PORT |
| (echo "$da"; sleep 2) |$CMD2 2>"${te}2" |
| kill "$pid" 2>/dev/null; wait |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| wait |
| fi # NUMCOND, featsesac |
| ;; |
| esac |
| 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 |
| # more data, no EOF), socat waits for more data instead of generating EOF on |
| # this in put stream. |
| NAME=READBYTES_EOF |
| #set -vx |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: trigger EOF after that many bytes, even when socket idle" |
| #idea: we deliver that many bytes to socat; the process should terminate then. |
| # we try to transfer data in the other direction then; if transfer succeeds, |
| # the process did not terminate and the bug is still there. |
| 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" |
| else |
| tr="$td/test$N.ref" |
| ti="$td/test$N.in" |
| to="$td/test$N.out" |
| te="$td/test$N.err" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')" |
| CMD="$TRACE $SOCAT $opts SYSTEM:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null" |
| printf "test $F_n $TEST... " $N |
| (usleep $((2*MICROS)); echo) |eval "$CMD" >"$to" 2>"$te" |
| if test -s "$to"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # test: there was a bug with exec:...,pty that did not kill the exec'd sub |
| # process under some circumstances. |
| NAME=EXECPTYKILL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%pty%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: exec:...,pty explicitely 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 |
| # has failed |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ts="$td/test$N.sock" |
| tda="$td/test$N.data" |
| tsh="$td/test$N.sh" |
| tdiff="$td/test$N.diff" |
| cat >"$tsh" <<EOF |
| sleep $SECONDs; echo; sleep $SECONDs; touch "$tda"; echo |
| EOF |
| chmod a+x "$tsh" |
| CMD1="$TRACE $SOCAT $opts -t $SECONDs -U UNIX-LISTEN:$ts,fork EXEC:$tsh,pty" |
| CMD="$TRACE $SOCAT $opts -t $SECONDs /dev/null UNIX-CONNECT:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}2" & |
| pid1=$! |
| sleep $SECONDs |
| waitfile $ts $SECONDs |
| $CMD 2>>"${te}1" >>"$tf" |
| sleep $((2*SECONDs)) |
| kill "$pid1" 2>/dev/null |
| wait |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif [ -f "$tda" ]; then |
| $PRINTF "$FAILED\n" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test if service name resolution works; this was buggy in 1.5 and 1.6.0.0 |
| NAME=TCP4SERVICE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: echo via connection to TCP V4 socket" |
| # select a tcp entry from /etc/services, have a server listen on the port |
| # number and connect using the service name; with the bug, connection will to a |
| # wrong port |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| # find a service entry we do not need root for (>=1024; here >=1100 for ease) |
| SERVENT="$(grep '^[a-z][a-z]*[^!-~][^!-~]*[1-9][1-9][0-9][0-9]/tcp' /etc/services |head -n 1)" |
| SERVICE="$(echo $SERVENT |cut -d' ' -f1)" |
| _PORT="$PORT" |
| PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')" |
| tsl="$PORT" |
| ts="127.0.0.1:$SERVICE" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waittcp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid1 2>/dev/null |
| wait |
| PORT=$_PORT |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test: up to socat 1.6.0.0, the highest file descriptor supported in socats |
| # transfer engine was FOPEN_MAX-1; this usually worked fine but would fail when |
| # socat was invoked with many file descriptors already opened. socat would |
| # just hang in the select() call. Thanks to Daniel Lucq for reporting this |
| # problem. |
| # FOPEN_MAX on different OS's: |
| # OS FOPEN_ ulimit ulimit FD_ |
| # MAX -H -n -S -n SETSIZE |
| # Linux 2.6: 16 1024 1024 1024 |
| # HP-UX 11.11: 60 2048 2048 2048 |
| # FreeBSD: 20 11095 11095 1024 |
| # Cygwin: 20 unlimit 256 64 |
| # AIX: 32767 65534 65534 |
| # SunOS 8: 20 1024 |
| # musl libc: 1024 |
| NAME=EXCEED_FOPEN_MAX |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%maxfds%*|*%$NAME%*) |
| TEST="$NAME: more than FOPEN_MAX FDs in use" |
| # this test opens a number of FDs before socat is invoked. socat will have to |
| # allocate higher FD numbers and thus hang if it cannot handle them. |
| 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" |
| 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" |
| else |
| if [ $FOPEN_MAX -lt 270 ]; then |
| OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX |
| else |
| OPEN_FILES=269 # bash tends to SIGSEGV on higher value |
| # btw, the test is obsolete anyway |
| fi |
| i=3; while [ "$i" -lt "$OPEN_FILES" ]; do |
| REDIR="$REDIR $i>&2" |
| i=$((i+1)) |
| done |
| #echo "$REDIR" |
| #testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1 |
| #set -vx |
| eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR |
| #set +vx |
| fi # could determine FOPEN_MAX |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # there was a bug with udp-listen and fork: terminating sub processes became |
| # zombies because the master process did not catch SIGCHLD |
| NAME=UDP4LISTEN_SIGCHLD |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%zombie%*|*%signal%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: test if UDP4-LISTEN child becomes zombie" |
| # idea: run a udp-listen process with fork and -T. Connect once, so a sub |
| # process is forked off. Make some transfer and wait until the -T timeout is |
| # over. Now check for the child process: if it is zombie the test failed. |
| # Correct is that child process terminated |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; tsl=$PORT |
| ts="$LOCALHOST:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,$REUSEADDR,fork PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waitudp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| sleep 1 |
| #read -p ">" |
| 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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif $(isdefunct "$l"); then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| #set +vx |
| |
| # there was a bug with udp-recvfrom and fork: terminating sub processes became |
| # zombies because the master process caught SIGCHLD but did not wait() |
| NAME=UDP4RECVFROM_SIGCHLD |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%fork%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%signal%*|*%$NAME%*) |
| TEST="$NAME: test if UDP4-RECVFROM child becomes zombie" |
| # idea: run a udp-recvfrom process with fork and -T. Send it one packet, so a |
| # sub process is forked off. Make some transfer and wait until the -T timeout |
| # is over. Now check for the child process: if it is zombie the test failed. |
| # Correct is that child process terminated |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; tsl=$PORT |
| ts="$LOCALHOST:$tsl" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE" |
| CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waitudp4port $tsl 1 |
| echo "$da" |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2=$? |
| sleep 1 |
| #read -p ">" |
| l="$(childprocess $pid1)" |
| #echo "l=\"$l\"" |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2 -ne 0 ]; 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" |
| 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" |
| elif $(isdefunct "$l"); then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| cat "${te}1" "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test: there was a bug with ip*-recv and bind option: it would not bind, and |
| # with the first received packet an error: |
| # socket_init(): unknown address family 0 |
| # occurred |
| NAME=RAWIP4RECVBIND |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*) |
| TEST="$NAME: raw IPv4 receive with bind" |
| # idea: start a socat process with ip4-recv:...,bind=... and send it a packet |
| # if the packet passes the test succeeded |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts1p=$PROTO; PROTO=$((PROTO+1)) |
| ts1a="127.0.0.1" |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -" |
| CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1="$!" |
| waitip4proto $ts1p 1 |
| echo "$da" |$CMD2 2>>"${te}2" |
| rc2="$?" |
| #ls -l $tf |
| i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid1" 2>/dev/null; wait |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| echo "$CMD2" |
| cat "${te}1" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, root |
| esac |
| PROTO=$((PROTO+1)) |
| N=$((N+1)) |
| |
| |
| # there was a bug in *-recvfrom with fork: due to an error in the appropriate |
| # signal handler the master process would hang after forking off the first |
| # child process. |
| NAME=UDP4RECVFROM_FORK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: test if UDP4-RECVFROM handles more than one packet" |
| # idea: run a UDP4-RECVFROM process with fork and -T. Send it one packet; |
| # send it a second packet and check if this is processed properly. If yes, the |
| # test succeeded. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; tsp=$PORT |
| ts="$LOCALHOST:$tsp" |
| da2a="test$N $(date) $RANDOM" |
| da2b="test$N $(date) $RANDOM" |
| CMD1="$TRACE $SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE" |
| CMD2="$TRACE $SOCAT $opts -T 1 - UDP4-SENDTO:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >/dev/null 2>"${te}1" & |
| pid1=$! |
| waitudp4port $tsp 1 |
| echo "$da2a" |$CMD2 >/dev/null 2>>"${te}2a" # this should always work |
| rc2a=$? |
| echo "$da2b" |$CMD2 >"$tf" 2>>"${te}2b" # this would fail when bug |
| rc2b=$? |
| kill $pid1 2>/dev/null; wait |
| if [ $rc2b -ne 0 ]; then |
| $PRINTF "$NO_RESULT\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" >&2 |
| cat "${te}1" >&2 |
| echo "$CMD2" >&2 |
| cat "${te}2b" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # there was a bug in parsing the arguments of exec: consecutive spaces resulted |
| # in additional empty arguments |
| NAME=EXECSPACES |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%parse%*|*%$NAME%*) |
| TEST="$NAME: correctly parse exec with consecutive spaces" |
| if ! eval $NUMCOND; then :; else |
| $PRINTF "test $F_n $TEST... " $N |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| da="test$N $(date) $RANDOM" # with a double space |
| tdiff="$td/test$N.diff" |
| # put the test data as first argument after two spaces. expect the data in the |
| # first argument of the exec'd command. |
| $TRACE $SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te" |
| rc=$? |
| echo "$da" |diff - "$tf" >"$tdiff" |
| if [ "$rc" -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # a bug was found in the way UDP-LISTEN handles the listening socket: |
| # when UDP-LISTEN continued to listen after a packet had been dropped by, e.g., |
| # range option, the old listen socket would not be closed but a new one created. |
| NAME=UDP4LISTENCONT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: let range drop a packet and see if old socket is closed" |
| # idea: run a UDP4-LISTEN process with range option. Send it one packet from an |
| # address outside range and check if two listening sockets are open then |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; tp=$PORT |
| da1="test$N $(date) $RANDOM" |
| a1="$LOCALHOST" |
| a2="$SECONDADDR" |
| #CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE" |
| CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,$REUSEADDR,range=$a2/32 PIPE" |
| CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$a1:$tp" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid1=$! |
| waitudp4port $tp 1 |
| echo "$da1" |$CMD1 >"${tf}1" 2>"${te}1" # this should fail |
| rc1=$? |
| waitudp4port $tp 1 |
| if [ "$SS" ]; then |
| nsocks="$($SS -anu |grep ":$PORT\>" |wc -l)" |
| else |
| nsocks="$(netstat -an |grep "^udp.*[:.]$PORT\>" |wc -l)" |
| fi |
| kill $pid1 2>/dev/null; wait |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$NO_RESULT\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ $nsocks -eq 0 ]; then |
| $PRINTF "$NO_RESULT\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # during wait for next poll time option ignoreeof blocked the data transfer in |
| # the reverse direction |
| NAME=IGNOREEOFNOBLOCK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%socket%*|*%ignoreeof%*|*%$NAME%*) |
| TEST="$NAME: ignoreeof does not block other direction" |
| # have socat poll in ignoreeof mode. while it waits one second for next check, |
| # we send data in the reverse direction and then the total timeout fires. |
| # it the data has passed, the test succeeded. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null" |
| printf "test $F_n $TEST... " $N |
| (usleep 333333; echo "$da") |$CMD0 >"$tf" 2>"${te}0" |
| rc0=$? |
| if [ $rc0 != 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif echo "$da" |diff - "$tf" >/dev/null; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test the escape option |
| NAME=ESCAPE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%escape%*|*%$NAME%*) |
| TEST="$NAME: escape character triggers EOF" |
| # idea: start socat just echoing input, but apply escape option. send a string |
| # containing the escape character and check if the output is truncated |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts -,escape=27 pipe" |
| printf "test $F_n $TEST... " $N |
| $ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test the escape option combined with ignoreeof |
| NAME=ESCAPE_IGNOREEOF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%escape%*|*%$NAME%*) |
| TEST="$NAME: escape character triggers EOF" |
| # idea: start socat just echoing input, but apply escape option. send a string |
| # containing the escape character and check if the output is truncated |
| if ! eval $NUMCOND; then :; 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 -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe" |
| printf "test $F_n $TEST... " $N |
| >"$ti" |
| $CMD >"$tf" 2>"$te" & |
| $ECHO "$da\n\x1bXYZ" >>"$ti" |
| sleep 1 |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| cat "$te" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test: logging of ancillary message |
| while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE |
| do |
| if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi |
| # |
| pf="$(echo "$PF" |tr A-Z a-z)" |
| proto="$(echo "$KEYW" |tr A-Z a-z)" |
| NAME=${KEYW}SCM_$SCM_TYPE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%$ROOT%*|*%$NAME%*) |
| TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME" |
| # idea: start a socat process with *-RECV:..,... , ev. with ancillary message |
| # enabling option and send it a packet, ev. with some option. check the info log |
| # for the appropriate output. |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| case "X$IPPORT" in |
| "XPORT") |
| newport $proto; tra="$PORT" # test recv address |
| tsa="$ADDR:$PORT" # test sendto address |
| ;; |
| "XPROTO") |
| tra="$PROTO" # test recv address |
| tsa="$ADDR:$PROTO" # test sendto address |
| PROTO=$((PROTO+1)) ;; |
| *) |
| tra="$(eval echo "$ADDR")" # resolve $N |
| tsa="$tra" |
| esac |
| CMD0="$TRACE $SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -" |
| CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE" |
| printf "test $F_n $TEST... " $N |
| # is this option supported? |
| if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then |
| if [ "$SCM_VALUE" = "timestamp" ]; then |
| secs="$(date '+%S')" |
| if [ "$secs" -ge 58 -a "$secs" -le 59 ]; then |
| dsecs=$((60-secs)) |
| #echo "Sleeping $dsecs seconds to avoid minute change in timestamp" >/dev/tty |
| sleep $dsecs |
| fi |
| fi |
| $CMD0 >"$tf" 2>"${te}0" & |
| pid0="$!" |
| wait${proto}port $tra 1 |
| echo "XYZ" |$CMD1 2>"${te}1" |
| rc1="$?" |
| sleep 1 |
| i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid0" 2>/dev/null; wait |
| # do not show more messages than requested |
| case "$opts" in |
| *-d*-d*-d*-d*) LEVELS="[EWNID]" ;; |
| *-d*-d*-d*) LEVELS="[EWNI]" ;; |
| *-d*-d*) LEVELS="[EWN]" ;; |
| *-d*) LEVELS="[EW]" ;; |
| *) LEVELS="[E]" ;; |
| esac |
| if [ "$SCM_VALUE" = "timestamp" ]; then |
| SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs" |
| fi |
| if [ "$rc1" -ne 0 ]; then |
| $PRINTF "$NO_RESULT: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| grep " $LEVELS " "${te}0" |
| grep " $LEVELS " "${te}1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then |
| $PRINTF "$FAILED\n" |
| echo "variable $SCM_TYPE: $SCM_NAME not set" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| grep " $LEVELS " "${te}0" |
| grep " $LEVELS " "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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')" |
| echo "variable $SCM_TYPE: $SCM_NAME has value \"$badval\" instead of pattern \"$SCM_VALUE\"" >&2 |
| echo "$CMD0 &" |
| echo "$CMD1" |
| grep " $LEVELS " "${te}0" |
| grep " $LEVELS " "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| else # option is not supported |
| $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| fi # option is not supported |
| fi # NUMCOND, root, feats |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS options user x01000000 |
| IP4 UDP4 127.0.0.1 PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp |
| IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL ttl user 53 |
| IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS tos user 7 |
| IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO locaddr user 127.0.0.1 |
| IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO dstaddr user 127.0.0.1 |
| IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO if user lo |
| IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF if user lo0 |
| IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR dstaddr user 127.0.0.1 |
| IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS options root x01000000 |
| IP4 IP4 127.0.0.1 PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp |
| IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL ttl root 53 |
| IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS tos root 7 |
| IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO locaddr root 127.0.0.1 |
| IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO dstaddr root 127.0.0.1 |
| IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO if root lo |
| IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF if root lo0 |
| IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR dstaddr root 127.0.0.1 |
| IP6 UDP6 [::1] PORT , so-timestamp SCM_TIMESTAMP timestamp user 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 x000000aa |
| 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 x000000aa |
| #UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user timestamp |
| " |
| # this one fails, appearently due to a Linux weakness: |
| # UNIX so-timestamp |
| |
| |
| # test: setting of environment variables that describe a stream socket |
| # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT, |
| # SOCAT_PEERPORT when applicable |
| while read KEYW FEAT TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do |
| if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi |
| # |
| protov="$(echo "$KEYW" |tr A-Z a-z)" |
| proto="${protov%%[0-9]}" |
| NAME=${KEYW}LISTENENV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses" |
| # have a server accepting a connection and invoking some shell code. The shell |
| # code extracts and prints the SOCAT related environment vars. |
| # outside code then checks if the environment contains the variables correctly |
| # describing the peer and local sockets. |
| 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" |
| elif [ "$KEYW" = "TCP6" -o "$KEYW" = "UDP6" -o "$KEYW" = "SCTP6" ] && \ |
| ! runsip6 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ "$KEYW" = "SCTP4" ] && ! runssctp4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available${NORMAL}\n" $N |
| elif [ "$KEYW" = "SCTP6" ] && ! runssctp6 >/dev/null; then |
| #!!! branch not reached - caught above! |
| $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available${NORMAL}\n" $N |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars |
| tsa="$TEST_SOCKADDR" # test server address |
| if [ "$PORTMETHOD" == PORT ]; then |
| newport $proto; tsp="$PORT"; # test server port |
| tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind= |
| else |
| tsa1="$tsa"; tsa2= # tsa1 used for addr parameter |
| fi |
| TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars |
| tca="$TEST_PEERADDR" # test client address |
| if [ $PORTMETHOD = PORT ]; then |
| newport $proto; tcp="$PORT"; # test client port |
| tca="$tca:$tcp" |
| fi |
| #CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\"" |
| CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-LISTEN:$tsa1,$REUSEADDR SYSTEM:\"echo SOCAT_SOCKADDR=\\\$SOCAT_SOCKADDR; echo SOCAT_PEERADDR=\\\$SOCAT_PEERADDR; echo SOCAT_SOCKPORT=\\\$SOCAT_SOCKPORT; echo SOCAT_PEERPORT=\\\$SOCAT_PEERPORT; sleep 1\"" |
| CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" >\"$tf\" &" |
| pid0=$! |
| wait${protov}port $tsa1 1 |
| { echo; sleep 0.1; } |$CMD1 2>"${te}1" |
| rc1=$? |
| waitfile "$tf" 2 |
| kill $pid0 2>/dev/null; wait |
| #set -vx |
| if [ $rc1 != 0 ]; then |
| $PRINTF "$NO_RESULT (client failed):\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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')" = "$tsp" \) -a \ |
| \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tcp" \) \ |
| ]; then |
| $PRINTF "$OK\n" |
| if [ "$debug" ]; then |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| 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" |
| fi |
| fi # NUMCOND, feats |
| ;; |
| esac |
| N=$((N+1)) |
| #set +xv |
| # |
| done <<<" |
| TCP4 TCP 127.0.0.1 $SECONDADDR PORT |
| TCP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT |
| UDP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT |
| SCTP4 SCTP 127.0.0.1 $SECONDADDR PORT |
| SCTP6 SCTP [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT |
| UNIX UNIX $td/test\$N.server $td/test\$N.client , |
| " |
| # this one fails due to weakness in socats UDP4-LISTEN implementation: |
| #UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5)) |
| |
| |
| # test: environment variables from ancillary message |
| while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE |
| do |
| if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi |
| # |
| pf="$(echo "$PF" |tr A-Z a-z)" |
| proto="$(echo "$KEYW" |tr A-Z a-z)" |
| NAME=${KEYW}ENV_$SCM_ENVNAME |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*) |
| #set -vx |
| TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME" |
| # idea: start a socat process with *-RECVFROM:..,... , ev. with ancillary |
| # message enabling option and send it a packet, ev. with some option. write |
| # the resulting environment to a file and check its contents for the |
| # appropriate variable. |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| case "X$IPPORT" in |
| "XPORT") |
| newport $proto; tra="$PORT" # test recv address |
| tsa="$ADDR:$tra" # test sendto address |
| ;; |
| "XPROTO") |
| tra="$PROTO" # test recv address |
| tsa="$ADDR:$PROTO" # test sendto address |
| PROTO=$((PROTO+1)) ;; |
| *) |
| tra="$(eval echo "$ADDR")" # resolve $N |
| tsa="$tra" |
| esac |
| #CMD0="$TRACE $SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"export -p\"" |
| # without that ultra escaped quote the test failed for IPv6 when there was file ./1 |
| CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"echo \\\\\\\"\\\$SOCAT_$SCM_ENVNAME\\\\\\\"\"" |
| CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE" |
| printf "test $F_n $TEST... " $N |
| # is this option supported? |
| if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then |
| if [ "$SCM_VALUE" = "timestamp" ]; then |
| secs="$(date '+%S')" |
| if [ "$secs" -ge 58 -a "$secs" -le 59 ]; then |
| dsecs=$((60-secs)) |
| #echo "Sleeping $dsecs seconds to avoid minute change in timestamp" >/dev/tty |
| sleep $dsecs |
| fi |
| fi |
| eval "$CMD0 >\"$tf\" 2>\"${te}0\" &" |
| pid0="$!" |
| wait${proto}port $tra 1 |
| { echo "XYZ"; sleep 0.1; } |$CMD1 2>"${te}1" |
| rc1="$?" |
| waitfile "$tf" 2 |
| #i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done |
| kill "$pid0" 2>/dev/null; wait |
| # do not show more messages than requested |
| if [ "$SCM_VALUE" = "timestamp" ]; then |
| SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs" |
| #echo "\"$SCM_VALUE\"" >&2 # debugging |
| fi |
| if [ "$rc1" -ne 0 ]; then |
| $PRINTF "$NO_RESULT: $SOCAT:\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| #elif ! egrep "^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 |
| $PRINTF "$FAILED\n" |
| echo "logged value \"$(cat "$tf")\" instead of $SCM_VALUE" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| else # option is not supported |
| $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| fi # option is not supported |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000 |
| IP4 UDP4 127.0.0.1 PORT , so-timestamp TIMESTAMP user timestamp |
| IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53 |
| IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7 |
| IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1 |
| IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1 |
| IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_IF user lo |
| IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_IF user lo0 |
| IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1 |
| IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000 |
| IP4 IP4 127.0.0.1 PROTO , so-timestamp TIMESTAMP root timestamp |
| IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53 |
| IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7 |
| IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1 |
| IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1 |
| IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo |
| IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_IF root lo0 |
| IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1 |
| IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]] |
| IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35 |
| IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user x000000aa |
| IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]] |
| IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35 |
| IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root x000000aa |
| #UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user timestamp |
| " |
| |
| |
| # test the SOCKET-CONNECT address (against TCP4-LISTEN) |
| NAME=SOCKET_CONNECT_TCP4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: socket connect with TCP/IPv4" |
| # start a TCP4-LISTEN process that echoes data, and send test data using |
| # SOCKET-CONNECT, selecting TCP/IPv4. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; ts0p=$PORT |
| ts0a="127.0.0.1" |
| ts1p=$(printf "%04x" $ts0p); |
| ts1a="7f000001" # "127.0.0.1" |
| ts1="x${ts1p}${ts1a}x0000000000000000" |
| newport tcp4; ts1b=$(printf "%04x" $PORT) |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$ts0p,$REUSEADDR,bind=$ts0a PIPE" |
| CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| waittcp4port $ts0p 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test the SOCKET-CONNECT address (against TCP6-LISTEN) |
| NAME=SOCKET_CONNECT_TCP6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%tcp6%*|*%socket%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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. |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp6; ts0p=$PORT |
| ts0a="[::1]" |
| ts1p=$(printf "%04x" $ts0p); |
| ts1a="00000000000000000000000000000001" # "[::1]" |
| ts1="x${ts1p}x00000000x${ts1a}x00000000" |
| newport tcp6; ts1b=$(printf "%04x" $PORT) |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$ts0p,$REUSEADDR,bind=$ts0a PIPE" |
| CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| waittcp6port $ts0p 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test the SOCKET-CONNECT address (against UNIX-LISTEN) |
| NAME=SOCKET_CONNECT_UNIX |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: socket connect with UNIX domain" |
| # start a UNIX-LISTEN process that echoes data, and send test data using |
| # SOCKET-CONNECT, selecting UNIX socket. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| ts0="$td/test$N.server" |
| ts1="$td/test$N.client" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts0,$REUSEADDR PIPE" |
| CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\"" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| waitfile $ts0 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test the SOCKET-LISTEN address (with TCP4-CONNECT) |
| NAME=SOCKET_LISTEN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: socket recvfrom with TCP/IPv4" |
| # start a SOCKET-LISTEN process that uses TCP/IPv4 and echoes data, and |
| # send test data using TCP4-CONNECT. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport tcp4; ts1p=$PORT |
| ts1a="127.0.0.1" |
| ts0p=$(printf "%04x" $ts1p); |
| ts0a="7f000001" # "127.0.0.1" |
| ts0="x${ts0p}${ts0a}x0000000000000000" |
| newport tcp4; ts1b=$PORT |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts SOCKET-LISTEN:2:6:$ts0,$REUSEADDR PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| #sleep 1 |
| waittcp4port $ts1p 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test the SOCKET-SENDTO address (against UDP4-RECVFROM) |
| NAME=SOCKET_SENDTO |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: socket sendto with UDP/IPv4" |
| # start a UDP4-RECVFROM process that echoes data, and send test data using |
| # SOCKET-SENDTO, selecting UDP/IPv4. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts0p=$PORT |
| ts0a="127.0.0.1" |
| ts1p=$(printf "%04x" $ts0p); |
| ts1a="7f000001" # "127.0.0.1" |
| ts1="x${ts1p}${ts1a}x0000000000000000" |
| newport udp4; ts1b=$(printf "%04x" $PORT) |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE" |
| CMD1="$TRACE $SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| waitudp4port $ts0p 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test the SOCKET-RECVFROM address (with UDP4-SENDTO) |
| NAME=SOCKET_RECVFROM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: socket recvfrom with UDP/IPv4" |
| # start a SOCKET-RECVFROM process that uses UDP/IPv4 and echoes data, and |
| # send test data using UDP4-SENDTO. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| ts1a="127.0.0.1" |
| ts0p=$(printf "%04x" $ts1p); |
| ts0a="7f000001" # "127.0.0.1" |
| ts0="x${ts0p}${ts0a}x0000000000000000" |
| newport udp4; ts1b=$PORT |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE" |
| CMD1="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| sleep 1 # waitudp4port $ts1p 1 |
| echo "$da" |$CMD1 >>"$tf" 2>>"${te}1" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test the SOCKET-RECV address (with UDP4-SENDTO) |
| NAME=SOCKET_RECV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: socket recv with UDP/IPv4" |
| # start a SOCKET-RECV process that uses UDP/IPv4 and writes received data to file, and |
| # send test data using UDP4-SENDTO. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts1p=$PORT |
| ts1a="127.0.0.1" |
| ts0p=$(printf "%04x" $ts1p); |
| ts0a="7f000001" # "127.0.0.1" |
| ts0="x${ts0p}${ts0a}x0000000000000000" |
| newport udp4; ts1b=$PORT |
| ts1="$ts1a:$ts1p" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -" |
| CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" >"$tf" & |
| pid0="$!" |
| sleep 1 # waitudp4port $ts1p 1 |
| echo "$da" |$CMD1 2>>"${te}1" |
| rc1="$?" |
| sleep 1 |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| # test SOCKET-DATAGRAM (with UDP4-DATAGRAM) |
| NAME=SOCKET_DATAGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: socket datagram via UDP/IPv4" |
| # start a UDP4-DATAGRAM process that echoes data, and send test data using |
| # SOCKET-DATAGRAM, selecting UDP/IPv4. The sent data should be returned. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport udp4; ts0p=$PORT |
| newport udp4; ts1p=$PORT |
| ts0a="127.0.0.1" |
| ts1b=$(printf "%04x" $ts0p); |
| ts1a="7f000001" # "127.0.0.1" |
| ts0b=$(printf "%04x" $ts0p) |
| ts1b=$(printf "%04x" $ts1p) |
| ts1="x${ts0b}${ts1a}x0000000000000000" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE" |
| CMD1="$TRACE $SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0="$!" |
| waitudp4port $ts0p 1 |
| echo "$da" |$CMD1 2>>"${te}1" >"$tf" |
| rc1="$?" |
| kill "$pid0" 2>/dev/null; wait; |
| if [ "$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" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat $te; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| NAME=SOCKETRANGEMASK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: security of generic socket-listen with RANGE option" |
| 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" |
| 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 |
| fi ;; # NUMCOND, $SECONDADDR |
| esac |
| N=$((N+1)) |
| |
| |
| # test the generic ioctl-void option |
| NAME=IOCTL_VOID |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%pty%*|*%generic%*|*%$NAME%*) |
| TEST="$NAME: test the ioctl-void option" |
| # there are not many ioctls that apply to non global resources and do not |
| # require root. TIOCEXCL seems to fit: |
| # process 0 provides a pty; |
| # process 1 opens it with the TIOCEXCL ioctl; |
| # process 2 opens it too and fails with "device or resource busy" only when the |
| # previous ioctl was successful |
| 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" |
| else |
| tp="$td/test$N.pty" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts PTY,LINK=$tp pipe" |
| CMD1="$TRACE $SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0" |
| CMD2="$TRACE $SOCAT $opts - file:$tp,raw,echo=0" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitfile $tp 1 |
| (echo "$da"; sleep 2) |$CMD1 >"$tf" 2>"${te}1" & # this should always work |
| pid1=$! |
| usleep 1000000 |
| $CMD2 >/dev/null 2>"${te}2" </dev/null |
| rc2=$? |
| kill $pid0 $pid1 2>/dev/null; wait |
| if ! echo "$da" |diff - "$tf" >/dev/null; then |
| $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| echo "$da" |diff - "$tf" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND, TIOCEXCL |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the generic setsockopt option |
| NAME=SETSOCKOPT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: test the setsockopt option" |
| # Set the TCP_MAXSEG (MSS) option with a reasonable value, this should succeed. |
| # The try again with TCP_MAXSEG=1, this fails at least on Linux. |
| # Thus: |
| # process 0 provides a tcp listening,forking socket |
| # process 1 connects to this port using reasonably MSS, data transfer should |
| # succeed. |
| # Then, |
| # process 2 connects to this port using a very small MSS, this should fail |
| 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" |
| 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-L:$PORT,so-reuseaddr,fork PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,setsockopt=6:$TCP_MAXSEG:512" |
| CMD2="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,setsockopt=6:$TCP_MAXSEG:1" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| (echo "$da"; sleep 1) |$CMD1 >"${tf}1" 2>"${te}1" # this should always work |
| rc1=$? |
| usleep 1000000 |
| (echo "$da"; sleep 1) |$CMD2 >"${tf}2" 2>"${te}2" # this should fail |
| rc2=$? |
| kill $pid0 $pid1 $pid2 2>/dev/null; wait |
| if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then |
| $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" |
| echo "$CMD0 &" |
| cat ${te}0 |
| echo "$CMD1" |
| cat ${te}1 |
| cat "$tdiff" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND, SO_REUSEADDR |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the generic setsockopt-listen option |
| # This test, with setsockopt-int, no longer worked due to fix for options on |
| # listening sockets |
| # Now it got a chance again using new option setsockopt-listen |
| #NAME=SETSOCKOPT_INT |
| NAME=SETSOCKOPT_LISTEN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test the setsockopt-listen option" |
| # there are not many socket options that apply to non global resources, do not |
| # require root, do not require a network connection, and can easily be |
| # tested. SO_REUSEADDR seems to fit: |
| # process 0 provides a tcp listening socket with reuseaddr; |
| # process 1 connects to this port; thus the port is connected but no longer |
| # listening |
| # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the |
| # (generically specified) SO_REUSEADDR socket options did not work |
| # process 3 connects to this port; only if it is successful the test is ok |
| 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" |
| 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-L:$PORT,setsockopt-listen=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT" |
| CMD2="$CMD0" |
| CMD3="$CMD1" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" # this should always work |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| $CMD2 >/dev/null 2>"${te}2" & |
| pid2=$! |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD3 >"${tf}3" 2>"${te}3" |
| rc3=$? |
| kill $pid2 2>/dev/null; wait |
| if ! echo "$da" |diff - "${tf}1" >"${tdiff}1"; then |
| $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" |
| echo "$CMD0 &" |
| cat ${te}0 |
| echo "$CMD1" |
| cat ${te}1 |
| cat "${tdiff}1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ $rc3 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat ${te}0 |
| echo "$CMD1" |
| cat ${te}1 |
| echo "$CMD2 &" |
| cat ${te}2 |
| echo "$CMD3" |
| cat ${te}3 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat ${te}0 |
| echo "$CMD1" |
| cat ${te}1 |
| echo "$CMD2 &" |
| cat ${te}2 |
| echo "$CMD3" |
| cat ${te}3 |
| cat "${tdiff}3" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND, SO_REUSEADDR |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=SCTP4STREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport sctp4; tsl=$PORT |
| ts="127.0.0.1:$tsl" |
| da=$(date) |
| CMD1="$TRACE $SOCAT $opts SCTP4-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT SCTP4:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid1=$! |
| waitsctp4port $tsl 1 |
| # SCTP does not seem to support half close, so we give it 1s to finish |
| (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid1 2>/dev/null |
| wait |
| fi # NUMCOND, feats |
| ;; |
| esac |
| N=$((N+1)) |
| |
| NAME=SCTP6STREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| newport sctp6; tsl=$PORT |
| ts="[::1]:$tsl" |
| da=$(date) |
| CMD1="$TRACE $SOCAT $opts SCTP6-LISTEN:$tsl,$REUSEADDR PIPE" |
| CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT SCTP6:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >"$tf" 2>"${te}1" & |
| pid=$! # background process id |
| waitsctp6port $tsl 1 |
| # SCTP does not seem to support half close, so we let it 1s to finish |
| (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2" |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: diff:\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| fi # NUMCOND, feats |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| if type openssl >/dev/null 2>&1; then |
| OPENSSL_METHOD=$(openssl s_client -help 2>&1 |egrep -e '-tls1_[012]' |sed -e 's/.*\(-tls1_[012]\).*/\1/' |sort |tail -n 1) |
| #OPENSSL_METHOD=$(openssl s_client -help 2>&1 |egrep -o -e '-tls1(_[012])?' |sort |tail -n 1) |
| [ -z "$OPENSSL_METHOD" ] && OPENSSL_METHOD="-tls1" # just so |
| fi |
| |
| # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer |
| # performed a renegotiation. Test if this is fixed. |
| # Note: the renegotiation feature in OpenSSL exists only up to TLSv1.2 |
| NAME=OPENSSLRENEG1 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL connections survive renogotiation" |
| # connect with s_client to socat ssl-l; force a renog, then transfer data. When |
| # data is passed the test succeeded |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| 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,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" |
| #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g |
| CMD1="openssl s_client $OPENSSL_S_CLIENT_4 $OPENSSL_METHOD -port $PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| (echo "R"; sleep 1; echo "$da"; sleep 1) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}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 |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer |
| # performed a renegotiation. The first temporary fix to this problem might |
| # leave socat in a blocking ssl-read state. Test if this has been fixed. |
| # Note: the renegotiation feature in OpenSSL exists only up to TLSv1.2 |
| NAME=OPENSSLRENEG2 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL connections do not block after renogotiation" |
| # connect with s_client to socat ssl-l; force a renog, then transfer data from |
| # socat to the peer. When data is passed this means that the former ssl read no |
| # longer blocks and the test succeeds |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| 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,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 SYSTEM:\"sleep 1; echo \\\\\\\"\\\"$da\\\"\\\\\\\"; sleep 1\"!!STDIO" |
| #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g |
| CMD1="openssl s_client $OPENSSL_S_CLIENT_4 $OPENSSL_METHOD -port $PORT" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 >/dev/null 2>\"${te}0\" &" |
| pid0=$! |
| waittcp4port $PORT 1 |
| (echo "R"; sleep 2) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}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 |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when |
| # command line arguments (whole addresses, host names, file names) were longer |
| # than 512 bytes. |
| NAME=HOSTNAMEOVFL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: stack overflow on overly long host name" |
| # provide a long host name to TCP-CONNECT and check socats exit code |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # prepare long data - perl might not be installed |
| rm -f "$td/test$N.dat" |
| i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts TCP-CONNECT:$(cat "$td/test$N.dat"):$PORT STDIO" |
| printf "test $F_n $TEST... " $N |
| $CMD0 </dev/null 1>&0 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when |
| # command line arguments (whole addresses, host names, file names) were longer |
| # than 512 bytes. |
| NAME=FILENAMEOVFL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%openssl%*|*%$NAME%*) |
| TEST="$NAME: stack overflow on overly long file name" |
| # provide a 600 bytes long key file option to OPENSSL-CONNECT and check socats exit code |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts OPENSSL:localhost:$PORT,key=$(cat "$td/test$N.dat") STDIO" |
| printf "test $F_n $TEST... " $N |
| $CMD0 </dev/null 1>&0 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # socat up to 1.7.3.0 had a stack overflow vulnerability that occurred when |
| # command line arguments (whole addresses, host names, file names) were longer |
| # than 512 bytes and specially crafted. |
| NAME=NESTEDOVFL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%exec%*|*%$NAME%*) |
| TEST="$NAME: stack overflow on overly long nested arg" |
| # provide a long host name to TCP-CONNECT and check socats exit code |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # prepare long data - perl might not be installed |
| rm -f "$td/test$N.dat" |
| i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done |
| CMD0="$TRACE $SOCAT $opts EXEC:[$(cat "$td/test$N.dat")] STDIO" |
| printf "test $F_n $TEST... " $N |
| $CMD0 </dev/null 1>&0 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test for a bug in gopen that lead to crash or warning when opening a unix |
| # domain socket with GOPEN |
| NAME=GOPEN_UNIX_CRASH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%gopen%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: check crash when connecting to a unix domain socket using address GOPEN" |
| # a unix domain server is started in background. the check process connects to |
| # its socket. when this process crashes or issues a warning the bug is present. |
| # please note that a clean behaviour does not proof anything; behaviour of bug |
| # depends on the value of an uninitialized var |
| #set -vx |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ts="$td/test$N.sock" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE" |
| CMD1="$TRACE $SOCAT $opts -d - GOPEN:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" </dev/null & |
| pid0=$! |
| waitunixport "$ts" 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test if socat keeps an existing file where it wanted to create a UNIX socket |
| NAME=UNIXLISTEN_KEEPFILE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: socat keeps an existing file where it wanted to create a UNIX socket" |
| # we create a file and start socat with UNIX-LISTEN on this file. expected |
| # behaviour: socat exits immediately with error, but keeps the file |
| # up to 1.7.1.3, it removed the file |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.file" |
| te="$td/test$N.stderr" |
| CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$tf /dev/null" |
| printf "test $F_n $TEST... " $N |
| rm -f "$tf"; touch "$tf" |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -ne 0 -a -f "$tf" ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # PTY address allowed to specify address parameters but ignored them |
| NAME=PTY_VOIDARG |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*) |
| TEST="$NAME: check if address params of PTY produce error" |
| # invoke socat with address PTY and some param; expect an error |
| if ! eval $NUMCOND; then :; 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 /dev/null PTY:/tmp/xyz" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -ne 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # incomplete writes were reported but led to data loss |
| NAME=INCOMPLETE_WRITE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*) |
| TEST="$NAME: check if incomplete writes are handled properly" |
| # write to a nonblocking fd a block that is too large for atomic write |
| # and check if all data arrives |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tp="$td/test$N.pipe" |
| tw="$td/test$N.wc-c" |
| # this is the size we write() in one call; data is never stored on disk, so |
| # make it large enough to exceed any atomic write size; but higher number might |
| # take much time |
| bytes=100000 # for Linux 2.6.? this must be >65536 |
| CMD0="$TRACE $SOCAT $opts -u PIPE:$tp STDOUT" |
| CMD1="$TRACE $SOCAT $opts -u -b $bytes OPEN:/dev/zero,readbytes=$bytes FILE:$tp,o-nonblock" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" |wc -c >"$tw" & |
| pid=$! |
| waitfile "$tp" |
| $CMD1 2>"${te}1" >"${tf}1" |
| rc1=$? |
| wait |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$NO_RESULT\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ ! -e "$tw" ]; then |
| $PRINTF "$NO_RESULT\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ "$bytes" -eq $(cat "$tw") ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "transferred only $(cat $tw) of $bytes bytes" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSL_ANULL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,$SOCAT_EGD,ciphers=aNULL,verify=0 pipe" |
| CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,ciphers=aNULL,verify=0,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD2 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| echo "$da" |$CMD >$tf 2>"${te}2" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "${YELLOW}FAILED${NORMAL}\n" |
| #echo "$CMD2 &" |
| #echo "$CMD" |
| #cat "${te}1" |
| #cat "${te}2" |
| #cat "$tdiff" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| while read KEYW FEAT ADDR IPPORT; do |
| if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi |
| RUNS=$(tolower $KEYW) |
| PROTO=$KEYW |
| proto="$(echo "$PROTO" |tr A-Z a-z)" |
| feat="$(tolower "$FEAT")" |
| # test the max-children option on really connection oriented sockets |
| NAME=${KEYW}MAXCHILDREN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$feat%*|*%$proto%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: max-children option" |
| # 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 |
| # arrive first because the second process has to wait. |
| 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" |
| 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" |
| else |
| case "X$IPPORT" in |
| "XPORT") |
| newport $proto |
| tsl=$PORT # test socket listen address |
| tsc="$ADDR:$PORT" # test socket connect address |
| ;; |
| *) |
| tsl="$(eval echo "$ADDR")" # resolve $N |
| tsc=$tsl |
| esac |
| #ts="$td/test$N.sock" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -U FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1" |
| CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,shut-null" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| wait${proto}port $tsl 1 |
| (echo "$da 1"; sleep 2) |$CMD1 >"${tf}1" 2>"${te}1" & |
| pid1=$! |
| sleep 1 |
| echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" & |
| pid2=$! |
| sleep 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "(echo \"$da 1\"; sleep 2) |$CMD1" |
| echo "echo \"$da 2\" |$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| done <<<" |
| TCP4 TCP 127.0.0.1 PORT |
| TCP6 TCP [::1] PORT |
| SCTP4 SCTP 127.0.0.1 PORT |
| SCTP6 SCTP [::1] PORT |
| UNIX unix $td/test\$N.server - |
| " |
| # debugging this hanging test was difficult - following lessons learned: |
| # kill <parent> had no effect when child process existed |
| # strace -f (on Fedora-23) sometimes writes/pads? blocks with \0, overwriting client traces |
| # using the TRACE feature lets above kill command kill strace, not socat |
| # care for timing, understand what you want :-) |
| |
| |
| while read KEYW FEAT ADDR IPPORT SHUT; do |
| if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi |
| RUNS=$(tolower $KEYW) |
| PROTO=$KEYW |
| proto="$(echo "$PROTO" |tr A-Z a-z)" |
| # test the max-children option on pseudo connected sockets |
| NAME=${KEYW}MAXCHILDREN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: max-children option" |
| # 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. |
| #If max-children is working correctly only the first data should |
| # arrive. |
| 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" |
| 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" |
| else |
| case "X$IPPORT" in |
| "XPORT") |
| newport $proto |
| tsl=$PORT # test socket listen address |
| tsc="$ADDR:$PORT" # test socket connect address |
| ;; |
| *) |
| tsl="$(eval echo "$ADDR")" # resolve $N |
| tsc=$tsl |
| esac |
| #ts="$td/test$N.sock" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # on some Linux distributions it hangs, thus -T option here |
| CMD0="$TRACE $SOCAT $opts -U -T 4 FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1" |
| CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,$SHUT" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| wait${proto}port $tsl 1 |
| (echo "$da 1"; sleep 3) |$CMD1 >"${tf}1" 2>"${te}1" & |
| pid1=$! |
| sleep 1 |
| echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" & |
| pid2=$! |
| sleep 1 |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "(echo \"$da 1\"; sleep 2) |$CMD1" |
| echo "echo \"$da 2\" |$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| cat "${te}2" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| done <<<" |
| UDP4 UDP 127.0.0.1 PORT shut-null |
| UDP6 UDP [::1] PORT shut-null |
| " |
| # debugging this hanging test was difficult - following lessons learned: |
| # kill <parent> had no effect when child process existed |
| # strace -f (on Fedora-23) sometimes writes/pads? blocks with \0, overwriting client traces |
| # using the TRACE feature lets above kill command kill strace, not socat |
| # care for timing, understand what you want :-) |
| |
| |
| # socat up to 1.7.2.0 had a bug in xioscan_readline() that could be exploited |
| # to overflow a heap based buffer (socat security advisory 3) |
| # problem reported by Johan Thillemann |
| NAME=READLINE_OVFL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%readline%*|*%pty%*|*%$NAME%*) |
| TEST="$NAME: test for buffer overflow in readline prompt handling" |
| # address 1 is the readline where write data was handled erroneous |
| # address 2 provides data to trigger the buffer overflow |
| # when no SIGSEGV or so occurs the test succeeded (bug fixed) |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ti="$td/test$N.data" |
| CMD0="$SOCAT $opts READLINE $ti" |
| printf "test $F_n $TEST... " $N |
| # prepare long data - perl might not be installed |
| #perl -e 'print "\r","Z"x513' >"$ti" |
| echo $E -n "\rA" >"$ti" |
| i=0; while [ $i -lt 32 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$ti"; let i=i+1; done |
| $TRACE $SOCAT - SYSTEM:"$CMD0; echo rc=\$? >&2",pty >/dev/null 2>"${te}0" |
| rc=$? |
| rc0="$(grep ^rc= "${te}0" |sed 's/.*=//')" |
| if [ $rc -ne 0 ]; then |
| $PRINTF "${YELLOW}framework failed${NORMAL}\n" |
| elif [ $rc0 -eq 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| grep -v ^rc= "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Does Socat have -d0 option? |
| opt_d0= |
| if $SOCAT -h |grep -e -d0 >/dev/null; then |
| opt_d0="-d0" |
| fi |
| |
| # socat up to 1.7.2.1 did only shutdown() but not close() an accept() socket |
| # that was rejected due to range, tcpwrap, lowport, or sourceport option. |
| # This file descriptor leak could be used for a denial of service attack. |
| NAME=FDLEAK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: file descriptor leak with range option" |
| # have a TCP-LISTEN with range option; connect with wrong source address until |
| # "open files" limit would exceed. When server continues operation the bug is |
| # not present. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| 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 |
| $PRINTF "${YELLOW}cannot determine ulimit -n${NORMAL}" |
| else |
| if [ $RLIMIT_NOFILE -gt 1024 ]; then |
| ulimit -n 1024 # 65536 takes too long |
| RLIMIT_NOFILE="$(ulimit -n)" |
| fi |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opt_d0 $opts TCP4-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE" |
| #CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,pf=ip4,$REUSEADDR,range=$LOCALHOST4:255.255.255.255 PIPE" |
| CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP4:$SECONDADDR:$PORT,bind=$SECONDADDR" |
| CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST4:$PORT,bind=$LOCALHOST4" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| while [ $RLIMIT_NOFILE -gt 0 ]; do |
| $CMD1 >/dev/null 2>>"${te}1" |
| let RLIMIT_NOFILE=RLIMIT_NOFILE-1 |
| done |
| echo "$da" |$CMD2 >"${tf}2" 2>"${te}2" |
| rc2=$? |
| kill $pid0 2>/dev/null; wait |
| echo -e "$da" |diff "${tf}2" - >$tdiff |
| if [ $rc2 -ne 0 ]; then |
| $PRINTF "$FAILED (rc2=$rc2)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif [ -f "$tdiff" -a ! -s "$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 |
| if [ "$VERBOSE" ]; then echo "$CMD2"; fi |
| if [ "$DEBUG" ]; then cat "${te}2" >&2; fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # ulimit -n |
| fi # NUMCOND |
| ;; |
| esac |
| 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. |
| NAME=PROXY_ADDR_OVFL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: proxy address parameters overflow" |
| # invoke socat PROXY-CONNECT with long proxy server and target server names. If it terminates with exit code >= 128 it is vulnerable |
| # However, even if vulnerable it often does not crash. Therefore we try to use a boundary check program like ElectricFence; only with its help we can tell that clean run proofs absence of vulnerability |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| EF=; for p in ef; do |
| if type ef >/dev/null 2>&1; then |
| EF="ef "; break |
| fi |
| done |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,$REUSEADDR FILE:/dev/null" |
| #CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80" |
| CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >/dev/null 2>"${te}1" |
| rc1=$? |
| if [ $rc1 -lt 128 ]; then |
| if [ "$EF" ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n" |
| numCANT=$((num+1)) |
| listCANT="$listCANT $N" |
| fi |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD1" |
| cat "${te}" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| fi # false |
| |
| |
| # LISTEN addresses in socat up to 1.7.2.1 applied many file descriptor, socket, |
| # and TCP options only to the listening socket instead of the connection socket. |
| NAME=LISTEN_KEEPALIVE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%listen%*|*%keepalive%*|*%socket%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: keepalive option is applied to connection socket" |
| # instance 0 has TCP-LISTEN with option so-keepalive and invokes filan after |
| # accept(). filan writes its output to the socket. instance 1 connects to |
| # instance 0. The value of the sockets so-keepalive option is checked, it must |
| # be 1 |
| if ! eval $NUMCOND; then :; 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,$REUSEADDR,so-keepalive EXEC:\"$FILAN -i 1\",nofork" |
| CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| eval $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| KEEPALIVE="$(cat "${tf}1" |tail -n +2 |sed -e "s/.*KEEPALIVE=//" -e "s/[[:space:]].*//")" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ -z "$KEEPALIVE" ]; then |
| $PRINTF "$NO_RESULT\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ "$KEEPALIVE" = "1" ]; then |
| $PRINTF "$OK\n"; |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # OPENSSL-CONNECT with bind option failed on some systems (eg.FreeBSD, but not |
| # Linux) with "Invalid argument". |
| NAME=OPENSSL_CONNECT_BIND |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test OPENSSL-CONNECT with bind option" |
| # have a simple SSL server that just echoes data. |
| # connect with socat using OPENSSL-CONNECT with bind, send data and check if the |
| # reply is identical. |
| 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" |
| else |
| gentestcert testsrv |
| tf0="$td/test$N.0.stdout" |
| te0="$td/test$N.0.stderr" |
| tf1="$td/test$N.1.stdout" |
| te1="$td/test$N.1.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 PIPE" |
| CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,bind=$LOCALHOST,verify=0" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"$te0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 >"$tf1" 2>"$te1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ "$rc1" -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "$te0" |
| cat "$te1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - $tf1 >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # socat up to version 1.7.2.3 |
| # 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%*) |
| TEST="$NAME: correct evaluation of range mask 0" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| #testserversec "$N" "$TEST" "$opts" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0 |
| CMD0="$TRACE $SOCAT $opts -u TCP4-LISTEN:$PORT,$REUSEADDR,range=127.0.0.1/0 CREATE:$tf" |
| CMD1="$TRACE $SOCAT $opts -u - TCP4-CONNECT:$SECONDADDR:$PORT,bind=$SECONDADDR" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| sleep 1 |
| kill $pid0 2>/dev/null; wait |
| if [ $rc1 != 0 ]; then |
| $PRINTF "${YELLOW}invocation failed${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! [ -f "$tf" ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "${YELLOW}diff failed${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| |
| fi ;; # $SECONDADDR, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test: OPENSSL sets of environment variables with important values of peer certificate |
| newport tcp4 |
| while read ssldist MODE MODULE FIELD TESTADDRESS PEERADDRESS VALUE; do |
| if [ -z "$ssldist" ] || [[ "$ssldist" == \#* ]]; then continue; fi |
| # |
| SSLDIST=$(toupper $ssldist) |
| NAME="ENV_${SSLDIST}_${MODE}_${MODULE}_${FIELD}" |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$ssldist%*|*%envvar%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $SSLDIST sets env SOCAT_${SSLDIST}_${MODULE}_${FIELD}" |
| # have a server accepting a connection and invoking some shell code. The shell |
| # code extracts and prints the SOCAT related environment vars. |
| # outside code then checks if the environment contains the variables correctly |
| # describing the desired field. |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| gentestcert testsrv |
| gentestcert testcli |
| test_proto=tcp4 |
| case "$MODE" in |
| SERVER) |
| CMD0="$SOCAT $opts -u -lp socat $TESTADDRESS SYSTEM:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\"" |
| CMD1="$SOCAT $opts -u /dev/null $PEERADDRESS" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" >\"$tf\" &" |
| pid0=$! |
| wait${test_proto}port $PORT 1 |
| { $CMD1 2>"${te}1"; sleep 1; } |
| rc1=$? |
| waitfile "$tf" 2 |
| kill $pid0 2>/dev/null; wait |
| ;; |
| CLIENT) |
| CMD0="$SOCAT $opts -u /dev/null $PEERADDRESS" |
| CMD1="$SOCAT $opts -u -lp socat $TESTADDRESS SYSTEM:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\"" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" & |
| pid0=$! |
| wait${test_proto}port $PORT 1 |
| eval "$CMD1 2>\"${te}1\" >\"$tf\"" |
| rc1=$? |
| waitfile "$tf" 2 |
| kill $pid0 2>/dev/null; wait |
| ;; |
| esac |
| if [ $rc1 != 0 ]; then |
| $PRINTF "$NO_RESULT (client failed):\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")"; |
| [ "$effval" = "$VALUE" ]; then |
| $PRINTF "$OK\n" |
| if [ "$debug" ]; then |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "expected \"$VALUE\", got \"$effval\"" >&2 |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND, feats |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| openssl SERVER X509 ISSUER OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_ISSUER |
| openssl SERVER X509 SUBJECT OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_SUBJECT |
| openssl SERVER X509 COMMONNAME OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_COMMONNAME |
| openssl SERVER X509 COUNTRYNAME OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_COUNTRYNAME |
| openssl SERVER X509 LOCALITYNAME OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_LOCALITYNAME |
| openssl SERVER X509 ORGANIZATIONALUNITNAME OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_ORGANIZATIONALUNITNAME |
| openssl SERVER X509 ORGANIZATIONNAME OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 $TESTCERT_ORGANIZATIONNAME |
| openssl CLIENT X509 SUBJECT OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 $TESTCERT_SUBJECT |
| openssl CLIENT X509 ISSUER OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,verify=1 OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,bind=$LOCALHOST,cert=testsrv.pem,cafile=testcli.crt,verify=1 $TESTCERT_ISSUER |
| " |
| |
| |
| ############################################################################### |
| # tests: option umask with "passive" NAMED group addresses |
| while read addr fileopt addropts proto diropt ADDR2; do |
| if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi |
| # some passive (listening...) filesystem based addresses did not implement the |
| # umask option |
| ADDR=$(toupper $addr) |
| ADDR_=${ADDR/-/_} |
| PROTO=$(toupper $proto) |
| if [ "$diropt" = "." ]; then diropt=; fi |
| if [ "$fileopt" = "." ]; then fileopt=; fi |
| if [ "$addropts" = "." ]; then addropts=; fi |
| NAME=${ADDR_}_UMASK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%umask%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $ADDR applies option umask" |
| # start a socat process with passive/listening file system entry. Check the |
| # permissions of the FS entry, then terminate the process. |
| # Test succeeds when FS entry exists and has expected permissions. |
| if ! eval $NUMCOND; then :; else |
| if [ $ADDR = PTY ]; then set -xv; fi |
| tlog="$td/test$N.log" |
| te0="$td/test$N.0.stderr" |
| tsock="$td/test$N.sock" |
| if [ -z "$fileopt" ]; then |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,unlink-close=0,umask=177 $ADDR2" |
| else |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,unlink-close=0,umask=177 $ADDR2" |
| fi |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"$te0" & |
| pid0=$! |
| wait${proto} $tsock 1 2>"$tlog" |
| ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi |
| perms=$(fileperms "$tsock") |
| kill $pid0 2>>"$tlog" |
| wait |
| if [ "$ERRNOENT" ]; then |
| $PRINTF "${RED}no entry${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| elif [ "$perms" != "600" ]; then |
| $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| let numOK=numOK+1 |
| fi |
| set +xv |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| # address fileopt addropts waitfor direction ADDR2 |
| create . . file -U FILE:/dev/null |
| open . creat file . FILE:/dev/null |
| gopen . creat file . FILE:/dev/null |
| unix-listen . . unixport . FILE:/dev/null |
| unix-recvfrom . . unixport . FILE:/dev/null |
| unix-recv . . unixport -u FILE:/dev/null |
| pipe . . file -u FILE:/dev/null |
| # pty does not seem to honor umask: |
| #pty link . file . PIPE |
| " |
| |
| |
| # tests: option perm with "passive" NAMED group addresses |
| while read addr fileopt addropts feat waitfor diropt; do |
| if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi |
| # test if passive (listening...) filesystem based addresses implement option perm |
| ADDR=$(toupper $addr) |
| ADDR_=${ADDR/-/_} |
| if [ "$diropt" = "." ]; then diropt=; fi |
| if [ "$fileopt" = "." ]; then fileopt=; fi |
| if [ "$addropts" = "." ]; then addropts=; fi |
| NAME=${ADDR_}_PERM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$feat%*|*%ignoreeof%*|*%perm%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $ADDR applies option perm" |
| # start a socat process with passive/listening file system entry. Check the |
| # permissions of the FS entry, then terminate the process. |
| # Test succeeds when FS entry exists and has expected permissions. |
| if ! eval $NUMCOND; then :; else |
| tlog="$td/test$N.log" |
| te0="$td/test$N.0.stderr" |
| tsock="$td/test$N.sock" |
| # set -vx |
| if [ -z "$fileopt" ]; then |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof" |
| else |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof" |
| fi |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"$te0" & |
| pid0=$! |
| wait${waitfor} $tsock 1 2>"$tlog" |
| ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi |
| perms=$(fileperms "$tsock") |
| kill $pid0 2>>"$tlog" |
| wait |
| if [ "$ERRNOENT" ]; then |
| $PRINTF "${RED}no entry${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| elif [ "$perms" != "511" ]; then |
| $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| let numOK=numOK+1 |
| fi |
| set +vx |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| # address fileopt addropts feat waitfor direction |
| create . . file file -U |
| open . creat file file . |
| gopen . creat file file . |
| unix-listen . . unix unixport . |
| unix-recvfrom . . unix unixport . |
| unix-recv . . unix unixport -u |
| pipe . . pipe file -u |
| pty link . pty file . |
| " |
| |
| |
| # tests: option user with "passive" NAMED group addresses |
| while read addr fileopt addropts feat waitfor diropt; do |
| if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi |
| # test if passive (listening...) filesystem based addresses implement option user |
| ADDR=$(toupper $addr) |
| ADDR_=${ADDR/-/_} |
| if [ "$diropt" = "." ]; then diropt=; fi |
| if [ "$fileopt" = "." ]; then fileopt=; fi |
| if [ "$addropts" = "." ]; then addropts=; fi |
| NAME=${ADDR_}_USER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$feat%*|*%root%*|*%ignoreeof%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $ADDR applies option user" |
| # start a socat process with passive/listening file system entry with user option. |
| # Check the owner of the FS entry, then terminate the process. |
| # Test succeeds when FS entry exists and has expected owner. |
| 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" |
| else |
| tlog="$td/test$N.log" |
| te0="$td/test$N.0.stderr" |
| tsock="$td/test$N.sock" |
| # set -vx |
| if [ -z "$fileopt" ]; then |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof" |
| else |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof" |
| fi |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"$te0" & |
| pid0=$! |
| wait${waitfor} $tsock 1 2>"$tlog" |
| ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi |
| user=$(fileuser "$tsock") |
| kill $pid0 2>>"$tlog" |
| wait |
| if [ "$ERRNOENT" ]; then |
| $PRINTF "${RED}no entry${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| elif [ "$user" != "$SUBSTUSER" ]; then |
| $PRINTF "${RED}user \"$user\", expected \"$SUBSTUSER\" ${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| let numOK=numOK+1 |
| fi |
| set +vx |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| # address fileopt addropts feat waitfor direction |
| create . . file file -U |
| open . creat file file . |
| gopen . creat file file . |
| unix-listen . . unix unixport . |
| unix-recvfrom . . unix unixport . |
| unix-recv . . unix unixport -u |
| pipe . . pipe file -u |
| pty link . pty file . |
| " |
| |
| |
| # tests: is "passive" filesystem entry removed at the end? (without fork) |
| while read addr fileopt addropts feat waitfor diropt crit ADDR2; do |
| if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi |
| # some passive (listening...) filesystem based addresses did not remove the file |
| # system entry at the end |
| ADDR=$(toupper $addr) |
| ADDR_=${ADDR/-/_} |
| if [ "$diropt" = "." ]; then diropt=; fi |
| if [ "$fileopt" = "." ]; then fileopt=; fi |
| if [ "$addropts" = "." ]; then addropts=; fi |
| # $ADDR removes the file system entry when the process is terminated |
| NAME=${ADDR_}_REMOVE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%feat%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $ADDR removes socket entry when terminated while waiting for connection" |
| # start a socat process with listening unix domain socket etc. Terminate the |
| # process and check if the file system socket entry still exists. |
| # Test succeeds when entry does not exist. |
| if ! eval $NUMCOND; then :; else |
| tlog="$td/test$N.log" |
| te0="$td/test$N.0.stderr" |
| tsock="$td/test$N.sock" |
| if [ -z "$fileopt" ]; then |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts $ADDR2" |
| else |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2" |
| fi |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"$te0" & |
| pid0=$! |
| wait${waitfor} "$crit" $tsock 1 2>"$tlog" |
| kill $pid0 2>>"$tlog" |
| rc1=$? |
| wait >>"$tlog" |
| if [ $rc1 != 0 ]; then |
| $PRINTF "${YELLOW}setup failed${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! [ $crit $tsock ]; then |
| $PRINTF "$OK\n" |
| let numOK=numOK+1 |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| # address fileopt addropts feat waitfor direction crit ADDR2 |
| unix-listen . . unix unixport . -e FILE:/dev/null |
| unix-recvfrom . . unix unixport . -e FILE:/dev/null |
| unix-recv . . unix unixport -u -e FILE:/dev/null |
| pipe . . pipe file -u -e FILE:/dev/null |
| pty link . pty file . -L PIPE |
| " |
| |
| |
| # tests: is "passive" filesystem entry removed at the end? (with fork) |
| while read addr fileopt addropts proto diropt crit ADDR2; do |
| if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi |
| # some passive (listening...) filesystem based addresses with fork did not remove |
| # the file system entry at the end |
| ADDR=$(toupper $addr) |
| ADDR_=${ADDR/-/_} |
| PROTO=$(toupper $proto) |
| if [ "$diropt" = "." ]; then diropt=; fi |
| if [ "$fileopt" = "." ]; then fileopt=; fi |
| if [ "$addropts" = "." ]; then addropts=; fi |
| # $ADDR with fork removes the file system entry when the process is terminated |
| NAME=${ADDR_}_REMOVE_FORK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%fork%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: $ADDR with fork removes socket entry when terminated during accept" |
| # start a socat process with listening unix domain socket etc and option fork. |
| # Terminate the process and check if the file system socket entry still exists. |
| # Test succeeds when entry does not exist. |
| if ! eval $NUMCOND; then :; else |
| tlog="$td/test$N.log" |
| te0="$td/test$N.0.stderr" |
| tsock="$td/test$N.sock" |
| if [ -z "$fileopt" ]; then |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,fork,$addropts $ADDR2" |
| else |
| CMD0="$TRACE $SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2" |
| fi |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"$te0" & |
| pid0=$! |
| wait${proto} "$crit" $tsock 1 2>"$tlog" |
| kill $pid0 2>>"$tlog" |
| rc1=$? |
| wait |
| if [ $rc1 != 0 ]; then |
| $PRINTF "${YELLOW}setup failed${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! [ $crit $tsock ]; then |
| $PRINTF "$OK\n" |
| let numOK=numOK+1 |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "$te0" |
| cat "$tlog" |
| let numFAIL=numFAIL+1 |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| # |
| done <<<" |
| # address fileopt addropts waitfor direction crit ADDR2 |
| unix-listen . . unixport . -e FILE:/dev/null |
| unix-recvfrom . . unixport . -e FILE:/dev/null |
| " |
| |
| |
| # bug fix: SYSTEM address child process shut down parents sockets including |
| # SSL connection under some circumstances. |
| NAME=SYSTEM_SHUTDOWN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%system%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*) |
| 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 |
| # 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 :; |
| elif ! testfeats openssl >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 SYSTEM:cat" |
| CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0" |
| 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 [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "rc1=$rc1" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then |
| $PRINTF "$FAILED\n" |
| echo "diff:" |
| cat "$tdiff" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test if TCP4-LISTEN with empty port arg terminates with error |
| NAME=TCP4_NOPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test if TCP4-LISTEN with empty port arg bails out" |
| # run socat with TCP4-LISTEN with empty port arg. Check if it terminates |
| # immediately with return code 1 |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| t0rc="$td/test$N.rc" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$SOCAT $opts TCP4-LISTEN: /dev/null" |
| printf "test $F_n $TEST... " $N |
| { $CMD0 >/dev/null 2>"${te}0"; echo $? >"$t0rc"; } & 2>/dev/null |
| pid0=$! |
| sleep 1 |
| kill $pid0 2>/dev/null; wait |
| if [ ! -f "$t0rc" ]; then |
| $PRINTF "$FAILED\n" |
| echo "no return code of CMD0 stored" >&2 |
| echo "$CMD0 &" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # tests of various SSL methods; from TLS1.3 this method is not avail in OpenSSL: |
| OPENSSL_METHODS_OBSOLETE="SSL3 SSL23" |
| OPENSSL_METHODS_EXPECTED="TLS1 TLS1.1 TLS1.2 DTLS1 DTLS1.2" |
| |
| # the OPENSSL_METHOD_DTLS1 test hangs sometimes, probably depending on the openssl version. |
| OPENSSL_VERSION="$(openssl version)" |
| OPENSSL_VERSION="${OPENSSL_VERSION#* }" |
| OPENSSL_VERSION="${OPENSSL_VERSION%%-*}" |
| OPENSSL_VERSION_GOOD=1.0.2 # this is just a guess. |
| # known bad: 1.0.1e |
| # known good: 1.0.2j |
| |
| |
| # test if the obsolete SSL methods can be used with OpenSSL |
| for method in $OPENSSL_METHODS_OBSOLETE; do |
| |
| NAME=OPENSSL_METHOD_$method |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test OpenSSL method $method" |
| # Start a socat process with obsoelete OpenSSL method, it should fail |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,openssl-method=$method,cert=testsrv.pem,verify=0 PIPE" |
| CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,opensslmethod=$method,verify=0" |
| 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" |
| else |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 1 2>/dev/null; w0=$? # result of waiting for process 0 |
| if [ $w0 -eq 0 ]; then |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| 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)) |
| else |
| $PRINTF "$OK (obsolete method fails)\n" |
| cat "$tdiff" |
| numOK=$((numOK+1)) |
| fi |
| if [ "$VERBOSE" ]; then |
| echo " $CMD0" |
| echo " echo \"$da\" |$CMD1" |
| fi |
| fi # !DTLS1 hang |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| done |
| |
| # test if the various SSL methods can be used with OpenSSL |
| for method in $OPENSSL_METHODS_EXPECTED; do |
| |
| NAME=OPENSSL_METHOD_$method |
| METHFAM=$(tolower "${method%%[0-9]*}") |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%$METHFAM%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test OpenSSL method $method" |
| # Start a socat process listening with OpenSSL and echoing data, |
| # using the selected method |
| # Start a second socat process connecting to the listener using |
| # the same method, send some data and catch the reply. |
| # If the reply is identical to the sent data the test succeeded. |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| if [[ "$method" =~ DTLS* ]]; then |
| newport udp4 |
| else |
| newport tcp4 |
| fi |
| CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,openssl-method=$method,cert=testsrv.pem,verify=0 PIPE" |
| CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,openssl-method=$method,verify=0" |
| 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" |
| else |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| if [[ "$method" =~ DTLS* ]]; then |
| waitudp4port $PORT 1 |
| else |
| waittcp4port $PORT 1 |
| fi |
| 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" |
| numOK=$((numOK+1)) |
| if [ "$VERBOSE" ]; then |
| echo " $CMD0" |
| echo " echo \"$da\" |$CMD1" |
| fi |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| #esac |
| fi |
| fi # !DTLS1 hang |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| done |
| |
| # test security of option openssl-set-min-proto-version |
| OPENSSL_LATEST_PROTO_VERSION=$(openssl s_server --help 2>&1 |grep -e -ssl[1-9] -e -tls[1-9] |awk '{print($1);}' |cut -c 2- |tr '[a-z_]' '[A-Z.]' |sort |tail -n 1) |
| OPENSSL_BEFORELAST_PROTO_VERSION=$(openssl s_server --help 2>&1 |grep -e -ssl[1-9] -e -tls[1-9] |awk '{print($1);}' |cut -c 2- |tr '[a-z_]' '[A-Z.]' |sort |tail -n 2 |head -n 1) |
| |
| NAME=OPENSSL_MIN_VERSION |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| newport tcp4 |
| testserversec "$N" "$TEST" "$opts -4" "SSL-L:$PORT,pf=ip4,reuseaddr,$SOCAT_EGD,verify=0,cert=testsrv.crt,key=testsrv.key" "" "openssl-min-proto-version=$OPENSSL_LATEST_PROTO_VERSION" "SSL:$LOCALHOST:$PORT,cafile=testsrv.crt,$SOCAT_EGD,openssl-max-proto-version=$OPENSSL_BEFORELAST_PROTO_VERSION" 4 tcp $PORT -1 |
| fi ;; # NUMCOND, $fets |
| esac |
| N=$((N+1)) |
| |
| |
| # Address options fdin and fdout were silently ignored when not applicable |
| # due to -u or -U option. Now these combinations are caught as errors. |
| NAME=FDOUT_ERROR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: fdout bails out in write-only context" |
| # use EXEC in write-only context with option fdout. Expected behaviour: error |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$SOCAT $opts -u /dev/null EXEC:cat,fdout=1" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" |
| rc=$? |
| if [ $rc -eq 1 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" |
| echo "command did not terminate with error!" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test if failure exit code of SYSTEM invocation causes socat to also exit |
| # with !=0 |
| NAME=SYSTEM_RC |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%system%*|*%$NAME%*) |
| TEST="$NAME: promote failure of SYSTEM" |
| # run socat with SYSTEM:false and check if socat exits with !=0 |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # shut-none makes sure that the child is not killed by parent |
| CMD0="$TRACE $SOCAT $opts - SYSTEM:false,shut-none" |
| printf "test $F_n $TEST... " $N |
| sleep 1 |$CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test if failure exit code of EXEC invocation causes socat to also exit |
| # with !=0 |
| NAME=EXEC_RC |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%$NAME%*) |
| TEST="$NAME: promote failure of EXEC" |
| # run socat with EXEC:false and check if socat exits with !=0 |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| # shut-none makes sure that the child is not killed by parent |
| CMD0="$TRACE $SOCAT $opts - EXEC:false,shut-none" |
| printf "test $F_n $TEST... " $N |
| sleep 1 |$CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test the so-reuseaddr option |
| NAME=SO_REUSEADDR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test the so-reuseaddr option" |
| # process 0 provides a tcp listening socket with so-reuseaddr; |
| # process 1 connects to this port; thus the port is connected but no longer |
| # listening |
| # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the |
| # SO_REUSEADDR socket options did not work |
| # process 3 connects to this port; only if it is successful the test is ok |
| 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" |
| else |
| newport tcp4; tp="$PORT" |
| 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-L:$tp,$REUSEADDR PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4:localhost:$tp" |
| CMD2="$CMD0" |
| CMD3="$CMD1" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $tp 1 |
| (echo "$da"; sleep 3) |$CMD1 >"$tf" 2>"${te}1" & # this should always work |
| pid1=$! |
| usleep 1000000 |
| $CMD2 >/dev/null 2>"${te}2" & |
| pid2=$! |
| waittcp4port $tp 1 |
| (echo "$da") |$CMD3 >"${tf}3" 2>"${te}3" |
| rc3=$? |
| kill $pid0 $pid1 $pid2 2>/dev/null; wait |
| if ! echo "$da" |diff - "$tf"; then |
| $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ $rc3 -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| echo "$CMD2 &" |
| echo "$CMD3" |
| cat "${te}2" "${te}3" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "${tf}3"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| echo "$CMD2 &" |
| echo "$CMD3" |
| echo "$da" |diff - "${tf}3" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND, SO_REUSEADDR |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test the so-reuseport option |
| NAME=SO_REUSEPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test the so-reuseport option" |
| # process 0 provides a tcp listening socket with so-reuseport; |
| # process 1 provides an equivalent tcp listening socket with so-reuseport; |
| # process 2 connects to this port and transfers data |
| # process 3 connects to this port and transfers data |
| # test succeeds when both data transfers work |
| 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" |
| else |
| newport tcp4; tp="$PORT" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da2="test$N $(date) $RANDOM" |
| da3="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,$REUSEADDR,so-reuseport PIPE" |
| CMD1="$CMD0" |
| CMD2="$TRACE $SOCAT $opts - TCP4:localhost:$tp" |
| CMD3="$CMD2" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| $CMD1 >/dev/null 2>"${te}1" & |
| pid1=$! |
| waittcp4port $tp 1 |
| (echo "$da2") |$CMD2 >"${tf}2" 2>"${te}2" # this should always work |
| rc2=$? |
| (echo "$da3") |$CMD3 >"${tf}3" 2>"${te}3" |
| rc3=$? |
| kill $pid0 $pid1 $pid2 2>/dev/null; wait |
| if ! echo "$da2" |diff - "${tf}2"; then |
| $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ $rc3 -ne 0 ]; then |
| $PRINTF "$FAILED:\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| echo "$CMD3" |
| cat "${te}3" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da2" |diff - "${tf}2"; then |
| $PRINTF "$FAILED:\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| echo "$CMD3" |
| cat "${te}3" |
| echo "$da2" |diff - "${tf}2" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da3" |diff - "${tf}3"; then |
| $PRINTF "$FAILED:\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD2" |
| cat "${te}2" |
| echo "$CMD3" |
| cat "${te}3" |
| echo "$da3" |diff - "${tf}3" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND, SO_REUSEPORT |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped. |
| NAME=EXEC_NOFORK_UNIDIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*) |
| TEST="$NAME: Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped" |
| # invoke a simple echo command with EXEC, nofork, and -u |
| # expected behaviour: output appears on stdout |
| if ! eval $NUMCOND; then :; 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 -u /dev/null EXEC:\"echo \\\\\\\"\\\"$da\\\"\\\\\\\"\",nofork" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0" >"${tf}0" 2>"${te}0" |
| rc1=$? |
| if echo "$da" |diff - "${tf}0" >"$tdiff"; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # OpenSSL ECDHE ciphers were introduced in socat 1.7.3.0 but in the same release |
| # they were broken by a porting effort. This test checks if OpenSSL ECDHE works |
| # 2019-02: this does no longer work (Ubuntu-18.04) |
| NAME=OPENSSL_ECDHE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test OpenSSL ECDHE" |
| # generate a ECDHE key, start an OpenSSL server, connect with a client and try to |
| # pass data |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| #TESTSRV=./testsrvec; gentesteccert $TESTSRV |
| TESTSRV=./testsrv; gentestcert $TESTSRV |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=$TESTSRV.crt,key=$TESTSRV.pem,verify=0 PIPE" |
| CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cipher=ECDHE-ECDSA-AES256-GCM-SHA384,cafile=$TESTSRV.crt,verify=0" |
| 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 [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "failure symptom: client error" >&2 |
| echo "server and stderr:" >&2 |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "client and stderr:" >&2 |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif echo "$da" |diff - "${tf}1" >"$tdiff"; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "server and stderr:" >&2 |
| echo "$CMD1" |
| cat "${te}1" |
| echo "client and stderr:" >&2 |
| echo "$CMD0 &" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # option ipv6-join-group "could not be used" |
| # fixed in 1.7.3.2 |
| NAME=USE_IPV6_JOIN_GROUP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip6%*|*%udp%*|*%udp6%*|*%dgram%*|*%multicast%*|*%$NAME%*) |
| TEST="$NAME: is option ipv6-join-group used" |
| # Invoke socat with option ipv6-join-group on UDP6 address. |
| # 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 |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport udp6 |
| CMD0="$TRACE $SOCAT $opts UDP6-RECV:$PORT,ipv6-join-group=[ff02::2]:$MCINTERFACE /dev/null" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # The fix to "Make code async-signal-safe" used internally FD 3 and FD 4. |
| # Using option fdin=3 did not pass data to executed program. |
| 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 |
| # program |
| if ! eval $NUMCOND; then :; 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 - SYSTEM:\"cat >&3 <&4\",fdin=4,fdout=3" |
| printf "test $F_n $TEST... " $N |
| echo "$da" |$TRACE $SOCAT $opts - SYSTEM:"cat <&3 >&4",fdin=3,fdout=4 >${tf}0 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif echo "$da" |diff - ${tf}0 >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=SOCAT_OPT_HINT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%$NAME%*) |
| TEST="$NAME: check if merging single character options is rejected" |
| if ! eval $NUMCOND; then :; else |
| te="$td/test$N.stderr" |
| CMD0="$TRACE $SOCAT $opts -vx FILE:/dev/null ECHO" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ "$rc0" = "1" ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # test for a bug in Socat version 1.7.3.3 where |
| # termios options of the first address were applied to the second address. |
| NAME=TERMIOS_PH_ALL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%termios%*|*%$NAME%*) |
| TEST="$NAME: are termios options applied to the correct address" |
| # add a termios option to the first address, a tty, and have a second address |
| # with pipe. If no error occurs the termios option was not applied to the pipe, |
| # thus the test succeeded. |
| if ! eval $NUMCOND; then :; 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 -T 1 STDIO,echo=0 EXEC:cat 2>${te}0" |
| echo "$CMD0" >$td/test$N.sh |
| chmod a+x $td/test$N.sh |
| # EXEC need not work with script (musl libc), so use SYSTEM |
| CMD1="$TRACE $SOCAT $opts /dev/null SYSTEM:$td/test$N.sh,pty,$PTYOPTS" |
| printf "test $F_n $TEST... " $N |
| $CMD1 2>"${te}1" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| echo "$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Due to a fallback logic before calling getaddrinfo(), intended to allow use |
| # of service (port) names with SCTP, raw socket addresses where resolved with |
| # socket type stream, which fails for protocol 6 (TCP) |
| # Fixed after 1.7.3.3 |
| NAME=IP_SENDTO_6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%rawip%*|*%rawip4%*|*%$NAME%*) |
| TEST="$NAME: IP-SENDTO::6 passes getaddrinfo()" |
| # invoke socat with address IP-SENDTO:*:6; when this does not fail with |
| # "ai_socktype not supported", the test succeeded |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| CMD0="$TRACE $SOCAT $opts -u /dev/null IP-SENDTO:127.0.0.1:6" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test if the multiple EOF messages are fixed |
| NAME=MULTIPLE_EOF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: multiple EOF messages" |
| # start two processes, connected via UNIX socket. The listener gets EOF from local address immediately; the second process then sends data. If the listener reports "socket 1 (fd .*) is at EOF" only once, the test succeeded |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.sock" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -d -d UNIX-LISTEN:$ts /dev/null" |
| CMD1="$TRACE $SOCAT $opts -d -d - UNIX-CONNECT:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitunixport $ts 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test for integer overflow with data transfer block size parameter |
| NAME=BLKSIZE_INT_OVERFL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%$NAME%*) |
| TEST="$NAME: integer overflow with buffer size parameter" |
| # Use a buffer size that would lead to integer overflow |
| # Test succeeds when Socat terminates with correct error message |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| dat="$td/test$N.dat" |
| # calculate the minimal length with integer overflow |
| case $SIZE_T in |
| 2) CHKSIZE=32768 ;; |
| 4) CHKSIZE=2147483648 ;; |
| 8) CHKSIZE=9223372036854775808 ;; |
| 16) CHKSIZE=170141183460469231731687303715884105728 ;; |
| esac |
| CMD0="$TRACE $SOCAT $opts -T 1 -b $CHKSIZE /dev/null PIPE" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$FAILED (rc=$rc0)\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif [ $rc0 -eq 1 ]; then |
| if grep -q "buffer size option (-b) to big" "${te}0"; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED (rc=$rc0)\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test if unbalanced quoting in Socat addresses is detected |
| NAME=UNBALANCED_QUOTE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*) |
| TEST="$NAME: Test fix of unbalanced quoting" |
| # Invoke Socat with an address containing unbalanced quoting. If Socat prints |
| # a "syntax error" message, the test succeeds |
| if ! eval $NUMCOND; then :; 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 -u FILE:$td/ab\"cd FILE:/dev/null" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Currently (2020) SCTP has not found its way into main distributions |
| # /etc/services file. A fallback mechanism has been implemented in Socat |
| # that allows use of TCP service names when service resolution for SCTP failed. |
| # Furthermore, older getaddrinfo() implementations to not handle SCTP as SOCK_STREAM |
| # at all, fall back to unspecified socktype then. |
| NAME=SCTP_SERVICENAME |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%sctp%*|*%$NAME%*) |
| TEST="$NAME: Service name resolution works with SCTP" |
| # invoke socat with address SCTP4-CONNECT:$LOCALHOST:http; when this fails with |
| # "Connection refused", or does not fail at all, the test succeeded |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| CMD0="$TRACE $SOCAT $opts -u /dev/null SCTP4-CONNECT:$LOCALHOST:http" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| if [ $? -eq 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| elif grep -q "Connection refused" ${te}0; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the o-direct option on reading |
| NAME=O_DIRECT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%engine%*|*%file%*|*%$NAME%*) |
| TEST="$NAME: echo via file with o-direct" |
| # Write data to a file and read it with options o-direct (and ignoreeof) |
| # When the data read is the same as the data written the test succeeded. |
| 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" |
| else |
| tf="$td/test$N.file" |
| to="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| $PRINTF "test $F_n $TEST... " $N |
| CMD="$TRACE $SOCAT $opts - $tf,o-direct,ignoreeof!!$tf" |
| echo "$da" |$CMD >"$to" 2>"$te" |
| rc=$? |
| if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then |
| case $(stat -f $tf |grep "Type: [^[:space:]]*" |sed -e 's/.*\(Type: [^[:space:]]*\).*/\1/' |cut -c 7-) in |
| #case $(stat -f $tf |grep -o "Type: [^[:space:]]*" |cut -c 7-) in |
| ext2/ext3|xfs|reiserfs) |
| $PRINTF "${FAILED}\n" |
| echo "$CMD" >&2 |
| cat "$te" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" ;; |
| *) $PRINTF "${YELLOW}inable file system${NORMAL}\n" |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" ;; |
| esac |
| elif [ $rc -ne 0 ]; then |
| $PRINTF "${FAILED}:\n" |
| echo "$CMD" >&2 |
| cat "$te" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi # command ok |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # test if option unlink-close removes the bind socket file |
| NAME=UNIX_SENDTO_UNLINK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%$NAME%*) |
| TEST="$NAME: Option unlink-close with UNIX sendto socket" |
| # Have a recv socket with option unlink-close=0 |
| # and a sendto socket with option unlink-close=1 |
| # Expected beavior: the recv socket is kept, the |
| # sendto/bind socket is removed |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| uns="$td/test$N.server" |
| unc="$td/test$N.client" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -u UNIX-RECV:$uns,unlink-close=0 GOPEN:$tf" |
| CMD1="$TRACE $SOCAT $opts - UNIX-SENDTO:$uns,bind=$unc,unlink-close=1" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitunixport $uns 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if test -S $uns && ! test -S $unc; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| ls -ld $uns $unc |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # test if option unlink-close removes the bind socket file |
| NAME=UNIX_CONNECT_UNLINK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: Option unlink-close with UNIX connect socket" |
| # Have a listen socket with option unlink-close=0 |
| # and a connect socket with option unlink-close=1 |
| # Expected beavior: the listen socket entry is kept, the |
| # connect/bind socket is removed |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| uns="$td/test$N.server" |
| unc="$td/test$N.client" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$uns,unlink-close=0 GOPEN:$tf" |
| CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$uns,bind=$unc,unlink-close=1" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitunixport $uns 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if test -S $uns && ! test -S $unc; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| ls -ld $uns $unc |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # test the DTLS client feature |
| NAME=OPENSSL_DTLS_CLIENT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL DTLS client" |
| # Run openssl s_server in DTLS mode, wrapped into a simple Socat echoing command. |
| # Start a Socat DTLS client, send data to server and check if reply is received. |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| #set -vx |
| da="test$N $(date) $RANDOM" |
| init_openssl_s_server |
| newport udp4 |
| CMD1="$TRACE openssl s_server $OPENSSL_S_SERVER_4 $OPENSSL_S_SERVER_DTLS -accept $PORT -quiet $OPENSSL_S_SERVER_NO_IGN_EOF -cert testsrv.pem" |
| CMD="$TRACE $SOCAT $opts -T 3 - OPENSSL-DTLS-CLIENT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| ( sleep 2; echo "$da"; sleep 1 ) |$CMD1 2>"${te}1" & |
| pid1=$! # background process id |
| waitudp4port $PORT |
| $CMD >$tf 2>"$te" |
| kill $pid1 2>/dev/null; wait 2>/dev/null |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "$te"; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| # test the DTLS server feature |
| NAME=OPENSSL_DTLS_SERVER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL DTLS server" |
| # Run a socat OpenSSL DTLS server with echo function |
| # Start an OpenSSL s_client, send data and check if repley is received. |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert testsrv |
| 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 udp4 |
| CMD1="$TRACE $SOCAT $opts OPENSSL-DTLS-SERVER:$PORT,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" |
| CMD="openssl s_client $OPENSSL_S_CLIENT_4 -host $LOCALHOST -port $PORT $OPENSSL_S_CLIENT_DTLS" |
| printf "test $F_n $TEST... " $N |
| $CMD1 >/dev/null 2>"${te}1" & |
| pid1=$! |
| waitudp4port $PORT 1 |
| ( echo "$da"; psleep 0.1 ) |$CMD 2>"$te" |grep "$da" >"$tf" |
| rc=$? |
| kill $pid1 2>/dev/null; wait |
| if echo "$da" |diff - $tf >"$tdiff"; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" |
| echo "$CMD" |
| cat "$te" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=OPENSSL_SERVERALTAUTH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestaltcert testalt |
| 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 OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe" |
| CMD1="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=1,cafile=testalt.crt,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| echo "$da" |$CMD1 >$tf 2>"${te}1" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSL_SERVERALTIP4AUTH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestaltcert testalt |
| 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 OPENSSL-LISTEN:$PORT,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe" |
| CMD1="$TRACE $SOCAT $opts - OPENSSL:127.0.0.1:$PORT,verify=1,cafile=testalt.crt,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" &" |
| pid=$! # background process id |
| waittcp4port $PORT |
| echo "$da" |$CMD1 >$tf 2>"${te}1" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| NAME=OPENSSL_SERVERALTIP6AUTH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| else |
| gentestaltcert testalt |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp6 |
| CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe" |
| CMD1="$TRACE $SOCAT $opts - OPENSSL:[::1]:$PORT,verify=1,cafile=testalt.crt,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}0\" &" |
| pid=$! # background process id |
| waittcp6port $PORT |
| echo "$da" |$CMD1 >$tf 2>"${te}1" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the -r and -R options |
| NAME=OPTION_RAW_DUMP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%option%*|*%$NAME%*) |
| TEST="$NAME: raw dump of transferred data" |
| # Start Socat transferring data from left named pipe to right and from right |
| # pipe to left, use options -r and -R, and check if dump files contain correct |
| # 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tp1="$td/test$N.pipe1" |
| tp2="$td/test$N.pipe2" |
| tr1="$td/test$N.raw1" |
| tr2="$td/test$N.raw2" |
| tdiff1="$td/test$N.diff1" |
| tdiff2="$td/test$N.diff2" |
| da1="test$N $(date) $RANDOM" |
| da2="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -r $tr1 -R $tr2 PIPE:$tp1!!/dev/null PIPE:$tp2!!/dev/null" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitfile $tp1 1 |
| echo "$da1" >$tp1 |
| waitfile $tp2 1 |
| echo "$da2" >$tp2 |
| sleep 1 |
| kill $pid0 2>/dev/null; wait |
| if ! echo "$da1" |diff - $tr1 >$tdiff1 || ! echo "$da2" |diff - $tr2 >$tdiff2; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "Left-to-right:" >&2 |
| cat $tdiff1 >&2 |
| echo "Right-to-left:" >&2 |
| cat $tdiff2 >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the OpenSSL SNI feature |
| NAME=OPENSSL_SNI |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%openssl%*|*%foreign%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: Test the OpenSSL SNI feature" |
| # Connect to a server that is known to use SNI. Use an SNI name, not the |
| # certifications default name. When the TLS connection is established |
| # the test succeeded. |
| 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" |
| elif ! feat=$(testoptions openssl-snihost); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ -z "$FOREIGN" ]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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 FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,pf=ip4" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" >&2 |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the openssl-no-sni option |
| NAME=OPENSSL_NO_SNI |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%openssl%*|*%foreign%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: Test the openssl-no-sni option" |
| # Connect to a server that is known to use SNI. Use an SNI name, not the |
| # certifications default name, and use option openssl-no-sni. |
| # When the TLS connection failed the test succeeded. |
| # Please note that this test is only relevant when test OPENSSL_SNI succeeded. |
| 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" |
| 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" |
| elif [ -z "$FOREIGN" ]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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 FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,openssl-no-sni" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -ne 0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" >&2 |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the accept-timeout (listen-timeout) address option |
| NAME=ACCEPTTIMEOUT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%timeout%*|*%$NAME%*) |
| 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" |
| 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" |
| 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 |
| te1="$td/test$N.stderr1" |
| tk1="$td/test$N.kill1" |
| te2="$td/test$N.stderr2" |
| tk2="$td/test$N.kill2" |
| $PRINTF "test $F_n $TEST... " $N |
| # First, try to make socat hang and see if it can be killed |
| newport tcp4 |
| CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr PIPE" |
| $CMD1 >"$te1" 2>&1 </dev/null & |
| pid1=$! |
| sleep 1 |
| if ! kill $pid1 2>"$tk1"; then |
| $PRINTF "${YELLOW}does not hang${NORMAL}\n" |
| echo $CMD1 >&2 |
| cat "$te1" >&2 |
| cat "$tk1" >&2 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| # Second, set accept-timeout and see if socat exits before kill |
| CMD2="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,accept-timeout=1 PIPE" |
| $CMD2 >"$te2" 2>&1 </dev/null & |
| pid2=$! |
| sleep 2 |
| if kill $pid2 2>"$tk2"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD2" >&2 |
| cat "$te2" >&2 |
| cat "$tk2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| fi |
| fi |
| wait |
| fi ;; # testaddrs, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the modified UDP-DATAGRAM address: Now it ignores peerport by default |
| NAME=UDP_DATAGRAM_PEERPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%udp%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: test UDP-DATAGRAM ignoring peerport" |
| # A UDP-DATAGRAM address bound to PORT has defined peer on PORT+1 |
| # From another Socat instance we send a packet to PORT but with source port |
| # PORT+2. The first instance should accept the packet |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport udp4; PORT1=$PORT |
| newport udp4; PORT2=$PORT |
| newport udp4; PORT3=$PORT |
| CMD0="$TRACE $SOCAT $opts -u UDP-DATAGRAM:$LOCALHOST:$PORT2,bind=:$PORT1 -" |
| CMD1="$TRACE $SOCAT $opts -u - UDP-DATAGRAM:$LOCALHOST:$PORT1,bind=:$PORT3" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >${tf}0 2>"${te}0" & |
| pid0=$! |
| waitudp4port $PORT1 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| psleep 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| cat "${tdiff}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the proxy-authorization-file option |
| NAME=PROXYAUTHFILE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| else |
| ta="$td/test$N.auth" |
| 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 |
| CMD0="{ echo -e \"HTTP/1.0 200 OK\\n\"; sleep 2; } |$TRACE $SOCAT $opts - TCP4-L:$PORT,$REUSEADDR,crlf" |
| CMD1="$TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT,proxy-authorization-file=$ta" |
| printf "test $F_n $TEST... " $N |
| echo "user:s3cr3t" >$ta |
| eval "$CMD0 >${tf}0 2>${te}0 &" |
| pid0=$! # background process id |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null |
| wait $pid0 |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| cat "${tf}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then |
| $PRINTF "$FAILED:\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| cat "${tf}0" >&2 |
| echo "Authorization string not in client request" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi |
| numOK=$((numOK+1)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| N=$((N+1)) |
| |
| |
| # Test communication via vsock loopback socket |
| NAME=VSOCK_ECHO |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%vsock%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test communication via VSOCK loopback socket" |
| # Start a listening echo server |
| # Connect with a client, send data and compare reply with original data |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| #newport vsock # nope |
| CMD0="$TRACE $SOCAT $opts VSOCK-LISTEN:$PORT PIPE" |
| CMD1="$TRACE $SOCAT $opts - VSOCK-CONNECT:1:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| sleep 1 |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| 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" |
| 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" |
| elif grep -q "No such device" "${te}1"; then |
| $PRINTF "${YELLOW}Loopback does not work${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # File transfer with OpenSSL stream connection was incomplete |
| # Test file transfer from client to server |
| NAME=OPENSSL_STREAM_TO_SERVER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL stream from client to server" |
| # Start a unidirectional OpenSSL server and stream receiver |
| # Start a unidirectional OpenSSL client that connects to the server and sends |
| # data |
| # Test succeeded when the data received and stored by server is the same as |
| # sent by the 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert testsrv |
| ti="$td/test$N.datain" |
| to="$td/test$N.dataout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts -u OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 CREAT:$to" |
| CMD1="$TRACE $SOCAT $opts -u OPEN:$ti OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt" |
| printf "test $F_n $TEST... " $N |
| i=0; while [ $i -lt 100000 ]; do printf "%9u %9u %9u %9u %9u %9u %9u %9u %9u %9u\n" $i $i $i $i $i $i $i $i $i $i; let i+=100; done >$ti |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| usleep $MICROS |
| kill $pid0 2>/dev/null; wait |
| if [ $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" |
| elif diff $ti $to >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| echo "diff:" >&2 |
| head -n 2 $tdiff >&2 |
| echo ... >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # File transfer with OpenSSL stream connection was incomplete |
| # Test file transfer from server to client |
| NAME=OPENSSL_STREAM_TO_CLIENT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL stream from server to client" |
| # Start a unidirectional OpenSSL server and stream sender |
| # Start a unidirectional OpenSSL client that connects to the server and receives |
| # data |
| # Test succeeded when the data received and stored by client is the same as |
| # sent by the 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert testsrv |
| ti="$td/test$N.datain" |
| to="$td/test$N.dataout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts -U OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 OPEN:$ti" |
| CMD1="$TRACE $SOCAT $opts -u OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt CREAT:$to" |
| printf "test $F_n $TEST... " $N |
| i=0; while [ $i -lt 100000 ]; do printf "%9u %9u %9u %9u %9u %9u %9u %9u %9u %9u\n" $i $i $i $i $i $i $i $i $i $i; let i+=100; done >$ti |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| usleep $MICROS |
| kill $pid0 2>/dev/null; wait |
| if [ $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" |
| elif diff $ti $to >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| echo "diff:" >&2 |
| head -n 2 $tdiff >&2 |
| echo ... >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test file transfer from client to server using DTLS |
| NAME=OPENSSL_DTLS_TO_SERVER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%dtls%*|*%udp%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL DTLS transfer from client to server" |
| # Start a unidirectional OpenSSL DTLS server/receiver |
| # Start a unidirectional OpenSSL DTLS client that connects to the server and |
| # sends data |
| # Test succeeded when the data received and stored by server is the same as |
| # sent by the 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert testsrv |
| ti="$td/test$N.datain" |
| to="$td/test$N.dataout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport udp4 |
| CMD0="$TRACE $SOCAT $opts -u OPENSSL-DTLS-LISTEN:$PORT,pf=ip4,cert=testsrv.pem,verify=0 CREAT:$to" |
| CMD1="$TRACE $SOCAT $opts -u OPEN:$ti OPENSSL-DTLS-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt" |
| printf "test $F_n $TEST... " $N |
| i=0; while [ $i -lt $((2*8192)) ]; do printf "%9u %9u %9u %9u %9u %9u %9u %9u %9u %9u\n" $i $i $i $i $i $i $i $i $i $i; let i+=100; done >$ti |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitudp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| usleep $MICROS |
| kill $pid0 2>/dev/null; wait |
| if [ $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" |
| elif diff $ti $to >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| echo "diff:" >&2 |
| head -n 2 $tdiff >&2 |
| echo ... >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test file transfer from server to client using DTLS |
| NAME=OPENSSL_DTLS_TO_CLIENT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%dtls%*|*%udp%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: OpenSSL DTLS transfer from server to client" |
| # Start a unidirectional OpenSSL DTLS server/sender |
| # Start a unidirectional OpenSSL DTLS client that connects to the server and |
| # receives data |
| # Test succeeded when the data received and stored by client is the same as |
| # sent by the 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| gentestcert testsrv |
| ti="$td/test$N.datain" |
| to="$td/test$N.dataout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport udp4 |
| CMD0="$TRACE $SOCAT $opts -U OPENSSL-DTLS-LISTEN:$PORT,pf=ip4,cert=testsrv.pem,verify=0 OPEN:$ti" |
| CMD1="$TRACE $SOCAT $opts -u OPENSSL-DTLS-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt CREAT:$to" |
| printf "test $F_n $TEST... " $N |
| i=0; while [ $i -lt $((2*8192)) ]; do printf "%9u %9u %9u %9u %9u %9u %9u %9u %9u %9u\n" $i $i $i $i $i $i $i $i $i $i; let i+=100; done >$ti |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitudp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| usleep $MICROS |
| kill $pid0 2>/dev/null; wait |
| if [ $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" |
| elif diff $ti $to >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| echo "diff:" >&2 |
| head -n 2 $tdiff >&2 |
| echo ... >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if the problem with overlapping internal parameters of sockets and |
| # openssl are fixed |
| NAME=OPENSSL_PARA_OVERLAP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%openssl%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test diverse of socket,openssl params" |
| # That bug had not many effects; the simplest to use is possible SIGSEGV on |
| # close when option accept-timeout with fractional seconds was applied |
| 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" |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| trc0="$td/test$N.rc0" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,accept-timeout=4.5,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" |
| CMD1="$TRACE $SOCAT $opts /dev/null OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" || echo $? >$trc0 & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| psleep 0.5 |
| kill $pid0 2>/dev/null; wait |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$CANT\n" |
| numCANT=$((numCANT+1)) |
| elif [ ! -e $trc0 ]; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Bug fix, OpenSSL server could be crashed by client cert with IPv6 address in SubjectAltname |
| NAME=OPENSSL_CLIENT_IP6_CN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%ip6%*|*%socket%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: Test if OpenSSL server may be crashed by client cert with IPv6 address" |
| # Socat 1.7.4.1 had a bug that caused OpenSSL server to crash with SIGSEGV when |
| # it checked a client certificate containing IPv6 address in SubjectAltName and |
| # no openssl-commonname option was given |
| 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" |
| 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" |
| else |
| gentestcert testsrv |
| gentestaltcert testalt |
| 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 -u OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,cert=./testsrv.pem,cafile=./testalt.crt -" |
| CMD1="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:localhost:$PORT,pf=ip4,cafile=testsrv.crt,cert=testalt.pem,verify=0" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null >"${tf}0" 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ $rc1 -eq 0 ] && echo "$da" |diff - "${tf}0" >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if unknown service specs are handled properly |
| NAME=BAD_SERVICE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: test if unknown service specs are handled properly" |
| # Try to resolve an unspecified TCP service " |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts - TCP:$LOCALHOST:zyxw" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" & |
| pid=$! |
| sleep 1 |
| kill -9 $pid 2>/dev/null; |
| rc=$? # did process still exist? |
| if [ $rc -ne 0 ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD &" >&2 |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD &" >&2 |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if the user option with abstract UNIX domain socket is not applied to |
| # file "" (empty name) |
| NAME=ABSTRACT_USER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: Is the fs related user option on ABSTRACT socket applied to FD" |
| # Apply the user option to an abstract socket; check if this produces an error. |
| # No error should occur |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT ABSTRACT-LISTEN:temp,accept-timeout=0.1,user=$USER FILE:/dev/null" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" |
| echo "$da" |$CMD >"${tf}1" 2>"${te}1" |
| rc=$? |
| if [ $rc -eq 0 ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD" >&2 |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" >&2 |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if option -R does not "sniff" left-to-right traffic |
| NAME=SNIFF_RIGHT_TO_LEFT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*) |
| TEST="$NAME: test if option -R does not "sniff" left-to-right traffic" |
| # Use option -R, check if left-to-right traffic is not in output file |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| ts="$td/test$N.sniffed" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts -R $ts - /dev/null" |
| printf "test $F_n $TEST... " $N |
| echo "$da" |$CMD >"${tf}" 2>"${te}" |
| rc=$? |
| if [ ! -f "$ts" ]; then |
| $PRINTF "$CANT\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD" >&2 |
| cat "${te}" >&2 |
| fi |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ ! -s "$ts" ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD" >&2 |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD &" >&2 |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| # Socats access to different types of file system entries using various kinds |
| # of addresses fails in a couple of useless combinations. These failures have |
| # to print an error message and exit with return code 1. |
| # Up to version 1.7.4.2 this desired behaviour was found for most combinations, |
| # however some fix in 1.7.4.3 degraded the overall result. |
| # This group of tests checks all known compinations. |
| while read entry method; do |
| if [ -z "$entry" ] || [[ "$entry" == \#* ]]; then continue; fi |
| NAME=$(toupper $method)_TO_$(toupper $entry) |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%listen%*|*%$NAME%*) |
| #set -vx |
| TEST="$NAME: Failure handling on $method access to $entry" |
| # Create some kind of system entry and try to access it with some improper |
| # address. Check if Socat returns with rc 1 and prints an error message |
| if ! eval $NUMCOND; then :; else |
| ts="$td/test$N.socket" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| |
| printf "test $F_n $TEST... " $N |
| # create an invalid or non-matching UNIX socket |
| case "$entry" in |
| missing) pid0=; rm -f $ts ;; |
| denied) pid0=; rm -f $ts; touch $ts; chmod 000 $ts ;; |
| directory) pid0=; mkdir -p $ts ;; |
| orphaned) pid0= # the remainder of a UNIX socket in FS |
| SOCAT_MAIN_WAIT= $SOCAT $opts UNIX-LISTEN:$ts,unlink-close=0 /dev/null >${tf}0 2>${te}0 & |
| waitunixport $ts 1 |
| SOCAT_MAIN_WAIT= $SOCAT $opts /dev/null UNIX-CONNECT:$ts >>${tf}0 2>>${te}0 |
| ;; |
| file) pid0=; rm -f $ts; touch $ts ;; |
| stream) CMD0="$SOCAT $opts UNIX-LISTEN:$ts /dev/null" |
| SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 & |
| pid0=$! ;; |
| dgram) CMD0="$SOCAT $opts -u UNIX-RECV:$ts /dev/null" |
| SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 & |
| pid0=$! ;; |
| seqpacket) CMD0="$SOCAT $opts UNIX-LISTEN:$ts,socktype=$SOCK_SEQPACKET /dev/null" |
| SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 & |
| pid0=$! ;; |
| esac |
| [ "$pid0" ] && waitunixport $ts 1 |
| # try to access this socket |
| case "$method" in |
| connect) CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts" ;; |
| send) CMD1="$TRACE $SOCAT $opts -u - UNIX-SEND:$ts" ;; |
| sendto) CMD1="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts" ;; |
| seqpacket) CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts,socktype=$SOCK_SEQPACKET" ;; |
| unix) CMD1="$TRACE $SOCAT $opts -u - UNIX-CLIENT:$ts" ;; |
| gopen) CMD1="$TRACE $SOCAT $opts -u - GOPEN:$ts" ;; |
| esac |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| [ "$pid0" ] && { kill $pid0 2>/dev/null; wait; } |
| if [ $rc1 != 1 ]; then |
| $PRINTF "$FAILED (bad return code $rc1)\n" |
| if [ "$pid0" ]; then |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| fi |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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 |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| fi |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| if [ "$pid0" ]; then echo "$CMD0 &" >&2; fi |
| echo "$CMD1" >&2 |
| fi |
| numOK=$((numOK+1)) |
| fi |
| set +vx |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| done <<<" |
| missing connect |
| denied connect |
| directory connect |
| orphaned connect |
| file connect |
| dgram connect |
| seqpacket connect |
| missing send |
| denied send |
| directory send |
| orphaned send |
| file send |
| stream send |
| seqpacket send |
| missing sendto |
| denied sendto |
| directory sendto |
| orphaned sendto |
| file sendto |
| stream sendto |
| seqpacket sendto |
| missing seqpacket |
| denied seqpacket |
| directory seqpacket |
| orphaned seqpacket |
| file seqpacket |
| stream seqpacket |
| dgram seqpacket |
| missing unix |
| denied unix |
| directory unix |
| file unix |
| orphaned unix |
| denied gopen |
| directory gopen |
| orphaned gopen |
| " |
| |
| |
| # Test TCP with options connect-timeout and retry. |
| # 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%*) |
| 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 |
| # server is not listening; when socat makes a second attempt that succeeds, the |
| # bug is absent and the test succeeded. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="sleep 1 && $TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,connect-timeout=2,retry=1,interval=2" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0" >/dev/null 2>"${te}0" & |
| pid0=$! |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ $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" |
| elif echo "$da" |diff - "${tf}1" >$tdiff; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD0 &" >&2 |
| echo "$CMD1" >&2 |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "$CMD1" >&2 |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if the rawer option works. Up to Socat 1.7.4.3, it failed because it |
| # cleared the CREAD flag. |
| NAME=RAWER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*) |
| TEST="$NAME: Test if the rawer option fails" |
| # Invoke Socat with a terminal address with option rawer. When it has no error |
| # the test succeeded. |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$SOCAT -lp outer /dev/null EXEC:\"$SOCAT\\ -lp\\ inner\\ -\\,rawer\\ PIPE\",pty" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0" >/dev/null 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -eq 0 ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD0" >&2 |
| fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" >&2 |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| # Up to 1.7.4.3 there was a bug with the lowport option: |
| # Active addresses UDP-SEND, UDP-SENDTO always bound to port 1 instead of |
| # 640..1023 |
| NAME=UDP_LOWPORT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: UDP4-SEND with lowport" |
| # Run Socat with UDP4-SEND:...,lowport and full logging and check the |
| # parameters of bind() call. If port is in the range 640..1023 the test |
| # succeeded. |
| # This test does not require root because it just checks log of bind() but does |
| # not require success |
| # This test fails if WITH_SYCLS is turned off |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| #newport udp4 # not needed in this test |
| CMD="$TRACE $SOCAT $opts -d -d -d -d /dev/null UDP4-SENDTO:$LOCALHOST:$PORT,lowport" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" |
| 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 |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| 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" |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| # Test if trailing garbage in integer type options gives error |
| NAME=MISSING_INTEGER |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*) |
| TEST="$NAME: Error on option that's missing integer value" |
| # Invoke Socat with pty and option ispeed=b19200. |
| # When socat terminates with error the test succeeded |
| if ! eval $NUMCOND; then :; 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 - PTY,ispeed=b19200" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test if trailing garbage in integer type options gives error |
| NAME=INTEGER_GARBAGE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*) |
| TEST="$NAME: Error on trailing garbage" |
| # Invoke Socat with pty and option ispeed=b19200. |
| # When socat terminates with error the test succeeded |
| if ! eval $NUMCOND; then :; 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 - PTY,ispeed=19200B" |
| printf "test $F_n $TEST... " $N |
| $CMD0 </dev/null >/dev/null 2>"${te}0" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if Filan can print the target of symbolic links |
| NAME=FILANSYMLINK |
| case "$TESTS" in |
| *%$N%*|*%filan%*|*%$NAME%*) |
| TEST="$NAME: capability to display symlink target" |
| # Run Filan on a symbolic link |
| # When its output contains "LINKTARGET=<target>" the test succeeded |
| if ! eval $NUMCOND; then :; else |
| tf="$td/test$N.file" |
| tl="$td/test$N.symlink" |
| te="$td/test$N.stderr" |
| printf "test $F_n $TEST... " $N |
| touch "$tf" |
| ln -s "$tf" "$tl" |
| target=$($FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/') |
| if [ "$target" = "$tf" ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "touch \"$tf\"" |
| echo "ln -s \"$tf\" \"$tl\"" |
| echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" |
| fi |
| numOK=$((numOK+1)) |
| 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" |
| fi |
| kill $spid 2>/dev/null |
| wait |
| fi ;; # NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # Test preservation of packet boundaries from Socat to sub processes of |
| # various kind and back to Socat via socketpair with socket type datagram. |
| # (EXECSOCKETPAIRPACKETS SYSTEMSOCKETPAIRPACKETS) |
| for addr in exec system; do |
| ADDR=$(echo $addr |tr a-z A-Z) |
| NAME=${ADDR}SOCKETPAIRPACKETS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%packets%*|*%$NAME%*) |
| TEST="$NAME: simple echo via $addr of cat with socketpair, keeping packet boundaries" |
| # Start a Socat process with a UNIX datagram socket on the left side and with |
| # a sub process connected via datagram socketpair that keeps packet boundaries |
| # (here: another Socat process in unidirectional mode). |
| # Pass two packets to the UNIX datagram socket; let Socat wait a little time |
| # before processing, |
| # so the packets are at the same time in the receive queue. |
| # The process that sends thes packet uses a short packet size (-b), |
| # so the returned data is truncated in case the packets were merged. |
| # When the complete data is returned, the test succeeded. |
| if ! eval $NUMCOND; then :; else |
| ts0="$td/test$N.sock0" |
| ts1="$td/test$N.sock1" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| #CMD0="$TRACE $SOCAT $opts -lp server -T 2 UNIX-SENDTO:$ts1,bind=$ts0 $ADDR:\"$SOCAT -lp echoer -u - -\",pty,echo=0,pipes" # test the test |
| CMD0="$TRACE $SOCAT $opts -lp server -T 2 UNIX-SENDTO:$ts1,bind=$ts0,null-eof $ADDR:\"$SOCAT -lp echoer -u - -\",socktype=$SOCK_DGRAM",shut-null |
| CMD1="$SOCAT $opts -lp client -b 24 -t 2 -T 3 - UNIX-SENDTO:$ts0,bind=$ts1",shut-null |
| printf "test $F_n $TEST... " $N |
| export SOCAT_TRANSFER_WAIT=2 |
| eval "$CMD0" >/dev/null 2>"${te}0" & |
| pid0="$!" |
| unset SOCAT_TRANSFER_WAIT |
| waitunixport $ts0 1 |
| { echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ "$rc1" -ne 0 ]; then |
| $PRINTF "$FAILED (rc1=$rc1): $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" |
| echo "{ echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then |
| $PRINTF "$FAILED (diff)\n" |
| echo "$CMD0 &" >&2 |
| cat "${te}0" >&2 |
| echo "{ echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1" >&2 |
| cat "${te}1" >&2 |
| echo "diff:" >&2 |
| cat $tdiff >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "$CMD0 &" >&2 |
| echo "{ echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1" >&2 |
| fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| done # for |
| |
| |
| # Test if a special quote based syntax error in dalan module does not raise |
| # SIGSEGV |
| NAME=DALAN_NO_SIGSEGV |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%dalan%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: Dalan syntax error does not raise SIGSEGV" |
| # Invoke Socat with an address that has this quote based syntax error. |
| # When exit code is 1 (due to syntax error) the test succeeded. |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts /dev/null SOCKET-LISTEN:1:1:'"/tmp/sock"'" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" |
| rc1=$? |
| if [ $rc1 -eq 1 ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD"; fi |
| if [ "$DEBUG" ]; then cat "${te}" >&2; fi |
| numOK=$((numOK+1)) |
| elif [ $rc1 -eq 139 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| else |
| # soemthing unexpected happened |
| $PRINTF "$CANT\n" |
| echo "$CMD" |
| cat "${te}" >&2 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if filan -s correctly displays TCP on appropriate FDs |
| # This feature was broken in version 1.7.4.4 |
| NAME=FILAN_SHORT_TCP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: filan -s displays TCP etc" |
| # Establish a TCP connection using Socat server and client; on the server |
| # exec() filan -s using nofork option, so its output appears on the client. |
| # When the second word in the first line is "tcp" the test succeeded. |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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 TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork" |
| CMD1="$TRACE $SOCAT $opts - TCP4:localhost:$PORT" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0" >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" </dev/null |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| result="$(head -n 1 ${tf}1 |awk '{print($2);}')" |
| if [ $rc1 -eq 0 -a "$result" = tcp ]; 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)) |
| else |
| $PRINTF "$FAILED\n" |
| if [ $rc1 -ne 0 ]; then |
| echo "rc=$rc1" >&2 |
| else |
| echo "result is \"$result\" instead of \"tcp\"" >&2 |
| fi |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| |
| # Test if the settings of the terminal that Socat is invoked in are restored |
| # on termination. |
| # This failed on Open-Solaris family OSes up to 1.7.4.4 |
| NAME=RESTORE_TTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%termios%*|*%tty%*|*%$NAME%*) |
| TEST="$NAME: Restoring of terminal settings" |
| # With an outer Socat command create a new pty and a bash in it. |
| # In this bash store the current terminal settings, then invoke a temporary |
| # inner Socat command that changes the term to raw mode and terminates. |
| # When the terminal settings afterwards are the same as before the call the |
| # test succeeded. |
| 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" |
| 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" |
| 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" |
| 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" |
| else |
| te="$td/test$N.stderr" |
| tx0="$td/test$N.stty0" |
| tx1="$td/test$N.stty1" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts -lp outersocat - SYSTEM:\"stty\ >$tx0;\ $SOCAT\ -\,cfmakeraw\ /dev/nul\l >${te};\ stty\ >$tx1\",pty,setsid,ctty,stderr" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD" >/dev/null 2>${te}.outer |
| rc=$? |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" >&2 |
| cat "${te}.outer" >&2 |
| cat $tdiff >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| |
| # Test if EXEC'd program inherits only the stdio file descriptors |
| # thus there are no FD leaks from Socat to EXEC'd program |
| NAME=EXEC_FDS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%$NAME%*) |
| TEST="$NAME: Socat does not leak FDs to EXEC'd program" |
| # Run Socat with EXEC address, execute Filan to display its file descriptors |
| # Test succeeds when only FDs 0, 1, 2 are in use. |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts - EXEC:\"$FILAN -s\"" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD" >"${tf}" 2>"${te}" |
| # "door" is a special FD type on Solaris/SunOS |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" >&2 |
| cat "${te}" >&2 |
| cat "${tf}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| # Test if Socat makes the sniffing file descriptos (-r, -R) CLOEXEC to not leak |
| # them to EXEC'd program |
| NAME=EXEC_SNIFF |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%$NAME%*) |
| TEST="$NAME: Socat does not leak sniffing FDs" |
| # Run Socat sniffing both directions, with EXEC address, |
| # execute Filan to display its file descriptors |
| # Test succeeds when only FDs 0, 1, 2 are in use. |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD="$TRACE $SOCAT $opts -r $td/test$N.-r -R $td/test$N.-R - EXEC:\"$FILAN -s\"" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD" >"${tf}" 2>"${te}" |
| # "door" is a special FD type on Solaris/SunOS |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" >&2 |
| cat "${te}" >&2 |
| cat "${tf}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| |
| while read KEYW FEAT RUNS ADDR IPPORT; do |
| if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi |
| PROTO=$KEYW |
| proto="$(echo "$PROTO" |tr A-Z a-z)" |
| feat="$(tolower "$FEAT")" |
| # test the fork option on really RECVFROM oriented sockets |
| NAME=${KEYW}_FORK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%$feat%*|*%$proto%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: ${KEYW}-RECVFROM with fork option" |
| # Start a RECVFROM process with fork option and SYSTEM address where clients |
| # data determines the sleep time; send a record with sleep before storing the |
| # data, then send a record with 0 sleep before storing data. |
| # When the second record is stored before the first one the test succeeded. |
| 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" |
| 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" |
| 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" |
| 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" |
| else |
| case "X$IPPORT" in |
| "XPORT") |
| newport $proto |
| tsl=$PORT # test socket listen address |
| tsc="$ADDR:$PORT" # test socket connect address |
| ;; |
| *) |
| tsl="$(eval echo "$ADDR")" # resolve $N |
| tsc=$tsl |
| esac |
| #ts="$td/test$N.sock" |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts -t 3 $PROTO-RECVFROM:$tsl,fork SYSTEM:'read t x; sleep \$t; echo \\\"\$x\\\" >>'\"$tf\"" |
| CMD1="$TRACE $SOCAT $opts -t 3 - $PROTO-SENDTO:$tsc" |
| printf "test $F_n $TEST... " $N |
| eval $CMD0 </dev/null 2>"${te}0" & |
| pid0=$! |
| wait${proto}port $tsl 1 |
| echo "2 $da 1" |$CMD1 >"${tf}1" 2>"${te}1" & |
| pid1=$! |
| sleep 1 |
| echo "0 $da 2" |$CMD1 >"${tf}2" 2>"${te}2" & |
| pid2=$! |
| sleep 2 |
| cpids="$(childpids $pid0 </dev/null)" |
| kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait |
| if $ECHO "$da 2\n$da 1" |diff - $tf >$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 |
| if [ "$VERBOSE" ]; then echo "$CMD2"; fi |
| if [ "$DEBUG" ]; then cat "${te}2" >&2; fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo "diff:" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| done <<<" |
| UDP4 UDP ip4 127.0.0.1 PORT |
| UDP6 UDP ip6 [::1] PORT |
| UNIX unix unix $td/test\$N.server - |
| " |
| |
| |
| # Test if option -S turns off logging of SIGTERM |
| NAME=SIGTERM_NOLOG |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%signal%*|*%$NAME%*) |
| TEST="$NAME: Option -S can turn off logging of SIGTERM" |
| # Start Socat with option -S 0x0000, kill it with SIGTERM |
| # When no logging entry regarding this signal is there, the test succeeded |
| 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" |
| elif ! F=$(testfeats PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! A=$(testaddrs PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| CMD0="$TRACE $SOCAT $opts -S 0x0000 PIPE PIPE" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| relsleep 1 # give process time to start |
| kill -TERM $pid0 2>/dev/null; wait |
| if ! grep "exiting on signal" ${te}0 >/dev/null; then |
| $PRINTF "$OK\n" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "kill -TERM <pid>" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if option -S turns on logging of signal 31 |
| NAME=SIG31_LOG |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%signal%*|*%$NAME%*) |
| TEST="$NAME: Option -S can turn on logging of signal 31" |
| # Start Socat with option -S 0x80000000, kill it with -31 |
| # When a logging entry regarding this signal is there, the test succeeded |
| 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" |
| elif ! F=$(testfeats PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! A=$(testaddrs PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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 -S 0x80000000 PIPE PIPE" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| relsleep 1 # give process time to start |
| kill -31 $pid0 2>/dev/null; wait |
| if grep "exiting on signal" ${te}0 >/dev/null; then |
| $PRINTF "$OK\n" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "kill -31 <pid>" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the http-version of the PROXY-CONNECT address |
| NAME=PROXY_HTTPVERSION |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%proxy%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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')" |
| CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr,crlf EXEC:\"/usr/bin/env bash proxyecho.sh -V 1.1\"" |
| CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT,http-version=1.1" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0 2>\"${te}1\" &" |
| pid=$! # background process id |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 >"$tf" 2>"${te}0" |
| if ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "diff:" >&2 |
| cat "$tdiff" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| kill $pid 2>/dev/null |
| wait |
| fi ;; # NUMCOND, feats |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| |
| # Test the so-rcvtimeo address option with DTLS |
| NAME=RCVTIMEO_DTLS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%timeout%*|*%openssl%*|*%dtls%*|*%$NAME%*) |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| # We need a hanging connection attempt, guess an address for this |
| HANGIP=0.0.0.1 |
| te1="$td/test$N.stderr1" |
| tk1="$td/test$N.kill1" |
| te2="$td/test$N.stderr2" |
| tk2="$td/test$N.kill2" |
| $PRINTF "test $F_n $TEST... " $N |
| # First, try to make socat hang and see if it can be killed |
| CMD1="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0" |
| $CMD1 >"$te1" 2>$te1 </dev/null & |
| pid1=$! |
| sleep 2 |
| 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" |
| wait |
| else |
| # DTLS restarts read() a few times |
| while kill $pid1 2>/dev/null; do :; done |
| # Second, set so-rcvtimeo and see if Socat exits before kill |
| CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=1.0" |
| $CMD2 >"$te1" 2>$te2 </dev/null & |
| pid2=$! |
| sleep 3 # in OpenSSL 1.1.1f DTLS takes two timeouts |
| if kill $pid2 2>"$tk2"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD2" |
| cat "$te2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi |
| wait |
| fi ;; # testfeats, NUMCOND |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the use of interesting variables in the sniffing file names |
| NAME=VARS_IN_SNIFFPATH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%listen%*|*%fork%*|*%$NAME%*) |
| TEST="$NAME: sniff file names with variables" |
| # Start a server process with option fork that sniffs traffic and stores it in |
| # two files for each child process, using PID, timestamp, microseconds, and |
| # client IP |
| # Connect two times. |
| # For now we say that the test succeeded when 4 log files have been generated. |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| 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 |
| CMD0="$TRACE $SOCAT $opts -lp server0 -r \"$td/test$N.\\\$PROGNAME-\\\$TIMESTAMP.\\\$MICROS-\\\$SERVER0_PEERADDR-\\\$\\\$.in.log\" -R \"$td/test$N.\\\$PROGNAME-\\\$TIMESTAMP.\\\$MICROS-\\\$SERVER0_PEERADDR-\\\$\\\$.out.log\" TCP4-LISTEN:$PORT,so-reuseaddr,fork PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0" >/dev/null 2>"${te}0" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| echo "$da" |$CMD1 >"${tf}1a" 2>"${te}1a" |
| rc1a=$? |
| echo "$da" |$CMD1 >"${tf}1b" 2>"${te}1b" |
| rc1b=$? |
| kill $(childpids $pid0) $pid0 2>/dev/null; wait |
| if [ $rc1a != 0 -o $rc1b != 0 ]; then |
| $PRINTF "$FAILED (client problem)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1a" >&2 |
| echo "$CMD1" |
| cat "${te}1b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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? |
| # Convert timestamps to epoch and compare |
| # Are the contents correct? |
| $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}1a" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1"; fi |
| if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi |
| numOK=$((numOK+1)) |
| elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.in.log; then |
| $PRINTF "$FAILED (vars not resolved)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1a" >&2 |
| echo "$CMD1" |
| cat "${te}1b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| else |
| $PRINTF "$FAILED (unknown)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1a" >&2 |
| echo "$CMD1" |
| cat "${te}1b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test logging of statistics on Socat option --statistics |
| NAME=OPTION_STATISTICS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%stats%*|*%system%*|*%stdio%*|*%$NAME%*) |
| TEST="$NAME: Socat option --statistics" |
| # Invoke Socat with option --statistics, transfer some date, and check the log |
| # file for the values |
| 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" |
| 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" |
| 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" |
| 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" |
| 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 --statistics STDIO SYSTEM:'tee /dev/stdout',pty,cfmakeraw" |
| printf "test $F_n $TEST... " $N |
| echo "$da" |eval "$CMD0" >"${tf}0" 2>"${te}0" |
| rc0=$? |
| if [ $rc0 -ne 0 ]; then |
| # The test could not run meaningfully |
| $PRINTF "$CANT\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test logging of statistics on SIGUSR1 |
| NAME=SIGUSR1_STATISTICS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%signal%*|*%stats%*|*%system%*|*%stdio%*|*%$NAME%*) |
| TEST="$NAME: statistics on SIGUSR1" |
| # Invoke Socat without option --statistics, transfer some date, send signal |
| # USR1,and check the log file for the values |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| 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 STDIO SYSTEM:'tee /dev/stdout 2>/dev/null',pty,cfmakeraw" |
| #set -vx |
| printf "test $F_n $TEST... " $N |
| { echo "$da"; relsleep 3; } |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"; } |
| relsleep 1 |
| pkill -t $TTY socat |
| wait |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the children-shutup option |
| NAME=CHILDREN_SHUTUP |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*) |
| TEST="$NAME: test the children-shutup option" |
| # Run a UNIX domain listening server with options fork and children-shutup, and |
| # that connects to a closed TCP4 port. |
| # Connect to the server and check if it logs the TCP4-CONNECT failure as warning. |
| 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" |
| 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" |
| 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" |
| else |
| newport tcp4 |
| ts="$td/test$N.sock" |
| 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,fork,children-shutup TCP4:localhost:$PORT" |
| CMD1="$TRACE $SOCAT $opts -u FILE:/dev/null UNIX-CONNECT:$ts" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| waitunixport $ts 1 |
| { $CMD1 2>"${te}1"; sleep 1; } |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| relsleep 1 # child process might need more time |
| if grep -q " W connect" ${te}0; 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)) |
| 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" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Socats INTERFACE address has to ignore outgoing packets if possible. |
| # On Linux is uses socket option PACKET_IGNORE_OUTGOING or it queries per |
| # packet the PACKET_OUTGOING flag of struct sockaddr_ll.sll_pkttype |
| NAME=INTERFACE_IGNOREOUTGOING |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%interface%*|*%tun%*|*%root%*|*%$NAME%*) |
| TEST="$NAME: INTERFACE ignores outgoing packets" |
| #idea: create a TUN interface and hook with INTERFACE. |
| # Send a packet out the interface, should not be seen by INTERFACE |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| tl="$td/test$N.lock" |
| da="$(date) $RANDOM" |
| TUNNET=10.255.255 |
| TUNNAME=tun9 |
| CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME -" |
| CMD1="$TRACE $SOCAT $opts -u INTERFACE:$TUNNAME -" |
| CMD2="ping -c 1 -w 1 -b $TUNNET.255" |
| printf "test $F_n $TEST... " $N |
| sleep 1 |$CMD0 2>"${te}0" >/dev/null & |
| pid0="$!" |
| #waitinterface "$TUNNAME" |
| usleep $MICROS |
| $CMD1 >"${tf}1" 2>"${te}1" & |
| pid1="$!" |
| usleep $MICROS |
| $CMD2 2>"${te}2" 1>&2 |
| kill $pid1 2>/dev/null |
| usleep $MICROS |
| kill $pid0 2>/dev/null |
| wait |
| if [ $? -ne 0 ]; then |
| $PRINTF "$FAILED: $TRACE $SOCAT:\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif test -s "${tf}1"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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 |
| if [ "$VERBOSE" ]; then echo "$CMD2"; fi |
| if [ "$DEBUG" ]; then cat "${te}2" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi ;; # NUMCOND, feats |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| |
| # Test if the SO_REUSEADDR socket option is applied automatically to TCP LISTEN |
| # type addresses. |
| NAME=TCP4_REUSEADDR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test if option reuseaddr's default is 1" |
| # Start a TCP4-LISTEN server, connect with a client, have the server shutdown |
| # the connection. Start the server on the same port again. If it starts the |
| # test succeeded. |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0a="$TRACE $SOCAT $opts -T 0.1 TCP4-LISTEN:$PORT PIPE" |
| CMD0b="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,accept-timeout=0.1 PIPE" |
| CMD1="$TRACE $SOCAT $opts STDIO TCP4-CONNECT:$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD0a >/dev/null 2>"${te}0a" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| $CMD0b >/dev/null 2>"${te}0b" |
| rc0b=$? |
| if [ $rc0b -eq 0 ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1"; fi |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0a &" |
| cat "${te}0a" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD0b" |
| cat "${te}0b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test if the SO_REUSEADDR socket option is applied automatically to OPENSSL LISTEN |
| # type addresses. |
| NAME=OPENSSL_6_REUSEADDR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip6%*|*%tcp%*|*%tcp6%*|*%listen%*|*%openssl%*|*%$NAME%*) |
| TEST="$NAME: test if option reuseaddr's default is 1 with SSL-L" |
| # Start an OPENSSL-LISTEN server using TCP on IPv6, connect with a client, have |
| # the server shutdown the connection. Start the server on the same port again. |
| # If it starts the test succeeded. |
| 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" |
| 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" |
| 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" |
| elif ! runsip6 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| printf "test $F_n $TEST... " $N |
| newport tcp6 |
| # Yup, it seems that with OpenSSL the side that begins with shutdown does NOT |
| # begin shutdown of the TCP connection |
| # therefore we let the client timeout |
| # result is not reliable (OK seen even without any SO_REUSEADDR) |
| CMD0a="$TRACE $SOCAT $opts -lp server1 -6 OPENSSL-LISTEN:$PORT,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" |
| CMD0b="$TRACE $SOCAT $opts -lp server2 -6 OPENSSL-LISTEN:$PORT,accept-timeout=.01,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE" |
| CMD1="$TRACE $SOCAT $opts -lp client -6 -T 0.1 PIPE OPENSSL-CONNECT:$LOCALHOST6:$PORT,verify=0" |
| printf "test $F_n $TEST... " $N |
| $CMD0a >/dev/null 2>"${te}0a" & |
| pid0=$! |
| waittcp6port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| $CMD0b >/dev/null 2>"${te}0b" |
| rc0b=$? |
| if [ $rc0b -eq 0 ]; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1"; fi |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0a &" |
| cat "${te}0a" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD0b" |
| cat "${te}0b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test if the so-reuseaddr= option prevents the SO_REUSEADDR socket option |
| NAME=REUSEADDR_NULL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*) |
| TEST="$NAME: test option reuseaddr without value" |
| # Start a TCP4-LISTEN server with so-reuseaddr=, connect with a client, have |
| # the server shutdown the connection. |
| # Start the server on the same port again. If it fails with |
| # "Address already in use" the test succeeded. |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0a="$TRACE $SOCAT $opts -T 0.1 TCP4-LISTEN:$PORT,so-reuseaddr= PIPE" |
| CMD0b="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,accept-timeout=0.1 PIPE" |
| CMD1="$TRACE $SOCAT $opts STDIO TCP4-CONNECT:$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD0a >/dev/null 2>"${te}0a" & |
| pid0=$! |
| waittcp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| $CMD0b >/dev/null 2>"${te}0b" |
| rc0b=$? |
| if [ $rc0b -eq 1 ] && grep -q -e "Address already in use" -e "Address in use" "${te}0b"; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1"; fi |
| 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)) |
| #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 |
| $PRINTF "$CANT\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1"; fi |
| 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" |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0a &" |
| cat "${te}0a" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD0b" |
| cat "${te}0b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if Socats TCP4-client tries all addresses if necessary |
| NAME=TRY_ADDRS_4 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%socket%*|*%foreign%*|*%$NAME%*) |
| TEST="$NAME: try all available TCP4 addresses" |
| # Connect to a TCP4 port of a hostname that resolves to two addresses where at |
| # least on the first one the port is closed. |
| # server-4.dest-unreach.net has been configured for this purpose, it |
| # resolves to its public address and to 127.0.0.1; unfortunately |
| # forwarding nameservers need not keep order of A entries, so we need a port |
| # 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 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| #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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif [ -z "$FOREIGN" ]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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= |
| for addr in $ADDRS; do |
| if $SOCAT /dev/null TCP4:$addr:$PORT 2>/dev/null; then |
| # port is open :-( |
| OPEN=1 |
| break |
| fi |
| done |
| if [ -z "$OPEN" ]; then |
| break; |
| fi |
| newport tcp4 |
| done |
| CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP4:server-4.dest-unreach.net:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" |
| rc=$? |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test if Socats TCP-client tries all addresses (IPv4+IPv6) if necessary |
| NAME=TRY_ADDRS_4_6 |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%tcp6%*|*%socket%*|*%foreign%*|*%$NAME%*) |
| TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses" |
| # Connect to a TCP port that is not open on localhost-4-6.dest-unreach.net, |
| # neither IPv4 nor IPv6 |
| # Check the log if Socat tried both addresses |
| if ! eval $NUMCOND; then :; |
| elif [ -z "$FOREIGN" ]; then # only needs Internet DNS |
| $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| #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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| elif [ -z "$FOREIGN" ]; then # only needs Internet DNS |
| $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| LOCALHOST_4_6=localhost-4-6.dest-unreach.net |
| if type nslookup >/dev/null 2>&1; then |
| ADDRS=$(nslookup $LOCALHOST_4_6 |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}') |
| elif type host >/dev/null 2>&1; then |
| ADDRS=$(host $LOCALHOST_4_6 |sed 's/.*address //') |
| fi |
| # Specific config: on Ubuntu-12.04: getaddrinfo(...AI_ADDRCONFIG) does not |
| # resolve to IPv6 addresses even when there are link local IPv6 addresses |
| if test -f /etc/os-release && |
| grep -q '^NAME="Ubuntu"' /etc/os-release && |
| grep -q '^VERSION="12\.04' /etc/os-release; then |
| AI_ADDRCONFIG="ai-addrconfig=0," |
| fi |
| # Check if PORT is really closed on both addresses |
| while true; do |
| OPEN= |
| for addr in $ADDRS; do |
| case $addr in |
| *.*) ;; |
| *:*) addr="[$addr]" ; |
| esac |
| if $SOCAT /dev/null TCP:$addr:$PORT,$AI_ADDRCONFIG 2>/dev/null; then |
| # port is open :-( |
| OPEN=1 |
| break |
| fi |
| done |
| if [ -z "$OPEN" ]; then |
| break; |
| fi |
| newport tcp4 |
| done |
| CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP:$LOCALHOST_4_6:$PORT,$AI_ADDRCONFIG" |
| printf "test $F_n $TEST... " $N |
| $CMD >/dev/null 2>"${te}" |
| rc=$? |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD" |
| cat "${te}" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the netns (net namespace) feature |
| NAME=NETNS |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%root%*|*%namespace%*|*%netns%*|*%socket%*|*%$NAME%*) |
| ns=socat-$$-test$N |
| TEST="$NAME: option netns (net namespace $ns)" |
| # Start a simple echo server with option netns on localhost of a net namespace; |
| # use a client process with option netns to send data to the net namespace |
| # net server and check the reply. |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| 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 |
| CMD0="$TRACE $SOCAT $opts --experimental TCP4-LISTEN:$PORT,netns=$ns EXEC:'od -c'" |
| CMD1="$TRACE $SOCAT $opts --experimental - TCP4:127.0.0.1:$PORT,netns=$ns" |
| printf "test $F_n $TEST... " $N |
| ip netns del $ns 2>/dev/null # make sure it does not exist |
| ip netns add $ns |
| ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8 |
| ip netns exec $ns ip link set lo up |
| eval "$CMD0" >/dev/null 2>"${te}0" & |
| pid0=$! |
| relsleep 1 # if no matching wait*port function |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| ip netns del $ns |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED (client failed)\n" |
| echo "ip netns del $ns" |
| echo "ip netns add $ns" |
| echo "ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8" |
| echo "ip netns exec $ns ip link set lo up" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "ip netns del $ns" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then |
| echo "ip netns del $ns" |
| echo "ip netns add $ns" |
| echo "ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8" |
| echo "ip netns exec $ns ip link set lo up" |
| 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 |
| if [ "$VERBOSE" ]; then echo "ip netns del $ns"; fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED (bad output)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| diff: |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the netns (net namespace) feature with EXEC and reset |
| NAME=NETNS_EXEC |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%root%*|*%namespace%*|*%netns%*|*%socket%*|*%$NAME%*) |
| ns=socat-$$-test$N |
| TEST="$NAME: option netns with EXEC (net namespace $ns)" |
| # Start a simple server with option netns on localhost of a net namespace that |
| # stores data it receives; |
| # use a middle process that EXECs a socat client that connects to the server on |
| # the net namespace; then it listens on default namespace. |
| # With a third command line connect and send data to the middle process. |
| # When the data received by the server is correct the test succeeded. |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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 --experimental -u -T 1 ABSTRACT-RECV:test$N,netns=$ns CREAT:${tf}0" |
| CMD1="$TRACE $SOCAT $opts --experimental -U -T 1 EXEC:\"$SOCAT STDIO ABSTRACT-SENDTO\:test$N\",netns=$ns UDP4-RECV:$PORT" |
| CMD2="$TRACE $SOCAT $opts -u STDIO UDP4:127.0.0.1:$PORT" |
| printf "test $F_n $TEST... " $N |
| ip netns del $ns 2>/dev/null # make sure it does not exist |
| ip netns add $ns |
| #ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8 |
| #ip netns exec $ns ip link set lo up |
| eval "$CMD0" >/dev/null 2>"${te}0" & |
| pid0=$! |
| relsleep 1 # if no matching wait*port function |
| eval "$CMD1" 2>${te}1 & |
| pid1=$! |
| relsleep 1 |
| echo "$da" |$CMD2 >"${tf}2" 2>"${te}2" |
| rc1=$? |
| kill $pid0 $pid1 2>/dev/null; wait |
| ip netns del $ns |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED (client failed)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; 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 |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED (bad output)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo diff: |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| NAME=SOCKETPAIR_STREAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*) |
| TEST="$NAME: stdio and internal socketpair with stream" |
| testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts" |
| esac |
| N=$((N+1)) |
| |
| NAME=SOCKETPAIR_DATAGRAM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*) |
| TEST="$NAME: stdio and internal socketpair with datagram" |
| testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts" |
| esac |
| N=$((N+1)) |
| |
| NAME=SOCKETPAIR_SEQPACKET |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*) |
| TEST="$NAME: stdio and internal socketpair with seqpacket" |
| testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts" |
| esac |
| N=$((N+1)) |
| |
| # Test if SOCKETPAIR address with SOCK_DGRAM keeps packet boundaries |
| NAME=SOCKETPAIR_BOUNDARIES |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socketpair%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*) |
| TEST="$NAME: Internal socketpair keeps packet boundaries" |
| # Start a UDP4-DATAGRAM process that echoes data with datagram SOCKETPAIR; |
| # a client sends two packets with 24 and ~18 bytes using a UDP4-DATAGRAM. The |
| # client truncates packets to size 24, so when a large merged packet comes from |
| # server some data will be lost. If the original data is received, the test |
| # succeeded. |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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)) |
| 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" |
| printf "test $F_n $TEST... " $N |
| export SOCAT_TRANSFER_WAIT=0.2 |
| $CMD1 2>"${te}1" & |
| pid1="$!" |
| unset SOCAT_TRANSFER_WAIT |
| waitudp4port $ts1p 1 |
| { echo -n "${da:0:20}"; usleep 100000; echo "${da:20}"; } |$CMD2 >>"$tf" 2>>"${te}2" |
| rc2="$?" |
| kill "$pid1" 2>/dev/null; wait; |
| if [ "$rc2" -ne 0 ]; then |
| $PRINTF "$FAILED (rc2=$rc2): $TRACE $SOCAT:\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif ! echo "$da" |diff - "$tf" >"$tdiff"; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD1 &" |
| cat "${te}1" >&2 |
| echo "$CMD2" |
| cat "${te}2" >&2 |
| echo diff: |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| 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)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| PORT=$((PORT+1)) |
| N=$((N+1)) |
| |
| |
| # Test the ACCEPT-FD address |
| NAME=ACCEPT_FD |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%systemd%*|*%accept%*|*%$NAME%*) |
| TEST="$NAME: ACCEPT-FD address" |
| # Start Socat with address ACCEPT-FD via systemd-socket-activate for echoing |
| # data. |
| # Connect with a client; the test succeeds when the client gets its data back. |
| 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" |
| 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" |
| 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" |
| elif ! runsip4 >/dev/null; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| newport tcp4 |
| CMD0="systemd-socket-activate -l $PORT --inetd $TRACE $SOCAT $opts ACCEPT-FD:0 PIPE" |
| CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT" |
| 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 |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| cat $tdiff >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| |
| # Test the POSIX MQ feature with continuous READ and priorization on Linux |
| NAME=LINUX_POSIXMQ_READ_PRIO |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*) |
| TEST="$NAME: POSIX-MQ (Linux) 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 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| 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" |
| printf "test $F_n $TEST... " $N |
| echo "$da 0" |$CMD0a 2>"${te}0a" |
| rc0a=$? |
| echo "$da 1" |$CMD0b 2>"${te}0b" |
| rc0b=$? |
| $CMD1 >"${tf}1" 2>"${te}1" & |
| pid1=$! |
| relsleep 1 |
| kill $pid1; wait |
| if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0a" |
| cat "${te}0a" >&2 |
| echo "$CMD0b" |
| cat "${te}0b" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0a"; fi |
| if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD0b"; fi |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0a" |
| cat "${te}0a" >&2 |
| echo "$CMD0b" |
| cat "${te}0b" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "difference:" >&2 |
| cat ${tdiff}1 >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the POSIX MQ feature with RECV,fork on Linux |
| NAME=LINUX_POSIXMQ_RECV_FORK |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%socket%*|*%posixmq%*|*%$NAME%*) |
| TEST="$NAME: POSIX-MQ (Linux) 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 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| 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" |
| printf "test $F_n $TEST... " $N |
| $CMD0 2>"${te}0" >"${tf}0" & |
| pid0=$! |
| relsleep 1 |
| echo "$da 0" |$CMD1a >/dev/null 2>"${te}1a" |
| rc1a=$? |
| echo "$da 1" |$CMD1b >/dev/null 2>"${te}1b" |
| rc1b=$? |
| relsleep 1 |
| kill $pid0; wait |
| if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" >&2 |
| echo "$CMD1a" |
| cat "${te}1a" >&2 |
| echo "$CMD1b" |
| cat "${te}1b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1a"; fi |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" >&2 |
| echo "$CMD1a" |
| cat "${te}1a" >&2 |
| echo "$CMD1b" |
| cat "${te}1b" >&2 |
| echo "difference:" >&2 |
| cat ${tdiff}0 >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the POSIX MQ feature with RECV,fork,max-children on Linux |
| NAME=LINUX_POSIXMQ_RECV_MAXCHILDREN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) |
| TEST="$NAME: POSIX-MQ (Linux) 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; |
| # run a client/sender that sends message 3, has to wait; |
| # 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 |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| 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" |
| printf "test $F_n $TEST... " $N |
| eval $CMD0 2>"${te}0" >"${tf}0" & |
| pid0=$! |
| relsleep 1 |
| echo "$da 1" |$CMD1a >/dev/null 2>"${te}1a" |
| rc1a=$? |
| echo "$da 3" |$CMD1b >/dev/null 2>"${te}1b" |
| rc1b=$? |
| psleep 0.5 |
| echo "$da 2" >>"${tf}0" |
| sleep 1 # as in SYSTEM |
| kill $(childpids $pid0) $pid0; wait |
| if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" >&2 |
| echo "$CMD1a" |
| cat "${te}1a" >&2 |
| echo "$CMD1b" |
| cat "${te}1b" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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 |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| if [ "$VERBOSE" ]; then echo "$CMD1a"; fi |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" >&2 |
| echo "$CMD1a" |
| cat "${te}1a" >&2 |
| echo "$CMD1b" |
| cat "${te}1b" >&2 |
| echo "difference:" >&2 |
| cat ${tdiff}0 >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the POSIX MQ feature with SEND,fork,max-children on Linux |
| NAME=LINUX_POSIXMQ_SEND_MAXCHILDREN |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*) |
| TEST="$NAME: POSIX-MQ (Linux) 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 |
| # 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 |
| # 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| #elif ! runsposixmq >/dev/null; then |
| # $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N |
| # numCANT=$((numCANT+1)) |
| # listCANT="$listCANT $N" |
| else |
| tf="$td/test$N.stdout" |
| 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\"" |
| 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" & |
| pid1=$! |
| psleep 0.5 |
| echo "$da 2" >>"${tf}0" |
| sleep 1 # as in SYSTEM |
| kill $pid0 $(childpids $pid0) $pid1 $(childpids $pid1) |
| wait |
| $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 |
| $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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| echo "difference:" >&2 |
| cat ${tdiff}0 >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the sigint option with SHELL address |
| NAME=SHELL_SIGINT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%shell%*|*%progcall%*|*%sigint%*|*%$NAME%*) |
| TEST="$NAME: sigint option with SHELL" |
| # Run Socat with an EXEC address invoking Socat, with option sigint |
| # Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM) |
| # the test succeeded |
| if ! eval $NUMCOND; then :; |
| # Remove unneeded checks, adapt lists of the remaining ones |
| 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" |
| 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" |
| 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" |
| 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 -T 2 PIPE EXEC:\"socat\ -d\ -d\ -d\ -d\ -lu\ PIPE\ PIPE\",pty,setsid,sigint" |
| #CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint" |
| CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR EXEC:\"$CAT\",pty,setsid,sigint" |
| printf "test $F_n $TEST... " $N |
| eval $CMD0 >/dev/null 2>"${te}0" & |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| sleep 1 |
| kill -INT $pid0 |
| wait |
| if grep -q " W waitpid..: child .* exited with status 130" "${te}0" || |
| grep -q " W waitpid..: child .* exited on signal 2" "${te}0"; then |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the SHELL address with socketpair (default) |
| NAME=SHELL_SOCKETPAIR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%socketpair%*|*%$NAME%*) |
| TEST="$NAME: simple echo via SHELL of cat with socketpair" |
| # testecho ... |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t" |
| fi |
| esac |
| N=$((N+1)) |
| |
| # Test the SHELL address with pipes |
| NAME=SHELL_PIPES |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%pipe%*|*%$NAME%*) |
| TEST="$NAME: simple echo via SHELL of cat with pipes" |
| # testecho ... |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t" |
| fi |
| esac |
| N=$((N+1)) |
| |
| # Test the SHELL address with pty |
| NAME=SHELL_PTY |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%pty%*|*%$NAME%*) |
| TEST="$NAME: simple echo via SHELL of cat with pty" |
| # testecho ... |
| 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" |
| 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" |
| else |
| testecho "$N" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t" |
| fi |
| esac |
| N=$((N+1)) |
| |
| # Test the SHELL address halfclose with socketpair |
| NAME=SHELL_SOCKETPAIR_FLUSH |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%socketpair%*|*%halfclose%*|*%$NAME%*) |
| TEST="$NAME: call od -c via SHELL using socketpair" |
| # testecho ... |
| 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" |
| 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" |
| else |
| testod "$N" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t" |
| fi |
| esac |
| N=$((N+1)) |
| |
| # Test SHELL address halfclose with pipes |
| NAME=SHELL_PIPES |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%pipe%*|*%halfclose%*|*%$NAME%*) |
| TEST="$NAME: call od -c via SHELL using pipes" |
| # testecho ... |
| 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" |
| 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" |
| else |
| testod "$N" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t" |
| fi |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the sigint option with SYSTEM address |
| NAME=SYSTEM_SIGINT |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%socket%*|*%progcall%*|*%system%*|*%sigint%*|*%$NAME%*) |
| TEST="$NAME: sigint option with SYSTEM" |
| # Run Socat with a SYSTEM address invoking Socat, with option sigint |
| # Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM) |
| # the test succeeded |
| # setsid is required so the initial SIGINT is not delivered to the sub process. |
| if ! eval $NUMCOND; then :; |
| # Remove unneeded checks, adapt lists of the remaining ones |
| elif ! F=$(testfeats STDIO SYSTEM PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! A=$(testaddrs STDIO SYSTEM PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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 PIPE SHELL:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" |
| CMD0="$TRACE $SOCAT $opts SOCKETPAIR SHELL:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint" |
| printf "test $F_n $TEST... " $N |
| eval $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| sleep 1 |
| kill -INT $(childpids $pid0) |
| wait |
| 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)) |
| else |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the res-nsaddr (resolver, dns) option |
| NAME=RES_NSADDR |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%resolv%*|*%ip4%*|*%tcp4%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: test the res-nsaddr option" |
| # Start a supplementary Socat instance that will receive the DNS query. |
| # Run main Socat process, opening an IPv4 socket with option res-nsaddr |
| # directed to the aux process. |
| # When the supplementary Socat instance received the query the test succeeded. |
| 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" |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tdiff="$td/test$N.diff" |
| da="$(echo test$N $(date) $RANDOM |tr ' :' '-')" |
| echo "$da" >"$td/test$N.da" |
| newport udp4 # or whatever proto, or drop this line |
| CMD0="$TRACE $SOCAT $opts -u UDP-RECVFROM:$PORT -" |
| CMD1="$TRACE $SOCAT $opts - TCP4:$da:0,res-nsaddr=$LOCALHOST:$PORT" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" >"${tf}0" & |
| pid0=$! |
| waitudp4port $PORT 1 |
| $CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if grep "$da" "${tf}0" >/dev/null; 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)) |
| 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" |
| 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" |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Some of the following tests need absolute path of Socat |
| case "$SOCAT" in |
| /*) absSOCAT="$SOCAT" ;; |
| *) absSOCAT="$PWD/$SOCAT" ;; |
| esac |
| |
| # Test the chdir option, in particular if chdir with the first address |
| # (CREATE) does not affect pwd of second address, i.e. original pwd is |
| # recovered |
| NAME=CHDIR_ON_CREATE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%creat%*|*%system%*|*%chdir%*|*%$NAME%*) |
| TEST="$NAME: restore of pwd after CREAT with chdir option" |
| # Run Socat with first address CREAT with modified chdir, |
| # and second address SYSTEM (shell) with pwd command |
| # Check if the file is created with modified pwd but shell has original pwd |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tc="test$N.creat" |
| tdd="test$N.d" |
| tdiff="$td/test$N.diff" |
| tdebug="$td/test$N.debug" |
| opwd=$(pwd) |
| CMD0="$TRACE $absSOCAT $opts -U CREAT:$tc,chdir=$td SYSTEM:pwd" |
| printf "test $F_n $TEST... " $N |
| mkdir "$td/$tdd" |
| pushd "$td/$tdd" >/dev/null |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| popd >/dev/null |
| tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*} |
| pwd2=$(cat $tpwd/$tc </dev/null) |
| echo "Original pwd: $opwd" >>$tdebug |
| echo "Temporary pwd: $tpwd" >>$tdebug |
| echo "Addr2 pwd: $pwd2" >>$tdebug |
| if [ "$rc0" -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif [ "$tpwd" != "$td" ]; then |
| $PRINTF "$FAILED (chdir failed)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the chdir option, in particular if chdir with first address |
| # (SHELL) does not affect pwd of second address, i.e. original pwd is |
| # recovered |
| NAME=CHDIR_ON_SHELL |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%system%*|*%chdir%*|*%$NAME%*) |
| TEST="$NAME: restore of pwd after SYSTEM with chdir option" |
| # Run Socat with first address SYSTEM:"cat >file" with chdir, |
| # and second address SYSTEM (shell) with pwd command. |
| # Check if the file is created with modified pwd but shell has original pwd |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tc="test$N.creat" |
| tdd="test$N.d" |
| tdiff="$td/test$N.diff" |
| tdebug="$td/test$N.debug" |
| opwd=$(pwd) |
| CMD0="$TRACE $absSOCAT $opts -U SHELL:\"cat\ >$tc\",chdir=$td SYSTEM:pwd" |
| printf "test $F_n $TEST... " $N |
| mkdir "$td/$tdd" |
| pushd "$td/$tdd" >/dev/null |
| eval "$CMD0" >/dev/null 2>"${te}0" |
| rc0=$? |
| popd >/dev/null |
| tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*} |
| pwd2=$(cat $tpwd/$tc </dev/null) |
| echo "Original pwd: $opwd" >>$tdebug |
| echo "Temporary pwd: $tpwd" >>$tdebug |
| echo "Addr2 pwd: $pwd2" >>$tdebug |
| if [ "$rc0" -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif [ "$tpwd" != "$td" ]; then |
| $PRINTF "$FAILED (chdir failed)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # Test the modified umask option, in particular if umask with first address |
| # (CREATE) does not affect umask of second address, i.e. original umask is |
| # recovered |
| NAME=UMASK_ON_CREATE |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%creat%*|*%system%*|*%umask%*|*%$NAME%*) |
| TEST="$NAME: test restore after CREAT with umask option" |
| # Run Socat with first address CREAT with modified umask, |
| # and second address SYSTEM (shell) with umask command |
| # Check if the file is created with modified umask but shell has original umask |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tc="$td/test$N.creat" |
| tdiff="$td/test$N.diff" |
| tdebug="$td/test$N.debug" |
| oumask=$(umask) |
| # Construct a temp umask differing from original umask |
| case oumask in |
| *066) tumask=0026 ;; |
| *) tumask=0066 ;; |
| esac |
| CMD0="$TRACE $SOCAT $opts -U CREAT:$tc,umask=$tumask SYSTEM:umask" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" |
| rc0=$? |
| tperms=$(fileperms $tc) |
| case $tperms in |
| 0*) ;; |
| *) tperms=0$tperms ;; |
| esac |
| echo "Original umask: $oumask" >>$tdebug |
| echo "Temporary umask: $tumask" >>$tdebug |
| echo "Created umask: $tperms" >>$tdebug |
| if [ "$rc0" -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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" |
| elif ! echo "$oumask" |diff "$tc" - >$tdiff; then |
| $PRINTF "$FAILED (bad umask)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| # Test the modified umask option, in particular if umask with first address |
| # (SHELL) does not affect umask of second address, i.e. original umask is |
| # recovered |
| NAME=UMASK_ON_SYSTEM |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%shell%*|*%system%*|*%umask%*|*%socket%*|*%$NAME%*) |
| TEST="$NAME: test restore after SHELL with umask option" |
| # Run Socat with first address SHELL:"cat >file" with modified umask, |
| # and second address SYSTEM (shell) with umask command. |
| # Check if the file is created with modified umask but shell has original umask |
| 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" |
| 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" |
| 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" |
| else |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tc="$td/test$N.creat" |
| tdiff="$td/test$N.diff" |
| tdebug="$td/test$N.debug" |
| oumask=$(umask) |
| # Construct a temp umask differing from original umask |
| case oumask in |
| *066) tumask=0026 ;; |
| *) tumask=0066 ;; |
| esac |
| CMD0="$TRACE $SOCAT $opts -U SHELL:\"cat\ >$tc\",umask=$tumask SYSTEM:umask" |
| printf "test $F_n $TEST... " $N |
| eval "$CMD0" >/dev/null 2>"${te}0" |
| rc0=$? |
| tperms=$(fileperms $tc) |
| case $tperms in |
| 0*) ;; |
| *) tperms=0$tperms ;; |
| esac |
| echo "Original umask: $oumask" >>$tdebug |
| echo "Temporary umask: $tumask" >>$tdebug |
| echo "Created umask: $tperms" >>$tdebug |
| if [ "$rc0" -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| 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" |
| elif ! echo "$oumask" |diff "$tc" - >$tdiff; then |
| $PRINTF "$FAILED (bad umask)\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| else |
| $PRINTF "$OK\n" |
| if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi |
| if [ "$DEBUG" ]; then cat "${te}0" >&2; fi |
| numOK=$((numOK+1)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| # end of common 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) |
| |
| NAME=PTYGROUPLATE |
| case "$TESTS" in |
| *%roottough%*|*%$NAME%*) |
| 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. |
| # ATTENTION: in case of failure of this test the |
| # group of /dev/ptmx might be changed! |
| if ! eval $NUMCOND; then :; else |
| # save current /dev/ptmx properties |
| F= |
| for f in /dev/ptmx /dev/ptc; do |
| if [ -e $f ]; then |
| F=$(echo "$f" |tr / ..) |
| ls -l $f >"$td/test$N.$F.ls-l" |
| break |
| fi |
| done |
| printf "test $F_n $TEST... " $N |
| if [ -z "$F" ]; then |
| echo -e "${YELLOW}no /dev/ptmx or /dev/ptc${NORMAL}" |
| else |
| GROUP=daemon |
| tf="$td/test$N.stdout" |
| te="$td/test$N.stderr" |
| tl="$td/test$N.pty" |
| tdiff="$td/test$N.diff" |
| da="test$N $(date) $RANDOM" |
| CMD0="$TRACE $SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE" |
| CMD1="$TRACE $SOCAT $opts - $tl,raw,echo=0" |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| (echo "$da"; usleep $MICROS; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ $rc1 -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| echo "$CMD1" |
| cat "${te}0" |
| cat "${te}1" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| elif echo "$da" |diff - "$tf" >$tdiff; then |
| $PRINTF "$OK\n" |
| numOK=$((numOK+1)) |
| else |
| $PRINTF "$FAILED\n" |
| cat "$tdiff" |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| fi |
| if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then |
| $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n" |
| fi |
| fi # no /dev/ptmx |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |
| |
| |
| echo "Used temp directory $TD - you might want to remove it after analysis" |
| echo "Summary: $((N-1)) tests, $((numOK+numFAIL+numCANT)) selected; $numOK ok, $numFAIL failed, $numCANT could not be performed" |
| |
| set -- $listCANT; while [ "$1" ]; do echo "$1"; shift; done >"$td/cannot.lst" |
| ln -sf "$td/cannot.lst" . |
| set -- $listFAIL; while [ "$1" ]; do echo "$1"; shift; done >"$td/failed.lst" |
| ln -sf "$td/failed.lst" . |
| sort -n <(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" . |
| if [ "$numCANT" -gt 0 ]; then |
| echo "CANT: $listCANT" |
| fi |
| if [ "$numFAIL" -gt 0 ]; then |
| echo "FAILED: $listFAIL" |
| fi |
| |
| if [ -z "$OPT_EXPECT_FAIL" ]; then |
| [ "$numFAIL" -eq 0 ] |
| 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" . |
| #grep "^" |
| grep "^> " "$td/failed.diff" |awk '{print($2);}' >"$td/failed.unexp" |
| ln -s "$td/failed.unexp" . |
| echo "FAILED unexpected: $(cat "$td/failed.unexp" |xargs echo)" |
| grep "^< " "$td/failed.diff" |awk '{print($2);}' >"$td/ok.unexp" |
| ln -s "$td/ok.unexp" . |
| echo "OK unexpected: $(cat "$td/ok.unexp" |xargs echo)" |
| else |
| touch "$td/failed.diff" |
| fi |
| #listFAIL=$(cat "$td/failed.lst" |xargs echo) |
| #numFAIL="$(wc -l "$td/failed.lst" |awk '{print($1);}')" |
| |
| ! test -s "$td/failed.unexp" |
| exit |
| |
| #============================================================================== |
| |
| rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips* |
| |
| # end |
| |
| # too dangerous - run as root and having a shell problem, it might purge your |
| # file systems |
| #rm -r "$td" |
| |
| # sometimes subprocesses hang; we want to see this |
| wait |
| |
| exit |
| |
| #============================================================================== |
| # test template |
| |
| # Give a description of what is tested (a bugfix, a new feature...) |
| NAME=SHORT_UNIQUE_TESTNAME |
| case "$TESTS" in |
| *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*) |
| #*%foreign%*|*%root%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%bug%*|... |
| TEST="$NAME: give a one line description of test" |
| # Describe how the test is performed, and what's the success criteria |
| if ! eval $NUMCOND; then :; |
| # Remove unneeded checks, adapt lists of the remaining ones |
| elif [ "$UNAME" != Linux ]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| elif ! F=$(testfeats STDIO IP4 TCP PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE); then |
| $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| 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" |
| 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" |
| elif [ -z "$FOREIGN" ]; then |
| $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option -foreign${NORMAL}\n" $N |
| numCANT=$((numCANT+1)) |
| listCANT="$listCANT $N" |
| else |
| 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 |
| CMD0="$TRACE $SOCAT $opts server-address PIPE" |
| CMD1="$TRACE $SOCAT $opts - client-address" |
| printf "test $F_n $TEST... " $N |
| $CMD0 >/dev/null 2>"${te}0" & |
| pid0=$! |
| wait<something>port $PORT 1 |
| #relsleep 1 # if no matching wait*port function |
| echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" |
| rc1=$? |
| kill $pid0 2>/dev/null; wait |
| if [ "$rc1" -ne 0 ]; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif ! echo "$da" |diff "${tf}1" - >$tdiff; then |
| $PRINTF "$FAILED\n" |
| echo "$CMD0 &" |
| cat "${te}0" >&2 |
| echo "$CMD1" |
| cat "${te}1" >&2 |
| numFAIL=$((numFAIL+1)) |
| listFAIL="$listFAIL $N" |
| namesFAIL="$namesFAIL $NAME" |
| elif [ ??? ]; then |
| # The test could not run meaningfully |
| $PRINTF "$CANT\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" |
| 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)) |
| fi |
| fi # NUMCOND |
| ;; |
| esac |
| N=$((N+1)) |