Version 1.8.0.0
[socat.git] / test.sh
blobf70ad8936c4a7ebb38cc2aa49d7903f8632fd032
1 #! /usr/bin/env bash
2 # source: test.sh
3 # Copyright Gerhard Rieger and contributors (see file CHANGES)
4 # Published under the GNU General Public License V.2, see file COPYING
6 # perform lots of tests on socat
8 # this script uses functions; you need a shell that supports them
10 # you can pass general options to socat: export OPTS="-d -d -d -d -lu"
11 # you can eg strace socat with: export TRACE="strace -v -tt -ff -D -x -s 1024 -o /tmp/$USER/socat.strace"
12 #set -vx
14 #TODO: Add options for interface, broadcast-interface
16 [ -z "$USER" ] && USER="$LOGNAME" # HP-UX
17 if [ -z "$TMPDIR" ]; then
18 if [ -z "$TMP" ]; then
19 TMP=/tmp
21 TMPDIR="$TMP"
23 #E=-e # Linux
24 if [ $(echo "x\c") = "x" ]; then E=""
25 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
26 else
27 echo "cannot suppress trailing newline on echo" >&2
28 exit 1
30 ECHO="echo $E"
31 PRINTF="printf"
33 usage() {
34 $ECHO "Usage: $0 <options> [<test-spec> ...]"
35 $ECHO "options:"
36 $ECHO "\t-h \t\tShow this help"
37 $ECHO "\t-t <sec> \tBase for timeouts in seconds, default: 0.1"
38 $ECHO "\t-v \t\tBe more verbose, show failed commands"
39 $ECHO "\t-n <num> \tOnly perform test with given number"
40 $ECHO "\t-N <num> \tOnly perform tests starting with given number"
41 $ECHO "\t-C \t\tClear/remove left over certificates from previous runs"
42 $ECHO "\t-x \t\tShow commands executed, even when test succeeded"
43 #$ECHO "\t-d \t\tShow log output of commands, even when they did not fail"
44 $ECHO "\t--internet \tAllow tests that send packets to Internet"
45 $ECHO "\t--expect-fail N1,N2,... \tIgnore failure of these tests"
46 $ECHO "\ttest-spec \Number of test or name of test"
47 $ECHO "Contents of environment variable OPTS are passed to Socat invocations, e.'g:"
48 $ECHO "OPTS=\"-d -d -d -d -lu\" ./test.sh"
49 $ECHO "TRACE=\"strace -tt -v\" Use trace,valgrind etc.on socat"
50 $ECHO "SOCAT=/path/to/socat \tselect socat executable for test"
51 $ECHO "FILAN=... PROCAN=..."
52 $ECHO "Find the tests' stdout,stderr,diff in $TMPDIR/$USER/\$PID"
55 val_t=0.1
56 NUMCOND=true
57 #NUMCOND="test \$N -gt 70"
58 VERBOSE=
59 DEBUG=
60 INTERNET=
61 OPT_EXPECT_FAIL= EXPECT_FAIL=
62 while [ "$1" ]; do
63 case "X$1" in
64 X-h) usage; exit 0 ;;
65 X-d) DEBUG="1" ;;
66 X-t?*) val_t="${1#-t}" ;;
67 X-t) shift; val_t="$1" ;;
68 X-v) VERBOSE=1 ;; # show commands
69 X-n?*) NUMCOND="test \$N -eq ${1#-n}" ;;
70 X-n) shift; NUMCOND="test \$N -eq $1" ;;
71 X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;;
72 X-N) shift; NUMCOND="test \$N -ge $1" ;;
73 X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;;
74 X--internet|X-internet) INTERNET=1 ;; # allow access to 3rd party Internet hosts
75 X--expect-fail|X-expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;;
76 X-*) echo "Unknown option \"$1\"" >&2
77 usage >&2
78 exit 1 ;;
79 *) break;
80 esac
81 shift
82 done
83 debug=$DEBUG
85 opt_t="-t $val_t"
87 UNAME=`uname`
88 UNAME_R=`uname -r`
90 #MICROS=100000
91 case "X$val_t" in
92 X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;;
93 X*.*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS}000000"; uS="${uS:0:6}" ;;
94 X*) S="${val_t}"; uS="000000" ;;
95 esac
96 MICROS=${S}${uS}
97 MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0}
98 #echo MICROS=$MICROS >&2
100 _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}"
101 [ -z "$SECONDs" ] && SECONDs=0
103 withroot=0 # perform privileged tests even if not run by root
105 [ -z "$SOCAT" ] && SOCAT="./socat"
106 if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then
107 echo "$SOCAT does not exist" >&2; exit 1;
109 if [ "$SOCAT" = socat ]; then
110 SOCAT=$(type -p socat) || SOCAT=$(which socat)
112 #echo $SOCAT
113 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
114 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
116 #PATH=$PATH:/opt/freeware/bin
117 #PATH=$PATH:/usr/local/ssl/bin
118 PATH=$PATH:/sbin # RHEL6:ip
119 case "$0" in
120 */*) PATH="${0%/*}:$PATH"
121 esac
122 #OPENSSL_RAND="-rand /dev/egd-pool"
123 #SOCAT_EGD="egd=/dev/egd-pool"
124 MISCDELAY=1
126 OPTS="$opt_t $OPTS"
127 opts="$OPTS"
129 TESTS="$*"; export TESTS
130 if ! SOCAT_MAIN_WAIT= $SOCAT -V >/dev/null 2>&1; then
131 echo "Failed to execute $SOCAT, exiting" >&2
132 exit 1
135 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/')
136 if [ -z "$SOCAT_VERSION" ]; then
137 echo "Warning: failed to retrieve Socat version" >&2
140 if type ip >/dev/null 2>&1; then
141 if ip -V |grep -q -i -e "^ip utility, iproute2-" -e BusyBox; then
142 IP=$(type -p ip)
143 else
144 unset IP
148 if type ss >/dev/null 2>&1; then
149 # on Ubuntu-10 ss has differing output format
150 if ss -V |grep -q "^ss utility, iproute2-[2-6]"; then
151 SS=$(type -p ss)
152 else
153 unset SS
157 # for some tests we need a network interface
158 if type ip >/dev/null 2>&1; then
159 INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/")
160 else
161 case "$UNAME" in
162 Linux)
163 if [ "$IP" ]; then
164 INTERFACE="$($IP route get 8.8.8.8 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')"
165 else
166 INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($8);}')"
167 fi ;;
168 FreeBSD) INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($4);}')" ;;
169 *) INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($4);}')" ;;
170 esac
172 MCINTERFACE=$INTERFACE
173 [ -z "$MCINTERFACE" ] && MCINTERFACE=lo # !!! Linux only - and not always
174 #LOCALHOST=192.168.58.1
175 LOCALHOST=localhost # attention: on FreeBSD-10 localhost resolves primarily to IPv6
176 LOCALHOST4=127.0.0.1
177 LOCALHOST6="[::1]"
178 #PROTO=$(awk '{print($2);}' /etc/protocols |sort -n |tail -n 1)
179 #PROTO=$(($PROTO+1))
180 PROTO=$((144+RANDOM/2048))
181 _PORT=12001
182 SOURCEPORT=2002
183 REUSEADDR=reuseaddr # use this with LISTEN addresses and bind options
185 # get some system constants for use in tests
186 SOCK_DGRAM="$($PROCAN -c |grep "^#define[[:space:]]*SOCK_DGRAM[[:space:]]" |cut -d' ' -f3)"
187 FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print($3);}')
188 PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)"
189 TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)"
190 SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)"
191 SO_REUSEADDR="$($PROCAN -c |grep "^#define[[:space:]]*SO_REUSEADDR[[:space:]]" |cut -d' ' -f3)"
192 TCP_MAXSEG="$($PROCAN -c |grep "^#define[[:space:]]*TCP_MAXSEG[[:space:]]" |cut -d' ' -f3)"
193 SIZE_T=$($PROCAN |grep "^[^[:space:]]*size_t" |awk '{print($3);}')
194 #AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi
196 # SSL certificate contents
197 TESTCERT_CONF=testcert.conf
198 TESTCERT6_CONF=testcert6.conf
199 TESTALT_CONF=testalt.conf
201 TESTCERT_COMMONNAME="$LOCALHOST"
202 TESTCERT_COMMONNAME6="$LOCALHOST6"
203 TESTCERT_COUNTRYNAME="XY"
204 TESTCERT_LOCALITYNAME="Lunar Base"
205 TESTCERT_ORGANIZATIONALUNITNAME="socat"
206 TESTCERT_ORGANIZATIONNAME="dest-unreach"
207 TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
208 TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
209 RSABITS=2048 # Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536
210 DSABITS=2048
211 cat >$TESTCERT_CONF <<EOF
212 prompt=no
214 [ req ]
215 default_bits = $RSABITS
216 distinguished_name=Test
218 [ Test ]
219 countryName=$TESTCERT_COUNTRYNAME
220 commonName=$TESTCERT_COMMONNAME
221 O=$TESTCERT_ORGANIZATIONNAME
222 OU=$TESTCERT_ORGANIZATIONALUNITNAME
223 L=$TESTCERT_LOCALITYNAME
227 cat >$TESTCERT6_CONF <<EOF
228 prompt=no
230 [ req ]
231 default_bits = $RESBITS
232 distinguished_name=Test
234 [ Test ]
235 countryName=$TESTCERT_COUNTRYNAME
236 commonName=$TESTCERT_COMMONNAME6
237 O=$TESTCERT_ORGANIZATIONNAME
238 OU=$TESTCERT_ORGANIZATIONALUNITNAME
239 L=$TESTCERT_LOCALITYNAME
243 cat >$TESTALT_CONF <<EOF
244 # config for generation of self signed certificate with IP addresses in
245 # SubjectAltNames
246 prompt=no
248 [ req ]
249 default_bits = $RSABITS
250 distinguished_name = subject
251 x509_extensions = x509_ext
253 [ subject ]
254 countryName=$TESTCERT_COUNTRYNAME
255 commonName=servername
256 O=$TESTCERT_ORGANIZATIONNAME
257 OU=$TESTCERT_ORGANIZATIONALUNITNAME
258 L=$TESTCERT_LOCALITYNAME
260 [ x509_ext ]
261 subjectAltName = @alternate_names
263 [ alternate_names ]
264 DNS.1 = localhost
265 DNS.2 = localhost4
266 DNS.3 = localhost6
267 IP.1 = 127.0.0.1
268 IP.2 = ::1
272 # clean up from previous runs
273 rm -f testcli.{crt,key,pem}
274 rm -f testsrv.{crt,key,pem}
275 rm -f testcli6.{crt,key,pem}
276 rm -f testsrv6.{crt,key,pem}
277 rm -f testalt.{crt,key,pem}
279 CAT="cat"
280 OD_C="od -c"
282 toupper () {
283 case ${BASH_VERSION:0:1} in
284 [1-3]) echo "$@" |tr a-z A-Z ;;
285 [4-9]) echo "${@^^*}" ;;
286 esac
289 tolower () {
290 case ${BASH_VERSION:0:1} in
291 [1-3]) echo "$@" |tr A-Z a-z ;;
292 [4-9]) echo "${@,,*}" ;;
293 esac
296 # precision sleep; takes seconds with fractional part
297 psleep () {
298 local T="$1"
299 [ "$T" = 0 ] && T=0.000002
300 $SOCAT -T "$T" pipe pipe 2>/dev/null
302 # time in microseconds to wait in some situations
303 if ! type usleep >/dev/null 2>&1 ||
304 usleep 0 2>&1 |grep -q deprecated; then
305 usleep () {
306 local n="$1"
307 case "$n" in
308 *???????) S="${n%??????}"; uS="${n:${#n}-6}" ;;
309 *) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;;
310 esac
311 $SOCAT -T "$S.$uS" pipe pipe 2>/dev/null
314 #USLEEP=usleep
316 # A sleep with configurable clocking ($vat_t)
317 # val_t should be at least the time that a Socat invocation, no action, and
318 # termination takes
319 relsleep () {
320 usleep $(($1*MICROS))
323 if type ping6 >/dev/null 2>&1; then
324 PING6=ping6
325 else
326 PING6="ping -6"
329 F_n="%3d" # format string for test numbers
330 export LC_ALL=C # for timestamps format...
331 export LANG=C
332 export LANGUAGE=C # knoppix
333 case "$UNAME" in
334 HP-UX|OSF1)
335 echo "$SOCAT -u stdin stdout" >cat.sh
336 chmod a+x cat.sh
337 CAT=./cat.sh
339 SunOS)
340 # /usr/bin/tr doesn't handle the a-z range syntax (needs [a-z]), use
341 # /usr/xpg4/bin/tr instead
342 alias tr=/usr/xpg4/bin/tr
345 CAT="cat"
347 esac
349 # some OSes need special options
350 case "$UNAME" in
351 #HP-UX)
352 # # on HP-UX, the default options (below) hang some tests (former 14, 15)
353 # PTYOPTS=
354 # PTYOPTS2=
355 # ;;
356 SunOS)
357 PTYOPTS="perm=600"
358 PTYOPTS2="echo=0,opost=0"
361 PTYOPTS="echo=0,opost=0"
362 #PTYOPTS2="raw,echo=0"
363 PTYOPTS2="cfmakeraw"
364 #PTYOPTS2="rawer"
366 esac
368 # for some tests we need an unprivileged user id to su to
369 if [ "$SUDO_USER" ]; then
370 SUBSTUSER="$SUDO_USER"
371 else
372 SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)"
375 if [ -z "$SS" ]; then
376 # non-root users might miss ifconfig in their path
377 case "$UNAME" in
378 AIX) IFCONFIG=/usr/sbin/ifconfig ;;
379 FreeBSD) IFCONFIG=/sbin/ifconfig ;;
380 HP-UX) IFCONFIG=/usr/sbin/ifconfig ;;
381 Linux) IFCONFIG=/sbin/ifconfig ;;
382 NetBSD)IFCONFIG=/sbin/ifconfig ;;
383 OpenBSD)IFCONFIG=/sbin/ifconfig ;;
384 OSF1) IFCONFIG=/sbin/ifconfig ;;
385 SunOS) IFCONFIG=/sbin/ifconfig ;;
386 Darwin)IFCONFIG=/sbin/ifconfig ;;
387 DragonFly) IFCONFIG=/sbin/ifconfig ;;
388 *) IFCONFIG=/sbin/ifconfig ;;
389 esac
392 # need output like "644"
393 case "$UNAME" in
394 Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;;
395 FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;;
396 *) fileperms() {
397 local p s=0 c
398 p="$(ls -l -L "$1" |awk '{print($1);}')"
399 p="${p:1:9}"
400 while [ "$p" ]; do c=${p:0:1}; p=${p:1}; [ "x$c" == x- ]; let "s=2*s+$?"; done
401 printf "%03o\n" $s;
402 } ;;
403 esac
405 # need user (owner) of filesystem entry
406 case "$UNAME" in
407 Linux) fileuser() { stat -L --print "%U\n" "$1" 2>/dev/null; } ;;
408 FreeBSD) fileuser() { ls -l "$1" |awk '{print($3);}'; } ;;
409 *) fileuser() { ls -l "$1" |awk '{print($3);}'; } ;;
410 esac
412 if2addr4() {
413 local IF="$1"
414 if [ "$IP" ]; then
415 $IP address show dev "$IF" |grep "inet " |sed -e "s/.*inet //" -e "s/ .*//"
416 else
417 $IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}' |cut -d: -f2
421 if2bc4() {
422 local IF="$1"
423 if [ "$IP" ]; then
424 $IP address show dev "$IF" |grep ' inet .* brd ' |awk '{print($4);}'
425 else
426 $IFCONFIG "$IF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}'
430 # for some tests we need a second local IPv4 address
431 case "$UNAME" in
432 Linux)
433 if [ "$IP" ]; then
434 BROADCASTIF=$($IP r get 8.8.8.8 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/')
435 else
436 BROADCASTIF=$(route -n |grep '^0.0.0.0 ' |awk '{print($8);}')
438 [ -z "$BROADCASTIF" ] && BROADCASTIF=eth0
439 SECONDADDR=127.1.0.1
440 SECONDMASK=255.255.0.0
441 BCADDR=127.255.255.255
442 BCIFADDR=$(if2addr4 $BROADCASTIF) ;;
443 FreeBSD|NetBSD|OpenBSD)
444 MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1)
445 BROADCASTIF="$MAINIF"
446 SECONDADDR=$($IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}')
447 BCIFADDR="$SECONDADDR"
448 BCADDR=$($IFCONFIG "$BROADCASTIF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;;
449 HP-UX)
450 MAINIF=lan0 # might use "netstat -ni" for this
451 BROADCASTIF="$MAINIF"
452 SECONDADDR=$($IFCONFIG $MAINIF |tail -n 1 |awk '{print($2);}')
453 BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;;
454 SunOS)
455 MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1)
456 BROADCASTIF="$MAINIF"
457 #BROADCASTIF=hme0
458 #BROADCASTIF=eri0
459 #SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}')
460 SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 '| head -n 1)" : '.*inet \([0-9.]*\) .*')
461 #BCIFADDR="$SECONDADDR"
462 #BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}')
464 DragonFly)
465 MAINIF=$($IFCONFIG -a |grep -v ^lp |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1)
466 BROADCASTIF="$MAINIF"
467 SECONDADDR=$($IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}')
468 BCIFADDR="$SECONDADDR"
469 BCADDR=$($IFCONFIG "$BROADCASTIF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;;
470 #AIX|FreeBSD|Solaris)
472 SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |fgrep -v ' 127.0.0.1 ' |head -n 1)" : '.*inet \([0-9.]*\) .*')
474 esac
475 # for generic sockets we need this address in hex form
476 if [ "$SECONDADDR" ]; then
477 SECONDADDRHEX="$(printf "%02x%02x%02x%02x\n" $(echo "$SECONDADDR" |tr '.' ' '))"
480 # for some tests we need a second local IPv6 address
481 case "$UNAME" in
482 Linux) if [ "$IP" ]; then
483 SECONDIP6ADDR=$(expr "$($IP address |grep 'inet6 ' |fgrep -v ' ::1/128 '| head -n 1)" : '.*inet6 \([0-9a-f:][0-9a-f:]*\)/.*')
484 else
485 SECONDIP6ADDR=$(expr "$($IFCONFIG -a |grep 'inet6 ' |fgrep -v ' ::1/128 '| head -n 1)" : '.*inet \([0-9.]*\) .*')
486 fi ;;
488 SECONDIP6ADDR=$(expr "$($IFCONFIG -a |grep 'inet6 ' |fgrep -v ' ::1/128 '| head -n 1)" : '.*inet \([0-9.]*\) .*')
490 esac
491 if [ -z "$SECONDIP6ADDR" ]; then
492 # case "$TESTS" in
493 # *%root2%*) $IFCONFIG eth0 ::2/128
494 # esac
495 SECONDIP6ADDR="$LOCALHOST6"
496 else
497 SECONDIP6ADDR="[$SECONDIP6ADDR]"
500 TRUE=$(which true)
501 #E=-e # Linux
502 if [ $(echo "x\c") = "x" ]; then E=""
503 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
504 else
505 echo "cannot suppress trailing newline on echo" >&2
506 exit 1
508 ECHO="echo $E"
509 PRINTF="printf"
511 case "$TERM" in
512 vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256color|screen)
513 # there are different behaviours of printf (and echo)
514 # on some systems, echo behaves different than printf...
515 if [ "$($PRINTF "\0101")" = "A" ]; then
516 RED="\0033[31m"
517 GREEN="\0033[32m"
518 YELLOW="\0033[33m"
519 # if [ "$UNAME" = SunOS ]; then
520 # NORMAL="\0033[30m"
521 # else
522 NORMAL="\0033[39m"
523 # fi
524 else
525 RED="\033[31m"
526 GREEN="\033[32m"
527 YELLOW="\033[33m"
528 # if [ "$UNAME" = SunOS ]; then
529 # NORMAL="\033[30m"
530 # else
531 NORMAL="\033[39m"
532 # fi
534 OK="${GREEN}OK${NORMAL}"
535 FAILED="${RED}FAILED${NORMAL}"
536 NO_RESULT="${YELLOW}NO RESULT${NORMAL}"
537 CANT="$NO_RESULT"
539 *) OK="OK"
540 FAILED="FAILED"
541 NO_RESULT="NO RESULT"
542 CANT="$NO_RESULT"
544 esac
546 if [ -x /usr/xpg4/bin/id ]; then
547 # SunOS has rather useless tools in its default path
548 PATH="/usr/xpg4/bin:$PATH"
551 OPENSSL_S_CLIENT_4=
552 OPENSSL_S_CLIENT_DTLS=
553 init_openssl_s_client () {
554 if openssl s_client -help 2>&1 |grep -q ' -4 '; then
555 OPENSSL_S_CLIENT_4="-4"
556 else
557 OPENSSL_S_CLIENT_4=" "
559 if openssl s_client -help 2>&1 | grep -q ' -dtls '; then
560 OPENSSL_S_CLIENT_DTLS=-dtls
561 else
562 OPENSSL_S_CLIENT_DTLS=-dtls1
566 OPENSSL_S_SERVER_4=
567 OPENSSL_S_SERVER_DTLS=
568 OPENSSL_S_SERVER_NO_IGN_EOF=
569 init_openssl_s_server () {
570 if openssl s_server -help 2>&1 |grep -q ' -4 '; then
571 OPENSSL_S_SERVER_4="-4"
572 else
573 OPENSSL_S_SERVER_4=" "
575 if openssl s_server -help 2>&1 | grep -q ' -dtls '; then
576 OPENSSL_S_SERVER_DTLS="-dtls"
577 else
578 OPENSSL_S_SERVER_DTLS="-dtls1"
580 if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then
581 OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof"
582 else
583 OPENSSL_S_SERVER_NO_IGN_EOF=" "
588 [ -z "$TESTS" ] && TESTS="consistency functions filan"
589 # use '%' as separation char
590 TESTS="%$(echo " $TESTS " |tr ' ' '%')%"
592 [ -z "$USER" ] && USER="$LOGNAME" # HP-UX
593 if [ -z "$TMPDIR" ]; then
594 if [ -z "$TMP" ]; then
595 TMP=/tmp
597 TMPDIR="$TMP"
599 TD="$TMPDIR/$USER/$$"; td="$TD"
600 rm -rf "$TD" || (echo "cannot rm $TD" >&2; exit 1)
601 mkdir -p "$TD"
602 #trap "rm -r $TD" 0 3
604 echo "Using temp directory $TD"
606 case "$TESTS" in
607 *%consistency%*)
608 # test if addresses are sorted alphabetically:
609 $ECHO "testing if address array is sorted...\c"
610 TF="$TD/socat-q"
611 IFS="$($ECHO ' \n\t')"
612 if ! $SOCAT -hhh >/dev/null; then
613 echo "Failed: $SOCAT -hhh" >&2
614 exit -1
616 $SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF"
617 $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"
618 if [ -s "$TF-diff" ]; then
619 $ECHO "\n*** address array is not sorted. Wrong entries:" >&2
620 cat "$TD/socat-q-diff" >&2
621 exit 1
622 else
623 echo " ok"
625 #/bin/rm "$TF"
626 #/bin/rm "$TF-diff"
627 esac
629 case "$TESTS" in
630 *%consistency%*)
631 # test if address options array ("optionnames") is sorted alphabetically:
632 $ECHO "testing if address options are sorted...\c"
633 TF="$TD/socat-qq"
634 $SOCAT -hhh |sed '1,/opt:/ d' |awk '{print($1);}' >"$TF"
635 LC_ALL=C sort "$TF" |diff "$TF" - >"$TF-diff"
636 if [ -s "$TF-diff" ]; then
637 $ECHO "\n*** option array is not sorted. Wrong entries:" >&2
638 cat "$TD/socat-qq-diff" >&2
639 exit 1
640 else
641 echo " ok"
643 /bin/rm "$TF"
644 /bin/rm "$TF-diff"
645 esac
647 #==============================================================================
650 numOK=0
651 numFAIL=0
652 numCANT=0
653 listFAIL=
654 listCANT=
655 namesFAIL=
657 #==============================================================================
658 # test if selected socat features work ("FUNCTIONS")
660 testecho () {
661 local N="$1"
662 local title="$2"
663 local arg1="$3"; [ -z "$arg1" ] && arg1="-"
664 local arg2="$4"; [ -z "$arg2" ] && arg2="echo"
665 local opts="$5"
666 local T="$6"; [ -z "$T" ] && T=0
667 local tf="$td/test$N.stdout"
668 local te="$td/test$N.stderr"
669 local tdiff="$td/test$N.diff"
670 local da="test$N $(date) $RANDOM"
671 if ! eval $NUMCOND; then :; else
672 #local cmd="$TRACE $SOCAT $opts $arg1 $arg2"
673 #$ECHO "testing $title (test $N)... \c"
674 $PRINTF "test $F_n %s... " $N "$title"
675 #echo "$da" |$cmd >"$tf" 2>"$te"
676 (psleep $T; echo "$da"; psleep $T) |($TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc") &
677 export rc1=$!
678 #sleep 5 && kill $rc1 2>/dev/null &
679 # rc2=$!
680 wait $rc1
681 # kill $rc2 2>/dev/null
682 if [ "$(cat "$td/test$N.rc")" != 0 ]; then
683 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
684 echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2
685 cat "$te" >&2
686 numFAIL=$((numFAIL+1))
687 listFAIL="$listFAIL $N"
688 elif echo "$da" |diff - "$tf" >"$tdiff" 2>&1; then
689 $PRINTF "$OK\n"
690 if [ "$VERBOSE" ]; then echo "$SOCAT $opts $arg1 $arg2" >&2; fi
691 if [ -n "$debug" ]; then cat $te >&2; fi
692 numOK=$((numOK+1))
693 else
694 $PRINTF "$FAILED:\n"
695 echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2
696 cat "$te" >&2
697 echo diff: >&2
698 cat "$tdiff" >&2
699 numFAIL=$((numFAIL+1))
700 listFAIL="$listFAIL $N"
702 fi # NUMCOND
705 # test if call to od and throughput of data works - with graceful shutdown and
706 # flush of od buffers
707 testod () {
708 local num="$1"
709 local title="$2"
710 local arg1="$3"; [ -z "$arg1" ] && arg1="-"
711 local arg2="$4"; [ -z "$arg2" ] && arg2="echo"
712 local opts="$5"
713 local T="$6"; [ -z "$T" ] && T=0
714 local tf="$td/test$N.stdout"
715 local te="$td/test$N.stderr"
716 local tr="$td/test$N.ref"
717 local tdiff="$td/test$N.diff"
718 local dain="$(date) $RANDOM"
719 if ! eval $NUMCOND; then :; else
720 echo "$dain" |$OD_C >"$tr"
721 # local daout="$(echo "$dain" |$OD_C)"
722 $PRINTF "test $F_n %s... " $num "$title"
723 (psleep $T; echo "$dain"; psleep $T) |$TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"
724 if [ "$?" != 0 ]; then
725 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
726 echo "$TRACE $SOCAT $opts $arg1 $arg2"
727 cat "$te"
728 numFAIL=$((numFAIL+1))
729 listFAIL="$listFAIL $num"
730 # elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then
731 elif diff "$tr" "$tf" >"$tdiff" 2>&1; then
732 $PRINTF "$OK\n"
733 if [ -n "$debug" ]; then cat $te; fi
734 numOK=$((numOK+1))
735 else
736 $PRINTF "$FAILED: diff:\n"
737 echo "$TRACE $SOCAT $opts $arg1 $arg2"
738 cat "$te"
739 cat "$tdiff"
740 numFAIL=$((numFAIL+1))
741 listFAIL="$listFAIL $num"
743 fi # NUMCOND
746 # test if the socat executable has these features compiled in
747 # print the first missing address type
748 testfeats () {
749 local a A;
750 for a in $@; do
751 A=$(echo "$a" |tr 'a-z-' 'A-Z_')
752 if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then
753 if [[ "$A" =~ OPENSSL.* ]]; then
754 gentestcert testsrv
755 gentestcert testcli
757 shift
758 continue
760 echo "$a"
761 return 1
762 done
763 return 0
766 # test if the socat executable has these address types compiled in
767 # print the first missing address type
768 testaddrs () {
769 local a A;
770 for a in $@; do
771 A=$(echo "$a" |tr 'a-z' 'A-Z')
772 # the ::::: forces syntax errer and prevents the address from doing anything
773 if ! $SOCAT $A::::: /dev/null 2>&1 </dev/null |grep -q "E unknown device/address"; then
774 shift
775 continue
777 echo "$a"
778 return 1
779 done
780 return 0
783 # test if the socat executable has these options compiled in
784 # print the first missing option
785 testoptions () {
786 local a A;
787 for a in $@; do
788 A=$(echo "$a" |tr 'a-z' 'A-Z')
789 if $SOCAT -hhh |grep "[^a-z0-9-]$a[^a-z0-9-]" >/dev/null; then
790 shift
791 continue
793 echo "$a"
794 return 1
795 done
796 return 0
799 # check if the given pid exists and has child processes
800 # if yes: prints child process lines to stdout, returns 0
801 # if not: prints ev.message to stderr, returns 1
802 childprocess () {
803 local l
804 case "$UNAME" in
805 AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;;
806 FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;;
807 HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;;
808 Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;;
809 # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;;
810 NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;;
811 OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)")" ;;
812 SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;;
813 DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;;
814 CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]")" ;;
815 *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]**[ ][ ]*$(printf %5u $1) ")" ;; esac
816 if [ -z "$l" ]; then
817 return 1;
819 echo "$l"
820 return 0
823 # return a list of child process pids [killchild]
824 childpids () {
825 case "$UNAME" in
826 AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;;
827 FreeBSD) l="$(ps -fl |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
828 HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
829 # Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
830 Linux) l="$(ps -fade |grep "^[^[:space:]][^[:space:]]*[[:space:]][[:space:]]*[^[:space:]][^[:space:]]*[[:space:]][[:space:]]*$1 " |awk '{print($2);}')" ;;
831 # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)" |awk '{print($2);}')" ;;
832 NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)" |awk '{print($2);}')" ;;
833 OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
834 SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
835 DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)" |awk '{print($2);}')" ;;
836 CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
837 *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$(printf %5u $1) " |awk '{print($2);}')" ;; esac
838 if [ -z "$l" ]; then
839 return 1;
841 echo "$l"
842 return 0
845 # check if the given process line refers to a defunct (zombie) process
846 # yes: returns 0
847 # no: returns 1
848 isdefunct () {
849 local l
850 case "$UNAME" in
851 AIX) l="$(echo "$1" |grep ' <defunct>$')" ;;
852 FreeBSD) l="$(echo "$1" |grep ' <defunct>$')" ;;
853 HP-UX) l="$(echo "$1" |grep ' <defunct>$')" ;;
854 Linux) l="$(echo "$1" |grep ' <defunct>$')" ;;
855 SunOS) l="$(echo "$1" |grep ' <defunct>$')" ;;
856 DragonFly)l="$(echo "$1" |grep ' <defunct>$')" ;;
857 *) l="$(echo "$1" |grep ' <defunct>$')" ;;
858 esac
859 [ -n "$l" ];
862 # check if UNIX socket protocol is available on host
863 runsunix () {
864 return 0;
865 $TRACE $SOCAT /dev/null UNIX-LISTEN:"$td/unix.socket" 2>"$td/unix.stderr" &
866 pid=$!
867 usleep $MICROS
868 kill "$pid" 2>/dev/null
869 test ! -s "$td/unix.stderr"
872 unset HAVENOT_IP4
873 # check if an IP4 loopback interface exists
874 runsip4 () {
875 [ -n "$HAVENOT_IP4" ] && return $HAVENOT_IP4
876 local l
877 case "$UNAME" in
878 AIX) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;;
879 FreeBSD) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;;
880 HP-UX) l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;;
881 Linux) if [ "$IP" ]; then
882 l=$($IP address |egrep ' inet 127.0.0.1/')
883 else
884 l=$($IFCONFIG |egrep 'inet (addr:)?127\.0\.0\.1 ')
885 fi ;;
886 NetBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');;
887 OpenBSD)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');;
888 OSF1) l=$($IFCONFIG -a |grep ' inet ') ;;
889 SunOS) l=$($IFCONFIG -a |grep 'inet ') ;;
890 Darwin)l=$($IFCONFIG lo0 |fgrep 'inet 127.0.0.1 ') ;;
891 DragonFly)l=$($IFCONFIG -a |fgrep 'inet 127.0.0.1 ');;
892 CYGWIN*) l=$(ipconfig |grep IPv4);;
893 *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;;
894 esac
895 [ -z "$l" ] && return 1
896 # existence of interface might not suffice, check for routeability:
897 case "$UNAME" in
898 Darwin) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;;
899 Linux) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;;
900 *) if [ -n "$l" ]; then l=0; else l=1; fi ;;
901 esac
902 HAVENOT_IP4=$l
903 if [ "$HAVENOT_IP4" -ne 0 ]; then
904 echo IP4
906 return $l;
909 unset HAVENOT_IP6
910 # check if an IP6 loopback interface exists
911 runsip6 () {
912 [ -n "$HAVENOT_IP6" ] && return $HAVENOT_IP6
913 local l
914 case "$UNAME" in
915 AIX) l=$($IFCONFIG lo0 |grep 'inet6 ::1[/%]') ;;
916 HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;;
917 Linux) if [ "$IP" ]; then
918 l=$($IP address |egrep 'inet6 ::1/128')
919 else
920 l=$($IFCONFIG |egrep 'inet6 (addr: )?::1/?')
921 fi ;;
922 NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1 ');;
923 OSF1) l=$($IFCONFIG -a |grep ' inet6 ') ;;
924 SunOS) l=$($IFCONFIG -a |grep 'inet6 ') ;;
925 Darwin)l=$($IFCONFIG lo0 |grep 'inet6 ::1 ') ;;
926 CYGWIN*) l=$(ipconfig |grep IPv6);;
927 *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;;
928 esac
929 [ -z "$l" ] && return 1
930 # existence of interface might not suffice, check for routeability:
931 case "$UNAME" in
932 Darwin) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;;
933 Linux) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;;
934 *) if [ -n "$l" ]; then l=0; else l=1; fi ;;
935 esac
936 HAVENOT_IP6=$l
937 if [ "$HAVENOT_IP6" -ne 0 ]; then
938 echo IP6
940 return "$HAVENOT_IP6"
943 # check if TCP on IPv4 is available on host
944 runstcp4 () {
945 runsip4 >/dev/null || { echo TCP4; return 1; }
946 $SOCAT -h |grep -i ' TCP4-' >/dev/null || return 1
947 return 0;
950 # check if TCP on IPv6 is available on host
951 runstcp6 () {
952 runsip6 >/dev/null || { echo TCP6; return 1; }
953 $SOCAT -h |grep -i ' TCP6-' >/dev/null || return 1
954 return 0;
957 # check if UDP on IPv4 is available on host
958 runsudp4 () {
959 runsip4 >/dev/null || { echo UDP4; return 1; }
960 $SOCAT -h |grep -i ' UDP4-' >/dev/null || return 1
961 return 0;
964 # check if UDP on IPv6 is available on host
965 runsudp6 () {
966 runsip6 >/dev/null || { echo UDP6; return 1; }
967 $SOCAT -h |grep -i ' UDP6-' >/dev/null || return 1
968 return 0;
971 # check if SCTP on IPv4 is available on host
972 runssctp4 () {
973 runsip4 >/dev/null || { echo SCTP4; return 1; }
974 $SOCAT -h |grep -i ' SCTP4-' >/dev/null || return 1
975 $SOCAT /dev/null SCTP4-L:0,accept-timeout=0.001 2>/dev/null || return 1;
976 return 0;
979 # check if SCTP on IPv6 is available on host
980 runssctp6 () {
981 runsip6 >/dev/null || { echo SCTP6; return 1; }
982 $SOCAT -h |grep -i ' SCTP6-' >/dev/null || return 1
983 $SOCAT /dev/null SCTP6-L:0,accept-timeout=0.001 2>/dev/null || return 1;
984 return 0;
987 # check if DCCP on IPv4 is available on host
988 runsdccp4 () {
989 runsip4 >/dev/null || { echo DCCP4; return 1; }
990 $SOCAT -h |grep -i ' DCCP4-' >/dev/null || return 1
991 $SOCAT /dev/null DCCP4-L:0,accept-timeout=0.001 2>/dev/null || return 1;
992 return 0;
995 # check if DCCP on IPv6 is available on host
996 runsdccp6 () {
997 runsip6 >/dev/null || { echo DCCP6; return 1; }
998 $SOCAT -h |grep -i ' DCCP6-' >/dev/null || return 1
999 $SOCAT /dev/null DCCP6-L:0,accept-timeout=0.001 2>/dev/null || return 1;
1000 return 0;
1003 # check if UDPLITE on IPv4 is available on host
1004 runsudplite4 () {
1005 runsip4 >/dev/null || { echo UDPLITE4; return 1; }
1006 $SOCAT -u -T 0.001 /dev/null UDPLITE4-SENDTO:$LOCALHOST4:0 2>/dev/null || return 1;
1007 return 0;
1010 # check if UDPLITE on IPv6 is available on host
1011 runsudplite6 () {
1012 runsip6 >/dev/null || { echo UDPLITE6; return 1; }
1013 $SOCAT -u -T 0.001 /dev/null UDPLITE6-SENDTO:$LOCALHOST6:0 2>/dev/null || return 1;
1014 return 0;
1017 # check if UNIX domain sockets work
1018 runsunix () {
1019 # for now...
1020 return 0;
1023 routesip6 () {
1024 runsip6 >/dev/null || { echo route6; return 1; }
1025 ping -c 1 -s 0 -6 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; }
1026 return 0;
1030 # Perform a couple of checks to make sure the test has a chance of a useful
1031 # result:
1032 # platform is supported, features compiled in, addresses and options
1033 # available; needs root; is allowed to access the internet
1034 checkconds() {
1035 local unames="$(echo "$1")" # must be one of... exa: "Linux,FreeBSD"
1036 local root="$2" # "root" or ""
1037 local progs="$(echo "$3" |tr 'A-Z,' 'a-z ')" # exa: "nslookup"
1038 local feats="$(echo "$4" |tr 'a-z,' 'A-Z ')" # list of req.features (socat -V)
1039 local addrs="$(echo "$5" |tr 'a-z,' 'A-Z ')" # list of req.addresses (socat -h)
1040 local opts="$(echo "$6" |tr 'A-Z,' 'a-z ')" # list of req.options (socat -hhh)
1041 local runs="$(echo "$7" |tr , ' ')" # list of req.protocols, exa: "sctp6"
1042 local inet="$8" # when "internet": needs allowance
1043 local i
1045 if [ "$unames" ]; then
1046 local uname="$(echo $UNAME |tr 'A-Z' 'a-z')"
1047 for i in $unames; do
1048 if [ "$uname" = "$(echo "$i" |tr 'A-Z,' 'a-z ')" ]; then
1049 # good, mark as passed
1051 break;
1053 done
1054 [ "$i" ] && { echo "Only on (one of) $unames"; return 255; }
1057 if [ "$root" = "root" ]; then
1058 if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
1059 echo "Must be root"
1060 return 255
1064 if [ "$progs" ]; then
1065 for i in $progs; do
1066 if ! type >/dev/null 2>&1; then
1067 echo "Program $i not available"
1068 return 255
1070 done
1073 if [ "$feats" ]; then
1074 if ! F=$(testfeats $feats); then
1075 echo "Feature $F not configured in $SOCAT"
1076 return 255
1080 if [ "$addrs" ]; then
1081 if ! A=$(testaddrs - $addrs); then
1082 echo "Address $A not available in $SOCAT"
1083 return 255
1087 if [ "$opts" ]; then
1088 if ! o=$(testoptions $opts); then
1089 echo "Option $o not available in $SOCAT"
1090 return 255
1094 if [ "$runs" ]; then
1095 for i in $runs; do
1096 if ! runs$i >/dev/null; then
1097 echo "$i not available on host"
1098 return 255;
1100 done
1103 if [ "$inet" ]; then
1104 if [ -z "$NTERNET" ]; then
1105 echo "Use test.sh option --internet"
1106 return 255
1109 return 0
1113 # wait until an IP4 protocol is ready
1114 waitip4proto () {
1115 local proto="$1"
1116 local logic="$2" # 0..wait until free; 1..wait until listening
1117 local timeout="$3"
1118 local l
1119 [ "$logic" ] || logic=1
1120 [ "$timeout" ] || timeout=5
1121 while [ $timeout -gt 0 ]; do
1122 case "$UNAME" in
1123 Linux) if [ "$SS" ]; then
1124 l=$($SS -n -w -l |grep '^\(raw\|UNCONN\) .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*')
1125 else
1126 l=$(netstat -n -w -l |grep '^raw .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*')
1127 fi ;;
1128 # FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;;
1129 # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1130 # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1131 # Darwin) case "$(uname -r)" in
1132 # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;;
1133 # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;;
1134 # esac ;;
1135 AIX) # does not seem to show raw sockets in netstat
1136 sleep 1; return 0 ;;
1137 # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;;
1138 # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;;
1139 # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;;
1140 *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;;
1141 sleep 1; return 0 ;;
1142 esac
1143 [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1144 \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
1145 psleep $val_t
1146 timeout=$((timeout-1))
1147 done
1149 $ECHO "!protocol $proto timed out! \c" >&2
1150 return 1
1153 # we need this misleading function name for canonical reasons
1154 waitip4port () {
1155 waitip4proto "$1" "$2" "$3"
1158 # wait until an IP6 protocol is ready
1159 waitip6proto () {
1160 local proto="$1"
1161 local logic="$2" # 0..wait until free; 1..wait until listening
1162 local timeout="$3"
1163 local l
1164 [ "$logic" ] || logic=1
1165 [ "$timeout" ] || timeout=5
1166 while [ $timeout -gt 0 ]; do
1167 case "$UNAME" in
1168 Linux)
1169 if [ "$SS" ]; then
1170 l=$($SS -n -w -l |grep '^\(raw\|UNCONN\) .* \*:'$proto' [ ]*\*:\*')
1171 else
1172 l=$(netstat -n -w -l |grep '^raw[6 ] .* .*:[0-9*]*:'$proto' [ ]*:::\*')
1173 fi ;;
1174 # FreeBSD) l=$(netstat -an |egrep '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;;
1175 # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1176 # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1177 # Darwin) case "$(uname -r)" in
1178 # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;;
1179 # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;;
1180 # esac ;;
1181 AIX) # does not seem to show raw sockets in netstat
1182 sleep 1; return 0 ;;
1183 # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;;
1184 # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;;
1185 # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;;
1186 *) #l=$(netstat -an |egrep -i 'raw6? .*[0-9*][:.]'$proto' ') ;;
1187 sleep 1; return 0 ;;
1188 esac
1189 [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1190 \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
1191 psleep $val_t
1192 timeout=$((timeout-1))
1193 done
1195 $ECHO "!protocol $proto timed out! \c" >&2
1196 return 1
1199 # we need this misleading function name for canonical reasons
1200 waitip6port () {
1201 waitip6proto "$1" "$2" "$3"
1204 # Check if a TCP port is in use
1205 # exits with 0 when it is not used
1206 checktcpport () {
1207 local port="$1"
1208 local l
1209 case "$UNAME" in
1210 Linux) if [ "$SS" ]; then
1211 l=$($SS -a -n -t |grep ".*:$port\>")
1212 else
1213 l=$(netstat -a -n -t |grep '^tcp.* .*[0-9*]:'$port' .*')
1214 fi ;;
1215 FreeBSD) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .*') ;;
1216 NetBSD) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' [ ]* .* [ ]*.*') ;;
1217 Darwin) case "$(uname -r)" in
1218 [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .* .*') ;;
1219 *) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .* .*') ;;
1220 esac ;;
1221 AIX) l=$(netstat -an |grep '^tcp.* 0 0 .*[*0-9]\.'$port' .*') ;;
1222 SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;;
1223 HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .*') ;;
1224 OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;;
1225 CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .*') ;;
1226 DragonFly)l=$(netstat -ant |grep '^tcp.* .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1227 *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .*') ;;
1228 esac
1229 [ -z "$l" ] && return 0
1230 return 1
1233 checktcp4port () {
1234 checktcpport $1
1237 # wait until a TCP4 listen port is ready
1238 waittcp4port () {
1239 local port="$1"
1240 local logic="$2" # 0..wait until free; 1..wait until listening (default)
1241 local timeout="$3"
1242 local l
1243 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1244 [ "$logic" ] || logic=1
1245 [ "$timeout" ] || timeout=5
1246 while true; do
1247 case "$UNAME" in
1248 Linux) if [ "$SS" ]; then
1249 l=$($SS -l -n -t |grep "^LISTEN .*:$port\>")
1250 else
1251 l=$(netstat -a -n -t |grep '^tcp .* .*[0-9*]:'$port' .* LISTEN')
1252 fi ;;
1253 FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1254 NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1255 Darwin) case "$(uname -r)" in
1256 [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1257 *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1258 esac ;;
1259 AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1260 SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* .* 0 .* LISTEN') ;;
1261 HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;;
1262 OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
1263 CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;;
1264 DragonFly) l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1265 *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;;
1266 esac
1267 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1268 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1269 set ${vx}vx
1270 return 0
1272 if [ $timeout -le 0 ]; then
1273 set ${vx}vx
1274 return 1
1276 psleep $val_t
1277 timeout=$((timeout-1))
1278 done
1280 $ECHO "!port $port timed out! \c" >&2
1281 set ${vx}vx
1282 return 1
1285 # Check if a UDP4 port is in use
1286 # exits with 0 when it is not used
1287 checkudpport () {
1288 local port="$1"
1289 local l
1290 case "$UNAME" in
1291 Linux) if [ "$SS" ]; then
1292 l=$($SS -a -n -u |grep ".*:$port\>")
1293 else
1294 l=$(netstat -a -n -u |grep '^udp.* .*[0-9*]:'$port' .*')
1295 fi ;;
1296 FreeBSD) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1297 NetBSD) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*.*') ;;
1298 Darwin) case "$(uname -r)" in
1299 [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1300 *) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1301 esac ;;
1302 AIX) l=$(netstat -an |grep '^udp.* 0 0 .*[*0-9]\.'$port' .*') ;;
1303 SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;;
1304 HP-UX) l=$(netstat -an |grep '^udp.* 0 0 .*[0-9*]\.'$port' .*') ;;
1305 OSF1) l=$(/usr/sbin/netstat -an |grep '^udp.* 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;;
1306 CYGWIN*) l=$(netstat -an -p UDP |grep '^ UDP [0-9.]*:'$port' .*') ;;
1307 DragonFly)l=$(netstat -ant |grep '^udp.* .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1308 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' .*') ;;
1309 esac
1310 [ -z "$l" ] && return 0
1311 return 1
1314 checkudp4port () {
1315 checkudpport $1
1318 # wait until a UDP4 port is ready
1319 waitudp4port () {
1320 local port="$1"
1321 local logic="$2" # 0..wait until free; 1..wait until listening
1322 local timeout="$3"
1323 local l
1324 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1325 [ "$logic" ] || logic=1
1326 [ "$timeout" ] || timeout=5
1327 while [ $timeout -gt 0 ]; do
1328 case "$UNAME" in
1329 Linux) if [ "$SS" ]; then
1330 l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>")
1331 else
1332 l=$(netstat -a -n -u -l |grep '^udp .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*')
1333 fi ;;
1334 FreeBSD) l=$(netstat -an |egrep '^udp46? .*[0-9*]\.'$port' .* \*\.\*') ;;
1335 NetBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1336 OpenBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1337 Darwin) case "$(uname -r)" in
1338 [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;;
1339 *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1340 esac ;;
1341 AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1342 SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1343 HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;;
1344 OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1345 DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1346 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1347 esac
1348 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1349 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1350 set ${vx}vx
1351 return 0
1353 psleep $val_t
1354 timeout=$((timeout-1))
1355 done
1357 $ECHO "!port $port timed out! \c" >&2
1358 set ${vx}vx
1359 return 1
1362 # Check if a SCTP port is in use
1363 # exits with 0 when it is not used
1364 checksctpport () {
1365 local port="$1"
1366 local l
1367 case "$UNAME" in
1368 Linux) if [ "$SS" ]; then
1369 l=$($SS -a -n |grep "^sctp.*:$port\>")
1370 else
1371 l=$(netstat -a -n |grep '^sctp.* .*[0-9*]:'$port' .*')
1372 fi ;;
1373 FreeBSD) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1374 NetBSD) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*.*') ;;
1375 Darwin) case "$(uname -r)" in
1376 [1-5]*) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1377 *) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1378 esac ;;
1379 AIX) l=$(netstat -an |grep '^sctp.* 0 0 .*[*0-9]\.'$port' .*') ;;
1380 SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;;
1381 HP-UX) l=$(netstat -an |grep '^sctp 0 0 .*[0-9*]\.'$port' .*') ;;
1382 OSF1) l=$(/usr/sbin/netstat -an |grep '^sctp.* 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;;
1383 CYGWIN*) l=$(netstat -an -p SCTP |grep '^ SCTP [0-9.]*:'$port' .*') ;;
1384 DragonFly)l=$(netstat -ant |grep '^sctp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1385 *) l=$(netstat -an |grep -i 'sctp.*[0-9*][:.]'$port' .*') ;;
1386 esac
1387 [ -z "$l" ] && return 0
1388 return 1
1391 checksctp4port () {
1392 checksctpport $1
1395 # wait until an SCTP4 listen port is ready
1396 waitsctp4port () {
1397 local port="$1"
1398 local logic="$2" # 0..wait until free; 1..wait until listening
1399 local timeout="$3"
1400 local l
1401 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1402 [ "$logic" ] || logic=1
1403 [ "$timeout" ] || timeout=5
1404 while [ $timeout -gt 0 ]; do
1405 case "$UNAME" in
1406 Linux) if [ "$SS" ]; then
1407 l=$($SS -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>")
1408 else
1409 l=$(netstat -n -a |grep '^sctp .*[0-9*]:'$port' .* LISTEN')
1410 fi ;;
1411 # FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1412 # NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1413 # Darwin) case "$(uname -r)" in
1414 # [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1415 # *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1416 # esac ;;
1417 # AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1418 SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;;
1419 # HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;;
1420 # OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
1421 # CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;;
1422 *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;;
1423 esac
1424 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1425 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1426 set ${vx}vx
1427 return 0
1429 psleep $val_t
1430 timeout=$((timeout-1))
1431 done
1433 $ECHO "!port $port timed out! \c" >&2
1434 set ${vx}vx
1435 return 1
1438 # wait until a UDPLITE4 port is ready
1439 waitudplite4port () {
1440 local port="$1"
1441 local logic="$2" # 0..wait until free; 1..wait until listening
1442 local timeout="$3"
1443 local l
1444 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1445 [ "$logic" ] || logic=1
1446 [ "$timeout" ] || timeout=5
1447 while [ $timeout -gt 0 ]; do
1448 case "$UNAME" in
1449 Linux) #if [ "$SS" ]; then
1450 #l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>")
1451 #else
1452 if ! netstat -nU >/dev/null 2>&1; then
1453 return 0 # speculative
1455 l=$(netstat -a -n -U -l |grep '^udpl .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*')
1458 FreeBSD) l=$(netstat -an |egrep '^udpl46? .*[0-9*]\.'$port' .* \*\.\*') ;;
1459 NetBSD) l=$(netstat -an |grep '^udpl .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1460 OpenBSD) l=$(netstat -an |grep '^udpl .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1461 #Darwin) case "$(uname -r)" in
1462 # [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;;
1463 # *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1464 # esac ;;
1465 #AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1466 #SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1467 #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;;
1468 #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1469 #DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1470 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1471 esac
1472 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1473 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1474 set ${vx}vx
1475 return 0
1477 sleep 1
1478 timeout=$((timeout-1))
1479 done
1481 $ECHO "!port $port timed out! \c" >&2
1482 set ${vx}vx
1483 return 1
1486 # check if a TCP6 port is in use
1487 # exits with 0 when it is not used
1488 checktcp6port () {
1489 checktcpport $1
1492 # wait until a tcp6 listen port is ready
1493 waittcp6port () {
1494 local port="$1"
1495 local logic="$2" # 0..wait until free; 1..wait until listening
1496 local timeout="$3"
1497 local l
1498 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1499 [ "$logic" ] || logic=1
1500 [ "$timeout" ] || timeout=5
1501 while [ $timeout -gt 0 ]; do
1502 case "$UNAME" in
1503 Linux) if [ "$SS" ]; then
1504 l=$($SS -6 -n -t -l |grep "^LISTEN .*:$port\>")
1505 #l=$($SS -6 -n -t -l |grep "^tcp6* .*:$port\>")
1506 else
1507 l=$(netstat -an |grep -E '^tcp6? .* [0-9a-f:%]*:'$port' .* LISTEN')
1508 fi ;;
1509 FreeBSD) l=$(netstat -an |egrep -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;;
1510 NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1511 OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;;
1512 Darwin) l=$(netstat -an |egrep '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN') ;;
1513 AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1514 SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
1515 #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
1516 DragonFly) l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1517 *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;;
1518 esac
1519 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1520 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1521 set ${vx}vx
1522 return 0
1524 psleep $val_t
1525 timeout=$((timeout-1))
1526 done
1528 $ECHO "!port $port timed out! \c" >&2
1529 #echo set ${vx}vx >&2
1530 set ${vx}vx
1531 return 1
1534 # Check if a UDP6 port is in use
1535 # exits with 0 when it is not used
1536 checkudp6port () {
1537 checkudpport $1
1540 # wait until a UDP6 port is ready
1541 waitudp6port () {
1542 local port="$1"
1543 local logic="$2" # 0..wait until free; 1..wait until listening
1544 local timeout="$3"
1545 local l
1546 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1547 [ "$logic" ] || logic=1
1548 [ "$timeout" ] || timeout=5
1549 while [ $timeout -gt 0 ]; do
1550 case "$UNAME" in
1551 Linux) if [ "$SS" ]; then
1552 # CAUTION!!! ss from iproute2 4.15.0-2ubuntu on 18-04 changes
1553 # the output format when writing to pipe
1554 l=$($SS -6 -u -l -n |grep "^UNCONN.*:$port\>")
1555 else
1556 l=$(netstat -an |grep -E '^udp6? .* .*[0-9*:%]:'$port' [ ]*:::\*')
1557 fi ;;
1558 FreeBSD) l=$(netstat -an |egrep '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;;
1559 NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;;
1560 OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1561 Darwin) l=$(netstat -an |egrep '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;;
1562 AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1563 SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1564 #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;;
1565 #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1566 DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1567 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1568 esac
1569 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1570 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1571 set ${vx}vx
1572 return 0
1574 psleep $val_t
1575 timeout=$((timeout-1))
1576 done
1578 $ECHO "!port $port timed out! \c" >&2
1579 set ${vx}vx
1580 return 1
1583 # Check if a SCTP6 port is in use
1584 # exits with 0 when it is not used
1585 checksctp6port () {
1586 checksctpport $1
1589 # wait until a sctp6 listen port is ready
1590 # not all (Linux) variants show this in netstat
1591 waitsctp6port () {
1592 local port="$1"
1593 local logic="$2" # 0..wait until free; 1..wait until listening
1594 local timeout="$3"
1595 local l
1596 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1597 [ "$logic" ] || logic=1
1598 [ "$timeout" ] || timeout=5
1599 while [ $timeout -gt 0 ]; do
1600 case "$UNAME" in
1601 Linux) if [ "$SS" ]; then
1602 l=$($SS -6 -n 2>/dev/null |grep "^LISTEN .*:$port\>")
1603 else
1604 l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN')
1605 fi ;;
1606 # FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;;
1607 # NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1608 # OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;;
1609 # AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1610 SunOS) l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
1611 # #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
1612 *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
1613 esac
1614 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1615 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1616 set ${vx}vx
1617 return 0
1619 psleep $val_t
1620 timeout=$((timeout-1))
1621 done
1623 $ECHO "!port $port timed out! \c" >&2
1624 set ${vx}vx
1625 return 1
1628 # wait until a UDPLITE6 port is ready
1629 waitudplite6port () {
1630 local port="$1"
1631 local logic="$2" # 0..wait until free; 1..wait until listening
1632 local timeout="$3"
1633 local l
1634 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1635 [ "$logic" ] || logic=1
1636 [ "$timeout" ] || timeout=5
1637 while [ $timeout -gt 0 ]; do
1638 case "$UNAME" in
1639 Linux) #if [ "$SS" ]; then
1640 #l=$($SS -6 -u -l -n |grep "^UNCONN .*:$port\>")
1641 #else
1642 if ! netstat -nU >/dev/null 2>&1; then
1643 return 0 # speculative
1645 l=$(netstat -an |grep -E '^udpl6? .* .*[0-9*:%]:'$port' [ ]*:::\*')
1648 FreeBSD) l=$(netstat -an |egrep '^udpl(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;;
1649 NetBSD) l=$(netstat -an |grep '^udpl6 .* \*\.'$port' [ ]* \*\.\*') ;;
1650 OpenBSD) l=$(netstat -an |grep '^udpl6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1651 Darwin) l=$(netstat -an |egrep '^udpl4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;;
1652 #AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1653 #SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1654 #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;;
1655 #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1656 #DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1657 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1658 esac
1659 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1660 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1661 set ${vx}vx
1662 return 0
1664 sleep 1
1665 timeout=$((timeout-1))
1666 done
1668 $ECHO "!port $port timed out! \c" >&2
1669 set ${vx}vx
1670 return 1
1673 # we need this misleading function name for canonical reasons
1674 waitunixport () {
1675 waitfile "$1" "$2" "$3"
1678 # Not implemented
1679 waitabstractport () {
1680 relsleep 5
1683 # wait until a filesystem entry exists
1684 waitfile () {
1685 local crit=-e
1686 case "X$1" in X-*) crit="$1"; shift ;; esac
1687 local file="$1"
1688 local logic="$2" # 0..wait until gone; 1..wait until exists (default);
1689 # 2..wait until not empty
1690 local timeout="$3"
1691 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1692 [ "$logic" ] || logic=1
1693 [ "$logic" -eq 2 ] && crit=-s
1694 [ "$timeout" ] || timeout=5
1695 while [ $timeout -gt 0 ]; do
1696 if [ \( $logic -ne 0 -a $crit "$file" \) -o \
1697 \( $logic -eq 0 -a ! $crit "$file" \) ]; then
1698 set ${vx}vx
1699 return 0
1701 psleep $val_t
1702 timeout=$((timeout-1))
1703 done
1705 echo "file $file timed out" >&2
1706 set ${vx}vx
1707 return 1
1710 # system dependent values
1711 case "$UNAME" in
1712 SunOS) SOCK_SEQPACKET=6 ;;
1713 *) SOCK_SEQPACKET=5 ;;
1714 esac
1716 # generate a test certificate and key
1717 gentestcert () {
1718 local name="$1"
1719 if ! [ -f testcert.dh ]; then
1720 openssl dhparam -out testcert.dh $RSABITS
1722 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1723 openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1
1724 #openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 -extensions v3_ca >/dev/null 2>&1
1725 openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1
1726 cat $name.key $name.crt testcert.dh >$name.pem
1729 # generate a test DSA key and certificate
1730 gentestdsacert () {
1731 local name="$1"
1732 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1733 openssl dsaparam -out $name-dsa.pem $DSABITS >/dev/null 2>&1
1734 openssl dhparam -dsaparam -out $name-dh.pem $DSABITS >/dev/null 2>&1
1735 openssl req -newkey dsa:$name-dsa.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1
1736 cat $name-dsa.pem $name-dh.pem $name.key $name.crt >$name.pem
1739 # generate a test EC key and certificate
1740 gentesteccert () {
1741 local name="$1"
1742 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1743 openssl ecparam -name secp521r1 -out $name-ec.pem >/dev/null 2>&1
1744 chmod 0400 $name-ec.pem
1745 openssl req -newkey ec:$name-ec.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1
1746 cat $name-ec.pem $name.key $name.crt >$name.pem
1749 gentestcert6 () {
1750 local name="$1"
1751 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1752 cat $TESTCERT_CONF |
1753 { echo "# automatically generated by $0"; cat; } |
1754 sed 's/\(commonName\s*=\s*\).*/\1[::1]/' >$TESTCERT6_CONF
1755 openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1
1756 openssl req -new -config $TESTCERT6_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1
1757 cat $name.key $name.crt >$name.pem
1760 # generate a server certificate and key with SubjectAltName
1761 gentestaltcert () {
1762 local name="$1"
1763 if ! [ -f testcert.dh ]; then
1764 openssl dhparam -out testcert.dh $RSABITS
1766 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1767 openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1
1768 openssl req -new -config $TESTALT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1
1769 cat $name.key $name.crt testcert.dh >$name.pem
1772 #------------------------------------------------------------------------------
1773 # Begin of functional tests
1775 NAME=UNISTDIO
1776 case "$TESTS " in
1777 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1778 TEST="$NAME: unidirectional throughput from stdin to stdout"
1779 testecho "$N" "$TEST" "stdin" "stdout" "$opts -u"
1780 esac
1781 N=$((N+1))
1783 #------------------------------------------------------------------------------
1784 # Begin of common tests
1786 NAME=UNPIPESTDIO
1787 case "$TESTS" in
1788 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1789 TEST="$NAME: stdio with simple echo via internal pipe"
1790 testecho "$N" "$TEST" "stdio" "pipe" "$opts"
1791 esac
1792 N=$((N+1))
1795 NAME=UNPIPESHORT
1796 case "$TESTS" in
1797 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1798 TEST="$NAME: short form of stdio ('-') with simple echo via internal pipe"
1799 testecho "$N" "$TEST" "-" "pipe" "$opts"
1800 esac
1801 N=$((N+1))
1804 NAME=DUALSTDIO
1805 case "$TESTS" in
1806 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1807 TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe"
1808 testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts"
1809 esac
1810 N=$((N+1))
1813 NAME=DUALSHORTSTDIO
1814 case "$TESTS" in
1815 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1816 TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe"
1817 testecho "$N" "$TEST" "-!!-" "pipe" "$opts"
1818 esac
1819 N=$((N+1))
1822 NAME=DUALFDS
1823 case "$TESTS" in
1824 *%$N%*|*%functions%*|*%fd%*|*%$NAME%*)
1825 TEST="$NAME: file descriptors with simple echo via internal pipe"
1826 testecho "$N" "$TEST" "0!!1" "pipe" "$opts"
1827 esac
1828 N=$((N+1))
1831 NAME=NAMEDPIPE
1832 case "$TESTS" in
1833 *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*)
1834 TEST="$NAME: simple echo via named pipe"
1835 # with MacOS, this test hangs if nonblock is not used. Is an OS bug.
1836 tp="$td/pipe$N"
1837 # note: the nonblock is required by MacOS 10.1(?), otherwise it hangs (OS bug?)
1838 testecho "$N" "$TEST" "" "pipe:$tp,nonblock" "$opts"
1839 esac
1840 N=$((N+1))
1843 NAME=DUALPIPE
1844 case "$TESTS" in
1845 *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*)
1846 TEST="$NAME: simple echo via named pipe, specified twice"
1847 tp="$td/pipe$N"
1848 testecho "$N" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts"
1849 esac
1850 N=$((N+1))
1853 NAME=FILE
1854 case "$TESTS" in
1855 *%$N%*|*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*)
1856 TEST="$NAME: simple echo via file"
1857 tf="$td/file$N"
1858 testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts"
1859 esac
1860 N=$((N+1))
1863 NAME=EXECSOCKETPAIR
1864 case "$TESTS" in
1865 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*)
1866 TEST="$NAME: simple echo via exec of cat with socketpair"
1867 testecho "$N" "$TEST" "" "EXEC:$CAT" "$opts"
1868 esac
1869 N=$((N+1))
1871 NAME=SYSTEMSOCKETPAIR
1872 case "$TESTS" in
1873 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
1874 TEST="$NAME: simple echo via system() of cat with socketpair"
1875 testecho "$N" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t"
1876 esac
1877 N=$((N+1))
1880 NAME=EXECPIPES
1881 case "$TESTS" in
1882 *%$N%*|*%functions%*|*%exec%*|*%pipe%*|*%$NAME%*)
1883 TEST="$NAME: simple echo via exec of cat with pipes"
1884 testecho "$N" "$TEST" "" "EXEC:$CAT,pipes" "$opts"
1885 esac
1886 N=$((N+1))
1888 NAME=SYSTEMPIPES
1889 case "$TESTS" in
1890 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
1891 TEST="$NAME: simple echo via system() of cat with pipes"
1892 testecho "$N" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts"
1893 esac
1894 N=$((N+1))
1897 NAME=EXECPTY
1898 case "$TESTS" in
1899 *%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*)
1900 TEST="$NAME: simple echo via exec of cat with pseudo terminal"
1901 if ! eval $NUMCOND; then :;
1902 elif ! testfeats pty >/dev/null; then
1903 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
1904 numCANT=$((numCANT+1))
1905 listCANT="$listCANT $N"
1906 else
1907 testecho "$N" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
1909 esac
1910 N=$((N+1))
1912 NAME=SYSTEMPTY
1913 case "$TESTS" in
1914 *%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*)
1915 TEST="$NAME: simple echo via system() of cat with pseudo terminal"
1916 if ! eval $NUMCOND; then :;
1917 elif ! testfeats pty >/dev/null; then
1918 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
1919 numCANT=$((numCANT+1))
1920 listCANT="$listCANT $N"
1921 else
1922 testecho "$N" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
1924 esac
1925 N=$((N+1))
1928 NAME=SYSTEMPIPESFDS
1929 case "$TESTS" in
1930 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
1931 TEST="$NAME: simple echo via system() of cat with pipes, non stdio"
1932 testecho "$N" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts"
1933 esac
1934 N=$((N+1))
1937 NAME=DUALSYSTEMFDS
1938 case "$TESTS" in
1939 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
1940 TEST="$NAME: echo via dual system() of cat"
1941 testecho "$N" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t"
1942 esac
1943 N=$((N+1))
1946 # test: send EOF to exec'ed sub process, let it finish its operation, and
1947 # check if the sub process returns its data before terminating.
1948 NAME=EXECSOCKETPAIRFLUSH
1949 # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data
1950 # arrives.
1951 case "$TESTS" in
1952 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*)
1953 TEST="$NAME: call to od via exec with socketpair"
1954 testod "$N" "$TEST" "" "EXEC:$OD_C" "$opts"
1955 esac
1956 N=$((N+1))
1958 NAME=SYSTEMSOCKETPAIRFLUSH
1959 case "$TESTS" in
1960 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
1961 TEST="$NAME: call to od via system() with socketpair"
1962 testod "$N" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t
1963 esac
1964 N=$((N+1))
1967 NAME=EXECPIPESFLUSH
1968 case "$TESTS" in
1969 *%$N%*|*%functions%*|*%exec%*|*%pipes%*|*%$NAME%*)
1970 TEST="$NAME: call to od via EXEC with pipes"
1971 testod "$N" "$TEST" "" "EXEC:$OD_C,pipes" "$opts"
1972 esac
1973 N=$((N+1))
1975 NAME=SYSTEMPIPESFLUSH
1976 case "$TESTS" in
1977 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
1978 TEST="$NAME: call to od via system() with pipes"
1979 testod "$N" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t"
1980 esac
1981 N=$((N+1))
1984 ## LATER:
1985 #NAME=EXECPTYFLUSH
1986 #case "$TESTS" in
1987 #*%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*)
1988 #TEST="$NAME: call to od via exec with pseudo terminal"
1989 #if ! testfeats pty >/dev/null; then
1990 # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
1991 # numCANT=$((numCANT+1))
1992 # listCANT="$listCANT $N"
1993 #else
1994 #testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts"
1996 #esac
1997 #N=$((N+1))
2000 ## LATER:
2001 #NAME=SYSTEMPTYFLUSH
2002 #case "$TESTS" in
2003 #*%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*)
2004 #TEST="$NAME: call to od via system() with pseudo terminal"
2005 #if ! testfeats pty >/dev/null; then
2006 # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
2007 # numCANT=$((numCANT+1))
2008 # listCANT="$listCANT $N"
2009 #else
2010 #testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts"
2012 #esac
2013 #N=$((N+1))
2016 NAME=SYSTEMPIPESFDSFLUSH
2017 case "$TESTS" in
2018 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2019 TEST="$NAME: call to od via system() with pipes, non stdio"
2020 testod "$N" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t"
2021 esac
2022 N=$((N+1))
2024 NAME=DUALSYSTEMFDSFLUSH
2025 case "$TESTS" in
2026 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2027 TEST="$NAME: call to od via dual system()"
2028 testod "$N" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t"
2029 esac
2030 N=$((N+1))
2033 case "$UNAME" in
2034 Linux) IPPROTO=254 ;;
2035 Darwin) IPPROTO=255 ;;
2036 *) IPPROTO=254 ;; # just a guess
2037 esac
2039 NAME=RAWIP4SELF
2040 case "$TESTS" in
2041 *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*)
2042 TEST="$NAME: simple echo via self receiving raw IPv4 protocol"
2043 if ! eval $NUMCOND; then :;
2044 elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then
2045 $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
2046 numCANT=$((numCANT+1))
2047 listCANT="$listCANT $N"
2048 elif ! feat=$(testfeats rawip) >/dev/null; then
2049 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2050 numCANT=$((numCANT+1))
2051 listCANT="$listCANT $N"
2052 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2053 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2054 numCANT=$((numCANT+1))
2055 listCANT="$listCANT $N"
2056 else
2057 testecho "$N" "$TEST" "" "ip4:127.0.0.1:$IPPROTO" "$opts"
2059 esac
2060 N=$((N+1))
2062 NAME=RAWIPX4SELF
2063 case "$TESTS" in
2064 *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*)
2065 TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target"
2066 if ! eval $NUMCOND; then :;
2067 elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then
2068 $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
2069 numCANT=$((numCANT+1))
2070 listCANT="$listCANT $N"
2071 elif ! feat=$(testfeats rawip) >/dev/null; then
2072 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2073 numCANT=$((numCANT+1))
2074 listCANT="$listCANT $N"
2075 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2076 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2077 numCANT=$((numCANT+1))
2078 listCANT="$listCANT $N"
2079 else
2080 testecho "$N" "$TEST" "" "ip:127.0.0.1:$IPPROTO" "$opts"
2081 fi ;; # NUMCOND, feats
2082 esac
2083 N=$((N+1))
2085 NAME=RAWIP6SELF
2086 case "$TESTS" in
2087 *%$N%*|*%functions%*|*%ip6%*|*%rawip%*|*%root%*|*%$NAME%*)
2088 TEST="$NAME: simple echo via self receiving raw IPv6 protocol"
2089 if ! eval $NUMCOND; then :;
2090 elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then
2091 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2092 numCANT=$((numCANT+1))
2093 listCANT="$listCANT $N"
2094 elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then
2095 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2096 numCANT=$((numCANT+1))
2097 listCANT="$listCANT $N"
2098 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2099 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2100 numCANT=$((numCANT+1))
2101 listCANT="$listCANT $N"
2102 else
2103 testecho "$N" "$TEST" "" "ip6:[::1]:$IPPROTO" "$opts"
2104 fi ;; # NUMCOND, feats
2105 esac
2106 N=$((N+1))
2108 NAME=RAWIPX6SELF
2109 case "$TESTS" in
2110 *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%root%*|*%$NAME%*)
2111 TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target"
2112 if ! eval $NUMCOND; then :;
2113 elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then
2114 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2115 numCANT=$((numCANT+1))
2116 listCANT="$listCANT $N"
2117 elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then
2118 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2119 numCANT=$((numCANT+1))
2120 listCANT="$listCANT $N"
2121 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2122 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2123 numCANT=$((numCANT+1))
2124 listCANT="$listCANT $N"
2125 else
2126 testecho "$N" "$TEST" "" "ip:[::1]:$IPPROTO" "$opts"
2128 esac
2129 N=$((N+1))
2131 newport() {
2132 _PORT=$((_PORT+1))
2133 while eval wait${1}port $_PORT 1 0 2>/dev/null; do _PORT=$((_PORT+1)); done
2134 #echo "PORT=$_PORT" >&2
2135 PORT=$_PORT
2138 NAME=TCPSELF
2139 case "$TESTS" in
2140 *%$N%*|*%functions%*|*%$NAME%*)
2141 TEST="$NAME: echo via self connection of TCP IPv4 socket"
2142 if ! eval $NUMCOND; then :;
2143 elif [ "$UNAME" != Linux ]; then
2144 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N
2145 numCANT=$((numCANT+1))
2146 listCANT="$listCANT $N"
2147 else
2148 newport tcp4 # provide free port number in $PORT
2149 #ts="127.0.0.1:$tsl"
2150 testecho "$N" "$TEST" "" "tcp:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts"
2152 esac
2153 N=$((N+1))
2156 NAME=UDPSELF
2157 if ! eval $NUMCOND; then :; else
2158 case "$TESTS" in
2159 *%$N%*|*%functions%*|*%$NAME%*)
2160 TEST="$NAME: echo via self connection of UDP IPv4 socket"
2161 if [ "$UNAME" != Linux ]; then
2162 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N
2163 numCANT=$((numCANT+1))
2164 listCANT="$listCANT $N"
2165 else
2166 newport udp4 # provide free port number in $PORT
2167 testecho "$N" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts"
2169 esac
2170 fi # NUMCOND
2171 N=$((N+1))
2174 NAME=UDP6SELF
2175 case "$TESTS" in
2176 *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%$NAME%*)
2177 TEST="$NAME: echo via self connection of UDP IPv6 socket"
2178 if ! eval $NUMCOND; then :;
2179 elif [ "$UNAME" != Linux ]; then
2180 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
2181 numCANT=$((numCANT+1))
2182 listCANT="$listCANT $N"
2183 elif ! testfeats udp ip6 >/dev/null || ! runsudp6 >/dev/null; then
2184 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
2185 numCANT=$((numCANT+1))
2186 listCANT="$listCANT $N"
2187 else
2188 tf="$td/file$N"
2189 newport udp6 # provide free port number in $PORT
2190 testecho "$N" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts"
2192 esac
2193 N=$((N+1))
2196 NAME=DUALUDPSELF
2197 if ! eval $NUMCOND; then :; else
2198 case "$TESTS" in
2199 *%$N%*|*%functions%*|*%$NAME%*)
2200 TEST="$NAME: echo via two unidirectional UDP IPv4 sockets"
2201 tf="$td/file$N"
2202 newport udp4; PORT1=$PORT # get free port
2203 newport udp4; PORT2=$PORT # get free port
2204 testecho "$N" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts"
2205 esac
2206 fi # NUMCOND
2207 N=$((N+1))
2210 #function testdual {
2211 # local
2215 NAME=UNIXSTREAM
2216 if ! eval $NUMCOND; then :; else
2217 case "$TESTS" in
2218 *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*)
2219 TEST="$NAME: echo via connection to UNIX domain socket"
2220 tf="$td/test$N.stdout"
2221 te="$td/test$N.stderr"
2222 ts="$td/test$N.socket"
2223 tdiff="$td/test$N.diff"
2224 da="test$N $(date) $RANDOM"
2225 CMD1="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE"
2226 CMD2="$TRACE $SOCAT $opts -!!- UNIX-CONNECT:$ts"
2227 printf "test $F_n $TEST... " $N
2228 $CMD1 </dev/null >$tf 2>"${te}1" &
2229 bg=$! # background process id
2230 waitfile "$ts"
2231 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2232 rc2=$?
2233 if [ "$rc2" -ne 0 ]; then
2234 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2235 echo "$CMD1 &"
2236 cat "${te}1"
2237 echo "$CMD2"
2238 echo "rc=$rc2"
2239 cat "${te}2"
2240 numFAIL=$((numFAIL+1))
2241 listFAIL="$listFAIL $N"
2242 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2243 $PRINTF "$FAILED: diff:\n"
2244 cat "$tdiff"
2245 echo "$CMD1 &"
2246 cat "${te}1"
2247 echo "$CMD2"
2248 cat "${te}2"
2249 numFAIL=$((numFAIL+1))
2250 listFAIL="$listFAIL $N"
2251 else
2252 $PRINTF "$OK\n"
2253 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2254 numOK=$((numOK+1))
2256 kill $bg 2>/dev/null
2257 esac
2258 fi # NUMCOND
2259 N=$((N+1))
2262 NAME=TCP4
2263 case "$TESTS" in
2264 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2265 TEST="$NAME: echo via connection to TCP V4 socket"
2266 if ! eval $NUMCOND; then :
2267 elif ! cond=$(checkconds "" "" "" \
2268 "IP4 TCP LISTEN STDIO PIPE" \
2269 "TCP4-LISTEN PIPE STDIN STDOUT TCP4" \
2270 "so-reuseaddr" \
2271 "tcp4" ); then
2272 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
2273 numCANT=$((numCANT+1))
2274 listCANT="$listCANT $N"
2275 else
2276 tf="$td/test$N.stdout"
2277 te="$td/test$N.stderr"
2278 tdiff="$td/test$N.diff"
2279 newport tcp4; tsl=$PORT
2280 ts="127.0.0.1:$tsl"
2281 da="test$N $(date) $RANDOM"
2282 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE"
2283 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2284 printf "test $F_n $TEST... " $N
2285 $CMD1 >"$tf" 2>"${te}1" &
2286 pid1=$!
2287 waittcp4port $tsl 1
2288 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2289 if [ $? -ne 0 ]; then
2290 $PRINTF "$FAILED\n"
2291 echo "$CMD0 &"
2292 cat "${te}0" >&2
2293 echo "$CMD1"
2294 cat "${te}1" >&2
2295 numFAIL=$((numFAIL+1))
2296 listFAIL="$listFAIL $N"
2297 namesFAIL="$namesFAIL $NAME"
2298 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2299 $PRINTF "$FAILED\n"
2300 echo "$CMD0 &"
2301 cat "${te}0" >&2
2302 echo "$CMD1"
2303 cat "${te}1" >&2
2304 echo "// diff:" >&2
2305 cat "$tdiff" >&2
2306 numFAIL=$((numFAIL+1))
2307 listFAIL="$listFAIL $N"
2308 namesFAIL="$namesFAIL $NAME"
2309 else
2310 $PRINTF "$OK\n"
2311 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
2312 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
2313 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
2314 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2315 numOK=$((numOK+1))
2317 kill $pid1 2>/dev/null
2318 wait
2319 fi ;; # NUMCOND, checkconds
2320 esac
2321 N=$((N+1))
2324 #et -xv
2325 NAME=TCP6
2326 case "$TESTS" in
2327 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2328 TEST="$NAME: echo via connection to TCP V6 socket"
2329 if ! eval $NUMCOND; then :;
2330 elif ! F=$(testfeats IP6 TCP LISTEN STDIO PIPE); then
2331 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
2332 numCANT=$((numCANT+1))
2333 listCANT="$listCANT $N"
2334 elif ! A=$(testaddrs - TCP6-LISTEN PIPE STDIN STDOUT TCP6-CONNECT); then
2335 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
2336 numCANT=$((numCANT+1))
2337 listCANT="$listCANT $N"
2338 elif ! o=$(testoptions so-reuseaddr ) >/dev/null; then
2339 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
2340 numCANT=$((numCANT+1))
2341 listCANT="$listCANT $N"
2342 elif ! runsip6 >/dev/null; then
2343 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
2344 numCANT=$((numCANT+1))
2345 listCANT="$listCANT $N"
2346 else
2347 tf="$td/test$N.stdout"
2348 te="$td/test$N.stderr"
2349 tdiff="$td/test$N.diff"
2350 newport tcp6; tsl=$PORT
2351 ts="[::1]:$tsl"
2352 da="test$N $(date) $RANDOM"
2353 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE"
2354 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2355 printf "test $F_n $TEST... " $N
2356 $CMD1 >"$tf" 2>"${te}1" &
2357 pid=$! # background process id
2358 waittcp6port $tsl 1
2359 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2360 if [ $? -ne 0 ]; then
2361 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2362 echo "$CMD1 &"
2363 cat "${te}1" >&2
2364 echo "$CMD2"
2365 cat "${te}2" >&2
2366 numFAIL=$((numFAIL+1))
2367 listFAIL="$listFAIL $N"
2368 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2369 $PRINTF "$FAILED: diff:\n"
2370 echo "$CMD1 &"
2371 cat "${te}1" >&2
2372 echo "$CMD2"
2373 cat "${te}2" >&2
2374 echo diff:
2375 cat "$tdiff"
2376 numFAIL=$((numFAIL+1))
2377 listFAIL="$listFAIL $N"
2378 else
2379 $PRINTF "$OK\n"
2380 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
2381 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2382 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
2383 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
2384 numOK=$((numOK+1))
2386 kill $pid 2>/dev/null
2388 esac
2389 N=$((N+1))
2390 #set +vx
2393 # Test if TCP client with IPv4 address connects to IPv4 port
2394 NAME=TCPX4
2395 case "$TESTS" in
2396 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2397 TEST="$NAME: echo via connection to TCP socket, v4 by target"
2398 if ! eval $NUMCOND; then :;
2399 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
2400 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
2401 numCANT=$((numCANT+1))
2402 listCANT="$listCANT $N"
2403 elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
2404 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
2405 numCANT=$((numCANT+1))
2406 listCANT="$listCANT $N"
2407 elif ! o=$(testoptions pf) >/dev/null; then
2408 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
2409 numCANT=$((numCANT+1))
2410 listCANT="$listCANT $N"
2411 elif ! runsip4 >/dev/null; then
2412 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
2413 numCANT=$((numCANT+1))
2414 listCANT="$listCANT $N"
2415 else
2416 tf="$td/test$N.stdout"
2417 te="$td/test$N.stderr"
2418 tdiff="$td/test$N.diff"
2419 newport tcp4; tsl=$PORT
2420 ts="127.0.0.1:$tsl"
2421 da="test$N $(date) $RANDOM"
2422 CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE"
2423 CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
2424 printf "test $F_n $TEST... " $N
2425 $CMD0 >"$tf" 2>"${te}0" &
2426 pid=$! # background process id
2427 waittcp4port $tsl 1
2428 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
2429 if [ $? -ne 0 ]; then
2430 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2431 echo "$CMD0 &"
2432 cat "${te}0" >&2
2433 echo "$CMD1"
2434 cat "${te}1" >&2
2435 numFAIL=$((numFAIL+1))
2436 listFAIL="$listFAIL $N"
2437 namesFAIL="$namesFAIL $NAME"
2438 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2439 $PRINTF "$FAILED: diff:\n"
2440 cat "$tdiff"
2441 echo "$CMD0 &"
2442 cat "${te}0" >&2
2443 echo "$CMD1"
2444 cat "${te}1" >&2
2445 numFAIL=$((numFAIL+1))
2446 listFAIL="$listFAIL $N"
2447 namesFAIL="$namesFAIL $NAME"
2448 else
2449 $PRINTF "$OK\n"
2450 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
2451 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
2452 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
2453 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2454 numOK=$((numOK+1))
2456 kill $pid 2>/dev/null
2458 esac
2459 N=$((N+1))
2462 # Test if TCP client with IPv6 address connects to IPv6 port
2463 NAME=TCPX6
2464 case "$TESTS" in
2465 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2466 TEST="$NAME: echo via connection to TCP socket, v6 by target"
2467 if ! eval $NUMCOND; then :;
2468 elif ! F=$(testfeats STDIO PIPE IP6 TCP LISTEN); then
2469 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
2470 numCANT=$((numCANT+1))
2471 listCANT="$listCANT $N"
2472 elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
2473 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
2474 numCANT=$((numCANT+1))
2475 listCANT="$listCANT $N"
2476 elif ! o=$(testoptions pf) >/dev/null; then
2477 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
2478 numCANT=$((numCANT+1))
2479 listCANT="$listCANT $N"
2480 elif ! runsip6 >/dev/null; then
2481 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
2482 numCANT=$((numCANT+1))
2483 listCANT="$listCANT $N"
2484 else
2485 tf="$td/test$N.stdout"
2486 te="$td/test$N.stderr"
2487 tdiff="$td/test$N.diff"
2488 newport tcp6; tsl=$PORT
2489 ts="[::1]:$tsl"
2490 da="test$N $(date) $RANDOM"
2491 CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE"
2492 CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
2493 printf "test $F_n $TEST... " $N
2494 $CMD0 >"$tf" 2>"${te}0" &
2495 pid=$! # background process id
2496 waittcp6port $tsl 1
2497 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
2498 if [ $? -ne 0 ]; then
2499 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2500 echo "$CMD0 &"
2501 cat "${te}0" >&2
2502 echo "$CMD1"
2503 cat "${te}1" >&2
2504 numFAIL=$((numFAIL+1))
2505 listFAIL="$listFAIL $N"
2506 namesFAIL="$namesFAIL $NAME"
2507 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2508 $PRINTF "$FAILED: diff:\n"
2509 cat "$tdiff"
2510 echo "$CMD0 &"
2511 cat "${te}0" >&2
2512 echo "$CMD1"
2513 cat "${te}1" >&2
2514 numFAIL=$((numFAIL+1))
2515 listFAIL="$listFAIL $N"
2516 namesFAIL="$namesFAIL $NAME"
2517 else
2518 $PRINTF "$OK\n"
2519 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
2520 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
2521 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
2522 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2523 numOK=$((numOK+1))
2525 kill $pid 2>/dev/null
2527 esac
2528 N=$((N+1))
2530 # TCP6-LISTEN may also listen for IPv4 connections. Test if option
2531 # ipv6-v6only=0 shows this behaviour.
2532 # On OpenBSD-7.2 ipv6-v6only=0 gives "Invalid argument"
2533 NAME=IPV6ONLY0
2534 case "$TESTS" in
2535 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2536 TEST="$NAME: option ipv6-v6only=0 listens on IPv4"
2537 # create a listening TCP6 socket and try to connect to the port using TCP4
2538 if ! eval $NUMCOND; then :;
2539 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2540 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2541 numCANT=$((numCANT+1))
2542 listCANT="$listCANT $N"
2543 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2544 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
2545 numCANT=$((numCANT+1))
2546 listCANT="$listCANT $N"
2547 elif ! feat=$(testoptions ipv6-v6only); then
2548 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2549 numCANT=$((numCANT+1))
2550 listCANT="$listCANT $N"
2551 else
2552 tf="$td/test$N.stdout"
2553 te="$td/test$N.stderr"
2554 tdiff="$td/test$N.diff"
2555 newport tcp6; tsl=$PORT
2556 ts="127.0.0.1:$tsl"
2557 da="test$N $(date) $RANDOM"
2558 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=0,$REUSEADDR PIPE"
2559 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2560 printf "test $F_n $TEST... " $N
2561 $CMD1 >"$tf" 2>"${te}1" &
2562 pid=$! # background process id
2563 waittcp6port $tsl 1
2564 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2565 if [ $? -ne 0 ]; then
2566 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2567 echo "$CMD1 &"
2568 echo "$CMD2"
2569 cat "${te}1" "${te}2"
2570 numFAIL=$((numFAIL+1))
2571 listFAIL="$listFAIL $N"
2572 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2573 $PRINTF "$FAILED: diff:\n"
2574 cat "$tdiff"
2575 numFAIL=$((numFAIL+1))
2576 listFAIL="$listFAIL $N"
2577 else
2578 $PRINTF "$OK\n"
2579 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2580 numOK=$((numOK+1))
2582 kill $pid 2>/dev/null
2584 esac
2585 N=$((N+1))
2587 #set -vx
2588 # TCP6-LISTEN may also listen for IPv4 connections. Test if option
2589 # ipv6-v6only=1 turns off this behaviour.
2590 NAME=IPV6ONLY1
2591 case "$TESTS" in
2592 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2593 TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4"
2594 if ! eval $NUMCOND; then :;
2595 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2596 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2597 numCANT=$((numCANT+1))
2598 listCANT="$listCANT $N"
2599 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2600 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2601 numCANT=$((numCANT+1))
2602 listCANT="$listCANT $N"
2603 elif ! feat=$(testoptions ipv6-v6only); then
2604 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2605 numCANT=$((numCANT+1))
2606 listCANT="$listCANT $N"
2607 else
2608 tf="$td/test$N.stdout"
2609 te="$td/test$N.stderr"
2610 tdiff="$td/test$N.diff"
2611 newport tcp6; tsl=$PORT
2612 ts="127.0.0.1:$tsl"
2613 da="test$N $(date) $RANDOM"
2614 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=1,$REUSEADDR PIPE"
2615 CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
2616 printf "test $F_n $TEST... " $N
2617 $CMD1 >"$tf" 2>"${te}1" &
2618 pid=$! # background process id
2619 waittcp6port $tsl 1
2620 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2621 if [ $? -eq 0 ]; then
2622 $PRINTF "$FAILED:\n"
2623 cat "${te}1" "${te}2"
2624 numFAIL=$((numFAIL+1))
2625 listFAIL="$listFAIL $N"
2626 elif echo "$da" |diff - "$tf" >"$tdiff"; then
2627 $PRINTF "$FAILED:\n"
2628 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2629 numFAIL=$((numFAIL+1))
2630 listFAIL="$listFAIL $N"
2631 else
2632 $PRINTF "$OK\n"
2633 numOK=$((numOK+1))
2635 kill $pid; wait
2636 wait
2638 esac
2639 N=$((N+1))
2640 #set +vx
2642 NAME=ENV_LISTEN_4
2643 case "$TESTS" in
2644 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2645 TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen"
2646 if ! eval $NUMCOND; then :;
2647 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2648 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2649 numCANT=$((numCANT+1))
2650 listCANT="$listCANT $N"
2651 elif ! testfeats ip6 >/dev/null || ! runstcp6 >/dev/null; then
2652 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
2653 numCANT=$((numCANT+1))
2654 listCANT="$listCANT $N"
2655 elif ! feat=$(testoptions ipv6-v6only); then
2656 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2657 numCANT=$((numCANT+1))
2658 listCANT="$listCANT $N"
2659 else
2660 tf="$td/test$N.stdout"
2661 te="$td/test$N.stderr"
2662 tdiff="$td/test$N.diff"
2663 newport tcp4; tsl=$PORT
2664 ts="127.0.0.1:$tsl"
2665 da="test$N $(date) $RANDOM"
2666 CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2667 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2668 printf "test $F_n $TEST... " $N
2669 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
2670 pid=$! # background process id
2671 waittcp4port $tsl 1
2672 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2673 if [ $? -ne 0 ]; then
2674 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2675 echo "$CMD1 &"
2676 echo "$CMD2"
2677 cat "${te}1" "${te}2"
2678 numFAIL=$((numFAIL+1))
2679 listFAIL="$listFAIL $N"
2680 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2681 $PRINTF "$FAILED: diff:\n"
2682 cat "$tdiff"
2683 numFAIL=$((numFAIL+1))
2684 listFAIL="$listFAIL $N"
2685 else
2686 $PRINTF "$OK\n"
2687 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2688 numOK=$((numOK+1))
2690 kill $pid 2>/dev/null; wait
2692 esac
2693 N=$((N+1))
2695 NAME=ENV_LISTEN_6
2696 case "$TESTS" in
2697 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2698 TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen"
2699 if ! eval $NUMCOND; then :;
2700 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2701 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2702 numCANT=$((numCANT+1))
2703 listCANT="$listCANT $N"
2704 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2705 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2706 numCANT=$((numCANT+1))
2707 listCANT="$listCANT $N"
2708 else
2709 tf="$td/test$N.stdout"
2710 te="$td/test$N.stderr"
2711 tdiff="$td/test$N.diff"
2712 newport tcp6; tsl=$PORT
2713 ts="[::1]:$tsl"
2714 da="test$N $(date) $RANDOM"
2715 CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2716 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2717 printf "test $F_n $TEST... " $N
2718 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
2719 pid=$! # background process id
2720 waittcp6port $tsl 1
2721 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2722 if [ $? -ne 0 ]; then
2723 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2724 echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &"
2725 cat "${te}1" >&2
2726 echo "$CMD2"
2727 cat "${te}2" >&2
2728 numFAIL=$((numFAIL+1))
2729 listFAIL="$listFAIL $N"
2730 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2731 $PRINTF "$FAILED (diff):\n"
2732 echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &"
2733 cat "${te}1" >&2
2734 echo "$CMD2"
2735 cat "${te}2" >&2
2736 echo "// diff:" >&2
2737 cat "$tdiff" >&2
2738 numFAIL=$((numFAIL+1))
2739 listFAIL="$listFAIL $N"
2740 else
2741 $PRINTF "$OK\n"
2742 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
2743 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2744 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
2745 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
2746 numOK=$((numOK+1))
2748 kill $pid 2>/dev/null; wait
2750 esac
2751 N=$((N+1))
2753 NAME=LISTEN_OPTION_4
2754 case "$TESTS" in
2755 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2756 TEST="$NAME: option -4 for IPv4 preference on listen"
2757 if ! eval $NUMCOND; then :;
2758 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2759 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2760 numCANT=$((numCANT+1))
2761 listCANT="$listCANT $N"
2762 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2763 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2764 numCANT=$((numCANT+1))
2765 listCANT="$listCANT $N"
2766 elif ! feat=$(testoptions ipv6-v6only); then
2767 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2768 numCANT=$((numCANT+1))
2769 listCANT="$listCANT $N"
2770 else
2771 tf="$td/test$N.stdout"
2772 te="$td/test$N.stderr"
2773 tdiff="$td/test$N.diff"
2774 newport tcp4; tsl=$PORT
2775 ts="127.0.0.1:$tsl"
2776 da="test$N $(date) $RANDOM"
2777 CMD1="$TRACE $SOCAT $opts -4 TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2778 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2779 printf "test $F_n $TEST... " $N
2780 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
2781 pid=$! # background process id
2782 waittcp4port $tsl 1
2783 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2784 if [ $? -ne 0 ]; then
2785 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2786 echo "$CMD1 &"
2787 echo "$CMD2"
2788 cat "${te}1" "${te}2"
2789 numFAIL=$((numFAIL+1))
2790 listFAIL="$listFAIL $N"
2791 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2792 $PRINTF "$FAILED: diff:\n"
2793 cat "$tdiff"
2794 numFAIL=$((numFAIL+1))
2795 listFAIL="$listFAIL $N"
2796 else
2797 $PRINTF "$OK\n"
2798 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2799 numOK=$((numOK+1))
2801 kill $pid 2>/dev/null; wait
2803 esac
2804 N=$((N+1))
2806 NAME=LISTEN_OPTION_6
2807 case "$TESTS" in
2808 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2809 TEST="$NAME: option -6 for IPv6 preference on listen"
2810 if ! eval $NUMCOND; then :;
2811 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2812 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2813 numCANT=$((numCANT+1))
2814 listCANT="$listCANT $N"
2815 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2816 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2817 numCANT=$((numCANT+1))
2818 listCANT="$listCANT $N"
2819 else
2820 tf="$td/test$N.stdout"
2821 te="$td/test$N.stderr"
2822 tdiff="$td/test$N.diff"
2823 newport tcp6; tsl=$PORT
2824 ts="[::1]:$tsl"
2825 da="test$N $(date) $RANDOM"
2826 CMD1="$TRACE $SOCAT $opts -6 TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2827 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2828 printf "test $F_n $TEST... " $N
2829 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
2830 pid=$! # background process id
2831 waittcp6port $tsl 1
2832 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2833 if [ $? -ne 0 ]; then
2834 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2835 echo "$CMD1 &"
2836 echo "$CMD2"
2837 cat "${te}1" "${te}2"
2838 numFAIL=$((numFAIL+1))
2839 listFAIL="$listFAIL $N"
2840 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2841 $PRINTF "$FAILED: diff:\n"
2842 cat "$tdiff"
2843 numFAIL=$((numFAIL+1))
2844 listFAIL="$listFAIL $N"
2845 else
2846 $PRINTF "$OK\n"
2847 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2848 numOK=$((numOK+1))
2850 kill $pid 2>/dev/null; wait
2851 wait
2852 fi # feats
2853 esac
2854 N=$((N+1))
2856 NAME=LISTEN_PF_IP4
2857 case "$TESTS" in
2858 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2859 TEST="$NAME: pf=4 overrides option -6 on listen"
2860 if ! eval $NUMCOND; then :;
2861 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2862 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2863 numCANT=$((numCANT+1))
2864 listCANT="$listCANT $N"
2865 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2866 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2867 numCANT=$((numCANT+1))
2868 listCANT="$listCANT $N"
2869 elif ! feat=$(testoptions ipv6-v6only); then
2870 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2871 numCANT=$((numCANT+1))
2872 listCANT="$listCANT $N"
2873 else
2874 tf="$td/test$N.stdout"
2875 te="$td/test$N.stderr"
2876 tdiff="$td/test$N.diff"
2877 newport tcp4; tsl=$PORT
2878 ts="127.0.0.1:$tsl"
2879 da="test$N $(date) $RANDOM"
2880 CMD1="$TRACE $SOCAT $opts -6 TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE"
2881 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2882 printf "test $F_n $TEST... " $N
2883 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
2884 pid=$! # background process id
2885 waittcp4port $tsl 1
2886 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2887 if [ $? -ne 0 ]; then
2888 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2889 echo "$CMD1 &"
2890 echo "$CMD2"
2891 cat "${te}1" "${te}2"
2892 numFAIL=$((numFAIL+1))
2893 listFAIL="$listFAIL $N"
2894 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2895 $PRINTF "$FAILED: diff:\n"
2896 cat "$tdiff"
2897 numFAIL=$((numFAIL+1))
2898 listFAIL="$listFAIL $N"
2899 else
2900 $PRINTF "$OK\n"
2901 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2902 numOK=$((numOK+1))
2904 kill $pid 2>/dev/null; wait
2906 esac
2907 N=$((N+1))
2909 NAME=LISTEN_PF_IP6
2910 case "$TESTS" in
2911 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2912 TEST="$NAME: pf=6 overrides option -4 on listen"
2913 if ! eval $NUMCOND; then :;
2914 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2915 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2916 numCANT=$((numCANT+1))
2917 listCANT="$listCANT $N"
2918 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2919 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2920 numCANT=$((numCANT+1))
2921 listCANT="$listCANT $N"
2922 else
2923 tf="$td/test$N.stdout"
2924 te="$td/test$N.stderr"
2925 tdiff="$td/test$N.diff"
2926 newport tcp6; tsl=$PORT
2927 ts="[::1]:$tsl"
2928 da="test$N $(date) $RANDOM"
2929 CMD1="$TRACE $SOCAT $opts -4 TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE"
2930 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2931 printf "test $F_n $TEST... " $N
2932 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
2933 pid=$! # background process id
2934 waittcp6port $tsl 1
2935 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2936 if [ $? -ne 0 ]; then
2937 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2938 echo "$CMD1 &"
2939 echo "$CMD2"
2940 cat "${te}1" "${te}2"
2941 numFAIL=$((numFAIL+1))
2942 listFAIL="$listFAIL $N"
2943 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2944 $PRINTF "$FAILED: diff:\n"
2945 cat "$tdiff"
2946 numFAIL=$((numFAIL+1))
2947 listFAIL="$listFAIL $N"
2948 else
2949 $PRINTF "$OK\n"
2950 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2951 numOK=$((numOK+1))
2953 kill $pid 2>/dev/null; wait
2954 fi ;; # NUMCOND, feats
2955 esac
2956 N=$((N+1))
2959 NAME=UDP4STREAM
2960 case "$TESTS" in
2961 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%listen%*|*%$NAME%*)
2962 TEST="$NAME: echo via connection to UDP V4 socket"
2963 if ! eval $NUMCOND; then :; else
2964 tf="$td/test$N.stdout"
2965 te="$td/test$N.stderr"
2966 tdiff="$td/test$N.diff"
2967 newport udp4; tsl=$PORT
2968 ts="$LOCALHOST:$tsl"
2969 da="test$N $(date) $RANDOM"
2970 CMD1="$TRACE $SOCAT $opts UDP4-LISTEN:$tsl,$REUSEADDR PIPE"
2971 CMD2="$TRACE $SOCAT $opts - UDP4:$ts"
2972 printf "test $F_n $TEST... " $N
2973 $CMD1 >"$tf" 2>"${te}1" &
2974 pid1=$!
2975 waitudp4port $tsl 1
2976 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2977 rc2=$?
2978 kill $pid1 2>/dev/null; wait
2979 if [ $rc2 -ne 0 ]; then
2980 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2981 echo "$CMD1 &"
2982 echo "$CMD2"
2983 cat "${te}1" "${te}2"
2984 numFAIL=$((numFAIL+1))
2985 listFAIL="$listFAIL $N"
2986 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2987 $PRINTF "$FAILED\n"
2988 echo "$CMD1 &"
2989 cat "${te}1"
2990 echo "$CMD2"
2991 cat "${te}2"
2992 cat "$tdiff"
2993 numFAIL=$((numFAIL+1))
2994 listFAIL="$listFAIL $N"
2995 else
2996 $PRINTF "$OK\n"
2997 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2998 numOK=$((numOK+1))
3000 fi ;; # NUMCOND
3001 esac
3002 N=$((N+1))
3005 NAME=UDP6STREAM
3006 case "$TESTS" in
3007 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udp%*|*%listen%*|*%$NAME%*)
3008 TEST="$NAME: echo via connection to UDP V6 socket"
3009 if ! eval $NUMCOND; then :;
3010 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
3011 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
3012 numCANT=$((numCANT+1))
3013 listCANT="$listCANT $N"
3014 else
3015 tf="$td/test$N.stdout"
3016 te="$td/test$N.stderr"
3017 tdiff="$td/test$N.diff"
3018 newport udp6; tsl=$PORT
3019 ts="$LOCALHOST6:$tsl"
3020 da="test$N $(date) $RANDOM"
3021 CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,$REUSEADDR PIPE"
3022 CMD2="$TRACE $SOCAT $opts - UDP6:$ts"
3023 printf "test $F_n $TEST... " $N
3024 $CMD1 >"$tf" 2>"${te}1" &
3025 pid1=$!
3026 waitudp6port $tsl 1
3027 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
3028 rc2=$?
3029 kill $pid1 2>/dev/null; wait
3030 if [ $rc2 -ne 0 ]; then
3031 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3032 echo "$CMD1 &"
3033 echo "$CMD2"
3034 cat "${te}1" "${te}2"
3035 numFAIL=$((numFAIL+1))
3036 listFAIL="$listFAIL $N"
3037 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
3038 $PRINTF "$FAILED\n"
3039 cat "$tdiff"
3040 numFAIL=$((numFAIL+1))
3041 listFAIL="$listFAIL $N"
3042 else
3043 $PRINTF "$OK\n"
3044 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3045 numOK=$((numOK+1))
3047 fi ;; # ! testfeats
3048 esac
3049 N=$((N+1))
3052 NAME=GOPENFILE
3053 case "$TESTS" in
3054 *%$N%*|*%functions%*|*%engine%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*)
3055 TEST="$NAME: file opening with gopen"
3056 if ! eval $NUMCOND; then :; else
3057 tf1="$td/test$N.1.stdout"
3058 tf2="$td/test$N.2.stdout"
3059 te="$td/test$N.stderr"
3060 tdiff="$td/test$N.diff"
3061 da="test$N $(date) $RANDOM"
3062 echo "$da" >$tf1
3063 CMD="$TRACE $SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-"
3064 printf "test $F_n $TEST... " $N
3065 $CMD >"$tf2" 2>"$te"
3066 if [ $? -ne 0 ]; then
3067 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3068 echo "$CMD"
3069 cat "$te"
3070 numFAIL=$((numFAIL+1))
3071 listFAIL="$listFAIL $N"
3072 elif ! diff "$tf1" "$tf2" >"$tdiff"; then
3073 $PRINTF "$FAILED: diff:\n"
3074 cat "$tdiff"
3075 numFAIL=$((numFAIL+1))
3076 listFAIL="$listFAIL $N"
3077 else
3078 $PRINTF "$OK\n"
3079 if [ -n "$debug" ]; then cat $te; fi
3080 numOK=$((numOK+1))
3082 fi # NUMCOND
3083 esac
3084 N=$((N+1))
3087 NAME=GOPENPIPE
3088 case "$TESTS" in
3089 *%$N%*|*%functions%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*)
3090 TEST="$NAME: pipe opening with gopen for reading"
3091 if ! eval $NUMCOND; then :; else
3092 tp="$td/pipe$N"
3093 tf="$td/test$N.stdout"
3094 te="$td/test$N.stderr"
3095 tdiff="$td/test$N.diff"
3096 da="test$N $(date) $RANDOM"
3097 CMD="$TRACE $SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf"
3098 printf "test $F_n $TEST... " $N
3099 #mknod $tp p # no mknod p on FreeBSD
3100 mkfifo $tp
3101 $CMD >$tf 2>"$te" &
3102 #($CMD >$tf 2>"$te" || rm -f "$tp") 2>/dev/null &
3103 bg=$! # background process id
3104 usleep $MICROS
3105 if [ ! -p "$tp" ]; then
3106 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3107 echo "$CMD"
3108 cat "$te"
3109 numFAIL=$((numFAIL+1))
3110 listFAIL="$listFAIL $N"
3111 else
3112 #echo "$da" >"$tp" # might hang forever
3113 echo "$da" >"$tp" & export pid=$!; (sleep 1; kill $pid 2>/dev/null) &
3114 # Solaris needs more time:
3115 sleep 1
3116 kill "$bg" 2>/dev/null; wait
3117 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3118 if [ -s "$te" ]; then
3119 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3120 echo "$CMD"
3121 cat "$te"
3122 else
3123 $PRINTF "$FAILED: diff:\n"
3124 cat "$tdiff"
3126 numFAIL=$((numFAIL+1))
3127 listFAIL="$listFAIL $N"
3128 else
3129 $PRINTF "$OK\n"
3130 if [ -n "$debug" ]; then cat $te; fi
3131 numOK=$((numOK+1))
3134 wait
3135 fi # NUMCOND
3136 esac
3137 N=$((N+1))
3140 NAME=GOPENUNIXSTREAM
3141 case "$TESTS" in
3142 *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%$NAME%*)
3143 TEST="$NAME: GOPEN on UNIX stream socket"
3144 if ! eval $NUMCOND; then :; else
3145 ts="$td/test$N.socket"
3146 tf="$td/test$N.stdout"
3147 te="$td/test$N.stderr"
3148 tdiff="$td/test$N.diff"
3149 da1="test$N $(date) $RANDOM"
3150 #establish a listening unix socket in background
3151 SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
3152 #make a connection
3153 CMD="$TRACE $SOCAT $opts - $ts"
3154 $PRINTF "test $F_n $TEST... " $N
3155 eval "$SRV 2>${te}s &"
3156 pids=$!
3157 waitfile "$ts"
3158 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
3159 if [ $? -ne 0 ]; then
3160 kill "$pids" 2>/dev/null
3161 $PRINTF "$FAILED:\n"
3162 echo "$SRV &"
3163 cat "${te}s"
3164 echo "$CMD"
3165 cat "${te}1"
3166 numFAIL=$((numFAIL+1))
3167 listFAIL="$listFAIL $N"
3168 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
3169 kill "$pids" 2>/dev/null
3170 $PRINTF "$FAILED:\n"
3171 echo "$SRV &"
3172 cat "${te}s"
3173 echo "$CMD"
3174 cat "${te}1"
3175 cat "$tdiff"
3176 numFAIL=$((numFAIL+1))
3177 listFAIL="$listFAIL $N"
3178 else
3179 $PRINTF "$OK\n"
3180 if [ -n "$debug" ]; then cat $te; fi
3181 numOK=$((numOK+1))
3182 fi # !(rc -ne 0)
3183 wait
3184 fi # NUMCOND
3185 esac
3186 N=$((N+1))
3188 NAME=GOPENUNIXSEQPACKET
3189 case "$TESTS" in
3190 *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%seqpacket%*|*%$NAME%*)
3191 TEST="$NAME: GOPEN on UNIX seqpacket socket"
3192 if ! eval $NUMCOND; then :; else
3193 ts="$td/test$N.socket"
3194 tf="$td/test$N.stdout"
3195 te="$td/test$N.stderr"
3196 tdiff="$td/test$N.diff"
3197 da1="test$N $(date) $RANDOM"
3198 #establish a listening unix socket in background
3199 SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\",so-type=$SOCK_SEQPACKET PIPE"
3200 #make a connection
3201 CMD="$TRACE $SOCAT $opts - $ts"
3202 $PRINTF "test $F_n $TEST... " $N
3203 eval "$SRV 2>${te}s &"
3204 pids=$!
3205 waitfile "$ts"
3206 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
3207 if [ $? -ne 0 ]; then
3208 kill "$pids" 2>/dev/null
3209 $PRINTF "$FAILED:\n"
3210 echo "$SRV &"
3211 cat "${te}s"
3212 echo "$CMD"
3213 cat "${te}1"
3214 numFAIL=$((numFAIL+1))
3215 listFAIL="$listFAIL $N"
3216 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
3217 kill "$pids" 2>/dev/null
3218 $PRINTF "$FAILED:\n"
3219 echo "$SRV &"
3220 cat "${te}s"
3221 echo "$CMD"
3222 cat "${te}1"
3223 cat "$tdiff"
3224 numFAIL=$((numFAIL+1))
3225 listFAIL="$listFAIL $N"
3226 else
3227 $PRINTF "$OK\n"
3228 if [ -n "$debug" ]; then cat $te; fi
3229 numOK=$((numOK+1))
3230 fi # !(rc -ne 0)
3231 wait
3232 fi # NUMCOND
3233 esac
3234 N=$((N+1))
3237 NAME=GOPENUNIXDGRAM
3238 case "$TESTS" in
3239 *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%dgram%*|*%$NAME%*)
3240 TEST="$NAME: GOPEN on UNIX datagram socket"
3241 if ! eval $NUMCOND; then :; else
3242 ts="$td/test$N.socket"
3243 tf="$td/test$N.stdout"
3244 te="$td/test$N.stderr"
3245 tdiff="$td/test$N.diff"
3246 da1="test$N $(date) $RANDOM"
3247 #establish a receiving unix socket in background
3248 SRV="$TRACE $SOCAT $opts -u -lpserver UNIX-RECV:\"$ts\" file:\"$tf\",create"
3249 #make a connection
3250 CMD="$TRACE $SOCAT $opts -u - $ts"
3251 $PRINTF "test $F_n $TEST... " $N
3252 eval "$SRV 2>${te}s &"
3253 pids=$!
3254 waitfile "$ts"
3255 echo "$da1" |eval "$CMD" 2>"${te}1"
3256 waitfile -s "$tf"
3257 if [ $? -ne 0 ]; then
3258 $PRINTF "$FAILED:\n"
3259 echo "$SRV &"
3260 cat "${te}s"
3261 echo "$CMD"
3262 cat "${te}1"
3263 numFAIL=$((numFAIL+1))
3264 listFAIL="$listFAIL $N"
3265 elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then
3266 $PRINTF "$FAILED:\n"
3267 echo "$SRV &"
3268 cat "${te}s"
3269 echo "$CMD"
3270 cat "${te}1"
3271 cat "$tdiff"
3272 numFAIL=$((numFAIL+1))
3273 listFAIL="$listFAIL $N"
3274 else
3275 $PRINTF "$OK\n"
3276 if [ -n "$debug" ]; then cat $te; fi
3277 numOK=$((numOK+1))
3278 fi # !(rc -ne 0)
3279 kill "$pids" 2>/dev/null; wait
3280 fi ;; # NUMCOND
3281 esac
3282 N=$((N+1))
3285 NAME=IGNOREEOF
3286 case "$TESTS" in
3287 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
3288 TEST="$NAME: ignoreeof on file"
3289 if ! eval $NUMCOND; then :; else
3290 ti="$td/test$N.file"
3291 tf="$td/test$N.stdout"
3292 te="$td/test$N.stderr"
3293 tdiff="$td/test$N.diff"
3294 da="test$N $(date) $RANDOM"
3295 CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -"
3296 printf "test $F_n $TEST... " $N
3297 touch "$ti"
3298 $CMD >"$tf" 2>"$te" &
3299 bg=$!
3300 usleep 500000
3301 echo "$da" >>"$ti"
3302 sleep 1
3303 kill $bg 2>/dev/null; wait
3304 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3305 $PRINTF "$FAILED: diff:\n"
3306 cat "$tdiff"
3307 listFAIL="$listFAIL $N"
3308 numFAIL=$((numFAIL+1))
3309 else
3310 $PRINTF "$OK\n"
3311 if [ -n "$debug" ]; then cat $te; fi
3312 numOK=$((numOK+1))
3314 fi ;; # NUMCOND
3315 esac
3316 N=$((N+1))
3318 NAME=IGNOREEOF_REV
3319 case "$TESTS" in
3320 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
3321 TEST="$NAME: ignoreeof on file right-to-left"
3322 if ! eval $NUMCOND; then :; else
3323 ti="$td/test$N.file"
3324 tf="$td/test$N.stdout"
3325 te="$td/test$N.stderr"
3326 tdiff="$td/test$N.diff"
3327 da="test$N $(date) $RANDOM"
3328 CMD="$SOCAT $opts -U - file:\"$ti\",ignoreeof"
3329 printf "test $F_n $TEST... " $N
3330 touch "$ti"
3331 $CMD >"$tf" 2>"$te" &
3332 bg=$!
3333 usleep 500000
3334 echo "$da" >>"$ti"
3335 sleep 1
3336 kill $bg 2>/dev/null
3337 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3338 $PRINTF "$FAILED: diff:\n"
3339 cat "$tdiff"
3340 listFAIL="$listFAIL $N"
3341 numFAIL=$((numFAIL+1))
3342 else
3343 $PRINTF "$OK\n"
3344 if [ -n "$debug" ]; then cat $te; fi
3345 numOK=$((numOK+1))
3347 wait
3348 fi ;; # NUMCOND
3349 esac
3350 N=$((N+1))
3353 NAME=EXECIGNOREEOF
3354 case "$TESTS" in
3355 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
3356 TEST="$NAME: exec against address with ignoreeof"
3357 if ! eval $NUMCOND; then :; else
3358 tf="$td/test$N.stdout"
3359 te="$td/test$N.stderr"
3360 # remark: diagnostics to null, no good style
3361 CMD="$TRACE $SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof"
3362 printf "test $F_n $TEST... " $N
3363 $CMD >"$tf" 2>"$te"
3364 if [ -s "$te" ]; then
3365 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3366 echo "$CMD"
3367 cat "$te"
3368 numFAIL=$((numFAIL+1))
3369 listFAIL="$listFAIL $N"
3370 else
3371 $PRINTF "$OK\n"
3372 if [ -n "$debug" ]; then cat $te; fi
3373 numOK=$((numOK+1))
3375 fi ;; # NUMCOND
3376 esac
3377 N=$((N+1))
3380 NAME=FAKEPTY
3381 case "$TESTS" in
3382 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
3383 TEST="$NAME: generation of pty for other processes"
3384 if ! eval $NUMCOND; then :;
3385 elif ! testfeats pty >/dev/null; then
3386 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
3387 numCANT=$((numCANT+1))
3388 listCANT="$listCANT $N"
3389 else
3390 tt="$td/pty$N"
3391 tf="$td/test$N.stdout"
3392 te="$td/test$N.stderr"
3393 tdiff="$td/test$N.diff"
3394 da="test$N $(date) $RANDOM"
3395 CMD1="$TRACE $SOCAT $opts PTY,$PTYOPTS,link=$tt PIPE"
3396 CMD2="$TRACE $SOCAT $opts - $tt,$PTYOPTS2"
3397 printf "test $F_n $TEST... " $N
3398 $CMD1 2>"${te}1" &
3399 pid=$! # background process id
3400 waitfile "$tt"
3401 # this hangs on HP-UX, so we use a timeout
3402 (echo "$da"; sleep 1) |$CMD2 >$tf 2>"${te}2" &
3403 pid2=$!
3404 #sleep 5 && kill $rc2 2>/dev/null &
3405 wait $pid2
3406 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3407 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3408 echo "$CMD1 &"
3409 sleep 1
3410 echo "$CMD2"
3411 cat "${te}1"
3412 cat "${te}2"
3413 cat "$tdiff"
3414 numFAIL=$((numFAIL+1))
3415 listFAIL="$listFAIL $N"
3416 else
3417 $PRINTF "$OK\n"
3418 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3419 numOK=$((numOK+1))
3421 kill $pid 2>/dev/null; wait
3422 fi ;; # NUMCOND, feats
3423 esac
3424 N=$((N+1))
3427 NAME=O_TRUNC
3428 case "$TESTS" in
3429 *%$N%*|*%functions%*|*%$NAME%*)
3430 TEST="$NAME: option o-trunc"
3431 if ! eval $NUMCOND; then :; else
3432 ff="$td/test$N.file"
3433 tf="$td/test$N.stdout"
3434 te="$td/test$N.stderr"
3435 tdiff="$td/test$N.diff"
3436 da="test$N $(date) $RANDOM"
3437 CMD="$TRACE $SOCAT -u $opts - open:$ff,append,o-trunc"
3438 printf "test $F_n $TEST... " $N
3439 rm -f $ff; $ECHO "prefix-\c" >$ff
3440 echo "$da" |$CMD >$tf 2>"$te"
3441 rc0=$?
3442 if ! [ $rc0 = 0 ] ||
3443 ! echo "$da" |diff - $ff >"$tdiff"; then
3444 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3445 echo "$CMD"
3446 cat "$te"
3447 cat "$tdiff"
3448 numFAIL=$((numFAIL+1))
3449 listFAIL="$listFAIL $N"
3450 else
3451 $PRINTF "$OK\n"
3452 if [ -n "$debug" ]; then cat $te; fi
3453 numOK=$((numOK+1))
3455 fi ;; # NUMCOND
3456 esac
3457 N=$((N+1))
3460 NAME=FTRUNCATE
3461 case "$TESTS" in
3462 *%$N%*|*%functions%*|*%$NAME%*)
3463 TEST="$NAME: option ftruncate"
3464 if ! eval $NUMCOND; then :; else
3465 ff="$td/test$N.file"
3466 tf="$td/test$N.stdout"
3467 te="$td/test$N.stderr"
3468 tdiff="$td/test$N.diff"
3469 da="test$N $(date) $RANDOM"
3470 CMD="$TRACE $SOCAT -u $opts - open:$ff,append,ftruncate=0"
3471 printf "test $F_n $TEST... " $N
3472 rm -f $ff; $ECHO "prefix-\c" >$ff
3473 if ! echo "$da" |$CMD >$tf 2>"$te" ||
3474 ! echo "$da" |diff - $ff >"$tdiff"; then
3475 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3476 echo "$CMD"
3477 cat "$te"
3478 cat "$tdiff"
3479 numFAIL=$((numFAIL+1))
3480 listFAIL="$listFAIL $N"
3481 else
3482 $PRINTF "$OK\n"
3483 if [ -n "$debug" ]; then cat $te; fi
3484 numOK=$((numOK+1))
3486 fi ;; # NUMCOND
3487 esac
3488 N=$((N+1))
3491 NAME=RIGHTTOLEFT
3492 case "$TESTS" in
3493 *%$N%*|*%functions%*|*%$NAME%*)
3494 TEST="$NAME: unidirectional throughput from stdin to stdout, right to left"
3495 testecho "$N" "$TEST" "stdout" "stdin" "$opts -U"
3496 esac
3497 N=$((N+1))
3500 # I cannot remember the clou of this test, seems rather useless
3501 NAME=CHILDDEFAULT
3502 case "$TESTS" in
3503 *%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
3504 if ! eval $NUMCOND; then :
3505 elif ! F=$(testfeats STDIO EXEC); then
3506 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
3507 numCANT=$((numCANT+1))
3508 listCANT="$listCANT $N"
3509 elif ! A=$(testaddrs STDIO EXEC); then
3510 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
3511 numCANT=$((numCANT+1))
3512 listCANT="$listCANT $N"
3513 else
3514 TEST="$NAME: child process default properties"
3515 tf="$td/test$N.stdout"
3516 te="$td/test$N.stderr"
3517 CMD="$TRACE $SOCAT $opts -u EXEC:$PROCAN -"
3518 printf "test $F_n $TEST... " $N
3519 $CMD >$tf 2>$te
3520 MYPID=`expr "\`grep "process id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3521 MYPPID=`expr "\`grep "process parent id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3522 MYPGID=`expr "\`grep "process group id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3523 MYSID=`expr "\`grep "process session id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3524 #echo "PID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID"
3525 #if [ "$MYPID" = "$MYPPID" -o "$MYPID" = "$MYPGID" -o "$MYPID" = "$MYSID" -o \
3526 # "$MYPPID" = "$MYPGID" -o "$MYPPID" = "$MYSID" -o "$MYPGID" = "$MYSID" ];
3527 if [ "$MYPID" = "$MYPPID" ];
3528 then
3529 $PRINTF "$FAILED:\n"
3530 echo "$CMD"
3531 cat "$te" >&2
3532 numFAIL=$((numFAIL+1))
3533 listFAIL="$listFAIL $N"
3534 else
3535 $PRINTF "$OK\n"
3536 if [ "$VERBOSE" ]; then echo "$CMD"; fi
3537 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
3538 numOK=$((numOK+1))
3540 fi ;; # NUMCOND
3541 esac
3542 N=$((N+1))
3545 NAME=CHILDSETSID
3546 case "$TESTS" in
3547 *%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
3548 TEST="$NAME: child process with setsid"
3549 if ! eval $NUMCOND; then :; else
3550 tf="$td/test$N.stdout"
3551 te="$td/test$N.stderr"
3552 CMD="$TRACE $SOCAT $opts -u exec:$PROCAN,setsid -"
3553 printf "test $F_n $TEST... " $N
3554 $CMD >$tf 2>$te
3555 MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3556 MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3557 MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3558 MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3559 #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID"
3560 # PID, PGID, and SID must be the same
3561 if [ "$MYPID" = "$MYPPID" -o \
3562 "$MYPID" != "$MYPGID" -o "$MYPID" != "$MYSID" ];
3563 then
3564 $PRINTF "$FAILED\n"
3565 echo "$CMD"
3566 cat "$te"
3567 numFAIL=$((numFAIL+1))
3568 listFAIL="$listFAIL $N"
3569 else
3570 $PRINTF "$OK\n"
3571 numOK=$((numOK+1))
3573 fi ;; # NUMCOND
3574 esac
3575 N=$((N+1))
3578 NAME=MAINSETSID
3579 case "$TESTS" in
3580 *%$N%*|*%functions%*|*%stdio%*|*%exec%*|*%procan%*|*%$NAME%*)
3581 TEST="$NAME: main process with setsid"
3582 if ! eval $NUMCOND; then :; else
3583 tf="$td/test$N.stdout"
3584 te="$td/test$N.stderr"
3585 CMD="$TRACE $SOCAT $opts -U -,setsid EXEC:$PROCAN"
3586 printf "test $F_n $TEST... " $N
3587 $CMD >$tf 2>$te
3588 MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3589 MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3590 MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3591 MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3592 #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID"
3593 # PPID, PGID, and SID must be the same
3594 if [ "$MYPID" = "$MYPPID" -o \
3595 "$MYPPID" != "$MYPGID" -o "$MYPPID" != "$MYSID" ];
3596 then
3597 $PRINTF "$FAILED\n"
3598 echo "$CMD"
3599 cat "$te"
3600 numFAIL=$((numFAIL+1))
3601 listFAIL="$listFAIL $N"
3602 else
3603 $PRINTF "$OK\n"
3604 numOK=$((numOK+1))
3606 fi ;; # NUMCOND
3607 esac
3608 N=$((N+1))
3611 NAME=OPENSSL_TCP4
3612 case "$TESTS" in
3613 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*)
3614 TEST="$NAME: openssl connect"
3615 if ! eval $NUMCOND; then :;
3616 elif ! testfeats openssl >/dev/null; then
3617 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3618 numCANT=$((numCANT+1))
3619 listCANT="$listCANT $N"
3620 elif ! type openssl >/dev/null 2>&1; then
3621 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
3622 numCANT=$((numCANT+1))
3623 listCANT="$listCANT $N"
3624 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3625 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3626 numCANT=$((numCANT+1))
3627 listCANT="$listCANT $N"
3628 else
3629 gentestcert testsrv
3630 tf="$td/test$N.stdout"
3631 te="$td/test$N.stderr"
3632 tdiff="$td/test$N.diff"
3633 da="test$N $(date) $RANDOM"
3634 newport tcp4 # provide free port number in $PORT
3635 init_openssl_s_server
3636 CMD2="$TRACE $SOCAT $opts exec:'openssl s_server $OPENSSL_S_SERVER_4 -accept "$PORT" -quiet -cert testsrv.pem' pipe"
3637 CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
3638 printf "test $F_n $TEST... " $N
3639 eval "$CMD2 2>\"${te}1\" &"
3640 pid=$! # background process id
3641 # this might timeout when openssl opens tcp46 port like " :::$PORT"
3642 waittcp4port $PORT
3643 #echo "$da" |$CMD >$tf 2>"${te}2"
3644 #note: with about OpenSSL 1.1 s_server lost the half close feature, thus:
3645 (echo "$da"; psleep 0.1) |$CMD >$tf 2>"${te}2"
3646 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3647 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3648 echo "$CMD2 &"
3649 echo "$CMD"
3650 cat "${te}1"
3651 cat "${te}2"
3652 cat "$tdiff"
3653 numFAIL=$((numFAIL+1))
3654 listFAIL="$listFAIL $N"
3655 else
3656 $PRINTF "$OK\n"
3657 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3658 numOK=$((numOK+1))
3660 kill $pid 2>/dev/null; wait
3661 fi ;; # NUMCOND, feats
3662 esac
3663 N=$((N+1))
3666 NAME=OPENSSLLISTEN_TCP4
3667 case "$TESTS" in
3668 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
3669 TEST="$NAME: openssl listen"
3670 if ! eval $NUMCOND; then :;
3671 elif ! testfeats openssl >/dev/null; then
3672 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3673 numCANT=$((numCANT+1))
3674 listCANT="$listCANT $N"
3675 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3676 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3677 numCANT=$((numCANT+1))
3678 listCANT="$listCANT $N"
3679 else
3680 gentestcert testsrv
3681 tf="$td/test$N.stdout"
3682 te="$td/test$N.stderr"
3683 tdiff="$td/test$N.diff"
3684 da="test$N $(date) $RANDOM"
3685 newport tcp4 # provide free port number in $PORT
3686 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
3687 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
3688 printf "test $F_n $TEST... " $N
3689 eval "$CMD2 2>\"${te}1\" &"
3690 pid=$! # background process id
3691 waittcp4port $PORT
3692 echo "$da" |$CMD >$tf 2>"${te}2"
3693 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3694 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3695 echo "$CMD2 &"
3696 echo "$CMD"
3697 cat "${te}1"
3698 cat "${te}2"
3699 cat "$tdiff"
3700 numFAIL=$((numFAIL+1))
3701 listFAIL="$listFAIL $N"
3702 else
3703 $PRINTF "$OK\n"
3704 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3705 numOK=$((numOK+1))
3707 kill $pid 2>/dev/null
3708 wait
3709 fi ;; # NUMCOND, feats
3710 esac
3711 N=$((N+1))
3713 NAME=OPENSSLLISTEN_TCP6
3714 case "$TESTS" in
3715 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
3716 TEST="$NAME: openssl listen"
3717 if ! eval $NUMCOND; then :;
3718 elif ! testfeats openssl >/dev/null; then
3719 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3720 numCANT=$((numCANT+1))
3721 listCANT="$listCANT $N"
3722 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
3723 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
3724 numCANT=$((numCANT+1))
3725 listCANT="$listCANT $N"
3726 else
3727 gentestcert testsrv
3728 tf="$td/test$N.stdout"
3729 te="$td/test$N.stderr"
3730 tdiff="$td/test$N.diff"
3731 da="test$N $(date) $RANDOM"
3732 newport tcp6 # provide free port number in $PORT
3733 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
3734 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD"
3735 printf "test $F_n $TEST... " $N
3736 eval "$CMD2 2>\"${te}1\" &"
3737 pid=$! # background process id
3738 waittcp6port $PORT
3739 echo "$da" |$CMD >$tf 2>"${te}2"
3740 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3741 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3742 echo "$CMD2 &"
3743 echo "$CMD"
3744 cat "${te}1"
3745 cat "${te}2"
3746 cat "$tdiff"
3747 numFAIL=$((numFAIL+1))
3748 listFAIL="$listFAIL $N"
3749 else
3750 $PRINTF "$OK\n"
3751 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3752 numOK=$((numOK+1))
3754 kill $pid 2>/dev/null
3755 wait
3756 fi ;; # NUMCOND, feats
3757 esac
3758 N=$((N+1))
3761 newport $RUNS # in case it has not yet been invoked
3763 while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do
3764 if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi
3766 export ts="$td/test$N.socket"
3767 case $RUNS in tcp4|tcp6) newport $RUNS;; esac
3768 WAITTMPL="$(echo "$WAITTMPL" |sed -e 's/\040/ /g')"
3769 TESTADDR=$(eval echo $TESTTMPL)
3770 PEERADDR=$(eval echo $PEERTMPL)
3771 WAITCMD=$(eval echo $WAITTMPL)
3772 TESTKEYW=${TESTADDR%%:*}
3773 feat=$(tolower $FEAT)
3775 # does our address implementation support halfclose?
3776 NAME=${NAMEKEYW}_HALFCLOSE
3777 case "$TESTS" in
3778 *%$N%*|*%functions%*|*%$feat%*|*%socket%*|*%halfclose%*|*%listen%*|*%$NAME%*)
3779 TEST="$NAME: $TESTKEYW half close"
3780 # have a "peer" socat "peer" that executes "$OD_C" and see if EOF on the
3781 # connecting socat brings the result of od
3782 if ! eval $NUMCOND; then :;
3783 elif [ "$FEAT" != ',' ] && ! testfeats "$FEAT" >/dev/null; then
3784 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $FEAT not configured${NORMAL}\n" $N
3785 numCANT=$((numCANT+1))
3786 listCANT="$listCANT $N"
3787 elif ! runs$RUNS >/dev/null; then
3788 $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available$ on host${NORMAL}\n" $N
3789 numCANT=$((numCANT+1))
3790 listCANT="$listCANT $N"
3791 else
3792 tf="$td/test$N.stdout"
3793 te="$td/test$N.stderr"
3794 tdiff="$td/test$N.diff"
3795 da="test$N $(date) $RANDOM"
3796 case $RUNS in tcp4|tcp6) newport $RUNS;; esac
3797 CMD2="$TRACE $SOCAT $opts \"$PEERADDR\" EXEC:'$OD_C'"
3798 CMD="$TRACE $SOCAT -T1 $opts -t 1 - $TESTADDR"
3799 printf "test $F_n $TEST... " $N
3800 eval "$CMD2 2>\"${te}2\" &"
3801 pid2=$! # background process id
3802 $WAITCMD
3803 echo "$da" |$CMD >$tf 2>"${te}"
3804 kill $pid2 2>/dev/null
3805 wait
3806 if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then
3807 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3808 echo "$CMD2 &"
3809 cat "${te}2"
3810 echo "$CMD"
3811 cat "${te}"
3812 cat "$tdiff"
3813 numFAIL=$((numFAIL+1))
3814 listFAIL="$listFAIL $N"
3815 else
3816 $PRINTF "$OK\n"
3817 if [ "$VERBOSE" ]; then
3818 echo " $CMD2 &"
3819 echo " $CMD"
3821 if [ -n "$debug" ]; then cat "${te}2" "${te}"; fi
3822 numOK=$((numOK+1))
3824 wait
3825 fi ;; # NUMCOND, feats
3826 esac
3827 N=$((N+1))
3829 done <<<"
3830 UNIXCONNECT , unix UNIX-CONNECT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts
3831 UNIXCLIENT , unix UNIX-CLIENT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts
3832 GOPEN_UNIXSTREAM , unix GOPEN:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts
3833 UNIXLISTEN , unix UNIX-LISTEN:\$ts UNIX-CONNECT:\$ts,retry=3 sleep\040\1
3834 TCP4CONNECT , tcp4 TCP4-CONNECT:\$LOCALHOST:\$PORT TCP4-LISTEN:\$PORT,$REUSEADDR waittcp4port\040\$PORT
3835 TCP4LISTEN , tcp4 TCP4-LISTEN:\$PORT,$REUSEADDR TCP4-CONNECT:\$LOCALHOST:\$PORT,retry=3
3836 TCP6CONNECT , tcp6 TCP6-CONNECT:\$LOCALHOST6:\$PORT TCP6-LISTEN:\$PORT,$REUSEADDR waittcp6port\040\$PORT
3837 TCP6LISTEN , tcp6 TCP6-LISTEN:\$PORT,$REUSEADDR TCP6-CONNECT:\$LOCALHOST6:\$PORT,retry=3
3838 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
3839 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
3840 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
3841 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
3845 NAME=OPENSSL_SERVERAUTH
3846 case "$TESTS" in
3847 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
3848 TEST="$NAME: OpenSSL server authentication (hostname)"
3849 if ! eval $NUMCOND; then :;
3850 elif ! testfeats openssl >/dev/null; then
3851 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3852 numCANT=$((numCANT+1))
3853 listCANT="$listCANT $N"
3854 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3855 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3856 numCANT=$((numCANT+1))
3857 listCANT="$listCANT $N"
3858 else
3859 gentestcert testsrv
3860 gentestcert testcli
3861 tf="$td/test$N.stdout"
3862 te="$td/test$N.stderr"
3863 tdiff="$td/test$N.diff"
3864 da="test$N $(date) $RANDOM"
3865 newport tcp4 # provide free port number in $PORT
3866 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
3867 CMD1="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=1,cafile=testsrv.crt,$SOCAT_EGD"
3868 printf "test $F_n $TEST... " $N
3869 eval "$CMD0 2>\"${te}0\" &"
3870 pid=$! # background process id
3871 waittcp4port $PORT
3872 echo "$da" |$CMD1 >$tf 2>"${te}1"
3873 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3874 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3875 echo "$CMD0 &"
3876 cat "${te}0"
3877 echo "$CMD1"
3878 cat "${te}1"
3879 cat "$tdiff"
3880 numFAIL=$((numFAIL+1))
3881 listFAIL="$listFAIL $N"
3882 else
3883 $PRINTF "$OK\n"
3884 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3885 numOK=$((numOK+1))
3887 kill $pid 2>/dev/null
3888 wait
3889 fi ;; # NUMCOND, feats
3890 esac
3891 N=$((N+1))
3893 NAME=OPENSSL_CLIENTAUTH
3894 case "$TESTS" in
3895 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
3896 TEST="$NAME: openssl client authentication"
3897 if ! eval $NUMCOND; then :;
3898 elif ! testfeats openssl >/dev/null; then
3899 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3900 numCANT=$((numCANT+1))
3901 listCANT="$listCANT $N"
3902 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3903 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3904 numCANT=$((numCANT+1))
3905 listCANT="$listCANT $N"
3906 else
3907 gentestcert testsrv
3908 gentestcert testcli
3909 tf="$td/test$N.stdout"
3910 te="$td/test$N.stderr"
3911 tdiff="$td/test$N.diff"
3912 da="test$N $(date) $RANDOM"
3913 newport tcp4 # provide free port number in $PORT
3914 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD PIPE"
3915 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD"
3916 printf "test $F_n $TEST... " $N
3917 eval "$CMD2 2>\"${te}1\" &"
3918 pid=$! # background process id
3919 waittcp4port $PORT
3920 echo "$da" |$CMD >$tf 2>"${te}2"
3921 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3922 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3923 echo "$CMD2 &"
3924 echo "$CMD"
3925 cat "${te}1"
3926 cat "${te}2"
3927 cat "$tdiff"
3928 numFAIL=$((numFAIL+1))
3929 listFAIL="$listFAIL $N"
3930 else
3931 $PRINTF "$OK\n"
3932 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3933 numOK=$((numOK+1))
3935 kill $pid 2>/dev/null
3936 wait
3937 fi ;; # NUMCOND, feats
3938 esac
3939 N=$((N+1))
3941 NAME=OPENSSL_FIPS_BOTHAUTH
3942 case "$TESTS" in
3943 *%$N%*|*%functions%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
3944 TEST="$NAME: OpenSSL+FIPS client and server authentication"
3945 if ! eval $NUMCOND; then :;
3946 elif ! testfeats openssl >/dev/null; then
3947 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3948 numCANT=$((numCANT+1))
3949 listCANT="$listCANT $N"
3950 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3951 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3952 numCANT=$((numCANT+1))
3953 listCANT="$listCANT $N"
3954 elif ! testoptions fips >/dev/null; then
3955 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N
3956 numCANT=$((numCANT+1))
3957 listCANT="$listCANT $N"
3958 else
3959 OPENSSL_FIPS=1 gentestcert testsrvfips
3960 OPENSSL_FIPS=1 gentestcert testclifips
3961 tf="$td/test$N.stdout"
3962 te="$td/test$N.stderr"
3963 tdiff="$td/test$N.diff"
3964 da="test$N $(date) $RANDOM"
3965 newport tcp4 # provide free port number in $PORT
3966 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe"
3967 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD"
3968 printf "test $F_n $TEST... " $N
3969 eval "$CMD2 2>\"${te}1\" &"
3970 pid=$! # background process id
3971 waittcp4port $PORT
3972 echo "$da" |$CMD >$tf 2>"${te}2"
3973 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3974 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3975 echo "$CMD2 &"
3976 echo "$CMD"
3977 cat "${te}1"
3978 cat "${te}2"
3979 cat "$tdiff"
3980 numFAIL=$((numFAIL+1))
3981 listFAIL="$listFAIL $N"
3982 else
3983 $PRINTF "$OK\n"
3984 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3985 numOK=$((numOK+1))
3987 kill $pid 2>/dev/null
3988 wait
3989 fi ;; # NUMCOND, feats
3990 esac
3991 N=$((N+1))
3994 NAME=OPENSSL_COMPRESS
3995 case "$TESTS" in
3996 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
3997 TEST="$NAME: OpenSSL compression"
3998 if ! eval $NUMCOND; then :;
3999 elif ! testfeats openssl >/dev/null; then
4000 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
4001 numCANT=$((numCANT+1))
4002 listCANT="$listCANT $N"
4003 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4004 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4005 numCANT=$((numCANT+1))
4006 listCANT="$listCANT $N"
4007 elif ! testoptions openssl-compress >/dev/null; then
4008 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL compression option not available${NORMAL}\n" $N
4009 numCANT=$((numCANT+1))
4010 listCANT="$listCANT $N"
4011 else
4012 gentestcert testsrv
4013 printf "test $F_n $TEST... " $N
4014 tf="$td/test$N.stdout"
4015 te="$td/test$N.stderr"
4016 tdiff="$td/test$N.diff"
4017 da="test$N $(date) $RANDOM"
4018 success=yes
4019 for srccompr in '' compress=auto compress=none; do
4020 for dstcompr in '' compress=auto compress=none; do
4021 newport tcp4 # provide free port number in $PORT
4022 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0,$dstcompr PIPE"
4023 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,$srccompr"
4024 eval "$CMD2 2>\"${te}1\" &"
4025 pid=$! # background process id
4026 waittcp4port $PORT
4027 echo "$da" | $CMD >$tf 2>"${te}2"
4028 kill $pid 2>/dev/null
4029 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4030 success=
4031 break
4033 done
4034 done
4035 if test -z "$success"; then
4036 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4037 echo "$CMD2 &"
4038 echo "$CMD"
4039 cat "${te}1"
4040 cat "${te}2"
4041 cat "$tdiff"
4042 numFAIL=$((numFAIL+1))
4043 listFAIL="$listFAIL $N"
4044 else
4045 $PRINTF "$OK\n"
4046 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4047 numOK=$((numOK+1))
4049 fi ;; # NUMCOND, feats
4050 esac
4051 N=$((N+1))
4054 NAME=SOCKS4CONNECT_TCP4
4055 case "$TESTS" in
4056 *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4057 TEST="$NAME: socks4 connect over TCP/IPv4"
4058 if ! eval $NUMCOND; then :;
4059 elif ! testfeats socks4 >/dev/null; then
4060 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
4061 numCANT=$((numCANT+1))
4062 listCANT="$listCANT $N"
4063 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4064 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4065 numCANT=$((numCANT+1))
4066 listCANT="$listCANT $N"
4067 else
4068 tf="$td/test$N.stdout"
4069 te="$td/test$N.stderr"
4070 tdiff="$td/test$N.diff"
4071 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4072 # we have a normal tcp echo listening - so the socks header must appear in answer
4073 newport tcp4 # provide free port number in $PORT
4074 CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\""
4075 CMD="$TRACE $SOCAT $opts - SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
4076 printf "test $F_n $TEST... " $N
4077 eval "$CMD2 2>\"${te}1\" &"
4078 pid=$! # background process id
4079 waittcp4port $PORT 1
4080 echo "$da" |$CMD >$tf 2>"${te}2"
4081 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4082 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4083 echo "$CMD2 &"
4084 echo "$CMD"
4085 cat "${te}1"
4086 cat "${te}2"
4087 cat "$tdiff"
4088 numFAIL=$((numFAIL+1))
4089 listFAIL="$listFAIL $N"
4090 else
4091 $PRINTF "$OK\n"
4092 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4093 numOK=$((numOK+1))
4095 kill $pid 2>/dev/null
4096 wait
4097 fi ;; # NUMCOND, feats
4098 esac
4099 N=$((N+1))
4101 NAME=SOCKS4CONNECT_TCP6
4102 case "$TESTS" in
4103 *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
4104 TEST="$NAME: socks4 connect over TCP/IPv6"
4105 if ! eval $NUMCOND; then :;
4106 elif ! testfeats socks4 >/dev/null; then
4107 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
4108 numCANT=$((numCANT+1))
4109 listCANT="$listCANT $N"
4110 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
4111 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
4112 numCANT=$((numCANT+1))
4113 listCANT="$listCANT $N"
4114 else
4115 tf="$td/test$N.stdout"
4116 te="$td/test$N.stderr"
4117 tdiff="$td/test$N.diff"
4118 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4119 # we have a normal tcp echo listening - so the socks header must appear in answer
4120 newport tcp6 # provide free port number in $PORT
4121 CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR exec:\"./socks4echo.sh\""
4122 CMD1="$TRACE $SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody"
4123 printf "test $F_n $TEST... " $N
4124 eval "$CMD0 2>\"${te}0\" &"
4125 pid=$! # background process id
4126 waittcp6port $PORT 1
4127 echo "$da" |$CMD1 >${tf}1 2>"${te}1"
4128 if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
4129 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4130 echo "$CMD0 &"
4131 cat "${te}0" >&2
4132 echo "$CMD1"
4133 cat "${te}1" >&2
4134 echo "// diff:" >&2
4135 cat "$tdiff" >&2
4136 numFAIL=$((numFAIL+1))
4137 listFAIL="$listFAIL $N"
4138 else
4139 $PRINTF "$OK\n"
4140 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
4141 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
4142 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
4143 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
4144 numOK=$((numOK+1))
4146 kill $pid 2>/dev/null
4147 wait
4148 fi ;; # NUMCOND, feats
4149 esac
4150 N=$((N+1))
4153 NAME=SOCKS4ACONNECT_TCP4
4154 case "$TESTS" in
4155 *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4156 TEST="$NAME: socks4a connect over TCP/IPv4"
4157 if ! eval $NUMCOND; then :;
4158 elif ! testfeats socks4a >/dev/null; then
4159 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N
4160 numCANT=$((numCANT+1))
4161 listCANT="$listCANT $N"
4162 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4163 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4164 numCANT=$((numCANT+1))
4165 listCANT="$listCANT $N"
4166 else
4167 tf="$td/test$N.stdout"
4168 te="$td/test$N.stderr"
4169 tdiff="$td/test$N.diff"
4170 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4171 # we have a normal tcp echo listening - so the socks header must appear in answer
4172 newport tcp4 # provide free port number in $PORT
4173 CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4a-echo.sh\""
4174 CMD="$TRACE $SOCAT $opts - SOCKS4A:$LOCALHOST:localhost:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
4175 printf "test $F_n $TEST... " $N
4176 eval "$CMD2 2>\"${te}1\" &"
4177 pid=$! # background process id
4178 waittcp4port $PORT 1
4179 echo "$da" |$CMD >$tf 2>"${te}2"
4180 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4181 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4182 echo "$CMD2 &"
4183 echo "$CMD"
4184 cat "${te}1"
4185 cat "${te}2"
4186 cat "$tdiff"
4187 numFAIL=$((numFAIL+1))
4188 listFAIL="$listFAIL $N"
4189 else
4190 $PRINTF "$OK\n"
4191 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4192 numOK=$((numOK+1))
4194 kill $pid 2>/dev/null
4195 wait
4196 fi ;; # NUMCOND, feats
4197 esac
4198 N=$((N+1))
4200 NAME=SOCKS4ACONNECT_TCP6
4201 case "$TESTS" in
4202 *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
4203 TEST="$NAME: socks4a connect over TCP/IPv6"
4204 if ! eval $NUMCOND; then :;
4205 elif ! testfeats socks4a >/dev/null; then
4206 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N
4207 numCANT=$((numCANT+1))
4208 listCANT="$listCANT $N"
4209 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
4210 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
4211 numCANT=$((numCANT+1))
4212 listCANT="$listCANT $N"
4213 else
4214 tf="$td/test$N.stdout"
4215 te="$td/test$N.stderr"
4216 tdiff="$td/test$N.diff"
4217 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4218 # we have a normal tcp echo listening - so the socks header must appear in answer
4219 newport tcp6 # provide free port number in $PORT
4220 CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR EXEC:\"./socks4a-echo.sh\""
4221 CMD="$TRACE $SOCAT $opts - SOCKS4A:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody"
4222 printf "test $F_n $TEST... " $N
4223 eval "$CMD2 2>\"${te}1\" &"
4224 pid=$! # background process id
4225 waittcp6port $PORT 1
4226 echo "$da" |$CMD >$tf 2>"${te}2"
4227 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4228 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4229 echo "$CMD2 &"
4230 echo "$CMD"
4231 cat "${te}1"
4232 cat "${te}2"
4233 cat "$tdiff"
4234 numFAIL=$((numFAIL+1))
4235 listFAIL="$listFAIL $N"
4236 else
4237 $PRINTF "$OK\n"
4238 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4239 numOK=$((numOK+1))
4241 kill $pid 2>/dev/null
4242 wait
4243 fi ;; # NUMCOND, feats
4244 esac
4245 N=$((N+1))
4248 NAME=PROXYCONNECT_TCP4
4249 case "$TESTS" in
4250 *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4251 TEST="$NAME: proxy connect over TCP/IPv4"
4252 if ! eval $NUMCOND; then :;
4253 elif ! testfeats proxy >/dev/null; then
4254 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
4255 numCANT=$((numCANT+1))
4256 listCANT="$listCANT $N"
4257 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4258 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4259 numCANT=$((numCANT+1))
4260 listCANT="$listCANT $N"
4261 else
4262 ts="$td/test$N.sh"
4263 tf="$td/test$N.stdout"
4264 te="$td/test$N.stderr"
4265 tdiff="$td/test$N.diff"
4266 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4267 newport tcp4 # provide free port number in $PORT
4268 #CMD2="$TRACE $SOCAT tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
4269 CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\""
4270 CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
4271 printf "test $F_n $TEST... " $N
4272 eval "$CMD2 2>\"${te}2\" &"
4273 pid=$! # background process id
4274 waittcp4port $PORT 1
4275 echo "$da" |$CMD >"$tf" 2>"${te}1"
4276 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4277 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4278 echo "$CMD2 &"
4279 echo "$CMD"
4280 cat "${te}1"
4281 cat "${te}2"
4282 cat "$tdiff"
4283 numFAIL=$((numFAIL+1))
4284 listFAIL="$listFAIL $N"
4285 else
4286 $PRINTF "$OK\n"
4287 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4288 numOK=$((numOK+1))
4290 kill $pid 2>/dev/null
4291 wait
4292 fi ;; # NUMCOND, feats
4293 esac
4294 N=$((N+1))
4296 NAME=PROXYCONNECT_TCP6
4297 case "$TESTS" in
4298 *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
4299 TEST="$NAME: proxy connect over TCP/IPv6"
4300 if ! eval $NUMCOND; then :;
4301 elif ! testfeats proxy >/dev/null; then
4302 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
4303 numCANT=$((numCANT+1))
4304 listCANT="$listCANT $N"
4305 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
4306 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
4307 numCANT=$((numCANT+1))
4308 listCANT="$listCANT $N"
4309 else
4310 ts="$td/test$N.sh"
4311 tf="$td/test$N.stdout"
4312 te="$td/test$N.stderr"
4313 tdiff="$td/test$N.diff"
4314 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4315 newport tcp6 # provide free port number in $PORT
4316 #CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
4317 CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\""
4318 CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT"
4319 printf "test $F_n $TEST... " $N
4320 eval "$CMD2 2>\"${te}2\" &"
4321 pid=$! # background process id
4322 waittcp6port $PORT 1
4323 echo "$da" |$CMD >"$tf" 2>"${te}1"
4324 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4325 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4326 echo "$CMD2 &"
4327 echo "$CMD"
4328 cat "${te}1"
4329 cat "${te}2"
4330 cat "$tdiff"
4331 numFAIL=$((numFAIL+1))
4332 listFAIL="$listFAIL $N"
4333 else
4334 $PRINTF "$OK\n"
4335 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4336 numOK=$((numOK+1))
4338 kill $pid 2>/dev/null
4339 wait
4340 fi ;; # NUMCOND, feats
4341 esac
4342 N=$((N+1))
4345 NAME=TCP4NOFORK
4346 case "$TESTS" in
4347 *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%exec%*|*%listen%*|*%$NAME%*)
4348 TEST="$NAME: echo via connection to TCP V4 socket with nofork'ed exec"
4349 if ! eval $NUMCOND; then :; else
4350 tf="$td/test$N.stdout"
4351 te="$td/test$N.stderr"
4352 tdiff="$td/test$N.diff"
4353 newport tcp4; tsl=$PORT
4354 ts="127.0.0.1:$tsl"
4355 da="test$N $(date) $RANDOM"
4356 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR EXEC:$CAT,nofork"
4357 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
4358 printf "test $F_n $TEST... " $N
4359 #$CMD1 >"$tf" 2>"${te}1" &
4360 $CMD1 >/dev/null 2>"${te}1" &
4361 waittcp4port $tsl
4362 #usleep $MICROS
4363 echo "$da" |$CMD2 >"$tf" 2>>"${te}2"
4364 if [ $? -ne 0 ]; then
4365 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4366 echo "$CMD1 &"
4367 echo "$CMD2"
4368 cat "${te}1"
4369 cat "${te}2"
4370 numFAIL=$((numFAIL+1))
4371 listFAIL="$listFAIL $N"
4372 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
4373 $PRINTF "$FAILED\n"
4374 cat "$tdiff"
4375 numFAIL=$((numFAIL+1))
4376 listFAIL="$listFAIL $N"
4377 else
4378 $PRINTF "$OK\n"
4379 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4380 numOK=$((numOK+1))
4382 fi ;; # NUMCOND
4383 esac
4384 N=$((N+1))
4387 NAME=EXECCATNOFORK
4388 case "$TESTS" in
4389 *%$N%*|*%functions%*|*%$NAME%*)
4390 TEST="$NAME: simple echo via exec of cat with nofork"
4391 testecho "$N" "$TEST" "" "EXEC:$CAT,nofork" "$opts"
4392 esac
4393 N=$((N+1))
4396 NAME=SYSTEMCATNOFORK
4397 case "$TESTS" in
4398 *%$N%*|*%functions%*|*%$NAME%*)
4399 TEST="$NAME: simple echo via system() of cat with nofork"
4400 testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts"
4401 esac
4402 N=$((N+1))
4405 NAME=NOFORKSETSID
4406 case "$TESTS" in
4407 *%$N%*|*%functions%*|*%$NAME%*)
4408 TEST="$NAME: simple echo via exec() of cat with nofork and setsid"
4409 testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts"
4410 esac
4411 N=$((N+1))
4413 #==============================================================================
4414 #TEST="$NAME: echo via 'connection' to UDP V4 socket"
4415 #if ! eval $NUMCOND; then :; else
4416 #tf="$td/file$N"
4417 #tsl=65534
4418 #ts="127.0.0.1:$tsl"
4419 #da="test$N $(date) $RANDOM"
4420 #$TRACE $SOCAT UDP-LISTEN:$tsl,$REUSEADDR PIPE &
4421 #sleep 2
4422 #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf"
4423 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
4424 # $ECHO "... test $N succeeded"
4425 # numOK=$((numOK+1))
4426 #else
4427 # $ECHO "*** test $N $FAILED"
4428 # numFAIL=$((numFAIL+1))
4429 # listFAIL="$listFAIL $N"
4431 #fi ;; # NUMCOND
4432 #N=$((N+1))
4433 #==============================================================================
4434 # TEST 4 - simple echo via new file
4435 #if ! eval $NUMCOND; then :; else
4436 #N=4
4437 #tf="$td/file$N"
4438 #tp="$td/pipe$N"
4439 #da="test$N $(date) $RANDOM"
4440 #rm -f "$tf.tmp"
4441 #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf"
4442 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
4443 # $ECHO "... test $N succeeded"
4444 # numOK=$((numOK+1))
4445 #else
4446 # $ECHO "*** test $N $FAILED"
4447 # numFAIL=$((numFAIL+1))
4448 # listFAIL="$listFAIL $N"
4450 #fi ;; # NUMCOND
4452 #==============================================================================
4454 NAME=TOTALTIMEOUT
4455 case "$TESTS" in
4456 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%listen%*|*%$NAME%*)
4457 TEST="$NAME: socat inactivity timeout"
4458 if ! eval $NUMCOND; then :; else
4459 #set -vx
4460 tf="$td/test$N.stdout"
4461 te="$td/test$N.stderr"
4462 tdiff="$td/test$N.diff"
4463 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4464 newport tcp4 # provide free port number in $PORT
4465 CMD2="$TRACE $SOCAT $opts -T 1 TCP4-LISTEN:$PORT,$REUSEADDR pipe"
4466 CMD="$TRACE $SOCAT $opts - TCP4-CONNECT:$LOCALHOST:$PORT"
4467 printf "test $F_n $TEST... " $N
4468 eval "$CMD2 2>${te}1 &"
4469 pid=$! # background process id
4470 waittcp4port $PORT 1
4471 (echo "$da"; sleep 2; echo X) |$CMD >"$tf" 2>"${te}2"
4472 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4473 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4474 echo "$CMD2 &"
4475 echo "$CMD"
4476 cat "${te}1"
4477 cat "${te}2"
4478 cat "$tdiff"
4479 numFAIL=$((numFAIL+1))
4480 listFAIL="$listFAIL $N"
4481 else
4482 $PRINTF "$OK\n"
4483 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4484 numOK=$((numOK+1))
4486 kill $pid 2>/dev/null
4487 wait
4488 #set +vx
4489 fi ;; # NUMCOND
4490 esac
4491 N=$((N+1))
4494 NAME=IGNOREEOF+TOTALTIMEOUT
4495 case "$TESTS" in
4496 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*)
4497 TEST="$NAME: ignoreeof and inactivity timeout"
4498 if ! eval $NUMCOND; then :; else
4499 #set -vx
4500 ti="$td/test$N.file"
4501 tf="$td/test$N.stdout"
4502 te="$td/test$N.stderr"
4503 tdiff="$td/test$N.diff"
4504 da="test$N $(date) $RANDOM"
4505 CMD="$TRACE $SOCAT $opts -T 2 -u file:\"$ti\",ignoreeof -"
4506 printf "test $F_n $TEST... " $N
4507 touch "$ti"
4508 $CMD >"$tf" 2>"$te" &
4509 bg=$! # background process id
4510 psleep 0.5
4511 echo "$da" >>"$ti"
4512 sleep 4
4513 echo X >>"$ti"
4514 sleep 1
4515 kill $bg 2>/dev/null
4516 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4517 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4518 echo "$CMD &"
4519 cat "$te"
4520 cat "$tdiff"
4521 numFAIL=$((numFAIL+1))
4522 listFAIL="$listFAIL $N"
4523 else
4524 $PRINTF "$OK\n"
4525 if [ -n "$debug" ]; then cat "$te"; fi
4526 numOK=$((numOK+1))
4528 wait
4529 fi ;; # NUMCOND, feats
4530 esac
4531 N=$((N+1))
4534 NAME=PROXY2SPACES
4535 case "$TESTS" in
4536 *%$N%*|*%functions%*|*%proxy%*|*%listen%*|*%$NAME%*)
4537 TEST="$NAME: proxy connect accepts status with multiple spaces"
4538 if ! eval $NUMCOND; then :;
4539 elif ! testfeats proxy >/dev/null; then
4540 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
4541 numCANT=$((numCANT+1))
4542 listCANT="$listCANT $N"
4543 else
4544 ts="$td/test$N.sh"
4545 tf="$td/test$N.stdout"
4546 te="$td/test$N.stderr"
4547 tdiff="$td/test$N.diff"
4548 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4549 newport tcp4 # provide free port number in $PORT
4550 #CMD2="$TRACE $SOCAT $opts TCP-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
4551 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr,crlf EXEC:\"/usr/bin/env bash proxyecho.sh -w 2\""
4552 CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
4553 printf "test $F_n $TEST... " $N
4554 eval "$CMD0 2>\"${te}1\" &"
4555 pid=$! # background process id
4556 waittcp4port $PORT 1
4557 echo "$da" |$CMD1 >"$tf" 2>"${te}0"
4558 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4559 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4560 echo "$CMD0 &"
4561 cat "${te}0" >&2
4562 echo "$CMD1"
4563 cat "${te}1" >&2
4564 echo "diff:"
4565 cat "$tdiff"
4566 numFAIL=$((numFAIL+1))
4567 listFAIL="$listFAIL $N"
4568 else
4569 $PRINTF "$OK\n"
4570 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
4571 if [ "$debug" ]; then cat "${te}0" >&2; fi
4572 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
4573 if [ "$debug" ]; then cat "${te}1" >&2; fi
4574 numOK=$((numOK+1))
4576 kill $pid 2>/dev/null
4577 wait
4578 fi ;; # NUMCOND, feats
4579 esac
4580 N=$((N+1))
4583 NAME=BUG-UNISTDIO
4584 case "$TESTS" in
4585 *%$N%*|*%functions%*|*%$NAME%*)
4586 TEST="$NAME: for bug with address options on both stdin/out in unidirectional mode"
4587 if ! eval $NUMCOND; then :; else
4588 tf="$td/test$N.stdout"
4589 te="$td/test$N.stderr"
4590 ff="$td/test$N.file"
4591 printf "test $F_n $TEST... " $N
4592 >"$ff"
4593 #$TRACE $SOCAT $opts -u /dev/null -,setlk <"$ff" 2>"$te"
4594 CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk"
4595 $CMD <"$ff" 2>"$te"
4596 if [ "$?" -eq 0 ]; then
4597 $PRINTF "$OK\n"
4598 numOK=$((numOK+1))
4599 else
4600 if [ "$UNAME" = "Linux" ]; then
4601 $PRINTF "$FAILED\n"
4602 echo "$CMD"
4603 cat "$te"
4604 numFAIL=$((numFAIL+1))
4605 listFAIL="$listFAIL $N"
4606 else
4607 $PRINTF "${YELLOW}failed (don't care)${NORMAL}\n"
4608 numCANT=$((numCANT+1))
4609 listCANT="$listCANT $N"
4612 fi ;; # NUMCOND
4613 esac
4614 N=$((N+1))
4617 NAME=SINGLEEXECOUTSOCKETPAIR
4618 case "$TESTS" in
4619 *%$N%*|*%functions%*|*%$NAME%*)
4620 TEST="$NAME: inheritance of stdout to single exec with socketpair"
4621 testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1
4622 esac
4623 N=$((N+1))
4625 NAME=SINGLEEXECOUTPIPE
4626 case "$TESTS" in
4627 *%$N%*|*%functions%*|*%$NAME%*)
4628 TEST="$NAME: inheritance of stdout to single exec with pipe"
4629 testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1
4630 esac
4631 N=$((N+1))
4633 NAME=SINGLEEXECOUTPTY
4634 case "$TESTS" in
4635 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
4636 TEST="$NAME: inheritance of stdout to single exec with pty"
4637 if ! eval $NUMCOND; then :;
4638 elif ! testfeats pty >/dev/null; then
4639 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
4640 numCANT=$((numCANT+1))
4641 listCANT="$listCANT $N"
4642 else
4643 testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1
4644 fi ;; # NUMCOND, feats
4645 esac
4646 N=$((N+1))
4648 NAME=SINGLEEXECINSOCKETPAIR
4649 case "$TESTS" in
4650 *%$N%*|*%functions%*|*%$NAME%*)
4651 TEST="$NAME: inheritance of stdin to single exec with socketpair"
4652 testecho "$N" "$TEST" "exec:cat!!-" "" "$opts"
4653 esac
4654 N=$((N+1))
4656 NAME=SINGLEEXECINPIPE
4657 case "$TESTS" in
4658 *%$N%*|*%functions%*|*%$NAME%*)
4659 TEST="$NAME: inheritance of stdin to single exec with pipe"
4660 testecho "$N" "$TEST" "exec:cat,pipes!!-" "" "$opts"
4661 esac
4662 N=$((N+1))
4664 NAME=SINGLEEXECINPTYDELAY
4665 case "$TESTS" in
4666 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
4667 TEST="$NAME: inheritance of stdin to single exec with pty, with delay"
4668 if ! eval $NUMCOND; then :;
4669 elif ! testfeats pty >/dev/null; then
4670 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
4671 numCANT=$((numCANT+1))
4672 listCANT="$listCANT $N"
4673 else
4674 testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY
4675 fi ;; # NUMCOND, feats
4676 esac
4677 N=$((N+1))
4679 NAME=SINGLEEXECINPTY
4680 case "$TESTS" in
4681 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
4682 TEST="$NAME: inheritance of stdin to single exec with pty"
4683 if ! eval $NUMCOND; then :;
4684 elif ! testfeats pty >/dev/null; then
4685 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
4686 numCANT=$((numCANT+1))
4687 listCANT="$listCANT $N"
4688 else
4689 # T value needed (only) by AIX
4690 testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1
4691 fi ;; # NUMCOND, feats
4692 esac
4693 N=$((N+1))
4696 NAME=READLINE
4697 #set -vx
4698 case "$TESTS" in
4699 *%$N%*|*%functions%*|*%pty%*|*%readline%*|*%sigint%*|*%$NAME%*)
4700 TEST="$NAME: readline with password and sigint"
4701 if ! eval $NUMCOND; then :;
4702 elif ! feat=$(testfeats readline pty); then
4703 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
4704 numCANT=$((numCANT+1))
4705 listCANT="$listCANT $N"
4706 else
4707 SAVETERM="$TERM"; TERM= # 'cause console might print controls even in raw
4708 SAVEMICS=$MICROS
4709 #MICROS=2000000
4710 ts="$td/test$N.sh"
4711 to="$td/test$N.stdout"
4712 tpi="$td/test$N.inpipe"
4713 tpo="$td/test$N.outpipe"
4714 te="$td/test$N.stderr"
4715 tr="$td/test$N.ref"
4716 tdiff="$td/test$N.diff"
4717 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4718 # the feature that we really want to test is in the readline.sh script:
4719 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"
4720 #echo "$CMD" >"$ts"
4721 #chmod a+x "$ts"
4722 printf "test $F_n $TEST... " $N
4723 rm -f "$tpi" "$tpo"
4724 mkfifo "$tpi"
4725 touch "$tpo"
4727 # during development of this test, the following command line succeeded:
4728 # ECHO="echo -e" SOCAT=./socat
4729 # (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
4731 # the following cat, in case of socat failure, reads the pipe to prevent below writer from hanging
4732 PATH=${SOCAT%socat}:$PATH eval "$CMD 2>$te || cat $tpi >/dev/null &"
4733 pid=$! # background process id
4734 usleep $MICROS
4737 usleep $((3*MICROS))
4738 $ECHO "user\n\c"
4739 usleep $MICROS
4740 $ECHO "password\c"
4741 usleep $MICROS
4742 $ECHO "\n\c"
4743 usleep $MICROS
4744 $ECHO "test 1\n\c"
4745 usleep $MICROS
4746 $ECHO "\003\c"
4747 usleep $MICROS
4748 $ECHO "test 2\n\c"
4749 usleep $MICROS
4750 $ECHO "exit\n\c"
4751 usleep $MICROS
4752 ) >"$tpi"
4754 cat >$tr <<EOF
4755 readline feature test program
4756 Authentication required
4757 Username: user
4758 Password:
4759 prog> test 1
4760 executing test 1
4761 prog> ./readline-test.sh got SIGINT
4762 test 2
4763 executing test 2
4764 prog> exit
4767 #0 if ! sed 's/.*\r//g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then
4768 #0 if ! sed 's/.*'"$($ECHO '\r\c')"'/</g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then
4769 wait
4770 if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" - >"$tdiff" 2>&1; then
4771 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4772 echo "$CMD" 2>&1
4773 cat "$te" 2>&1
4774 echo diff: 2>&1
4775 cat "$tdiff" 2>&1
4776 numFAIL=$((numFAIL+1))
4777 listFAIL="$listFAIL $N"
4778 else
4779 $PRINTF "$OK\n"
4780 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
4781 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
4782 numOK=$((numOK+1))
4784 kill $pid 2>/dev/null # necc on OpenBSD
4785 wait
4786 MICROS=$SAVEMICS
4787 TERM="$SAVETERM"
4788 fi ;; # NUMCOND, feats
4789 esac
4790 N=$((N+1))
4793 NAME=GENDERCHANGER
4794 case "$TESTS" in
4795 *%$N%*|*%functions%*|*%listen%*|*%$NAME%*)
4796 TEST="$NAME: TCP4 \"gender changer\""
4797 if ! eval $NUMCOND; then :; else
4798 tf="$td/test$N.stdout"
4799 te="$td/test$N.stderr"
4800 tdiff="$td/test$N.diff"
4801 da="test$N $(date) $RANDOM"
4802 newport tcp4; PORT1=$PORT
4803 newport tcp4; PORT2=$PORT
4804 newport tcp4; PORT3=$PORT
4805 # this is the server in the protected network that we want to reach
4806 CMD1="$TRACE $SOCAT -lpserver $opts TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST ECHO"
4807 # this is the double client in the protected network
4808 CMD2="$TRACE $SOCAT -lp2client $opts TCP4:$LOCALHOST:$PORT2,retry=10,interval=1 TCP4:$LOCALHOST:$PORT1"
4809 # this is the double server in the outside network
4810 CMD3="$TRACE $SOCAT -lp2server $opts TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST"
4811 # this is the outside client that wants to use the protected server
4812 CMD4="$TRACE $SOCAT -lpclient $opts -t1 - tcp4:$LOCALHOST:$PORT3"
4813 printf "test $F_n $TEST... " $N
4814 eval "$CMD1 2>${te}1 &"
4815 pid1=$!
4816 eval "$CMD2 2>${te}2 &"
4817 pid2=$!
4818 eval "$CMD3 2>${te}3 &"
4819 pid3=$!
4820 waittcp4port $PORT1 1 &&
4821 waittcp4port $PORT3 1
4822 sleep 1
4823 echo "$da" |$CMD4 >$tf 2>"${te}4"
4824 kill $pid1 $pid2 $pid3 $pid4 2>/dev/null
4825 wait
4826 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4827 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4828 echo "$CMD1 &"
4829 cat "${te}1" >&2
4830 echo "$CMD2 &"
4831 cat "${te}2" >&2
4832 echo "$CMD3 &"
4833 cat "${te}3" >&2
4834 echo "$CMD4"
4835 cat "${te}4" >&2
4836 echo diff: >&2
4837 cat "$tdiff"
4838 numFAIL=$((numFAIL+1))
4839 listFAIL="$listFAIL $N"
4840 else
4841 $PRINTF "$OK\n"
4842 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
4843 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
4844 if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
4845 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
4846 if [ "$VERBOSE" ]; then echo "$CMD3 &"; fi
4847 if [ "$DEBUG" ]; then cat "${te}3" >&2; fi
4848 if [ "$VERBOSE" ]; then echo "$CMD4"; fi
4849 if [ "$DEBUG" ]; then cat "${te}4" >&2; fi
4850 numOK=$((numOK+1))
4852 fi ;; # NUMCOND
4853 esac
4854 N=$((N+1))
4857 NAME=OUTBOUNDIN
4858 case "$TESTS" in
4859 *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%$NAME%*)
4860 TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot"
4861 if ! eval $NUMCOND; then :;
4862 elif ! feat=$(testfeats openssl proxy); then
4863 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
4864 numCANT=$((numCANT+1))
4865 listCANT="$listCANT $N"
4866 else
4867 gentestcert testsrv
4868 gentestcert testcli
4869 tf="$td/test$N.stdout"
4870 te="$td/test$N.stderr"
4871 tdiff="$td/test$N.diff"
4872 da="test$N $(date) $RANDOM"
4873 newport tcp4; PORT1=$PORT
4874 newport tcp4; PORT2=$PORT
4875 newport tcp4; PORT3=$PORT
4876 newport tcp4; PORT4=$PORT
4877 newport tcp4; PORT5=$PORT
4878 # this is the server in the protected network that we want to reach
4879 CMD1="$TRACE $SOCAT $opts -lpserver TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST ECHO"
4880 # this is the proxy in the protected network that provides a way out
4881 CMD2="$TRACE $SOCAT $opts -lpproxy TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
4882 # this is our proxy connect wrapper in the protected network
4883 CMD3="$TRACE $SOCAT $opts -lpwrapper TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve"
4884 # this is our double client in the protected network using SSL
4885 #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"
4886 CMD4="$TRACE $SOCAT $opts -lp2client SSL:$LOCALHOST:$PORT3,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD TCP4:$LOCALHOST:$PORT1"
4887 # this is the double server in the outside network
4888 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"
4889 # this is the outside client that wants to use the protected server
4890 CMD6="$TRACE $SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$PORT5"
4891 printf "test $F_n $TEST... " $N
4892 eval "$CMD1 2>${te}1 &"
4893 pid1=$!
4894 eval "$CMD2 2>${te}2 &"
4895 pid2=$!
4896 eval "$CMD3 2>${te}3 &"
4897 pid3=$!
4898 waittcp4port $PORT1 1 || $PRINTF "$FAILED: port $PORT1\n" >&2 </dev/null
4899 waittcp4port $PORT2 1 || $PRINTF "$FAILED: port $PORT2\n" >&2 </dev/null
4900 waittcp4port $PORT3 1 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null
4901 eval "$CMD5 2>${te}5 &"
4902 pid5=$!
4903 waittcp4port $PORT5 1 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null
4904 echo "$da" |$CMD6 >$tf 2>"${te}6" &
4905 pid6=$!
4906 waittcp4port $PORT4 1 || $PRINTF "$FAILED: port $PORT4\n" >&2 </dev/null
4907 eval "$CMD4 2>${te}4 &"
4908 pid4=$!
4909 wait $pid6
4910 if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then
4911 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4912 echo "$CMD1 &"
4913 cat "${te}1"
4914 echo "$CMD2 &"
4915 cat "${te}2"
4916 echo "$CMD3 &"
4917 cat "${te}3"
4918 echo "$CMD5 &"
4919 cat "${te}5"
4920 echo "$CMD6"
4921 cat "${te}6"
4922 echo "$CMD4 &"
4923 cat "${te}4"
4924 cat "$tdiff"
4925 numFAIL=$((numFAIL+1))
4926 listFAIL="$listFAIL $N"
4927 else
4928 $PRINTF "$OK\n"
4929 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" "${te}6"; fi
4930 numOK=$((numOK+1))
4932 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
4933 wait
4934 fi ;; # NUMCOND, feats
4935 esac
4936 N=$((N+1))
4939 # test the TCP gender changer with almost production requirements: a double
4940 # client repeatedly tries to connect to a double server via SSL through an HTTP
4941 # proxy. the double servers SSL port becomes active for one connection only
4942 # after a (real) client has connected to its TCP port. when the double client
4943 # succeeded to establish an SSL connection, it connects with its second client
4944 # side to the specified (protected) server. all three consecutive connections
4945 # must function for full success of this test.
4946 #PORT=$((RANDOM+16184))
4948 NAME=INTRANETRIPPER
4949 case "$TESTS" in
4950 *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%$NAME%*)
4951 TEST="$NAME: gender changer via SSL through HTTP proxy, daemons"
4952 if ! eval $NUMCOND; then :;
4953 elif ! feat=$(testfeats openssl proxy); then
4954 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
4955 numCANT=$((numCANT+1))
4956 listCANT="$listCANT $N"
4957 else
4958 gentestcert testsrv
4959 gentestcert testcli
4960 tf="$td/test$N.stdout"
4961 te="$td/test$N.stderr"
4962 tdiff="$td/test$N.diff"
4963 da1="test$N.1 $(date) $RANDOM"
4964 da2="test$N.2 $(date) $RANDOM"
4965 da3="test$N.3 $(date) $RANDOM"
4966 newport tcp4; PORT1=$PORT
4967 newport tcp4; PORT2=$PORT
4968 newport tcp4; PORT3=$PORT
4969 newport tcp4; PORT4=$PORT
4970 newport tcp4; PORT5=$PORT
4971 # this is the server in the protected network that we want to reach
4972 CMD1="$TRACE $SOCAT $opts -lpserver -t1 tcp4-l:$PORT1,reuseaddr,bind=$LOCALHOST,fork echo"
4973 # this is the proxy in the protected network that provides a way out
4974 # note: the proxy.sh script starts one or two more socat processes without
4975 # setting the program name
4976 CMD2="$TRACE $SOCAT $opts -lpproxy -t1 tcp4-l:$PORT2,reuseaddr,bind=$LOCALHOST,fork exec:./proxy.sh"
4977 # this is our proxy connect wrapper in the protected network
4978 CMD3="$TRACE $SOCAT $opts -lpwrapper -t3 tcp4-l:$PORT3,reuseaddr,bind=$LOCALHOST,fork proxy:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve"
4979 # this is our double client in the protected network using SSL
4980 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"
4981 # this is the double server in the outside network
4982 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"
4983 # this is the outside client that wants to use the protected server
4984 CMD6="$TRACE $SOCAT $opts -lpclient -t6 - tcp4:$LOCALHOST:$PORT5,retry=3"
4985 printf "test $F_n $TEST... " $N
4986 # start the intranet infrastructure
4987 eval "$CMD1 2>\"${te}1\" &"
4988 pid1=$!
4989 eval "$CMD2 2>\"${te}2\" &"
4990 pid2=$!
4991 waittcp4port $PORT1 1 || $PRINTF "$FAILED: port $PORT1\n" >&2 </dev/null
4992 waittcp4port $PORT2 1 || $PRINTF "$FAILED: port $PORT2\n" >&2 </dev/null
4993 # initiate our internal measures
4994 eval "$CMD3 2>\"${te}3\" &"
4995 pid3=$!
4996 eval "$CMD4 2>\"${te}4\" &"
4997 pid4=$!
4998 waittcp4port $PORT3 1 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null
4999 # now we start the external daemon
5000 eval "$CMD5 2>\"${te}5\" &"
5001 pid5=$!
5002 waittcp4port $PORT5 1 || $PRINTF "$FAILED: port $5PORT\n" >&2 </dev/null
5003 # and this is the outside client:
5004 echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" &
5005 pid6_1=$!
5006 echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" &
5007 pid6_2=$!
5008 echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" &
5009 pid6_3=$!
5010 wait $pid6_1 $pid6_2 $pid6_3
5011 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
5013 (echo "$da1"; sleep 2) |diff - "${tf}_1" >"${tdiff}1"
5014 (echo "$da2"; sleep 2) |diff - "${tf}_2" >"${tdiff}2"
5015 (echo "$da3"; sleep 2) |diff - "${tf}_3" >"${tdiff}3"
5016 if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then
5017 # FAILED only when none of the three transfers succeeded
5018 if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then
5019 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
5020 echo "$CMD1 &"
5021 cat "${te}1"
5022 echo "$CMD2 &"
5023 cat "${te}2"
5024 echo "$CMD3 &"
5025 cat "${te}3"
5026 echo "$CMD4 &"
5027 cat "${te}4"
5028 echo "$CMD5 &"
5029 cat "${te}5"
5030 echo "$CMD6 &"
5031 cat "${te}6_1"
5032 cat "${tdiff}1"
5033 echo "$CMD6 &"
5034 cat "${te}6_2"
5035 cat "${tdiff}2"
5036 echo "$CMD6 &"
5037 cat "${te}6_3"
5038 cat "${tdiff}3"
5039 numFAIL=$((numFAIL+1))
5040 listFAIL="$listFAIL $N"
5041 else
5042 $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n"
5043 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi
5044 numOK=$((numOK+1))
5046 else
5047 $PRINTF "$OK\n"
5048 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi
5049 numOK=$((numOK+1))
5051 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
5052 wait
5053 fi ;; # NUMCOND, feats
5054 esac
5055 N=$((N+1))
5058 # let us test the security features with -s, retry, and fork
5059 # method: first test without security feature if it works
5060 # then try with security feature, must fail
5062 # test the security features of a server address
5063 testserversec () {
5064 local N="$1"
5065 local title="$2"
5066 local opts="$3"
5067 local arg1="$4" # the server address
5068 local secopt0="$5" # option without security for server, mostly empty
5069 local secopt1="$6" # the security option for server, to be tested
5070 local arg2="$7" # the client address
5071 local ipvers="$8" # IP version, for check of listen port
5072 local proto="$9" # protocol, for check of listen port
5073 local port="${10}" # start client when this port is listening
5074 local expect="${11}" # expected behaviour of client: 0..empty output; -1..error; *: any of these
5075 local T="${12}"; [ -z "$T" ] && T=0
5076 local tf="$td/test$N.stdout"
5077 local te="$td/test$N.stderr"
5078 local tdiff1="$td/test$N.diff1"
5079 local tdiff2="$td/test$N.diff2"
5080 local da="test$N.1 $(date) $RANDOM"
5081 local stat result
5083 $PRINTF "test $F_n %s... " $N "$title"
5084 # first: without security
5085 # start server
5086 $TRACE $SOCAT $opts "$arg1,$secopt0" echo 2>"${te}1" &
5087 spid=$!
5088 if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then
5089 kill $spid 2>/dev/null
5090 $PRINTF "$NO_RESULT (ph.1 server not working):\n"
5091 echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
5092 cat "${te}1"
5093 numCANT=$((numCANT+1))
5094 listCANT="$listCANT $N"
5095 wait; return
5097 # now use client
5098 (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}2"
5099 stat="$?"
5100 kill $spid 2>/dev/null
5101 #killall $TRACE $SOCAT 2>/dev/null
5102 if [ "$stat" != 0 ]; then
5103 $PRINTF "$NO_RESULT (ph.1 function fails): $TRACE $SOCAT:\n"
5104 echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
5105 cat "${te}1"
5106 echo "$TRACE $SOCAT $opts - \"$arg2\""
5107 cat "${te}2"
5108 numCANT=$((numCANT+1))
5109 listCANT="$listCANT $N"
5110 wait; return
5111 elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then
5112 : # function without security is ok, go on
5113 else
5114 $PRINTF "$NO_RESULT (ph.1 function fails): diff:\n"
5115 echo "$TRACE $SOCAT $opts $arg1,$secopt0 echo &"
5116 cat "${te}1"
5117 echo "$TRACE $SOCAT $opts - $arg2"
5118 cat "${te}2"
5119 cat "$tdiff1"
5120 numCANT=$((numCANT+1))
5121 listCANT="$listCANT $N"
5122 wait; return
5125 # then: with security
5126 if [ "$port" ] && ! wait${proto}${ipvers}port $port 0; then
5127 $PRINTF "$NO_RESULT (ph.1 port remains in use)\n"
5128 numCANT=$((numCANT+1))
5129 listCANT="$listCANT $N"
5130 wait; return
5132 wait
5134 #set -vx
5135 # assemble address w/ security option; on dual, take read part:
5136 case "$arg1" in
5137 *!!*) arg="${arg1%!!*},$secopt1!!${arg1#*!!}" ;;
5138 *) arg="$arg1,$secopt1" ;;
5139 esac
5140 # start server
5141 # use -s to make sure that it fails due to a sec violation, not some other failure
5142 CMD3="$TRACE $SOCAT $opts -s $arg echo"
5143 $CMD3 2>"${te}3" &
5144 spid=$!
5145 if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then
5146 kill $spid 2>/dev/null
5147 $PRINTF "$NO_RESULT (ph.2 server not working)\n"
5148 wait
5149 echo "$CMD3"
5150 cat "${te}3"
5151 numCANT=$((numCANT+1))
5152 listCANT="$listCANT $N"
5153 return
5155 # now use client
5156 da="test$N.2 $(date) $RANDOM"
5157 (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}4"
5158 stat=$?
5159 kill $spid 2>/dev/null
5160 #set +vx
5161 #killall $TRACE $SOCAT 2>/dev/null
5162 if [ "$stat" != 0 ]; then
5163 result=-1; # socat had error
5164 elif [ ! -s "$tf" ]; then
5165 result=0; # empty output
5166 elif echo "$da" |diff - "$tf" >"$tdiff2" 2>&1; then
5167 result=1; # output is copy of input
5168 else
5169 result=2; # output differs from input
5171 if [ "$expect" != '1' -a "$result" -eq 1 ]; then
5172 $PRINTF "$FAILED: SECURITY BROKEN\n"
5173 echo "$TRACE $SOCAT $opts $arg echo"
5174 cat "${te}3"
5175 echo "$TRACE $SOCAT $opts - $arg2"
5176 cat "${te}4"
5177 cat "$tdiff2"
5178 numFAIL=$((numFAIL+1))
5179 listFAIL="$listFAIL $N"
5180 elif [ "X$expect" != 'X*' -a X$result != X$expect ]; then
5181 case X$result in
5182 X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n"
5183 echo "$TRACE $SOCAT $opts $arg echo"
5184 cat "${te}3"
5185 echo "$TRACE $SOCAT $opts - $arg2"
5186 cat "${te}4"
5187 numCANT=$((numCANT+1))
5188 listCANT="$listCANT $N"
5190 X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n"
5191 echo "$TRACE $SOCAT $opts $arg echo"
5192 cat "${te}3"
5193 echo "$TRACE $SOCAT $opts - $arg2"
5194 cat "${te}4"
5195 cat "$tdiff2"
5196 numCANT=$((numCANT+1))
5197 listCANT="$listCANT $N"
5199 X1) $PRINTF "$FAILED: SECURITY BROKEN\n"
5200 echo "$TRACE $SOCAT $opts $arg echo"
5201 cat "${te}3"
5202 echo "$TRACE $SOCAT $opts - $arg2"
5203 cat "${te}4"
5204 cat "$tdiff2"
5205 numFAIL=$((numFAIL+1))
5206 listFAIL="$listFAIL $N"
5208 X2) $PRINTF "$FAILED: diff:\n"
5209 echo "$TRACE $SOCAT $opts $arg echo"
5210 cat "${te}3"
5211 echo "$TRACE $SOCAT $opts - $arg2"
5212 cat "${te}4"
5213 cat "$tdiff2"
5214 numFAIL=$((numFAIL+1))
5215 listFAIL="$listFAIL $N"
5217 esac
5218 else
5219 $PRINTF "$OK\n"
5220 [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts $arg echo"
5221 [ "$debug" ] && cat ${te}3
5222 [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts - $arg2"
5223 [ "$debug" ] && cat ${te}4
5224 numOK=$((numOK+1))
5226 wait
5227 #set +vx
5231 NAME=TCP4RANGEBITS
5232 case "$TESTS" in
5233 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5234 TEST="$NAME: security of TCP4-L with RANGE option"
5235 if ! eval $NUMCOND; then :;
5236 elif [ -z "$SECONDADDR" ]; then
5237 # we need access to a second addresses
5238 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
5239 numCANT=$((numCANT+1))
5240 listCANT="$listCANT $N"
5241 else
5242 newport tcp4 # provide free port number in $PORT
5243 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
5244 fi ;; # $SECONDADDR, NUMCOND
5245 esac
5246 N=$((N+1))
5248 NAME=TCP4RANGEMASK
5249 case "$TESTS" in
5250 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5251 TEST="$NAME: security of TCP4-L with RANGE option"
5252 if ! eval $NUMCOND; then :;
5253 elif [ -z "$SECONDADDR" ]; then
5254 # we need access to a second addresses
5255 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
5256 numCANT=$((numCANT+1))
5257 listCANT="$listCANT $N"
5258 else
5259 newport tcp4 # provide free port number in $PORT
5260 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
5261 fi ;; # $SECONDADDR, NUMCOND
5262 esac
5263 N=$((N+1))
5265 # like TCP4RANGEMASK, but the "bad" address is within the same class A network
5266 NAME=TCP4RANGEMASKHAIRY
5267 case "$TESTS" in
5268 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5269 TEST="$NAME: security of TCP4-L with RANGE option"
5270 if ! eval $NUMCOND; then :; else
5271 newport tcp4 # provide free port number in $PORT
5272 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
5273 fi ;; # Linux, NUMCOND
5274 esac
5275 N=$((N+1))
5278 NAME=TCP4SOURCEPORT
5279 case "$TESTS" in
5280 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
5281 TEST="$NAME: security of TCP4-L with SOURCEPORT option"
5282 if ! eval $NUMCOND; then :; else
5283 newport tcp4 # provide free port number in $PORT
5284 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
5285 fi ;; # NUMCOND
5286 esac
5287 N=$((N+1))
5289 NAME=TCP4LOWPORT
5290 case "$TESTS" in
5291 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5292 TEST="$NAME: security of TCP4-L with LOWPORT option"
5293 if ! eval $NUMCOND; then :; else
5294 newport tcp4 # provide free port number in $PORT
5295 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
5296 fi ;; # NUMCOND
5297 esac
5298 N=$((N+1))
5300 NAME=TCP4WRAPPERS_ADDR
5301 case "$TESTS" in
5302 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5303 TEST="$NAME: security of TCP4-L with TCPWRAP option"
5304 if ! eval $NUMCOND; then :;
5305 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
5306 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5307 numCANT=$((numCANT+1))
5308 listCANT="$listCANT $N"
5309 else
5310 ha="$td/hosts.allow"
5311 hd="$td/hosts.deny"
5312 $ECHO "socat: $SECONDADDR" >"$ha"
5313 $ECHO "ALL: ALL" >"$hd"
5314 newport tcp4 # provide free port number in $PORT
5315 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
5316 fi ;; # NUMCOND, feats
5317 esac
5318 N=$((N+1))
5320 NAME=TCP4WRAPPERS_NAME
5321 case "$TESTS" in
5322 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5323 TEST="$NAME: security of TCP4-L with TCPWRAP option"
5324 if ! eval $NUMCOND; then :;
5325 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
5326 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5327 numCANT=$((numCANT+1))
5328 listCANT="$listCANT $N"
5329 else
5330 ha="$td/hosts.allow"
5331 hd="$td/hosts.deny"
5332 $ECHO "socat: $LOCALHOST" >"$ha"
5333 $ECHO "ALL: ALL" >"$hd"
5334 newport tcp4 # provide free port number in $PORT
5335 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
5336 fi ;; # NUMCOND, feats
5337 esac
5338 N=$((N+1))
5341 NAME=TCP6RANGE
5342 case "$TESTS" in
5343 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5344 TEST="$NAME: security of TCP6-L with RANGE option"
5345 if ! eval $NUMCOND; then :;
5346 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5347 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5348 numCANT=$((numCANT+1))
5349 listCANT="$listCANT $N"
5350 else
5351 newport tcp6 # provide free port number in $PORT
5352 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "range=[::2]/128" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5353 fi ;; # NUMCOND, feats
5354 esac
5355 N=$((N+1))
5357 NAME=TCP6SOURCEPORT
5358 case "$TESTS" in
5359 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%**|*%$NAME%*)
5360 TEST="$NAME: security of TCP6-L with SOURCEPORT option"
5361 if ! eval $NUMCOND; then :;
5362 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5363 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5364 numCANT=$((numCANT+1))
5365 listCANT="$listCANT $N"
5366 else
5367 newport tcp6 # provide free port number in $PORT
5368 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5369 fi ;; # NUMCOND, feats
5370 esac
5371 N=$((N+1))
5373 NAME=TCP6LOWPORT
5374 case "$TESTS" in
5375 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5376 TEST="$NAME: security of TCP6-L with LOWPORT option"
5377 if ! eval $NUMCOND; then :;
5378 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5379 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5380 numCANT=$((numCANT+1))
5381 listCANT="$listCANT $N"
5382 else
5383 newport tcp6 # provide free port number in $PORT
5384 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5385 fi ;; # NUMCOND, feats
5386 esac
5387 N=$((N+1))
5389 NAME=TCP6TCPWRAP
5390 case "$TESTS" in
5391 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5392 TEST="$NAME: security of TCP6-L with TCPWRAP option"
5393 if ! eval $NUMCOND; then :;
5394 elif ! feat=$(testfeats tcp ip6 libwrap && runstcp6); then
5395 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5396 numCANT=$((numCANT+1))
5397 listCANT="$listCANT $N"
5398 else
5399 ha="$td/hosts.allow"
5400 hd="$td/hosts.deny"
5401 $ECHO "socat: [::2]" >"$ha"
5402 $ECHO "ALL: ALL" >"$hd"
5403 newport tcp6 # provide free port number in $PORT
5404 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5405 fi ;; # NUMCOND, feats
5406 esac
5407 N=$((N+1))
5410 NAME=UDP4RANGE
5411 case "$TESTS" in
5412 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5413 TEST="$NAME: security of UDP4-L with RANGE option"
5414 if ! eval $NUMCOND; then :; else
5415 newport udp4 # provide free port number in $PORT
5416 #testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5417 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5418 fi ;; # NUMCOND
5419 esac
5420 N=$((N+1))
5422 NAME=UDP4SOURCEPORT
5423 case "$TESTS" in
5424 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%$NAME%*)
5425 TEST="$NAME: security of UDP4-L with SOURCEPORT option"
5426 if ! eval $NUMCOND; then :; else
5427 newport udp4 # provide free port number in $PORT
5428 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5429 fi ;; # NUMCOND
5430 esac
5431 N=$((N+1))
5433 NAME=UDP4LOWPORT
5434 case "$TESTS" in
5435 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%$NAME%*)
5436 TEST="$NAME: security of UDP4-L with LOWPORT option"
5437 if ! eval $NUMCOND; then :; else
5438 newport udp4 # provide free port number in $PORT
5439 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "lowport" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5440 fi ;; # NUMCOND
5441 esac
5442 N=$((N+1))
5444 NAME=UDP4TCPWRAP
5445 case "$TESTS" in
5446 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
5447 TEST="$NAME: security of UDP4-L with TCPWRAP option"
5448 if ! eval $NUMCOND; then :;
5449 elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then
5450 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5451 numCANT=$((numCANT+1))
5452 listCANT="$listCANT $N"
5453 else
5454 ha="$td/hosts.allow"
5455 hd="$td/hosts.deny"
5456 $ECHO "socat: $SECONDADDR" >"$ha"
5457 $ECHO "ALL: ALL" >"$hd"
5458 newport udp4 # provide free port number in $PORT
5459 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5460 fi ;; # NUMCOND, feats
5461 esac
5462 N=$((N+1))
5465 NAME=UDP6RANGE
5466 case "$TESTS" in
5467 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5468 TEST="$NAME: security of UDP6-L with RANGE option"
5469 if ! eval $NUMCOND; then :;
5470 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5471 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5472 numCANT=$((numCANT+1))
5473 listCANT="$listCANT $N"
5474 else
5475 newport udp6 # provide free port number in $PORT
5476 #testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5477 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5478 fi ;; # NUMCOND, feats
5479 esac
5480 N=$((N+1))
5482 NAME=UDP6SOURCEPORT
5483 case "$TESTS" in
5484 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%listen%*|*%$NAME%*)
5485 TEST="$NAME: security of UDP6-L with SOURCEPORT option"
5486 if ! eval $NUMCOND; then :;
5487 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
5488 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
5489 numCANT=$((numCANT+1))
5490 listCANT="$listCANT $N"
5491 else
5492 newport udp6 # provide free port number in $PORT
5493 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5494 fi ;; # NUMCOND, feats
5495 esac
5496 N=$((N+1))
5498 NAME=UDP6LOWPORT
5499 case "$TESTS" in
5500 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%$NAME%*)
5501 TEST="$NAME: security of UDP6-L with LOWPORT option"
5502 if ! eval $NUMCOND; then :;
5503 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
5504 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
5505 numCANT=$((numCANT+1))
5506 listCANT="$listCANT $N"
5507 else
5508 newport udp6 # provide free port number in $PORT
5509 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5510 fi ;; # NUMCOND, feats
5511 esac
5512 N=$((N+1))
5514 NAME=UDP6TCPWRAP
5515 case "$TESTS" in
5516 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
5517 TEST="$NAME: security of UDP6-L with TCPWRAP option"
5518 if ! eval $NUMCOND; then :;
5519 elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then
5520 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5521 numCANT=$((numCANT+1))
5522 listCANT="$listCANT $N"
5523 else
5524 ha="$td/hosts.allow"
5525 hd="$td/hosts.deny"
5526 $ECHO "socat: [::2]" >"$ha"
5527 $ECHO "ALL: ALL" >"$hd"
5528 newport udp6 # provide free port number in $PORT
5529 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5530 fi ;; # NUMCOND, feats
5531 esac
5532 N=$((N+1))
5534 NAME=OPENSSLTCP4_RANGE
5535 case "$TESTS" in
5536 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5537 TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option"
5538 if ! eval $NUMCOND; then :;
5539 elif ! testfeats openssl >/dev/null; then
5540 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5541 numCANT=$((numCANT+1))
5542 listCANT="$listCANT $N"
5543 else
5544 gentestcert testsrv
5545 newport tcp4 # provide free port number in $PORT
5546 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
5547 fi ;; # NUMCOND, feats
5548 esac
5549 N=$((N+1))
5551 NAME=OPENSSLTCP4_SOURCEPORT
5552 case "$TESTS" in
5553 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
5554 TEST="$NAME: security of SSL-L with SOURCEPORT option"
5555 if ! eval $NUMCOND; then :;
5556 elif ! testfeats openssl >/dev/null; then
5557 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5558 numCANT=$((numCANT+1))
5559 listCANT="$listCANT $N"
5560 else
5561 gentestcert testsrv
5562 newport tcp4 # provide free port number in $PORT
5563 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
5564 fi ;; # NUMCOND, feats
5565 esac
5566 N=$((N+1))
5568 NAME=OPENSSLTCP4_LOWPORT
5569 case "$TESTS" in
5570 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5571 TEST="$NAME: security of SSL-L with LOWPORT option"
5572 if ! eval $NUMCOND; then :;
5573 elif ! testfeats openssl >/dev/null; then
5574 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5575 numCANT=$((numCANT+1))
5576 listCANT="$listCANT $N"
5577 else
5578 gentestcert testsrv
5579 newport tcp4 # provide free port number in $PORT
5580 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
5581 fi ;; # NUMCOND, feats
5582 esac
5583 N=$((N+1))
5585 NAME=OPENSSLTCP4_TCPWRAP
5586 case "$TESTS" in
5587 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5588 TEST="$NAME: security of SSL-L with TCPWRAP option"
5589 if ! eval $NUMCOND; then :;
5590 elif ! feat=$(testfeats ip4 tcp libwrap openssl); then
5591 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5592 numCANT=$((numCANT+1))
5593 listCANT="$listCANT $N"
5594 else
5595 gentestcert testsrv
5596 ha="$td/hosts.allow"
5597 hd="$td/hosts.deny"
5598 $ECHO "socat: $SECONDADDR" >"$ha"
5599 $ECHO "ALL: ALL" >"$hd"
5600 newport tcp4 # provide free port number in $PORT
5601 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
5602 fi ;; # NUMCOND, feats
5603 esac
5604 N=$((N+1))
5606 NAME=OPENSSLCERTSERVER
5607 case "$TESTS" in
5608 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*)
5609 TEST="$NAME: security of SSL-L with client certificate"
5610 if ! eval $NUMCOND; then :;
5611 elif ! testfeats openssl >/dev/null; then
5612 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5613 numCANT=$((numCANT+1))
5614 listCANT="$listCANT $N"
5615 else
5616 gentestcert testsrv
5617 gentestcert testcli
5618 newport tcp4 # provide free port number in $PORT
5619 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 '*'
5620 fi ;; # NUMCOND, feats
5621 esac
5622 N=$((N+1))
5624 NAME=OPENSSLCERTCLIENT
5625 case "$TESTS" in
5626 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*)
5627 TEST="$NAME: security of SSL with server certificate"
5628 if ! eval $NUMCOND; then :;
5629 elif ! testfeats openssl >/dev/null; then
5630 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5631 numCANT=$((numCANT+1))
5632 listCANT="$listCANT $N"
5633 else
5634 gentestcert testsrv
5635 gentestcert testcli
5636 newport tcp4 # provide free port number in $PORT
5637 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
5638 fi ;; # NUMCOND, feats
5639 esac
5640 N=$((N+1))
5643 NAME=OPENSSLTCP6_RANGE
5644 case "$TESTS" in
5645 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5646 TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option"
5647 if ! eval $NUMCOND; then :;
5648 elif ! testfeats openssl >/dev/null; then
5649 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5650 numCANT=$((numCANT+1))
5651 listCANT="$listCANT $N"
5652 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5653 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5654 numCANT=$((numCANT+1))
5655 listCANT="$listCANT $N"
5656 else
5657 gentestcert6 testsrv6
5658 newport tcp6 # provide free port number in $PORT
5659 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
5660 fi ;; # NUMCOND, feats
5661 esac
5662 N=$((N+1))
5664 NAME=OPENSSLTCP6_SOURCEPORT
5665 case "$TESTS" in
5666 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
5667 TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option"
5668 if ! eval $NUMCOND; then :;
5669 elif ! testfeats openssl >/dev/null; then
5670 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5671 numCANT=$((numCANT+1))
5672 listCANT="$listCANT $N"
5673 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5674 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5675 numCANT=$((numCANT+1))
5676 listCANT="$listCANT $N"
5677 else
5678 gentestcert6 testsrv6
5679 newport tcp6 # provide free port number in $PORT
5680 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
5681 fi ;; # NUMCOND, feats
5682 esac
5683 N=$((N+1))
5685 NAME=OPENSSLTCP6_LOWPORT
5686 case "$TESTS" in
5687 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5688 TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option"
5689 if ! eval $NUMCOND; then :;
5690 elif ! testfeats openssl >/dev/null; then
5691 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5692 numCANT=$((numCANT+1))
5693 listCANT="$listCANT $N"
5694 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5695 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5696 numCANT=$((numCANT+1))
5697 listCANT="$listCANT $N"
5698 else
5699 gentestcert6 testsrv6
5700 newport tcp6 # provide free port number in $PORT
5701 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
5702 fi ;; # NUMCOND, feats
5703 esac
5704 N=$((N+1))
5706 NAME=OPENSSLTCP6_TCPWRAP
5707 case "$TESTS" in
5708 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5709 TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option"
5710 if ! eval $NUMCOND; then :;
5711 elif ! feat=$(testfeats ip6 tcp libwrap openssl && runsip6); then
5712 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5713 numCANT=$((numCANT+1))
5714 listCANT="$listCANT $N"
5715 else
5716 gentestcert6 testsrv6
5717 ha="$td/hosts.allow"
5718 hd="$td/hosts.deny"
5719 $ECHO "socat: [::2]" >"$ha"
5720 $ECHO "ALL: ALL" >"$hd"
5721 newport tcp6 # provide free port number in $PORT
5722 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
5723 fi ;; # NUMCOND, feats
5724 esac
5725 N=$((N+1))
5728 # test security with the openssl-commonname option on client side
5729 NAME=OPENSSL_CN_CLIENT_SECURITY
5730 case "$TESTS" in
5731 *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*)
5732 TEST="$NAME: security of client openssl-commonname option"
5733 # connect using non matching server name/address with commonname
5734 # options, this should succeed. Then without this option, should fail
5735 if ! eval $NUMCOND; then :;
5736 elif ! testfeats openssl >/dev/null; then
5737 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5738 numCANT=$((numCANT+1))
5739 listCANT="$listCANT $N"
5740 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
5741 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
5742 numCANT=$((numCANT+1))
5743 listCANT="$listCANT $N"
5744 else
5745 gentestcert testsrv
5746 gentestcert testcli
5747 newport tcp4 # provide free port number in $PORT
5748 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 "" '*'
5749 fi ;; # testfeats, NUMCOND
5750 esac
5751 N=$((N+1))
5753 # test security with the openssl-commonname option on server side
5754 NAME=OPENSSL_CN_SERVER_SECURITY
5755 case "$TESTS" in
5756 *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
5757 TEST="$NAME: security of server openssl-commonname option"
5758 # connect using with client certificate to server, this should succeed.
5759 # Then use the server with a non matching openssl-commonname option,
5760 # this must fail
5761 if ! eval $NUMCOND; then :;
5762 elif ! testfeats openssl >/dev/null; then
5763 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5764 numCANT=$((numCANT+1))
5765 listCANT="$listCANT $N"
5766 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
5767 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
5768 numCANT=$((numCANT+1))
5769 listCANT="$listCANT $N"
5770 else
5771 gentestcert testsrv
5772 gentestcert testcli
5773 newport tcp4 # provide free port number in $PORT
5774 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" '*'
5775 fi ;; # testfeats, NUMCOND
5776 esac
5777 N=$((N+1))
5780 NAME=OPENSSL_FIPS_SECURITY
5781 case "$TESTS" in
5782 *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*)
5783 TEST="$NAME: OpenSSL restrictions by FIPS"
5784 if ! eval $NUMCOND; then :;
5785 elif ! testfeats openssl >/dev/null; then
5786 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5787 numCANT=$((numCANT+1))
5788 listCANT="$listCANT $N"
5789 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
5790 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
5791 numCANT=$((numCANT+1))
5792 listCANT="$listCANT $N"
5793 elif ! testoptions fips >/dev/null; then
5794 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N
5795 numCANT=$((numCANT+1))
5796 listCANT="$listCANT $N"
5797 else
5798 gentestcert testsrv
5799 gentestcert testcli
5800 newport tcp4 # provide free port number in $PORT
5801 # openssl client accepts a "normal" certificate only when not in fips mode
5802 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
5803 fi ;; # testfeats, NUMCOND
5804 esac
5805 N=$((N+1))
5808 NAME=UNIEXECEOF
5809 case "$TESTS" in
5810 *%$N%*|*%functions%*|*%$NAME%*)
5811 TEST="$NAME: give exec'd write-only process a chance to flush (-u)"
5812 testod "$N" "$TEST" "" EXEC:"$OD_C" "$opts -u"
5813 esac
5814 N=$((N+1))
5817 NAME=REVEXECEOF
5818 case "$TESTS" in
5819 *%$N%*|*%functions%*|*%$NAME%*)
5820 TEST="$NAME: give exec'd write-only process a chance to flush (-U)"
5821 testod "$N" "$TEST" EXEC:"$OD_C" "-" "$opts -U"
5822 esac
5823 N=$((N+1))
5826 NAME=FILANDIR
5827 case "$TESTS" in
5828 *%$N%*|*%filan%*|*%$NAME%*)
5829 TEST="$NAME: check type printed for directories"
5830 if ! eval $NUMCOND; then :; else
5831 te="$td/test$N.stderr"
5832 printf "test $F_n $TEST... " $N
5833 type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}')
5834 if [ "$type" = "dir" ]; then
5835 $PRINTF "$OK\n"
5836 numOK=$((numOK+1))
5837 else
5838 $PRINTF "$FAILED\n"
5839 cat "$te"
5840 numFAIL=$((numFAIL+1))
5841 listFAIL="$listFAIL $N"
5843 fi ;; # NUMCOND
5844 esac
5845 N=$((N+1))
5848 # Test if Filan can determine UNIX domain socket in file system
5849 NAME=FILANSOCKET
5850 case "$TESTS" in
5851 *%$N%*|*%filan%*|*%unix%*|*%listen%*|*%$NAME%*)
5852 TEST="$NAME: capability to analyze named unix socket"
5853 # Run Filan on a listening UNIX domain socket.
5854 # When its output gives "socket" as type (2nd column), the test succeeded
5855 if ! eval $NUMCOND; then :; else
5856 ts="$td/test$N.socket"
5857 te1="$td/test$N.stderr1" # socat
5858 te2="$td/test$N.stderr2" # filan
5859 printf "test $F_n $TEST... " $N
5860 $TRACE $SOCAT $opts UNIX-LISTEN:"$ts" /dev/null </dev/null 2>"$te1" &
5861 spid=$!
5862 waitfile "$ts" 1
5863 type=$($FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print($2);}')
5864 if [ "$type" = "socket" ]; then
5865 $PRINTF "$OK\n"
5866 if [ "$VERBOSE" ]; then
5867 echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\""
5868 echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'"
5870 numOK=$((numOK+1))
5871 else
5872 $PRINTF "$FAILED\n"
5873 echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" >&2
5874 cat "$te1"
5875 echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" >&2
5876 cat "$te2"
5877 numFAIL=$((numFAIL+1))
5878 listFAIL="$listFAIL $N"
5880 kill $spid 2>/dev/null
5881 wait
5882 fi ;; # NUMCOND
5883 esac
5884 N=$((N+1))
5887 testptywaitslave () {
5888 local N="$1"
5889 local TEST="$2"
5890 local PTYTYPE="$3" # ptmx or openpty
5891 local opts="$4"
5893 local tp="$td/test$N.pty"
5894 local ts="$td/test$N.socket"
5895 local tf="$td/test$N.file"
5896 local tdiff="$td/test$N.diff"
5897 local te1="$td/test$N.stderr1"
5898 local te2="$td/test$N.stderr2"
5899 local te3="$td/test$N.stderr3"
5900 local te4="$td/test$N.stderr4"
5901 local da="test$N $(date) $RANDOM"
5902 printf "test $F_n $TEST... " $N
5903 # first generate a pty, then a socket
5904 ($TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link="$tp" UNIX-LISTEN:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null &
5905 pid=$!
5906 waitfile "$tp"
5907 # if pty was non-blocking, the socket is active, and socat1 will term
5908 $TRACE $SOCAT $opts -T 10 -lpsocat2 FILE:/dev/null UNIX-CONNECT:"$ts" 2>"$te2"
5909 # if pty is blocking, first socat is still active and we get a connection now
5910 #((echo "$da"; sleep 2) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
5911 ( (waitfile "$ts" 1 20; echo "$da"; sleep 1) |$TRACE $SOCAT -lpsocat3 $opts - FILE:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
5912 waitfile "$ts" 1 20
5913 # but we need an echoer on the socket
5914 $TRACE $SOCAT $opts -lpsocat4 UNIX:"$ts" ECHO 2>"$te4"
5915 # now $tf file should contain $da
5916 #kill $pid 2>/dev/null
5917 wait
5919 if echo "$da" |diff - "$tf"> "$tdiff"; then
5920 $PRINTF "$OK\n"
5921 if [ "$VERBOSE" ]; then
5922 echo " $TRACE $SOCAT $opts -T 10 -lpsocat2 FILE:/dev/null UNIX-CONNECT:\"$ts\"" 2>"$te2"
5923 echo " $TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link=\"$tp\" UNIX-LISTEN:\"$ts\"" >&2
5924 echo " $TRACE $SOCAT -lpsocat3 $opts - file:\"$tp\",$PTYOPTS2" >&2
5926 numOK=$((numOK+1))
5927 else
5928 $PRINTF "${YELLOW}FAILED${NORMAL}\n"
5929 cat "$te1"
5930 #cat "$te2" # not of interest
5931 cat "$te3"
5932 cat "$te4"
5933 cat "$tdiff"
5934 numCANT=$((numCANT+1))
5935 listCANT="$listCANT $N"
5939 NAME=PTMXWAITSLAVE
5940 PTYTYPE=ptmx
5941 case "$TESTS" in
5942 *%$N%*|*%functions%*|*%pty%*|*%unix%*|*%listen%*|*%$NAME%*)
5943 TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
5944 if ! eval $NUMCOND; then :; else
5945 if ! feat=$(testfeats pty); then
5946 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5947 numCANT=$((numCANT+1))
5948 listCANT="$listCANT $N"
5949 elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
5950 $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5951 numCANT=$((numCANT+1))
5952 listCANT="$listCANT $N"
5953 else
5954 testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
5956 fi ;; # NUMCOND
5957 esac
5958 N=$((N+1))
5960 NAME=OPENPTYWAITSLAVE
5961 PTYTYPE=openpty
5962 case "$TESTS" in
5963 *%$N%*|*%functions%*|*%pty%*|*%unix%*|*%listen%*|*%$NAME%*)
5964 TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
5965 if ! eval $NUMCOND; then :;
5966 elif ! feat=$(testfeats pty); then
5967 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5968 numCANT=$((numCANT+1))
5969 listCANT="$listCANT $N"
5970 elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
5971 $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5972 numCANT=$((numCANT+1))
5973 listCANT="$listCANT $N"
5974 else
5975 testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
5976 fi ;; # NUMCOND, feats
5977 esac
5978 N=$((N+1))
5981 # Test the connect-timeout address option
5982 NAME=CONNECTTIMEOUT
5983 case "$TESTS" in
5984 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%listen%*|*%$NAME%*)
5985 TEST="$NAME: test the connect-timeout option"
5986 if ! eval $NUMCOND; then :;
5987 elif ! feat=$(testfeats tcp); then
5988 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5989 numCANT=$((numCANT+1))
5990 listCANT="$listCANT $N"
5991 elif ! feat=$(testoptions connect-timeout); then
5992 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5993 numCANT=$((numCANT+1))
5994 listCANT="$listCANT $N"
5995 else
5996 # We need a hanging connection attempt, guess an address for this
5997 case "$UNAME" in
5998 Linux) HANGIP=1.0.0.1 ;;
5999 *) HANGIP=255.255.255.254 ;;
6000 esac
6001 te1="$td/test$N.stderr1"
6002 tk1="$td/test$N.kill1"
6003 te2="$td/test$N.stderr2"
6004 tk2="$td/test$N.kill2"
6005 $PRINTF "test $F_n $TEST... " $N
6006 # First, try to make socat hang and see if it can be killed
6007 #$TRACE $SOCAT $opts - TCP:$HANGIP:1 >"$te1" 2>&1 </dev/null &
6008 CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1"
6009 $CMD >"$te1" 2>$te1 </dev/null &
6010 pid1=$!
6011 sleep 2
6012 if ! kill $pid1 2>"$tk1"; then
6013 $PRINTF "${YELLOW}does not hang${NORMAL}\n"
6014 echo "$CMD" >&2
6015 cat "$te1" >&2
6016 numCANT=$((numCANT+1))
6017 listCANT="$listCANT $N"
6018 else
6019 # Second, set connect-timeout and see if socat exits before kill
6020 CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1,connect-timeout=1.0"
6021 $CMD >"$te1" 2>$te2 </dev/null &
6022 pid2=$!
6023 sleep 2
6024 if kill $pid2 2>"$tk2"; then
6025 $PRINTF "$FAILED\n"
6026 echo "$CMD" >&2
6027 cat "$te2" >&2
6028 numFAIL=$((numFAIL+1))
6029 listFAIL="$listFAIL $N"
6030 else
6031 $PRINTF "$OK\n"
6032 if [ "$VERBOSE" ]; then
6033 echo "$CMD" >&2
6035 numOK=$((numOK+1))
6038 wait
6039 fi ;; # testfeats, NUMCOND
6040 esac
6041 N=$((N+1))
6044 # version 1.7.0.0 had a bug with the connect-timeout option: while it correctly
6045 # terminated a hanging connect attempt, it prevented a successful connection
6046 # establishment from being recognized by socat, instead the timeout occurred
6047 NAME=CONNECTTIMEOUT_CONN
6048 if ! eval $NUMCOND; then :; else
6049 case "$TESTS" in
6050 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%listen%*|*%$NAME%*)
6051 TEST="$NAME: TCP4 connect-timeout option when server replies"
6052 # just try a connection that is expected to succeed with the usual data
6053 # transfer; with the bug it will fail
6054 tf="$td/test$N.stdout"
6055 te="$td/test$N.stderr"
6056 tdiff="$td/test$N.diff"
6057 newport tcp4; tsl=$PORT
6058 ts="127.0.0.1:$tsl"
6059 da="test$N $(date) $RANDOM"
6060 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE"
6061 CMD2="$TRACE $SOCAT $opts STDIO TCP4:$ts,connect-timeout=1"
6062 printf "test $F_n $TEST... " $N
6063 $CMD1 >"$tf" 2>"${te}1" &
6064 pid1=$!
6065 waittcp4port $tsl 1
6066 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6067 if [ $? -ne 0 ]; then
6068 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6069 echo "$CMD1 &"
6070 cat "${te}1"
6071 echo "$CMD2"
6072 cat "${te}2"
6073 numFAIL=$((numFAIL+1))
6074 listFAIL="$listFAIL $N"
6075 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6076 $PRINTF "$FAILED\n"
6077 cat "$tdiff"
6078 numFAIL=$((numFAIL+1))
6079 listFAIL="$listFAIL $N"
6080 else
6081 $PRINTF "$OK\n"
6082 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
6083 numOK=$((numOK+1))
6085 kill $pid1 2>/dev/null
6086 wait ;;
6087 esac
6088 fi # NUMCOND
6089 N=$((N+1))
6092 NAME=OPENSSLLISTENDSA
6093 case "$TESTS" in
6094 *%$N%*|*%functions%*|*%openssl%*|*%listen%*|*%$NAME%*)
6095 TEST="$NAME: openssl listen with DSA certificate"
6096 if ! eval $NUMCOND; then :;
6097 elif ! testfeats openssl >/dev/null; then
6098 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
6099 numCANT=$((numCANT+1))
6100 listCANT="$listCANT $N"
6101 else
6102 SRVCERT=testsrvdsa
6103 gentestdsacert $SRVCERT
6104 tf="$td/test$N.stdout"
6105 te="$td/test$N.stderr"
6106 tdiff="$td/test$N.diff"
6107 da="test$N $(date) $RANDOM"
6108 newport tcp4 # provide free port number in $PORT
6109 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe"
6110 CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
6111 $PRINTF "test $F_n $TEST... " $N
6112 eval "$CMD2 2>\"${te}1\" &"
6113 pid=$! # background process id
6114 waittcp4port $PORT
6115 echo "$da" |$CMD >$tf 2>"${te}2"
6116 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
6117 $PRINTF "$FAILED\n"
6118 echo "$CMD2 &"
6119 echo "$CMD"
6120 cat "${te}1"
6121 cat "${te}2"
6122 cat "$tdiff"
6123 numFAIL=$((numFAIL+1))
6124 listFAIL="$listFAIL $N"
6125 else
6126 $PRINTF "$OK\n"
6127 if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi
6128 numOK=$((numOK+1))
6130 kill $pid 2>/dev/null
6131 wait
6132 fi ;; # testfeats, NUMCOND
6133 esac
6134 N=$((N+1))
6137 # derive signal number from signal name
6138 # kill -l should provide the info
6139 signum () {
6140 if [ ! "$BASH_VERSION" -o -o posix ]; then
6141 # we expect:
6142 for i in $(POSIXLY_CORRECT=1 kill -l); do echo "$i"; done |grep -n -i "^$1$" |cut -d: -f1
6143 else
6144 # expect:
6145 # " 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL"
6146 signam="$1"
6147 kill -l </dev/null |
6148 while read l; do printf "%s %s\n%s %s\n%s %s\n%s %s\n" $l; done |
6149 grep -e "SIG$signam\$" |
6150 cut -d ')' -f 1
6154 # problems with QUIT, INT (are blocked in system() )
6155 for signam in TERM ILL; do
6156 NAME=EXITCODESIG$signam
6157 case "$TESTS" in
6158 *%$N%*|*%functions%*|*%pty%*|*%signal%*|*%$NAME%*)
6159 TEST="$NAME: exit status when dying on SIG$signam"
6160 if ! eval $NUMCOND; then :;
6161 elif ! feat=$(testfeats pty); then
6162 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
6163 numCANT=$((numCANT+1))
6164 listCANT="$listCANT $N"
6165 else
6166 SIG="$(signum $signam)"
6167 te="$td/test$N.stderr"
6168 tpp="$td/test$N.ppid"
6169 tp="$td/test$N.pid"
6170 $PRINTF "test $F_n $TEST... " $N
6171 (sleep 1; kill -"$SIG" "$(cat "$tpp")") &
6172 # a simple "system:echo $PPID..." does not work on NetBSD, OpenBSD
6173 #$TRACE $SOCAT $opts echo SYSTEM:'exec /usr/bin/env bash -c "echo \$PPID '">$tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$?
6174 tsh="$td/test$N.sh"
6175 cat <<EOF >"$tsh"
6176 #! /usr/bin/env bash
6177 echo \$PPID >"$tpp"
6178 echo \$\$ >"$tp"
6179 read x
6181 chmod a+x "$tsh"
6182 #$TRACE $SOCAT $opts echo SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"; stat=$?
6183 CMD="$TRACE $SOCAT $opts ECHO SYSTEM:\"exec\\\ \\\"$tsh\\\"\",pty,setsid,nofork"
6184 $TRACE $SOCAT $opts ECHO SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"
6185 stat=$?
6186 sleep 1; kill -INT $(cat $tp)
6187 wait
6188 if [ "$stat" -eq $((128+$SIG)) ]; then
6189 $PRINTF "$OK\n"
6190 numOK=$((numOK+1))
6191 else
6192 $PRINTF "$FAILED\n"
6193 echo "$CMD"
6194 cat "$te"
6195 numFAIL=$((numFAIL+1))
6196 listFAIL="$listFAIL $N"
6198 wait
6199 fi ;; # NUMCOND, feats
6200 esac
6201 N=$((N+1))
6202 done
6205 NAME=READBYTES
6206 #set -vx
6207 case "$TESTS" in
6208 *%$N%*|*%functions%*|*%$NAME%*)
6209 TEST="$NAME: restrict reading from file with bytes option"
6210 if ! eval $NUMCOND; then :;
6211 elif false; then
6212 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6213 numCANT=$((numCANT+1))
6214 listCANT="$listCANT $N"
6215 else
6216 tr="$td/test$N.ref"
6217 ti="$td/test$N.in"
6218 to="$td/test$N.out"
6219 te="$td/test$N.err"
6220 tdiff="$td/test$N.diff"
6221 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
6223 CMD="$TRACE $SOCAT $opts -u open:$ti,readbytes=100 -"
6224 printf "test $F_n $TEST... " $N
6225 rm -f "$tf" "$ti" "$to"
6227 echo "AAAAAAAAAAAAAAAAAAAAAAAA
6228 AAAAAAAAAAAAAAAAAAAAAAAA
6229 AAAAAAAAAAAAAAAAAAAAAAAA
6230 AAAAAAAAAAAAAAAAAAAAAAAA" >"$tr" # 100 bytes
6231 cat "$tr" "$tr" >"$ti" # 200 bytes
6232 $CMD >"$to" 2>"$te"
6233 if ! diff "$tr" "$to" >"$tdiff" 2>&1; then
6234 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6235 echo "$CMD"
6236 cat "$te"
6237 cat "$tdiff"
6238 numFAIL=$((numFAIL+1))
6239 listFAIL="$listFAIL $N"
6240 else
6241 $PRINTF "$OK\n"
6242 if [ -n "$debug" ]; then cat $te; fi
6243 numOK=$((numOK+1))
6245 fi ;; # NUMCOND, feats
6246 esac
6247 N=$((N+1))
6250 NAME=UDPLISTENFORK
6251 case "$TESTS" in
6252 *%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%listen%*|*%fork%*|*%$NAME%*)
6253 TEST="$NAME: UDP socket rebinds after first connection"
6254 if ! eval $NUMCOND; then :;
6255 elif ! F=$(testfeats STDIO IP4 UDP PIPE); then
6256 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
6257 numCANT=$((numCANT+1))
6258 listCANT="$listCANT $N"
6259 elif ! A=$(testaddrs STDIO UDP4-CONNECT UDP4-LISTEN PIPE); then
6260 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
6261 numCANT=$((numCANT+1))
6262 listCANT="$listCANT $N"
6263 elif ! o=$(testoptions bind so-reuseaddr fork) >/dev/null; then
6264 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
6265 numCANT=$((numCANT+1))
6266 listCANT="$listCANT $N"
6267 elif ! runsip4 >/dev/null; then
6268 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
6269 numCANT=$((numCANT+1))
6270 listCANT="$listCANT $N"
6271 else
6272 tf="$td/test$N.stdout"
6273 te="$td/test$N.stderr"
6274 tdiff="$td/test$N.diff"
6275 da1="test$N $(date) $RANDOM"
6276 da2="test$N $(date) $RANDOM"
6277 #establish a listening and forking udp socket in background
6278 #processes hang forever without -T
6279 newport udp4 # provide free port number in $PORT
6280 CMD0="$TRACE $SOCAT -T 5 $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,$REUSEADDR,fork PIPE"
6281 #make a first and a second connection
6282 CMD1="$TRACE $SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT"
6283 $PRINTF "test $F_n $TEST... " $N
6284 eval "$CMD0 2>${te}0 &"
6285 pids=$!
6286 waitudp4port "$PORT"
6287 echo "$da1" |eval "$CMD1" >"${tf}1" 2>"${te}1"
6288 if [ $? -ne 0 ]; then
6289 kill "$pids" 2>/dev/null
6290 $PRINTF "$NO_RESULT (first conn failed):\n"
6291 echo "$CMD0 &"
6292 cat "${te}0" >&2
6293 echo "$CMD1"
6294 cat "${te}1" >&2
6295 numCANT=$((numCANT+1))
6296 listCANT="$listCANT $N"
6297 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
6298 kill "$pids" 2>/dev/null
6299 $PRINTF "$NO_RESULT (first conn failed); diff:\n"
6300 echo "$CMD0 &"
6301 cat "${te}0" >&2
6302 echo "$CMD1"
6303 cat "${te}1" >&2
6304 cat "$tdiff"
6305 numCANT=$((numCANT+1))
6306 listCANT="$listCANT $N"
6307 else
6308 sleep 2 # UDP-LISTEN sleeps 1s
6309 echo "$da2" |eval "$CMD1" >"${tf}2" 2>"${te}2"
6310 rc="$?"; kill "$pids" 2>/dev/null
6311 if [ $rc -ne 0 ]; then
6312 $PRINTF "$FAILED:\n"
6313 echo "$CMD0 &"
6314 cat "${te}0" >&2
6315 echo "$CMD1"
6316 cat "${te}1" >&2
6317 numFAIL=$((numFAIL+1))
6318 listFAIL="$listFAIL $N"
6319 elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then
6320 $PRINTF "$FAILED: diff\n"
6321 echo "$CMD0 &"
6322 cat "${te}0" >&2
6323 echo "$CMD1"
6324 cat "${te}1" >&2
6325 echo "diff:"
6326 cat "$tdiff"
6327 numFAIL=$((numFAIL+1))
6328 listFAIL="$listFAIL $N"
6329 else
6330 $PRINTF "$OK\n"
6331 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
6332 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
6333 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
6334 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
6335 numOK=$((numOK+1))
6336 fi # !( $? -ne 0)
6337 fi # !(rc -ne 0)
6338 wait
6339 fi ;; # NUMCOND, feats
6340 esac
6341 N=$((N+1))
6344 # Is a listen address capable of forking two child processes and have both
6345 # active?
6346 while read PROTOV MAJADDR MINADDR; do
6347 if [ -z "$PROTOV" ] || [[ "$PROTOV" == \#* ]]; then continue; fi
6348 protov="$(echo "$PROTOV" |tr A-Z a-z)"
6349 proto="${protov%%[0-9]}"
6350 NAME=${PROTOV}LISTENFORK
6351 case "$TESTS" in
6352 *%$N%*|*%functions%*|*%$protov%*|*%$proto%*|*%listen%*|*%fork%*|*%$NAME%*)
6353 TEST="$NAME: $PROTOV listen handles 2 concurrent connections"
6354 # Have a listening address with fork option. connect with client1, send a piece
6355 # of data, wait 1s, connect with client2, send another piece of data, wait 1s,
6356 # and send another piece of data with client1. The server processes append all
6357 # data to the same file. Check all data are written to the file in correct
6358 # order.
6359 if ! eval $NUMCOND; then :;
6360 #elif ! feat=$(testfeats $PROTOV); then
6361 # $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N
6362 # numCANT=$((numCANT+1))
6363 elif ! runs$protov >/dev/null; then
6364 $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N
6365 numCANT=$((numCANT+1))
6366 listCANT="$listCANT $N"
6367 else
6368 ts="$td/test$N.sock"
6369 tref="$td/test$N.ref"
6370 tf="$td/test$N.stdout"
6371 te="$td/test$N.stderr"
6372 tdiff="$td/test$N.diff"
6373 da1a="test$N $(date) 1a $RANDOM"
6374 da1b="test$N $(date) 1b $RANDOM"
6375 da2="test$N $(date) 2 $RANDOM"
6376 case "$MAJADDR" in
6377 "FILE")
6378 tla="$ts"
6379 tca="$ts"
6380 waitproto="file"
6381 waitfor="$ts" ;;
6382 esac
6383 case "$MINADDR" in
6384 "PORT")
6385 newport $protov # provide free port number in $PORT
6386 tla="$PORT,bind=$MAJADDR"
6387 tca="$MAJADDR:$PORT"
6388 waitproto="${protov}port"
6389 waitfor="$PORT" ;;
6390 esac
6391 #set -xv
6392 echo -e "$da1a\n$da2\n$da1b" >"$tref"
6393 # establish a listening and forking listen socket in background
6394 # UDP processes hang forever without -T
6395 CMD0="$TRACE $SOCAT -T 5 $opts -lpserver $PROTOV-LISTEN:$tla,$REUSEADDR,fork PIPE"
6396 # make a first and a second connection
6397 CMD1="$TRACE $SOCAT $opts -lpclient - $PROTOV-CONNECT:$tca"
6398 $PRINTF "test $F_n $TEST... " $N
6399 eval "$CMD0 2>${te}0 &"
6400 pid0=$!
6401 wait$waitproto "$waitfor" 1 2
6402 (echo "$da1a"; sleep 2; echo "$da1b") |eval "$CMD1" >>"${tf}" 2>"${te}1" &
6403 sleep 1
6404 # trailing sleep req for sctp because no half close
6405 (echo "$da2"; sleep 1) |eval "$CMD1" >>"${tf}" 2>"${te}2" &
6406 sleep 2
6407 kill $pid0 2>/dev/null
6408 wait
6409 if ! diff "$tref" "$tf" >"$tdiff"; then
6410 $PRINTF "$FAILED\n"
6411 echo "$CMD0 &"
6412 cat "${te}0" >&2
6413 echo "$CMD1 &"
6414 cat "${te}1" >&2
6415 echo "$CMD1"
6416 cat "${te}2" >&2
6417 cat "$tdiff" >&2
6418 numFAIL=$((numFAIL+1))
6419 listFAIL="$listFAIL $N"
6420 else
6421 $PRINTF "$OK\n"
6422 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
6423 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
6424 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
6425 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
6426 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
6427 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
6428 numOK=$((numOK+1))
6429 fi # !(rc -ne 0)
6430 wait
6431 fi ;; # NUMCOND, feats
6432 esac
6433 N=$((N+1))
6434 done <<<"
6435 TCP4 $LOCALHOST PORT
6436 TCP6 $LOCALHOST6 PORT
6437 UDP4 $LOCALHOST PORT
6438 UDP6 $LOCALHOST6 PORT
6439 SCTP4 $LOCALHOST PORT
6440 SCTP6 $LOCALHOST6 PORT
6441 UNIX FILE ,
6445 NAME=UNIXTOSTREAM
6446 case "$TESTS" in
6447 *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*)
6448 TEST="$NAME: generic UNIX client connects to stream socket"
6449 if ! eval $NUMCOND; then :; else
6450 ts="$td/test$N.socket"
6451 tf="$td/test$N.stdout"
6452 te="$td/test$N.stderr"
6453 tdiff="$td/test$N.diff"
6454 da1="test$N $(date) $RANDOM"
6455 #establish a listening unix socket in background
6456 SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
6457 #make a connection
6458 CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts\""
6459 $PRINTF "test $F_n $TEST... " $N
6460 eval "$SRV 2>${te}s &"
6461 pids=$!
6462 waitfile "$ts"
6463 echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1"
6464 if [ $? -ne 0 ]; then
6465 kill "$pids" 2>/dev/null
6466 $PRINTF "$FAILED:\n"
6467 echo "$SRV &"
6468 echo "$CLI"
6469 cat "${te}s" "${te}1"
6470 numFAIL=$((numFAIL+1))
6471 listFAIL="$listFAIL $N"
6472 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
6473 kill "$pids" 2>/dev/null
6474 $PRINTF "$FAILED; diff:\n"
6475 cat "$tdiff"
6476 numFAIL=$((numFAIL+1))
6477 listFAIL="$listFAIL $N"
6478 else
6479 $PRINTF "$OK\n"
6480 numOK=$((numOK+1))
6481 fi # !(rc -ne 0)
6482 wait
6483 fi ;; # NUMCOND
6484 esac
6485 N=$((N+1))
6488 NAME=UNIXTODGRAM
6489 case "$TESTS" in
6490 *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%recv%*|*%$NAME%*)
6491 TEST="$NAME: generic UNIX client connects to datagram socket"
6492 if ! eval $NUMCOND; then :; else
6493 ts1="$td/test$N.socket1"
6494 ts2="$td/test$N.socket2"
6495 tf="$td/test$N.stdout"
6496 te="$td/test$N.stderr"
6497 tdiff="$td/test$N.diff"
6498 da1="test$N $(date) $RANDOM"
6499 #establish a receiving unix datagram socket in background
6500 SRV="$TRACE $SOCAT $opts -lpserver UNIX-RECVFROM:\"$ts1\" PIPE"
6501 #make a connection
6502 CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\",bind=\"$ts2\""
6503 #CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\""
6504 $PRINTF "test $F_n $TEST... " $N
6505 eval "$SRV 2>${te}s &"
6506 pids=$!
6507 waitfile "$ts1"
6508 echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1"
6509 rc=$?
6510 kill $pids 2>/dev/null
6511 wait
6512 if [ $rc -ne 0 ]; then
6513 kill "$pids" 2>/dev/null
6514 $PRINTF "$FAILED:\n"
6515 echo "$SRV &"
6516 cat "${te}s"
6517 echo "$CLI"
6518 cat "${te}1" "${te}1"
6519 numFAIL=$((numFAIL+1))
6520 listFAIL="$listFAIL $N"
6521 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
6522 kill "$pids" 2>/dev/null
6523 $PRINTF "$FAILED:\n"
6524 echo "$SRV &"
6525 cat "${te}s"
6526 echo "$CLI"
6527 cat "${te}1"
6528 cat "$tdiff"
6529 numFAIL=$((numFAIL+1))
6530 listFAIL="$listFAIL $N"
6531 else
6532 $PRINTF "$OK\n"
6533 numOK=$((numOK+1))
6534 fi # !(rc -ne 0)
6535 fi ;; # NUMCOND
6536 esac
6537 N=$((N+1))
6540 # there was an error in address EXEC with options pipes,stderr
6541 NAME=EXECPIPESSTDERR
6542 case "$TESTS" in
6543 *%$N%*|*%functions%*|*%$NAME%*)
6544 TEST="$NAME: simple echo via exec of cat with pipes,stderr"
6545 # this test is known to fail when logging is enabled with OPTS/opts env var.
6546 SAVE_opts="$opts"
6547 opts="$(echo "$opts" |sed 's/-dd*//g')"
6548 testecho "$N" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts"
6549 opts="$SAVE_opts"
6550 esac
6551 N=$((N+1))
6553 # EXEC and SYSTEM with stderr injected socat messages into the data stream.
6554 NAME=EXECSTDERRLOG
6555 case "$TESTS" in
6556 *%$N%*|*%functions%*|*%$NAME%*)
6557 TEST="$NAME: simple echo via exec of cat with pipes,stderr"
6558 SAVE_opts="$opts"
6559 # make sure at least two -d are there
6560 case "$opts" in
6561 *-d*-d*) ;;
6562 *-d*) opts="$opts -d" ;;
6563 *) opts="-d -d" ;;
6564 esac
6565 testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts"
6566 opts="$SAVE_opts"
6567 esac
6568 N=$((N+1))
6571 NAME=SIMPLEPARSE
6572 case "$TESTS" in
6573 *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*)
6574 TEST="$NAME: invoke socat from socat"
6575 testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts"
6576 esac
6577 N=$((N+1))
6580 NAME=FULLPARSE
6581 case "$TESTS" in
6582 *%$N%*|*%functions%*|*%parse%*|*%$NAME%*)
6583 TEST="$NAME: correctly parse special chars"
6584 if ! eval $NUMCOND; then :; else
6585 $PRINTF "test $F_n $TEST... " $N
6586 tf="$td/test$N.stdout"
6587 te="$td/test$N.stderr"
6588 tdiff="$td/test$N.diff"
6589 # a string where commas are hidden in nesting lexical constructs
6590 # if they are scanned incorrectly, socat will see an "unknown option"
6591 dain='(,)[,]{,}","([),])hugo'
6592 daout='(,)[,]{,},([),])hugo'
6593 $TRACE "$SOCAT" $opts -u "exec:echo $dain" - >"$tf" 2>"$te"
6594 rc=$?
6595 echo "$daout" |diff "$tf" - >"$tdiff"
6596 if [ "$rc" -ne 0 ]; then
6597 $PRINTF "$FAILED:\n"
6598 echo "$TRACE $SOCAT" -u "exec:echo $da" -
6599 cat "$te"
6600 numFAIL=$((numFAIL+1))
6601 listFAIL="$listFAIL $N"
6602 elif [ -s "$tdiff" ]; then
6603 $PRINTF "$FAILED:\n"
6604 echo diff:
6605 cat "$tdiff"
6606 if [ -n "$debug" ]; then cat $te; fi
6607 numFAIL=$((numFAIL+1))
6608 listFAIL="$listFAIL $N"
6609 else
6610 $PRINTF "$OK\n"
6611 if [ -n "$debug" ]; then cat $te; fi
6612 numOK=$((numOK+1))
6614 fi ;; # NUMCOND
6615 esac
6616 N=$((N+1))
6618 NAME=NESTEDSOCATEXEC
6619 case "$TESTS" in
6620 *%parse%*|*%$N%*|*%functions%*|*%$NAME%*)
6621 TEST="$NAME: does lexical analysis work sensibly (exec)"
6622 testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1
6623 esac
6624 N=$((N+1))
6626 NAME=NESTEDSOCATSYSTEM
6627 case "$TESTS" in
6628 *%parse%*|*%$N%*|*%functions%*|*%$NAME%*)
6629 TEST="$NAME: does lexical analysis work sensibly (system)"
6630 testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1
6631 esac
6632 N=$((N+1))
6635 NAME=TCP6BYTCP4
6636 case "$TESTS" in
6637 *%$N%*|*%functions%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
6638 TEST="$NAME: TCP4 mapped into TCP6 address space"
6639 if ! eval $NUMCOND; then :;
6640 elif true; then
6641 $PRINTF "test $F_n $TEST... ${YELLOW}Feature removed${NORMAL}\n" $N
6642 numCANT=$((numCANT+1))
6643 listCANT="$listCANT $N"
6644 elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
6645 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
6646 numCANT=$((numCANT+1))
6647 listCANT="$listCANT $N"
6648 else
6649 tf="$td/test$N.stdout"
6650 te="$td/test$N.stderr"
6651 tdiff="$td/test$N.diff"
6652 newport tcp6; tsl=$PORT
6653 ts="127.0.0.1:$tsl"
6654 da="test$N $(date) $RANDOM"
6655 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE"
6656 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
6657 printf "test $F_n $TEST... " $N
6658 $CMD1 >"$tf" 2>"${te}1" &
6659 pid=$! # background process id
6660 waittcp6port $tsl 1
6661 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6662 if [ $? -ne 0 ]; then
6663 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6664 echo "$CMD1 &"
6665 echo "$CMD2"
6666 cat "${te}1"
6667 cat "${te}2"
6668 numFAIL=$((numFAIL+1))
6669 listFAIL="$listFAIL $N"
6670 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6671 $PRINTF "$FAILED: diff:\n"
6672 cat "$tdiff"
6673 numFAIL=$((numFAIL+1))
6674 listFAIL="$listFAIL $N"
6675 else
6676 $PRINTF "$OK\n"
6677 if [ -n "$debug" ]; then cat $te; fi
6678 numOK=$((numOK+1))
6680 kill $pid 2>/dev/null; wait
6681 fi ;; # NUMCOND, feats
6682 esac
6683 N=$((N+1))
6686 # test the UDP4-SENDTO and UDP4-RECVFROM addresses together
6687 NAME=UDP4DGRAM
6688 case "$TESTS" in
6689 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*)
6690 TEST="$NAME: UDP/IPv4 sendto and recvfrom"
6691 # start a UDP4-RECVFROM process that echoes data, and send test data using
6692 # UDP4-SENDTO. The sent data should be returned.
6693 if ! eval $NUMCOND; then :; else
6694 tf="$td/test$N.stdout"
6695 te="$td/test$N.stderr"
6696 tdiff="$td/test$N.diff"
6697 newport udp4; ts1p=$PORT
6698 ts1a="127.0.0.1"
6699 ts1="$ts1a:$ts1p"
6700 newport udp4; ts2p=$PORT
6701 ts2="127.0.0.1:$ts2p"
6702 da="test$N $(date) $RANDOM"
6703 CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
6704 CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2"
6705 printf "test $F_n $TEST... " $N
6706 $CMD1 2>"${te}1" &
6707 pid1="$!"
6708 waitudp4port $ts1p 1
6709 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6710 rc2="$?"
6711 kill "$pid1" 2>/dev/null; wait;
6712 if [ "$rc2" -ne 0 ]; then
6713 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6714 echo "$CMD1 &"
6715 cat "${te}1"
6716 echo "$CMD2"
6717 cat "${te}2"
6718 numFAIL=$((numFAIL+1))
6719 listFAIL="$listFAIL $N"
6720 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6721 $PRINTF "$FAILED\n"
6722 cat "$tdiff"
6723 echo "$CMD1 &"
6724 cat "${te}1"
6725 echo "$CMD2"
6726 cat "${te}2"
6727 numFAIL=$((numFAIL+1))
6728 listFAIL="$listFAIL $N"
6729 else
6730 $PRINTF "$OK\n"
6731 if [ -n "$debug" ]; then cat $te; fi
6732 numOK=$((numOK+1))
6734 fi # NUMCOND
6736 esac
6737 N=$((N+1))
6740 NAME=UDP6DGRAM
6741 case "$TESTS" in
6742 *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%$NAME%*)
6743 TEST="$NAME: UDP/IPv6 datagram"
6744 if ! eval $NUMCOND; then :;
6745 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
6746 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
6747 numCANT=$((numCANT+1))
6748 listCANT="$listCANT $N"
6749 else
6750 tf="$td/test$N.stdout"
6751 te="$td/test$N.stderr"
6752 tdiff="$td/test$N.diff"
6753 newport udp6; ts1p=$PORT
6754 tsa="[::1]"
6755 ts1="$tsa:$ts1p"
6756 newport udp6; ts2p=$PORT
6757 ts2="$tsa:$ts2p"
6758 da="test$N $(date) $RANDOM"
6759 CMD1="$TRACE $SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
6760 CMD2="$TRACE $SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2"
6761 printf "test $F_n $TEST... " $N
6762 $CMD1 2>"${te}1" &
6763 waitudp6port $ts1p 1
6764 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6765 if [ $? -ne 0 ]; then
6766 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6767 echo "$CMD1 &"
6768 echo "$CMD2"
6769 cat "${te}1"
6770 cat "${te}2"
6771 numFAIL=$((numFAIL+1))
6772 listFAIL="$listFAIL $N"
6773 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6774 $PRINTF "$FAILED\n"
6775 cat "$tdiff"
6776 numFAIL=$((numFAIL+1))
6777 listFAIL="$listFAIL $N"
6778 else
6779 $PRINTF "$OK\n"
6780 if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi
6781 numOK=$((numOK+1))
6783 fi ;; # NUMCOND, feats
6784 esac
6785 N=$((N+1))
6788 NAME=RAWIP4RECVFROM
6789 case "$TESTS" in
6790 *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%rawip%*|*%rawip4%*|*%dgram%*|*%root%*|*%$NAME%*)
6791 TEST="$NAME: raw IPv4 datagram"
6792 if ! eval $NUMCOND; then :;
6793 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
6794 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
6795 numCANT=$((numCANT+1))
6796 listCANT="$listCANT $N"
6797 else
6798 tf="$td/test$N.stdout"
6799 te="$td/test$N.stderr"
6800 tdiff="$td/test$N.diff"
6801 ts1p=$PROTO; PROTO=$((PROTO+1))
6802 ts1a="127.0.0.1"
6803 ts1="$ts1a:$ts1p"
6804 ts2a="$SECONDADDR"
6805 ts2="$ts2a:$ts2p"
6806 da="test$N $(date) $RANDOM"
6807 CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
6808 CMD2="$TRACE $SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a"
6809 printf "test $F_n $TEST... " $N
6810 $CMD1 2>"${te}1" &
6811 pid1=$!
6812 waitip4proto $ts1p 1
6813 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6814 rc2=$?
6815 kill $pid1 2>/dev/null; wait
6816 if [ $rc2 -ne 0 ]; then
6817 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6818 echo "$CMD1 &"
6819 echo "$CMD2"
6820 cat "${te}1"
6821 cat "${te}2"
6822 numFAIL=$((numFAIL+1))
6823 listFAIL="$listFAIL $N"
6824 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6825 $PRINTF "$FAILED\n"
6826 cat "$tdiff"
6827 numFAIL=$((numFAIL+1))
6828 listFAIL="$listFAIL $N"
6829 else
6830 $PRINTF "$OK\n"
6831 if [ -n "$debug" ]; then cat $te; fi
6832 numOK=$((numOK+1))
6834 fi ;; # root, NUMCOND
6835 esac
6836 N=$((N+1))
6839 if false; then
6840 NAME=RAWIP6RECVFROM
6841 case "$TESTS" in
6842 *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%dgram%*|*%root%*|*%$NAME%*)
6843 TEST="$NAME: raw IPv6 datagram by self addressing"
6844 if ! eval $NUMCOND; then :;
6845 elif ! feat=$(testfeats ip6 rawip && runsip6); then
6846 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
6847 numCANT=$((numCANT+1))
6848 listCANT="$listCANT $N"
6849 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
6850 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
6851 numCANT=$((numCANT+1))
6852 listCANT="$listCANT $N"
6853 else
6854 tf="$td/test$N.stdout"
6855 te="$td/test$N.stderr"
6856 tdiff="$td/test$N.diff"
6857 ts1p=$PROTO; PROTO=$((PROTO+1))
6858 tsa="[::1]"
6859 ts1="$tsa:$ts1p"
6860 ts2="$tsa"
6861 da="test$N $(date) $RANDOM"
6862 #CMD1="$TRACE $SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
6863 CMD2="$TRACE $SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2"
6864 printf "test $F_n $TEST... " $N
6865 #$CMD1 2>"${te}1" &
6866 waitip6proto $ts1p 1
6867 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6868 if [ $? -ne 0 ]; then
6869 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6870 # echo "$CMD1 &"
6871 # cat "${te}1"
6872 echo "$CMD2"
6873 cat "${te}2"
6874 numFAIL=$((numFAIL+1))
6875 listFAIL="$listFAIL $N"
6876 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6877 $PRINTF "$FAILED\n"
6878 cat "$tdiff"
6879 numFAIL=$((numFAIL+1))
6880 listFAIL="$listFAIL $N"
6881 else
6882 $PRINTF "$OK\n"
6883 if [ -n "$debug" ]; then cat "$te"; fi
6884 numOK=$((numOK+1))
6886 fi ;; # root, NUMCOND
6887 esac
6888 N=$((N+1))
6889 fi #false
6892 NAME=UNIXDGRAM
6893 case "$TESTS" in
6894 *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%dgram%*|*%$NAME%*)
6895 TEST="$NAME: UNIX datagram"
6896 if ! eval $NUMCOND; then :; else
6897 tf="$td/test$N.stdout"
6898 te="$td/test$N.stderr"
6899 tdiff="$td/test$N.diff"
6900 ts1="$td/test$N.socket1"
6901 ts2="$td/test$N.socket2"
6902 da="test$N $(date) $RANDOM"
6903 CMD1="$TRACE $SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE"
6904 CMD2="$TRACE $SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2"
6905 printf "test $F_n $TEST... " $N
6906 $CMD1 2>"${te}1" &
6907 pid1="$!"
6908 waitfile $ts1 1
6909 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6910 rc2=$?
6911 kill "$pid1" 2>/dev/null; wait
6912 if [ $rc2 -ne 0 ]; then
6913 $PRINTF "$FAILED (rc=$rc2)\n"
6914 echo "$CMD1 &"
6915 cat "${te}1" >&2
6916 echo "$CMD2"
6917 cat "${te}2" >&2
6918 numFAIL=$((numFAIL+1))
6919 listFAIL="$listFAIL $N"
6920 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6921 $PRINTF "$FAILED (diff)\n"
6922 echo "$CMD1 &"
6923 cat "${te}1" >&2
6924 echo "$CMD2"
6925 cat "${te}2" >&2
6926 echo "// diff:" >&2
6927 cat "$tdiff" >&2
6928 numFAIL=$((numFAIL+1))
6929 listFAIL="$listFAIL $N"
6930 else
6931 $PRINTF "$OK\n"
6932 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
6933 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
6934 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
6935 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
6936 numOK=$((numOK+1))
6938 fi # NUMCOND
6940 esac
6941 N=$((N+1))
6944 NAME=UDP4RECV
6945 case "$TESTS" in
6946 *%$N%*|*%functions%*|*%engine%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*)
6947 TEST="$NAME: UDP/IPv4 receive"
6948 if ! eval $NUMCOND; then :; else
6949 tf="$td/test$N.stdout"
6950 te="$td/test$N.stderr"
6951 tdiff="$td/test$N.diff"
6952 newport udp4; ts1p=$PORT
6953 ts1a="127.0.0.1"
6954 ts1="$ts1a:$ts1p"
6955 da="test$N $(date) $RANDOM"
6956 CMD1="$TRACE $SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -"
6957 CMD2="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1"
6958 printf "test $F_n $TEST... " $N
6959 $CMD1 >"$tf" 2>"${te}1" &
6960 pid1="$!"
6961 waitudp4port $ts1p 1
6962 echo "$da" |$CMD2 2>>"${te}2"
6963 rc2="$?"
6964 #ls -l $tf
6965 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
6966 kill "$pid1" 2>/dev/null; wait
6967 if [ "$rc2" -ne 0 ]; then
6968 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6969 echo "$CMD1 &"
6970 echo "$CMD2"
6971 cat "${te}1"
6972 cat "${te}2"
6973 numFAIL=$((numFAIL+1))
6974 listFAIL="$listFAIL $N"
6975 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6976 $PRINTF "$FAILED\n"
6977 cat "$tdiff"
6978 echo "$CMD1 &"
6979 echo "$CMD2"
6980 cat "${te}1"
6981 cat "${te}2"
6982 numFAIL=$((numFAIL+1))
6983 listFAIL="$listFAIL $N"
6984 else
6985 $PRINTF "$OK\n"
6986 if [ -n "$debug" ]; then cat $te; fi
6987 numOK=$((numOK+1))
6989 fi # NUMCOND
6991 esac
6992 N=$((N+1))
6995 NAME=UDP6RECV
6996 case "$TESTS" in
6997 *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%udp%*|*%udp6%*|*%recv%*|*%$NAME%*)
6998 TEST="$NAME: UDP/IPv6 receive"
6999 if ! eval $NUMCOND; then :;
7000 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
7001 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
7002 numCANT=$((numCANT+1))
7003 listCANT="$listCANT $N"
7004 else
7005 tf="$td/test$N.stdout"
7006 te="$td/test$N.stderr"
7007 tdiff="$td/test$N.diff"
7008 newport udp6; ts1p=$PORT
7009 ts1a="[::1]"
7010 ts1="$ts1a:$ts1p"
7011 da="test$N $(date) $RANDOM"
7012 CMD1="$TRACE $SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -"
7013 CMD2="$TRACE $SOCAT $opts -u - UDP6-SENDTO:$ts1"
7014 printf "test $F_n $TEST... " $N
7015 $CMD1 >"$tf" 2>"${te}1" &
7016 pid1="$!"
7017 waitudp6port $ts1p 1
7018 echo "$da" |$CMD2 2>>"${te}2"
7019 rc2="$?"
7020 #ls -l $tf
7021 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
7022 kill "$pid1" 2>/dev/null; wait
7023 if [ "$rc2" -ne 0 ]; then
7024 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7025 echo "$CMD1 &"
7026 echo "$CMD2"
7027 cat "${te}1"
7028 cat "${te}2"
7029 numFAIL=$((numFAIL+1))
7030 listFAIL="$listFAIL $N"
7031 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7032 $PRINTF "$FAILED\n"
7033 cat "$tdiff"
7034 numFAIL=$((numFAIL+1))
7035 listFAIL="$listFAIL $N"
7036 else
7037 $PRINTF "$OK\n"
7038 if [ -n "$debug" ]; then cat $te; fi
7039 numOK=$((numOK+1))
7041 fi ;; # NUMCOND, feats
7042 esac
7043 N=$((N+1))
7046 NAME=RAWIP4RECV
7047 case "$TESTS" in
7048 *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*)
7049 TEST="$NAME: raw IPv4 receive"
7050 if ! eval $NUMCOND; then :;
7051 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7052 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7053 numCANT=$((numCANT+1))
7054 listCANT="$listCANT $N"
7055 else
7056 tf="$td/test$N.stdout"
7057 te="$td/test$N.stderr"
7058 tdiff="$td/test$N.diff"
7059 ts1p=$PROTO; PROTO=$((PROTO+1))
7060 ts1a="127.0.0.1"
7061 ts1="$ts1a:$ts1p"
7062 da="test$N $(date) $RANDOM"
7063 CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -"
7064 CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1"
7065 printf "test $F_n $TEST... " $N
7066 $CMD1 >"$tf" 2>"${te}1" &
7067 pid1="$!"
7068 waitip4proto $ts1p 1
7069 echo "$da" |$CMD2 2>>"${te}2"
7070 rc2="$?"
7071 #ls -l $tf
7072 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
7073 kill "$pid1" 2>/dev/null; wait
7074 if [ "$rc2" -ne 0 ]; then
7075 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7076 echo "$CMD1 &"
7077 echo "$CMD2"
7078 cat "${te}1"
7079 cat "${te}2"
7080 numFAIL=$((numFAIL+1))
7081 listFAIL="$listFAIL $N"
7082 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7083 $PRINTF "$FAILED\n"
7084 cat "$tdiff"
7085 numFAIL=$((numFAIL+1))
7086 listFAIL="$listFAIL $N"
7087 else
7088 $PRINTF "$OK\n"
7089 if [ -n "$debug" ]; then cat $te; fi
7090 numOK=$((numOK+1))
7092 fi ;; # NUMCOND, root
7093 esac
7094 N=$((N+1))
7097 NAME=RAWIP6RECV
7098 case "$TESTS" in
7099 *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%rawip%*|*%rawip6%*|*%recv%*|*%root%*|*%$NAME%*)
7100 TEST="$NAME: raw IPv6 receive"
7101 if ! eval $NUMCOND; then :;
7102 elif ! feat=$(testfeats ip6 rawip && runsip6); then
7103 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7104 numCANT=$((numCANT+1))
7105 listCANT="$listCANT $N"
7106 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7107 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7108 numCANT=$((numCANT+1))
7109 listCANT="$listCANT $N"
7110 else
7111 tf="$td/test$N.stdout"
7112 te="$td/test$N.stderr"
7113 tdiff="$td/test$N.diff"
7114 ts1p=$PROTO; PROTO=$((PROTO+1))
7115 ts1a="[::1]"
7116 ts1="$ts1a:$ts1p"
7117 da="test$N $(date) $RANDOM"
7118 CMD1="$TRACE $SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -"
7119 CMD2="$TRACE $SOCAT $opts -u - IP6-SENDTO:$ts1"
7120 printf "test $F_n $TEST... " $N
7121 $CMD1 >"$tf" 2>"${te}1" &
7122 pid1="$!"
7123 waitip6proto $ts1p 1
7124 echo "$da" |$CMD2 2>>"${te}2"
7125 rc2="$?"
7126 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
7127 kill "$pid1" 2>/dev/null; wait
7128 if [ "$rc2" -ne 0 ]; then
7129 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7130 echo "$CMD1 &"
7131 echo "$CMD2"
7132 cat "${te}1"
7133 cat "${te}2"
7134 numFAIL=$((numFAIL+1))
7135 listFAIL="$listFAIL $N"
7136 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7137 $PRINTF "$FAILED\n"
7138 cat "$tdiff"
7139 numFAIL=$((numFAIL+1))
7140 listFAIL="$listFAIL $N"
7141 else
7142 $PRINTF "$OK\n"
7143 if [ -n "$debug" ]; then cat $te; fi
7144 numOK=$((numOK+1))
7146 fi ;; # NUMCOND, root
7147 esac
7148 N=$((N+1))
7151 NAME=UNIXRECV
7152 case "$TESTS" in
7153 *%$N%*|*%functions%*|*%unix%*|*%dgram%*|*%recv%*|*%$NAME%*)
7154 TEST="$NAME: UNIX receive"
7155 if ! eval $NUMCOND; then :; else
7156 ts="$td/test$N.socket"
7157 tf="$td/test$N.stdout"
7158 te="$td/test$N.stderr"
7159 tdiff="$td/test$N.diff"
7160 ts1="$ts"
7161 da="test$N $(date) $RANDOM"
7162 CMD1="$TRACE $SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -"
7163 CMD2="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts1"
7164 printf "test $F_n $TEST... " $N
7165 $CMD1 >"$tf" 2>"${te}1" &
7166 pid1="$!"
7167 waitfile $ts1 1
7168 echo "$da" |$CMD2 2>>"${te}2"
7169 rc2="$?"
7170 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
7171 kill "$pid1" 2>/dev/null; wait
7172 if [ "$rc2" -ne 0 ]; then
7173 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7174 echo "$CMD1 &"
7175 echo "$CMD2"
7176 cat "${te}1"
7177 cat "${te}2"
7178 numFAIL=$((numFAIL+1))
7179 listFAIL="$listFAIL $N"
7180 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7181 $PRINTF "$FAILED\n"
7182 cat "$tdiff"
7183 numFAIL=$((numFAIL+1))
7184 listFAIL="$listFAIL $N"
7185 else
7186 $PRINTF "$OK\n"
7187 if [ -n "$debug" ]; then cat $te; fi
7188 numOK=$((numOK+1))
7190 fi # NUMCOND
7192 esac
7193 N=$((N+1))
7196 NAME=UDP4RECVFROM_SOURCEPORT
7197 case "$TESTS" in
7198 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*)
7199 TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option"
7200 if ! eval $NUMCOND; then :;
7201 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7202 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7203 numCANT=$((numCANT+1))
7204 listCANT="$listCANT $N"
7205 else
7206 newport udp4 # provide free port number in $PORT
7207 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7208 fi ;; # NUMCOND, feats
7209 esac
7210 N=$((N+1))
7212 NAME=UDP4RECVFROM_LOWPORT
7213 case "$TESTS" in
7214 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*)
7215 TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option"
7216 if ! eval $NUMCOND; then :;
7217 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7218 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7219 numCANT=$((numCANT+1))
7220 listCANT="$listCANT $N"
7221 else
7222 newport udp4 # provide free port number in $PORT
7223 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7224 fi ;; # NUMCOND, feats
7225 esac
7226 N=$((N+1))
7228 NAME=UDP4RECVFROM_RANGE
7229 case "$TESTS" in
7230 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*)
7231 TEST="$NAME: security of UDP4-RECVFROM with RANGE option"
7232 newport udp4 # provide free port number in $PORT
7233 #testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7234 if ! eval $NUMCOND; then :; else
7235 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7236 fi ;; # NUMCOND
7237 esac
7238 N=$((N+1))
7240 NAME=UDP4RECVFROM_TCPWRAP
7241 case "$TESTS" in
7242 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*)
7243 TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option"
7244 if ! eval $NUMCOND; then :;
7245 elif ! feat=$(testfeats ip4 udp libwrap) || ! runsip4 >/dev/null; then
7246 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7247 numCANT=$((numCANT+1))
7248 listCANT="$listCANT $N"
7249 else
7250 ha="$td/hosts.allow"
7251 hd="$td/hosts.deny"
7252 $ECHO "socat: $SECONDADDR" >"$ha"
7253 $ECHO "ALL: ALL" >"$hd"
7254 newport udp4 # provide free port number in $PORT
7255 #testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr,fork" "" "tcpwrap=$d" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7256 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7257 fi ;; # NUMCOND, feats
7258 esac
7259 N=$((N+1))
7262 NAME=UDP4RECV_SOURCEPORT
7263 case "$TESTS" in
7264 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*)
7265 TEST="$NAME: security of UDP4-RECV with SOURCEPORT option"
7266 if ! eval $NUMCOND; then :;
7267 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7268 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7269 numCANT=$((numCANT+1))
7270 listCANT="$listCANT $N"
7271 else
7272 newport udp4; PORT1=$PORT
7273 newport udp4; PORT2=$PORT
7274 newport udp4; PORT3=$PORT
7275 # we use the forward channel (PORT1) for testing, and have a backward channel
7276 # (PORT2) to get the data back, so we get the classical echo behaviour
7277 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
7278 fi ;; # NUMCOND, feats
7279 esac
7280 N=$((N+1))
7282 NAME=UDP4RECV_LOWPORT
7283 case "$TESTS" in
7284 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*)
7285 TEST="$NAME: security of UDP4-RECV with LOWPORT option"
7286 if ! eval $NUMCOND; then :;
7287 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7288 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7289 numCANT=$((numCANT+1))
7290 listCANT="$listCANT $N"
7291 else
7292 newport udp4; PORT1=$PORT
7293 newport udp4; PORT2=$PORT
7294 # we use the forward channel (PORT1) for testing, and have a backward channel
7295 # (PORT2) to get the data back, so we get the classical echo behaviour
7296 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
7297 fi ;; # NUMCOND, feats
7298 esac
7299 N=$((N+1))
7301 NAME=UDP4RECV_RANGE
7302 case "$TESTS" in
7303 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*)
7304 TEST="$NAME: security of UDP4-RECV with RANGE option"
7305 if ! eval $NUMCOND; then :;
7306 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7307 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7308 numCANT=$((numCANT+1))
7309 listCANT="$listCANT $N"
7310 else
7311 newport udp4; PORT1=$PORT
7312 newport udp4; PORT2=$PORT
7313 # we use the forward channel (PORT1) for testing, and have a backward channel
7314 # (PORT2) to get the data back, so we get the classical echo behaviour
7315 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
7316 fi ;; # NUMCOND, feats
7317 esac
7318 N=$((N+1))
7320 NAME=UDP4RECV_TCPWRAP
7321 case "$TESTS" in
7322 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*)
7323 TEST="$NAME: security of UDP4-RECV with TCPWRAP option"
7324 if ! eval $NUMCOND; then :;
7325 elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then
7326 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7327 numCANT=$((numCANT+1))
7328 listCANT="$listCANT $N"
7329 else
7330 newport udp4; PORT1=$PORT
7331 newport udp4; PORT2=$PORT
7332 ha="$td/hosts.allow"
7333 hd="$td/hosts.deny"
7334 $ECHO "socat: $SECONDADDR" >"$ha"
7335 $ECHO "ALL: ALL" >"$hd"
7336 # we use the forward channel (PORT1) for testing, and have a backward channel
7337 # (PORT2) to get the data back, so we get the classical echo behaviour
7338 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
7339 fi ;; # NUMCOND, feats
7340 esac
7341 N=$((N+1))
7344 NAME=UDP6RECVFROM_SOURCEPORT
7345 case "$TESTS" in
7346 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*)
7347 TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option"
7348 if ! eval $NUMCOND; then :;
7349 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7350 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7351 numCANT=$((numCANT+1))
7352 listCANT="$listCANT $N"
7353 else
7354 newport udp6 # provide free port number in $PORT
7355 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7356 fi ;; # NUMCOND, feats
7357 esac
7358 N=$((N+1))
7360 NAME=UDP6RECVFROM_LOWPORT
7361 case "$TESTS" in
7362 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*)
7363 TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option"
7364 if ! eval $NUMCOND; then :;
7365 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7366 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7367 numCANT=$((numCANT+1))
7368 listCANT="$listCANT $N"
7369 else
7370 newport udp6 # provide free port number in $PORT
7371 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7372 fi ;; # NUMCOND, feats
7373 esac
7374 N=$((N+1))
7376 NAME=UDP6RECVFROM_RANGE
7377 case "$TESTS" in
7378 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*)
7379 TEST="$NAME: security of UDP6-RECVFROM with RANGE option"
7380 if ! eval $NUMCOND; then :;
7381 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
7382 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
7383 numCANT=$((numCANT+1))
7384 listCANT="$listCANT $N"
7385 else
7386 newport udp6 # provide free port number in $PORT
7387 #testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7388 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7389 fi ;; # NUMCOND, feats
7390 esac
7391 N=$((N+1))
7393 NAME=UDP6RECVFROM_TCPWRAP
7394 case "$TESTS" in
7395 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*)
7396 TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option"
7397 if ! eval $NUMCOND; then :;
7398 elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then
7399 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7400 numCANT=$((numCANT+1))
7401 listCANT="$listCANT $N"
7402 else
7403 ha="$td/hosts.allow"
7404 hd="$td/hosts.deny"
7405 $ECHO "socat: [::2]" >"$ha"
7406 $ECHO "ALL: ALL" >"$hd"
7407 newport udp6 # provide free port number in $PORT
7408 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7409 fi ;; # NUMCOND, feats
7410 esac
7411 N=$((N+1))
7414 NAME=UDP6RECV_SOURCEPORT
7415 case "$TESTS" in
7416 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*)
7417 TEST="$NAME: security of UDP6-RECV with SOURCEPORT option"
7418 if ! eval $NUMCOND; then :;
7419 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7420 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7421 numCANT=$((numCANT+1))
7422 listCANT="$listCANT $N"
7423 else
7424 newport udp6; PORT1=$PORT
7425 newport udp6; PORT2=$PORT
7426 newport udp6; PORT3=$PORT
7427 # we use the forward channel (PORT1) for testing, and have a backward channel
7428 # (PORT2) to get the data back, so we get the classical echo behaviour
7429 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
7430 fi ;; # NUMCOND, feats
7431 esac
7432 N=$((N+1))
7434 NAME=UDP6RECV_LOWPORT
7435 case "$TESTS" in
7436 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*)
7437 TEST="$NAME: security of UDP6-RECV with LOWPORT option"
7438 if ! eval $NUMCOND; then :;
7439 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7440 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7441 numCANT=$((numCANT+1))
7442 listCANT="$listCANT $N"
7443 else
7444 newport udp6; PORT1=$PORT
7445 newport udp6; PORT2=$PORT
7446 # we use the forward channel (PORT1) for testing, and have a backward channel
7447 # (PORT2) to get the data back, so we get the classical echo behaviour
7448 testserversec "$N" "$TEST" "$opts" "UDP6-RECV:$PORT1,reuseaddr!!UDP6-SENDTO:[::1]:$PORT2" "" "lowport" "UDP6-RECV:$PORT2!!UDP6-SENDTO:[::1]:$PORT1" 6 udp $PORT1 0
7449 fi ;; # NUMCOND, feats
7450 esac
7451 N=$((N+1))
7453 NAME=UDP6RECV_RANGE
7454 case "$TESTS" in
7455 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*)
7456 TEST="$NAME: security of UDP6-RECV with RANGE option"
7457 if ! eval $NUMCOND; then :;
7458 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7459 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7460 numCANT=$((numCANT+1))
7461 listCANT="$listCANT $N"
7462 else
7463 newport udp6; PORT1=$PORT
7464 newport udp6; PORT2=$PORT
7465 # we use the forward channel (PORT1) for testing, and have a backward channel
7466 # (PORT2) to get the data back, so we get the classical echo behaviour
7467 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
7468 fi ;; # NUMCOND, feats
7469 esac
7470 N=$((N+1))
7472 NAME=UDP6RECV_TCPWRAP
7473 case "$TESTS" in
7474 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*)
7475 TEST="$NAME: security of UDP6-RECV with TCPWRAP option"
7476 if ! eval $NUMCOND; then :;
7477 elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then
7478 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7479 numCANT=$((numCANT+1))
7480 listCANT="$listCANT $N"
7481 else
7482 ha="$td/hosts.allow"
7483 hd="$td/hosts.deny"
7484 $ECHO "socat: [::2]" >"$ha"
7485 $ECHO "ALL: ALL" >"$hd"
7486 newport udp6; PORT1=$PORT
7487 newport udp6; PORT2=$PORT
7488 # we use the forward channel (PORT1) for testing, and have a backward channel
7489 # (PORT2) to get the data back, so we get the classical echo behaviour
7490 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
7491 fi ;; # NUMCOND, feats
7492 esac
7493 N=$((N+1))
7496 NAME=IP4RECVFROM_RANGE
7497 case "$TESTS" in
7498 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*)
7499 TEST="$NAME: security of IP4-RECVFROM with RANGE option"
7500 if ! eval $NUMCOND; then :;
7501 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
7502 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7503 numCANT=$((numCANT+1))
7504 listCANT="$listCANT $N"
7505 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7506 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7507 numCANT=$((numCANT+1))
7508 listCANT="$listCANT $N"
7509 else
7510 newport udp4 # provide free port number in $PORT
7511 #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$PROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "IP4-SENDTO:127.0.0.1:$PROTO" 4 ip $PROTO 0
7512 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
7513 fi ;; # NUMCOND, feats, root
7514 esac
7515 PROTO=$((PROTO+1))
7516 N=$((N+1))
7518 NAME=IP4RECVFROM_TCPWRAP
7519 case "$TESTS" in
7520 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7521 TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option"
7522 if ! eval $NUMCOND; then :;
7523 elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then
7524 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7525 numCANT=$((numCANT+1))
7526 listCANT="$listCANT $N"
7527 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7528 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7529 numCANT=$((numCANT+1))
7530 listCANT="$listCANT $N"
7531 else
7532 ha="$td/hosts.allow"
7533 hd="$td/hosts.deny"
7534 $ECHO "socat: $SECONDADDR" >"$ha"
7535 $ECHO "ALL: ALL" >"$hd"
7536 newport udp4 # provide free port number in $PORT
7537 #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "IP4-SENDTO:127.0.0.1:$PROTO" 4 ip $PROTO 0
7538 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
7539 fi # NUMCOND, feats, root
7541 esac
7542 PROTO=$((PROTO+1))
7543 N=$((N+1))
7546 NAME=IP4RECV_RANGE
7547 case "$TESTS" in
7548 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*)
7549 TEST="$NAME: security of IP4-RECV with RANGE option"
7550 if ! eval $NUMCOND; then :;
7551 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
7552 $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
7553 numCANT=$((numCANT+1))
7554 listCANT="$listCANT $N"
7555 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7556 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7557 numCANT=$((numCANT+1))
7558 listCANT="$listCANT $N"
7559 else
7560 PROTO1=$PROTO; PROTO=$((PROTO+1))
7561 PROTO2=$PROTO
7562 # we use the forward channel (PROTO1) for testing, and have a backward channel
7563 # (PROTO2) to get the data back, so we get the classical echo behaviour
7564 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
7565 fi ;; # NUMCOND, feats, root
7566 esac
7567 PROTO=$((PROTO+1))
7568 N=$((N+1))
7572 NAME=IP4RECV_TCPWRAP
7573 case "$TESTS" in
7574 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7575 TEST="$NAME: security of IP4-RECV with TCPWRAP option"
7576 if ! eval $NUMCOND; then :;
7577 elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then
7578 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7579 numCANT=$((numCANT+1))
7580 listCANT="$listCANT $N"
7581 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7582 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7583 numCANT=$((numCANT+1))
7584 listCANT="$listCANT $N"
7585 else
7586 PROTO1=$PROTO; PROTO=$((PROTO+1))
7587 PROTO2=$PROTO
7588 ha="$td/hosts.allow"
7589 hd="$td/hosts.deny"
7590 $ECHO "socat: $SECONDADDR" >"$ha"
7591 $ECHO "ALL: ALL" >"$hd"
7592 # we use the forward channel (PROTO1) for testing, and have a backward channel
7593 # (PROTO2) to get the data back, so we get the classical echo behaviour
7594 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
7595 fi ;; # NUMCOND, feats, root
7596 esac
7597 PROTO=$((PROTO+1))
7598 N=$((N+1))
7601 NAME=IP6RECVFROM_RANGE
7602 case "$TESTS" in
7603 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*)
7604 TEST="$NAME: security of IP6-RECVFROM with RANGE option"
7605 if ! eval $NUMCOND; then :;
7606 elif ! feat=$(testfeats ip6 rawip && runsip6); then
7607 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7608 numCANT=$((numCANT+1))
7609 listCANT="$listCANT $N"
7610 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7611 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7612 numCANT=$((numCANT+1))
7613 listCANT="$listCANT $N"
7614 else
7615 newport udp6 # provide free port number in $PORT
7616 #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$PROTO,reuseaddr,fork" "" "range=[::2]/128" "IP6-SENDTO:[::1]:$PROTO" 6 ip $PROTO 0
7617 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
7618 fi ;; # NUMCOND, feats
7619 esac
7620 PROTO=$((PROTO+1))
7621 N=$((N+1))
7623 NAME=IP6RECVFROM_TCPWRAP
7624 case "$TESTS" in
7625 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7626 TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option"
7627 if ! eval $NUMCOND; then :;
7628 elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then
7629 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7630 numCANT=$((numCANT+1))
7631 listCANT="$listCANT $N"
7632 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7633 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7634 numCANT=$((numCANT+1))
7635 listCANT="$listCANT $N"
7636 else
7637 ha="$td/hosts.allow"
7638 hd="$td/hosts.deny"
7639 $ECHO "socat: [::2]" >"$ha"
7640 $ECHO "ALL: ALL" >"$hd"
7641 newport udp6 # provide free port number in $PORT
7642 #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$PROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "IP6-SENDTO:[::1]:$PROTO" 6 ip $PROTO 0
7643 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
7644 fi ;; # NUMCOND, feats
7645 esac
7646 PROTO=$((PROTO+1))
7647 N=$((N+1))
7650 NAME=IP6RECV_RANGE
7651 case "$TESTS" in
7652 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*)
7653 TEST="$NAME: security of IP6-RECV with RANGE option"
7654 if ! eval $NUMCOND; then :;
7655 elif ! feat=$(testfeats ip6 rawip) || ! runsip6 >/dev/null; then
7656 $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N
7657 numCANT=$((numCANT+1))
7658 listCANT="$listCANT $N"
7659 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7660 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7661 numCANT=$((numCANT+1))
7662 listCANT="$listCANT $N"
7663 else
7664 PROTO1=$PROTO; PROTO=$((PROTO+1))
7665 PROTO2=$PROTO
7666 # we use the forward channel (PROTO1) for testing, and have a backward channel
7667 # (PROTO2) to get the data back, so we get the classical echo behaviour
7668 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
7669 fi ;; # NUMCOND, feats
7670 esac
7671 PROTO=$((PROTO+1))
7672 N=$((N+1))
7674 NAME=IP6RECV_TCPWRAP
7675 case "$TESTS" in
7676 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7677 TEST="$NAME: security of IP6-RECV with TCPWRAP option"
7678 if ! eval $NUMCOND; then :;
7679 elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then
7680 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7681 numCANT=$((numCANT+1))
7682 listCANT="$listCANT $N"
7683 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7684 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7685 numCANT=$((numCANT+1))
7686 listCANT="$listCANT $N"
7687 else
7688 PROTO1=$PROTO; PROTO=$((PROTO+1))
7689 PROTO2=$PROTO
7690 ha="$td/hosts.allow"
7691 hd="$td/hosts.deny"
7692 $ECHO "socat: [::2]" >"$ha"
7693 $ECHO "ALL: ALL" >"$hd"
7694 # we use the forward channel (PROTO1) for testing, and have a backward channel
7695 # (PROTO2) to get the data back, so we get the classical echo behaviour
7696 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
7697 fi ;; # NUMCOND, feats
7698 esac
7699 PROTO=$((PROTO+1))
7700 N=$((N+1))
7703 NAME=O_NOATIME_FILE
7704 case "$TESTS" in
7705 *%$N%*|*%functions%*|*%open%*|*%noatime%*|*%$NAME%*)
7706 TEST="$NAME: option O_NOATIME on file"
7707 # idea: create a file with o-noatime option; one second later create a file
7708 # without this option (using touch); one second later read from the first file.
7709 # Then we check which file has the later ATIME stamp. For this check we use
7710 # "ls -ltu" because it is more portable than "test ... -nt ..."
7711 if ! eval $NUMCOND; then :;
7712 elif ! testoptions o-noatime >/dev/null; then
7713 $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N
7714 numCANT=$((numCANT+1))
7715 listCANT="$listCANT $N"
7716 else
7717 tf="$td/test$N.file"
7718 te="$td/test$N.stderr"
7719 tdiff="$td/test$N.diff"
7720 da="test$N $(date) $RANDOM"
7721 $PRINTF "test $F_n $TEST... " $N
7722 CMD="$TRACE $SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null"
7723 # generate a file
7724 touch "${tf}1"
7725 sleep 1
7726 # generate a reference file
7727 touch "${tf}2"
7728 sleep 1
7729 # read from the first file
7730 $CMD 2>"$te"
7731 if [ $? -ne 0 ]; then # command failed
7732 $PRINTF "${FAILED}:\n"
7733 echo "$CMD"
7734 cat "$te"
7735 numFAIL=$((numFAIL+1))
7736 listFAIL="$listFAIL $N"
7737 else
7738 # check which file has a later atime stamp
7739 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
7740 then
7741 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7742 echo "$CMD"
7743 cat "$te"
7744 numFAIL=$((numFAIL+1))
7745 listFAIL="$listFAIL $N"
7746 else
7747 $PRINTF "$OK\n"
7748 if [ -n "$debug" ]; then cat "$te"; fi
7749 numOK=$((numOK+1))
7750 fi # wrong time stamps
7751 fi # command ok
7752 fi ;; # NUMCOND, feats
7753 esac
7754 N=$((N+1))
7756 NAME=O_NOATIME_FD
7757 case "$TESTS" in
7758 *%$N%*|*%functions%*|*%noatime%*|*%$NAME%*)
7759 TEST="$NAME: option O_NOATIME on file descriptor"
7760 # idea: use a fd of a file with o-noatime option; one second later create a file
7761 # without this option (using touch); one second later read from the first file.
7762 # Then we check which file has the later ATIME stamp. For this check we use
7763 # "ls -ltu" because it is more portable than "test ... -nt ..."
7764 if ! eval $NUMCOND; then :;
7765 elif ! testoptions o-noatime >/dev/null; then
7766 $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N
7767 numCANT=$((numCANT+1))
7768 listCANT="$listCANT $N"
7769 else
7770 tf="$td/test$N.file"
7771 te="$td/test$N.stderr"
7772 tdiff="$td/test$N.diff"
7773 da="test$N $(date) $RANDOM"
7774 $PRINTF "test $F_n $TEST... " $N
7775 touch ${tf}1
7776 CMD="$TRACE $SOCAT $opts -u -,o-noatime /dev/null <${tf}1"
7777 # generate a file, len >= 1
7778 touch "${tf}1"
7779 sleep 1
7780 # generate a reference file
7781 touch "${tf}2"
7782 sleep 1
7783 # read from the first file
7784 sh -c "$CMD" 2>"$te"
7785 rc=$?
7786 if [ $rc -ne 0 ]; then # command failed
7787 $PRINTF "${FAILED} (rc=$rc):\n"
7788 echo "$CMD"
7789 cat "$te" >&2
7790 numFAIL=$((numFAIL+1))
7791 listFAIL="$listFAIL $N"
7792 else
7793 # check which file has a later atime stamp
7794 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
7795 then
7796 $PRINTF "$FAILED (bad order):\n"
7797 echo "$CMD" >&2
7798 cat "$te"
7799 numFAIL=$((numFAIL+1))
7800 listFAIL="$listFAIL $N"
7801 else
7802 $PRINTF "$OK\n"
7803 if [ "$VERBOSE" ]; then echo "$CMD"; fi
7804 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
7805 numOK=$((numOK+1))
7806 fi # wrong time stamps
7807 fi # command ok
7808 fi ;; # NUMCOND, feats
7809 esac
7810 N=$((N+1))
7812 NAME=FS_NOATIME
7813 case "$TESTS" in
7814 *%$N%*|*%functions%*|*%fs%*|*%noatime%*|*%$NAME%*)
7815 TEST="$NAME: extended file system options using fs noatime option"
7816 # idea: create a file with fs-noatime option; one second later create a file
7817 # without this option (using touch); one second later read from the first file.
7818 # Then we check which file has the later ATIME stamp. For this check we use
7819 # "ls -ltu" because it is more portable than "test ... -nt ..."
7820 if ! eval $NUMCOND; then :;
7821 elif ! testoptions fs-noatime >/dev/null; then
7822 $PRINTF "test $F_n $TEST... ${YELLOW}fs-noatime not available${NORMAL}\n" $N
7823 numCANT=$((numCANT+1))
7824 listCANT="$listCANT $N"
7825 else
7826 ts="$td/test$N.socket"
7827 tf="$td/test$N.file"
7828 te="$td/test$N.stderr"
7829 tdiff="$td/test$N.diff"
7830 ts1="$ts"
7831 da="test$N $(date) $RANDOM"
7832 $PRINTF "test $F_n $TEST... " $N
7833 CMD0="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\""
7834 CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",fs-noatime"
7835 # check if this is a capable FS; lsattr does other things on AIX, thus socat
7836 $CMD0 2>"${te}0"
7837 if [ $? -ne 0 ]; then
7838 $PRINTF "${YELLOW} cannot test${NORMAL}\n"
7839 numCANT=$((numCANT+1))
7840 listCANT="$listCANT $N"
7841 else
7842 # generate a file with noatime, len >= 1
7843 $CMD 2>"$te"
7844 if [ $? -ne 0 ]; then # command failed
7845 $PRINTF "${YELLOW}impotent file system?${NORMAL}\n"
7846 echo "$CMD"
7847 cat "$te"
7848 numCANT=$((numCANT+1))
7849 listCANT="$listCANT $N"
7850 else
7851 sleep 1
7852 # generate a reference file
7853 touch "${tf}2"
7854 sleep 1
7855 # read from the first file
7856 cat "${tf}1" >/dev/null
7857 # check which file has a later atime stamp
7858 #if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |awk '{print($8);}') != "${tf}2" ];
7859 if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |sed "s|.*\\($td.*\\)|\1|g") != "${tf}2" ];
7860 then
7861 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7862 echo "$CMD"
7863 cat "$te"
7864 numFAIL=$((numFAIL+1))
7865 listFAIL="$listFAIL $N"
7866 else
7867 $PRINTF "$OK\n"
7868 if [ -n "$debug" ]; then cat "$te"; fi
7869 numOK=$((numOK+1))
7871 fi # not impotent
7872 fi # can test
7873 fi ;; # NUMCOND, feats
7874 esac
7875 N=$((N+1))
7878 NAME=COOLWRITE
7879 case "$TESTS" in
7880 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*)
7881 TEST="$NAME: option cool-write"
7882 if ! eval $NUMCOND; then :;
7883 elif ! testoptions cool-write >/dev/null; then
7884 $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N
7885 numCANT=$((numCANT+1))
7886 listCANT="$listCANT $N"
7887 else
7888 #set -vx
7889 ti="$td/test$N.pipe"
7890 tf="$td/test$N.stdout"
7891 te="$td/test$N.stderr"
7892 tdiff="$td/test$N.diff"
7893 da="test$N $(date) $RANDOM"
7894 # a reader that will terminate after 1 byte
7895 CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
7896 CMD="$TRACE $SOCAT $opts -u - file:\"$ti\",cool-write"
7897 printf "test $F_n $TEST... " $N
7898 $CMD1 2>"${te}1" &
7899 bg=$! # background process id
7900 sleep 1
7901 (echo .; sleep 1; echo) |$CMD 2>"$te"
7902 rc=$?
7903 kill $bg 2>/dev/null; wait
7904 if [ $rc -ne 0 ]; then
7905 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7906 echo "$CMD &"
7907 cat "$te"
7908 numFAIL=$((numFAIL+1))
7909 listFAIL="$listFAIL $N"
7910 else
7911 $PRINTF "$OK\n"
7912 if [ -n "$debug" ]; then cat "$te"; fi
7913 numOK=$((numOK+1))
7915 fi ;; # NUMCOND, feats
7916 esac
7917 N=$((N+1))
7920 # test if option coolwrite can be applied to bidirectional address stdio
7921 # this failed up to socat 1.6.0.0
7922 NAME=COOLSTDIO
7923 case "$TESTS" in
7924 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*)
7925 TEST="$NAME: option cool-write on bidirectional stdio"
7926 # this test starts a socat reader that terminates after receiving one+
7927 # bytes (option readbytes); and a test process that sends two bytes via
7928 # named pipe to the receiving process and, a second later, sends another
7929 # byte. The last write will fail with "broken pipe"; if option coolwrite
7930 # has been applied successfully, socat will terminate with 0 (OK),
7931 # otherwise with error.
7932 if ! eval $NUMCOND; then :;
7933 elif ! testoptions cool-write >/dev/null; then
7934 $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N
7935 numCANT=$((numCANT+1))
7936 listCANT="$listCANT $N"
7937 else
7938 #set -vx
7939 ti="$td/test$N.pipe"
7940 tf="$td/test$N.stdout"
7941 te="$td/test$N.stderr"
7942 tdiff="$td/test$N.diff"
7943 da="test$N $(date) $RANDOM"
7944 # a reader that will terminate after 1 byte
7945 CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
7946 CMD="$TRACE $SOCAT $opts -,cool-write pipe >\"$ti\""
7947 printf "test $F_n $TEST... " $N
7948 $CMD1 2>"${te}1" &
7949 bg=$! # background process id
7950 sleep 1
7951 (echo .; sleep 1; echo) |eval "$CMD" 2>"$te"
7952 rc=$?
7953 kill $bg 2>/dev/null; wait
7954 if [ $rc -ne 0 ]; then
7955 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7956 echo "$CMD1 &"
7957 cat "${te}1"
7958 echo "$CMD"
7959 cat "$te"
7960 numFAIL=$((numFAIL+1))
7961 listFAIL="$listFAIL $N"
7962 else
7963 $PRINTF "$OK\n"
7964 if [ -n "$debug" ]; then cat "$te"; fi
7965 numOK=$((numOK+1))
7967 fi ;; # NUMCOND, feats
7968 esac
7969 N=$((N+1))
7972 NAME=TCP4ENDCLOSE
7973 case "$TESTS" in
7974 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%fork%*|*%$NAME%*)
7975 TEST="$NAME: end-close keeps TCP V4 socket open"
7976 if ! eval $NUMCOND; then :; else
7977 tf="$td/test$N.stdout"
7978 te="$td/test$N.stderr"
7979 tdiff="$td/test$N.diff"
7980 newport tcp4; p0=$PORT
7981 newport tcp4; p1=$PORT
7982 da2a="$(date) $RANDOM"
7983 da2b="$(date) $RANDOM"
7984 CMD0="$TRACE $SOCAT -lp collector $opts -u TCP4-LISTEN:$p0,$REUSEADDR,bind=$LOCALHOST -"
7985 CMD1="$TRACE $SOCAT -lp forker $opts -U TCP4:$LOCALHOST:$p0,end-close TCP4-LISTEN:$p1,bind=$LOCALHOST,$REUSEADDR,fork"
7986 CMD2="$TRACE $SOCAT -lp client $opts -u - TCP4-CONNECT:$LOCALHOST:$p1"
7987 printf "test $F_n $TEST... " $N
7988 $CMD0 >"${tf}0" 2>"${te}0" &
7989 pid0=$!
7990 waittcp4port $p0 1
7991 $CMD1 2>"${te}1" &
7992 pid1=$!
7993 usleep $MICROS
7994 waittcp4port $p1 1
7995 echo "$da2a" |$CMD2 2>>"${te}2a"
7996 rc2a=$?
7997 echo "$da2b" |$CMD2 2>>"${te}2b"
7998 rc2b=$?
7999 sleep 1
8000 kill "$pid0" "$pid1" 2>/dev/null
8001 wait
8002 if [ $rc2a -ne 0 -o $rc2b -ne 0 ]; then
8003 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8004 echo "$CMD0 &"
8005 cat "${te}0" >&2
8006 echo "$CMD1"
8007 cat "${te}1" >&2
8008 echo "$CMD2"
8009 cat "${te}2a" >&2
8010 echo "$CMD2"
8011 cat "${te}2b" >&2
8012 numFAIL=$((numFAIL+1))
8013 listFAIL="$listFAIL $N"
8014 elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then
8015 $PRINTF "$FAILED (diff)\n"
8016 echo "$CMD0 &"
8017 cat "${te}0" >&2
8018 echo "$CMD1"
8019 cat "${te}1" >&2
8020 echo "$CMD2"
8021 cat "${te}2a" >&2
8022 echo "$CMD2"
8023 cat "${te}2b" >&2
8024 cat "$tdiff"
8025 numFAIL=$((numFAIL+1))
8026 listFAIL="$listFAIL $N"
8027 else
8028 $PRINTF "$OK\n"
8029 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
8030 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
8031 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8032 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8033 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8034 if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi
8035 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8036 if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi
8037 numOK=$((numOK+1))
8039 fi ;; # NUMCOND
8040 esac
8041 N=$((N+1))
8044 NAME=EXECENDCLOSE
8045 case "$TESTS" in
8046 *%$N%*|*%functions%*|*%exec%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*)
8047 TEST="$NAME: end-close keeps EXEC child running"
8048 if ! eval $NUMCOND; then :; else
8049 tf="$td/test$N.stdout"
8050 te="$td/test$N.stderr"
8051 ts="$td/test$N.sock"
8052 tdiff="$td/test$N.diff"
8053 da1a="$(date) $RANDOM"
8054 da1b="$(date) $RANDOM"
8055 CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$ts"
8056 CMD="$TRACE $SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork"
8057 printf "test $F_n $TEST... " $N
8058 $CMD 2>"${te}2" &
8059 pid2=$!
8060 waitfile $ts 1
8061 echo "$da1a" |$CMD1 2>>"${te}1a" >"$tf"
8062 usleep $MICROS
8063 echo "$da1b" |$CMD1 2>>"${te}1b" >>"$tf"
8064 #usleep $MICROS
8065 kill "$pid2" 2>/dev/null
8066 wait
8067 if [ $? -ne 0 ]; then
8068 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8069 echo "$CMD1 &"
8070 echo "$CMD2"
8071 cat "${te}1a" "${te}1b" "${te}2"
8072 numFAIL=$((numFAIL+1))
8073 listFAIL="$listFAIL $N"
8074 elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then
8075 $PRINTF "$FAILED\n"
8076 cat "$tdiff"
8077 cat "${te}1a" "${te}1b" "${te}2"
8078 numFAIL=$((numFAIL+1))
8079 listFAIL="$listFAIL $N"
8080 else
8081 $PRINTF "$OK\n"
8082 if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi
8083 numOK=$((numOK+1))
8085 fi ;; # NUMCOND
8086 esac
8087 N=$((N+1))
8090 # up to 1.7.0.0 option end-close led to an error with some address types due to
8091 # bad internal handling. here we check it for address PTY
8092 NAME=PTYENDCLOSE
8093 case "$TESTS" in
8094 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
8095 TEST="$NAME: PTY handles option end-close"
8096 # with the bug, socat exits with error. we invoke socat in a no-op mode and
8097 # check its return status.
8098 if ! eval $NUMCOND; then :;
8099 else
8100 tf="$td/test$N.stout"
8101 te="$td/test$N.stderr"
8102 # -t must be longer than 0.1 on OpenBSD
8103 CMD="$TRACE $SOCAT $opts -d -d -t 0.5 /dev/null pty,end-close"
8104 printf "test $F_n $TEST... " $N
8105 # AIX reports the pty writeable for select() only when its slave side has been
8106 # opened, therefore we run this process in background and check its NOTICE
8107 # output for the PTY name
8108 { $CMD 2>"${te}"; echo $? >"$td/test$N.rc0"; } &
8109 waitfile "${te}"
8110 psleep 0.5 # 0.1 is too few for FreeBSD-10
8111 PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //')
8112 # So this for AIX? but "cat" hangs on OpenBSD, thus use socat with timeout instead
8113 [ -e "$PTY" ] && $SOCAT -T 0.1 -u $PTY,o-nonblock - >/dev/null 2>/dev/null
8114 rc=$(cat "$td/test$N.rc0")
8115 if [ "$rc" = 0 ]; then
8116 $PRINTF "$OK\n"
8117 numOK=$((numOK+1))
8118 else
8119 $PRINTF "$FAILED\n"
8120 echo "$CMD"
8121 cat "${te}"
8122 numFAIL=$((numFAIL+1))
8123 listFAIL="$listFAIL $N"
8125 fi # NUMCOND
8127 esac
8128 N=$((N+1))
8131 # Test the shut-null and null-eof options
8132 NAME=SHUTNULLEOF
8133 case "$TESTS" in
8134 *%$N%*|*%functions%*|*%socket%*|*%$NAME%*)
8135 TEST="$NAME: options shut-null and null-eof"
8136 # Run a receiving background process with option null-eof.
8137 # Start a sending process with option shut-null that sends a test record to the
8138 # receiving process and then terminates.
8139 # Send another test record.
8140 # When the receiving process only received and stored the first test record the
8141 # test succeeded
8142 if ! eval $NUMCOND; then :; else
8143 tf="$td/test$N.stout"
8144 te="$td/test$N.stderr"
8145 tdiff="$td/test$N.diff"
8146 da="test$N $(date) $RANDOM"
8147 newport udp4 # provide free port number in $PORT
8148 CMD0="$TRACE $SOCAT $opts -u UDP4-RECV:$PORT,null-eof CREAT:$tf"
8149 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:127.0.0.1:$PORT,shut-null"
8150 printf "test $F_n $TEST... " $N
8151 $CMD0 >/dev/null 2>"${te}0" &
8152 pid0=$!
8153 waitudp4port $PORT 1
8154 { echo "$da"; psleep 0.1; } |$CMD1 >"${tf}1" 2>"${te}1"
8155 rc1=$?
8156 { echo "xyz"; psleep 0.1; } |$CMD1 >"${tf}2" 2>"${te}2"
8157 rc2=$?
8158 kill $pid0 2>/dev/null; wait
8159 if [ $rc1 != 0 -o $rc2 != 0 ]; then
8160 $PRINTF "$FAILED (client(s) failed)\n"
8161 echo "$CMD0 &"
8162 cat "${te}0" >&2
8163 echo "$CMD1"
8164 cat "${te}1" >&2
8165 echo "$CMD1"
8166 cat "${te}2" >&2
8167 numFAIL=$((numFAIL+1))
8168 listFAIL="$listFAIL $N"
8169 elif echo "$da" |diff - "${tf}" >"$tdiff"; then
8170 $PRINTF "$OK\n"
8171 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
8172 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
8173 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
8174 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8175 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8176 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8177 numOK=$((numOK+1))
8178 else
8179 $PRINTF "$FAILED (diff)\n"
8180 echo "$CMD0 &"
8181 cat "${te}0" >&2
8182 echo "$CMD1"
8183 cat "${te}1" >&2
8184 echo "$CMD2"
8185 cat "${te}2" >&2
8186 echo "// diff:" >&2
8187 cat "${tdiff}" >&2
8188 numFAIL=$((numFAIL+1))
8189 listFAIL="$listFAIL $N"
8191 fi # NUMCOND
8193 esac
8194 N=$((N+1))
8197 NAME=UDP6LISTENBIND
8198 # this tests for a bug in (up to) 1.5.0.0:
8199 # with udp*-listen, the bind option supported only IPv4
8200 case "$TESTS" in
8201 *%$N%*|*%functions%*|*%bugs%*|*%ip6%*|*%ipapp%*|*%udp%*|*%udp6%*|*%listen%*|*%$NAME%*)
8202 TEST="$NAME: UDP6-LISTEN with bind"
8203 if ! eval $NUMCOND; then :;
8204 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
8205 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
8206 numCANT=$((numCANT+1))
8207 listCANT="$listCANT $N"
8208 else
8209 tf="$td/test$N.stdout"
8210 te="$td/test$N.stderr"
8211 tdiff="$td/test$N.diff"
8212 newport udp6; tsl=$PORT
8213 ts="$LOCALHOST6:$tsl"
8214 da="test$N $(date) $RANDOM"
8215 CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,$REUSEADDR,bind=$LOCALHOST6 PIPE"
8216 CMD2="$TRACE $SOCAT $opts - UDP6:$ts"
8217 printf "test $F_n $TEST... " $N
8218 $CMD1 >"$tf" 2>"${te}1" &
8219 pid1=$!
8220 waitudp6port $tsl 1
8221 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8222 rc2=$?
8223 kill $pid1 2>/dev/null; wait
8224 if [ $rc2 -ne 0 ]; then
8225 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8226 echo "$CMD1 &"
8227 echo "$CMD2"
8228 cat "${te}1" "${te}2"
8229 numFAIL=$((numFAIL+1))
8230 listFAIL="$listFAIL $N"
8231 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8232 $PRINTF "$FAILED\n"
8233 cat "$tdiff"
8234 numFAIL=$((numFAIL+1))
8235 listFAIL="$listFAIL $N"
8236 else
8237 $PRINTF "$OK\n"
8238 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
8239 numOK=$((numOK+1))
8241 fi ;; # NUMCOND, feats
8242 esac
8243 N=$((N+1))
8246 NAME=TCPWRAPPERS_MULTIOPTS
8247 # this tests for a bug in 1.5.0.0 that let socat fail when more than one
8248 # tcp-wrappers related option was specified in one address
8249 case "$TESTS" in
8250 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
8251 TEST="$NAME: use of multiple tcpwrapper enabling options"
8252 if ! eval $NUMCOND; then :;
8253 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
8254 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8255 numCANT=$((numCANT+1))
8256 listCANT="$listCANT $N"
8257 else
8258 tf="$td/test$N.stdout"
8259 te="$td/test$N.stderr"
8260 tdiff="$td/test$N.diff"
8261 da="test$N $(date) $RANDOM"
8262 ha="$td/hosts.allow"
8263 $ECHO "test : ALL : allow" >"$ha"
8264 newport tcp4 # provide free port number in $PORT
8265 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR,hosts-allow=$ha,tcpwrap=test pipe"
8266 CMD2="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
8267 printf "test $F_n $TEST... " $N
8268 $CMD1 2>"${te}1" &
8269 pid1=$!
8270 waittcp4port $PORT
8271 echo "$da" |$CMD2 >"$tf" 2>"${te}2"
8272 rc2=$?
8273 kill $pid1 2>/dev/null; wait
8274 if [ $rc2 -ne 0 ]; then
8275 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8276 echo "$CMD1 &"
8277 echo "$CMD2"
8278 cat "${te}1"
8279 cat "${te}2"
8280 numFAIL=$((numFAIL+1))
8281 listFAIL="$listFAIL $N"
8282 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8283 $PRINTF "$FAILED\n"
8284 cat "$tdiff"
8285 numFAIL=$((numFAIL+1))
8286 listFAIL="$listFAIL $N"
8287 else
8288 $PRINTF "$OK\n"
8289 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
8290 numOK=$((numOK+1))
8292 fi ;; # NUMCOND, feats
8293 esac
8294 N=$((N+1))
8297 NAME=TCPWRAPPERS_TCP6ADDR
8298 # this tests for a bug in 1.5.0.0 that brought false results with tcp-wrappers
8299 # and IPv6 when
8300 case "$TESTS" in
8301 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
8302 TEST="$NAME: specification of TCP6 address in hosts.allow"
8303 if ! eval $NUMCOND; then :;
8304 elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then
8305 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8306 numCANT=$((numCANT+1))
8307 listCANT="$listCANT $N"
8308 else
8309 tf="$td/test$N.stdout"
8310 te="$td/test$N.stderr"
8311 tdiff="$td/test$N.diff"
8312 da="test$N $(date) $RANDOM"
8313 ha="$td/hosts.allow"
8314 hd="$td/hosts.deny"
8315 $ECHO "socat : [::1] : allow" >"$ha"
8316 $ECHO "ALL : ALL : deny" >"$hd"
8317 newport tcp6 # provide free port number in $PORT
8318 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT,$REUSEADDR,tcpwrap-etc=$td,tcpwrappers=socat pipe"
8319 CMD2="$TRACE $SOCAT $opts - TCP6:[::1]:$PORT"
8320 printf "test $F_n $TEST... " $N
8321 $CMD1 2>"${te}1" &
8322 pid1=$!
8323 waittcp6port $PORT
8324 echo "$da" |$CMD2 >"$tf" 2>"${te}2"
8325 rc2=$?
8326 kill $pid1 2>/dev/null; wait
8327 if [ $rc2 -ne 0 ]; then
8328 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8329 echo "$CMD1 &"
8330 echo "$CMD2"
8331 cat "${te}1"
8332 cat "${te}2"
8333 numFAIL=$((numFAIL+1))
8334 listFAIL="$listFAIL $N"
8335 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8336 $PRINTF "$FAILED\n"
8337 cat "$tdiff"
8338 numFAIL=$((numFAIL+1))
8339 listFAIL="$listFAIL $N"
8340 else
8341 $PRINTF "$OK\n"
8342 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
8343 numOK=$((numOK+1))
8345 fi ;; # NUMCOND, feats
8346 esac
8347 N=$((N+1))
8350 NAME=UDP4BROADCAST
8351 case "$TESTS" in
8352 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%$NAME%*)
8353 TEST="$NAME: UDP/IPv4 broadcast"
8354 if ! eval $NUMCOND; then :;
8355 elif [ -z "$BCADDR" ]; then
8356 $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
8357 numCANT=$((numCANT+1))
8358 listCANT="$listCANT $N"
8359 else
8360 tf="$td/test$N.stdout"
8361 te="$td/test$N.stderr"
8362 tdiff="$td/test$N.diff"
8363 newport udp4; ts1p=$PORT
8364 #ts1="$BCADDR/8:$ts1p"
8365 ts1="$BCADDR:$ts1p"
8366 newport udp4; ts2p=$PORT
8367 ts2="$BCIFADDR:$ts2p"
8368 da="test$N $(date) $RANDOM"
8369 CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE"
8370 #CMD2="$TRACE $SOCAT $opts - UDP4-BROADCAST:$ts1"
8371 CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast"
8372 printf "test $F_n $TEST... " $N
8373 $CMD1 2>"${te}1" &
8374 pid1="$!"
8375 waitudp4port $ts1p 1
8376 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8377 rc2="$?"
8378 kill "$pid1" 2>/dev/null; wait;
8379 if [ "$rc2" -ne 0 ]; then
8380 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8381 echo "$CMD1 &"
8382 echo "$CMD2"
8383 cat "${te}1"
8384 cat "${te}2"
8385 numFAIL=$((numFAIL+1))
8386 listFAIL="$listFAIL $N"
8387 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8388 $PRINTF "$FAILED\n"
8389 cat "$tdiff"
8390 numFAIL=$((numFAIL+1))
8391 listFAIL="$listFAIL $N"
8392 else
8393 $PRINTF "$OK\n"
8394 if [ -n "$tut" ]; then
8395 echo "$CMD1 &"
8396 echo "$CMD2"
8398 if [ -n "$debug" ]; then cat $te; fi
8399 numOK=$((numOK+1))
8401 fi ;; # NUMCOND, feats
8402 esac
8403 N=$((N+1))
8406 NAME=IP4BROADCAST
8407 # test a local broadcast of a raw IPv4 protocol.
8408 # because we receive - in addition to the regular reply - our own broadcast,
8409 # we use a token XXXX that is changed to YYYY in the regular reply packet.
8410 case "$TESTS" in
8411 *%$N%*|*%functions%*|*%engine%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*)
8412 TEST="$NAME: raw IPv4 broadcast"
8413 if ! eval $NUMCOND; then :;
8414 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
8415 $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N
8416 numCANT=$((numCANT+1))
8417 listCANT="$listCANT $N"
8418 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8419 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8420 numCANT=$((numCANT+1))
8421 listCANT="$listCANT $N"
8422 elif [ -z "$BCADDR" ]; then
8423 $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
8424 else
8425 tf="$td/test$N.stdout"
8426 te="$td/test$N.stderr"
8427 tdiff="$td/test$N.diff"
8428 ts1p=$PROTO
8429 #ts1="$BCADDR/8:$ts1p"
8430 ts1="$BCADDR:$ts1p"
8431 ts2p=$ts1p
8432 ts2="$BCIFADDR"
8433 da="test$N $(date) $RANDOM XXXX"
8434 sh="$td/test$N-sed.sh"
8435 echo 'sed s/XXXX/YYYY/' >"$sh"
8436 chmod a+x "$sh"
8437 # EXEC need not work with script (musl libc), so use SYSTEM
8438 CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,broadcast SYSTEM:$sh"
8439 #CMD2="$TRACE $SOCAT $opts - IP4-BROADCAST:$ts1"
8440 CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:$ts1,broadcast"
8441 printf "test $F_n $TEST... " $N
8442 $CMD1 2>"${te}1" &
8443 pid1="$!"
8444 waitip4port $ts1p 1
8445 echo "$da" |$CMD2 2>>"${te}2" |grep -v XXXX >>"$tf"
8446 rc2="$?"
8447 kill "$pid1" 2>/dev/null; wait;
8448 if [ "$rc2" -ne 0 ]; then
8449 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8450 echo "$CMD1 &"
8451 echo "$CMD2"
8452 cat "${te}1"
8453 cat "${te}2"
8454 numFAIL=$((numFAIL+1))
8455 listFAIL="$listFAIL $N"
8456 elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then
8457 $PRINTF "$FAILED\n"
8458 cat "$tdiff"
8459 numFAIL=$((numFAIL+1))
8460 listFAIL="$listFAIL $N"
8461 else
8462 $PRINTF "$OK\n"
8463 if [ -n "$debug" ]; then cat $te; fi
8464 numOK=$((numOK+1))
8466 fi ;; # NUMCOND, feats
8467 esac
8468 PROTO=$((PROTO+1))
8469 N=$((N+1))
8472 #NAME=UDP4BROADCAST_RANGE
8473 #case "$TESTS" in
8474 #*%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%range%*|*%$NAME%*)
8475 #TEST="$NAME: security of UDP4-BROADCAST with RANGE option"
8476 #if ! eval $NUMCOND; then :;
8477 #elif [ -z "$BCADDR" ]; then
8478 # $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
8479 #else
8480 #newport udp4 # provide free port number in $PORT
8481 #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
8482 #fi ;; # NUMCOND, feats
8483 #esac
8484 #N=$((N+1))
8487 NAME=UDP4MULTICAST_UNIDIR
8488 case "$TESTS" in
8489 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*)
8490 TEST="$NAME: UDP/IPv4 multicast, send only"
8491 if ! eval $NUMCOND; then :;
8492 elif ! feat=$(testfeats ip4 udp) || ! runsip4 >/dev/null; then
8493 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8494 numCANT=$((numCANT+1))
8495 listCANT="$listCANT $N"
8496 elif ! a=$(testaddrs UDP4-RECV UDP4-SENDTO); then
8497 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
8498 numCANT=$((numCANT+1))
8499 listCANT="$listCANT $N"
8500 elif ! o=$(testoptions ip-add-membership bind) >/dev/null; then
8501 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
8502 numCANT=$((numCANT+1))
8503 listCANT="$listCANT $N"
8504 else
8505 tf="$td/test$N.stdout"
8506 te="$td/test$N.stderr"
8507 tdiff="$td/test$N.diff"
8508 newport udp4; ts1p=$PORT
8509 ts1a="$SECONDADDR"
8510 ts1="$ts1a:$ts1p"
8511 da="test$N $(date) $RANDOM"
8512 CMD1="$TRACE $SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
8513 CMD2="$TRACE $SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
8514 printf "test $F_n $TEST... " $N
8515 $CMD1 2>"${te}1" >"${tf}" &
8516 pid1="$!"
8517 waitudp4port $ts1p 1
8518 echo "$da" |$CMD2 2>>"${te}2"
8519 rc2="$?"
8520 usleep $MICROS
8521 kill "$pid1" 2>/dev/null; wait;
8522 if [ "$rc2" -ne 0 ]; then
8523 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8524 echo "$CMD1 &"
8525 cat "${te}1" >&2
8526 echo "$CMD2"
8527 cat "${te}2" >&2
8528 numFAIL=$((numFAIL+1))
8529 listFAIL="$listFAIL $N"
8530 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8531 $PRINTF "$FAILED\n"
8532 echo "$CMD1 &"
8533 cat "${te}1" >&2
8534 echo "$CMD2"
8535 cat "${te}2" >&2
8536 cat "$tdiff"
8537 numFAIL=$((numFAIL+1))
8538 listFAIL="$listFAIL $N"
8539 else
8540 $PRINTF "$OK\n"
8541 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
8542 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
8543 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
8544 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8545 numOK=$((numOK+1))
8547 fi ;; # NUMCOND, feats
8548 esac
8549 N=$((N+1))
8551 NAME=IP4MULTICAST_UNIDIR
8552 case "$TESTS" in
8553 *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*)
8554 TEST="$NAME: IPv4 multicast"
8555 if ! eval $NUMCOND; then :;
8556 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
8557 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8558 numCANT=$((numCANT+1))
8559 listCANT="$listCANT $N"
8560 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8561 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8562 numCANT=$((numCANT+1))
8563 listCANT="$listCANT $N"
8564 else
8565 tf="$td/test$N.stdout"
8566 te="$td/test$N.stderr"
8567 tdiff="$td/test$N.diff"
8568 ts1p=$PROTO
8569 ts1a="$SECONDADDR"
8570 ts1="$ts1a:$ts1p"
8571 da="test$N $(date) $RANDOM"
8572 CMD1="$TRACE $SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
8573 CMD2="$TRACE $SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
8574 printf "test $F_n $TEST... " $N
8575 $CMD1 2>"${te}1" >"${tf}" &
8576 pid1="$!"
8577 waitip4proto $ts1p 1
8578 usleep $MICROS
8579 echo "$da" |$CMD2 2>>"${te}2"
8580 rc2="$?"
8581 #usleep $MICROS
8582 sleep 1
8583 kill "$pid1" 2>/dev/null; wait;
8584 if [ "$rc2" -ne 0 ]; then
8585 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8586 echo "$CMD1 &"
8587 echo "$CMD2"
8588 cat "${te}1"
8589 cat "${te}2"
8590 numFAIL=$((numFAIL+1))
8591 listFAIL="$listFAIL $N"
8592 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8593 $PRINTF "$FAILED\n"
8594 cat "$tdiff"
8595 numFAIL=$((numFAIL+1))
8596 listFAIL="$listFAIL $N"
8597 else
8598 $PRINTF "$OK\n"
8599 if [ -n "$debug" ]; then cat $te; fi
8600 numOK=$((numOK+1))
8602 fi ;; # NUMCOND, feats
8603 esac
8604 PROTO=$((PROTO+1))
8605 N=$((N+1))
8607 if true; then
8608 # This test succeeds, e.g., on CentOS-7 with kernel 3.10.0, Ubuntu-16.04 with 4.4.0
8609 # but fails, e.g., on Ubuntu-18.04 with kernel 4.15.0, CentOS-8 with 4.10.0
8610 NAME=UDP6MULTICAST_UNIDIR
8611 case "$TESTS" in
8612 *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%multicast%*|*%$NAME%*)
8613 TEST="$NAME: UDP/IPv6 multicast"
8614 if ! eval $NUMCOND; then :;
8615 elif ! f=$(testfeats ip6 udp); then
8616 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not configured in $SOCAT${NORMAL}\n" $N
8617 numCANT=$((numCANT+1))
8618 listCANT="$listCANT $N"
8619 elif ! a=$(testaddrs - STDIO UDP6-RECV UDP6-SENDTO); then
8620 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
8621 numCANT=$((numCANT+1))
8622 listCANT="$listCANT $N"
8623 elif ! o=$(testoptions ipv6-join-group) >/dev/null; then
8624 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
8625 numCANT=$((numCANT+1))
8626 listCANT="$listCANT $N"
8627 elif ! runsip6 >/dev/null; then
8628 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 does not work on $HOSTNAME${NORMAL}\n" $N
8629 numCANT=$((numCANT+1))
8630 listCANT="$listCANT $N"
8631 elif ! echo |$SOCAT -u -t 0.1 - UDP6-SENDTO:[ff02::2]:12002 >/dev/null 2>&1; then
8632 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 multicasting does not work${NORMAL}\n" $N
8633 numCANT=$((numCANT+1))
8634 listCANT="$listCANT $N"
8635 else
8636 tf="$td/test$N.stdout"
8637 te="$td/test$N.stderr"
8638 tdiff="$td/test$N.diff"
8639 newport udp6; ts1p=$PORT
8640 if1="$MCINTERFACE"
8641 ts1a="[::1]"
8642 da="test$N $(date) $RANDOM"
8643 CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,$REUSEADDR,ipv6-join-group=[ff02::2]:$if1 -"
8644 #CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a"
8645 CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p"
8646 printf "test $F_n $TEST... " $N
8647 $CMD1 2>"${te}1" >"${tf}" &
8648 pid1="$!"
8649 waitudp6port $ts1p 1
8650 echo "$da" |$CMD2 2>>"${te}2"
8651 rc2="$?"
8652 usleep $MICROS
8653 kill "$pid1" 2>/dev/null; wait;
8654 if [ "$rc2" -ne 0 ]; then
8655 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8656 echo "$CMD1 &"
8657 cat "${te}1"
8658 echo "$CMD2"
8659 cat "${te}2"
8660 numFAIL=$((numFAIL+1))
8661 listFAIL="$listFAIL $N"
8662 namesFAIL="$namesFAIL $NAME"
8663 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8664 # if ! [ "$UNAME" = Linux ] || ! [[ $(uname -r) =~ ^2\.* ]] || ! [[ ^3\.* ]] || ! [[ ^4\.[0-4]\.* ]]; then
8665 # $PRINTF "${YELLOW}works only on Linux up to about 4.4${NORMAL}\n" $N
8666 # numCANT=$((numCANT+1))
8667 # listCANT="$listCANT $N"
8668 # else
8669 $PRINTF "$FAILED\n"
8670 echo "$CMD1 &"
8671 cat "${te}1"
8672 echo "$CMD2"
8673 cat "${te}2"
8674 cat "$tdiff"
8675 numFAIL=$((numFAIL+1))
8676 listFAIL="$listFAIL $N"
8677 # fi
8678 else
8679 $PRINTF "$OK\n"
8680 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8681 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8682 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8683 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8684 numOK=$((numOK+1))
8686 fi ;; # NUMCOND, feats
8687 esac
8688 N=$((N+1))
8689 fi # false
8691 NAME=UDP4MULTICAST_BIDIR
8692 case "$TESTS" in
8693 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*)
8694 TEST="$NAME: UDP/IPv4 multicast, with reply"
8695 if ! eval $NUMCOND; then :; else
8696 tf="$td/test$N.stdout"
8697 te="$td/test$N.stderr"
8698 tdiff="$td/test$N.diff"
8699 newport udp4; ts1p=$PORT
8700 ts1a="$SECONDADDR"
8701 ts1="$ts1a:$ts1p"
8702 newport udp4; ts2p=$PORT
8703 ts2="$BCIFADDR:$ts2p"
8704 da="test$N $(date) $RANDOM"
8705 CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
8706 #CMD2="$TRACE $SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
8707 CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
8708 printf "test $F_n $TEST... " $N
8709 $CMD1 2>"${te}1" &
8710 pid1="$!"
8711 waitudp4port $ts1p 1
8712 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8713 rc2="$?"
8714 kill "$pid1" 2>/dev/null; wait;
8715 if [ "$rc2" -ne 0 ]; then
8716 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8717 echo "$CMD1 &"
8718 cat "${te}1" >&2
8719 echo "$CMD2"
8720 cat "${te}2" >&2
8721 numFAIL=$((numFAIL+1))
8722 listFAIL="$listFAIL $N"
8723 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8724 $PRINTF "$FAILED\n"
8725 echo "$CMD1 &"
8726 cat "${te}1" >&2
8727 echo "$CMD2"
8728 cat "${te}2" >&2
8729 echo diff: >&2
8730 cat "$tdiff" >&2
8731 numFAIL=$((numFAIL+1))
8732 listFAIL="$listFAIL $N"
8733 else
8734 $PRINTF "$OK\n"
8735 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8736 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8737 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8738 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8739 numOK=$((numOK+1))
8741 fi ;; # NUMCOND
8742 esac
8743 N=$((N+1))
8745 NAME=IP4MULTICAST_BIDIR
8746 case "$TESTS" in
8747 *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*)
8748 TEST="$NAME: IPv4 multicast, with reply"
8749 if ! eval $NUMCOND; then :;
8750 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
8751 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8752 numCANT=$((numCANT+1))
8753 listCANT="$listCANT $N"
8754 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8755 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8756 numCANT=$((numCANT+1))
8757 listCANT="$listCANT $N"
8758 else
8759 tf="$td/test$N.stdout"
8760 te="$td/test$N.stderr"
8761 tdiff="$td/test$N.diff"
8762 ts1p=$PROTO
8763 ts1a="$SECONDADDR"
8764 ts1="$ts1a:$ts1p"
8765 da="test$N $(date) $RANDOM"
8766 CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
8767 #CMD2="$TRACE $SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
8768 CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
8769 printf "test $F_n $TEST... " $N
8770 $CMD1 2>"${te}1" &
8771 pid1="$!"
8772 waitip4port $ts1p 1
8773 usleep 100000 # give process a chance to add multicast membership
8774 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8775 rc2="$?"
8776 kill "$pid1" 2>/dev/null; wait;
8777 if [ "$rc2" -ne 0 ]; then
8778 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8779 echo "$CMD1 &"
8780 echo "$CMD2"
8781 cat "${te}1"
8782 cat "${te}2"
8783 numFAIL=$((numFAIL+1))
8784 listFAIL="$listFAIL $N"
8785 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8786 $PRINTF "$FAILED\n"
8787 cat "$tdiff"
8788 numFAIL=$((numFAIL+1))
8789 listFAIL="$listFAIL $N"
8790 else
8791 $PRINTF "$OK\n"
8792 if [ -n "$tut" ]; then
8793 echo "$CMD1 &"
8794 echo "$CMD2"
8796 if [ -n "$debug" ]; then cat $te; fi
8797 numOK=$((numOK+1))
8799 fi ;; # NUMCOND, feats
8800 esac
8801 PROTO=$((PROTO+1))
8802 N=$((N+1))
8805 NAME=TUNREAD
8806 case "$TESTS" in
8807 *%$N%*|*%functions%*|*%tun%*|*%root%*|*%$NAME%*)
8808 TEST="$NAME: reading data sent through tun interface"
8809 #idea: create a TUN interface and send a datagram to one of the addresses of
8810 # its virtual network. On the tunnel side, read the packet and compare its last
8811 # bytes with the datagram payload
8812 if ! eval $NUMCOND; then :;
8813 elif ! feat=$(testfeats ip4 tun) || ! runsip4 >/dev/null; then
8814 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8815 numCANT=$((numCANT+1))
8816 listCANT="$listCANT $N"
8817 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8818 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8819 numCANT=$((numCANT+1))
8820 listCANT="$listCANT $N"
8821 else
8822 tf="$td/test$N.stdout"
8823 te="$td/test$N.stderr"
8824 tdiff="$td/test$N.diff"
8825 tl="$td/test$N.lock"
8826 da="test$N $(date) $RANDOM"
8827 dalen=$((${#da}+1))
8828 TUNNET=10.255.255
8829 newport udp4 # provide free port number in $PORT
8830 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT"
8831 #CMD="$TRACE $SOCAT $opts -u -L $tl TUN,ifaddr=$TUNNET.1,netmask=255.255.255.0,iff-up=1 -"
8832 CMD="$TRACE $SOCAT $opts -u -L $tl TUN:$TUNNET.1/24,iff-up=1 -"
8833 printf "test $F_n $TEST... " $N
8834 $CMD 2>"${te}" |tail -c $dalen >"${tf}" &
8835 sleep 1
8836 echo "$da" |$CMD1 2>"${te}1"
8837 sleep 1
8838 kill "$(cat $tl 2>/dev/null)" 2>/dev/null
8839 wait
8840 if [ $? -ne 0 ]; then
8841 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8842 echo "$CMD &"
8843 echo "$CMD1"
8844 cat "${te}" "${te}1"
8845 numFAIL=$((numFAIL+1))
8846 listFAIL="$listFAIL $N"
8847 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8848 $PRINTF "$FAILED\n"
8849 echo "$CMD &"
8850 echo "$CMD1"
8851 cat "$tdiff"
8852 cat "${te}" "${te}1"
8853 numFAIL=$((numFAIL+1))
8854 listFAIL="$listFAIL $N"
8855 else
8856 $PRINTF "$OK\n"
8857 if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi
8858 numOK=$((numOK+1))
8860 fi ;; # NUMCOND, feats
8861 esac
8862 N=$((N+1))
8865 # use the INTERFACE address on a tun/tap device and transfer data fully
8866 # transparent
8867 NAME=TUNINTERFACE
8868 case "$TESTS" in
8869 *%$N%*|*%functions%*|*%tun%*|*%interface%*|*%root%*|*%$NAME%*)
8870 TEST="$NAME: pass data through tun interface using INTERFACE"
8871 #idea: create a TUN interface and send a raw packet on the interface side.
8872 # It should arrive unmodified on the tunnel side.
8873 if ! eval $NUMCOND; then :;
8874 elif ! feat=$(testfeats ip4 tun interface) || ! runsip4 >/dev/null; then
8875 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8876 numCANT=$((numCANT+1))
8877 listCANT="$listCANT $N"
8878 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8879 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8880 numCANT=$((numCANT+1))
8881 listCANT="$listCANT $N"
8882 else
8883 tf="$td/test$N.stdout"
8884 te="$td/test$N.stderr"
8885 tdiff="$td/test$N.diff"
8886 tl="$td/test$N.lock"
8887 da="$(date) $RANDOM"
8888 TUNNET=10.255.255
8889 TUNNAME=tun9
8890 CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME PIPE"
8891 CMD1="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME"
8892 printf "test $F_n $TEST... " $N
8893 $CMD0 2>"${te}1" &
8894 pid0="$!"
8895 #waitinterface "$TUNNAME"
8896 usleep $MICROS
8897 { echo "$da"; usleep $MICROS ; } |$CMD1 >"$tf" 2>"${te}"
8898 rc1=$?
8899 usleep $MICROS
8900 kill $pid0 2>/dev/null
8901 wait
8902 if [ "$rc1" -ne 0 ]; then
8903 $PRINTF "$FAILED (rc1=$rc1):\n"
8904 echo "$CMD0 &"
8905 cat "${te}0" >&2
8906 echo "$CMD1"
8907 cat "${te}1" >&2
8908 numFAIL=$((numFAIL+1))
8909 listFAIL="$listFAIL $N"
8910 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8911 $PRINTF "$FAILED (diff)\n"
8912 echo "$CMD0 &"
8913 cat "${te}0" >&2
8914 echo "$CMD1"
8915 cat "${te}1" >&2
8916 echo "// diff:"
8917 cat "$tdiff"
8918 numFAIL=$((numFAIL+1))
8919 listFAIL="$listFAIL $N"
8920 else
8921 $PRINTF "$OK\n"
8922 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
8923 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
8924 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
8925 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8926 numOK=$((numOK+1))
8928 fi ;; # NUMCOND, feats
8929 esac
8930 N=$((N+1))
8933 NAME=ABSTRACTSTREAM
8934 case "$TESTS" in
8935 *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%connect%*|*%listen%*|*%$NAME%*)
8936 TEST="$NAME: abstract UNIX stream socket, listen and connect"
8937 if ! eval $NUMCOND; then :;
8938 elif ! feat=$(testfeats abstract-unixsocket); then
8939 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8940 numCANT=$((numCANT+1))
8941 listCANT="$listCANT $N"
8942 else
8943 ts="$td/test$N.socket"
8944 tf="$td/test$N.stdout"
8945 te="$td/test$N.stderr"
8946 tdiff="$td/test$N.diff"
8947 da1="test$N $(date) $RANDOM"
8948 #establish a listening abstract unix socket
8949 SRV="$TRACE $SOCAT $opts -lpserver ABSTRACT-LISTEN:\"$ts\",$REUSEADDR PIPE"
8950 #make a connection
8951 CMD="$TRACE $SOCAT $opts - ABSTRACT-CONNECT:$ts"
8952 $PRINTF "test $F_n $TEST... " $N
8953 touch "$ts" # make a file with same name, so non-abstract fails
8954 eval "$SRV 2>${te}s &"
8955 pids=$!
8956 #waitfile "$ts"
8957 sleep 1
8958 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
8959 if [ $? -ne 0 ]; then
8960 kill "$pids" 2>/dev/null
8961 $PRINTF "$FAILED:\n"
8962 echo "$SRV &"
8963 cat "${te}s"
8964 echo "$CMD"
8965 cat "${te}1"
8966 numFAIL=$((numFAIL+1))
8967 listFAIL="$listFAIL $N"
8968 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
8969 kill "$pids" 2>/dev/null
8970 $PRINTF "$FAILED:\n"
8971 echo "$SRV &"
8972 cat "${te}s"
8973 echo "$CMD"
8974 cat "${te}1"
8975 cat "$tdiff"
8976 numFAIL=$((numFAIL+1))
8977 listFAIL="$listFAIL $N"
8978 else
8979 $PRINTF "$OK\n"
8980 if [ -n "$debug" ]; then cat $te; fi
8981 numOK=$((numOK+1))
8982 fi # !(rc -ne 0)
8983 wait
8984 fi ;; # NUMCOND, feats
8985 esac
8986 N=$((N+1))
8989 NAME=ABSTRACTDGRAM
8990 case "$TESTS" in
8991 *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%$NAME%*)
8992 TEST="$NAME: abstract UNIX datagram"
8993 if ! eval $NUMCOND; then :;
8994 elif ! feat=$(testfeats abstract-unixsocket); then
8995 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8996 numCANT=$((numCANT+1))
8997 listCANT="$listCANT $N"
8998 else
8999 tf="$td/test$N.stdout"
9000 te="$td/test$N.stderr"
9001 tdiff="$td/test$N.diff"
9002 ts1="$td/test$N.socket1"
9003 ts2="$td/test$N.socket2"
9004 da="test$N $(date) $RANDOM"
9005 CMD1="$TRACE $SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE"
9006 #CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
9007 CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
9008 printf "test $F_n $TEST... " $N
9009 touch "$ts1" # make a file with same name, so non-abstract fails
9010 $CMD1 2>"${te}1" &
9011 pid1="$!"
9012 sleep 1
9013 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9014 rc2=$?
9015 kill "$pid1" 2>/dev/null; wait
9016 if [ $rc2 -ne 0 ]; then
9017 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9018 echo "$CMD1 &"
9019 cat "${te}1" >&2
9020 echo "$CMD2"
9021 cat "${te}2" >&2
9022 numFAIL=$((numFAIL+1))
9023 listFAIL="$listFAIL $N"
9024 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9025 $PRINTF "$FAILED\n"
9026 echo "$CMD1 &"
9027 cat "${te}1" >&2
9028 echo "$CMD2"
9029 cat "${te}2" >&2
9030 cat "$tdiff" >&2
9031 numFAIL=$((numFAIL+1))
9032 listFAIL="$listFAIL $N"
9033 else
9034 $PRINTF "$OK\n"
9035 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9036 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9037 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9038 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9039 numOK=$((numOK+1))
9041 fi ;; # NUMCOND, feats
9042 esac
9043 N=$((N+1))
9046 NAME=ABSTRACTRECV
9047 case "$TESTS" in
9048 *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%recv%*|*%$NAME%*)
9049 TEST="$NAME: abstract UNIX datagram receive"
9050 if ! eval $NUMCOND; then :;
9051 elif ! feat=$(testfeats abstract-unixsocket); then
9052 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9053 numCANT=$((numCANT+1))
9054 listCANT="$listCANT $N"
9055 else
9056 ts="$td/test$N.socket"
9057 tf="$td/test$N.stdout"
9058 te="$td/test$N.stderr"
9059 tdiff="$td/test$N.diff"
9060 ts1="$ts"
9061 da="test$N $(date) $RANDOM"
9062 CMD1="$TRACE $SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -"
9063 CMD2="$TRACE $SOCAT $opts -u - ABSTRACT-SENDTO:$ts1"
9064 printf "test $F_n $TEST... " $N
9065 touch "$ts1" # make a file with same name, so non-abstract fails
9066 $CMD1 >"$tf" 2>"${te}1" &
9067 pid1="$!"
9068 #waitfile $ts1 1
9069 sleep 1
9070 echo "$da" |$CMD2 2>>"${te}2"
9071 rc2="$?"
9072 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
9073 kill "$pid1" 2>/dev/null; wait
9074 if [ "$rc2" -ne 0 ]; then
9075 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9076 echo "$CMD1 &"
9077 cat "${te}1" >&2
9078 echo "$CMD2"
9079 cat "${te}2" >&2
9080 numFAIL=$((numFAIL+1))
9081 listFAIL="$listFAIL $N"
9082 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9083 $PRINTF "$FAILED\n"
9084 echo "$CMD1 &"
9085 cat "${te}1" >&2
9086 echo "$CMD2"
9087 cat "${te}2" >&2
9088 cat "$tdiff"
9089 numFAIL=$((numFAIL+1))
9090 listFAIL="$listFAIL $N"
9091 else
9092 $PRINTF "$OK\n"
9093 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9094 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9095 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9096 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9097 numOK=$((numOK+1))
9099 fi ;; # NUMCOND, feats
9100 esac
9101 N=$((N+1))
9104 # bind with Linux abstract UNIX domain addresses bound to filesystem socket
9105 # instead of abstract namespace
9106 NAME=ABSTRACT_BIND
9107 case "$TESTS" in
9108 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%$NAME%*)
9109 TEST="$NAME: abstract bind"
9110 # open an abstract client address with bind option, bind to the target socket.
9111 # send a datagram.
9112 # when socat outputs the datagram it got the test succeeded
9113 if ! eval $NUMCOND; then :;
9114 elif [ "$UNAME" != Linux ]; then
9115 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
9116 numCANT=$((numCANT+1))
9117 listCANT="$listCANT $N"
9118 else
9119 tf="$td/test$N.stdout"
9120 te="$td/test$N.stderr"
9121 tdiff="$td/test$N.diff"
9122 ts1="$td/test$N.sock1"
9123 da="test$N $(date) $RANDOM"
9124 CMD1="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts1"
9125 printf "test $F_n $TEST... " $N
9126 echo "$da" |$CMD1 >$tf 2>"${te}1"
9127 rc1=$?
9128 if [ $rc1 -ne 0 ]; then
9129 $PRINTF "$FAILED\n"
9130 echo "$CMD1"
9131 echo "rc=$rc1" >&2
9132 cat "${te}1" >&2
9133 numFAIL=$((numFAIL+1))
9134 listFAIL="$listFAIL $N"
9135 elif echo "$da" |diff -q - $tf; then
9136 $PRINTF "$OK\n"
9137 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9138 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9139 numOK=$((numOK+1))
9140 else
9141 $PRINTF "$FAILED\n"
9142 echo "$CMD1" >&2
9143 cat "${te}1" >&2
9144 echo "$da" |diff - "$tf" >&2
9145 numFAIL=$((numFAIL+1))
9146 listFAIL="$listFAIL $N"
9148 fi # NUMCOND
9150 esac
9151 N=$((N+1))
9154 NAME=OPENSSLREAD
9155 # socat determined availability of data using select(). With openssl, the
9156 # following situation might occur:
9157 # a SSL data block with more than 8192 bytes (socats default blocksize)
9158 # arrives; socat calls SSL_read, and the SSL routine reads the complete block.
9159 # socat then reads 8192 bytes from the SSL layer, the rest remains buffered.
9160 # If the TCP connection stays idle for some time, the data in the SSL layer
9161 # keeps there and is not transferred by socat until the socket indicates more
9162 # data or EOF.
9163 case "$TESTS" in
9164 *%$N%*|*%functions%*|*%openssl%*|*%listen%*|*%$NAME%*)
9165 TEST="$NAME: socat handles data buffered by openssl"
9166 #idea: have a socat process (server) that gets an SSL block that is larger than
9167 # socat transfer block size; keep the socket connection open and kill the
9168 # server process after a short time; if not the whole data block has been
9169 # transferred, the test has failed.
9170 if ! eval $NUMCOND; then :;
9171 elif ! feat=$(testfeats openssl) >/dev/null; then
9172 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
9173 numCANT=$((numCANT+1))
9174 listCANT="$listCANT $N"
9175 else
9176 tf="$td/test$N.out"
9177 te="$td/test$N.err"
9178 tdiff="$td/test$N.diff"
9179 da="test$N $(date) $RANDOM"
9180 SRVCERT=testsrv
9181 gentestcert "$SRVCERT"
9182 newport tcp4 # provide free port number in $PORT
9183 CMD1="$TRACE $SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=$SRVCERT.pem,verify=0 -"
9184 CMD2="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0"
9185 printf "test $F_n $TEST... " $N
9187 $CMD1 2>"${te}1" >"$tf" &
9188 pid=$! # background process id
9189 waittcp4port $PORT
9190 (echo "$da"; sleep 2) |$CMD2 2>"${te}2"
9191 kill "$pid" 2>/dev/null; wait
9192 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
9193 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9194 echo "$CMD1"
9195 cat "${te}1"
9196 echo "$CMD2"
9197 cat "${te}2"
9198 cat "$tdiff"
9199 numFAIL=$((numFAIL+1))
9200 listFAIL="$listFAIL $N"
9201 else
9202 $PRINTF "$OK\n"
9203 if [ -n "$debug" ]; then cat $te; fi
9204 numOK=$((numOK+1))
9206 wait
9207 fi # NUMCOND, featsesac
9209 esac
9210 N=$((N+1))
9213 # test: there is a bug with the readbytes option: when the socket delivered
9214 # exacly that many bytes as specified with readbytes and the stays idle (no
9215 # more data, no EOF), socat waits for more data instead of generating EOF on
9216 # this in put stream.
9217 NAME=READBYTES_EOF
9218 #set -vx
9219 case "$TESTS" in
9220 *%$N%*|*%functions%*|*%$NAME%*)
9221 TEST="$NAME: trigger EOF after that many bytes, even when socket idle"
9222 #idea: we deliver that many bytes to socat; the process should terminate then.
9223 # we try to transfer data in the other direction then; if transfer succeeds,
9224 # the process did not terminate and the bug is still there.
9225 if ! eval $NUMCOND; then :;
9226 elif false; then
9227 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
9228 numCANT=$((numCANT+1))
9229 listCANT="$listCANT $N"
9230 else
9231 tr="$td/test$N.ref"
9232 ti="$td/test$N.in"
9233 to="$td/test$N.out"
9234 te="$td/test$N.err"
9235 tdiff="$td/test$N.diff"
9236 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
9237 CMD="$TRACE $SOCAT $opts SYSTEM:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null"
9238 printf "test $F_n $TEST... " $N
9239 (usleep $((2*MICROS)); echo) |eval "$CMD" >"$to" 2>"$te"
9240 if test -s "$to"; then
9241 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9242 echo "$CMD"
9243 numFAIL=$((numFAIL+1))
9244 listFAIL="$listFAIL $N"
9245 else
9246 $PRINTF "$OK\n"
9247 if [ -n "$debug" ]; then cat $te; fi
9248 numOK=$((numOK+1))
9250 fi ;; # NUMCOND, feats
9251 esac
9252 N=$((N+1))
9255 # test: there was a bug with exec:...,pty that did not kill the exec'd sub
9256 # process under some circumstances.
9257 NAME=EXECPTYKILL
9258 case "$TESTS" in
9259 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%pty%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*)
9260 TEST="$NAME: exec:...,pty explicitely kills sub process"
9261 # we want to check if the exec'd sub process is killed in time
9262 # for this we have a shell script that generates a file after two seconds;
9263 # it should be killed after one second, so if the file was generated the test
9264 # has failed
9265 if ! eval $NUMCOND; then :; else
9266 tf="$td/test$N.stdout"
9267 te="$td/test$N.stderr"
9268 ts="$td/test$N.sock"
9269 tda="$td/test$N.data"
9270 tsh="$td/test$N.sh"
9271 tdiff="$td/test$N.diff"
9272 cat >"$tsh" <<EOF
9273 sleep $SECONDs; echo; sleep $SECONDs; touch "$tda"; echo
9275 chmod a+x "$tsh"
9276 CMD1="$TRACE $SOCAT $opts -t $SECONDs -U UNIX-LISTEN:$ts,fork EXEC:$tsh,pty"
9277 CMD="$TRACE $SOCAT $opts -t $SECONDs /dev/null UNIX-CONNECT:$ts"
9278 printf "test $F_n $TEST... " $N
9279 $CMD1 2>"${te}2" &
9280 pid1=$!
9281 sleep $SECONDs
9282 waitfile $ts $SECONDs
9283 $CMD 2>>"${te}1" >>"$tf"
9284 sleep $((2*SECONDs))
9285 kill "$pid1" 2>/dev/null
9286 wait
9287 if [ $? -ne 0 ]; then
9288 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9289 echo "$CMD1 &"
9290 echo "$CMD2"
9291 cat "${te}1" "${te}2"
9292 numFAIL=$((numFAIL+1))
9293 listFAIL="$listFAIL $N"
9294 elif [ -f "$tda" ]; then
9295 $PRINTF "$FAILED\n"
9296 cat "${te}1" "${te}2"
9297 numFAIL=$((numFAIL+1))
9298 listFAIL="$listFAIL $N"
9299 else
9300 $PRINTF "$OK\n"
9301 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
9302 numOK=$((numOK+1))
9304 fi ;; # NUMCOND
9305 esac
9306 N=$((N+1))
9309 # test if service name resolution works; this was buggy in 1.5 and 1.6.0.0
9310 NAME=TCP4SERVICE
9311 case "$TESTS" in
9312 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
9313 TEST="$NAME: echo via connection to TCP V4 socket"
9314 # select a tcp entry from /etc/services, have a server listen on the port
9315 # number and connect using the service name; with the bug, connection will to a
9316 # wrong port
9317 if ! eval $NUMCOND; then :; else
9318 tf="$td/test$N.stdout"
9319 te="$td/test$N.stderr"
9320 tdiff="$td/test$N.diff"
9321 # find a service entry we do not need root for (>=1024; here >=1100 for ease)
9322 SERVENT="$(grep '^[a-z][a-z]*[^!-~][^!-~]*[1-9][1-9][0-9][0-9]/tcp' /etc/services |head -n 1)"
9323 SERVICE="$(echo $SERVENT |cut -d' ' -f1)"
9324 _PORT="$PORT"
9325 PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')"
9326 tsl="$PORT"
9327 ts="127.0.0.1:$SERVICE"
9328 da="test$N $(date) $RANDOM"
9329 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE"
9330 CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
9331 printf "test $F_n $TEST... " $N
9332 $CMD1 >"$tf" 2>"${te}1" &
9333 pid1=$!
9334 waittcp4port $tsl 1
9335 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9336 if [ $? -ne 0 ]; then
9337 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9338 echo "$CMD1 &"
9339 cat "${te}1"
9340 echo "$CMD2"
9341 cat "${te}2"
9342 numFAIL=$((numFAIL+1))
9343 listFAIL="$listFAIL $N"
9344 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9345 $PRINTF "$FAILED\n"
9346 cat "$tdiff"
9347 numFAIL=$((numFAIL+1))
9348 listFAIL="$listFAIL $N"
9349 else
9350 $PRINTF "$OK\n"
9351 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
9352 numOK=$((numOK+1))
9354 kill $pid1 2>/dev/null
9355 wait
9356 PORT=$_PORT
9357 fi ;; # NUMCOND
9358 esac
9359 N=$((N+1))
9362 # test: up to socat 1.6.0.0, the highest file descriptor supported in socats
9363 # transfer engine was FOPEN_MAX-1; this usually worked fine but would fail when
9364 # socat was invoked with many file descriptors already opened. socat would
9365 # just hang in the select() call. Thanks to Daniel Lucq for reporting this
9366 # problem.
9367 # FOPEN_MAX on different OS's:
9368 # OS FOPEN_ ulimit ulimit FD_
9369 # MAX -H -n -S -n SETSIZE
9370 # Linux 2.6: 16 1024 1024 1024
9371 # HP-UX 11.11: 60 2048 2048 2048
9372 # FreeBSD: 20 11095 11095 1024
9373 # Cygwin: 20 unlimit 256 64
9374 # AIX: 32767 65534 65534
9375 # SunOS 8: 20 1024
9376 # musl libc: 1024
9377 NAME=EXCEED_FOPEN_MAX
9378 case "$TESTS" in
9379 *%$N%*|*%functions%*|*%maxfds%*|*%$NAME%*)
9380 TEST="$NAME: more than FOPEN_MAX FDs in use"
9381 # this test opens a number of FDs before socat is invoked. socat will have to
9382 # allocate higher FD numbers and thus hang if it cannot handle them.
9383 if ! eval $NUMCOND; then :;
9384 elif [ "$UNAME" != Linux ]; then
9385 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
9386 numCANT=$((numCANT+1))
9387 listCANT="$listCANT $N"
9388 else
9389 REDIR=
9390 #set -vx
9391 if [ -z "$FOPEN_MAX" ]; then
9392 $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N"
9393 numCANT=$((numCANT+1))
9394 listCANT="$listCANT $N"
9395 else
9396 if [ $FOPEN_MAX -lt 270 ]; then
9397 OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX
9398 else
9399 OPEN_FILES=269 # bash tends to SIGSEGV on higher value
9400 # btw, the test is obsolete anyway
9402 i=3; while [ "$i" -lt "$OPEN_FILES" ]; do
9403 REDIR="$REDIR $i>&2"
9404 i=$((i+1))
9405 done
9406 #echo "$REDIR"
9407 #testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1
9408 #set -vx
9409 eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR
9410 #set +vx
9411 fi # could determine FOPEN_MAX
9412 fi ;; # NUMCOND
9413 esac
9414 N=$((N+1))
9417 # there was a bug with udp-listen and fork: terminating sub processes became
9418 # zombies because the master process did not catch SIGCHLD
9419 NAME=UDP4LISTEN_SIGCHLD
9420 case "$TESTS" in
9421 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%zombie%*|*%signal%*|*%listen%*|*%fork%*|*%$NAME%*)
9422 TEST="$NAME: test if UDP4-LISTEN child becomes zombie"
9423 # idea: run a udp-listen process with fork and -T. Connect once, so a sub
9424 # process is forked off. Make some transfer and wait until the -T timeout is
9425 # over. Now check for the child process: if it is zombie the test failed.
9426 # Correct is that child process terminated
9427 if ! eval $NUMCOND; then :; else
9428 tf="$td/test$N.stdout"
9429 te="$td/test$N.stderr"
9430 tdiff="$td/test$N.diff"
9431 newport udp4; tsl=$PORT
9432 ts="$LOCALHOST:$tsl"
9433 da="test$N $(date) $RANDOM"
9434 CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,$REUSEADDR,fork PIPE"
9435 CMD2="$TRACE $SOCAT $opts - UDP4:$ts"
9436 printf "test $F_n $TEST... " $N
9437 $CMD1 >"$tf" 2>"${te}1" &
9438 pid1=$!
9439 waitudp4port $tsl 1
9440 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9441 rc2=$?
9442 sleep 1
9443 #read -p ">"
9444 l="$(childprocess $pid1)"
9445 kill $pid1 2>/dev/null; wait
9446 if [ $rc2 -ne 0 ]; then
9447 $PRINTF "$NO_RESULT (client failed)\n" # already handled in test UDP4STREAM
9448 numCANT=$((numCANT+1))
9449 listCANT="$listCANT $N"
9450 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9451 $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM
9452 numCANT=$((numCANT+1))
9453 listCANT="$listCANT $N"
9454 elif $(isdefunct "$l"); then
9455 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9456 echo "$CMD1 &"
9457 echo "$CMD2"
9458 cat "${te}1" "${te}2"
9459 numFAIL=$((numFAIL+1))
9460 listFAIL="$listFAIL $N"
9461 else
9462 $PRINTF "$OK\n"
9463 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
9464 numOK=$((numOK+1))
9466 fi ;; # NUMCOND
9467 esac
9468 N=$((N+1))
9469 #set +vx
9471 # there was a bug with udp-recvfrom and fork: terminating sub processes became
9472 # zombies because the master process caught SIGCHLD but did not wait()
9473 NAME=UDP4RECVFROM_SIGCHLD
9474 case "$TESTS" in
9475 *%$N%*|*%functions%*|*%bugs%*|*%fork%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%signal%*|*%$NAME%*)
9476 TEST="$NAME: test if UDP4-RECVFROM child becomes zombie"
9477 # idea: run a udp-recvfrom process with fork and -T. Send it one packet, so a
9478 # sub process is forked off. Make some transfer and wait until the -T timeout
9479 # is over. Now check for the child process: if it is zombie the test failed.
9480 # Correct is that child process terminated
9481 if ! eval $NUMCOND; then :; else
9482 tf="$td/test$N.stdout"
9483 te="$td/test$N.stderr"
9484 tdiff="$td/test$N.diff"
9485 newport udp4; tsl=$PORT
9486 ts="$LOCALHOST:$tsl"
9487 da="test$N $(date) $RANDOM"
9488 CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE"
9489 CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts"
9490 printf "test $F_n $TEST... " $N
9491 $CMD1 >"$tf" 2>"${te}1" &
9492 pid1=$!
9493 waitudp4port $tsl 1
9494 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9495 rc2=$?
9496 sleep 1
9497 #read -p ">"
9498 l="$(childprocess $pid1)"
9499 #echo "l=\"$l\""
9500 kill $pid1 2>/dev/null; wait
9501 if [ $rc2 -ne 0 ]; then
9502 $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM
9503 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9504 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9505 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9506 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9507 numCANT=$((numCANT+1))
9508 listCANT="$listCANT $N"
9509 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9510 $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM
9511 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9512 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9513 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9514 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9515 numCANT=$((numCANT+1))
9516 listCANT="$listCANT $N"
9517 elif $(isdefunct "$l"); then
9518 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9519 echo "$CMD1 &"
9520 cat "${te}1" >&2
9521 echo "$CMD2"
9522 cat "${te}2" >&2
9523 cat "${te}1" "${te}2"
9524 numFAIL=$((numFAIL+1))
9525 listFAIL="$listFAIL $N"
9526 else
9527 $PRINTF "$OK\n"
9528 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9529 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9530 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9531 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9532 numOK=$((numOK+1))
9534 fi ;; # NUMCOND
9535 esac
9536 N=$((N+1))
9539 # test: there was a bug with ip*-recv and bind option: it would not bind, and
9540 # with the first received packet an error:
9541 # socket_init(): unknown address family 0
9542 # occurred
9543 NAME=RAWIP4RECVBIND
9544 case "$TESTS" in
9545 *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*)
9546 TEST="$NAME: raw IPv4 receive with bind"
9547 # idea: start a socat process with ip4-recv:...,bind=... and send it a packet
9548 # if the packet passes the test succeeded
9549 if ! eval $NUMCOND; then :;
9550 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
9551 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
9552 numCANT=$((numCANT+1))
9553 listCANT="$listCANT $N"
9554 else
9555 tf="$td/test$N.stdout"
9556 te="$td/test$N.stderr"
9557 tdiff="$td/test$N.diff"
9558 ts1p=$PROTO; PROTO=$((PROTO+1))
9559 ts1a="127.0.0.1"
9560 ts1="$ts1a:$ts1p"
9561 da="test$N $(date) $RANDOM"
9562 CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -"
9563 CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1"
9564 printf "test $F_n $TEST... " $N
9565 $CMD1 >"$tf" 2>"${te}1" &
9566 pid1="$!"
9567 waitip4proto $ts1p 1
9568 echo "$da" |$CMD2 2>>"${te}2"
9569 rc2="$?"
9570 #ls -l $tf
9571 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
9572 kill "$pid1" 2>/dev/null; wait
9573 if [ "$rc2" -ne 0 ]; then
9574 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9575 echo "$CMD1 &"
9576 echo "$CMD2"
9577 cat "${te}1"
9578 cat "${te}2"
9579 numFAIL=$((numFAIL+1))
9580 listFAIL="$listFAIL $N"
9581 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9582 $PRINTF "$FAILED\n"
9583 cat "$tdiff"
9584 numFAIL=$((numFAIL+1))
9585 listFAIL="$listFAIL $N"
9586 else
9587 $PRINTF "$OK\n"
9588 if [ -n "$debug" ]; then cat $te; fi
9589 numOK=$((numOK+1))
9591 fi ;; # NUMCOND, root
9592 esac
9593 PROTO=$((PROTO+1))
9594 N=$((N+1))
9597 # there was a bug in *-recvfrom with fork: due to an error in the appropriate
9598 # signal handler the master process would hang after forking off the first
9599 # child process.
9600 NAME=UDP4RECVFROM_FORK
9601 case "$TESTS" in
9602 *%$N%*|*%functions%*|*%fork%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
9603 TEST="$NAME: test if UDP4-RECVFROM handles more than one packet"
9604 # idea: run a UDP4-RECVFROM process with fork and -T. Send it one packet;
9605 # send it a second packet and check if this is processed properly. If yes, the
9606 # test succeeded.
9607 if ! eval $NUMCOND; then :; else
9608 tf="$td/test$N.stdout"
9609 te="$td/test$N.stderr"
9610 tdiff="$td/test$N.diff"
9611 newport udp4; tsp=$PORT
9612 ts="$LOCALHOST:$tsp"
9613 da2a="test$N $(date) $RANDOM"
9614 da2b="test$N $(date) $RANDOM"
9615 CMD1="$TRACE $SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE"
9616 CMD2="$TRACE $SOCAT $opts -T 1 - UDP4-SENDTO:$ts"
9617 printf "test $F_n $TEST... " $N
9618 $CMD1 >/dev/null 2>"${te}1" &
9619 pid1=$!
9620 waitudp4port $tsp 1
9621 echo "$da2a" |$CMD2 >/dev/null 2>>"${te}2a" # this should always work
9622 rc2a=$?
9623 echo "$da2b" |$CMD2 >"$tf" 2>>"${te}2b" # this would fail when bug
9624 rc2b=$?
9625 kill $pid1 2>/dev/null; wait
9626 if [ $rc2b -ne 0 ]; then
9627 $PRINTF "$NO_RESULT\n"
9628 numCANT=$((numCANT+1))
9629 listCANT="$listCANT $N"
9630 elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then
9631 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9632 echo "$CMD1 &" >&2
9633 cat "${te}1" >&2
9634 echo "$CMD2" >&2
9635 cat "${te}2b" >&2
9636 cat "$tdiff" >&2
9637 numFAIL=$((numFAIL+1))
9638 listFAIL="$listFAIL $N"
9639 else
9640 $PRINTF "$OK\n"
9641 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi
9642 numOK=$((numOK+1))
9644 fi ;; # NUMCOND
9645 esac
9646 N=$((N+1))
9649 # there was a bug in parsing the arguments of exec: consecutive spaces resulted
9650 # in additional empty arguments
9651 NAME=EXECSPACES
9652 case "$TESTS" in
9653 *%$N%*|*%functions%*|*%exec%*|*%parse%*|*%$NAME%*)
9654 TEST="$NAME: correctly parse exec with consecutive spaces"
9655 if ! eval $NUMCOND; then :; else
9656 $PRINTF "test $F_n $TEST... " $N
9657 tf="$td/test$N.stdout"
9658 te="$td/test$N.stderr"
9659 da="test$N $(date) $RANDOM" # with a double space
9660 tdiff="$td/test$N.diff"
9661 # put the test data as first argument after two spaces. expect the data in the
9662 # first argument of the exec'd command.
9663 $TRACE $SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te"
9664 rc=$?
9665 echo "$da" |diff - "$tf" >"$tdiff"
9666 if [ "$rc" -ne 0 ]; then
9667 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9668 cat "$te"
9669 numFAIL=$((numFAIL+1))
9670 listFAIL="$listFAIL $N"
9671 elif [ -s "$tdiff" ]; then
9672 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9673 echo diff:
9674 cat "$tdiff"
9675 if [ -n "$debug" ]; then cat $te; fi
9676 numFAIL=$((numFAIL+1))
9677 listFAIL="$listFAIL $N"
9678 else
9679 $PRINTF "$OK\n"
9680 if [ -n "$debug" ]; then cat $te; fi
9681 numOK=$((numOK+1))
9683 fi ;; # NUMCOND
9684 esac
9685 N=$((N+1))
9688 # a bug was found in the way UDP-LISTEN handles the listening socket:
9689 # when UDP-LISTEN continued to listen after a packet had been dropped by, e.g.,
9690 # range option, the old listen socket would not be closed but a new one created.
9691 NAME=UDP4LISTENCONT
9692 case "$TESTS" in
9693 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%listen%*|*%$NAME%*)
9694 TEST="$NAME: let range drop a packet and see if old socket is closed"
9695 # idea: run a UDP4-LISTEN process with range option. Send it one packet from an
9696 # address outside range and check if two listening sockets are open then
9697 if ! eval $NUMCOND; then :; else
9698 tf="$td/test$N.stdout"
9699 te="$td/test$N.stderr"
9700 tdiff="$td/test$N.diff"
9701 newport udp4; tp=$PORT
9702 da1="test$N $(date) $RANDOM"
9703 a1="$LOCALHOST"
9704 a2="$SECONDADDR"
9705 #CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE"
9706 CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,$REUSEADDR,range=$a2/32 PIPE"
9707 CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$a1:$tp"
9708 printf "test $F_n $TEST... " $N
9709 $CMD0 >/dev/null 2>"${te}0" &
9710 pid1=$!
9711 waitudp4port $tp 1
9712 echo "$da1" |$CMD1 >"${tf}1" 2>"${te}1" # this should fail
9713 rc1=$?
9714 waitudp4port $tp 1
9715 if [ "$SS" ]; then
9716 nsocks="$($SS -anu |grep ":$PORT\>" |wc -l)"
9717 else
9718 nsocks="$(netstat -an |grep "^udp.*[:.]$PORT\>" |wc -l)"
9720 kill $pid1 2>/dev/null; wait
9721 if [ $rc1 -ne 0 ]; then
9722 $PRINTF "$NO_RESULT\n"
9723 numCANT=$((numCANT+1))
9724 listCANT="$listCANT $N"
9725 elif [ $nsocks -eq 0 ]; then
9726 $PRINTF "$NO_RESULT\n"
9727 numCANT=$((numCANT+1))
9728 listCANT="$listCANT $N"
9729 elif [ $nsocks -ne 1 ]; then
9730 $PRINTF "$FAILED ($nsocks listening sockets)\n"
9731 echo "$CMD0 &"
9732 echo "$CMD1"
9733 cat "${te}0" "${te}1"
9734 numFAIL=$((numFAIL+1))
9735 listFAIL="$listFAIL $N"
9736 else
9737 $PRINTF "$OK\n"
9738 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
9739 numOK=$((numOK+1))
9741 fi ;; # NUMCOND
9742 esac
9743 N=$((N+1))
9746 # during wait for next poll time option ignoreeof blocked the data transfer in
9747 # the reverse direction
9748 NAME=IGNOREEOFNOBLOCK
9749 case "$TESTS" in
9750 *%$N%*|*%functions%*|*%engine%*|*%socket%*|*%ignoreeof%*|*%$NAME%*)
9751 TEST="$NAME: ignoreeof does not block other direction"
9752 # have socat poll in ignoreeof mode. while it waits one second for next check,
9753 # we send data in the reverse direction and then the total timeout fires.
9754 # it the data has passed, the test succeeded.
9755 if ! eval $NUMCOND; then :; else
9756 tf="$td/test$N.stout"
9757 te="$td/test$N.stderr"
9758 tdiff="$td/test$N.diff"
9759 da="test$N $(date) $RANDOM"
9760 CMD0="$TRACE $SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null"
9761 printf "test $F_n $TEST... " $N
9762 (usleep 333333; echo "$da") |$CMD0 >"$tf" 2>"${te}0"
9763 rc0=$?
9764 if [ $rc0 != 0 ]; then
9765 $PRINTF "$FAILED\n"
9766 echo "$CMD0 &"
9767 echo "$CMD1"
9768 cat "${te}0"
9769 cat "${te}1"
9770 numFAIL=$((numFAIL+1))
9771 listFAIL="$listFAIL $N"
9772 elif echo "$da" |diff - "$tf" >/dev/null; then
9773 $PRINTF "$OK\n"
9774 numOK=$((numOK+1))
9775 else
9776 $PRINTF "$FAILED\n"
9777 echo "$CMD0 &"
9778 echo "$CMD1"
9779 cat "${te}0"
9780 numFAIL=$((numFAIL+1))
9781 listFAIL="$listFAIL $N"
9783 fi ;; # NUMCOND
9784 esac
9785 N=$((N+1))
9788 # test the escape option
9789 NAME=ESCAPE
9790 case "$TESTS" in
9791 *%$N%*|*%functions%*|*%engine%*|*%escape%*|*%$NAME%*)
9792 TEST="$NAME: escape character triggers EOF"
9793 # idea: start socat just echoing input, but apply escape option. send a string
9794 # containing the escape character and check if the output is truncated
9795 if ! eval $NUMCOND; then :; else
9796 tf="$td/test$N.stdout"
9797 te="$td/test$N.stderr"
9798 tdiff="$td/test$N.diff"
9799 da="test$N $(date) $RANDOM"
9800 CMD="$TRACE $SOCAT $opts -,escape=27 pipe"
9801 printf "test $F_n $TEST... " $N
9802 $ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te"
9803 if [ $? -ne 0 ]; then
9804 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9805 echo "$CMD"
9806 cat "$te"
9807 numFAIL=$((numFAIL+1))
9808 listFAIL="$listFAIL $N"
9809 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9810 $PRINTF "$FAILED: diff:\n"
9811 cat "$tdiff"
9812 numFAIL=$((numFAIL+1))
9813 listFAIL="$listFAIL $N"
9814 else
9815 $PRINTF "$OK\n"
9816 if [ -n "$debug" ]; then cat $te; fi
9817 numOK=$((numOK+1))
9819 fi ;; # NUMCOND
9820 esac
9821 N=$((N+1))
9823 # test the escape option combined with ignoreeof
9824 NAME=ESCAPE_IGNOREEOF
9825 case "$TESTS" in
9826 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%escape%*|*%$NAME%*)
9827 TEST="$NAME: escape character triggers EOF"
9828 # idea: start socat just echoing input, but apply escape option. send a string
9829 # containing the escape character and check if the output is truncated
9830 if ! eval $NUMCOND; then :; else
9831 ti="$td/test$N.file"
9832 tf="$td/test$N.stdout"
9833 te="$td/test$N.stderr"
9834 tdiff="$td/test$N.diff"
9835 da="test$N $(date) $RANDOM"
9836 CMD="$TRACE $SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe"
9837 printf "test $F_n $TEST... " $N
9838 >"$ti"
9839 $CMD >"$tf" 2>"$te" &
9840 $ECHO "$da\n\x1bXYZ" >>"$ti"
9841 sleep 1
9842 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
9843 $PRINTF "$FAILED: diff:\n"
9844 cat "$tdiff"
9845 cat "$te"
9846 numFAIL=$((numFAIL+1))
9847 listFAIL="$listFAIL $N"
9848 else
9849 $PRINTF "$OK\n"
9850 if [ -n "$debug" ]; then cat $te; fi
9851 numOK=$((numOK+1))
9853 fi ;; # NUMCOND
9854 esac
9855 N=$((N+1))
9858 # test: logging of ancillary message
9859 while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE
9861 if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
9863 pf="$(echo "$PF" |tr A-Z a-z)"
9864 proto="$(echo "$KEYW" |tr A-Z a-z)"
9865 NAME=${KEYW}SCM_$SCM_TYPE
9866 case "$TESTS" in
9867 *%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%$ROOT%*|*%$NAME%*)
9868 TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME"
9869 # idea: start a socat process with *-RECV:..,... , ev. with ancillary message
9870 # enabling option and send it a packet, ev. with some option. check the info log
9871 # for the appropriate output.
9872 if ! eval $NUMCOND; then :;
9873 #elif [[ "$PF" == "#*" ]]; then :
9874 elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
9875 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
9876 numCANT=$((numCANT+1))
9877 listCANT="$listCANT $N"
9878 elif ! feat=$(testfeats ${KEYW%[46]} IP${KEYW##*[A-Z]}); then
9879 $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not configured in $SOCAT${NORMAL}\n" $N
9880 numCANT=$((numCANT+1))
9881 listCANT="$listCANT $N"
9882 elif ! runs${proto} >/dev/null; then
9883 $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available on host${NORMAL}\n" $N
9884 numCANT=$((numCANT+1))
9885 listCANT="$listCANT $N"
9886 elif ! testoptions $SCM_RECV >/dev/null; then
9887 $PRINTF "test $F_n $TEST... ${YELLOW}option $SCM_RECV not available${NORMAL}\n" $N
9888 numCANT=$((numCANT+1))
9889 listCANT="$listCANT $N"
9890 else
9891 tf="$td/test$N.stdout"
9892 te="$td/test$N.stderr"
9893 case "X$IPPORT" in
9894 "XPORT")
9895 newport $proto; tra="$PORT" # test recv address
9896 tsa="$ADDR:$PORT" # test sendto address
9898 "XPROTO")
9899 tra="$PROTO" # test recv address
9900 tsa="$ADDR:$PROTO" # test sendto address
9901 PROTO=$((PROTO+1)) ;;
9903 tra="$(eval echo "$ADDR")" # resolve $N
9904 tsa="$tra"
9905 esac
9906 CMD0="$TRACE $SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -"
9907 CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
9908 printf "test $F_n $TEST... " $N
9909 # is this option supported?
9910 if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
9911 if [ "$SCM_VALUE" = "timestamp" ]; then
9912 secs="$(date '+%S')"
9913 if [ "$secs" -ge 58 -a "$secs" -le 59 ]; then
9914 dsecs=$((60-secs))
9915 #echo "Sleeping $dsecs seconds to avoid minute change in timestamp" >/dev/tty
9916 sleep $dsecs
9919 $CMD0 >"$tf" 2>"${te}0" &
9920 pid0="$!"
9921 wait${proto}port $tra 1
9922 echo "XYZ" |$CMD1 2>"${te}1"
9923 rc1="$?"
9924 sleep 1
9925 i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
9926 kill "$pid0" 2>/dev/null; wait
9927 # do not show more messages than requested
9928 case "$opts" in
9929 *-d*-d*-d*-d*) LEVELS="[EWNID]" ;;
9930 *-d*-d*-d*) LEVELS="[EWNI]" ;;
9931 *-d*-d*) LEVELS="[EWN]" ;;
9932 *-d*) LEVELS="[EW]" ;;
9933 *) LEVELS="[E]" ;;
9934 esac
9935 if [ "$SCM_VALUE" = "timestamp" ]; then
9936 SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs"
9938 if [ "$rc1" -ne 0 ]; then
9939 $PRINTF "$NO_RESULT: $TRACE $SOCAT:\n"
9940 echo "$CMD0 &"
9941 echo "$CMD1"
9942 grep " $LEVELS " "${te}0"
9943 grep " $LEVELS " "${te}1"
9944 numCANT=$((numCANT+1))
9945 listCANT="$listCANT $N"
9946 elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then
9947 $PRINTF "$FAILED\n"
9948 echo "variable $SCM_TYPE: $SCM_NAME not set"
9949 echo "$CMD0 &"
9950 echo "$CMD1"
9951 grep " $LEVELS " "${te}0"
9952 grep " $LEVELS " "${te}1"
9953 numFAIL=$((numFAIL+1))
9954 listFAIL="$listFAIL $N"
9955 elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/null; then
9956 $PRINTF "$FAILED\n"
9957 badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')"
9958 echo "variable $SCM_TYPE: $SCM_NAME has value \"$badval\" instead of pattern \"$SCM_VALUE\"" >&2
9959 echo "$CMD0 &"
9960 echo "$CMD1"
9961 grep " $LEVELS " "${te}0"
9962 grep " $LEVELS " "${te}1"
9963 numFAIL=$((numFAIL+1))
9964 listFAIL="$listFAIL $N"
9965 else
9966 $PRINTF "$OK\n"
9967 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
9968 if [ "$DEBUG" ]; then grep " $LEVELS " "${te}0" >&2; fi
9969 if [ "$VERBOSE" ]; then echo "echo XYZ |$CMD1"; fi
9970 if [ "$DEBUG" ]; then grep " $LEVELS " "${te}1" >&2; fi
9971 numOK=$((numOK+1))
9973 else # option is not supported
9974 $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
9975 numCANT=$((numCANT+1))
9976 listCANT="$listCANT $N"
9977 fi # option is not supported
9978 fi # NUMCOND, root, feats
9980 esac
9981 N=$((N+1))
9983 done <<<"
9984 IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS options user x01000000
9985 IP4 UDP4 127.0.0.1 PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp
9986 IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL ttl user 53
9987 IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS tos user 7
9988 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO locaddr user 127.0.0.1
9989 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO dstaddr user 127.0.0.1
9990 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO if user lo
9991 IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF if user lo0
9992 IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR dstaddr user 127.0.0.1
9993 IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS options root x01000000
9994 IP4 IP4 127.0.0.1 PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp
9995 IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL ttl root 53
9996 IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS tos root 7
9997 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO locaddr root 127.0.0.1
9998 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO dstaddr root 127.0.0.1
9999 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO if root lo
10000 IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF if root lo0
10001 IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR dstaddr root 127.0.0.1
10002 IP6 UDP6 [::1] PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp
10003 IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_PKTINFO dstaddr user [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10004 IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit user 35
10005 IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass user x000000aa
10006 IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp
10007 IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_PKTINFO dstaddr root [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10008 IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit root 35
10009 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass root x000000aa
10010 #UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user timestamp
10012 # this one fails, appearently due to a Linux weakness:
10013 # UNIX so-timestamp
10016 # test: setting of environment variables that describe a stream socket
10017 # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT,
10018 # SOCAT_PEERPORT when applicable
10019 while read KEYW FEAT SEL TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
10020 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
10022 protov="$(echo "$KEYW" |tr A-Z a-z)"
10023 proto="${protov%%[0-9]}"
10024 NAME=${KEYW}LISTENENV
10025 case "$TESTS" in
10026 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%$SEL%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
10027 TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
10028 # have a server accepting a connection and invoking some shell code. The shell
10029 # code extracts and prints the SOCAT related environment vars.
10030 # outside code then checks if the environment contains the variables correctly
10031 # describing the peer and local sockets.
10032 if ! eval $NUMCOND; then :;
10033 elif ! feat=$(testfeats $FEAT); then
10034 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
10035 numCANT=$((numCANT+1))
10036 listCANT="$listCANT $N"
10037 elif ! runs${protov} >/dev/null; then
10038 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
10039 numCANT=$((numCANT+1))
10040 listCANT="$listCANT $N"
10041 else
10042 tf="$td/test$N.stdout"
10043 te="$td/test$N.stderr"
10044 TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars
10045 tsa="$TEST_SOCKADDR" # test server address
10046 if [ "$PORTMETHOD" == PORT ]; then
10047 newport $proto; tsp="$PORT"; # test server port
10048 tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind=
10049 TEST_SOCKPORT=$tsp
10050 else
10051 tsa1="$tsa"; tsa2= # tsa1 used for addr parameter
10053 TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars
10054 tca="$TEST_PEERADDR" # test client address
10055 if [ $PORTMETHOD = PORT ]; then
10056 newport $proto; tcp="$PORT"; # test client port
10057 tca="$tca:$tcp"
10058 TEST_PEERPORT=$tcp
10060 #CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\""
10061 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\""
10062 CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
10063 printf "test $F_n $TEST... " $N
10064 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
10065 pid0=$!
10066 wait${protov}port $tsa1 1
10067 { echo; sleep 0.1; } |$CMD1 2>"${te}1"
10068 rc1=$?
10069 waitfile "$tf" 2
10070 kill $pid0 2>/dev/null; wait
10071 #set -vx
10072 if [ $rc1 != 0 ]; then
10073 $PRINTF "$NO_RESULT (client failed):\n"
10074 echo "$CMD0 &"
10075 cat "${te}0"
10076 echo "$CMD1"
10077 cat "${te}1"
10078 numCANT=$((numCANT+1))
10079 listCANT="$listCANT $N"
10080 elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
10081 "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
10082 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \
10083 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_PEERPORT" \) \
10084 ]; then
10085 $PRINTF "$OK\n"
10086 if [ "$debug" ]; then
10087 echo "$CMD0 &"
10088 cat "${te}0"
10089 echo "$CMD1"
10090 cat "${te}1"
10092 numOK=$((numOK+1))
10093 else
10094 $PRINTF "$FAILED\n"
10095 echo "$CMD0 &"
10096 cat "${te}0"
10097 echo "$CMD1"
10098 cat "${te}1"
10099 echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
10100 diff - "${tf}"
10101 numFAIL=$((numFAIL+1))
10102 listFAIL="$listFAIL $N"
10104 fi # NUMCOND, feats
10106 esac
10107 N=$((N+1))
10108 #set +xv
10110 done <<<"
10111 TCP4 TCP tcp 127.0.0.1 $SECONDADDR PORT
10112 TCP6 IP6 tcp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
10113 UDP6 IP6 udp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
10114 SCTP4 SCTP sctp 127.0.0.1 $SECONDADDR PORT
10115 SCTP6 SCTP sctp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
10116 UNIX UNIX unix $td/test\$N.server $td/test\$N.client ,
10118 # this one fails due to weakness in socats UDP4-LISTEN implementation:
10119 #UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5))
10122 # test: environment variables from ancillary message
10123 while read PF KEYW SEL ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE
10125 if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
10127 pf="$(echo "$PF" |tr A-Z a-z)"
10128 proto="$(echo "$KEYW" |tr A-Z a-z)"
10129 NAME=${KEYW}ENV_$SCM_ENVNAME
10130 case "$TESTS" in
10131 *%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%$SEL%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*)
10132 #set -vx
10133 TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME"
10134 # idea: start a socat process with *-RECVFROM:..,... , ev. with ancillary
10135 # message enabling option and send it a packet, ev. with some option. write
10136 # the resulting environment to a file and check its contents for the
10137 # appropriate variable.
10138 if ! eval $NUMCOND; then :;
10139 elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
10140 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
10141 numCANT=$((numCANT+1))
10142 listCANT="$listCANT $N"
10143 elif [ "$PF" = "IP6" ] && ( ! feat=$(testfeats ip6) || ! runsip6 ) >/dev/null; then
10144 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
10145 numCANT=$((numCANT+1))
10146 listCANT="$listCANT $N"
10147 else
10148 tf="$td/test$N.stdout"
10149 te="$td/test$N.stderr"
10150 case "X$IPPORT" in
10151 "XPORT")
10152 newport $proto; tra="$PORT" # test recv address
10153 tsa="$ADDR:$tra" # test sendto address
10155 "XPROTO")
10156 tra="$PROTO" # test recv address
10157 tsa="$ADDR:$PROTO" # test sendto address
10158 PROTO=$((PROTO+1)) ;;
10160 tra="$(eval echo "$ADDR")" # resolve $N
10161 tsa="$tra"
10162 esac
10163 #CMD0="$TRACE $SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"export -p\""
10164 # without that ultra escaped quote the test failed for IPv6 when there was file ./1
10165 CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"echo \\\\\\\"\\\$SOCAT_$SCM_ENVNAME\\\\\\\"\""
10166 CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
10167 printf "test $F_n $TEST... " $N
10168 # is this option supported?
10169 if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
10170 if [ "$SCM_VALUE" = "timestamp" ]; then
10171 secs="$(date '+%S')"
10172 if [ "$secs" -ge 58 -a "$secs" -le 59 ]; then
10173 dsecs=$((60-secs))
10174 #echo "Sleeping $dsecs seconds to avoid minute change in timestamp" >/dev/tty
10175 sleep $dsecs
10178 eval "$CMD0 >\"$tf\" 2>\"${te}0\" &"
10179 pid0="$!"
10180 wait${proto}port $tra 1
10181 { echo "XYZ"; sleep 0.1; } |$CMD1 2>"${te}1"
10182 rc1="$?"
10183 waitfile "$tf" 2
10184 #i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
10185 kill "$pid0" 2>/dev/null; wait
10186 # do not show more messages than requested
10187 if [ "$SCM_VALUE" = "timestamp" ]; then
10188 SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs"
10189 #echo "\"$SCM_VALUE\"" >&2 # debugging
10191 if [ "$rc1" -ne 0 ]; then
10192 $PRINTF "$NO_RESULT: $SOCAT:\n"
10193 echo "$CMD0 &"
10194 echo "$CMD1"
10195 cat "${te}0"
10196 cat "${te}1"
10197 numCANT=$((numCANT+1))
10198 listCANT="$listCANT $N"
10199 #elif ! egrep "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then
10200 #elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then
10201 elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then
10202 $PRINTF "$FAILED\n"
10203 echo "logged value \"$(cat "$tf")\" instead of $SCM_VALUE"
10204 echo "$CMD0 &"
10205 echo "$CMD1"
10206 cat "${te}0"
10207 cat "${te}1"
10208 numFAIL=$((numFAIL+1))
10209 listFAIL="$listFAIL $N"
10210 else
10211 $PRINTF "$OK\n"
10212 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
10213 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
10214 if [ "$VERBOSE" ]; then echo "{ echo XYZ; sleep 0.1; } |$CMD1"; fi
10215 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
10216 numOK=$((numOK+1))
10218 else # option is not supported
10219 $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
10220 numCANT=$((numCANT+1))
10221 listCANT="$listCANT $N"
10222 fi # option is not supported
10223 fi ;; # NUMCOND, feats
10224 esac
10225 N=$((N+1))
10227 done <<<"
10228 IP4 UDP4 udp 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000
10229 IP4 UDP4 udp 127.0.0.1 PORT , so-timestamp TIMESTAMP user timestamp
10230 IP4 UDP4 udp 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53
10231 IP4 UDP4 udp 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7
10232 IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1
10233 IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1
10234 IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_IF user lo
10235 IP4 UDP4 udp 127.0.0.1 PORT , ip-recvif IP_IF user lo0
10236 IP4 UDP4 udp 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1
10237 IP4 IP4 rawip 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000
10238 IP4 IP4 rawip 127.0.0.1 PROTO , so-timestamp TIMESTAMP root timestamp
10239 IP4 IP4 rawip 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53
10240 IP4 IP4 rawip 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7
10241 IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1
10242 IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1
10243 IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo
10244 IP4 IP4 rawip 127.0.0.1 PROTO , ip-recvif IP_IF root lo0
10245 IP4 IP4 rawip 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1
10246 IP6 UDP6 udp [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10247 IP6 UDP6 udp [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35
10248 IP6 UDP6 udp [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user x000000aa
10249 IP6 IP6 rawip [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10250 IP6 IP6 rawip [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35
10251 IP6 IP6 rawip [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root x000000aa
10252 #UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user timestamp
10256 # test the SOCKET-CONNECT address (against TCP4-LISTEN)
10257 NAME=SOCKET_CONNECT_TCP4
10258 case "$TESTS" in
10259 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%listen%*|*%$NAME%*)
10260 TEST="$NAME: socket connect with TCP/IPv4"
10261 # start a TCP4-LISTEN process that echoes data, and send test data using
10262 # SOCKET-CONNECT, selecting TCP/IPv4. The sent data should be returned.
10263 if ! eval $NUMCOND; then :; else
10264 tf="$td/test$N.stdout"
10265 te="$td/test$N.stderr"
10266 tdiff="$td/test$N.diff"
10267 newport tcp4; ts0p=$PORT
10268 ts0a="127.0.0.1"
10269 ts1p=$(printf "%04x" $ts0p);
10270 ts1a="7f000001" # "127.0.0.1"
10271 ts1="x${ts1p}${ts1a}x0000000000000000"
10272 newport tcp4; ts1b=$(printf "%04x" $PORT)
10273 da="test$N $(date) $RANDOM"
10274 CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$ts0p,$REUSEADDR,bind=$ts0a PIPE"
10275 CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000"
10276 printf "test $F_n $TEST... " $N
10277 $CMD0 2>"${te}0" &
10278 pid0="$!"
10279 waittcp4port $ts0p 1
10280 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10281 rc1="$?"
10282 kill "$pid0" 2>/dev/null; wait;
10283 if [ "$rc1" -ne 0 ]; then
10284 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10285 echo "$CMD0 &"
10286 cat "${te}0"
10287 echo "$CMD1"
10288 cat "${te}1"
10289 numFAIL=$((numFAIL+1))
10290 listFAIL="$listFAIL $N"
10291 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10292 $PRINTF "$FAILED\n"
10293 cat "$tdiff"
10294 echo "$CMD0 &"
10295 cat "${te}0"
10296 echo "$CMD1"
10297 cat "${te}1"
10298 numFAIL=$((numFAIL+1))
10299 listFAIL="$listFAIL $N"
10300 else
10301 $PRINTF "$OK\n"
10302 if [ -n "$debug" ]; then cat $te; fi
10303 numOK=$((numOK+1))
10305 fi # NUMCOND
10307 esac
10308 N=$((N+1))
10311 # test the SOCKET-CONNECT address (against TCP6-LISTEN)
10312 NAME=SOCKET_CONNECT_TCP6
10313 case "$TESTS" in
10314 *%$N%*|*%functions%*|*%generic%*|*%tcp6%*|*%socket%*|*%listen%*|*%$NAME%*)
10315 TEST="$NAME: socket connect with TCP/IPv6"
10316 if ! eval $NUMCOND; then :;
10317 elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
10318 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
10319 numCANT=$((numCANT+1))
10320 listCANT="$listCANT $N"
10321 else
10322 # start a TCP6-LISTEN process that echoes data, and send test data using
10323 # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned.
10324 tf="$td/test$N.stdout"
10325 te="$td/test$N.stderr"
10326 tdiff="$td/test$N.diff"
10327 newport tcp6; ts0p=$PORT
10328 ts0a="[::1]"
10329 ts1p=$(printf "%04x" $ts0p);
10330 ts1a="00000000000000000000000000000001" # "[::1]"
10331 ts1="x${ts1p}x00000000x${ts1a}x00000000"
10332 newport tcp6; ts1b=$(printf "%04x" $PORT)
10333 da="test$N $(date) $RANDOM"
10334 CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$ts0p,$REUSEADDR,bind=$ts0a PIPE"
10335 CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000"
10336 printf "test $F_n $TEST... " $N
10337 $CMD0 2>"${te}0" &
10338 pid0="$!"
10339 waittcp6port $ts0p 1
10340 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10341 rc1="$?"
10342 kill "$pid0" 2>/dev/null; wait;
10343 if [ "$rc1" -ne 0 ]; then
10344 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10345 echo "$CMD0 &"
10346 cat "${te}0"
10347 echo "$CMD1"
10348 cat "${te}1"
10349 numFAIL=$((numFAIL+1))
10350 listFAIL="$listFAIL $N"
10351 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10352 $PRINTF "$FAILED\n"
10353 cat "$tdiff"
10354 echo "$CMD0 &"
10355 cat "${te}0"
10356 echo "$CMD1"
10357 cat "${te}1"
10358 numFAIL=$((numFAIL+1))
10359 listFAIL="$listFAIL $N"
10360 else
10361 $PRINTF "$OK\n"
10362 if [ -n "$debug" ]; then cat $te; fi
10363 numOK=$((numOK+1))
10365 fi ;; # NUMCOND
10366 esac
10367 N=$((N+1))
10369 # test the SOCKET-CONNECT address (against UNIX-LISTEN)
10370 NAME=SOCKET_CONNECT_UNIX
10371 case "$TESTS" in
10372 *%$N%*|*%functions%*|*%generic%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
10373 TEST="$NAME: socket connect with UNIX domain"
10374 # start a UNIX-LISTEN process that echoes data, and send test data using
10375 # SOCKET-CONNECT, selecting UNIX socket. The sent data should be returned.
10376 if ! eval $NUMCOND; then :; else
10377 tf="$td/test$N.stdout"
10378 te="$td/test$N.stderr"
10379 tdiff="$td/test$N.diff"
10380 ts0="$td/test$N.server"
10381 ts1="$td/test$N.client"
10382 da="test$N $(date) $RANDOM"
10383 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts0,$REUSEADDR PIPE"
10384 CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\""
10385 printf "test $F_n $TEST... " $N
10386 $CMD0 2>"${te}0" &
10387 pid0="$!"
10388 waitfile $ts0 1
10389 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10390 rc1="$?"
10391 kill "$pid0" 2>/dev/null; wait;
10392 if [ "$rc1" -ne 0 ]; then
10393 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10394 echo "$CMD0 &"
10395 cat "${te}0"
10396 echo "$CMD1"
10397 cat "${te}1"
10398 numFAIL=$((numFAIL+1))
10399 listFAIL="$listFAIL $N"
10400 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10401 $PRINTF "$FAILED\n"
10402 cat "$tdiff"
10403 echo "$CMD0 &"
10404 cat "${te}0"
10405 echo "$CMD1"
10406 cat "${te}1"
10407 numFAIL=$((numFAIL+1))
10408 listFAIL="$listFAIL $N"
10409 else
10410 $PRINTF "$OK\n"
10411 if [ -n "$debug" ]; then cat $te; fi
10412 numOK=$((numOK+1))
10414 fi ;; # NUMCOND
10415 esac
10416 N=$((N+1))
10418 # test the SOCKET-LISTEN address (with TCP4-CONNECT)
10419 NAME=SOCKET_LISTEN
10420 case "$TESTS" in
10421 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%listen%*|*%$NAME%*)
10422 TEST="$NAME: socket recvfrom with TCP/IPv4"
10423 # start a SOCKET-LISTEN process that uses TCP/IPv4 and echoes data, and
10424 # send test data using TCP4-CONNECT. The sent data should be returned.
10425 if ! eval $NUMCOND; then :; else
10426 tf="$td/test$N.stdout"
10427 te="$td/test$N.stderr"
10428 tdiff="$td/test$N.diff"
10429 newport tcp4; ts1p=$PORT
10430 ts1a="127.0.0.1"
10431 ts0p=$(printf "%04x" $ts1p);
10432 ts0a="7f000001" # "127.0.0.1"
10433 ts0="x${ts0p}${ts0a}x0000000000000000"
10434 newport tcp4; ts1b=$PORT
10435 ts1="$ts1a:$ts1p"
10436 da="test$N $(date) $RANDOM"
10437 CMD0="$TRACE $SOCAT $opts SOCKET-LISTEN:2:6:$ts0,$REUSEADDR PIPE"
10438 CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b"
10439 printf "test $F_n $TEST... " $N
10440 $CMD0 2>"${te}0" &
10441 pid0="$!"
10442 #sleep 1
10443 waittcp4port $ts1p 1
10444 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10445 rc1="$?"
10446 kill "$pid0" 2>/dev/null; wait;
10447 if [ "$rc1" -ne 0 ]; then
10448 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10449 echo "$CMD0 &"
10450 cat "${te}0"
10451 echo "$CMD1"
10452 cat "${te}1"
10453 numFAIL=$((numFAIL+1))
10454 listFAIL="$listFAIL $N"
10455 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10456 $PRINTF "$FAILED\n"
10457 cat "$tdiff"
10458 echo "$CMD0 &"
10459 cat "${te}0"
10460 echo "$CMD1"
10461 cat "${te}1"
10462 numFAIL=$((numFAIL+1))
10463 listFAIL="$listFAIL $N"
10464 else
10465 $PRINTF "$OK\n"
10466 if [ -n "$debug" ]; then cat $te; fi
10467 numOK=$((numOK+1))
10469 fi ;; # NUMCOND
10470 esac
10471 N=$((N+1))
10473 # test the SOCKET-SENDTO address (against UDP4-RECVFROM)
10474 NAME=SOCKET_SENDTO
10475 case "$TESTS" in
10476 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10477 TEST="$NAME: socket sendto with UDP/IPv4"
10478 # start a UDP4-RECVFROM process that echoes data, and send test data using
10479 # SOCKET-SENDTO, selecting UDP/IPv4. The sent data should be returned.
10480 if ! eval $NUMCOND; then :; else
10481 tf="$td/test$N.stdout"
10482 te="$td/test$N.stderr"
10483 tdiff="$td/test$N.diff"
10484 newport udp4; ts0p=$PORT
10485 ts0a="127.0.0.1"
10486 ts1p=$(printf "%04x" $ts0p);
10487 ts1a="7f000001" # "127.0.0.1"
10488 ts1="x${ts1p}${ts1a}x0000000000000000"
10489 newport udp4; ts1b=$(printf "%04x" $PORT)
10490 da="test$N $(date) $RANDOM"
10491 CMD0="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE"
10492 CMD1="$TRACE $SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
10493 printf "test $F_n $TEST... " $N
10494 $CMD0 2>"${te}0" &
10495 pid0="$!"
10496 waitudp4port $ts0p 1
10497 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10498 rc1="$?"
10499 kill "$pid0" 2>/dev/null; wait;
10500 if [ "$rc1" -ne 0 ]; then
10501 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10502 echo "$CMD0 &"
10503 cat "${te}0"
10504 echo "$CMD1"
10505 cat "${te}1"
10506 numFAIL=$((numFAIL+1))
10507 listFAIL="$listFAIL $N"
10508 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10509 $PRINTF "$FAILED\n"
10510 cat "$tdiff"
10511 echo "$CMD0 &"
10512 cat "${te}0"
10513 echo "$CMD1"
10514 cat "${te}1"
10515 numFAIL=$((numFAIL+1))
10516 listFAIL="$listFAIL $N"
10517 else
10518 $PRINTF "$OK\n"
10519 if [ -n "$debug" ]; then cat $te; fi
10520 numOK=$((numOK+1))
10522 fi ;; # NUMCOND
10523 esac
10524 N=$((N+1))
10526 # test the SOCKET-RECVFROM address (with UDP4-SENDTO)
10527 NAME=SOCKET_RECVFROM
10528 case "$TESTS" in
10529 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10530 TEST="$NAME: socket recvfrom with UDP/IPv4"
10531 # start a SOCKET-RECVFROM process that uses UDP/IPv4 and echoes data, and
10532 # send test data using UDP4-SENDTO. The sent data should be returned.
10533 if ! eval $NUMCOND; then :; else
10534 tf="$td/test$N.stdout"
10535 te="$td/test$N.stderr"
10536 tdiff="$td/test$N.diff"
10537 newport udp4; ts1p=$PORT
10538 ts1a="127.0.0.1"
10539 ts0p=$(printf "%04x" $ts1p);
10540 ts0a="7f000001" # "127.0.0.1"
10541 ts0="x${ts0p}${ts0a}x0000000000000000"
10542 newport udp4; ts1b=$PORT
10543 ts1="$ts1a:$ts1p"
10544 da="test$N $(date) $RANDOM"
10545 CMD0="$TRACE $SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE"
10546 CMD1="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b"
10547 printf "test $F_n $TEST... " $N
10548 $CMD0 2>"${te}0" &
10549 pid0="$!"
10550 sleep 1 # waitudp4port $ts1p 1
10551 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10552 rc1="$?"
10553 kill "$pid0" 2>/dev/null; wait;
10554 if [ "$rc1" -ne 0 ]; then
10555 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10556 echo "$CMD0 &"
10557 cat "${te}0"
10558 echo "$CMD1"
10559 cat "${te}1"
10560 numFAIL=$((numFAIL+1))
10561 listFAIL="$listFAIL $N"
10562 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10563 $PRINTF "$FAILED\n"
10564 cat "$tdiff"
10565 echo "$CMD0 &"
10566 cat "${te}0"
10567 echo "$CMD1"
10568 cat "${te}1"
10569 numFAIL=$((numFAIL+1))
10570 listFAIL="$listFAIL $N"
10571 else
10572 $PRINTF "$OK\n"
10573 if [ -n "$debug" ]; then cat $te; fi
10574 numOK=$((numOK+1))
10576 fi ;; # NUMCOND
10577 esac
10578 N=$((N+1))
10581 # test the SOCKET-RECV address (with UDP4-SENDTO)
10582 NAME=SOCKET_RECV
10583 case "$TESTS" in
10584 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10585 TEST="$NAME: socket recv with UDP/IPv4"
10586 # start a SOCKET-RECV process that uses UDP/IPv4 and writes received data to file, and
10587 # send test data using UDP4-SENDTO.
10588 if ! eval $NUMCOND; then :; else
10589 tf="$td/test$N.stdout"
10590 te="$td/test$N.stderr"
10591 tdiff="$td/test$N.diff"
10592 newport udp4; ts1p=$PORT
10593 ts1a="127.0.0.1"
10594 ts0p=$(printf "%04x" $ts1p);
10595 ts0a="7f000001" # "127.0.0.1"
10596 ts0="x${ts0p}${ts0a}x0000000000000000"
10597 newport udp4; ts1b=$PORT
10598 ts1="$ts1a:$ts1p"
10599 da="test$N $(date) $RANDOM"
10600 CMD0="$TRACE $SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -"
10601 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b"
10602 printf "test $F_n $TEST... " $N
10603 $CMD0 2>"${te}0" >"$tf" &
10604 pid0="$!"
10605 sleep 1 # waitudp4port $ts1p 1
10606 echo "$da" |$CMD1 2>>"${te}1"
10607 rc1="$?"
10608 sleep 1
10609 kill "$pid0" 2>/dev/null; wait;
10610 if [ "$rc1" -ne 0 ]; then
10611 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10612 echo "$CMD0 &"
10613 cat "${te}0"
10614 echo "$CMD1"
10615 cat "${te}1"
10616 numFAIL=$((numFAIL+1))
10617 listFAIL="$listFAIL $N"
10618 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10619 $PRINTF "$FAILED\n"
10620 cat "$tdiff"
10621 echo "$CMD0 &"
10622 cat "${te}0"
10623 echo "$CMD1"
10624 cat "${te}1"
10625 numFAIL=$((numFAIL+1))
10626 listFAIL="$listFAIL $N"
10627 else
10628 $PRINTF "$OK\n"
10629 if [ -n "$debug" ]; then cat $te; fi
10630 numOK=$((numOK+1))
10632 fi ;; # NUMCOND
10633 esac
10634 N=$((N+1))
10636 # test SOCKET-DATAGRAM (with UDP4-DATAGRAM)
10637 NAME=SOCKET_DATAGRAM
10638 case "$TESTS" in
10639 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10640 TEST="$NAME: socket datagram via UDP/IPv4"
10641 # start a UDP4-DATAGRAM process that echoes data, and send test data using
10642 # SOCKET-DATAGRAM, selecting UDP/IPv4. The sent data should be returned.
10643 if ! eval $NUMCOND; then :; else
10644 tf="$td/test$N.stdout"
10645 te="$td/test$N.stderr"
10646 tdiff="$td/test$N.diff"
10647 newport udp4; ts0p=$PORT
10648 newport udp4; ts1p=$PORT
10649 ts0a="127.0.0.1"
10650 ts1b=$(printf "%04x" $ts0p);
10651 ts1a="7f000001" # "127.0.0.1"
10652 ts0b=$(printf "%04x" $ts0p)
10653 ts1b=$(printf "%04x" $ts1p)
10654 ts1="x${ts0b}${ts1a}x0000000000000000"
10655 da="test$N $(date) $RANDOM"
10656 CMD0="$TRACE $SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE"
10657 CMD1="$TRACE $SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
10658 printf "test $F_n $TEST... " $N
10659 $CMD0 2>"${te}0" &
10660 pid0="$!"
10661 waitudp4port $ts0p 1
10662 echo "$da" |$CMD1 2>>"${te}1" >"$tf"
10663 rc1="$?"
10664 kill "$pid0" 2>/dev/null; wait;
10665 if [ "$rc1" -ne 0 ]; then
10666 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10667 echo "$CMD0 &"
10668 cat "${te}0"
10669 echo "$CMD1"
10670 cat "${te}1"
10671 numFAIL=$((numFAIL+1))
10672 listFAIL="$listFAIL $N"
10673 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10674 $PRINTF "$FAILED\n"
10675 cat "$tdiff"
10676 echo "$CMD0 &"
10677 cat "${te}0"
10678 echo "$CMD1"
10679 cat "${te}1"
10680 numFAIL=$((numFAIL+1))
10681 listFAIL="$listFAIL $N"
10682 else
10683 $PRINTF "$OK\n"
10684 if [ -n "$debug" ]; then cat $te; fi
10685 numOK=$((numOK+1))
10687 fi ;; # NUMCOND
10688 esac
10689 N=$((N+1))
10691 NAME=SOCKETRANGEMASK
10692 case "$TESTS" in
10693 *%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
10694 TEST="$NAME: security of generic socket-listen with RANGE option"
10695 if ! eval $NUMCOND; then :;
10696 elif [ -z "$SECONDADDR" ]; then
10697 # we need access to more loopback addresses
10698 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
10699 numCANT=$((numCANT+1))
10700 listCANT="$listCANT $N"
10701 else
10702 newport tcp4; ts1p=$(printf "%04x" $PORT);
10703 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
10704 fi ;; # NUMCOND, $SECONDADDR
10705 esac
10706 N=$((N+1))
10709 # test the generic ioctl-void option
10710 NAME=IOCTL_VOID
10711 case "$TESTS" in
10712 *%$N%*|*%functions%*|*%pty%*|*%generic%*|*%$NAME%*)
10713 TEST="$NAME: test the ioctl-void option"
10714 # there are not many ioctls that apply to non global resources and do not
10715 # require root. TIOCEXCL seems to fit:
10716 # process 0 provides a pty;
10717 # process 1 opens it with the TIOCEXCL ioctl;
10718 # process 2 opens it too and fails with "device or resource busy" only when the
10719 # previous ioctl was successful
10720 if ! eval $NUMCOND; then :;
10721 elif [ -z "$TIOCEXCL" ]; then
10722 # we use the numeric value of TIOCEXL which is system dependent
10723 $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N
10724 numCANT=$((numCANT+1))
10725 listCANT="$listCANT $N"
10726 else
10727 tp="$td/test$N.pty"
10728 tf="$td/test$N.stdout"
10729 te="$td/test$N.stderr"
10730 tdiff="$td/test$N.diff"
10731 da="test$N $(date) $RANDOM"
10732 CMD0="$TRACE $SOCAT $opts PTY,LINK=$tp pipe"
10733 CMD1="$TRACE $SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0"
10734 CMD2="$TRACE $SOCAT $opts - file:$tp,raw,echo=0"
10735 printf "test $F_n $TEST... " $N
10736 $CMD0 >/dev/null 2>"${te}0" &
10737 pid0=$!
10738 waitfile $tp 1
10739 (echo "$da"; sleep 2) |$CMD1 >"$tf" 2>"${te}1" & # this should always work
10740 pid1=$!
10741 usleep 1000000
10742 $CMD2 >/dev/null 2>"${te}2" </dev/null
10743 rc2=$?
10744 kill $pid0 $pid1 2>/dev/null; wait
10745 if ! echo "$da" |diff - "$tf" >/dev/null; then
10746 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
10747 echo "$CMD0 &"
10748 echo "$CMD1"
10749 echo "$da" |diff - "$tf"
10750 numCANT=$((numCANT+1))
10751 listCANT="$listCANT $N"
10752 elif [ $rc2 -eq 0 ]; then
10753 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10754 echo "$CMD0 &"
10755 echo "$CMD1"
10756 echo "$CMD2"
10757 cat "${te}0" "${te}1" "${te}2"
10758 numFAIL=$((numFAIL+1))
10759 listFAIL="$listFAIL $N"
10760 else
10761 $PRINTF "$OK\n"
10762 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
10763 numOK=$((numOK+1))
10765 fi # NUMCOND, TIOCEXCL
10767 esac
10768 N=$((N+1))
10771 # Test the generic setsockopt option
10772 NAME=SETSOCKOPT
10773 case "$TESTS" in
10774 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%listen%*|*%fork%*|*%$NAME%*)
10775 TEST="$NAME: test the setsockopt option"
10776 # Set the TCP_MAXSEG (MSS) option with a reasonable value, this should succeed.
10777 # Then try again with TCP_MAXSEG=1, this fails at least on Linux.
10778 # Thus:
10779 # process 0 provides a tcp listening,forking socket
10780 # process 1 connects to this port using reasonably MSS, data transfer should
10781 # succeed.
10782 # Then,
10783 # process 2 connects to this port using a very small MSS, this should fail
10784 if ! eval $NUMCOND; then :;
10785 elif [ -z "$TCP_MAXSEG" ]; then
10786 # we use the numeric value of TCP_MAXSEG which might be system dependent
10787 $PRINTF "test $F_n $TEST... ${YELLOW}value of TCPMAXSEG not known${NORMAL}\n" $N
10788 numCANT=$((numCANT+1))
10789 listCANT="$listCANT $N"
10790 else
10791 tf="$td/test$N.stdout"
10792 te="$td/test$N.stderr"
10793 tdiff="$td/test$N.diff"
10794 da="test$N $(date) $RANDOM"
10795 newport tcp4
10796 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,so-reuseaddr,fork PIPE"
10797 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,setsockopt=6:$TCP_MAXSEG:512"
10798 CMD2="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,setsockopt=6:$TCP_MAXSEG:1"
10799 printf "test $F_n $TEST... " $N
10800 $CMD0 >/dev/null 2>"${te}0" &
10801 pid0=$!
10802 waittcp4port $PORT 1
10803 (echo "$da"; sleep 1) |$CMD1 >"${tf}1" 2>"${te}1" # this should always work
10804 rc1=$?
10805 usleep 1000000
10806 (echo "$da"; sleep 1) |$CMD2 >"${tf}2" 2>"${te}2" # this should fail
10807 rc2=$?
10808 kill $pid0 $pid1 $pid2 2>/dev/null; wait
10809 if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
10810 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
10811 echo "$CMD0 &"
10812 cat ${te}0
10813 echo "$CMD1"
10814 cat ${te}1
10815 cat "$tdiff"
10816 numCANT=$((numCANT+1))
10817 listCANT="$listCANT $N"
10818 elif [ $rc1 -ne 0 ]; then
10819 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10820 echo "$CMD0 &"
10821 cat ${te}0
10822 echo "$CMD1"
10823 cat ${te}1
10824 numFAIL=$((numFAIL+1))
10825 listFAIL="$listFAIL $N"
10826 elif [ $rc2 -eq 0 ]; then
10827 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10828 echo "$CMD0 &"
10829 cat ${te}0
10830 echo "$CMD2"
10831 cat ${te}2
10832 numFAIL=$((numFAIL+1))
10833 listFAIL="$listFAIL $N"
10834 else
10835 $PRINTF "$OK\n"
10836 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
10837 numOK=$((numOK+1))
10839 fi # NUMCOND
10841 esac
10842 N=$((N+1))
10844 # Test the generic setsockopt-listen option
10845 # This test, with setsockopt-int, no longer worked due to fix for options on
10846 # listening sockets
10847 # Now it got a chance again using new option setsockopt-listen
10848 #NAME=SETSOCKOPT_INT
10849 NAME=SETSOCKOPT_LISTEN
10850 case "$TESTS" in
10851 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%listen%*|*%$NAME%*)
10852 TEST="$NAME: test the setsockopt-listen option"
10853 # there are not many socket options that apply to non global resources, do not
10854 # require root, do not require a network connection, and can easily be
10855 # tested. SO_REUSEADDR seems to fit:
10856 # process 0 provides a tcp listening socket with reuseaddr;
10857 # process 1 connects to this port; thus the port is connected but no longer
10858 # listening
10859 # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the
10860 # (generically specified) SO_REUSEADDR socket options did not work
10861 # process 3 connects to this port; only if it is successful the test is ok
10862 if ! eval $NUMCOND; then :;
10863 elif [ -z "$SO_REUSEADDR" ]; then
10864 # we use the numeric value of SO_REUSEADDR which might be system dependent
10865 $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N
10866 numCANT=$((numCANT+1))
10867 listCANT="$listCANT $N"
10868 else
10869 tf="$td/test$N.stdout"
10870 te="$td/test$N.stderr"
10871 tdiff="$td/test$N.diff"
10872 da="test$N $(date) $RANDOM"
10873 newport tcp4
10874 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,setsockopt-listen=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE"
10875 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
10876 CMD2="$CMD0"
10877 CMD3="$CMD1"
10878 printf "test $F_n $TEST... " $N
10879 $CMD0 >/dev/null 2>"${te}0" &
10880 pid0=$!
10881 waittcp4port $PORT 1
10882 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" # this should always work
10883 rc1=$?
10884 kill $pid0 2>/dev/null; wait
10885 $CMD2 >/dev/null 2>"${te}2" &
10886 pid2=$!
10887 waittcp4port $PORT 1
10888 echo "$da" |$CMD3 >"${tf}3" 2>"${te}3"
10889 rc3=$?
10890 kill $pid2 2>/dev/null; wait
10891 if ! echo "$da" |diff - "${tf}1" >"${tdiff}1"; then
10892 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
10893 echo "$CMD0 &"
10894 cat ${te}0
10895 echo "$CMD1"
10896 cat ${te}1
10897 cat "${tdiff}1"
10898 numCANT=$((numCANT+1))
10899 listCANT="$listCANT $N"
10900 elif [ $rc3 -ne 0 ]; then
10901 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10902 echo "$CMD0 &"
10903 cat ${te}0
10904 echo "$CMD1"
10905 cat ${te}1
10906 echo "$CMD2 &"
10907 cat ${te}2
10908 echo "$CMD3"
10909 cat ${te}3
10910 numFAIL=$((numFAIL+1))
10911 listFAIL="$listFAIL $N"
10912 elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then
10913 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10914 echo "$CMD0 &"
10915 cat ${te}0
10916 echo "$CMD1"
10917 cat ${te}1
10918 echo "$CMD2 &"
10919 cat ${te}2
10920 echo "$CMD3"
10921 cat ${te}3
10922 cat "${tdiff}3"
10923 numCANT=$((numCANT+1))
10924 listCANT="$listCANT $N"
10925 else
10926 $PRINTF "$OK\n"
10927 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
10928 numOK=$((numOK+1))
10930 fi # NUMCOND, SO_REUSEADDR
10932 esac
10933 N=$((N+1))
10936 NAME=SCTP4STREAM
10937 case "$TESTS" in
10938 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%listen%*|*%$NAME%*)
10939 TEST="$NAME: echo via connection to SCTP V4 socket"
10940 if ! eval $NUMCOND; then :;
10941 elif ! testfeats sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 >/dev/null; then
10942 $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
10943 listCANT="$listCANT $N"
10944 numCANT=$((numCANT+1))
10945 listCANT="$listCANT $N"
10946 elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
10947 # RHEL5 based systems became unusable when an sctp socket was created but
10948 # module sctp not loaded
10949 $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
10950 numCANT=$((numCANT+1))
10951 listCANT="$listCANT $N"
10952 else
10953 tf="$td/test$N.stdout"
10954 te="$td/test$N.stderr"
10955 tdiff="$td/test$N.diff"
10956 newport sctp4; tsl=$PORT
10957 ts="127.0.0.1:$tsl"
10958 da=$(date)
10959 CMD1="$TRACE $SOCAT $opts SCTP4-LISTEN:$tsl,$REUSEADDR PIPE"
10960 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT SCTP4:$ts"
10961 printf "test $F_n $TEST... " $N
10962 $CMD1 >"$tf" 2>"${te}1" &
10963 pid1=$!
10964 waitsctp4port $tsl 1
10965 # SCTP does not seem to support half close, so we give it 1s to finish
10966 (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
10967 if [ $? -ne 0 ]; then
10968 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10969 echo "$CMD1 &"
10970 cat "${te}1"
10971 echo "$CMD2"
10972 cat "${te}2"
10973 numFAIL=$((numFAIL+1))
10974 listFAIL="$listFAIL $N"
10975 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10976 $PRINTF "$FAILED\n"
10977 cat "$tdiff"
10978 numFAIL=$((numFAIL+1))
10979 listFAIL="$listFAIL $N"
10980 else
10981 $PRINTF "$OK\n"
10982 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
10983 numOK=$((numOK+1))
10985 kill $pid1 2>/dev/null
10986 wait
10987 fi # NUMCOND, feats
10989 esac
10990 N=$((N+1))
10992 NAME=SCTP6STREAM
10993 case "$TESTS" in
10994 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%listen%*|*%$NAME%*)
10995 TEST="$NAME: echo via connection to SCTP V6 socket"
10996 if ! eval $NUMCOND; then :;
10997 elif ! testfeats sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 >/dev/null; then
10998 $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N
10999 numCANT=$((numCANT+1))
11000 listCANT="$listCANT $N"
11001 elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
11002 $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
11003 numCANT=$((numCANT+1))
11004 listCANT="$listCANT $N"
11005 else
11006 tf="$td/test$N.stdout"
11007 te="$td/test$N.stderr"
11008 tdiff="$td/test$N.diff"
11009 newport sctp6; tsl=$PORT
11010 ts="[::1]:$tsl"
11011 da=$(date)
11012 CMD1="$TRACE $SOCAT $opts SCTP6-LISTEN:$tsl,$REUSEADDR PIPE"
11013 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT SCTP6:$ts"
11014 printf "test $F_n $TEST... " $N
11015 $CMD1 >"$tf" 2>"${te}1" &
11016 pid=$! # background process id
11017 waitsctp6port $tsl 1
11018 # SCTP does not seem to support half close, so we let it 1s to finish
11019 (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
11020 if [ $? -ne 0 ]; then
11021 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11022 echo "$CMD1 &"
11023 cat "${te}1"
11024 echo "$CMD2"
11025 cat "${te}2"
11026 numFAIL=$((numFAIL+1))
11027 listFAIL="$listFAIL $N"
11028 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
11029 $PRINTF "$FAILED: diff:\n"
11030 cat "$tdiff"
11031 numFAIL=$((numFAIL+1))
11032 listFAIL="$listFAIL $N"
11033 else
11034 $PRINTF "$OK\n"
11035 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
11036 numOK=$((numOK+1))
11038 kill $pid 2>/dev/null
11039 fi # NUMCOND, feats
11041 esac
11042 N=$((N+1))
11045 if type openssl >/dev/null 2>&1; then
11046 OPENSSL_METHOD=$(openssl s_client -help 2>&1 |egrep -e '-tls1_[012]' |sed -e 's/.*\(-tls1_[012]\).*/\1/' |sort |tail -n 1)
11047 #OPENSSL_METHOD=$(openssl s_client -help 2>&1 |egrep -o -e '-tls1(_[012])?' |sort |tail -n 1)
11048 [ -z "$OPENSSL_METHOD" ] && OPENSSL_METHOD="-tls1" # just so
11051 # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer
11052 # performed a renegotiation. Test if this is fixed.
11053 # Note: the renegotiation feature in OpenSSL exists only up to TLSv1.2
11054 NAME=OPENSSLRENEG1
11055 case "$TESTS" in
11056 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
11057 TEST="$NAME: OpenSSL connections survive renogotiation"
11058 # connect with s_client to socat ssl-l; force a renog, then transfer data. When
11059 # data is passed the test succeeded
11060 if ! eval $NUMCOND; then :;
11061 elif ! testfeats openssl >/dev/null; then
11062 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11063 numCANT=$((numCANT+1))
11064 listCANT="$listCANT $N"
11065 elif ! type openssl >/dev/null 2>&1; then
11066 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
11067 numCANT=$((numCANT+1))
11068 listCANT="$listCANT $N"
11069 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
11070 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
11071 numCANT=$((numCANT+1))
11072 listCANT="$listCANT $N"
11073 else
11074 gentestcert testsrv
11075 tf="$td/test$N.stdout"
11076 te="$td/test$N.stderr"
11077 tdiff="$td/test$N.diff"
11078 da="test$N $(date) $RANDOM"
11079 init_openssl_s_client
11080 newport tcp4
11081 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
11082 #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g
11083 CMD1="openssl s_client $OPENSSL_S_CLIENT_4 $OPENSSL_METHOD -port $PORT"
11084 printf "test $F_n $TEST... " $N
11085 $CMD0 >/dev/null 2>"${te}0" &
11086 pid0=$!
11087 waittcp4port $PORT 1
11088 (echo "R"; sleep 1; echo "$da"; sleep 1) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}1"
11089 rc1=$?
11090 kill $pid0 2>/dev/null; wait
11091 if echo "$da" |diff - ${tf}1 >"$tdiff"; then
11092 $PRINTF "$OK\n"
11093 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11094 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11095 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11096 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11097 numOK=$((numOK+1))
11098 elif grep -i "Connection refused" "${te}1" >/dev/null; then
11099 $PRINTF "$CANT (conn failed)\n"
11100 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11101 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11102 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11103 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11104 numCANT=$((numCANT+1))
11105 listCANT="$listCANT $N"
11106 else
11107 $PRINTF "$FAILED (diff)\n"
11108 echo "$CMD0 &"
11109 cat "${te}0" >&2
11110 echo "$CMD1"
11111 cat "${te}1" >&2
11112 echo "// diff:" >&2
11113 cat "$tdiff" >&2
11114 numFAIL=$((numFAIL+1))
11115 listFAIL="$listFAIL $N"
11117 fi # NUMCOND
11119 esac
11120 N=$((N+1))
11123 # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer
11124 # performed a renegotiation. The first temporary fix to this problem might
11125 # leave socat in a blocking ssl-read state. Test if this has been fixed.
11126 # Note: the renegotiation feature in OpenSSL exists only up to TLSv1.2
11127 NAME=OPENSSLRENEG2
11128 case "$TESTS" in
11129 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
11130 TEST="$NAME: OpenSSL connections do not block after renogotiation"
11131 # connect with s_client to socat ssl-l; force a renog, then transfer data from
11132 # socat to the peer. When data is passed this means that the former ssl read no
11133 # longer blocks and the test succeeds
11134 if ! eval $NUMCOND; then :;
11135 elif ! testfeats openssl >/dev/null; then
11136 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11137 numCANT=$((numCANT+1))
11138 listCANT="$listCANT $N"
11139 elif ! type openssl >/dev/null 2>&1; then
11140 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
11141 numCANT=$((numCANT+1))
11142 listCANT="$listCANT $N"
11143 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
11144 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
11145 numCANT=$((numCANT+1))
11146 listCANT="$listCANT $N"
11147 else
11148 gentestcert testsrv
11149 tf="$td/test$N.stdout"
11150 te="$td/test$N.stderr"
11151 tdiff="$td/test$N.diff"
11152 da="test$N $(date) $RANDOM"
11153 init_openssl_s_client
11154 newport tcp4
11155 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 SYSTEM:\"sleep 1; echo \\\\\\\"\\\"$da\\\"\\\\\\\"; sleep 1\"!!STDIO"
11156 #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g
11157 CMD1="openssl s_client $OPENSSL_S_CLIENT_4 $OPENSSL_METHOD -port $PORT"
11158 printf "test $F_n $TEST... " $N
11159 eval "$CMD0 >/dev/null 2>\"${te}0\" &"
11160 pid0=$!
11161 waittcp4port $PORT 1
11162 (echo "R"; sleep 2) |$CMD1 2>"${te}1" |fgrep "$da" >"${tf}1"
11163 rc1=$?
11164 kill $pid0 2>/dev/null; wait
11165 if echo "$da" |diff - ${tf}1 >"$tdiff"; then
11166 $PRINTF "$OK\n"
11167 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11168 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11169 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11170 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11171 numOK=$((numOK+1))
11172 elif grep -i "Connection refused" "${te}1" >/dev/null; then
11173 $PRINTF "$CANT (conn failed)\n"
11174 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11175 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11176 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11177 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11178 numCANT=$((numCANT+1))
11179 listCANT="$listCANT $N"
11180 else
11181 $PRINTF "$FAILED (diff)\n"
11182 echo "$CMD0 &"
11183 cat "${te}0" >&2
11184 echo "$CMD1"
11185 cat "${te}1" >&2
11186 echo "// diff:" >&2
11187 cat "$tdiff" >&2
11188 numFAIL=$((numFAIL+1))
11189 listFAIL="$listFAIL $N"
11191 fi # NUMCOND
11193 esac
11194 N=$((N+1))
11197 # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when
11198 # command line arguments (whole addresses, host names, file names) were longer
11199 # than 512 bytes.
11200 NAME=HOSTNAMEOVFL
11201 case "$TESTS" in
11202 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*)
11203 TEST="$NAME: stack overflow on overly long host name"
11204 # provide a long host name to TCP-CONNECT and check socats exit code
11205 if ! eval $NUMCOND; then :; else
11206 tf="$td/test$N.stdout"
11207 te="$td/test$N.stderr"
11208 tdiff="$td/test$N.diff"
11209 da="test$N $(date) $RANDOM"
11210 # prepare long data - perl might not be installed
11211 rm -f "$td/test$N.dat"
11212 i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
11213 newport tcp4
11214 CMD0="$TRACE $SOCAT $opts TCP-CONNECT:$(cat "$td/test$N.dat"):$PORT STDIO"
11215 printf "test $F_n $TEST... " $N
11216 $CMD0 </dev/null 1>&0 2>"${te}0"
11217 rc0=$?
11218 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
11219 $PRINTF "$OK\n"
11220 numOK=$((numOK+1))
11221 else
11222 $PRINTF "$FAILED\n"
11223 echo "$CMD0"
11224 cat "${te}0"
11225 numFAIL=$((numFAIL+1))
11226 listFAIL="$listFAIL $N"
11228 fi # NUMCOND
11230 esac
11231 N=$((N+1))
11233 # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when
11234 # command line arguments (whole addresses, host names, file names) were longer
11235 # than 512 bytes.
11236 NAME=FILENAMEOVFL
11237 case "$TESTS" in
11238 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%openssl%*|*%$NAME%*)
11239 TEST="$NAME: stack overflow on overly long file name"
11240 # provide a 600 bytes long key file option to OPENSSL-CONNECT and check socats exit code
11241 if ! eval $NUMCOND; then :; else
11242 tf="$td/test$N.stdout"
11243 te="$td/test$N.stderr"
11244 tdiff="$td/test$N.diff"
11245 da="test$N $(date) $RANDOM"
11246 i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
11247 newport tcp4
11248 CMD0="$TRACE $SOCAT $opts OPENSSL:localhost:$PORT,key=$(cat "$td/test$N.dat") STDIO"
11249 printf "test $F_n $TEST... " $N
11250 $CMD0 </dev/null 1>&0 2>"${te}0"
11251 rc0=$?
11252 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
11253 $PRINTF "$OK\n"
11254 numOK=$((numOK+1))
11255 else
11256 $PRINTF "$FAILED\n"
11257 echo "$CMD0"
11258 cat "${te}0"
11259 numFAIL=$((numFAIL+1))
11260 listFAIL="$listFAIL $N"
11262 fi # NUMCOND
11264 esac
11265 N=$((N+1))
11267 # socat up to 1.7.3.0 had a stack overflow vulnerability that occurred when
11268 # command line arguments (whole addresses, host names, file names) were longer
11269 # than 512 bytes and specially crafted.
11270 NAME=NESTEDOVFL
11271 case "$TESTS" in
11272 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%exec%*|*%$NAME%*)
11273 TEST="$NAME: stack overflow on overly long nested arg"
11274 # provide a long host name to TCP-CONNECT and check socats exit code
11275 if ! eval $NUMCOND; then :; else
11276 tf="$td/test$N.stdout"
11277 te="$td/test$N.stderr"
11278 tdiff="$td/test$N.diff"
11279 da="test$N $(date) $RANDOM"
11280 # prepare long data - perl might not be installed
11281 rm -f "$td/test$N.dat"
11282 i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
11283 CMD0="$TRACE $SOCAT $opts EXEC:[$(cat "$td/test$N.dat")] STDIO"
11284 printf "test $F_n $TEST... " $N
11285 $CMD0 </dev/null 1>&0 2>"${te}0"
11286 rc0=$?
11287 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
11288 $PRINTF "$OK\n"
11289 numOK=$((numOK+1))
11290 else
11291 $PRINTF "$FAILED\n"
11292 echo "$CMD0"
11293 cat "${te}0"
11294 numFAIL=$((numFAIL+1))
11295 listFAIL="$listFAIL $N"
11297 fi # NUMCOND
11299 esac
11300 N=$((N+1))
11303 # test for a bug in gopen that lead to crash or warning when opening a unix
11304 # domain socket with GOPEN
11305 NAME=GOPEN_UNIX_CRASH
11306 case "$TESTS" in
11307 *%$N%*|*%functions%*|*%bugs%*|*%gopen%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
11308 TEST="$NAME: check crash when connecting to a unix domain socket using address GOPEN"
11309 # a unix domain server is started in background. the check process connects to
11310 # its socket. when this process crashes or issues a warning the bug is present.
11311 # please note that a clean behaviour does not proof anything; behaviour of bug
11312 # depends on the value of an uninitialized var
11313 #set -vx
11314 if ! eval $NUMCOND; then :; else
11315 tf="$td/test$N.stdout"
11316 te="$td/test$N.stderr"
11317 ts="$td/test$N.sock"
11318 tdiff="$td/test$N.diff"
11319 da="test$N $(date) $RANDOM"
11320 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE"
11321 CMD1="$TRACE $SOCAT $opts -d - GOPEN:$ts"
11322 printf "test $F_n $TEST... " $N
11323 $CMD0 >/dev/null 2>"${te}0" </dev/null &
11324 pid0=$!
11325 waitunixport "$ts" 1
11326 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
11327 rc1=$?
11328 kill $pid0 2>/dev/null; wait
11329 if [ $rc1 -ne 0 ]; then
11330 $PRINTF "$FAILED\n"
11331 echo "$CMD0 &"
11332 echo "$CMD1"
11333 cat "${te}0"
11334 cat "${te}1"
11335 numFAIL=$((numFAIL+1))
11336 listFAIL="$listFAIL $N"
11337 elif grep -q ' W ' "${te}1"; then
11338 $PRINTF "$FAILED\n"
11339 echo "$CMD0 &"
11340 echo "$CMD1"
11341 cat "${te}0"
11342 cat "${te}1"
11343 numFAIL=$((numFAIL+1))
11344 listFAIL="$listFAIL $N"
11345 elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then
11346 $PRINTF "$FAILED\n"
11347 echo "$CMD0 &"
11348 echo "$CMD1"
11349 cat "${te}0"
11350 cat "${te}1"
11351 cat "$tdiff"
11352 numFAIL=$((numFAIL+1))
11353 listFAIL="$listFAIL $N"
11354 else
11355 $PRINTF "$OK\n"
11356 numOK=$((numOK+1))
11358 fi # NUMCOND
11360 esac
11361 N=$((N+1))
11364 # test if socat keeps an existing file where it wanted to create a UNIX socket
11365 NAME=UNIXLISTEN_KEEPFILE
11366 case "$TESTS" in
11367 *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
11368 TEST="$NAME: socat keeps an existing file where it wanted to create a UNIX socket"
11369 # we create a file and start socat with UNIX-LISTEN on this file. expected
11370 # behaviour: socat exits immediately with error, but keeps the file
11371 # up to 1.7.1.3, it removed the file
11372 if ! eval $NUMCOND; then :; else
11373 tf="$td/test$N.file"
11374 te="$td/test$N.stderr"
11375 CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$tf /dev/null"
11376 printf "test $F_n $TEST... " $N
11377 rm -f "$tf"; touch "$tf"
11378 $CMD0 >/dev/null 2>"${te}0"
11379 rc0=$?
11380 if [ $rc0 -ne 0 -a -f "$tf" ]; then
11381 $PRINTF "$OK\n"
11382 numOK=$((numOK+1))
11383 else
11384 $PRINTF "$FAILED\n"
11385 echo "$CMD0"
11386 cat "${te}0"
11387 numFAIL=$((numFAIL+1))
11388 listFAIL="$listFAIL $N"
11390 fi # NUMCOND
11392 esac
11393 N=$((N+1))
11396 # PTY address allowed to specify address parameters but ignored them
11397 NAME=PTY_VOIDARG
11398 case "$TESTS" in
11399 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
11400 TEST="$NAME: check if address params of PTY produce error"
11401 # invoke socat with address PTY and some param; expect an error
11402 if ! eval $NUMCOND; then :; else
11403 tf="$td/test$N.stdout"
11404 te="$td/test$N.stderr"
11405 tdiff="$td/test$N.diff"
11406 da="test$N $(date) $RANDOM"
11407 CMD0="$TRACE $SOCAT $opts /dev/null PTY:/tmp/xyz"
11408 printf "test $F_n $TEST... " $N
11409 $CMD0 >/dev/null 2>"${te}0"
11410 rc0=$?
11411 if [ $rc0 -ne 0 ]; then
11412 $PRINTF "$OK\n"
11413 numOK=$((numOK+1))
11414 else
11415 $PRINTF "$FAILED\n"
11416 echo "$CMD0"
11417 cat "${te}0"
11418 numFAIL=$((numFAIL+1))
11419 listFAIL="$listFAIL $N"
11421 fi # NUMCOND
11423 esac
11424 N=$((N+1))
11427 # incomplete writes were reported but led to data loss
11428 NAME=INCOMPLETE_WRITE
11429 case "$TESTS" in
11430 *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*)
11431 TEST="$NAME: check if incomplete writes are handled properly"
11432 # write to a nonblocking fd a block that is too large for atomic write
11433 # and check if all data arrives
11434 if ! eval $NUMCOND; then :; else
11435 tf="$td/test$N.stdout"
11436 te="$td/test$N.stderr"
11437 tp="$td/test$N.pipe"
11438 tw="$td/test$N.wc-c"
11439 # this is the size we write() in one call; data is never stored on disk, so
11440 # make it large enough to exceed any atomic write size; but higher number might
11441 # take much time
11442 bytes=100000 # for Linux 2.6.? this must be >65536
11443 CMD0="$TRACE $SOCAT $opts -u PIPE:$tp STDOUT"
11444 CMD1="$TRACE $SOCAT $opts -u -b $bytes OPEN:/dev/zero,readbytes=$bytes FILE:$tp,o-nonblock"
11445 printf "test $F_n $TEST... " $N
11446 $CMD0 2>"${te}0" |wc -c >"$tw" &
11447 pid=$!
11448 waitfile "$tp"
11449 $CMD1 2>"${te}1" >"${tf}1"
11450 rc1=$?
11451 wait
11452 if [ $rc1 -ne 0 ]; then
11453 $PRINTF "$NO_RESULT\n"
11454 numCANT=$((numCANT+1))
11455 listCANT="$listCANT $N"
11456 elif [ ! -e "$tw" ]; then
11457 $PRINTF "$NO_RESULT\n"
11458 numCANT=$((numCANT+1))
11459 listCANT="$listCANT $N"
11460 elif [ "$bytes" -eq $(cat "$tw") ]; then
11461 $PRINTF "$OK\n"
11462 numOK=$((numOK+1))
11463 else
11464 $PRINTF "$FAILED\n"
11465 echo "transferred only $(cat $tw) of $bytes bytes" >&2
11466 numFAIL=$((numFAIL+1))
11467 listFAIL="$listFAIL $N"
11469 fi # NUMCOND
11471 esac
11472 N=$((N+1))
11475 NAME=OPENSSL_ANULL
11476 case "$TESTS" in
11477 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
11478 TEST="$NAME: OpenSSL server with cipher aNULL "
11479 if ! eval $NUMCOND; then :;
11480 elif ! testfeats openssl >/dev/null; then
11481 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11482 numCANT=$((numCANT+1))
11483 listCANT="$listCANT $N"
11484 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
11485 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
11486 numCANT=$((numCANT+1))
11487 listCANT="$listCANT $N"
11488 else
11489 tf="$td/test$N.stdout"
11490 te="$td/test$N.stderr"
11491 tdiff="$td/test$N.diff"
11492 da="test$N $(date) $RANDOM"
11493 newport tcp4
11494 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,$SOCAT_EGD,ciphers=aNULL,verify=0 pipe"
11495 CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,ciphers=aNULL,verify=0,$SOCAT_EGD"
11496 printf "test $F_n $TEST... " $N
11497 eval "$CMD2 2>\"${te}1\" &"
11498 pid=$! # background process id
11499 waittcp4port $PORT
11500 echo "$da" |$CMD >$tf 2>"${te}2"
11501 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
11502 $PRINTF "${YELLOW}FAILED${NORMAL}\n"
11503 #echo "$CMD2 &"
11504 #echo "$CMD"
11505 #cat "${te}1"
11506 #cat "${te}2"
11507 #cat "$tdiff"
11508 numOK=$((numOK+1))
11509 else
11510 $PRINTF "$OK\n"
11511 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
11512 numOK=$((numOK+1))
11514 kill $pid 2>/dev/null
11515 wait
11516 fi ;; # NUMCOND, feats
11517 esac
11518 N=$((N+1))
11521 while read KEYW FEAT ADDR IPPORT; do
11522 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
11523 RUNS=$(tolower $KEYW)
11524 PROTO=$KEYW
11525 proto="$(echo "$PROTO" |tr A-Z a-z)"
11526 feat="$(tolower "$FEAT")"
11527 # test the max-children option on really connection oriented sockets
11528 NAME=${KEYW}MAXCHILDREN
11529 case "$TESTS" in
11530 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$feat%*|*%$proto%*|*%socket%*|*%listen%*|*%$NAME%*)
11531 TEST="$NAME: max-children option"
11532 # start a listen process with max-children=1; connect with a client, let it
11533 # sleep some time before sending data; connect with second client that sends
11534 # data immediately. If max-children is working correctly the first data should
11535 # arrive first because the second process has to wait.
11536 if ! eval $NUMCOND; then :;
11537 elif ! testfeats "$FEAT" >/dev/null; then
11538 $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
11539 numCANT=$((numCANT+1))
11540 listCANT="$listCANT $N"
11541 elif ! runs$RUNS >/dev/null; then
11542 $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
11543 numCANT=$((numCANT+1))
11544 listCANT="$listCANT $N"
11545 else
11546 case "X$IPPORT" in
11547 "XPORT")
11548 newport $proto
11549 tsl=$PORT # test socket listen address
11550 tsc="$ADDR:$PORT" # test socket connect address
11553 tsl="$(eval echo "$ADDR")" # resolve $N
11554 tsc=$tsl
11555 esac
11556 #ts="$td/test$N.sock"
11557 tf="$td/test$N.stdout"
11558 te="$td/test$N.stderr"
11559 tdiff="$td/test$N.diff"
11560 da="test$N $(date) $RANDOM"
11561 CMD0="$TRACE $SOCAT $opts -U FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
11562 CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,shut-null"
11563 printf "test $F_n $TEST... " $N
11564 $CMD0 >/dev/null 2>"${te}0" &
11565 pid0=$!
11566 wait${proto}port $tsl 1
11567 (echo "$da 1"; sleep 2) |$CMD1 >"${tf}1" 2>"${te}1" &
11568 pid1=$!
11569 sleep 1
11570 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
11571 pid2=$!
11572 sleep 2
11573 kill $pid1 $pid2 $pid0 2>/dev/null; wait
11574 if echo -e "$da 1\n$da 2" |diff - $tf >$tdiff; then
11575 $PRINTF "$OK\n"
11576 numOK=$((numOK+1))
11577 else
11578 $PRINTF "$FAILED\n"
11579 echo "$CMD0 &"
11580 echo "(echo \"$da 1\"; sleep 2) |$CMD1"
11581 echo "echo \"$da 2\" |$CMD1"
11582 cat "${te}0"
11583 cat "${te}1"
11584 cat "${te}2"
11585 cat "$tdiff"
11586 numFAIL=$((numFAIL+1))
11587 listFAIL="$listFAIL $N"
11589 fi # NUMCOND
11591 esac
11592 N=$((N+1))
11593 done <<<"
11594 TCP4 TCP 127.0.0.1 PORT
11595 TCP6 TCP [::1] PORT
11596 SCTP4 SCTP 127.0.0.1 PORT
11597 SCTP6 SCTP [::1] PORT
11598 UNIX unix $td/test\$N.server -
11600 # debugging this hanging test was difficult - following lessons learned:
11601 # kill <parent> had no effect when child process existed
11602 # strace -f (on Fedora-23) sometimes writes/pads? blocks with \0, overwriting client traces
11603 # using the TRACE feature lets above kill command kill strace, not socat
11604 # care for timing, understand what you want :-)
11607 # test the max-children option on pseudo connected sockets
11608 while read KEYW FEAT SEL ADDR IPPORT SHUT; do
11609 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
11610 RUNS=$(tolower $KEYW)
11611 PROTO=$KEYW
11612 proto="$(echo "$PROTO" |tr A-Z a-z)"
11613 # test the max-children option on pseudo connected sockets
11614 NAME=${KEYW}MAXCHILDREN
11615 case "$TESTS" in
11616 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
11617 TEST="$NAME: max-children option"
11618 # start a listen process with max-children=1; connect with a client, let it
11619 # send data and then sleep; connect with second client that wants to send
11620 # data immediately, but keep first client active until server terminates.
11621 #If max-children is working correctly only the first data should
11622 # arrive.
11623 if ! eval $NUMCOND; then :;
11624 elif ! testfeats "$FEAT" >/dev/null; then
11625 $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
11626 numCANT=$((numCANT+1))
11627 listCANT="$listCANT $N"
11628 elif ! runs$RUNS >/dev/null; then
11629 $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
11630 numCANT=$((numCANT+1))
11631 listCANT="$listCANT $N"
11632 else
11633 case "X$IPPORT" in
11634 "XPORT")
11635 newport $proto
11636 tsl=$PORT # test socket listen address
11637 tsc="$ADDR:$PORT" # test socket connect address
11640 tsl="$(eval echo "$ADDR")" # resolve $N
11641 tsc=$tsl
11642 esac
11643 #ts="$td/test$N.sock"
11644 tf="$td/test$N.stdout"
11645 te="$td/test$N.stderr"
11646 tdiff="$td/test$N.diff"
11647 da="test$N $(date) $RANDOM"
11648 # on some Linux distributions it hangs, thus -T option here
11649 CMD0="$TRACE $SOCAT $opts -U -T 4 FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
11650 CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,$SHUT"
11651 printf "test $F_n $TEST... " $N
11652 $CMD0 >/dev/null 2>"${te}0" &
11653 pid0=$!
11654 wait${proto}port $tsl 1
11655 (echo "$da 1"; sleep 3) |$CMD1 >"${tf}1" 2>"${te}1" &
11656 pid1=$!
11657 sleep 1
11658 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
11659 pid2=$!
11660 sleep 1
11661 cpids="$(childpids $pid0)"
11662 kill $pid1 $pid2 $pid0 $cpids 2>/dev/null; wait
11663 if echo -e "$da 1" |diff - $tf >$tdiff; then
11664 $PRINTF "$OK\n"
11665 numOK=$((numOK+1))
11666 else
11667 $PRINTF "$FAILED\n"
11668 echo "$CMD0 &"
11669 echo "(echo \"$da 1\"; sleep 2) |$CMD1"
11670 echo "echo \"$da 2\" |$CMD1"
11671 cat "${te}0"
11672 cat "${te}1"
11673 cat "${te}2"
11674 cat "$tdiff"
11675 numFAIL=$((numFAIL+1))
11676 listFAIL="$listFAIL $N"
11678 fi # NUMCOND
11680 esac
11681 N=$((N+1))
11682 done <<<"
11683 UDP4 UDP udp 127.0.0.1 PORT shut-null
11684 UDP6 UDP udp [::1] PORT shut-null
11686 # debugging this hanging test was difficult - following lessons learned:
11687 # kill <parent> had no effect when child process existed
11688 # strace -f (on Fedora-23) sometimes writes/pads? blocks with \0, overwriting client traces
11689 # using the TRACE feature lets above kill command kill strace, not socat
11690 # care for timing, understand what you want :-)
11693 # socat up to 1.7.2.0 had a bug in xioscan_readline() that could be exploited
11694 # to overflow a heap based buffer (socat security advisory 3)
11695 # problem reported by Johan Thillemann
11696 NAME=READLINE_OVFL
11697 case "$TESTS" in
11698 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%readline%*|*%pty%*|*%$NAME%*)
11699 TEST="$NAME: test for buffer overflow in readline prompt handling"
11700 # address 1 is the readline where write data was handled erroneous
11701 # address 2 provides data to trigger the buffer overflow
11702 # when no SIGSEGV or so occurs the test succeeded (bug fixed)
11703 if ! eval $NUMCOND; then :;
11704 elif ! feat=$(testfeats readline pty); then
11705 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
11706 numCANT=$((numCANT+1))
11707 listCANT="$listCANT $N"
11708 else
11709 tf="$td/test$N.stdout"
11710 te="$td/test$N.stderr"
11711 ti="$td/test$N.data"
11712 CMD0="$SOCAT $opts READLINE $ti"
11713 printf "test $F_n $TEST... " $N
11714 # prepare long data - perl might not be installed
11715 #perl -e 'print "\r","Z"x513' >"$ti"
11716 echo $E -n "\rA" >"$ti"
11717 i=0; while [ $i -lt 32 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$ti"; let i=i+1; done
11718 $TRACE $SOCAT - SYSTEM:"$CMD0; echo rc=\$? >&2",pty >/dev/null 2>"${te}0"
11719 rc=$?
11720 rc0="$(grep ^rc= "${te}0" |sed 's/.*=//')"
11721 if [ $rc -ne 0 ]; then
11722 $PRINTF "${YELLOW}framework failed${NORMAL}\n"
11723 elif [ $rc0 -eq 0 ]; then
11724 $PRINTF "$OK\n"
11725 numOK=$((numOK+1))
11726 else
11727 $PRINTF "$FAILED\n"
11728 echo "$CMD0"
11729 grep -v ^rc= "${te}0"
11730 numFAIL=$((numFAIL+1))
11731 listFAIL="$listFAIL $N"
11733 fi # NUMCOND
11735 esac
11736 N=$((N+1))
11739 # Does Socat have -d0 option?
11740 opt_d0=
11741 if $SOCAT -h |grep -e -d0 >/dev/null; then
11742 opt_d0="-d0"
11745 # socat up to 1.7.2.1 did only shutdown() but not close() an accept() socket
11746 # that was rejected due to range, tcpwrap, lowport, or sourceport option.
11747 # This file descriptor leak could be used for a denial of service attack.
11748 NAME=FDLEAK
11749 case "$TESTS" in
11750 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*)
11751 TEST="$NAME: file descriptor leak with range option"
11752 # have a TCP-LISTEN with range option; connect with wrong source address until
11753 # "open files" limit would exceed. When server continues operation the bug is
11754 # not present.
11755 if ! eval $NUMCOND; then :; else
11756 tf="$td/test$N.stdout"
11757 te="$td/test$N.stderr"
11758 tdiff="$td/test$N.diff"
11759 da="test$N $(date) $RANDOM"
11760 RLIMIT_NOFILE="$(ulimit -n)"
11761 if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then
11762 $PRINTF "${YELLOW}cannot determine ulimit -n${NORMAL}"
11763 else
11764 if [ $RLIMIT_NOFILE -gt 1024 ]; then
11765 ulimit -n 1024 # 65536 takes too long
11766 RLIMIT_NOFILE="$(ulimit -n)"
11768 newport tcp4
11769 CMD0="$TRACE $SOCAT $opt_d0 $opts TCP4-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE"
11770 #CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,pf=ip4,$REUSEADDR,range=$LOCALHOST4:255.255.255.255 PIPE"
11771 CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP4:$SECONDADDR:$PORT,bind=$SECONDADDR"
11772 CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST4:$PORT,bind=$LOCALHOST4"
11773 printf "test $F_n $TEST... " $N
11774 $CMD0 >/dev/null 2>"${te}0" &
11775 pid0=$!
11776 waittcp4port $PORT 1
11777 while [ $RLIMIT_NOFILE -gt 0 ]; do
11778 $CMD1 >/dev/null 2>>"${te}1"
11779 let RLIMIT_NOFILE=RLIMIT_NOFILE-1
11780 done
11781 echo "$da" |$CMD2 >"${tf}2" 2>"${te}2"
11782 rc2=$?
11783 kill $pid0 2>/dev/null; wait
11784 echo -e "$da" |diff "${tf}2" - >$tdiff
11785 if [ $rc2 -ne 0 ]; then
11786 $PRINTF "$FAILED (rc2=$rc2)\n"
11787 echo "$CMD0 &"
11788 cat "${te}0" >&2
11789 echo "$CMD1"
11790 cat "${te}1" >&2
11791 echo "$CMD2"
11792 cat "${te}2" >&2
11793 numFAIL=$((numFAIL+1))
11794 listFAIL="$listFAIL $N"
11795 elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then
11796 $PRINTF "$OK\n"
11797 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11798 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11799 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11800 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11801 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
11802 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
11803 numOK=$((numOK+1))
11804 else
11805 $PRINTF "$FAILED\n"
11806 echo "$CMD0 &"
11807 cat "${te}0" >&2
11808 echo "$CMD1"
11809 cat "${te}1" >&2
11810 echo "$CMD2"
11811 cat "${te}2" >&2
11812 numFAIL=$((numFAIL+1))
11813 listFAIL="$listFAIL $N"
11815 fi # ulimit -n
11816 fi # NUMCOND
11818 esac
11819 N=$((N+1))
11822 if false; then # this overflow is not reliably reproducable
11823 # 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.
11824 NAME=PROXY_ADDR_OVFL
11825 case "$TESTS" in
11826 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*)
11827 TEST="$NAME: proxy address parameters overflow"
11828 # invoke socat PROXY-CONNECT with long proxy server and target server names. If it terminates with exit code >= 128 it is vulnerable
11829 # 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
11830 if ! eval $NUMCOND; then :; else
11831 tf="$td/test$N.stdout"
11832 te="$td/test$N.stderr"
11833 tdiff="$td/test$N.diff"
11834 da="test$N $(date) $RANDOM"
11835 EF=; for p in ef; do
11836 if type ef >/dev/null 2>&1; then
11837 EF="ef "; break
11839 done
11840 newport tcp4
11841 CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,$REUSEADDR FILE:/dev/null"
11842 #CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80"
11843 CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT"
11844 printf "test $F_n $TEST... " $N
11845 $CMD0 >/dev/null 2>"${te}0" &
11846 pid0=$!
11847 waittcp4port $PORT 1
11848 $CMD1 >/dev/null 2>"${te}1"
11849 rc1=$?
11850 if [ $rc1 -lt 128 ]; then
11851 if [ "$EF" ]; then
11852 $PRINTF "$OK\n"
11853 numOK=$((numOK+1))
11854 else
11855 $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n"
11856 numCANT=$((num+1))
11857 listCANT="$listCANT $N"
11859 else
11860 $PRINTF "$FAILED\n"
11861 echo "$CMD1"
11862 cat "${te}"
11863 numFAIL=$((numFAIL+1))
11864 listFAIL="$listFAIL $N"
11866 fi # NUMCOND
11868 esac
11869 N=$((N+1))
11870 fi # false
11873 # LISTEN addresses in socat up to 1.7.2.1 applied many file descriptor, socket,
11874 # and TCP options only to the listening socket instead of the connection socket.
11875 NAME=LISTEN_KEEPALIVE
11876 case "$TESTS" in
11877 *%$N%*|*%functions%*|*%bugs%*|*%listen%*|*%keepalive%*|*%socket%*|*%listen%*|*%fork%*|*%$NAME%*)
11878 TEST="$NAME: keepalive option is applied to connection socket"
11879 # Instance 0 has TCP-LISTEN with option so-keepalive and invokes filan after
11880 # accept(). filan writes its output to the socket. instance 1 connects to
11881 # instance 0. The value of the sockets so-keepalive option is checked, it must
11882 # be 1
11883 if ! eval $NUMCOND; then :; else
11884 tf="$td/test$N.stdout"
11885 te="$td/test$N.stderr"
11886 #tdiff="$td/test$N.diff"
11887 #da="test$N $(date) $RANDOM"
11888 newport tcp4
11889 CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR,so-keepalive EXEC:\"$FILAN -i 1\",nofork"
11890 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
11891 printf "test $F_n $TEST... " $N
11892 eval $CMD0 >/dev/null 2>"${te}0" &
11893 pid0=$!
11894 waittcp4port $PORT 1
11895 $CMD1 >"${tf}1" 2>"${te}1"
11896 KEEPALIVE="$(cat "${tf}1" |tail -n +2 |sed -e "s/.*KEEPALIVE=//" -e "s/[[:space:]].*//")"
11897 rc1=$?
11898 kill $pid0 2>/dev/null; wait
11899 if [ -z "$KEEPALIVE" ]; then
11900 $PRINTF "$NO_RESULT\n"
11901 echo "$CMD0 &"
11902 cat "${te}0" >&2
11903 echo "$CMD1"
11904 cat "${te}1" >&2
11905 numCANT=$((numCANT+1))
11906 listCANT="$listCANT $N"
11907 namesCANT="$namesCANT $NAME"
11908 elif [ "$KEEPALIVE" = "1" ]; then
11909 $PRINTF "$OK\n";
11910 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11911 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11912 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11913 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11914 numOK=$((numOK+1))
11915 else
11916 $PRINTF "$FAILED (KEEPALIVE=$KEEPALIVE)\n"
11917 echo "$CMD0 &"
11918 cat "${te}0" >&2
11919 echo "$CMD1"
11920 cat "${te}1" >&2
11921 numFAIL=$((numFAIL+1))
11922 listFAIL="$listFAIL $N"
11923 namesFAIL="$namesFAIL $NAME"
11925 fi # NUMCOND
11927 esac
11928 N=$((N+1))
11931 # OPENSSL-CONNECT with bind option failed on some systems (eg.FreeBSD, but not
11932 # Linux) with "Invalid argument".
11933 NAME=OPENSSL_CONNECT_BIND
11934 case "$TESTS" in
11935 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%listen%*|*%$NAME%*)
11936 TEST="$NAME: test OPENSSL-CONNECT with bind option"
11937 # have a simple SSL server that just echoes data.
11938 # connect with socat using OPENSSL-CONNECT with bind, send data and check if the
11939 # reply is identical.
11940 if ! eval $NUMCOND; then :;
11941 elif ! testfeats openssl >/dev/null; then
11942 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11943 numCANT=$((numCANT+1))
11944 listCANT="$listCANT $N"
11945 else
11946 gentestcert testsrv
11947 tf0="$td/test$N.0.stdout"
11948 te0="$td/test$N.0.stderr"
11949 tf1="$td/test$N.1.stdout"
11950 te1="$td/test$N.1.stderr"
11951 tdiff="$td/test$N.diff"
11952 da="test$N $(date) $RANDOM"
11953 newport tcp4
11954 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 PIPE"
11955 CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,bind=$LOCALHOST,verify=0"
11956 printf "test $F_n $TEST... " $N
11957 $CMD0 >/dev/null 2>"$te0" &
11958 pid0=$!
11959 waittcp4port $PORT 1
11960 echo "$da" |$CMD1 >"$tf1" 2>"$te1"
11961 rc1=$?
11962 kill $pid0 2>/dev/null; wait
11963 if [ "$rc1" -ne 0 ]; then
11964 $PRINTF "$FAILED\n"
11965 echo "$CMD0 &"
11966 echo "$CMD1"
11967 cat "$te0"
11968 cat "$te1"
11969 numFAIL=$((numFAIL+1))
11970 listFAIL="$listFAIL $N"
11971 elif ! echo "$da" |diff - $tf1 >"$tdiff"; then
11972 $PRINTF "$FAILED\n"
11973 echo "$CMD0 &"
11974 echo "$CMD1"
11975 cat "${te}0"
11976 cat "${te}1"
11977 cat "$tdiff"
11978 numFAIL=$((numFAIL+1))
11979 listFAIL="$listFAIL $N"
11980 else
11981 $PRINTF "$OK\n"
11982 numOK=$((numOK+1))
11984 fi # NUMCOND
11986 esac
11987 N=$((N+1))
11990 # socat up to version 1.7.2.3
11991 # had a bug that converted a bit mask of 0 internally to 0xffffffff
11992 NAME=TCP4RANGE_0BITS
11993 case "$TESTS" in
11994 *%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%$NAME%*)
11995 TEST="$NAME: correct evaluation of range mask 0"
11996 if ! eval $NUMCOND; then :;
11997 elif [ -z "$SECONDADDR" ]; then
11998 # we need access to a second address
11999 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
12000 numCANT=$((numCANT+1))
12001 listCANT="$listCANT $N"
12002 else
12003 tf="$td/test$N.stdout"
12004 te="$td/test$N.stderr"
12005 tdiff="$td/test$N.diff"
12006 da="test$N $(date) $RANDOM"
12007 newport tcp4
12008 #testserversec "$N" "$TEST" "$opts" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0
12009 CMD0="$TRACE $SOCAT $opts -u TCP4-LISTEN:$PORT,$REUSEADDR,range=127.0.0.1/0 CREATE:$tf"
12010 CMD1="$TRACE $SOCAT $opts -u - TCP4-CONNECT:$SECONDADDR:$PORT,bind=$SECONDADDR"
12011 printf "test $F_n $TEST... " $N
12012 $CMD0 2>"${te}0" &
12013 pid0=$!
12014 waittcp4port $PORT 1
12015 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
12016 rc1=$?
12017 sleep 1
12018 kill $pid0 2>/dev/null; wait
12019 if [ $rc1 != 0 ]; then
12020 $PRINTF "${YELLOW}invocation failed${NORMAL}\n"
12021 numCANT=$((numCANT+1))
12022 listCANT="$listCANT $N"
12023 elif ! [ -f "$tf" ]; then
12024 $PRINTF "$FAILED\n"
12025 echo "$CMD0 &"
12026 echo "$CMD1"
12027 cat "${te}0"
12028 cat "${te}1"
12029 numFAIL=$((numFAIL+1))
12030 listFAIL="$listFAIL $N"
12031 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
12032 $PRINTF "${YELLOW}diff failed${NORMAL}\n"
12033 numCANT=$((numCANT+1))
12034 listCANT="$listCANT $N"
12035 else
12036 $PRINTF "$OK\n"
12037 numOK=$((numOK+1))
12040 fi ;; # $SECONDADDR, NUMCOND
12041 esac
12042 N=$((N+1))
12045 # test: OPENSSL sets of environment variables with important values of peer certificate
12046 newport tcp4
12047 while read ssldist MODE MODULE FIELD TESTADDRESS PEERADDRESS VALUE; do
12048 if [ -z "$ssldist" ] || [[ "$ssldist" == \#* ]]; then continue; fi
12050 SSLDIST=$(toupper $ssldist)
12051 NAME="ENV_${SSLDIST}_${MODE}_${MODULE}_${FIELD}"
12052 case "$TESTS" in
12053 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$ssldist%*|*%envvar%*|*%listen%*|*%$NAME%*)
12054 TEST="$NAME: $SSLDIST sets env SOCAT_${SSLDIST}_${MODULE}_${FIELD}"
12055 # have a server accepting a connection and invoking some shell code. The shell
12056 # code extracts and prints the SOCAT related environment vars.
12057 # outside code then checks if the environment contains the variables correctly
12058 # describing the desired field.
12059 FEAT=$(echo "$ssldist" |tr a-z A-Z)
12060 if ! eval $NUMCOND; then :;
12061 elif ! testfeats $FEAT >/dev/null; then
12062 $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
12063 numCANT=$((numCANT+1))
12064 listCANT="$listCANT $N"
12065 else
12066 tf="$td/test$N.stdout"
12067 te="$td/test$N.stderr"
12068 gentestcert testsrv
12069 gentestcert testcli
12070 test_proto=tcp4
12071 case "$MODE" in
12072 SERVER)
12073 CMD0="$SOCAT $opts -u -lp socat $TESTADDRESS SYSTEM:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\""
12074 CMD1="$SOCAT $opts -u /dev/null $PEERADDRESS"
12075 printf "test $F_n $TEST... " $N
12076 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
12077 pid0=$!
12078 wait${test_proto}port $PORT 1
12079 { $CMD1 2>"${te}1"; sleep 1; }
12080 rc1=$?
12081 waitfile "$tf" 2
12082 kill $pid0 2>/dev/null; wait
12084 CLIENT)
12085 CMD0="$SOCAT $opts -u /dev/null $PEERADDRESS"
12086 CMD1="$SOCAT $opts -u -lp socat $TESTADDRESS SYSTEM:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\""
12087 printf "test $F_n $TEST... " $N
12088 $CMD0 2>"${te}0" &
12089 pid0=$!
12090 wait${test_proto}port $PORT 1
12091 eval "$CMD1 2>\"${te}1\" >\"$tf\""
12092 rc1=$?
12093 waitfile "$tf" 2
12094 kill $pid0 2>/dev/null; wait
12096 esac
12097 if [ $rc1 != 0 ]; then
12098 $PRINTF "$NO_RESULT (client failed):\n"
12099 echo "$CMD0 &"
12100 cat "${te}0"
12101 echo "$CMD1"
12102 cat "${te}1"
12103 numCANT=$((numCANT+1))
12104 listCANT="$listCANT $N"
12105 elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")";
12106 [ "$effval" = "$VALUE" ]; then
12107 $PRINTF "$OK\n"
12108 if [ "$debug" ]; then
12109 echo "$CMD0 &"
12110 cat "${te}0"
12111 echo "$CMD1"
12112 cat "${te}1"
12114 numOK=$((numOK+1))
12115 else
12116 $PRINTF "$FAILED\n"
12117 echo "expected \"$VALUE\", got \"$effval\"" >&2
12118 echo "$CMD0 &"
12119 cat "${te}0"
12120 echo "$CMD1"
12121 cat "${te}1"
12122 numFAIL=$((numFAIL+1))
12123 listFAIL="$listFAIL $N"
12125 fi # NUMCOND, feats
12127 esac
12128 N=$((N+1))
12130 done <<<"
12131 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
12132 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
12133 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
12134 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
12135 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
12136 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
12137 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
12138 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
12139 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
12143 ###############################################################################
12144 # tests: option umask with "passive" NAMED group addresses
12145 while read addr fileopt addropts proto diropt ADDR2; do
12146 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12147 # some passive (listening...) filesystem based addresses did not implement the
12148 # umask option
12149 ADDR=$(toupper $addr)
12150 ADDR_=${ADDR/-/_}
12151 PROTO=$(toupper $proto)
12152 if [ "$diropt" = "." ]; then diropt=; fi
12153 if [ "$fileopt" = "." ]; then fileopt=; fi
12154 if [ "$addropts" = "." ]; then addropts=; fi
12155 NAME=${ADDR_}_UMASK
12156 case "$TESTS" in
12157 *%$N%*|*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%umask%*|*%listen%*|*%$NAME%*)
12158 TEST="$NAME: $ADDR applies option umask"
12159 # start a socat process with passive/listening file system entry. Check the
12160 # permissions of the FS entry, then terminate the process.
12161 # Test succeeds when FS entry exists and has expected permissions.
12162 if ! eval $NUMCOND; then :; else
12163 if [ $ADDR = PTY ]; then set -xv; fi
12164 tlog="$td/test$N.log"
12165 te0="$td/test$N.0.stderr"
12166 tsock="$td/test$N.sock"
12167 if [ -z "$fileopt" ]; then
12168 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,unlink-close=0,umask=177 $ADDR2"
12169 else
12170 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,unlink-close=0,umask=177 $ADDR2"
12172 printf "test $F_n $TEST... " $N
12173 $CMD0 >/dev/null 2>"$te0" &
12174 pid0=$!
12175 wait${proto} $tsock 1 2>"$tlog"
12176 ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
12177 perms=$(fileperms "$tsock")
12178 kill $pid0 2>>"$tlog"
12179 wait
12180 if [ "$ERRNOENT" ]; then
12181 $PRINTF "${RED}no entry${NORMAL}\n"
12182 echo "$CMD0 &"
12183 cat "$te0"
12184 cat "$tlog"
12185 let numFAIL=numFAIL+1
12186 listFAIL="$listFAIL $N"
12187 elif [ "$perms" != "600" ]; then
12188 $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n"
12189 echo "$CMD0 &"
12190 cat "$te0"
12191 let numFAIL=numFAIL+1
12192 listFAIL="$listFAIL $N"
12193 else
12194 $PRINTF "$OK\n"
12195 let numOK=numOK+1
12197 set +xv
12198 fi # NUMCOND
12200 esac
12201 N=$((N+1))
12203 done <<<"
12204 # address fileopt addropts waitfor direction ADDR2
12205 create . . file -U FILE:/dev/null
12206 open . creat file . FILE:/dev/null
12207 gopen . creat file . FILE:/dev/null
12208 unix-listen . . unixport . FILE:/dev/null
12209 unix-recvfrom . . unixport . FILE:/dev/null
12210 unix-recv . . unixport -u FILE:/dev/null
12211 pipe . . file -u FILE:/dev/null
12212 # pty does not seem to honor umask:
12213 #pty link . file . PIPE
12217 # Tests: option perm with "passive" NAMED group addresses
12218 # Note tests UNIX_RECVFROM_PERM and UNIX_RECV_PERM had chmod() applied after
12219 # bind() due to an error but succeeded. After a correction with Socat 1.8.0.0
12220 # the perm option is applied as fchown() call which does not affect the FS
12221 # entry on Freebsd (10.3) and OpenIndiana (2021-04), so they fail now
12222 while read addr fileopt addropts feat waitfor diropt; do
12223 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12224 # test if passive (listening...) filesystem based addresses implement option perm
12225 ADDR=$(toupper $addr)
12226 ADDR_=${ADDR/-/_}
12227 if [ "$diropt" = "." ]; then diropt=; fi
12228 if [ "$fileopt" = "." ]; then fileopt=; fi
12229 if [ "$addropts" = "." ]; then addropts=; fi
12230 NAME=${ADDR_}_PERM
12231 case "$TESTS" in
12232 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$feat%*|*%ignoreeof%*|*%perm%*|*%listen%*|*%$NAME%*)
12233 TEST="$NAME: $ADDR applies option perm"
12234 # start a socat process with passive/listening file system entry. Check the
12235 # permissions of the FS entry, then terminate the process.
12236 # Test succeeds when FS entry exists and has expected permissions.
12237 if ! eval $NUMCOND; then :; else
12238 tlog="$td/test$N.log"
12239 te0="$td/test$N.0.stderr"
12240 tsock="$td/test$N.sock"
12241 # set -vx
12242 if [ -z "$fileopt" ]; then
12243 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof"
12244 else
12245 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof"
12247 printf "test $F_n $TEST... " $N
12248 $CMD0 >/dev/null 2>"$te0" &
12249 pid0=$!
12250 wait${waitfor} $tsock 1 2>"$tlog"
12251 ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
12252 perms=$(fileperms "$tsock")
12253 kill $pid0 2>>"$tlog"
12254 wait
12255 if [ "$ERRNOENT" ]; then
12256 $PRINTF "${RED}no entry${NORMAL}\n"
12257 echo "$CMD0 &"
12258 cat "$te0"
12259 cat "$tlog"
12260 let numFAIL=numFAIL+1
12261 listFAIL="$listFAIL $N"
12262 elif [ "$perms" != "511" ]; then
12263 $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n"
12264 echo "$CMD0 &"
12265 cat "$te0"
12266 let numFAIL=numFAIL+1
12267 listFAIL="$listFAIL $N"
12268 else
12269 $PRINTF "$OK\n"
12270 let numOK=numOK+1
12272 set +vx
12273 fi # NUMCOND
12275 esac
12276 N=$((N+1))
12278 done <<<"
12279 # address fileopt addropts feat waitfor direction
12280 create . . file file -U
12281 open . creat file file .
12282 gopen . creat file file .
12283 unix-listen . . unix unixport .
12284 unix-recvfrom . . unix unixport .
12285 unix-recv . . unix unixport -u
12286 pipe . . pipe file -u
12287 pty link . pty file .
12291 # tests: option user with "passive" NAMED group addresses
12292 while read addr fileopt addropts feat waitfor diropt; do
12293 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12294 # test if passive (listening...) filesystem based addresses implement option user
12295 ADDR=$(toupper $addr)
12296 ADDR_=${ADDR/-/_}
12297 if [ "$diropt" = "." ]; then diropt=; fi
12298 if [ "$fileopt" = "." ]; then fileopt=; fi
12299 if [ "$addropts" = "." ]; then addropts=; fi
12300 NAME=${ADDR_}_USER
12301 case "$TESTS" in
12302 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$feat%*|*%root%*|*%ignoreeof%*|*%listen%*|*%$NAME%*)
12303 TEST="$NAME: $ADDR applies option user"
12304 # start a socat process with passive/listening file system entry with user option.
12305 # Check the owner of the FS entry, then terminate the process.
12306 # Test succeeds when FS entry exists and has expected owner.
12307 if ! eval $NUMCOND; then :;
12308 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
12309 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
12310 numCANT=$((numCANT+1))
12311 listCANT="$listCANT $N"
12312 else
12313 tlog="$td/test$N.log"
12314 te0="$td/test$N.0.stderr"
12315 tsock="$td/test$N.sock"
12316 # set -vx
12317 if [ -z "$fileopt" ]; then
12318 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof"
12319 else
12320 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof"
12322 printf "test $F_n $TEST... " $N
12323 $CMD0 >/dev/null 2>"$te0" &
12324 pid0=$!
12325 wait${waitfor} $tsock 1 2>"$tlog"
12326 ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
12327 user=$(fileuser "$tsock")
12328 kill $pid0 2>>"$tlog"
12329 wait
12330 if [ "$ERRNOENT" ]; then
12331 $PRINTF "${FAILED}(no entry)\n"
12332 echo "$CMD0 &"
12333 cat "$te0" >&2
12334 cat "$tlog" >&2
12335 let numFAIL=numFAIL+1
12336 listFAIL="$listFAIL $N"
12337 elif [ "$user" != "$SUBSTUSER" ]; then
12338 $PRINTF "${FAILD}(user \"$user\", expected \"$SUBSTUSER\")\n"
12339 echo "$CMD0 &"
12340 cat "$te0" >&2
12341 let numFAIL=numFAIL+1
12342 listFAIL="$listFAIL $N"
12343 else
12344 $PRINTF "$OK\n"
12345 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
12346 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
12347 numOK=$((numOK+1))
12349 set +vx
12350 fi # NUMCOND
12352 esac
12353 N=$((N+1))
12355 done <<<"
12356 # address fileopt addropts feat waitfor direction
12357 create . . file file -U
12358 open . creat file file .
12359 gopen . creat file file .
12360 unix-listen . . unix unixport .
12361 unix-recvfrom . . unix unixport .
12362 unix-recv . . unix unixport -u
12363 pipe . . pipe file -u
12364 pty link . pty file .
12368 # tests: is "passive" filesystem entry removed at the end? (without fork)
12369 while read addr fileopt addropts feat waitfor diropt crit ADDR2; do
12370 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12371 # some passive (listening...) filesystem based addresses did not remove the file
12372 # system entry at the end
12373 ADDR=$(toupper $addr)
12374 ADDR_=${ADDR/-/_}
12375 if [ "$diropt" = "." ]; then diropt=; fi
12376 if [ "$fileopt" = "." ]; then fileopt=; fi
12377 if [ "$addropts" = "." ]; then addropts=; fi
12378 # $ADDR removes the file system entry when the process is terminated
12379 NAME=${ADDR_}_REMOVE
12380 case "$TESTS" in
12381 *%$N%*|*%functions%*|*%bugs%*|*%feat%*|*%socket%*|*%listen%*|*%$NAME%*)
12382 TEST="$NAME: $ADDR removes socket entry when terminated while waiting for connection"
12383 # start a socat process with listening unix domain socket etc. Terminate the
12384 # process and check if the file system socket entry still exists.
12385 # Test succeeds when entry does not exist.
12386 if ! eval $NUMCOND; then :; else
12387 tlog="$td/test$N.log"
12388 te0="$td/test$N.0.stderr"
12389 tsock="$td/test$N.sock"
12390 if [ -z "$fileopt" ]; then
12391 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts $ADDR2"
12392 else
12393 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2"
12395 printf "test $F_n $TEST... " $N
12396 $CMD0 >/dev/null 2>"$te0" &
12397 pid0=$!
12398 wait${waitfor} "$crit" $tsock 1 2>"$tlog"
12399 kill $pid0 2>>"$tlog"
12400 rc1=$?
12401 wait >>"$tlog"
12402 if [ $rc1 != 0 ]; then
12403 $PRINTF "${YELLOW}setup failed${NORMAL}\n"
12404 echo "$CMD0 &"
12405 cat "$te0"
12406 cat "$tlog"
12407 numCANT=$((numCANT+1))
12408 listCANT="$listCANT $N"
12409 elif ! [ $crit $tsock ]; then
12410 $PRINTF "$OK\n"
12411 let numOK=numOK+1
12412 else
12413 $PRINTF "$FAILED\n"
12414 echo "$CMD0 &"
12415 cat "$te0"
12416 cat "$tlog"
12417 let numFAIL=numFAIL+1
12418 listFAIL="$listFAIL $N"
12420 fi # NUMCOND
12422 esac
12423 N=$((N+1))
12425 done <<<"
12426 # address fileopt addropts feat waitfor direction crit ADDR2
12427 unix-listen . . unix unixport . -e FILE:/dev/null
12428 unix-recvfrom . . unix unixport . -e FILE:/dev/null
12429 unix-recv . . unix unixport -u -e FILE:/dev/null
12430 pipe . . pipe file -u -e FILE:/dev/null
12431 pty link . pty file . -L PIPE
12435 # tests: is "passive" filesystem entry removed at the end? (with fork)
12436 while read addr fileopt addropts proto diropt crit ADDR2; do
12437 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12438 # some passive (listening...) filesystem based addresses with fork did not remove
12439 # the file system entry at the end
12440 ADDR=$(toupper $addr)
12441 ADDR_=${ADDR/-/_}
12442 PROTO=$(toupper $proto)
12443 if [ "$diropt" = "." ]; then diropt=; fi
12444 if [ "$fileopt" = "." ]; then fileopt=; fi
12445 if [ "$addropts" = "." ]; then addropts=; fi
12446 # $ADDR with fork removes the file system entry when the process is terminated
12447 NAME=${ADDR_}_REMOVE_FORK
12448 case "$TESTS" in
12449 *%$N%*|*%functions%*|*%bugs%*|*%fork%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
12450 TEST="$NAME: $ADDR with fork removes socket entry when terminated during accept"
12451 # start a socat process with listening unix domain socket etc and option fork.
12452 # Terminate the process and check if the file system socket entry still exists.
12453 # Test succeeds when entry does not exist.
12454 if ! eval $NUMCOND; then :; else
12455 tlog="$td/test$N.log"
12456 te0="$td/test$N.0.stderr"
12457 tsock="$td/test$N.sock"
12458 if [ -z "$fileopt" ]; then
12459 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,fork,$addropts $ADDR2"
12460 else
12461 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2"
12463 printf "test $F_n $TEST... " $N
12464 $CMD0 >/dev/null 2>"$te0" &
12465 pid0=$!
12466 wait${proto} "$crit" $tsock 1 2>"$tlog"
12467 kill $pid0 2>>"$tlog"
12468 rc1=$?
12469 wait
12470 if [ $rc1 != 0 ]; then
12471 $PRINTF "${YELLOW}setup failed${NORMAL}\n"
12472 echo "$CMD0 &"
12473 cat "$te0"
12474 cat "$tlog"
12475 numCANT=$((numCANT+1))
12476 listCANT="$listCANT $N"
12477 elif ! [ $crit $tsock ]; then
12478 $PRINTF "$OK\n"
12479 let numOK=numOK+1
12480 else
12481 $PRINTF "$FAILED\n"
12482 echo "$CMD0 &"
12483 cat "$te0"
12484 cat "$tlog"
12485 let numFAIL=numFAIL+1
12486 listFAIL="$listFAIL $N"
12488 fi # NUMCOND
12490 esac
12491 N=$((N+1))
12493 done <<<"
12494 # address fileopt addropts waitfor direction crit ADDR2
12495 unix-listen . . unixport . -e FILE:/dev/null
12496 unix-recvfrom . . unixport . -e FILE:/dev/null
12500 # bug fix: SYSTEM address child process shut down parents sockets including
12501 # SSL connection under some circumstances.
12502 NAME=SYSTEM_SHUTDOWN
12503 case "$TESTS" in
12504 *%$N%*|*%functions%*|*%bugs%*|*%system%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
12505 TEST="$NAME: SYSTEM address does not shutdown its parents addresses"
12506 # start an OpenSSL echo server using SYSTEM:cat
12507 # start an OpenSSL client that sends data
12508 # when the client recieves its data and terminates without error the test succeeded
12509 # in case of the bug the client issues an error like:
12510 # SSL_connect(): error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
12511 if ! eval $NUMCOND; then :;
12512 elif ! testfeats openssl >/dev/null; then
12513 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
12514 numCANT=$((numCANT+1))
12515 listCANT="$listCANT $N"
12516 else
12517 gentestcert testsrv
12518 tf="$td/test$N.stdout"
12519 te="$td/test$N.stderr"
12520 tdiff="$td/test$N.diff"
12521 da="test$N $(date) $RANDOM"
12522 newport tcp4
12523 CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 SYSTEM:cat"
12524 CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0"
12525 printf "test $F_n $TEST... " $N
12526 $CMD0 >/dev/null 2>"${te}0" &
12527 pid0=$!
12528 waittcp4port $PORT 1
12529 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
12530 rc1=$?
12531 kill $pid0 2>/dev/null; wait
12532 if [ $rc1 -ne 0 ]; then
12533 $PRINTF "$FAILED\n"
12534 echo "rc1=$rc1"
12535 echo "$CMD0 &"
12536 echo "$CMD1"
12537 cat "${te}0"
12538 cat "${te}1"
12539 numFAIL=$((numFAIL+1))
12540 listFAIL="$listFAIL $N"
12541 elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then
12542 $PRINTF "$FAILED\n"
12543 echo "diff:"
12544 cat "$tdiff"
12545 echo "$CMD0 &"
12546 echo "$CMD1"
12547 cat "${te}0"
12548 cat "${te}1"
12549 numFAIL=$((numFAIL+1))
12550 listFAIL="$listFAIL $N"
12551 else
12552 $PRINTF "$OK\n"
12553 numOK=$((numOK+1))
12555 fi # NUMCOND
12557 esac
12558 N=$((N+1))
12561 # test if TCP4-LISTEN with empty port arg terminates with error
12562 NAME=TCP4_NOPORT
12563 case "$TESTS" in
12564 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*)
12565 TEST="$NAME: test if TCP4-LISTEN with empty port arg bails out"
12566 # run socat with TCP4-LISTEN with empty port arg. Check if it terminates
12567 # immediately with return code 1
12568 if ! eval $NUMCOND; then :; else
12569 tf="$td/test$N.stdout"
12570 te="$td/test$N.stderr"
12571 t0rc="$td/test$N.rc"
12572 tdiff="$td/test$N.diff"
12573 da="test$N $(date) $RANDOM"
12574 CMD0="$SOCAT $opts TCP4-LISTEN: /dev/null"
12575 printf "test $F_n $TEST... " $N
12576 { $CMD0 >/dev/null 2>"${te}0"; echo $? >"$t0rc"; } & 2>/dev/null
12577 pid0=$!
12578 sleep 1
12579 kill $pid0 2>/dev/null; wait
12580 if [ ! -f "$t0rc" ]; then
12581 $PRINTF "$FAILED\n"
12582 echo "no return code of CMD0 stored" >&2
12583 echo "$CMD0 &"
12584 cat "${te}0"
12585 numFAIL=$((numFAIL+1))
12586 listFAIL="$listFAIL $N"
12587 elif ! echo 1 |diff - "$t0rc" >"$tdiff"; then
12588 $PRINTF "$FAILED\n"
12589 echo "CMD0 exited with $(cat $t0rc), expected 1"
12590 echo "$CMD0 &"
12591 cat "${te}0"
12592 numFAIL=$((numFAIL+1))
12593 listFAIL="$listFAIL $N"
12594 else
12595 $PRINTF "$OK\n"
12596 numOK=$((numOK+1))
12598 fi # NUMCOND
12600 esac
12601 N=$((N+1))
12604 # tests of various SSL methods; from TLS1.3 this method is not avail in OpenSSL:
12605 OPENSSL_METHODS_OBSOLETE="SSL3 SSL23"
12606 OPENSSL_METHODS_EXPECTED="TLS1 TLS1.1 TLS1.2 DTLS1 DTLS1.2"
12608 # the OPENSSL_METHOD_DTLS1 test hangs sometimes, probably depending on the openssl version.
12609 OPENSSL_VERSION="$(openssl version)"
12610 OPENSSL_VERSION="${OPENSSL_VERSION#* }"
12611 OPENSSL_VERSION="${OPENSSL_VERSION%%-*}"
12612 OPENSSL_VERSION_GOOD=1.0.2 # this is just a guess.
12613 # known bad: 1.0.1e
12614 # known good: 1.0.2j
12617 # test if the obsolete SSL methods can be used with OpenSSL
12618 for method in $OPENSSL_METHODS_OBSOLETE; do
12620 NAME=OPENSSL_METHOD_$method
12621 case "$TESTS" in
12622 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%listen%*|*%$NAME%*)
12623 TEST="$NAME: test OpenSSL method $method"
12624 # Start a socat process with obsoelete OpenSSL method, it should fail
12625 if ! eval $NUMCOND; then :;
12626 elif ! testfeats openssl >/dev/null; then
12627 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
12628 numCANT=$((numCANT+1))
12629 listCANT="$listCANT $N"
12630 elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then
12631 $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N
12632 numCANT=$((numCANT+1))
12633 listCANT="$listCANT $N"
12634 else
12635 gentestcert testsrv
12636 tf="$td/test$N.stdout"
12637 te="$td/test$N.stderr"
12638 tdiff="$td/test$N.diff"
12639 da="test$N $(date) $RANDOM"
12640 newport tcp4
12641 CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,openssl-method=$method,cert=testsrv.pem,verify=0 PIPE"
12642 CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,opensslmethod=$method,verify=0"
12643 printf "test $F_n $TEST... " $N
12644 if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then
12645 $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n"
12646 numCANT=$((numCANT+1))
12647 listCANT="$listCANT $N"
12648 else
12649 $CMD0 >/dev/null 2>"${te}0" &
12650 pid0=$!
12651 waittcp4port $PORT 1 1 2>/dev/null; w0=$? # result of waiting for process 0
12652 if [ $w0 -eq 0 ]; then
12653 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
12654 rc1=$?
12655 kill $pid0 2>/dev/null; wait
12657 echo "$da" |diff - "${tf}1" >"$tdiff" 2>/dev/null
12658 if [ $w0 -eq 0 ] && [ -f "${tf}1" ] && ! [ -s "$tdiff" ]; then
12659 $PRINTF "${YELLOW}WARN${NORMAL} (obsolete method succeeds)\n"
12660 numOK=$((numOK+1))
12661 else
12662 $PRINTF "$OK (obsolete method fails)\n"
12663 cat "$tdiff"
12664 numOK=$((numOK+1))
12666 if [ "$VERBOSE" ]; then
12667 echo " $CMD0"
12668 echo " echo \"$da\" |$CMD1"
12670 fi # !DTLS1 hang
12671 fi # NUMCOND
12673 esac
12674 N=$((N+1))
12676 done
12678 # test if the various SSL methods can be used with OpenSSL
12679 for method in $OPENSSL_METHODS_EXPECTED; do
12681 NAME=OPENSSL_METHOD_$method
12682 METHFAM=$(tolower "${method%%[0-9]*}")
12683 case "$TESTS" in
12684 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%$METHFAM%*|*%listen%*|*%$NAME%*)
12685 TEST="$NAME: test OpenSSL method $method"
12686 # Start a socat process listening with OpenSSL and echoing data,
12687 # using the selected method
12688 # Start a second socat process connecting to the listener using
12689 # the same method, send some data and catch the reply.
12690 # If the reply is identical to the sent data the test succeeded.
12691 if ! eval $NUMCOND; then :;
12692 elif ! testfeats openssl >/dev/null; then
12693 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
12694 numCANT=$((numCANT+1))
12695 listCANT="$listCANT $N"
12696 elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then
12697 $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N
12698 numCANT=$((numCANT+1))
12699 listCANT="$listCANT $N"
12700 else
12701 gentestcert testsrv
12702 tf="$td/test$N.stdout"
12703 te="$td/test$N.stderr"
12704 tdiff="$td/test$N.diff"
12705 da="test$N $(date) $RANDOM"
12706 if [[ "$method" =~ DTLS* ]]; then
12707 newport udp4
12708 else
12709 newport tcp4
12711 CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,openssl-method=$method,cert=testsrv.pem,verify=0 PIPE"
12712 CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,openssl-method=$method,verify=0"
12713 printf "test $F_n $TEST... " $N
12714 if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then
12715 $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n"
12716 numCANT=$((numCANT+1))
12717 listCANT="$listCANT $N"
12718 else
12719 $CMD0 >/dev/null 2>"${te}0" &
12720 pid0=$!
12721 if [[ "$method" =~ DTLS* ]]; then
12722 waitudp4port $PORT 1
12723 else
12724 waittcp4port $PORT 1
12726 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
12727 rc1=$?
12728 kill $pid0 2>/dev/null; wait
12729 if echo "$da" |diff - "${tf}1" >"$tdiff"; then
12730 $PRINTF "$OK\n"
12731 numOK=$((numOK+1))
12732 if [ "$VERBOSE" ]; then
12733 echo " $CMD0"
12734 echo " echo \"$da\" |$CMD1"
12736 else
12737 $PRINTF "$FAILED\n"
12738 echo "$CMD0 &"
12739 cat "${te}0"
12740 echo "$CMD1"
12741 cat "${te}1"
12742 cat "$tdiff"
12743 numFAIL=$((numFAIL+1))
12744 listFAIL="$listFAIL $N"
12745 #esac
12747 fi # !DTLS1 hang
12748 fi # NUMCOND
12750 esac
12751 N=$((N+1))
12753 done
12755 # test security of option openssl-set-min-proto-version
12756 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)
12757 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)
12759 NAME=OPENSSL_MIN_VERSION
12760 case "$TESTS" in
12761 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%$NAME%*)
12762 TEST="$NAME: security of OpenSSL server with openssl-min-proto-version"
12763 if ! eval $NUMCOND; then :;
12764 elif ! testaddrs openssl >/dev/null; then
12765 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
12766 numCANT=$((numCANT+1))
12767 listCANT="$listCANT $N"
12768 elif ! feat=$(testoptions openssl-min-proto-version); then
12769 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
12770 numCANT=$((numCANT+1))
12771 listCANT="$listCANT $N"
12772 elif ! [ "$OPENSSL_LATEST_PROTO_VERSION" -a "$OPENSSL_BEFORELAST_PROTO_VERSION" -a \
12773 "$OPENSSL_LATEST_PROTO_VERSION" != "$OPENSSL_BEFORELAST_PROTO_VERSION" ]; then
12774 $PRINTF "test $F_n $TEST... ${YELLOW}cannot determine two available SSL/TLS versions${NORMAL}\n" $N
12775 numCANT=$((numCANT+1))
12776 listCANT="$listCANT $N"
12777 else
12778 gentestcert testsrv
12779 newport tcp4
12780 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
12781 fi ;; # NUMCOND, $fets
12782 esac
12783 N=$((N+1))
12786 # Address options fdin and fdout were silently ignored when not applicable
12787 # due to -u or -U option. Now these combinations are caught as errors.
12788 NAME=FDOUT_ERROR
12789 case "$TESTS" in
12790 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
12791 TEST="$NAME: fdout bails out in write-only context"
12792 # use EXEC in write-only context with option fdout. Expected behaviour: error
12793 if ! eval $NUMCOND; then :; else
12794 tf="$td/test$N.stdout"
12795 te="$td/test$N.stderr"
12796 tdiff="$td/test$N.diff"
12797 da="test$N $(date) $RANDOM"
12798 CMD="$SOCAT $opts -u /dev/null EXEC:cat,fdout=1"
12799 printf "test $F_n $TEST... " $N
12800 $CMD >/dev/null 2>"${te}"
12801 rc=$?
12802 if [ $rc -eq 1 ]; then
12803 $PRINTF "$OK\n"
12804 numOK=$((numOK+1))
12805 else
12806 $PRINTF "$FAILED\n"
12807 echo "$CMD"
12808 cat "${te}"
12809 echo "command did not terminate with error!"
12810 numFAIL=$((numFAIL+1))
12811 listFAIL="$listFAIL $N"
12813 fi # NUMCOND
12815 esac
12816 N=$((N+1))
12819 # test if failure exit code of SYSTEM invocation causes socat to also exit
12820 # with !=0
12821 NAME=SYSTEM_RC
12822 case "$TESTS" in
12823 *%$N%*|*%functions%*|*%system%*|*%$NAME%*)
12824 TEST="$NAME: promote failure of SYSTEM"
12825 # run socat with SYSTEM:false and check if socat exits with !=0
12826 if ! eval $NUMCOND; then :; else
12827 tf="$td/test$N.stdout"
12828 te="$td/test$N.stderr"
12829 tdiff="$td/test$N.diff"
12830 da="test$N $(date) $RANDOM"
12831 # shut-none makes sure that the child is not killed by parent
12832 CMD0="$TRACE $SOCAT $opts - SYSTEM:false,shut-none"
12833 printf "test $F_n $TEST... " $N
12834 sleep 1 |$CMD0 >/dev/null 2>"${te}0"
12835 rc0=$?
12836 if [ $rc0 -eq 0 ]; then
12837 $PRINTF "$FAILED\n"
12838 echo "$CMD0"
12839 cat "${te}0"
12840 numFAIL=$((numFAIL+1))
12841 listFAIL="$listFAIL $N"
12842 else
12843 $PRINTF "$OK\n"
12844 numOK=$((numOK+1))
12846 fi # NUMCOND
12848 esac
12849 N=$((N+1))
12852 # test if failure exit code of EXEC invocation causes socat to also exit
12853 # with !=0
12854 NAME=EXEC_RC
12855 case "$TESTS" in
12856 *%$N%*|*%functions%*|*%exec%*|*%$NAME%*)
12857 TEST="$NAME: promote failure of EXEC"
12858 # run socat with EXEC:false and check if socat exits with !=0
12859 if ! eval $NUMCOND; then :; else
12860 tf="$td/test$N.stdout"
12861 te="$td/test$N.stderr"
12862 tdiff="$td/test$N.diff"
12863 da="test$N $(date) $RANDOM"
12864 # shut-none makes sure that the child is not killed by parent
12865 CMD0="$TRACE $SOCAT $opts - EXEC:false,shut-none"
12866 printf "test $F_n $TEST... " $N
12867 sleep 1 |$CMD0 >/dev/null 2>"${te}0"
12868 rc0=$?
12869 if [ $rc0 -eq 0 ]; then
12870 $PRINTF "$FAILED\n"
12871 echo "$CMD0"
12872 cat "${te}0"
12873 numFAIL=$((numFAIL+1))
12874 listFAIL="$listFAIL $N"
12875 else
12876 $PRINTF "$OK\n"
12877 numOK=$((numOK+1))
12879 fi # NUMCOND
12881 esac
12882 N=$((N+1))
12885 # test the so-reuseaddr option
12886 NAME=SO_REUSEADDR
12887 case "$TESTS" in
12888 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
12889 TEST="$NAME: test the so-reuseaddr option"
12890 # process 0 provides a tcp listening socket with so-reuseaddr;
12891 # process 1 connects to this port; thus the port is connected but no longer
12892 # listening
12893 # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the
12894 # SO_REUSEADDR socket options did not work
12895 # process 3 connects to this port; only if it is successful the test is ok
12896 if ! eval $NUMCOND; then :;
12897 elif ! feat=$(testoptions so-reuseaddr); then
12898 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
12899 numCANT=$((numCANT+1))
12900 listCANT="$listCANT $N"
12901 else
12902 newport tcp4; tp="$PORT"
12903 tf="$td/test$N.stdout"
12904 te="$td/test$N.stderr"
12905 tdiff="$td/test$N.diff"
12906 da="test$N $(date) $RANDOM"
12907 CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,$REUSEADDR PIPE"
12908 CMD1="$TRACE $SOCAT $opts - TCP4:localhost:$tp"
12909 CMD2="$CMD0"
12910 CMD3="$CMD1"
12911 printf "test $F_n $TEST... " $N
12912 $CMD0 >/dev/null 2>"${te}0" &
12913 pid0=$!
12914 waittcp4port $tp 1
12915 (echo "$da"; sleep 3) |$CMD1 >"$tf" 2>"${te}1" & # this should always work
12916 pid1=$!
12917 usleep 1000000
12918 $CMD2 >/dev/null 2>"${te}2" &
12919 pid2=$!
12920 waittcp4port $tp 1
12921 (echo "$da") |$CMD3 >"${tf}3" 2>"${te}3"
12922 rc3=$?
12923 kill $pid0 $pid1 $pid2 2>/dev/null; wait
12924 if ! echo "$da" |diff - "$tf"; then
12925 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
12926 echo "$CMD0 &"
12927 echo "$CMD1"
12928 numCANT=$((numCANT+1))
12929 listCANT="$listCANT $N"
12930 elif [ $rc3 -ne 0 ]; then
12931 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
12932 echo "$CMD0 &"
12933 echo "$CMD1"
12934 echo "$CMD2 &"
12935 echo "$CMD3"
12936 cat "${te}2" "${te}3"
12937 numFAIL=$((numFAIL+1))
12938 listFAIL="$listFAIL $N"
12939 elif ! echo "$da" |diff - "${tf}3"; then
12940 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
12941 echo "$CMD0 &"
12942 echo "$CMD1"
12943 echo "$CMD2 &"
12944 echo "$CMD3"
12945 echo "$da" |diff - "${tf}3"
12946 numCANT=$((numCANT+1))
12947 listCANT="$listCANT $N"
12948 else
12949 $PRINTF "$OK\n"
12950 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
12951 numOK=$((numOK+1))
12953 fi # NUMCOND, SO_REUSEADDR
12955 esac
12956 N=$((N+1))
12959 # test the so-reuseport option
12960 NAME=SO_REUSEPORT
12961 case "$TESTS" in
12962 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
12963 TEST="$NAME: test the so-reuseport option"
12964 # process 0 provides a tcp listening socket with so-reuseport;
12965 # process 1 provides an equivalent tcp listening socket with so-reuseport;
12966 # process 2 connects to this port and transfers data
12967 # process 3 connects to this port and transfers data
12968 # test succeeds when both data transfers work
12969 if ! eval $NUMCOND; then :;
12970 elif ! feat=$(testoptions so-reuseport); then
12971 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
12972 numCANT=$((numCANT+1))
12973 listCANT="$listCANT $N"
12974 else
12975 newport tcp4; tp="$PORT"
12976 tf="$td/test$N.stdout"
12977 te="$td/test$N.stderr"
12978 tdiff="$td/test$N.diff"
12979 da2="test$N $(date) $RANDOM"
12980 da3="test$N $(date) $RANDOM"
12981 CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,$REUSEADDR,so-reuseport PIPE"
12982 CMD1="$CMD0"
12983 CMD2="$TRACE $SOCAT $opts - TCP4:localhost:$tp"
12984 CMD3="$CMD2"
12985 printf "test $F_n $TEST... " $N
12986 $CMD0 >/dev/null 2>"${te}0" &
12987 pid0=$!
12988 $CMD1 >/dev/null 2>"${te}1" &
12989 pid1=$!
12990 waittcp4port $tp 1
12991 (echo "$da2") |$CMD2 >"${tf}2" 2>"${te}2" # this should always work
12992 rc2=$?
12993 (echo "$da3") |$CMD3 >"${tf}3" 2>"${te}3"
12994 rc3=$?
12995 kill $pid0 $pid1 $pid2 2>/dev/null; wait
12996 if ! echo "$da2" |diff - "${tf}2"; then
12997 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
12998 echo "$CMD0 &"
12999 cat "${te}0"
13000 echo "$CMD1 &"
13001 cat "${te}1"
13002 echo "$CMD2"
13003 cat "${te}2"
13004 numCANT=$((numCANT+1))
13005 listCANT="$listCANT $N"
13006 elif [ $rc3 -ne 0 ]; then
13007 $PRINTF "$FAILED:\n"
13008 echo "$CMD0 &"
13009 cat "${te}0"
13010 echo "$CMD1 &"
13011 cat "${te}1"
13012 echo "$CMD2"
13013 cat "${te}2"
13014 echo "$CMD3"
13015 cat "${te}3"
13016 numFAIL=$((numFAIL+1))
13017 listFAIL="$listFAIL $N"
13018 elif ! echo "$da2" |diff - "${tf}2"; then
13019 $PRINTF "$FAILED:\n"
13020 echo "$CMD0 &"
13021 cat "${te}0"
13022 echo "$CMD1 &"
13023 cat "${te}1"
13024 echo "$CMD2"
13025 cat "${te}2"
13026 echo "$CMD3"
13027 cat "${te}3"
13028 echo "$da2" |diff - "${tf}2"
13029 numFAIL=$((numFAIL+1))
13030 listFAIL="$listFAIL $N"
13031 elif ! echo "$da3" |diff - "${tf}3"; then
13032 $PRINTF "$FAILED:\n"
13033 echo "$CMD0 &"
13034 cat "${te}0"
13035 echo "$CMD1 &"
13036 cat "${te}1"
13037 echo "$CMD2"
13038 cat "${te}2"
13039 echo "$CMD3"
13040 cat "${te}3"
13041 echo "$da3" |diff - "${tf}3"
13042 numFAIL=$((numFAIL+1))
13043 listFAIL="$listFAIL $N"
13044 else
13045 $PRINTF "$OK\n"
13046 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
13047 numOK=$((numOK+1))
13049 fi # NUMCOND, SO_REUSEPORT
13051 esac
13052 N=$((N+1))
13055 # Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped.
13056 NAME=EXEC_NOFORK_UNIDIR
13057 case "$TESTS" in
13058 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*)
13059 TEST="$NAME: Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped"
13060 # invoke a simple echo command with EXEC, nofork, and -u
13061 # expected behaviour: output appears on stdout
13062 if ! eval $NUMCOND; then :; else
13063 tf="$td/test$N.stdout"
13064 te="$td/test$N.stderr"
13065 tdiff="$td/test$N.diff"
13066 da="test$N $(date) $RANDOM"
13067 CMD0="$TRACE $SOCAT $opts -u /dev/null EXEC:\"echo \\\\\\\"\\\"$da\\\"\\\\\\\"\",nofork"
13068 printf "test $F_n $TEST... " $N
13069 eval "$CMD0" >"${tf}0" 2>"${te}0"
13070 rc1=$?
13071 if echo "$da" |diff - "${tf}0" >"$tdiff"; then
13072 $PRINTF "$OK\n"
13073 numOK=$((numOK+1))
13074 else
13075 $PRINTF "$FAILED\n"
13076 echo "$CMD0"
13077 cat "${te}0"
13078 cat "$tdiff"
13079 numFAIL=$((numFAIL+1))
13080 listFAIL="$listFAIL $N"
13082 fi # NUMCOND
13084 esac
13085 N=$((N+1))
13088 # OpenSSL ECDHE ciphers were introduced in socat 1.7.3.0 but in the same release
13089 # they were broken by a porting effort. This test checks if OpenSSL ECDHE works
13090 # 2019-02: this does no longer work (Ubuntu-18.04)
13091 NAME=OPENSSL_ECDHE
13092 case "$TESTS" in
13093 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
13094 TEST="$NAME: test OpenSSL ECDHE"
13095 # generate a ECDHE key, start an OpenSSL server, connect with a client and try to
13096 # pass data
13097 if ! eval $NUMCOND; then :;
13098 elif ! testfeats openssl >/dev/null; then
13099 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13100 numCANT=$((numCANT+1))
13101 listCANT="$listCANT $N"
13102 elif ! openssl ciphers |grep -q '\<ECDHE\>'; then
13103 $PRINTF "test $F_n $TEST... ${YELLOW}openssl: cipher ECDHE not available${NORMAL}\n" $N
13104 numCANT=$((numCANT+1))
13105 listCANT="$listCANT $N"
13106 else
13107 tf="$td/test$N.stdout"
13108 te="$td/test$N.stderr"
13109 tdiff="$td/test$N.diff"
13110 da="test$N $(date) $RANDOM"
13111 #TESTSRV=./testsrvec; gentesteccert $TESTSRV
13112 TESTSRV=./testsrv; gentestcert $TESTSRV
13113 newport tcp4
13114 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=$TESTSRV.crt,key=$TESTSRV.pem,verify=0 PIPE"
13115 CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cipher=ECDHE-ECDSA-AES256-GCM-SHA384,cafile=$TESTSRV.crt,verify=0"
13116 printf "test $F_n $TEST... " $N
13117 $CMD0 >/dev/null 2>"${te}0" &
13118 pid0=$!
13119 waittcp4port $PORT 1
13120 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13121 rc1=$?
13122 kill $pid0 2>/dev/null; wait
13123 if [ $rc1 -ne 0 ]; then
13124 $PRINTF "$FAILED\n"
13125 echo "failure symptom: client error" >&2
13126 echo "server and stderr:" >&2
13127 echo "$CMD0 &"
13128 cat "${te}0"
13129 echo "client and stderr:" >&2
13130 echo "$CMD1"
13131 cat "${te}1"
13132 numFAIL=$((numFAIL+1))
13133 listFAIL="$listFAIL $N"
13134 elif echo "$da" |diff - "${tf}1" >"$tdiff"; then
13135 $PRINTF "$OK\n"
13136 numOK=$((numOK+1))
13137 else
13138 $PRINTF "$FAILED\n"
13139 echo "server and stderr:" >&2
13140 echo "$CMD1"
13141 cat "${te}1"
13142 echo "client and stderr:" >&2
13143 echo "$CMD0 &"
13144 cat "${te}0"
13145 numFAIL=$((numFAIL+1))
13146 listFAIL="$listFAIL $N"
13148 fi # NUMCOND
13150 esac
13151 N=$((N+1))
13154 # option ipv6-join-group "could not be used"
13155 # fixed in 1.7.3.2
13156 NAME=USE_IPV6_JOIN_GROUP
13157 case "$TESTS" in
13158 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip6%*|*%udp%*|*%udp6%*|*%dgram%*|*%multicast%*|*%$NAME%*)
13159 TEST="$NAME: is option ipv6-join-group used"
13160 # Invoke socat with option ipv6-join-group on UDP6 address.
13161 # Terminate immediately, do not transfer data.
13162 # If socat exits with 0 the test succeeds.
13163 # Up to 1.7.3.1 it failed with "1 option(s) could not be used"
13164 if ! eval $NUMCOND; then :; else
13165 tf="$td/test$N.stdout"
13166 te="$td/test$N.stderr"
13167 tdiff="$td/test$N.diff"
13168 da="test$N $(date) $RANDOM"
13169 newport udp6
13170 CMD0="$TRACE $SOCAT $opts UDP6-RECV:$PORT,ipv6-join-group=[ff02::2]:$MCINTERFACE /dev/null"
13171 printf "test $F_n $TEST... " $N
13172 $CMD0 >/dev/null 2>"${te}0"
13173 rc0=$?
13174 if [ $rc0 -eq 0 ]; then
13175 $PRINTF "$OK\n"
13176 numOK=$((numOK+1))
13177 else
13178 $PRINTF "$FAILED\n"
13179 echo "$CMD0"
13180 cat "${te}0"
13181 numFAIL=$((numFAIL+1))
13182 listFAIL="$listFAIL $N"
13184 fi # NUMCOND
13186 esac
13187 N=$((N+1))
13190 # The fix to "Make code async-signal-safe" used internally FD 3 and FD 4.
13191 # Using option fdin=3 did not pass data to executed program.
13192 NAME=DIAG_FDIN
13193 case "$TESTS" in
13194 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*)
13195 TEST="$NAME: test use of fdin=3"
13196 # Use FD 3 explicitely with fdin and test if Socat passes data to executed
13197 # program
13198 if ! eval $NUMCOND; then :; else
13199 tf="$td/test$N.stdout"
13200 te="$td/test$N.stderr"
13201 tdiff="$td/test$N.diff"
13202 da="test$N $(date) $RANDOM"
13203 CMD0="$TRACE $SOCAT $opts - SYSTEM:\"cat >&3 <&4\",fdin=4,fdout=3"
13204 printf "test $F_n $TEST... " $N
13205 echo "$da" |$TRACE $SOCAT $opts - SYSTEM:"cat <&3 >&4",fdin=3,fdout=4 >${tf}0 2>"${te}0"
13206 rc0=$?
13207 if [ $rc0 -ne 0 ]; then
13208 $PRINTF "$FAILED\n"
13209 echo "$CMD0"
13210 cat "${te}0"
13211 numFAIL=$((numFAIL+1))
13212 listFAIL="$listFAIL $N"
13213 elif echo "$da" |diff - ${tf}0 >$tdiff; then
13214 $PRINTF "$OK\n"
13215 numOK=$((numOK+1))
13216 else
13217 $PRINTF "$FAILED\n"
13218 echo "$CMD0"
13219 cat "${te}0"
13220 cat "$tdiff"
13221 numFAIL=$((numFAIL+1))
13222 listFAIL="$listFAIL $N"
13224 fi # NUMCOND
13226 esac
13227 N=$((N+1))
13230 NAME=SOCAT_OPT_HINT
13231 case "$TESTS" in
13232 *%$N%*|*%functions%*|*%$NAME%*)
13233 TEST="$NAME: check if merging single character options is rejected"
13234 if ! eval $NUMCOND; then :; else
13235 te="$td/test$N.stderr"
13236 CMD0="$TRACE $SOCAT $opts -vx FILE:/dev/null ECHO"
13237 printf "test $F_n $TEST... " $N
13238 $CMD0 >/dev/null 2>"${te}0"
13239 rc0=$?
13240 if [ "$rc0" = "1" ]; then
13241 $PRINTF "$OK\n"
13242 numOK=$((numOK+1))
13243 else
13244 $PRINTF "$FAILED\n"
13245 echo "$CMD0" >&2
13246 numFAIL=$((numFAIL+1))
13247 listFAIL="$listFAIL $N"
13249 fi ;; # NUMCOND
13250 esac
13251 N=$((N+1))
13254 # test for a bug in Socat version 1.7.3.3 where
13255 # termios options of the first address were applied to the second address.
13256 NAME=TERMIOS_PH_ALL
13257 case "$TESTS" in
13258 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%termios%*|*%$NAME%*)
13259 TEST="$NAME: are termios options applied to the correct address"
13260 # add a termios option to the first address, a tty, and have a second address
13261 # with pipe. If no error occurs the termios option was not applied to the pipe,
13262 # thus the test succeeded.
13263 if ! eval $NUMCOND; then :; else
13264 tf="$td/test$N.stdout"
13265 te="$td/test$N.stderr"
13266 tdiff="$td/test$N.diff"
13267 da="test$N $(date) $RANDOM"
13268 CMD0="$TRACE $SOCAT $opts -T 1 STDIO,echo=0 EXEC:cat 2>${te}0"
13269 echo "$CMD0" >$td/test$N.sh
13270 chmod a+x $td/test$N.sh
13271 # EXEC need not work with script (musl libc), so use SYSTEM
13272 CMD1="$TRACE $SOCAT $opts /dev/null SYSTEM:$td/test$N.sh,pty,$PTYOPTS"
13273 printf "test $F_n $TEST... " $N
13274 $CMD1 2>"${te}1"
13275 rc0=$?
13276 if [ $rc0 -eq 0 ]; then
13277 $PRINTF "$OK\n"
13278 numOK=$((numOK+1))
13279 else
13280 $PRINTF "$FAILED\n"
13281 echo "$CMD0"
13282 cat "${te}0"
13283 echo "$CMD1"
13284 cat "${te}1"
13285 numFAIL=$((numFAIL+1))
13286 listFAIL="$listFAIL $N"
13288 fi # NUMCOND
13290 esac
13291 N=$((N+1))
13294 # Due to a fallback logic before calling getaddrinfo(), intended to allow use
13295 # of service (port) names with SCTP, raw socket addresses where resolved with
13296 # socket type stream, which fails for protocol 6 (TCP)
13297 # Fixed after 1.7.3.3
13298 NAME=IP_SENDTO_6
13299 case "$TESTS" in
13300 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%rawip%*|*%rawip4%*|*%$NAME%*)
13301 TEST="$NAME: IP-SENDTO::6 passes getaddrinfo()"
13302 # invoke socat with address IP-SENDTO:*:6; when this does not fail with
13303 # "ai_socktype not supported", the test succeeded
13304 if ! eval $NUMCOND; then :; else
13305 tf="$td/test$N.stdout"
13306 te="$td/test$N.stderr"
13307 tdiff="$td/test$N.diff"
13308 CMD0="$TRACE $SOCAT $opts -u /dev/null IP-SENDTO:127.0.0.1:6"
13309 printf "test $F_n $TEST... " $N
13310 $CMD0 >/dev/null 2>"${te}0"
13311 if ! grep -q "ai_socktype not supported" ${te}0; then
13312 $PRINTF "$OK\n"
13313 numOK=$((numOK+1))
13314 else
13315 $PRINTF "$FAILED\n"
13316 echo "$CMD0"
13317 cat "${te}0"
13318 numFAIL=$((numFAIL+1))
13319 listFAIL="$listFAIL $N"
13321 fi # NUMCOND
13323 esac
13324 N=$((N+1))
13327 # test if the multiple EOF messages are fixed
13328 NAME=MULTIPLE_EOF
13329 case "$TESTS" in
13330 *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
13331 TEST="$NAME: multiple EOF messages"
13332 # 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
13333 if ! eval $NUMCOND; then :; else
13334 ts="$td/test$N.sock"
13335 tf="$td/test$N.stdout"
13336 te="$td/test$N.stderr"
13337 tdiff="$td/test$N.diff"
13338 da="test$N $(date) $RANDOM"
13339 CMD0="$TRACE $SOCAT $opts -d -d UNIX-LISTEN:$ts /dev/null"
13340 CMD1="$TRACE $SOCAT $opts -d -d - UNIX-CONNECT:$ts"
13341 printf "test $F_n $TEST... " $N
13342 $CMD0 >/dev/null 2>"${te}0" &
13343 pid0=$!
13344 waitunixport $ts 1
13345 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13346 rc1=$?
13347 kill $pid0 2>/dev/null; wait
13348 if [ $(grep "socket 2 (fd .*) is at EOF" ${te}0 |wc -l) -eq 1 ]; then
13349 $PRINTF "$OK\n"
13350 numOK=$((numOK+1))
13351 else
13352 $PRINTF "$FAILED\n"
13353 echo "$CMD0 &"
13354 echo "$CMD1"
13355 cat "${te}0"
13356 cat "${te}1"
13357 numFAIL=$((numFAIL+1))
13358 listFAIL="$listFAIL $N"
13360 fi # NUMCOND
13362 esac
13363 N=$((N+1))
13366 # Test for integer overflow with data transfer block size parameter
13367 NAME=BLKSIZE_INT_OVERFL
13368 case "$TESTS" in
13369 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%$NAME%*)
13370 TEST="$NAME: integer overflow with buffer size parameter"
13371 # Use a buffer size that would lead to integer overflow
13372 # Test succeeds when Socat terminates with correct error message
13373 if ! eval $NUMCOND; then :; else
13374 tf="$td/test$N.stdout"
13375 te="$td/test$N.stderr"
13376 tdiff="$td/test$N.diff"
13377 dat="$td/test$N.dat"
13378 # calculate the minimal length with integer overflow
13379 case $SIZE_T in
13380 2) CHKSIZE=32768 ;;
13381 4) CHKSIZE=2147483648 ;;
13382 8) CHKSIZE=9223372036854775808 ;;
13383 16) CHKSIZE=170141183460469231731687303715884105728 ;;
13384 *) echo "Unsupported SIZE_T=\"$SIZE_T\"" >2 ;;
13385 esac
13386 CMD0="$TRACE $SOCAT $opts -T 1 -b $CHKSIZE /dev/null PIPE"
13387 printf "test $F_n $TEST... " $N
13388 $CMD0 >/dev/null 2>"${te}0"
13389 rc0=$?
13390 if [ $rc0 -eq 0 ]; then
13391 $PRINTF "$FAILED (rc=$rc0)\n"
13392 echo "$CMD0"
13393 cat "${te}0"
13394 numFAIL=$((numFAIL+1))
13395 listFAIL="$listFAIL $N"
13396 elif [ $rc0 -eq 1 ]; then
13397 if grep -q "buffer size option (-b) to big" "${te}0"; then
13398 $PRINTF "$OK\n"
13399 numOK=$((numOK+1))
13400 else
13401 $PRINTF "$FAILED (rc=$rc0)\n"
13402 echo "$CMD0"
13403 cat "${te}0"
13404 numFAIL=$((numFAIL+1))
13405 listFAIL="$listFAIL $N"
13408 fi # NUMCOND
13410 esac
13411 N=$((N+1))
13413 # Test if unbalanced quoting in Socat addresses is detected
13414 NAME=UNBALANCED_QUOTE
13415 case "$TESTS" in
13416 *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*)
13417 TEST="$NAME: Test fix of unbalanced quoting"
13418 # Invoke Socat with an address containing unbalanced quoting. If Socat prints
13419 # a "syntax error" message, the test succeeds
13420 if ! eval $NUMCOND; then :; else
13421 tf="$td/test$N.stdout"
13422 te="$td/test$N.stderr"
13423 tdiff="$td/test$N.diff"
13424 da="test$N $(date) $RANDOM"
13425 CMD0="$TRACE $SOCAT $opts -u FILE:$td/ab\"cd FILE:/dev/null"
13426 printf "test $F_n $TEST... " $N
13427 $CMD0 >/dev/null 2>"${te}0"
13428 if grep -q -i -e "syntax error" -e "unexpected end" "${te}0"; then
13429 $PRINTF "$OK\n"
13430 if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi
13431 if [ "$debug" ]; then cat ${te} >&2; fi
13432 numOK=$((numOK+1))
13433 else
13434 $PRINTF "$FAILED\n"
13435 echo "$CMD0"
13436 cat "${te}0"
13437 numFAIL=$((numFAIL+1))
13438 listFAIL="$listFAIL $N"
13440 fi # NUMCOND
13442 esac
13443 N=$((N+1))
13446 # Currently (2020) SCTP has not found its way into main distributions
13447 # /etc/services file. A fallback mechanism has been implemented in Socat
13448 # that allows use of TCP service names when service resolution for SCTP failed.
13449 # Furthermore, older getaddrinfo() implementations to not handle SCTP as SOCK_STREAM
13450 # at all, fall back to unspecified socktype then.
13451 NAME=SCTP_SERVICENAME
13452 case "$TESTS" in
13453 *%$N%*|*%functions%*|*%socket%*|*%sctp%*|*%$NAME%*)
13454 TEST="$NAME: Service name resolution works with SCTP"
13455 # invoke socat with address SCTP4-CONNECT:$LOCALHOST:http; when this fails with
13456 # "Connection refused", or does not fail at all, the test succeeded
13457 if ! eval $NUMCOND; then :;
13458 elif ! runssctp4 >/dev/null; then
13459 $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
13460 numCANT=$((numCANT+1))
13461 listCANT="$listCANT $N"
13462 else
13463 tf="$td/test$N.stdout"
13464 te="$td/test$N.stderr"
13465 tdiff="$td/test$N.diff"
13466 CMD0="$TRACE $SOCAT $opts -u /dev/null SCTP4-CONNECT:$LOCALHOST:http"
13467 printf "test $F_n $TEST... " $N
13468 $CMD0 >/dev/null 2>"${te}0"
13469 if [ $? -eq 0 ]; then
13470 $PRINTF "$OK\n"
13471 numOK=$((numOK+1))
13472 elif grep -q "Connection refused" ${te}0; then
13473 $PRINTF "$OK\n"
13474 numOK=$((numOK+1))
13475 else
13476 $PRINTF "$FAILED\n"
13477 echo "$CMD0"
13478 cat "${te}0"
13479 numFAIL=$((numFAIL+1))
13480 listFAIL="$listFAIL $N"
13482 fi # NUMCOND
13484 esac
13485 N=$((N+1))
13488 # Test the o-direct option on reading
13489 NAME=O_DIRECT
13490 case "$TESTS" in
13491 *%$N%*|*%functions%*|*%engine%*|*%file%*|*%$NAME%*)
13492 TEST="$NAME: echo via file with o-direct"
13493 # Write data to a file and read it with options o-direct (and ignoreeof)
13494 # When the data read is the same as the data written the test succeeded.
13495 if ! eval $NUMCOND; then :;
13496 elif ! testoptions o-direct >/dev/null; then
13497 $PRINTF "test $F_n $TEST... ${YELLOW}o-direct not available${NORMAL}\n" $N
13498 numCANT=$((numCANT+1))
13499 listCANT="$listCANT $N"
13500 else
13501 tf="$td/test$N.file"
13502 to="$td/test$N.stdout"
13503 te="$td/test$N.stderr"
13504 tdiff="$td/test$N.diff"
13505 da="test$N $(date) $RANDOM"
13506 $PRINTF "test $F_n $TEST... " $N
13507 CMD="$TRACE $SOCAT $opts - $tf,o-direct,ignoreeof!!$tf"
13508 echo "$da" |$CMD >"$to" 2>"$te"
13509 rc=$?
13510 if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then
13511 case $(stat -f $tf |grep "Type: [^[:space:]]*" |sed -e 's/.*\(Type: [^[:space:]]*\).*/\1/' |cut -c 7-) in
13512 #case $(stat -f $tf |grep -o "Type: [^[:space:]]*" |cut -c 7-) in
13513 ext2/ext3|xfs|reiserfs)
13514 $PRINTF "${FAILED}\n"
13515 echo "$CMD" >&2
13516 cat "$te" >&2
13517 numFAIL=$((numFAIL+1))
13518 listFAIL="$listFAIL $N" ;;
13519 *) $PRINTF "${YELLOW}inable file system${NORMAL}\n"
13520 numCANT=$((numCANT+1))
13521 listCANT="$listCANT $N" ;;
13522 esac
13523 elif [ $rc -ne 0 ]; then
13524 $PRINTF "${FAILED}:\n"
13525 echo "$CMD" >&2
13526 cat "$te" >&2
13527 numFAIL=$((numFAIL+1))
13528 listFAIL="$listFAIL $N"
13529 elif ! echo "$da" |diff - "$to" >$tdiff; then
13530 $PRINTF "${FAILED}\n"
13531 echo "$CMD" >&2
13532 cat "$te" >&2
13533 cat "$tdiff" >&2
13534 numFAIL=$((numFAIL+1))
13535 listFAIL="$listFAIL $N"
13536 else
13537 $PRINTF "$OK\n"
13538 numOK=$((numOK+1))
13539 fi # command ok
13540 fi ;; # NUMCOND, feats
13541 esac
13542 N=$((N+1))
13545 # test if option unlink-close removes the bind socket file
13546 NAME=UNIX_SENDTO_UNLINK
13547 case "$TESTS" in
13548 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%$NAME%*)
13549 TEST="$NAME: Option unlink-close with UNIX sendto socket"
13550 # Have a recv socket with option unlink-close=0
13551 # and a sendto socket with option unlink-close=1
13552 # Expected beavior: the recv socket is kept, the
13553 # sendto/bind socket is removed
13554 if ! eval $NUMCOND; then :; else
13555 tf="$td/test$N.stdout"
13556 te="$td/test$N.stderr"
13557 uns="$td/test$N.server"
13558 unc="$td/test$N.client"
13559 tdiff="$td/test$N.diff"
13560 da="test$N $(date) $RANDOM"
13561 CMD0="$TRACE $SOCAT $opts -u UNIX-RECV:$uns,unlink-close=0 GOPEN:$tf"
13562 CMD1="$TRACE $SOCAT $opts - UNIX-SENDTO:$uns,bind=$unc,unlink-close=1"
13563 printf "test $F_n $TEST... " $N
13564 $CMD0 >/dev/null 2>"${te}0" &
13565 pid0=$!
13566 waitunixport $uns 1
13567 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13568 rc1=$?
13569 kill $pid0 2>/dev/null; wait
13570 if test -S $uns && ! test -S $unc; then
13571 $PRINTF "$OK\n"
13572 numOK=$((numOK+1))
13573 else
13574 $PRINTF "$FAILED\n"
13575 echo "$CMD0 &"
13576 echo "$CMD1"
13577 ls -ld $uns $unc
13578 cat "${te}0"
13579 cat "${te}1"
13580 numFAIL=$((numFAIL+1))
13581 listFAIL="$listFAIL $N"
13583 fi # NUMCOND
13585 esac
13586 N=$((N+1))
13588 # test if option unlink-close removes the bind socket file
13589 NAME=UNIX_CONNECT_UNLINK
13590 case "$TESTS" in
13591 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%listen%*|*%$NAME%*)
13592 TEST="$NAME: Option unlink-close with UNIX connect socket"
13593 # Have a listen socket with option unlink-close=0
13594 # and a connect socket with option unlink-close=1
13595 # Expected beavior: the listen socket entry is kept, the
13596 # connect/bind socket is removed
13597 if ! eval $NUMCOND; then :; else
13598 tf="$td/test$N.stdout"
13599 te="$td/test$N.stderr"
13600 uns="$td/test$N.server"
13601 unc="$td/test$N.client"
13602 tdiff="$td/test$N.diff"
13603 da="test$N $(date) $RANDOM"
13604 CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$uns,unlink-close=0 GOPEN:$tf"
13605 CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$uns,bind=$unc,unlink-close=1"
13606 printf "test $F_n $TEST... " $N
13607 $CMD0 >/dev/null 2>"${te}0" &
13608 pid0=$!
13609 waitunixport $uns 1
13610 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13611 rc1=$?
13612 kill $pid0 2>/dev/null; wait
13613 if test -S $uns && ! test -S $unc; then
13614 $PRINTF "$OK\n"
13615 numOK=$((numOK+1))
13616 else
13617 $PRINTF "$FAILED\n"
13618 echo "$CMD0 &"
13619 echo "$CMD1"
13620 ls -ld $uns $unc
13621 cat "${te}0"
13622 cat "${te}1"
13623 numFAIL=$((numFAIL+1))
13624 listFAIL="$listFAIL $N"
13626 fi # NUMCOND
13628 esac
13629 N=$((N+1))
13632 # test the DTLS client feature
13633 NAME=OPENSSL_DTLS_CLIENT
13634 case "$TESTS" in
13635 *%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%$NAME%*)
13636 TEST="$NAME: OpenSSL DTLS client"
13637 # Run openssl s_server in DTLS mode, wrapped into a simple Socat echoing command.
13638 # Start a Socat DTLS client, send data to server and check if reply is received.
13639 if ! eval $NUMCOND; then :;
13640 elif ! a=$(testfeats ip4 udp openssl); then
13641 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available${NORMAL}\n" $N
13642 numCANT=$((numCANT+1))
13643 listCANT="$listCANT $N"
13644 elif ! a=$(testaddrs openssl-dtls-client); then
13645 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
13646 numCANT=$((numCANT+1))
13647 listCANT="$listCANT $N"
13648 elif ! runsip4 >/dev/null; then
13649 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
13650 numCANT=$((numCANT+1))
13651 listCANT="$listCANT $N"
13652 elif ! type openssl >/dev/null 2>&1; then
13653 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
13654 numCANT=$((numCANT+1))
13655 listCANT="$listCANT $N"
13656 else
13657 gentestcert testsrv
13658 tf="$td/test$N.stdout"
13659 te="$td/test$N.stderr"
13660 tdiff="$td/test$N.diff"
13661 #set -vx
13662 da="test$N $(date) $RANDOM"
13663 init_openssl_s_server
13664 newport udp4
13665 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"
13666 CMD="$TRACE $SOCAT $opts -T 3 - OPENSSL-DTLS-CLIENT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
13667 printf "test $F_n $TEST... " $N
13668 ( sleep 2; echo "$da"; sleep 1 ) |$CMD1 2>"${te}1" &
13669 pid1=$! # background process id
13670 waitudp4port $PORT
13671 $CMD >$tf 2>"$te"
13672 kill $pid1 2>/dev/null; wait 2>/dev/null
13673 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
13674 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
13675 echo "$CMD1 &"
13676 cat "${te}1"
13677 echo "$CMD"
13678 cat "$te"
13679 cat "$tdiff"
13680 numFAIL=$((numFAIL+1))
13681 listFAIL="$listFAIL $N"
13682 else
13683 $PRINTF "$OK\n"
13684 if [ -n "$debug" ]; then cat "${te}1" "$te"; fi
13685 numOK=$((numOK+1))
13687 fi ;; # NUMCOND, feats
13688 esac
13689 N=$((N+1))
13691 # test the DTLS server feature
13692 NAME=OPENSSL_DTLS_SERVER
13693 case "$TESTS" in
13694 *%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%socket%*|*%$NAME%*)
13695 TEST="$NAME: OpenSSL DTLS server"
13696 # Run a socat OpenSSL DTLS server with echo function
13697 # Start an OpenSSL s_client, send data and check if repley is received.
13698 if ! eval $NUMCOND; then :;
13699 elif ! a=$(testfeats ip4 udp openssl) >/dev/null; then
13700 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
13701 numCANT=$((numCANT+1))
13702 listCANT="$listCANT $N"
13703 elif ! a=$(testaddrs openssl-dtls-server); then
13704 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
13705 numCANT=$((numCANT+1))
13706 listCANT="$listCANT $N"
13707 elif ! runsip4 >/dev/null; then
13708 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
13709 numCANT=$((numCANT+1))
13710 listCANT="$listCANT $N"
13711 elif ! type openssl >/dev/null 2>&1; then
13712 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
13713 numCANT=$((numCANT+1))
13714 listCANT="$listCANT $N"
13715 elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then
13716 $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
13717 numCANT=$((numCANT+1))
13718 listCANT="$listCANT $N"
13719 else
13720 gentestcert testsrv
13721 tf="$td/test$N.stdout"
13722 te="$td/test$N.stderr"
13723 tdiff="$td/test$N.diff"
13724 da="test$N $(date) $RANDOM"
13725 init_openssl_s_client
13726 newport udp4
13727 CMD1="$TRACE $SOCAT $opts OPENSSL-DTLS-SERVER:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
13728 CMD="openssl s_client $OPENSSL_S_CLIENT_4 -host $LOCALHOST -port $PORT $OPENSSL_S_CLIENT_DTLS"
13729 printf "test $F_n $TEST... " $N
13730 $CMD1 >/dev/null 2>"${te}1" &
13731 pid1=$!
13732 waitudp4port $PORT 1
13733 ( echo "$da"; psleep 0.1 ) |$CMD 2>"$te" |grep "$da" >"$tf"
13734 rc=$?
13735 kill $pid1 2>/dev/null; wait
13736 if echo "$da" |diff - $tf >"$tdiff"; then
13737 $PRINTF "$OK\n"
13738 numOK=$((numOK+1))
13739 else
13740 $PRINTF "$FAILED\n"
13741 echo "$CMD1 &"
13742 cat "${te}1"
13743 echo "$CMD"
13744 cat "$te"
13745 cat "$tdiff"
13746 numFAIL=$((numFAIL+1))
13747 listFAIL="$listFAIL $N"
13749 fi # NUMCOND
13751 esac
13752 N=$((N+1))
13755 NAME=OPENSSL_SERVERALTAUTH
13756 case "$TESTS" in
13757 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
13758 TEST="$NAME: OpenSSL server authentication with SubjectAltName (hostname)"
13759 if ! eval $NUMCOND; then :;
13760 elif ! testfeats openssl >/dev/null; then
13761 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13762 numCANT=$((numCANT+1))
13763 listCANT="$listCANT $N"
13764 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
13765 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
13766 numCANT=$((numCANT+1))
13767 listCANT="$listCANT $N"
13768 else
13769 gentestaltcert testalt
13770 tf="$td/test$N.stdout"
13771 te="$td/test$N.stderr"
13772 tdiff="$td/test$N.diff"
13773 da="test$N $(date) $RANDOM"
13774 newport tcp4
13775 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe"
13776 CMD1="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=1,cafile=testalt.crt,$SOCAT_EGD"
13777 printf "test $F_n $TEST... " $N
13778 eval "$CMD0 2>\"${te}0\" &"
13779 pid=$! # background process id
13780 waittcp4port $PORT
13781 echo "$da" |$CMD1 >$tf 2>"${te}1"
13782 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
13783 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
13784 echo "$CMD0 &" >&2
13785 cat "${te}0" >&2
13786 echo "$CMD1" >&2
13787 cat "${te}1" >&2
13788 cat "$tdiff" >&2
13789 numFAIL=$((numFAIL+1))
13790 listFAIL="$listFAIL $N"
13791 else
13792 $PRINTF "$OK\n"
13793 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
13794 numOK=$((numOK+1))
13796 kill $pid 2>/dev/null
13797 wait
13798 fi ;; # NUMCOND, feats
13799 esac
13800 N=$((N+1))
13802 NAME=OPENSSL_SERVERALTIP4AUTH
13803 case "$TESTS" in
13804 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
13805 TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv4 address)"
13806 if ! eval $NUMCOND; then :;
13807 elif ! testfeats openssl >/dev/null; then
13808 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13809 numCANT=$((numCANT+1))
13810 listCANT="$listCANT $N"
13811 elif ! testfeats listen tcp ip4 openssl >/dev/null || ! runsip4 >/dev/null; then
13812 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
13813 numCANT=$((numCANT+1))
13814 listCANT="$listCANT $N"
13815 else
13816 gentestaltcert testalt
13817 tf="$td/test$N.stdout"
13818 te="$td/test$N.stderr"
13819 tdiff="$td/test$N.diff"
13820 da="test$N $(date) $RANDOM"
13821 newport tcp4
13822 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,pf=ip4,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe"
13823 CMD1="$TRACE $SOCAT $opts - OPENSSL:127.0.0.1:$PORT,verify=1,cafile=testalt.crt,$SOCAT_EGD"
13824 printf "test $F_n $TEST... " $N
13825 eval "$CMD0 2>\"${te}0\" &"
13826 pid=$! # background process id
13827 waittcp4port $PORT
13828 echo "$da" |$CMD1 >$tf 2>"${te}1"
13829 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
13830 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
13831 echo "$CMD0 &" >&2
13832 cat "${te}0" >&2
13833 echo "$CMD1" >&2
13834 cat "${te}1" >&2
13835 cat "$tdiff" >&2
13836 numFAIL=$((numFAIL+1))
13837 listFAIL="$listFAIL $N"
13838 else
13839 $PRINTF "$OK\n"
13840 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
13841 numOK=$((numOK+1))
13843 kill $pid 2>/dev/null
13844 wait
13845 fi ;; # NUMCOND, feats
13846 esac
13847 N=$((N+1))
13849 NAME=OPENSSL_SERVERALTIP6AUTH
13850 case "$TESTS" in
13851 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
13852 TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv6 address)"
13853 if ! eval $NUMCOND; then :;
13854 elif ! testfeats openssl >/dev/null; then
13855 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13856 numCANT=$((numCANT+1))
13857 listCANT="$listCANT $N"
13858 elif ! testfeats listen tcp ip6 openssl >/dev/null || ! runsip6 >/dev/null; then
13859 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
13860 numCANT=$((numCANT+1))
13861 listCANT="$listCANT $N"
13862 else
13863 gentestaltcert testalt
13864 tf="$td/test$N.stdout"
13865 te="$td/test$N.stderr"
13866 tdiff="$td/test$N.diff"
13867 da="test$N $(date) $RANDOM"
13868 newport tcp6
13869 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe"
13870 CMD1="$TRACE $SOCAT $opts - OPENSSL:[::1]:$PORT,verify=1,cafile=testalt.crt,$SOCAT_EGD"
13871 printf "test $F_n $TEST... " $N
13872 eval "$CMD0 2>\"${te}0\" &"
13873 pid=$! # background process id
13874 waittcp6port $PORT
13875 echo "$da" |$CMD1 >$tf 2>"${te}1"
13876 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
13877 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
13878 echo "$CMD0 &" >&2
13879 cat "${te}0" >&2
13880 echo "$CMD1" >&2
13881 cat "${te}1" >&2
13882 cat "$tdiff" >&2
13883 numFAIL=$((numFAIL+1))
13884 listFAIL="$listFAIL $N"
13885 else
13886 $PRINTF "$OK\n"
13887 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
13888 numOK=$((numOK+1))
13890 kill $pid 2>/dev/null
13891 wait
13892 fi ;; # NUMCOND, feats
13893 esac
13894 N=$((N+1))
13897 # Test the -r and -R options
13898 NAME=OPTION_RAW_DUMP
13899 case "$TESTS" in
13900 *%$N%*|*%functions%*|*%option%*|*%$NAME%*)
13901 TEST="$NAME: raw dump of transferred data"
13902 # Start Socat transferring data from left named pipe to right and from right
13903 # pipe to left, use options -r and -R, and check if dump files contain correct
13904 # data
13905 if ! eval $NUMCOND; then :;
13906 elif [ $($SOCAT -h |grep -e ' -[rR] ' |wc -l) -lt 2 ]; then
13907 $PRINTF "test $F_n $TEST... ${YELLOW}Options -r, -R not available${NORMAL}\n" $N
13908 numCANT=$((numCANT+1))
13909 listCANT="$listCANT $N"
13910 else
13911 tf="$td/test$N.stdout"
13912 te="$td/test$N.stderr"
13913 tp1="$td/test$N.pipe1"
13914 tp2="$td/test$N.pipe2"
13915 tr1="$td/test$N.raw1"
13916 tr2="$td/test$N.raw2"
13917 tdiff1="$td/test$N.diff1"
13918 tdiff2="$td/test$N.diff2"
13919 da1="test$N $(date) $RANDOM"
13920 da2="test$N $(date) $RANDOM"
13921 CMD0="$TRACE $SOCAT $opts -r $tr1 -R $tr2 PIPE:$tp1!!/dev/null PIPE:$tp2!!/dev/null"
13922 printf "test $F_n $TEST... " $N
13923 $CMD0 >/dev/null 2>"${te}0" &
13924 pid0=$!
13925 waitfile $tp1 1
13926 echo "$da1" >$tp1
13927 waitfile $tp2 1
13928 echo "$da2" >$tp2
13929 sleep 1
13930 kill $pid0 2>/dev/null; wait
13931 if ! echo "$da1" |diff - $tr1 >$tdiff1 || ! echo "$da2" |diff - $tr2 >$tdiff2; then
13932 $PRINTF "$FAILED\n"
13933 echo "$CMD0 &" >&2
13934 cat "${te}0" >&2
13935 echo "Left-to-right:" >&2
13936 cat $tdiff1 >&2
13937 echo "Right-to-left:" >&2
13938 cat $tdiff2 >&2
13939 numFAIL=$((numFAIL+1))
13940 listFAIL="$listFAIL $N"
13941 else
13942 $PRINTF "$OK\n"
13943 numOK=$((numOK+1))
13945 fi # NUMCOND
13947 esac
13948 N=$((N+1))
13951 # Test the OpenSSL SNI feature
13952 NAME=OPENSSL_SNI
13953 case "$TESTS" in
13954 *%$N%*|*%functions%*|*%socket%*|*%openssl%*|*%internet%*|*%listen%*|*%$NAME%*)
13955 TEST="$NAME: Test the OpenSSL SNI feature"
13956 # Connect to a server that is known to use SNI. Use an SNI name, not the
13957 # certifications default name. When the TLS connection is established
13958 # the test succeeded.
13959 SNISERVER=badssl.com
13960 if ! eval $NUMCOND; then :;
13961 elif ! testaddrs openssl >/dev/null; then
13962 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13963 numCANT=$((numCANT+1))
13964 listCANT="$listCANT $N"
13965 elif ! feat=$(testoptions openssl-snihost); then
13966 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
13967 numCANT=$((numCANT+1))
13968 listCANT="$listCANT $N"
13969 elif [ -z "$INTERNET" ]; then
13970 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
13971 numCANT=$((numCANT+1))
13972 listCANT="$listCANT $N"
13973 else
13974 tf="$td/test$N.stdout"
13975 te="$td/test$N.stderr"
13976 tdiff="$td/test$N.diff"
13977 da="test$N $(date) $RANDOM"
13978 CMD0="$TRACE $SOCAT $opts FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,pf=ip4"
13979 printf "test $F_n $TEST... " $N
13980 $CMD0 >/dev/null 2>"${te}0"
13981 rc0=$?
13982 if [ $rc0 -eq 0 ]; then
13983 $PRINTF "$OK\n"
13984 numOK=$((numOK+1))
13985 else
13986 $PRINTF "$FAILED\n"
13987 echo "$CMD0" >&2
13988 cat "${te}0" >&2
13989 numFAIL=$((numFAIL+1))
13990 listFAIL="$listFAIL $N"
13992 fi # NUMCOND
13994 esac
13995 N=$((N+1))
13998 # Test the openssl-no-sni option
13999 NAME=OPENSSL_NO_SNI
14000 case "$TESTS" in
14001 *%$N%*|*%functions%*|*%socket%*|*%openssl%*|*%internet%*|*%listen%*|*%$NAME%*)
14002 TEST="$NAME: Test the openssl-no-sni option"
14003 # Connect to a server that is known to use SNI. Use an SNI name, not the
14004 # certifications default name, and use option openssl-no-sni.
14005 # When the TLS connection failed the test succeeded.
14006 # Please note that this test is only relevant when test OPENSSL_SNI succeeded.
14007 SNISERVER=badssl.com
14008 if ! eval $NUMCOND; then :;
14009 elif ! testaddrs openssl >/dev/null; then
14010 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14011 numCANT=$((numCANT+1))
14012 listCANT="$listCANT $N"
14013 elif ! feat=$(testoptions openssl-no-sni); then
14014 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
14015 numCANT=$((numCANT+1))
14016 listCANT="$listCANT $N"
14017 elif [ -z "$INTERNET" ]; then
14018 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
14019 numCANT=$((numCANT+1))
14020 listCANT="$listCANT $N"
14021 else
14022 tf="$td/test$N.stdout"
14023 te="$td/test$N.stderr"
14024 tdiff="$td/test$N.diff"
14025 da="test$N $(date) $RANDOM"
14026 CMD0="$TRACE $SOCAT $opts FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,openssl-no-sni"
14027 printf "test $F_n $TEST... " $N
14028 $CMD0 >/dev/null 2>"${te}0"
14029 rc0=$?
14030 if [ $rc0 -ne 0 ]; then
14031 $PRINTF "$OK\n"
14032 numOK=$((numOK+1))
14033 else
14034 $PRINTF "$FAILED\n"
14035 echo "$CMD0" >&2
14036 cat "${te}0" >&2
14037 numFAIL=$((numFAIL+1))
14038 listFAIL="$listFAIL $N"
14040 fi # NUMCOND
14042 esac
14043 N=$((N+1))
14046 # Test the accept-timeout (listen-timeout) address option
14047 NAME=ACCEPTTIMEOUT
14048 case "$TESTS" in
14049 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%timeout%*|*%$NAME%*)
14050 TEST="$NAME: test the accept-timeout option"
14051 if ! eval $NUMCOND; then :;
14052 elif ! feat=$(testaddrs tcp); then
14053 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
14054 numCANT=$((numCANT+1))
14055 listCANT="$listCANT $N"
14056 elif ! feat=$(testoptions accept-timeout); then
14057 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
14058 numCANT=$((numCANT+1))
14059 listCANT="$listCANT $N"
14060 else
14061 # Just start a process with accept-timeout 1s and check if it still runs 2s later
14062 # but before this, we test if the process waits at all
14063 te1="$td/test$N.stderr1"
14064 tk1="$td/test$N.kill1"
14065 te2="$td/test$N.stderr2"
14066 tk2="$td/test$N.kill2"
14067 $PRINTF "test $F_n $TEST... " $N
14068 # First, try to make socat hang and see if it can be killed
14069 newport tcp4
14070 CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr PIPE"
14071 $CMD1 >"$te1" 2>&1 </dev/null &
14072 pid1=$!
14073 sleep 1
14074 if ! kill $pid1 2>"$tk1"; then
14075 $PRINTF "${YELLOW}does not hang${NORMAL}\n"
14076 echo $CMD1 >&2
14077 cat "$te1" >&2
14078 cat "$tk1" >&2
14079 numCANT=$((numCANT+1))
14080 listCANT="$listCANT $N"
14081 else
14082 # Second, set accept-timeout and see if socat exits before kill
14083 CMD2="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,accept-timeout=1 PIPE"
14084 $CMD2 >"$te2" 2>&1 </dev/null &
14085 pid2=$!
14086 sleep 2
14087 if kill $pid2 2>"$tk2"; then
14088 $PRINTF "$FAILED\n"
14089 echo "$CMD2" >&2
14090 cat "$te2" >&2
14091 cat "$tk2" >&2
14092 numFAIL=$((numFAIL+1))
14093 listFAIL="$listFAIL $N"
14094 else
14095 $PRINTF "$OK\n"
14096 numOK=$((numOK+1))
14099 wait
14100 fi ;; # testaddrs, NUMCOND
14101 esac
14102 N=$((N+1))
14105 # Test the modified UDP-DATAGRAM address: Now it ignores peerport by default
14106 NAME=UDP_DATAGRAM_PEERPORT
14107 case "$TESTS" in
14108 *%$N%*|*%functions%*|*%udp%*|*%socket%*|*%$NAME%*)
14109 TEST="$NAME: test UDP-DATAGRAM ignoring peerport"
14110 # A UDP-DATAGRAM address bound to PORT has defined peer on PORT+1
14111 # From another Socat instance we send a packet to PORT but with source port
14112 # PORT+2. The first instance should accept the packet
14113 if ! eval $NUMCOND; then :
14114 elif [ $(echo $E "$SOCAT_VERSION\n1.7.3.4" |sort -n |tail -n 1) = 1.7.3.4 ]; then
14115 $PRINTF "test $F_n $TEST... ${YELLOW}Only with Socat 1.7.4.0 or higher${NORMAL}\n" $N
14116 numCANT=$((numCANT+1))
14117 listCANT="$listCANT $N"
14118 else
14119 tf="$td/test$N.stdout"
14120 te="$td/test$N.stderr"
14121 tdiff="$td/test$N.diff"
14122 da="test$N $(date) $RANDOM"
14123 newport udp4; PORT1=$PORT
14124 newport udp4; PORT2=$PORT
14125 newport udp4; PORT3=$PORT
14126 CMD0="$TRACE $SOCAT $opts -u UDP-DATAGRAM:$LOCALHOST:$PORT2,bind=:$PORT1 -"
14127 CMD1="$TRACE $SOCAT $opts -u - UDP-DATAGRAM:$LOCALHOST:$PORT1,bind=:$PORT3"
14128 printf "test $F_n $TEST... " $N
14129 $CMD0 >${tf}0 2>"${te}0" &
14130 pid0=$!
14131 waitudp4port $PORT1 1
14132 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14133 rc1=$?
14134 psleep 0.1
14135 kill $pid0 2>/dev/null; wait
14136 if [ -f ${tf}0 ] && echo "$da" |diff - ${tf}0 >$tdiff; then
14137 $PRINTF "$OK\n"
14138 numOK=$((numOK+1))
14139 else
14140 $PRINTF "$FAILED\n"
14141 echo "$CMD0 &" >&2
14142 cat "${te}0" >&2
14143 echo "$CMD1" >&2
14144 cat "${te}1" >&2
14145 cat "${tdiff}" >&2
14146 numFAIL=$((numFAIL+1))
14147 listFAIL="$listFAIL $N"
14149 fi # NUMCOND
14151 esac
14152 N=$((N+1))
14155 # Test the proxy-authorization-file option
14156 NAME=PROXYAUTHFILE
14157 case "$TESTS" in
14158 *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
14159 TEST="$NAME: proxy-authorization-file option"
14160 if ! eval $NUMCOND; then :;
14161 elif ! testfeats proxy >/dev/null; then
14162 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
14163 numCANT=$((numCANT+1))
14164 listCANT="$listCANT $N"
14165 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
14166 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
14167 numCANT=$((numCANT+1))
14168 listCANT="$listCANT $N"
14169 elif ! testoptions proxy-authorization-file >/dev/null; then
14170 $PRINTF "test $F_n $TEST... ${YELLOW}Option proxy-authorization-file not available${NORMAL}\n" $N
14171 numCANT=$((numCANT+1))
14172 listCANT="$listCANT $N"
14173 else
14174 ta="$td/test$N.auth"
14175 tf="$td/test$N.stdout"
14176 te="$td/test$N.stderr"
14177 tdiff="$td/test$N.diff"
14178 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
14179 newport tcp4
14180 CMD0="{ echo -e \"HTTP/1.0 200 OK\\n\"; sleep 2; } |$TRACE $SOCAT $opts - TCP4-L:$PORT,$REUSEADDR,crlf"
14181 CMD1="$TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT,proxy-authorization-file=$ta"
14182 printf "test $F_n $TEST... " $N
14183 echo "user:s3cr3t" >$ta
14184 eval "$CMD0 >${tf}0 2>${te}0 &"
14185 pid0=$! # background process id
14186 waittcp4port $PORT 1
14187 $CMD1 >"${tf}1" 2>"${te}1"
14188 rc1=$?
14189 kill $pid0 2>/dev/null
14190 wait $pid0
14191 if [ $rc1 -ne 0 ]; then
14192 $PRINTF "$FAILED\n"
14193 echo "$CMD0 &" >&2
14194 cat "${te}0" >&2
14195 echo "$CMD1" >&2
14196 cat "${te}1" >&2
14197 cat "${tf}0" >&2
14198 numFAIL=$((numFAIL+1))
14199 listFAIL="$listFAIL $N"
14200 elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then
14201 $PRINTF "$FAILED:\n"
14202 echo "$CMD0 &" >&2
14203 cat "${te}0" >&2
14204 echo "$CMD1" >&2
14205 cat "${te}1" >&2
14206 cat "${tf}0" >&2
14207 echo "Authorization string not in client request" >&2
14208 numFAIL=$((numFAIL+1))
14209 listFAIL="$listFAIL $N"
14210 else
14211 $PRINTF "$OK\n"
14212 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
14213 numOK=$((numOK+1))
14215 kill $pid 2>/dev/null
14216 wait
14217 fi ;; # NUMCOND, feats
14218 esac
14219 N=$((N+1))
14222 # Test communication via vsock loopback socket
14223 NAME=VSOCK_ECHO
14224 case "$TESTS" in
14225 *%$N%*|*%functions%*|*%vsock%*|*%socket%*|*%listen%*|*%$NAME%*)
14226 TEST="$NAME: test communication via VSOCK loopback socket"
14227 # Start a listening echo server
14228 # Connect with a client, send data and compare reply with original data
14229 if ! eval $NUMCOND; then :;
14230 elif ! fea=$(testfeats VSOCK); then
14231 $PRINTF "test $F_n $TEST... ${YELLOW}$fea not available${NORMAL}\n" $N
14232 numCANT=$((numCANT+1))
14233 listCANT="$listCANT $N"
14234 else
14235 tf="$td/test$N.stdout"
14236 te="$td/test$N.stderr"
14237 tdiff="$td/test$N.diff"
14238 da="test$N $(date) $RANDOM"
14239 #newport vsock # nope
14240 CMD0="$TRACE $SOCAT $opts VSOCK-LISTEN:$PORT PIPE"
14241 CMD1="$TRACE $SOCAT $opts - VSOCK-CONNECT:1:$PORT"
14242 printf "test $F_n $TEST... " $N
14243 $CMD0 >/dev/null 2>"${te}0" &
14244 pid0=$!
14245 sleep 1
14246 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14247 rc1=$?
14248 kill $pid0 2>/dev/null; wait
14249 if [ $rc1 -ne 0 ] && [ "$UNAME" != Linux ]; then
14250 $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N
14251 numCANT=$((numCANT+1))
14252 listCANT="$listCANT $N"
14253 elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then
14254 $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N
14255 numCANT=$((numCANT+1))
14256 listCANT="$listCANT $N"
14257 elif grep -q "No such device" "${te}1"; then
14258 $PRINTF "${YELLOW}Loopback does not work${NORMAL}\n" $N
14259 numCANT=$((numCANT+1))
14260 listCANT="$listCANT $N"
14261 elif [ $rc1 -ne 0 ]; then
14262 $PRINTF "$FAILED\n"
14263 echo "$CMD0 &" >&2
14264 cat "${te}0" >&2
14265 echo "$CMD1" >&2
14266 cat "${te}1" >&2
14267 numFAIL=$((numFAIL+1))
14268 listFAIL="$listFAIL $N"
14269 elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then
14270 $PRINTF "$OK\n"
14271 numOK=$((numOK+1))
14272 else
14273 $PRINTF "$FAILED\n"
14274 echo "$CMD0 &" >&2
14275 cat "${te}0" >&2
14276 echo "$CMD1" >&2
14277 cat "${te}1" >&2
14278 numFAIL=$((numFAIL+1))
14279 listFAIL="$listFAIL $N"
14281 fi # NUMCOND
14283 esac
14284 N=$((N+1))
14287 # File transfer with OpenSSL stream connection was incomplete
14288 # Test file transfer from client to server
14289 NAME=OPENSSL_STREAM_TO_SERVER
14290 case "$TESTS" in
14291 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
14292 TEST="$NAME: OpenSSL stream from client to server"
14293 # Start a unidirectional OpenSSL server and stream receiver
14294 # Start a unidirectional OpenSSL client that connects to the server and sends
14295 # data
14296 # Test succeeded when the data received and stored by server is the same as
14297 # sent by the client
14298 if ! eval $NUMCOND; then :;
14299 elif ! a=$(testfeats ip4 tcp openssl); then
14300 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14301 numCANT=$((numCANT+1))
14302 listCANT="$listCANT $N"
14303 elif ! a=$(testaddrs openssl-listen openssl-connect); then
14304 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14305 numCANT=$((numCANT+1))
14306 listCANT="$listCANT $N"
14307 elif ! runsip4 >/dev/null; then
14308 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14309 numCANT=$((numCANT+1))
14310 listCANT="$listCANT $N"
14311 else
14312 gentestcert testsrv
14313 ti="$td/test$N.datain"
14314 to="$td/test$N.dataout"
14315 te="$td/test$N.stderr"
14316 tdiff="$td/test$N.diff"
14317 da="test$N $(date) $RANDOM"
14318 newport tcp4
14319 CMD0="$TRACE $SOCAT $opts -u OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 CREAT:$to"
14320 CMD1="$TRACE $SOCAT $opts -u OPEN:$ti OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt"
14321 printf "test $F_n $TEST... " $N
14322 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
14323 $CMD0 >/dev/null 2>"${te}0" &
14324 pid0=$!
14325 waittcp4port $PORT 1
14326 $CMD1 >"${tf}1" 2>"${te}1"
14327 rc1=$?
14328 usleep $MICROS
14329 kill $pid0 2>/dev/null; wait
14330 if [ $rc1 -ne 0 ]; then
14331 $PRINTF "$FAILED\n"
14332 echo "$CMD0 &" >&2
14333 cat "${te}0" >&2
14334 echo "$CMD1" >&2
14335 cat "${te}1" >&2
14336 numFAIL=$((numFAIL+1))
14337 listFAIL="$listFAIL $N"
14338 elif diff $ti $to >$tdiff; then
14339 $PRINTF "$OK\n"
14340 numOK=$((numOK+1))
14341 else
14342 $PRINTF "$FAILED\n"
14343 echo "$CMD0 &" >&2
14344 cat "${te}0" >&2
14345 echo "$CMD1" >&2
14346 cat "${te}1" >&2
14347 echo "diff:" >&2
14348 head -n 2 $tdiff >&2
14349 echo ... >&2
14350 numFAIL=$((numFAIL+1))
14351 listFAIL="$listFAIL $N"
14353 fi # NUMCOND
14355 esac
14356 N=$((N+1))
14358 # File transfer with OpenSSL stream connection was incomplete
14359 # Test file transfer from server to client
14360 NAME=OPENSSL_STREAM_TO_CLIENT
14361 case "$TESTS" in
14362 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
14363 TEST="$NAME: OpenSSL stream from server to client"
14364 # Start a unidirectional OpenSSL server and stream sender
14365 # Start a unidirectional OpenSSL client that connects to the server and receives
14366 # data
14367 # Test succeeded when the data received and stored by client is the same as
14368 # sent by the server
14369 if ! eval $NUMCOND; then :;
14370 elif ! a=$(testfeats ip4 tcp openssl); then
14371 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14372 numCANT=$((numCANT+1))
14373 listCANT="$listCANT $N"
14374 elif ! a=$(testaddrs openssl-listen openssl-connect); then
14375 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14376 numCANT=$((numCANT+1))
14377 listCANT="$listCANT $N"
14378 elif ! runsip4 >/dev/null; then
14379 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14380 numCANT=$((numCANT+1))
14381 listCANT="$listCANT $N"
14382 else
14383 gentestcert testsrv
14384 ti="$td/test$N.datain"
14385 to="$td/test$N.dataout"
14386 te="$td/test$N.stderr"
14387 tdiff="$td/test$N.diff"
14388 da="test$N $(date) $RANDOM"
14389 newport tcp4
14390 CMD0="$TRACE $SOCAT $opts -U OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 OPEN:$ti"
14391 CMD1="$TRACE $SOCAT $opts -u OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt CREAT:$to"
14392 printf "test $F_n $TEST... " $N
14393 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
14394 $CMD0 >/dev/null 2>"${te}0" &
14395 pid0=$!
14396 waittcp4port $PORT 1
14397 $CMD1 >"${tf}1" 2>"${te}1"
14398 rc1=$?
14399 usleep $MICROS
14400 kill $pid0 2>/dev/null; wait
14401 if [ $rc1 -ne 0 ]; then
14402 $PRINTF "$FAILED\n"
14403 echo "$CMD0 &" >&2
14404 cat "${te}0" >&2
14405 echo "$CMD1" >&2
14406 cat "${te}1" >&2
14407 numFAIL=$((numFAIL+1))
14408 listFAIL="$listFAIL $N"
14409 elif diff $ti $to >$tdiff; then
14410 $PRINTF "$OK\n"
14411 numOK=$((numOK+1))
14412 else
14413 $PRINTF "$FAILED\n"
14414 echo "$CMD0 &" >&2
14415 cat "${te}0" >&2
14416 echo "$CMD1" >&2
14417 cat "${te}1" >&2
14418 echo "diff:" >&2
14419 head -n 2 $tdiff >&2
14420 echo ... >&2
14421 numFAIL=$((numFAIL+1))
14422 listFAIL="$listFAIL $N"
14424 fi # NUMCOND
14426 esac
14427 N=$((N+1))
14429 # Test file transfer from client to server using DTLS
14430 NAME=OPENSSL_DTLS_TO_SERVER
14431 case "$TESTS" in
14432 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%dtls%*|*%udp%*|*%socket%*|*%listen%*|*%$NAME%*)
14433 TEST="$NAME: OpenSSL DTLS transfer from client to server"
14434 # Start a unidirectional OpenSSL DTLS server/receiver
14435 # Start a unidirectional OpenSSL DTLS client that connects to the server and
14436 # sends data
14437 # Test succeeded when the data received and stored by server is the same as
14438 # sent by the client
14439 if ! eval $NUMCOND; then :;
14440 elif ! a=$(testfeats ip4 udp openssl); then
14441 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14442 numCANT=$((numCANT+1))
14443 listCANT="$listCANT $N"
14444 elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then
14445 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14446 numCANT=$((numCANT+1))
14447 listCANT="$listCANT $N"
14448 elif ! runsip4 >/dev/null; then
14449 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14450 numCANT=$((numCANT+1))
14451 listCANT="$listCANT $N"
14452 elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then
14453 $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
14454 numCANT=$((numCANT+1))
14455 listCANT="$listCANT $N"
14456 else
14457 gentestcert testsrv
14458 ti="$td/test$N.datain"
14459 to="$td/test$N.dataout"
14460 te="$td/test$N.stderr"
14461 tdiff="$td/test$N.diff"
14462 da="test$N $(date) $RANDOM"
14463 newport udp4
14464 CMD0="$TRACE $SOCAT $opts -u OPENSSL-DTLS-LISTEN:$PORT,pf=ip4,cert=testsrv.pem,verify=0 CREAT:$to"
14465 CMD1="$TRACE $SOCAT $opts -u OPEN:$ti OPENSSL-DTLS-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt"
14466 printf "test $F_n $TEST... " $N
14467 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
14468 $CMD0 >/dev/null 2>"${te}0" &
14469 pid0=$!
14470 waitudp4port $PORT 1
14471 $CMD1 >"${tf}1" 2>"${te}1"
14472 rc1=$?
14473 usleep $MICROS
14474 kill $pid0 2>/dev/null; wait
14475 if [ $rc1 -ne 0 ]; then
14476 $PRINTF "$FAILED\n"
14477 echo "$CMD0 &" >&2
14478 cat "${te}0" >&2
14479 echo "$CMD1" >&2
14480 cat "${te}1" >&2
14481 numFAIL=$((numFAIL+1))
14482 listFAIL="$listFAIL $N"
14483 elif diff $ti $to >$tdiff; then
14484 $PRINTF "$OK\n"
14485 numOK=$((numOK+1))
14486 else
14487 $PRINTF "$FAILED\n"
14488 echo "$CMD0 &" >&2
14489 cat "${te}0" >&2
14490 echo "$CMD1" >&2
14491 cat "${te}1" >&2
14492 echo "diff:" >&2
14493 head -n 2 $tdiff >&2
14494 echo ... >&2
14495 numFAIL=$((numFAIL+1))
14496 listFAIL="$listFAIL $N"
14498 fi # NUMCOND
14500 esac
14501 N=$((N+1))
14503 # Test file transfer from server to client using DTLS
14504 NAME=OPENSSL_DTLS_TO_CLIENT
14505 case "$TESTS" in
14506 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%dtls%*|*%udp%*|*%socket%*|*%listen%*|*%$NAME%*)
14507 TEST="$NAME: OpenSSL DTLS transfer from server to client"
14508 # Start a unidirectional OpenSSL DTLS server/sender
14509 # Start a unidirectional OpenSSL DTLS client that connects to the server and
14510 # receives data
14511 # Test succeeded when the data received and stored by client is the same as
14512 # sent by the server
14513 if ! eval $NUMCOND; then :;
14514 elif ! a=$(testfeats ip4 udp openssl); then
14515 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14516 numCANT=$((numCANT+1))
14517 listCANT="$listCANT $N"
14518 elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then
14519 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14520 numCANT=$((numCANT+1))
14521 listCANT="$listCANT $N"
14522 elif ! runsip4 >/dev/null; then
14523 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14524 numCANT=$((numCANT+1))
14525 listCANT="$listCANT $N"
14526 elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-c] ]]; then
14527 $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
14528 numCANT=$((numCANT+1))
14529 listCANT="$listCANT $N"
14530 else
14531 gentestcert testsrv
14532 ti="$td/test$N.datain"
14533 to="$td/test$N.dataout"
14534 te="$td/test$N.stderr"
14535 tdiff="$td/test$N.diff"
14536 da="test$N $(date) $RANDOM"
14537 newport udp4
14538 CMD0="$TRACE $SOCAT $opts -U OPENSSL-DTLS-LISTEN:$PORT,pf=ip4,cert=testsrv.pem,verify=0 OPEN:$ti"
14539 CMD1="$TRACE $SOCAT $opts -u OPENSSL-DTLS-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt CREAT:$to"
14540 printf "test $F_n $TEST... " $N
14541 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
14542 $CMD0 >/dev/null 2>"${te}0" &
14543 pid0=$!
14544 waitudp4port $PORT 1
14545 $CMD1 >"${tf}1" 2>"${te}1"
14546 rc1=$?
14547 usleep $MICROS
14548 kill $pid0 2>/dev/null; wait
14549 if [ $rc1 -ne 0 ]; then
14550 $PRINTF "$FAILED\n"
14551 echo "$CMD0 &" >&2
14552 cat "${te}0" >&2
14553 echo "$CMD1" >&2
14554 cat "${te}1" >&2
14555 numFAIL=$((numFAIL+1))
14556 listFAIL="$listFAIL $N"
14557 elif diff $ti $to >$tdiff; then
14558 $PRINTF "$OK\n"
14559 numOK=$((numOK+1))
14560 else
14561 $PRINTF "$FAILED\n"
14562 echo "$CMD0 &" >&2
14563 cat "${te}0" >&2
14564 echo "$CMD1" >&2
14565 cat "${te}1" >&2
14566 echo "diff:" >&2
14567 head -n 2 $tdiff >&2
14568 echo ... >&2
14569 numFAIL=$((numFAIL+1))
14570 listFAIL="$listFAIL $N"
14572 fi # NUMCOND
14574 esac
14575 N=$((N+1))
14578 # Test if the problem with overlapping internal parameters of sockets and
14579 # openssl are fixed
14580 NAME=OPENSSL_PARA_OVERLAP
14581 case "$TESTS" in
14582 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%openssl%*|*%listen%*|*%$NAME%*)
14583 TEST="$NAME: test diverse of socket,openssl params"
14584 # That bug had not many effects; the simplest to use is possible SIGSEGV on
14585 # close when option accept-timeout with fractional seconds was applied
14586 if ! eval $NUMCOND; then :;
14587 elif ! testfeats openssl >/dev/null; then
14588 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14589 numCANT=$((numCANT+1))
14590 listCANT="$listCANT $N"
14591 elif ! type openssl >/dev/null 2>&1; then
14592 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
14593 numCANT=$((numCANT+1))
14594 listCANT="$listCANT $N"
14595 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
14596 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
14597 numCANT=$((numCANT+1))
14598 listCANT="$listCANT $N"
14599 else
14600 gentestcert testsrv
14601 tf="$td/test$N.stdout"
14602 te="$td/test$N.stderr"
14603 tdiff="$td/test$N.diff"
14604 trc0="$td/test$N.rc0"
14605 da="test$N $(date) $RANDOM"
14606 newport tcp4
14607 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"
14608 CMD1="$TRACE $SOCAT $opts /dev/null OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
14609 printf "test $F_n $TEST... " $N
14610 $CMD0 >/dev/null 2>"${te}0" || echo $? >$trc0 &
14611 pid0=$!
14612 waittcp4port $PORT 1
14613 $CMD1 >"${tf}1" 2>"${te}1"
14614 rc1=$?
14615 psleep 0.5
14616 kill $pid0 2>/dev/null; wait
14617 if [ $rc1 -ne 0 ]; then
14618 $PRINTF "$CANT\n"
14619 numCANT=$((numCANT+1))
14620 elif [ ! -e $trc0 ]; then
14621 $PRINTF "$OK\n"
14622 numOK=$((numOK+1))
14623 else
14624 $PRINTF "$FAILED\n"
14625 echo "$CMD0 &" >&2
14626 cat "${te}0" >&2
14627 echo "$CMD1" >&2
14628 cat "${te}1" >&2
14629 numFAIL=$((numFAIL+1))
14630 listFAIL="$listFAIL $N"
14632 fi # NUMCOND
14634 esac
14635 N=$((N+1))
14638 # Bug fix, OpenSSL server could be crashed by client cert with IPv6 address in SubjectAltname
14639 NAME=OPENSSL_CLIENT_IP6_CN
14640 case "$TESTS" in
14641 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%ip6%*|*%socket%*|*%listen%*|*%$NAME%*)
14642 TEST="$NAME: Test if OpenSSL server may be crashed by client cert with IPv6 address"
14643 # Socat 1.7.4.1 had a bug that caused OpenSSL server to crash with SIGSEGV when
14644 # it checked a client certificate containing IPv6 address in SubjectAltName and
14645 # no openssl-commonname option was given
14646 if ! eval $NUMCOND; then :;
14647 elif ! testfeats openssl >/dev/null; then
14648 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14649 numCANT=$((numCANT+1))
14650 listCANT="$listCANT $N"
14651 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
14652 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
14653 numCANT=$((numCANT+1))
14654 listCANT="$listCANT $N"
14655 else
14656 gentestcert testsrv
14657 gentestaltcert testalt
14658 tf="$td/test$N.stdout"
14659 te="$td/test$N.stderr"
14660 tdiff="$td/test$N.diff"
14661 da="test$N $(date) $RANDOM"
14662 newport tcp4
14663 CMD0="$TRACE $SOCAT $opts -u OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,cert=./testsrv.pem,cafile=./testalt.crt -"
14664 CMD1="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:localhost:$PORT,pf=ip4,cafile=testsrv.crt,cert=testalt.pem,verify=0"
14665 printf "test $F_n $TEST... " $N
14666 $CMD0 >/dev/null >"${tf}0" 2>"${te}0" &
14667 pid0=$!
14668 waittcp4port $PORT 1
14669 echo "$da" |$CMD1 2>"${te}1"
14670 rc1=$?
14671 kill $pid0 2>/dev/null; wait
14672 if [ $rc1 -eq 0 ] && echo "$da" |diff - "${tf}0" >$tdiff; then
14673 $PRINTF "$OK\n"
14674 numOK=$((numOK+1))
14675 else
14676 $PRINTF "$FAILED\n"
14677 echo "$CMD0 &" >&2
14678 cat "${te}0" >&2
14679 echo "$CMD1" >&2
14680 cat "${te}1" >&2
14681 numFAIL=$((numFAIL+1))
14682 listFAIL="$listFAIL $N"
14684 fi # NUMCOND
14686 esac
14687 N=$((N+1))
14690 # Test if unknown service specs are handled properly
14691 NAME=BAD_SERVICE
14692 case "$TESTS" in
14693 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%$NAME%*)
14694 TEST="$NAME: test if unknown service specs are handled properly"
14695 # Try to resolve an unspecified TCP service "
14696 if ! eval $NUMCOND; then :; else
14697 tf="$td/test$N.stdout"
14698 te="$td/test$N.stderr"
14699 tdiff="$td/test$N.diff"
14700 da="test$N $(date) $RANDOM"
14701 CMD="$TRACE $SOCAT $opts - TCP:$LOCALHOST:zyxw"
14702 printf "test $F_n $TEST... " $N
14703 $CMD >/dev/null 2>"${te}" &
14704 pid=$!
14705 sleep 1
14706 kill -9 $pid 2>/dev/null;
14707 rc=$? # did process still exist?
14708 if [ $rc -ne 0 ]; then
14709 $PRINTF "$OK\n"
14710 if [ "$VERBOSE" ]; then
14711 echo "$CMD &" >&2
14713 numOK=$((numOK+1))
14714 else
14715 $PRINTF "$FAILED\n"
14716 echo "$CMD &" >&2
14717 cat "${te}" >&2
14718 numFAIL=$((numFAIL+1))
14719 listFAIL="$listFAIL $N"
14721 fi # NUMCOND
14723 esac
14724 N=$((N+1))
14727 # Test if the user option with abstract UNIX domain socket is not applied to
14728 # file "" (empty name)
14729 NAME=ABSTRACT_USER
14730 case "$TESTS" in
14731 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%listen%*|*%$NAME%*)
14732 TEST="$NAME: Is the fs related user option on ABSTRACT socket applied to FD"
14733 # Apply the user option to an abstract socket; check if this produces an error.
14734 # No error should occur
14735 if ! eval $NUMCOND; then :;
14736 elif [ "$UNAME" != Linux ]; then
14737 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
14738 numCANT=$((numCANT+1))
14739 listCANT="$listCANT $N"
14740 else
14741 tf="$td/test$N.stdout"
14742 te="$td/test$N.stderr"
14743 tdiff="$td/test$N.diff"
14744 da="test$N $(date) $RANDOM"
14745 CMD="$TRACE $SOCAT ABSTRACT-LISTEN:temp,accept-timeout=0.1,user=$USER FILE:/dev/null"
14746 printf "test $F_n $TEST... " $N
14747 $CMD >/dev/null 2>"${te}"
14748 echo "$da" |$CMD >"${tf}1" 2>"${te}1"
14749 rc=$?
14750 if [ $rc -eq 0 ]; then
14751 $PRINTF "$OK\n"
14752 if [ "$VERBOSE" ]; then
14753 echo "$CMD" >&2
14755 numOK=$((numOK+1))
14756 else
14757 $PRINTF "$FAILED\n"
14758 echo "$CMD" >&2
14759 cat "${te}" >&2
14760 numFAIL=$((numFAIL+1))
14761 listFAIL="$listFAIL $N"
14763 fi # NUMCOND
14765 esac
14766 N=$((N+1))
14769 # Test if option -R does not "sniff" left-to-right traffic
14770 NAME=SNIFF_RIGHT_TO_LEFT
14771 case "$TESTS" in
14772 *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*)
14773 TEST="$NAME: test if option -R does not "sniff" left-to-right traffic"
14774 # Use option -R, check if left-to-right traffic is not in output file
14775 if ! eval $NUMCOND; then :; else
14776 tf="$td/test$N.stdout"
14777 te="$td/test$N.stderr"
14778 ts="$td/test$N.sniffed"
14779 tdiff="$td/test$N.diff"
14780 da="test$N $(date) $RANDOM"
14781 CMD="$TRACE $SOCAT $opts -R $ts - /dev/null"
14782 printf "test $F_n $TEST... " $N
14783 echo "$da" |$CMD >"${tf}" 2>"${te}"
14784 rc=$?
14785 if [ ! -f "$ts" ]; then
14786 $PRINTF "$CANT\n"
14787 if [ "$VERBOSE" ]; then
14788 echo "$CMD" >&2
14789 cat "${te}" >&2
14791 numCANT=$((numCANT+1))
14792 listCANT="$listCANT $N"
14793 elif [ ! -s "$ts" ]; then
14794 $PRINTF "$OK\n"
14795 if [ "$VERBOSE" ]; then
14796 echo "$CMD" >&2
14798 numOK=$((numOK+1))
14799 else
14800 $PRINTF "$FAILED\n"
14801 echo "$CMD &" >&2
14802 cat "${te}" >&2
14803 numFAIL=$((numFAIL+1))
14804 listFAIL="$listFAIL $N"
14806 fi # NUMCOND
14808 esac
14809 PORT=$((PORT+1))
14810 N=$((N+1))
14812 # Socats access to different types of file system entries using various kinds
14813 # of addresses fails in a couple of useless combinations. These failures have
14814 # to print an error message and exit with return code 1.
14815 # Up to version 1.7.4.2 this desired behaviour was found for most combinations,
14816 # however some fix in 1.7.4.3 degraded the overall result.
14817 # This group of tests checks all known compinations.
14818 while read entry method; do
14819 if [ -z "$entry" ] || [[ "$entry" == \#* ]]; then continue; fi
14820 NAME=$(toupper $method)_TO_$(toupper $entry)
14821 case "$TESTS" in
14822 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%listen%*|*%$NAME%*)
14823 #set -vx
14824 TEST="$NAME: Failure handling on $method access to $entry"
14825 # Create some kind of system entry and try to access it with some improper
14826 # address. Check if Socat returns with rc 1 and prints an error message
14827 if ! eval $NUMCOND; then :; else
14828 ts="$td/test$N.socket"
14829 tf="$td/test$N.stdout"
14830 te="$td/test$N.stderr"
14831 tdiff="$td/test$N.diff"
14832 da="test$N $(date) $RANDOM"
14834 printf "test $F_n $TEST... " $N
14835 # create an invalid or non-matching UNIX socket
14836 case "$entry" in
14837 missing) pid0=; rm -f $ts ;;
14838 denied) pid0=; rm -f $ts; touch $ts; chmod 000 $ts ;;
14839 directory) pid0=; mkdir -p $ts ;;
14840 orphaned) pid0= # the remainder of a UNIX socket in FS
14841 SOCAT_MAIN_WAIT= $SOCAT $opts UNIX-LISTEN:$ts,unlink-close=0 /dev/null >${tf}0 2>${te}0 &
14842 waitunixport $ts 1
14843 SOCAT_MAIN_WAIT= $SOCAT $opts /dev/null UNIX-CONNECT:$ts >>${tf}0 2>>${te}0
14845 file) pid0=; rm -f $ts; touch $ts ;;
14846 stream) CMD0="$SOCAT $opts UNIX-LISTEN:$ts /dev/null"
14847 SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 &
14848 pid0=$! ;;
14849 dgram) CMD0="$SOCAT $opts -u UNIX-RECV:$ts /dev/null"
14850 SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 &
14851 pid0=$! ;;
14852 seqpacket) CMD0="$SOCAT $opts UNIX-LISTEN:$ts,socktype=$SOCK_SEQPACKET /dev/null"
14853 SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 &
14854 pid0=$! ;;
14855 esac
14856 [ "$pid0" ] && waitunixport $ts 1
14857 # try to access this socket
14858 case "$method" in
14859 connect) CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts" ;;
14860 send) CMD1="$TRACE $SOCAT $opts -u - UNIX-SEND:$ts" ;;
14861 sendto) CMD1="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts" ;;
14862 seqpacket) CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts,socktype=$SOCK_SEQPACKET" ;;
14863 unix) CMD1="$TRACE $SOCAT $opts -u - UNIX-CLIENT:$ts" ;;
14864 gopen) CMD1="$TRACE $SOCAT $opts -u - GOPEN:$ts" ;;
14865 esac
14866 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14867 rc1=$?
14868 [ "$pid0" ] && { kill $pid0 2>/dev/null; wait; }
14869 if [ $rc1 != 1 ]; then
14870 $PRINTF "$FAILED (bad return code $rc1)\n"
14871 if [ "$pid0" ]; then
14872 echo "$CMD0 &" >&2
14873 cat "${te}0" >&2
14875 echo "$CMD1" >&2
14876 cat "${te}1" >&2
14877 numFAIL=$((numFAIL+1))
14878 listFAIL="$listFAIL $N"
14879 elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then
14880 $PRINTF "$FAILED ($nerr error message(s) instead of 1)\n"
14881 if [ "$pid0" ]; then
14882 echo "$CMD0 &" >&2
14883 cat "${te}0" >&2
14885 echo "$CMD1" >&2
14886 cat "${te}1" >&2
14887 numFAIL=$((numFAIL+1))
14888 listFAIL="$listFAIL $N"
14889 else
14890 $PRINTF "$OK\n"
14891 if [ "$VERBOSE" ]; then
14892 if [ "$pid0" ]; then echo "$CMD0 &" >&2; fi
14893 echo "$CMD1" >&2
14895 numOK=$((numOK+1))
14897 set +vx
14898 fi # NUMCOND
14900 esac
14901 N=$((N+1))
14902 done <<<"
14903 missing connect
14904 denied connect
14905 directory connect
14906 orphaned connect
14907 file connect
14908 dgram connect
14909 seqpacket connect
14910 missing send
14911 denied send
14912 directory send
14913 orphaned send
14914 file send
14915 stream send
14916 seqpacket send
14917 missing sendto
14918 denied sendto
14919 directory sendto
14920 orphaned sendto
14921 file sendto
14922 stream sendto
14923 seqpacket sendto
14924 missing seqpacket
14925 denied seqpacket
14926 directory seqpacket
14927 orphaned seqpacket
14928 file seqpacket
14929 stream seqpacket
14930 dgram seqpacket
14931 missing unix
14932 denied unix
14933 directory unix
14934 file unix
14935 orphaned unix
14936 denied gopen
14937 directory gopen
14938 orphaned gopen
14942 # Test TCP with options connect-timeout and retry.
14943 # Up to 1.7.4.3 this terminated immediately on connection refused
14944 NAME=TCP_TIMEOUT_RETRY
14945 case "$TESTS" in
14946 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
14947 TEST="$NAME: TCP with options connect-timeout and retry"
14948 # In background run a delayed echo server
14949 # In foreground start TCP with connect-timeout and retry. On first attempt the
14950 # server is not listening; when socat makes a second attempt that succeeds, the
14951 # bug is absent and the test succeeded.
14952 if ! eval $NUMCOND; then :; else
14953 tf="$td/test$N.stdout"
14954 te="$td/test$N.stderr"
14955 tdiff="$td/test$N.diff"
14956 da="test$N $(date) $RANDOM"
14957 CMD0="sleep 1 && $TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr PIPE"
14958 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,connect-timeout=2,retry=1,interval=2"
14959 printf "test $F_n $TEST... " $N
14960 eval "$CMD0" >/dev/null 2>"${te}0" &
14961 pid0=$!
14962 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14963 rc1=$?
14964 kill $pid0 2>/dev/null; wait
14965 if [ $rc1 -ne 0 ]; then
14966 $PRINTF "$FAILED\n"
14967 echo "$CMD0 &" >&2
14968 cat "${te}0" >&2
14969 echo "$CMD1" >&2
14970 cat "${te}1" >&2
14971 numFAIL=$((numFAIL+1))
14972 listFAIL="$listFAIL $N"
14973 elif echo "$da" |diff - "${tf}1" >$tdiff; then
14974 $PRINTF "$OK\n"
14975 if [ "$VERBOSE" ]; then
14976 echo "$CMD0 &" >&2
14977 echo "$CMD1" >&2
14979 numOK=$((numOK+1))
14980 else
14981 $PRINTF "$FAILED\n"
14982 echo "$CMD0 &" >&2
14983 cat "${te}0" >&2
14984 echo "$CMD1" >&2
14985 cat "${te}1" >&2
14986 numFAIL=$((numFAIL+1))
14987 listFAIL="$listFAIL $N"
14989 fi # NUMCOND
14991 esac
14992 N=$((N+1))
14995 # Test if the rawer option works. Up to Socat 1.7.4.3, it failed because it
14996 # cleared the CREAD flag.
14997 NAME=RAWER
14998 case "$TESTS" in
14999 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
15000 TEST="$NAME: Test if the rawer option fails"
15001 # Invoke Socat with a terminal address with option rawer. When it has no error
15002 # the test succeeded.
15003 if ! eval $NUMCOND; then :; else
15004 tf="$td/test$N.stdout"
15005 te="$td/test$N.stderr"
15006 tdiff="$td/test$N.diff"
15007 da="test$N $(date) $RANDOM"
15008 CMD0="$SOCAT -lp outer /dev/null EXEC:\"$SOCAT\\ -lp\\ inner\\ -\\,rawer\\ PIPE\",pty"
15009 printf "test $F_n $TEST... " $N
15010 eval "$CMD0" >/dev/null 2>"${te}0"
15011 rc0=$?
15012 if [ $rc0 -eq 0 ]; then
15013 $PRINTF "$OK\n"
15014 if [ "$VERBOSE" ]; then
15015 echo "$CMD0" >&2
15017 numOK=$((numOK+1))
15018 else
15019 $PRINTF "$FAILED\n"
15020 echo "$CMD0" >&2
15021 cat "${te}0" >&2
15022 numFAIL=$((numFAIL+1))
15023 listFAIL="$listFAIL $N"
15025 fi # NUMCOND
15027 esac
15028 PORT=$((PORT+1))
15029 N=$((N+1))
15031 # Up to 1.7.4.3 there was a bug with the lowport option:
15032 # Active addresses UDP-SEND, UDP-SENDTO always bound to port 1 instead of
15033 # 640..1023
15034 NAME=UDP_LOWPORT
15035 case "$TESTS" in
15036 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
15037 TEST="$NAME: UDP4-SEND with lowport"
15038 # Run Socat with UDP4-SEND:...,lowport and full logging and check the
15039 # parameters of bind() call. If port is in the range 640..1023 the test
15040 # succeeded.
15041 # This test does not require root because it just checks log of bind() but does
15042 # not require success
15043 # This test fails if WITH_SYCLS is turned off
15044 if ! eval $NUMCOND; then :; else
15045 tf="$td/test$N.stdout"
15046 te="$td/test$N.stderr"
15047 tdiff="$td/test$N.diff"
15048 da="test$N $(date) $RANDOM"
15049 #newport udp4 # not needed in this test
15050 CMD="$TRACE $SOCAT $opts -d -d -d -d /dev/null UDP4-SENDTO:$LOCALHOST:$PORT,lowport"
15051 printf "test $F_n $TEST... " $N
15052 $CMD >/dev/null 2>"${te}"
15053 rc1=$?
15054 LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head -n 1)
15055 #echo "LOWPORT=\"$LOWPORT\"" >&2
15056 #type socat >&2
15057 if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then
15058 $PRINTF "$OK\n"
15059 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15060 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15061 numOK=$((numOK+1))
15062 elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then
15063 $PRINTF "$CANT (no SYCLS)\n"
15064 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15065 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15066 numCANT=$((numCANT+1))
15067 listCANT="$listCANT $N"
15068 else
15069 $PRINTF "$FAILED\n"
15070 echo "$CMD"
15071 cat "${te}" >&2
15072 numFAIL=$((numFAIL+1))
15073 listFAIL="$listFAIL $N"
15075 fi # NUMCOND
15077 esac
15078 PORT=$((PORT+1))
15079 N=$((N+1))
15081 # Test if trailing garbage in integer type options gives error
15082 NAME=MISSING_INTEGER
15083 case "$TESTS" in
15084 *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*)
15085 TEST="$NAME: Error on option that's missing integer value"
15086 # Invoke Socat with pty and option ispeed=b19200.
15087 # When socat terminates with error the test succeeded
15088 if ! eval $NUMCOND; then :; else
15089 tf="$td/test$N.stdout"
15090 te="$td/test$N.stderr"
15091 tdiff="$td/test$N.diff"
15092 da="test$N $(date) $RANDOM"
15093 CMD0="$TRACE $SOCAT $opts - PTY,ispeed=b19200"
15094 printf "test $F_n $TEST... " $N
15095 $CMD0 </dev/null >/dev/null 2>"${te}0"
15096 if grep -q "missing numerical value" "${te}0"; then
15097 $PRINTF "$OK\n"
15098 numOK=$((numOK+1))
15099 else
15100 $PRINTF "$FAILED\n"
15101 echo "$CMD0"
15102 cat "${te}0"
15103 numFAIL=$((numFAIL+1))
15104 listFAIL="$listFAIL $N"
15106 fi # NUMCOND
15108 esac
15109 N=$((N+1))
15111 # Test if trailing garbage in integer type options gives error
15112 NAME=INTEGER_GARBAGE
15113 case "$TESTS" in
15114 *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*)
15115 TEST="$NAME: Error on trailing garbage"
15116 # Invoke Socat with pty and option ispeed=b19200.
15117 # When socat terminates with error the test succeeded
15118 if ! eval $NUMCOND; then :; else
15119 tf="$td/test$N.stdout"
15120 te="$td/test$N.stderr"
15121 tdiff="$td/test$N.diff"
15122 da="test$N $(date) $RANDOM"
15123 CMD0="$TRACE $SOCAT $opts - PTY,ispeed=19200B"
15124 printf "test $F_n $TEST... " $N
15125 $CMD0 </dev/null >/dev/null 2>"${te}0"
15126 if grep -q "trailing garbage" "${te}0"; then
15127 $PRINTF "$OK\n"
15128 if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi
15129 if [ "$debug" ]; then cat ${te} >&2; fi
15130 numOK=$((numOK+1))
15131 else
15132 $PRINTF "$FAILED\n"
15133 echo "$CMD0"
15134 cat "${te}0"
15135 numFAIL=$((numFAIL+1))
15136 listFAIL="$listFAIL $N"
15138 fi # NUMCOND
15140 esac
15141 N=$((N+1))
15144 # Test if Filan can print the target of symbolic links
15145 NAME=FILANSYMLINK
15146 case "$TESTS" in
15147 *%$N%*|*%filan%*|*%$NAME%*)
15148 TEST="$NAME: capability to display symlink target"
15149 # Run Filan on a symbolic link
15150 # When its output contains "LINKTARGET=<target>" the test succeeded
15151 if ! eval $NUMCOND; then :; else
15152 tf="$td/test$N.file"
15153 tl="$td/test$N.symlink"
15154 te="$td/test$N.stderr"
15155 printf "test $F_n $TEST... " $N
15156 touch "$tf"
15157 ln -s "$tf" "$tl"
15158 target=$($FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/')
15159 if [ "$target" = "$tf" ]; then
15160 $PRINTF "$OK\n"
15161 if [ "$VERBOSE" ]; then
15162 echo "touch \"$tf\""
15163 echo "ln -s \"$tf\" \"$tl\""
15164 echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'"
15166 numOK=$((numOK+1))
15167 else
15168 $PRINTF "$FAILED\n"
15169 echo "touch \"$tf\"" >&2
15170 echo "ln -s \"$tf\" \"$tl\"" >&2
15171 echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" >&2
15172 cat "$te"
15173 numFAIL=$((numFAIL+1))
15174 listFAIL="$listFAIL $N"
15176 kill $spid 2>/dev/null
15177 wait
15178 fi ;; # NUMCOND
15179 esac
15180 N=$((N+1))
15183 # Test preservation of packet boundaries from Socat to sub processes of
15184 # various kind and back to Socat via socketpair with socket type datagram.
15185 # (EXECSOCKETPAIRPACKETS SYSTEMSOCKETPAIRPACKETS)
15186 for addr in exec system; do
15187 ADDR=$(echo $addr |tr a-z A-Z)
15188 NAME=${ADDR}SOCKETPAIRPACKETS
15189 case "$TESTS" in
15190 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%unix%*|*%dgram%*|*%packets%*|*%$NAME%*)
15191 TEST="$NAME: simple echo via $addr of cat with socketpair, keeping packet boundaries"
15192 # Start a Socat process with a UNIX datagram socket on the left side and with
15193 # a sub process connected via datagram socketpair that keeps packet boundaries
15194 # (here: another Socat process in unidirectional mode).
15195 # Pass two packets to the UNIX datagram socket; let Socat wait a little time
15196 # before processing,
15197 # so the packets are at the same time in the receive queue.
15198 # The process that sends thes packet uses a short packet size (-b),
15199 # so the returned data is truncated in case the packets were merged.
15200 # When the complete data is returned, the test succeeded.
15201 if ! eval $NUMCOND; then :; else
15202 ts0="$td/test$N.sock0"
15203 ts1="$td/test$N.sock1"
15204 tf="$td/test$N.stdout"
15205 te="$td/test$N.stderr"
15206 tdiff="$td/test$N.diff"
15207 da="test$N $(date) $RANDOM"
15208 #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
15209 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
15210 CMD1="$SOCAT $opts -lp client -b 24 -t 2 -T 3 - UNIX-SENDTO:$ts0,bind=$ts1",shut-null
15211 printf "test $F_n $TEST... " $N
15212 export SOCAT_TRANSFER_WAIT=2
15213 eval "$CMD0" >/dev/null 2>"${te}0" &
15214 pid0="$!"
15215 unset SOCAT_TRANSFER_WAIT
15216 waitunixport $ts0 1
15217 { echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1 >"${tf}1" 2>"${te}1"
15218 rc1=$?
15219 kill $pid0 2>/dev/null; wait
15220 if [ "$rc1" -ne 0 ]; then
15221 $PRINTF "$FAILED (rc1=$rc1): $TRACE $SOCAT:\n"
15222 echo "$CMD0 &"
15223 cat "${te}0"
15224 echo "{ echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1"
15225 cat "${te}1"
15226 numFAIL=$((numFAIL+1))
15227 listFAIL="$listFAIL $N"
15228 elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
15229 $PRINTF "$FAILED (diff)\n"
15230 echo "$CMD0 &" >&2
15231 cat "${te}0" >&2
15232 echo "{ echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1" >&2
15233 cat "${te}1" >&2
15234 echo "diff:" >&2
15235 cat $tdiff >&2
15236 numFAIL=$((numFAIL+1))
15237 listFAIL="$listFAIL $N"
15238 else
15239 $PRINTF "$OK\n"
15240 if [ "$VERBOSE" ]; then
15241 echo "$CMD0 &" >&2
15242 echo "{ echo -n "${da:0:20}"; sleep 1; echo "${da:20}"; } |$CMD1" >&2
15244 numOK=$((numOK+1))
15246 fi # NUMCOND
15248 esac
15249 N=$((N+1))
15250 done # for
15253 # Test if a special quote based syntax error in dalan module does not raise
15254 # SIGSEGV
15255 NAME=DALAN_NO_SIGSEGV
15256 case "$TESTS" in
15257 *%$N%*|*%functions%*|*%bugs%*|*%dalan%*|*%listen%*|*%$NAME%*)
15258 TEST="$NAME: Dalan syntax error does not raise SIGSEGV"
15259 # Invoke Socat with an address that has this quote based syntax error.
15260 # When exit code is 1 (due to syntax error) the test succeeded.
15261 if ! eval $NUMCOND; then :
15262 elif ! a=$(testfeats GOPEN); then
15263 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
15264 numCANT=$((numCANT+1))
15265 listCANT="$listCANT $N"
15266 elif ! a=$(testaddrs - GOPEN SOCKET-LISTEN); then
15267 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
15268 numCANT=$((numCANT+1))
15269 listCANT="$listCANT $N"
15270 else
15271 tf="$td/test$N.stdout"
15272 te="$td/test$N.stderr"
15273 tdiff="$td/test$N.diff"
15274 da="test$N $(date) $RANDOM"
15275 CMD="$TRACE $SOCAT $opts /dev/null SOCKET-LISTEN:1:1:'"/tmp/sock"'"
15276 printf "test $F_n $TEST... " $N
15277 $CMD >/dev/null 2>"${te}"
15278 rc1=$?
15279 if [ $rc1 -eq 1 ]; then
15280 $PRINTF "$OK\n"
15281 if [ "$VERBOSE" ]; then echo "$CMD"; fi
15282 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15283 numOK=$((numOK+1))
15284 elif [ $rc1 -eq 139 ]; then
15285 $PRINTF "$FAILED\n"
15286 echo "$CMD"
15287 cat "${te}" >&2
15288 numFAIL=$((numFAIL+1))
15289 listFAIL="$listFAIL $N"
15290 else
15291 # soemthing unexpected happened
15292 $PRINTF "$CANT\n"
15293 echo "$CMD"
15294 cat "${te}" >&2
15295 numCANT=$((numCANT+1))
15296 listCANT="$listCANT $N"
15298 fi # NUMCOND
15300 esac
15301 N=$((N+1))
15304 # Test if filan -s correctly displays TCP on appropriate FDs
15305 # This feature was broken in version 1.7.4.4
15306 NAME=FILAN_SHORT_TCP
15307 case "$TESTS" in
15308 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%listen%*|*%$NAME%*)
15309 TEST="$NAME: filan -s displays TCP etc"
15310 # Establish a TCP connection using Socat server and client; on the server
15311 # exec() filan -s using nofork option, so its output appears on the client.
15312 # When the second word in the first line is "tcp" the test succeeded.
15313 if ! eval $NUMCOND; then :
15314 elif ! a=$(testfeats STDIO IP4 TCP LISTEN EXEC); then
15315 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
15316 numCANT=$((numCANT+1))
15317 listCANT="$listCANT $N"
15318 elif ! a=$(testaddrs STDIO TCP4 TCP4-LISTEN EXEC); then
15319 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
15320 numCANT=$((numCANT+1))
15321 listCANT="$listCANT $N"
15322 elif ! o=$(testoptions so-reuseaddr nofork ) >/dev/null; then
15323 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15324 numCANT=$((numCANT+1))
15325 listCANT="$listCANT $N"
15326 elif ! runsip4 >/dev/null; then
15327 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
15328 numCANT=$((numCANT+1))
15329 listCANT="$listCANT $N"
15330 else
15331 tf="$td/test$N.stdout"
15332 te="$td/test$N.stderr"
15333 tdiff="$td/test$N.diff"
15334 da="test$N $(date) $RANDOM"
15335 CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork"
15336 CMD1="$TRACE $SOCAT $opts - TCP4:localhost:$PORT"
15337 printf "test $F_n $TEST... " $N
15338 eval "$CMD0" >/dev/null 2>"${te}0" &
15339 pid0=$!
15340 waittcp4port $PORT 1
15341 $CMD1 >"${tf}1" 2>"${te}1" </dev/null
15342 rc1=$?
15343 kill $pid0 2>/dev/null; wait
15344 result="$(head -n 1 ${tf}1 |awk '{print($2);}')"
15345 if [ $rc1 -eq 0 -a "$result" = tcp ]; then
15346 $PRINTF "$OK\n"
15347 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15348 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15349 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
15350 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
15351 numOK=$((numOK+1))
15352 else
15353 $PRINTF "$FAILED\n"
15354 if [ $rc1 -ne 0 ]; then
15355 echo "rc=$rc1" >&2
15356 else
15357 echo "result is \"$result\" instead of \"tcp\"" >&2
15359 echo "$CMD0 &"
15360 cat "${te}0" >&2
15361 echo "$CMD1"
15362 cat "${te}1" >&2
15363 numFAIL=$((numFAIL+1))
15364 listFAIL="$listFAIL $N"
15366 fi # NUMCOND
15368 esac
15369 PORT=$((PORT+1))
15370 N=$((N+1))
15373 # Test if the settings of the terminal that Socat is invoked in are restored
15374 # on termination.
15375 # This failed on Open-Solaris family OSes up to 1.7.4.4
15376 NAME=RESTORE_TTY
15377 case "$TESTS" in
15378 *%$N%*|*%functions%*|*%bugs%*|*%termios%*|*%tty%*|*%$NAME%*)
15379 TEST="$NAME: Restoring of terminal settings"
15380 # With an outer Socat command create a new pty and a bash in it.
15381 # In this bash store the current terminal settings, then invoke a temporary
15382 # inner Socat command that changes the term to raw mode and terminates.
15383 # When the terminal settings afterwards are the same as before the call the
15384 # test succeeded.
15385 if ! eval $NUMCOND; then :
15386 elif ! $(type stty >/dev/null 2>&1); then
15387 $PRINTF "test $F_n $TEST... ${YELLOW}stty not available${NORMAL}\n" $N
15388 numCANT=$((numCANT+1))
15389 listCANT="$listCANT $N"
15390 elif ! a=$(testfeats STDIO SYSTEM PTY GOPEN); then
15391 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
15392 numCANT=$((numCANT+1))
15393 listCANT="$listCANT $N"
15394 elif ! a=$(testaddrs - STDIO SYSTEM GOPEN); then
15395 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
15396 numCANT=$((numCANT+1))
15397 listCANT="$listCANT $N"
15398 elif ! o=$(testoptions cfmakeraw pty setsid ctty stderr) >/dev/null; then
15399 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15400 numCANT=$((numCANT+1))
15401 listCANT="$listCANT $N"
15402 else
15403 te="$td/test$N.stderr"
15404 tx0="$td/test$N.stty0"
15405 tx1="$td/test$N.stty1"
15406 tdiff="$td/test$N.diff"
15407 da="test$N $(date) $RANDOM"
15408 CMD="$TRACE $SOCAT $opts -lp outersocat - SYSTEM:\"stty\ >$tx0;\ $SOCAT\ -\,cfmakeraw\ /dev/nul\l >${te};\ stty\ >$tx1\",pty,setsid,ctty,stderr"
15409 printf "test $F_n $TEST... " $N
15410 eval "$CMD" >/dev/null 2>${te}.outer
15411 rc=$?
15412 if diff $tx0 $tx1 >$tdiff 2>&1; then
15413 $PRINTF "$OK\n"
15414 if [ "$VERBOSE" ]; then echo "$CMD &"; fi
15415 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15416 numOK=$((numOK+1))
15417 else
15418 $PRINTF "$FAILED\n"
15419 echo "$CMD"
15420 cat "${te}" >&2
15421 cat "${te}.outer" >&2
15422 cat $tdiff >&2
15423 numFAIL=$((numFAIL+1))
15424 listFAIL="$listFAIL $N"
15426 fi # NUMCOND
15428 esac
15429 PORT=$((PORT+1))
15430 N=$((N+1))
15433 # Test if EXEC'd program inherits only the stdio file descriptors
15434 # thus there are no FD leaks from Socat to EXEC'd program
15435 NAME=EXEC_FDS
15436 case "$TESTS" in
15437 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%$NAME%*)
15438 TEST="$NAME: Socat does not leak FDs to EXEC'd program"
15439 # Run Socat with EXEC address, execute Filan to display its file descriptors
15440 # Test succeeds when only FDs 0, 1, 2 are in use.
15441 if ! eval $NUMCOND; then :;
15442 elif ! a=$(testaddrs STDIO EXEC); then
15443 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
15444 numCANT=$((numCANT+1))
15445 listCANT="$listCANT $N"
15446 elif ! o=$(testoptions stderr) >/dev/null; then
15447 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15448 numCANT=$((numCANT+1))
15449 listCANT="$listCANT $N"
15450 else
15451 tf="$td/test$N.stdout"
15452 te="$td/test$N.stderr"
15453 tdiff="$td/test$N.diff"
15454 da="test$N $(date) $RANDOM"
15455 CMD="$TRACE $SOCAT $opts - EXEC:\"$FILAN -s\""
15456 printf "test $F_n $TEST... " $N
15457 eval "$CMD" >"${tf}" 2>"${te}"
15458 # "door" is a special FD type on Solaris/SunOS
15459 if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then
15460 $PRINTF "$OK\n"
15461 if [ "$VERBOSE" ]; then echo "$CMD"; fi
15462 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15463 numOK=$((numOK+1))
15464 else
15465 $PRINTF "$FAILED\n"
15466 echo "$CMD" >&2
15467 cat "${te}" >&2
15468 cat "${tf}" >&2
15469 numFAIL=$((numFAIL+1))
15470 listFAIL="$listFAIL $N"
15472 fi # NUMCOND
15474 esac
15475 PORT=$((PORT+1))
15476 N=$((N+1))
15478 # Test if Socat makes the sniffing file descriptos (-r, -R) CLOEXEC to not leak
15479 # them to EXEC'd program
15480 NAME=EXEC_SNIFF
15481 case "$TESTS" in
15482 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%$NAME%*)
15483 TEST="$NAME: Socat does not leak sniffing FDs"
15484 # Run Socat sniffing both directions, with EXEC address,
15485 # execute Filan to display its file descriptors
15486 # Test succeeds when only FDs 0, 1, 2 are in use.
15487 if ! eval $NUMCOND; then :;
15488 elif ! a=$(testaddrs STDIO EXEC); then
15489 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
15490 numCANT=$((numCANT+1))
15491 listCANT="$listCANT $N"
15492 elif ! o=$(testoptions stderr) >/dev/null; then
15493 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15494 numCANT=$((numCANT+1))
15495 listCANT="$listCANT $N"
15496 else
15497 tf="$td/test$N.stdout"
15498 te="$td/test$N.stderr"
15499 tdiff="$td/test$N.diff"
15500 da="test$N $(date) $RANDOM"
15501 CMD="$TRACE $SOCAT $opts -r $td/test$N.-r -R $td/test$N.-R - EXEC:\"$FILAN -s\""
15502 printf "test $F_n $TEST... " $N
15503 eval "$CMD" >"${tf}" 2>"${te}"
15504 # "door" is a special FD type on Solaris/SunOS
15505 if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then
15506 $PRINTF "$OK\n"
15507 if [ "$VERBOSE" ]; then echo "$CMD"; fi
15508 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15509 numOK=$((numOK+1))
15510 else
15511 $PRINTF "$FAILED\n"
15512 echo "$CMD" >&2
15513 cat "${te}" >&2
15514 cat "${tf}" >&2
15515 numFAIL=$((numFAIL+1))
15516 listFAIL="$listFAIL $N"
15518 fi # NUMCOND
15520 esac
15521 PORT=$((PORT+1))
15522 N=$((N+1))
15525 while read KEYW FEAT RUNS ADDR IPPORT; do
15526 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
15527 PROTO=$KEYW
15528 proto="$(echo "$PROTO" |tr A-Z a-z)"
15529 feat="$(tolower "$FEAT")"
15530 # test the fork option on really RECVFROM oriented sockets
15531 NAME=${KEYW}_FORK
15532 case "$TESTS" in
15533 *%$N%*|*%functions%*|*%fork%*|*%$feat%*|*%$proto%*|*%socket%*|*%$NAME%*)
15534 TEST="$NAME: ${KEYW}-RECVFROM with fork option"
15535 # Start a RECVFROM process with fork option and SYSTEM address where clients
15536 # data determines the sleep time; send a record with sleep before storing the
15537 # data, then send a record with 0 sleep before storing data.
15538 # When the second record is stored before the first one the test succeeded.
15539 if ! eval $NUMCOND; then :;
15540 elif ! F=$(testfeats $FEAT STDIO SYSTEM); then
15541 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
15542 numCANT=$((numCANT+1))
15543 listCANT="$listCANT $N"
15544 elif ! A=$(testaddrs - STDIO SYSTEM $PROTO-RECVFROM $PROTO-SENDTO); then
15545 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
15546 numCANT=$((numCANT+1))
15547 listCANT="$listCANT $N"
15548 elif ! o=$(testoptions fork ) >/dev/null; then
15549 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15550 numCANT=$((numCANT+1))
15551 listCANT="$listCANT $N"
15552 elif ! runs$RUNS >/dev/null; then
15553 $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
15554 numCANT=$((numCANT+1))
15555 listCANT="$listCANT $N"
15556 else
15557 case "X$IPPORT" in
15558 "XPORT")
15559 newport $proto
15560 tsl=$PORT # test socket listen address
15561 tsc="$ADDR:$PORT" # test socket connect address
15564 tsl="$(eval echo "$ADDR")" # resolve $N
15565 tsc=$tsl
15566 esac
15567 #ts="$td/test$N.sock"
15568 tf="$td/test$N.stdout"
15569 te="$td/test$N.stderr"
15570 tdiff="$td/test$N.diff"
15571 da="test$N $(date) $RANDOM"
15572 CMD0="$TRACE $SOCAT $opts -t 3 $PROTO-RECVFROM:$tsl,fork SYSTEM:'read t x; sleep \$t; echo \\\"\$x\\\" >>'\"$tf\""
15573 CMD1="$TRACE $SOCAT $opts -t 3 - $PROTO-SENDTO:$tsc"
15574 printf "test $F_n $TEST... " $N
15575 eval $CMD0 </dev/null 2>"${te}0" &
15576 pid0=$!
15577 wait${proto}port $tsl 1
15578 echo "2 $da 1" |$CMD1 >"${tf}1" 2>"${te}1" &
15579 pid1=$!
15580 sleep 1
15581 echo "0 $da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
15582 pid2=$!
15583 sleep 2
15584 cpids="$(childpids $pid0 </dev/null)"
15585 kill $pid1 $pid2 $cpids $pid0 2>/dev/null
15586 wait 2>/dev/null
15587 if $ECHO "$da 2\n$da 1" |diff - $tf >$tdiff; then
15588 $PRINTF "$OK\n"
15589 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15590 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15591 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
15592 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
15593 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
15594 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
15595 numOK=$((numOK+1))
15596 else
15597 $PRINTF "$FAILED\n"
15598 echo "$CMD0 &"
15599 cat "${te}0" >&2
15600 echo "$CMD1"
15601 cat "${te}1" >&2
15602 echo "$CMD2"
15603 cat "${te}2" >&2
15604 echo "diff:" >&2
15605 cat "$tdiff" >&2
15606 numFAIL=$((numFAIL+1))
15607 listFAIL="$listFAIL $N"
15608 namesFAIL="$namesFAIL $NAME"
15610 fi # NUMCOND
15612 esac
15613 N=$((N+1))
15614 done <<<"
15615 UDP4 UDP ip4 127.0.0.1 PORT
15616 UDP6 UDP ip6 [::1] PORT
15617 UNIX unix unix $td/test\$N.server -
15621 # Test if option -S turns off logging of SIGTERM
15622 NAME=SIGTERM_NOLOG
15623 case "$TESTS" in
15624 *%$N%*|*%functions%*|*%signal%*|*%$NAME%*)
15625 TEST="$NAME: Option -S can turn off logging of SIGTERM"
15626 # Start Socat with option -S 0x0000, kill it with SIGTERM
15627 # When no logging entry regarding this signal is there, the test succeeded
15628 if ! eval $NUMCOND; then :;
15629 elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
15630 $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
15631 numCANT=$((numCANT+1))
15632 listCANT="$listCANT $N"
15633 elif ! F=$(testfeats PIPE); then
15634 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
15635 numCANT=$((numCANT+1))
15636 listCANT="$listCANT $N"
15637 elif ! A=$(testaddrs PIPE); then
15638 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
15639 numCANT=$((numCANT+1))
15640 listCANT="$listCANT $N"
15641 else
15642 tf="$td/test$N.stdout"
15643 te="$td/test$N.stderr"
15644 tdiff="$td/test$N.diff"
15645 CMD0="$TRACE $SOCAT $opts -S 0x0000 PIPE PIPE"
15646 printf "test $F_n $TEST... " $N
15647 $CMD0 >/dev/null 2>"${te}0" &
15648 pid0=$!
15649 relsleep 1 # give process time to start
15650 kill -TERM $pid0 2>/dev/null
15651 wait 2>/dev/null
15652 if ! grep "exiting on signal" ${te}0 >/dev/null; then
15653 $PRINTF "$OK\n"
15654 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15655 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15656 if [ "$DEBUG" ]; then echo "kill -TERM <pid>" >&2; fi
15657 numOK=$((numOK+1))
15658 else
15659 $PRINTF "$FAILED\n"
15660 echo "$CMD0 &"
15661 cat "${te}0" >&2
15662 echo "kill -TERM <pid>" >&2
15663 numFAIL=$((numFAIL+1))
15664 listFAIL="$listFAIL $N"
15665 namesFAIL="$namesFAIL $NAME"
15667 fi # NUMCOND
15669 esac
15670 N=$((N+1))
15673 # Test if option -S turns on logging of signal 31
15674 NAME=SIG31_LOG
15675 case "$TESTS" in
15676 *%$N%*|*%functions%*|*%signal%*|*%$NAME%*)
15677 TEST="$NAME: Option -S can turn on logging of signal 31"
15678 # Start Socat with option -S 0x80000000, kill it with -31
15679 # When a logging entry regarding this signal is there, the test succeeded
15680 if ! eval $NUMCOND; then :;
15681 elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
15682 $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
15683 numCANT=$((numCANT+1))
15684 listCANT="$listCANT $N"
15685 elif ! F=$(testfeats PIPE); then
15686 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
15687 numCANT=$((numCANT+1))
15688 listCANT="$listCANT $N"
15689 elif ! A=$(testaddrs PIPE); then
15690 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
15691 numCANT=$((numCANT+1))
15692 listCANT="$listCANT $N"
15693 else
15694 tf="$td/test$N.stdout"
15695 te="$td/test$N.stderr"
15696 tdiff="$td/test$N.diff"
15697 da="test$N $(date) $RANDOM"
15698 CMD0="$TRACE $SOCAT $opts -S 0x80000000 PIPE PIPE"
15699 printf "test $F_n $TEST... " $N
15700 $CMD0 >/dev/null 2>"${te}0" &
15701 pid0=$!
15702 relsleep 1 # give process time to start
15703 kill -31 $pid0 2>/dev/null; wait
15704 if grep "exiting on signal" ${te}0 >/dev/null; then
15705 $PRINTF "$OK\n"
15706 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15707 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15708 if [ "$DEBUG" ]; then echo "kill -31 <pid>" >&2; fi
15709 numOK=$((numOK+1))
15710 else
15711 $PRINTF "$FAILED\n"
15712 echo "$CMD0 &"
15713 cat "${te}0" >&2
15714 echo "kill -31 <pid>" >&2
15715 numFAIL=$((numFAIL+1))
15716 listFAIL="$listFAIL $N"
15717 namesFAIL="$namesFAIL $NAME"
15719 fi # NUMCOND
15721 esac
15722 N=$((N+1))
15725 # Test the http-version of the PROXY-CONNECT address
15726 NAME=PROXY_HTTPVERSION
15727 case "$TESTS" in
15728 *%$N%*|*%functions%*|*%proxy%*|*%$NAME%*)
15729 TEST="$NAME: PROXY-CONNECT with option http-version"
15730 if ! eval $NUMCOND; then :;
15731 elif ! $(type proxyecho.sh >/dev/null 2>&1); then
15732 $PRINTF "test $F_n $TEST... ${YELLOW}proxyecho.sh not available${NORMAL}\n" $N
15733 numCANT=$((numCANT+1))
15734 listCANT="$listCANT $N"
15735 elif ! F=$(testfeats IP4 TCP LISTEN EXEC STDIO PROXY); then
15736 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
15737 numCANT=$((numCANT+1))
15738 listCANT="$listCANT $N"
15739 elif ! A=$(testaddrs TCP4-LISTEN EXEC STDIO PROXY-CONNECT); then
15740 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
15741 numCANT=$((numCANT+1))
15742 listCANT="$listCANT $N"
15743 elif ! o=$(testoptions so-reuseaddr crlf pf proxyport http-version) >/dev/null; then
15744 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15745 numCANT=$((numCANT+1))
15746 listCANT="$listCANT $N"
15747 elif ! runsip4 >/dev/null; then
15748 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
15749 numCANT=$((numCANT+1))
15750 listCANT="$listCANT $N"
15751 else
15752 ts="$td/test$N.sh"
15753 tf="$td/test$N.stdout"
15754 te="$td/test$N.stderr"
15755 tdiff="$td/test$N.diff"
15756 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
15757 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr,crlf EXEC:\"/usr/bin/env bash proxyecho.sh -V 1.1\""
15758 CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT,http-version=1.1"
15759 printf "test $F_n $TEST... " $N
15760 eval "$CMD0 2>\"${te}1\" &"
15761 pid=$! # background process id
15762 waittcp4port $PORT 1
15763 echo "$da" |$CMD1 >"$tf" 2>"${te}0"
15764 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
15765 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
15766 echo "$CMD0 &"
15767 cat "${te}0" >&2
15768 echo "$CMD1"
15769 cat "${te}1" >&2
15770 echo "diff:" >&2
15771 cat "$tdiff" >&2
15772 numFAIL=$((numFAIL+1))
15773 listFAIL="$listFAIL $N"
15774 else
15775 $PRINTF "$OK\n"
15776 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15777 if [ "$debug" ]; then cat "${te}0" >&2; fi
15778 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
15779 if [ "$debug" ]; then cat "${te}1" >&2; fi
15780 numOK=$((numOK+1))
15782 kill $pid 2>/dev/null
15783 wait
15784 fi ;; # NUMCOND, feats
15785 esac
15786 PORT=$((PORT+1))
15787 N=$((N+1))
15790 # Test the so-rcvtimeo address option with DTLS
15791 NAME=RCVTIMEO_DTLS
15792 case "$TESTS" in
15793 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%timeout%*|*%openssl%*|*%dtls%*|*%$NAME%*)
15794 TEST="$NAME: test the so-rcvtimeo option with DTLS"
15795 if ! eval $NUMCOND; then :;
15796 elif ! F=$(testfeats STDIO OPENSSL); then
15797 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
15798 numCANT=$((numCANT+1))
15799 listCANT="$listCANT $N"
15800 elif ! A=$(testaddrs STDIO DTLS); then
15801 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
15802 numCANT=$((numCANT+1))
15803 listCANT="$listCANT $N"
15804 elif ! o=$(testoptions verify so-rcvtimeo) >/dev/null; then
15805 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15806 numCANT=$((numCANT+1))
15807 listCANT="$listCANT $N"
15808 elif ! runsip4 >/dev/null; then
15809 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
15810 numCANT=$((numCANT+1))
15811 listCANT="$listCANT $N"
15812 else
15813 # We need a hanging connection attempt, guess an address for this
15814 HANGIP=0.0.0.1
15815 te1="$td/test$N.stderr1"
15816 tk1="$td/test$N.kill1"
15817 te2="$td/test$N.stderr2"
15818 tk2="$td/test$N.kill2"
15819 $PRINTF "test $F_n $TEST... " $N
15820 # First, try to make socat hang and see if it can be killed
15821 CMD1="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0"
15822 $CMD1 >"$te1" 2>$te1 </dev/null &
15823 pid1=$!
15824 sleep 2
15825 if ! kill -0 $pid1 2>"$tk1"; then
15826 $PRINTF "${YELLOW}does not hang${NORMAL}\n"
15827 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
15828 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
15829 numCANT=$((numCANT+1))
15830 listCANT="$listCANT $N"
15831 wait
15832 else
15833 # DTLS restarts read() a few times
15834 while kill $pid1 2>/dev/null; do :; done
15835 # Second, set so-rcvtimeo and see if Socat exits before kill
15836 CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=1.0"
15837 $CMD2 >"$te1" 2>$te2 </dev/null &
15838 pid2=$!
15839 sleep 3 # in OpenSSL 1.1.1f DTLS takes two timeouts
15840 if kill $pid2 2>"$tk2"; then
15841 $PRINTF "$FAILED\n"
15842 echo "$CMD2"
15843 cat "$te2" >&2
15844 numFAIL=$((numFAIL+1))
15845 listFAIL="$listFAIL $N"
15846 while kill $pid2 2>/dev/null; do :; done
15847 wait
15848 else
15849 $PRINTF "$OK\n"
15850 if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
15851 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
15852 numOK=$((numOK+1))
15855 wait
15856 fi ;; # testfeats, NUMCOND
15857 esac
15858 N=$((N+1))
15861 # Test the use of interesting variables in the sniffing file names
15862 NAME=VARS_IN_SNIFFPATH
15863 case "$TESTS" in
15864 *%$N%*|*%functions%*|*%socket%*|*%listen%*|*%fork%*|*%$NAME%*)
15865 TEST="$NAME: sniff file names with variables"
15866 # Start a server process with option fork that sniffs traffic and stores it in
15867 # two files for each child process, using PID, timestamp, microseconds, and
15868 # client IP
15869 # Connect two times.
15870 # For now we say that the test succeeded when 4 log files have been generated.
15871 if ! eval $NUMCOND; then :;
15872 elif ! A=$(testfeats IP4 TCP LISTEN PIPE STDIO); then
15873 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
15874 numCANT=$((numCANT+1))
15875 listCANT="$listCANT $N"
15876 elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE STDIO); then
15877 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
15878 numCANT=$((numCANT+1))
15879 listCANT="$listCANT $N"
15880 elif ! o=$(testoptions so-reuseaddr fork) >/dev/null; then
15881 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15882 numCANT=$((numCANT+1))
15883 listCANT="$listCANT $N"
15884 elif ! runsip4 >/dev/null; then
15885 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
15886 numCANT=$((numCANT+1))
15887 listCANT="$listCANT $N"
15888 else
15889 tf="$td/test$N.stdout"
15890 te="$td/test$N.stderr"
15891 tdiff="$td/test$N.diff"
15892 da="test$N $(date) $RANDOM"
15893 newport tcp4
15894 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"
15895 CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$LOCALHOST:$PORT"
15896 printf "test $F_n $TEST... " $N
15897 eval "$CMD0" >/dev/null 2>"${te}0" &
15898 pid0=$!
15899 waittcp4port $PORT 1
15900 echo "$da" |$CMD1 >"${tf}1a" 2>"${te}1a"
15901 rc1a=$?
15902 echo "$da" |$CMD1 >"${tf}1b" 2>"${te}1b"
15903 rc1b=$?
15904 kill $(childpids $pid0) $pid0 2>/dev/null
15905 wait 2>/dev/null
15906 if [ $rc1a != 0 -o $rc1b != 0 ]; then
15907 $PRINTF "$FAILED (client problem)\n"
15908 echo "$CMD0 &"
15909 cat "${te}0" >&2
15910 echo "$CMD1"
15911 cat "${te}1a" >&2
15912 echo "$CMD1"
15913 cat "${te}1b" >&2
15914 numFAIL=$((numFAIL+1))
15915 listFAIL="$listFAIL $N"
15916 namesFAIL="$namesFAIL $NAME"
15917 elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 &&
15918 test $(ls $td/test$N.*.log |head -n 1 |wc -c) -ge 56; then
15919 # Are the names correct?
15920 # Convert timestamps to epoch and compare
15921 # Are the contents correct?
15922 $PRINTF "$OK\n"
15923 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15924 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15925 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
15926 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
15927 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
15928 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
15929 numOK=$((numOK+1))
15930 elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.in.log; then
15931 $PRINTF "$FAILED (vars not resolved)\n"
15932 echo "$CMD0 &"
15933 cat "${te}0" >&2
15934 echo "$CMD1"
15935 cat "${te}1a" >&2
15936 echo "$CMD1"
15937 cat "${te}1b" >&2
15938 numFAIL=$((numFAIL+1))
15939 listFAIL="$listFAIL $N"
15940 namesFAIL="$namesFAIL $NAME"
15941 else
15942 $PRINTF "$FAILED (unknown)\n"
15943 echo "$CMD0 &"
15944 cat "${te}0" >&2
15945 echo "$CMD1"
15946 cat "${te}1a" >&2
15947 echo "$CMD1"
15948 cat "${te}1b" >&2
15949 numFAIL=$((numFAIL+1))
15950 listFAIL="$listFAIL $N"
15951 namesFAIL="$namesFAIL $NAME"
15953 fi # NUMCOND
15955 esac
15956 N=$((N+1))
15959 # Test logging of statistics on Socat option --statistics
15960 NAME=OPTION_STATISTICS
15961 case "$TESTS" in
15962 *%$N%*|*%functions%*|*%stats%*|*%system%*|*%stdio%*|*%$NAME%*)
15963 TEST="$NAME: Socat option --statistics"
15964 # Invoke Socat with option --statistics, transfer some date, and check the log
15965 # file for the values
15966 if ! eval $NUMCOND; then :;
15967 elif ! $(type >/dev/null 2>&1); then
15968 $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N
15969 numCANT=$((numCANT+1))
15970 listCANT="$listCANT $N"
15971 elif ! F=$(testfeats STATS STDIO SYSTEM); then
15972 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
15973 numCANT=$((numCANT+1))
15974 listCANT="$listCANT $N"
15975 elif ! A=$(testaddrs STDIO SYSTEM); then
15976 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
15977 numCANT=$((numCANT+1))
15978 listCANT="$listCANT $N"
15979 elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then
15980 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15981 numCANT=$((numCANT+1))
15982 listCANT="$listCANT $N"
15983 else
15984 tf="$td/test$N.stdout"
15985 te="$td/test$N.stderr"
15986 tdiff="$td/test$N.diff"
15987 da="test$N $(date) $RANDOM"
15988 CMD0="$TRACE $SOCAT $opts --statistics STDIO SYSTEM:'tee /dev/stdout',pty,cfmakeraw"
15989 printf "test $F_n $TEST... " $N
15990 echo "$da" |eval "$CMD0" >"${tf}0" 2>"${te}0"
15991 rc0=$?
15992 if [ $rc0 -ne 0 ]; then
15993 # The test could not run meaningfully
15994 $PRINTF "$CANT\n"
15995 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
15996 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15997 numCANT=$((numCANT+1))
15998 listCANT="$listCANT $N"
15999 elif [ $(grep STATISTICS "${te}0" |wc -l) -eq 2 ]; then
16000 $PRINTF "$OK\n"
16001 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
16002 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16003 numOK=$((numOK+1))
16004 else
16005 $PRINTF "$FAILED\n"
16006 echo "$CMD0 &"
16007 cat "${te}0" >&2
16008 numFAIL=$((numFAIL+1))
16009 listFAIL="$listFAIL $N"
16010 namesFAIL="$namesFAIL $NAME"
16012 fi # NUMCOND
16014 esac
16015 N=$((N+1))
16017 # Test logging of statistics on SIGUSR1
16018 NAME=SIGUSR1_STATISTICS
16019 case "$TESTS" in
16020 *%$N%*|*%functions%*|*%signal%*|*%stats%*|*%system%*|*%stdio%*|*%$NAME%*)
16021 TEST="$NAME: statistics on SIGUSR1"
16022 # Invoke Socat without option --statistics, transfer some date, send signal
16023 # USR1,and check the log file for the values
16024 if ! eval $NUMCOND; then :;
16025 elif ! $(type tee >/dev/null 2>&1); then
16026 $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N
16027 numCANT=$((numCANT+1))
16028 listCANT="$listCANT $N"
16029 elif ! $(type pkill >/dev/null 2>&1); then
16030 $PRINTF "test $F_n $TEST... ${YELLOW}pkill not available${NORMAL}\n" $N
16031 numCANT=$((numCANT+1))
16032 listCANT="$listCANT $N"
16033 elif ! F=$(testfeats STATS STDIO SYSTEM); then
16034 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16035 numCANT=$((numCANT+1))
16036 listCANT="$listCANT $N"
16037 elif ! A=$(testaddrs STDIO SYSTEM); then
16038 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16039 numCANT=$((numCANT+1))
16040 listCANT="$listCANT $N"
16041 elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then
16042 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16043 numCANT=$((numCANT+1))
16044 listCANT="$listCANT $N"
16045 else
16046 tf="$td/test$N.stdout"
16047 te="$td/test$N.stderr"
16048 tdiff="$td/test$N.diff"
16049 da="test$N $(date) $RANDOM"
16050 CMD0="$TRACE $SOCAT $opts STDIO SYSTEM:'tee /dev/stdout 2>/dev/null',pty,cfmakeraw"
16051 #set -vx
16052 printf "test $F_n $TEST... " $N
16053 { echo "$da"; relsleep 3; } |eval "$CMD0" >"${tf}0" 2>"${te}0" &
16054 pid0=$!
16055 relsleep 2
16056 TTY=$(tty |sed 's|/dev/||')
16057 pkill -USR1 -t $TTY socat || { echo "pkill -t $TTY -USR1 socat"; }
16058 relsleep 1
16059 pkill -t $TTY socat
16060 wait
16061 if [ "$(grep STATISTICS "${te}0" |wc -l)" -eq 2 ]; then
16062 $PRINTF "$OK\n"
16063 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
16064 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16065 numOK=$((numOK+1))
16066 else
16067 $PRINTF "$FAILED\n"
16068 echo "$CMD0 &"
16069 cat "${te}0" >&2
16070 numFAIL=$((numFAIL+1))
16071 listFAIL="$listFAIL $N"
16072 namesFAIL="$namesFAIL $NAME"
16074 fi # NUMCOND
16076 esac
16077 N=$((N+1))
16080 # Test the children-shutup option
16081 NAME=CHILDREN_SHUTUP
16082 case "$TESTS" in
16083 *%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*)
16084 TEST="$NAME: test the children-shutup option"
16085 # Run a UNIX domain listening server with options fork and children-shutup, and
16086 # that connects to a closed TCP4 port.
16087 # Connect to the server and check if it logs the TCP4-CONNECT failure as warning.
16088 if ! eval $NUMCOND; then :;
16089 elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then
16090 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16091 numCANT=$((numCANT+1))
16092 listCANT="$listCANT $N"
16093 elif ! A=$(testaddrs UNIX-LISTEN TCP4 FILE UNIX-CONNECT); then
16094 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16095 numCANT=$((numCANT+1))
16096 listCANT="$listCANT $N"
16097 elif ! o=$(testoptions fork children-shutup) >/dev/null; then
16098 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16099 numCANT=$((numCANT+1))
16100 listCANT="$listCANT $N"
16101 else
16102 newport tcp4
16103 ts="$td/test$N.sock"
16104 tf="$td/test$N.stdout"
16105 te="$td/test$N.stderr"
16106 tdiff="$td/test$N.diff"
16107 da="test$N $(date) $RANDOM"
16108 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,fork,children-shutup TCP4:localhost:$PORT"
16109 CMD1="$TRACE $SOCAT $opts -u FILE:/dev/null UNIX-CONNECT:$ts"
16110 printf "test $F_n $TEST... " $N
16111 $CMD0 >/dev/null 2>"${te}0" &
16112 pid0=$!
16113 waitunixport $ts 1
16114 { $CMD1 2>"${te}1"; sleep 1; }
16115 rc1=$?
16116 kill $pid0 2>/dev/null; wait
16117 relsleep 1 # child process might need more time
16118 if grep -q " W connect" ${te}0; then
16119 $PRINTF "$OK\n"
16120 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16121 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16122 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16123 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16124 numOK=$((numOK+1))
16125 else
16126 $PRINTF "$FAILED\n"
16127 echo "$CMD0 &"
16128 cat "${te}0" >&2
16129 echo "$CMD1"
16130 cat "${te}1" >&2
16131 numFAIL=$((numFAIL+1))
16132 listFAIL="$listFAIL $N"
16133 namesFAIL="$namesFAIL $NAME"
16135 fi # NUMCOND
16137 esac
16138 N=$((N+1))
16141 # Socats INTERFACE address has to ignore outgoing packets if possible.
16142 # On Linux is uses socket option PACKET_IGNORE_OUTGOING or it queries per
16143 # packet the PACKET_OUTGOING flag of struct sockaddr_ll.sll_pkttype
16144 NAME=INTERFACE_IGNOREOUTGOING
16145 case "$TESTS" in
16146 *%$N%*|*%functions%*|*%interface%*|*%tun%*|*%root%*|*%$NAME%*)
16147 TEST="$NAME: INTERFACE ignores outgoing packets"
16148 #idea: create a TUN interface and hook with INTERFACE.
16149 # Send a packet out the interface, should not be seen by INTERFACE
16150 if ! eval $NUMCOND; then :;
16151 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
16152 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
16153 numCANT=$((numCANT+1))
16154 listCANT="$listCANT $N"
16155 elif ! $(type ping >/dev/null 2>&1); then
16156 $PRINTF "test $F_n $TEST... ${YELLOW}ping not available${NORMAL}\n" $N
16157 numCANT=$((numCANT+1))
16158 listCANT="$listCANT $N"
16159 elif ! feat=$(testfeats TUN STDIO INTERFACE); then
16160 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
16161 numCANT=$((numCANT+1))
16162 listCANT="$listCANT $N"
16163 elif ! A=$(testaddrs - TUN STDIO INTERFACE); then
16164 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16165 numCANT=$((numCANT+1))
16166 listCANT="$listCANT $N"
16167 elif ! o=$(testoptions iff-up tun-type tun-name ) >/dev/null; then
16168 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16169 numCANT=$((numCANT+1))
16170 listCANT="$listCANT $N"
16171 elif ! runsip4 >/dev/null; then
16172 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16173 numCANT=$((numCANT+1))
16174 listCANT="$listCANT $N"
16175 else
16176 tf="$td/test$N.stdout"
16177 te="$td/test$N.stderr"
16178 tdiff="$td/test$N.diff"
16179 tl="$td/test$N.lock"
16180 da="$(date) $RANDOM"
16181 TUNNET=10.255.255
16182 TUNNAME=tun9
16183 CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME -"
16184 CMD1="$TRACE $SOCAT $opts -u INTERFACE:$TUNNAME -"
16185 CMD2="ping -c 1 -w 1 -b $TUNNET.255"
16186 printf "test $F_n $TEST... " $N
16187 sleep 1 |$CMD0 2>"${te}0" >/dev/null &
16188 pid0="$!"
16189 #waitinterface "$TUNNAME"
16190 usleep $MICROS
16191 $CMD1 >"${tf}1" 2>"${te}1" &
16192 pid1="$!"
16193 usleep $MICROS
16194 $CMD2 2>"${te}2" 1>&2
16195 kill $pid1 2>/dev/null
16196 usleep $MICROS
16197 kill $pid0 2>/dev/null
16198 wait
16199 if [ $? -ne 0 ]; then
16200 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
16201 echo "$CMD0 &"
16202 cat "${te}0" >&2
16203 echo "$CMD1"
16204 cat "${te}1" >&2
16205 echo "$CMD2"
16206 cat "${te}2" >&2
16207 numCANT=$((numCANT+1))
16208 listCANT="$listCANT $N"
16209 elif test -s "${tf}1"; then
16210 $PRINTF "$FAILED\n"
16211 echo "$CMD0 &"
16212 cat "${te}0" >&2
16213 echo "$CMD1"
16214 cat "${te}1" >&2
16215 echo "$CMD2"
16216 cat "${te}2" >&2
16217 numFAIL=$((numFAIL+1))
16218 listFAIL="$listFAIL $N"
16219 else
16220 $PRINTF "$OK\n"
16221 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16222 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16223 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16224 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16225 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
16226 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
16227 numOK=$((numOK+1))
16229 fi ;; # NUMCOND, feats
16230 esac
16231 PORT=$((PORT+1))
16232 N=$((N+1))
16235 # Test if the SO_REUSEADDR socket option is applied automatically to TCP LISTEN
16236 # type addresses.
16237 NAME=TCP4_REUSEADDR
16238 case "$TESTS" in
16239 *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*)
16240 TEST="$NAME: test if option reuseaddr's default is 1"
16241 # Start a TCP4-LISTEN server, connect with a client, have the server shutdown
16242 # the connection. Start the server on the same port again. If it starts the
16243 # test succeeded.
16244 if ! eval $NUMCOND; then :;
16245 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
16246 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16247 numCANT=$((numCANT+1))
16248 listCANT="$listCANT $N"
16249 elif ! A=$(testaddrs STDIO PIPE TCP4 TCP4-LISTEN); then
16250 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16251 numCANT=$((numCANT+1))
16252 listCANT="$listCANT $N"
16253 elif ! o=$(testoptions accept-timeout) >/dev/null; then
16254 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16255 numCANT=$((numCANT+1))
16256 listCANT="$listCANT $N"
16257 elif ! runsip4 >/dev/null; then
16258 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16259 numCANT=$((numCANT+1))
16260 listCANT="$listCANT $N"
16261 else
16262 tf="$td/test$N.stdout"
16263 te="$td/test$N.stderr"
16264 tdiff="$td/test$N.diff"
16265 da="test$N $(date) $RANDOM"
16266 newport tcp4
16267 CMD0a="$TRACE $SOCAT $opts -T 0.1 TCP4-LISTEN:$PORT PIPE"
16268 CMD0b="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,accept-timeout=0.1 PIPE"
16269 CMD1="$TRACE $SOCAT $opts STDIO TCP4-CONNECT:$LOCALHOST:$PORT"
16270 printf "test $F_n $TEST... " $N
16271 $CMD0a >/dev/null 2>"${te}0a" &
16272 pid0=$!
16273 waittcp4port $PORT 1
16274 $CMD1 >"${tf}1" 2>"${te}1"
16275 rc1=$?
16276 kill $pid0 2>/dev/null; wait
16277 $CMD0b >/dev/null 2>"${te}0b"
16278 rc0b=$?
16279 if [ $rc0b -eq 0 ]; then
16280 $PRINTF "$OK\n"
16281 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16282 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16283 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16284 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16285 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16286 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16287 numOK=$((numOK+1))
16288 else
16289 $PRINTF "$FAILED\n"
16290 echo "$CMD0a &"
16291 cat "${te}0a" >&2
16292 echo "$CMD1"
16293 cat "${te}1" >&2
16294 echo "$CMD0b"
16295 cat "${te}0b" >&2
16296 numFAIL=$((numFAIL+1))
16297 listFAIL="$listFAIL $N"
16298 namesFAIL="$namesFAIL $NAME"
16300 fi # NUMCOND
16302 esac
16303 N=$((N+1))
16305 # Test if the SO_REUSEADDR socket option is applied automatically to OPENSSL LISTEN
16306 # type addresses.
16307 NAME=OPENSSL_6_REUSEADDR
16308 case "$TESTS" in
16309 *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip6%*|*%tcp%*|*%tcp6%*|*%listen%*|*%openssl%*|*%$NAME%*)
16310 TEST="$NAME: test if option reuseaddr's default is 1 with SSL-L"
16311 # Start an OPENSSL-LISTEN server using TCP on IPv6, connect with a client, have
16312 # the server shutdown the connection. Start the server on the same port again.
16313 # If it starts the test succeeded.
16314 if ! eval $NUMCOND; then :;
16315 elif ! F=$(testfeats PIPE IP6 TCP OPENSSL LISTEN); then
16316 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16317 numCANT=$((numCANT+1))
16318 listCANT="$listCANT $N"
16319 elif ! A=$(testaddrs PIPE OPENSSL-CONNECT OPENSSL-LISTEN); then
16320 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16321 numCANT=$((numCANT+1))
16322 listCANT="$listCANT $N"
16323 elif ! o=$(testoptions verify cert key) >/dev/null; then
16324 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16325 numCANT=$((numCANT+1))
16326 listCANT="$listCANT $N"
16327 elif ! runsip6 >/dev/null; then
16328 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
16329 numCANT=$((numCANT+1))
16330 listCANT="$listCANT $N"
16331 else
16332 tf="$td/test$N.stdout"
16333 te="$td/test$N.stderr"
16334 tdiff="$td/test$N.diff"
16335 da="test$N $(date) $RANDOM"
16336 printf "test $F_n $TEST... " $N
16337 newport tcp6
16338 # Yup, it seems that with OpenSSL the side that begins with shutdown does NOT
16339 # begin shutdown of the TCP connection
16340 # therefore we let the client timeout
16341 # result is not reliable (OK seen even without any SO_REUSEADDR)
16342 CMD0a="$TRACE $SOCAT $opts -lp server1 -6 OPENSSL-LISTEN:$PORT,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
16343 CMD0b="$TRACE $SOCAT $opts -lp server2 -6 OPENSSL-LISTEN:$PORT,accept-timeout=.01,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
16344 CMD1="$TRACE $SOCAT $opts -lp client -6 -T 0.1 PIPE OPENSSL-CONNECT:$LOCALHOST6:$PORT,verify=0"
16345 $CMD0a >/dev/null 2>"${te}0a" &
16346 pid0=$!
16347 waittcp6port $PORT 1
16348 $CMD1 >"${tf}1" 2>"${te}1"
16349 rc1=$?
16350 kill $pid0 2>/dev/null; wait
16351 $CMD0b >/dev/null 2>"${te}0b"
16352 rc0b=$?
16353 if [ $rc0b -eq 0 ]; then
16354 $PRINTF "$OK\n"
16355 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16356 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16357 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16358 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16359 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16360 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16361 numOK=$((numOK+1))
16362 else
16363 $PRINTF "$FAILED\n"
16364 echo "$CMD0a &"
16365 cat "${te}0a" >&2
16366 echo "$CMD1"
16367 cat "${te}1" >&2
16368 echo "$CMD0b"
16369 cat "${te}0b" >&2
16370 numFAIL=$((numFAIL+1))
16371 listFAIL="$listFAIL $N"
16372 namesFAIL="$namesFAIL $NAME"
16374 fi # NUMCOND
16376 esac
16377 N=$((N+1))
16379 # Test if the so-reuseaddr= option prevents the SO_REUSEADDR socket option
16380 NAME=REUSEADDR_NULL
16381 case "$TESTS" in
16382 *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*)
16383 TEST="$NAME: test option reuseaddr without value"
16384 # Start a TCP4-LISTEN server with so-reuseaddr=, connect with a client, have
16385 # the server shutdown the connection.
16386 # Start the server on the same port again. If it fails with
16387 # "Address already in use" the test succeeded.
16388 if ! eval $NUMCOND; then :;
16389 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
16390 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16391 numCANT=$((numCANT+1))
16392 listCANT="$listCANT $N"
16393 elif ! A=$(testaddrs STDIO PIPE TCP4-CONNECT TCP4-LISTEN); then
16394 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16395 numCANT=$((numCANT+1))
16396 listCANT="$listCANT $N"
16397 elif ! o=$(testoptions so-reuseaddr accept-timeout) >/dev/null; then
16398 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16399 numCANT=$((numCANT+1))
16400 listCANT="$listCANT $N"
16401 elif ! runsip4 >/dev/null; then
16402 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16403 numCANT=$((numCANT+1))
16404 listCANT="$listCANT $N"
16405 else
16406 tf="$td/test$N.stdout"
16407 te="$td/test$N.stderr"
16408 tdiff="$td/test$N.diff"
16409 da="test$N $(date) $RANDOM"
16410 newport tcp4
16411 CMD0a="$TRACE $SOCAT $opts -T 0.1 TCP4-LISTEN:$PORT,so-reuseaddr= PIPE"
16412 CMD0b="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,accept-timeout=0.1 PIPE"
16413 CMD1="$TRACE $SOCAT $opts STDIO TCP4-CONNECT:$LOCALHOST:$PORT"
16414 printf "test $F_n $TEST... " $N
16415 $CMD0a >/dev/null 2>"${te}0a" &
16416 pid0=$!
16417 waittcp4port $PORT 1
16418 $CMD1 >"${tf}1" 2>"${te}1"
16419 rc1=$?
16420 kill $pid0 2>/dev/null; wait
16421 $CMD0b >/dev/null 2>"${te}0b"
16422 rc0b=$?
16423 if [ $rc0b -eq 1 ] && grep -q -e "Address already in use" -e "Address in use" "${te}0b"; then
16424 $PRINTF "$OK\n"
16425 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16426 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16427 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16428 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16429 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16430 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16431 numOK=$((numOK+1))
16432 #elif grep -q "accept: \(Connection\|Operation\) timed out" "${te}0b"; then
16433 elif grep -q "accept: .* timed out" "${te}0b"; then
16434 # FreeBSD, Solaris do not seem to need SO_REUSEADDR with TCP at all
16435 $PRINTF "$CANT\n"
16436 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16437 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16438 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16439 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16440 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16441 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16442 numCANT=$((numCANT+1))
16443 listCANT="$listCANT $N"
16444 else
16445 $PRINTF "$FAILED\n"
16446 echo "$CMD0a &"
16447 cat "${te}0a" >&2
16448 echo "$CMD1"
16449 cat "${te}1" >&2
16450 echo "$CMD0b"
16451 cat "${te}0b" >&2
16452 numFAIL=$((numFAIL+1))
16453 listFAIL="$listFAIL $N"
16454 namesFAIL="$namesFAIL $NAME"
16456 fi # NUMCOND
16458 esac
16459 N=$((N+1))
16462 # Test if Socats TCP4-client tries all addresses if necessary
16463 NAME=TRY_ADDRS_4
16464 case "$TESTS" in
16465 *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%socket%*|*%internet%*|*%$NAME%*)
16466 TEST="$NAME: try all available TCP4 addresses"
16467 # Connect to a TCP4 port of a hostname that resolves to two addresses where at
16468 # least on the first one the port is closed.
16469 # server-4.dest-unreach.net has been configured for this purpose, it
16470 # resolves to its public address and to 127.0.0.1; unfortunately
16471 # forwarding nameservers need not keep order of A entries, so we need a port
16472 # that is closed on both addresses.
16473 # The test succeeded when the log shows that Socat tried to connect two times.
16474 if ! eval $NUMCOND; then :;
16475 elif ! $(type nslookup >/dev/null 2>&1); then
16476 $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N
16477 numCANT=$((numCANT+1))
16478 listCANT="$listCANT $N"
16479 #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
16480 # $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
16481 # numCANT=$((numCANT+1))
16482 # listCANT="$listCANT $N"
16483 elif ! F=$(testfeats IP4 TCP GOPEN); then
16484 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16485 numCANT=$((numCANT+1))
16486 listCANT="$listCANT $N"
16487 elif ! A=$(testaddrs TCP4-CONNECT GOPEN); then
16488 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16489 numCANT=$((numCANT+1))
16490 listCANT="$listCANT $N"
16491 elif ! runsip4 >/dev/null; then
16492 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16493 numCANT=$((numCANT+1))
16494 listCANT="$listCANT $N"
16495 elif [ -z "$INTERNET" ]; then
16496 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
16497 numCANT=$((numCANT+1))
16498 listCANT="$listCANT $N"
16499 else
16500 tf="$td/test$N.stdout"
16501 te="$td/test$N.stderr"
16502 tdiff="$td/test$N.diff"
16503 da="test$N $(date) $RANDOM"
16504 if type nslookup >/dev/null 2>&1; then
16505 ADDRS=$(nslookup server-4.dest-unreach.net. |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
16506 elif type host >/dev/null 2>&1; then
16507 ADDRS=$(host server-4.dest-unreach.net. |sed 's/.*address //')
16509 while true; do
16510 newport tcp4
16511 OPEN=
16512 for addr in $ADDRS; do
16513 if $SOCAT /dev/null TCP4:$addr:$PORT 2>/dev/null; then
16514 # port is open :-(
16515 OPEN=1
16516 break
16518 done
16519 if [ -z "$OPEN" ]; then
16520 break;
16522 newport tcp4
16523 done
16524 CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP4:server-4.dest-unreach.net:$PORT"
16525 printf "test $F_n $TEST... " $N
16526 $CMD >/dev/null 2>"${te}"
16527 rc=$?
16528 if [ $(grep " N opening connection to .*AF=2 " ${te} |wc -l) -eq 2 ]; then
16529 $PRINTF "$OK\n"
16530 if [ "$VERBOSE" ]; then echo "$CMD"; fi
16531 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
16532 numOK=$((numOK+1))
16533 else
16534 $PRINTF "$FAILED\n"
16535 echo "$CMD"
16536 cat "${te}" >&2
16537 numFAIL=$((numFAIL+1))
16538 listFAIL="$listFAIL $N"
16539 namesFAIL="$namesFAIL $NAME"
16541 fi # NUMCOND
16543 esac
16544 N=$((N+1))
16547 # Test if Socats TCP-client tries all addresses (IPv4+IPv6) if necessary
16548 # Gives useful result only when getaddrinfo() to return both IPv4 and IPv6 addresses
16549 # Therefore it appears useful to use AI-ADDRCONFIG on non-Linux systems
16550 NAME=TRY_ADDRS_4_6
16551 case "$TESTS" in
16552 *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%tcp6%*|*%socket%*|*%internet%*|*%$NAME%*)
16553 TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses"
16554 # Connect to a TCP port that is not open on localhost-4-6.dest-unreach.net,
16555 # neither IPv4 nor IPv6
16556 # Check the log if Socat tried both addresses
16557 if ! eval $NUMCOND; then :;
16558 #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
16559 # $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
16560 # numCANT=$((numCANT+1))
16561 # listCANT="$listCANT $N"
16562 elif ! F=$(testfeats IP4 IP6 TCP); then
16563 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16564 numCANT=$((numCANT+1))
16565 listCANT="$listCANT $N"
16566 elif ! A=$(testaddrs TCP-CONNECT GOPEN); then
16567 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16568 numCANT=$((numCANT+1))
16569 listCANT="$listCANT $N"
16570 elif ! runsip4 >/dev/null; then
16571 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16572 numCANT=$((numCANT+1))
16573 listCANT="$listCANT $N"
16574 elif ! runsip6 >/dev/null; then
16575 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N
16576 numCANT=$((numCANT+1))
16577 listCANT="$listCANT $N"
16578 elif [ -z "$INTERNET" ]; then # only needs Internet DNS
16579 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
16580 numCANT=$((numCANT+1))
16581 listCANT="$listCANT $N"
16582 else
16583 tf="$td/test$N.stdout"
16584 te="$td/test$N.stderr"
16585 tdiff="$td/test$N.diff"
16586 da="test$N $(date) $RANDOM"
16587 LOCALHOST_4_6=localhost-4-6.dest-unreach.net
16588 if type nslookup >/dev/null 2>&1; then
16589 ADDRS=$(nslookup $LOCALHOST_4_6 |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
16590 elif type host >/dev/null 2>&1; then
16591 ADDRS=$(host $LOCALHOST_4_6 |sed 's/.*address //')
16593 # Specific config: on Ubuntu-12.04: getaddrinfo(...AI_ADDRCONFIG) does not
16594 # resolve to IPv6 addresses even when there are link local IPv6 addresses
16595 if test -f /etc/os-release &&
16596 grep -q '^NAME="Ubuntu"' /etc/os-release &&
16597 grep -q '^VERSION="12\.04' /etc/os-release; then
16598 AI_ADDRCONFIG="ai-addrconfig=0,"
16599 elif [ $UNAME != 'Linux' ]; then
16600 AI_ADDRCONFIG="ai-addrconfig=0,"
16602 # Check if PORT is really closed on both addresses
16603 while true; do
16604 OPEN=
16605 for addr in $ADDRS; do
16606 case $addr in
16607 *.*) ;;
16608 *:*) addr="[$addr]" ;
16609 esac
16610 if $SOCAT /dev/null TCP:$addr:$PORT,$AI_ADDRCONFIG 2>/dev/null; then
16611 # port is open :-(
16612 OPEN=1
16613 break
16615 done
16616 if [ -z "$OPEN" ]; then
16617 break;
16619 newport tcp4
16620 done
16621 CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP:$LOCALHOST_4_6:$PORT,$AI_ADDRCONFIG"
16622 printf "test $F_n $TEST... " $N
16623 $CMD >/dev/null 2>"${te}"
16624 rc=$?
16625 if [ $(grep " N opening connection to .*AF=[0-9]" ${te} |wc -l) -eq 2 ]; then
16626 $PRINTF "$OK\n"
16627 if [ "$VERBOSE" ]; then echo "$CMD"; fi
16628 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
16629 numOK=$((numOK+1))
16630 else
16631 $PRINTF "$FAILED\n"
16632 echo "$CMD"
16633 cat "${te}" >&2
16634 numFAIL=$((numFAIL+1))
16635 listFAIL="$listFAIL $N"
16636 namesFAIL="$namesFAIL $NAME"
16638 fi # NUMCOND
16640 esac
16641 N=$((N+1))
16644 # Test the netns (net namespace) feature
16645 NAME=NETNS
16646 case "$TESTS" in
16647 *%$N%*|*%functions%*|*%root%*|*%namespace%*|*%netns%*|*%socket%*|*%$NAME%*)
16648 ns=socat-$$-test$N
16649 TEST="$NAME: option netns (net namespace $ns)"
16650 # Start a simple echo server with option netns on localhost of a net namespace;
16651 # use a client process with option netns to send data to the net namespace
16652 # net server and check the reply.
16653 if ! eval $NUMCOND; then :;
16654 elif [ "$UNAME" != Linux ]; then
16655 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
16656 numCANT=$((numCANT+1))
16657 listCANT="$listCANT $N"
16658 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
16659 $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
16660 numCANT=$((numCANT+1))
16661 listCANT="$listCANT $N"
16662 elif ! $(type ip >/dev/null 2>&1); then
16663 $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N
16664 numCANT=$((numCANT+1))
16665 listCANT="$listCANT $N"
16666 elif ! F=$(testfeats IP4 TCP LISTEN NAMESPACES); then
16667 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16668 numCANT=$((numCANT+1))
16669 listCANT="$listCANT $N"
16670 elif ! A=$(testaddrs STDIO TCP-LISTEN TCP EXEC); then
16671 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16672 numCANT=$((numCANT+1))
16673 listCANT="$listCANT $N"
16674 elif ! o=$(testoptions netns) >/dev/null; then
16675 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16676 numCANT=$((numCANT+1))
16677 listCANT="$listCANT $N"
16678 elif ! runsip4 >/dev/null; then
16679 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16680 numCANT=$((numCANT+1))
16681 listCANT="$listCANT $N"
16682 else
16683 tf="$td/test$N.stdout"
16684 te="$td/test$N.stderr"
16685 tdiff="$td/test$N.diff"
16686 da="test$N $(date) $RANDOM"
16687 newport tcp4
16688 CMD0="$TRACE $SOCAT $opts --experimental TCP4-LISTEN:$PORT,netns=$ns EXEC:'od -c'"
16689 CMD1="$TRACE $SOCAT $opts --experimental - TCP4:127.0.0.1:$PORT,netns=$ns"
16690 printf "test $F_n $TEST... " $N
16691 ip netns del $ns 2>/dev/null # make sure it does not exist
16692 ip netns add $ns
16693 ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8
16694 ip netns exec $ns ip link set lo up
16695 eval "$CMD0" >/dev/null 2>"${te}0" &
16696 pid0=$!
16697 relsleep 1 # if no matching wait*port function
16698 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
16699 rc1=$?
16700 kill $pid0 2>/dev/null; wait
16701 ip netns del $ns
16702 if [ $rc1 -ne 0 ]; then
16703 $PRINTF "$FAILED (client failed)\n"
16704 echo "ip netns del $ns"
16705 echo "ip netns add $ns"
16706 echo "ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8"
16707 echo "ip netns exec $ns ip link set lo up"
16708 echo "$CMD0 &"
16709 cat "${te}0" >&2
16710 echo "$CMD1"
16711 cat "${te}1" >&2
16712 echo "ip netns del $ns"
16713 numFAIL=$((numFAIL+1))
16714 listFAIL="$listFAIL $N"
16715 namesFAIL="$namesFAIL $NAME"
16716 elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then
16717 $PRINTF "$OK\n"
16718 if [ "$VERBOSE" ]; then
16719 echo "ip netns del $ns"
16720 echo "ip netns add $ns"
16721 echo "ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8"
16722 echo "ip netns exec $ns ip link set lo up"
16724 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16725 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16726 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16727 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16728 if [ "$VERBOSE" ]; then echo "ip netns del $ns"; fi
16729 numOK=$((numOK+1))
16730 else
16731 $PRINTF "$FAILED (bad output)\n"
16732 echo "$CMD0 &"
16733 cat "${te}0" >&2
16734 echo "$CMD1"
16735 cat "${te}1" >&2
16736 diff:
16737 cat "$tdiff"
16738 numFAIL=$((numFAIL+1))
16739 listFAIL="$listFAIL $N"
16740 namesFAIL="$namesFAIL $NAME"
16742 fi # NUMCOND
16744 esac
16745 N=$((N+1))
16747 # Test the netns (net namespace) feature with EXEC and reset
16748 NAME=NETNS_EXEC
16749 case "$TESTS" in
16750 *%$N%*|*%functions%*|*%root%*|*%namespace%*|*%netns%*|*%socket%*|*%abstract%*|*%dgram%*|*%$NAME%*)
16751 ns=socat-$$-test$N
16752 TEST="$NAME: option netns with EXEC (net namespace $ns)"
16753 # Start a simple server with option netns on localhost of a net namespace that
16754 # stores data it receives;
16755 # use a middle process that EXECs a socat client that connects to the server on
16756 # the net namespace; then it listens on default namespace.
16757 # With a third command line connect and send data to the middle process.
16758 # When the data received by the server is correct the test succeeded.
16759 if ! eval $NUMCOND; then :;
16760 elif [ "$UNAME" != Linux ]; then
16761 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
16762 numCANT=$((numCANT+1))
16763 listCANT="$listCANT $N"
16764 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
16765 $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
16766 numCANT=$((numCANT+1))
16767 listCANT="$listCANT $N"
16768 elif ! $(type ip >/dev/null 2>&1); then
16769 $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N
16770 numCANT=$((numCANT+1))
16771 listCANT="$listCANT $N"
16772 elif ! F=$(testfeats IP4 ABSTRACT_UNIXSOCKET UDP LISTEN NAMESPACES STDIO); then
16773 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16774 numCANT=$((numCANT+1))
16775 listCANT="$listCANT $N"
16776 elif ! A=$(testaddrs ABSTRACT-RECV ABSTRACT-SENDTO CREATE EXEC UDP4-RECV STDIO UDP4); then
16777 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
16778 numCANT=$((numCANT+1))
16779 listCANT="$listCANT $N"
16780 elif ! o=$(testoptions netns) >/dev/null; then
16781 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16782 numCANT=$((numCANT+1))
16783 listCANT="$listCANT $N"
16784 elif ! runsip4 >/dev/null; then
16785 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16786 numCANT=$((numCANT+1))
16787 listCANT="$listCANT $N"
16788 else
16789 tf="$td/test$N.stdout"
16790 te="$td/test$N.stderr"
16791 tdiff="$td/test$N.diff"
16792 da="test$N $(date) $RANDOM"
16793 newport udp4
16794 CMD0="$TRACE $SOCAT $opts --experimental -u -T 1 ABSTRACT-RECV:test$N,netns=$ns CREAT:${tf}0"
16795 CMD1="$TRACE $SOCAT $opts --experimental -U -T 1 EXEC:\"$SOCAT STDIO ABSTRACT-SENDTO\:test$N\",netns=$ns UDP4-RECV:$PORT"
16796 CMD2="$TRACE $SOCAT $opts -u STDIO UDP4:127.0.0.1:$PORT"
16797 printf "test $F_n $TEST... " $N
16798 ip netns del $ns 2>/dev/null # make sure it does not exist
16799 ip netns add $ns
16800 #ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8
16801 #ip netns exec $ns ip link set lo up
16802 eval "$CMD0" >/dev/null 2>"${te}0" &
16803 pid0=$!
16804 relsleep 1 # if no matching wait*port function
16805 eval "$CMD1" 2>${te}1 &
16806 pid1=$!
16807 relsleep 1
16808 echo "$da" |$CMD2 >"${tf}2" 2>"${te}2"
16809 rc1=$?
16810 kill $pid0 $pid1 2>/dev/null; wait
16811 ip netns del $ns
16812 if [ $rc1 -ne 0 ]; then
16813 $PRINTF "$FAILED (client failed)\n"
16814 echo "$CMD0 &"
16815 cat "${te}0" >&2
16816 echo "$CMD1"
16817 cat "${te}1" >&2
16818 echo "$CMD2"
16819 cat "${te}2" >&2
16820 numFAIL=$((numFAIL+1))
16821 listFAIL="$listFAIL $N"
16822 namesFAIL="$namesFAIL $NAME"
16823 elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then
16824 $PRINTF "$OK\n"
16825 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16826 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16827 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16828 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16829 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
16830 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
16831 numOK=$((numOK+1))
16832 else
16833 $PRINTF "$FAILED (bad output)\n"
16834 echo "$CMD0 &"
16835 cat "${te}0" >&2
16836 echo "$CMD1"
16837 cat "${te}1" >&2
16838 echo "$CMD2"
16839 cat "${te}2" >&2
16840 echo diff:
16841 cat "$tdiff"
16842 numFAIL=$((numFAIL+1))
16843 listFAIL="$listFAIL $N"
16844 namesFAIL="$namesFAIL $NAME"
16846 fi # NUMCOND
16848 esac
16849 N=$((N+1))
16852 NAME=SOCKETPAIR_STREAM
16853 case "$TESTS" in
16854 *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
16855 TEST="$NAME: stdio and internal socketpair with stream"
16856 testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts"
16857 esac
16858 N=$((N+1))
16860 NAME=SOCKETPAIR_DATAGRAM
16861 case "$TESTS" in
16862 *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
16863 TEST="$NAME: stdio and internal socketpair with datagram"
16864 testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts"
16865 esac
16866 N=$((N+1))
16868 NAME=SOCKETPAIR_SEQPACKET
16869 case "$TESTS" in
16870 *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
16871 TEST="$NAME: stdio and internal socketpair with seqpacket"
16872 testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts"
16873 esac
16874 N=$((N+1))
16876 # Test if SOCKETPAIR address with SOCK_DGRAM keeps packet boundaries
16877 NAME=SOCKETPAIR_BOUNDARIES
16878 case "$TESTS" in
16879 *%$N%*|*%functions%*|*%socketpair%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*)
16880 TEST="$NAME: Internal socketpair keeps packet boundaries"
16881 # Start a UDP4-DATAGRAM process that echoes data with datagram SOCKETPAIR;
16882 # a client sends two packets with 24 and ~18 bytes using a UDP4-DATAGRAM. The
16883 # client truncates packets to size 24, so when a large merged packet comes from
16884 # server some data will be lost. If the original data is received, the test
16885 # succeeded.
16886 if ! eval $NUMCOND; then :;
16887 elif ! F=$(testfeats STDIO IP4 UDP SOCKETPAIR); then
16888 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16889 numCANT=$((numCANT+1))
16890 listCANT="$listCANT $N"
16891 elif ! A=$(testaddrs - STDIO UDP4-DATAGRAM SOCKETPAIR); then
16892 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16893 numCANT=$((numCANT+1))
16894 listCANT="$listCANT $N"
16895 elif ! o=$(testoptions bind socktype ) >/dev/null; then
16896 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16897 numCANT=$((numCANT+1))
16898 listCANT="$listCANT $N"
16899 elif ! runsip4 >/dev/null; then
16900 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16901 numCANT=$((numCANT+1))
16902 listCANT="$listCANT $N"
16903 else
16904 tf="$td/test$N.stdout"
16905 te="$td/test$N.stderr"
16906 tdiff="$td/test$N.diff"
16907 ts1p=$PORT; PORT=$((PORT+1))
16908 ts2p=$PORT; PORT=$((PORT+1))
16909 da="test$N $(date) $RANDOM"
16910 CMD1="$TRACE $SOCAT $opts -T 0.2 UDP4-DATAGRAM:$LOCALHOST:$ts2p,bind=$LOCALHOST:$ts1p SOCKETPAIR,socktype=$SOCK_DGRAM"
16911 CMD2="$TRACE $SOCAT $opts -b 24 -t 0.2 -T 0.3 - UDP4-DATAGRAM:$LOCALHOST:$ts1p,bind=$LOCALHOST:$ts2p"
16912 printf "test $F_n $TEST... " $N
16913 export SOCAT_TRANSFER_WAIT=0.2
16914 $CMD1 2>"${te}1" &
16915 pid1="$!"
16916 unset SOCAT_TRANSFER_WAIT
16917 waitudp4port $ts1p 1
16918 { echo -n "${da:0:20}"; usleep 100000; echo "${da:20}"; } |$CMD2 >>"$tf" 2>>"${te}2"
16919 rc2="$?"
16920 kill "$pid1" 2>/dev/null; wait;
16921 if [ "$rc2" -ne 0 ]; then
16922 $PRINTF "$FAILED (rc2=$rc2): $TRACE $SOCAT:\n"
16923 echo "$CMD1 &"
16924 cat "${te}1" >&2
16925 echo "$CMD2"
16926 cat "${te}2" >&2
16927 numFAIL=$((numFAIL+1))
16928 listFAIL="$listFAIL $N"
16929 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
16930 $PRINTF "$FAILED\n"
16931 echo "$CMD1 &"
16932 cat "${te}1" >&2
16933 echo "$CMD2"
16934 cat "${te}2" >&2
16935 echo diff:
16936 cat "$tdiff"
16937 numFAIL=$((numFAIL+1))
16938 listFAIL="$listFAIL $N"
16939 else
16940 $PRINTF "$OK\n"
16941 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16942 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16943 if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
16944 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
16945 numOK=$((numOK+1))
16947 fi # NUMCOND
16949 esac
16950 PORT=$((PORT+1))
16951 N=$((N+1))
16954 # Test the ACCEPT-FD address
16955 NAME=ACCEPT_FD
16956 case "$TESTS" in
16957 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%systemd%*|*%accept%*|*%$NAME%*)
16958 TEST="$NAME: ACCEPT-FD address"
16959 # Start Socat with address ACCEPT-FD via systemd-socket-activate for echoing
16960 # data.
16961 # Connect with a client; the test succeeds when the client gets its data back.
16962 if ! eval $NUMCOND; then :;
16963 elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
16964 $PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N
16965 numCANT=$((numCANT+1))
16966 listCANT="$listCANT $N"
16967 elif ! F=$(testfeats IP4 TCP LISTEN); then
16968 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16969 numCANT=$((numCANT+1))
16970 listCANT="$listCANT $N"
16971 elif ! A=$(testaddrs ACCEPT-FD PIPE STDIO TCP4); then
16972 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16973 numCANT=$((numCANT+1))
16974 listCANT="$listCANT $N"
16975 elif ! runsip4 >/dev/null; then
16976 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16977 numCANT=$((numCANT+1))
16978 listCANT="$listCANT $N"
16979 else
16980 tf="$td/test$N.stdout"
16981 te="$td/test$N.stderr"
16982 tdiff="$td/test$N.diff"
16983 da="test$N $(date) $RANDOM"
16984 newport tcp4
16985 CMD0="systemd-socket-activate -l $PORT --inetd $TRACE $SOCAT $opts ACCEPT-FD:0 PIPE"
16986 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
16987 printf "test $F_n $TEST... " $N
16988 $CMD0 >/dev/null 2>"${te}0" &
16989 pid0=$!
16990 waittcp4port $PORT 1
16991 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
16992 rc1=$?
16993 kill $pid0 2>/dev/null; wait
16994 if echo "$da" |diff "${tf}1" - >$tdiff; then
16995 $PRINTF "$OK\n"
16996 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16997 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16998 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16999 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17000 numOK=$((numOK+1))
17001 else
17002 $PRINTF "$FAILED\n"
17003 echo "$CMD0 &"
17004 cat "${te}0" >&2
17005 echo "$CMD1"
17006 cat "${te}1" >&2
17007 cat $tdiff >&2
17008 numFAIL=$((numFAIL+1))
17009 listFAIL="$listFAIL $N"
17010 namesFAIL="$namesFAIL $NAME"
17012 fi # NUMCOND
17014 esac
17015 N=$((N+1))
17019 # Test the POSIX MQ feature with continuous READ and priorization on Linux
17020 NAME=LINUX_POSIXMQ_READ_PRIO
17021 case "$TESTS" in
17022 *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17023 TEST="$NAME: POSIX-MQ (Linux) with prio"
17024 # Run a client/sender that creates a POSIX-MQ and sends a normal message and
17025 # then a client/sender with a higher priority message.
17026 # Run a passive/listening/receiving/reading process and check if it receives
17027 # both messages and in the prioritized order
17028 if ! eval $NUMCOND; then :;
17029 elif [ "$UNAME" != Linux ]; then
17030 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17031 numCANT=$((numCANT+1))
17032 listCANT="$listCANT $N"
17033 elif ! F=$(testfeats POSIXMQ STDIO); then
17034 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17035 numCANT=$((numCANT+1))
17036 listCANT="$listCANT $N"
17037 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO); then
17038 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17039 numCANT=$((numCANT+1))
17040 listCANT="$listCANT $N"
17041 elif ! o=$(testoptions mq-prio unlink-early unlink-close) >/dev/null; then
17042 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17043 numCANT=$((numCANT+1))
17044 listCANT="$listCANT $N"
17045 else
17046 tf="$td/test$N.stdout"
17047 te="$td/test$N.stderr"
17048 tdiff="$td/test$N.diff"
17049 da="test$N $(date) $RANDOM"
17050 tq=/test$N
17051 CMD0a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early"
17052 CMD0b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1"
17053 CMD1="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-close STDIO"
17054 printf "test $F_n $TEST... " $N
17055 echo "$da 0" |$CMD0a 2>"${te}0a"
17056 rc0a=$?
17057 echo "$da 1" |$CMD0b 2>"${te}0b"
17058 rc0b=$?
17059 $CMD1 >"${tf}1" 2>"${te}1" &
17060 pid1=$!
17061 relsleep 1
17062 kill $pid1; wait
17063 if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then
17064 $PRINTF "$FAILED\n"
17065 echo "$CMD0a"
17066 cat "${te}0a" >&2
17067 echo "$CMD0b"
17068 cat "${te}0b" >&2
17069 echo "$CMD1"
17070 cat "${te}1" >&2
17071 numFAIL=$((numFAIL+1))
17072 listFAIL="$listFAIL $N"
17073 namesFAIL="$namesFAIL $NAME"
17074 elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then
17075 $PRINTF "$OK\n"
17076 if [ "$VERBOSE" ]; then echo "$CMD0a"; fi
17077 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
17078 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
17079 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
17080 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17081 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17082 numOK=$((numOK+1))
17083 else
17084 $PRINTF "$FAILED\n"
17085 echo "$CMD0a"
17086 cat "${te}0a" >&2
17087 echo "$CMD0b"
17088 cat "${te}0b" >&2
17089 echo "$CMD1"
17090 cat "${te}1" >&2
17091 echo "difference:" >&2
17092 cat ${tdiff}1 >&2
17093 numFAIL=$((numFAIL+1))
17094 listFAIL="$listFAIL $N"
17095 namesFAIL="$namesFAIL $NAME"
17097 fi # NUMCOND
17099 esac
17100 N=$((N+1))
17102 # Test the POSIX MQ feature with RECV,fork on Linux
17103 NAME=LINUX_POSIXMQ_RECV_FORK
17104 case "$TESTS" in
17105 *%$N%*|*%functions%*|*%fork%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17106 TEST="$NAME: POSIX-MQ (Linux) RECV with fork"
17107 # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its
17108 # output.
17109 # Run two clients/senders each with a message.
17110 # Check if both messages are stored.
17111 if ! eval $NUMCOND; then :;
17112 elif [ "$UNAME" != Linux ]; then
17113 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17114 numCANT=$((numCANT+1))
17115 listCANT="$listCANT $N"
17116 elif ! F=$(testfeats POSIXMQ STDIO); then
17117 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17118 numCANT=$((numCANT+1))
17119 listCANT="$listCANT $N"
17120 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO); then
17121 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17122 numCANT=$((numCANT+1))
17123 listCANT="$listCANT $N"
17124 elif ! o=$(testoptions fork unlink-early unlink-close) >/dev/null; then
17125 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17126 numCANT=$((numCANT+1))
17127 listCANT="$listCANT $N"
17128 else
17129 tf="$td/test$N.stdout"
17130 te="$td/test$N.stderr"
17131 tdiff="$td/test$N.diff"
17132 da="test$N $(date) $RANDOM"
17133 tq=/test$N
17134 CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO"
17135 CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq"
17136 CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
17137 printf "test $F_n $TEST... " $N
17138 $CMD0 2>"${te}0" >"${tf}0" &
17139 pid0=$!
17140 relsleep 1
17141 echo "$da 0" |$CMD1a >/dev/null 2>"${te}1a"
17142 rc1a=$?
17143 echo "$da 1" |$CMD1b >/dev/null 2>"${te}1b"
17144 rc1b=$?
17145 relsleep 1
17146 kill $pid0; wait
17147 if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then
17148 $PRINTF "$FAILED\n"
17149 echo "$CMD0"
17150 cat "${te}0" >&2
17151 echo "$CMD1a"
17152 cat "${te}1a" >&2
17153 echo "$CMD1b"
17154 cat "${te}1b" >&2
17155 numFAIL=$((numFAIL+1))
17156 listFAIL="$listFAIL $N"
17157 namesFAIL="$namesFAIL $NAME"
17158 elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then
17159 $PRINTF "$OK\n"
17160 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
17161 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17162 if [ "$VERBOSE" ]; then echo "$CMD1a"; fi
17163 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
17164 if [ "$VERBOSE" ]; then echo "$CMD1b"; fi
17165 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
17166 numOK=$((numOK+1))
17167 else
17168 $PRINTF "$FAILED\n"
17169 echo "$CMD0"
17170 cat "${te}0" >&2
17171 echo "$CMD1a"
17172 cat "${te}1a" >&2
17173 echo "$CMD1b"
17174 cat "${te}1b" >&2
17175 echo "difference:" >&2
17176 cat ${tdiff}0 >&2
17177 numFAIL=$((numFAIL+1))
17178 listFAIL="$listFAIL $N"
17179 namesFAIL="$namesFAIL $NAME"
17181 fi # NUMCOND
17183 esac
17184 N=$((N+1))
17186 # Test the POSIX MQ feature with RECV,fork,max-children on Linux
17187 NAME=LINUX_POSIXMQ_RECV_MAXCHILDREN
17188 case "$TESTS" in
17189 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17190 TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children"
17191 # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its
17192 # output via sub processes that sleeps after writing.
17193 # Run a client/sender that sends message 1;
17194 # run a client/sender that sends message 3, has to wait;
17195 # write message 2 directly into output file;
17196 # Check if the messages are stored in order of their numbers
17197 if ! eval $NUMCOND; then :;
17198 elif [ "$UNAME" != Linux ]; then
17199 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17200 numCANT=$((numCANT+1))
17201 listCANT="$listCANT $N"
17202 elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then
17203 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17204 numCANT=$((numCANT+1))
17205 listCANT="$listCANT $N"
17206 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM); then
17207 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17208 numCANT=$((numCANT+1))
17209 listCANT="$listCANT $N"
17210 elif ! o=$(testoptions fork max-children unlink-early unlink-close) >/dev/null; then
17211 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17212 numCANT=$((numCANT+1))
17213 listCANT="$listCANT $N"
17214 else
17215 tf="$td/test$N.stdout"
17216 te="$td/test$N.stderr"
17217 tdiff="$td/test$N.diff"
17218 da="test$N $(date) $RANDOM"
17219 tq=/test$N
17220 CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\""
17221 CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq"
17222 CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
17223 printf "test $F_n $TEST... " $N
17224 eval $CMD0 2>"${te}0" >"${tf}0" &
17225 pid0=$!
17226 relsleep 1
17227 echo "$da 1" |$CMD1a >/dev/null 2>"${te}1a"
17228 rc1a=$?
17229 echo "$da 3" |$CMD1b >/dev/null 2>"${te}1b"
17230 rc1b=$?
17231 psleep 0.5
17232 echo "$da 2" >>"${tf}0"
17233 sleep 1 # as in SYSTEM
17234 kill $(childpids $pid0) $pid0 2>/dev/null
17235 wait 2>/dev/null
17236 if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then
17237 $PRINTF "$FAILED\n"
17238 echo "$CMD0"
17239 cat "${te}0" >&2
17240 echo "$CMD1a"
17241 cat "${te}1a" >&2
17242 echo "$CMD1b"
17243 cat "${te}1b" >&2
17244 numFAIL=$((numFAIL+1))
17245 listFAIL="$listFAIL $N"
17246 namesFAIL="$namesFAIL $NAME"
17247 elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
17248 $PRINTF "$OK\n"
17249 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
17250 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17251 if [ "$VERBOSE" ]; then echo "$CMD1a"; fi
17252 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
17253 if [ "$VERBOSE" ]; then echo "$CMD1b"; fi
17254 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
17255 numOK=$((numOK+1))
17256 else
17257 $PRINTF "$FAILED\n"
17258 echo "$CMD0"
17259 cat "${te}0" >&2
17260 echo "$CMD1a"
17261 cat "${te}1a" >&2
17262 echo "$CMD1b"
17263 cat "${te}1b" >&2
17264 echo "difference:" >&2
17265 cat ${tdiff}0 >&2
17266 numFAIL=$((numFAIL+1))
17267 listFAIL="$listFAIL $N"
17268 namesFAIL="$namesFAIL $NAME"
17270 fi # NUMCOND
17272 esac
17273 N=$((N+1))
17275 # Test the POSIX MQ feature with SEND,fork,max-children on Linux
17276 NAME=LINUX_POSIXMQ_SEND_MAXCHILDREN
17277 case "$TESTS" in
17278 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17279 TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children"
17280 # Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from
17281 # there to an output file
17282 # Run a POSIX-MQ sender that two times forks and invokes a data generator
17283 # for messages 1 and 3 in a shell process with some trailing sleep.
17284 # Afterwards write message 2 directly into output file; message 3 should be
17285 # delayed due to max-children option
17286 # Check if the messages are stored in order of their numbers.
17287 # The data generator is implemented as a receiver from an MQ with "1", "3"
17288 if ! eval $NUMCOND; then :;
17289 elif [ "$UNAME" != Linux ]; then
17290 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17291 numCANT=$((numCANT+1))
17292 listCANT="$listCANT $N"
17293 elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then
17294 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17295 numCANT=$((numCANT+1))
17296 listCANT="$listCANT $N"
17297 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM); then
17298 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17299 numCANT=$((numCANT+1))
17300 listCANT="$listCANT $N"
17301 elif ! o=$(testoptions fork max-children mq-prio unlink-early unlink-close) >/dev/null; then
17302 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17303 numCANT=$((numCANT+1))
17304 listCANT="$listCANT $N"
17305 #elif ! runsposixmq >/dev/null; then
17306 # $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17307 # numCANT=$((numCANT+1))
17308 # listCANT="$listCANT $N"
17309 else
17310 tf="$td/test$N.stdout"
17311 te="$td/test$N.stderr"
17312 tdiff="$td/test$N.diff"
17313 da="test$N $(date) $RANDOM"
17314 tq=/test$N
17315 CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-early STDIO"
17316 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\""
17317 printf "test $F_n $TEST... " $N
17318 # create data for the generator
17319 echo "$da 1" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data,unlink-early
17320 echo "$da 3" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data
17321 eval $CMD0 2>"${te}0" >>"${tf}0" &
17322 pid0=$!
17323 relsleep 1
17324 eval $CMD1 2>"${te}1" &
17325 pid1=$!
17326 psleep 0.5
17327 echo "$da 2" >>"${tf}0"
17328 sleep 1 # as in SYSTEM
17329 kill $pid0 $(childpids $pid0) $pid1 $(childpids $pid1) 2>/dev/null
17330 wait 2>/dev/null
17331 $SOCAT -u --experimental /dev/null POSIXMQ-SEND:$tq-data,unlink-close
17332 if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
17333 $PRINTF "$OK\n"
17334 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
17335 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17336 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17337 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17338 numOK=$((numOK+1))
17339 else
17340 $PRINTF "$FAILED\n"
17341 echo "$CMD0"
17342 cat "${te}0" >&2
17343 echo "$CMD1"
17344 cat "${te}1" >&2
17345 echo "difference:" >&2
17346 cat ${tdiff}0 >&2
17347 numFAIL=$((numFAIL+1))
17348 listFAIL="$listFAIL $N"
17349 namesFAIL="$namesFAIL $NAME"
17351 fi # NUMCOND
17353 esac
17354 N=$((N+1))
17357 # Test the sigint option with SHELL address
17358 NAME=SHELL_SIGINT
17359 case "$TESTS" in
17360 *%$N%*|*%functions%*|*%socket%*|*%shell%*|*%progcall%*|*%sigint%*|*%$NAME%*)
17361 TEST="$NAME: sigint option with SHELL"
17362 # Run Socat with an EXEC address invoking Socat, with option sigint
17363 # Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM)
17364 # the test succeeded
17365 if ! eval $NUMCOND; then :;
17366 # Remove unneeded checks, adapt lists of the remaining ones
17367 elif ! F=$(testfeats STDIO SHELL PIPE); then
17368 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17369 numCANT=$((numCANT+1))
17370 listCANT="$listCANT $N"
17371 elif ! A=$(testaddrs STDIO SHELL PIPE); then
17372 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17373 numCANT=$((numCANT+1))
17374 listCANT="$listCANT $N"
17375 elif ! o=$(testoptions setsid sigint) >/dev/null; then
17376 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17377 numCANT=$((numCANT+1))
17378 listCANT="$listCANT $N"
17379 else
17380 tf="$td/test$N.stdout"
17381 te="$td/test$N.stderr"
17382 tdiff="$td/test$N.diff"
17383 da="test$N $(date) $RANDOM"
17384 #CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"socat\ -d\ -d\ -d\ -d\ -lu\ PIPE\ PIPE\",pty,setsid,sigint"
17385 #CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint"
17386 CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR EXEC:\"$CAT\",pty,setsid,sigint"
17387 printf "test $F_n $TEST... " $N
17388 eval $CMD0 >/dev/null 2>"${te}0" &
17389 $CMD0 >/dev/null 2>"${te}0" &
17390 pid0=$!
17391 sleep 1
17392 kill -INT $pid0
17393 wait
17394 if grep -q " W waitpid..: child .* exited with status 130" "${te}0" ||
17395 grep -q " W waitpid..: child .* exited on signal 2" "${te}0"; then
17396 $PRINTF "$OK\n"
17397 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17398 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17399 numOK=$((numOK+1))
17400 else
17401 $PRINTF "$FAILED\n"
17402 echo "$CMD0 &"
17403 cat "${te}0" >&2
17404 numFAIL=$((numFAIL+1))
17405 listFAIL="$listFAIL $N"
17406 namesFAIL="$namesFAIL $NAME"
17408 fi # NUMCOND
17410 esac
17411 N=$((N+1))
17414 # Test the SHELL address with socketpair (default)
17415 NAME=SHELL_SOCKETPAIR
17416 case "$TESTS" in
17417 *%$N%*|*%functions%*|*%shell%*|*%socketpair%*|*%$NAME%*)
17418 TEST="$NAME: simple echo via SHELL of cat with socketpair"
17419 # testecho ...
17420 if ! eval $NUMCOND; then :;
17421 elif ! F=$(testfeats STDIO SHELL); then
17422 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17423 numCANT=$((numCANT+1))
17424 listCANT="$listCANT $N"
17425 elif ! A=$(testaddrs STDIO SHELL); then
17426 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17427 numCANT=$((numCANT+1))
17428 listCANT="$listCANT $N"
17429 else
17430 testecho "$N" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t"
17432 esac
17433 N=$((N+1))
17435 # Test the SHELL address with pipes
17436 NAME=SHELL_PIPES
17437 case "$TESTS" in
17438 *%$N%*|*%functions%*|*%shell%*|*%pipe%*|*%$NAME%*)
17439 TEST="$NAME: simple echo via SHELL of cat with pipes"
17440 # testecho ...
17441 if ! eval $NUMCOND; then :;
17442 elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then
17443 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17444 numCANT=$((numCANT+1))
17445 listCANT="$listCANT $N"
17446 elif ! A=$(testaddrs STDIO SHELL PIPE); then
17447 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17448 numCANT=$((numCANT+1))
17449 listCANT="$listCANT $N"
17450 else
17451 testecho "$N" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t"
17453 esac
17454 N=$((N+1))
17456 # Test the SHELL address with pty
17457 NAME=SHELL_PTY
17458 case "$TESTS" in
17459 *%$N%*|*%functions%*|*%shell%*|*%pty%*|*%$NAME%*)
17460 TEST="$NAME: simple echo via SHELL of cat with pty"
17461 # testecho ...
17462 if ! eval $NUMCOND; then :;
17463 elif ! F=$(testfeats STDIO SHELL PTY); then
17464 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17465 numCANT=$((numCANT+1))
17466 listCANT="$listCANT $N"
17467 elif ! A=$(testaddrs STDIO SHELL PTY); then
17468 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17469 numCANT=$((numCANT+1))
17470 listCANT="$listCANT $N"
17471 else
17472 testecho "$N" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t"
17474 esac
17475 N=$((N+1))
17477 # Test the SHELL address halfclose with socketpair
17478 NAME=SHELL_SOCKETPAIR_FLUSH
17479 case "$TESTS" in
17480 *%$N%*|*%functions%*|*%shell%*|*%socketpair%*|*%halfclose%*|*%$NAME%*)
17481 TEST="$NAME: call od -c via SHELL using socketpair"
17482 # testecho ...
17483 if ! eval $NUMCOND; then :;
17484 elif ! F=$(testfeats STDIO SHELL); then
17485 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17486 numCANT=$((numCANT+1))
17487 listCANT="$listCANT $N"
17488 elif ! A=$(testaddrs STDIO SHELL); then
17489 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17490 numCANT=$((numCANT+1))
17491 listCANT="$listCANT $N"
17492 else
17493 testod "$N" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t"
17495 esac
17496 N=$((N+1))
17498 # Test SHELL address halfclose with pipes
17499 NAME=SHELL_PIPES
17500 case "$TESTS" in
17501 *%$N%*|*%functions%*|*%shell%*|*%pipe%*|*%halfclose%*|*%$NAME%*)
17502 TEST="$NAME: call od -c via SHELL using pipes"
17503 # testecho ...
17504 if ! eval $NUMCOND; then :;
17505 elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then
17506 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17507 numCANT=$((numCANT+1))
17508 listCANT="$listCANT $N"
17509 elif ! A=$(testaddrs STDIO SHELL PIPE); then
17510 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17511 numCANT=$((numCANT+1))
17512 listCANT="$listCANT $N"
17513 else
17514 testod "$N" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t"
17516 esac
17517 N=$((N+1))
17520 # Test the sigint option with SYSTEM address
17521 NAME=SYSTEM_SIGINT
17522 case "$TESTS" in
17523 *%$N%*|*%functions%*|*%socket%*|*%progcall%*|*%system%*|*%sigint%*|*%$NAME%*)
17524 TEST="$NAME: sigint option with SYSTEM"
17525 # Run Socat with a SYSTEM address invoking Socat, with option sigint
17526 # Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM)
17527 # the test succeeded
17528 # setsid is required so the initial SIGINT is not delivered to the sub process.
17529 if ! eval $NUMCOND; then :;
17530 # Remove unneeded checks, adapt lists of the remaining ones
17531 elif ! F=$(testfeats STDIO SYSTEM PIPE); then
17532 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17533 numCANT=$((numCANT+1))
17534 listCANT="$listCANT $N"
17535 elif ! A=$(testaddrs STDIO SYSTEM PIPE); then
17536 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17537 numCANT=$((numCANT+1))
17538 listCANT="$listCANT $N"
17539 elif ! o=$(testoptions setsid sigint) >/dev/null; then
17540 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17541 numCANT=$((numCANT+1))
17542 listCANT="$listCANT $N"
17543 else
17544 tf="$td/test$N.stdout"
17545 te="$td/test$N.stderr"
17546 tdiff="$td/test$N.diff"
17547 da="test$N $(date) $RANDOM"
17548 #CMD0="$TRACE $SOCAT $opts PIPE SHELL:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
17549 CMD0="$TRACE $SOCAT $opts SOCKETPAIR SHELL:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
17550 printf "test $F_n $TEST... " $N
17551 eval $CMD0 >/dev/null 2>"${te}0" &
17552 pid0=$!
17553 sleep 1
17554 kill -INT $(childpids $pid0) 2>/dev/null
17555 wait 2>/dev/null
17556 if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then
17557 $PRINTF "$OK\n"
17558 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17559 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17560 numOK=$((numOK+1))
17561 else
17562 $PRINTF "$FAILED\n"
17563 echo "$CMD0 &"
17564 cat "${te}0" >&2
17565 numFAIL=$((numFAIL+1))
17566 listFAIL="$listFAIL $N"
17567 namesFAIL="$namesFAIL $NAME"
17569 fi # NUMCOND
17571 esac
17572 N=$((N+1))
17575 # Test the res-nsaddr (resolver, dns) option
17576 NAME=RES_NSADDR
17577 case "$TESTS" in
17578 *%$N%*|*%functions%*|*%resolv%*|*%ip4%*|*%tcp4%*|*%socket%*|*%$NAME%*)
17579 TEST="$NAME: test the res-nsaddr option"
17580 # Start a supplementary Socat instance that will receive the DNS query.
17581 # Run main Socat process, opening an IPv4 socket with option res-nsaddr
17582 # directed to the aux process.
17583 # When the supplementary Socat instance received the query the test succeeded.
17584 if ! eval $NUMCOND; then :;
17585 elif ! F=$(testfeats STDIO IP4 UDP TCP); then
17586 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17587 numCANT=$((numCANT+1))
17588 listCANT="$listCANT $N"
17589 elif ! A=$(testaddrs STDIO TCP4 UDP-RECVFROM); then
17590 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17591 numCANT=$((numCANT+1))
17592 listCANT="$listCANT $N"
17593 elif ! o=$(testoptions res-nsaddr) >/dev/null; then
17594 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17595 numCANT=$((numCANT+1))
17596 listCANT="$listCANT $N"
17597 elif ! runsip4 >/dev/null; then
17598 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N
17599 numCANT=$((numCANT+1))
17600 listCANT="$listCANT $N"
17601 else
17602 tf="$td/test$N.stdout"
17603 te="$td/test$N.stderr"
17604 tdiff="$td/test$N.diff"
17605 da="$(echo test$N $(date) $RANDOM |tr ' :' '-')"
17606 echo "$da" >"$td/test$N.da"
17607 newport udp4
17608 CMD0="$TRACE $SOCAT $opts -u UDP4-RECVFROM:$PORT -"
17609 CMD1="$TRACE $SOCAT $opts - TCP4:$da:0,res-nsaddr=$LOCALHOST:$PORT"
17610 printf "test $F_n $TEST... " $N
17611 $CMD0 >/dev/null 2>"${te}0" >"${tf}0" &
17612 pid0=$!
17613 waitudp4port $PORT 1
17614 $CMD1 >"${tf}1" 2>"${te}1"
17615 rc1=$?
17616 kill $pid0 2>/dev/null; wait
17617 if grep "$da" "${tf}0" >/dev/null; then
17618 $PRINTF "$OK\n"
17619 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17620 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17621 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17622 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17623 numOK=$((numOK+1))
17624 elif pgrep -u root nscd >/dev/null 2>&1; then
17625 $PRINTF "${YELLOW}FAILED (due to nscd?)${NORMAL}\n"
17626 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17627 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17628 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17629 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17630 numCANT=$((numCANT+1))
17631 listCANT="$listCANT $N"
17632 namesCAnT="$namesCANT $NAME"
17633 else
17634 $PRINTF "$FAILED (query not received)\n"
17635 echo "$CMD0 &"
17636 cat "${te}0" >&2
17637 echo "$CMD1"
17638 cat "${te}1" >&2
17639 numFAIL=$((numFAIL+1))
17640 listFAIL="$listFAIL $N"
17641 namesFAIL="$namesFAIL $NAME"
17643 fi # NUMCOND
17645 esac
17646 N=$((N+1))
17649 # Some of the following tests need absolute path of Socat
17650 case "$SOCAT" in
17651 /*) absSOCAT="$SOCAT" ;;
17652 *) absSOCAT="$PWD/$SOCAT" ;;
17653 esac
17655 # Test the chdir option, in particular if chdir with the first address
17656 # (CREATE) does not affect pwd of second address, i.e. original pwd is
17657 # recovered
17658 NAME=CHDIR_ON_CREATE
17659 case "$TESTS" in
17660 *%$N%*|*%functions%*|*%creat%*|*%system%*|*%chdir%*|*%$NAME%*)
17661 TEST="$NAME: restore of pwd after CREAT with chdir option"
17662 # Run Socat with first address CREAT with modified chdir,
17663 # and second address SYSTEM (shell) with pwd command
17664 # Check if the file is created with modified pwd but shell has original pwd
17665 if ! eval $NUMCOND; then :;
17666 elif ! F=$(testfeats CREAT SYSTEM); then
17667 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17668 numCANT=$((numCANT+1))
17669 listCANT="$listCANT $N"
17670 elif ! A=$(testaddrs - CREAT SYSTEM); then
17671 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17672 numCANT=$((numCANT+1))
17673 listCANT="$listCANT $N"
17674 elif ! o=$(testoptions chdir) >/dev/null; then
17675 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17676 numCANT=$((numCANT+1))
17677 listCANT="$listCANT $N"
17678 else
17679 tf="$td/test$N.stdout"
17680 te="$td/test$N.stderr"
17681 tc="test$N.creat"
17682 tdd="test$N.d"
17683 tdiff="$td/test$N.diff"
17684 tdebug="$td/test$N.debug"
17685 opwd=$(pwd)
17686 CMD0="$TRACE $absSOCAT $opts -U CREAT:$tc,chdir=$td SYSTEM:pwd"
17687 printf "test $F_n $TEST... " $N
17688 mkdir "$td/$tdd"
17689 pushd "$td/$tdd" >/dev/null
17690 $CMD0 >/dev/null 2>"${te}0"
17691 rc0=$?
17692 popd >/dev/null
17693 tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*}
17694 pwd2=$(cat $tpwd/$tc </dev/null)
17695 echo "Original pwd: $opwd" >>$tdebug
17696 echo "Temporary pwd: $tpwd" >>$tdebug
17697 echo "Addr2 pwd: $pwd2" >>$tdebug
17698 if [ "$rc0" -ne 0 ]; then
17699 $PRINTF "$FAILED\n"
17700 echo "$CMD0 &"
17701 cat "${te}0" >&2
17702 numFAIL=$((numFAIL+1))
17703 listFAIL="$listFAIL $N"
17704 namesFAIL="$namesFAIL $NAME"
17705 elif [ "$tpwd" != "$td" ]; then
17706 $PRINTF "$FAILED (chdir failed)\n"
17707 echo "$CMD0 &"
17708 cat "${te}0" >&2
17709 numFAIL=$((numFAIL+1))
17710 listFAIL="$listFAIL $N"
17711 namesFAIL="$namesFAIL $NAME"
17712 elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
17713 $PRINTF "$FAILED (bad pwd2)\n"
17714 echo "$CMD0 &"
17715 cat "${te}0" >&2
17716 echo "// diff:" >&2
17717 cat "$tdiff" >&2
17718 numFAIL=$((numFAIL+1))
17719 listFAIL="$listFAIL $N"
17720 namesFAIL="$namesFAIL $NAME"
17721 else
17722 $PRINTF "$OK\n"
17723 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17724 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17725 numOK=$((numOK+1))
17727 fi # NUMCOND
17729 esac
17730 N=$((N+1))
17732 # Test the chdir option, in particular if chdir with first address
17733 # (SHELL) does not affect pwd of second address, i.e. original pwd is
17734 # recovered
17735 NAME=CHDIR_ON_SHELL
17736 case "$TESTS" in
17737 *%$N%*|*%functions%*|*%shell%*|*%system%*|*%chdir%*|*%$NAME%*)
17738 TEST="$NAME: restore of pwd after SYSTEM with chdir option"
17739 # Run Socat with first address SYSTEM:"cat >file" with chdir,
17740 # and second address SYSTEM (shell) with pwd command.
17741 # Check if the file is created with modified pwd but shell has original pwd
17742 if ! eval $NUMCOND; then :;
17743 elif ! F=$(testfeats SHELL SYSTEM); then
17744 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17745 numCANT=$((numCANT+1))
17746 listCANT="$listCANT $N"
17747 elif ! A=$(testaddrs SHELL SYSTEM); then
17748 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17749 numCANT=$((numCANT+1))
17750 listCANT="$listCANT $N"
17751 elif ! o=$(testoptions chdir) >/dev/null; then
17752 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17753 numCANT=$((numCANT+1))
17754 listCANT="$listCANT $N"
17755 else
17756 tf="$td/test$N.stdout"
17757 te="$td/test$N.stderr"
17758 tc="test$N.creat"
17759 tdd="test$N.d"
17760 tdiff="$td/test$N.diff"
17761 tdebug="$td/test$N.debug"
17762 opwd=$(pwd)
17763 CMD0="$TRACE $absSOCAT $opts SHELL:\"cat\ >$tc\",chdir=$td SYSTEM:pwd"
17764 printf "test $F_n $TEST... " $N
17765 mkdir "$td/$tdd"
17766 pushd "$td/$tdd" >/dev/null
17767 eval "$CMD0" >/dev/null 2>"${te}0"
17768 rc0=$?
17769 popd >/dev/null
17770 waitfile "$td/$tc"
17771 tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*}
17772 pwd2=$(cat $tpwd/$tc </dev/null)
17773 echo "Original pwd: $opwd" >>$tdebug
17774 echo "Temporary pwd: $tpwd" >>$tdebug
17775 echo "Addr2 pwd: $pwd2" >>$tdebug
17776 if [ "$rc0" -ne 0 ]; then
17777 $PRINTF "$FAILED (rc=$rc0)\n"
17778 echo "$CMD0 &"
17779 cat "${te}0" >&2
17780 numFAIL=$((numFAIL+1))
17781 listFAIL="$listFAIL $N"
17782 namesFAIL="$namesFAIL $NAME"
17783 elif [ "$tpwd" != "$td" ]; then
17784 $PRINTF "$FAILED (chdir failed)\n"
17785 echo "$CMD0 &"
17786 cat "${te}0" >&2
17787 numFAIL=$((numFAIL+1))
17788 listFAIL="$listFAIL $N"
17789 namesFAIL="$namesFAIL $NAME"
17790 elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
17791 $PRINTF "$FAILED (bad pwd)\n"
17792 echo "$CMD0 &"
17793 cat "${te}0" >&2
17794 echo "// diff:" >&2
17795 cat "$tdiff" >&2
17796 numFAIL=$((numFAIL+1))
17797 listFAIL="$listFAIL $N"
17798 namesFAIL="$namesFAIL $NAME"
17799 else
17800 $PRINTF "$OK\n"
17801 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17802 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17803 numOK=$((numOK+1))
17805 fi # NUMCOND
17807 esac
17808 N=$((N+1))
17811 # Test the modified umask option, in particular if umask with first address
17812 # (CREATE) does not affect umask of second address, i.e. original umask is
17813 # recovered
17814 NAME=UMASK_ON_CREATE
17815 case "$TESTS" in
17816 *%$N%*|*%functions%*|*%creat%*|*%system%*|*%umask%*|*%$NAME%*)
17817 TEST="$NAME: test restore after CREAT with umask option"
17818 # Run Socat with first address CREAT with modified umask,
17819 # and second address SYSTEM (shell) with umask command
17820 # Check if the file is created with modified umask but shell has original umask
17821 if ! eval $NUMCOND; then :;
17822 elif ! F=$(testfeats CREAT SYSTEM); then
17823 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17824 numCANT=$((numCANT+1))
17825 listCANT="$listCANT $N"
17826 elif ! A=$(testaddrs CREAT SYSTEM); then
17827 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17828 numCANT=$((numCANT+1))
17829 listCANT="$listCANT $N"
17830 elif ! o=$(testoptions umask) >/dev/null; then
17831 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17832 numCANT=$((numCANT+1))
17833 listCANT="$listCANT $N"
17834 else
17835 tf="$td/test$N.stdout"
17836 te="$td/test$N.stderr"
17837 tc="$td/test$N.creat"
17838 tdiff="$td/test$N.diff"
17839 tdebug="$td/test$N.debug"
17840 oumask=$(umask)
17841 # Construct a temp umask differing from original umask
17842 case oumask in
17843 *066) tumask=0026 ;;
17844 *) tumask=0066 ;;
17845 esac
17846 CMD0="$TRACE $SOCAT $opts -U CREAT:$tc,umask=$tumask SYSTEM:umask"
17847 printf "test $F_n $TEST... " $N
17848 $CMD0 >/dev/null 2>"${te}0"
17849 rc0=$?
17850 tperms=$(fileperms $tc)
17851 case $tperms in
17852 0*) ;;
17853 *) tperms=0$tperms ;;
17854 esac
17855 echo "Original umask: $oumask" >>$tdebug
17856 echo "Temporary umask: $tumask" >>$tdebug
17857 echo "Created umask: $tperms" >>$tdebug
17858 echo "Restored umask: $(cat $tc)" >>$tdebug
17859 if [ "$rc0" -ne 0 ]; then
17860 $PRINTF "$FAILED\n"
17861 echo "$CMD0 &"
17862 cat "${te}0" >&2
17863 numFAIL=$((numFAIL+1))
17864 listFAIL="$listFAIL $N"
17865 namesFAIL="$namesFAIL $NAME"
17866 elif [ $((tumask + tperms - 0666)) -ne 0 ]; then
17867 $PRINTF "$FAILED (umask failed)\n"
17868 echo "$CMD0 &"
17869 cat "${te}0" >&2
17870 numFAIL=$((numFAIL+1))
17871 listFAIL="$listFAIL $N"
17872 namesFAIL="$namesFAIL $NAME"
17873 elif ! [ "$oumask" -eq $(cat "$tc") ]; then
17874 $PRINTF "$FAILED (bad umask)\n"
17875 echo "$CMD0 &"
17876 cat "${te}0" >&2
17877 cat "$tdebug" >&2
17878 numFAIL=$((numFAIL+1))
17879 listFAIL="$listFAIL $N"
17880 namesFAIL="$namesFAIL $NAME"
17881 else
17882 $PRINTF "$OK\n"
17883 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17884 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17885 numOK=$((numOK+1))
17887 fi # NUMCOND
17889 esac
17890 N=$((N+1))
17892 # Test the modified umask option, in particular if umask with first address
17893 # (SHELL) does not affect umask of second address, i.e. original umask is
17894 # recovered
17895 NAME=UMASK_ON_SYSTEM
17896 case "$TESTS" in
17897 *%$N%*|*%functions%*|*%shell%*|*%system%*|*%umask%*|*%socket%*|*%$NAME%*)
17898 TEST="$NAME: test restore after SHELL with umask option"
17899 # Run Socat with first address SHELL:"cat >file" with modified umask,
17900 # and second address SYSTEM (shell) with umask command.
17901 # Check if the file is created with modified umask but shell has original umask
17902 if ! eval $NUMCOND; then :;
17903 elif ! F=$(testfeats SHELL SYSTEM); then
17904 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17905 numCANT=$((numCANT+1))
17906 listCANT="$listCANT $N"
17907 elif ! A=$(testaddrs SHELL SYSTEM); then
17908 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17909 numCANT=$((numCANT+1))
17910 listCANT="$listCANT $N"
17911 elif ! o=$(testoptions umask) >/dev/null; then
17912 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17913 numCANT=$((numCANT+1))
17914 listCANT="$listCANT $N"
17915 else
17916 tf="$td/test$N.stdout"
17917 te="$td/test$N.stderr"
17918 tc="$td/test$N.creat"
17919 tdiff="$td/test$N.diff"
17920 tdebug="$td/test$N.debug"
17921 oumask=$(umask)
17922 # Construct a temp umask differing from original umask
17923 case oumask in
17924 *066) tumask=0026 ;;
17925 *) tumask=0066 ;;
17926 esac
17927 CMD0="$TRACE $SOCAT $opts -U SHELL:\"cat\ >$tc\",umask=$tumask SYSTEM:\"umask; sleep 1\""
17928 printf "test $F_n $TEST... " $N
17929 eval "$CMD0" >/dev/null 2>"${te}0"
17930 rc0=$?
17931 tperms=$(fileperms $tc)
17932 case $tperms in
17933 0*) ;;
17934 *) tperms=0$tperms ;;
17935 esac
17936 echo "Original umask: $oumask" >>$tdebug
17937 echo "Temporary umask: $tumask" >>$tdebug
17938 echo "Created umask: $tperms" >>$tdebug
17939 echo "Restored umask: $(cat $tc)" >>$tdebug
17940 if [ "$rc0" -ne 0 ]; then
17941 $PRINTF "$FAILED\n"
17942 echo "$CMD0 &"
17943 cat "${te}0" >&2
17944 numFAIL=$((numFAIL+1))
17945 listFAIL="$listFAIL $N"
17946 namesFAIL="$namesFAIL $NAME"
17947 elif [ $((tumask + tperms - 0666)) -ne 0 ]; then
17948 $PRINTF "$FAILED (umask failed)\n"
17949 echo "$CMD0 &"
17950 cat "${te}0" >&2
17951 numFAIL=$((numFAIL+1))
17952 listFAIL="$listFAIL $N"
17953 namesFAIL="$namesFAIL $NAME"
17954 elif ! [ "$oumask" -eq $(cat "$tc") ]; then
17955 $PRINTF "$FAILED (bad umask)\n"
17956 echo "$CMD0 &"
17957 cat "${te}0" >&2
17958 cat "$tdebug" >&2
17959 numFAIL=$((numFAIL+1))
17960 listFAIL="$listFAIL $N"
17961 namesFAIL="$namesFAIL $NAME"
17962 else
17963 $PRINTF "$OK\n"
17964 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17965 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17966 numOK=$((numOK+1))
17968 fi # NUMCOND
17970 esac
17971 N=$((N+1))
17974 while read _UNIX _SRV _CLI; do
17975 if [ -z "$_UNIX" ] || [[ "$_UNIX" == \#* ]]; then continue; fi
17976 SRV=${_UNIX}-$_SRV
17977 CLI=${_UNIX}-$_CLI
17978 CLI_=$(echo $CLI |tr x- x_)
17979 PROTO=${_UNIX}
17980 proto=$(tolower $PROTO)
17982 # Test the unix-bind-tempname option
17983 NAME=${_UNIX}_${_SRV}_${_CLI}_BIND_TEMPNAME
17984 case "$TESTS" in
17985 *%$N%*|*%functions%*|*%$proto%*|*%socket%*|*%tempname%*|*%listen%*|*%fork%*|*%$NAME%*)
17986 TEST="$NAME: Option unix-bind-tempname"
17987 # Start a UNIX domain service with forking
17988 # Start a TCP service with forking that relays to the UNIX domain service
17989 # Open two concurrent client sessions to the TCP service.
17990 # When both sessions work (in particular, when the UNIX domain service does not
17991 # log "Transport endpoint is not connected" and the TCP service does not fail
17992 # with "Address already in use"), the test succeeded.
17993 if ! eval $NUMCOND; then :;
17994 elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then
17995 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
17996 numCANT=$((numCANT+1))
17997 listCANT="$listCANT $N"
17998 else
17999 ts="$td/test$N.sock"
18000 tf="$td/test$N.stdout"
18001 te="$td/test$N.stderr"
18002 tdiff="$td/test$N.diff"
18003 da="test$N $(date) $RANDOM"
18004 CMD0="$TRACE $SOCAT $opts -lp server $SRV:${ts}0,fork PIPE"
18005 # Using this command would show the principal problem: UNIX (and ABSTRACT)
18006 # datagram clients do not internally bind to a defined address and thus cannot
18007 # receive replies. Applies to all(?) Linux, (some)FreeBSD, (some)Solaris, others
18008 # not tried
18009 #CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0"
18010 # Attempt to bind the datagram client to some address works, but only for a
18011 # single client; when multiple clients are forked they conflict
18012 # The following command is the solution: option unix-bind-tempname generates
18013 # random names (like tempnam(2)) for binding the datagram client socket;
18014 # creating the XXXXXX file makes sure that the (non abstract) clients cannot
18015 # erronously bind there (part of the test)
18016 CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind=${ts}1"
18017 touch ${ts}1.XXXXXX; CMD1="$TRACE $SOCAT $opts -lp tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind-tempname=${ts}1.XXXXXX"
18018 CMD2="$TRACE $SOCAT $opts -lp client - TCP4-CONNECT:$LOCALHOST:$PORT"
18019 printf "test $F_n $TEST... " $N
18020 $CMD0 2>"${te}0" &
18021 pid0=$!
18022 wait${proto}port ${ts}0 1
18023 $CMD1 2>"${te}1" &
18024 pid1=$!
18025 waittcp4port $PORT 1
18026 { echo "$da a"; sleep 2; } |$CMD2 >"${tf}2a" 2>"${te}2a" &
18027 pid2a=$!
18028 sleep 1
18029 echo "$da b" |$CMD2 >"${tf}2b" 2>"${te}2b"
18030 rc2b=$?
18031 sleep 1
18032 kill $pid0 $pid1 $pid2a 2>/dev/null; wait
18033 if [ $rc2b -ne 0 ]; then
18034 $PRINTF "$FAILED\n"
18035 echo "$CMD0 &"
18036 cat "${te}0" >&2
18037 echo "$CMD1 &"
18038 cat "${te}1" >&2
18039 echo "$CMD2 &"
18040 cat "${te}2a" >&2
18041 echo "$CMD2"
18042 cat "${te}2b" >&2
18043 numFAIL=$((numFAIL+1))
18044 listFAIL="$listFAIL $N"
18045 elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then
18046 $PRINTF "$FAILED (phase a)\n"
18047 echo "$CMD0 &"
18048 cat "${te}0" >&2
18049 echo "$CMD1 &"
18050 cat "${te}1" >&2
18051 echo "$CMD2"
18052 cat "${te}2a" >&2
18053 echo "diff a:" >&2
18054 cat ${tdiff}2a >&2
18055 numFAIL=$((numFAIL+1))
18056 listFAIL="$listFAIL $N"
18057 elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then
18058 $PRINTF "$FAILED\n"
18059 echo "$CMD0 &"
18060 cat "${te}0" >&2
18061 echo "$CMD1 &"
18062 cat "${te}1" >&2
18063 echo "$CMD2 &"
18064 cat "${te}2a" >&2
18065 echo "$CMD2"
18066 cat "${te}2b" >&2
18067 echo "diff b:" >&2
18068 cat ${tdiff}2b >&2
18069 numFAIL=$((numFAIL+1))
18070 listFAIL="$listFAIL $N"
18071 else
18072 $PRINTF "$OK\n"
18073 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18074 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18075 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18076 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18077 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18078 if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi
18079 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18080 if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi
18081 numOK=$((numOK+1))
18083 fi # NUMCOND
18085 esac
18086 PORT=$((PORT+1))
18087 N=$((N+1))
18089 done <<<"
18090 UNIX LISTEN CONNECT
18091 UNIX LISTEN CLIENT
18092 UNIX RECVFROM CLIENT
18093 UNIX RECVFROM SENDTO
18094 ABSTRACT LISTEN CONNECT
18095 ABSTRACT LISTEN CLIENT
18096 ABSTRACT RECVFROM CLIENT
18097 ABSTRACT RECVFROM SENDTO
18100 # Test if OS/libc is not prone to symlink attacks on UNIX bind()
18101 NAME=TEMPNAME_SEC
18102 case "$TESTS" in
18103 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%dgram%*|*%security%*|*%$NAME%*)
18104 TEST="$NAME: test if a symlink attack works against bind()"
18105 # Create a symlink .sock2 pointing to non-existing .sock3
18106 # Start Socat with UNIX-SENDTO...,bind=.sock2
18107 # When .sock3 exists the test failed
18108 if ! eval $NUMCOND; then :; else
18109 tf="$td/test$N.stdout"
18110 te="$td/test$N.stderr"
18111 ts1="$td/test$N.sock1"
18112 ts2="$td/test$N.sock2"
18113 ts3="$td/test$N.sock3"
18114 tdiff="$td/test$N.diff"
18115 da="test$N $(date) $RANDOM"
18116 CMD0a="rm -f $ts3"
18117 CMD0b="ln -s $ts3 $ts2"
18118 CMD1="$TRACE $SOCAT $opts UNIX-SENDTO:$ts1,bind=$ts2 PIPE"
18119 rc1=$?
18120 printf "test $F_n $TEST... " $N
18121 $CMD0a
18122 $CMD0b
18123 #echo; ls -l $ts2 $ts3
18124 $CMD1 2>"${te}1" &
18125 pid1=$!
18126 waitunixport $ts1 1 1 2>/dev/null
18127 #res="$(ls -l $ts3 2>/dev/null)"
18128 kill $pid1 2>/dev/null
18129 if [ -e $ts3 ]; then
18130 $PRINTF "$FAILED\n"
18131 echo "symlink target has been created" >&2
18132 echo "$CMD0a" >&2
18133 cat "${te}0a" >&2
18134 echo "$CMD0b" >&2
18135 cat "${te}0b" >&2
18136 echo "$CMD1" >&2
18137 cat "${te}1" >&2
18138 numFAIL=$((numFAIL+1))
18139 listFAIL="$listFAIL $N"
18140 elif ! grep -q " E " ${te}1; then
18141 $PRINTF "$FAILED\n"
18142 echo "Socat did not fail"
18143 echo "$CMD0a" >&2
18144 cat "${te}0a" >&2
18145 echo "$CMD0b" >&2
18146 cat "${te}0b" >&2
18147 echo "$CMD1" >&2
18148 cat "${te}1" >&2
18149 numFAIL=$((numFAIL+1))
18150 listFAIL="$listFAIL $N"
18151 else
18152 $PRINTF "$OK\n"
18153 if [ "$VERBOSE" ]; then echo "$CMD0a"; fi
18154 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
18155 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
18156 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
18157 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18158 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18159 numOK=$((numOK+1))
18161 fi # NUMCOND
18163 esac
18164 PORT=$((PORT+1))
18165 N=$((N+1))
18168 # Test the new f-setpipe-sz option on a STDIN pipe
18169 NAME=STDIN_F_SETPIPE_SZ
18170 case "$TESTS" in
18171 *%$N%*|*%functions%*|*%filan%*|*%dual%*|*%stdio%*|*%exec%*|*%pipe%*|*%f-setpipe-sz%*|*%$NAME%*)
18172 TEST="$NAME: f-setpipe-sz on STDIN"
18173 # Start Socat in a shell pipe and have it calling Filan via EXEC and nofork
18174 # Check Filan output if pipe size of its input pipe is modified.
18175 if ! eval $NUMCOND; then :;
18176 # Remove unneeded checks, adapt lists of the remaining ones
18177 elif ! $(type true >/dev/null 2>&1); then
18178 $PRINTF "test $F_n $TEST... ${YELLOW}true not available${NORMAL}\n" $N
18179 numCANT=$((numCANT+1))
18180 listCANT="$listCANT $N"
18181 elif ! F=$(testfeats STDIO EXEC); then
18182 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18183 numCANT=$((numCANT+1))
18184 listCANT="$listCANT $N"
18185 elif ! A=$(testaddrs STDIO EXEC); then
18186 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18187 numCANT=$((numCANT+1))
18188 listCANT="$listCANT $N"
18189 elif ! o=$(testoptions f-setpipe-sz nofork) >/dev/null; then
18190 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18191 numCANT=$((numCANT+1))
18192 listCANT="$listCANT $N"
18193 else
18194 tf="$td/test$N.stdout"
18195 te="$td/test$N.stderr"
18196 tdiff="$td/test$N.diff"
18197 da="test$N $(date) $RANDOM"
18198 newport tcp4 # or whatever proto, or drop this line
18199 # Find the default pipe size
18200 PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18201 PIPESZ2=$((2*PIPESZ))
18202 CMD0="$TRACE $SOCAT $opts STDIN,f-setpipe-sz=$PIPESZ2!!STDOUT EXEC:$FILAN,nofork"
18203 printf "test $F_n $TEST... " $N
18204 true |$CMD0 >"${tf}" 2>"${te}0"
18205 rc0=$?
18206 PIPESZ2b="$(cat "$tf" |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18207 if [ "$rc0" -ne 0 ]; then
18208 $PRINTF "$FAILED\n"
18209 echo "$CMD0"
18210 cat "${te}0" >&2
18211 numFAIL=$((numFAIL+1))
18212 listFAIL="$listFAIL $N"
18213 namesFAIL="$namesFAIL $NAME"
18214 elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then
18215 $PRINTF "$FAILED\n"
18216 echo "$CMD0"
18217 cat "${te}0" >&2
18218 echo "diff:" >&2
18219 cat "$tdiff" >&2
18220 numFAIL=$((numFAIL+1))
18221 listFAIL="$listFAIL $N"
18222 namesFAIL="$namesFAIL $NAME"
18223 else
18224 $PRINTF "$OK\n"
18225 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
18226 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18227 numOK=$((numOK+1))
18229 fi # NUMCOND
18231 esac
18232 N=$((N+1))
18234 # Test the new f-setpipe-sz option on EXEC with pipes
18235 NAME=EXEC_F_SETPIPE_SZ
18236 case "$TESTS" in
18237 *%$N%*|*%functions%*|*%filan%*|*%stdio%*|*%exec%*|*%pipe%*|*%f-setpipe-sz%*|*%$NAME%*)
18238 TEST="$NAME: f-setpipe-sz on EXEC with pipes"
18239 # Start Socat calling Filan via EXEC and pipes and f-setpipe-sz
18240 # Check Filan output if pipe size of both pipes is modified.
18241 if ! eval $NUMCOND; then :;
18242 # Remove unneeded checks, adapt lists of the remaining ones
18243 elif ! F=$(testfeats STDIO EXEC); then
18244 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18245 numCANT=$((numCANT+1))
18246 listCANT="$listCANT $N"
18247 elif ! A=$(testaddrs STDIO EXEC); then
18248 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18249 numCANT=$((numCANT+1))
18250 listCANT="$listCANT $N"
18251 elif ! o=$(testoptions pipes f-setpipe-sz) >/dev/null; then
18252 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18253 numCANT=$((numCANT+1))
18254 listCANT="$listCANT $N"
18255 else
18256 tf="$td/test$N.stdout"
18257 te="$td/test$N.stderr"
18258 tdiff="$td/test$N.diff"
18259 # Find the default pipe size
18260 PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18261 PIPESZ2=$((2*PIPESZ))
18262 CMD0="$TRACE $SOCAT $opts STDIO EXEC:$FILAN,pipes,f-setpipe-sz=$PIPESZ2"
18263 printf "test $F_n $TEST... " $N
18264 $CMD0 >"$tf" 2>"${te}0"
18265 rc0=$?
18266 PIPESZ2b="$(cat "$tf" |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18267 if [ "$rc0" -ne 0 ]; then
18268 $PRINTF "$FAILED\n"
18269 echo "$CMD0"
18270 cat "${te}0" >&2
18271 numFAIL=$((numFAIL+1))
18272 listFAIL="$listFAIL $N"
18273 namesFAIL="$namesFAIL $NAME"
18274 elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then
18275 $PRINTF "$FAILED\n"
18276 echo "$CMD0 &"
18277 cat "${te}0" >&2
18278 echo "diff:" >&2
18279 cat "$tdiff" >&2
18280 numFAIL=$((numFAIL+1))
18281 listFAIL="$listFAIL $N"
18282 namesFAIL="$namesFAIL $NAME"
18283 else
18284 $PRINTF "$OK\n"
18285 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
18286 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18287 numOK=$((numOK+1))
18289 fi # NUMCOND
18291 esac
18292 N=$((N+1))
18295 NAME=DCCP4
18296 case "$TESTS" in
18297 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%dccp%*|*%listen%*|*%$NAME%*)
18298 TEST="$NAME: DCCP over IPv4"
18299 if ! eval $NUMCOND; then :
18300 elif ! cond=$(checkconds "" "" "" \
18301 "IP4 DCCP LISTEN STDIO PIPE" \
18302 "DCCP4-LISTEN PIPE STDIN STDOUT DCCP4" \
18303 "so-reuseaddr" \
18304 "dccp4" ); then
18305 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18306 numCANT=$((numCANT+1))
18307 listCANT="$listCANT $N"
18308 else
18309 tf="$td/test$N.stdout"
18310 te="$td/test$N.stderr"
18311 tdiff="$td/test$N.diff"
18312 newport dccp4; tsl=$PORT
18313 ts="127.0.0.1:$tsl"
18314 da="test$N $(date) $RANDOM"
18315 CMD1="$TRACE $SOCAT $opts DCCP4-LISTEN:$tsl,$REUSEADDR PIPE"
18316 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT DCCP4:$ts"
18317 printf "test $F_n $TEST... " $N
18318 $CMD1 >"$tf" 2>"${te}1" &
18319 pid1=$!
18320 waittcp4port $tsl 1
18321 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18322 if [ $? -ne 0 ]; then
18323 $PRINTF "$FAILED\n"
18324 echo "$CMD0 &"
18325 cat "${te}0" >&2
18326 echo "$CMD1"
18327 cat "${te}1" >&2
18328 numFAIL=$((numFAIL+1))
18329 listFAIL="$listFAIL $N"
18330 namesFAIL="$namesFAIL $NAME"
18331 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
18332 $PRINTF "$FAILED\n"
18333 echo "$CMD0 &"
18334 cat "${te}0" >&2
18335 echo "$CMD1"
18336 cat "${te}1" >&2
18337 echo "// diff:" >&2
18338 cat "$tdiff" >&2
18339 numFAIL=$((numFAIL+1))
18340 listFAIL="$listFAIL $N"
18341 namesFAIL="$namesFAIL $NAME"
18342 else
18343 $PRINTF "$OK\n"
18344 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18345 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18346 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18347 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18348 numOK=$((numOK+1))
18350 kill $pid1 2>/dev/null
18351 wait
18352 fi ;; # NUMCOND, checkconds
18353 esac
18354 N=$((N+1))
18357 NAME=UDPLITE4STREAM
18358 case "$TESTS" in
18359 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
18360 TEST="$NAME: echo via connection to UDP-Lite V4 socket"
18361 if ! eval $NUMCOND; then :;
18362 # Remove unneeded checks, adapt lists of the remaining ones
18363 elif ! cond=$(checkconds \
18364 "" \
18365 "" \
18366 "" \
18367 "IP4 UDPLITE LISTEN STDIO PIPE" \
18368 "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
18369 "so-reuseaddr" \
18370 "udplite4" ); then
18371 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18372 numCANT=$((numCANT+1))
18373 listCANT="$listCANT $N"
18374 namesCANT="$namesCANT $NAME"
18375 else
18376 tf="$td/test$N.stdout"
18377 te="$td/test$N.stderr"
18378 tdiff="$td/test$N.diff"
18379 tsl=$PORT
18380 ts="$LOCALHOST:$tsl"
18381 da="test$N $(date) $RANDOM"
18382 CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
18383 CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
18384 printf "test $F_n $TEST... " $N
18385 $CMD1 >"$tf" 2>"${te}1" &
18386 pid1=$!
18387 waitudplite4port $tsl 1
18388 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18389 rc2=$?
18390 kill $pid1 2>/dev/null; wait
18391 if [ $rc2 -ne 0 ]; then
18392 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
18393 echo "$CMD1 &"
18394 cat "${te}1" >&2
18395 echo "$CMD2"
18396 cat "${te}2" >&2
18397 numFAIL=$((numFAIL+1))
18398 listFAIL="$listFAIL $N"
18399 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
18400 $PRINTF "$FAILED (diff)\n"
18401 echo "$CMD1 &" >&2
18402 cat "${te}1"
18403 echo "$CMD2" >&2
18404 cat "${te}2" >&2
18405 echo "// diff:" >&2
18406 cat "$tdiff" >&2
18407 numFAIL=$((numFAIL+1))
18408 listFAIL="$listFAIL $N"
18409 namesFAIL="$namesFAIL $NAME"
18410 else
18411 $PRINTF "$OK\n"
18412 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
18413 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18414 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18415 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
18416 numOK=$((numOK+1))
18418 fi ;; # NUMCOND
18419 esac
18420 PORT=$((PORT+1))
18421 N=$((N+1))
18424 NAME=UDPLITE4STREAM
18425 case "$TESTS" in
18426 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
18427 TEST="$NAME: echo via connection to UDP-Lite V4 socket"
18428 if ! eval $NUMCOND; then :;
18429 # Remove unneeded checks, adapt lists of the remaining ones
18430 elif ! cond=$(checkconds \
18431 "" \
18432 "" \
18433 "" \
18434 "IP4 UDPLITE LISTEN STDIO PIPE" \
18435 "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
18436 "so-reuseaddr" \
18437 "udplite4" ); then
18438 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18439 numCANT=$((numCANT+1))
18440 listCANT="$listCANT $N"
18441 namesCANT="$namesCANT $NAME"
18442 else
18443 tf="$td/test$N.stdout"
18444 te="$td/test$N.stderr"
18445 tdiff="$td/test$N.diff"
18446 tsl=$PORT
18447 ts="$LOCALHOST:$tsl"
18448 da="test$N $(date) $RANDOM"
18449 CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
18450 CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
18451 printf "test $F_n $TEST... " $N
18452 $CMD1 >"$tf" 2>"${te}1" &
18453 pid1=$!
18454 waitudplite4port $tsl 1
18455 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18456 rc2=$?
18457 kill $pid1 2>/dev/null; wait
18458 if [ $rc2 -ne 0 ]; then
18459 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
18460 echo "$CMD1 &"
18461 cat "${te}1" >&2
18462 echo "$CMD2"
18463 cat "${te}2" >&2
18464 numFAIL=$((numFAIL+1))
18465 listFAIL="$listFAIL $N"
18466 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
18467 $PRINTF "$FAILED (diff)\n"
18468 echo "$CMD1 &" >&2
18469 cat "${te}1"
18470 echo "$CMD2" >&2
18471 cat "${te}2" >&2
18472 echo "// diff:" >&2
18473 cat "$tdiff" >&2
18474 numFAIL=$((numFAIL+1))
18475 listFAIL="$listFAIL $N"
18476 namesFAIL="$namesFAIL $NAME"
18477 else
18478 $PRINTF "$OK\n"
18479 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
18480 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18481 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18482 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
18483 numOK=$((numOK+1))
18485 fi ;; # NUMCOND
18486 esac
18487 PORT=$((PORT+1))
18488 N=$((N+1))
18491 NAME=UDPLITE4STREAM
18492 case "$TESTS" in
18493 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
18494 TEST="$NAME: echo via connection to UDP-Lite V4 socket"
18495 if ! eval $NUMCOND; then :;
18496 # Remove unneeded checks, adapt lists of the remaining ones
18497 elif ! cond=$(checkconds \
18498 "" \
18499 "" \
18500 "" \
18501 "IP4 UDPLITE LISTEN STDIO PIPE" \
18502 "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
18503 "so-reuseaddr" \
18504 "udplite4" ); then
18505 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18506 numCANT=$((numCANT+1))
18507 listCANT="$listCANT $N"
18508 namesCANT="$namesCANT $NAME"
18509 else
18510 tf="$td/test$N.stdout"
18511 te="$td/test$N.stderr"
18512 tdiff="$td/test$N.diff"
18513 tsl=$PORT
18514 ts="$LOCALHOST:$tsl"
18515 da="test$N $(date) $RANDOM"
18516 CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
18517 CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
18518 printf "test $F_n $TEST... " $N
18519 $CMD1 >"$tf" 2>"${te}1" &
18520 pid1=$!
18521 waitudplite4port $tsl 1
18522 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18523 rc2=$?
18524 kill $pid1 2>/dev/null; wait
18525 if [ $rc2 -ne 0 ]; then
18526 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
18527 echo "$CMD1 &"
18528 cat "${te}1" >&2
18529 echo "$CMD2"
18530 cat "${te}2" >&2
18531 numFAIL=$((numFAIL+1))
18532 listFAIL="$listFAIL $N"
18533 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
18534 $PRINTF "$FAILED (diff)\n"
18535 echo "$CMD1 &" >&2
18536 cat "${te}1"
18537 echo "$CMD2" >&2
18538 cat "${te}2" >&2
18539 echo "// diff:" >&2
18540 cat "$tdiff" >&2
18541 numFAIL=$((numFAIL+1))
18542 listFAIL="$listFAIL $N"
18543 namesFAIL="$namesFAIL $NAME"
18544 else
18545 $PRINTF "$OK\n"
18546 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
18547 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18548 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18549 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
18550 numOK=$((numOK+1))
18552 fi ;; # NUMCOND
18553 esac
18554 PORT=$((PORT+1))
18555 N=$((N+1))
18558 # test: setting of environment variables that describe a stream socket
18559 # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT,
18560 # SOCAT_PEERPORT when applicable
18561 while read KEYW FEAT SEL TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
18562 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
18564 protov="$(echo "$KEYW" |tr A-Z a-z)"
18565 proto="${protov%%[0-9]}"
18566 NAME=${KEYW}LISTENENV
18567 case "$TESTS" in
18568 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%$SEL%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
18569 TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
18570 # have a server accepting a connection and invoking some shell code. The shell
18571 # code extracts and prints the SOCAT related environment vars.
18572 # outside code then checks if the environment contains the variables correctly
18573 # describing the peer and local sockets.
18574 if ! eval $NUMCOND; then :;
18575 elif ! cond=$(checkconds \
18576 "" \
18577 "" \
18578 "" \
18579 "$FEAT $(echo $SEL |tr a-z A-Z) STDIO SYSTEM" \
18580 "$KEYW-LISTEN SYSTEM STDIO $KEYW-CONNECT" \
18581 "$REUSEADDR bind" \
18582 "$protov" ); then
18583 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18584 numCANT=$((numCANT+1))
18585 listCANT="$listCANT $N"
18586 namesCANT="$namesCANT $NAME"
18587 else
18588 tf="$td/test$N.stdout"
18589 te="$td/test$N.stderr"
18590 TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars
18591 tsa="$TEST_SOCKADDR" # test server address
18592 if [ "$PORTMETHOD" = PORT ]; then
18593 newport $proto; tsp="$PORT"; # test server port
18594 tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind=
18595 TEST_SOCKPORT=$tsp
18596 else
18597 tsa1="$tsa"; tsa2= # tsa1 used for addr parameter
18599 TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars
18600 tca="$TEST_PEERADDR" # test client address
18601 if [ "$PORTMETHOD" = PORT ]; then
18602 newport $proto; tcp="$PORT"; # test client port
18603 tca="$tca:$tcp"
18604 TEST_PEERPORT=$tcp
18606 #CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\""
18607 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\""
18608 CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
18609 printf "test $F_n $TEST... " $N
18610 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
18611 pid0=$!
18612 wait${protov}port $tsa1 1
18613 { echo; sleep 0.1; } |$CMD1 2>"${te}1"
18614 rc1=$?
18615 waitfile "$tf" 2
18616 kill $pid0 2>/dev/null; wait
18617 #set -vx
18618 if [ $rc1 != 0 ]; then
18619 $PRINTF "$NO_RESULT (client failed):\n"
18620 echo "$CMD0 &"
18621 cat "${te}0"
18622 echo "$CMD1"
18623 cat "${te}1"
18624 numCANT=$((numCANT+1))
18625 listCANT="$listCANT $N"
18626 elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
18627 "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
18628 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \
18629 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_PEERPORT" \) \
18630 ]; then
18631 $PRINTF "$OK\n"
18632 if [ "$debug" ]; then
18633 echo "$CMD0 &"
18634 cat "${te}0"
18635 echo "$CMD1"
18636 cat "${te}1"
18638 numOK=$((numOK+1))
18639 else
18640 $PRINTF "$FAILED\n"
18641 echo "$CMD0 &"
18642 cat "${te}0"
18643 echo "$CMD1"
18644 cat "${te}1"
18645 echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
18646 diff - "${tf}"
18647 numFAIL=$((numFAIL+1))
18648 listFAIL="$listFAIL $N"
18650 fi # NUMCOND, feats
18652 esac
18653 N=$((N+1))
18654 #set +xv
18656 done <<<"
18657 UDPLITE4 IP4 udplite 127.0.0.1 $SECONDADDR PORT
18658 UDPLITE6 IP6 udplite [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
18662 # test the max-children option on pseudo connected sockets
18663 while read KEYW FEAT SEL ADDR IPPORT SHUT; do
18664 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
18665 RUNS=$(tolower $KEYW)
18666 PROTO=$KEYW
18667 proto="$(echo "$PROTO" |tr A-Z a-z)"
18668 # test the max-children option on pseudo connected sockets
18669 NAME=${KEYW}MAXCHILDREN
18670 case "$TESTS" in
18671 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
18672 TEST="$NAME: max-children option"
18673 # start a listen process with max-children=1; connect with a client, let it
18674 # send data and then sleep; connect with second client that wants to send
18675 # data immediately, but keep first client active until server terminates.
18676 #If max-children is working correctly only the first data should
18677 # arrive.
18678 if ! eval $NUMCOND; then :;
18679 elif ! cond=$(checkconds \
18680 "" \
18681 "" \
18682 "" \
18683 "$FEAT IP${KEYW##*[A-Z]} FILE STDIO" \
18684 "FILE $PROTO-LISTEN STDIO $PROTO-CONNECT" \
18685 "$REUSEADDR o-trunc o-creat o-append fork max-children $SHUT" \
18686 "$RUNS" ); then
18687 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18688 numCANT=$((numCANT+1))
18689 listCANT="$listCANT $N"
18690 namesCANT="$namesCANT $NAME"
18691 else
18692 case "X$IPPORT" in
18693 "XPORT")
18694 newport $proto
18695 tsl=$PORT # test socket listen address
18696 tsc="$ADDR:$PORT" # test socket connect address
18699 tsl="$(eval echo "$ADDR")" # resolve $N
18700 tsc=$tsl
18701 esac
18702 #ts="$td/test$N.sock"
18703 tf="$td/test$N.stdout"
18704 te="$td/test$N.stderr"
18705 tdiff="$td/test$N.diff"
18706 da="test$N $(date) $RANDOM"
18707 # on some Linux distributions it hangs, thus -T option here
18708 CMD0="$TRACE $SOCAT $opts -U -T 4 FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
18709 CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,$SHUT"
18710 printf "test $F_n $TEST... " $N
18711 $CMD0 >/dev/null 2>"${te}0" &
18712 pid0=$!
18713 wait${proto}port $tsl 1
18714 (echo "$da 1"; sleep 3) |$CMD1 >"${tf}1" 2>"${te}1" &
18715 pid1=$!
18716 sleep 1
18717 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
18718 pid2=$!
18719 sleep 1
18720 cpids="$(childpids $pid0)"
18721 kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait
18722 if echo -e "$da 1" |diff - $tf >$tdiff; then
18723 $PRINTF "$OK\n"
18724 numOK=$((numOK+1))
18725 else
18726 $PRINTF "$FAILED\n"
18727 echo "$CMD0 &"
18728 echo "(echo \"$da 1\"; sleep 2) |$CMD1"
18729 echo "echo \"$da 2\" |$CMD1"
18730 cat "${te}0"
18731 cat "${te}1"
18732 cat "${te}2"
18733 cat "$tdiff"
18734 numFAIL=$((numFAIL+1))
18735 listFAIL="$listFAIL $N"
18737 fi # NUMCOND
18739 esac
18740 N=$((N+1))
18741 done <<<"
18742 UDPLITE4 UDPLITE udplite 127.0.0.1 PORT shut-null
18743 UDPLITE6 UDPLITE udplite [::1] PORT shut-null
18747 # Test the procan controlling terminal output
18748 NAME=PROCAN_CTTY
18749 case "$TESTS" in
18750 *%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
18751 TEST="$NAME: test procan controlling terminal output"
18752 # Run procan and compare its controlling terminal output with tty (oops)"
18753 if ! eval $NUMCOND; then :
18754 elif ! cond=$(checkconds \
18755 "" \
18756 "" \
18757 "tty" \
18758 "" \
18759 "" \
18760 "" \
18761 "" ); then
18762 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18763 numCANT=$((numCANT+1))
18764 listCANT="$listCANT $N"
18765 else
18766 tf="$td/test$N.stdout"
18767 te="$td/test$N.stderr"
18768 tdiff="$td/test$N.diff"
18769 CMD0="$TRACE $PROCAN"
18770 printf "test $F_n $TEST... " $N
18771 $CMD0 >"${tf}0" 2>"${te}0"
18772 rc0=$?
18773 if [ "$rc0" -ne 0 ]; then
18774 $PRINTF "$FAILED\n"
18775 echo "$CMD0"
18776 cat "${te}0" >&2
18777 numFAIL=$((numFAIL+1))
18778 listFAIL="$listFAIL $N"
18779 namesFAIL="$namesFAIL $NAME"
18780 elif ! tty |diff - <(cat ${tf}0 |grep "controlling terminal" |grep -v -e '"/dev/tty"' -e none |head -n 1 |sed -e 's/controlling terminal by .*:[[:space:]]*//' -e 's/"//g') >$tdiff; then
18781 $PRINTF "$FAILED\n"
18782 echo "$CMD0"
18783 cat "${te}0" >&2
18784 echo "// diff:" >&2
18785 cat "$tdiff" >&2
18786 numFAIL=$((numFAIL+1))
18787 listFAIL="$listFAIL $N"
18788 namesFAIL="$namesFAIL $NAME"
18789 else
18790 $PRINTF "$OK\n"
18791 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
18792 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18793 numOK=$((numOK+1))
18795 fi # NUMCOND
18797 esac
18798 N=$((N+1))
18801 # Test the socat-chain.sh script with SOCKS4 over UNIX-socket
18802 NAME=SOCAT_CHAIN_SOCKS4
18803 case "$TESTS" in
18804 *%$N%*|*%functions%*|*%scripts%*|*%socat-chain%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%unix%*|*%socks4%*|*%socket%*|*%$NAME%*)
18805 TEST="$NAME: test socat-chain.sh with SOCKS4 over UNIX-socket"
18806 # Run a socks4 server on UNIX-listen
18807 # Connect with socat-chein.sh; check if data transfer is correct
18808 if ! eval $NUMCOND; then :
18809 # Remove unneeded checks, adapt lists of the remaining ones
18810 elif ! cond=$(checkconds \
18811 "" \
18812 "" \
18813 "" \
18814 "IP4 TCP LISTEN STDIO UNIX" \
18815 "TCP4-LISTEN PIPE STDIN STDOUT TCP4 UNIX UNIX-LISTEN" \
18816 "so-reuseaddr" \
18817 "tcp4 unix" ); then
18818 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18819 numCANT=$((numCANT+1))
18820 listCANT="$listCANT $N"
18821 namesCANT="$namesCANT $NAME"
18822 else
18823 ts="$td/test$N.sock"
18824 tf="$td/test$N.stdout"
18825 te="$td/test$N.stderr"
18826 tdiff="$td/test$N.diff"
18827 da="test$N $(date) $RANDOM"
18828 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,reuseaddr EXEC:./socks4echo.sh"
18829 CMD1="$TRACE ./socat-chain.sh $opts - SOCKS4::32.98.76.54:32109,socksuser=nobody UNIX:$ts"
18830 printf "test $F_n $TEST... " $N
18831 $CMD0 >/dev/null 2>"${te}0" &
18832 pid0=$!
18833 waitunixport $ts 1
18834 #relsleep 1 # if no matching wait*port function
18835 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
18836 rc1=$?
18837 kill $pid0 2>/dev/null; wait
18838 if [ "$rc1" -ne 0 ]; then
18839 $PRINTF "$FAILED (rc1=$rc1)\n"
18840 echo "$CMD0 &"
18841 cat "${te}0" >&2
18842 echo "$CMD1"
18843 cat "${te}1" >&2
18844 numFAIL=$((numFAIL+1))
18845 listFAIL="$listFAIL $N"
18846 namesFAIL="$namesFAIL $NAME"
18847 elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
18848 $PRINTF "$FAILED (diff)\n"
18849 echo "$CMD0 &"
18850 cat "${te}0" >&2
18851 echo "$CMD1"
18852 cat "${te}1" >&2
18853 echo "// diff:" >&2
18854 cat "$tdiff" >&2
18855 numFAIL=$((numFAIL+1))
18856 listFAIL="$listFAIL $N"
18857 namesFAIL="$namesFAIL $NAME"
18858 else
18859 $PRINTF "$OK\n"
18860 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18861 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18862 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18863 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18864 numOK=$((numOK+1))
18866 fi # NUMCOND
18868 esac
18869 N=$((N+1))
18871 # Test the socat-chain.sh script by driving SSL over serial
18872 NAME=SOCAT_CHAIN_SSL_PTY
18873 case "$TESTS" in
18874 *%$N%*|*%functions%*|*%scripts%*|*%socat-chain%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%openssl%*|*%unix%*|*%socket%*|*%pty%*|*%$NAME%*)
18875 TEST="$NAME: test socat-chain.sh with SSL over PTY"
18876 # Run a socat-chain.sh instance with SSL listening behind a PTY;
18877 # open the PTY with socat-chein.sh using SSL;
18878 # check if data transfer is correct
18879 if ! eval $NUMCOND; then :
18880 # Remove unneeded checks, adapt lists of the remaining ones
18881 elif ! cond=$(checkconds \
18882 "" \
18883 "" \
18884 "" \
18885 "IP4 TCP LISTEN OPENSSL STDIO PTY" \
18886 "TCP4-LISTEN SOCKETPAIR STDIN STDOUT TCP4 SSL SSL-L" \
18887 "so-reuseaddr" \
18888 "tcp4" ); then
18889 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18890 numCANT=$((numCANT+1))
18891 listCANT="$listCANT $N"
18892 namesCANT="$namesCANT $NAME"
18893 elif [[ $BASH_VERSION =~ ^[1-3]\. ]]; then
18894 $PRINTF "test $F_n $TEST... ${YELLOW}requires bash 4 or higher${NORMAL}\n" $N
18895 numCANT=$((numCANT+1))
18896 listCANT="$listCANT $N"
18897 namesCANT="$namesCANT $NAME"
18898 else
18899 gentestcert testsrv
18900 tp="$td/test$N.pty"
18901 tf="$td/test$N.stdout"
18902 te="$td/test$N.stderr"
18903 tdiff="$td/test$N.diff"
18904 da="test$N $(date) $RANDOM"
18905 CMD0="$TRACE ./socat-chain.sh $opts PTY,link=$tp SSL-L,cert=testsrv.pem,verify=0 SOCKETPAIR"
18906 CMD1="$TRACE ./socat-chain.sh $opts - SSL,cafile=testsrv.crt,commonname=localhost $tp,cfmakeraw"
18907 printf "test $F_n $TEST... " $N
18908 $CMD0 >/dev/null 2>"${te}0" &
18909 pid0=$!
18910 waitfile $tp 1
18911 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
18912 rc1=$?
18913 kill $pid0 2>/dev/null
18914 wait 2>/dev/null
18915 if [ "$rc1" -ne 0 ]; then
18916 $PRINTF "$FAILED (rc1=$rc1)\n"
18917 echo "$CMD0 &"
18918 cat "${te}0" >&2
18919 echo "$CMD1"
18920 cat "${te}1" >&2
18921 numFAIL=$((numFAIL+1))
18922 listFAIL="$listFAIL $N"
18923 namesFAIL="$namesFAIL $NAME"
18924 elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
18925 $PRINTF "$FAILED (diff)\n"
18926 echo "$CMD0 &"
18927 cat "${te}0" >&2
18928 echo "$CMD1"
18929 cat "${te}1" >&2
18930 echo "// diff:" >&2
18931 cat "$tdiff" >&2
18932 numFAIL=$((numFAIL+1))
18933 listFAIL="$listFAIL $N"
18934 namesFAIL="$namesFAIL $NAME"
18935 else
18936 $PRINTF "$OK\n"
18937 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18938 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18939 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18940 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18941 numOK=$((numOK+1))
18943 fi # NUMCOND
18945 esac
18946 N=$((N+1))
18949 # Test the socat-mux.sh script
18950 # Requires lo/lo0 to have broadcast address 127.255.255.255
18951 NAME=SOCAT_MUX
18952 case "$TESTS" in
18953 *%$N%*|*%functions%*|*%script%*|*%socat-mux%*|*%socket%*|*%udp%*|*%broadcast%*|*%$NAME%*)
18954 TEST="$NAME: test the socat-mux.sh script"
18955 # Start a simple TCP server
18956 # Start socat-mux.sh to connect to this server
18957 # Connect with two clients to mux, send different data records from both.
18958 # Check if both client received both records in order.
18959 if ! eval $NUMCOND; then :
18960 # Remove unneeded checks, adapt lists of the remaining ones
18961 elif ! cond=$(checkconds \
18962 "" \
18963 "" \
18964 "" \
18965 "IP4 TCP LISTEN STDIO UNIX" \
18966 "TCP4-LISTEN PIPE STDIN STDOUT TCP4 UNIX UNIX-LISTEN" \
18967 "so-reuseaddr" \
18968 "tcp4 unix" ); then
18969 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18970 numCANT=$((numCANT+1))
18971 listCANT="$listCANT $N"
18972 namesCANT="$namesCANT $NAME"
18973 else
18974 tf="$td/test$N.stdout"
18975 te="$td/test$N.stderr"
18976 tdiff="$td/test$N.diff"
18977 newport tcp4
18978 PORT0=$PORT
18979 newport tcp4
18980 PORT1=$PORT
18981 CMD0="$TRACE $SOCAT $opts -lp server TCP-LISTEN:$PORT0 PIPE"
18982 CMD1="./socat-mux.sh TCP-LISTEN:$PORT1 TCP-CONNECT:$LOCALHOST:$PORT0"
18983 CMD2="$TRACE $SOCAT $opts -lp client STDIO TCP:$LOCALHOST:$PORT1"
18984 da_a="test$N $(date) $RANDOM"
18985 da_b="test$N $(date) $RANDOM"
18986 printf "test $F_n $TEST... " $N
18987 $CMD0 >/dev/null 2>"${te}0" &
18988 pid0=$!
18989 waittcp4port $PORT0 1
18990 $CMD1 >/dev/null 2>"${te}1" &
18991 pid1=$!
18992 waittcp4port $PORT1 1
18993 { sleep 1; echo "$da_a"; sleep 2; } </dev/null |$CMD2 >"${tf}2a" 2>"${te}2a" &
18994 pid2a=$!
18995 { sleep 2; echo "$da_b"; sleep 1; } |$CMD2 >"${tf}2b" 2>"${te}2b"
18996 rc2b=$?
18997 kill $pid0 $(childpids $pid1) $pid1 2>/dev/null
18998 wait 2>/dev/null
18999 kill $pid0 2>/dev/null; wait
19000 if [ "$rc2b" -ne 0 ]; then
19001 $PRINTF "$FAILED (rc2b=$rc2b)\n"
19002 echo "$CMD0 &"
19003 cat "${te}0" >&2
19004 echo "$CMD1 &"
19005 cat "${te}1" >&2
19006 echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD2 &"
19007 cat "${te}2a" >&2
19008 echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD2"
19009 cat "${te}2b" >&2
19010 numFAIL=$((numFAIL+1))
19011 listFAIL="$listFAIL $N"
19012 namesFAIL="$namesFAIL $NAME"
19013 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2a" >${tdiff}_a; then
19014 $PRINTF "$FAILED (diff a)\n"
19015 echo "$CMD0 &"
19016 cat "${te}0" >&2
19017 echo "$CMD1 &"
19018 cat "${te}1" >&2
19019 echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD2 &"
19020 cat "${te}2a" >&2
19021 echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD2"
19022 cat "${te}2b" >&2
19023 echo "// diff a:" >&2
19024 cat "${tdiff}_a" >&2
19025 numFAIL=$((numFAIL+1))
19026 listFAIL="$listFAIL $N"
19027 namesFAIL="$namesFAIL $NAME"
19028 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2b" >${tdiff}_b; then
19029 $PRINTF "$FAILED (diff b)\n"
19030 echo "$CMD0 &"
19031 cat "${te}0" >&2
19032 echo "$CMD1 &"
19033 cat "${te}1" >&2
19034 echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD2 &"
19035 cat "${te}2a" >&2
19036 echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD2"
19037 cat "${te}2b" >&2
19038 echo "// diff b:" >&2
19039 cat "${tdiff}_b" >&2
19040 numFAIL=$((numFAIL+1))
19041 listFAIL="$listFAIL $N"
19042 namesFAIL="$namesFAIL $NAME"
19043 else
19044 $PRINTF "$OK\n"
19045 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19046 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19047 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
19048 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19049 if [ "$VERBOSE" ]; then echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD2 &"; fi
19050 if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi
19051 if [ "$VERBOSE" ]; then echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD2"; fi
19052 if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi
19053 numOK=$((numOK+1))
19055 fi # NUMCOND
19057 esac
19058 N=$((N+1))
19061 # Test the socat-broker.sh script
19062 # Requires lo/lo0 to have broadcast address 127.255.255.255
19063 NAME=SOCAT_BROKER
19064 case "$TESTS" in
19065 *%$N%*|*%functions%*|*%script%*|*%socat-broker%*|*%socket%*|*%udp%*|*%broadcast%*|*%$NAME%*)
19066 TEST="$NAME: test the socat-broker.sh script"
19067 # Start a socat-broker.sh instance
19068 # Connect with two clients, send different data records from both.
19069 # Check if both client received both records in order.
19070 if ! eval $NUMCOND; then :
19071 # Remove unneeded checks, adapt lists of the remaining ones
19072 elif ! cond=$(checkconds \
19073 "" \
19074 "" \
19075 "" \
19076 "IP4 UDP TCP LISTEN STDIO" \
19077 "TCP4-LISTEN TCP4-CONNECT STDIO UDP-DATAGRAM" \
19078 "so-reuseaddr" \
19079 "udp4 tcp4" ); then
19080 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19081 numCANT=$((numCANT+1))
19082 listCANT="$listCANT $N"
19083 namesCANT="$namesCANT $NAME"
19084 else
19085 tf="$td/test$N.stdout"
19086 te="$td/test$N.stderr"
19087 tdiff="$td/test$N.diff"
19088 newport tcp4
19089 CMD0="$TRACE ./socat-broker.sh $OPTS TCP4-LISTEN:$PORT"
19090 CMD1="$TRACE $SOCAT $OPTS - TCP:$LOCALHOST:$PORT"
19091 da_a="test$N $(date) $RANDOM"
19092 da_b="test$N $(date) $RANDOM"
19093 printf "test $F_n $TEST... " $N
19094 $CMD0 >/dev/null 2>"${te}0" &
19095 pid0=$!
19096 waittcp4port $PORT 1
19097 { sleep 1; echo "$da_a"; sleep 2; } </dev/null |$CMD1 >"${tf}1a" 2>"${te}1a" &
19098 pid1a=$!
19099 { sleep 2; echo "$da_b"; sleep 1; } |$CMD1 >"${tf}1b" 2>"${te}1b"
19100 rc1b=$?
19101 kill $(childpids $pid0) $pid0 $pid1a 2>/dev/null
19102 wait 2>/dev/null
19103 #kill $pid0 2>/dev/null; wait
19104 if [ "$rc1b" -ne 0 ]; then
19105 $PRINTF "$FAILED (rc1b=$rc1b)\n"
19106 echo "$CMD0 &"
19107 cat "${te}0" >&2
19108 echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD1"
19109 cat "${te}1a" >&2
19110 echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD1"
19111 cat "${te}1b" >&2
19112 numFAIL=$((numFAIL+1))
19113 listFAIL="$listFAIL $N"
19114 namesFAIL="$namesFAIL $NAME"
19115 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1a" >${tdiff}_a; then
19116 $PRINTF "$FAILED (diff a)\n"
19117 echo "$CMD0 &"
19118 cat "${te}0" >&2
19119 echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD1"
19120 cat "${te}1a" >&2
19121 echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD1"
19122 cat "${te}1b" >&2
19123 echo "// diff a:" >&2
19124 cat "${tdiff}_a" >&2
19125 numFAIL=$((numFAIL+1))
19126 listFAIL="$listFAIL $N"
19127 namesFAIL="$namesFAIL $NAME"
19128 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1b" >${tdiff}_b; then
19129 $PRINTF "$FAILED (diff b)\n"
19130 echo "$CMD0 &"
19131 cat "${te}0" >&2
19132 echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD1"
19133 cat "${te}1a" >&2
19134 echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD1"
19135 cat "${te}1b" >&2
19136 echo "// diff b:" >&2
19137 cat "${tdiff}_b" >&2
19138 numFAIL=$((numFAIL+1))
19139 listFAIL="$listFAIL $N"
19140 namesFAIL="$namesFAIL $NAME"
19141 else
19142 $PRINTF "$OK\n"
19143 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19144 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19145 if [ "$VERBOSE" ]; then echo "{ sleep 1; echo \"\$da_a\"; sleep 2; } |$CMD1"; fi
19146 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
19147 if [ "$VERBOSE" ]; then echo "{ sleep 2; echo \"\$da_b\"; sleep 1; } |$CMD1"; fi
19148 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
19149 numOK=$((numOK+1))
19151 fi # NUMCOND
19153 esac
19154 N=$((N+1))
19157 # end of common tests
19159 ##################################################################################
19160 #=================================================================================
19161 # here come tests that might affect your systems integrity. Put normal tests
19162 # before this paragraph.
19163 # tests must be explicitely selected by roottough or name (not number)
19165 NAME=PTYGROUPLATE
19166 case "$TESTS" in
19167 *%roottough%*|*%$NAME%*)
19168 TEST="$NAME: pty with group-late works on pty"
19169 # up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of
19170 # the pty with options user-late, group-late, or perm-late.
19171 # here we check for correct behaviour.
19172 # ATTENTION: in case of failure of this test the
19173 # group of /dev/ptmx might be changed!
19174 if ! eval $NUMCOND; then :; else
19175 # save current /dev/ptmx properties
19177 for f in /dev/ptmx /dev/ptc; do
19178 if [ -e $f ]; then
19179 F=$(echo "$f" |tr / ..)
19180 ls -l $f >"$td/test$N.$F.ls-l"
19181 break
19183 done
19184 printf "test $F_n $TEST... " $N
19185 if [ -z "$F" ]; then
19186 echo -e "${YELLOW}no /dev/ptmx or /dev/ptc${NORMAL}"
19187 else
19188 GROUP=daemon
19189 tf="$td/test$N.stdout"
19190 te="$td/test$N.stderr"
19191 tl="$td/test$N.pty"
19192 tdiff="$td/test$N.diff"
19193 da="test$N $(date) $RANDOM"
19194 CMD0="$TRACE $SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE"
19195 CMD1="$TRACE $SOCAT $opts - $tl,raw,echo=0"
19196 $CMD0 >/dev/null 2>"${te}0" &
19197 pid0=$!
19198 (echo "$da"; usleep $MICROS; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf"
19199 rc1=$?
19200 kill $pid0 2>/dev/null; wait
19201 if [ $rc1 -ne 0 ]; then
19202 $PRINTF "$FAILED\n"
19203 echo "$CMD0 &"
19204 echo "$CMD1"
19205 cat "${te}0"
19206 cat "${te}1"
19207 numFAIL=$((numFAIL+1))
19208 listFAIL="$listFAIL $N"
19209 elif echo "$da" |diff - "$tf" >$tdiff; then
19210 $PRINTF "$OK\n"
19211 numOK=$((numOK+1))
19212 else
19213 $PRINTF "$FAILED\n"
19214 cat "$tdiff"
19215 numFAIL=$((numFAIL+1))
19216 listFAIL="$listFAIL $N"
19218 if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then
19219 $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n"
19221 fi # no /dev/ptmx
19222 fi # NUMCOND
19224 esac
19225 N=$((N+1))
19228 echo "Used temp directory $TD - you might want to remove it after analysis"
19229 echo "Summary: $((N-1)) tests, $((numOK+numFAIL+numCANT)) selected; $numOK ok, $numFAIL failed, $numCANT could not be performed"
19231 set -- $listCANT; while [ "$1" ]; do echo "$1"; shift; done >"$td/cannot.lst"
19232 ln -sf "$td/cannot.lst" .
19233 set -- $listFAIL; while [ "$1" ]; do echo "$1"; shift; done >"$td/failed.lst"
19234 ln -sf "$td/failed.lst" .
19235 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"
19236 ln -sf "$td/result.txt" .
19237 if [ "$numCANT" -gt 0 ]; then
19238 echo "CANT: $listCANT"
19240 if [ "$numFAIL" -gt 0 ]; then
19241 echo "FAILED: $listFAIL"
19244 if [ -z "$OPT_EXPECT_FAIL" ]; then
19245 [ "$numFAIL" -eq 0 ]
19246 exit # with rc from above statement
19249 #set -vx
19251 if [ "$OPT_EXPECT_FAIL" ]; then
19252 diff <(set -- $(echo "$EXPECT_FAIL" |tr ',' ' '); while [ "$1" ]; do echo "$1"; shift; done) "$td/failed.lst" >"$td/failed.diff"
19253 ln -sf "$td/failed.diff" .
19254 #grep "^"
19255 grep "^> " "$td/failed.diff" |awk '{print($2);}' >"$td/failed.unexp"
19256 ln -sf "$td/failed.unexp" .
19257 echo "FAILED unexpected: $(cat "$td/failed.unexp" |xargs echo)"
19258 grep "^< " "$td/failed.diff" |awk '{print($2);}' >"$td/ok.unexp"
19259 ln -sf "$td/ok.unexp" .
19260 echo "OK unexpected: $(cat "$td/ok.unexp" |xargs echo)"
19261 else
19262 touch "$td/failed.diff"
19264 #listFAIL=$(cat "$td/failed.lst" |xargs echo)
19265 #numFAIL="$(wc -l "$td/failed.lst" |awk '{print($1);}')"
19267 ! test -s "$td/failed.unexp"
19268 exit
19270 #==============================================================================
19272 rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips*
19274 # end
19276 # too dangerous - run as root and having a shell problem, it might purge your
19277 # file systems
19278 #rm -r "$td"
19280 # sometimes subprocesses hang; we want to see this
19281 wait
19283 exit
19285 #==============================================================================
19286 # test template
19288 # Give a description of what is tested (a bugfix, a new feature...)
19289 NAME=SHORT_UNIQUE_TESTNAME
19290 case "$TESTS" in
19291 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
19292 #*%internet%*|*%root%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%bug%*|...
19293 TEST="$NAME: give a one line description of test"
19294 # Describe how the test is performed, and what's the success criteria
19295 if ! eval $NUMCOND; then :
19296 # Remove unneeded checks, adapt lists of the remaining ones
19297 elif ! cond=$(checkconds \
19298 "Linux,FreeBSD" \
19299 "root" \
19300 "nslookup" \
19301 "IP4 TCP LISTEN STDIO PIPE" \
19302 "TCP4-LISTEN PIPE STDIN STDOUT TCP4" \
19303 "so-reuseaddr" \
19304 "tcp4" ); then
19305 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19306 numCANT=$((numCANT+1))
19307 listCANT="$listCANT $N"
19308 namesCANT="$namesCANT $NAME"
19309 else
19310 tf="$td/test$N.stdout"
19311 te="$td/test$N.stderr"
19312 tdiff="$td/test$N.diff"
19313 da="test$N $(date) $RANDOM"
19314 newport tcp4 # or whatever proto, or drop this line
19315 CMD0="$TRACE $SOCAT $opts server-address PIPE"
19316 CMD1="$TRACE $SOCAT $opts - client-address"
19317 printf "test $F_n $TEST... " $N
19318 $CMD0 >/dev/null 2>"${te}0" &
19319 pid0=$!
19320 wait<something>port $PORT 1
19321 #relsleep 1 # if no matching wait*port function
19322 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
19323 rc1=$?
19324 kill $pid0 2>/dev/null; wait
19325 if [ "$rc1" -ne 0 ]; then
19326 $PRINTF "$FAILED (rc1=$rc1)\n"
19327 echo "$CMD0 &"
19328 cat "${te}0" >&2
19329 echo "$CMD1"
19330 cat "${te}1" >&2
19331 numFAIL=$((numFAIL+1))
19332 listFAIL="$listFAIL $N"
19333 namesFAIL="$namesFAIL $NAME"
19334 elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
19335 $PRINTF "$FAILED (diff)\n"
19336 echo "$CMD0 &"
19337 cat "${te}0" >&2
19338 echo "$CMD1"
19339 cat "${te}1" >&2
19340 echo "// diff:" >&2
19341 cat "$tdiff" >&2
19342 numFAIL=$((numFAIL+1))
19343 listFAIL="$listFAIL $N"
19344 namesFAIL="$namesFAIL $NAME"
19345 elif [ ??? ]; then
19346 # The test could not run meaningfully
19347 $PRINTF "$CANT\n"
19348 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19349 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19350 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
19351 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19352 numCANT=$((numCANT+1))
19353 listCANT="$listCANT $N"
19354 else
19355 $PRINTF "$OK\n"
19356 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19357 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19358 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
19359 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19360 numOK=$((numOK+1))
19362 fi # NUMCOND
19364 esac
19365 N=$((N+1))