Version 1.8.0.2 - CVE-2024-54661: Arbitrary file overwrite in readline.sh
[socat.git] / test.sh
blob5204ac713746f278e26c616b978bca27f914dcfa
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 GREP_E="grep -E"
34 GREP_F="grep -F"
36 TRUE=$(type -p true)
38 usage() {
39 $ECHO "Usage: $0 <options> [<test-spec> ...]"
40 $ECHO "options:"
41 $ECHO "\t-h \t\tShow this help"
42 $ECHO "\t-t <sec> \tBase for timeouts in seconds, default: 0.1"
43 $ECHO "\t-v \t\tBe more verbose, show failed commands"
44 $ECHO "\t-n <num> \tOnly perform test with given number"
45 $ECHO "\t-N <num> \tOnly perform tests starting with given number"
46 $ECHO "\t-C \t\tClear/remove left over certificates from previous runs"
47 $ECHO "\t-x \t\tShow commands executed, even when test succeeded"
48 $ECHO "\t-d \t\tShow log output of commands, even when they did not fail (not yet completed)"
49 $ECHO "\t-D \t\tOutput some platform/system specific defines (variables)"
50 $ECHO "\t--internet \tAllow tests that send packets to Internet"
51 $ECHO "\t--expect-fail N1,N2,... \tIgnore failure of these tests"
52 $ECHO "\ttest-spec \Number of test or name of test"
53 $ECHO "Contents of environment variable OPTS are passed to Socat invocations, e.'g:"
54 $ECHO "OPTS=\"-d -d -d -d -lu\" ./test.sh"
55 $ECHO "TRACE=\"strace -tt -v\" Use trace,valgrind etc.on socat"
56 $ECHO "SOCAT=/path/to/socat \tselect socat executable for test"
57 $ECHO "FILAN=... PROCAN=..."
58 $ECHO "Find the tests' stdout,stderr,diff in $TMPDIR/$USER/\$PID"
61 val_t=
62 NUMCOND=true
63 #NUMCOND="test \$N -gt 70"
64 VERBOSE=
65 DEBUG=
66 DEFS=
67 INTERNET=
68 OPT_EXPECT_FAIL= EXPECT_FAIL=
69 while [ "$1" ]; do
70 case "X$1" in
71 X-h) usage; exit 0 ;;
72 X-d) DEBUG="1" ;;
73 X-D) DEFS="1" ;;
74 X-t?*) val_t="${1#-t}" ;;
75 X-t) shift; val_t="$1" ;;
76 X-v) VERBOSE=1 ;; # show commands
77 X-n?*) NUMCOND="test \$N -eq ${1#-n}" ;;
78 X-n) shift; NUMCOND="test \$N -eq $1" ;;
79 X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;;
80 X-N) shift; NUMCOND="test \$N -ge $1" ;;
81 X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;;
82 X--internet|X-internet) INTERNET=1 ;; # allow access to 3rd party Internet hosts
83 X--expect-fail|X-expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;;
84 X-*) echo "Unknown option \"$1\"" >&2
85 usage >&2
86 exit 1 ;;
87 *) break;
88 esac
89 shift
90 done
91 debug=$DEBUG
93 [ "$DEFS" ] && echo "BASH_VERSION=\"$BASH_VERSION\"" >&2
95 [ "$DEFS" ] && echo "ECHO_E=\"$ECHO_E\"" >&2
97 UNAME=`uname`
98 [ "$DEFS" ] && echo "UNAME=\"$UNAME\"" >&2
99 UNAME_R=`uname -r`
100 [ "$DEFS" ] && echo "UNAME_R=\"$UNAME_R\"" >&2
102 #MICROS=100000
103 case "X$val_t" in
104 X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;;
105 X*.*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS}000000"; uS="${uS:0:6}" ;;
106 X*) S="${val_t}"; uS="000000" ;;
107 esac
108 MICROS=${S}${uS}
109 MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0}
110 # changed below again
112 _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}"
113 [ -z "$SECONDs" ] && SECONDs=0
114 [ "$DEFS" ] && echo "SECONDs=\"$SECONDs\"" >&2
116 withroot=0 # 1: perform privileged tests even if not run by root
118 [ -z "$SOCAT" ] && SOCAT="./socat"
119 if ! [ -x "$SOCAT" ] && ! type $SOCAT >/dev/null 2>&1; then
120 echo "$SOCAT does not exist" >&2; exit 1;
122 if [ "$SOCAT" = socat ]; then
123 SOCAT=$(type -p socat) || SOCAT=$(which socat)
125 [ "$DEFS" ] && echo "SOCAT=\"$SOCAT\"" >&2
127 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
128 [ "$DEFS" ] && echo "PROCAN=\"$PROCAN\"" >&2
129 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
130 [ "$DEFS" ] && echo "FILAN=\"$FILAN\"" >&2
132 if [ -z "$val_t" ]; then
133 # Determine the time Socat needs for an empty run
134 $SOCAT /dev/null /dev/null # populate caches
135 MILLIs=$(bash -c 'time socat /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.)
136 while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done # strip leading '0' to avoid octal
137 [ -z "$MILLIs" ] && MILLIs=1
138 [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2
140 # On my idle development computer this value flaps from 0.001 to 0.004
141 # 0.001 lets many tests fail, so we triple the result
142 MILLIs=$((3*MILLIs))
143 [ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (2)" >&2
144 MICROS=${MILLIs}000
146 #set -vx
147 case $MICROS in
148 ???????*) val_t=${MICROS%??????}.${MICROS: -6} ;;
149 *) x=000000$MICROS; val_t=0.${x: -6} ;;
150 esac
151 else
152 # Calculate MICROS from val_t
153 case "X$val_t" in
154 X*.???????*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS:0:6}" ;;
155 X*.*) S="${val_t%.*}"; uS="${val_t#*.}"; uS="${uS}000000"; uS="${uS:0:6}" ;;
156 X*) S="${val_t}"; uS="000000" ;;
157 esac
158 MICROS=${S}${uS}
159 MICROS=${MICROS##0000}; MICROS=${MICROS##00}; MICROS=${MICROS##0}
161 export MICROS
162 [ "$DEFS" ] && echo "MICROS=\"$MICROS\"" >&2
163 [ "$DEFS" ] && echo "val_t=\"$val_t\"" >&2
164 opt_t="-t $val_t"
165 M2=$((2*MICROS))
166 M4=$((4*MICROS))
167 M8=$((8*MICROS))
168 case $M2 in ???????*) T2=${M2%??????}.${M2: -6};; *) x=00000$M2; T2=0.${x: -6};; esac
169 case $M4 in ???????*) T4=${M4%??????}.${M4: -6};; *) x=00000$M4; T4=0.${x: -6};; esac
170 case $M8 in ???????*) T8=${M8%??????}.${M8: -6};; *) x=00000$M8; T8=0.${x: -6};; esac
171 [ "$DEFS" ] && echo "M2=\"$M2\"" >&2
172 [ "$DEFS" ] && echo "T2=\"$T2\"" >&2
173 [ "$DEFS" ] && echo "T4=\"$T4\"" >&2
174 [ "$DEFS" ] && echo "T8=\"$T8\"" >&2
176 _MICROS=$((MICROS+999999)); SECONDs="${_MICROS%??????}"
177 [ -z "$SECONDs" ] && SECONDs=0
180 #PATH=$PATH:/opt/freeware/bin
181 #PATH=$PATH:/usr/local/ssl/bin
182 PATH=$PATH:/sbin # RHEL6:ip
183 case "$0" in
184 */*) PATH="${0%/*}:$PATH"
185 esac
186 PATH=.:$PATH # for usleep,relsleep
187 [ "$DEFS" ] && echo "PATH=\"$PATH\"" >&2
189 #OPENSSL_RAND="-rand /dev/egd-pool"
190 #SOCAT_EGD="egd=/dev/egd-pool"
191 MISCDELAY=1
193 OPTS="$opt_t $OPTS"
194 opts="$OPTS"
195 [ "$DEFS" ] && echo "opts=\"$opts\"" >&2
197 TESTS="$*"; export TESTS
198 if ! SOCAT_MAIN_WAIT= $SOCAT -V >/dev/null 2>&1; then
199 echo "Failed to execute $SOCAT, exiting" >&2
200 exit 1
203 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/')
204 if [ -z "$SOCAT_VERSION" ]; then
205 echo "Warning: failed to retrieve Socat version" >&2
207 [ "$DEFS" ] && echo "SOCAT_VERSION=\"$SOCAT_VERSION\"" >&2
209 if type ip >/dev/null 2>&1; then
210 IP_V="$(ip -V)"
211 [ "$DEFS" ] && echo "IP_V=\"$IP_V\""
212 if echo "$IP_V" |grep -q -i -e "^ip utility, iproute2-" -e BusyBox; then
213 IP=$(type -p ip)
214 else
215 unset IP
219 if type ss >/dev/null 2>&1; then
220 SS_V="$(ss -V)"
221 [ "$DEFS" ] && echo "SS_V=\"$SS_V\""
222 # On Ubuntu-10 ss has differing output format (no "LISTEN"), use netstat then
223 if echo "$SS_V" |grep -q -e "^ss utility, iproute2-[2-6]" -e "^ss utility, iproute2-ss[^0]"; then
224 SS=$(type -p ss)
225 else
226 unset SS
229 [ "$DEFS" ] && echo "NETSTAT=\"$(type netstat 2>/dev/null)\""
231 # for some tests we need a network interface
232 if type ip >/dev/null 2>&1; then
233 INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/")
234 else
235 case "$UNAME" in
236 Linux)
237 if [ "$IP" ]; then
238 INTERFACE="$($IP route get 8.8.8.8 |grep ' dev ' |sed -e 's/.* dev //' -e 's/ .*//')"
239 else
240 INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($8);}')"
241 fi ;;
242 FreeBSD) INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($4);}')" ;;
243 *) INTERFACE="$(netstat -rn |grep -e "^default" -e "^0\.0\.0\.0" |awk '{print($4);}')" ;;
244 esac
246 [ "$DEFS" ] && echo "INTERFACE=\"$INTERFACE\"" >&2
247 MCINTERFACE=$INTERFACE
248 [ -z "$MCINTERFACE" ] && MCINTERFACE=lo # !!! Linux only - and not always
249 [ "$DEFS" ] && echo "MCINTERFACE=\"$MCINTERFACE\"" >&2
251 #LOCALHOST=192.168.58.1
252 LOCALHOST=localhost # attention: on FreeBSD-10 localhost resolves primarily to IPv6
253 LOCALHOST4=127.0.0.1
254 LOCALHOST6="[::1]"
255 #IPPROTO=$(awk '{print($2);}' /etc/protocols |sort -n |tail -n 1)
256 #IPPROTO=$(($PROTO+1))
257 IPPROTO=$((144+RANDOM/2048))
258 [ "$DEFS" ] && echo "IPPROTO=\"$IPPROTO\"" >&2
259 _PORT=12001
260 SOURCEPORT=2002
261 REUSEADDR=reuseaddr # use this with LISTEN addresses and bind options
263 # get some system constants for use in tests
264 SOCK_DGRAM="$($PROCAN -c |grep "^#define[[:space:]]*SOCK_DGRAM[[:space:]]" |cut -d' ' -f3)"
265 [ "$DEFS" ] && echo "SOCK_DGRAM=\"$SOCK_DGRAM\"" >&2
266 FOPEN_MAX=$($PROCAN -c 2>/dev/null |grep '^#define[ ][ ]*FOPEN_MAX' |awk '{print($3);}')
267 [ "$DEFS" ] && echo "FOPEN_MAX=\"$FOPEN_MAX\"" >&2
268 PF_INET6="$($PROCAN -c |grep "^#define[[:space:]]*PF_INET6[[:space:]]" |cut -d' ' -f3)"
269 [ "$DEFS" ] && echo "PF_INET6=\"$PF_INET6\"" >&2
270 TIOCEXCL="$($PROCAN -c |grep "^#define[[:space:]]*TIOCEXCL[[:space:]]" |cut -d' ' -f3)"
271 [ "$DEFS" ] && echo "TIOCEXCL=\"$TIOCEXCL\"" >&2
272 SOL_SOCKET="$($PROCAN -c |grep "^#define[[:space:]]*SOL_SOCKET[[:space:]]" |cut -d' ' -f3)"
273 [ "$DEFS" ] && echo "SOL_SOCKET=\"$SOL_SOCKET\"" >&2
274 SO_REUSEADDR="$($PROCAN -c |grep "^#define[[:space:]]*SO_REUSEADDR[[:space:]]" |cut -d' ' -f3)"
275 [ "$DEFS" ] && echo "SO_REUSEADDR=\"$SO_REUSEADDR\"" >&2
276 TCP_MAXSEG="$($PROCAN -c |grep "^#define[[:space:]]*TCP_MAXSEG[[:space:]]" |cut -d' ' -f3)"
277 [ "$DEFS" ] && echo "TCP_MAXSEG=\"$TCP_MAXSEG\"" >&2
278 SIZE_T=$($PROCAN |grep "^[^[:space:]]*size_t" |awk '{print($3);}')
279 [ "$DEFS" ] && echo "SIZE_T=\"$SIZE_T\"" >&2
280 #AI_ADDRCONFIG=; if [ "$($SOCAT -hhh |grep ai-addrconfig)" ]; then AI_ADDRCONFIG="ai-addrconfig=0"; fi
281 #[ "$DEFS" ] && echo "AI_ADDRCONFIG=\"$AI_ADDRCONFIG\"" >&2
283 # SSL certificate contents
284 TESTCERT_CONF=testcert.conf
285 TESTCERT6_CONF=testcert6.conf
286 TESTALT_CONF=testalt.conf
288 TESTCERT_COMMONNAME="$LOCALHOST"
289 TESTCERT_COMMONNAME6="$LOCALHOST6"
290 TESTCERT_COUNTRYNAME="XY"
291 TESTCERT_LOCALITYNAME="Lunar Base"
292 TESTCERT_ORGANIZATIONALUNITNAME="socat"
293 TESTCERT_ORGANIZATIONNAME="dest-unreach"
294 TESTCERT_SUBJECT="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
295 TESTCERT_ISSUER="C = $TESTCERT_COUNTRYNAME, CN = $TESTCERT_COMMONNAME, O = $TESTCERT_ORGANIZATIONNAME, OU = $TESTCERT_ORGANIZATIONALUNITNAME, L = $TESTCERT_LOCALITYNAME"
296 RSABITS=2048 # Ubuntu-20.04 with OpenSSL-1.1.1f does not work with 1024 nor 1536
297 DSABITS=2048
298 cat >$TESTCERT_CONF <<EOF
299 prompt=no
301 [ req ]
302 default_bits = $RSABITS
303 distinguished_name=Test
305 [ Test ]
306 countryName=$TESTCERT_COUNTRYNAME
307 commonName=$TESTCERT_COMMONNAME
308 O=$TESTCERT_ORGANIZATIONNAME
309 OU=$TESTCERT_ORGANIZATIONALUNITNAME
310 L=$TESTCERT_LOCALITYNAME
314 cat >$TESTCERT6_CONF <<EOF
315 prompt=no
317 [ req ]
318 default_bits = $RESBITS
319 distinguished_name=Test
321 [ Test ]
322 countryName=$TESTCERT_COUNTRYNAME
323 commonName=$TESTCERT_COMMONNAME6
324 O=$TESTCERT_ORGANIZATIONNAME
325 OU=$TESTCERT_ORGANIZATIONALUNITNAME
326 L=$TESTCERT_LOCALITYNAME
330 cat >$TESTALT_CONF <<EOF
331 # config for generation of self signed certificate with IP addresses in
332 # SubjectAltNames
333 prompt=no
335 [ req ]
336 default_bits = $RSABITS
337 distinguished_name = subject
338 x509_extensions = x509_ext
340 [ subject ]
341 countryName=$TESTCERT_COUNTRYNAME
342 commonName=servername
343 O=$TESTCERT_ORGANIZATIONNAME
344 OU=$TESTCERT_ORGANIZATIONALUNITNAME
345 L=$TESTCERT_LOCALITYNAME
347 [ x509_ext ]
348 subjectAltName = @alternate_names
350 [ alternate_names ]
351 DNS.1 = localhost
352 DNS.2 = localhost4
353 DNS.3 = localhost6
354 IP.1 = 127.0.0.1
355 IP.2 = ::1
359 # clean up from previous runs
360 rm -f testcli.{crt,key,pem}
361 rm -f testsrv.{crt,key,pem}
362 rm -f testcli6.{crt,key,pem}
363 rm -f testsrv6.{crt,key,pem}
364 rm -f testalt.{crt,key,pem}
366 CAT="cat"
367 OD_C="od -c"
369 toupper () {
370 case ${BASH_VERSION:0:1} in
371 [1-3]) echo "$@" |tr a-z A-Z ;;
372 [4-9]) echo "${@^^*}" ;;
373 esac
376 tolower () {
377 case ${BASH_VERSION:0:1} in
378 [1-3]) echo "$@" |tr A-Z a-z ;;
379 [4-9]) echo "${@,,*}" ;;
380 esac
383 if ! which usleep >/dev/null 2>&1; then
384 cat >usleep <<EOF
385 #! /usr/bin/env bash
386 # temporary script from Socat test.sh:
387 # sleep for a number of µs
388 u=\$1
389 l=\${#u}
391 [ "\$l" -gt 6 ] && i=\${u%??????}
392 u0=000000\$u
393 s=\${i}.\${u0: -6:6};
394 #echo \$s
395 sleep \$s
397 chmod a+x usleep
400 # precision sleep; takes seconds with fractional part; sleep does this on all test platforms
401 if false; then
402 psleep () {
403 local T="$1"
404 [ "$T" = 0 ] && T=0.000002
405 #$SOCAT -T "$T" PIPE PIPE 2>/dev/null
406 sleep "$T"
408 # time in microseconds to wait in some situations
409 if ! type usleep >/dev/null 2>&1 ||
410 usleep 0 2>&1 |grep -q deprecated; then
411 usleep () {
412 local n="$1"
413 case "$n" in
414 *???????) S="${n%??????}"; uS="${n:${#n}-6}" ;;
415 *) S=0; uS="00000$n"; uS="${uS:${#uS}-6}" ;;
416 esac
417 #$SOCAT -T "$S.$uS" PIPE PIPE 2>/dev/null
418 sleep "$S.$uS"
421 #USLEEP=usleep
424 # calculate the time i*MICROS, output as float number for us with -t
425 reltime () {
426 local n="$1"
427 local S uS
428 local N=$((n*MICROS))
429 case "$N" in
430 *???????) S="${N%??????}"; uS="${N:${#N}-6}" ;;
431 *) S=0; uS="00000$N"; uS="${uS:${#uS}-6}" ;;
432 esac
433 echo "$S.$uS"
436 # A sleep with configurable clocking ($vat_t)
437 # val_t should be at least the time that a Socat invocation, no action, and
438 # termination takes
439 relsleep () {
440 usleep $(($1*MICROS))
443 cat >relsleep <<-'EOF'
444 #! /usr/bin/env bash
445 n="$1"
446 N=$((n*MICROS))
447 case "$N" in
448 *???????) S="${N%??????}"; uS="${N:${#N}-6}" ;;
449 *) S=0; uS="00000$N"; uS="${uS:${#uS}-6}" ;;
450 esac
451 sleep "$S.$uS"
453 chmod a+x relsleep
455 if type ping6 >/dev/null 2>&1; then
456 PING6=ping6
457 else
458 PING6="ping -6"
461 F_n="%3d" # format string for test numbers
462 export LC_ALL=C # for timestamps format...
463 export LANG=C
464 export LANGUAGE=C # knoppix
465 case "$UNAME" in
466 HP-UX|OSF1)
467 echo "$SOCAT -u stdin stdout" >cat.sh
468 chmod a+x cat.sh
469 CAT=./cat.sh
471 SunOS)
472 # /usr/bin/tr doesn't handle the a-z range syntax (needs [a-z]), use
473 # /usr/xpg4/bin/tr instead
474 alias tr=/usr/xpg4/bin/tr
477 CAT="cat"
479 esac
480 [ "$DEFS" ] && echo "CAT=\"$CAT\"" >&2
482 TRUE=$(type -p true)
483 #E=-e # Linux
484 if [ $(echo "x\c") = "x" ]; then E=""
485 elif [ $(echo -e "x\c") = "x" ]; then E="-e"
486 else
487 echo "cannot suppress trailing newline on echo" >&2
488 exit 1
490 ECHO="echo $E"
491 PRINTF="printf"
493 GREP_E="grep -E"
494 GREP_F="grep -F"
496 # some OSes need special options
497 case "$UNAME" in
498 #HP-UX)
499 # # on HP-UX, the default options (below) hang some tests (former 14, 15)
500 # PTYOPTS=
501 # PTYOPTS2=
502 # ;;
503 SunOS)
504 PTYOPTS="perm=600"
505 PTYOPTS2="echo=0,opost=0"
508 PTYOPTS="echo=0,opost=0"
509 #PTYOPTS2="raw,echo=0"
510 PTYOPTS2="cfmakeraw"
511 #PTYOPTS2="rawer"
513 esac
514 [ "$DEFS" ] && echo "PTYOPTS=\"$PTYOPTS\"" >&2
515 [ "$DEFS" ] && echo "PTYOPTS2=\"$PTYOPTS2\"" >&2
517 # for some tests we need an unprivileged user id to su to
518 if [ "$SUDO_USER" ]; then
519 SUBSTUSER="$SUDO_USER"
520 else
521 SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)"
523 [ "$DEFS" ] && echo "SUBSTUSER=\"$SECONDs\"" >&2
525 if [ -z "$SS" ]; then
526 # non-root users might miss ifconfig in their path
527 case "$UNAME" in
528 AIX) IFCONFIG=/usr/sbin/ifconfig ;;
529 FreeBSD) IFCONFIG=/sbin/ifconfig ;;
530 HP-UX) IFCONFIG=/usr/sbin/ifconfig ;;
531 Linux) IFCONFIG=/sbin/ifconfig ;;
532 NetBSD)IFCONFIG=/sbin/ifconfig ;;
533 OpenBSD)IFCONFIG=/sbin/ifconfig ;;
534 OSF1) IFCONFIG=/sbin/ifconfig ;;
535 SunOS) IFCONFIG=/sbin/ifconfig ;;
536 Darwin)IFCONFIG=/sbin/ifconfig ;;
537 DragonFly) IFCONFIG=/sbin/ifconfig ;;
538 *) IFCONFIG=/sbin/ifconfig ;;
539 esac
541 [ "$DEFS" ] && echo "SS=\"$SS\"" >&2
542 [ "$DEFS" ] && echo "IFCONFIG=\"$IFCONFIG\"" >&2
544 # need output like "644"
545 case "$UNAME" in
546 Linux) fileperms() { stat -L --print "%a\n" "$1" 2>/dev/null; } ;;
547 FreeBSD) fileperms() { stat -L -x "$1" |grep ' Mode:' |sed 's/.* Mode:[[:space:]]*([0-9]\([0-7][0-7][0-7]\).*/\1/'; } ;;
548 *) fileperms() {
549 local p s=0 c
550 p="$(ls -l -L "$1" |awk '{print($1);}')"
551 p="${p:1:9}"
552 while [ "$p" ]; do c=${p:0:1}; p=${p:1}; [ "x$c" == x- ]; let "s=2*s+$?"; done
553 printf "%03o\n" $s;
554 } ;;
555 esac
557 # need user (owner) of filesystem entry
558 case "$UNAME" in
559 Linux) fileuser() { stat -L --print "%U\n" "$1" 2>/dev/null; } ;;
560 FreeBSD) fileuser() { ls -l "$1" |awk '{print($3);}'; } ;;
561 *) fileuser() { ls -l "$1" |awk '{print($3);}'; } ;;
562 esac
564 if2addr4() {
565 local IF="$1"
566 if [ "$IP" ]; then
567 $IP address show dev "$IF" |grep "inet " |sed -e "s/.*inet //" -e "s/ .*//"
568 else
569 $IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}' |cut -d: -f2
573 if2bc4() {
574 local IF="$1"
575 if [ "$IP" ]; then
576 $IP address show dev "$IF" |grep ' inet .* brd ' |awk '{print($4);}'
577 else
578 $IFCONFIG "$IF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}'
582 # for some tests we need a second local IPv4 address
583 case "$UNAME" in
584 Linux)
585 if [ "$IP" ]; then
586 BROADCASTIF=$($IP r get 8.8.8.8 |grep ' dev ' |sed 's/.*\<dev[[:space:]][[:space:]]*\([a-z0-9][a-z0-9]*\).*/\1/')
587 else
588 BROADCASTIF=$(route -n |grep '^0.0.0.0 ' |awk '{print($8);}')
590 [ -z "$BROADCASTIF" ] && BROADCASTIF=eth0
591 SECONDADDR=127.1.0.1
592 SECONDMASK=255.255.0.0
593 BCADDR=127.255.255.255
594 BCIFADDR=$(if2addr4 $BROADCASTIF) ;;
595 FreeBSD|NetBSD|OpenBSD)
596 MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1)
597 BROADCASTIF="$MAINIF"
598 SECONDADDR=$($IFCONFIG "$BROADCASTIF" |grep 'inet ' |sed 's|/.*||' |awk '{print($2);}')
599 BCIFADDR="$SECONDADDR"
600 BCADDR=$($IFCONFIG "$BROADCASTIF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;;
601 HP-UX)
602 MAINIF=lan0 # might use "netstat -ni" for this
603 BROADCASTIF="$MAINIF"
604 SECONDADDR=$($IFCONFIG $MAINIF |tail -n 1 |awk '{print($2);}')
605 BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;;
606 SunOS)
607 MAINIF=$($IFCONFIG -a |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1)
608 BROADCASTIF="$MAINIF"
609 #BROADCASTIF=hme0
610 #BROADCASTIF=eri0
611 #SECONDADDR=$($IFCONFIG $BROADCASTIF |grep 'inet ' |awk '{print($2);}')
612 SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |$GREP_F -v ' 127.0.0.1 '| head -n 1)" : '.*inet \([0-9.]*\) .*')
613 #BCIFADDR="$SECONDADDR"
614 #BCADDR=$($IFCONFIG $BROADCASTIF |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}')
616 DragonFly)
617 MAINIF=$($IFCONFIG -a |grep -v ^lp |grep '^[a-z]' |grep -v '^lo0: ' |head -1 |cut -d: -f1)
618 BROADCASTIF="$MAINIF"
619 SECONDADDR=$($IFCONFIG "$BROADCASTIF" |grep 'inet ' |awk '{print($2);}')
620 BCIFADDR="$SECONDADDR"
621 BCADDR=$($IFCONFIG "$BROADCASTIF" |grep 'broadcast ' |sed 's/.*broadcast/broadcast/' |awk '{print($2);}') ;;
622 #AIX|FreeBSD|Solaris)
624 SECONDADDR=$(expr "$($IFCONFIG -a |grep 'inet ' |$GREP_F -v ' 127.0.0.1 ' |head -n 1)" : '.*inet \([0-9.]*\) .*')
626 esac
627 # for generic sockets we need this address in hex form
628 if [ "$SECONDADDR" ]; then
629 SECONDADDRHEX="$(printf "%02x%02x%02x%02x\n" $(echo "$SECONDADDR" |tr '.' ' '))"
632 # for some tests we need a second local IPv6 address
633 case "$UNAME" in
634 Linux) if [ "$IP" ]; then
635 SECONDIP6ADDR=$(expr "$($IP address |grep 'inet6 ' |$GREP_F -v ' ::1/128 '| head -n 1)" : '.*inet6 \([0-9a-f:][0-9a-f:]*\)/.*')
636 else
637 SECONDIP6ADDR=$(expr "$($IFCONFIG -a |grep 'inet6 ' |$GREP_F -v ' ::1/128 '| head -n 1)" : '.*inet \([0-9.]*\) .*')
638 fi ;;
640 SECONDIP6ADDR=$(expr "$($IFCONFIG -a |grep 'inet6 ' |$GREP_F -v ' ::1/128 '| head -n 1)" : '.*inet \([0-9.]*\) .*')
642 esac
643 if [ -z "$SECONDIP6ADDR" ]; then
644 # case "$TESTS" in
645 # *%root2%*) $IFCONFIG eth0 ::2/128
646 # esac
647 SECONDIP6ADDR="$LOCALHOST6"
648 else
649 SECONDIP6ADDR="[$SECONDIP6ADDR]"
652 case "$TERM" in
653 vt100|vt320|linux|xterm|cons25|dtterm|aixterm|sun-color|xterm-color|xterm-256color|screen)
654 # there are different behaviours of printf (and echo)
655 # on some systems, echo behaves different than printf...
656 if [ "$($PRINTF "\0101")" = "A" ]; then
657 RED="\0033[31m"
658 GREEN="\0033[32m"
659 YELLOW="\0033[33m"
660 # if [ "$UNAME" = SunOS ]; then
661 # NORMAL="\0033[30m"
662 # else
663 NORMAL="\0033[39m"
664 # fi
665 else
666 RED="\033[31m"
667 GREEN="\033[32m"
668 YELLOW="\033[33m"
669 # if [ "$UNAME" = SunOS ]; then
670 # NORMAL="\033[30m"
671 # else
672 NORMAL="\033[39m"
673 # fi
675 OK="${GREEN}OK${NORMAL}"
676 FAILED="${RED}FAILED${NORMAL}"
677 NO_RESULT="${YELLOW}NO RESULT${NORMAL}"
678 CANT="$NO_RESULT"
680 *) OK="OK"
681 FAILED="FAILED"
682 NO_RESULT="NO RESULT"
683 CANT="$NO_RESULT"
685 esac
687 if [ -x /usr/xpg4/bin/id ]; then
688 # SunOS has rather useless tools in its default path
689 PATH="/usr/xpg4/bin:$PATH"
692 OPENSSL_S_CLIENT_4=
693 OPENSSL_S_CLIENT_DTLS=
694 init_openssl_s_client () {
695 if openssl s_client -help 2>&1 |grep -q ' -4 '; then
696 OPENSSL_S_CLIENT_4="-4"
697 else
698 OPENSSL_S_CLIENT_4=" "
700 if openssl s_client -help 2>&1 | grep -q ' -dtls '; then
701 OPENSSL_S_CLIENT_DTLS=-dtls
702 else
703 OPENSSL_S_CLIENT_DTLS=-dtls1
707 OPENSSL_S_SERVER_4=
708 OPENSSL_S_SERVER_DTLS=
709 OPENSSL_S_SERVER_NO_IGN_EOF=
710 init_openssl_s_server () {
711 if openssl s_server -help 2>&1 |grep -q ' -4 '; then
712 OPENSSL_S_SERVER_4="-4"
713 else
714 OPENSSL_S_SERVER_4=" "
716 if openssl s_server -help 2>&1 | grep -q ' -dtls '; then
717 OPENSSL_S_SERVER_DTLS="-dtls"
718 else
719 OPENSSL_S_SERVER_DTLS="-dtls1"
721 if openssl s_server -help 2>&1 | grep -q ' -no-ign_eof '; then
722 OPENSSL_S_SERVER_NO_IGN_EOF="-no-ign_eof"
723 else
724 OPENSSL_S_SERVER_NO_IGN_EOF=" "
729 [ -z "$TESTS" ] && TESTS="consistency functions filan"
730 # use '%' as separation char
731 TESTS="%$(echo " $TESTS " |tr ' ' '%')%"
733 [ -z "$USER" ] && USER="$LOGNAME" # HP-UX
734 if [ -z "$TMPDIR" ]; then
735 if [ -z "$TMP" ]; then
736 TMP=/tmp
738 TMPDIR="$TMP"
740 TD="$TMPDIR/$USER/$$"; td="$TD"
741 rm -rf "$TD" || (echo "cannot rm $TD" >&2; exit 1)
742 mkdir -p "$TD"
743 #trap "rm -r $TD" 0 3
745 echo "Using temp directory $TD"
747 case "$TESTS" in
748 *%consistency%*)
749 # test if addresses are sorted alphabetically:
750 $ECHO "testing if address array is sorted...\c"
751 TF="$TD/socat-q"
752 IFS="$($ECHO ' \n\t')"
753 if ! $SOCAT -hhh >/dev/null; then
754 echo "Failed: $SOCAT -hhh" >&2
755 exit -1
757 $SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF"
758 $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"
759 if [ -s "$TF-diff" ]; then
760 $ECHO "\n*** address array is not sorted. Wrong entries:" >&2
761 cat "$TD/socat-q-diff" >&2
762 exit 1
763 else
764 echo " ok"
766 #/bin/rm "$TF"
767 #/bin/rm "$TF-diff"
768 esac
770 case "$TESTS" in
771 *%consistency%*)
772 # test if address options array ("optionnames") is sorted alphabetically:
773 $ECHO "testing if address options are sorted...\c"
774 TF="$TD/socat-qq"
775 $SOCAT -hhh |sed '1,/opt:/ d' |awk '{print($1);}' >"$TF"
776 LC_ALL=C sort "$TF" |diff "$TF" - >"$TF-diff"
777 if [ -s "$TF-diff" ]; then
778 $ECHO "\n*** option array is not sorted. Wrong entries:" >&2
779 cat "$TD/socat-qq-diff" >&2
780 exit 1
781 else
782 echo " ok"
784 /bin/rm "$TF"
785 /bin/rm "$TF-diff"
786 esac
788 #==============================================================================
791 numOK=0
792 numFAIL=0
793 numCANT=0
794 listOK=
795 listFAIL=
796 listCANT=
797 namesFAIL=
799 #==============================================================================
800 # test if selected socat features work ("FUNCTIONS")
802 testecho () {
803 local N="$1"
804 local title="$2"
805 local arg1="$3"; [ -z "$arg1" ] && arg1="-"
806 local arg2="$4"; [ -z "$arg2" ] && arg2="echo"
807 local opts="$5"
808 local T="$6"; [ -z "$T" ] && T=0 # fractional seconds
809 local tf="$td/test$N.stdout"
810 local te="$td/test$N.stderr"
811 local tdiff="$td/test$N.diff"
812 local da="test$N $(date) $RANDOM"
813 if ! eval $NUMCOND; then :; else
814 #local cmd="$TRACE $SOCAT $opts $arg1 $arg2"
815 #$ECHO "testing $title (test $N)... \c"
816 $PRINTF "test $F_n %s... " $N "$title"
817 #echo "$da" |$cmd >"$tf" 2>"$te"
818 { sleep $T; echo "$da"; sleep $T; } | { $TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"; echo $? >"$td/test$N.rc"; } &
819 pid1=$!
820 #sleep 5 && kill $rc1 2>/dev/null &
821 # rc2=$!
822 wait $pid1
823 # kill $rc2 2>/dev/null
824 if [ "$(cat "$td/test$N.rc")" != 0 ]; then
825 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
826 echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2
827 cat "$te" >&2
828 numFAIL=$((numFAIL+1))
829 listFAIL="$listFAIL $N"
830 elif echo "$da" |diff - "$tf" >"$tdiff" 2>&1; then
831 $PRINTF "$OK\n"
832 if [ "$VERBOSE" ]; then echo "$SOCAT $opts $arg1 $arg2" >&2; fi
833 if [ -n "$debug" ]; then cat $te >&2; fi
834 numOK=$((numOK+1))
835 listOK="$listOK $N"
836 else
837 $PRINTF "$FAILED:\n"
838 echo "$TRACE $SOCAT $opts $arg1 $arg2" >&2
839 cat "$te" >&2
840 echo diff: >&2
841 cat "$tdiff" >&2
842 numFAIL=$((numFAIL+1))
843 listFAIL="$listFAIL $N"
845 fi # NUMCOND
848 # test if call to od and throughput of data works - with graceful shutdown and
849 # flush of od buffers
850 testod () {
851 local num="$1"
852 local title="$2"
853 local arg1="$3"; [ -z "$arg1" ] && arg1="-"
854 local arg2="$4"; [ -z "$arg2" ] && arg2="echo"
855 local opts="$5"
856 local T="$6"; [ -z "$T" ] && T=0 # fractional seconds
857 local tf="$td/test$N.stdout"
858 local te="$td/test$N.stderr"
859 local tr="$td/test$N.ref"
860 local tdiff="$td/test$N.diff"
861 local dain="$(date) $RANDOM"
862 if ! eval $NUMCOND; then :; else
863 echo "$dain" |$OD_C >"$tr"
864 # local daout="$(echo "$dain" |$OD_C)"
865 $PRINTF "test $F_n %s... " $num "$title"
866 (sleep $T; echo "$dain"; sleep $T) |$TRACE $SOCAT $opts "$arg1" "$arg2" >"$tf" 2>"$te"
867 if [ "$?" != 0 ]; then
868 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
869 echo "$TRACE $SOCAT $opts $arg1 $arg2"
870 cat "$te"
871 numFAIL=$((numFAIL+1))
872 listFAIL="$listFAIL $num"
873 # elif echo "$daout" |diff - "$tf" >"$tdiff" 2>&1; then
874 elif diff "$tr" "$tf" >"$tdiff" 2>&1; then
875 $PRINTF "$OK\n"
876 if [ -n "$debug" ]; then cat $te; fi
877 numOK=$((numOK+1))
878 listOK="$listOK $N"
879 else
880 $PRINTF "$FAILED: diff:\n"
881 echo "$TRACE $SOCAT $opts $arg1 $arg2"
882 cat "$te"
883 cat "$tdiff"
884 numFAIL=$((numFAIL+1))
885 listFAIL="$listFAIL $num"
887 fi # NUMCOND
890 # test if the socat executable has these features compiled in
891 # print the first missing address type
892 testfeats () {
893 local a A;
894 for a in $@; do
895 A=$(echo "$a" |tr 'a-z-' 'A-Z_')
896 if [ "$A" = "IP" ]; then
897 if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_IP4 1\$" >/dev/null ||
898 SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_IP6 1\$" >/dev/null; then
899 shift
900 continue
901 else
902 echo "$a"
903 return 1
906 if SOCAT_MAIN_WAIT= $SOCAT -V |grep "#define WITH_$A 1\$" >/dev/null; then
907 if [[ "$A" =~ OPENSSL.* ]]; then
908 gentestcert testsrv
909 gentestcert testcli
911 shift
912 continue
914 echo "$a"
915 return 1
916 done
917 return 0
920 # test if the socat executable has these address types compiled in
921 # print the first missing address type
922 testaddrs () {
923 local a A;
924 for a in $@; do
925 A=$(echo "$a" |tr 'a-z' 'A-Z')
926 # the ::::: forces syntax errer and prevents the address from doing anything
927 if ! $SOCAT $A::::: /dev/null 2>&1 </dev/null |grep -q "E unknown device/address"; then
928 shift
929 continue
931 echo "$a"
932 return 1
933 done
934 return 0
937 # test if the socat executable has these options compiled in
938 # print the first missing option
939 testoptions () {
940 local a A;
941 for a in $@; do
942 A=$(echo "$a" |tr 'a-z' 'A-Z')
943 if $SOCAT -hhh |grep "[^a-z0-9-]$a[^a-z0-9-]" >/dev/null; then
944 shift
945 continue
947 echo "$a"
948 return 1
949 done
950 return 0
953 # check if the given pid exists and has child processes
954 # if yes: prints child process lines to stdout, returns 0
955 # if not: prints ev.message to stderr, returns 1
956 childprocess () {
957 local l
958 case "$UNAME" in
959 AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)")" ;;
960 FreeBSD) l="$(ps -faje |grep "^........ ..... $(printf %5u $1)")" ;;
961 HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;;
962 Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;;
963 # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)")" ;;
964 NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;;
965 OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)")" ;;
966 SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)")" ;;
967 DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)")" ;;
968 CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]")" ;;
969 *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]**[ ][ ]*$(printf %5u $1) ")" ;; esac
970 if [ -z "$l" ]; then
971 return 1;
973 echo "$l"
974 return 0
977 # return a list of child process pids [killchild]
978 childpids () {
979 local recursive i
980 if [ "X$1" = "X-r" ]; then recursive=1; shift; fi
981 case "$UNAME" in
982 AIX) l="$(ps -fade |grep "^........ ...... $(printf %6u $1)" |awk '{print($2);}')" ;;
983 FreeBSD) l="$(ps -fl |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
984 HP-UX) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
985 # Linux) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
986 Linux) l="$(ps -fade |grep "^[^[:space:]][^[:space:]]*[[:space:]][[:space:]]*[^[:space:]][^[:space:]]*[[:space:]][[:space:]]*$1 " |awk '{print($2);}')" ;;
987 # NetBSD) l="$(ps -aj |grep "^........ ..... $(printf %4u $1)" |awk '{print($2);}')" ;;
988 NetBSD) l="$(ps -aj |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)" |awk '{print($2);}')" ;;
989 OpenBSD) l="$(ps -aj |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
990 SunOS) l="$(ps -fade |grep "^........ ..... $(printf %5u $1)" |awk '{print($2);}')" ;;
991 DragonFly)l="$(ps -faje |grep "^[^ ][^ ]*[ ][ ]*..... $(printf %5u $1)" |awk '{print($2);}')" ;;
992 CYGWIN*) l="$(ps -pafe |grep "^[^ ]*[ ][ ]*[^ ][^ ]*[ ][ ]*$1[ ]" |awk '{print($2);}')" ;;
993 *) l="$(ps -fade |grep "^[^ ][^ ]*[ ][ ]*[0-9][0-9]*[ ][ ]*$(printf %5u $1) " |awk '{print($2);}')" ;; esac
994 if [ -z "$l" ]; then
995 return 1;
997 if [ "$recursive" ]; then
998 for i in $l; do
999 l="$l $(childpids -r $i)"
1000 done
1002 echo "$l"
1003 return 0
1006 # check if the given process line refers to a defunct (zombie) process
1007 # yes: returns 0
1008 # no: returns 1
1009 isdefunct () {
1010 local l
1011 case "$UNAME" in
1012 AIX) l="$(echo "$1" |grep ' <defunct>$')" ;;
1013 FreeBSD) l="$(echo "$1" |grep ' <defunct>$')" ;;
1014 HP-UX) l="$(echo "$1" |grep ' <defunct>$')" ;;
1015 Linux) l="$(echo "$1" |grep ' <defunct>$')" ;;
1016 SunOS) l="$(echo "$1" |grep ' <defunct>$')" ;;
1017 DragonFly)l="$(echo "$1" |grep ' <defunct>$')" ;;
1018 *) l="$(echo "$1" |grep ' <defunct>$')" ;;
1019 esac
1020 [ -n "$l" ];
1023 # check if UNIX socket protocol is available on host
1024 runsunix () {
1025 return 0;
1026 $TRACE $SOCAT /dev/null UNIX-LISTEN:"$td/unix.socket" 2>"$td/unix.stderr" &
1027 pid=$!
1028 relsleep 1
1029 kill "$pid" 2>/dev/null
1030 test ! -s "$td/unix.stderr"
1033 unset HAVENOT_IP4
1034 # check if an IP4 loopback interface exists
1035 runsip4 () {
1036 [ -n "$HAVENOT_IP4" ] && return $HAVENOT_IP4
1037 local l
1038 case "$UNAME" in
1039 AIX) l=$($IFCONFIG lo0 |$GREP_F 'inet 127.0.0.1 ') ;;
1040 FreeBSD) l=$($IFCONFIG lo0 |$GREP_F 'inet 127.0.0.1 ') ;;
1041 HP-UX) l=$($IFCONFIG lo0 |$GREP_F 'inet 127.0.0.1 ') ;;
1042 Linux) if [ "$IP" ]; then
1043 l=$($IP address |$GREP_E ' inet 127.0.0.1/')
1044 else
1045 l=$($IFCONFIG |$GREP_E 'inet (addr:)?127\.0\.0\.1 ')
1046 fi ;;
1047 NetBSD)l=$($IFCONFIG -a |grep 'inet 127\.0\.0\.1\>');;
1048 OpenBSD)l=$($IFCONFIG -a |$GREP_F 'inet 127.0.0.1 ');;
1049 OSF1) l=$($IFCONFIG -a |grep ' inet ') ;;
1050 SunOS) l=$($IFCONFIG -a |grep 'inet ') ;;
1051 Darwin)l=$($IFCONFIG lo0 |$GREP_F 'inet 127.0.0.1 ') ;;
1052 DragonFly)l=$($IFCONFIG -a |$GREP_F 'inet 127.0.0.1 ');;
1053 CYGWIN*) l=$(ipconfig |grep IPv4);;
1054 *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;;
1055 esac
1056 [ -z "$l" ] && return 1
1057 # existence of interface might not suffice, check for routeability:
1058 case "$UNAME" in
1059 Darwin) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;;
1060 Linux) ping -c 1 127.0.0.1 >/dev/null 2>&1; l="$?" ;;
1061 *) if [ -n "$l" ]; then l=0; else l=1; fi ;;
1062 esac
1063 HAVENOT_IP4=$l
1064 if [ "$HAVENOT_IP4" -ne 0 ]; then
1065 echo IP4
1067 return $l;
1070 unset HAVENOT_IP6
1071 # check if an IP6 loopback interface exists
1072 runsip6 () {
1073 [ -n "$HAVENOT_IP6" ] && return $HAVENOT_IP6
1074 local l
1075 case "$UNAME" in
1076 AIX) l=$($IFCONFIG lo0 |grep 'inet6 ::1[/%]') ;;
1077 HP-UX) l=$($IFCONFIG lo0 |grep ' inet6 ') ;;
1078 Linux) if [ "$IP" ]; then
1079 l=$($IP address |$GREP_E 'inet6 ::1/128')
1080 else
1081 l=$($IFCONFIG |$GREP_E 'inet6 (addr: )?::1/?')
1082 fi ;;
1083 NetBSD)l=$($IFCONFIG -a |grep 'inet6 ::1\>');;
1084 OSF1) l=$($IFCONFIG -a |grep ' inet6 ') ;;
1085 SunOS) l=$($IFCONFIG -a |grep 'inet6 ') ;;
1086 Darwin)l=$($IFCONFIG lo0 |grep 'inet6 ::1 ') ;;
1087 CYGWIN*) l=$(ipconfig |grep IPv6);;
1088 *) l=$($IFCONFIG -a |grep ' ::1[^:0-9A-Fa-f]') ;;
1089 esac
1090 [ -z "$l" ] && return 1
1091 # existence of interface might not suffice, check for routeability:
1092 case "$UNAME" in
1093 Darwin) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;;
1094 Linux) $PING6 -c 1 ::1 >/dev/null 2>&1; l="$?" ;;
1095 *) if [ -n "$l" ]; then l=0; else l=1; fi ;;
1096 esac
1097 HAVENOT_IP6=$l
1098 if [ "$HAVENOT_IP6" -ne 0 ]; then
1099 echo IP6
1101 return "$HAVENOT_IP6"
1104 # check if TCP on IPv4 is available on host
1105 runstcp4 () {
1106 runsip4 >/dev/null || { echo TCP4; return 1; }
1107 $SOCAT -h |grep -i ' TCP4-' >/dev/null || return 1
1108 return 0;
1111 # check if TCP on IPv6 is available on host
1112 runstcp6 () {
1113 runsip6 >/dev/null || { echo TCP6; return 1; }
1114 $SOCAT -h |grep -i ' TCP6-' >/dev/null || return 1
1115 return 0;
1118 # check if UDP on IPv4 is available on host
1119 runsudp4 () {
1120 runsip4 >/dev/null || { echo UDP4; return 1; }
1121 $SOCAT -h |grep -i ' UDP4-' >/dev/null || return 1
1122 return 0;
1125 # check if UDP on IPv6 is available on host
1126 runsudp6 () {
1127 runsip6 >/dev/null || { echo UDP6; return 1; }
1128 $SOCAT -h |grep -i ' UDP6-' >/dev/null || return 1
1129 return 0;
1132 # check if SCTP on IPv4 is available on host
1133 runssctp4 () {
1134 runsip4 >/dev/null || { echo SCTP4; return 1; }
1135 $SOCAT -h |grep -i ' SCTP4-' >/dev/null || return 1
1136 $SOCAT /dev/null SCTP4-L:0,accept-timeout=0.001 2>/dev/null || return 1;
1137 return 0;
1140 # check if SCTP on IPv6 is available on host
1141 runssctp6 () {
1142 runsip6 >/dev/null || { echo SCTP6; return 1; }
1143 $SOCAT -h |grep -i ' SCTP6-' >/dev/null || return 1
1144 $SOCAT /dev/null SCTP6-L:0,accept-timeout=0.001 2>/dev/null || return 1;
1145 return 0;
1148 # check if DCCP on IPv4 is available on host
1149 runsdccp4 () {
1150 runsip4 >/dev/null || { echo DCCP4; return 1; }
1151 $SOCAT -h |grep -i ' DCCP4-' >/dev/null || return 1
1152 $SOCAT /dev/null DCCP4-L:0,accept-timeout=0.001 2>/dev/null || return 1;
1153 return 0;
1156 # check if DCCP on IPv6 is available on host
1157 runsdccp6 () {
1158 runsip6 >/dev/null || { echo DCCP6; return 1; }
1159 $SOCAT -h |grep -i ' DCCP6-' >/dev/null || return 1
1160 $SOCAT /dev/null DCCP6-L:0,accept-timeout=0.001 2>/dev/null || return 1;
1161 return 0;
1164 # check if UDPLITE on IPv4 is available on host
1165 runsudplite4 () {
1166 runsip4 >/dev/null || { echo UDPLITE4; return 1; }
1167 $SOCAT -u -T 0.001 /dev/null UDPLITE4-SENDTO:$LOCALHOST4:0 2>/dev/null || return 1;
1168 return 0;
1171 # check if UDPLITE on IPv6 is available on host
1172 runsudplite6 () {
1173 runsip6 >/dev/null || { echo UDPLITE6; return 1; }
1174 $SOCAT -u -T 0.001 /dev/null UDPLITE6-SENDTO:$LOCALHOST6:0 2>/dev/null || return 1;
1175 return 0;
1178 # check if UNIX domain sockets work
1179 runsunix () {
1180 # for now...
1181 return 0;
1184 routesip6 () {
1185 runsip6 >/dev/null || { echo route6; return 1; }
1186 ping -c 1 -s 0 -6 2606:4700:4700::1111 >/dev/null 2>&1 || { echo route6; return 1; }
1187 return 0;
1191 # Perform a couple of checks to make sure the test has a chance of a useful
1192 # result:
1193 # platform is supported, features compiled in, addresses and options
1194 # available; needs root; is allowed to access the internet
1195 checkconds() {
1196 local unames="$(echo "$1")" # must be one of... exa: "Linux,FreeBSD"
1197 local root="$2" # "root" or ""
1198 local progs="$(echo "$3" |tr 'A-Z,' 'a-z ')" # exa: "nslookup"
1199 local feats="$(echo "$4" |tr 'a-z,' 'A-Z ')" # list of req.features (socat -V)
1200 local addrs="$(echo "$5" |tr 'a-z,' 'A-Z ')" # list of req.addresses (socat -h)
1201 local opts="$(echo "$6" |tr 'A-Z,' 'a-z ')" # list of req.options (socat -hhh)
1202 local runs="$(echo "$7" |tr , ' ')" # list of req.protocols, exa: "sctp6"
1203 local inet="$8" # when "internet": needs allowance
1204 local i
1206 if [ "$unames" ]; then
1207 local uname="$(echo $UNAME |tr 'A-Z' 'a-z')"
1208 for i in $unames; do
1209 if [ "$uname" = "$(echo "$i" |tr 'A-Z,' 'a-z ')" ]; then
1210 # good, mark as passed
1212 break;
1214 done
1215 [ "$i" ] && { echo "Only on (one of) $unames"; return 255; }
1218 if [ "$root" = "root" ]; then
1219 if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
1220 echo "Must be root"
1221 return 255
1225 if [ "$progs" ]; then
1226 for i in $progs; do
1227 if ! type >/dev/null 2>&1; then
1228 echo "Program $i not available"
1229 return 255
1231 done
1234 if [ "$feats" ]; then
1235 if ! F=$(testfeats $feats); then
1236 echo "Feature $F not configured in $SOCAT"
1237 return 255
1241 if [ "$addrs" ]; then
1242 if ! A=$(testaddrs - $addrs); then
1243 echo "Address $A not available in $SOCAT"
1244 return 255
1248 if [ "$opts" ]; then
1249 if ! o=$(testoptions $opts); then
1250 echo "Option $o not available in $SOCAT"
1251 return 255
1255 if [ "$runs" ]; then
1256 for i in $runs; do
1257 if ! runs$i >/dev/null; then
1258 echo "$i not available on host"
1259 return 255;
1261 done
1264 if [ "$inet" ]; then
1265 if [ -z "$NTERNET" ]; then
1266 echo "Use test.sh option --internet"
1267 return 255
1270 return 0
1274 # wait until an IP4 protocol is ready
1275 waitip4proto () {
1276 local proto="$1"
1277 local logic="$2" # 0..wait until free; 1..wait until listening
1278 local timeout="$3"
1279 local l
1280 [ "$logic" ] || logic=1
1281 [ "$timeout" ] || timeout=5
1282 while [ $timeout -gt 0 ]; do
1283 case "$UNAME" in
1284 Linux) if [ "$SS" ]; then
1285 l=$($SS -n -w -l |grep '^\(raw\|UNCONN\) .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*')
1286 else
1287 l=$(netstat -n -w -l |grep '^raw .* .*[0-9*]:'$proto' [ ]*0\.0\.0\.0:\*')
1288 fi ;;
1289 # FreeBSD) l=$(netstat -an |$GREP_E '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;;
1290 # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1291 # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1292 # Darwin) case "$(uname -r)" in
1293 # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;;
1294 # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;;
1295 # esac ;;
1296 AIX) # does not seem to show raw sockets in netstat
1297 relsleep 5; return 0 ;;
1298 # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;;
1299 # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;;
1300 # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;;
1301 *) #l=$(netstat -an |grep -i 'raw .*[0-9*][:.]'$proto' ') ;;
1302 relsleep 5; return 0 ;;
1303 esac
1304 [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1305 \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
1306 sleep $val_t
1307 timeout=$((timeout-1))
1308 done
1310 $ECHO "!protocol $proto timed out! \c" >&2
1311 return 1
1314 # we need this misleading function name for canonical reasons
1315 waitip4port () {
1316 waitip4proto "$1" "$2" "$3"
1319 # wait until an IP6 protocol is ready
1320 waitip6proto () {
1321 local proto="$1"
1322 local logic="$2" # 0..wait until free; 1..wait until listening
1323 local timeout="$3"
1324 local l
1325 [ "$logic" ] || logic=1
1326 [ "$timeout" ] || timeout=5
1327 while [ $timeout -gt 0 ]; do
1328 case "$UNAME" in
1329 Linux)
1330 if [ "$SS" ]; then
1331 l=$($SS -n -w -l |grep '^\(raw\|UNCONN\) .* \*:'$proto' [ ]*\*:\*')
1332 else
1333 l=$(netstat -n -w -l |grep '^raw[6 ] .* .*:[0-9*]*:'$proto' [ ]*:::\*')
1334 fi ;;
1335 # FreeBSD) l=$(netstat -an |$GREP_E '^raw46? .*[0-9*]\.'$proto' .* \*\.\*') ;;
1336 # NetBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1337 # OpenBSD) l=$(netstat -an |grep '^raw .*[0-9*]\.'$proto' [ ]* \*\.\*') ;;
1338 # Darwin) case "$(uname -r)" in
1339 # [1-5]*) l=$(netstat -an |grep '^raw.* .*[0-9*]\.'$proto' .* \*\.\*') ;;
1340 # *) l=$(netstat -an |grep '^raw4.* .*[0-9*]\.'$proto' .* \*\.\* .*') ;;
1341 # esac ;;
1342 AIX) # does not seem to show raw sockets in netstat
1343 relsleep 5; return 0 ;;
1344 # SunOS) l=$(netstat -an -f inet -P raw |grep '.*[1-9*]\.'$proto' [ ]*Idle') ;;
1345 # HP-UX) l=$(netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' .* \*\.\* ') ;;
1346 # OSF1) l=$(/usr/sbin/netstat -an |grep '^raw 0 0 .*[0-9*]\.'$proto' [ ]*\*\.\*') ;;
1347 *) #l=$(netstat -an |$GREP_E -i 'raw6? .*[0-9*][:.]'$proto' ') ;;
1348 relsleep 5; return 0 ;;
1349 esac
1350 [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1351 \( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
1352 sleep $val_t
1353 timeout=$((timeout-1))
1354 done
1356 $ECHO "!protocol $proto timed out! \c" >&2
1357 return 1
1360 # we need this misleading function name for canonical reasons
1361 waitip6port () {
1362 waitip6proto "$1" "$2" "$3"
1365 # Check if a TCP port is in use
1366 # exits with 0 when it is not used
1367 checktcpport () {
1368 local port="$1"
1369 local l
1370 case "$UNAME" in
1371 Linux) if [ "$SS" ]; then
1372 l=$($SS -a -n -t |grep ".*:$port\>")
1373 else
1374 l=$(netstat -a -n -t |grep '^tcp.* .*[0-9*]:'$port' .*')
1375 fi ;;
1376 FreeBSD) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .*') ;;
1377 NetBSD) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' [ ]* .* [ ]*.*') ;;
1378 Darwin) case "$(uname -r)" in
1379 [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .* .*') ;;
1380 *) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* .* .*') ;;
1381 esac ;;
1382 AIX) l=$(netstat -an |grep '^tcp.* 0 0 .*[*0-9]\.'$port' .*') ;;
1383 SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;;
1384 HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .*') ;;
1385 OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;;
1386 CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .*') ;;
1387 DragonFly)l=$(netstat -ant |grep '^tcp.* .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1388 *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .*') ;;
1389 esac
1390 [ -z "$l" ] && return 0
1391 return 1
1394 checktcp4port () {
1395 checktcpport $1
1398 # wait until a TCP4 listen port is ready
1399 waittcp4port () {
1400 local port="$1"
1401 local logic="$2" # 0..wait until free; 1..wait until listening (default)
1402 local timeout="$3"
1403 local l
1404 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1405 [ "$logic" ] || logic=1
1406 [ "$timeout" ] || timeout=5
1407 while true; do
1408 case "$UNAME" in
1409 Linux) if [ "$SS" ]; then
1410 l=$($SS -l -n -t |grep "^LISTEN .*:$port\>")
1411 else
1412 l=$(netstat -a -n -t |grep '^tcp .* .*[0-9*]:'$port' .* LISTEN')
1413 fi ;;
1414 FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1415 NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1416 Darwin) case "$(uname -r)" in
1417 [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1418 *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1419 esac ;;
1420 AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1421 SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* .* 0 .* LISTEN') ;;
1422 HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;;
1423 OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
1424 CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;;
1425 DragonFly) l=$(netstat -ant |grep '^tcp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1426 *) l=$(netstat -an |grep -i 'tcp .*[0-9*][:.]'$port' .* listen') ;;
1427 esac
1428 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1429 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1430 set ${vx}vx
1431 return 0
1433 if [ $timeout -le 0 ]; then
1434 set ${vx}vx
1435 return 1
1437 sleep $val_t
1438 timeout=$((timeout-1))
1439 done
1441 $ECHO "!port $port timed out! \c" >&2
1442 set ${vx}vx
1443 return 1
1446 # Check if a UDP4 port is in use
1447 # exits with 0 when it is not used
1448 checkudpport () {
1449 local port="$1"
1450 local l
1451 case "$UNAME" in
1452 Linux) if [ "$SS" ]; then
1453 l=$($SS -a -n -u |grep ".*:$port\>")
1454 else
1455 l=$(netstat -a -n -u |grep '^udp.* .*[0-9*]:'$port' .*')
1456 fi ;;
1457 FreeBSD) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1458 NetBSD) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*.*') ;;
1459 Darwin) case "$(uname -r)" in
1460 [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1461 *) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1462 esac ;;
1463 AIX) l=$(netstat -an |grep '^udp.* 0 0 .*[*0-9]\.'$port' .*') ;;
1464 SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;;
1465 HP-UX) l=$(netstat -an |grep '^udp.* 0 0 .*[0-9*]\.'$port' .*') ;;
1466 OSF1) l=$(/usr/sbin/netstat -an |grep '^udp.* 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;;
1467 CYGWIN*) l=$(netstat -an -p UDP |grep '^ UDP [0-9.]*:'$port' .*') ;;
1468 DragonFly)l=$(netstat -ant |grep '^udp.* .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1469 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' .*') ;;
1470 esac
1471 [ -z "$l" ] && return 0
1472 return 1
1475 checkudp4port () {
1476 checkudpport $1
1479 # wait until a UDP4 port is ready
1480 waitudp4port () {
1481 local port="$1"
1482 local logic="$2" # 0..wait until free; 1..wait until listening
1483 local timeout="$3"
1484 local l
1485 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1486 [ "$logic" ] || logic=1
1487 [ "$timeout" ] || timeout=5
1488 while [ $timeout -gt 0 ]; do
1489 case "$UNAME" in
1490 Linux) if [ "$SS" ]; then
1491 l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>")
1492 else
1493 l=$(netstat -a -n -u -l |grep '^udp .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*')
1494 fi ;;
1495 FreeBSD) l=$(netstat -an |$GREP_E '^udp46? .*[0-9*]\.'$port' .* \*\.\*') ;;
1496 NetBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1497 OpenBSD) l=$(netstat -an |grep '^udp .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1498 Darwin) case "$(uname -r)" in
1499 [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;;
1500 *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1501 esac ;;
1502 AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1503 SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1504 HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;;
1505 OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1506 DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1507 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1508 esac
1509 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1510 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1511 set ${vx}vx
1512 return 0
1514 sleep $val_t
1515 timeout=$((timeout-1))
1516 done
1518 $ECHO "!port $port timed out! \c" >&2
1519 set ${vx}vx
1520 return 1
1523 # Check if a SCTP port is in use
1524 # exits with 0 when it is not used
1525 checksctpport () {
1526 local port="$1"
1527 local l
1528 case "$UNAME" in
1529 Linux) if [ "$SS" ]; then
1530 l=$($SS -a -n |grep "^sctp.*:$port\>")
1531 else
1532 l=$(netstat -a -n |grep '^sctp.* .*[0-9*]:'$port' .*')
1533 fi ;;
1534 FreeBSD) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1535 NetBSD) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*.*') ;;
1536 Darwin) case "$(uname -r)" in
1537 [1-5]*) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1538 *) l=$(netstat -an |grep '^sctp.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1539 esac ;;
1540 AIX) l=$(netstat -an |grep '^sctp.* 0 0 .*[*0-9]\.'$port' .*') ;;
1541 SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .*') ;;
1542 HP-UX) l=$(netstat -an |grep '^sctp 0 0 .*[0-9*]\.'$port' .*') ;;
1543 OSF1) l=$(/usr/sbin/netstat -an |grep '^sctp.* 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*') ;;
1544 CYGWIN*) l=$(netstat -an -p SCTP |grep '^ SCTP [0-9.]*:'$port' .*') ;;
1545 DragonFly)l=$(netstat -ant |grep '^sctp.* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1546 *) l=$(netstat -an |grep -i 'sctp.*[0-9*][:.]'$port' .*') ;;
1547 esac
1548 [ -z "$l" ] && return 0
1549 return 1
1552 checksctp4port () {
1553 checksctpport $1
1556 # wait until an SCTP4 listen port is ready
1557 waitsctp4port () {
1558 local port="$1"
1559 local logic="$2" # 0..wait until free; 1..wait until listening
1560 local timeout="$3"
1561 local l
1562 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1563 [ "$logic" ] || logic=1
1564 [ "$timeout" ] || timeout=5
1565 while [ $timeout -gt 0 ]; do
1566 case "$UNAME" in
1567 Linux) if [ "$SS" ]; then
1568 l=$($SS -4 -n 2>/dev/null |grep "^sctp.*LISTEN .*:$port\>")
1569 else
1570 l=$(netstat -n -a |grep '^sctp .*[0-9*]:'$port' .* LISTEN')
1571 fi ;;
1572 # FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1573 # NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1574 # Darwin) case "$(uname -r)" in
1575 # [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1576 # *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
1577 # esac ;;
1578 # AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1579 SunOS) l=$(netstat -an -f inet -P sctp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;;
1580 # HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;;
1581 # OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
1582 # CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;;
1583 *) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;;
1584 esac
1585 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1586 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1587 set ${vx}vx
1588 return 0
1590 sleep $val_t
1591 timeout=$((timeout-1))
1592 done
1594 $ECHO "!port $port timed out! \c" >&2
1595 set ${vx}vx
1596 return 1
1599 # wait until a UDPLITE4 port is ready
1600 waitudplite4port () {
1601 local port="$1"
1602 local logic="$2" # 0..wait until free; 1..wait until listening
1603 local timeout="$3"
1604 local l
1605 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1606 [ "$logic" ] || logic=1
1607 [ "$timeout" ] || timeout=5
1608 while [ $timeout -gt 0 ]; do
1609 case "$UNAME" in
1610 Linux) #if [ "$SS" ]; then
1611 #l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>")
1612 #else
1613 if ! netstat -nU >/dev/null 2>&1; then
1614 return 0 # speculative
1616 l=$(netstat -a -n -U -l |grep '^udpl .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*')
1619 FreeBSD) l=$(netstat -an |$GREP_E '^udpl46? .*[0-9*]\.'$port' .* \*\.\*') ;;
1620 NetBSD) l=$(netstat -an |grep '^udpl .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1621 OpenBSD) l=$(netstat -an |grep '^udpl .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1622 #Darwin) case "$(uname -r)" in
1623 # [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;;
1624 # *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
1625 # esac ;;
1626 #AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1627 #SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1628 #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;;
1629 #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1630 #DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1631 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1632 esac
1633 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1634 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1635 set ${vx}vx
1636 return 0
1638 relsleep 1
1639 timeout=$((timeout-1))
1640 done
1642 $ECHO "!port $port timed out! \c" >&2
1643 set ${vx}vx
1644 return 1
1647 # check if a TCP6 port is in use
1648 # exits with 0 when it is not used
1649 checktcp6port () {
1650 checktcpport $1
1653 # wait until a tcp6 listen port is ready
1654 waittcp6port () {
1655 local port="$1"
1656 local logic="$2" # 0..wait until free; 1..wait until listening
1657 local timeout="$3"
1658 local l
1659 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1660 [ "$logic" ] || logic=1
1661 [ "$timeout" ] || timeout=5
1662 while [ $timeout -gt 0 ]; do
1663 case "$UNAME" in
1664 Linux) if [ "$SS" ]; then
1665 l=$($SS -6 -n -t -l |grep "^LISTEN .*:$port\>")
1666 #l=$($SS -6 -n -t -l |grep "^tcp6* .*:$port\>")
1667 else
1668 l=$(netstat -an |$GREP_E '^tcp6? .* [0-9a-f:%]*:'$port' .* LISTEN')
1669 fi ;;
1670 FreeBSD) l=$(netstat -an |$GREP_E -i 'tcp(6|46) .*[0-9*][:.]'$port' .* listen') ;;
1671 NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1672 OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;;
1673 Darwin) l=$(netstat -an |$GREP_E '^tcp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+ +LISTEN') ;;
1674 AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1675 SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
1676 #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
1677 DragonFly) l=$(netstat -ant |grep '^tcp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
1678 *) l=$(netstat -an |grep -i 'tcp6 .*:'$port' .* listen') ;;
1679 esac
1680 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1681 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1682 set ${vx}vx
1683 return 0
1685 sleep $val_t
1686 timeout=$((timeout-1))
1687 done
1689 $ECHO "!port $port timed out! \c" >&2
1690 #echo set ${vx}vx >&2
1691 set ${vx}vx
1692 return 1
1695 # Check if a UDP6 port is in use
1696 # exits with 0 when it is not used
1697 checkudp6port () {
1698 checkudpport $1
1701 # wait until a UDP6 port is ready
1702 waitudp6port () {
1703 local port="$1"
1704 local logic="$2" # 0..wait until free; 1..wait until listening
1705 local timeout="$3"
1706 local l
1707 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1708 [ "$logic" ] || logic=1
1709 [ "$timeout" ] || timeout=5
1710 while [ $timeout -gt 0 ]; do
1711 case "$UNAME" in
1712 Linux) if [ "$SS" ]; then
1713 # CAUTION!!! ss from iproute2 4.15.0-2ubuntu on 18-04 changes
1714 # the output format when writing to pipe
1715 l=$($SS -6 -u -l -n |grep "^UNCONN.*:$port\>")
1716 else
1717 l=$(netstat -an |$GREP_E '^udp6? .* .*[0-9*:%]:'$port' [ ]*:::\*')
1718 fi ;;
1719 FreeBSD) l=$(netstat -an |$GREP_E '^udp(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;;
1720 NetBSD) l=$(netstat -an |grep '^udp6 .* \*\.'$port' [ ]* \*\.\*') ;;
1721 OpenBSD) l=$(netstat -an |grep '^udp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1722 Darwin) l=$(netstat -an |$GREP_E '^udp4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;;
1723 AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1724 SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1725 #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;;
1726 #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1727 DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1728 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1729 esac
1730 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1731 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1732 set ${vx}vx
1733 return 0
1735 sleep $val_t
1736 timeout=$((timeout-1))
1737 done
1739 $ECHO "!port $port timed out! \c" >&2
1740 set ${vx}vx
1741 return 1
1744 # Check if a SCTP6 port is in use
1745 # exits with 0 when it is not used
1746 checksctp6port () {
1747 checksctpport $1
1750 # wait until a sctp6 listen port is ready
1751 # not all (Linux) variants show this in netstat
1752 waitsctp6port () {
1753 local port="$1"
1754 local logic="$2" # 0..wait until free; 1..wait until listening
1755 local timeout="$3"
1756 local l
1757 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1758 [ "$logic" ] || logic=1
1759 [ "$timeout" ] || timeout=5
1760 while [ $timeout -gt 0 ]; do
1761 case "$UNAME" in
1762 Linux) if [ "$SS" ]; then
1763 l=$($SS -6 -n 2>/dev/null |grep "^LISTEN .*:$port\>")
1764 else
1765 l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN')
1766 fi ;;
1767 # FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;;
1768 # NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1769 # OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;;
1770 # AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
1771 SunOS) l=$(netstat -an -f inet6 -P sctp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
1772 # #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
1773 *) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
1774 esac
1775 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1776 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1777 set ${vx}vx
1778 return 0
1780 sleep $val_t
1781 timeout=$((timeout-1))
1782 done
1784 $ECHO "!port $port timed out! \c" >&2
1785 set ${vx}vx
1786 return 1
1789 # wait until a UDPLITE6 port is ready
1790 waitudplite6port () {
1791 local port="$1"
1792 local logic="$2" # 0..wait until free; 1..wait until listening
1793 local timeout="$3"
1794 local l
1795 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1796 [ "$logic" ] || logic=1
1797 [ "$timeout" ] || timeout=5
1798 while [ $timeout -gt 0 ]; do
1799 case "$UNAME" in
1800 Linux) #if [ "$SS" ]; then
1801 #l=$($SS -6 -u -l -n |grep "^UNCONN .*:$port\>")
1802 #else
1803 if ! netstat -nU >/dev/null 2>&1; then
1804 return 0 # speculative
1806 l=$(netstat -an |$GREP_E '^udpl6? .* .*[0-9*:%]:'$port' [ ]*:::\*')
1809 FreeBSD) l=$(netstat -an |$GREP_E '^udpl(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;;
1810 NetBSD) l=$(netstat -an |grep '^udpl6 .* \*\.'$port' [ ]* \*\.\*') ;;
1811 OpenBSD) l=$(netstat -an |grep '^udpl6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
1812 Darwin) l=$(netstat -an |$GREP_E '^udpl4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;;
1813 #AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
1814 #SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
1815 #HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;;
1816 #OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
1817 #DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
1818 *) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
1819 esac
1820 if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
1821 \( \( $logic -eq 0 \) -a -z "$l" \) ]; then
1822 set ${vx}vx
1823 return 0
1825 relsleep 1
1826 timeout=$((timeout-1))
1827 done
1829 $ECHO "!port $port timed out! \c" >&2
1830 set ${vx}vx
1831 return 1
1834 # we need this misleading function name for canonical reasons
1835 waitunixport () {
1836 waitfile "$1" "$2" "$3"
1839 # Not implemented
1840 waitabstractport () {
1841 relsleep 5
1844 # wait until a filesystem entry exists
1845 waitfile () {
1846 local crit=-e
1847 case "X$1" in X-*) crit="$1"; shift ;; esac
1848 local file="$1"
1849 local logic="$2" # 0..wait until gone; 1..wait until exists (default);
1850 # 2..wait until not empty
1851 local timeout="$3"
1852 local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
1853 [ "$logic" ] || logic=1
1854 [ "$logic" -eq 2 ] && crit=-s
1855 [ "$timeout" ] || timeout=5
1856 while [ $timeout -gt 0 ]; do
1857 if [ \( $logic -ne 0 -a $crit "$file" \) -o \
1858 \( $logic -eq 0 -a ! $crit "$file" \) ]; then
1859 set ${vx}vx
1860 return 0
1862 sleep $val_t
1863 timeout=$((timeout-1))
1864 done
1866 echo "file $file timed out" >&2
1867 set ${vx}vx
1868 return 1
1871 # system dependent values
1872 case "$UNAME" in
1873 SunOS) SOCK_SEQPACKET=6 ;;
1874 *) SOCK_SEQPACKET=5 ;;
1875 esac
1877 # generate a test certificate and key
1878 gentestcert () {
1879 local name="$1"
1880 if ! [ -f testcert.dh ]; then
1881 openssl dhparam -out testcert.dh $RSABITS
1883 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1884 openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1
1885 #openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 -extensions v3_ca >/dev/null 2>&1
1886 openssl req -new -config $TESTCERT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1
1887 cat $name.key $name.crt testcert.dh >$name.pem
1890 # generate a test DSA key and certificate
1891 gentestdsacert () {
1892 local name="$1"
1893 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1894 openssl dsaparam -out $name-dsa.pem $DSABITS >/dev/null 2>&1
1895 openssl dhparam -dsaparam -out $name-dh.pem $DSABITS >/dev/null 2>&1
1896 openssl req -newkey dsa:$name-dsa.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1
1897 cat $name-dsa.pem $name-dh.pem $name.key $name.crt >$name.pem
1900 # generate a test EC key and certificate
1901 gentesteccert () {
1902 local name="$1"
1903 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1904 openssl ecparam -name secp521r1 -out $name-ec.pem >/dev/null 2>&1
1905 chmod 0400 $name-ec.pem
1906 openssl req -newkey ec:$name-ec.pem -keyout $name.key -nodes -x509 -config $TESTCERT_CONF -out $name.crt -days 3653 >/dev/null 2>&1
1907 cat $name-ec.pem $name.key $name.crt >$name.pem
1910 gentestcert6 () {
1911 local name="$1"
1912 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1913 cat $TESTCERT_CONF |
1914 { echo "# automatically generated by $0"; cat; } |
1915 sed 's/\(commonName\s*=\s*\).*/\1[::1]/' >$TESTCERT6_CONF
1916 openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1
1917 openssl req -new -config $TESTCERT6_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1
1918 cat $name.key $name.crt >$name.pem
1921 # generate a server certificate and key with SubjectAltName
1922 gentestaltcert () {
1923 local name="$1"
1924 if ! [ -f testcert.dh ]; then
1925 openssl dhparam -out testcert.dh $RSABITS
1927 if [ -s $name.key -a -s $name.crt -a -s $name.pem ]; then return; fi
1928 openssl genrsa $OPENSSL_RAND -out $name.key $RSABITS >/dev/null 2>&1
1929 openssl req -new -config $TESTALT_CONF -key $name.key -x509 -out $name.crt -days 3653 >/dev/null 2>&1
1930 cat $name.key $name.crt testcert.dh >$name.pem
1933 #------------------------------------------------------------------------------
1934 # Begin of functional tests
1936 NAME=UNISTDIO
1937 case "$TESTS " in
1938 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1939 TEST="$NAME: unidirectional throughput from stdin to stdout"
1940 testecho "$N" "$TEST" "stdin" "stdout" "$opts -u"
1941 esac
1942 N=$((N+1))
1944 #------------------------------------------------------------------------------
1945 # Begin of common tests
1947 NAME=UNPIPESTDIO
1948 case "$TESTS" in
1949 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1950 TEST="$NAME: stdio with simple echo via internal pipe"
1951 testecho "$N" "$TEST" "stdio" "pipe" "$opts"
1952 esac
1953 N=$((N+1))
1956 NAME=UNPIPESHORT
1957 case "$TESTS" in
1958 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1959 TEST="$NAME: short form of stdio ('-') with simple echo via internal pipe"
1960 testecho "$N" "$TEST" "-" "pipe" "$opts"
1961 esac
1962 N=$((N+1))
1965 NAME=DUALSTDIO
1966 case "$TESTS" in
1967 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1968 TEST="$NAME: splitted form of stdio ('stdin!!stdout') with simple echo via internal pipe"
1969 testecho "$N" "$TEST" "stdin!!stdout" "pipe" "$opts"
1970 esac
1971 N=$((N+1))
1974 NAME=DUALSHORTSTDIO
1975 case "$TESTS" in
1976 *%$N%*|*%functions%*|*%stdio%*|*%$NAME%*)
1977 TEST="$NAME: short splitted form of stdio ('-!!-') with simple echo via internal pipe"
1978 testecho "$N" "$TEST" "-!!-" "pipe" "$opts"
1979 esac
1980 N=$((N+1))
1983 NAME=DUALFDS
1984 case "$TESTS" in
1985 *%$N%*|*%functions%*|*%fd%*|*%$NAME%*)
1986 TEST="$NAME: file descriptors with simple echo via internal pipe"
1987 testecho "$N" "$TEST" "0!!1" "pipe" "$opts"
1988 esac
1989 N=$((N+1))
1992 NAME=NAMEDPIPE
1993 case "$TESTS" in
1994 *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*)
1995 TEST="$NAME: simple echo via named pipe"
1996 # with MacOS, this test hangs if nonblock is not used. Is an OS bug.
1997 tp="$td/pipe$N"
1998 # note: the nonblock is required by MacOS 10.1(?), otherwise it hangs (OS bug?)
1999 testecho "$N" "$TEST" "" "pipe:$tp,nonblock" "$opts"
2000 esac
2001 N=$((N+1))
2004 NAME=DUALPIPE
2005 case "$TESTS" in
2006 *%$N%*|*%functions%*|*%pipe%*|*%$NAME%*)
2007 TEST="$NAME: simple echo via named pipe, specified twice"
2008 tp="$td/pipe$N"
2009 testecho "$N" "$TEST" "" "pipe:$tp,nonblock!!pipe:$tp" "$opts"
2010 esac
2011 N=$((N+1))
2014 NAME=FILE
2015 case "$TESTS" in
2016 *%$N%*|*%functions%*|*%engine%*|*%file%*|*%ignoreeof%*|*%$NAME%*)
2017 TEST="$NAME: simple echo via file"
2018 tf="$td/file$N"
2019 testecho "$N" "$TEST" "" "$tf,ignoreeof!!$tf" "$opts"
2020 esac
2021 N=$((N+1))
2024 NAME=EXECSOCKETPAIR
2025 case "$TESTS" in
2026 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*)
2027 TEST="$NAME: simple echo via exec of cat with socketpair"
2028 testecho "$N" "$TEST" "" "EXEC:$CAT" "$opts"
2029 esac
2030 N=$((N+1))
2032 NAME=SYSTEMSOCKETPAIR
2033 case "$TESTS" in
2034 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
2035 TEST="$NAME: simple echo via system() of cat with socketpair"
2036 testecho "$N" "$TEST" "" "SYSTEM:$CAT" "$opts" "$val_t"
2037 esac
2038 N=$((N+1))
2041 NAME=EXECPIPES
2042 case "$TESTS" in
2043 *%$N%*|*%functions%*|*%exec%*|*%pipe%*|*%$NAME%*)
2044 TEST="$NAME: simple echo via exec of cat with pipes"
2045 testecho "$N" "$TEST" "" "EXEC:$CAT,pipes" "$opts"
2046 esac
2047 N=$((N+1))
2049 NAME=SYSTEMPIPES
2050 case "$TESTS" in
2051 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2052 TEST="$NAME: simple echo via system() of cat with pipes"
2053 testecho "$N" "$TEST" "" "SYSTEM:$CAT,pipes" "$opts"
2054 esac
2055 N=$((N+1))
2058 NAME=EXECPTY
2059 case "$TESTS" in
2060 *%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*)
2061 TEST="$NAME: simple echo via exec of cat with pseudo terminal"
2062 if ! eval $NUMCOND; then :;
2063 elif ! testfeats pty >/dev/null; then
2064 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
2065 numCANT=$((numCANT+1))
2066 listCANT="$listCANT $N"
2067 else
2068 testecho "$N" "$TEST" "" "EXEC:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
2070 esac
2071 N=$((N+1))
2073 NAME=SYSTEMPTY
2074 case "$TESTS" in
2075 *%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*)
2076 TEST="$NAME: simple echo via system() of cat with pseudo terminal"
2077 if ! eval $NUMCOND; then :;
2078 elif ! testfeats pty >/dev/null; then
2079 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
2080 numCANT=$((numCANT+1))
2081 listCANT="$listCANT $N"
2082 else
2083 testecho "$N" "$TEST" "" "SYSTEM:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts"
2085 esac
2086 N=$((N+1))
2089 NAME=SYSTEMPIPESFDS
2090 case "$TESTS" in
2091 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2092 TEST="$NAME: simple echo via system() of cat with pipes, non stdio"
2093 testecho "$N" "$TEST" "" "SYSTEM:$CAT>&9 <&8,pipes,fdin=8,fdout=9" "$opts"
2094 esac
2095 N=$((N+1))
2098 NAME=DUALSYSTEMFDS
2099 case "$TESTS" in
2100 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
2101 TEST="$NAME: echo via dual system() of cat"
2102 testecho "$N" "$TEST" "SYSTEM:$CAT>&6,fdout=6!!system:$CAT<&7,fdin=7" "" "$opts" "$val_t"
2103 esac
2104 N=$((N+1))
2107 # test: send EOF to exec'ed sub process, let it finish its operation, and
2108 # check if the sub process returns its data before terminating.
2109 NAME=EXECSOCKETPAIRFLUSH
2110 # idea: have socat exec'ing od; send data and EOF, and check if the od'ed data
2111 # arrives.
2112 case "$TESTS" in
2113 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%$NAME%*)
2114 TEST="$NAME: call to od via exec with socketpair"
2115 testod "$N" "$TEST" "" "EXEC:$OD_C" "$opts"
2116 esac
2117 N=$((N+1))
2119 NAME=SYSTEMSOCKETPAIRFLUSH
2120 case "$TESTS" in
2121 *%$N%*|*%functions%*|*%system%*|*%socketpair%*|*%$NAME%*)
2122 TEST="$NAME: call to od via system() with socketpair"
2123 testod "$N" "$TEST" "" "SYSTEM:$OD_C" "$opts" $val_t
2124 esac
2125 N=$((N+1))
2128 NAME=EXECPIPESFLUSH
2129 case "$TESTS" in
2130 *%$N%*|*%functions%*|*%exec%*|*%pipes%*|*%$NAME%*)
2131 TEST="$NAME: call to od via EXEC with pipes"
2132 testod "$N" "$TEST" "" "EXEC:$OD_C,pipes" "$opts"
2133 esac
2134 N=$((N+1))
2136 NAME=SYSTEMPIPESFLUSH
2137 case "$TESTS" in
2138 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2139 TEST="$NAME: call to od via system() with pipes"
2140 testod "$N" "$TEST" "" "SYSTEM:$OD_C,pipes" "$opts" "$val_t"
2141 esac
2142 N=$((N+1))
2145 ## LATER:
2146 #NAME=EXECPTYFLUSH
2147 #case "$TESTS" in
2148 #*%$N%*|*%functions%*|*%exec%*|*%pty%*|*%$NAME%*)
2149 #TEST="$NAME: call to od via exec with pseudo terminal"
2150 #if ! testfeats pty >/dev/null; then
2151 # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
2152 # numCANT=$((numCANT+1))
2153 # listCANT="$listCANT $N"
2154 #else
2155 #testod "$N" "$TEST" "" "exec:$OD_C,pty,$PTYOPTS" "$opts"
2157 #esac
2158 #N=$((N+1))
2161 ## LATER:
2162 #NAME=SYSTEMPTYFLUSH
2163 #case "$TESTS" in
2164 #*%$N%*|*%functions%*|*%system%*|*%pty%*|*%$NAME%*)
2165 #TEST="$NAME: call to od via system() with pseudo terminal"
2166 #if ! testfeats pty >/dev/null; then
2167 # $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
2168 # numCANT=$((numCANT+1))
2169 # listCANT="$listCANT $N"
2170 #else
2171 #testod "$N" "$TEST" "" "system:$OD_C,pty,$PTYOPTS" "$opts"
2173 #esac
2174 #N=$((N+1))
2177 NAME=SYSTEMPIPESFDSFLUSH
2178 case "$TESTS" in
2179 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2180 TEST="$NAME: call to od via system() with pipes, non stdio"
2181 testod "$N" "$TEST" "" "SYSTEM:$OD_C>&9 <&8,pipes,fdin=8,fdout=9" "$opts" "$val_t"
2182 esac
2183 N=$((N+1))
2185 NAME=DUALSYSTEMFDSFLUSH
2186 case "$TESTS" in
2187 *%$N%*|*%functions%*|*%system%*|*%pipes%*|*%$NAME%*)
2188 TEST="$NAME: call to od via dual system()"
2189 testod "$N" "$TEST" "SYSTEM:$OD_C>&6,fdout=6!!SYSTEM:$CAT<&7,fdin=7" "pipe" "$opts" "$val_t"
2190 esac
2191 N=$((N+1))
2194 NAME=RAWIP4SELF
2195 case "$TESTS" in
2196 *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*)
2197 TEST="$NAME: simple echo via self receiving raw IPv4 protocol"
2198 if ! eval $NUMCOND; then :;
2199 elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then
2200 $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
2201 numCANT=$((numCANT+1))
2202 listCANT="$listCANT $N"
2203 elif ! feat=$(testfeats rawip) >/dev/null; then
2204 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2205 numCANT=$((numCANT+1))
2206 listCANT="$listCANT $N"
2207 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2208 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2209 numCANT=$((numCANT+1))
2210 listCANT="$listCANT $N"
2211 else
2212 testecho "$N" "$TEST" "" "IP4:127.0.0.1:$IPPROTO" "$opts"
2214 esac
2215 N=$((N+1))
2217 NAME=RAWIPX4SELF
2218 case "$TESTS" in
2219 *%$N%*|*%functions%*|*%ip4%*|*%rawip%*|*%root%*|*%$NAME%*)
2220 TEST="$NAME: simple echo via self receiving raw IP protocol, v4 by target"
2221 if ! eval $NUMCOND; then :;
2222 elif ! feat=$(testfeats ip4) || ! runsip4 >/dev/null; then
2223 $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
2224 numCANT=$((numCANT+1))
2225 listCANT="$listCANT $N"
2226 elif ! feat=$(testfeats rawip) >/dev/null; then
2227 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2228 numCANT=$((numCANT+1))
2229 listCANT="$listCANT $N"
2230 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2231 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2232 numCANT=$((numCANT+1))
2233 listCANT="$listCANT $N"
2234 else
2235 testecho "$N" "$TEST" "" "IP:127.0.0.1:$IPPROTO" "$opts"
2236 fi ;; # NUMCOND, feats
2237 esac
2238 N=$((N+1))
2240 NAME=RAWIP6SELF
2241 case "$TESTS" in
2242 *%$N%*|*%functions%*|*%ip6%*|*%rawip%*|*%root%*|*%$NAME%*)
2243 TEST="$NAME: simple echo via self receiving raw IPv6 protocol"
2244 if ! eval $NUMCOND; then :;
2245 elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then
2246 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2247 numCANT=$((numCANT+1))
2248 listCANT="$listCANT $N"
2249 elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then
2250 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2251 numCANT=$((numCANT+1))
2252 listCANT="$listCANT $N"
2253 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2254 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2255 numCANT=$((numCANT+1))
2256 listCANT="$listCANT $N"
2257 else
2258 testecho "$N" "$TEST" "" "IP6:[::1]:$IPPROTO" "$opts"
2259 fi ;; # NUMCOND, feats
2260 esac
2261 N=$((N+1))
2263 NAME=RAWIPX6SELF
2264 case "$TESTS" in
2265 *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%root%*|*%$NAME%*)
2266 TEST="$NAME: simple echo via self receiving raw IP protocol, v6 by target"
2267 if ! eval $NUMCOND; then :;
2268 elif ! feat=$(testfeats ip6) || ! runsip6 >/dev/null; then
2269 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2270 numCANT=$((numCANT+1))
2271 listCANT="$listCANT $N"
2272 elif ! feat=$(testfeats rawip) || ! runsip6 >/dev/null; then
2273 $PRINTF "test $F_n $TEST... ${YELLOW}RAWIP not available${NORMAL}\n" $N
2274 numCANT=$((numCANT+1))
2275 listCANT="$listCANT $N"
2276 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
2277 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
2278 numCANT=$((numCANT+1))
2279 listCANT="$listCANT $N"
2280 else
2281 testecho "$N" "$TEST" "" "IP:[::1]:$IPPROTO" "$opts"
2283 esac
2284 N=$((N+1))
2286 newport() {
2287 _PORT=$((_PORT+1))
2288 while eval wait${1}port $_PORT 1 0 2>/dev/null; do _PORT=$((_PORT+1)); done
2289 #echo "PORT=$_PORT" >&2
2290 PORT=$_PORT
2293 NAME=TCPSELF
2294 case "$TESTS" in
2295 *%$N%*|*%functions%*|*%$NAME%*)
2296 TEST="$NAME: echo via self connection of TCP IPv4 socket"
2297 if ! eval $NUMCOND; then :;
2298 elif [ "$UNAME" != Linux ]; then
2299 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N
2300 numCANT=$((numCANT+1))
2301 listCANT="$listCANT $N"
2302 else
2303 newport tcp4 # provide free port number in $PORT
2304 #ts="127.0.0.1:$tsl"
2305 testecho "$N" "$TEST" "" "TCP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR,reuseaddr" "$opts"
2307 esac
2308 N=$((N+1))
2311 NAME=UDPSELF
2312 if ! eval $NUMCOND; then :; else
2313 case "$TESTS" in
2314 *%$N%*|*%functions%*|*%$NAME%*)
2315 TEST="$NAME: echo via self connection of UDP IPv4 socket"
2316 if [ "$UNAME" != Linux ]; then
2317 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux$NORMAL\n" $N
2318 numCANT=$((numCANT+1))
2319 listCANT="$listCANT $N"
2320 else
2321 newport udp4 # provide free port number in $PORT
2322 testecho "$N" "$TEST" "" "UDP:$SECONDADDR:$PORT,sp=$PORT,bind=$SECONDADDR" "$opts"
2324 esac
2325 fi # NUMCOND
2326 N=$((N+1))
2329 NAME=UDP6SELF
2330 case "$TESTS" in
2331 *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%$NAME%*)
2332 TEST="$NAME: echo via self connection of UDP IPv6 socket"
2333 if ! eval $NUMCOND; then :;
2334 elif [ "$UNAME" != Linux ]; then
2335 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
2336 numCANT=$((numCANT+1))
2337 listCANT="$listCANT $N"
2338 elif ! testfeats udp ip6 >/dev/null || ! runsudp6 >/dev/null; then
2339 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
2340 numCANT=$((numCANT+1))
2341 listCANT="$listCANT $N"
2342 else
2343 tf="$td/file$N"
2344 newport udp6 # provide free port number in $PORT
2345 testecho "$N" "$TEST" "" "UDP6:[::1]:$PORT,sp=$PORT,bind=[::1]" "$opts"
2347 esac
2348 N=$((N+1))
2351 NAME=DUALUDPSELF
2352 if ! eval $NUMCOND; then :; else
2353 case "$TESTS" in
2354 *%$N%*|*%functions%*|*%$NAME%*)
2355 TEST="$NAME: echo via two unidirectional UDP IPv4 sockets"
2356 tf="$td/file$N"
2357 newport udp4; PORT1=$PORT # get free port
2358 newport udp4; PORT2=$PORT # get free port
2359 testecho "$N" "$TEST" "" "UDP:127.0.0.1:$PORT2,sp=$PORT1!!UDP:127.0.0.1:$PORT1,sp=$PORT2" "$opts"
2360 esac
2361 fi # NUMCOND
2362 N=$((N+1))
2365 #function testdual {
2366 # local
2370 NAME=UNIXSTREAM
2371 if ! eval $NUMCOND; then :; else
2372 case "$TESTS" in
2373 *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*)
2374 TEST="$NAME: echo via connection to UNIX domain socket"
2375 tf="$td/test$N.stdout"
2376 te="$td/test$N.stderr"
2377 ts="$td/test$N.socket"
2378 tdiff="$td/test$N.diff"
2379 da="test$N $(date) $RANDOM"
2380 CMD1="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE"
2381 CMD2="$TRACE $SOCAT $opts -!!- UNIX-CONNECT:$ts"
2382 printf "test $F_n $TEST... " $N
2383 $CMD1 </dev/null >$tf 2>"${te}1" &
2384 bg=$! # background process id
2385 waitfile "$ts"
2386 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2387 rc2=$?
2388 if [ "$rc2" -ne 0 ]; then
2389 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2390 echo "$CMD1 &"
2391 cat "${te}1"
2392 echo "$CMD2"
2393 echo "rc=$rc2"
2394 cat "${te}2"
2395 numFAIL=$((numFAIL+1))
2396 listFAIL="$listFAIL $N"
2397 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2398 $PRINTF "$FAILED: diff:\n"
2399 cat "$tdiff"
2400 echo "$CMD1 &"
2401 cat "${te}1"
2402 echo "$CMD2"
2403 cat "${te}2"
2404 numFAIL=$((numFAIL+1))
2405 listFAIL="$listFAIL $N"
2406 else
2407 $PRINTF "$OK\n"
2408 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2409 numOK=$((numOK+1))
2410 listOK="$listOK $N"
2412 kill $bg 2>/dev/null
2413 esac
2414 fi # NUMCOND
2415 N=$((N+1))
2418 NAME=TCP4
2419 case "$TESTS" in
2420 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2421 TEST="$NAME: echo via connection to TCP V4 socket"
2422 if ! eval $NUMCOND; then :
2423 elif ! cond=$(checkconds "" "" "" \
2424 "IP4 TCP LISTEN STDIO PIPE" \
2425 "TCP4-LISTEN PIPE STDIN STDOUT TCP4" \
2426 "so-reuseaddr" \
2427 "tcp4" ); then
2428 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
2429 numCANT=$((numCANT+1))
2430 listCANT="$listCANT $N"
2431 else
2432 tf="$td/test$N.stdout"
2433 te="$td/test$N.stderr"
2434 tdiff="$td/test$N.diff"
2435 newport tcp4; tsl=$PORT
2436 ts="127.0.0.1:$tsl"
2437 da="test$N $(date) $RANDOM"
2438 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE"
2439 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2440 printf "test $F_n $TEST... " $N
2441 $CMD1 >"$tf" 2>"${te}1" &
2442 pid1=$!
2443 waittcp4port $tsl 1
2444 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2445 if [ $? -ne 0 ]; then
2446 $PRINTF "$FAILED\n"
2447 echo "$CMD0 &"
2448 cat "${te}0" >&2
2449 echo "$CMD1"
2450 cat "${te}1" >&2
2451 numFAIL=$((numFAIL+1))
2452 listFAIL="$listFAIL $N"
2453 namesFAIL="$namesFAIL $NAME"
2454 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2455 $PRINTF "$FAILED\n"
2456 echo "$CMD0 &"
2457 cat "${te}0" >&2
2458 echo "$CMD1"
2459 cat "${te}1" >&2
2460 echo "// diff:" >&2
2461 cat "$tdiff" >&2
2462 numFAIL=$((numFAIL+1))
2463 listFAIL="$listFAIL $N"
2464 namesFAIL="$namesFAIL $NAME"
2465 else
2466 $PRINTF "$OK\n"
2467 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
2468 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
2469 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
2470 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2471 numOK=$((numOK+1))
2472 listOK="$listOK $N"
2474 kill $pid1 2>/dev/null
2475 wait
2476 fi ;; # NUMCOND, checkconds
2477 esac
2478 N=$((N+1))
2481 #et -xv
2482 NAME=TCP6
2483 case "$TESTS" in
2484 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2485 TEST="$NAME: echo via connection to TCP V6 socket"
2486 if ! eval $NUMCOND; then :;
2487 elif ! F=$(testfeats IP6 TCP LISTEN STDIO PIPE); then
2488 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
2489 numCANT=$((numCANT+1))
2490 listCANT="$listCANT $N"
2491 elif ! A=$(testaddrs - TCP6-LISTEN PIPE STDIN STDOUT TCP6-CONNECT); then
2492 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
2493 numCANT=$((numCANT+1))
2494 listCANT="$listCANT $N"
2495 elif ! o=$(testoptions so-reuseaddr ) >/dev/null; then
2496 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
2497 numCANT=$((numCANT+1))
2498 listCANT="$listCANT $N"
2499 elif ! runsip6 >/dev/null; then
2500 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
2501 numCANT=$((numCANT+1))
2502 listCANT="$listCANT $N"
2503 else
2504 tf="$td/test$N.stdout"
2505 te="$td/test$N.stderr"
2506 tdiff="$td/test$N.diff"
2507 newport tcp6; tsl=$PORT
2508 ts="[::1]:$tsl"
2509 da="test$N $(date) $RANDOM"
2510 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE"
2511 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2512 printf "test $F_n $TEST... " $N
2513 $CMD1 >"$tf" 2>"${te}1" &
2514 pid=$! # background process id
2515 waittcp6port $tsl 1
2516 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2517 if [ $? -ne 0 ]; then
2518 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2519 echo "$CMD1 &"
2520 cat "${te}1" >&2
2521 echo "$CMD2"
2522 cat "${te}2" >&2
2523 numFAIL=$((numFAIL+1))
2524 listFAIL="$listFAIL $N"
2525 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2526 $PRINTF "$FAILED: diff:\n"
2527 echo "$CMD1 &"
2528 cat "${te}1" >&2
2529 echo "$CMD2"
2530 cat "${te}2" >&2
2531 echo diff:
2532 cat "$tdiff"
2533 numFAIL=$((numFAIL+1))
2534 listFAIL="$listFAIL $N"
2535 else
2536 $PRINTF "$OK\n"
2537 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
2538 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2539 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
2540 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
2541 numOK=$((numOK+1))
2542 listOK="$listOK $N"
2544 kill $pid 2>/dev/null
2546 esac
2547 N=$((N+1))
2548 #set +vx
2551 # Test if TCP client with IPv4 address connects to IPv4 port
2552 NAME=TCPX4
2553 case "$TESTS" in
2554 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2555 TEST="$NAME: echo via connection to TCP socket, v4 by target"
2556 if ! eval $NUMCOND; then :;
2557 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
2558 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
2559 numCANT=$((numCANT+1))
2560 listCANT="$listCANT $N"
2561 elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
2562 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
2563 numCANT=$((numCANT+1))
2564 listCANT="$listCANT $N"
2565 elif ! o=$(testoptions pf) >/dev/null; then
2566 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
2567 numCANT=$((numCANT+1))
2568 listCANT="$listCANT $N"
2569 elif ! runsip4 >/dev/null; then
2570 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
2571 numCANT=$((numCANT+1))
2572 listCANT="$listCANT $N"
2573 else
2574 tf="$td/test$N.stdout"
2575 te="$td/test$N.stderr"
2576 tdiff="$td/test$N.diff"
2577 newport tcp4; tsl=$PORT
2578 ts="127.0.0.1:$tsl"
2579 da="test$N $(date) $RANDOM"
2580 CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE"
2581 CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
2582 printf "test $F_n $TEST... " $N
2583 $CMD0 >"$tf" 2>"${te}0" &
2584 pid=$! # background process id
2585 waittcp4port $tsl 1
2586 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
2587 if [ $? -ne 0 ]; then
2588 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2589 echo "$CMD0 &"
2590 cat "${te}0" >&2
2591 echo "$CMD1"
2592 cat "${te}1" >&2
2593 numFAIL=$((numFAIL+1))
2594 listFAIL="$listFAIL $N"
2595 namesFAIL="$namesFAIL $NAME"
2596 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2597 $PRINTF "$FAILED: diff:\n"
2598 cat "$tdiff"
2599 echo "$CMD0 &"
2600 cat "${te}0" >&2
2601 echo "$CMD1"
2602 cat "${te}1" >&2
2603 numFAIL=$((numFAIL+1))
2604 listFAIL="$listFAIL $N"
2605 namesFAIL="$namesFAIL $NAME"
2606 else
2607 $PRINTF "$OK\n"
2608 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
2609 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
2610 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
2611 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2612 numOK=$((numOK+1))
2613 listOK="$listOK $N"
2615 kill $pid 2>/dev/null
2617 esac
2618 N=$((N+1))
2621 # Test if TCP client with IPv6 address connects to IPv6 port
2622 NAME=TCPX6
2623 case "$TESTS" in
2624 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2625 TEST="$NAME: echo via connection to TCP socket, v6 by target"
2626 if ! eval $NUMCOND; then :;
2627 elif ! F=$(testfeats STDIO PIPE IP6 TCP LISTEN); then
2628 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
2629 numCANT=$((numCANT+1))
2630 listCANT="$listCANT $N"
2631 elif ! A=$(testaddrs TCP TCP-LISTEN STDIN STDOUT PIPE); then
2632 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
2633 numCANT=$((numCANT+1))
2634 listCANT="$listCANT $N"
2635 elif ! o=$(testoptions pf) >/dev/null; then
2636 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
2637 numCANT=$((numCANT+1))
2638 listCANT="$listCANT $N"
2639 elif ! runsip6 >/dev/null; then
2640 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
2641 numCANT=$((numCANT+1))
2642 listCANT="$listCANT $N"
2643 else
2644 tf="$td/test$N.stdout"
2645 te="$td/test$N.stderr"
2646 tdiff="$td/test$N.diff"
2647 newport tcp6; tsl=$PORT
2648 ts="[::1]:$tsl"
2649 da="test$N $(date) $RANDOM"
2650 CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE"
2651 CMD1="$TRACE $SOCAT $opts STDIN!!STDOUT TCP:$ts"
2652 printf "test $F_n $TEST... " $N
2653 $CMD0 >"$tf" 2>"${te}0" &
2654 pid=$! # background process id
2655 waittcp6port $tsl 1
2656 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
2657 if [ $? -ne 0 ]; then
2658 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2659 echo "$CMD0 &"
2660 cat "${te}0" >&2
2661 echo "$CMD1"
2662 cat "${te}1" >&2
2663 numFAIL=$((numFAIL+1))
2664 listFAIL="$listFAIL $N"
2665 namesFAIL="$namesFAIL $NAME"
2666 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2667 $PRINTF "$FAILED: diff:\n"
2668 cat "$tdiff"
2669 echo "$CMD0 &"
2670 cat "${te}0" >&2
2671 echo "$CMD1"
2672 cat "${te}1" >&2
2673 numFAIL=$((numFAIL+1))
2674 listFAIL="$listFAIL $N"
2675 namesFAIL="$namesFAIL $NAME"
2676 else
2677 $PRINTF "$OK\n"
2678 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
2679 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
2680 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
2681 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2682 numOK=$((numOK+1))
2683 listOK="$listOK $N"
2685 kill $pid 2>/dev/null
2687 esac
2688 N=$((N+1))
2690 # TCP6-LISTEN may also listen for IPv4 connections. Test if option
2691 # ipv6-v6only=0 shows this behaviour.
2692 # On OpenBSD-7.2 ipv6-v6only=0 gives "Invalid argument"
2693 NAME=IPV6ONLY0
2694 case "$TESTS" in
2695 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2696 TEST="$NAME: option ipv6-v6only=0 listens on IPv4"
2697 # create a listening TCP6 socket and try to connect to the port using TCP4
2698 if ! eval $NUMCOND; then :;
2699 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2700 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2701 numCANT=$((numCANT+1))
2702 listCANT="$listCANT $N"
2703 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2704 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
2705 numCANT=$((numCANT+1))
2706 listCANT="$listCANT $N"
2707 elif ! feat=$(testoptions ipv6-v6only); then
2708 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2709 numCANT=$((numCANT+1))
2710 listCANT="$listCANT $N"
2711 else
2712 tf="$td/test$N.stdout"
2713 te="$td/test$N.stderr"
2714 tdiff="$td/test$N.diff"
2715 newport tcp6; tsl=$PORT
2716 ts="127.0.0.1:$tsl"
2717 da="test$N $(date) $RANDOM"
2718 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=0,$REUSEADDR PIPE"
2719 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2720 printf "test $F_n $TEST... " $N
2721 $CMD1 >"$tf" 2>"${te}1" &
2722 pid=$! # background process id
2723 waittcp6port $tsl 1
2724 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2725 if [ $? -ne 0 ]; then
2726 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2727 echo "$CMD1 &"
2728 echo "$CMD2"
2729 cat "${te}1" "${te}2"
2730 numFAIL=$((numFAIL+1))
2731 listFAIL="$listFAIL $N"
2732 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2733 $PRINTF "$FAILED: diff:\n"
2734 cat "$tdiff"
2735 numFAIL=$((numFAIL+1))
2736 listFAIL="$listFAIL $N"
2737 else
2738 $PRINTF "$OK\n"
2739 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2740 numOK=$((numOK+1))
2741 listOK="$listOK $N"
2743 kill $pid 2>/dev/null
2745 esac
2746 N=$((N+1))
2748 #set -vx
2749 # TCP6-LISTEN may also listen for IPv4 connections. Test if option
2750 # ipv6-v6only=1 turns off this behaviour.
2751 NAME=IPV6ONLY1
2752 case "$TESTS" in
2753 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2754 TEST="$NAME: option ipv6-v6only=1 does not listen on IPv4"
2755 if ! eval $NUMCOND; then :;
2756 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2757 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2758 numCANT=$((numCANT+1))
2759 listCANT="$listCANT $N"
2760 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2761 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2762 numCANT=$((numCANT+1))
2763 listCANT="$listCANT $N"
2764 elif ! feat=$(testoptions ipv6-v6only); then
2765 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2766 numCANT=$((numCANT+1))
2767 listCANT="$listCANT $N"
2768 else
2769 tf="$td/test$N.stdout"
2770 te="$td/test$N.stderr"
2771 tdiff="$td/test$N.diff"
2772 newport tcp6; tsl=$PORT
2773 ts="127.0.0.1:$tsl"
2774 da="test$N $(date) $RANDOM"
2775 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,ipv6-v6only=1,$REUSEADDR PIPE"
2776 CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
2777 printf "test $F_n $TEST... " $N
2778 $CMD1 >"$tf" 2>"${te}1" &
2779 pid=$! # background process id
2780 waittcp6port $tsl 1
2781 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2782 if [ $? -eq 0 ]; then
2783 $PRINTF "$FAILED:\n"
2784 cat "${te}1" "${te}2"
2785 numFAIL=$((numFAIL+1))
2786 listFAIL="$listFAIL $N"
2787 elif echo "$da" |diff - "$tf" >"$tdiff"; then
2788 $PRINTF "$FAILED:\n"
2789 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2790 numFAIL=$((numFAIL+1))
2791 listFAIL="$listFAIL $N"
2792 else
2793 $PRINTF "$OK\n"
2794 numOK=$((numOK+1))
2795 listOK="$listOK $N"
2797 kill $pid; wait
2798 wait
2800 esac
2801 N=$((N+1))
2802 #set +vx
2804 NAME=ENV_LISTEN_4
2805 case "$TESTS" in
2806 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2807 TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv4 preference on listen"
2808 if ! eval $NUMCOND; then :;
2809 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2810 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2811 numCANT=$((numCANT+1))
2812 listCANT="$listCANT $N"
2813 elif ! testfeats ip6 >/dev/null || ! runstcp6 >/dev/null; then
2814 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
2815 numCANT=$((numCANT+1))
2816 listCANT="$listCANT $N"
2817 elif ! feat=$(testoptions ipv6-v6only); then
2818 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2819 numCANT=$((numCANT+1))
2820 listCANT="$listCANT $N"
2821 else
2822 tf="$td/test$N.stdout"
2823 te="$td/test$N.stderr"
2824 tdiff="$td/test$N.diff"
2825 newport tcp4; tsl=$PORT
2826 ts="127.0.0.1:$tsl"
2827 da="test$N $(date) $RANDOM"
2828 CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2829 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2830 printf "test $F_n $TEST... " $N
2831 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
2832 pid=$! # background process id
2833 waittcp4port $tsl 1
2834 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2835 if [ $? -ne 0 ]; then
2836 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2837 echo "$CMD1 &"
2838 echo "$CMD2"
2839 cat "${te}1" "${te}2"
2840 numFAIL=$((numFAIL+1))
2841 listFAIL="$listFAIL $N"
2842 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2843 $PRINTF "$FAILED: diff:\n"
2844 cat "$tdiff"
2845 numFAIL=$((numFAIL+1))
2846 listFAIL="$listFAIL $N"
2847 else
2848 $PRINTF "$OK\n"
2849 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2850 numOK=$((numOK+1))
2851 listOK="$listOK $N"
2853 kill $pid 2>/dev/null; wait
2855 esac
2856 N=$((N+1))
2858 NAME=ENV_LISTEN_6
2859 case "$TESTS" in
2860 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2861 TEST="$NAME: env SOCAT_DEFAULT_LISTEN_IP for IPv6 preference on listen"
2862 if ! eval $NUMCOND; then :;
2863 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2864 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2865 numCANT=$((numCANT+1))
2866 listCANT="$listCANT $N"
2867 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2868 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2869 numCANT=$((numCANT+1))
2870 listCANT="$listCANT $N"
2871 else
2872 tf="$td/test$N.stdout"
2873 te="$td/test$N.stderr"
2874 tdiff="$td/test$N.diff"
2875 newport tcp6; tsl=$PORT
2876 ts="[::1]:$tsl"
2877 da="test$N $(date) $RANDOM"
2878 CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2879 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2880 printf "test $F_n $TEST... " $N
2881 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
2882 pid=$! # background process id
2883 waittcp6port $tsl 1
2884 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2885 if [ $? -ne 0 ]; then
2886 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2887 echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &"
2888 cat "${te}1" >&2
2889 echo "$CMD2"
2890 cat "${te}2" >&2
2891 numFAIL=$((numFAIL+1))
2892 listFAIL="$listFAIL $N"
2893 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2894 $PRINTF "$FAILED (diff):\n"
2895 echo "SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 &"
2896 cat "${te}1" >&2
2897 echo "$CMD2"
2898 cat "${te}2" >&2
2899 echo "// diff:" >&2
2900 cat "$tdiff" >&2
2901 numFAIL=$((numFAIL+1))
2902 listFAIL="$listFAIL $N"
2903 else
2904 $PRINTF "$OK\n"
2905 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
2906 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
2907 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
2908 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
2909 numOK=$((numOK+1))
2910 listOK="$listOK $N"
2912 kill $pid 2>/dev/null; wait
2914 esac
2915 N=$((N+1))
2917 NAME=LISTEN_OPTION_4
2918 case "$TESTS" in
2919 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2920 TEST="$NAME: option -4 for IPv4 preference on listen"
2921 if ! eval $NUMCOND; then :;
2922 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2923 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2924 numCANT=$((numCANT+1))
2925 listCANT="$listCANT $N"
2926 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2927 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2928 numCANT=$((numCANT+1))
2929 listCANT="$listCANT $N"
2930 elif ! feat=$(testoptions ipv6-v6only); then
2931 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
2932 numCANT=$((numCANT+1))
2933 listCANT="$listCANT $N"
2934 else
2935 tf="$td/test$N.stdout"
2936 te="$td/test$N.stderr"
2937 tdiff="$td/test$N.diff"
2938 newport tcp4; tsl=$PORT
2939 ts="127.0.0.1:$tsl"
2940 da="test$N $(date) $RANDOM"
2941 CMD1="$TRACE $SOCAT $opts -4 TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2942 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
2943 printf "test $F_n $TEST... " $N
2944 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
2945 pid=$! # background process id
2946 waittcp4port $tsl 1
2947 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2948 if [ $? -ne 0 ]; then
2949 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
2950 echo "$CMD1 &"
2951 echo "$CMD2"
2952 cat "${te}1" "${te}2"
2953 numFAIL=$((numFAIL+1))
2954 listFAIL="$listFAIL $N"
2955 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
2956 $PRINTF "$FAILED: diff:\n"
2957 cat "$tdiff"
2958 numFAIL=$((numFAIL+1))
2959 listFAIL="$listFAIL $N"
2960 else
2961 $PRINTF "$OK\n"
2962 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
2963 numOK=$((numOK+1))
2964 listOK="$listOK $N"
2966 kill $pid 2>/dev/null; wait
2968 esac
2969 N=$((N+1))
2971 NAME=LISTEN_OPTION_6
2972 case "$TESTS" in
2973 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
2974 TEST="$NAME: option -6 for IPv6 preference on listen"
2975 if ! eval $NUMCOND; then :;
2976 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
2977 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
2978 numCANT=$((numCANT+1))
2979 listCANT="$listCANT $N"
2980 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
2981 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
2982 numCANT=$((numCANT+1))
2983 listCANT="$listCANT $N"
2984 else
2985 tf="$td/test$N.stdout"
2986 te="$td/test$N.stderr"
2987 tdiff="$td/test$N.diff"
2988 newport tcp6; tsl=$PORT
2989 ts="[::1]:$tsl"
2990 da="test$N $(date) $RANDOM"
2991 CMD1="$TRACE $SOCAT $opts -6 TCP-LISTEN:$tsl,$REUSEADDR PIPE"
2992 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
2993 printf "test $F_n $TEST... " $N
2994 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
2995 pid=$! # background process id
2996 waittcp6port $tsl 1
2997 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
2998 if [ $? -ne 0 ]; then
2999 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3000 echo "$CMD1 &"
3001 echo "$CMD2"
3002 cat "${te}1" "${te}2"
3003 numFAIL=$((numFAIL+1))
3004 listFAIL="$listFAIL $N"
3005 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
3006 $PRINTF "$FAILED: diff:\n"
3007 cat "$tdiff"
3008 numFAIL=$((numFAIL+1))
3009 listFAIL="$listFAIL $N"
3010 else
3011 $PRINTF "$OK\n"
3012 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3013 numOK=$((numOK+1))
3014 listOK="$listOK $N"
3016 kill $pid 2>/dev/null; wait
3017 wait
3018 fi # feats
3019 esac
3020 N=$((N+1))
3022 NAME=LISTEN_PF_IP4
3023 case "$TESTS" in
3024 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
3025 TEST="$NAME: pf=4 overrides option -6 on listen"
3026 if ! eval $NUMCOND; then :;
3027 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3028 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
3029 numCANT=$((numCANT+1))
3030 listCANT="$listCANT $N"
3031 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
3032 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
3033 numCANT=$((numCANT+1))
3034 listCANT="$listCANT $N"
3035 elif ! feat=$(testoptions ipv6-v6only); then
3036 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
3037 numCANT=$((numCANT+1))
3038 listCANT="$listCANT $N"
3039 else
3040 tf="$td/test$N.stdout"
3041 te="$td/test$N.stderr"
3042 tdiff="$td/test$N.diff"
3043 newport tcp4; tsl=$PORT
3044 ts="127.0.0.1:$tsl"
3045 da="test$N $(date) $RANDOM"
3046 CMD1="$TRACE $SOCAT $opts -6 TCP-LISTEN:$tsl,pf=ip4,$REUSEADDR PIPE"
3047 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
3048 printf "test $F_n $TEST... " $N
3049 SOCAT_DEFAULT_LISTEN_IP=6 $CMD1 >"$tf" 2>"${te}1" &
3050 pid=$! # background process id
3051 waittcp4port $tsl 1
3052 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
3053 if [ $? -ne 0 ]; then
3054 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3055 echo "$CMD1 &"
3056 echo "$CMD2"
3057 cat "${te}1" "${te}2"
3058 numFAIL=$((numFAIL+1))
3059 listFAIL="$listFAIL $N"
3060 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
3061 $PRINTF "$FAILED: diff:\n"
3062 cat "$tdiff"
3063 numFAIL=$((numFAIL+1))
3064 listFAIL="$listFAIL $N"
3065 else
3066 $PRINTF "$OK\n"
3067 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3068 numOK=$((numOK+1))
3069 listOK="$listOK $N"
3071 kill $pid 2>/dev/null; wait
3073 esac
3074 N=$((N+1))
3076 NAME=LISTEN_PF_IP6
3077 case "$TESTS" in
3078 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
3079 TEST="$NAME: pf=6 overrides option -4 on listen"
3080 if ! eval $NUMCOND; then :;
3081 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3082 $PRINTF "test $F_n $TEST... ${YELLOW}TCP4 not available${NORMAL}\n" $N
3083 numCANT=$((numCANT+1))
3084 listCANT="$listCANT $N"
3085 elif ! testfeats ip6 >/dev/null || ! runsip6 >/dev/null; then
3086 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
3087 numCANT=$((numCANT+1))
3088 listCANT="$listCANT $N"
3089 else
3090 tf="$td/test$N.stdout"
3091 te="$td/test$N.stderr"
3092 tdiff="$td/test$N.diff"
3093 newport tcp6; tsl=$PORT
3094 ts="[::1]:$tsl"
3095 da="test$N $(date) $RANDOM"
3096 CMD1="$TRACE $SOCAT $opts -4 TCP-LISTEN:$tsl,pf=ip6,$REUSEADDR PIPE"
3097 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
3098 printf "test $F_n $TEST... " $N
3099 SOCAT_DEFAULT_LISTEN_IP=4 $CMD1 >"$tf" 2>"${te}1" &
3100 pid=$! # background process id
3101 waittcp6port $tsl 1
3102 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
3103 if [ $? -ne 0 ]; then
3104 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3105 echo "$CMD1 &"
3106 echo "$CMD2"
3107 cat "${te}1" "${te}2"
3108 numFAIL=$((numFAIL+1))
3109 listFAIL="$listFAIL $N"
3110 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
3111 $PRINTF "$FAILED: diff:\n"
3112 cat "$tdiff"
3113 numFAIL=$((numFAIL+1))
3114 listFAIL="$listFAIL $N"
3115 else
3116 $PRINTF "$OK\n"
3117 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3118 numOK=$((numOK+1))
3119 listOK="$listOK $N"
3121 kill $pid 2>/dev/null; wait
3122 fi ;; # NUMCOND, feats
3123 esac
3124 N=$((N+1))
3127 NAME=UDP4STREAM
3128 case "$TESTS" in
3129 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%listen%*|*%$NAME%*)
3130 TEST="$NAME: echo via connection to UDP V4 socket"
3131 if ! eval $NUMCOND; then :; else
3132 tf="$td/test$N.stdout"
3133 te="$td/test$N.stderr"
3134 tdiff="$td/test$N.diff"
3135 newport udp4; tsl=$PORT
3136 ts="$LOCALHOST:$tsl"
3137 da="test$N $(date) $RANDOM"
3138 CMD1="$TRACE $SOCAT $opts UDP4-LISTEN:$tsl,$REUSEADDR PIPE"
3139 CMD2="$TRACE $SOCAT $opts - UDP4:$ts"
3140 printf "test $F_n $TEST... " $N
3141 $CMD1 >"$tf" 2>"${te}1" &
3142 pid1=$!
3143 waitudp4port $tsl 1
3144 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
3145 rc2=$?
3146 kill $pid1 2>/dev/null; wait
3147 if [ $rc2 -ne 0 ]; then
3148 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3149 echo "$CMD1 &"
3150 echo "$CMD2"
3151 cat "${te}1" "${te}2"
3152 numFAIL=$((numFAIL+1))
3153 listFAIL="$listFAIL $N"
3154 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
3155 $PRINTF "$FAILED\n"
3156 echo "$CMD1 &"
3157 cat "${te}1"
3158 echo "$CMD2"
3159 cat "${te}2"
3160 cat "$tdiff"
3161 numFAIL=$((numFAIL+1))
3162 listFAIL="$listFAIL $N"
3163 else
3164 $PRINTF "$OK\n"
3165 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3166 numOK=$((numOK+1))
3167 listOK="$listOK $N"
3169 fi ;; # NUMCOND
3170 esac
3171 N=$((N+1))
3174 NAME=UDP6STREAM
3175 case "$TESTS" in
3176 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%udp%*|*%listen%*|*%$NAME%*)
3177 TEST="$NAME: echo via connection to UDP V6 socket"
3178 if ! eval $NUMCOND; then :;
3179 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
3180 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
3181 numCANT=$((numCANT+1))
3182 listCANT="$listCANT $N"
3183 else
3184 tf="$td/test$N.stdout"
3185 te="$td/test$N.stderr"
3186 tdiff="$td/test$N.diff"
3187 newport udp6; tsl=$PORT
3188 ts="$LOCALHOST6:$tsl"
3189 da="test$N $(date) $RANDOM"
3190 CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,$REUSEADDR PIPE"
3191 CMD2="$TRACE $SOCAT $opts - UDP6:$ts"
3192 printf "test $F_n $TEST... " $N
3193 $CMD1 >"$tf" 2>"${te}1" &
3194 pid1=$!
3195 waitudp6port $tsl 1
3196 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
3197 rc2=$?
3198 kill $pid1 2>/dev/null; wait
3199 if [ $rc2 -ne 0 ]; then
3200 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3201 echo "$CMD1 &"
3202 echo "$CMD2"
3203 cat "${te}1" "${te}2"
3204 numFAIL=$((numFAIL+1))
3205 listFAIL="$listFAIL $N"
3206 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
3207 $PRINTF "$FAILED\n"
3208 cat "$tdiff"
3209 numFAIL=$((numFAIL+1))
3210 listFAIL="$listFAIL $N"
3211 else
3212 $PRINTF "$OK\n"
3213 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3214 numOK=$((numOK+1))
3215 listOK="$listOK $N"
3217 fi ;; # ! testfeats
3218 esac
3219 N=$((N+1))
3222 NAME=GOPENFILE
3223 case "$TESTS" in
3224 *%$N%*|*%functions%*|*%engine%*|*%gopen%*|*%file%*|*%ignoreeof%*|*%$NAME%*)
3225 TEST="$NAME: file opening with gopen"
3226 if ! eval $NUMCOND; then :; else
3227 tf1="$td/test$N.1.stdout"
3228 tf2="$td/test$N.2.stdout"
3229 te="$td/test$N.stderr"
3230 tdiff="$td/test$N.diff"
3231 da="test$N $(date) $RANDOM"
3232 echo "$da" >$tf1
3233 CMD="$TRACE $SOCAT $opts $tf1!!/dev/null /dev/null,ignoreeof!!-"
3234 printf "test $F_n $TEST... " $N
3235 $CMD >"$tf2" 2>"$te"
3236 if [ $? -ne 0 ]; then
3237 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3238 echo "$CMD"
3239 cat "$te"
3240 numFAIL=$((numFAIL+1))
3241 listFAIL="$listFAIL $N"
3242 elif ! diff "$tf1" "$tf2" >"$tdiff"; then
3243 $PRINTF "$FAILED: diff:\n"
3244 cat "$tdiff"
3245 numFAIL=$((numFAIL+1))
3246 listFAIL="$listFAIL $N"
3247 else
3248 $PRINTF "$OK\n"
3249 if [ -n "$debug" ]; then cat $te; fi
3250 numOK=$((numOK+1))
3251 listOK="$listOK $N"
3253 fi # NUMCOND
3254 esac
3255 N=$((N+1))
3258 NAME=GOPENPIPE
3259 case "$TESTS" in
3260 *%$N%*|*%functions%*|*%gopen%*|*%pipe%*|*%ignoreeof%*|*%$NAME%*)
3261 TEST="$NAME: pipe opening with gopen for reading"
3262 if ! eval $NUMCOND; then :; else
3263 tp="$td/pipe$N"
3264 tf="$td/test$N.stdout"
3265 te="$td/test$N.stderr"
3266 tdiff="$td/test$N.diff"
3267 da="test$N $(date) $RANDOM"
3268 CMD="$TRACE $SOCAT $opts $tp!!/dev/null /dev/null,ignoreeof!!$tf"
3269 printf "test $F_n $TEST... " $N
3270 #mknod $tp p # no mknod p on FreeBSD
3271 mkfifo $tp
3272 $CMD >$tf 2>"$te" &
3273 #($CMD >$tf 2>"$te" || rm -f "$tp") 2>/dev/null &
3274 bg=$! # background process id
3275 #relsleep 1
3276 waitfile "$tp"
3277 if [ ! -p "$tp" ]; then
3278 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3279 echo "$CMD"
3280 cat "$te"
3281 numFAIL=$((numFAIL+1))
3282 listFAIL="$listFAIL $N"
3283 else
3284 #echo "$da" >"$tp" # might hang forever
3285 echo "$da" >"$tp" & export pid=$!; (relsleep 1; kill $pid 2>/dev/null) &
3286 # Solaris needs more time:
3287 relsleep 1
3288 kill "$bg" 2>/dev/null; wait
3289 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3290 if [ -s "$te" ]; then
3291 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3292 echo "$CMD"
3293 cat "$te"
3294 else
3295 $PRINTF "$FAILED: diff:\n"
3296 cat "$tdiff"
3298 numFAIL=$((numFAIL+1))
3299 listFAIL="$listFAIL $N"
3300 else
3301 $PRINTF "$OK\n"
3302 if [ -n "$debug" ]; then cat $te; fi
3303 numOK=$((numOK+1))
3304 listOK="$listOK $N"
3307 wait
3308 fi # NUMCOND
3309 esac
3310 N=$((N+1))
3313 NAME=GOPENUNIXSTREAM
3314 case "$TESTS" in
3315 *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%$NAME%*)
3316 TEST="$NAME: GOPEN on UNIX stream socket"
3317 if ! eval $NUMCOND; then :; else
3318 ts="$td/test$N.socket"
3319 tf="$td/test$N.stdout"
3320 te="$td/test$N.stderr"
3321 tdiff="$td/test$N.diff"
3322 da1="test$N $(date) $RANDOM"
3323 #establish a listening unix socket in background
3324 SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
3325 #make a connection
3326 CMD="$TRACE $SOCAT $opts - $ts"
3327 $PRINTF "test $F_n $TEST... " $N
3328 eval "$SRV 2>${te}s &"
3329 pids=$!
3330 waitfile "$ts"
3331 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
3332 if [ $? -ne 0 ]; then
3333 kill "$pids" 2>/dev/null
3334 $PRINTF "$FAILED:\n"
3335 echo "$SRV &"
3336 cat "${te}s"
3337 echo "$CMD"
3338 cat "${te}1"
3339 numFAIL=$((numFAIL+1))
3340 listFAIL="$listFAIL $N"
3341 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
3342 kill "$pids" 2>/dev/null
3343 $PRINTF "$FAILED:\n"
3344 echo "$SRV &"
3345 cat "${te}s"
3346 echo "$CMD"
3347 cat "${te}1"
3348 cat "$tdiff"
3349 numFAIL=$((numFAIL+1))
3350 listFAIL="$listFAIL $N"
3351 else
3352 $PRINTF "$OK\n"
3353 if [ -n "$debug" ]; then cat $te; fi
3354 numOK=$((numOK+1))
3355 listOK="$listOK $N"
3356 fi # !(rc -ne 0)
3357 wait
3358 fi # NUMCOND
3359 esac
3360 N=$((N+1))
3362 NAME=GOPENUNIXSEQPACKET
3363 case "$TESTS" in
3364 *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%seqpacket%*|*%$NAME%*)
3365 TEST="$NAME: GOPEN on UNIX seqpacket socket"
3366 if ! eval $NUMCOND; then :; else
3367 ts="$td/test$N.socket"
3368 tf="$td/test$N.stdout"
3369 te="$td/test$N.stderr"
3370 tdiff="$td/test$N.diff"
3371 da1="test$N $(date) $RANDOM"
3372 #establish a listening unix socket in background
3373 SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\",so-type=$SOCK_SEQPACKET PIPE"
3374 #make a connection
3375 CMD="$TRACE $SOCAT $opts - $ts"
3376 $PRINTF "test $F_n $TEST... " $N
3377 eval "$SRV 2>${te}s &"
3378 pids=$!
3379 waitfile "$ts"
3380 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
3381 if [ $? -ne 0 ]; then
3382 kill "$pids" 2>/dev/null
3383 $PRINTF "$FAILED:\n"
3384 echo "$SRV &"
3385 cat "${te}s"
3386 echo "$CMD"
3387 cat "${te}1"
3388 numFAIL=$((numFAIL+1))
3389 listFAIL="$listFAIL $N"
3390 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
3391 kill "$pids" 2>/dev/null
3392 $PRINTF "$FAILED:\n"
3393 echo "$SRV &"
3394 cat "${te}s"
3395 echo "$CMD"
3396 cat "${te}1"
3397 cat "$tdiff"
3398 numFAIL=$((numFAIL+1))
3399 listFAIL="$listFAIL $N"
3400 else
3401 $PRINTF "$OK\n"
3402 if [ -n "$debug" ]; then cat $te; fi
3403 numOK=$((numOK+1))
3404 listOK="$listOK $N"
3405 fi # !(rc -ne 0)
3406 wait
3407 fi # NUMCOND
3408 esac
3409 N=$((N+1))
3412 NAME=GOPENUNIXDGRAM
3413 case "$TESTS" in
3414 *%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%dgram%*|*%$NAME%*)
3415 TEST="$NAME: GOPEN on UNIX datagram socket"
3416 if ! eval $NUMCOND; then :; else
3417 ts="$td/test$N.socket"
3418 tf="$td/test$N.stdout"
3419 te="$td/test$N.stderr"
3420 tdiff="$td/test$N.diff"
3421 da1="test$N $(date) $RANDOM"
3422 #establish a receiving unix socket in background
3423 SRV="$TRACE $SOCAT $opts -u -lpserver UNIX-RECV:\"$ts\" file:\"$tf\",create"
3424 #make a connection
3425 CMD="$TRACE $SOCAT $opts -u - $ts"
3426 $PRINTF "test $F_n $TEST... " $N
3427 eval "$SRV 2>${te}s &"
3428 pids=$!
3429 waitfile "$ts"
3430 echo "$da1" |eval "$CMD" 2>"${te}1"
3431 waitfile -s "$tf"
3432 if [ $? -ne 0 ]; then
3433 $PRINTF "$FAILED:\n"
3434 echo "$SRV &"
3435 cat "${te}s"
3436 echo "$CMD"
3437 cat "${te}1"
3438 numFAIL=$((numFAIL+1))
3439 listFAIL="$listFAIL $N"
3440 elif ! echo "$da1" |diff - "${tf}" >"$tdiff"; then
3441 $PRINTF "$FAILED:\n"
3442 echo "$SRV &"
3443 cat "${te}s"
3444 echo "$CMD"
3445 cat "${te}1"
3446 cat "$tdiff"
3447 numFAIL=$((numFAIL+1))
3448 listFAIL="$listFAIL $N"
3449 else
3450 $PRINTF "$OK\n"
3451 if [ -n "$debug" ]; then cat $te; fi
3452 numOK=$((numOK+1))
3453 listOK="$listOK $N"
3454 fi # !(rc -ne 0)
3455 kill "$pids" 2>/dev/null; wait
3456 fi ;; # NUMCOND
3457 esac
3458 N=$((N+1))
3461 NAME=IGNOREEOF
3462 case "$TESTS" in
3463 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
3464 TEST="$NAME: ignoreeof on file"
3465 if ! eval $NUMCOND; then :; else
3466 ti="$td/test$N.file"
3467 tf="$td/test$N.stdout"
3468 te="$td/test$N.stderr"
3469 tdiff="$td/test$N.diff"
3470 da="test$N $(date) $RANDOM"
3471 CMD="$TRACE $SOCAT $opts -u file:\"$ti\",ignoreeof -"
3472 printf "test $F_n $TEST... " $N
3473 touch "$ti"
3474 $CMD >"$tf" 2>"$te" &
3475 bg=$!
3476 sleep 0.1
3477 echo "$da" >>"$ti"
3478 sleep 1
3479 kill $bg 2>/dev/null; wait
3480 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3481 $PRINTF "$FAILED: diff:\n"
3482 cat "$tdiff"
3483 listFAIL="$listFAIL $N"
3484 numFAIL=$((numFAIL+1))
3485 else
3486 $PRINTF "$OK\n"
3487 if [ -n "$debug" ]; then cat $te; fi
3488 numOK=$((numOK+1))
3489 listOK="$listOK $N"
3491 fi ;; # NUMCOND
3492 esac
3493 N=$((N+1))
3495 NAME=IGNOREEOF_REV
3496 case "$TESTS" in
3497 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
3498 TEST="$NAME: ignoreeof on file right-to-left"
3499 if ! eval $NUMCOND; then :; else
3500 ti="$td/test$N.file"
3501 tf="$td/test$N.stdout"
3502 te="$td/test$N.stderr"
3503 tdiff="$td/test$N.diff"
3504 da="test$N $(date) $RANDOM"
3505 CMD="$SOCAT $opts -U - file:\"$ti\",ignoreeof"
3506 printf "test $F_n $TEST... " $N
3507 touch "$ti"
3508 $CMD >"$tf" 2>"$te" &
3509 bg=$!
3510 relsleep 1
3511 echo "$da" >>"$ti"
3512 sleep 1
3513 kill $bg 2>/dev/null
3514 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3515 $PRINTF "$FAILED: diff:\n"
3516 cat "$tdiff"
3517 listFAIL="$listFAIL $N"
3518 numFAIL=$((numFAIL+1))
3519 else
3520 $PRINTF "$OK\n"
3521 if [ -n "$debug" ]; then cat $te; fi
3522 numOK=$((numOK+1))
3523 listOK="$listOK $N"
3525 wait
3526 fi ;; # NUMCOND
3527 esac
3528 N=$((N+1))
3531 NAME=EXECIGNOREEOF
3532 case "$TESTS" in
3533 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%$NAME%*)
3534 TEST="$NAME: exec against address with ignoreeof"
3535 if ! eval $NUMCOND; then :; else
3536 tf="$td/test$N.stdout"
3537 te="$td/test$N.stderr"
3538 # remark: diagnostics to null, no good style
3539 CMD="$TRACE $SOCAT $opts -lf /dev/null EXEC:$TRUE /dev/null,ignoreeof"
3540 printf "test $F_n $TEST... " $N
3541 $CMD >"$tf" 2>"$te"
3542 if [ -s "$te" ]; then
3543 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3544 echo "$CMD"
3545 cat "$te"
3546 numFAIL=$((numFAIL+1))
3547 listFAIL="$listFAIL $N"
3548 else
3549 $PRINTF "$OK\n"
3550 if [ -n "$debug" ]; then cat $te; fi
3551 numOK=$((numOK+1))
3552 listOK="$listOK $N"
3554 fi ;; # NUMCOND
3555 esac
3556 N=$((N+1))
3559 NAME=FAKEPTY
3560 case "$TESTS" in
3561 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
3562 TEST="$NAME: generation of pty for other processes"
3563 if ! eval $NUMCOND; then :;
3564 elif ! testfeats pty >/dev/null; then
3565 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
3566 numCANT=$((numCANT+1))
3567 listCANT="$listCANT $N"
3568 else
3569 tt="$td/pty$N"
3570 tf="$td/test$N.stdout"
3571 te="$td/test$N.stderr"
3572 tdiff="$td/test$N.diff"
3573 da="test$N $(date) $RANDOM"
3574 CMD1="$TRACE $SOCAT $opts PTY,$PTYOPTS,link=$tt PIPE"
3575 CMD2="$TRACE $SOCAT $opts - $tt,$PTYOPTS2"
3576 printf "test $F_n $TEST... " $N
3577 $CMD1 2>"${te}1" &
3578 pid=$! # background process id
3579 waitfile "$tt"
3580 # this hangs on HP-UX, so we use a timeout
3581 (echo "$da"; sleep 1) |$CMD2 >$tf 2>"${te}2" &
3582 pid2=$!
3583 #sleep 5 && kill $rc2 2>/dev/null &
3584 wait $pid2
3585 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3586 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3587 echo "$CMD1 &"
3588 sleep 1
3589 echo "$CMD2"
3590 cat "${te}1"
3591 cat "${te}2"
3592 cat "$tdiff"
3593 numFAIL=$((numFAIL+1))
3594 listFAIL="$listFAIL $N"
3595 else
3596 $PRINTF "$OK\n"
3597 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3598 numOK=$((numOK+1))
3599 listOK="$listOK $N"
3601 kill $pid 2>/dev/null; wait
3602 fi ;; # NUMCOND, feats
3603 esac
3604 N=$((N+1))
3607 NAME=O_TRUNC
3608 case "$TESTS" in
3609 *%$N%*|*%functions%*|*%$NAME%*)
3610 TEST="$NAME: option o-trunc"
3611 if ! eval $NUMCOND; then :; else
3612 ff="$td/test$N.file"
3613 tf="$td/test$N.stdout"
3614 te="$td/test$N.stderr"
3615 tdiff="$td/test$N.diff"
3616 da="test$N $(date) $RANDOM"
3617 CMD="$TRACE $SOCAT -u $opts - open:$ff,append,o-trunc"
3618 printf "test $F_n $TEST... " $N
3619 rm -f $ff; $ECHO "prefix-\c" >$ff
3620 echo "$da" |$CMD >$tf 2>"$te"
3621 rc0=$?
3622 if ! [ $rc0 = 0 ] ||
3623 ! echo "$da" |diff - $ff >"$tdiff"; then
3624 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3625 echo "$CMD"
3626 cat "$te"
3627 cat "$tdiff"
3628 numFAIL=$((numFAIL+1))
3629 listFAIL="$listFAIL $N"
3630 else
3631 $PRINTF "$OK\n"
3632 if [ -n "$debug" ]; then cat $te; fi
3633 numOK=$((numOK+1))
3634 listOK="$listOK $N"
3636 fi ;; # NUMCOND
3637 esac
3638 N=$((N+1))
3641 NAME=FTRUNCATE
3642 case "$TESTS" in
3643 *%$N%*|*%functions%*|*%$NAME%*)
3644 TEST="$NAME: option ftruncate"
3645 if ! eval $NUMCOND; then :; else
3646 ff="$td/test$N.file"
3647 tf="$td/test$N.stdout"
3648 te="$td/test$N.stderr"
3649 tdiff="$td/test$N.diff"
3650 da="test$N $(date) $RANDOM"
3651 CMD="$TRACE $SOCAT -u $opts - open:$ff,append,ftruncate=0"
3652 printf "test $F_n $TEST... " $N
3653 rm -f $ff; $ECHO "prefix-\c" >$ff
3654 if ! echo "$da" |$CMD >$tf 2>"$te" ||
3655 ! echo "$da" |diff - $ff >"$tdiff"; then
3656 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3657 echo "$CMD"
3658 cat "$te"
3659 cat "$tdiff"
3660 numFAIL=$((numFAIL+1))
3661 listFAIL="$listFAIL $N"
3662 else
3663 $PRINTF "$OK\n"
3664 if [ -n "$debug" ]; then cat $te; fi
3665 numOK=$((numOK+1))
3666 listOK="$listOK $N"
3668 fi ;; # NUMCOND
3669 esac
3670 N=$((N+1))
3673 NAME=RIGHTTOLEFT
3674 case "$TESTS" in
3675 *%$N%*|*%functions%*|*%$NAME%*)
3676 TEST="$NAME: unidirectional throughput from stdin to stdout, right to left"
3677 testecho "$N" "$TEST" "stdout" "stdin" "$opts -U"
3678 esac
3679 N=$((N+1))
3682 # I cannot remember the clou of this test, seems rather useless
3683 NAME=CHILDDEFAULT
3684 case "$TESTS" in
3685 *%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
3686 if ! eval $NUMCOND; then :
3687 elif ! F=$(testfeats STDIO EXEC); then
3688 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
3689 numCANT=$((numCANT+1))
3690 listCANT="$listCANT $N"
3691 elif ! A=$(testaddrs STDIO EXEC); then
3692 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
3693 numCANT=$((numCANT+1))
3694 listCANT="$listCANT $N"
3695 else
3696 TEST="$NAME: child process default properties"
3697 tf="$td/test$N.stdout"
3698 te="$td/test$N.stderr"
3699 CMD="$TRACE $SOCAT $opts -u EXEC:$PROCAN -"
3700 printf "test $F_n $TEST... " $N
3701 $CMD >$tf 2>$te
3702 MYPID=`expr "\`grep "process id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3703 MYPPID=`expr "\`grep "process parent id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3704 MYPGID=`expr "\`grep "process group id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3705 MYSID=`expr "\`grep "process session id =" $tf\`" : '[^0-9]*\([0-9]*\).*'`
3706 #echo "PID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID"
3707 #if [ "$MYPID" = "$MYPPID" -o "$MYPID" = "$MYPGID" -o "$MYPID" = "$MYSID" -o \
3708 # "$MYPPID" = "$MYPGID" -o "$MYPPID" = "$MYSID" -o "$MYPGID" = "$MYSID" ];
3709 if [ "$MYPID" = "$MYPPID" ];
3710 then
3711 $PRINTF "$FAILED:\n"
3712 echo "$CMD"
3713 cat "$te" >&2
3714 numFAIL=$((numFAIL+1))
3715 listFAIL="$listFAIL $N"
3716 else
3717 $PRINTF "$OK\n"
3718 if [ "$VERBOSE" ]; then echo "$CMD"; fi
3719 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
3720 numOK=$((numOK+1))
3721 listOK="$listOK $N"
3723 fi ;; # NUMCOND
3724 esac
3725 N=$((N+1))
3728 NAME=CHILDSETSID
3729 case "$TESTS" in
3730 *%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
3731 TEST="$NAME: child process with setsid"
3732 if ! eval $NUMCOND; then :; else
3733 tf="$td/test$N.stdout"
3734 te="$td/test$N.stderr"
3735 CMD="$TRACE $SOCAT $opts -u exec:$PROCAN,setsid -"
3736 printf "test $F_n $TEST... " $N
3737 $CMD >$tf 2>$te
3738 MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3739 MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3740 MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3741 MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3742 #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID"
3743 # PID, PGID, and SID must be the same
3744 if [ "$MYPID" = "$MYPPID" -o \
3745 "$MYPID" != "$MYPGID" -o "$MYPID" != "$MYSID" ];
3746 then
3747 $PRINTF "$FAILED\n"
3748 echo "$CMD"
3749 cat "$te"
3750 numFAIL=$((numFAIL+1))
3751 listFAIL="$listFAIL $N"
3752 else
3753 $PRINTF "$OK\n"
3754 numOK=$((numOK+1))
3755 listOK="$listOK $N"
3757 fi ;; # NUMCOND
3758 esac
3759 N=$((N+1))
3762 NAME=MAINSETSID
3763 case "$TESTS" in
3764 *%$N%*|*%functions%*|*%stdio%*|*%exec%*|*%procan%*|*%$NAME%*)
3765 TEST="$NAME: main process with setsid"
3766 if ! eval $NUMCOND; then :; else
3767 tf="$td/test$N.stdout"
3768 te="$td/test$N.stderr"
3769 CMD="$TRACE $SOCAT $opts -U -,setsid EXEC:$PROCAN"
3770 printf "test $F_n $TEST... " $N
3771 $CMD >$tf 2>$te
3772 MYPID=`grep "process id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3773 MYPPID=`grep "process parent id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3774 MYPGID=`grep "process group id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3775 MYSID=`grep "process session id =" $tf |(expr "\`cat\`" : '[^0-9]*\([0-9]*\).*')`
3776 #$ECHO "\nPID=$MYPID, PPID=$MYPPID, PGID=$MYPGID, SID=$MYSID"
3777 # PPID, PGID, and SID must be the same
3778 if [ "$MYPID" = "$MYPPID" -o \
3779 "$MYPPID" != "$MYPGID" -o "$MYPPID" != "$MYSID" ];
3780 then
3781 $PRINTF "$FAILED\n"
3782 echo "$CMD"
3783 cat "$te"
3784 numFAIL=$((numFAIL+1))
3785 listFAIL="$listFAIL $N"
3786 else
3787 $PRINTF "$OK\n"
3788 numOK=$((numOK+1))
3789 listOK="$listOK $N"
3791 fi ;; # NUMCOND
3792 esac
3793 N=$((N+1))
3796 NAME=OPENSSL_TCP4
3797 case "$TESTS" in
3798 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%$NAME%*)
3799 TEST="$NAME: openssl connect"
3800 if ! eval $NUMCOND; then :;
3801 elif ! testfeats openssl >/dev/null; then
3802 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3803 numCANT=$((numCANT+1))
3804 listCANT="$listCANT $N"
3805 elif ! type openssl >/dev/null 2>&1; then
3806 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
3807 numCANT=$((numCANT+1))
3808 listCANT="$listCANT $N"
3809 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3810 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3811 numCANT=$((numCANT+1))
3812 listCANT="$listCANT $N"
3813 else
3814 gentestcert testsrv
3815 tf="$td/test$N.stdout"
3816 te="$td/test$N.stderr"
3817 tdiff="$td/test$N.diff"
3818 da="test$N $(date) $RANDOM"
3819 newport tcp4 # provide free port number in $PORT
3820 init_openssl_s_server
3821 CMD2="$TRACE $SOCAT $opts exec:'openssl s_server $OPENSSL_S_SERVER_4 -accept "$PORT" -quiet -cert testsrv.pem' pipe"
3822 CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
3823 printf "test $F_n $TEST... " $N
3824 eval "$CMD2 2>\"${te}1\" &"
3825 pid=$! # background process id
3826 # this might timeout when openssl opens tcp46 port like " :::$PORT"
3827 waittcp4port $PORT
3828 #echo "$da" |$CMD >$tf 2>"${te}2"
3829 #note: with about OpenSSL 1.1 s_server lost the half close feature, thus:
3830 (echo "$da"; sleep 0.1) |$CMD >$tf 2>"${te}2"
3831 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3832 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3833 echo "$CMD2 &"
3834 echo "$CMD"
3835 cat "${te}1"
3836 cat "${te}2"
3837 cat "$tdiff"
3838 numFAIL=$((numFAIL+1))
3839 listFAIL="$listFAIL $N"
3840 else
3841 $PRINTF "$OK\n"
3842 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3843 numOK=$((numOK+1))
3844 listOK="$listOK $N"
3846 kill $pid 2>/dev/null; wait
3847 fi ;; # NUMCOND, feats
3848 esac
3849 N=$((N+1))
3852 NAME=OPENSSLLISTEN_TCP4
3853 case "$TESTS" in
3854 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
3855 TEST="$NAME: openssl listen"
3856 if ! eval $NUMCOND; then :;
3857 elif ! testfeats openssl >/dev/null; then
3858 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3859 numCANT=$((numCANT+1))
3860 listCANT="$listCANT $N"
3861 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
3862 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
3863 numCANT=$((numCANT+1))
3864 listCANT="$listCANT $N"
3865 else
3866 gentestcert testsrv
3867 tf="$td/test$N.stdout"
3868 te="$td/test$N.stderr"
3869 tdiff="$td/test$N.diff"
3870 da="test$N $(date) $RANDOM"
3871 newport tcp4 # provide free port number in $PORT
3872 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
3873 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
3874 printf "test $F_n $TEST... " $N
3875 eval "$CMD2 2>\"${te}1\" &"
3876 pid=$! # background process id
3877 waittcp4port $PORT
3878 echo "$da" |$CMD >$tf 2>"${te}2"
3879 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3880 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3881 echo "$CMD2 &"
3882 echo "$CMD"
3883 cat "${te}1"
3884 cat "${te}2"
3885 cat "$tdiff"
3886 numFAIL=$((numFAIL+1))
3887 listFAIL="$listFAIL $N"
3888 else
3889 $PRINTF "$OK\n"
3890 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3891 numOK=$((numOK+1))
3892 listOK="$listOK $N"
3894 kill $pid 2>/dev/null
3895 wait
3896 fi ;; # NUMCOND, feats
3897 esac
3898 N=$((N+1))
3900 NAME=OPENSSLLISTEN_TCP6
3901 case "$TESTS" in
3902 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
3903 TEST="$NAME: openssl listen"
3904 if ! eval $NUMCOND; then :;
3905 elif ! testfeats openssl >/dev/null; then
3906 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
3907 numCANT=$((numCANT+1))
3908 listCANT="$listCANT $N"
3909 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
3910 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
3911 numCANT=$((numCANT+1))
3912 listCANT="$listCANT $N"
3913 else
3914 gentestcert testsrv
3915 tf="$td/test$N.stdout"
3916 te="$td/test$N.stderr"
3917 tdiff="$td/test$N.diff"
3918 da="test$N $(date) $RANDOM"
3919 newport tcp6 # provide free port number in $PORT
3920 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
3921 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST6:$PORT,verify=0,$SOCAT_EGD"
3922 printf "test $F_n $TEST... " $N
3923 eval "$CMD2 2>\"${te}1\" &"
3924 pid=$! # background process id
3925 waittcp6port $PORT
3926 echo "$da" |$CMD >$tf 2>"${te}2"
3927 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
3928 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3929 echo "$CMD2 &"
3930 echo "$CMD"
3931 cat "${te}1"
3932 cat "${te}2"
3933 cat "$tdiff"
3934 numFAIL=$((numFAIL+1))
3935 listFAIL="$listFAIL $N"
3936 else
3937 $PRINTF "$OK\n"
3938 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
3939 numOK=$((numOK+1))
3940 listOK="$listOK $N"
3942 kill $pid 2>/dev/null
3943 wait
3944 fi ;; # NUMCOND, feats
3945 esac
3946 N=$((N+1))
3949 newport $RUNS # in case it has not yet been invoked
3951 while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do
3952 if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi
3954 export ts="$td/test$N.socket"
3955 case $RUNS in tcp4|tcp6) newport $RUNS;; esac
3956 WAITTMPL="$(echo "$WAITTMPL" |sed -e 's/\040/ /g')"
3957 TESTADDR=$(eval echo $TESTTMPL)
3958 PEERADDR=$(eval echo $PEERTMPL)
3959 WAITCMD=$(eval echo $WAITTMPL)
3960 TESTKEYW=${TESTADDR%%:*}
3961 feat=$(tolower $FEAT)
3963 # does our address implementation support halfclose?
3964 NAME=${NAMEKEYW}_HALFCLOSE
3965 case "$TESTS" in
3966 *%$N%*|*%functions%*|*%$feat%*|*%socket%*|*%halfclose%*|*%listen%*|*%$NAME%*)
3967 TEST="$NAME: $TESTKEYW half close"
3968 # have a "peer" socat "peer" that executes "$OD_C" and see if EOF on the
3969 # connecting socat brings the result of od
3970 if ! eval $NUMCOND; then :;
3971 elif [ "$FEAT" != ',' ] && ! testfeats "$FEAT" >/dev/null; then
3972 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $FEAT not configured${NORMAL}\n" $N
3973 numCANT=$((numCANT+1))
3974 listCANT="$listCANT $N"
3975 elif ! runs$RUNS >/dev/null; then
3976 $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available on host${NORMAL}\n" $N
3977 numCANT=$((numCANT+1))
3978 listCANT="$listCANT $N"
3979 else
3980 tf="$td/test$N.stdout"
3981 te="$td/test$N.stderr"
3982 tdiff="$td/test$N.diff"
3983 da="test$N $(date) $RANDOM"
3984 case $RUNS in tcp4|tcp6) newport $RUNS;; esac
3985 CMD2="$TRACE $SOCAT $opts \"$PEERADDR\" EXEC:'$OD_C'"
3986 CMD="$TRACE $SOCAT -T1 $opts -t 1 - $TESTADDR"
3987 printf "test $F_n $TEST... " $N
3988 eval "$CMD2 2>\"${te}2\" &"
3989 pid2=$! # background process id
3990 $WAITCMD
3991 echo "$da" |$CMD >$tf 2>"${te}"
3992 kill $pid2 2>/dev/null
3993 wait
3994 if ! echo "$da" |$OD_C |diff - "$tf" >"$tdiff"; then
3995 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
3996 echo "$CMD2 &"
3997 cat "${te}2"
3998 echo "$CMD"
3999 cat "${te}"
4000 cat "$tdiff"
4001 numFAIL=$((numFAIL+1))
4002 listFAIL="$listFAIL $N"
4003 else
4004 $PRINTF "$OK\n"
4005 if [ "$VERBOSE" ]; then
4006 echo " $CMD2 &"
4007 echo " $CMD"
4009 if [ -n "$debug" ]; then cat "${te}2" "${te}"; fi
4010 numOK=$((numOK+1))
4011 listOK="$listOK $N"
4013 wait
4014 fi ;; # NUMCOND, feats
4015 esac
4016 N=$((N+1))
4018 done <<<"
4019 UNIXCONNECT , unix UNIX-CONNECT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts
4020 UNIXCLIENT , unix UNIX-CLIENT:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts
4021 GOPEN_UNIXSTREAM , unix GOPEN:\$ts UNIX-LISTEN:\$ts waitfile\040\$ts
4022 UNIXLISTEN , unix UNIX-LISTEN:\$ts UNIX-CONNECT:\$ts,retry=3 sleep\040\1
4023 TCP4CONNECT , tcp4 TCP4-CONNECT:\$LOCALHOST:\$PORT TCP4-LISTEN:\$PORT,$REUSEADDR waittcp4port\040\$PORT
4024 TCP4LISTEN , tcp4 TCP4-LISTEN:\$PORT,$REUSEADDR TCP4-CONNECT:\$LOCALHOST:\$PORT,retry=3
4025 TCP6CONNECT , tcp6 TCP6-CONNECT:\$LOCALHOST6:\$PORT TCP6-LISTEN:\$PORT,$REUSEADDR waittcp6port\040\$PORT
4026 TCP6LISTEN , tcp6 TCP6-LISTEN:\$PORT,$REUSEADDR TCP6-CONNECT:\$LOCALHOST6:\$PORT,retry=3
4027 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
4028 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
4029 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
4030 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
4034 NAME=OPENSSL_SERVERAUTH
4035 case "$TESTS" in
4036 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4037 TEST="$NAME: OpenSSL server authentication (hostname)"
4038 if ! eval $NUMCOND; then :;
4039 elif ! testfeats openssl >/dev/null; then
4040 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
4041 numCANT=$((numCANT+1))
4042 listCANT="$listCANT $N"
4043 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4044 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4045 numCANT=$((numCANT+1))
4046 listCANT="$listCANT $N"
4047 else
4048 gentestcert testsrv
4049 gentestcert testcli
4050 tf="$td/test$N.stdout"
4051 te="$td/test$N.stderr"
4052 tdiff="$td/test$N.diff"
4053 da="test$N $(date) $RANDOM"
4054 newport tcp4 # provide free port number in $PORT
4055 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0 pipe"
4056 CMD1="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=1,cafile=testsrv.crt,$SOCAT_EGD"
4057 printf "test $F_n $TEST... " $N
4058 eval "$CMD0 2>\"${te}0\" &"
4059 pid=$! # background process id
4060 waittcp4port $PORT
4061 echo "$da" |$CMD1 >$tf 2>"${te}1"
4062 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4063 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4064 echo "$CMD0 &"
4065 cat "${te}0"
4066 echo "$CMD1"
4067 cat "${te}1"
4068 cat "$tdiff"
4069 numFAIL=$((numFAIL+1))
4070 listFAIL="$listFAIL $N"
4071 else
4072 $PRINTF "$OK\n"
4073 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4074 numOK=$((numOK+1))
4075 listOK="$listOK $N"
4077 kill $pid 2>/dev/null
4078 wait
4079 fi ;; # NUMCOND, feats
4080 esac
4081 N=$((N+1))
4083 NAME=OPENSSL_CLIENTAUTH
4084 case "$TESTS" in
4085 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4086 TEST="$NAME: openssl client authentication"
4087 if ! eval $NUMCOND; then :;
4088 elif ! testfeats openssl >/dev/null; then
4089 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
4090 numCANT=$((numCANT+1))
4091 listCANT="$listCANT $N"
4092 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4093 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4094 numCANT=$((numCANT+1))
4095 listCANT="$listCANT $N"
4096 else
4097 gentestcert testsrv
4098 gentestcert testcli
4099 tf="$td/test$N.stdout"
4100 te="$td/test$N.stderr"
4101 tdiff="$td/test$N.diff"
4102 da="test$N $(date) $RANDOM"
4103 newport tcp4 # provide free port number in $PORT
4104 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,verify=1,cert=testsrv.crt,key=testsrv.key,cafile=testcli.crt,$SOCAT_EGD PIPE"
4105 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,cert=testcli.crt,key=testcli.key,$SOCAT_EGD"
4106 printf "test $F_n $TEST... " $N
4107 eval "$CMD2 2>\"${te}1\" &"
4108 pid=$! # background process id
4109 waittcp4port $PORT
4110 echo "$da" |$CMD >$tf 2>"${te}2"
4111 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4112 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4113 echo "$CMD2 &"
4114 echo "$CMD"
4115 cat "${te}1"
4116 cat "${te}2"
4117 cat "$tdiff"
4118 numFAIL=$((numFAIL+1))
4119 listFAIL="$listFAIL $N"
4120 else
4121 $PRINTF "$OK\n"
4122 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4123 numOK=$((numOK+1))
4124 listOK="$listOK $N"
4126 kill $pid 2>/dev/null
4127 wait
4128 fi ;; # NUMCOND, feats
4129 esac
4130 N=$((N+1))
4132 NAME=OPENSSL_FIPS_BOTHAUTH
4133 case "$TESTS" in
4134 *%$N%*|*%functions%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4135 TEST="$NAME: OpenSSL+FIPS client and server authentication"
4136 if ! eval $NUMCOND; then :;
4137 elif ! testfeats openssl >/dev/null; then
4138 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
4139 numCANT=$((numCANT+1))
4140 listCANT="$listCANT $N"
4141 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4142 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4143 numCANT=$((numCANT+1))
4144 listCANT="$listCANT $N"
4145 elif ! testoptions fips >/dev/null; then
4146 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N
4147 numCANT=$((numCANT+1))
4148 listCANT="$listCANT $N"
4149 else
4150 OPENSSL_FIPS=1 gentestcert testsrvfips
4151 OPENSSL_FIPS=1 gentestcert testclifips
4152 tf="$td/test$N.stdout"
4153 te="$td/test$N.stderr"
4154 tdiff="$td/test$N.diff"
4155 da="test$N $(date) $RANDOM"
4156 newport tcp4 # provide free port number in $PORT
4157 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,fips,$SOCAT_EGD,cert=testsrvfips.crt,key=testsrvfips.key,cafile=testclifips.crt pipe"
4158 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,fips,verify=1,cert=testclifips.crt,key=testclifips.key,cafile=testsrvfips.crt,$SOCAT_EGD"
4159 printf "test $F_n $TEST... " $N
4160 eval "$CMD2 2>\"${te}1\" &"
4161 pid=$! # background process id
4162 waittcp4port $PORT
4163 echo "$da" |$CMD >$tf 2>"${te}2"
4164 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4165 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4166 echo "$CMD2 &"
4167 echo "$CMD"
4168 cat "${te}1"
4169 cat "${te}2"
4170 cat "$tdiff"
4171 numFAIL=$((numFAIL+1))
4172 listFAIL="$listFAIL $N"
4173 else
4174 $PRINTF "$OK\n"
4175 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4176 numOK=$((numOK+1))
4177 listOK="$listOK $N"
4179 kill $pid 2>/dev/null
4180 wait
4181 fi ;; # NUMCOND, feats
4182 esac
4183 N=$((N+1))
4186 NAME=OPENSSL_COMPRESS
4187 case "$TESTS" in
4188 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4189 TEST="$NAME: OpenSSL compression"
4190 if ! eval $NUMCOND; then :;
4191 elif ! testfeats openssl >/dev/null; then
4192 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
4193 numCANT=$((numCANT+1))
4194 listCANT="$listCANT $N"
4195 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4196 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4197 numCANT=$((numCANT+1))
4198 listCANT="$listCANT $N"
4199 elif ! testoptions openssl-compress >/dev/null; then
4200 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL compression option not available${NORMAL}\n" $N
4201 numCANT=$((numCANT+1))
4202 listCANT="$listCANT $N"
4203 else
4204 gentestcert testsrv
4205 printf "test $F_n $TEST... " $N
4206 tf="$td/test$N.stdout"
4207 te="$td/test$N.stderr"
4208 tdiff="$td/test$N.diff"
4209 da="test$N $(date) $RANDOM"
4210 success=yes
4211 for srccompr in '' compress=auto compress=none; do
4212 for dstcompr in '' compress=auto compress=none; do
4213 newport tcp4 # provide free port number in $PORT
4214 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testsrv.crt,key=testsrv.key,verify=0,$dstcompr PIPE"
4215 CMD="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,$srccompr"
4216 eval "$CMD2 2>\"${te}1\" &"
4217 pid=$! # background process id
4218 waittcp4port $PORT
4219 echo "$da" | $CMD >$tf 2>"${te}2"
4220 kill $pid 2>/dev/null
4221 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4222 success=
4223 break
4225 done
4226 done
4227 if test -z "$success"; 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))
4240 listOK="$listOK $N"
4242 fi ;; # NUMCOND, feats
4243 esac
4244 N=$((N+1))
4247 NAME=SOCKS4CONNECT_TCP4
4248 case "$TESTS" in
4249 *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4250 TEST="$NAME: socks4 connect over TCP/IPv4"
4251 if ! eval $NUMCOND; then :;
4252 elif ! testfeats socks4 >/dev/null; then
4253 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
4254 numCANT=$((numCANT+1))
4255 listCANT="$listCANT $N"
4256 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4257 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4258 numCANT=$((numCANT+1))
4259 listCANT="$listCANT $N"
4260 else
4261 tf="$td/test$N.stdout"
4262 te="$td/test$N.stderr"
4263 tdiff="$td/test$N.diff"
4264 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4265 # we have a normal tcp echo listening - so the socks header must appear in answer
4266 newport tcp4 # provide free port number in $PORT
4267 CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4echo.sh\""
4268 CMD="$TRACE $SOCAT $opts - SOCKS4:$LOCALHOST:32.98.76.54:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
4269 printf "test $F_n $TEST... " $N
4270 eval "$CMD2 2>\"${te}1\" &"
4271 pid=$! # background process id
4272 waittcp4port $PORT 1
4273 echo "$da" |$CMD >$tf 2>"${te}2"
4274 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4275 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4276 echo "$CMD2 &"
4277 echo "$CMD"
4278 cat "${te}1"
4279 cat "${te}2"
4280 cat "$tdiff"
4281 numFAIL=$((numFAIL+1))
4282 listFAIL="$listFAIL $N"
4283 else
4284 $PRINTF "$OK\n"
4285 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4286 numOK=$((numOK+1))
4287 listOK="$listOK $N"
4289 kill $pid 2>/dev/null
4290 wait
4291 fi ;; # NUMCOND, feats
4292 esac
4293 N=$((N+1))
4295 NAME=SOCKS4CONNECT_TCP6
4296 case "$TESTS" in
4297 *%$N%*|*%functions%*|*%socks%*|*%socks4%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
4298 TEST="$NAME: socks4 connect over TCP/IPv6"
4299 if ! eval $NUMCOND; then :;
4300 elif ! testfeats socks4 >/dev/null; then
4301 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4 not available${NORMAL}\n" $N
4302 numCANT=$((numCANT+1))
4303 listCANT="$listCANT $N"
4304 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
4305 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
4306 numCANT=$((numCANT+1))
4307 listCANT="$listCANT $N"
4308 else
4309 tf="$td/test$N.stdout"
4310 te="$td/test$N.stderr"
4311 tdiff="$td/test$N.diff"
4312 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4313 # we have a normal tcp echo listening - so the socks header must appear in answer
4314 newport tcp6 # provide free port number in $PORT
4315 CMD0="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR exec:\"./socks4echo.sh\""
4316 CMD1="$TRACE $SOCAT $opts - socks4:$LOCALHOST6:32.98.76.54:32109,socksport=$PORT",socksuser="nobody"
4317 printf "test $F_n $TEST... " $N
4318 eval "$CMD0 2>\"${te}0\" &"
4319 pid=$! # background process id
4320 waittcp6port $PORT 1
4321 echo "$da" |$CMD1 >${tf}1 2>"${te}1"
4322 if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
4323 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4324 echo "$CMD0 &"
4325 cat "${te}0" >&2
4326 echo "$CMD1"
4327 cat "${te}1" >&2
4328 echo "// diff:" >&2
4329 cat "$tdiff" >&2
4330 numFAIL=$((numFAIL+1))
4331 listFAIL="$listFAIL $N"
4332 else
4333 $PRINTF "$OK\n"
4334 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
4335 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
4336 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
4337 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
4338 numOK=$((numOK+1))
4339 listOK="$listOK $N"
4341 kill $pid 2>/dev/null
4342 wait
4343 fi ;; # NUMCOND, feats
4344 esac
4345 N=$((N+1))
4348 NAME=SOCKS4ACONNECT_TCP4
4349 case "$TESTS" in
4350 *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4351 TEST="$NAME: socks4a connect over TCP/IPv4"
4352 if ! eval $NUMCOND; then :;
4353 elif ! testfeats socks4a >/dev/null; then
4354 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N
4355 numCANT=$((numCANT+1))
4356 listCANT="$listCANT $N"
4357 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4358 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4359 numCANT=$((numCANT+1))
4360 listCANT="$listCANT $N"
4361 else
4362 tf="$td/test$N.stdout"
4363 te="$td/test$N.stderr"
4364 tdiff="$td/test$N.diff"
4365 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4366 # we have a normal tcp echo listening - so the socks header must appear in answer
4367 newport tcp4 # provide free port number in $PORT
4368 CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR EXEC:\"./socks4a-echo.sh\""
4369 CMD="$TRACE $SOCAT $opts - SOCKS4A:$LOCALHOST:localhost:32109,pf=ip4,socksport=$PORT",socksuser="nobody"
4370 printf "test $F_n $TEST... " $N
4371 eval "$CMD2 2>\"${te}1\" &"
4372 pid=$! # background process id
4373 waittcp4port $PORT 1
4374 echo "$da" |$CMD >$tf 2>"${te}2"
4375 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4376 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4377 echo "$CMD2 &"
4378 echo "$CMD"
4379 cat "${te}1"
4380 cat "${te}2"
4381 cat "$tdiff"
4382 numFAIL=$((numFAIL+1))
4383 listFAIL="$listFAIL $N"
4384 else
4385 $PRINTF "$OK\n"
4386 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4387 numOK=$((numOK+1))
4388 listOK="$listOK $N"
4390 kill $pid 2>/dev/null
4391 wait
4392 fi ;; # NUMCOND, feats
4393 esac
4394 N=$((N+1))
4396 NAME=SOCKS4ACONNECT_TCP6
4397 case "$TESTS" in
4398 *%$N%*|*%functions%*|*%socks%*|*%socks4a%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
4399 TEST="$NAME: socks4a connect over TCP/IPv6"
4400 if ! eval $NUMCOND; then :;
4401 elif ! testfeats socks4a >/dev/null; then
4402 $PRINTF "test $F_n $TEST... ${YELLOW}SOCKS4A not available${NORMAL}\n" $N
4403 numCANT=$((numCANT+1))
4404 listCANT="$listCANT $N"
4405 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
4406 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
4407 numCANT=$((numCANT+1))
4408 listCANT="$listCANT $N"
4409 else
4410 tf="$td/test$N.stdout"
4411 te="$td/test$N.stderr"
4412 tdiff="$td/test$N.diff"
4413 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4414 # we have a normal tcp echo listening - so the socks header must appear in answer
4415 newport tcp6 # provide free port number in $PORT
4416 CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR EXEC:\"./socks4a-echo.sh\""
4417 CMD="$TRACE $SOCAT $opts - SOCKS4A:$LOCALHOST6:localhost:32109,socksport=$PORT",socksuser="nobody"
4418 printf "test $F_n $TEST... " $N
4419 eval "$CMD2 2>\"${te}1\" &"
4420 pid=$! # background process id
4421 waittcp6port $PORT 1
4422 echo "$da" |$CMD >$tf 2>"${te}2"
4423 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4424 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4425 echo "$CMD2 &"
4426 echo "$CMD"
4427 cat "${te}1"
4428 cat "${te}2"
4429 cat "$tdiff"
4430 numFAIL=$((numFAIL+1))
4431 listFAIL="$listFAIL $N"
4432 else
4433 $PRINTF "$OK\n"
4434 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4435 numOK=$((numOK+1))
4436 listOK="$listOK $N"
4438 kill $pid 2>/dev/null
4439 wait
4440 fi ;; # NUMCOND, feats
4441 esac
4442 N=$((N+1))
4445 NAME=PROXYCONNECT_TCP4
4446 case "$TESTS" in
4447 *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
4448 TEST="$NAME: proxy connect over TCP/IPv4"
4449 if ! eval $NUMCOND; then :;
4450 elif ! testfeats proxy >/dev/null; then
4451 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
4452 numCANT=$((numCANT+1))
4453 listCANT="$listCANT $N"
4454 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
4455 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
4456 numCANT=$((numCANT+1))
4457 listCANT="$listCANT $N"
4458 else
4459 ts="$td/test$N.sh"
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 tcp4-l:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
4466 CMD2="$TRACE $SOCAT $opts TCP4-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\""
4467 CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
4468 printf "test $F_n $TEST... " $N
4469 eval "$CMD2 2>\"${te}2\" &"
4470 pid=$! # background process id
4471 waittcp4port $PORT 1
4472 echo "$da" |$CMD >"$tf" 2>"${te}1"
4473 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4474 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4475 echo "$CMD2 &"
4476 echo "$CMD"
4477 cat "${te}1"
4478 cat "${te}2"
4479 cat "$tdiff"
4480 numFAIL=$((numFAIL+1))
4481 listFAIL="$listFAIL $N"
4482 else
4483 $PRINTF "$OK\n"
4484 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4485 numOK=$((numOK+1))
4486 listOK="$listOK $N"
4488 kill $pid 2>/dev/null
4489 wait
4490 fi ;; # NUMCOND, feats
4491 esac
4492 N=$((N+1))
4494 NAME=PROXYCONNECT_TCP6
4495 case "$TESTS" in
4496 *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
4497 TEST="$NAME: proxy connect over TCP/IPv6"
4498 if ! eval $NUMCOND; then :;
4499 elif ! testfeats proxy >/dev/null; then
4500 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
4501 numCANT=$((numCANT+1))
4502 listCANT="$listCANT $N"
4503 elif ! testfeats listen tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
4504 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
4505 numCANT=$((numCANT+1))
4506 listCANT="$listCANT $N"
4507 else
4508 ts="$td/test$N.sh"
4509 tf="$td/test$N.stdout"
4510 te="$td/test$N.stderr"
4511 tdiff="$td/test$N.diff"
4512 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4513 newport tcp6 # provide free port number in $PORT
4514 #CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
4515 CMD2="$TRACE $SOCAT $opts TCP6-L:$PORT,$REUSEADDR,crlf EXEC:\"/usr/bin/env bash proxyecho.sh\""
4516 CMD="$TRACE $SOCAT $opts - PROXY:$LOCALHOST6:127.0.0.1:1000,proxyport=$PORT"
4517 printf "test $F_n $TEST... " $N
4518 eval "$CMD2 2>\"${te}2\" &"
4519 pid=$! # background process id
4520 waittcp6port $PORT 1
4521 echo "$da" |$CMD >"$tf" 2>"${te}1"
4522 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4523 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4524 echo "$CMD2 &"
4525 echo "$CMD"
4526 cat "${te}1"
4527 cat "${te}2"
4528 cat "$tdiff"
4529 numFAIL=$((numFAIL+1))
4530 listFAIL="$listFAIL $N"
4531 else
4532 $PRINTF "$OK\n"
4533 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4534 numOK=$((numOK+1))
4535 listOK="$listOK $N"
4537 kill $pid 2>/dev/null
4538 wait
4539 fi ;; # NUMCOND, feats
4540 esac
4541 N=$((N+1))
4544 NAME=TCP4NOFORK
4545 case "$TESTS" in
4546 *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%exec%*|*%listen%*|*%$NAME%*)
4547 TEST="$NAME: echo via connection to TCP V4 socket with nofork'ed exec"
4548 if ! eval $NUMCOND; then :; else
4549 tf="$td/test$N.stdout"
4550 te="$td/test$N.stderr"
4551 tdiff="$td/test$N.diff"
4552 newport tcp4; tsl=$PORT
4553 ts="127.0.0.1:$tsl"
4554 da="test$N $(date) $RANDOM"
4555 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR EXEC:$CAT,nofork"
4556 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP4:$ts"
4557 printf "test $F_n $TEST... " $N
4558 #$CMD1 >"$tf" 2>"${te}1" &
4559 $CMD1 >/dev/null 2>"${te}1" &
4560 waittcp4port $tsl
4561 #relsleep 1
4562 echo "$da" |$CMD2 >"$tf" 2>>"${te}2"
4563 if [ $? -ne 0 ]; then
4564 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4565 echo "$CMD1 &"
4566 echo "$CMD2"
4567 cat "${te}1"
4568 cat "${te}2"
4569 numFAIL=$((numFAIL+1))
4570 listFAIL="$listFAIL $N"
4571 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
4572 $PRINTF "$FAILED\n"
4573 cat "$tdiff"
4574 numFAIL=$((numFAIL+1))
4575 listFAIL="$listFAIL $N"
4576 else
4577 $PRINTF "$OK\n"
4578 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4579 numOK=$((numOK+1))
4580 listOK="$listOK $N"
4582 fi ;; # NUMCOND
4583 esac
4584 N=$((N+1))
4587 NAME=EXECCATNOFORK
4588 case "$TESTS" in
4589 *%$N%*|*%functions%*|*%$NAME%*)
4590 TEST="$NAME: simple echo via exec of cat with nofork"
4591 testecho "$N" "$TEST" "" "EXEC:$CAT,nofork" "$opts"
4592 esac
4593 N=$((N+1))
4596 NAME=SYSTEMCATNOFORK
4597 case "$TESTS" in
4598 *%$N%*|*%functions%*|*%$NAME%*)
4599 TEST="$NAME: simple echo via system() of cat with nofork"
4600 testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork" "$opts"
4601 esac
4602 N=$((N+1))
4605 NAME=NOFORKSETSID
4606 case "$TESTS" in
4607 *%$N%*|*%functions%*|*%$NAME%*)
4608 TEST="$NAME: simple echo via exec() of cat with nofork and setsid"
4609 testecho "$N" "$TEST" "" "SYSTEM:$CAT,nofork,setsid" "$opts"
4610 esac
4611 N=$((N+1))
4613 #==============================================================================
4614 #TEST="$NAME: echo via 'connection' to UDP V4 socket"
4615 #if ! eval $NUMCOND; then :; else
4616 #tf="$td/file$N"
4617 #tsl=65534
4618 #ts="127.0.0.1:$tsl"
4619 #da="test$N $(date) $RANDOM"
4620 #$TRACE $SOCAT UDP-LISTEN:$tsl,$REUSEADDR PIPE &
4621 #sleep 2
4622 #echo "$da" |$TRACE $SOCAT stdin!!stdout UDP:$ts >"$tf"
4623 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
4624 # $ECHO "... test $N succeeded"
4625 # numOK=$((numOK+1))
4626 # listOK="$listOK $N"
4627 #else
4628 # $ECHO "*** test $N $FAILED"
4629 # numFAIL=$((numFAIL+1))
4630 # listFAIL="$listFAIL $N"
4632 #fi ;; # NUMCOND
4633 #N=$((N+1))
4634 #==============================================================================
4635 # TEST 4 - simple echo via new file
4636 #if ! eval $NUMCOND; then :; else
4637 #N=4
4638 #tf="$td/file$N"
4639 #tp="$td/pipe$N"
4640 #da="test$N $(date) $RANDOM"
4641 #rm -f "$tf.tmp"
4642 #echo "$da" |$TRACE $SOCAT - FILE:$tf.tmp,ignoreeof >"$tf"
4643 #if [ $? -eq 0 ] && echo "$da" |diff "$tf" -; then
4644 # $ECHO "... test $N succeeded"
4645 # numOK=$((numOK+1))
4646 # listOK="$listOK $N"
4647 #else
4648 # $ECHO "*** test $N $FAILED"
4649 # numFAIL=$((numFAIL+1))
4650 # listFAIL="$listFAIL $N"
4652 #fi ;; # NUMCOND
4654 #==============================================================================
4656 NAME=TOTALTIMEOUT
4657 case "$TESTS" in
4658 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%listen%*|*%$NAME%*)
4659 TEST="$NAME: socat inactivity timeout"
4660 if ! eval $NUMCOND; then :; else
4661 #set -vx
4662 tf="$td/test$N.stdout"
4663 te="$td/test$N.stderr"
4664 tdiff="$td/test$N.diff"
4665 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4666 newport tcp4 # provide free port number in $PORT
4667 CMD2="$TRACE $SOCAT $opts -T 1 TCP4-LISTEN:$PORT,$REUSEADDR pipe"
4668 CMD="$TRACE $SOCAT $opts - TCP4-CONNECT:$LOCALHOST:$PORT"
4669 printf "test $F_n $TEST... " $N
4670 eval "$CMD2 2>${te}1 &"
4671 pid=$! # background process id
4672 waittcp4port $PORT 1
4673 (echo "$da"; sleep 2; echo X) |$CMD >"$tf" 2>"${te}2"
4674 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4675 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4676 echo "$CMD2 &"
4677 echo "$CMD"
4678 cat "${te}1"
4679 cat "${te}2"
4680 cat "$tdiff"
4681 numFAIL=$((numFAIL+1))
4682 listFAIL="$listFAIL $N"
4683 else
4684 $PRINTF "$OK\n"
4685 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
4686 numOK=$((numOK+1))
4687 listOK="$listOK $N"
4689 kill $pid 2>/dev/null
4690 wait
4691 #set +vx
4692 fi ;; # NUMCOND
4693 esac
4694 N=$((N+1))
4697 NAME=IGNOREEOF+TOTALTIMEOUT
4698 case "$TESTS" in
4699 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%ignoreeof%*|*%$NAME%*)
4700 TEST="$NAME: ignoreeof and inactivity timeout"
4701 if ! eval $NUMCOND; then :; else
4702 #set -vx
4703 SAVEMICS=$MICROS
4704 MICROS=1000000
4705 ti="$td/test$N.file"
4706 tf="$td/test$N.stdout"
4707 te="$td/test$N.stderr"
4708 tdiff="$td/test$N.diff"
4709 da="test$N $(date) $RANDOM"
4710 CMD="$TRACE $SOCAT $opts -T $(reltime 4) -u file:\"$ti\",ignoreeof -"
4711 printf "test $F_n $TEST... " $N
4712 touch "$ti"
4713 $CMD >"$tf" 2>"$te" &
4714 bg=$! # background process id
4715 relsleep 1
4716 echo "$da" >>"$ti"
4717 relsleep 8
4718 echo X >>"$ti"
4719 relsleep 2
4720 kill $bg 2>/dev/null
4721 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4722 $PRINTF "$FAILED (diff):\n"
4723 echo "$CMD &" >&2
4724 cat "$te" >&2
4725 echo "// diff:" >&2
4726 cat "$tdiff" >&2
4727 numFAIL=$((numFAIL+1))
4728 listFAIL="$listFAIL $N"
4729 else
4730 $PRINTF "$OK\n"
4731 if [ -n "$debug" ]; then cat "$te"; fi
4732 numOK=$((numOK+1))
4733 listOK="$listOK $N"
4735 wait
4736 MICROS=$SAVEMICS
4737 fi ;; # NUMCOND, feats
4738 esac
4739 N=$((N+1))
4742 NAME=PROXY2SPACES
4743 case "$TESTS" in
4744 *%$N%*|*%functions%*|*%proxy%*|*%listen%*|*%$NAME%*)
4745 TEST="$NAME: proxy connect accepts status with multiple spaces"
4746 if ! eval $NUMCOND; then :;
4747 elif ! testfeats proxy >/dev/null; then
4748 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
4749 numCANT=$((numCANT+1))
4750 listCANT="$listCANT $N"
4751 else
4752 ts="$td/test$N.sh"
4753 tf="$td/test$N.stdout"
4754 te="$td/test$N.stderr"
4755 tdiff="$td/test$N.diff"
4756 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4757 newport tcp4 # provide free port number in $PORT
4758 #CMD2="$TRACE $SOCAT $opts TCP-L:$PORT,crlf SYSTEM:\"read; read; $ECHO \\\"HTTP/1.0 200 OK\n\\\"; cat\""
4759 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr,crlf EXEC:\"/usr/bin/env bash proxyecho.sh -w 2\""
4760 CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT"
4761 printf "test $F_n $TEST... " $N
4762 eval "$CMD0 2>\"${te}1\" &"
4763 pid=$! # background process id
4764 waittcp4port $PORT 1
4765 echo "$da" |$CMD1 >"$tf" 2>"${te}0"
4766 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
4767 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4768 echo "$CMD0 &"
4769 cat "${te}0" >&2
4770 echo "$CMD1"
4771 cat "${te}1" >&2
4772 echo "diff:"
4773 cat "$tdiff"
4774 numFAIL=$((numFAIL+1))
4775 listFAIL="$listFAIL $N"
4776 else
4777 $PRINTF "$OK\n"
4778 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
4779 if [ "$debug" ]; then cat "${te}0" >&2; fi
4780 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
4781 if [ "$debug" ]; then cat "${te}1" >&2; fi
4782 numOK=$((numOK+1))
4783 listOK="$listOK $N"
4785 kill $pid 2>/dev/null
4786 wait
4787 fi ;; # NUMCOND, feats
4788 esac
4789 N=$((N+1))
4792 NAME=BUG-UNISTDIO
4793 case "$TESTS" in
4794 *%$N%*|*%functions%*|*%$NAME%*)
4795 TEST="$NAME: for bug with address options on both stdin/out in unidirectional mode"
4796 if ! eval $NUMCOND; then :; else
4797 tf="$td/test$N.stdout"
4798 te="$td/test$N.stderr"
4799 ff="$td/test$N.file"
4800 printf "test $F_n $TEST... " $N
4801 >"$ff"
4802 #$TRACE $SOCAT $opts -u /dev/null -,setlk <"$ff" 2>"$te"
4803 CMD="$TRACE $SOCAT $opts -u /dev/null -,setlk"
4804 $CMD <"$ff" 2>"$te"
4805 if [ "$?" -eq 0 ]; then
4806 $PRINTF "$OK\n"
4807 numOK=$((numOK+1))
4808 listOK="$listOK $N"
4809 else
4810 if [ "$UNAME" = "Linux" ]; then
4811 $PRINTF "$FAILED\n"
4812 echo "$CMD"
4813 cat "$te"
4814 numFAIL=$((numFAIL+1))
4815 listFAIL="$listFAIL $N"
4816 else
4817 $PRINTF "${YELLOW}failed (don't care)${NORMAL}\n"
4818 numCANT=$((numCANT+1))
4819 listCANT="$listCANT $N"
4822 fi ;; # NUMCOND
4823 esac
4824 N=$((N+1))
4827 NAME=SINGLEEXECOUTSOCKETPAIR
4828 case "$TESTS" in
4829 *%$N%*|*%functions%*|*%$NAME%*)
4830 TEST="$NAME: inheritance of stdout to single exec with socketpair"
4831 testecho "$N" "$TEST" "-!!exec:cat" "" "$opts" 1
4832 esac
4833 N=$((N+1))
4835 NAME=SINGLEEXECOUTPIPE
4836 case "$TESTS" in
4837 *%$N%*|*%functions%*|*%$NAME%*)
4838 TEST="$NAME: inheritance of stdout to single exec with pipe"
4839 testecho "$N" "$TEST" "-!!exec:cat,pipes" "" "$opts" 1
4840 esac
4841 N=$((N+1))
4843 NAME=SINGLEEXECOUTPTY
4844 case "$TESTS" in
4845 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
4846 TEST="$NAME: inheritance of stdout to single exec with pty"
4847 if ! eval $NUMCOND; then :;
4848 elif ! testfeats pty >/dev/null; then
4849 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
4850 numCANT=$((numCANT+1))
4851 listCANT="$listCANT $N"
4852 else
4853 testecho "$N" "$TEST" "-!!exec:cat,pty,raw" "" "$opts" 1
4854 fi ;; # NUMCOND, feats
4855 esac
4856 N=$((N+1))
4858 NAME=SINGLEEXECINSOCKETPAIR
4859 case "$TESTS" in
4860 *%$N%*|*%functions%*|*%$NAME%*)
4861 TEST="$NAME: inheritance of stdin to single exec with socketpair"
4862 testecho "$N" "$TEST" "exec:cat!!-" "" "$opts"
4863 esac
4864 N=$((N+1))
4866 NAME=SINGLEEXECINPIPE
4867 case "$TESTS" in
4868 *%$N%*|*%functions%*|*%$NAME%*)
4869 TEST="$NAME: inheritance of stdin to single exec with pipe"
4870 testecho "$N" "$TEST" "exec:cat,pipes!!-" "" "$opts"
4871 esac
4872 N=$((N+1))
4874 NAME=SINGLEEXECINPTYDELAY
4875 case "$TESTS" in
4876 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
4877 TEST="$NAME: inheritance of stdin to single exec with pty, with delay"
4878 if ! eval $NUMCOND; then :;
4879 elif ! testfeats pty >/dev/null; then
4880 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
4881 numCANT=$((numCANT+1))
4882 listCANT="$listCANT $N"
4883 else
4884 testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" $MISCDELAY
4885 fi ;; # NUMCOND, feats
4886 esac
4887 N=$((N+1))
4889 NAME=SINGLEEXECINPTY
4890 case "$TESTS" in
4891 *%$N%*|*%functions%*|*%pty%*|*%$NAME%*)
4892 TEST="$NAME: inheritance of stdin to single exec with pty"
4893 if ! eval $NUMCOND; then :;
4894 elif ! testfeats pty >/dev/null; then
4895 $PRINTF "test $F_n $TEST... ${YELLOW}PTY not available${NORMAL}\n" $N
4896 numCANT=$((numCANT+1))
4897 listCANT="$listCANT $N"
4898 else
4899 # T value needed (only) by AIX
4900 testecho "$N" "$TEST" "exec:cat,pty,raw!!-" "" "$opts" 0.1
4901 fi ;; # NUMCOND, feats
4902 esac
4903 N=$((N+1))
4906 NAME=READLINE
4907 #set -vx
4908 case "$TESTS" in
4909 *%$N%*|*%functions%*|*%pty%*|*%readline%*|*%sigint%*|*%$NAME%*)
4910 TEST="$NAME: readline with password and sigint"
4911 if ! eval $NUMCOND; then :;
4912 elif ! feat=$(testfeats readline pty); then
4913 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
4914 numCANT=$((numCANT+1))
4915 listCANT="$listCANT $N"
4916 else
4917 SAVETERM="$TERM"; TERM= # 'cause console might print controls even in raw
4918 SAVEMICS=$MICROS
4919 #MICROS=2000000
4920 ts="$td/test$N.sh"
4921 to="$td/test$N.stdout"
4922 tpi="$td/test$N.inpipe"
4923 tpo="$td/test$N.outpipe"
4924 te="$td/test$N.stderr"
4925 tr="$td/test$N.ref"
4926 tdiff="$td/test$N.diff"
4927 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
4928 # the feature that we really want to test is in the readline.sh script:
4929 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"
4930 #echo "$CMD" >"$ts"
4931 #chmod a+x "$ts"
4932 printf "test $F_n $TEST... " $N
4933 rm -f "$tpi" "$tpo"
4934 mkfifo "$tpi"
4935 touch "$tpo"
4937 # during development of this test, the following command line succeeded:
4938 # ECHO="echo -e" SOCAT=./socat
4939 # (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
4941 # the following cat, in case of socat failure, reads the pipe to prevent below writer from hanging
4942 PATH=${SOCAT%socat}:$PATH eval "$CMD 2>$te || cat $tpi >/dev/null &"
4943 pid=$! # background process id
4944 relsleep 1
4947 relsleep 3
4948 $ECHO "user\n\c"
4949 relsleep 1
4950 $ECHO "password\c"
4951 relsleep 1
4952 $ECHO "\n\c"
4953 relsleep 1
4954 $ECHO "test 1\n\c"
4955 relsleep 1
4956 $ECHO "\003\c"
4957 relsleep 1
4958 $ECHO "test 2\n\c"
4959 relsleep 1
4960 $ECHO "exit\n\c"
4961 relsleep 1
4962 ) >"$tpi"
4964 cat >$tr <<EOF
4965 readline feature test program
4966 Authentication required
4967 Username: user
4968 Password:
4969 prog> test 1
4970 executing test 1
4971 prog> ./readline-test.sh got SIGINT
4972 test 2
4973 executing test 2
4974 prog> exit
4977 #0 if ! sed 's/.*\r//g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then
4978 #0 if ! sed 's/.*'"$($ECHO '\r\c')"'/</g' "$tpo" |diff -q "$tr" - >/dev/null 2>&1; then
4979 kill $pid 2>/dev/null # necc on OpenBSD
4980 wait
4981 if ! tr "$($ECHO '\r \c')" "% " <$tpo |sed 's/%$//g' |sed 's/.*%//g' |diff "$tr" - >"$tdiff" 2>&1; then
4982 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
4983 echo "$CMD" 2>&1
4984 cat "$te" 2>&1
4985 echo diff: 2>&1
4986 cat "$tdiff" 2>&1
4987 numFAIL=$((numFAIL+1))
4988 listFAIL="$listFAIL $N"
4989 else
4990 $PRINTF "$OK\n"
4991 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
4992 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
4993 numOK=$((numOK+1))
4994 listOK="$listOK $N"
4996 wait
4997 MICROS=$SAVEMICS
4998 TERM="$SAVETERM"
4999 fi ;; # NUMCOND, feats
5000 esac
5001 N=$((N+1))
5004 NAME=GENDERCHANGER
5005 case "$TESTS" in
5006 *%$N%*|*%functions%*|*%listen%*|*%$NAME%*)
5007 TEST="$NAME: TCP4 \"gender changer\""
5008 if ! eval $NUMCOND; then :; else
5009 tf="$td/test$N.stdout"
5010 te="$td/test$N.stderr"
5011 tdiff="$td/test$N.diff"
5012 da="test$N $(date) $RANDOM"
5013 newport tcp4; PORT1=$PORT
5014 newport tcp4; PORT2=$PORT
5015 newport tcp4; PORT3=$PORT
5016 # this is the server in the protected network that we want to reach
5017 CMD1="$TRACE $SOCAT -lpserver $opts TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST ECHO"
5018 # this is the double client in the protected network
5019 CMD2="$TRACE $SOCAT -lp2client $opts TCP4:$LOCALHOST:$PORT2,retry=10,interval=1 TCP4:$LOCALHOST:$PORT1"
5020 # this is the double server in the outside network
5021 CMD3="$TRACE $SOCAT -lp2server $opts TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST"
5022 # this is the outside client that wants to use the protected server
5023 CMD4="$TRACE $SOCAT -lpclient $opts -t1 - tcp4:$LOCALHOST:$PORT3"
5024 printf "test $F_n $TEST... " $N
5025 eval "$CMD1 2>${te}1 &"
5026 pid1=$!
5027 eval "$CMD2 2>${te}2 &"
5028 pid2=$!
5029 eval "$CMD3 2>${te}3 &"
5030 pid3=$!
5031 waittcp4port $PORT1 1 &&
5032 waittcp4port $PORT3 1
5033 sleep 1
5034 echo "$da" |$CMD4 >$tf 2>"${te}4"
5035 kill $pid1 $pid2 $pid3 $pid4 2>/dev/null
5036 wait
5037 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
5038 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
5039 echo "$CMD1 &"
5040 cat "${te}1" >&2
5041 echo "$CMD2 &"
5042 cat "${te}2" >&2
5043 echo "$CMD3 &"
5044 cat "${te}3" >&2
5045 echo "$CMD4"
5046 cat "${te}4" >&2
5047 echo diff: >&2
5048 cat "$tdiff"
5049 numFAIL=$((numFAIL+1))
5050 listFAIL="$listFAIL $N"
5051 else
5052 $PRINTF "$OK\n"
5053 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
5054 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
5055 if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
5056 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
5057 if [ "$VERBOSE" ]; then echo "$CMD3 &"; fi
5058 if [ "$DEBUG" ]; then cat "${te}3" >&2; fi
5059 if [ "$VERBOSE" ]; then echo "$CMD4"; fi
5060 if [ "$DEBUG" ]; then cat "${te}4" >&2; fi
5061 numOK=$((numOK+1))
5062 listOK="$listOK $N"
5064 fi ;; # NUMCOND
5065 esac
5066 N=$((N+1))
5069 NAME=OUTBOUNDIN
5070 case "$TESTS" in
5071 *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%fork%*|*%listen%*|*%$NAME%*)
5072 TEST="$NAME: gender changer via SSL through HTTP proxy, oneshot"
5073 if ! eval $NUMCOND; then :;
5074 elif ! feat=$(testfeats openssl proxy); then
5075 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5076 numCANT=$((numCANT+1))
5077 listCANT="$listCANT $N"
5078 else
5079 gentestcert testsrv
5080 gentestcert testcli
5081 tf="$td/test$N.stdout"
5082 te="$td/test$N.stderr"
5083 tdiff="$td/test$N.diff"
5084 da="test$N $(date) $RANDOM"
5085 newport tcp4; PORT1=$PORT
5086 newport tcp4; PORT2=$PORT
5087 newport tcp4; PORT3=$PORT
5088 newport tcp4; PORT4=$PORT
5089 newport tcp4; PORT5=$PORT
5090 # this is the server in the protected network that we want to reach
5091 CMD1="$TRACE $SOCAT $opts -lpserver TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST ECHO"
5092 # this is the proxy in the protected network that provides a way out
5093 CMD2="$TRACE $SOCAT $opts -lpproxy TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
5094 # this is our proxy connect wrapper in the protected network
5095 CMD3="$TRACE $SOCAT $opts -lpwrapper TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve"
5096 # this is our double client in the protected network using SSL
5097 #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"
5098 CMD4="$TRACE $SOCAT $opts -lp2client SSL:$LOCALHOST:$PORT3,pf=ip4,cert=testcli.pem,cafile=testsrv.crt,$SOCAT_EGD TCP4:$LOCALHOST:$PORT1"
5099 # this is the double server in the outside network
5100 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"
5101 # this is the outside client that wants to use the protected server
5102 CMD6="$TRACE $SOCAT $opts -lpclient -t5 - tcp4:$LOCALHOST:$PORT5"
5103 printf "test $F_n $TEST... " $N
5104 eval "$CMD1 2>${te}1 &"
5105 pid1=$!
5106 eval "$CMD2 2>${te}2 &"
5107 pid2=$!
5108 eval "$CMD3 2>${te}3 &"
5109 pid3=$!
5110 waittcp4port $PORT1 1 || $PRINTF "$FAILED: port $PORT1\n" >&2 </dev/null
5111 waittcp4port $PORT2 1 || $PRINTF "$FAILED: port $PORT2\n" >&2 </dev/null
5112 waittcp4port $PORT3 1 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null
5113 eval "$CMD5 2>${te}5 &"
5114 pid5=$!
5115 waittcp4port $PORT5 1 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null
5116 echo "$da" |$CMD6 >$tf 2>"${te}6" &
5117 pid6=$!
5118 waittcp4port $PORT4 1 || $PRINTF "$FAILED: port $PORT4\n" >&2 </dev/null
5119 eval "$CMD4 2>${te}4 &"
5120 pid4=$!
5121 wait $pid6
5122 if ! (echo "$da"; sleep 2) |diff - "$tf" >"$tdiff"; then
5123 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
5124 echo "$CMD1 &"
5125 cat "${te}1"
5126 echo "$CMD2 &"
5127 cat "${te}2"
5128 echo "$CMD3 &"
5129 cat "${te}3"
5130 echo "$CMD5 &"
5131 cat "${te}5"
5132 echo "$CMD6"
5133 cat "${te}6"
5134 echo "$CMD4 &"
5135 cat "${te}4"
5136 cat "$tdiff"
5137 numFAIL=$((numFAIL+1))
5138 listFAIL="$listFAIL $N"
5139 else
5140 $PRINTF "$OK\n"
5141 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" "${te}6"; fi
5142 numOK=$((numOK+1))
5143 listOK="$listOK $N"
5145 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
5146 wait
5147 fi ;; # NUMCOND, feats
5148 esac
5149 N=$((N+1))
5152 # test the TCP gender changer with almost production requirements: a double
5153 # client repeatedly tries to connect to a double server via SSL through an HTTP
5154 # proxy. the double servers SSL port becomes active for one connection only
5155 # after a (real) client has connected to its TCP port. when the double client
5156 # succeeded to establish an SSL connection, it connects with its second client
5157 # side to the specified (protected) server. all three consecutive connections
5158 # must function for full success of this test.
5159 #PORT=$((RANDOM+16184))
5161 NAME=INTRANETRIPPER
5162 case "$TESTS" in
5163 *%$N%*|*%functions%*|*%openssl%*|*%proxy%*|*%listen%*|*%fork%*|*%$NAME%*)
5164 TEST="$NAME: gender changer via SSL through HTTP proxy, daemons"
5165 if ! eval $NUMCOND; then :;
5166 elif ! feat=$(testfeats openssl proxy); then
5167 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
5168 numCANT=$((numCANT+1))
5169 listCANT="$listCANT $N"
5170 else
5171 gentestcert testsrv
5172 gentestcert testcli
5173 tf="$td/test$N.stdout"
5174 te="$td/test$N.stderr"
5175 tdiff="$td/test$N.diff"
5176 da1="test$N.1 $(date) $RANDOM"
5177 da2="test$N.2 $(date) $RANDOM"
5178 da3="test$N.3 $(date) $RANDOM"
5179 newport tcp4; PORT1=$PORT
5180 newport tcp4; PORT2=$PORT
5181 newport tcp4; PORT3=$PORT
5182 newport tcp4; PORT4=$PORT
5183 newport tcp4; PORT5=$PORT
5184 # this is the server in the protected network that we want to reach
5185 CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 10) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO"
5186 # this is the proxy in the protected network that provides a way out
5187 # note: the proxy.sh script starts one or two more socat processes without
5188 # setting the program name
5189 CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 10) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
5190 # this is our proxy connect wrapper in the protected network
5191 CMD3="$TRACE $SOCAT $opts -lpwrapper -t$(reltime 30) TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve"
5192 # this is our double client in the protected network using SSL
5193 CMD4="$TRACE $SOCAT $opts -lp2client -t$(reltime 30) SSL:$LOCALHOST:$PORT3,retry=10,interval=$(reltime 10),cert=testcli.pem,cafile=testsrv.crt,verify,fork,$SOCAT_EGD TCP4:$LOCALHOST:$PORT1,forever,interval=$(reltime 1)"
5194 # This is the double server in the outside network; accept-timeout because it likes to remain hanging on BSD
5195 CMD5="$TRACE $SOCAT $opts -lp2server -t$(reltime 40) TCP4-L:$PORT5,reuseaddr,bind=$LOCALHOST,backlog=3,accept-timeout=4,fork SSL-L:$PORT4,pf=ip4,reuseaddr,bind=$LOCALHOST,$SOCAT_EGD,cert=testsrv.pem,cafile=testcli.crt,retry=20,interval=$(reltime 5)"
5196 # this is the outside client that wants to use the protected server
5197 CMD6="$TRACE $SOCAT $opts -lpclient -t$(reltime 60) - TCP4:$LOCALHOST:$PORT5,retry=3,interval=$(reltime 10)"
5198 printf "test $F_n $TEST... " $N
5199 # start the intranet infrastructure
5200 eval "$CMD1 2>\"${te}1\" &"
5201 pid1=$!
5202 eval "$CMD2 2>\"${te}2\" &"
5203 pid2=$!
5204 waittcp4port $PORT1 1 50 || $PRINTF "$FAILED: port $PORT1\n" >&2 </dev/null
5205 waittcp4port $PORT2 1 50 || $PRINTF "$FAILED: port $PORT2\n" >&2 </dev/null
5206 # initiate our internal measures
5207 eval "$CMD3 2>\"${te}3\" &"
5208 pid3=$!
5209 eval "$CMD4 2>\"${te}4\" &"
5210 pid4=$!
5211 waittcp4port $PORT3 1 50 || $PRINTF "$FAILED: port $PORT3\n" >&2 </dev/null
5212 # now we start the external daemon
5213 eval "$CMD5 2>\"${te}5\" &"
5214 pid5=$!
5215 waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $5PORT\n" >&2 </dev/null
5216 # and this is the outside client:
5217 echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" &
5218 pid6_1=$!
5219 echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" &
5220 pid6_2=$!
5221 echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" &
5222 pid6_3=$!
5223 wait $pid6_1 $pid6_2 $pid6_3
5224 kill $pid1 $pid2 $pid3 $pid4 $pid5 $(childpids $pid5) 2>/dev/null
5225 # (On BSDs a child of pid5 loves to hang)
5227 (echo "$da1"; relsleep 2) |diff - "${tf}_1" >"${tdiff}1"
5228 (echo "$da2"; relsleep 2) |diff - "${tf}_2" >"${tdiff}2"
5229 (echo "$da3"; relsleep 2) |diff - "${tf}_3" >"${tdiff}3"
5230 if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then
5231 # FAILED only when none of the three transfers succeeded
5232 if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then
5233 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
5234 echo "$CMD1 &"
5235 cat "${te}1"
5236 echo "$CMD2 &"
5237 cat "${te}2"
5238 echo "$CMD3 &"
5239 cat "${te}3"
5240 echo "$CMD4 &"
5241 cat "${te}4"
5242 echo "$CMD5 &"
5243 cat "${te}5"
5244 echo "$CMD6 &"
5245 cat "${te}6_1"
5246 cat "${tdiff}1"
5247 echo "$CMD6 &"
5248 cat "${te}6_2"
5249 cat "${tdiff}2"
5250 echo "$CMD6 &"
5251 cat "${te}6_3"
5252 cat "${tdiff}3"
5253 numFAIL=$((numFAIL+1))
5254 listFAIL="$listFAIL $N"
5255 else
5256 $PRINTF "$OK ${YELLOW}(partial failure)${NORMAL}\n"
5257 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi
5258 numOK=$((numOK+1))
5259 listOK="$listOK $N"
5261 else
5262 $PRINTF "$OK\n"
5263 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3" "${te}4" "${te}5" ${te}6*; fi
5264 numOK=$((numOK+1))
5265 listOK="$listOK $N"
5267 kill $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
5268 wait
5269 fi ;; # NUMCOND, feats
5270 esac
5271 N=$((N+1))
5274 # let us test the security features with -s, retry, and fork
5275 # method: first test without security feature if it works
5276 # then try with security feature, must fail
5278 # test the security features of a server address
5279 testserversec () {
5280 local N="$1"
5281 local title="$2"
5282 local opts="$3"
5283 local arg1="$4" # the server address
5284 local secopt0="$5" # option without security for server, mostly empty
5285 local secopt1="$6" # the security option for server, to be tested
5286 local arg2="$7" # the client address
5287 local ipvers="$8" # IP version, for check of listen port
5288 local proto="$9" # protocol, for check of listen port
5289 local port="${10}" # start client when this port is listening
5290 local expect="${11}" # expected behaviour of client: 0..empty output; -1..error; *: any of these
5291 local T="${12}"; [ -z "$T" ] && T=0
5292 local tf="$td/test$N.stdout"
5293 local te="$td/test$N.stderr"
5294 local tdiff1="$td/test$N.diff1"
5295 local tdiff2="$td/test$N.diff2"
5296 local da="test$N.1 $(date) $RANDOM"
5297 local stat result
5299 $PRINTF "test $F_n %s... " $N "$title"
5300 # first: without security
5301 # start server
5302 $TRACE $SOCAT $opts "$arg1,$secopt0" echo 2>"${te}1" &
5303 spid=$!
5304 if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then
5305 kill $spid 2>/dev/null
5306 $PRINTF "$NO_RESULT (ph.1 server not working):\n"
5307 echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
5308 cat "${te}1"
5309 numCANT=$((numCANT+1))
5310 listCANT="$listCANT $N"
5311 wait; return
5313 # now use client
5314 (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}2"
5315 stat="$?"
5316 kill $spid 2>/dev/null
5317 #killall $TRACE $SOCAT 2>/dev/null
5318 if [ "$stat" != 0 ]; then
5319 $PRINTF "$NO_RESULT (ph.1 function fails): $TRACE $SOCAT:\n"
5320 echo "$TRACE $SOCAT $opts \"$arg1,$secopt0\" echo &"
5321 cat "${te}1"
5322 echo "$TRACE $SOCAT $opts - \"$arg2\""
5323 cat "${te}2"
5324 numCANT=$((numCANT+1))
5325 listCANT="$listCANT $N"
5326 wait; return
5327 elif echo "$da" |diff - "$tf" >"$tdiff1" 2>&1; then
5328 : # function without security is ok, go on
5329 else
5330 $PRINTF "$NO_RESULT (ph.1 function fails): diff:\n"
5331 echo "$TRACE $SOCAT $opts $arg1,$secopt0 echo &"
5332 cat "${te}1"
5333 echo "$TRACE $SOCAT $opts - $arg2"
5334 cat "${te}2"
5335 cat "$tdiff1"
5336 numCANT=$((numCANT+1))
5337 listCANT="$listCANT $N"
5338 wait; return
5341 # then: with security
5342 if [ "$port" ] && ! wait${proto}${ipvers}port $port 0; then
5343 $PRINTF "$NO_RESULT (ph.1 port remains in use)\n"
5344 numCANT=$((numCANT+1))
5345 listCANT="$listCANT $N"
5346 wait; return
5348 wait
5350 #set -vx
5351 # assemble address w/ security option; on dual, take read part:
5352 case "$arg1" in
5353 *!!*) arg="${arg1%!!*},$secopt1!!${arg1#*!!}" ;;
5354 *) arg="$arg1,$secopt1" ;;
5355 esac
5356 # start server
5357 # use -s to make sure that it fails due to a sec violation, not some other failure
5358 CMD3="$TRACE $SOCAT $opts -s $arg echo"
5359 $CMD3 2>"${te}3" &
5360 spid=$!
5361 if [ "$port" ] && ! wait${proto}${ipvers}port $port 1; then
5362 kill $spid 2>/dev/null
5363 $PRINTF "$NO_RESULT (ph.2 server not working)\n"
5364 wait
5365 echo "$CMD3"
5366 cat "${te}3"
5367 numCANT=$((numCANT+1))
5368 listCANT="$listCANT $N"
5369 return
5371 # now use client
5372 da="test$N.2 $(date) $RANDOM"
5373 (echo "$da"; sleep $T) |$TRACE $SOCAT $opts - "$arg2" >"$tf" 2>"${te}4"
5374 stat=$?
5375 kill $spid 2>/dev/null
5376 #set +vx
5377 #killall $TRACE $SOCAT 2>/dev/null
5378 if [ "$stat" != 0 ]; then
5379 result=-1; # socat had error
5380 elif [ ! -s "$tf" ]; then
5381 result=0; # empty output
5382 elif echo "$da" |diff - "$tf" >"$tdiff2" 2>&1; then
5383 result=1; # output is copy of input
5384 else
5385 result=2; # output differs from input
5387 if [ "$expect" != '1' -a "$result" -eq 1 ]; then
5388 $PRINTF "$FAILED: SECURITY BROKEN\n"
5389 echo "$TRACE $SOCAT $opts $arg echo"
5390 cat "${te}3"
5391 echo "$TRACE $SOCAT $opts - $arg2"
5392 cat "${te}4"
5393 cat "$tdiff2"
5394 numFAIL=$((numFAIL+1))
5395 listFAIL="$listFAIL $N"
5396 elif [ "X$expect" != 'X*' -a X$result != X$expect ]; then
5397 case X$result in
5398 X-1) $PRINTF "$NO_RESULT (ph.2 client error): $TRACE $SOCAT:\n"
5399 echo "$TRACE $SOCAT $opts $arg echo"
5400 cat "${te}3"
5401 echo "$TRACE $SOCAT $opts - $arg2"
5402 cat "${te}4"
5403 numCANT=$((numCANT+1))
5404 listCANT="$listCANT $N"
5406 X0) $PRINTF "$NO_RESULT (ph.2 diff failed): diff:\n"
5407 echo "$TRACE $SOCAT $opts $arg echo"
5408 cat "${te}3"
5409 echo "$TRACE $SOCAT $opts - $arg2"
5410 cat "${te}4"
5411 cat "$tdiff2"
5412 numCANT=$((numCANT+1))
5413 listCANT="$listCANT $N"
5415 X1) $PRINTF "$FAILED: SECURITY BROKEN\n"
5416 echo "$TRACE $SOCAT $opts $arg echo"
5417 cat "${te}3"
5418 echo "$TRACE $SOCAT $opts - $arg2"
5419 cat "${te}4"
5420 cat "$tdiff2"
5421 numFAIL=$((numFAIL+1))
5422 listFAIL="$listFAIL $N"
5424 X2) $PRINTF "$FAILED: diff:\n"
5425 echo "$TRACE $SOCAT $opts $arg echo"
5426 cat "${te}3"
5427 echo "$TRACE $SOCAT $opts - $arg2"
5428 cat "${te}4"
5429 cat "$tdiff2"
5430 numFAIL=$((numFAIL+1))
5431 listFAIL="$listFAIL $N"
5433 esac
5434 else
5435 $PRINTF "$OK\n"
5436 [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts $arg echo"
5437 [ "$debug" ] && cat ${te}3
5438 [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts - $arg2"
5439 [ "$debug" ] && cat ${te}4
5440 numOK=$((numOK+1))
5441 listOK="$listOK $N"
5443 wait
5444 #set +vx
5448 NAME=TCP4RANGEBITS
5449 case "$TESTS" in
5450 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5451 TEST="$NAME: security of TCP4-L with RANGE option"
5452 if ! eval $NUMCOND; then :;
5453 elif [ -z "$SECONDADDR" ]; then
5454 # we need access to a second addresses
5455 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
5456 numCANT=$((numCANT+1))
5457 listCANT="$listCANT $N"
5458 else
5459 newport tcp4 # provide free port number in $PORT
5460 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
5461 fi ;; # $SECONDADDR, NUMCOND
5462 esac
5463 N=$((N+1))
5465 NAME=TCP4RANGEMASK
5466 case "$TESTS" in
5467 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5468 TEST="$NAME: security of TCP4-L with RANGE option"
5469 if ! eval $NUMCOND; then :;
5470 elif [ -z "$SECONDADDR" ]; then
5471 # we need access to a second addresses
5472 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
5473 numCANT=$((numCANT+1))
5474 listCANT="$listCANT $N"
5475 else
5476 newport tcp4 # provide free port number in $PORT
5477 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
5478 fi ;; # $SECONDADDR, NUMCOND
5479 esac
5480 N=$((N+1))
5482 # like TCP4RANGEMASK, but the "bad" address is within the same class A network
5483 NAME=TCP4RANGEMASKHAIRY
5484 case "$TESTS" in
5485 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5486 TEST="$NAME: security of TCP4-L with RANGE option"
5487 if ! eval $NUMCOND; then :; else
5488 newport tcp4 # provide free port number in $PORT
5489 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
5490 fi ;; # Linux, NUMCOND
5491 esac
5492 N=$((N+1))
5495 NAME=TCP4SOURCEPORT
5496 case "$TESTS" in
5497 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
5498 TEST="$NAME: security of TCP4-L with SOURCEPORT option"
5499 if ! eval $NUMCOND; then :; else
5500 newport tcp4 # provide free port number in $PORT
5501 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
5502 fi ;; # NUMCOND
5503 esac
5504 N=$((N+1))
5506 NAME=TCP4LOWPORT
5507 case "$TESTS" in
5508 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5509 TEST="$NAME: security of TCP4-L with LOWPORT option"
5510 if ! eval $NUMCOND; then :; else
5511 newport tcp4 # provide free port number in $PORT
5512 testserversec "$N" "$TEST" "$opts" "TCP4-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP4:127.0.0.1:$PORT" 4 tcp $PORT 0
5513 fi ;; # NUMCOND
5514 esac
5515 N=$((N+1))
5517 NAME=TCP4WRAPPERS_ADDR
5518 case "$TESTS" in
5519 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5520 TEST="$NAME: security of TCP4-L with TCPWRAP option"
5521 if ! eval $NUMCOND; then :;
5522 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
5523 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5524 numCANT=$((numCANT+1))
5525 listCANT="$listCANT $N"
5526 else
5527 ha="$td/hosts.allow"
5528 hd="$td/hosts.deny"
5529 $ECHO "socat: $SECONDADDR" >"$ha"
5530 $ECHO "ALL: ALL" >"$hd"
5531 newport tcp4 # provide free port number in $PORT
5532 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
5533 fi ;; # NUMCOND, feats
5534 esac
5535 N=$((N+1))
5537 NAME=TCP4WRAPPERS_NAME
5538 case "$TESTS" in
5539 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5540 TEST="$NAME: security of TCP4-L with TCPWRAP option"
5541 if ! eval $NUMCOND; then :;
5542 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
5543 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5544 numCANT=$((numCANT+1))
5545 listCANT="$listCANT $N"
5546 else
5547 ha="$td/hosts.allow"
5548 hd="$td/hosts.deny"
5549 $ECHO "socat: $LOCALHOST" >"$ha"
5550 $ECHO "ALL: ALL" >"$hd"
5551 newport tcp4 # provide free port number in $PORT
5552 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
5553 fi ;; # NUMCOND, feats
5554 esac
5555 N=$((N+1))
5558 NAME=TCP6RANGE
5559 case "$TESTS" in
5560 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5561 TEST="$NAME: security of TCP6-L with RANGE option"
5562 if ! eval $NUMCOND; then :;
5563 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5564 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5565 numCANT=$((numCANT+1))
5566 listCANT="$listCANT $N"
5567 else
5568 newport tcp6 # provide free port number in $PORT
5569 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "range=[::2]/128" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5570 fi ;; # NUMCOND, feats
5571 esac
5572 N=$((N+1))
5574 NAME=TCP6SOURCEPORT
5575 case "$TESTS" in
5576 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%sourceport%*|*%listen%|*%fork%**|*%$NAME%*)
5577 TEST="$NAME: security of TCP6-L with SOURCEPORT option"
5578 if ! eval $NUMCOND; then :;
5579 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5580 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5581 numCANT=$((numCANT+1))
5582 listCANT="$listCANT $N"
5583 else
5584 newport tcp6 # provide free port number in $PORT
5585 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "sp=$PORT" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5586 fi ;; # NUMCOND, feats
5587 esac
5588 N=$((N+1))
5590 NAME=TCP6LOWPORT
5591 case "$TESTS" in
5592 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5593 TEST="$NAME: security of TCP6-L with LOWPORT option"
5594 if ! eval $NUMCOND; then :;
5595 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5596 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5597 numCANT=$((numCANT+1))
5598 listCANT="$listCANT $N"
5599 else
5600 newport tcp6 # provide free port number in $PORT
5601 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "lowport" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5602 fi ;; # NUMCOND, feats
5603 esac
5604 N=$((N+1))
5606 NAME=TCP6TCPWRAP
5607 case "$TESTS" in
5608 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5609 TEST="$NAME: security of TCP6-L with TCPWRAP option"
5610 if ! eval $NUMCOND; then :;
5611 elif ! feat=$(testfeats tcp ip6 libwrap && runstcp6); then
5612 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5613 numCANT=$((numCANT+1))
5614 listCANT="$listCANT $N"
5615 else
5616 ha="$td/hosts.allow"
5617 hd="$td/hosts.deny"
5618 $ECHO "socat: [::2]" >"$ha"
5619 $ECHO "ALL: ALL" >"$hd"
5620 newport tcp6 # provide free port number in $PORT
5621 testserversec "$N" "$TEST" "$opts" "TCP6-L:$PORT,reuseaddr,fork,retry=1" "" "hosts-allow=$ha,hosts-deny=$hd" "TCP6:[::1]:$PORT" 6 tcp $PORT 0
5622 fi ;; # NUMCOND, feats
5623 esac
5624 N=$((N+1))
5627 NAME=UDP4RANGE
5628 case "$TESTS" in
5629 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5630 TEST="$NAME: security of UDP4-L with RANGE option"
5631 if ! eval $NUMCOND; then :; else
5632 newport udp4 # provide free port number in $PORT
5633 #testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5634 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5635 fi ;; # NUMCOND
5636 esac
5637 N=$((N+1))
5639 NAME=UDP4SOURCEPORT
5640 case "$TESTS" in
5641 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%listen%*|*%$NAME%*)
5642 TEST="$NAME: security of UDP4-L with SOURCEPORT option"
5643 if ! eval $NUMCOND; then :; else
5644 newport udp4 # provide free port number in $PORT
5645 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5646 fi ;; # NUMCOND
5647 esac
5648 N=$((N+1))
5650 NAME=UDP4LOWPORT
5651 case "$TESTS" in
5652 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%listen%*|*%$NAME%*)
5653 TEST="$NAME: security of UDP4-L with LOWPORT option"
5654 if ! eval $NUMCOND; then :; else
5655 newport udp4 # provide free port number in $PORT
5656 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "lowport" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5657 fi ;; # NUMCOND
5658 esac
5659 N=$((N+1))
5661 NAME=UDP4TCPWRAP
5662 case "$TESTS" in
5663 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
5664 TEST="$NAME: security of UDP4-L with TCPWRAP option"
5665 if ! eval $NUMCOND; then :;
5666 elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then
5667 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5668 numCANT=$((numCANT+1))
5669 listCANT="$listCANT $N"
5670 else
5671 ha="$td/hosts.allow"
5672 hd="$td/hosts.deny"
5673 $ECHO "socat: $SECONDADDR" >"$ha"
5674 $ECHO "ALL: ALL" >"$hd"
5675 newport udp4 # provide free port number in $PORT
5676 testserversec "$N" "$TEST" "$opts" "UDP4-L:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP4:127.0.0.1:$PORT" 4 udp $PORT 0
5677 fi ;; # NUMCOND, feats
5678 esac
5679 N=$((N+1))
5682 NAME=UDP6RANGE
5683 case "$TESTS" in
5684 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5685 TEST="$NAME: security of UDP6-L with RANGE option"
5686 if ! eval $NUMCOND; then :;
5687 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5688 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5689 numCANT=$((numCANT+1))
5690 listCANT="$listCANT $N"
5691 else
5692 newport udp6 # provide free port number in $PORT
5693 #testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5694 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "range=[::2]/128" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5695 fi ;; # NUMCOND, feats
5696 esac
5697 N=$((N+1))
5699 NAME=UDP6SOURCEPORT
5700 case "$TESTS" in
5701 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%listen%*|*%$NAME%*)
5702 TEST="$NAME: security of UDP6-L with SOURCEPORT option"
5703 if ! eval $NUMCOND; then :;
5704 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
5705 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
5706 numCANT=$((numCANT+1))
5707 listCANT="$listCANT $N"
5708 else
5709 newport udp6 # provide free port number in $PORT
5710 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "sp=$PORT" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5711 fi ;; # NUMCOND, feats
5712 esac
5713 N=$((N+1))
5715 NAME=UDP6LOWPORT
5716 case "$TESTS" in
5717 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%listen%*|*%$NAME%*)
5718 TEST="$NAME: security of UDP6-L with LOWPORT option"
5719 if ! eval $NUMCOND; then :;
5720 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
5721 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
5722 numCANT=$((numCANT+1))
5723 listCANT="$listCANT $N"
5724 else
5725 newport udp6 # provide free port number in $PORT
5726 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5727 fi ;; # NUMCOND, feats
5728 esac
5729 N=$((N+1))
5731 NAME=UDP6TCPWRAP
5732 case "$TESTS" in
5733 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
5734 TEST="$NAME: security of UDP6-L with TCPWRAP option"
5735 if ! eval $NUMCOND; then :;
5736 elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then
5737 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5738 numCANT=$((numCANT+1))
5739 listCANT="$listCANT $N"
5740 else
5741 ha="$td/hosts.allow"
5742 hd="$td/hosts.deny"
5743 $ECHO "socat: [::2]" >"$ha"
5744 $ECHO "ALL: ALL" >"$hd"
5745 newport udp6 # provide free port number in $PORT
5746 testserversec "$N" "$TEST" "$opts" "UDP6-L:$PORT,reuseaddr" "" "lowport" "UDP6:[::1]:$PORT" 6 udp $PORT 0
5747 fi ;; # NUMCOND, feats
5748 esac
5749 N=$((N+1))
5751 NAME=OPENSSLTCP4_RANGE
5752 case "$TESTS" in
5753 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5754 TEST="$NAME: security of SSL-L over TCP/IPv4 with RANGE option"
5755 if ! eval $NUMCOND; then :;
5756 elif ! testfeats openssl >/dev/null; then
5757 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5758 numCANT=$((numCANT+1))
5759 listCANT="$listCANT $N"
5760 else
5761 gentestcert testsrv
5762 newport tcp4 # provide free port number in $PORT
5763 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
5764 fi ;; # NUMCOND, feats
5765 esac
5766 N=$((N+1))
5768 NAME=OPENSSLTCP4_SOURCEPORT
5769 case "$TESTS" in
5770 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
5771 TEST="$NAME: security of SSL-L with SOURCEPORT option"
5772 if ! eval $NUMCOND; then :;
5773 elif ! testfeats openssl >/dev/null; then
5774 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5775 numCANT=$((numCANT+1))
5776 listCANT="$listCANT $N"
5777 else
5778 gentestcert testsrv
5779 newport tcp4 # provide free port number in $PORT
5780 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
5781 fi ;; # NUMCOND, feats
5782 esac
5783 N=$((N+1))
5785 NAME=OPENSSLTCP4_LOWPORT
5786 case "$TESTS" in
5787 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5788 TEST="$NAME: security of SSL-L with LOWPORT option"
5789 if ! eval $NUMCOND; then :;
5790 elif ! testfeats openssl >/dev/null; then
5791 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5792 numCANT=$((numCANT+1))
5793 listCANT="$listCANT $N"
5794 else
5795 gentestcert testsrv
5796 newport tcp4 # provide free port number in $PORT
5797 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
5798 fi ;; # NUMCOND, feats
5799 esac
5800 N=$((N+1))
5802 NAME=OPENSSLTCP4_TCPWRAP
5803 case "$TESTS" in
5804 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5805 TEST="$NAME: security of SSL-L with TCPWRAP option"
5806 if ! eval $NUMCOND; then :;
5807 elif ! feat=$(testfeats ip4 tcp libwrap openssl); then
5808 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5809 numCANT=$((numCANT+1))
5810 listCANT="$listCANT $N"
5811 else
5812 gentestcert testsrv
5813 ha="$td/hosts.allow"
5814 hd="$td/hosts.deny"
5815 $ECHO "socat: $SECONDADDR" >"$ha"
5816 $ECHO "ALL: ALL" >"$hd"
5817 newport tcp4 # provide free port number in $PORT
5818 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
5819 fi ;; # NUMCOND, feats
5820 esac
5821 N=$((N+1))
5823 NAME=OPENSSLCERTSERVER
5824 case "$TESTS" in
5825 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*)
5826 TEST="$NAME: security of SSL-L with client certificate"
5827 if ! eval $NUMCOND; then :;
5828 elif ! testfeats openssl >/dev/null; then
5829 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5830 numCANT=$((numCANT+1))
5831 listCANT="$listCANT $N"
5832 else
5833 gentestcert testsrv
5834 gentestcert testcli
5835 newport tcp4 # provide free port number in $PORT
5836 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 '*'
5837 fi ;; # NUMCOND, feats
5838 esac
5839 N=$((N+1))
5841 NAME=OPENSSLCERTCLIENT
5842 case "$TESTS" in
5843 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%fork%*|*%$NAME%*)
5844 TEST="$NAME: security of SSL with server certificate"
5845 if ! eval $NUMCOND; then :;
5846 elif ! testfeats openssl >/dev/null; then
5847 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5848 numCANT=$((numCANT+1))
5849 listCANT="$listCANT $N"
5850 else
5851 gentestcert testsrv
5852 gentestcert testcli
5853 newport tcp4 # provide free port number in $PORT
5854 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
5855 fi ;; # NUMCOND, feats
5856 esac
5857 N=$((N+1))
5860 NAME=OPENSSLTCP6_RANGE
5861 case "$TESTS" in
5862 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
5863 TEST="$NAME: security of SSL-L over TCP/IPv6 with RANGE option"
5864 if ! eval $NUMCOND; then :;
5865 elif ! testfeats openssl >/dev/null; then
5866 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5867 numCANT=$((numCANT+1))
5868 listCANT="$listCANT $N"
5869 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5870 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5871 numCANT=$((numCANT+1))
5872 listCANT="$listCANT $N"
5873 else
5874 gentestcert6 testsrv6
5875 newport tcp6 # provide free port number in $PORT
5876 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
5877 fi ;; # NUMCOND, feats
5878 esac
5879 N=$((N+1))
5881 NAME=OPENSSLTCP6_SOURCEPORT
5882 case "$TESTS" in
5883 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%sourceport%*|*%listen%*|*%fork%*|*%$NAME%*)
5884 TEST="$NAME: security of SSL-L over TCP/IPv6 with SOURCEPORT option"
5885 if ! eval $NUMCOND; then :;
5886 elif ! testfeats openssl >/dev/null; then
5887 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5888 numCANT=$((numCANT+1))
5889 listCANT="$listCANT $N"
5890 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5891 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5892 numCANT=$((numCANT+1))
5893 listCANT="$listCANT $N"
5894 else
5895 gentestcert6 testsrv6
5896 newport tcp6 # provide free port number in $PORT
5897 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
5898 fi ;; # NUMCOND, feats
5899 esac
5900 N=$((N+1))
5902 NAME=OPENSSLTCP6_LOWPORT
5903 case "$TESTS" in
5904 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%lowport%*|*%listen%*|*%fork%*|*%$NAME%*)
5905 TEST="$NAME: security of SSL-L over TCP/IPv6 with LOWPORT option"
5906 if ! eval $NUMCOND; then :;
5907 elif ! testfeats openssl >/dev/null; then
5908 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5909 numCANT=$((numCANT+1))
5910 listCANT="$listCANT $N"
5911 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
5912 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
5913 numCANT=$((numCANT+1))
5914 listCANT="$listCANT $N"
5915 else
5916 gentestcert6 testsrv6
5917 newport tcp6 # provide free port number in $PORT
5918 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
5919 fi ;; # NUMCOND, feats
5920 esac
5921 N=$((N+1))
5923 NAME=OPENSSLTCP6_TCPWRAP
5924 case "$TESTS" in
5925 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%openssl%*|*%tcpwrap%*|*%listen%*|*%fork%*|*%$NAME%*)
5926 TEST="$NAME: security of SSL-L over TCP/IPv6 with TCPWRAP option"
5927 if ! eval $NUMCOND; then :;
5928 elif ! feat=$(testfeats ip6 tcp libwrap openssl && runsip6); then
5929 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
5930 numCANT=$((numCANT+1))
5931 listCANT="$listCANT $N"
5932 else
5933 gentestcert6 testsrv6
5934 ha="$td/hosts.allow"
5935 hd="$td/hosts.deny"
5936 $ECHO "socat: [::2]" >"$ha"
5937 $ECHO "ALL: ALL" >"$hd"
5938 newport tcp6 # provide free port number in $PORT
5939 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
5940 fi ;; # NUMCOND, feats
5941 esac
5942 N=$((N+1))
5945 # test security with the openssl-commonname option on client side
5946 NAME=OPENSSL_CN_CLIENT_SECURITY
5947 case "$TESTS" in
5948 *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*)
5949 TEST="$NAME: security of client openssl-commonname option"
5950 # connect using non matching server name/address with commonname
5951 # options, this should succeed. Then without this option, should fail
5952 if ! eval $NUMCOND; then :;
5953 elif ! testfeats openssl >/dev/null; then
5954 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5955 numCANT=$((numCANT+1))
5956 listCANT="$listCANT $N"
5957 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
5958 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
5959 numCANT=$((numCANT+1))
5960 listCANT="$listCANT $N"
5961 else
5962 gentestcert testsrv
5963 gentestcert testcli
5964 newport tcp4 # provide free port number in $PORT
5965 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 "" '*'
5966 fi ;; # testfeats, NUMCOND
5967 esac
5968 N=$((N+1))
5970 # test security with the openssl-commonname option on server side
5971 NAME=OPENSSL_CN_SERVER_SECURITY
5972 case "$TESTS" in
5973 *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
5974 TEST="$NAME: security of server openssl-commonname option"
5975 # connect using with client certificate to server, this should succeed.
5976 # Then use the server with a non matching openssl-commonname option,
5977 # this must fail
5978 if ! eval $NUMCOND; then :;
5979 elif ! testfeats openssl >/dev/null; then
5980 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
5981 numCANT=$((numCANT+1))
5982 listCANT="$listCANT $N"
5983 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
5984 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
5985 numCANT=$((numCANT+1))
5986 listCANT="$listCANT $N"
5987 else
5988 gentestcert testsrv
5989 gentestcert testcli
5990 newport tcp4 # provide free port number in $PORT
5991 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" '*'
5992 fi ;; # testfeats, NUMCOND
5993 esac
5994 N=$((N+1))
5997 NAME=OPENSSL_FIPS_SECURITY
5998 case "$TESTS" in
5999 *%$N%*|*%functions%*|*%security%*|*%openssl%*|*%fips%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%fork%*|*%$NAME%*)
6000 TEST="$NAME: OpenSSL restrictions by FIPS"
6001 if ! eval $NUMCOND; then :;
6002 elif ! testfeats openssl >/dev/null; then
6003 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
6004 numCANT=$((numCANT+1))
6005 listCANT="$listCANT $N"
6006 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
6007 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
6008 numCANT=$((numCANT+1))
6009 listCANT="$listCANT $N"
6010 elif ! testoptions fips >/dev/null; then
6011 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL/FIPS not available${NORMAL}\n" $N
6012 numCANT=$((numCANT+1))
6013 listCANT="$listCANT $N"
6014 else
6015 gentestcert testsrv
6016 gentestcert testcli
6017 newport tcp4 # provide free port number in $PORT
6018 # openssl client accepts a "normal" certificate only when not in fips mode
6019 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
6020 fi ;; # testfeats, NUMCOND
6021 esac
6022 N=$((N+1))
6025 NAME=UNIEXECEOF
6026 case "$TESTS" in
6027 *%$N%*|*%functions%*|*%$NAME%*)
6028 TEST="$NAME: give exec'd write-only process a chance to flush (-u)"
6029 testod "$N" "$TEST" "" EXEC:"$OD_C" "$opts -u"
6030 esac
6031 N=$((N+1))
6034 NAME=REVEXECEOF
6035 case "$TESTS" in
6036 *%$N%*|*%functions%*|*%$NAME%*)
6037 TEST="$NAME: give exec'd write-only process a chance to flush (-U)"
6038 testod "$N" "$TEST" EXEC:"$OD_C" "-" "$opts -U"
6039 esac
6040 N=$((N+1))
6043 NAME=FILANDIR
6044 case "$TESTS" in
6045 *%$N%*|*%filan%*|*%$NAME%*)
6046 TEST="$NAME: check type printed for directories"
6047 if ! eval $NUMCOND; then :; else
6048 te="$td/test$N.stderr"
6049 printf "test $F_n $TEST... " $N
6050 type=$($FILAN -f . 2>$te |tail -n 1 |awk '{print($2);}')
6051 if [ "$type" = "dir" ]; then
6052 $PRINTF "$OK\n"
6053 numOK=$((numOK+1))
6054 listOK="$listOK $N"
6055 else
6056 $PRINTF "$FAILED\n"
6057 cat "$te"
6058 numFAIL=$((numFAIL+1))
6059 listFAIL="$listFAIL $N"
6061 fi ;; # NUMCOND
6062 esac
6063 N=$((N+1))
6066 # Test if Filan can determine UNIX domain socket in file system
6067 NAME=FILANSOCKET
6068 case "$TESTS" in
6069 *%$N%*|*%filan%*|*%unix%*|*%listen%*|*%$NAME%*)
6070 TEST="$NAME: capability to analyze named unix socket"
6071 # Run Filan on a listening UNIX domain socket.
6072 # When its output gives "socket" as type (2nd column), the test succeeded
6073 if ! eval $NUMCOND; then :; else
6074 ts="$td/test$N.socket"
6075 te1="$td/test$N.stderr1" # socat
6076 te2="$td/test$N.stderr2" # filan
6077 printf "test $F_n $TEST... " $N
6078 $TRACE $SOCAT $opts UNIX-LISTEN:"$ts" /dev/null </dev/null 2>"$te1" &
6079 spid=$!
6080 waitfile "$ts" 1
6081 type=$($FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print($2);}')
6082 if [ "$type" = "socket" ]; then
6083 $PRINTF "$OK\n"
6084 if [ "$VERBOSE" ]; then
6085 echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\""
6086 echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'"
6088 numOK=$((numOK+1))
6089 listOK="$listOK $N"
6090 else
6091 $PRINTF "$FAILED\n"
6092 echo "$SOCAT $opts UNIX-LISTEN:\"$ts\" /dev/null </dev/null 2>\"$te1\"" >&2
6093 cat "$te1"
6094 echo "$FILAN -f "$ts" 2>$te2 |tail -n 1 |awk '{print(\$2);}'" >&2
6095 cat "$te2"
6096 numFAIL=$((numFAIL+1))
6097 listFAIL="$listFAIL $N"
6099 kill $spid 2>/dev/null
6100 wait
6101 fi ;; # NUMCOND
6102 esac
6103 N=$((N+1))
6106 testptywaitslave () {
6107 local N="$1"
6108 local TEST="$2"
6109 local PTYTYPE="$3" # ptmx or openpty
6110 local opts="$4"
6112 local tp="$td/test$N.pty"
6113 local ts="$td/test$N.socket"
6114 local tf="$td/test$N.file"
6115 local tdiff="$td/test$N.diff"
6116 local te1="$td/test$N.stderr1"
6117 local te2="$td/test$N.stderr2"
6118 local te3="$td/test$N.stderr3"
6119 local te4="$td/test$N.stderr4"
6120 local da="test$N $(date) $RANDOM"
6121 printf "test $F_n $TEST... " $N
6122 # set -vx
6123 # first generate a pty, then a socket
6124 ($TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,pty-interval=$val_t,link="$tp" UNIX-LISTEN:"$ts" 2>"$te1"; rm -f "$tp") 2>/dev/null &
6125 pid=$!
6126 waitfile "$tp" 1 100
6127 # if pty was non-blocking, the socket is active, and socat1 will term
6128 $TRACE $SOCAT $opts -T 10 -lpsocat2 FILE:/dev/null UNIX-CONNECT:"$ts" 2>"$te2"
6129 # if pty is blocking, first socat is still active and we get a connection now
6130 #((echo "$da"; sleep 2) |$TRACE $SOCAT -lpsocat3 $opts - file:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
6131 ( (waitfile "$ts" 1 100; echo "$da"; sleep 1) |$TRACE $SOCAT -lpsocat3 $opts - FILE:"$tp",$PTYOPTS2 >"$tf" 2>"$te3") &
6132 waitfile "$ts" 1 100
6133 # but we need an echoer on the socket
6134 $TRACE $SOCAT $opts -lpsocat4 UNIX:"$ts" ECHO 2>"$te4"
6135 # now $tf file should contain $da
6136 #kill $pid 2>/dev/null
6137 wait
6139 if echo "$da" |diff - "$tf"> "$tdiff"; then
6140 $PRINTF "$OK\n"
6141 if [ "$VERBOSE" ]; then
6142 echo " $TRACE $SOCAT $opts -T 10 -lpsocat2 FILE:/dev/null UNIX-CONNECT:\"$ts\"" 2>"$te2"
6143 echo " $TRACE $SOCAT $opts -lpsocat1 PTY,$PTYTYPE,pty-wait-slave,link=\"$tp\" UNIX-LISTEN:\"$ts\"" >&2
6144 echo " $TRACE $SOCAT -lpsocat3 $opts - file:\"$tp\",$PTYOPTS2" >&2
6146 numOK=$((numOK+1))
6147 listOK="$listOK $N"
6148 else
6149 $PRINTF "${YELLOW}FAILED${NORMAL}\n"
6150 cat "$te1"
6151 #cat "$te2" # not of interest
6152 cat "$te3"
6153 cat "$te4"
6154 cat "$tdiff"
6155 numCANT=$((numCANT+1))
6156 listCANT="$listCANT $N"
6158 set +vx
6161 NAME=PTMXWAITSLAVE
6162 PTYTYPE=ptmx
6163 case "$TESTS" in
6164 *%$N%*|*%functions%*|*%pty%*|*%unix%*|*%listen%*|*%$NAME%*)
6165 TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
6166 if ! eval $NUMCOND; then :; else
6167 if ! feat=$(testfeats pty); then
6168 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6169 numCANT=$((numCANT+1))
6170 listCANT="$listCANT $N"
6171 elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
6172 $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6173 numCANT=$((numCANT+1))
6174 listCANT="$listCANT $N"
6175 else
6176 testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
6178 fi ;; # NUMCOND
6179 esac
6180 N=$((N+1))
6182 NAME=OPENPTYWAITSLAVE
6183 PTYTYPE=openpty
6184 case "$TESTS" in
6185 *%$N%*|*%functions%*|*%pty%*|*%unix%*|*%listen%*|*%$NAME%*)
6186 TEST="$NAME: test if master pty ($PTYTYPE) waits for slave connection"
6187 if ! eval $NUMCOND; then :;
6188 elif ! feat=$(testfeats pty); then
6189 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6190 numCANT=$((numCANT+1))
6191 listCANT="$listCANT $N"
6192 elif ! feat=$(testoptions "$PTYTYPE" pty-wait-slave); then
6193 $PRINTF "test $F_n $TEST... ${YELLOW}option $(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6194 numCANT=$((numCANT+1))
6195 listCANT="$listCANT $N"
6196 else
6197 testptywaitslave "$N" "$TEST" "$PTYTYPE" "$opts"
6198 fi ;; # NUMCOND, feats
6199 esac
6200 N=$((N+1))
6203 # Test the connect-timeout address option
6204 NAME=CONNECTTIMEOUT
6205 case "$TESTS" in
6206 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%listen%*|*%$NAME%*)
6207 TEST="$NAME: test the connect-timeout option"
6208 if ! eval $NUMCOND; then :;
6209 elif ! feat=$(testfeats tcp); then
6210 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6211 numCANT=$((numCANT+1))
6212 listCANT="$listCANT $N"
6213 elif ! feat=$(testoptions connect-timeout); then
6214 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6215 numCANT=$((numCANT+1))
6216 listCANT="$listCANT $N"
6217 else
6218 # We need a hanging connection attempt, guess an address for this
6219 case "$UNAME" in
6220 Linux) HANGIP=1.0.0.1 ;;
6221 *) HANGIP=255.255.255.254 ;;
6222 esac
6223 te1="$td/test$N.stderr1"
6224 tk1="$td/test$N.kill1"
6225 te2="$td/test$N.stderr2"
6226 tk2="$td/test$N.kill2"
6227 $PRINTF "test $F_n $TEST... " $N
6228 # First, try to make socat hang and see if it can be killed
6229 #$TRACE $SOCAT $opts - TCP:$HANGIP:1 >"$te1" 2>&1 </dev/null &
6230 CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1"
6231 $CMD >"$te1" 2>$te1 </dev/null &
6232 pid1=$!
6233 relsleep 2
6234 if ! kill $pid1 2>"$tk1"; then
6235 $PRINTF "${YELLOW}does not hang${NORMAL}\n"
6236 echo "$CMD" >&2
6237 cat "$te1" >&2
6238 numCANT=$((numCANT+1))
6239 listCANT="$listCANT $N"
6240 else
6241 # Second, set connect-timeout and see if socat exits before kill
6242 CMD="$TRACE $SOCAT $opts - TCP:$HANGIP:1,connect-timeout=$(reltime 1)"
6243 $CMD >"$te1" 2>$te2 </dev/null &
6244 pid2=$!
6245 relsleep 10
6246 if kill $pid2 2>"$tk2"; then
6247 $PRINTF "$FAILED (\n"
6248 echo "$CMD" >&2
6249 cat "$te2" >&2
6250 numFAIL=$((numFAIL+1))
6251 listFAIL="$listFAIL $N"
6252 else
6253 $PRINTF "$OK\n"
6254 if [ "$VERBOSE" ]; then
6255 echo "$CMD" >&2
6257 numOK=$((numOK+1))
6258 listOK="$listOK $N"
6261 wait
6262 fi ;; # testfeats, NUMCOND
6263 esac
6264 N=$((N+1))
6267 # version 1.7.0.0 had a bug with the connect-timeout option: while it correctly
6268 # terminated a hanging connect attempt, it prevented a successful connection
6269 # establishment from being recognized by socat, instead the timeout occurred
6270 NAME=CONNECTTIMEOUT_CONN
6271 if ! eval $NUMCOND; then :; else
6272 case "$TESTS" in
6273 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%timeout%*|*%listen%*|*%$NAME%*)
6274 TEST="$NAME: TCP4 connect-timeout option when server replies"
6275 # just try a connection that is expected to succeed with the usual data
6276 # transfer; with the bug it will fail
6277 tf="$td/test$N.stdout"
6278 te="$td/test$N.stderr"
6279 tdiff="$td/test$N.diff"
6280 newport tcp4; tsl=$PORT
6281 ts="127.0.0.1:$tsl"
6282 da="test$N $(date) $RANDOM"
6283 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE"
6284 CMD2="$TRACE $SOCAT $opts STDIO TCP4:$ts,connect-timeout=1"
6285 printf "test $F_n $TEST... " $N
6286 $CMD1 >"$tf" 2>"${te}1" &
6287 pid1=$!
6288 waittcp4port $tsl 1
6289 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6290 rc2=$?
6291 kill $pid1 2>/dev/null
6292 wait
6293 if [ $rc2 -ne 0 ]; then
6294 $PRINTF "$FAILED (rc2=$rc2)\n"
6295 echo "$CMD1 &"
6296 cat "${te}1" >&2
6297 echo "$CMD2"
6298 cat "${te}2" >&2
6299 numFAIL=$((numFAIL+1))
6300 listFAIL="$listFAIL $N"
6301 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6302 $PRINTF "$FAILED (diff)\n"
6303 echo "$CMD1 &"
6304 cat "${te}1" >&2
6305 echo "$CMD2"
6306 cat "${te}2" >&2
6307 echo "// diff:" >&2
6308 cat "$tdiff" >&2
6309 numFAIL=$((numFAIL+1))
6310 listFAIL="$listFAIL $N"
6311 else
6312 $PRINTF "$OK\n"
6313 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
6314 numOK=$((numOK+1))
6315 listOK="$listOK $N"
6316 fi ;;
6317 esac
6318 fi # NUMCOND
6319 N=$((N+1))
6322 NAME=OPENSSLLISTENDSA
6323 case "$TESTS" in
6324 *%$N%*|*%functions%*|*%openssl%*|*%listen%*|*%$NAME%*)
6325 TEST="$NAME: openssl listen with DSA certificate"
6326 if ! eval $NUMCOND; then :;
6327 elif ! testfeats openssl >/dev/null; then
6328 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
6329 numCANT=$((numCANT+1))
6330 listCANT="$listCANT $N"
6331 else
6332 SRVCERT=testsrvdsa
6333 gentestdsacert $SRVCERT
6334 tf="$td/test$N.stdout"
6335 te="$td/test$N.stderr"
6336 tdiff="$td/test$N.diff"
6337 da="test$N $(date) $RANDOM"
6338 newport tcp4 # provide free port number in $PORT
6339 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=$SRVCERT.pem,key=$SRVCERT.key,verify=0 pipe"
6340 CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
6341 $PRINTF "test $F_n $TEST... " $N
6342 eval "$CMD2 2>\"${te}1\" &"
6343 pid=$! # background process id
6344 waittcp4port $PORT
6345 echo "$da" |$CMD >$tf 2>"${te}2"
6346 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
6347 $PRINTF "$FAILED\n"
6348 echo "$CMD2 &"
6349 echo "$CMD"
6350 cat "${te}1"
6351 cat "${te}2"
6352 cat "$tdiff"
6353 numFAIL=$((numFAIL+1))
6354 listFAIL="$listFAIL $N"
6355 else
6356 $PRINTF "$OK\n"
6357 if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi
6358 numOK=$((numOK+1))
6359 listOK="$listOK $N"
6361 kill $pid 2>/dev/null
6362 wait
6363 fi ;; # testfeats, NUMCOND
6364 esac
6365 N=$((N+1))
6368 # derive signal number from signal name
6369 # kill -l should provide the info
6370 signum () {
6371 if [ ! "$BASH_VERSION" -o -o posix ]; then
6372 # we expect:
6373 for i in $(POSIXLY_CORRECT=1 kill -l); do echo "$i"; done |grep -n -i "^$1$" |cut -d: -f1
6374 else
6375 # expect:
6376 # " 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL"
6377 signam="$1"
6378 kill -l </dev/null |
6379 while read l; do printf "%s %s\n%s %s\n%s %s\n%s %s\n" $l; done |
6380 grep -e "SIG$signam\$" |
6381 cut -d ')' -f 1
6385 # problems with QUIT, INT (are blocked in system() )
6386 for signam in TERM ILL; do
6387 NAME=EXITCODESIG$signam
6388 case "$TESTS" in
6389 *%$N%*|*%functions%*|*%pty%*|*%signal%*|*%$NAME%*)
6390 TEST="$NAME: exit status when dying on SIG$signam"
6391 if ! eval $NUMCOND; then :;
6392 elif ! feat=$(testfeats pty); then
6393 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
6394 numCANT=$((numCANT+1))
6395 listCANT="$listCANT $N"
6396 else
6397 SIG="$(signum $signam)"
6398 te="$td/test$N.stderr"
6399 tpp="$td/test$N.ppid"
6400 tp="$td/test$N.pid"
6401 $PRINTF "test $F_n $TEST... " $N
6402 (sleep 1; kill -"$SIG" "$(cat "$tpp")") &
6403 # a simple "system:echo $PPID..." does not work on NetBSD, OpenBSD
6404 #$TRACE $SOCAT $opts echo SYSTEM:'exec /usr/bin/env bash -c "echo \$PPID '">$tpp"'; echo \$$ '">$tp; read x\"",nofork 2>"$te"; stat=$?
6405 tsh="$td/test$N.sh"
6406 cat <<EOF >"$tsh"
6407 #! /usr/bin/env bash
6408 echo \$PPID >"$tpp"
6409 echo \$\$ >"$tp"
6410 read x
6412 chmod a+x "$tsh"
6413 #$TRACE $SOCAT $opts echo SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"; stat=$?
6414 CMD="$TRACE $SOCAT $opts ECHO SYSTEM:\"exec\\\ \\\"$tsh\\\"\",pty,setsid,nofork"
6415 $TRACE $SOCAT $opts ECHO SYSTEM:"exec \"$tsh\"",pty,setsid,nofork 2>"$te"
6416 stat=$?
6417 sleep 1; kill -INT $(cat $tp)
6418 wait
6419 if [ "$stat" -eq $((128+$SIG)) ]; then
6420 $PRINTF "$OK\n"
6421 numOK=$((numOK+1))
6422 listOK="$listOK $N"
6423 else
6424 $PRINTF "$FAILED\n"
6425 echo "$CMD"
6426 cat "$te"
6427 numFAIL=$((numFAIL+1))
6428 listFAIL="$listFAIL $N"
6430 wait
6431 fi ;; # NUMCOND, feats
6432 esac
6433 N=$((N+1))
6434 done
6437 NAME=READBYTES
6438 #set -vx
6439 case "$TESTS" in
6440 *%$N%*|*%functions%*|*%$NAME%*)
6441 TEST="$NAME: restrict reading from file with bytes option"
6442 if ! eval $NUMCOND; then :;
6443 elif false; then
6444 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
6445 numCANT=$((numCANT+1))
6446 listCANT="$listCANT $N"
6447 else
6448 tr="$td/test$N.ref"
6449 ti="$td/test$N.in"
6450 to="$td/test$N.out"
6451 te="$td/test$N.err"
6452 tdiff="$td/test$N.diff"
6453 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
6455 CMD="$TRACE $SOCAT $opts -u open:$ti,readbytes=100 -"
6456 printf "test $F_n $TEST... " $N
6457 rm -f "$tf" "$ti" "$to"
6459 echo "AAAAAAAAAAAAAAAAAAAAAAAA
6460 AAAAAAAAAAAAAAAAAAAAAAAA
6461 AAAAAAAAAAAAAAAAAAAAAAAA
6462 AAAAAAAAAAAAAAAAAAAAAAAA" >"$tr" # 100 bytes
6463 cat "$tr" "$tr" >"$ti" # 200 bytes
6464 $CMD >"$to" 2>"$te"
6465 if ! diff "$tr" "$to" >"$tdiff" 2>&1; then
6466 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6467 echo "$CMD"
6468 cat "$te"
6469 cat "$tdiff"
6470 numFAIL=$((numFAIL+1))
6471 listFAIL="$listFAIL $N"
6472 else
6473 $PRINTF "$OK\n"
6474 if [ -n "$debug" ]; then cat $te; fi
6475 numOK=$((numOK+1))
6476 listOK="$listOK $N"
6478 fi ;; # NUMCOND, feats
6479 esac
6480 N=$((N+1))
6483 NAME=UDPLISTENFORK
6484 case "$TESTS" in
6485 *%$N%*|*%functions%*|*%ip4%*|*%udp%*|*%listen%*|*%fork%*|*%$NAME%*)
6486 TEST="$NAME: UDP socket rebinds after first connection"
6487 if ! eval $NUMCOND; then :;
6488 elif ! F=$(testfeats STDIO IP4 UDP PIPE); then
6489 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
6490 numCANT=$((numCANT+1))
6491 listCANT="$listCANT $N"
6492 elif ! A=$(testaddrs STDIO UDP4-CONNECT UDP4-LISTEN PIPE); then
6493 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
6494 numCANT=$((numCANT+1))
6495 listCANT="$listCANT $N"
6496 elif ! o=$(testoptions bind so-reuseaddr fork) >/dev/null; then
6497 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
6498 numCANT=$((numCANT+1))
6499 listCANT="$listCANT $N"
6500 elif ! runsip4 >/dev/null; then
6501 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
6502 numCANT=$((numCANT+1))
6503 listCANT="$listCANT $N"
6504 else
6505 tf="$td/test$N.stdout"
6506 te="$td/test$N.stderr"
6507 tdiff="$td/test$N.diff"
6508 da1="test$N $(date) $RANDOM"
6509 da2="test$N $(date) $RANDOM"
6510 #establish a listening and forking udp socket in background
6511 newport udp4 # provide free port number in $PORT
6512 #processes hang forever without -T
6513 CMD0="$TRACE $SOCAT -T $(reltime 5) $opts -lpserver UDP4-LISTEN:$PORT,bind=$LOCALHOST,$REUSEADDR,fork PIPE"
6514 #make a first and a second connection
6515 CMD1="$TRACE $SOCAT $opts -lpclient - UDP4-CONNECT:$LOCALHOST:$PORT"
6516 $PRINTF "test $F_n $TEST... " $N
6517 eval "$CMD0 2>${te}0 &"
6518 pids=$!
6519 waitudp4port "$PORT"
6520 echo "$da1" |eval "$CMD1" >"${tf}1" 2>"${te}1"
6521 if [ $? -ne 0 ]; then
6522 kill "$pids" 2>/dev/null
6523 $PRINTF "$NO_RESULT (first conn failed):\n"
6524 echo "$CMD0 &"
6525 cat "${te}0" >&2
6526 echo "$CMD1"
6527 cat "${te}1" >&2
6528 numCANT=$((numCANT+1))
6529 listCANT="$listCANT $N"
6530 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
6531 kill "$pids" 2>/dev/null
6532 $PRINTF "$NO_RESULT (first conn failed); diff:\n"
6533 echo "$CMD0 &"
6534 cat "${te}0" >&2
6535 echo "$CMD1"
6536 cat "${te}1" >&2
6537 cat "$tdiff"
6538 numCANT=$((numCANT+1))
6539 listCANT="$listCANT $N"
6540 else
6541 relsleep 2 # UDP-LISTEN sleeps 1s
6542 echo "$da2" |eval "$CMD1" >"${tf}2" 2>"${te}2"
6543 rc="$?"; kill "$pids" 2>/dev/null
6544 if [ $rc -ne 0 ]; then
6545 $PRINTF "$FAILED:\n"
6546 echo "$CMD0 &"
6547 cat "${te}0" >&2
6548 echo "$CMD1"
6549 cat "${te}1" >&2
6550 numFAIL=$((numFAIL+1))
6551 listFAIL="$listFAIL $N"
6552 elif ! echo "$da2" |diff - "${tf}2" >"$tdiff"; then
6553 $PRINTF "$FAILED: diff\n"
6554 echo "$CMD0 &"
6555 cat "${te}0" >&2
6556 echo "$CMD1"
6557 cat "${te}1" >&2
6558 echo "diff:"
6559 cat "$tdiff"
6560 numFAIL=$((numFAIL+1))
6561 listFAIL="$listFAIL $N"
6562 else
6563 $PRINTF "$OK\n"
6564 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
6565 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
6566 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
6567 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
6568 numOK=$((numOK+1))
6569 listOK="$listOK $N"
6570 fi # !( $? -ne 0)
6571 fi # !(rc -ne 0)
6572 wait
6573 fi ;; # NUMCOND, feats
6574 esac
6575 N=$((N+1))
6578 # Is a listen address capable of forking two child processes and have both
6579 # active?
6580 while read PROTOV MAJADDR MINADDR; do
6581 if [ -z "$PROTOV" ] || [[ "$PROTOV" == \#* ]]; then continue; fi
6582 protov="$(echo "$PROTOV" |tr A-Z a-z)"
6583 proto="${protov%%[0-9]}"
6584 NAME=${PROTOV}LISTENFORK
6585 case "$TESTS" in
6586 *%$N%*|*%functions%*|*%$protov%*|*%$proto%*|*%listen%*|*%fork%*|*%$NAME%*)
6587 TEST="$NAME: $PROTOV listen handles 2 concurrent connections"
6588 # Have a listening address with fork option. connect with client1, send a piece
6589 # of data, wait 1s, connect with client2, send another piece of data, wait 1s,
6590 # and send another piece of data with client1. The server processes append all
6591 # data to the same file. Check all data are written to the file in correct
6592 # order.
6593 if ! eval $NUMCOND; then :;
6594 #elif ! feat=$(testfeats $PROTOV); then
6595 # $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$PROTOV" |tr a-z A-Z) not available${NORMAL}\n" $N
6596 # numCANT=$((numCANT+1))
6597 elif ! runs$protov >/dev/null; then
6598 $PRINTF "test $F_n $TEST... ${YELLOW}$PROTOV not available${NORMAL}\n" $N
6599 numCANT=$((numCANT+1))
6600 listCANT="$listCANT $N"
6601 else
6602 ts="$td/test$N.sock"
6603 tref="$td/test$N.ref"
6604 tf="$td/test$N.stdout"
6605 te="$td/test$N.stderr"
6606 tdiff="$td/test$N.diff"
6607 da1a="test$N $(date) 1a $RANDOM"
6608 da1b="test$N $(date) 1b $RANDOM"
6609 da2="test$N $(date) 2 $RANDOM"
6610 case "$MAJADDR" in
6611 "FILE")
6612 tla="$ts"
6613 tca="$ts"
6614 waitproto="file"
6615 waitfor="$ts" ;;
6616 esac
6617 case "$MINADDR" in
6618 "PORT")
6619 newport $protov # provide free port number in $PORT
6620 tla="$PORT,bind=$MAJADDR"
6621 tca="$MAJADDR:$PORT"
6622 waitproto="${protov}port"
6623 waitfor="$PORT" ;;
6624 esac
6625 #set -xv
6626 echo -e "$da1a\n$da2\n$da1b" >"$tref"
6627 # establish a listening and forking listen socket in background
6628 # UDP processes hang forever without -T
6629 CMD0="$TRACE $SOCAT -T $(reltime 20) $opts -lpserver $PROTOV-LISTEN:$tla,$REUSEADDR,fork PIPE"
6630 # make a first and a second connection
6631 CMD1="$TRACE $SOCAT $opts -t $(reltime 1) -lpclient - $PROTOV-CONNECT:$tca"
6632 $PRINTF "test $F_n $TEST... " $N
6633 eval "$CMD0 2>${te}0 &"
6634 pid0=$!
6635 wait$waitproto "$waitfor" 1 2
6636 (echo "$da1a"; relsleep 10; echo "$da1b") |eval "$CMD1" >>"${tf}" 2>"${te}1" &
6637 relsleep 5
6638 # trailing sleep req for sctp because no half close
6639 (echo "$da2"; relsleep 5) |eval "$CMD1" >>"${tf}" 2>"${te}2" &
6640 relsleep 10
6641 kill $pid0 2>/dev/null
6642 wait
6643 if ! diff -u "$tref" "$tf" >"$tdiff"; then
6644 $PRINTF "$FAILED (diff)\n"
6645 echo "$CMD0 &"
6646 cat "${te}0" >&2
6647 echo "$CMD1 &"
6648 cat "${te}1" >&2
6649 echo "$CMD1"
6650 cat "${te}2" >&2
6651 cat "$tdiff" >&2
6652 numFAIL=$((numFAIL+1))
6653 listFAIL="$listFAIL $N"
6654 else
6655 $PRINTF "$OK\n"
6656 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
6657 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
6658 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
6659 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
6660 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
6661 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
6662 numOK=$((numOK+1))
6663 listOK="$listOK $N"
6664 fi # !(rc -ne 0)
6665 wait
6666 fi ;; # NUMCOND, feats
6667 esac
6668 N=$((N+1))
6669 done <<<"
6670 TCP4 $LOCALHOST PORT
6671 TCP6 $LOCALHOST6 PORT
6672 UDP4 $LOCALHOST PORT
6673 UDP6 $LOCALHOST6 PORT
6674 SCTP4 $LOCALHOST PORT
6675 SCTP6 $LOCALHOST6 PORT
6676 UNIX FILE ,
6680 NAME=UNIXTOSTREAM
6681 case "$TESTS" in
6682 *%$N%*|*%functions%*|*%unix%*|*%listen%*|*%$NAME%*)
6683 TEST="$NAME: generic UNIX client connects to stream socket"
6684 if ! eval $NUMCOND; then :; else
6685 ts="$td/test$N.socket"
6686 tf="$td/test$N.stdout"
6687 te="$td/test$N.stderr"
6688 tdiff="$td/test$N.diff"
6689 da1="test$N $(date) $RANDOM"
6690 #establish a listening unix socket in background
6691 SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\" PIPE"
6692 #make a connection
6693 CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts\""
6694 $PRINTF "test $F_n $TEST... " $N
6695 eval "$SRV 2>${te}s &"
6696 pids=$!
6697 waitfile "$ts"
6698 echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1"
6699 if [ $? -ne 0 ]; then
6700 kill "$pids" 2>/dev/null
6701 $PRINTF "$FAILED:\n"
6702 echo "$SRV &"
6703 echo "$CLI"
6704 cat "${te}s" "${te}1"
6705 numFAIL=$((numFAIL+1))
6706 listFAIL="$listFAIL $N"
6707 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
6708 kill "$pids" 2>/dev/null
6709 $PRINTF "$FAILED; diff:\n"
6710 cat "$tdiff"
6711 numFAIL=$((numFAIL+1))
6712 listFAIL="$listFAIL $N"
6713 else
6714 $PRINTF "$OK\n"
6715 numOK=$((numOK+1))
6716 listOK="$listOK $N"
6717 fi # !(rc -ne 0)
6718 wait
6719 fi ;; # NUMCOND
6720 esac
6721 N=$((N+1))
6724 NAME=UNIXTODGRAM
6725 case "$TESTS" in
6726 *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%recv%*|*%$NAME%*)
6727 TEST="$NAME: generic UNIX client connects to datagram socket"
6728 if ! eval $NUMCOND; then :; else
6729 ts1="$td/test$N.socket1"
6730 ts2="$td/test$N.socket2"
6731 tf="$td/test$N.stdout"
6732 te="$td/test$N.stderr"
6733 tdiff="$td/test$N.diff"
6734 da1="test$N $(date) $RANDOM"
6735 #establish a receiving unix datagram socket in background
6736 SRV="$TRACE $SOCAT $opts -lpserver UNIX-RECVFROM:\"$ts1\" PIPE"
6737 #make a connection
6738 CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\",bind=\"$ts2\""
6739 #CLI="$TRACE $SOCAT $opts -lpclient - UNIX:\"$ts1\""
6740 $PRINTF "test $F_n $TEST... " $N
6741 eval "$SRV 2>${te}s &"
6742 pids=$!
6743 waitfile "$ts1"
6744 echo "$da1" |eval "$CLI" >"${tf}1" 2>"${te}1"
6745 rc=$?
6746 kill $pids 2>/dev/null
6747 wait
6748 if [ $rc -ne 0 ]; then
6749 kill "$pids" 2>/dev/null
6750 $PRINTF "$FAILED:\n"
6751 echo "$SRV &"
6752 cat "${te}s"
6753 echo "$CLI"
6754 cat "${te}1" "${te}1"
6755 numFAIL=$((numFAIL+1))
6756 listFAIL="$listFAIL $N"
6757 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
6758 kill "$pids" 2>/dev/null
6759 $PRINTF "$FAILED:\n"
6760 echo "$SRV &"
6761 cat "${te}s"
6762 echo "$CLI"
6763 cat "${te}1"
6764 cat "$tdiff"
6765 numFAIL=$((numFAIL+1))
6766 listFAIL="$listFAIL $N"
6767 else
6768 $PRINTF "$OK\n"
6769 numOK=$((numOK+1))
6770 listOK="$listOK $N"
6771 fi # !(rc -ne 0)
6772 fi ;; # NUMCOND
6773 esac
6774 N=$((N+1))
6777 # there was an error in address EXEC with options pipes,stderr
6778 NAME=EXECPIPESSTDERR
6779 case "$TESTS" in
6780 *%$N%*|*%functions%*|*%$NAME%*)
6781 TEST="$NAME: simple echo via exec of cat with pipes,stderr"
6782 # this test is known to fail when logging is enabled with OPTS/opts env var.
6783 SAVE_opts="$opts"
6784 opts="$(echo "$opts" |sed 's/-dd*//g')"
6785 testecho "$N" "$TEST" "" "EXEC:$CAT,pipes,stderr" "$opts"
6786 opts="$SAVE_opts"
6787 esac
6788 N=$((N+1))
6790 # EXEC and SYSTEM with stderr injected socat messages into the data stream.
6791 NAME=EXECSTDERRLOG
6792 case "$TESTS" in
6793 *%$N%*|*%functions%*|*%$NAME%*)
6794 TEST="$NAME: simple echo via exec of cat with pipes,stderr"
6795 SAVE_opts="$opts"
6796 # make sure at least two -d are there
6797 case "$opts" in
6798 *-d*-d*) ;;
6799 *-d*) opts="$opts -d" ;;
6800 *) opts="-d -d" ;;
6801 esac
6802 testecho "$N" "$TEST" "" "exec:$CAT,pipes,stderr" "$opts"
6803 opts="$SAVE_opts"
6804 esac
6805 N=$((N+1))
6806 #TTY=$(tty); ps -fade |grep "${TTY#/*/}\>" >/tmp/ps.out
6809 NAME=SIMPLEPARSE
6810 case "$TESTS" in
6811 *%$N%*|*%functions%*|*%PARSE%*|*%$NAME%*)
6812 TEST="$NAME: invoke socat from socat"
6813 testecho "$N" "$TEST" "" exec:"$SOCAT - exec\:$CAT,pipes" "$opts" "$val_t"
6814 esac
6815 N=$((N+1))
6818 NAME=FULLPARSE
6819 case "$TESTS" in
6820 *%$N%*|*%functions%*|*%parse%*|*%$NAME%*)
6821 TEST="$NAME: correctly parse special chars"
6822 if ! eval $NUMCOND; then :; else
6823 $PRINTF "test $F_n $TEST... " $N
6824 tf="$td/test$N.stdout"
6825 te="$td/test$N.stderr"
6826 tdiff="$td/test$N.diff"
6827 # a string where commas are hidden in nesting lexical constructs
6828 # if they are scanned incorrectly, socat will see an "unknown option"
6829 dain='(,)[,]{,}","([),])hugo'
6830 daout='(,)[,]{,},([),])hugo'
6831 $TRACE "$SOCAT" $opts -u "exec:echo $dain" - >"$tf" 2>"$te"
6832 rc=$?
6833 echo "$daout" |diff "$tf" - >"$tdiff"
6834 if [ "$rc" -ne 0 ]; then
6835 $PRINTF "$FAILED:\n"
6836 echo "$TRACE $SOCAT" -u "exec:echo $da" -
6837 cat "$te"
6838 numFAIL=$((numFAIL+1))
6839 listFAIL="$listFAIL $N"
6840 elif [ -s "$tdiff" ]; then
6841 $PRINTF "$FAILED:\n"
6842 echo diff:
6843 cat "$tdiff"
6844 if [ -n "$debug" ]; then cat $te; fi
6845 numFAIL=$((numFAIL+1))
6846 listFAIL="$listFAIL $N"
6847 else
6848 $PRINTF "$OK\n"
6849 if [ -n "$debug" ]; then cat $te; fi
6850 numOK=$((numOK+1))
6851 listOK="$listOK $N"
6853 fi ;; # NUMCOND
6854 esac
6855 N=$((N+1))
6857 NAME=NESTEDSOCATEXEC
6858 case "$TESTS" in
6859 *%parse%*|*%$N%*|*%functions%*|*%$NAME%*)
6860 TEST="$NAME: does lexical analysis work sensibly (exec)"
6861 testecho "$N" "$TEST" "" "exec:'$SOCAT - exec:$CAT,pipes'" "$opts" 1
6862 esac
6863 N=$((N+1))
6865 NAME=NESTEDSOCATSYSTEM
6866 case "$TESTS" in
6867 *%parse%*|*%$N%*|*%functions%*|*%$NAME%*)
6868 TEST="$NAME: does lexical analysis work sensibly (system)"
6869 testecho "$N" "$TEST" "" "system:\"$SOCAT - exec:$CAT,pipes\"" "$opts" 1
6870 esac
6871 N=$((N+1))
6874 NAME=TCP6BYTCP4
6875 case "$TESTS" in
6876 *%$N%*|*%functions%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
6877 TEST="$NAME: TCP4 mapped into TCP6 address space"
6878 if ! eval $NUMCOND; then :;
6879 elif true; then
6880 $PRINTF "test $F_n $TEST... ${YELLOW}Feature removed${NORMAL}\n" $N
6881 numCANT=$((numCANT+1))
6882 listCANT="$listCANT $N"
6883 elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
6884 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
6885 numCANT=$((numCANT+1))
6886 listCANT="$listCANT $N"
6887 else
6888 tf="$td/test$N.stdout"
6889 te="$td/test$N.stderr"
6890 tdiff="$td/test$N.diff"
6891 newport tcp6; tsl=$PORT
6892 ts="127.0.0.1:$tsl"
6893 da="test$N $(date) $RANDOM"
6894 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$tsl,$REUSEADDR PIPE"
6895 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT TCP6:$ts"
6896 printf "test $F_n $TEST... " $N
6897 $CMD1 >"$tf" 2>"${te}1" &
6898 pid=$! # background process id
6899 waittcp6port $tsl 1
6900 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6901 if [ $? -ne 0 ]; then
6902 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6903 echo "$CMD1 &"
6904 echo "$CMD2"
6905 cat "${te}1"
6906 cat "${te}2"
6907 numFAIL=$((numFAIL+1))
6908 listFAIL="$listFAIL $N"
6909 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6910 $PRINTF "$FAILED: diff:\n"
6911 cat "$tdiff"
6912 numFAIL=$((numFAIL+1))
6913 listFAIL="$listFAIL $N"
6914 else
6915 $PRINTF "$OK\n"
6916 if [ -n "$debug" ]; then cat $te; fi
6917 numOK=$((numOK+1))
6918 listOK="$listOK $N"
6920 kill $pid 2>/dev/null; wait
6921 fi ;; # NUMCOND, feats
6922 esac
6923 N=$((N+1))
6926 # test the UDP4-SENDTO and UDP4-RECVFROM addresses together
6927 NAME=UDP4DGRAM
6928 case "$TESTS" in
6929 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*)
6930 TEST="$NAME: UDP/IPv4 sendto and recvfrom"
6931 # start a UDP4-RECVFROM process that echoes data, and send test data using
6932 # UDP4-SENDTO. The sent data should be returned.
6933 if ! eval $NUMCOND; then :; else
6934 tf="$td/test$N.stdout"
6935 te="$td/test$N.stderr"
6936 tdiff="$td/test$N.diff"
6937 newport udp4; ts1p=$PORT
6938 ts1a="127.0.0.1"
6939 ts1="$ts1a:$ts1p"
6940 newport udp4; ts2p=$PORT
6941 ts2="127.0.0.1:$ts2p"
6942 da="test$N $(date) $RANDOM"
6943 CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
6944 CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=$ts2"
6945 printf "test $F_n $TEST... " $N
6946 $CMD1 2>"${te}1" &
6947 pid1="$!"
6948 waitudp4port $ts1p 1
6949 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
6950 rc2="$?"
6951 kill "$pid1" 2>/dev/null; wait;
6952 if [ "$rc2" -ne 0 ]; then
6953 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
6954 echo "$CMD1 &"
6955 cat "${te}1"
6956 echo "$CMD2"
6957 cat "${te}2"
6958 numFAIL=$((numFAIL+1))
6959 listFAIL="$listFAIL $N"
6960 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
6961 $PRINTF "$FAILED\n"
6962 cat "$tdiff"
6963 echo "$CMD1 &"
6964 cat "${te}1"
6965 echo "$CMD2"
6966 cat "${te}2"
6967 numFAIL=$((numFAIL+1))
6968 listFAIL="$listFAIL $N"
6969 else
6970 $PRINTF "$OK\n"
6971 if [ -n "$debug" ]; then cat $te; fi
6972 numOK=$((numOK+1))
6973 listOK="$listOK $N"
6975 fi # NUMCOND
6977 esac
6978 N=$((N+1))
6981 NAME=UDP6DGRAM
6982 case "$TESTS" in
6983 *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%$NAME%*)
6984 TEST="$NAME: UDP/IPv6 datagram"
6985 if ! eval $NUMCOND; then :;
6986 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
6987 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
6988 numCANT=$((numCANT+1))
6989 listCANT="$listCANT $N"
6990 else
6991 tf="$td/test$N.stdout"
6992 te="$td/test$N.stderr"
6993 tdiff="$td/test$N.diff"
6994 newport udp6; ts1p=$PORT
6995 tsa="[::1]"
6996 ts1="$tsa:$ts1p"
6997 newport udp6; ts2p=$PORT
6998 ts2="$tsa:$ts2p"
6999 da="test$N $(date) $RANDOM"
7000 CMD1="$TRACE $SOCAT $opts UDP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
7001 CMD2="$TRACE $SOCAT $opts - UDP6-SENDTO:$ts1,bind=$ts2"
7002 printf "test $F_n $TEST... " $N
7003 $CMD1 2>"${te}1" &
7004 waitudp6port $ts1p 1
7005 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
7006 if [ $? -ne 0 ]; then
7007 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7008 echo "$CMD1 &"
7009 echo "$CMD2"
7010 cat "${te}1"
7011 cat "${te}2"
7012 numFAIL=$((numFAIL+1))
7013 listFAIL="$listFAIL $N"
7014 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7015 $PRINTF "$FAILED\n"
7016 cat "$tdiff"
7017 numFAIL=$((numFAIL+1))
7018 listFAIL="$listFAIL $N"
7019 else
7020 $PRINTF "$OK\n"
7021 if [ -n "$debug" ]; then cat ${te}1 ${te}2; fi
7022 numOK=$((numOK+1))
7023 listOK="$listOK $N"
7025 fi ;; # NUMCOND, feats
7026 esac
7027 N=$((N+1))
7030 NAME=RAWIP4RECVFROM
7031 case "$TESTS" in
7032 *%$N%*|*%functions%*|*%ip%*|*%ip4%*|*%rawip%*|*%rawip4%*|*%dgram%*|*%root%*|*%$NAME%*)
7033 TEST="$NAME: raw IPv4 datagram"
7034 if ! eval $NUMCOND; then :;
7035 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7036 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7037 numCANT=$((numCANT+1))
7038 listCANT="$listCANT $N"
7039 else
7040 tf="$td/test$N.stdout"
7041 te="$td/test$N.stderr"
7042 tdiff="$td/test$N.diff"
7043 ts1p=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7044 ts1a="127.0.0.1"
7045 ts1="$ts1a:$ts1p"
7046 ts2a="$SECONDADDR"
7047 ts2="$ts2a:$ts2p"
7048 da="test$N $(date) $RANDOM"
7049 CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,bind=$ts1a PIPE"
7050 CMD2="$TRACE $SOCAT $opts - IP4-SENDTO:$ts1,bind=$ts2a"
7051 printf "test $F_n $TEST... " $N
7052 $CMD1 2>"${te}1" &
7053 pid1=$!
7054 waitip4proto $ts1p 1
7055 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
7056 rc2=$?
7057 kill $pid1 2>/dev/null; wait
7058 if [ $rc2 -ne 0 ]; then
7059 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7060 echo "$CMD1 &"
7061 echo "$CMD2"
7062 cat "${te}1"
7063 cat "${te}2"
7064 numFAIL=$((numFAIL+1))
7065 listFAIL="$listFAIL $N"
7066 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7067 $PRINTF "$FAILED\n"
7068 cat "$tdiff"
7069 numFAIL=$((numFAIL+1))
7070 listFAIL="$listFAIL $N"
7071 else
7072 $PRINTF "$OK\n"
7073 if [ -n "$debug" ]; then cat $te; fi
7074 numOK=$((numOK+1))
7075 listOK="$listOK $N"
7077 fi ;; # root, NUMCOND
7078 esac
7079 N=$((N+1))
7082 if false; then
7083 NAME=RAWIP6RECVFROM
7084 case "$TESTS" in
7085 *%$N%*|*%functions%*|*%ip%*|*%ip6%*|*%rawip%*|*%rawip6%*|*%dgram%*|*%root%*|*%$NAME%*)
7086 TEST="$NAME: raw IPv6 datagram by self addressing"
7087 if ! eval $NUMCOND; then :;
7088 elif ! feat=$(testfeats ip6 rawip && runsip6); then
7089 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7090 numCANT=$((numCANT+1))
7091 listCANT="$listCANT $N"
7092 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7093 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7094 numCANT=$((numCANT+1))
7095 listCANT="$listCANT $N"
7096 else
7097 tf="$td/test$N.stdout"
7098 te="$td/test$N.stderr"
7099 tdiff="$td/test$N.diff"
7100 ts1p=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7101 tsa="[::1]"
7102 ts1="$tsa:$ts1p"
7103 ts2="$tsa"
7104 da="test$N $(date) $RANDOM"
7105 #CMD1="$TRACE $SOCAT $opts IP6-RECVFROM:$ts1p,reuseaddr,bind=$tsa PIPE"
7106 CMD2="$TRACE $SOCAT $opts - IP6-SENDTO:$ts1,bind=$ts2"
7107 printf "test $F_n $TEST... " $N
7108 #$CMD1 2>"${te}1" &
7109 waitip6proto $ts1p 1
7110 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
7111 if [ $? -ne 0 ]; then
7112 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7113 # echo "$CMD1 &"
7114 # cat "${te}1"
7115 echo "$CMD2"
7116 cat "${te}2"
7117 numFAIL=$((numFAIL+1))
7118 listFAIL="$listFAIL $N"
7119 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7120 $PRINTF "$FAILED\n"
7121 cat "$tdiff"
7122 numFAIL=$((numFAIL+1))
7123 listFAIL="$listFAIL $N"
7124 else
7125 $PRINTF "$OK\n"
7126 if [ -n "$debug" ]; then cat "$te"; fi
7127 numOK=$((numOK+1))
7128 listOK="$listOK $N"
7130 fi ;; # root, NUMCOND
7131 esac
7132 N=$((N+1))
7133 fi #false
7136 NAME=UNIXDGRAM
7137 case "$TESTS" in
7138 *%$N%*|*%functions%*|*%engine%*|*%unix%*|*%dgram%*|*%$NAME%*)
7139 TEST="$NAME: UNIX datagram"
7140 if ! eval $NUMCOND; then :; else
7141 tf="$td/test$N.stdout"
7142 te="$td/test$N.stderr"
7143 tdiff="$td/test$N.diff"
7144 ts1="$td/test$N.socket1"
7145 ts2="$td/test$N.socket2"
7146 da="test$N $(date) $RANDOM"
7147 CMD1="$TRACE $SOCAT $opts UNIX-RECVFROM:$ts1,reuseaddr PIPE"
7148 CMD2="$TRACE $SOCAT $opts - UNIX-SENDTO:$ts1,bind=$ts2"
7149 printf "test $F_n $TEST... " $N
7150 $CMD1 2>"${te}1" &
7151 pid1="$!"
7152 waitfile $ts1 1
7153 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
7154 rc2=$?
7155 kill "$pid1" 2>/dev/null; wait
7156 if [ $rc2 -ne 0 ]; then
7157 $PRINTF "$FAILED (rc=$rc2)\n"
7158 echo "$CMD1 &"
7159 cat "${te}1" >&2
7160 echo "$CMD2"
7161 cat "${te}2" >&2
7162 numFAIL=$((numFAIL+1))
7163 listFAIL="$listFAIL $N"
7164 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7165 $PRINTF "$FAILED (diff)\n"
7166 echo "$CMD1 &"
7167 cat "${te}1" >&2
7168 echo "$CMD2"
7169 cat "${te}2" >&2
7170 echo "// diff:" >&2
7171 cat "$tdiff" >&2
7172 numFAIL=$((numFAIL+1))
7173 listFAIL="$listFAIL $N"
7174 else
7175 $PRINTF "$OK\n"
7176 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
7177 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
7178 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
7179 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
7180 numOK=$((numOK+1))
7181 listOK="$listOK $N"
7183 fi # NUMCOND
7185 esac
7186 N=$((N+1))
7189 NAME=UDP4RECV
7190 case "$TESTS" in
7191 *%$N%*|*%functions%*|*%engine%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%$NAME%*)
7192 TEST="$NAME: UDP/IPv4 receive"
7193 if ! eval $NUMCOND; then :; else
7194 tf="$td/test$N.stdout"
7195 te="$td/test$N.stderr"
7196 tdiff="$td/test$N.diff"
7197 newport udp4; ts1p=$PORT
7198 ts1a="127.0.0.1"
7199 ts1="$ts1a:$ts1p"
7200 da="test$N $(date) $RANDOM"
7201 CMD1="$TRACE $SOCAT $opts -u UDP4-RECV:$ts1p,reuseaddr -"
7202 CMD2="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1"
7203 printf "test $F_n $TEST... " $N
7204 $CMD1 >"$tf" 2>"${te}1" &
7205 pid1="$!"
7206 waitudp4port $ts1p 1
7207 echo "$da" |$CMD2 2>>"${te}2"
7208 rc2="$?"
7209 #ls -l $tf
7210 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
7211 kill "$pid1" 2>/dev/null; wait
7212 if [ "$rc2" -ne 0 ]; then
7213 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7214 echo "$CMD1 &"
7215 echo "$CMD2"
7216 cat "${te}1"
7217 cat "${te}2"
7218 numFAIL=$((numFAIL+1))
7219 listFAIL="$listFAIL $N"
7220 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7221 $PRINTF "$FAILED\n"
7222 cat "$tdiff"
7223 echo "$CMD1 &"
7224 echo "$CMD2"
7225 cat "${te}1"
7226 cat "${te}2"
7227 numFAIL=$((numFAIL+1))
7228 listFAIL="$listFAIL $N"
7229 else
7230 $PRINTF "$OK\n"
7231 if [ -n "$debug" ]; then cat $te; fi
7232 numOK=$((numOK+1))
7233 listOK="$listOK $N"
7235 fi # NUMCOND
7237 esac
7238 N=$((N+1))
7241 NAME=UDP6RECV
7242 case "$TESTS" in
7243 *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%udp%*|*%udp6%*|*%recv%*|*%$NAME%*)
7244 TEST="$NAME: UDP/IPv6 receive"
7245 if ! eval $NUMCOND; then :;
7246 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
7247 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
7248 numCANT=$((numCANT+1))
7249 listCANT="$listCANT $N"
7250 else
7251 tf="$td/test$N.stdout"
7252 te="$td/test$N.stderr"
7253 tdiff="$td/test$N.diff"
7254 newport udp6; ts1p=$PORT
7255 ts1a="[::1]"
7256 ts1="$ts1a:$ts1p"
7257 da="test$N $(date) $RANDOM"
7258 CMD1="$TRACE $SOCAT $opts -u UDP6-RECV:$ts1p,reuseaddr -"
7259 CMD2="$TRACE $SOCAT $opts -u - UDP6-SENDTO:$ts1"
7260 printf "test $F_n $TEST... " $N
7261 $CMD1 >"$tf" 2>"${te}1" &
7262 pid1="$!"
7263 waitudp6port $ts1p 1
7264 echo "$da" |$CMD2 2>>"${te}2"
7265 rc2="$?"
7266 #ls -l $tf
7267 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
7268 kill "$pid1" 2>/dev/null; wait
7269 if [ "$rc2" -ne 0 ]; then
7270 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7271 echo "$CMD1 &"
7272 echo "$CMD2"
7273 cat "${te}1"
7274 cat "${te}2"
7275 numFAIL=$((numFAIL+1))
7276 listFAIL="$listFAIL $N"
7277 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7278 $PRINTF "$FAILED\n"
7279 cat "$tdiff"
7280 numFAIL=$((numFAIL+1))
7281 listFAIL="$listFAIL $N"
7282 else
7283 $PRINTF "$OK\n"
7284 if [ -n "$debug" ]; then cat $te; fi
7285 numOK=$((numOK+1))
7286 listOK="$listOK $N"
7288 fi ;; # NUMCOND, feats
7289 esac
7290 N=$((N+1))
7293 NAME=RAWIP4RECV
7294 case "$TESTS" in
7295 *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*)
7296 TEST="$NAME: raw IPv4 receive"
7297 if ! eval $NUMCOND; then :;
7298 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7299 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7300 numCANT=$((numCANT+1))
7301 listCANT="$listCANT $N"
7302 else
7303 tf="$td/test$N.stdout"
7304 te="$td/test$N.stderr"
7305 tdiff="$td/test$N.diff"
7306 ts1p=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7307 ts1a="127.0.0.1"
7308 ts1="$ts1a:$ts1p"
7309 da="test$N $(date) $RANDOM"
7310 CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,reuseaddr -"
7311 CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1"
7312 printf "test $F_n $TEST... " $N
7313 $CMD1 >"$tf" 2>"${te}1" &
7314 pid1="$!"
7315 waitip4proto $ts1p 1
7316 echo "$da" |$CMD2 2>>"${te}2"
7317 rc2="$?"
7318 #ls -l $tf
7319 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
7320 kill "$pid1" 2>/dev/null; wait
7321 if [ "$rc2" -ne 0 ]; then
7322 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7323 echo "$CMD1 &"
7324 echo "$CMD2"
7325 cat "${te}1"
7326 cat "${te}2"
7327 numFAIL=$((numFAIL+1))
7328 listFAIL="$listFAIL $N"
7329 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7330 $PRINTF "$FAILED\n"
7331 cat "$tdiff"
7332 numFAIL=$((numFAIL+1))
7333 listFAIL="$listFAIL $N"
7334 else
7335 $PRINTF "$OK\n"
7336 if [ -n "$debug" ]; then cat $te; fi
7337 numOK=$((numOK+1))
7338 listOK="$listOK $N"
7340 fi ;; # NUMCOND, root
7341 esac
7342 N=$((N+1))
7345 NAME=RAWIP6RECV
7346 case "$TESTS" in
7347 *%$N%*|*%functions%*|*%ip6%*|*%dgram%*|*%rawip%*|*%rawip6%*|*%recv%*|*%root%*|*%$NAME%*)
7348 TEST="$NAME: raw IPv6 receive"
7349 if ! eval $NUMCOND; then :;
7350 elif ! feat=$(testfeats ip6 rawip && runsip6); then
7351 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7352 numCANT=$((numCANT+1))
7353 listCANT="$listCANT $N"
7354 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7355 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7356 numCANT=$((numCANT+1))
7357 listCANT="$listCANT $N"
7358 else
7359 tf="$td/test$N.stdout"
7360 te="$td/test$N.stderr"
7361 tdiff="$td/test$N.diff"
7362 ts1p=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7363 ts1a="[::1]"
7364 ts1="$ts1a:$ts1p"
7365 da="test$N $(date) $RANDOM"
7366 CMD1="$TRACE $SOCAT $opts -u IP6-RECV:$ts1p,reuseaddr -"
7367 CMD2="$TRACE $SOCAT $opts -u - IP6-SENDTO:$ts1"
7368 printf "test $F_n $TEST... " $N
7369 $CMD1 >"$tf" 2>"${te}1" &
7370 pid1="$!"
7371 waitip6proto $ts1p 1
7372 echo "$da" |$CMD2 2>>"${te}2"
7373 rc2="$?"
7374 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
7375 kill "$pid1" 2>/dev/null; wait
7376 if [ "$rc2" -ne 0 ]; then
7377 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7378 echo "$CMD1 &"
7379 echo "$CMD2"
7380 cat "${te}1"
7381 cat "${te}2"
7382 numFAIL=$((numFAIL+1))
7383 listFAIL="$listFAIL $N"
7384 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7385 $PRINTF "$FAILED\n"
7386 cat "$tdiff"
7387 numFAIL=$((numFAIL+1))
7388 listFAIL="$listFAIL $N"
7389 else
7390 $PRINTF "$OK\n"
7391 if [ -n "$debug" ]; then cat $te; fi
7392 numOK=$((numOK+1))
7393 listOK="$listOK $N"
7395 fi ;; # NUMCOND, root
7396 esac
7397 N=$((N+1))
7400 NAME=UNIXRECV
7401 case "$TESTS" in
7402 *%$N%*|*%functions%*|*%unix%*|*%dgram%*|*%recv%*|*%$NAME%*)
7403 TEST="$NAME: UNIX receive"
7404 if ! eval $NUMCOND; then :; else
7405 ts="$td/test$N.socket"
7406 tf="$td/test$N.stdout"
7407 te="$td/test$N.stderr"
7408 tdiff="$td/test$N.diff"
7409 ts1="$ts"
7410 da="test$N $(date) $RANDOM"
7411 CMD1="$TRACE $SOCAT $opts -u UNIX-RECV:$ts1,reuseaddr -"
7412 CMD2="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts1"
7413 printf "test $F_n $TEST... " $N
7414 $CMD1 >"$tf" 2>"${te}1" &
7415 pid1="$!"
7416 waitfile $ts1 1
7417 echo "$da" |$CMD2 2>>"${te}2"
7418 rc2="$?"
7419 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
7420 kill "$pid1" 2>/dev/null; wait
7421 if [ "$rc2" -ne 0 ]; then
7422 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7423 echo "$CMD1 &"
7424 echo "$CMD2"
7425 cat "${te}1"
7426 cat "${te}2"
7427 numFAIL=$((numFAIL+1))
7428 listFAIL="$listFAIL $N"
7429 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
7430 $PRINTF "$FAILED\n"
7431 cat "$tdiff"
7432 numFAIL=$((numFAIL+1))
7433 listFAIL="$listFAIL $N"
7434 else
7435 $PRINTF "$OK\n"
7436 if [ -n "$debug" ]; then cat $te; fi
7437 numOK=$((numOK+1))
7438 listOK="$listOK $N"
7440 fi # NUMCOND
7442 esac
7443 N=$((N+1))
7446 NAME=UDP4RECVFROM_SOURCEPORT
7447 case "$TESTS" in
7448 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*)
7449 TEST="$NAME: security of UDP4-RECVFROM with SOURCEPORT option"
7450 if ! eval $NUMCOND; then :;
7451 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7452 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7453 numCANT=$((numCANT+1))
7454 listCANT="$listCANT $N"
7455 else
7456 newport udp4 # provide free port number in $PORT
7457 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7458 fi ;; # NUMCOND, feats
7459 esac
7460 N=$((N+1))
7462 NAME=UDP4RECVFROM_LOWPORT
7463 case "$TESTS" in
7464 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*)
7465 TEST="$NAME: security of UDP4-RECVFROM with LOWPORT option"
7466 if ! eval $NUMCOND; then :;
7467 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7468 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7469 numCANT=$((numCANT+1))
7470 listCANT="$listCANT $N"
7471 else
7472 newport udp4 # provide free port number in $PORT
7473 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7474 fi ;; # NUMCOND, feats
7475 esac
7476 N=$((N+1))
7478 NAME=UDP4RECVFROM_RANGE
7479 case "$TESTS" in
7480 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*)
7481 TEST="$NAME: security of UDP4-RECVFROM with RANGE option"
7482 newport udp4 # provide free port number in $PORT
7483 #testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr,fork" "" "range=$SECONDADDR/32" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7484 if ! eval $NUMCOND; then :; else
7485 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "range=$SECONDADDR/32" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7486 fi ;; # NUMCOND
7487 esac
7488 N=$((N+1))
7490 NAME=UDP4RECVFROM_TCPWRAP
7491 case "$TESTS" in
7492 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*)
7493 TEST="$NAME: security of UDP4-RECVFROM with TCPWRAP option"
7494 if ! eval $NUMCOND; then :;
7495 elif ! feat=$(testfeats ip4 udp libwrap) || ! runsip4 >/dev/null; then
7496 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7497 numCANT=$((numCANT+1))
7498 listCANT="$listCANT $N"
7499 else
7500 ha="$td/hosts.allow"
7501 hd="$td/hosts.deny"
7502 $ECHO "socat: $SECONDADDR" >"$ha"
7503 $ECHO "ALL: ALL" >"$hd"
7504 newport udp4 # provide free port number in $PORT
7505 #testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr,fork" "" "tcpwrap=$d" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7506 testserversec "$N" "$TEST" "$opts" "UDP4-RECVFROM:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP4-SENDTO:127.0.0.1:$PORT" 4 udp $PORT 0
7507 fi ;; # NUMCOND, feats
7508 esac
7509 N=$((N+1))
7512 NAME=UDP4RECV_SOURCEPORT
7513 case "$TESTS" in
7514 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%sourceport%*|*%$NAME%*)
7515 TEST="$NAME: security of UDP4-RECV with SOURCEPORT option"
7516 if ! eval $NUMCOND; then :;
7517 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7518 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7519 numCANT=$((numCANT+1))
7520 listCANT="$listCANT $N"
7521 else
7522 newport udp4; PORT1=$PORT
7523 newport udp4; PORT2=$PORT
7524 newport udp4; PORT3=$PORT
7525 # we use the forward channel (PORT1) for testing, and have a backward channel
7526 # (PORT2) to get the data back, so we get the classical echo behaviour
7527 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
7528 fi ;; # NUMCOND, feats
7529 esac
7530 N=$((N+1))
7532 NAME=UDP4RECV_LOWPORT
7533 case "$TESTS" in
7534 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%lowport%*|*%$NAME%*)
7535 TEST="$NAME: security of UDP4-RECV with LOWPORT option"
7536 if ! eval $NUMCOND; then :;
7537 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7538 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7539 numCANT=$((numCANT+1))
7540 listCANT="$listCANT $N"
7541 else
7542 newport udp4; PORT1=$PORT
7543 newport udp4; PORT2=$PORT
7544 # we use the forward channel (PORT1) for testing, and have a backward channel
7545 # (PORT2) to get the data back, so we get the classical echo behaviour
7546 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
7547 fi ;; # NUMCOND, feats
7548 esac
7549 N=$((N+1))
7551 NAME=UDP4RECV_RANGE
7552 case "$TESTS" in
7553 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%range%*|*%$NAME%*)
7554 TEST="$NAME: security of UDP4-RECV with RANGE option"
7555 if ! eval $NUMCOND; then :;
7556 elif ! feat=$(testfeats udp ip4) || ! runsip4 >/dev/null; then
7557 $PRINTF "test $F_n $TEST... ${YELLOW}UDP4 not available${NORMAL}\n" $N
7558 numCANT=$((numCANT+1))
7559 listCANT="$listCANT $N"
7560 else
7561 newport udp4; PORT1=$PORT
7562 newport udp4; PORT2=$PORT
7563 # we use the forward channel (PORT1) for testing, and have a backward channel
7564 # (PORT2) to get the data back, so we get the classical echo behaviour
7565 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
7566 fi ;; # NUMCOND, feats
7567 esac
7568 N=$((N+1))
7570 NAME=UDP4RECV_TCPWRAP
7571 case "$TESTS" in
7572 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%tcpwrap%*|*%$NAME%*)
7573 TEST="$NAME: security of UDP4-RECV with TCPWRAP option"
7574 if ! eval $NUMCOND; then :;
7575 elif ! feat=$(testfeats udp ip4 libwrap) || ! runsip4 >/dev/null; then
7576 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7577 numCANT=$((numCANT+1))
7578 listCANT="$listCANT $N"
7579 else
7580 newport udp4; PORT1=$PORT
7581 newport udp4; PORT2=$PORT
7582 ha="$td/hosts.allow"
7583 hd="$td/hosts.deny"
7584 $ECHO "socat: $SECONDADDR" >"$ha"
7585 $ECHO "ALL: ALL" >"$hd"
7586 # we use the forward channel (PORT1) for testing, and have a backward channel
7587 # (PORT2) to get the data back, so we get the classical echo behaviour
7588 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
7589 fi ;; # NUMCOND, feats
7590 esac
7591 N=$((N+1))
7594 NAME=UDP6RECVFROM_SOURCEPORT
7595 case "$TESTS" in
7596 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*)
7597 TEST="$NAME: security of UDP6-RECVFROM with SOURCEPORT option"
7598 if ! eval $NUMCOND; then :;
7599 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7600 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7601 numCANT=$((numCANT+1))
7602 listCANT="$listCANT $N"
7603 else
7604 newport udp6 # provide free port number in $PORT
7605 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "sp=$PORT" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7606 fi ;; # NUMCOND, feats
7607 esac
7608 N=$((N+1))
7610 NAME=UDP6RECVFROM_LOWPORT
7611 case "$TESTS" in
7612 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*)
7613 TEST="$NAME: security of UDP6-RECVFROM with LOWPORT option"
7614 if ! eval $NUMCOND; then :;
7615 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7616 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7617 numCANT=$((numCANT+1))
7618 listCANT="$listCANT $N"
7619 else
7620 newport udp6 # provide free port number in $PORT
7621 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "lowport" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7622 fi ;; # NUMCOND, feats
7623 esac
7624 N=$((N+1))
7626 NAME=UDP6RECVFROM_RANGE
7627 case "$TESTS" in
7628 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*)
7629 TEST="$NAME: security of UDP6-RECVFROM with RANGE option"
7630 if ! eval $NUMCOND; then :;
7631 elif ! feat=$(testfeats tcp ip6) || ! runsip6 >/dev/null; then
7632 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
7633 numCANT=$((numCANT+1))
7634 listCANT="$listCANT $N"
7635 else
7636 newport udp6 # provide free port number in $PORT
7637 #testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr,fork" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7638 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "range=[::2]/128" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7639 fi ;; # NUMCOND, feats
7640 esac
7641 N=$((N+1))
7643 NAME=UDP6RECVFROM_TCPWRAP
7644 case "$TESTS" in
7645 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*)
7646 TEST="$NAME: security of UDP6-RECVFROM with TCPWRAP option"
7647 if ! eval $NUMCOND; then :;
7648 elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then
7649 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7650 numCANT=$((numCANT+1))
7651 listCANT="$listCANT $N"
7652 else
7653 ha="$td/hosts.allow"
7654 hd="$td/hosts.deny"
7655 $ECHO "socat: [::2]" >"$ha"
7656 $ECHO "ALL: ALL" >"$hd"
7657 newport udp6 # provide free port number in $PORT
7658 testserversec "$N" "$TEST" "$opts" "UDP6-RECVFROM:$PORT,reuseaddr" "" "tcpwrap-etc=$td" "UDP6-SENDTO:[::1]:$PORT" 6 udp $PORT 0
7659 fi ;; # NUMCOND, feats
7660 esac
7661 N=$((N+1))
7664 NAME=UDP6RECV_SOURCEPORT
7665 case "$TESTS" in
7666 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%sourceport%*|*%$NAME%*)
7667 TEST="$NAME: security of UDP6-RECV with SOURCEPORT option"
7668 if ! eval $NUMCOND; then :;
7669 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7670 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7671 numCANT=$((numCANT+1))
7672 listCANT="$listCANT $N"
7673 else
7674 newport udp6; PORT1=$PORT
7675 newport udp6; PORT2=$PORT
7676 newport udp6; PORT3=$PORT
7677 # we use the forward channel (PORT1) for testing, and have a backward channel
7678 # (PORT2) to get the data back, so we get the classical echo behaviour
7679 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
7680 fi ;; # NUMCOND, feats
7681 esac
7682 N=$((N+1))
7684 NAME=UDP6RECV_LOWPORT
7685 case "$TESTS" in
7686 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%lowport%*|*%$NAME%*)
7687 TEST="$NAME: security of UDP6-RECV with LOWPORT option"
7688 if ! eval $NUMCOND; then :;
7689 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7690 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7691 numCANT=$((numCANT+1))
7692 listCANT="$listCANT $N"
7693 else
7694 newport udp6; PORT1=$PORT
7695 newport udp6; PORT2=$PORT
7696 # we use the forward channel (PORT1) for testing, and have a backward channel
7697 # (PORT2) to get the data back, so we get the classical echo behaviour
7698 testserversec "$N" "$TEST" "$opts" "UDP6-RECV:$PORT1,reuseaddr!!UDP6-SENDTO:[::1]:$PORT2" "" "lowport" "UDP6-RECV:$PORT2!!UDP6-SENDTO:[::1]:$PORT1" 6 udp $PORT1 0
7699 fi ;; # NUMCOND, feats
7700 esac
7701 N=$((N+1))
7703 NAME=UDP6RECV_RANGE
7704 case "$TESTS" in
7705 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%range%*|*%$NAME%*)
7706 TEST="$NAME: security of UDP6-RECV with RANGE option"
7707 if ! eval $NUMCOND; then :;
7708 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
7709 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
7710 numCANT=$((numCANT+1))
7711 listCANT="$listCANT $N"
7712 else
7713 newport udp6; PORT1=$PORT
7714 newport udp6; PORT2=$PORT
7715 # we use the forward channel (PORT1) for testing, and have a backward channel
7716 # (PORT2) to get the data back, so we get the classical echo behaviour
7717 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
7718 fi ;; # NUMCOND, feats
7719 esac
7720 N=$((N+1))
7722 NAME=UDP6RECV_TCPWRAP
7723 case "$TESTS" in
7724 *%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp6%*|*%ip6%*|*%tcpwrap%*|*%$NAME%*)
7725 TEST="$NAME: security of UDP6-RECV with TCPWRAP option"
7726 if ! eval $NUMCOND; then :;
7727 elif ! feat=$(testfeats udp ip6 libwrap && runsip6); then
7728 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7729 numCANT=$((numCANT+1))
7730 listCANT="$listCANT $N"
7731 else
7732 ha="$td/hosts.allow"
7733 hd="$td/hosts.deny"
7734 $ECHO "socat: [::2]" >"$ha"
7735 $ECHO "ALL: ALL" >"$hd"
7736 newport udp6; PORT1=$PORT
7737 newport udp6; PORT2=$PORT
7738 # we use the forward channel (PORT1) for testing, and have a backward channel
7739 # (PORT2) to get the data back, so we get the classical echo behaviour
7740 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
7741 fi ;; # NUMCOND, feats
7742 esac
7743 N=$((N+1))
7746 NAME=IP4RECVFROM_RANGE
7747 case "$TESTS" in
7748 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*)
7749 TEST="$NAME: security of IP4-RECVFROM with RANGE option"
7750 if ! eval $NUMCOND; then :;
7751 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
7752 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7753 numCANT=$((numCANT+1))
7754 listCANT="$listCANT $N"
7755 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7756 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7757 numCANT=$((numCANT+1))
7758 listCANT="$listCANT $N"
7759 else
7760 newport udp4 # provide free port number in $PORT
7761 #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=$SECONDADDR/32" "IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0
7762 testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT" "" "range=$SECONDADDR/32" "UDP4-RECV:$PORT!!IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0
7763 fi ;; # NUMCOND, feats, root
7764 esac
7765 #IPPROTO=$((IPPROTO+1))
7766 N=$((N+1))
7768 NAME=IP4RECVFROM_TCPWRAP
7769 case "$TESTS" in
7770 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7771 TEST="$NAME: security of IP4-RECVFROM with TCPWRAP option"
7772 if ! eval $NUMCOND; then :;
7773 elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then
7774 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7775 numCANT=$((numCANT+1))
7776 listCANT="$listCANT $N"
7777 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7778 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7779 numCANT=$((numCANT+1))
7780 listCANT="$listCANT $N"
7781 else
7782 ha="$td/hosts.allow"
7783 hd="$td/hosts.deny"
7784 $ECHO "socat: $SECONDADDR" >"$ha"
7785 $ECHO "ALL: ALL" >"$hd"
7786 newport udp4 # provide free port number in $PORT
7787 #testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0
7788 testserversec "$N" "$TEST" "$opts" "IP4-RECVFROM:$IPPROTO,reuseaddr!!UDP4-SENDTO:127.0.0.1:$PORT" "" "tcpwrap-etc=$td" "UDP4-RECV:$PORT!!IP4-SENDTO:127.0.0.1:$IPPROTO" 4 ip $IPPROTO 0
7789 fi # NUMCOND, feats, root
7791 esac
7792 #IPPROTO=$((IPPROTO+1))
7793 N=$((N+1))
7796 NAME=IP4RECV_RANGE
7797 case "$TESTS" in
7798 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%range%*|*%root%*|*%$NAME%*)
7799 TEST="$NAME: security of IP4-RECV with RANGE option"
7800 if ! eval $NUMCOND; then :;
7801 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
7802 $PRINTF "test $F_n $TEST... ${YELLOW}IP4 not available${NORMAL}\n" $N
7803 numCANT=$((numCANT+1))
7804 listCANT="$listCANT $N"
7805 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7806 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7807 numCANT=$((numCANT+1))
7808 listCANT="$listCANT $N"
7809 else
7810 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7811 IPPROTO2=$((IPPROTO+1))
7812 # we use the forward channel (IPPROTO1) for testing, and have a backward channel
7813 # (IPPROTO2) to get the data back, so we get the classical echo behaviour
7814 testserversec "$N" "$TEST" "$opts" "ip4-recv:$IPPROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$IPPROTO2" "" "range=$SECONDADDR/32" "ip4-recv:$IPPROTO2!!ip4-sendto:127.0.0.1:$IPPROTO1" 4 ip $IPPROTO1 0
7815 fi ;; # NUMCOND, feats, root
7816 esac
7817 #IPPROTO=$((IPPROTO+1))
7818 N=$((N+1))
7822 NAME=IP4RECV_TCPWRAP
7823 case "$TESTS" in
7824 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip4%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7825 TEST="$NAME: security of IP4-RECV with TCPWRAP option"
7826 if ! eval $NUMCOND; then :;
7827 elif ! feat=$(testfeats ip4 rawip libwrap) || ! runsip4 >/dev/null; then
7828 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7829 numCANT=$((numCANT+1))
7830 listCANT="$listCANT $N"
7831 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7832 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7833 numCANT=$((numCANT+1))
7834 listCANT="$listCANT $N"
7835 else
7836 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7837 IPPROTO2=$((IPPROTO+1))
7838 ha="$td/hosts.allow"
7839 hd="$td/hosts.deny"
7840 $ECHO "socat: $SECONDADDR" >"$ha"
7841 $ECHO "ALL: ALL" >"$hd"
7842 # we use the forward channel (IPPROTO1) for testing, and have a backward channel
7843 # (IPPROTO2) to get the data back, so we get the classical echo behaviour
7844 testserversec "$N" "$TEST" "$opts" "ip4-recv:$IPPROTO1,reuseaddr!!ip4-sendto:127.0.0.1:$IPPROTO2" "" "tcpwrap-etc=$td" "ip4-recv:$IPPROTO2!!ip4-sendto:127.0.0.1:$IPPROTO1" 4 ip $IPPROTO1 0
7845 fi ;; # NUMCOND, feats, root
7846 esac
7847 #IPPROTO=$((IPPROTO+1))
7848 N=$((N+1))
7851 NAME=IP6RECVFROM_RANGE
7852 case "$TESTS" in
7853 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*)
7854 TEST="$NAME: security of IP6-RECVFROM with RANGE option"
7855 if ! eval $NUMCOND; then :;
7856 elif ! feat=$(testfeats ip6 rawip && runsip6); then
7857 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7858 numCANT=$((numCANT+1))
7859 listCANT="$listCANT $N"
7860 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7861 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7862 numCANT=$((numCANT+1))
7863 listCANT="$listCANT $N"
7864 else
7865 newport udp6 # provide free port number in $PORT
7866 #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr,fork" "" "range=[::2]/128" "IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0
7867 testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr!!UDP6-SENDTO:[::1]:$PORT" "" "range=[::2]/128" "UDP6-RECV:$PORT!!IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0
7868 fi ;; # NUMCOND, feats
7869 esac
7870 #IPPROTO=$((IPPROTO+1))
7871 N=$((N+1))
7873 NAME=IP6RECVFROM_TCPWRAP
7874 case "$TESTS" in
7875 *%$N%*|*%functions%*|*%security%*|*%fork%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7876 TEST="$NAME: security of IP6-RECVFROM with TCPWRAP option"
7877 if ! eval $NUMCOND; then :;
7878 elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then
7879 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7880 numCANT=$((numCANT+1))
7881 listCANT="$listCANT $N"
7882 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7883 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7884 numCANT=$((numCANT+1))
7885 listCANT="$listCANT $N"
7886 else
7887 ha="$td/hosts.allow"
7888 hd="$td/hosts.deny"
7889 $ECHO "socat: [::2]" >"$ha"
7890 $ECHO "ALL: ALL" >"$hd"
7891 newport udp6 # provide free port number in $PORT
7892 #testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr,fork" "" "tcpwrap-etc=$td" "IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0
7893 testserversec "$N" "$TEST" "$opts" "IP6-RECVFROM:$IPPROTO,reuseaddr!!UDP6-SENDTO:[::1]:$PORT" "" "tcpwrap-etc=$td" "UDP6-RECV:$PORT!!IP6-SENDTO:[::1]:$IPPROTO" 6 ip $IPPROTO 0
7894 fi ;; # NUMCOND, feats
7895 esac
7896 #IPPROTO=$((IPPROTO+1))
7897 N=$((N+1))
7900 NAME=IP6RECV_RANGE
7901 case "$TESTS" in
7902 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%range%*|*%root%*|*%$NAME%*)
7903 TEST="$NAME: security of IP6-RECV with RANGE option"
7904 if ! eval $NUMCOND; then :;
7905 elif ! feat=$(testfeats ip6 rawip) || ! runsip6 >/dev/null; then
7906 $PRINTF "test $F_n $TEST... ${YELLOW}raw IP6 not available${NORMAL}\n" $N
7907 numCANT=$((numCANT+1))
7908 listCANT="$listCANT $N"
7909 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7910 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7911 numCANT=$((numCANT+1))
7912 listCANT="$listCANT $N"
7913 else
7914 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7915 IPPROTO2=$((IPPROTO+1))
7916 # we use the forward channel (IPPROTO1) for testing, and have a backward channel
7917 # (IPPROTO2) to get the data back, so we get the classical echo behaviour
7918 testserversec "$N" "$TEST" "$opts" "ip6-recv:$IPPROTO1,reuseaddr!!ip6-sendto:[::1]:$IPPROTO2" "" "range=[::2]/128" "ip6-recv:$IPPROTO2!!ip6-sendto:[::1]:$IPPROTO1" 6 ip $IPPROTO1 0
7919 fi ;; # NUMCOND, feats
7920 esac
7921 #IPPROTO=$((IPPROTO+1))
7922 N=$((N+1))
7924 NAME=IP6RECV_TCPWRAP
7925 case "$TESTS" in
7926 *%$N%*|*%functions%*|*%security%*|*%ip%*|*%ip6%*|*%tcpwrap%*|*%root%*|*%$NAME%*)
7927 TEST="$NAME: security of IP6-RECV with TCPWRAP option"
7928 if ! eval $NUMCOND; then :;
7929 elif ! feat=$(testfeats ip6 rawip libwrap && runsip6); then
7930 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
7931 numCANT=$((numCANT+1))
7932 listCANT="$listCANT $N"
7933 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
7934 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
7935 numCANT=$((numCANT+1))
7936 listCANT="$listCANT $N"
7937 else
7938 IPPROTO1=$IPPROTO; #IPPROTO=$((IPPROTO+1))
7939 IPPROTO2=$((IPPROTO+1))
7940 ha="$td/hosts.allow"
7941 hd="$td/hosts.deny"
7942 $ECHO "socat: [::2]" >"$ha"
7943 $ECHO "ALL: ALL" >"$hd"
7944 # we use the forward channel (IPPROTO1) for testing, and have a backward channel
7945 # (IPPROTO2) to get the data back, so we get the classical echo behaviour
7946 testserversec "$N" "$TEST" "$opts" "ip6-recv:$IPPROTO1,reuseaddr!!ip6-sendto:[::1]:$IPPROTO2" "" "tcpwrap-etc=$td" "ip6-recv:$IPPROTO2!!ip6-sendto:[::1]:$IPPROTO1" 6 ip $IPPROTO1 0
7947 fi ;; # NUMCOND, feats
7948 esac
7949 #IPPROTO=$((IPPROTO+1))
7950 N=$((N+1))
7953 NAME=O_NOATIME_FILE
7954 case "$TESTS" in
7955 *%$N%*|*%functions%*|*%open%*|*%noatime%*|*%$NAME%*)
7956 TEST="$NAME: option O_NOATIME on file"
7957 # idea: create a file with o-noatime option; one second later create a file
7958 # without this option (using touch); one second later read from the first file.
7959 # Then we check which file has the later ATIME stamp. For this check we use
7960 # "ls -ltu" because it is more portable than "test ... -nt ..."
7961 if ! eval $NUMCOND; then :;
7962 elif ! testoptions o-noatime >/dev/null; then
7963 $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N
7964 numCANT=$((numCANT+1))
7965 listCANT="$listCANT $N"
7966 else
7967 tf="$td/test$N.file"
7968 te="$td/test$N.stderr"
7969 tdiff="$td/test$N.diff"
7970 da="test$N $(date) $RANDOM"
7971 $PRINTF "test $F_n $TEST... " $N
7972 CMD="$TRACE $SOCAT $opts -u open:\"${tf}1\",o-noatime /dev/null"
7973 # generate a file
7974 touch "${tf}1"
7975 sleep 1
7976 # generate a reference file
7977 touch "${tf}2"
7978 sleep 1
7979 # read from the first file
7980 $CMD 2>"$te"
7981 if [ $? -ne 0 ]; then # command failed
7982 $PRINTF "${FAILED}:\n"
7983 echo "$CMD"
7984 cat "$te"
7985 numFAIL=$((numFAIL+1))
7986 listFAIL="$listFAIL $N"
7987 else
7988 # check which file has a later atime stamp
7989 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
7990 then
7991 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
7992 echo "$CMD"
7993 cat "$te"
7994 numFAIL=$((numFAIL+1))
7995 listFAIL="$listFAIL $N"
7996 else
7997 $PRINTF "$OK\n"
7998 if [ -n "$debug" ]; then cat "$te"; fi
7999 numOK=$((numOK+1))
8000 listOK="$listOK $N"
8001 fi # wrong time stamps
8002 fi # command ok
8003 fi ;; # NUMCOND, feats
8004 esac
8005 N=$((N+1))
8007 NAME=O_NOATIME_FD
8008 case "$TESTS" in
8009 *%$N%*|*%functions%*|*%noatime%*|*%$NAME%*)
8010 TEST="$NAME: option O_NOATIME on file descriptor"
8011 # idea: use a fd of a file with o-noatime option; one second later create a file
8012 # without this option (using touch); one second later read from the first file.
8013 # Then we check which file has the later ATIME stamp. For this check we use
8014 # "ls -ltu" because it is more portable than "test ... -nt ..."
8015 if ! eval $NUMCOND; then :;
8016 elif ! testoptions o-noatime >/dev/null; then
8017 $PRINTF "test $F_n $TEST... ${YELLOW}o-noatime not available${NORMAL}\n" $N
8018 numCANT=$((numCANT+1))
8019 listCANT="$listCANT $N"
8020 else
8021 tf="$td/test$N.file"
8022 te="$td/test$N.stderr"
8023 tdiff="$td/test$N.diff"
8024 da="test$N $(date) $RANDOM"
8025 $PRINTF "test $F_n $TEST... " $N
8026 touch ${tf}1
8027 CMD="$TRACE $SOCAT $opts -u -,o-noatime /dev/null <${tf}1"
8028 # generate a file, len >= 1
8029 touch "${tf}1"
8030 sleep 1
8031 # generate a reference file
8032 touch "${tf}2"
8033 sleep 1
8034 # read from the first file
8035 sh -c "$CMD" 2>"$te"
8036 rc=$?
8037 if [ $rc -ne 0 ]; then # command failed
8038 $PRINTF "${FAILED} (rc=$rc):\n"
8039 echo "$CMD"
8040 cat "$te" >&2
8041 numFAIL=$((numFAIL+1))
8042 listFAIL="$listFAIL $N"
8043 else
8044 # check which file has a later atime stamp
8045 if [ $(ls -ltu "${tf}1" "${tf}2" |head -1 |sed 's/.* //') != "${tf}2" ];
8046 then
8047 $PRINTF "$FAILED (bad order):\n"
8048 echo "$CMD" >&2
8049 cat "$te"
8050 numFAIL=$((numFAIL+1))
8051 listFAIL="$listFAIL $N"
8052 else
8053 $PRINTF "$OK\n"
8054 if [ "$VERBOSE" ]; then echo "$CMD"; fi
8055 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
8056 numOK=$((numOK+1))
8057 listOK="$listOK $N"
8058 fi # wrong time stamps
8059 fi # command ok
8060 fi ;; # NUMCOND, feats
8061 esac
8062 N=$((N+1))
8064 NAME=FS_NOATIME
8065 case "$TESTS" in
8066 *%$N%*|*%functions%*|*%fs%*|*%noatime%*|*%$NAME%*)
8067 TEST="$NAME: extended file system options using fs noatime option"
8068 # idea: create a file with fs-noatime option; one second later create a file
8069 # without this option (using touch); one second later read from the first file.
8070 # Then we check which file has the later ATIME stamp. For this check we use
8071 # "ls -ltu" because it is more portable than "test ... -nt ..."
8072 if ! eval $NUMCOND; then :;
8073 elif ! testoptions fs-noatime >/dev/null; then
8074 $PRINTF "test $F_n $TEST... ${YELLOW}fs-noatime not available${NORMAL}\n" $N
8075 numCANT=$((numCANT+1))
8076 listCANT="$listCANT $N"
8077 else
8078 ts="$td/test$N.socket"
8079 tf="$td/test$N.file"
8080 te="$td/test$N.stderr"
8081 tdiff="$td/test$N.diff"
8082 ts1="$ts"
8083 da="test$N $(date) $RANDOM"
8084 $PRINTF "test $F_n $TEST... " $N
8085 CMD0="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\""
8086 CMD="$TRACE $SOCAT $opts -u /dev/null create:\"${tf}1\",fs-noatime"
8087 # check if this is a capable FS; lsattr does other things on AIX, thus socat
8088 $CMD0 2>"${te}0"
8089 if [ $? -ne 0 ]; then
8090 $PRINTF "${YELLOW} cannot test${NORMAL}\n"
8091 numCANT=$((numCANT+1))
8092 listCANT="$listCANT $N"
8093 else
8094 # generate a file with noatime, len >= 1
8095 $CMD 2>"$te"
8096 if [ $? -ne 0 ]; then # command failed
8097 $PRINTF "${YELLOW}impotent file system?${NORMAL}\n"
8098 echo "$CMD"
8099 cat "$te"
8100 numCANT=$((numCANT+1))
8101 listCANT="$listCANT $N"
8102 else
8103 sleep 1
8104 # generate a reference file
8105 touch "${tf}2"
8106 sleep 1
8107 # read from the first file
8108 cat "${tf}1" >/dev/null
8109 # check which file has a later atime stamp
8110 #if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |awk '{print($8);}') != "${tf}2" ];
8111 if [ $(ls -ltu "${tf}1" "${tf}2" |head -n 1 |sed "s|.*\\($td.*\\)|\1|g") != "${tf}2" ];
8112 then
8113 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8114 echo "$CMD"
8115 cat "$te"
8116 numFAIL=$((numFAIL+1))
8117 listFAIL="$listFAIL $N"
8118 else
8119 $PRINTF "$OK\n"
8120 if [ -n "$debug" ]; then cat "$te"; fi
8121 numOK=$((numOK+1))
8122 listOK="$listOK $N"
8124 fi # not impotent
8125 fi # can test
8126 fi ;; # NUMCOND, feats
8127 esac
8128 N=$((N+1))
8131 NAME=COOLWRITE
8132 case "$TESTS" in
8133 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*)
8134 TEST="$NAME: option cool-write"
8135 if ! eval $NUMCOND; then :;
8136 elif ! testoptions cool-write >/dev/null; then
8137 $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N
8138 numCANT=$((numCANT+1))
8139 listCANT="$listCANT $N"
8140 else
8141 #set -vx
8142 ti="$td/test$N.pipe"
8143 tf="$td/test$N.stdout"
8144 te="$td/test$N.stderr"
8145 tdiff="$td/test$N.diff"
8146 da="test$N $(date) $RANDOM"
8147 # a reader that will terminate after 1 byte
8148 CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
8149 CMD="$TRACE $SOCAT $opts -u - file:\"$ti\",cool-write"
8150 printf "test $F_n $TEST... " $N
8151 $CMD1 2>"${te}1" &
8152 bg=$! # background process id
8153 sleep 1
8154 (echo .; sleep 1; echo) |$CMD 2>"$te"
8155 rc=$?
8156 kill $bg 2>/dev/null; wait
8157 if [ $rc -ne 0 ]; then
8158 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8159 echo "$CMD &"
8160 cat "$te"
8161 numFAIL=$((numFAIL+1))
8162 listFAIL="$listFAIL $N"
8163 else
8164 $PRINTF "$OK\n"
8165 if [ -n "$debug" ]; then cat "$te"; fi
8166 numOK=$((numOK+1))
8167 listOK="$listOK $N"
8169 fi ;; # NUMCOND, feats
8170 esac
8171 N=$((N+1))
8174 # test if option coolwrite can be applied to bidirectional address stdio
8175 # this failed up to socat 1.6.0.0
8176 NAME=COOLSTDIO
8177 case "$TESTS" in
8178 *%$N%*|*%functions%*|*%engine%*|*%timeout%*|*%coolwrite%*|*%$NAME%*)
8179 TEST="$NAME: option cool-write on bidirectional stdio"
8180 # this test starts a socat reader that terminates after receiving one+
8181 # bytes (option readbytes); and a test process that sends two bytes via
8182 # named pipe to the receiving process and, a second later, sends another
8183 # byte. The last write will fail with "broken pipe"; if option coolwrite
8184 # has been applied successfully, socat will terminate with 0 (OK),
8185 # otherwise with error.
8186 if ! eval $NUMCOND; then :;
8187 elif ! testoptions cool-write >/dev/null; then
8188 $PRINTF "test $F_n $TEST... ${YELLOW}option cool-write not available${NORMAL}\n" $N
8189 numCANT=$((numCANT+1))
8190 listCANT="$listCANT $N"
8191 else
8192 #set -vx
8193 ti="$td/test$N.pipe"
8194 tf="$td/test$N.stdout"
8195 te="$td/test$N.stderr"
8196 tdiff="$td/test$N.diff"
8197 da="test$N $(date) $RANDOM"
8198 # a reader that will terminate after 1 byte
8199 CMD1="$TRACE $SOCAT $opts -u pipe:\"$ti\",readbytes=1 /dev/null"
8200 CMD="$TRACE $SOCAT $opts -,cool-write pipe >\"$ti\""
8201 printf "test $F_n $TEST... " $N
8202 $CMD1 2>"${te}1" &
8203 bg=$! # background process id
8204 sleep 1
8205 (echo .; sleep 1; echo) |eval "$CMD" 2>"$te"
8206 rc=$?
8207 kill $bg 2>/dev/null; wait
8208 if [ $rc -ne 0 ]; then
8209 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8210 echo "$CMD1 &"
8211 cat "${te}1"
8212 echo "$CMD"
8213 cat "$te"
8214 numFAIL=$((numFAIL+1))
8215 listFAIL="$listFAIL $N"
8216 else
8217 $PRINTF "$OK\n"
8218 if [ -n "$debug" ]; then cat "$te"; fi
8219 numOK=$((numOK+1))
8220 listOK="$listOK $N"
8222 fi ;; # NUMCOND, feats
8223 esac
8224 N=$((N+1))
8227 NAME=TCP4ENDCLOSE
8228 case "$TESTS" in
8229 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%fork%*|*%$NAME%*)
8230 TEST="$NAME: end-close keeps TCP V4 socket open"
8231 if ! eval $NUMCOND; then :; else
8232 tf="$td/test$N.stdout"
8233 te="$td/test$N.stderr"
8234 tdiff="$td/test$N.diff"
8235 newport tcp4; p0=$PORT
8236 newport tcp4; p1=$PORT
8237 da2a="$(date) $RANDOM"
8238 da2b="$(date) $RANDOM"
8239 CMD0="$TRACE $SOCAT -lp collector $opts -u TCP4-LISTEN:$p0,$REUSEADDR,bind=$LOCALHOST -"
8240 CMD1="$TRACE $SOCAT -lp forker $opts -U TCP4:$LOCALHOST:$p0,end-close TCP4-LISTEN:$p1,bind=$LOCALHOST,$REUSEADDR,fork"
8241 CMD2="$TRACE $SOCAT -lp client $opts -u - TCP4-CONNECT:$LOCALHOST:$p1"
8242 printf "test $F_n $TEST... " $N
8243 $CMD0 >"${tf}0" 2>"${te}0" &
8244 pid0=$!
8245 waittcp4port $p0 1
8246 $CMD1 2>"${te}1" &
8247 pid1=$!
8248 relsleep 1
8249 waittcp4port $p1 1
8250 echo "$da2a" |$CMD2 2>>"${te}2a"
8251 rc2a=$?
8252 echo "$da2b" |$CMD2 2>>"${te}2b"
8253 rc2b=$?
8254 sleep 1
8255 kill "$pid0" "$pid1" 2>/dev/null
8256 wait
8257 if [ $rc2a -ne 0 -o $rc2b -ne 0 ]; then
8258 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8259 echo "$CMD0 &"
8260 cat "${te}0" >&2
8261 echo "$CMD1"
8262 cat "${te}1" >&2
8263 echo "$CMD2"
8264 cat "${te}2a" >&2
8265 echo "$CMD2"
8266 cat "${te}2b" >&2
8267 numFAIL=$((numFAIL+1))
8268 listFAIL="$listFAIL $N"
8269 elif ! $ECHO "$da2a\n$da2b" |diff - "${tf}0" >"$tdiff"; then
8270 $PRINTF "$FAILED (diff)\n"
8271 echo "$CMD0 &"
8272 cat "${te}0" >&2
8273 echo "$CMD1"
8274 cat "${te}1" >&2
8275 echo "$CMD2"
8276 cat "${te}2a" >&2
8277 echo "$CMD2"
8278 cat "${te}2b" >&2
8279 cat "$tdiff"
8280 numFAIL=$((numFAIL+1))
8281 listFAIL="$listFAIL $N"
8282 else
8283 $PRINTF "$OK\n"
8284 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
8285 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
8286 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8287 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8288 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8289 if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi
8290 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8291 if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi
8292 numOK=$((numOK+1))
8293 listOK="$listOK $N"
8295 fi ;; # NUMCOND
8296 esac
8297 N=$((N+1))
8300 NAME=EXECENDCLOSE
8301 case "$TESTS" in
8302 *%$N%*|*%functions%*|*%exec%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*)
8303 TEST="$NAME: end-close keeps EXEC child running"
8304 if ! eval $NUMCOND; then :; else
8305 tf="$td/test$N.stdout"
8306 te="$td/test$N.stderr"
8307 ts="$td/test$N.sock"
8308 tdiff="$td/test$N.diff"
8309 da1a="$(date) $RANDOM"
8310 da1b="$(date) $RANDOM"
8311 CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$ts"
8312 CMD="$TRACE $SOCAT $opts EXEC:"$CAT",end-close UNIX-LISTEN:$ts,fork"
8313 printf "test $F_n $TEST... " $N
8314 $CMD 2>"${te}2" &
8315 pid2=$!
8316 waitfile $ts 1
8317 echo "$da1a" |$CMD1 2>>"${te}1a" >"$tf"
8318 relsleep 1
8319 echo "$da1b" |$CMD1 2>>"${te}1b" >>"$tf"
8320 #relsleep 1
8321 kill "$pid2" 2>/dev/null
8322 wait
8323 if [ $? -ne 0 ]; then
8324 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8325 echo "$CMD1 &"
8326 echo "$CMD2"
8327 cat "${te}1a" "${te}1b" "${te}2"
8328 numFAIL=$((numFAIL+1))
8329 listFAIL="$listFAIL $N"
8330 elif ! $ECHO "$da1a\n$da1b" |diff - "$tf" >"$tdiff"; then
8331 $PRINTF "$FAILED\n"
8332 cat "$tdiff"
8333 cat "${te}1a" "${te}1b" "${te}2"
8334 numFAIL=$((numFAIL+1))
8335 listFAIL="$listFAIL $N"
8336 else
8337 $PRINTF "$OK\n"
8338 if [ -n "$debug" ]; then cat "${te}1a" "${te}1b" "${te}2"; fi
8339 numOK=$((numOK+1))
8340 listOK="$listOK $N"
8342 fi ;; # NUMCOND
8343 esac
8344 N=$((N+1))
8347 # up to 1.7.0.0 option end-close led to an error with some address types due to
8348 # bad internal handling. here we check it for address PTY
8349 NAME=PTYENDCLOSE
8350 case "$TESTS" in
8351 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
8352 TEST="$NAME: PTY handles option end-close"
8353 # with the bug, socat exits with error. we invoke socat in a no-op mode and
8354 # check its return status.
8355 if ! eval $NUMCOND; then :;
8356 else
8357 tf="$td/test$N.stout"
8358 te="$td/test$N.stderr"
8359 # -t must be longer than 0.1 on OpenBSD
8360 CMD="$TRACE $SOCAT $opts -d -d -t 0.5 /dev/null pty,end-close"
8361 printf "test $F_n $TEST... " $N
8362 # AIX reports the pty writeable for select() only when its slave side has been
8363 # opened, therefore we run this process in background and check its NOTICE
8364 # output for the PTY name
8365 { $CMD 2>"${te}"; echo $? >"$td/test$N.rc0"; } &
8366 waitfile "${te}"
8367 sleep 0.5 # 0.1 is too few for FreeBSD-10
8368 PTY=$(grep "N PTY is " $te |sed 's/.*N PTY is //')
8369 # So this for AIX? but "cat" hangs on OpenBSD, thus use socat with timeout instead
8370 [ -e "$PTY" ] && $SOCAT -T 0.1 -u $PTY,o-nonblock - >/dev/null 2>/dev/null
8371 rc=$(cat "$td/test$N.rc0")
8372 if [ "$rc" = 0 ]; then
8373 $PRINTF "$OK\n"
8374 numOK=$((numOK+1))
8375 listOK="$listOK $N"
8376 else
8377 $PRINTF "$FAILED\n"
8378 echo "$CMD"
8379 cat "${te}"
8380 numFAIL=$((numFAIL+1))
8381 listFAIL="$listFAIL $N"
8383 fi # NUMCOND
8385 esac
8386 N=$((N+1))
8389 # Test the shut-null and null-eof options
8390 NAME=SHUTNULLEOF
8391 case "$TESTS" in
8392 *%$N%*|*%functions%*|*%socket%*|*%$NAME%*)
8393 TEST="$NAME: options shut-null and null-eof"
8394 # Run a receiving background process with option null-eof.
8395 # Start a sending process with option shut-null that sends a test record to the
8396 # receiving process and then terminates.
8397 # Send another test record.
8398 # When the receiving process only received and stored the first test record the
8399 # test succeeded
8400 if ! eval $NUMCOND; then :; else
8401 tf="$td/test$N.stout"
8402 te="$td/test$N.stderr"
8403 tdiff="$td/test$N.diff"
8404 da="test$N $(date) $RANDOM"
8405 newport udp4 # provide free port number in $PORT
8406 CMD0="$TRACE $SOCAT $opts -u UDP4-RECV:$PORT,null-eof CREAT:$tf"
8407 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:127.0.0.1:$PORT,shut-null"
8408 printf "test $F_n $TEST... " $N
8409 $CMD0 >/dev/null 2>"${te}0" &
8410 pid0=$!
8411 waitudp4port $PORT 1
8412 { echo "$da"; sleep 0.1; } |$CMD1 >"${tf}1" 2>"${te}1"
8413 rc1=$?
8414 { echo "xyz"; sleep 0.1; } |$CMD1 >"${tf}2" 2>"${te}2"
8415 rc2=$?
8416 kill $pid0 2>/dev/null; wait
8417 if [ $rc1 != 0 -o $rc2 != 0 ]; then
8418 $PRINTF "$FAILED (client(s) failed)\n"
8419 echo "$CMD0 &"
8420 cat "${te}0" >&2
8421 echo "$CMD1"
8422 cat "${te}1" >&2
8423 echo "$CMD1"
8424 cat "${te}2" >&2
8425 numFAIL=$((numFAIL+1))
8426 listFAIL="$listFAIL $N"
8427 elif echo "$da" |diff - "${tf}" >"$tdiff"; then
8428 $PRINTF "$OK\n"
8429 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
8430 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
8431 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
8432 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8433 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8434 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8435 numOK=$((numOK+1))
8436 listOK="$listOK $N"
8437 else
8438 $PRINTF "$FAILED (diff)\n"
8439 echo "$CMD0 &"
8440 cat "${te}0" >&2
8441 echo "$CMD1"
8442 cat "${te}1" >&2
8443 echo "$CMD2"
8444 cat "${te}2" >&2
8445 echo "// diff:" >&2
8446 cat "${tdiff}" >&2
8447 numFAIL=$((numFAIL+1))
8448 listFAIL="$listFAIL $N"
8450 fi # NUMCOND
8452 esac
8453 N=$((N+1))
8456 NAME=UDP6LISTENBIND
8457 # this tests for a bug in (up to) 1.5.0.0:
8458 # with udp*-listen, the bind option supported only IPv4
8459 case "$TESTS" in
8460 *%$N%*|*%functions%*|*%bugs%*|*%ip6%*|*%ipapp%*|*%udp%*|*%udp6%*|*%listen%*|*%$NAME%*)
8461 TEST="$NAME: UDP6-LISTEN with bind"
8462 if ! eval $NUMCOND; then :;
8463 elif ! feat=$(testfeats udp ip6) || ! runsip6 >/dev/null; then
8464 $PRINTF "test $F_n $TEST... ${YELLOW}UDP6 not available${NORMAL}\n" $N
8465 numCANT=$((numCANT+1))
8466 listCANT="$listCANT $N"
8467 else
8468 tf="$td/test$N.stdout"
8469 te="$td/test$N.stderr"
8470 tdiff="$td/test$N.diff"
8471 newport udp6; tsl=$PORT
8472 ts="$LOCALHOST6:$tsl"
8473 da="test$N $(date) $RANDOM"
8474 CMD1="$TRACE $SOCAT $opts UDP6-LISTEN:$tsl,$REUSEADDR,bind=$LOCALHOST6 PIPE"
8475 CMD2="$TRACE $SOCAT $opts - UDP6:$ts"
8476 printf "test $F_n $TEST... " $N
8477 $CMD1 >"$tf" 2>"${te}1" &
8478 pid1=$!
8479 waitudp6port $tsl 1
8480 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8481 rc2=$?
8482 kill $pid1 2>/dev/null; wait
8483 if [ $rc2 -ne 0 ]; then
8484 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8485 echo "$CMD1 &"
8486 echo "$CMD2"
8487 cat "${te}1" "${te}2"
8488 numFAIL=$((numFAIL+1))
8489 listFAIL="$listFAIL $N"
8490 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8491 $PRINTF "$FAILED\n"
8492 cat "$tdiff"
8493 numFAIL=$((numFAIL+1))
8494 listFAIL="$listFAIL $N"
8495 else
8496 $PRINTF "$OK\n"
8497 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
8498 numOK=$((numOK+1))
8499 listOK="$listOK $N"
8501 fi ;; # NUMCOND, feats
8502 esac
8503 N=$((N+1))
8506 NAME=TCPWRAPPERS_MULTIOPTS
8507 # this tests for a bug in 1.5.0.0 that let socat fail when more than one
8508 # tcp-wrappers related option was specified in one address
8509 case "$TESTS" in
8510 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
8511 TEST="$NAME: use of multiple tcpwrapper enabling options"
8512 if ! eval $NUMCOND; then :;
8513 elif ! feat=$(testfeats tcp ip4 libwrap) || ! runsip4 >/dev/null; then
8514 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8515 numCANT=$((numCANT+1))
8516 listCANT="$listCANT $N"
8517 else
8518 tf="$td/test$N.stdout"
8519 te="$td/test$N.stderr"
8520 tdiff="$td/test$N.diff"
8521 da="test$N $(date) $RANDOM"
8522 ha="$td/hosts.allow"
8523 $ECHO "test : ALL : allow" >"$ha"
8524 newport tcp4 # provide free port number in $PORT
8525 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR,hosts-allow=$ha,tcpwrap=test pipe"
8526 CMD2="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
8527 printf "test $F_n $TEST... " $N
8528 $CMD1 2>"${te}1" &
8529 pid1=$!
8530 waittcp4port $PORT
8531 echo "$da" |$CMD2 >"$tf" 2>"${te}2"
8532 rc2=$?
8533 kill $pid1 2>/dev/null; wait
8534 if [ $rc2 -ne 0 ]; then
8535 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8536 echo "$CMD1 &"
8537 echo "$CMD2"
8538 cat "${te}1"
8539 cat "${te}2"
8540 numFAIL=$((numFAIL+1))
8541 listFAIL="$listFAIL $N"
8542 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8543 $PRINTF "$FAILED\n"
8544 cat "$tdiff"
8545 numFAIL=$((numFAIL+1))
8546 listFAIL="$listFAIL $N"
8547 else
8548 $PRINTF "$OK\n"
8549 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
8550 numOK=$((numOK+1))
8551 listOK="$listOK $N"
8553 fi ;; # NUMCOND, feats
8554 esac
8555 N=$((N+1))
8558 NAME=TCPWRAPPERS_TCP6ADDR
8559 # this tests for a bug in 1.5.0.0 that brought false results with tcp-wrappers
8560 # and IPv6 when
8561 case "$TESTS" in
8562 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%tcpwrap%*|*%listen%*|*%$NAME%*)
8563 TEST="$NAME: specification of TCP6 address in hosts.allow"
8564 if ! eval $NUMCOND; then :;
8565 elif ! feat=$(testfeats tcp ip6 libwrap && runsip6); then
8566 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8567 numCANT=$((numCANT+1))
8568 listCANT="$listCANT $N"
8569 else
8570 tf="$td/test$N.stdout"
8571 te="$td/test$N.stderr"
8572 tdiff="$td/test$N.diff"
8573 da="test$N $(date) $RANDOM"
8574 ha="$td/hosts.allow"
8575 hd="$td/hosts.deny"
8576 $ECHO "socat : [::1] : allow" >"$ha"
8577 $ECHO "ALL : ALL : deny" >"$hd"
8578 newport tcp6 # provide free port number in $PORT
8579 CMD1="$TRACE $SOCAT $opts TCP6-LISTEN:$PORT,$REUSEADDR,tcpwrap-etc=$td,tcpwrappers=socat pipe"
8580 CMD2="$TRACE $SOCAT $opts - TCP6:[::1]:$PORT"
8581 printf "test $F_n $TEST... " $N
8582 $CMD1 2>"${te}1" &
8583 pid1=$!
8584 waittcp6port $PORT
8585 echo "$da" |$CMD2 >"$tf" 2>"${te}2"
8586 rc2=$?
8587 kill $pid1 2>/dev/null; wait
8588 if [ $rc2 -ne 0 ]; then
8589 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8590 echo "$CMD1 &"
8591 echo "$CMD2"
8592 cat "${te}1"
8593 cat "${te}2"
8594 numFAIL=$((numFAIL+1))
8595 listFAIL="$listFAIL $N"
8596 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8597 $PRINTF "$FAILED\n"
8598 cat "$tdiff"
8599 numFAIL=$((numFAIL+1))
8600 listFAIL="$listFAIL $N"
8601 else
8602 $PRINTF "$OK\n"
8603 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
8604 numOK=$((numOK+1))
8605 listOK="$listOK $N"
8607 fi ;; # NUMCOND, feats
8608 esac
8609 N=$((N+1))
8612 NAME=UDP4BROADCAST
8613 case "$TESTS" in
8614 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%$NAME%*)
8615 TEST="$NAME: UDP/IPv4 broadcast"
8616 if ! eval $NUMCOND; then :;
8617 elif [ -z "$BCADDR" ]; then
8618 $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
8619 numCANT=$((numCANT+1))
8620 listCANT="$listCANT $N"
8621 else
8622 tf="$td/test$N.stdout"
8623 te="$td/test$N.stderr"
8624 tdiff="$td/test$N.diff"
8625 newport udp4; ts1p=$PORT
8626 #ts1="$BCADDR/8:$ts1p"
8627 ts1="$BCADDR:$ts1p"
8628 newport udp4; ts2p=$PORT
8629 ts2="$BCIFADDR:$ts2p"
8630 da="test$N $(date) $RANDOM"
8631 CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,broadcast PIPE"
8632 #CMD2="$TRACE $SOCAT $opts - UDP4-BROADCAST:$ts1"
8633 CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:$ts1,broadcast"
8634 printf "test $F_n $TEST... " $N
8635 $CMD1 2>"${te}1" &
8636 pid1="$!"
8637 waitudp4port $ts1p 1
8638 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8639 rc2="$?"
8640 kill "$pid1" 2>/dev/null; wait;
8641 if [ "$rc2" -ne 0 ]; then
8642 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8643 echo "$CMD1 &"
8644 echo "$CMD2"
8645 cat "${te}1"
8646 cat "${te}2"
8647 numFAIL=$((numFAIL+1))
8648 listFAIL="$listFAIL $N"
8649 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8650 $PRINTF "$FAILED\n"
8651 cat "$tdiff"
8652 numFAIL=$((numFAIL+1))
8653 listFAIL="$listFAIL $N"
8654 else
8655 $PRINTF "$OK\n"
8656 if [ -n "$tut" ]; then
8657 echo "$CMD1 &"
8658 echo "$CMD2"
8660 if [ -n "$debug" ]; then cat $te; fi
8661 numOK=$((numOK+1))
8662 listOK="$listOK $N"
8664 fi ;; # NUMCOND, feats
8665 esac
8666 N=$((N+1))
8669 NAME=IP4BROADCAST
8670 # test a local broadcast of a raw IPv4 protocol.
8671 # because we receive - in addition to the regular reply - our own broadcast,
8672 # we use a token XXXX that is changed to YYYY in the regular reply packet.
8673 case "$TESTS" in
8674 *%$N%*|*%functions%*|*%engine%*|*%rawip%*|*%rawip4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%root%*|*%$NAME%*)
8675 TEST="$NAME: raw IPv4 broadcast"
8676 if ! eval $NUMCOND; then :;
8677 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
8678 $PRINTF "test $F_n $TEST... ${YELLOW}raw IP4 not available${NORMAL}\n" $N
8679 numCANT=$((numCANT+1))
8680 listCANT="$listCANT $N"
8681 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8682 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8683 numCANT=$((numCANT+1))
8684 listCANT="$listCANT $N"
8685 elif [ -z "$BCADDR" ]; then
8686 $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
8687 else
8688 tf="$td/test$N.stdout"
8689 te="$td/test$N.stderr"
8690 tdiff="$td/test$N.diff"
8691 ts1p=$IPPROTO
8692 #ts1="$BCADDR/8:$ts1p"
8693 ts1="$BCADDR:$ts1p"
8694 ts2p=$ts1p
8695 ts2="$BCIFADDR"
8696 da="test$N $(date) $RANDOM XXXX"
8697 sh="$td/test$N-sed.sh"
8698 echo 'sed s/XXXX/YYYY/' >"$sh"
8699 chmod a+x "$sh"
8700 # EXEC need not work with script (musl libc), so use SYSTEM
8701 CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,broadcast SYSTEM:$sh"
8702 #CMD2="$TRACE $SOCAT $opts - IP4-BROADCAST:$ts1"
8703 CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:$ts1,broadcast"
8704 printf "test $F_n $TEST... " $N
8705 $CMD1 2>"${te}1" &
8706 pid1="$!"
8707 waitip4port $ts1p 1
8708 echo "$da" |$CMD2 2>>"${te}2" |grep -v XXXX >>"$tf"
8709 rc2="$?"
8710 kill "$pid1" 2>/dev/null; wait;
8711 if [ "$rc2" -ne 0 ]; then
8712 $PRINTF "$FAILED (rc2=$rc2):\n"
8713 echo "$CMD1 &"
8714 cat "${te}1" >&2
8715 echo "$CMD2"
8716 cat "${te}2" >&2
8717 numFAIL=$((numFAIL+1))
8718 listFAIL="$listFAIL $N"
8719 elif ! echo "$da" | sed 's/XXXX/YYYY/'|diff - "$tf" >"$tdiff"; then
8720 $PRINTF "$FAILED (diff)\n"
8721 echo "$CMD1 &"
8722 cat "${te}1" >&2
8723 echo "$CMD2"
8724 cat "${te}2" >&2
8725 echo "// diff:" >&2
8726 cat "$tdiff" >&2
8727 numFAIL=$((numFAIL+1))
8728 listFAIL="$listFAIL $N"
8729 else
8730 $PRINTF "$OK\n"
8731 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8732 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8733 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8734 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8735 numOK=$((numOK+1))
8736 listOK="$listOK $N"
8738 fi ;; # NUMCOND, feats
8739 esac
8740 #IPPROTO=$((IPPROTO+1))
8741 N=$((N+1))
8744 #NAME=UDP4BROADCAST_RANGE
8745 #case "$TESTS" in
8746 #*%$N%*|*%functions%*|*%security%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%broadcast%*|*%range%*|*%$NAME%*)
8747 #TEST="$NAME: security of UDP4-BROADCAST with RANGE option"
8748 #if ! eval $NUMCOND; then :;
8749 #elif [ -z "$BCADDR" ]; then
8750 # $PRINTF "test $F_n $TEST... ${YELLOW}dont know a broadcast address${NORMAL}\n" $N
8751 #else
8752 #newport udp4 # provide free port number in $PORT
8753 #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
8754 #fi ;; # NUMCOND, feats
8755 #esac
8756 #N=$((N+1))
8759 NAME=UDP4MULTICAST_UNIDIR
8760 case "$TESTS" in
8761 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*)
8762 TEST="$NAME: UDP/IPv4 multicast, send only"
8763 if ! eval $NUMCOND; then :;
8764 elif ! feat=$(testfeats ip4 udp) || ! runsip4 >/dev/null; then
8765 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8766 numCANT=$((numCANT+1))
8767 listCANT="$listCANT $N"
8768 elif ! a=$(testaddrs UDP4-RECV UDP4-SENDTO); then
8769 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
8770 numCANT=$((numCANT+1))
8771 listCANT="$listCANT $N"
8772 elif ! o=$(testoptions ip-add-membership bind) >/dev/null; then
8773 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
8774 numCANT=$((numCANT+1))
8775 listCANT="$listCANT $N"
8776 else
8777 tf="$td/test$N.stdout"
8778 te="$td/test$N.stderr"
8779 tdiff="$td/test$N.diff"
8780 newport udp4; ts1p=$PORT
8781 ts1a="$SECONDADDR"
8782 ts1="$ts1a:$ts1p"
8783 da="test$N $(date) $RANDOM"
8784 CMD1="$TRACE $SOCAT -u $opts UDP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
8785 CMD2="$TRACE $SOCAT -u $opts - UDP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
8786 printf "test $F_n $TEST... " $N
8787 $CMD1 2>"${te}1" >"${tf}" &
8788 pid1="$!"
8789 waitudp4port $ts1p 1
8790 echo "$da" |$CMD2 2>>"${te}2"
8791 rc2="$?"
8792 relsleep 1
8793 kill "$pid1" 2>/dev/null; wait;
8794 if [ "$rc2" -ne 0 ]; then
8795 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8796 echo "$CMD1 &"
8797 cat "${te}1" >&2
8798 echo "$CMD2"
8799 cat "${te}2" >&2
8800 numFAIL=$((numFAIL+1))
8801 listFAIL="$listFAIL $N"
8802 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8803 $PRINTF "$FAILED\n"
8804 echo "$CMD1 &"
8805 cat "${te}1" >&2
8806 echo "$CMD2"
8807 cat "${te}2" >&2
8808 cat "$tdiff"
8809 numFAIL=$((numFAIL+1))
8810 listFAIL="$listFAIL $N"
8811 else
8812 $PRINTF "$OK\n"
8813 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8814 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8815 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8816 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8817 numOK=$((numOK+1))
8818 listOK="$listOK $N"
8820 fi ;; # NUMCOND, feats
8821 esac
8822 N=$((N+1))
8824 NAME=IP4MULTICAST_UNIDIR
8825 case "$TESTS" in
8826 *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*)
8827 TEST="$NAME: IPv4 multicast"
8828 if ! eval $NUMCOND; then :;
8829 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
8830 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
8831 numCANT=$((numCANT+1))
8832 listCANT="$listCANT $N"
8833 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
8834 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
8835 numCANT=$((numCANT+1))
8836 listCANT="$listCANT $N"
8837 else
8838 tf="$td/test$N.stdout"
8839 te="$td/test$N.stderr"
8840 tdiff="$td/test$N.diff"
8841 ts1p=$IPPROTO
8842 ts1a="$SECONDADDR"
8843 ts1="$ts1a:$ts1p"
8844 da="test$N $(date) $RANDOM"
8845 CMD1="$TRACE $SOCAT -u $opts IP4-RECV:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a -"
8846 CMD2="$TRACE $SOCAT -u $opts - IP4-SENDTO:224.255.255.254:$ts1p,bind=$ts1a"
8847 printf "test $F_n $TEST... " $N
8848 $CMD1 2>"${te}1" >"${tf}" &
8849 pid1="$!"
8850 waitip4proto $ts1p 1
8851 relsleep 1
8852 echo "$da" |$CMD2 2>>"${te}2"
8853 rc2="$?"
8854 #relsleep 1
8855 sleep 1
8856 kill "$pid1" 2>/dev/null; wait;
8857 if [ "$rc2" -ne 0 ]; then
8858 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8859 echo "$CMD1 &"
8860 echo "$CMD2"
8861 cat "${te}1"
8862 cat "${te}2"
8863 numFAIL=$((numFAIL+1))
8864 listFAIL="$listFAIL $N"
8865 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8866 $PRINTF "$FAILED\n"
8867 cat "$tdiff"
8868 numFAIL=$((numFAIL+1))
8869 listFAIL="$listFAIL $N"
8870 else
8871 $PRINTF "$OK\n"
8872 if [ -n "$debug" ]; then cat $te; fi
8873 numOK=$((numOK+1))
8874 listOK="$listOK $N"
8876 fi ;; # NUMCOND, feats
8877 esac
8878 #IPPROTO=$((IPPROTO+1))
8879 N=$((N+1))
8881 if true; then
8882 # This test succeeds, e.g., on CentOS-7 with kernel 3.10.0, Ubuntu-16.04 with 4.4.0
8883 # but fails, e.g., on Ubuntu-18.04 with kernel 4.15.0, CentOS-8 with 4.10.0
8884 NAME=UDP6MULTICAST_UNIDIR
8885 case "$TESTS" in
8886 *%$N%*|*%functions%*|*%udp%*|*%udp6%*|*%ip6%*|*%dgram%*|*%multicast%*|*%$NAME%*)
8887 TEST="$NAME: UDP/IPv6 multicast"
8888 if ! eval $NUMCOND; then :;
8889 elif ! f=$(testfeats ip6 udp); then
8890 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $f not configured in $SOCAT${NORMAL}\n" $N
8891 numCANT=$((numCANT+1))
8892 listCANT="$listCANT $N"
8893 elif ! a=$(testaddrs - STDIO UDP6-RECV UDP6-SENDTO); then
8894 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
8895 numCANT=$((numCANT+1))
8896 listCANT="$listCANT $N"
8897 elif ! o=$(testoptions ipv6-join-group) >/dev/null; then
8898 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
8899 numCANT=$((numCANT+1))
8900 listCANT="$listCANT $N"
8901 elif ! runsip6 >/dev/null; then
8902 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 does not work on $HOSTNAME${NORMAL}\n" $N
8903 numCANT=$((numCANT+1))
8904 listCANT="$listCANT $N"
8905 elif ! echo |$SOCAT -u -t 0.1 - UDP6-SENDTO:[ff02::1]:12002 >/dev/null 2>&1; then
8906 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 multicasting does not work${NORMAL}\n" $N
8907 numCANT=$((numCANT+1))
8908 listCANT="$listCANT $N"
8909 else
8910 tf="$td/test$N.stdout"
8911 te="$td/test$N.stderr"
8912 tdiff="$td/test$N.diff"
8913 newport udp6; ts1p=$PORT
8914 if1="$MCINTERFACE"
8915 ts1a="[::1]"
8916 da="test$N $(date) $RANDOM"
8917 CMD1="$TRACE $SOCAT -u $opts UDP6-RECV:$ts1p,$REUSEADDR,ipv6-join-group=[ff02::2]:$if1 -"
8918 #CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p,bind=$ts1a"
8919 CMD2="$TRACE $SOCAT -u $opts - UDP6-SENDTO:[ff02::2]:$ts1p"
8920 printf "test $F_n $TEST... " $N
8921 $CMD1 2>"${te}1" >"${tf}" &
8922 pid1="$!"
8923 waitudp6port $ts1p 1
8924 echo "$da" |$CMD2 2>>"${te}2"
8925 rc2="$?"
8926 relsleep 1
8927 kill "$pid1" 2>/dev/null; wait;
8928 if [ "$rc2" -ne 0 ]; then
8929 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8930 echo "$CMD1 &"
8931 cat "${te}1"
8932 echo "$CMD2"
8933 cat "${te}2"
8934 numFAIL=$((numFAIL+1))
8935 listFAIL="$listFAIL $N"
8936 namesFAIL="$namesFAIL $NAME"
8937 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8938 # if ! [ "$UNAME" = Linux ] || ! [[ $(uname -r) =~ ^2\.* ]] || ! [[ ^3\.* ]] || ! [[ ^4\.[0-4]\.* ]]; then
8939 # $PRINTF "${YELLOW}works only on Linux up to about 4.4${NORMAL}\n" $N
8940 # numCANT=$((numCANT+1))
8941 # listCANT="$listCANT $N"
8942 # else
8943 $PRINTF "$FAILED\n"
8944 echo "$CMD1 &"
8945 cat "${te}1"
8946 echo "$CMD2"
8947 cat "${te}2"
8948 cat "$tdiff"
8949 numFAIL=$((numFAIL+1))
8950 listFAIL="$listFAIL $N"
8951 # fi
8952 else
8953 $PRINTF "$OK\n"
8954 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
8955 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
8956 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
8957 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
8958 numOK=$((numOK+1))
8959 listOK="$listOK $N"
8961 fi ;; # NUMCOND, feats
8962 esac
8963 N=$((N+1))
8964 fi # false
8966 NAME=UDP4MULTICAST_BIDIR
8967 case "$TESTS" in
8968 *%$N%*|*%functions%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%multicast%*|*%$NAME%*)
8969 TEST="$NAME: UDP/IPv4 multicast, with reply"
8970 if ! eval $NUMCOND; then :; else
8971 tf="$td/test$N.stdout"
8972 te="$td/test$N.stderr"
8973 tdiff="$td/test$N.diff"
8974 newport udp4; ts1p=$PORT
8975 ts1a="$SECONDADDR"
8976 ts1="$ts1a:$ts1p"
8977 newport udp4; ts2p=$PORT
8978 ts2="$BCIFADDR:$ts2p"
8979 da="test$N $(date) $RANDOM"
8980 CMD1="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
8981 #CMD2="$TRACE $SOCAT $opts - UDP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
8982 CMD2="$TRACE $SOCAT $opts - UDP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
8983 printf "test $F_n $TEST... " $N
8984 $CMD1 2>"${te}1" &
8985 pid1="$!"
8986 waitudp4port $ts1p 1
8987 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
8988 rc2="$?"
8989 kill "$pid1" 2>/dev/null; wait;
8990 if [ "$rc2" -ne 0 ]; then
8991 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
8992 echo "$CMD1 &"
8993 cat "${te}1" >&2
8994 echo "$CMD2"
8995 cat "${te}2" >&2
8996 numFAIL=$((numFAIL+1))
8997 listFAIL="$listFAIL $N"
8998 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
8999 $PRINTF "$FAILED\n"
9000 echo "$CMD1 &"
9001 cat "${te}1" >&2
9002 echo "$CMD2"
9003 cat "${te}2" >&2
9004 echo diff: >&2
9005 cat "$tdiff" >&2
9006 numFAIL=$((numFAIL+1))
9007 listFAIL="$listFAIL $N"
9008 else
9009 $PRINTF "$OK\n"
9010 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9011 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9012 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9013 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9014 numOK=$((numOK+1))
9015 listOK="$listOK $N"
9017 fi ;; # NUMCOND
9018 esac
9019 N=$((N+1))
9021 NAME=IP4MULTICAST_BIDIR
9022 case "$TESTS" in
9023 *%$N%*|*%functions%*|*%rawip%*|*%ip4%*|*%dgram%*|*%multicast%*|*%root%*|*%$NAME%*)
9024 TEST="$NAME: IPv4 multicast, with reply"
9025 if ! eval $NUMCOND; then :;
9026 elif ! feat=$(testfeats ip4 rawip) || ! runsip4 >/dev/null; then
9027 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9028 numCANT=$((numCANT+1))
9029 listCANT="$listCANT $N"
9030 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
9031 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
9032 numCANT=$((numCANT+1))
9033 listCANT="$listCANT $N"
9034 else
9035 tf="$td/test$N.stdout"
9036 te="$td/test$N.stderr"
9037 tdiff="$td/test$N.diff"
9038 ts1p=$IPPROTO
9039 ts1a="$SECONDADDR"
9040 ts1="$ts1a:$ts1p"
9041 da="test$N $(date) $RANDOM"
9042 CMD1="$TRACE $SOCAT $opts IP4-RECVFROM:$ts1p,reuseaddr,ip-add-membership=224.255.255.254:$ts1a PIPE"
9043 #CMD2="$TRACE $SOCAT $opts - IP4-MULTICAST:224.255.255.254:$ts1p,bind=$ts1a"
9044 CMD2="$TRACE $SOCAT $opts - IP4-DATAGRAM:224.255.255.254:$ts1p,bind=$ts1a"
9045 printf "test $F_n $TEST... " $N
9046 $CMD1 2>"${te}1" &
9047 pid1="$!"
9048 waitip4port $ts1p 1
9049 relsleep 1 # give process a chance to add multicast membership
9050 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9051 rc2="$?"
9052 kill "$pid1" 2>/dev/null; wait;
9053 if [ "$rc2" -ne 0 ]; then
9054 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9055 echo "$CMD1 &"
9056 echo "$CMD2"
9057 cat "${te}1"
9058 cat "${te}2"
9059 numFAIL=$((numFAIL+1))
9060 listFAIL="$listFAIL $N"
9061 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9062 $PRINTF "$FAILED\n"
9063 cat "$tdiff"
9064 numFAIL=$((numFAIL+1))
9065 listFAIL="$listFAIL $N"
9066 else
9067 $PRINTF "$OK\n"
9068 if [ -n "$tut" ]; then
9069 echo "$CMD1 &"
9070 echo "$CMD2"
9072 if [ -n "$debug" ]; then cat $te; fi
9073 numOK=$((numOK+1))
9074 listOK="$listOK $N"
9076 fi ;; # NUMCOND, feats
9077 esac
9078 #IPPROTO=$((IPPROTO+1))
9079 N=$((N+1))
9082 NAME=TUNREAD
9083 case "$TESTS" in
9084 *%$N%*|*%functions%*|*%tun%*|*%root%*|*%$NAME%*)
9085 TEST="$NAME: reading data sent through tun interface"
9086 #idea: create a TUN interface and send a datagram to one of the addresses of
9087 # its virtual network. On the tunnel side, read the packet and compare its last
9088 # bytes with the datagram payload
9089 if ! eval $NUMCOND; then :;
9090 elif ! feat=$(testfeats ip4 tun) || ! runsip4 >/dev/null; then
9091 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9092 numCANT=$((numCANT+1))
9093 listCANT="$listCANT $N"
9094 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
9095 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
9096 numCANT=$((numCANT+1))
9097 listCANT="$listCANT $N"
9098 else
9099 tf="$td/test$N.stdout"
9100 te="$td/test$N.stderr"
9101 tdiff="$td/test$N.diff"
9102 tl="$td/test$N.lock"
9103 da="test$N $(date) $RANDOM"
9104 dalen=$((${#da}+1))
9105 TUNNET=10.255.255
9106 newport udp4 # provide free port number in $PORT
9107 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$TUNNET.2:$PORT"
9108 #CMD="$TRACE $SOCAT $opts -u -L $tl TUN,ifaddr=$TUNNET.1,netmask=255.255.255.0,iff-up=1 -"
9109 CMD="$TRACE $SOCAT $opts -u -L $tl TUN:$TUNNET.1/24,iff-up=1 -"
9110 printf "test $F_n $TEST... " $N
9111 $CMD 2>"${te}" |tail -c $dalen >"${tf}" &
9112 sleep 1
9113 echo "$da" |$CMD1 2>"${te}1"
9114 sleep 1
9115 kill "$(cat $tl 2>/dev/null)" 2>/dev/null
9116 wait
9117 if [ $? -ne 0 ]; then
9118 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9119 echo "$CMD &"
9120 echo "$CMD1"
9121 cat "${te}" "${te}1"
9122 numFAIL=$((numFAIL+1))
9123 listFAIL="$listFAIL $N"
9124 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9125 $PRINTF "$FAILED\n"
9126 echo "$CMD &"
9127 echo "$CMD1"
9128 cat "$tdiff"
9129 cat "${te}" "${te}1"
9130 numFAIL=$((numFAIL+1))
9131 listFAIL="$listFAIL $N"
9132 else
9133 $PRINTF "$OK\n"
9134 if [ -n "$debug" ]; then cat "${te}" "${te}1"; fi
9135 numOK=$((numOK+1))
9136 listOK="$listOK $N"
9138 fi ;; # NUMCOND, feats
9139 esac
9140 N=$((N+1))
9143 # use the INTERFACE address on a tun/tap device and transfer data fully
9144 # transparent
9145 NAME=TUNINTERFACE
9146 case "$TESTS" in
9147 *%$N%*|*%functions%*|*%tun%*|*%interface%*|*%root%*|*%$NAME%*)
9148 TEST="$NAME: pass data through tun interface using INTERFACE"
9149 #idea: create a TUN interface and send a raw packet on the interface side.
9150 # It should arrive unmodified on the tunnel side.
9151 if ! eval $NUMCOND; then :;
9152 elif ! feat=$(testfeats ip4 tun interface) || ! runsip4 >/dev/null; then
9153 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9154 numCANT=$((numCANT+1))
9155 listCANT="$listCANT $N"
9156 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
9157 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
9158 numCANT=$((numCANT+1))
9159 listCANT="$listCANT $N"
9160 else
9161 tf="$td/test$N.stdout"
9162 te="$td/test$N.stderr"
9163 tdiff="$td/test$N.diff"
9164 tl="$td/test$N.lock"
9165 da="$(date) $RANDOM"
9166 TUNNET=10.255.255
9167 TUNNAME=tun9
9168 CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME PIPE"
9169 CMD1="$TRACE $SOCAT $opts - INTERFACE:$TUNNAME"
9170 printf "test $F_n $TEST... " $N
9171 $CMD0 2>"${te}1" &
9172 pid0="$!"
9173 #waitinterface "$TUNNAME"
9174 relsleep 1
9175 { echo "$da"; relsleep 1; } |$CMD1 >"$tf" 2>"${te}"
9176 rc1=$?
9177 relsleep 1
9178 kill $pid0 2>/dev/null
9179 wait
9180 if [ "$rc1" -ne 0 ]; then
9181 $PRINTF "$FAILED (rc1=$rc1):\n"
9182 echo "$CMD0 &"
9183 cat "${te}0" >&2
9184 echo "$CMD1"
9185 cat "${te}1" >&2
9186 numFAIL=$((numFAIL+1))
9187 listFAIL="$listFAIL $N"
9188 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9189 $PRINTF "$FAILED (diff)\n"
9190 echo "$CMD0 &"
9191 cat "${te}0" >&2
9192 echo "$CMD1"
9193 cat "${te}1" >&2
9194 echo "// diff:"
9195 cat "$tdiff"
9196 numFAIL=$((numFAIL+1))
9197 listFAIL="$listFAIL $N"
9198 else
9199 $PRINTF "$OK\n"
9200 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
9201 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
9202 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
9203 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9204 numOK=$((numOK+1))
9205 listOK="$listOK $N"
9207 fi ;; # NUMCOND, feats
9208 esac
9209 N=$((N+1))
9212 NAME=ABSTRACTSTREAM
9213 case "$TESTS" in
9214 *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%connect%*|*%listen%*|*%$NAME%*)
9215 TEST="$NAME: abstract UNIX stream socket, listen and connect"
9216 if ! eval $NUMCOND; then :;
9217 elif ! feat=$(testfeats abstract-unixsocket); then
9218 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9219 numCANT=$((numCANT+1))
9220 listCANT="$listCANT $N"
9221 else
9222 ts="$td/test$N.socket"
9223 tf="$td/test$N.stdout"
9224 te="$td/test$N.stderr"
9225 tdiff="$td/test$N.diff"
9226 da1="test$N $(date) $RANDOM"
9227 #establish a listening abstract unix socket
9228 SRV="$TRACE $SOCAT $opts -lpserver ABSTRACT-LISTEN:\"$ts\",$REUSEADDR PIPE"
9229 #make a connection
9230 CMD="$TRACE $SOCAT $opts - ABSTRACT-CONNECT:$ts"
9231 $PRINTF "test $F_n $TEST... " $N
9232 touch "$ts" # make a file with same name, so non-abstract fails
9233 eval "$SRV 2>${te}s &"
9234 pids=$!
9235 #waitfile "$ts"
9236 sleep 1
9237 echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
9238 if [ $? -ne 0 ]; then
9239 kill "$pids" 2>/dev/null
9240 $PRINTF "$FAILED:\n"
9241 echo "$SRV &"
9242 cat "${te}s"
9243 echo "$CMD"
9244 cat "${te}1"
9245 numFAIL=$((numFAIL+1))
9246 listFAIL="$listFAIL $N"
9247 elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
9248 kill "$pids" 2>/dev/null
9249 $PRINTF "$FAILED:\n"
9250 echo "$SRV &"
9251 cat "${te}s"
9252 echo "$CMD"
9253 cat "${te}1"
9254 cat "$tdiff"
9255 numFAIL=$((numFAIL+1))
9256 listFAIL="$listFAIL $N"
9257 else
9258 $PRINTF "$OK\n"
9259 if [ -n "$debug" ]; then cat $te; fi
9260 numOK=$((numOK+1))
9261 listOK="$listOK $N"
9262 fi # !(rc -ne 0)
9263 wait
9264 fi ;; # NUMCOND, feats
9265 esac
9266 N=$((N+1))
9269 NAME=ABSTRACTDGRAM
9270 case "$TESTS" in
9271 *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%$NAME%*)
9272 TEST="$NAME: abstract UNIX datagram"
9273 if ! eval $NUMCOND; then :;
9274 elif ! feat=$(testfeats abstract-unixsocket); then
9275 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9276 numCANT=$((numCANT+1))
9277 listCANT="$listCANT $N"
9278 else
9279 tf="$td/test$N.stdout"
9280 te="$td/test$N.stderr"
9281 tdiff="$td/test$N.diff"
9282 ts1="$td/test$N.socket1"
9283 ts2="$td/test$N.socket2"
9284 da="test$N $(date) $RANDOM"
9285 CMD1="$TRACE $SOCAT $opts ABSTRACT-RECVFROM:$ts1,reuseaddr PIPE"
9286 #CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
9287 CMD2="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts2"
9288 printf "test $F_n $TEST... " $N
9289 touch "$ts1" # make a file with same name, so non-abstract fails
9290 $CMD1 2>"${te}1" &
9291 pid1="$!"
9292 sleep 1
9293 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9294 rc2=$?
9295 kill "$pid1" 2>/dev/null; wait
9296 if [ $rc2 -ne 0 ]; then
9297 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9298 echo "$CMD1 &"
9299 cat "${te}1" >&2
9300 echo "$CMD2"
9301 cat "${te}2" >&2
9302 numFAIL=$((numFAIL+1))
9303 listFAIL="$listFAIL $N"
9304 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9305 $PRINTF "$FAILED\n"
9306 echo "$CMD1 &"
9307 cat "${te}1" >&2
9308 echo "$CMD2"
9309 cat "${te}2" >&2
9310 cat "$tdiff" >&2
9311 numFAIL=$((numFAIL+1))
9312 listFAIL="$listFAIL $N"
9313 else
9314 $PRINTF "$OK\n"
9315 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9316 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9317 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9318 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9319 numOK=$((numOK+1))
9320 listOK="$listOK $N"
9322 fi ;; # NUMCOND, feats
9323 esac
9324 N=$((N+1))
9327 NAME=ABSTRACTRECV
9328 case "$TESTS" in
9329 *%$N%*|*%functions%*|*%unix%*|*%abstract%*|*%dgram%*|*%recv%*|*%$NAME%*)
9330 TEST="$NAME: abstract UNIX datagram receive"
9331 if ! eval $NUMCOND; then :;
9332 elif ! feat=$(testfeats abstract-unixsocket); then
9333 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
9334 numCANT=$((numCANT+1))
9335 listCANT="$listCANT $N"
9336 else
9337 ts="$td/test$N.socket"
9338 tf="$td/test$N.stdout"
9339 te="$td/test$N.stderr"
9340 tdiff="$td/test$N.diff"
9341 ts1="$ts"
9342 da="test$N $(date) $RANDOM"
9343 CMD1="$TRACE $SOCAT $opts -u ABSTRACT-RECV:$ts1,reuseaddr -"
9344 CMD2="$TRACE $SOCAT $opts -u - ABSTRACT-SENDTO:$ts1"
9345 printf "test $F_n $TEST... " $N
9346 touch "$ts1" # make a file with same name, so non-abstract fails
9347 $CMD1 >"$tf" 2>"${te}1" &
9348 pid1="$!"
9349 #waitfile $ts1 1
9350 sleep 1
9351 echo "$da" |$CMD2 2>>"${te}2"
9352 rc2="$?"
9353 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
9354 kill "$pid1" 2>/dev/null; wait
9355 if [ "$rc2" -ne 0 ]; then
9356 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9357 echo "$CMD1 &"
9358 cat "${te}1" >&2
9359 echo "$CMD2"
9360 cat "${te}2" >&2
9361 numFAIL=$((numFAIL+1))
9362 listFAIL="$listFAIL $N"
9363 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9364 $PRINTF "$FAILED\n"
9365 echo "$CMD1 &"
9366 cat "${te}1" >&2
9367 echo "$CMD2"
9368 cat "${te}2" >&2
9369 cat "$tdiff"
9370 numFAIL=$((numFAIL+1))
9371 listFAIL="$listFAIL $N"
9372 else
9373 $PRINTF "$OK\n"
9374 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9375 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9376 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9377 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9378 numOK=$((numOK+1))
9379 listOK="$listOK $N"
9381 fi ;; # NUMCOND, feats
9382 esac
9383 N=$((N+1))
9386 # bind with Linux abstract UNIX domain addresses bound to filesystem socket
9387 # instead of abstract namespace
9388 NAME=ABSTRACT_BIND
9389 case "$TESTS" in
9390 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%$NAME%*)
9391 TEST="$NAME: abstract bind"
9392 # open an abstract client address with bind option, bind to the target socket.
9393 # send a datagram.
9394 # when socat outputs the datagram it got the test succeeded
9395 if ! eval $NUMCOND; then :;
9396 elif [ "$UNAME" != Linux ]; then
9397 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
9398 numCANT=$((numCANT+1))
9399 listCANT="$listCANT $N"
9400 else
9401 tf="$td/test$N.stdout"
9402 te="$td/test$N.stderr"
9403 tdiff="$td/test$N.diff"
9404 ts1="$td/test$N.sock1"
9405 da="test$N $(date) $RANDOM"
9406 CMD1="$TRACE $SOCAT $opts - ABSTRACT-SENDTO:$ts1,bind=$ts1"
9407 printf "test $F_n $TEST... " $N
9408 echo "$da" |$CMD1 >$tf 2>"${te}1"
9409 rc1=$?
9410 if [ $rc1 -ne 0 ]; then
9411 $PRINTF "$FAILED\n"
9412 echo "$CMD1"
9413 echo "rc=$rc1" >&2
9414 cat "${te}1" >&2
9415 numFAIL=$((numFAIL+1))
9416 listFAIL="$listFAIL $N"
9417 elif echo "$da" |diff -q - $tf; then
9418 $PRINTF "$OK\n"
9419 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9420 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9421 numOK=$((numOK+1))
9422 listOK="$listOK $N"
9423 else
9424 $PRINTF "$FAILED\n"
9425 echo "$CMD1" >&2
9426 cat "${te}1" >&2
9427 echo "$da" |diff - "$tf" >&2
9428 numFAIL=$((numFAIL+1))
9429 listFAIL="$listFAIL $N"
9431 fi # NUMCOND
9433 esac
9434 N=$((N+1))
9437 NAME=OPENSSLREAD
9438 # socat determined availability of data using select(). With openssl, the
9439 # following situation might occur:
9440 # a SSL data block with more than 8192 bytes (socats default blocksize)
9441 # arrives; socat calls SSL_read, and the SSL routine reads the complete block.
9442 # socat then reads 8192 bytes from the SSL layer, the rest remains buffered.
9443 # If the TCP connection stays idle for some time, the data in the SSL layer
9444 # keeps there and is not transferred by socat until the socket indicates more
9445 # data or EOF.
9446 case "$TESTS" in
9447 *%$N%*|*%functions%*|*%openssl%*|*%listen%*|*%$NAME%*)
9448 TEST="$NAME: socat handles data buffered by openssl"
9449 #idea: have a socat process (server) that gets an SSL block that is larger than
9450 # socat transfer block size; keep the socket connection open and kill the
9451 # server process after a short time; if not the whole data block has been
9452 # transferred, the test has failed.
9453 if ! eval $NUMCOND; then :;
9454 elif ! feat=$(testfeats openssl) >/dev/null; then
9455 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
9456 numCANT=$((numCANT+1))
9457 listCANT="$listCANT $N"
9458 else
9459 tf="$td/test$N.out"
9460 te="$td/test$N.err"
9461 tdiff="$td/test$N.diff"
9462 da="test$N $(date) $RANDOM"
9463 SRVCERT=testsrv
9464 gentestcert "$SRVCERT"
9465 newport tcp4 # provide free port number in $PORT
9466 CMD1="$TRACE $SOCAT $opts -u -T 1 -b $($ECHO "$da\c" |wc -c) OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=$SRVCERT.pem,verify=0 -"
9467 CMD2="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0"
9468 printf "test $F_n $TEST... " $N
9470 $CMD1 2>"${te}1" >"$tf" &
9471 pid=$! # background process id
9472 waittcp4port $PORT
9473 (echo "$da"; sleep 2) |$CMD2 2>"${te}2"
9474 kill "$pid" 2>/dev/null; wait
9475 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
9476 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9477 echo "$CMD1"
9478 cat "${te}1"
9479 echo "$CMD2"
9480 cat "${te}2"
9481 cat "$tdiff"
9482 numFAIL=$((numFAIL+1))
9483 listFAIL="$listFAIL $N"
9484 else
9485 $PRINTF "$OK\n"
9486 if [ -n "$debug" ]; then cat $te; fi
9487 numOK=$((numOK+1))
9488 listOK="$listOK $N"
9490 wait
9491 fi # NUMCOND, featsesac
9493 esac
9494 N=$((N+1))
9497 # test: there is a bug with the readbytes option: when the socket delivered
9498 # exacly that many bytes as specified with readbytes and the stays idle (no
9499 # more data, no EOF), socat waits for more data instead of generating EOF on
9500 # this in put stream.
9501 NAME=READBYTES_EOF
9502 #set -vx
9503 case "$TESTS" in
9504 *%$N%*|*%functions%*|*%$NAME%*)
9505 TEST="$NAME: trigger EOF after that many bytes, even when socket idle"
9506 #idea: we deliver that many bytes to socat; the process should terminate then.
9507 # we try to transfer data in the other direction then; if transfer succeeds,
9508 # the process did not terminate and the bug is still there.
9509 if ! eval $NUMCOND; then :;
9510 elif false; then
9511 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
9512 numCANT=$((numCANT+1))
9513 listCANT="$listCANT $N"
9514 else
9515 tr="$td/test$N.ref"
9516 ti="$td/test$N.in"
9517 to="$td/test$N.out"
9518 te="$td/test$N.err"
9519 tdiff="$td/test$N.diff"
9520 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
9521 CMD="$TRACE $SOCAT $opts SYSTEM:\"echo A; sleep $((2*SECONDs))\",readbytes=2!!- -!!/dev/null"
9522 printf "test $F_n $TEST... " $N
9523 (relsleep 2; echo) |eval "$CMD" >"$to" 2>"$te"
9524 if test -s "$to"; then
9525 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9526 echo "$CMD"
9527 numFAIL=$((numFAIL+1))
9528 listFAIL="$listFAIL $N"
9529 else
9530 $PRINTF "$OK\n"
9531 if [ -n "$debug" ]; then cat $te; fi
9532 numOK=$((numOK+1))
9533 listOK="$listOK $N"
9535 fi ;; # NUMCOND, feats
9536 esac
9537 N=$((N+1))
9540 # test: there was a bug with exec:...,pty that did not kill the exec'd sub
9541 # process under some circumstances.
9542 NAME=EXECPTYKILL
9543 case "$TESTS" in
9544 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%pty%*|*%listen%*|*%unix%*|*%fork%*|*%$NAME%*)
9545 TEST="$NAME: exec:...,pty explicitely kills sub process"
9546 # we want to check if the exec'd sub process is killed in time
9547 # for this we have a shell script that generates a file after two seconds;
9548 # it should be killed after one second, so if the file was generated the test
9549 # has failed
9550 if ! eval $NUMCOND; then :; else
9551 tf="$td/test$N.stdout"
9552 te="$td/test$N.stderr"
9553 ts="$td/test$N.sock"
9554 tda="$td/test$N.data"
9555 tsh="$td/test$N.sh"
9556 tdiff="$td/test$N.diff"
9557 cat >"$tsh" <<EOF
9558 relsleep $SECONDs; echo; relsleep $SECONDs; touch "$tda"; echo
9560 chmod a+x "$tsh"
9561 CMD1="$TRACE $SOCAT $opts -t $(reltime 1) -U UNIX-LISTEN:$ts,fork EXEC:$tsh,pty"
9562 CMD="$TRACE $SOCAT $opts -t $(reltime 1) /dev/null UNIX-CONNECT:$ts"
9563 printf "test $F_n $TEST... " $N
9564 $CMD1 2>"${te}2" &
9565 pid1=$!
9566 relsleep 1
9567 waitfile $ts 1
9568 $CMD 2>>"${te}1" >>"$tf"
9569 relsleep 2
9570 kill "$pid1" 2>/dev/null
9571 wait
9572 if [ $? -ne 0 ]; then
9573 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9574 echo "$CMD1 &"
9575 echo "$CMD2"
9576 cat "${te}1" "${te}2"
9577 numFAIL=$((numFAIL+1))
9578 listFAIL="$listFAIL $N"
9579 elif [ -f "$tda" ]; then
9580 $PRINTF "$FAILED\n"
9581 cat "${te}1" "${te}2"
9582 numFAIL=$((numFAIL+1))
9583 listFAIL="$listFAIL $N"
9584 else
9585 $PRINTF "$OK\n"
9586 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
9587 numOK=$((numOK+1))
9588 listOK="$listOK $N"
9590 fi ;; # NUMCOND
9591 esac
9592 N=$((N+1))
9595 # test if service name resolution works; this was buggy in 1.5 and 1.6.0.0
9596 NAME=TCP4SERVICE
9597 case "$TESTS" in
9598 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%$NAME%*)
9599 TEST="$NAME: echo via connection to TCP V4 socket"
9600 # select a tcp entry from /etc/services, have a server listen on the port
9601 # number and connect using the service name; with the bug, connection will to a
9602 # wrong port
9603 if ! eval $NUMCOND; then :; else
9604 tf="$td/test$N.stdout"
9605 te="$td/test$N.stderr"
9606 tdiff="$td/test$N.diff"
9607 # find a service entry we do not need root for (>=1024; here >=1100 for ease)
9608 SERVENT="$(grep '^[a-z][a-z]*[^!-~][^!-~]*[1-9][1-9][0-9][0-9]/tcp' /etc/services |head -n 1)"
9609 SERVICE="$(echo $SERVENT |cut -d' ' -f1)"
9610 _PORT="$PORT"
9611 PORT="$(echo $SERVENT |sed 's/.* \([1-9][0-9]*\).*/\1/')"
9612 tsl="$PORT"
9613 ts="127.0.0.1:$SERVICE"
9614 da="test$N $(date) $RANDOM"
9615 CMD1="$TRACE $SOCAT $opts TCP4-LISTEN:$tsl,$REUSEADDR PIPE"
9616 CMD2="$TRACE $SOCAT $opts stdin!!stdout TCP4:$ts"
9617 printf "test $F_n $TEST... " $N
9618 $CMD1 >"$tf" 2>"${te}1" &
9619 pid1=$!
9620 waittcp4port $tsl 1
9621 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9622 if [ $? -ne 0 ]; then
9623 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9624 echo "$CMD1 &"
9625 cat "${te}1"
9626 echo "$CMD2"
9627 cat "${te}2"
9628 numFAIL=$((numFAIL+1))
9629 listFAIL="$listFAIL $N"
9630 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9631 $PRINTF "$FAILED\n"
9632 cat "$tdiff"
9633 numFAIL=$((numFAIL+1))
9634 listFAIL="$listFAIL $N"
9635 else
9636 $PRINTF "$OK\n"
9637 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
9638 numOK=$((numOK+1))
9639 listOK="$listOK $N"
9641 kill $pid1 2>/dev/null
9642 wait
9643 PORT=$_PORT
9644 fi ;; # NUMCOND
9645 esac
9646 N=$((N+1))
9649 # test: up to socat 1.6.0.0, the highest file descriptor supported in socats
9650 # transfer engine was FOPEN_MAX-1; this usually worked fine but would fail when
9651 # socat was invoked with many file descriptors already opened. socat would
9652 # just hang in the select() call. Thanks to Daniel Lucq for reporting this
9653 # problem.
9654 # FOPEN_MAX on different OS's:
9655 # OS FOPEN_ ulimit ulimit FD_
9656 # MAX -H -n -S -n SETSIZE
9657 # Linux 2.6: 16 1024 1024 1024
9658 # HP-UX 11.11: 60 2048 2048 2048
9659 # FreeBSD: 20 11095 11095 1024
9660 # Cygwin: 20 unlimit 256 64
9661 # AIX: 32767 65534 65534
9662 # SunOS 8: 20 1024
9663 # musl libc: 1024
9664 NAME=EXCEED_FOPEN_MAX
9665 case "$TESTS" in
9666 *%$N%*|*%functions%*|*%maxfds%*|*%$NAME%*)
9667 TEST="$NAME: more than FOPEN_MAX FDs in use"
9668 # this test opens a number of FDs before socat is invoked. socat will have to
9669 # allocate higher FD numbers and thus hang if it cannot handle them.
9670 if ! eval $NUMCOND; then :;
9671 elif [ "$UNAME" != Linux ]; then
9672 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
9673 numCANT=$((numCANT+1))
9674 listCANT="$listCANT $N"
9675 else
9676 REDIR=
9677 #set -vx
9678 if [ -z "$FOPEN_MAX" ]; then
9679 $PRINTF "test $F_n $TEST... ${YELLOW}could not determine FOPEN_MAX${NORMAL}\n" "$N"
9680 numCANT=$((numCANT+1))
9681 listCANT="$listCANT $N"
9682 else
9683 if [ $FOPEN_MAX -lt 270 ]; then
9684 OPEN_FILES=$FOPEN_MAX # more than the highest FOPEN_MAX
9685 else
9686 OPEN_FILES=269 # bash tends to SIGSEGV on higher value
9687 # btw, the test is obsolete anyway
9689 i=3; while [ "$i" -lt "$OPEN_FILES" ]; do
9690 REDIR="$REDIR $i>&2"
9691 i=$((i+1))
9692 done
9693 #echo "$REDIR"
9694 #testecho "$N" "$TEST" "" "pipe" "$opts -T 3" "" 1
9695 #set -vx
9696 eval testecho "\"$N\"" "\"$TEST\"" "\"\"" "pipe" "\"$opts -T $((2*SECONDs))\"" 1 $REDIR
9697 #set +vx
9698 fi # could determine FOPEN_MAX
9699 fi ;; # NUMCOND
9700 esac
9701 N=$((N+1))
9704 # there was a bug with udp-listen and fork: terminating sub processes became
9705 # zombies because the master process did not catch SIGCHLD
9706 NAME=UDP4LISTEN_SIGCHLD
9707 case "$TESTS" in
9708 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%zombie%*|*%signal%*|*%listen%*|*%fork%*|*%$NAME%*)
9709 TEST="$NAME: test if UDP4-LISTEN child becomes zombie"
9710 # idea: run a udp-listen process with fork and -T. Connect once, so a sub
9711 # process is forked off. Make some transfer and wait until the -T timeout is
9712 # over. Now check for the child process: if it is zombie the test failed.
9713 # Correct is that child process terminated
9714 if ! eval $NUMCOND; then :; else
9715 tf="$td/test$N.stdout"
9716 te="$td/test$N.stderr"
9717 tdiff="$td/test$N.diff"
9718 newport udp4; tsl=$PORT
9719 ts="$LOCALHOST:$tsl"
9720 da="test$N $(date) $RANDOM"
9721 CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-LISTEN:$tsl,$REUSEADDR,fork PIPE"
9722 CMD2="$TRACE $SOCAT $opts - UDP4:$ts"
9723 printf "test $F_n $TEST... " $N
9724 $CMD1 >"$tf" 2>"${te}1" &
9725 pid1=$!
9726 waitudp4port $tsl 1
9727 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9728 rc2=$?
9729 sleep 1
9730 #read -p ">"
9731 l="$(childprocess $pid1)"
9732 kill $pid1 2>/dev/null; wait
9733 if [ $rc2 -ne 0 ]; then
9734 $PRINTF "$NO_RESULT (client failed)\n" # already handled in test UDP4STREAM
9735 numCANT=$((numCANT+1))
9736 listCANT="$listCANT $N"
9737 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9738 $PRINTF "$NO_RESULT (diff failed)\n" # already handled in test UDP4STREAM
9739 numCANT=$((numCANT+1))
9740 listCANT="$listCANT $N"
9741 elif $(isdefunct "$l"); then
9742 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9743 echo "$CMD1 &"
9744 echo "$CMD2"
9745 cat "${te}1" "${te}2"
9746 numFAIL=$((numFAIL+1))
9747 listFAIL="$listFAIL $N"
9748 else
9749 $PRINTF "$OK\n"
9750 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
9751 numOK=$((numOK+1))
9752 listOK="$listOK $N"
9754 fi ;; # NUMCOND
9755 esac
9756 N=$((N+1))
9757 #set +vx
9759 # there was a bug with udp-recvfrom and fork: terminating sub processes became
9760 # zombies because the master process caught SIGCHLD but did not wait()
9761 NAME=UDP4RECVFROM_SIGCHLD
9762 case "$TESTS" in
9763 *%$N%*|*%functions%*|*%bugs%*|*%fork%*|*%ip4%*|*%udp%*|*%dgram%*|*%zombie%*|*%signal%*|*%$NAME%*)
9764 TEST="$NAME: test if UDP4-RECVFROM child becomes zombie"
9765 # idea: run a udp-recvfrom process with fork and -T. Send it one packet, so a
9766 # sub process is forked off. Make some transfer and wait until the -T timeout
9767 # is over. Now check for the child process: if it is zombie the test failed.
9768 # Correct is that child process terminated
9769 if ! eval $NUMCOND; then :; else
9770 tf="$td/test$N.stdout"
9771 te="$td/test$N.stderr"
9772 tdiff="$td/test$N.diff"
9773 newport udp4; tsl=$PORT
9774 ts="$LOCALHOST:$tsl"
9775 da="test$N $(date) $RANDOM"
9776 CMD1="$TRACE $SOCAT $opts -T 0.5 UDP4-RECVFROM:$tsl,reuseaddr,fork PIPE"
9777 CMD2="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts"
9778 printf "test $F_n $TEST... " $N
9779 $CMD1 >"$tf" 2>"${te}1" &
9780 pid1=$!
9781 waitudp4port $tsl 1
9782 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
9783 rc2=$?
9784 sleep 1
9785 #read -p ">"
9786 l="$(childprocess $pid1)"
9787 #echo "l=\"$l\""
9788 kill $pid1 2>/dev/null; wait
9789 if [ $rc2 -ne 0 ]; then
9790 $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM
9791 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9792 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9793 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9794 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9795 numCANT=$((numCANT+1))
9796 listCANT="$listCANT $N"
9797 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9798 $PRINTF "$NO_RESULT\n" # already handled in test UDP4DGRAM
9799 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9800 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9801 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9802 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9803 numCANT=$((numCANT+1))
9804 listCANT="$listCANT $N"
9805 elif $(isdefunct "$l"); then
9806 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9807 echo "$CMD1 &"
9808 cat "${te}1" >&2
9809 echo "$CMD2"
9810 cat "${te}2" >&2
9811 cat "${te}1" "${te}2"
9812 numFAIL=$((numFAIL+1))
9813 listFAIL="$listFAIL $N"
9814 else
9815 $PRINTF "$OK\n"
9816 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
9817 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
9818 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
9819 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
9820 numOK=$((numOK+1))
9821 listOK="$listOK $N"
9823 fi ;; # NUMCOND
9824 esac
9825 N=$((N+1))
9828 # test: there was a bug with ip*-recv and bind option: it would not bind, and
9829 # with the first received packet an error:
9830 # socket_init(): unknown address family 0
9831 # occurred
9832 NAME=RAWIP4RECVBIND
9833 case "$TESTS" in
9834 *%$N%*|*%functions%*|*%ip4%*|*%dgram%*|*%rawip%*|*%rawip4%*|*%recv%*|*%root%*|*%$NAME%*)
9835 TEST="$NAME: raw IPv4 receive with bind"
9836 # idea: start a socat process with ip4-recv:...,bind=... and send it a packet
9837 # if the packet passes the test succeeded
9838 if ! eval $NUMCOND; then :;
9839 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
9840 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
9841 numCANT=$((numCANT+1))
9842 listCANT="$listCANT $N"
9843 else
9844 tf="$td/test$N.stdout"
9845 te="$td/test$N.stderr"
9846 tdiff="$td/test$N.diff"
9847 ts1p=$IPPROTO; #IPPROTO=$((IPPROTO+1))
9848 ts1a="127.0.0.1"
9849 ts1="$ts1a:$ts1p"
9850 da="test$N $(date) $RANDOM"
9851 CMD1="$TRACE $SOCAT $opts -u IP4-RECV:$ts1p,bind=$ts1a,reuseaddr -"
9852 CMD2="$TRACE $SOCAT $opts -u - IP4-SENDTO:$ts1"
9853 printf "test $F_n $TEST... " $N
9854 $CMD1 >"$tf" 2>"${te}1" &
9855 pid1="$!"
9856 waitip4proto $ts1p 1
9857 echo "$da" |$CMD2 2>>"${te}2"
9858 rc2="$?"
9859 #ls -l $tf
9860 i=0; while [ ! -s "$tf" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
9861 kill "$pid1" 2>/dev/null; wait
9862 if [ "$rc2" -ne 0 ]; then
9863 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9864 echo "$CMD1 &"
9865 echo "$CMD2"
9866 cat "${te}1"
9867 cat "${te}2"
9868 numFAIL=$((numFAIL+1))
9869 listFAIL="$listFAIL $N"
9870 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
9871 $PRINTF "$FAILED\n"
9872 cat "$tdiff"
9873 numFAIL=$((numFAIL+1))
9874 listFAIL="$listFAIL $N"
9875 else
9876 $PRINTF "$OK\n"
9877 if [ -n "$debug" ]; then cat $te; fi
9878 numOK=$((numOK+1))
9879 listOK="$listOK $N"
9881 fi ;; # NUMCOND, root
9882 esac
9883 #IPPROTO=$((IPPROTO+1))
9884 N=$((N+1))
9887 # there was a bug in *-recvfrom with fork: due to an error in the appropriate
9888 # signal handler the master process would hang after forking off the first
9889 # child process.
9890 NAME=UDP4RECVFROM_FORK
9891 case "$TESTS" in
9892 *%$N%*|*%functions%*|*%fork%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
9893 TEST="$NAME: test if UDP4-RECVFROM handles more than one packet"
9894 # idea: run a UDP4-RECVFROM process with fork and -T. Send it one packet;
9895 # send it a second packet and check if this is processed properly. If yes, the
9896 # test succeeded.
9897 if ! eval $NUMCOND; then :; else
9898 tf="$td/test$N.stdout"
9899 te="$td/test$N.stderr"
9900 tdiff="$td/test$N.diff"
9901 newport udp4; tsp=$PORT
9902 ts="$LOCALHOST:$tsp"
9903 da2a="test$N $(date) $RANDOM"
9904 da2b="test$N $(date) $RANDOM"
9905 CMD1="$TRACE $SOCAT $opts -T 2 UDP4-RECVFROM:$tsp,reuseaddr,fork PIPE"
9906 CMD2="$TRACE $SOCAT $opts -T 1 - UDP4-SENDTO:$ts"
9907 printf "test $F_n $TEST... " $N
9908 $CMD1 >/dev/null 2>"${te}1" &
9909 pid1=$!
9910 waitudp4port $tsp 1
9911 echo "$da2a" |$CMD2 >/dev/null 2>>"${te}2a" # this should always work
9912 rc2a=$?
9913 echo "$da2b" |$CMD2 >"$tf" 2>>"${te}2b" # this would fail when bug
9914 rc2b=$?
9915 kill $pid1 2>/dev/null; wait
9916 if [ $rc2b -ne 0 ]; then
9917 $PRINTF "$NO_RESULT\n"
9918 numCANT=$((numCANT+1))
9919 listCANT="$listCANT $N"
9920 elif ! echo "$da2b" |diff - "$tf" >"$tdiff"; then
9921 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9922 echo "$CMD1 &" >&2
9923 cat "${te}1" >&2
9924 echo "$CMD2" >&2
9925 cat "${te}2b" >&2
9926 cat "$tdiff" >&2
9927 numFAIL=$((numFAIL+1))
9928 listFAIL="$listFAIL $N"
9929 else
9930 $PRINTF "$OK\n"
9931 if [ -n "$debug" ]; then cat "${te}1" "${te}2" "${te}3"; fi
9932 numOK=$((numOK+1))
9933 listOK="$listOK $N"
9935 fi ;; # NUMCOND
9936 esac
9937 N=$((N+1))
9940 # there was a bug in parsing the arguments of exec: consecutive spaces resulted
9941 # in additional empty arguments
9942 NAME=EXECSPACES
9943 case "$TESTS" in
9944 *%$N%*|*%functions%*|*%exec%*|*%parse%*|*%$NAME%*)
9945 TEST="$NAME: correctly parse exec with consecutive spaces"
9946 if ! eval $NUMCOND; then :; else
9947 $PRINTF "test $F_n $TEST... " $N
9948 tf="$td/test$N.stdout"
9949 te="$td/test$N.stderr"
9950 da="test$N $(date) $RANDOM" # with a double space
9951 tdiff="$td/test$N.diff"
9952 # put the test data as first argument after two spaces. expect the data in the
9953 # first argument of the exec'd command.
9954 $TRACE $SOCAT $opts -u "exec:\"bash -c \\\"echo \\\\\\\"\$1\\\\\\\"\\\" \\\"\\\" \\\"$da\\\"\"" - >"$tf" 2>"$te"
9955 rc=$?
9956 echo "$da" |diff - "$tf" >"$tdiff"
9957 if [ "$rc" -ne 0 ]; then
9958 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9959 cat "$te"
9960 numFAIL=$((numFAIL+1))
9961 listFAIL="$listFAIL $N"
9962 elif [ -s "$tdiff" ]; then
9963 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
9964 echo diff:
9965 cat "$tdiff"
9966 if [ -n "$debug" ]; then cat $te; fi
9967 numFAIL=$((numFAIL+1))
9968 listFAIL="$listFAIL $N"
9969 else
9970 $PRINTF "$OK\n"
9971 if [ -n "$debug" ]; then cat $te; fi
9972 numOK=$((numOK+1))
9973 listOK="$listOK $N"
9975 fi ;; # NUMCOND
9976 esac
9977 N=$((N+1))
9980 # a bug was found in the way UDP-LISTEN handles the listening socket:
9981 # when UDP-LISTEN continued to listen after a packet had been dropped by, e.g.,
9982 # range option, the old listen socket would not be closed but a new one created.
9983 NAME=UDP4LISTENCONT
9984 case "$TESTS" in
9985 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%listen%*|*%$NAME%*)
9986 TEST="$NAME: let range drop a packet and see if old socket is closed"
9987 # idea: run a UDP4-LISTEN process with range option. Send it one packet from an
9988 # address outside range and check if two listening sockets are open then
9989 if ! eval $NUMCOND; then :; else
9990 tf="$td/test$N.stdout"
9991 te="$td/test$N.stderr"
9992 tdiff="$td/test$N.diff"
9993 newport udp4; tp=$PORT
9994 da1="test$N $(date) $RANDOM"
9995 a1="$LOCALHOST"
9996 a2="$SECONDADDR"
9997 #CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,bind=$a1,range=$a2/32 PIPE"
9998 CMD0="$TRACE $SOCAT $opts UDP4-LISTEN:$tp,$REUSEADDR,range=$a2/32 PIPE"
9999 CMD1="$TRACE $SOCAT $opts - UDP-CONNECT:$a1:$tp"
10000 printf "test $F_n $TEST... " $N
10001 $CMD0 >/dev/null 2>"${te}0" &
10002 pid1=$!
10003 waitudp4port $tp 1
10004 echo "$da1" |$CMD1 >"${tf}1" 2>"${te}1" # this should fail
10005 rc1=$?
10006 waitudp4port $tp 1
10007 if [ "$SS" ]; then
10008 nsocks="$($SS -anu |grep ":$PORT\>" |wc -l)"
10009 else
10010 nsocks="$(netstat -an |grep "^udp.*[:.]$PORT\>" |wc -l)"
10012 kill $pid1 2>/dev/null; wait
10013 if [ $rc1 -ne 0 ]; then
10014 $PRINTF "$NO_RESULT\n"
10015 numCANT=$((numCANT+1))
10016 listCANT="$listCANT $N"
10017 elif [ $nsocks -eq 0 ]; then
10018 $PRINTF "$NO_RESULT\n"
10019 numCANT=$((numCANT+1))
10020 listCANT="$listCANT $N"
10021 elif [ $nsocks -ne 1 ]; then
10022 $PRINTF "$FAILED ($nsocks listening sockets)\n"
10023 echo "$CMD0 &"
10024 echo "$CMD1"
10025 cat "${te}0" "${te}1"
10026 numFAIL=$((numFAIL+1))
10027 listFAIL="$listFAIL $N"
10028 else
10029 $PRINTF "$OK\n"
10030 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
10031 numOK=$((numOK+1))
10032 listOK="$listOK $N"
10034 fi ;; # NUMCOND
10035 esac
10036 N=$((N+1))
10039 # during wait for next poll time option ignoreeof blocked the data transfer in
10040 # the reverse direction
10041 NAME=IGNOREEOFNOBLOCK
10042 case "$TESTS" in
10043 *%$N%*|*%functions%*|*%engine%*|*%socket%*|*%ignoreeof%*|*%$NAME%*)
10044 TEST="$NAME: ignoreeof does not block other direction"
10045 # have socat poll in ignoreeof mode. while it waits one second for next check,
10046 # we send data in the reverse direction and then the total timeout fires.
10047 # it the data has passed, the test succeeded.
10048 if ! eval $NUMCOND; then :; else
10049 tf="$td/test$N.stout"
10050 te="$td/test$N.stderr"
10051 tdiff="$td/test$N.diff"
10052 da="test$N $(date) $RANDOM"
10053 CMD0="$TRACE $SOCAT $opts /dev/null,ignoreeof!!- -!!/dev/null"
10054 printf "test $F_n $TEST... " $N
10055 (sleep 0.333333; echo "$da") |$CMD0 >"$tf" 2>"${te}0"
10056 rc0=$?
10057 if [ $rc0 != 0 ]; then
10058 $PRINTF "$FAILED\n"
10059 echo "$CMD0 &"
10060 echo "$CMD1"
10061 cat "${te}0"
10062 cat "${te}1"
10063 numFAIL=$((numFAIL+1))
10064 listFAIL="$listFAIL $N"
10065 elif echo "$da" |diff - "$tf" >/dev/null; then
10066 $PRINTF "$OK\n"
10067 numOK=$((numOK+1))
10068 listOK="$listOK $N"
10069 else
10070 $PRINTF "$FAILED\n"
10071 echo "$CMD0 &"
10072 echo "$CMD1"
10073 cat "${te}0"
10074 numFAIL=$((numFAIL+1))
10075 listFAIL="$listFAIL $N"
10077 fi ;; # NUMCOND
10078 esac
10079 N=$((N+1))
10082 # test the escape option
10083 NAME=ESCAPE
10084 case "$TESTS" in
10085 *%$N%*|*%functions%*|*%engine%*|*%escape%*|*%$NAME%*)
10086 TEST="$NAME: escape character triggers EOF"
10087 # idea: start socat just echoing input, but apply escape option. send a string
10088 # containing the escape character and check if the output is truncated
10089 if ! eval $NUMCOND; then :; else
10090 tf="$td/test$N.stdout"
10091 te="$td/test$N.stderr"
10092 tdiff="$td/test$N.diff"
10093 da="test$N $(date) $RANDOM"
10094 CMD="$TRACE $SOCAT $opts -,escape=27 pipe"
10095 printf "test $F_n $TEST... " $N
10096 $ECHO "$da\n\x1bXYZ" |$CMD >"$tf" 2>"$te"
10097 if [ $? -ne 0 ]; then
10098 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10099 echo "$CMD"
10100 cat "$te"
10101 numFAIL=$((numFAIL+1))
10102 listFAIL="$listFAIL $N"
10103 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10104 $PRINTF "$FAILED: diff:\n"
10105 cat "$tdiff"
10106 numFAIL=$((numFAIL+1))
10107 listFAIL="$listFAIL $N"
10108 else
10109 $PRINTF "$OK\n"
10110 if [ -n "$debug" ]; then cat $te; fi
10111 numOK=$((numOK+1))
10112 listOK="$listOK $N"
10114 fi ;; # NUMCOND
10115 esac
10116 N=$((N+1))
10118 # test the escape option combined with ignoreeof
10119 NAME=ESCAPE_IGNOREEOF
10120 case "$TESTS" in
10121 *%$N%*|*%functions%*|*%engine%*|*%ignoreeof%*|*%escape%*|*%$NAME%*)
10122 TEST="$NAME: escape character triggers EOF"
10123 # idea: start socat just echoing input, but apply escape option. send a string
10124 # containing the escape character and check if the output is truncated
10125 if ! eval $NUMCOND; then :; else
10126 ti="$td/test$N.file"
10127 tf="$td/test$N.stdout"
10128 te="$td/test$N.stderr"
10129 tdiff="$td/test$N.diff"
10130 da="test$N $(date) $RANDOM"
10131 CMD="$TRACE $SOCAT -T 5 $opts file:$ti,ignoreeof,escape=27!!- pipe"
10132 printf "test $F_n $TEST... " $N
10133 >"$ti"
10134 $CMD >"$tf" 2>"$te" &
10135 $ECHO "$da\n\x1bXYZ" >>"$ti"
10136 sleep 1
10137 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
10138 $PRINTF "$FAILED: diff:\n"
10139 cat "$tdiff"
10140 cat "$te"
10141 numFAIL=$((numFAIL+1))
10142 listFAIL="$listFAIL $N"
10143 else
10144 $PRINTF "$OK\n"
10145 if [ -n "$debug" ]; then cat $te; fi
10146 numOK=$((numOK+1))
10147 listOK="$listOK $N"
10149 fi ;; # NUMCOND
10150 esac
10151 N=$((N+1))
10154 # test: logging of ancillary message
10155 while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE
10157 if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
10159 pf="$(echo "$PF" |tr A-Z a-z)"
10160 proto="$(echo "$KEYW" |tr A-Z a-z)"
10161 NAME=${KEYW}SCM_$SCM_TYPE
10162 case "$TESTS" in
10163 *%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%$ROOT%*|*%$NAME%*)
10164 TEST="$NAME: $KEYW log ancillary message $SCM_TYPE $SCM_NAME"
10165 # idea: start a socat process with *-RECV:..,... , ev. with ancillary message
10166 # enabling option and send it a packet, ev. with some option. check the info log
10167 # for the appropriate output.
10168 if ! eval $NUMCOND; then :;
10169 #elif [[ "$PF" == "#*" ]]; then :
10170 elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
10171 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
10172 numCANT=$((numCANT+1))
10173 listCANT="$listCANT $N"
10174 elif ! feat=$(testfeats ${KEYW%[46]} IP${KEYW##*[A-Z]}); then
10175 $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not configured in $SOCAT${NORMAL}\n" $N
10176 numCANT=$((numCANT+1))
10177 listCANT="$listCANT $N"
10178 elif ! runs${proto} >/dev/null; then
10179 $PRINTF "test $F_n $TEST... ${YELLOW}$KEYW not available on host${NORMAL}\n" $N
10180 numCANT=$((numCANT+1))
10181 listCANT="$listCANT $N"
10182 elif ! testoptions $SCM_RECV >/dev/null; then
10183 $PRINTF "test $F_n $TEST... ${YELLOW}option $SCM_RECV not available${NORMAL}\n" $N
10184 numCANT=$((numCANT+1))
10185 listCANT="$listCANT $N"
10186 else
10187 tf="$td/test$N.stdout"
10188 te="$td/test$N.stderr"
10189 case "X$IPPORT" in
10190 "XPORT")
10191 newport $proto; tra="$PORT" # test recv address
10192 tsa="$ADDR:$PORT" # test sendto address
10194 "XPROTO")
10195 tra="$IPPROTO" # test recv address
10196 tsa="$ADDR:$IPPROTO" # test sendto address
10197 #IPPROTO=$((IPPROTO+1))
10200 tra="$(eval echo "$ADDR")" # resolve $N
10201 tsa="$tra"
10202 esac
10203 CMD0="$TRACE $SOCAT $opts -d -d -d -u $KEYW-RECV:$tra,reuseaddr,$SCM_RECV -"
10204 CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
10205 printf "test $F_n $TEST... " $N
10206 # is this option supported?
10207 if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
10208 if [ "$SCM_VALUE" = "timestamp" ]; then
10209 secs="$(date '+%S')"
10210 if [ "$secs" -ge 58 -a "$secs" -le 59 ]; then
10211 dsecs=$((60-secs))
10212 #echo "Sleeping $dsecs seconds to avoid minute change in timestamp" >/dev/tty
10213 sleep $dsecs
10216 $CMD0 >"$tf" 2>"${te}0" &
10217 pid0="$!"
10218 wait${proto}port $tra 1
10219 echo "XYZ" |$CMD1 2>"${te}1"
10220 rc1="$?"
10221 sleep 1
10222 i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
10223 kill "$pid0" 2>/dev/null; wait
10224 # do not show more messages than requested
10225 case "$opts" in
10226 *-d*-d*-d*-d*) LEVELS="[EWNID]" ;;
10227 *-d*-d*-d*) LEVELS="[EWNI]" ;;
10228 *-d*-d*) LEVELS="[EWN]" ;;
10229 *-d*) LEVELS="[EW]" ;;
10230 *) LEVELS="[E]" ;;
10231 esac
10232 if [ "$SCM_VALUE" = "timestamp" ]; then
10233 SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs"
10235 if [ "$rc1" -ne 0 ]; then
10236 $PRINTF "$NO_RESULT: $TRACE $SOCAT:\n"
10237 echo "$CMD0 &"
10238 echo "$CMD1"
10239 grep " $LEVELS " "${te}0"
10240 grep " $LEVELS " "${te}1"
10241 numCANT=$((numCANT+1))
10242 listCANT="$listCANT $N"
10243 elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=" ${te}0 >/dev/null; then
10244 $PRINTF "$FAILED\n"
10245 echo "variable $SCM_TYPE: $SCM_NAME not set"
10246 echo "$CMD0 &"
10247 echo "$CMD1"
10248 grep " $LEVELS " "${te}0"
10249 grep " $LEVELS " "${te}1"
10250 numFAIL=$((numFAIL+1))
10251 listFAIL="$listFAIL $N"
10252 elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/null; then
10253 $PRINTF "$FAILED\n"
10254 badval="$(grep "ancillary message: $SCM_TYPE: $SCM_NAME" ${te}0 |sed 's/.*=//g')"
10255 echo "variable $SCM_TYPE: $SCM_NAME has value \"$badval\" instead of pattern \"$SCM_VALUE\"" >&2
10256 echo "$CMD0 &"
10257 echo "$CMD1"
10258 grep " $LEVELS " "${te}0"
10259 grep " $LEVELS " "${te}1"
10260 numFAIL=$((numFAIL+1))
10261 listFAIL="$listFAIL $N"
10262 else
10263 $PRINTF "$OK\n"
10264 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
10265 if [ "$DEBUG" ]; then grep " $LEVELS " "${te}0" >&2; fi
10266 if [ "$VERBOSE" ]; then echo "echo XYZ |$CMD1"; fi
10267 if [ "$DEBUG" ]; then grep " $LEVELS " "${te}1" >&2; fi
10268 numOK=$((numOK+1))
10269 listOK="$listOK $N"
10271 else # option is not supported
10272 $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
10273 numCANT=$((numCANT+1))
10274 listCANT="$listCANT $N"
10275 fi # option is not supported
10276 fi # NUMCOND, root, feats
10278 esac
10279 N=$((N+1))
10281 done <<<"
10282 IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS options user x01000000
10283 IP4 UDP4 127.0.0.1 PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp
10284 IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL ttl user 53
10285 IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS tos user 7
10286 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO locaddr user 127.0.0.1
10287 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO dstaddr user 127.0.0.1
10288 IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_PKTINFO if user lo
10289 IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_RECVIF if user lo0
10290 IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_RECVDSTADDR dstaddr user 127.0.0.1
10291 IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS options root x01000000
10292 IP4 IP4 127.0.0.1 PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp
10293 IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL ttl root 53
10294 IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS tos root 7
10295 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO locaddr root 127.0.0.1
10296 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO dstaddr root 127.0.0.1
10297 IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_PKTINFO if root lo
10298 IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_RECVIF if root lo0
10299 IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_RECVDSTADDR dstaddr root 127.0.0.1
10300 IP6 UDP6 [::1] PORT , so-timestamp SCM_TIMESTAMP timestamp user timestamp
10301 IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_PKTINFO dstaddr user [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10302 IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit user 35
10303 IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass user x000000aa
10304 IP6 IP6 [::1] PROTO , so-timestamp SCM_TIMESTAMP timestamp root timestamp
10305 IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_PKTINFO dstaddr root [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10306 IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT hoplimit root 35
10307 IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS tclass root x000000aa
10308 #UNIX UNIX $td/test\$N.server - , so-timestamp SCM_TIMESTAMP timestamp user timestamp
10310 # This one fails, apparently due to a Linux weakness:
10311 # UNIX so-timestamp
10314 # test: setting of environment variables that describe a stream socket
10315 # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT,
10316 # SOCAT_PEERPORT when applicable
10317 while read KEYW FEAT SEL TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
10318 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
10320 protov="$(echo "$KEYW" |tr A-Z a-z)"
10321 proto="${protov%%[0-9]}"
10322 NAME=${KEYW}LISTENENV
10323 case "$TESTS" in
10324 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%$SEL%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
10325 TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
10326 # have a server accepting a connection and invoking some shell code. The shell
10327 # code extracts and prints the SOCAT related environment vars.
10328 # outside code then checks if the environment contains the variables correctly
10329 # describing the peer and local sockets.
10330 if ! eval $NUMCOND; then :;
10331 elif ! feat=$(testfeats $FEAT); then
10332 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat" |tr a-z A-Z) not available${NORMAL}\n" $N
10333 numCANT=$((numCANT+1))
10334 listCANT="$listCANT $N"
10335 elif ! runs${protov} >/dev/null; then
10336 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
10337 numCANT=$((numCANT+1))
10338 listCANT="$listCANT $N"
10339 else
10340 tf="$td/test$N.stdout"
10341 te="$td/test$N.stderr"
10342 TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars
10343 tsa="$TEST_SOCKADDR" # test server address
10344 if [ "$PORTMETHOD" == PORT ]; then
10345 newport $proto; tsp="$PORT"; # test server port
10346 tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind=
10347 TEST_SOCKPORT=$tsp
10348 else
10349 tsa1="$tsa"; tsa2= # tsa1 used for addr parameter
10351 TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars
10352 tca="$TEST_PEERADDR" # test client address
10353 if [ $PORTMETHOD = PORT ]; then
10354 newport $proto; tcp="$PORT"; # test client port
10355 tca="$tca:$tcp"
10356 TEST_PEERPORT=$tcp
10358 #CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\""
10359 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\""
10360 CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
10361 printf "test $F_n $TEST... " $N
10362 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
10363 pid0=$!
10364 wait${protov}port $tsa1 1
10365 { echo; sleep 0.1; } |$CMD1 2>"${te}1"
10366 rc1=$?
10367 waitfile "$tf" 2
10368 kill $pid0 2>/dev/null; wait
10369 #set -vx
10370 if [ $rc1 != 0 ]; then
10371 $PRINTF "$NO_RESULT (client failed):\n"
10372 echo "$CMD0 &"
10373 cat "${te}0"
10374 echo "$CMD1"
10375 cat "${te}1"
10376 numCANT=$((numCANT+1))
10377 listCANT="$listCANT $N"
10378 elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
10379 "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
10380 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \
10381 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_PEERPORT" \) \
10382 ]; then
10383 $PRINTF "$OK\n"
10384 if [ "$debug" ]; then
10385 echo "$CMD0 &"
10386 cat "${te}0"
10387 echo "$CMD1"
10388 cat "${te}1"
10390 numOK=$((numOK+1))
10391 listOK="$listOK $N"
10392 else
10393 $PRINTF "$FAILED\n"
10394 echo "$CMD0 &"
10395 cat "${te}0"
10396 echo "$CMD1"
10397 cat "${te}1"
10398 echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
10399 diff - "${tf}"
10400 numFAIL=$((numFAIL+1))
10401 listFAIL="$listFAIL $N"
10403 fi # NUMCOND, feats
10405 esac
10406 N=$((N+1))
10407 #set +xv
10409 done <<<"
10410 TCP4 TCP tcp 127.0.0.1 $SECONDADDR PORT
10411 TCP6 IP6 tcp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
10412 UDP6 IP6 udp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
10413 SCTP4 SCTP sctp 127.0.0.1 $SECONDADDR PORT
10414 SCTP6 SCTP sctp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
10415 UNIX UNIX unix $td/test\$N.server $td/test\$N.client ,
10417 # this one fails due to weakness in socats UDP4-LISTEN implementation:
10418 #UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5))
10421 # test: environment variables from ancillary message
10422 while read PF KEYW SEL ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE
10424 if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
10426 pf="$(echo "$PF" |tr A-Z a-z)"
10427 proto="$(echo "$KEYW" |tr A-Z a-z)"
10428 NAME=${KEYW}ENV_$SCM_ENVNAME
10429 case "$TESTS" in
10430 *%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%$SEL%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*)
10431 #set -vx
10432 TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME"
10433 # idea: start a socat process with *-RECVFROM:..,... , ev. with ancillary
10434 # message enabling option and send it a packet, ev. with some option. write
10435 # the resulting environment to a file and check its contents for the
10436 # appropriate variable.
10437 if ! eval $NUMCOND; then :;
10438 elif [ "$ROOT" = root -a $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
10439 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
10440 numCANT=$((numCANT+1))
10441 listCANT="$listCANT $N"
10442 elif [ "$PF" = "IP6" ] && ( ! feat=$(testfeats ip6) || ! runsip6 ) >/dev/null; then
10443 $PRINTF "test $F_n $TEST... ${YELLOW}IP6 not available${NORMAL}\n" $N
10444 numCANT=$((numCANT+1))
10445 listCANT="$listCANT $N"
10446 else
10447 tf="$td/test$N.stdout"
10448 te="$td/test$N.stderr"
10449 case "X$IPPORT" in
10450 "XPORT")
10451 newport $proto; tra="$PORT" # test recv address
10452 tsa="$ADDR:$tra" # test sendto address
10454 "XPROTO")
10455 tra="$IPPROTO" # test recv address
10456 tsa="$ADDR:$IPPROTO" # test sendto address
10457 #IPPROTO=$((IPPROTO+1))
10460 tra="$(eval echo "$ADDR")" # resolve $N
10461 tsa="$tra"
10462 esac
10463 #CMD0="$TRACE $SOCAT $opts -u $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"export -p\""
10464 # without that ultra escaped quote the test failed for IPv6 when there was file ./1
10465 CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-RECVFROM:$tra,reuseaddr,$SCM_RECV SYSTEM:\"echo \\\\\\\"\\\$SOCAT_$SCM_ENVNAME\\\\\\\"\""
10466 CMD1="$TRACE $SOCAT $opts -u - $KEYW-SENDTO:$tsa,$SCM_ENABLE"
10467 printf "test $F_n $TEST... " $N
10468 # is this option supported?
10469 if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
10470 if [ "$SCM_VALUE" = "timestamp" ]; then
10471 secs="$(date '+%S')"
10472 if [ "$secs" -ge 58 -a "$secs" -le 59 ]; then
10473 dsecs=$((60-secs))
10474 #echo "Sleeping $dsecs seconds to avoid minute change in timestamp" >/dev/tty
10475 sleep $dsecs
10478 eval "$CMD0 >\"$tf\" 2>\"${te}0\" &"
10479 pid0="$!"
10480 wait${proto}port $tra 1
10481 { echo "XYZ"; sleep 0.1; } |$CMD1 2>"${te}1"
10482 rc1="$?"
10483 waitfile "$tf" 2
10484 #i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do relsleep 1; i=$((i+1)); done
10485 kill "$pid0" 2>/dev/null; wait
10486 # do not show more messages than requested
10487 if [ "$SCM_VALUE" = "timestamp" ]; then
10488 SCM_VALUE="$(date '+%a %b %e %H:%M:.. %Y'), ...... usecs"
10489 #echo "\"$SCM_VALUE\"" >&2 # debugging
10491 if [ "$rc1" -ne 0 ]; then
10492 $PRINTF "$NO_RESULT: $SOCAT:\n"
10493 echo "$CMD0 &"
10494 echo "$CMD1"
10495 cat "${te}0"
10496 cat "${te}1"
10497 numCANT=$((numCANT+1))
10498 listCANT="$listCANT $N"
10499 #elif ! $GREP_E "^export SOCAT_$SCM_ENVNAME=[\"']?$SCM_VALUE[\"']?\$" ${tf} >/dev/null; then
10500 #elif ! eval echo "$TRACE $SOCAT_\$SCM_VALUE" |diff - "${tf}" >/dev/null; then
10501 elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then
10502 $PRINTF "$FAILED\n"
10503 echo "logged value \"$(cat "$tf")\" instead of $SCM_VALUE"
10504 echo "$CMD0 &"
10505 echo "$CMD1"
10506 cat "${te}0"
10507 cat "${te}1"
10508 numFAIL=$((numFAIL+1))
10509 listFAIL="$listFAIL $N"
10510 else
10511 $PRINTF "$OK\n"
10512 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
10513 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
10514 if [ "$VERBOSE" ]; then echo "{ echo XYZ; sleep 0.1; } |$CMD1"; fi
10515 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
10516 numOK=$((numOK+1))
10517 listOK="$listOK $N"
10519 else # option is not supported
10520 $PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
10521 numCANT=$((numCANT+1))
10522 listCANT="$listCANT $N"
10523 fi # option is not supported
10524 fi ;; # NUMCOND, feats
10525 esac
10526 N=$((N+1))
10528 done <<<"
10529 IP4 UDP4 udp 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000
10530 IP4 UDP4 udp 127.0.0.1 PORT , so-timestamp TIMESTAMP user timestamp
10531 IP4 UDP4 udp 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53
10532 IP4 UDP4 udp 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7
10533 IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1
10534 IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1
10535 IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_IF user lo
10536 IP4 UDP4 udp 127.0.0.1 PORT , ip-recvif IP_IF user lo0
10537 IP4 UDP4 udp 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1
10538 IP4 IP4 rawip 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000
10539 IP4 IP4 rawip 127.0.0.1 PROTO , so-timestamp TIMESTAMP root timestamp
10540 IP4 IP4 rawip 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53
10541 IP4 IP4 rawip 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7
10542 IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1
10543 IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1
10544 IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo
10545 IP4 IP4 rawip 127.0.0.1 PROTO , ip-recvif IP_IF root lo0
10546 IP4 IP4 rawip 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1
10547 IP6 UDP6 udp [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10548 IP6 UDP6 udp [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35
10549 IP6 UDP6 udp [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user x000000aa
10550 IP6 IP6 rawip [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
10551 IP6 IP6 rawip [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35
10552 IP6 IP6 rawip [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root x000000aa
10553 #UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user timestamp
10557 # test the SOCKET-CONNECT address (against TCP4-LISTEN)
10558 NAME=SOCKET_CONNECT_TCP4
10559 case "$TESTS" in
10560 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%listen%*|*%$NAME%*)
10561 TEST="$NAME: socket connect with TCP/IPv4"
10562 # start a TCP4-LISTEN process that echoes data, and send test data using
10563 # SOCKET-CONNECT, selecting TCP/IPv4. The sent data should be returned.
10564 if ! eval $NUMCOND; then :; else
10565 tf="$td/test$N.stdout"
10566 te="$td/test$N.stderr"
10567 tdiff="$td/test$N.diff"
10568 newport tcp4; ts0p=$PORT
10569 ts0a="127.0.0.1"
10570 ts1p=$(printf "%04x" $ts0p);
10571 ts1a="7f000001" # "127.0.0.1"
10572 ts1="x${ts1p}${ts1a}x0000000000000000"
10573 newport tcp4; ts1b=$(printf "%04x" $PORT)
10574 da="test$N $(date) $RANDOM"
10575 CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$ts0p,$REUSEADDR,bind=$ts0a PIPE"
10576 CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:2:6:$ts1,bind=x${ts1b}00000000x0000000000000000"
10577 printf "test $F_n $TEST... " $N
10578 $CMD0 2>"${te}0" &
10579 pid0="$!"
10580 waittcp4port $ts0p 1
10581 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10582 rc1="$?"
10583 kill "$pid0" 2>/dev/null; wait;
10584 if [ "$rc1" -ne 0 ]; then
10585 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10586 echo "$CMD0 &"
10587 cat "${te}0"
10588 echo "$CMD1"
10589 cat "${te}1"
10590 numFAIL=$((numFAIL+1))
10591 listFAIL="$listFAIL $N"
10592 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10593 $PRINTF "$FAILED\n"
10594 cat "$tdiff"
10595 echo "$CMD0 &"
10596 cat "${te}0"
10597 echo "$CMD1"
10598 cat "${te}1"
10599 numFAIL=$((numFAIL+1))
10600 listFAIL="$listFAIL $N"
10601 else
10602 $PRINTF "$OK\n"
10603 if [ -n "$debug" ]; then cat $te; fi
10604 numOK=$((numOK+1))
10605 listOK="$listOK $N"
10607 fi # NUMCOND
10609 esac
10610 N=$((N+1))
10613 # test the SOCKET-CONNECT address (against TCP6-LISTEN)
10614 NAME=SOCKET_CONNECT_TCP6
10615 case "$TESTS" in
10616 *%$N%*|*%functions%*|*%generic%*|*%tcp6%*|*%socket%*|*%listen%*|*%$NAME%*)
10617 TEST="$NAME: socket connect with TCP/IPv6"
10618 if ! eval $NUMCOND; then :;
10619 elif ! testfeats tcp ip6 >/dev/null || ! runsip6 >/dev/null; then
10620 $PRINTF "test $F_n $TEST... ${YELLOW}TCP6 not available${NORMAL}\n" $N
10621 numCANT=$((numCANT+1))
10622 listCANT="$listCANT $N"
10623 else
10624 # start a TCP6-LISTEN process that echoes data, and send test data using
10625 # SOCKET-CONNECT, selecting TCP/IPv6. The sent data should be returned.
10626 tf="$td/test$N.stdout"
10627 te="$td/test$N.stderr"
10628 tdiff="$td/test$N.diff"
10629 newport tcp6; ts0p=$PORT
10630 ts0a="[::1]"
10631 ts1p=$(printf "%04x" $ts0p);
10632 ts1a="00000000000000000000000000000001" # "[::1]"
10633 ts1="x${ts1p}x00000000x${ts1a}x00000000"
10634 newport tcp6; ts1b=$(printf "%04x" $PORT)
10635 da="test$N $(date) $RANDOM"
10636 CMD0="$TRACE $SOCAT $opts TCP6-LISTEN:$ts0p,$REUSEADDR,bind=$ts0a PIPE"
10637 CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:$PF_INET6:6:$ts1,bind=x${ts1b}x00000000x00000000000000000000000000000000x00000000"
10638 printf "test $F_n $TEST... " $N
10639 $CMD0 2>"${te}0" &
10640 pid0="$!"
10641 waittcp6port $ts0p 1
10642 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10643 rc1="$?"
10644 kill "$pid0" 2>/dev/null; wait;
10645 if [ "$rc1" -ne 0 ]; then
10646 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10647 echo "$CMD0 &"
10648 cat "${te}0"
10649 echo "$CMD1"
10650 cat "${te}1"
10651 numFAIL=$((numFAIL+1))
10652 listFAIL="$listFAIL $N"
10653 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10654 $PRINTF "$FAILED\n"
10655 cat "$tdiff"
10656 echo "$CMD0 &"
10657 cat "${te}0"
10658 echo "$CMD1"
10659 cat "${te}1"
10660 numFAIL=$((numFAIL+1))
10661 listFAIL="$listFAIL $N"
10662 else
10663 $PRINTF "$OK\n"
10664 if [ -n "$debug" ]; then cat $te; fi
10665 numOK=$((numOK+1))
10666 listOK="$listOK $N"
10668 fi ;; # NUMCOND
10669 esac
10670 N=$((N+1))
10672 # test the SOCKET-CONNECT address (against UNIX-LISTEN)
10673 NAME=SOCKET_CONNECT_UNIX
10674 case "$TESTS" in
10675 *%$N%*|*%functions%*|*%generic%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
10676 TEST="$NAME: socket connect with UNIX domain"
10677 # start a UNIX-LISTEN process that echoes data, and send test data using
10678 # SOCKET-CONNECT, selecting UNIX socket. The sent data should be returned.
10679 if ! eval $NUMCOND; then :; else
10680 tf="$td/test$N.stdout"
10681 te="$td/test$N.stderr"
10682 tdiff="$td/test$N.diff"
10683 ts0="$td/test$N.server"
10684 ts1="$td/test$N.client"
10685 da="test$N $(date) $RANDOM"
10686 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts0,$REUSEADDR PIPE"
10687 CMD1="$TRACE $SOCAT $opts - SOCKET-CONNECT:1:0:\\\"$ts0\\\0\\\",bind=\\\"$ts1\\\0\\\""
10688 printf "test $F_n $TEST... " $N
10689 $CMD0 2>"${te}0" &
10690 pid0="$!"
10691 waitfile $ts0 1
10692 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10693 rc1="$?"
10694 kill "$pid0" 2>/dev/null; wait;
10695 if [ "$rc1" -ne 0 ]; then
10696 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10697 echo "$CMD0 &"
10698 cat "${te}0"
10699 echo "$CMD1"
10700 cat "${te}1"
10701 numFAIL=$((numFAIL+1))
10702 listFAIL="$listFAIL $N"
10703 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10704 $PRINTF "$FAILED\n"
10705 cat "$tdiff"
10706 echo "$CMD0 &"
10707 cat "${te}0"
10708 echo "$CMD1"
10709 cat "${te}1"
10710 numFAIL=$((numFAIL+1))
10711 listFAIL="$listFAIL $N"
10712 else
10713 $PRINTF "$OK\n"
10714 if [ -n "$debug" ]; then cat $te; fi
10715 numOK=$((numOK+1))
10716 listOK="$listOK $N"
10718 fi ;; # NUMCOND
10719 esac
10720 N=$((N+1))
10722 # test the SOCKET-LISTEN address (with TCP4-CONNECT)
10723 NAME=SOCKET_LISTEN
10724 case "$TESTS" in
10725 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%listen%*|*%$NAME%*)
10726 TEST="$NAME: socket recvfrom with TCP/IPv4"
10727 # start a SOCKET-LISTEN process that uses TCP/IPv4 and echoes data, and
10728 # send test data using TCP4-CONNECT. The sent data should be returned.
10729 if ! eval $NUMCOND; then :; else
10730 tf="$td/test$N.stdout"
10731 te="$td/test$N.stderr"
10732 tdiff="$td/test$N.diff"
10733 newport tcp4; ts1p=$PORT
10734 ts1a="127.0.0.1"
10735 ts0p=$(printf "%04x" $ts1p);
10736 ts0a="7f000001" # "127.0.0.1"
10737 ts0="x${ts0p}${ts0a}x0000000000000000"
10738 newport tcp4; ts1b=$PORT
10739 ts1="$ts1a:$ts1p"
10740 da="test$N $(date) $RANDOM"
10741 CMD0="$TRACE $SOCAT $opts SOCKET-LISTEN:2:6:$ts0,$REUSEADDR PIPE"
10742 CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$ts1,bind=:$ts1b"
10743 printf "test $F_n $TEST... " $N
10744 $CMD0 2>"${te}0" &
10745 pid0="$!"
10746 #sleep 1
10747 waittcp4port $ts1p 1
10748 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10749 rc1="$?"
10750 kill "$pid0" 2>/dev/null; wait;
10751 if [ "$rc1" -ne 0 ]; then
10752 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10753 echo "$CMD0 &"
10754 cat "${te}0"
10755 echo "$CMD1"
10756 cat "${te}1"
10757 numFAIL=$((numFAIL+1))
10758 listFAIL="$listFAIL $N"
10759 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10760 $PRINTF "$FAILED\n"
10761 cat "$tdiff"
10762 echo "$CMD0 &"
10763 cat "${te}0"
10764 echo "$CMD1"
10765 cat "${te}1"
10766 numFAIL=$((numFAIL+1))
10767 listFAIL="$listFAIL $N"
10768 else
10769 $PRINTF "$OK\n"
10770 if [ -n "$debug" ]; then cat $te; fi
10771 numOK=$((numOK+1))
10772 listOK="$listOK $N"
10774 fi ;; # NUMCOND
10775 esac
10776 N=$((N+1))
10778 # test the SOCKET-SENDTO address (against UDP4-RECVFROM)
10779 NAME=SOCKET_SENDTO
10780 case "$TESTS" in
10781 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10782 TEST="$NAME: socket sendto with UDP/IPv4"
10783 # start a UDP4-RECVFROM process that echoes data, and send test data using
10784 # SOCKET-SENDTO, selecting UDP/IPv4. The sent data should be returned.
10785 if ! eval $NUMCOND; then :; else
10786 tf="$td/test$N.stdout"
10787 te="$td/test$N.stderr"
10788 tdiff="$td/test$N.diff"
10789 newport udp4; ts0p=$PORT
10790 ts0a="127.0.0.1"
10791 ts1p=$(printf "%04x" $ts0p);
10792 ts1a="7f000001" # "127.0.0.1"
10793 ts1="x${ts1p}${ts1a}x0000000000000000"
10794 newport udp4; ts1b=$(printf "%04x" $PORT)
10795 da="test$N $(date) $RANDOM"
10796 CMD0="$TRACE $SOCAT $opts UDP4-RECVFROM:$ts0p,reuseaddr,bind=$ts0a PIPE"
10797 CMD1="$TRACE $SOCAT $opts - SOCKET-SENDTO:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
10798 printf "test $F_n $TEST... " $N
10799 $CMD0 2>"${te}0" &
10800 pid0="$!"
10801 waitudp4port $ts0p 1
10802 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10803 rc1="$?"
10804 kill "$pid0" 2>/dev/null; wait;
10805 if [ "$rc1" -ne 0 ]; then
10806 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10807 echo "$CMD0 &"
10808 cat "${te}0"
10809 echo "$CMD1"
10810 cat "${te}1"
10811 numFAIL=$((numFAIL+1))
10812 listFAIL="$listFAIL $N"
10813 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10814 $PRINTF "$FAILED\n"
10815 cat "$tdiff"
10816 echo "$CMD0 &"
10817 cat "${te}0"
10818 echo "$CMD1"
10819 cat "${te}1"
10820 numFAIL=$((numFAIL+1))
10821 listFAIL="$listFAIL $N"
10822 else
10823 $PRINTF "$OK\n"
10824 if [ -n "$debug" ]; then cat $te; fi
10825 numOK=$((numOK+1))
10826 listOK="$listOK $N"
10828 fi ;; # NUMCOND
10829 esac
10830 N=$((N+1))
10832 # test the SOCKET-RECVFROM address (with UDP4-SENDTO)
10833 NAME=SOCKET_RECVFROM
10834 case "$TESTS" in
10835 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10836 TEST="$NAME: socket recvfrom with UDP/IPv4"
10837 # start a SOCKET-RECVFROM process that uses UDP/IPv4 and echoes data, and
10838 # send test data using UDP4-SENDTO. The sent data should be returned.
10839 if ! eval $NUMCOND; then :; else
10840 tf="$td/test$N.stdout"
10841 te="$td/test$N.stderr"
10842 tdiff="$td/test$N.diff"
10843 newport udp4; ts1p=$PORT
10844 ts1a="127.0.0.1"
10845 ts0p=$(printf "%04x" $ts1p);
10846 ts0a="7f000001" # "127.0.0.1"
10847 ts0="x${ts0p}${ts0a}x0000000000000000"
10848 newport udp4; ts1b=$PORT
10849 ts1="$ts1a:$ts1p"
10850 da="test$N $(date) $RANDOM"
10851 CMD0="$TRACE $SOCAT $opts SOCKET-RECVFROM:2:$SOCK_DGRAM:17:$ts0,reuseaddr PIPE"
10852 CMD1="$TRACE $SOCAT $opts - UDP4-SENDTO:$ts1,bind=:$ts1b"
10853 printf "test $F_n $TEST... " $N
10854 $CMD0 2>"${te}0" &
10855 pid0="$!"
10856 sleep 1 # waitudp4port $ts1p 1
10857 echo "$da" |$CMD1 >>"$tf" 2>>"${te}1"
10858 rc1="$?"
10859 kill "$pid0" 2>/dev/null; wait;
10860 if [ "$rc1" -ne 0 ]; then
10861 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10862 echo "$CMD0 &"
10863 cat "${te}0"
10864 echo "$CMD1"
10865 cat "${te}1"
10866 numFAIL=$((numFAIL+1))
10867 listFAIL="$listFAIL $N"
10868 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10869 $PRINTF "$FAILED\n"
10870 cat "$tdiff"
10871 echo "$CMD0 &"
10872 cat "${te}0"
10873 echo "$CMD1"
10874 cat "${te}1"
10875 numFAIL=$((numFAIL+1))
10876 listFAIL="$listFAIL $N"
10877 else
10878 $PRINTF "$OK\n"
10879 if [ -n "$debug" ]; then cat $te; fi
10880 numOK=$((numOK+1))
10881 listOK="$listOK $N"
10883 fi ;; # NUMCOND
10884 esac
10885 N=$((N+1))
10888 # test the SOCKET-RECV address (with UDP4-SENDTO)
10889 NAME=SOCKET_RECV
10890 case "$TESTS" in
10891 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10892 TEST="$NAME: socket recv with UDP/IPv4"
10893 # start a SOCKET-RECV process that uses UDP/IPv4 and writes received data to file, and
10894 # send test data using UDP4-SENDTO.
10895 if ! eval $NUMCOND; then :; else
10896 tf="$td/test$N.stdout"
10897 te="$td/test$N.stderr"
10898 tdiff="$td/test$N.diff"
10899 newport udp4; ts1p=$PORT
10900 ts1a="127.0.0.1"
10901 ts0p=$(printf "%04x" $ts1p);
10902 ts0a="7f000001" # "127.0.0.1"
10903 ts0="x${ts0p}${ts0a}x0000000000000000"
10904 newport udp4; ts1b=$PORT
10905 ts1="$ts1a:$ts1p"
10906 da="test$N $(date) $RANDOM"
10907 CMD0="$TRACE $SOCAT $opts -u SOCKET-RECV:2:$SOCK_DGRAM:17:$ts0,reuseaddr -"
10908 CMD1="$TRACE $SOCAT $opts -u - UDP4-SENDTO:$ts1,bind=:$ts1b"
10909 printf "test $F_n $TEST... " $N
10910 $CMD0 2>"${te}0" >"$tf" &
10911 pid0="$!"
10912 sleep 1 # waitudp4port $ts1p 1
10913 echo "$da" |$CMD1 2>>"${te}1"
10914 rc1="$?"
10915 sleep 1
10916 kill "$pid0" 2>/dev/null; wait;
10917 if [ "$rc1" -ne 0 ]; then
10918 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10919 echo "$CMD0 &"
10920 cat "${te}0"
10921 echo "$CMD1"
10922 cat "${te}1"
10923 numFAIL=$((numFAIL+1))
10924 listFAIL="$listFAIL $N"
10925 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10926 $PRINTF "$FAILED\n"
10927 cat "$tdiff"
10928 echo "$CMD0 &"
10929 cat "${te}0"
10930 echo "$CMD1"
10931 cat "${te}1"
10932 numFAIL=$((numFAIL+1))
10933 listFAIL="$listFAIL $N"
10934 else
10935 $PRINTF "$OK\n"
10936 if [ -n "$debug" ]; then cat $te; fi
10937 numOK=$((numOK+1))
10938 listOK="$listOK $N"
10940 fi ;; # NUMCOND
10941 esac
10942 N=$((N+1))
10944 # test SOCKET-DATAGRAM (with UDP4-DATAGRAM)
10945 NAME=SOCKET_DATAGRAM
10946 case "$TESTS" in
10947 *%$N%*|*%functions%*|*%generic%*|*%socket%*|*%ip4%*|*%udp%*|*%dgram%*|*%$NAME%*)
10948 TEST="$NAME: socket datagram via UDP/IPv4"
10949 # start a UDP4-DATAGRAM process that echoes data, and send test data using
10950 # SOCKET-DATAGRAM, selecting UDP/IPv4. The sent data should be returned.
10951 if ! eval $NUMCOND; then :; else
10952 tf="$td/test$N.stdout"
10953 te="$td/test$N.stderr"
10954 tdiff="$td/test$N.diff"
10955 newport udp4; ts0p=$PORT
10956 newport udp4; ts1p=$PORT
10957 ts0a="127.0.0.1"
10958 ts1b=$(printf "%04x" $ts0p);
10959 ts1a="7f000001" # "127.0.0.1"
10960 ts0b=$(printf "%04x" $ts0p)
10961 ts1b=$(printf "%04x" $ts1p)
10962 ts1="x${ts0b}${ts1a}x0000000000000000"
10963 da="test$N $(date) $RANDOM"
10964 CMD0="$TRACE $SOCAT $opts UDP4-DATAGRAM:$ts0a:$ts1p,bind=:$ts0p,reuseaddr PIPE"
10965 CMD1="$TRACE $SOCAT $opts - SOCKET-DATAGRAM:2:$SOCK_DGRAM:17:$ts1,bind=x${ts1b}x00000000x0000000000000000"
10966 printf "test $F_n $TEST... " $N
10967 $CMD0 2>"${te}0" &
10968 pid0="$!"
10969 waitudp4port $ts0p 1
10970 echo "$da" |$CMD1 2>>"${te}1" >"$tf"
10971 rc1="$?"
10972 kill "$pid0" 2>/dev/null; wait;
10973 if [ "$rc1" -ne 0 ]; then
10974 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
10975 echo "$CMD0 &"
10976 cat "${te}0"
10977 echo "$CMD1"
10978 cat "${te}1"
10979 numFAIL=$((numFAIL+1))
10980 listFAIL="$listFAIL $N"
10981 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
10982 $PRINTF "$FAILED\n"
10983 cat "$tdiff"
10984 echo "$CMD0 &"
10985 cat "${te}0"
10986 echo "$CMD1"
10987 cat "${te}1"
10988 numFAIL=$((numFAIL+1))
10989 listFAIL="$listFAIL $N"
10990 else
10991 $PRINTF "$OK\n"
10992 if [ -n "$debug" ]; then cat $te; fi
10993 numOK=$((numOK+1))
10994 listOK="$listOK $N"
10996 fi ;; # NUMCOND
10997 esac
10998 N=$((N+1))
11000 NAME=SOCKETRANGEMASK
11001 case "$TESTS" in
11002 *%$N%*|*%functions%*|*%security%*|*%generic%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%socket%*|*%range%*|*%listen%*|*%fork%*|*%$NAME%*)
11003 TEST="$NAME: security of generic socket-listen with RANGE option"
11004 if ! eval $NUMCOND; then :;
11005 elif [ -z "$SECONDADDR" ]; then
11006 # we need access to more loopback addresses
11007 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
11008 numCANT=$((numCANT+1))
11009 listCANT="$listCANT $N"
11010 else
11011 newport tcp4; ts1p=$(printf "%04x" $PORT);
11012 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
11013 fi ;; # NUMCOND, $SECONDADDR
11014 esac
11015 N=$((N+1))
11018 # test the generic ioctl-void option
11019 NAME=IOCTL_VOID
11020 case "$TESTS" in
11021 *%$N%*|*%functions%*|*%pty%*|*%generic%*|*%$NAME%*)
11022 TEST="$NAME: test the ioctl-void option"
11023 # there are not many ioctls that apply to non global resources and do not
11024 # require root. TIOCEXCL seems to fit:
11025 # process 0 provides a pty;
11026 # process 1 opens it with the TIOCEXCL ioctl;
11027 # process 2 opens it too and fails with "device or resource busy" only when the
11028 # previous ioctl was successful
11029 if ! eval $NUMCOND; then :;
11030 elif [ -z "$TIOCEXCL" ]; then
11031 # we use the numeric value of TIOCEXL which is system dependent
11032 $PRINTF "test $F_n $TEST... ${YELLOW}no value of TIOCEXCL${NORMAL}\n" $N
11033 numCANT=$((numCANT+1))
11034 listCANT="$listCANT $N"
11035 else
11036 tp="$td/test$N.pty"
11037 tf="$td/test$N.stdout"
11038 te="$td/test$N.stderr"
11039 tdiff="$td/test$N.diff"
11040 da="test$N $(date) $RANDOM"
11041 CMD0="$TRACE $SOCAT $opts PTY,LINK=$tp pipe"
11042 CMD1="$TRACE $SOCAT $opts - file:$tp,ioctl-void=$TIOCEXCL,raw,echo=0"
11043 CMD2="$TRACE $SOCAT $opts - file:$tp,raw,echo=0"
11044 printf "test $F_n $TEST... " $N
11045 $CMD0 >/dev/null 2>"${te}0" &
11046 pid0=$!
11047 waitfile $tp 1
11048 (echo "$da"; sleep 2) |$CMD1 >"$tf" 2>"${te}1" & # this should always work
11049 pid1=$!
11050 sleep 1.0
11051 $CMD2 >/dev/null 2>"${te}2" </dev/null
11052 rc2=$?
11053 kill $pid0 $pid1 2>/dev/null; wait
11054 if ! echo "$da" |diff - "$tf" >/dev/null; then
11055 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
11056 echo "$CMD0 &"
11057 echo "$CMD1"
11058 echo "$da" |diff - "$tf"
11059 numCANT=$((numCANT+1))
11060 listCANT="$listCANT $N"
11061 elif [ $rc2 -eq 0 ]; then
11062 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11063 echo "$CMD0 &"
11064 echo "$CMD1"
11065 echo "$CMD2"
11066 cat "${te}0" "${te}1" "${te}2"
11067 numFAIL=$((numFAIL+1))
11068 listFAIL="$listFAIL $N"
11069 else
11070 $PRINTF "$OK\n"
11071 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
11072 numOK=$((numOK+1))
11073 listOK="$listOK $N"
11075 fi # NUMCOND, TIOCEXCL
11077 esac
11078 N=$((N+1))
11081 # Test the generic setsockopt option
11082 NAME=SETSOCKOPT
11083 case "$TESTS" in
11084 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%listen%*|*%fork%*|*%$NAME%*)
11085 TEST="$NAME: test the setsockopt option"
11086 # Set the TCP_MAXSEG (MSS) option with a reasonable value, this should succeed.
11087 # Then try again with TCP_MAXSEG=1, this fails at least on Linux.
11088 # Thus:
11089 # process 0 provides a tcp listening,forking socket
11090 # process 1 connects to this port using reasonably MSS, data transfer should
11091 # succeed.
11092 # Then,
11093 # process 2 connects to this port using a very small MSS, this should fail
11094 if ! eval $NUMCOND; then :;
11095 elif [ -z "$TCP_MAXSEG" ]; then
11096 # we use the numeric value of TCP_MAXSEG which might be system dependent
11097 $PRINTF "test $F_n $TEST... ${YELLOW}value of TCPMAXSEG not known${NORMAL}\n" $N
11098 numCANT=$((numCANT+1))
11099 listCANT="$listCANT $N"
11100 else
11101 tf="$td/test$N.stdout"
11102 te="$td/test$N.stderr"
11103 tdiff="$td/test$N.diff"
11104 da="test$N $(date) $RANDOM"
11105 newport tcp4
11106 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,so-reuseaddr,fork PIPE"
11107 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,setsockopt=6:$TCP_MAXSEG:512"
11108 CMD2="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,setsockopt=6:$TCP_MAXSEG:1"
11109 printf "test $F_n $TEST... " $N
11110 $CMD0 >/dev/null 2>"${te}0" &
11111 pid0=$!
11112 waittcp4port $PORT 1
11113 (echo "$da"; relsleep 1) |$CMD1 >"${tf}1" 2>"${te}1" # this should always work
11114 rc1=$?
11115 relsleep 1
11116 (echo "$da"; relsleep 1) |$CMD2 >"${tf}2" 2>"${te}2" # this should fail
11117 rc2=$?
11118 kill $pid0 $pid1 $pid2 2>/dev/null; wait
11119 if ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
11120 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
11121 echo "$CMD0 &"
11122 cat ${te}0
11123 echo "$CMD1"
11124 cat ${te}1
11125 cat "$tdiff"
11126 numCANT=$((numCANT+1))
11127 listCANT="$listCANT $N"
11128 elif [ $rc1 -ne 0 ]; then
11129 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11130 echo "$CMD0 &"
11131 cat ${te}0
11132 echo "$CMD1"
11133 cat ${te}1
11134 numFAIL=$((numFAIL+1))
11135 listFAIL="$listFAIL $N"
11136 elif [ $rc2 -eq 0 ]; then
11137 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11138 echo "$CMD0 &"
11139 cat ${te}0
11140 echo "$CMD2"
11141 cat ${te}2
11142 numFAIL=$((numFAIL+1))
11143 listFAIL="$listFAIL $N"
11144 else
11145 $PRINTF "$OK\n"
11146 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2"; fi
11147 numOK=$((numOK+1))
11148 listOK="$listOK $N"
11150 fi # NUMCOND
11152 esac
11153 N=$((N+1))
11155 # Test the generic setsockopt-listen option
11156 # This test, with setsockopt-int, no longer worked due to fix for options on
11157 # listening sockets
11158 # Now it got a chance again using new option setsockopt-listen
11159 #NAME=SETSOCKOPT_INT
11160 NAME=SETSOCKOPT_LISTEN
11161 case "$TESTS" in
11162 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%generic%*|*%listen%*|*%$NAME%*)
11163 TEST="$NAME: test the setsockopt-listen option"
11164 # there are not many socket options that apply to non global resources, do not
11165 # require root, do not require a network connection, and can easily be
11166 # tested. SO_REUSEADDR seems to fit:
11167 # process 0 provides a tcp listening socket with reuseaddr;
11168 # process 1 connects to this port; thus the port is connected but no longer
11169 # listening
11170 # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the
11171 # (generically specified) SO_REUSEADDR socket options did not work
11172 # process 3 connects to this port; only if it is successful the test is ok
11173 if ! eval $NUMCOND; then :;
11174 elif [ -z "$SO_REUSEADDR" ]; then
11175 # we use the numeric value of SO_REUSEADDR which might be system dependent
11176 $PRINTF "test $F_n $TEST... ${YELLOW}value of SO_REUSEADDR not known${NORMAL}\n" $N
11177 numCANT=$((numCANT+1))
11178 listCANT="$listCANT $N"
11179 else
11180 tf="$td/test$N.stdout"
11181 te="$td/test$N.stderr"
11182 tdiff="$td/test$N.diff"
11183 da="test$N $(date) $RANDOM"
11184 newport tcp4
11185 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,setsockopt-listen=$SOL_SOCKET:$SO_REUSEADDR:1 PIPE"
11186 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
11187 CMD2="$CMD0"
11188 CMD3="$CMD1"
11189 printf "test $F_n $TEST... " $N
11190 $CMD0 >/dev/null 2>"${te}0" &
11191 pid0=$!
11192 waittcp4port $PORT 1
11193 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1" # this should always work
11194 rc1=$?
11195 kill $pid0 2>/dev/null; wait
11196 $CMD2 >/dev/null 2>"${te}2" &
11197 pid2=$!
11198 waittcp4port $PORT 1
11199 echo "$da" |$CMD3 >"${tf}3" 2>"${te}3"
11200 rc3=$?
11201 kill $pid2 2>/dev/null; wait
11202 if ! echo "$da" |diff - "${tf}1" >"${tdiff}1"; then
11203 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
11204 echo "$CMD0 &"
11205 cat ${te}0
11206 echo "$CMD1"
11207 cat ${te}1
11208 cat "${tdiff}1"
11209 numCANT=$((numCANT+1))
11210 listCANT="$listCANT $N"
11211 elif [ $rc3 -ne 0 ]; then
11212 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11213 echo "$CMD0 &"
11214 cat ${te}0
11215 echo "$CMD1"
11216 cat ${te}1
11217 echo "$CMD2 &"
11218 cat ${te}2
11219 echo "$CMD3"
11220 cat ${te}3
11221 numFAIL=$((numFAIL+1))
11222 listFAIL="$listFAIL $N"
11223 elif ! echo "$da" |diff - "${tf}3" >"${tdiff}3"; then
11224 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11225 echo "$CMD0 &"
11226 cat ${te}0
11227 echo "$CMD1"
11228 cat ${te}1
11229 echo "$CMD2 &"
11230 cat ${te}2
11231 echo "$CMD3"
11232 cat ${te}3
11233 cat "${tdiff}3"
11234 numCANT=$((numCANT+1))
11235 listCANT="$listCANT $N"
11236 else
11237 $PRINTF "$OK\n"
11238 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
11239 numOK=$((numOK+1))
11240 listOK="$listOK $N"
11242 fi # NUMCOND, SO_REUSEADDR
11244 esac
11245 N=$((N+1))
11248 NAME=SCTP4STREAM
11249 case "$TESTS" in
11250 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%listen%*|*%$NAME%*)
11251 TEST="$NAME: echo via connection to SCTP V4 socket"
11252 if ! eval $NUMCOND; then :;
11253 elif ! testfeats sctp ip4 >/dev/null || ! runsip4 >/dev/null || ! runssctp4 >/dev/null; then
11254 $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
11255 listCANT="$listCANT $N"
11256 numCANT=$((numCANT+1))
11257 listCANT="$listCANT $N"
11258 elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
11259 # RHEL5 based systems became unusable when an sctp socket was created but
11260 # module sctp not loaded
11261 $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
11262 numCANT=$((numCANT+1))
11263 listCANT="$listCANT $N"
11264 else
11265 tf="$td/test$N.stdout"
11266 te="$td/test$N.stderr"
11267 tdiff="$td/test$N.diff"
11268 newport sctp4; tsl=$PORT
11269 ts="127.0.0.1:$tsl"
11270 da=$(date)
11271 CMD1="$TRACE $SOCAT $opts SCTP4-LISTEN:$tsl,$REUSEADDR PIPE"
11272 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT SCTP4:$ts"
11273 printf "test $F_n $TEST... " $N
11274 $CMD1 >"$tf" 2>"${te}1" &
11275 pid1=$!
11276 waitsctp4port $tsl 1
11277 # SCTP does not seem to support half close, so we give it 1s to finish
11278 (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
11279 if [ $? -ne 0 ]; then
11280 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11281 echo "$CMD1 &"
11282 cat "${te}1"
11283 echo "$CMD2"
11284 cat "${te}2"
11285 numFAIL=$((numFAIL+1))
11286 listFAIL="$listFAIL $N"
11287 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
11288 $PRINTF "$FAILED\n"
11289 cat "$tdiff"
11290 numFAIL=$((numFAIL+1))
11291 listFAIL="$listFAIL $N"
11292 else
11293 $PRINTF "$OK\n"
11294 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
11295 numOK=$((numOK+1))
11296 listOK="$listOK $N"
11298 kill $pid1 2>/dev/null
11299 wait
11300 fi # NUMCOND, feats
11302 esac
11303 N=$((N+1))
11305 NAME=SCTP6STREAM
11306 case "$TESTS" in
11307 *%$N%*|*%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%listen%*|*%$NAME%*)
11308 TEST="$NAME: echo via connection to SCTP V6 socket"
11309 if ! eval $NUMCOND; then :;
11310 elif ! testfeats sctp ip6 >/dev/null || ! runsip6 >/dev/null || ! runssctp6 >/dev/null; then
11311 $PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N
11312 numCANT=$((numCANT+1))
11313 listCANT="$listCANT $N"
11314 elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
11315 $PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
11316 numCANT=$((numCANT+1))
11317 listCANT="$listCANT $N"
11318 else
11319 tf="$td/test$N.stdout"
11320 te="$td/test$N.stderr"
11321 tdiff="$td/test$N.diff"
11322 newport sctp6; tsl=$PORT
11323 ts="[::1]:$tsl"
11324 da=$(date)
11325 CMD1="$TRACE $SOCAT $opts SCTP6-LISTEN:$tsl,$REUSEADDR PIPE"
11326 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT SCTP6:$ts"
11327 printf "test $F_n $TEST... " $N
11328 $CMD1 >"$tf" 2>"${te}1" &
11329 pid=$! # background process id
11330 waitsctp6port $tsl 1
11331 # SCTP does not seem to support half close, so we let it 1s to finish
11332 (echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
11333 if [ $? -ne 0 ]; then
11334 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
11335 echo "$CMD1 &"
11336 cat "${te}1"
11337 echo "$CMD2"
11338 cat "${te}2"
11339 numFAIL=$((numFAIL+1))
11340 listFAIL="$listFAIL $N"
11341 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
11342 $PRINTF "$FAILED: diff:\n"
11343 cat "$tdiff"
11344 numFAIL=$((numFAIL+1))
11345 listFAIL="$listFAIL $N"
11346 else
11347 $PRINTF "$OK\n"
11348 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
11349 numOK=$((numOK+1))
11350 listOK="$listOK $N"
11352 kill $pid 2>/dev/null
11353 fi # NUMCOND, feats
11355 esac
11356 N=$((N+1))
11359 if type openssl >/dev/null 2>&1; then
11360 OPENSSL_METHOD=$(openssl s_client -help 2>&1 |$GREP_E -e '-tls1_[012]' |sed -e 's/.*\(-tls1_[012]\).*/\1/' |sort |tail -n 1)
11361 #OPENSSL_METHOD=$(openssl s_client -help 2>&1 |$GREP_E -o -e '-tls1(_[012])?' |sort |tail -n 1)
11362 [ -z "$OPENSSL_METHOD" ] && OPENSSL_METHOD="-tls1" # just so
11365 # Old versions have DTLS hang, new versions cannot by client renegotiation, ...
11366 OPENSSL_VERSION="$(openssl version)"
11367 OPENSSL_VERSION="${OPENSSL_VERSION#* }"
11368 OPENSSL_VERSION="${OPENSSL_VERSION%%[ -]*}"
11369 [ "$DEFS" ] && echo "OPENSSL_VERSION=\"$OPENSSL_VERSION\"" >&2
11371 # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer
11372 # performed a renegotiation. Test if this is fixed.
11373 # Note: the renegotiation feature in OpenSSL exists only up to TLSv1.2
11374 NAME=OPENSSLRENEG1
11375 case "$TESTS" in
11376 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
11377 TEST="$NAME: OpenSSL connections survive renogotiation"
11378 # connect with s_client to socat ssl-l; force a renog, then transfer data. When
11379 # data is passed the test succeeded
11380 if ! eval $NUMCOND; then :;
11381 elif ! testfeats openssl >/dev/null; then
11382 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11383 numCANT=$((numCANT+1))
11384 listCANT="$listCANT $N"
11385 elif ! type openssl >/dev/null 2>&1; then
11386 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
11387 numCANT=$((numCANT+1))
11388 listCANT="$listCANT $N"
11389 elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then
11390 # openssl s_client apparently provides renegotiation only up to version 1.2
11391 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N
11392 numCANT=$((numCANT+1))
11393 listCANT="$listCANT $N"
11394 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
11395 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
11396 numCANT=$((numCANT+1))
11397 listCANT="$listCANT $N"
11398 else
11399 gentestcert testsrv
11400 tf="$td/test$N.stdout"
11401 te="$td/test$N.stderr"
11402 tdiff="$td/test$N.diff"
11403 da="test$N $(date) $RANDOM"
11404 init_openssl_s_client
11405 newport tcp4
11406 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
11407 #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g
11408 CMD1="openssl s_client $OPENSSL_S_CLIENT_4 $OPENSSL_METHOD -port $PORT"
11409 printf "test $F_n $TEST... " $N
11410 $CMD0 >/dev/null 2>"${te}0" &
11411 pid0=$!
11412 waittcp4port $PORT 1
11413 (echo "R"; sleep 1; echo "$da"; sleep 1) |$CMD1 2>"${te}1" |$GREP_F "$da" >"${tf}1"
11414 rc1=$?
11415 kill $pid0 2>/dev/null; wait
11416 if echo "$da" |diff - ${tf}1 >"$tdiff"; then
11417 $PRINTF "$OK\n"
11418 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11419 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11420 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11421 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11422 numOK=$((numOK+1))
11423 listOK="$listOK $N"
11424 elif grep -i "Connection refused" "${te}1" >/dev/null; then
11425 $PRINTF "$CANT (conn failed)\n"
11426 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11427 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11428 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11429 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11430 numCANT=$((numCANT+1))
11431 listCANT="$listCANT $N"
11432 else
11433 $PRINTF "$FAILED (diff)\n"
11434 echo "$CMD0 &"
11435 cat "${te}0" >&2
11436 echo "$CMD1"
11437 cat "${te}1" >&2
11438 echo "// diff:" >&2
11439 cat "$tdiff" >&2
11440 numFAIL=$((numFAIL+1))
11441 listFAIL="$listFAIL $N"
11443 fi # NUMCOND
11445 esac
11446 N=$((N+1))
11449 # socat up to 1.7.1.1 (and 2.0.0-b3) terminated with error when an openssl peer
11450 # performed a renegotiation. The first temporary fix to this problem might
11451 # leave socat in a blocking ssl-read state. Test if this has been fixed.
11452 # Note: the renegotiation feature in OpenSSL exists only up to TLSv1.2
11453 NAME=OPENSSLRENEG2
11454 case "$TESTS" in
11455 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
11456 TEST="$NAME: OpenSSL connections do not block after renogotiation"
11457 # connect with s_client to socat ssl-l; force a renog, then transfer data from
11458 # socat to the peer. When data is passed this means that the former ssl read no
11459 # longer blocks and the test succeeds
11460 if ! eval $NUMCOND; then :;
11461 elif ! testfeats openssl >/dev/null; then
11462 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11463 numCANT=$((numCANT+1))
11464 listCANT="$listCANT $N"
11465 elif ! type openssl >/dev/null 2>&1; then
11466 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
11467 numCANT=$((numCANT+1))
11468 listCANT="$listCANT $N"
11469 elif ! [[ $(echo $OPENSSL_VERSION |awk '{print($2);}') =~ [01].* ]]; then
11470 # openssl s_client apparently provides renegotiation only up to version 1.2
11471 $PRINTF "test $F_n $TEST... ${YELLOW}not with OpenSSL $OPENSSL_VERSION${NORMAL}\n" $N
11472 numCANT=$((numCANT+1))
11473 listCANT="$listCANT $N"
11474 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
11475 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
11476 numCANT=$((numCANT+1))
11477 listCANT="$listCANT $N"
11478 else
11479 gentestcert testsrv
11480 tf="$td/test$N.stdout"
11481 te="$td/test$N.stderr"
11482 tdiff="$td/test$N.diff"
11483 da="test$N $(date) $RANDOM"
11484 init_openssl_s_client
11485 newport tcp4
11486 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"
11487 #CMD1="openssl s_client -port $PORT -verify 0" # not with openssl 1.1.0g
11488 CMD1="openssl s_client $OPENSSL_S_CLIENT_4 $OPENSSL_METHOD -port $PORT"
11489 printf "test $F_n $TEST... " $N
11490 eval "$CMD0 >/dev/null 2>\"${te}0\" &"
11491 pid0=$!
11492 waittcp4port $PORT 1
11493 (echo "R"; sleep 2) |$CMD1 2>"${te}1" |$GREP_F "$da" >"${tf}1"
11494 rc1=$?
11495 kill $pid0 2>/dev/null; wait
11496 if echo "$da" |diff - ${tf}1 >"$tdiff"; then
11497 $PRINTF "$OK\n"
11498 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11499 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11500 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11501 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11502 numOK=$((numOK+1))
11503 listOK="$listOK $N"
11504 elif grep -i "Connection refused" "${te}1" >/dev/null; then
11505 $PRINTF "$CANT (conn failed)\n"
11506 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11507 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11508 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11509 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11510 numCANT=$((numCANT+1))
11511 listCANT="$listCANT $N"
11512 else
11513 $PRINTF "$FAILED (diff)\n"
11514 echo "$CMD0 &"
11515 cat "${te}0" >&2
11516 echo "$CMD1"
11517 cat "${te}1" >&2
11518 echo "// diff:" >&2
11519 cat "$tdiff" >&2
11520 numFAIL=$((numFAIL+1))
11521 listFAIL="$listFAIL $N"
11523 fi # NUMCOND
11525 esac
11526 N=$((N+1))
11529 # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when
11530 # command line arguments (whole addresses, host names, file names) were longer
11531 # than 512 bytes.
11532 NAME=HOSTNAMEOVFL
11533 case "$TESTS" in
11534 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%$NAME%*)
11535 TEST="$NAME: stack overflow on overly long host name"
11536 # provide a long host name to TCP-CONNECT and check socats exit code
11537 if ! eval $NUMCOND; then :; else
11538 tf="$td/test$N.stdout"
11539 te="$td/test$N.stderr"
11540 tdiff="$td/test$N.diff"
11541 da="test$N $(date) $RANDOM"
11542 # prepare long data - perl might not be installed
11543 rm -f "$td/test$N.dat"
11544 i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
11545 newport tcp4
11546 CMD0="$TRACE $SOCAT $opts TCP-CONNECT:$(cat "$td/test$N.dat"):$PORT STDIO"
11547 printf "test $F_n $TEST... " $N
11548 $CMD0 </dev/null 1>&0 2>"${te}0"
11549 rc0=$?
11550 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
11551 $PRINTF "$OK\n"
11552 numOK=$((numOK+1))
11553 listOK="$listOK $N"
11554 else
11555 $PRINTF "$FAILED\n"
11556 echo "$CMD0"
11557 cat "${te}0"
11558 numFAIL=$((numFAIL+1))
11559 listFAIL="$listFAIL $N"
11561 fi # NUMCOND
11563 esac
11564 N=$((N+1))
11566 # socat up to 1.7.1.2 had a stack overflow vulnerability that occurred when
11567 # command line arguments (whole addresses, host names, file names) were longer
11568 # than 512 bytes.
11569 NAME=FILENAMEOVFL
11570 case "$TESTS" in
11571 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%openssl%*|*%$NAME%*)
11572 TEST="$NAME: stack overflow on overly long file name"
11573 # provide a 600 bytes long key file option to OPENSSL-CONNECT and check socats exit code
11574 if ! eval $NUMCOND; then :; else
11575 tf="$td/test$N.stdout"
11576 te="$td/test$N.stderr"
11577 tdiff="$td/test$N.diff"
11578 da="test$N $(date) $RANDOM"
11579 i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
11580 newport tcp4
11581 CMD0="$TRACE $SOCAT $opts OPENSSL:localhost:$PORT,key=$(cat "$td/test$N.dat") STDIO"
11582 printf "test $F_n $TEST... " $N
11583 $CMD0 </dev/null 1>&0 2>"${te}0"
11584 rc0=$?
11585 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
11586 $PRINTF "$OK\n"
11587 numOK=$((numOK+1))
11588 listOK="$listOK $N"
11589 else
11590 $PRINTF "$FAILED\n"
11591 echo "$CMD0"
11592 cat "${te}0"
11593 numFAIL=$((numFAIL+1))
11594 listFAIL="$listFAIL $N"
11596 fi # NUMCOND
11598 esac
11599 N=$((N+1))
11601 # socat up to 1.7.3.0 had a stack overflow vulnerability that occurred when
11602 # command line arguments (whole addresses, host names, file names) were longer
11603 # than 512 bytes and specially crafted.
11604 NAME=NESTEDOVFL
11605 case "$TESTS" in
11606 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%exec%*|*%$NAME%*)
11607 TEST="$NAME: stack overflow on overly long nested arg"
11608 # provide a long host name to TCP-CONNECT and check socats exit code
11609 if ! eval $NUMCOND; then :; else
11610 tf="$td/test$N.stdout"
11611 te="$td/test$N.stderr"
11612 tdiff="$td/test$N.diff"
11613 da="test$N $(date) $RANDOM"
11614 # prepare long data - perl might not be installed
11615 rm -f "$td/test$N.dat"
11616 i=0; while [ $i -lt 64 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$td/test$N.dat"; i=$((i+1)); done
11617 CMD0="$TRACE $SOCAT $opts EXEC:[$(cat "$td/test$N.dat")] STDIO"
11618 printf "test $F_n $TEST... " $N
11619 $CMD0 </dev/null 1>&0 2>"${te}0"
11620 rc0=$?
11621 if [ $rc0 -lt 128 ] || [ $rc0 -eq 255 ]; then
11622 $PRINTF "$OK\n"
11623 numOK=$((numOK+1))
11624 listOK="$listOK $N"
11625 else
11626 $PRINTF "$FAILED\n"
11627 echo "$CMD0"
11628 cat "${te}0"
11629 numFAIL=$((numFAIL+1))
11630 listFAIL="$listFAIL $N"
11632 fi # NUMCOND
11634 esac
11635 N=$((N+1))
11638 # test for a bug in gopen that lead to crash or warning when opening a unix
11639 # domain socket with GOPEN
11640 NAME=GOPEN_UNIX_CRASH
11641 case "$TESTS" in
11642 *%$N%*|*%functions%*|*%bugs%*|*%gopen%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
11643 TEST="$NAME: check crash when connecting to a unix domain socket using address GOPEN"
11644 # a unix domain server is started in background. the check process connects to
11645 # its socket. when this process crashes or issues a warning the bug is present.
11646 # please note that a clean behaviour does not proof anything; behaviour of bug
11647 # depends on the value of an uninitialized var
11648 #set -vx
11649 if ! eval $NUMCOND; then :; else
11650 tf="$td/test$N.stdout"
11651 te="$td/test$N.stderr"
11652 ts="$td/test$N.sock"
11653 tdiff="$td/test$N.diff"
11654 da="test$N $(date) $RANDOM"
11655 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts PIPE"
11656 CMD1="$TRACE $SOCAT $opts -d - GOPEN:$ts"
11657 printf "test $F_n $TEST... " $N
11658 $CMD0 >/dev/null 2>"${te}0" </dev/null &
11659 pid0=$!
11660 waitunixport "$ts" 1
11661 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
11662 rc1=$?
11663 kill $pid0 2>/dev/null; wait
11664 if [ $rc1 -ne 0 ]; then
11665 $PRINTF "$FAILED\n"
11666 echo "$CMD0 &"
11667 echo "$CMD1"
11668 cat "${te}0"
11669 cat "${te}1"
11670 numFAIL=$((numFAIL+1))
11671 listFAIL="$listFAIL $N"
11672 elif grep -q ' W ' "${te}1"; then
11673 $PRINTF "$FAILED\n"
11674 echo "$CMD0 &"
11675 echo "$CMD1"
11676 cat "${te}0"
11677 cat "${te}1"
11678 numFAIL=$((numFAIL+1))
11679 listFAIL="$listFAIL $N"
11680 elif ! echo "$da" |diff - ${tf}1 >"$tdiff"; then
11681 $PRINTF "$FAILED\n"
11682 echo "$CMD0 &"
11683 echo "$CMD1"
11684 cat "${te}0"
11685 cat "${te}1"
11686 cat "$tdiff"
11687 numFAIL=$((numFAIL+1))
11688 listFAIL="$listFAIL $N"
11689 else
11690 $PRINTF "$OK\n"
11691 numOK=$((numOK+1))
11692 listOK="$listOK $N"
11694 fi # NUMCOND
11696 esac
11697 N=$((N+1))
11700 # test if socat keeps an existing file where it wanted to create a UNIX socket
11701 NAME=UNIXLISTEN_KEEPFILE
11702 case "$TESTS" in
11703 *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
11704 TEST="$NAME: socat keeps an existing file where it wanted to create a UNIX socket"
11705 # we create a file and start socat with UNIX-LISTEN on this file. expected
11706 # behaviour: socat exits immediately with error, but keeps the file
11707 # up to 1.7.1.3, it removed the file
11708 if ! eval $NUMCOND; then :; else
11709 tf="$td/test$N.file"
11710 te="$td/test$N.stderr"
11711 CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$tf /dev/null"
11712 printf "test $F_n $TEST... " $N
11713 rm -f "$tf"; touch "$tf"
11714 $CMD0 >/dev/null 2>"${te}0"
11715 rc0=$?
11716 if [ $rc0 -ne 0 -a -f "$tf" ]; then
11717 $PRINTF "$OK\n"
11718 numOK=$((numOK+1))
11719 listOK="$listOK $N"
11720 else
11721 $PRINTF "$FAILED\n"
11722 echo "$CMD0"
11723 cat "${te}0"
11724 numFAIL=$((numFAIL+1))
11725 listFAIL="$listFAIL $N"
11727 fi # NUMCOND
11729 esac
11730 N=$((N+1))
11733 # PTY address allowed to specify address parameters but ignored them
11734 NAME=PTY_VOIDARG
11735 case "$TESTS" in
11736 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
11737 TEST="$NAME: check if address params of PTY produce error"
11738 # invoke socat with address PTY and some param; expect an error
11739 if ! eval $NUMCOND; then :; else
11740 tf="$td/test$N.stdout"
11741 te="$td/test$N.stderr"
11742 tdiff="$td/test$N.diff"
11743 da="test$N $(date) $RANDOM"
11744 CMD0="$TRACE $SOCAT $opts /dev/null PTY:/tmp/xyz"
11745 printf "test $F_n $TEST... " $N
11746 $CMD0 >/dev/null 2>"${te}0"
11747 rc0=$?
11748 if [ $rc0 -ne 0 ]; then
11749 $PRINTF "$OK\n"
11750 numOK=$((numOK+1))
11751 listOK="$listOK $N"
11752 else
11753 $PRINTF "$FAILED\n"
11754 echo "$CMD0"
11755 cat "${te}0"
11756 numFAIL=$((numFAIL+1))
11757 listFAIL="$listFAIL $N"
11759 fi # NUMCOND
11761 esac
11762 N=$((N+1))
11765 # incomplete writes were reported but led to data loss
11766 NAME=INCOMPLETE_WRITE
11767 case "$TESTS" in
11768 *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*)
11769 TEST="$NAME: check if incomplete writes are handled properly"
11770 # write to a nonblocking fd a block that is too large for atomic write
11771 # and check if all data arrives
11772 if ! eval $NUMCOND; then :; else
11773 tf="$td/test$N.stdout"
11774 te="$td/test$N.stderr"
11775 tp="$td/test$N.pipe"
11776 tw="$td/test$N.wc-c"
11777 # this is the size we write() in one call; data is never stored on disk, so
11778 # make it large enough to exceed any atomic write size; but higher number might
11779 # take much time
11780 # Note: in OpenBSD-4 the PIPE does not deliver EOF, thus -T
11781 bytes=100000 # for Linux 2.6.? this must be >65536
11782 CMD0="$TRACE $SOCAT $opts -u -T 2 PIPE:$tp STDOUT"
11783 CMD1="$TRACE $SOCAT $opts -u -b $bytes OPEN:/dev/zero,readbytes=$bytes FILE:$tp,o-nonblock"
11784 printf "test $F_n $TEST... " $N
11785 $CMD0 2>"${te}0" |wc -c >"$tw" &
11786 pid=$!
11787 waitfile "$tp"
11788 $CMD1 2>"${te}1" >"${tf}1"
11789 rc1=$?
11790 wait
11791 if [ $rc1 -ne 0 ]; then
11792 $PRINTF "$FAILED (rc1=$rc1)\n"
11793 echo "$CMD0 &"
11794 cat "${te}0" >&2
11795 echo "$CMD1"
11796 cat "${te}1" >&2
11797 numFAIL=$((numFAIL+1))
11798 listFAIL="$listFAIL $N"
11799 namesFAIL="$namesFAIL $NAME"
11800 elif [ ! -e "$tw" ]; then
11801 $PRINTF "$NO_RESULT (no wc -c output)\n"
11802 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11803 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11804 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11805 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11806 numCANT=$((numCANT+1))
11807 listCANT="$listCANT $N"
11808 namesCANT="$namesCANT $NAME"
11809 elif [ "$bytes" -eq $(cat "$tw") ]; then
11810 $PRINTF "$OK\n"
11811 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
11812 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
11813 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
11814 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
11815 numOK=$((numOK+1))
11816 listOK="$listOK $N"
11817 else
11818 $PRINTF "$FAILED (incomplete)\n"
11819 echo "transferred only $(cat $tw) of $bytes bytes" >&2
11820 echo "$CMD0 &"
11821 cat "${te}0" >&2
11822 echo "$CMD1"
11823 cat "${te}1" >&2
11824 numFAIL=$((numFAIL+1))
11825 listFAIL="$listFAIL $N"
11826 namesFAIL="$namesFAIL $NAME"
11828 fi # NUMCOND
11830 esac
11831 N=$((N+1))
11834 NAME=OPENSSL_ANULL
11835 case "$TESTS" in
11836 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
11837 TEST="$NAME: OpenSSL server with cipher aNULL "
11838 if ! eval $NUMCOND; then :;
11839 elif ! testfeats openssl >/dev/null; then
11840 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
11841 numCANT=$((numCANT+1))
11842 listCANT="$listCANT $N"
11843 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
11844 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
11845 numCANT=$((numCANT+1))
11846 listCANT="$listCANT $N"
11847 else
11848 tf="$td/test$N.stdout"
11849 te="$td/test$N.stderr"
11850 tdiff="$td/test$N.diff"
11851 da="test$N $(date) $RANDOM"
11852 newport tcp4
11853 CMD2="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,$SOCAT_EGD,ciphers=aNULL,verify=0 pipe"
11854 CMD="$TRACE $SOCAT $opts - openssl:$LOCALHOST:$PORT,ciphers=aNULL,verify=0,$SOCAT_EGD"
11855 printf "test $F_n $TEST... " $N
11856 eval "$CMD2 2>\"${te}1\" &"
11857 pid=$! # background process id
11858 waittcp4port $PORT
11859 echo "$da" |$CMD >$tf 2>"${te}2"
11860 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
11861 $PRINTF "${YELLOW}FAILED${NORMAL}\n"
11862 #echo "$CMD2 &"
11863 #echo "$CMD"
11864 #cat "${te}1"
11865 #cat "${te}2"
11866 #cat "$tdiff"
11867 numOK=$((numOK+1))
11868 listOK="$listOK $N"
11869 else
11870 $PRINTF "$OK\n"
11871 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
11872 numOK=$((numOK+1))
11873 listOK="$listOK $N"
11875 kill $pid 2>/dev/null
11876 wait
11877 fi ;; # NUMCOND, feats
11878 esac
11879 N=$((N+1))
11882 while read KEYW FEAT ADDR IPPORT; do
11883 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
11884 RUNS=$(tolower $KEYW)
11885 PROTO=$KEYW
11886 proto="$(tolower "$PROTO")"
11887 feat="$(tolower "$FEAT")"
11888 # test the max-children option on really connection oriented sockets
11889 NAME=${KEYW}MAXCHILDREN
11890 case "$TESTS" in
11891 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$feat%*|*%$proto%*|*%socket%*|*%listen%*|*%$NAME%*)
11892 TEST="$NAME: max-children option"
11893 # start a listen process with max-children=1; connect with a client, let it
11894 # sleep some time before sending data; connect with second client that sends
11895 # data immediately. If max-children is working correctly the first data should
11896 # arrive first because the second process has to wait.
11897 if ! eval $NUMCOND; then :;
11898 elif ! testfeats "$FEAT" >/dev/null; then
11899 $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
11900 numCANT=$((numCANT+1))
11901 listCANT="$listCANT $N"
11902 elif ! runs$RUNS >/dev/null; then
11903 $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
11904 numCANT=$((numCANT+1))
11905 listCANT="$listCANT $N"
11906 else
11907 case "X$IPPORT" in
11908 "XPORT")
11909 newport $proto
11910 tsl=$PORT # test socket listen address
11911 tsc="$ADDR:$PORT" # test socket connect address
11914 tsl="$(eval echo "$ADDR")" # resolve $N
11915 tsc=$tsl
11916 esac
11917 #ts="$td/test$N.sock"
11918 tf="$td/test$N.stdout"
11919 te="$td/test$N.stderr"
11920 tdiff="$td/test$N.diff"
11921 da="test$N $(date) $RANDOM"
11922 CMD0="$TRACE $SOCAT $opts -U FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
11923 CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,shut-null"
11924 printf "test $F_n $TEST... " $N
11925 $CMD0 >/dev/null 2>"${te}0" &
11926 pid0=$!
11927 wait${proto}port $tsl 1
11928 (echo "$da 1"; relsleep 2) |$CMD1 >"${tf}1" 2>"${te}1" &
11929 pid1=$!
11930 relsleep 1
11931 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
11932 pid2=$!
11933 relsleep 2
11934 kill $pid1 $pid2 $pid0 2>/dev/null; wait
11935 if echo -e "$da 1\n$da 2" |diff - $tf >$tdiff; then
11936 $PRINTF "$OK\n"
11937 numOK=$((numOK+1))
11938 listOK="$listOK $N"
11939 else
11940 $PRINTF "$FAILED\n"
11941 echo "$CMD0 &"
11942 echo "(echo \"$da 1\"; sleep 2) |$CMD1"
11943 echo "echo \"$da 2\" |$CMD1"
11944 cat "${te}0"
11945 cat "${te}1"
11946 cat "${te}2"
11947 cat "$tdiff"
11948 numFAIL=$((numFAIL+1))
11949 listFAIL="$listFAIL $N"
11951 fi # NUMCOND
11953 esac
11954 N=$((N+1))
11955 done <<<"
11956 TCP4 TCP 127.0.0.1 PORT
11957 TCP6 TCP [::1] PORT
11958 SCTP4 SCTP 127.0.0.1 PORT
11959 SCTP6 SCTP [::1] PORT
11960 UNIX unix $td/test\$N.server -
11962 # debugging this hanging test was difficult - following lessons learned:
11963 # kill <parent> had no effect when child process existed
11964 # strace -f (on Fedora-23) sometimes writes/pads? blocks with \0, overwriting client traces
11965 # using the TRACE feature lets above kill command kill strace, not socat
11966 # care for timing, understand what you want :-)
11969 # test the max-children option on pseudo connected sockets
11970 while read KEYW FEAT SEL ADDR IPPORT SHUT; do
11971 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
11972 RUNS=$(tolower $KEYW)
11973 PROTO=$KEYW
11974 proto="$(tolower "$PROTO")"
11975 # test the max-children option on pseudo connected sockets
11976 NAME=${KEYW}MAXCHILDREN
11977 case "$TESTS" in
11978 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
11979 TEST="$NAME: max-children option"
11980 # start a listen process with max-children=1; connect with a client, let it
11981 # send data and then sleep; connect with second client that wants to send
11982 # data immediately, but keep first client active until server terminates.
11983 #If max-children is working correctly only the first data should
11984 # arrive.
11985 if ! eval $NUMCOND; then :;
11986 elif ! testfeats "$FEAT" >/dev/null; then
11987 $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
11988 numCANT=$((numCANT+1))
11989 listCANT="$listCANT $N"
11990 elif ! runs$RUNS >/dev/null; then
11991 $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
11992 numCANT=$((numCANT+1))
11993 listCANT="$listCANT $N"
11994 else
11995 case "X$IPPORT" in
11996 "XPORT")
11997 newport $proto
11998 tsl=$PORT # test socket listen address
11999 tsc="$ADDR:$PORT" # test socket connect address
12002 tsl="$(eval echo "$ADDR")" # resolve $N
12003 tsc=$tsl
12004 esac
12005 #ts="$td/test$N.sock"
12006 tf="$td/test$N.stdout"
12007 te="$td/test$N.stderr"
12008 tdiff="$td/test$N.diff"
12009 da="test$N $(date) $RANDOM"
12010 # on some Linux distributions it hangs, thus -T option here
12011 CMD0="$TRACE $SOCAT $opts -U -T $(reltime 4) FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
12012 CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,$SHUT"
12013 printf "test $F_n $TEST... " $N
12014 $CMD0 >/dev/null 2>"${te}0" &
12015 pid0=$!
12016 wait${proto}port $tsl 1
12017 (echo "$da 1"; relsleep 3) |$CMD1 >"${tf}1" 2>"${te}1" &
12018 pid1=$!
12019 relsleep 1
12020 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
12021 pid2=$!
12022 relsleep 1
12023 cpids="$(childpids $pid0)"
12024 kill $pid1 $pid2 $pid0 $cpids 2>/dev/null; wait
12025 if echo -e "$da 1" |diff - $tf >$tdiff; then
12026 $PRINTF "$OK\n"
12027 numOK=$((numOK+1))
12028 listOK="$listOK $N"
12029 else
12030 $PRINTF "$FAILED\n"
12031 echo "$CMD0 &"
12032 echo "(echo \"$da 1\"; sleep 2) |$CMD1"
12033 echo "echo \"$da 2\" |$CMD1"
12034 cat "${te}0"
12035 cat "${te}1"
12036 cat "${te}2"
12037 cat "$tdiff"
12038 numFAIL=$((numFAIL+1))
12039 listFAIL="$listFAIL $N"
12041 fi # NUMCOND
12043 esac
12044 N=$((N+1))
12045 done <<<"
12046 UDP4 UDP udp 127.0.0.1 PORT shut-null
12047 UDP6 UDP udp [::1] PORT shut-null
12049 # debugging this hanging test was difficult - following lessons learned:
12050 # kill <parent> had no effect when child process existed
12051 # strace -f (on Fedora-23) sometimes writes/pads? blocks with \0, overwriting client traces
12052 # using the TRACE feature lets above kill command kill strace, not socat
12053 # care for timing, understand what you want :-)
12056 # socat up to 1.7.2.0 had a bug in xioscan_readline() that could be exploited
12057 # to overflow a heap based buffer (socat security advisory 3)
12058 # problem reported by Johan Thillemann
12059 NAME=READLINE_OVFL
12060 case "$TESTS" in
12061 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%readline%*|*%pty%*|*%$NAME%*)
12062 TEST="$NAME: test for buffer overflow in readline prompt handling"
12063 # address 1 is the readline where write data was handled erroneous
12064 # address 2 provides data to trigger the buffer overflow
12065 # when no SIGSEGV or so occurs the test succeeded (bug fixed)
12066 if ! eval $NUMCOND; then :;
12067 elif ! feat=$(testfeats readline pty); then
12068 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
12069 numCANT=$((numCANT+1))
12070 listCANT="$listCANT $N"
12071 else
12072 tf="$td/test$N.stdout"
12073 te="$td/test$N.stderr"
12074 ti="$td/test$N.data"
12075 CMD0="$SOCAT $opts READLINE $ti"
12076 printf "test $F_n $TEST... " $N
12077 # prepare long data - perl might not be installed
12078 #perl -e 'print "\r","Z"x513' >"$ti"
12079 echo $E -n "\rA" >"$ti"
12080 i=0; while [ $i -lt 32 ]; do echo -n "AAAAAAAAAAAAAAAA" >>"$ti"; let i=i+1; done
12081 $TRACE $SOCAT - SYSTEM:"$CMD0; echo rc=\$? >&2",pty >/dev/null 2>"${te}0"
12082 rc=$?
12083 rc0="$(grep ^rc= "${te}0" |sed 's/.*=//')"
12084 if [ $rc -ne 0 ]; then
12085 $PRINTF "${YELLOW}framework failed${NORMAL}\n"
12086 elif [ $rc0 -eq 0 ]; then
12087 $PRINTF "$OK\n"
12088 numOK=$((numOK+1))
12089 listOK="$listOK $N"
12090 else
12091 $PRINTF "$FAILED\n"
12092 echo "$CMD0"
12093 grep -v ^rc= "${te}0"
12094 numFAIL=$((numFAIL+1))
12095 listFAIL="$listFAIL $N"
12097 fi # NUMCOND
12099 esac
12100 N=$((N+1))
12103 # Does Socat have -d0 option?
12104 opt_d0=
12105 if $SOCAT -h |grep -e -d0 >/dev/null; then
12106 opt_d0="-d0"
12109 # socat up to 1.7.2.1 did only shutdown() but not close() an accept() socket
12110 # that was rejected due to range, tcpwrap, lowport, or sourceport option.
12111 # This file descriptor leak could be used for a denial of service attack.
12112 NAME=FDLEAK
12113 case "$TESTS" in
12114 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*)
12115 TEST="$NAME: file descriptor leak with range option"
12116 # have a TCP-LISTEN with range option; connect with wrong source address until
12117 # "open files" limit would exceed. When server continues operation the bug is
12118 # not present.
12119 if ! eval $NUMCOND; then :; else
12120 tf="$td/test$N.stdout"
12121 te="$td/test$N.stderr"
12122 tdiff="$td/test$N.diff"
12123 da="test$N $(date) $RANDOM"
12124 RLIMIT_NOFILE="$(ulimit -n)"
12125 if ! [[ "$RLIMIT_NOFILE" =~ ^[0-9][0-9]*$ ]]; then
12126 $PRINTF "${YELLOW}cannot determine ulimit -n${NORMAL}"
12127 else
12128 if [ $RLIMIT_NOFILE -gt 1024 ]; then
12129 ulimit -n 1024 # 65536 takes too long
12130 RLIMIT_NOFILE="$(ulimit -n)"
12132 newport tcp4
12133 CMD0="$TRACE $SOCAT $opt_d0 $opts TCP4-LISTEN:$PORT,$REUSEADDR,range=$LOCALHOST:255.255.255.255 PIPE"
12134 #CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,pf=ip4,$REUSEADDR,range=$LOCALHOST4:255.255.255.255 PIPE"
12135 CMD1="$TRACE $SOCAT $opts -t 0 /dev/null TCP4:$SECONDADDR:$PORT,bind=$SECONDADDR"
12136 CMD2="$TRACE $SOCAT $opts - TCP:$LOCALHOST4:$PORT,bind=$LOCALHOST4"
12137 printf "test $F_n $TEST... " $N
12138 $CMD0 >/dev/null 2>"${te}0" &
12139 pid0=$!
12140 waittcp4port $PORT 1
12141 while [ $RLIMIT_NOFILE -gt 0 ]; do
12142 $CMD1 >/dev/null 2>>"${te}1"
12143 let RLIMIT_NOFILE=RLIMIT_NOFILE-1
12144 done
12145 echo "$da" |$CMD2 >"${tf}2" 2>"${te}2"
12146 rc2=$?
12147 kill $pid0 2>/dev/null; wait
12148 echo -e "$da" |diff "${tf}2" - >$tdiff
12149 if [ $rc2 -ne 0 ]; then
12150 $PRINTF "$FAILED (rc2=$rc2)\n"
12151 echo "$CMD0 &"
12152 cat "${te}0" >&2
12153 echo "$CMD1"
12154 cat "${te}1" >&2
12155 echo "$CMD2"
12156 cat "${te}2" >&2
12157 numFAIL=$((numFAIL+1))
12158 listFAIL="$listFAIL $N"
12159 elif [ -f "$tdiff" -a ! -s "$tdiff" ]; then
12160 $PRINTF "$OK\n"
12161 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
12162 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
12163 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
12164 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
12165 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
12166 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
12167 numOK=$((numOK+1))
12168 listOK="$listOK $N"
12169 else
12170 $PRINTF "$FAILED\n"
12171 echo "$CMD0 &"
12172 cat "${te}0" >&2
12173 echo "$CMD1"
12174 cat "${te}1" >&2
12175 echo "$CMD2"
12176 cat "${te}2" >&2
12177 numFAIL=$((numFAIL+1))
12178 listFAIL="$listFAIL $N"
12180 fi # ulimit -n
12181 fi # NUMCOND
12183 esac
12184 N=$((N+1))
12187 if false; then # this overflow is not reliably reproducable
12188 # 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.
12189 NAME=PROXY_ADDR_OVFL
12190 case "$TESTS" in
12191 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%socket%*|*%listen%*|*%$NAME%*)
12192 TEST="$NAME: proxy address parameters overflow"
12193 # invoke socat PROXY-CONNECT with long proxy server and target server names. If it terminates with exit code >= 128 it is vulnerable
12194 # 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
12195 if ! eval $NUMCOND; then :; else
12196 tf="$td/test$N.stdout"
12197 te="$td/test$N.stderr"
12198 tdiff="$td/test$N.diff"
12199 da="test$N $(date) $RANDOM"
12200 EF=; for p in ef; do
12201 if type ef >/dev/null 2>&1; then
12202 EF="ef "; break
12204 done
12205 newport tcp4
12206 CMD0="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,$REUSEADDR FILE:/dev/null"
12207 #CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$(perl -e "print 'A' x 256"):$(perl -e "print 'A' x 256"):80"
12208 CMD1="$EF $TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:localhost:$(perl -e "print 'A' x 384"):80,proxyport=$PORT"
12209 printf "test $F_n $TEST... " $N
12210 $CMD0 >/dev/null 2>"${te}0" &
12211 pid0=$!
12212 waittcp4port $PORT 1
12213 $CMD1 >/dev/null 2>"${te}1"
12214 rc1=$?
12215 if [ $rc1 -lt 128 ]; then
12216 if [ "$EF" ]; then
12217 $PRINTF "$OK\n"
12218 numOK=$((numOK+1))
12219 listOK="$listOK $N"
12220 else
12221 $PRINTF "$UNKNOWN $RED(install ElectricFEnce!)$NORMAL\n"
12222 numCANT=$((num+1))
12223 listCANT="$listCANT $N"
12225 else
12226 $PRINTF "$FAILED\n"
12227 echo "$CMD1"
12228 cat "${te}"
12229 numFAIL=$((numFAIL+1))
12230 listFAIL="$listFAIL $N"
12232 fi # NUMCOND
12234 esac
12235 N=$((N+1))
12236 fi # false
12239 # LISTEN addresses in socat up to 1.7.2.1 applied many file descriptor, socket,
12240 # and TCP options only to the listening socket instead of the connection socket.
12241 NAME=LISTEN_KEEPALIVE
12242 case "$TESTS" in
12243 *%$N%*|*%functions%*|*%bugs%*|*%listen%*|*%keepalive%*|*%socket%*|*%listen%*|*%fork%*|*%$NAME%*)
12244 TEST="$NAME: keepalive option is applied to connection socket"
12245 # Instance 0 has TCP-LISTEN with option so-keepalive and invokes filan after
12246 # accept(). filan writes its output to the socket. instance 1 connects to
12247 # instance 0. The value of the sockets so-keepalive option is checked, it must
12248 # be 1
12249 if ! eval $NUMCOND; then :; else
12250 tf="$td/test$N.stdout"
12251 te="$td/test$N.stderr"
12252 #tdiff="$td/test$N.diff"
12253 #da="test$N $(date) $RANDOM"
12254 newport tcp4
12255 CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,$REUSEADDR,so-keepalive EXEC:\"$FILAN -i 1\",nofork"
12256 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
12257 printf "test $F_n $TEST... " $N
12258 eval $CMD0 >/dev/null 2>"${te}0" &
12259 pid0=$!
12260 waittcp4port $PORT 1
12261 $CMD1 >"${tf}1" 2>"${te}1"
12262 KEEPALIVE="$(cat "${tf}1" |tail -n +2 |sed -e "s/.*KEEPALIVE=//" -e "s/[[:space:]].*//")"
12263 rc1=$?
12264 kill $pid0 2>/dev/null; wait
12265 if [ -z "$KEEPALIVE" ]; then
12266 $PRINTF "$NO_RESULT\n"
12267 echo "$CMD0 &"
12268 cat "${te}0" >&2
12269 echo "$CMD1"
12270 cat "${te}1" >&2
12271 numCANT=$((numCANT+1))
12272 listCANT="$listCANT $N"
12273 namesCANT="$namesCANT $NAME"
12274 elif [ "$KEEPALIVE" = "1" ]; then
12275 $PRINTF "$OK\n";
12276 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
12277 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
12278 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
12279 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
12280 numOK=$((numOK+1))
12281 listOK="$listOK $N"
12282 else
12283 $PRINTF "$FAILED (KEEPALIVE=$KEEPALIVE)\n"
12284 echo "$CMD0 &"
12285 cat "${te}0" >&2
12286 echo "$CMD1"
12287 cat "${te}1" >&2
12288 numFAIL=$((numFAIL+1))
12289 listFAIL="$listFAIL $N"
12290 namesFAIL="$namesFAIL $NAME"
12292 fi # NUMCOND
12294 esac
12295 N=$((N+1))
12298 # OPENSSL-CONNECT with bind option failed on some systems (eg.FreeBSD, but not
12299 # Linux) with "Invalid argument".
12300 NAME=OPENSSL_CONNECT_BIND
12301 case "$TESTS" in
12302 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%listen%*|*%$NAME%*)
12303 TEST="$NAME: test OPENSSL-CONNECT with bind option"
12304 # have a simple SSL server that just echoes data.
12305 # connect with socat using OPENSSL-CONNECT with bind, send data and check if the
12306 # reply is identical.
12307 if ! eval $NUMCOND; then :;
12308 elif ! testfeats openssl >/dev/null; then
12309 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
12310 numCANT=$((numCANT+1))
12311 listCANT="$listCANT $N"
12312 else
12313 gentestcert testsrv
12314 tf0="$td/test$N.0.stdout"
12315 te0="$td/test$N.0.stderr"
12316 tf1="$td/test$N.1.stdout"
12317 te1="$td/test$N.1.stderr"
12318 tdiff="$td/test$N.diff"
12319 da="test$N $(date) $RANDOM"
12320 newport tcp4
12321 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 PIPE"
12322 CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,bind=$LOCALHOST,verify=0"
12323 printf "test $F_n $TEST... " $N
12324 $CMD0 >/dev/null 2>"$te0" &
12325 pid0=$!
12326 waittcp4port $PORT 1
12327 echo "$da" |$CMD1 >"$tf1" 2>"$te1"
12328 rc1=$?
12329 kill $pid0 2>/dev/null; wait
12330 if [ "$rc1" -ne 0 ]; then
12331 $PRINTF "$FAILED\n"
12332 echo "$CMD0 &"
12333 echo "$CMD1"
12334 cat "$te0"
12335 cat "$te1"
12336 numFAIL=$((numFAIL+1))
12337 listFAIL="$listFAIL $N"
12338 elif ! echo "$da" |diff - $tf1 >"$tdiff"; then
12339 $PRINTF "$FAILED\n"
12340 echo "$CMD0 &"
12341 echo "$CMD1"
12342 cat "${te}0"
12343 cat "${te}1"
12344 cat "$tdiff"
12345 numFAIL=$((numFAIL+1))
12346 listFAIL="$listFAIL $N"
12347 else
12348 $PRINTF "$OK\n"
12349 numOK=$((numOK+1))
12350 listOK="$listOK $N"
12352 fi # NUMCOND
12354 esac
12355 N=$((N+1))
12358 # socat up to version 1.7.2.3
12359 # had a bug that converted a bit mask of 0 internally to 0xffffffff
12360 NAME=TCP4RANGE_0BITS
12361 case "$TESTS" in
12362 *%$N%*|*%functions%*|*%fork%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%range%*|*%listen%*|*%$NAME%*)
12363 TEST="$NAME: correct evaluation of range mask 0"
12364 if ! eval $NUMCOND; then :;
12365 elif [ -z "$SECONDADDR" ]; then
12366 # we need access to a second address
12367 $PRINTF "test $F_n $TEST... ${YELLOW}need a second IPv4 address${NORMAL}\n" $N
12368 numCANT=$((numCANT+1))
12369 listCANT="$listCANT $N"
12370 else
12371 tf="$td/test$N.stdout"
12372 te="$td/test$N.stderr"
12373 tdiff="$td/test$N.diff"
12374 da="test$N $(date) $RANDOM"
12375 newport tcp4
12376 #testserversec "$N" "$TEST" "$opts" "tcp4-l:$PORT,reuseaddr,fork,retry=1" "" "range=$SECONDADDR/32" "tcp4:127.0.0.1:$PORT" 4 tcp $PORT 0
12377 CMD0="$TRACE $SOCAT $opts -u TCP4-LISTEN:$PORT,$REUSEADDR,range=127.0.0.1/0 CREATE:$tf"
12378 CMD1="$TRACE $SOCAT $opts -u - TCP4-CONNECT:$SECONDADDR:$PORT,bind=$SECONDADDR"
12379 printf "test $F_n $TEST... " $N
12380 $CMD0 2>"${te}0" &
12381 pid0=$!
12382 waittcp4port $PORT 1
12383 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
12384 rc1=$?
12385 sleep 1
12386 kill $pid0 2>/dev/null; wait
12387 if [ $rc1 != 0 ]; then
12388 $PRINTF "${YELLOW}invocation failed${NORMAL}\n"
12389 numCANT=$((numCANT+1))
12390 listCANT="$listCANT $N"
12391 elif ! [ -f "$tf" ]; then
12392 $PRINTF "$FAILED\n"
12393 echo "$CMD0 &"
12394 echo "$CMD1"
12395 cat "${te}0"
12396 cat "${te}1"
12397 numFAIL=$((numFAIL+1))
12398 listFAIL="$listFAIL $N"
12399 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
12400 $PRINTF "${YELLOW}diff failed${NORMAL}\n"
12401 numCANT=$((numCANT+1))
12402 listCANT="$listCANT $N"
12403 else
12404 $PRINTF "$OK\n"
12405 numOK=$((numOK+1))
12406 listOK="$listOK $N"
12409 fi ;; # $SECONDADDR, NUMCOND
12410 esac
12411 N=$((N+1))
12414 # test: OPENSSL sets of environment variables with important values of peer certificate
12415 newport tcp4
12416 while read ssldist MODE MODULE FIELD TESTADDRESS PEERADDRESS VALUE; do
12417 if [ -z "$ssldist" ] || [[ "$ssldist" == \#* ]]; then continue; fi
12419 SSLDIST=$(toupper $ssldist)
12420 NAME="ENV_${SSLDIST}_${MODE}_${MODULE}_${FIELD}"
12421 case "$TESTS" in
12422 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$ssldist%*|*%envvar%*|*%listen%*|*%$NAME%*)
12423 TEST="$NAME: $SSLDIST sets env SOCAT_${SSLDIST}_${MODULE}_${FIELD}"
12424 # have a server accepting a connection and invoking some shell code. The shell
12425 # code extracts and prints the SOCAT related environment vars.
12426 # outside code then checks if the environment contains the variables correctly
12427 # describing the desired field.
12428 FEAT=$(echo "$ssldist" |tr a-z A-Z)
12429 if ! eval $NUMCOND; then :;
12430 elif ! testfeats $FEAT >/dev/null; then
12431 $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N
12432 numCANT=$((numCANT+1))
12433 listCANT="$listCANT $N"
12434 else
12435 tf="$td/test$N.stdout"
12436 te="$td/test$N.stderr"
12437 gentestcert testsrv
12438 gentestcert testcli
12439 test_proto=tcp4
12440 case "$MODE" in
12441 SERVER)
12442 CMD0="$SOCAT $opts -u -lp socat $TESTADDRESS SYSTEM:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\""
12443 CMD1="$SOCAT $opts -u /dev/null $PEERADDRESS"
12444 printf "test $F_n $TEST... " $N
12445 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
12446 pid0=$!
12447 wait${test_proto}port $PORT 1
12448 { $CMD1 2>"${te}1"; sleep 1; }
12449 rc1=$?
12450 waitfile "$tf" 2
12451 kill $pid0 2>/dev/null; wait
12453 CLIENT)
12454 CMD0="$SOCAT $opts -u /dev/null $PEERADDRESS"
12455 CMD1="$SOCAT $opts -u -lp socat $TESTADDRESS SYSTEM:\"echo SOCAT_${SSLDIST}_${MODULE}_${FIELD}=\\\$SOCAT_${SSLDIST}_${MODULE}_${FIELD}; sleep 1\""
12456 printf "test $F_n $TEST... " $N
12457 $CMD0 2>"${te}0" &
12458 pid0=$!
12459 wait${test_proto}port $PORT 1
12460 eval "$CMD1 2>\"${te}1\" >\"$tf\""
12461 rc1=$?
12462 waitfile "$tf" 2
12463 kill $pid0 2>/dev/null; wait
12465 esac
12466 if [ $rc1 != 0 ]; then
12467 $PRINTF "$NO_RESULT (client failed):\n"
12468 echo "$CMD0 &"
12469 cat "${te}0"
12470 echo "$CMD1"
12471 cat "${te}1"
12472 numCANT=$((numCANT+1))
12473 listCANT="$listCANT $N"
12474 elif effval="$(grep SOCAT_${SSLDIST}_${MODULE}_${FIELD} "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")";
12475 [ "$effval" = "$VALUE" ]; then
12476 $PRINTF "$OK\n"
12477 if [ "$debug" ]; then
12478 echo "$CMD0 &"
12479 cat "${te}0"
12480 echo "$CMD1"
12481 cat "${te}1"
12483 numOK=$((numOK+1))
12484 listOK="$listOK $N"
12485 else
12486 $PRINTF "$FAILED\n"
12487 echo "expected \"$VALUE\", got \"$effval\"" >&2
12488 echo "$CMD0 &"
12489 cat "${te}0"
12490 echo "$CMD1"
12491 cat "${te}1"
12492 numFAIL=$((numFAIL+1))
12493 listFAIL="$listFAIL $N"
12495 fi # NUMCOND, feats
12497 esac
12498 N=$((N+1))
12500 done <<<"
12501 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
12502 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
12503 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
12504 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
12505 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
12506 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
12507 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
12508 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
12509 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
12513 ###############################################################################
12514 # tests: option umask with "passive" NAMED group addresses
12515 while read addr fileopt addropts proto diropt ADDR2; do
12516 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12517 # some passive (listening...) filesystem based addresses did not implement the
12518 # umask option
12519 ADDR=$(toupper $addr)
12520 ADDR_=${ADDR/-/_}
12521 #PROTO=$(toupper $proto)
12522 if [ "$diropt" = "." ]; then diropt=; fi
12523 if [ "$fileopt" = "." ]; then fileopt=; fi
12524 if [ "$addropts" = "." ]; then addropts=; fi
12525 NAME=${ADDR_}_UMASK
12526 case "$TESTS" in
12527 *%$N%*|*%functions%*|*%bugs%*|*%proto%*|*%socket%*|*%$proto%*|*%umask%*|*%listen%*|*%$NAME%*)
12528 TEST="$NAME: $ADDR applies option umask"
12529 # start a socat process with passive/listening file system entry. Check the
12530 # permissions of the FS entry, then terminate the process.
12531 # Test succeeds when FS entry exists and has expected permissions.
12532 if ! eval $NUMCOND; then :; else
12533 if [ $ADDR = PTY ]; then set -xv; fi
12534 tlog="$td/test$N.log"
12535 te0="$td/test$N.0.stderr"
12536 tsock="$td/test$N.sock"
12537 if [ -z "$fileopt" ]; then
12538 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,unlink-close=0,umask=177 $ADDR2"
12539 else
12540 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,unlink-close=0,umask=177 $ADDR2"
12542 printf "test $F_n $TEST... " $N
12543 $CMD0 >/dev/null 2>"$te0" &
12544 pid0=$!
12545 wait${proto} $tsock 1 2>"$tlog"
12546 ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
12547 perms=$(fileperms "$tsock")
12548 kill $pid0 2>>"$tlog"
12549 wait
12550 if [ "$ERRNOENT" ]; then
12551 $PRINTF "${RED}no entry${NORMAL}\n"
12552 echo "$CMD0 &"
12553 cat "$te0"
12554 cat "$tlog"
12555 let numFAIL=numFAIL+1
12556 listFAIL="$listFAIL $N"
12557 elif [ "$perms" != "600" ]; then
12558 $PRINTF "${RED}perms \"$perms\", expected \"600\" ${NORMAL}\n"
12559 echo "$CMD0 &"
12560 cat "$te0"
12561 let numFAIL=numFAIL+1
12562 listFAIL="$listFAIL $N"
12563 else
12564 $PRINTF "$OK\n"
12565 let numOK=numOK+1
12566 listOK="$listOK $N"
12568 set +xv
12569 fi # NUMCOND
12571 esac
12572 N=$((N+1))
12574 done <<<"
12575 # address fileopt addropts waitfor direction ADDR2
12576 create . . file -U FILE:/dev/null
12577 open . creat file . FILE:/dev/null
12578 gopen . creat file . FILE:/dev/null
12579 unix-listen . . unixport . FILE:/dev/null
12580 unix-recvfrom . . unixport . FILE:/dev/null
12581 unix-recv . . unixport -u FILE:/dev/null
12582 pipe . . file -u FILE:/dev/null
12583 # pty does not seem to honor umask:
12584 #pty link . file . PIPE
12588 # Tests: option perm with "passive" NAMED group addresses
12589 # Note tests UNIX_RECVFROM_PERM and UNIX_RECV_PERM had chmod() applied after
12590 # bind() due to an error but succeeded. After a correction with Socat 1.8.0.0
12591 # the perm option is applied as fchown() call which does not affect the FS
12592 # entry on Freebsd (10.3) and OpenIndiana (2021-04), so they fail now
12593 while read addr fileopt addropts feat waitfor diropt; do
12594 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12595 # test if passive (listening...) filesystem based addresses implement option perm
12596 ADDR=$(toupper $addr)
12597 ADDR_=${ADDR/-/_}
12598 if [ "$diropt" = "." ]; then diropt=; fi
12599 if [ "$fileopt" = "." ]; then fileopt=; fi
12600 if [ "$addropts" = "." ]; then addropts=; fi
12601 NAME=${ADDR_}_PERM
12602 case "$TESTS" in
12603 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$feat%*|*%ignoreeof%*|*%perm%*|*%listen%*|*%$NAME%*)
12604 TEST="$NAME: $ADDR applies option perm"
12605 # start a socat process with passive/listening file system entry. Check the
12606 # permissions of the FS entry, then terminate the process.
12607 # Test succeeds when FS entry exists and has expected permissions.
12608 if ! eval $NUMCOND; then :; else
12609 tlog="$td/test$N.log"
12610 te0="$td/test$N.0.stderr"
12611 tsock="$td/test$N.sock"
12612 # set -vx
12613 if [ -z "$fileopt" ]; then
12614 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof"
12615 else
12616 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,perm=511 FILE:/dev/null,ignoreeof"
12618 printf "test $F_n $TEST... " $N
12619 $CMD0 >/dev/null 2>"$te0" &
12620 pid0=$!
12621 wait${waitfor} $tsock 1 2>"$tlog"
12622 ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
12623 perms=$(fileperms "$tsock")
12624 kill $pid0 2>>"$tlog"
12625 wait
12626 if [ "$ERRNOENT" ]; then
12627 $PRINTF "${RED}no entry${NORMAL}\n"
12628 echo "$CMD0 &"
12629 cat "$te0"
12630 cat "$tlog"
12631 let numFAIL=numFAIL+1
12632 listFAIL="$listFAIL $N"
12633 elif [ "$perms" != "511" ]; then
12634 $PRINTF "${RED}perms \"$perms\", expected \"511\" ${NORMAL}\n"
12635 echo "$CMD0 &"
12636 cat "$te0"
12637 let numFAIL=numFAIL+1
12638 listFAIL="$listFAIL $N"
12639 else
12640 $PRINTF "$OK\n"
12641 let numOK=numOK+1
12642 listOK="$listOK $N"
12644 set +vx
12645 fi # NUMCOND
12647 esac
12648 N=$((N+1))
12650 done <<<"
12651 # address fileopt addropts feat waitfor direction
12652 create . . file file -U
12653 open . creat file file .
12654 gopen . creat file file .
12655 unix-listen . . unix unixport .
12656 unix-recvfrom . . unix unixport .
12657 unix-recv . . unix unixport -u
12658 pipe . . pipe file -u
12659 pty link . pty file .
12663 # tests: option user with "passive" NAMED group addresses
12664 while read addr fileopt addropts feat waitfor diropt; do
12665 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12666 # test if passive (listening...) filesystem based addresses implement option user
12667 ADDR=$(toupper $addr)
12668 ADDR_=${ADDR/-/_}
12669 if [ "$diropt" = "." ]; then diropt=; fi
12670 if [ "$fileopt" = "." ]; then fileopt=; fi
12671 if [ "$addropts" = "." ]; then addropts=; fi
12672 NAME=${ADDR_}_USER
12673 case "$TESTS" in
12674 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$feat%*|*%root%*|*%ignoreeof%*|*%listen%*|*%$NAME%*)
12675 TEST="$NAME: $ADDR applies option user"
12676 # start a socat process with passive/listening file system entry with user option.
12677 # Check the owner of the FS entry, then terminate the process.
12678 # Test succeeds when FS entry exists and has expected owner.
12679 if ! eval $NUMCOND; then :;
12680 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
12681 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
12682 numCANT=$((numCANT+1))
12683 listCANT="$listCANT $N"
12684 else
12685 tlog="$td/test$N.log"
12686 te0="$td/test$N.0.stderr"
12687 tsock="$td/test$N.sock"
12688 # set -vx
12689 if [ -z "$fileopt" ]; then
12690 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof"
12691 else
12692 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts,user=$SUBSTUSER FILE:/dev/null,ignoreeof"
12694 printf "test $F_n $TEST... " $N
12695 $CMD0 >/dev/null 2>"$te0" &
12696 pid0=$!
12697 wait${waitfor} $tsock 1 2>"$tlog"
12698 ERRNOENT=; if ! [ -e "$tsock" ]; then ERRNOENT=1; fi
12699 user=$(fileuser "$tsock")
12700 kill $pid0 2>>"$tlog"
12701 wait
12702 if [ "$ERRNOENT" ]; then
12703 $PRINTF "${FAILED}(no entry)\n"
12704 echo "$CMD0 &"
12705 cat "$te0" >&2
12706 cat "$tlog" >&2
12707 let numFAIL=numFAIL+1
12708 listFAIL="$listFAIL $N"
12709 elif [ "$user" != "$SUBSTUSER" ]; then
12710 $PRINTF "${FAILD}(user \"$user\", expected \"$SUBSTUSER\")\n"
12711 echo "$CMD0 &"
12712 cat "$te0" >&2
12713 let numFAIL=numFAIL+1
12714 listFAIL="$listFAIL $N"
12715 else
12716 $PRINTF "$OK\n"
12717 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
12718 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
12719 numOK=$((numOK+1))
12720 listOK="$listOK $N"
12722 set +vx
12723 fi # NUMCOND
12725 esac
12726 N=$((N+1))
12728 done <<<"
12729 # address fileopt addropts feat waitfor direction
12730 create . . file file -U
12731 open . creat file file .
12732 gopen . creat file file .
12733 unix-listen . . unix unixport .
12734 unix-recvfrom . . unix unixport .
12735 unix-recv . . unix unixport -u
12736 pipe . . pipe file -u
12737 pty link . pty file .
12741 # tests: is "passive" filesystem entry removed at the end? (without fork)
12742 while read addr fileopt addropts feat waitfor diropt crit ADDR2; do
12743 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12744 # some passive (listening...) filesystem based addresses did not remove the file
12745 # system entry at the end
12746 ADDR=$(toupper $addr)
12747 ADDR_=${ADDR/-/_}
12748 if [ "$diropt" = "." ]; then diropt=; fi
12749 if [ "$fileopt" = "." ]; then fileopt=; fi
12750 if [ "$addropts" = "." ]; then addropts=; fi
12751 # $ADDR removes the file system entry when the process is terminated
12752 NAME=${ADDR_}_REMOVE
12753 case "$TESTS" in
12754 *%$N%*|*%functions%*|*%bugs%*|*%feat%*|*%socket%*|*%listen%*|*%$NAME%*)
12755 TEST="$NAME: $ADDR removes socket entry when terminated while waiting for connection"
12756 # start a socat process with listening unix domain socket etc. Terminate the
12757 # process and check if the file system socket entry still exists.
12758 # Test succeeds when entry does not exist.
12759 if ! eval $NUMCOND; then :; else
12760 tlog="$td/test$N.log"
12761 te0="$td/test$N.0.stderr"
12762 tsock="$td/test$N.sock"
12763 if [ -z "$fileopt" ]; then
12764 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,$addropts $ADDR2"
12765 else
12766 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,$fileopt=$tsock,$addropts $ADDR2"
12768 printf "test $F_n $TEST... " $N
12769 $CMD0 >/dev/null 2>"$te0" &
12770 pid0=$!
12771 wait${waitfor} "$crit" $tsock 1 2>"$tlog"
12772 kill $pid0 2>>"$tlog"
12773 rc1=$?
12774 wait >>"$tlog"
12775 if [ $rc1 != 0 ]; then
12776 $PRINTF "${YELLOW}setup failed${NORMAL}\n"
12777 echo "$CMD0 &"
12778 cat "$te0"
12779 cat "$tlog"
12780 numCANT=$((numCANT+1))
12781 listCANT="$listCANT $N"
12782 elif ! [ $crit $tsock ]; then
12783 $PRINTF "$OK\n"
12784 let numOK=numOK+1
12785 listOK="$listOK $N"
12786 else
12787 $PRINTF "$FAILED\n"
12788 echo "$CMD0 &"
12789 cat "$te0"
12790 cat "$tlog"
12791 let numFAIL=numFAIL+1
12792 listFAIL="$listFAIL $N"
12794 fi # NUMCOND
12796 esac
12797 N=$((N+1))
12799 done <<<"
12800 # address fileopt addropts feat waitfor direction crit ADDR2
12801 unix-listen . . unix unixport . -e FILE:/dev/null
12802 unix-recvfrom . . unix unixport . -e FILE:/dev/null
12803 unix-recv . . unix unixport -u -e FILE:/dev/null
12804 pipe . . pipe file -u -e FILE:/dev/null
12805 pty link . pty file . -L PIPE
12809 # tests: is "passive" filesystem entry removed at the end? (with fork)
12810 while read addr fileopt addropts proto diropt crit ADDR2; do
12811 if [ -z "$addr" ] || [[ "$addr" == \#* ]]; then continue; fi
12812 # some passive (listening...) filesystem based addresses with fork did not remove
12813 # the file system entry at the end
12814 ADDR=$(toupper $addr)
12815 ADDR_=${ADDR/-/_}
12816 #PROTO=$(toupper $proto)
12817 if [ "$diropt" = "." ]; then diropt=; fi
12818 if [ "$fileopt" = "." ]; then fileopt=; fi
12819 if [ "$addropts" = "." ]; then addropts=; fi
12820 # $ADDR with fork removes the file system entry when the process is terminated
12821 NAME=${ADDR_}_REMOVE_FORK
12822 case "$TESTS" in
12823 *%$N%*|*%functions%*|*%bugs%*|*%fork%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
12824 TEST="$NAME: $ADDR with fork removes socket entry when terminated during accept"
12825 # start a socat process with listening unix domain socket etc and option fork.
12826 # Terminate the process and check if the file system socket entry still exists.
12827 # Test succeeds when entry does not exist.
12828 if ! eval $NUMCOND; then :; else
12829 tlog="$td/test$N.log"
12830 te0="$td/test$N.0.stderr"
12831 tsock="$td/test$N.sock"
12832 if [ -z "$fileopt" ]; then
12833 CMD0="$TRACE $SOCAT $opts $diropt $ADDR:$tsock,fork,$addropts $ADDR2"
12834 else
12835 CMD0="$TRACE $SOCAT $opts $diropt $ADDR,fork,$fileopt=$tsock,$addropts $ADDR2"
12837 printf "test $F_n $TEST... " $N
12838 $CMD0 >/dev/null 2>"$te0" &
12839 pid0=$!
12840 wait${proto} "$crit" $tsock 1 2>"$tlog"
12841 kill $pid0 2>>"$tlog"
12842 rc1=$?
12843 wait
12844 if [ $rc1 != 0 ]; then
12845 $PRINTF "${YELLOW}setup failed${NORMAL}\n"
12846 echo "$CMD0 &"
12847 cat "$te0"
12848 cat "$tlog"
12849 numCANT=$((numCANT+1))
12850 listCANT="$listCANT $N"
12851 elif ! [ $crit $tsock ]; then
12852 $PRINTF "$OK\n"
12853 let numOK=numOK+1
12854 listOK="$listOK $N"
12855 else
12856 $PRINTF "$FAILED\n"
12857 echo "$CMD0 &"
12858 cat "$te0"
12859 cat "$tlog"
12860 let numFAIL=numFAIL+1
12861 listFAIL="$listFAIL $N"
12863 fi # NUMCOND
12865 esac
12866 N=$((N+1))
12868 done <<<"
12869 # address fileopt addropts waitfor direction crit ADDR2
12870 unix-listen . . unixport . -e FILE:/dev/null
12871 unix-recvfrom . . unixport . -e FILE:/dev/null
12875 # bug fix: SYSTEM address child process shut down parents sockets including
12876 # SSL connection under some circumstances.
12877 NAME=SYSTEM_SHUTDOWN
12878 case "$TESTS" in
12879 *%$N%*|*%functions%*|*%bugs%*|*%system%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
12880 TEST="$NAME: SYSTEM address does not shutdown its parents addresses"
12881 # start an OpenSSL echo server using SYSTEM:cat
12882 # start an OpenSSL client that sends data
12883 # when the client recieves its data and terminates without error the test succeeded
12884 # in case of the bug the client issues an error like:
12885 # SSL_connect(): error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
12886 if ! eval $NUMCOND; then :;
12887 elif ! testfeats openssl >/dev/null; then
12888 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
12889 numCANT=$((numCANT+1))
12890 listCANT="$listCANT $N"
12891 else
12892 gentestcert testsrv
12893 tf="$td/test$N.stdout"
12894 te="$td/test$N.stderr"
12895 tdiff="$td/test$N.diff"
12896 da="test$N $(date) $RANDOM"
12897 newport tcp4
12898 CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 SYSTEM:cat"
12899 CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0"
12900 printf "test $F_n $TEST... " $N
12901 $CMD0 >/dev/null 2>"${te}0" &
12902 pid0=$!
12903 waittcp4port $PORT 1
12904 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
12905 rc1=$?
12906 kill $pid0 2>/dev/null; wait
12907 if [ $rc1 -ne 0 ]; then
12908 $PRINTF "$FAILED\n"
12909 echo "rc1=$rc1"
12910 echo "$CMD0 &"
12911 echo "$CMD1"
12912 cat "${te}0"
12913 cat "${te}1"
12914 numFAIL=$((numFAIL+1))
12915 listFAIL="$listFAIL $N"
12916 elif ! echo "$da" |diff - "${tf}1" >"$tdiff" 2>&1; then
12917 $PRINTF "$FAILED\n"
12918 echo "diff:"
12919 cat "$tdiff"
12920 echo "$CMD0 &"
12921 echo "$CMD1"
12922 cat "${te}0"
12923 cat "${te}1"
12924 numFAIL=$((numFAIL+1))
12925 listFAIL="$listFAIL $N"
12926 else
12927 $PRINTF "$OK\n"
12928 numOK=$((numOK+1))
12929 listOK="$listOK $N"
12931 fi # NUMCOND
12933 esac
12934 N=$((N+1))
12937 # test if TCP4-LISTEN with empty port arg terminates with error
12938 NAME=TCP4_NOPORT
12939 case "$TESTS" in
12940 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*)
12941 TEST="$NAME: test if TCP4-LISTEN with empty port arg bails out"
12942 # run socat with TCP4-LISTEN with empty port arg. Check if it terminates
12943 # immediately with return code 1
12944 if ! eval $NUMCOND; then :; else
12945 tf="$td/test$N.stdout"
12946 te="$td/test$N.stderr"
12947 t0rc="$td/test$N.rc"
12948 tdiff="$td/test$N.diff"
12949 da="test$N $(date) $RANDOM"
12950 CMD0="$SOCAT $opts TCP4-LISTEN: /dev/null"
12951 printf "test $F_n $TEST... " $N
12952 { $CMD0 >/dev/null 2>"${te}0"; echo $? >"$t0rc"; } & 2>/dev/null
12953 pid0=$!
12954 sleep 1
12955 kill $pid0 2>/dev/null; wait
12956 if [ ! -f "$t0rc" ]; then
12957 $PRINTF "$FAILED\n"
12958 echo "no return code of CMD0 stored" >&2
12959 echo "$CMD0 &"
12960 cat "${te}0"
12961 numFAIL=$((numFAIL+1))
12962 listFAIL="$listFAIL $N"
12963 elif ! echo 1 |diff - "$t0rc" >"$tdiff"; then
12964 $PRINTF "$FAILED\n"
12965 echo "CMD0 exited with $(cat $t0rc), expected 1"
12966 echo "$CMD0 &"
12967 cat "${te}0"
12968 numFAIL=$((numFAIL+1))
12969 listFAIL="$listFAIL $N"
12970 else
12971 $PRINTF "$OK\n"
12972 numOK=$((numOK+1))
12973 listOK="$listOK $N"
12975 fi # NUMCOND
12977 esac
12978 N=$((N+1))
12981 # tests of various SSL methods; from TLS1.3 this method is not avail in OpenSSL:
12982 OPENSSL_METHODS_OBSOLETE="SSL3 SSL23"
12983 OPENSSL_METHODS_EXPECTED="TLS1 TLS1.1 TLS1.2 DTLS1 DTLS1.2"
12985 # The OPENSSL_METHOD_DTLS1 test hangs sometimes, probably depending on the openssl version.
12986 OPENSSL_VERSION_GOOD=1.0.2 # this is just a guess.
12987 # known bad: 1.0.1e
12988 # known good: 1.0.2j
12990 # test if the obsolete SSL methods can be used with OpenSSL
12991 for method in $OPENSSL_METHODS_OBSOLETE; do
12993 NAME=OPENSSL_METHOD_$method
12994 case "$TESTS" in
12995 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%listen%*|*%$NAME%*)
12996 TEST="$NAME: test OpenSSL method $method"
12997 # Start a socat process with obsoelete OpenSSL method, it should fail
12998 if ! eval $NUMCOND; then :;
12999 elif ! testfeats openssl >/dev/null; then
13000 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13001 numCANT=$((numCANT+1))
13002 listCANT="$listCANT $N"
13003 elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then
13004 $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N
13005 numCANT=$((numCANT+1))
13006 listCANT="$listCANT $N"
13007 else
13008 gentestcert testsrv
13009 tf="$td/test$N.stdout"
13010 te="$td/test$N.stderr"
13011 tdiff="$td/test$N.diff"
13012 da="test$N $(date) $RANDOM"
13013 newport tcp4
13014 CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,openssl-method=$method,cert=testsrv.pem,verify=0 PIPE"
13015 CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,opensslmethod=$method,verify=0"
13016 printf "test $F_n $TEST... " $N
13017 if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then
13018 $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n"
13019 numCANT=$((numCANT+1))
13020 listCANT="$listCANT $N"
13021 else
13022 $CMD0 >/dev/null 2>"${te}0" &
13023 pid0=$!
13024 waittcp4port $PORT 1 1 2>/dev/null; w0=$? # result of waiting for process 0
13025 if [ $w0 -eq 0 ]; then
13026 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13027 rc1=$?
13028 kill $pid0 2>/dev/null; wait
13030 echo "$da" |diff - "${tf}1" >"$tdiff" 2>/dev/null
13031 if [ $w0 -eq 0 ] && [ -f "${tf}1" ] && ! [ -s "$tdiff" ]; then
13032 $PRINTF "${YELLOW}WARN${NORMAL} (obsolete method succeeds)\n"
13033 numOK=$((numOK+1))
13034 listOK="$listOK $N"
13035 else
13036 $PRINTF "$OK (obsolete method fails)\n"
13037 cat "$tdiff"
13038 numOK=$((numOK+1))
13039 listOK="$listOK $N"
13041 if [ "$VERBOSE" ]; then
13042 echo " $CMD0"
13043 echo " echo \"$da\" |$CMD1"
13045 fi # !DTLS1 hang
13046 fi # NUMCOND
13048 esac
13049 N=$((N+1))
13051 done
13053 # test if the various SSL methods can be used with OpenSSL
13054 for method in $OPENSSL_METHODS_EXPECTED; do
13056 NAME=OPENSSL_METHOD_$method
13057 METHFAM=$(tolower "${method%%[0-9]*}")
13058 case "$TESTS" in
13059 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%openssl%*|*%$METHFAM%*|*%listen%*|*%$NAME%*)
13060 TEST="$NAME: test OpenSSL method $method"
13061 # Start a socat process listening with OpenSSL and echoing data,
13062 # using the selected method
13063 # Start a second socat process connecting to the listener using
13064 # the same method, send some data and catch the reply.
13065 # If the reply is identical to the sent data the test succeeded.
13066 if ! eval $NUMCOND; then :;
13067 elif ! testfeats openssl >/dev/null; then
13068 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13069 numCANT=$((numCANT+1))
13070 listCANT="$listCANT $N"
13071 elif ! socat -hhh |grep -q "^[[:space:]]*openssl-method[[:space:]]"; then
13072 $PRINTF "test $F_n $TEST... ${YELLOW}Option openssl-method not available${NORMAL}\n" $N
13073 numCANT=$((numCANT+1))
13074 listCANT="$listCANT $N"
13075 else
13076 gentestcert testsrv
13077 tf="$td/test$N.stdout"
13078 te="$td/test$N.stderr"
13079 tdiff="$td/test$N.diff"
13080 da="test$N $(date) $RANDOM"
13081 if [[ "$method" =~ DTLS* ]]; then
13082 newport udp4
13083 else
13084 newport tcp4
13086 CMD0="$SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,openssl-method=$method,cert=testsrv.pem,verify=0 PIPE"
13087 CMD1="$SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,openssl-method=$method,verify=0"
13088 printf "test $F_n $TEST... " $N
13089 if [ "$method" = DTLS1 -a "$(echo -e "$OPENSSL_VERSION\n1.0.2" |sort |tail -n 1)" = "$OPENSSL_VERSION_GOOD" ]; then
13090 $PRINTF "${YELLOW}might hang, skipping${NORMAL}\n"
13091 numCANT=$((numCANT+1))
13092 listCANT="$listCANT $N"
13093 else
13094 $CMD0 >/dev/null 2>"${te}0" &
13095 pid0=$!
13096 if [[ "$method" =~ DTLS* ]]; then
13097 waitudp4port $PORT 1
13098 else
13099 waittcp4port $PORT 1
13101 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13102 rc1=$?
13103 kill $pid0 2>/dev/null; wait
13104 if echo "$da" |diff - "${tf}1" >"$tdiff"; then
13105 $PRINTF "$OK\n"
13106 numOK=$((numOK+1))
13107 listOK="$listOK $N"
13108 if [ "$VERBOSE" ]; then
13109 echo " $CMD0"
13110 echo " echo \"$da\" |$CMD1"
13112 else
13113 $PRINTF "$FAILED\n"
13114 echo "$CMD0 &"
13115 cat "${te}0"
13116 echo "$CMD1"
13117 cat "${te}1"
13118 cat "$tdiff"
13119 numFAIL=$((numFAIL+1))
13120 listFAIL="$listFAIL $N"
13121 #esac
13123 fi # !DTLS1 hang
13124 fi # NUMCOND
13126 esac
13127 N=$((N+1))
13129 done
13131 # test security of option openssl-set-min-proto-version
13132 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)
13133 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)
13135 NAME=OPENSSL_MIN_VERSION
13136 case "$TESTS" in
13137 *%$N%*|*%functions%*|*%security%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%openssl%*|*%listen%*|*%$NAME%*)
13138 TEST="$NAME: security of OpenSSL server with openssl-min-proto-version"
13139 if ! eval $NUMCOND; then :;
13140 elif ! testaddrs openssl >/dev/null; then
13141 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13142 numCANT=$((numCANT+1))
13143 listCANT="$listCANT $N"
13144 elif ! feat=$(testoptions openssl-min-proto-version); then
13145 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
13146 numCANT=$((numCANT+1))
13147 listCANT="$listCANT $N"
13148 elif ! [ "$OPENSSL_LATEST_PROTO_VERSION" -a "$OPENSSL_BEFORELAST_PROTO_VERSION" -a \
13149 "$OPENSSL_LATEST_PROTO_VERSION" != "$OPENSSL_BEFORELAST_PROTO_VERSION" ]; then
13150 $PRINTF "test $F_n $TEST... ${YELLOW}cannot determine two available SSL/TLS versions${NORMAL}\n" $N
13151 numCANT=$((numCANT+1))
13152 listCANT="$listCANT $N"
13153 else
13154 gentestcert testsrv
13155 newport tcp4
13156 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
13157 fi ;; # NUMCOND, $fets
13158 esac
13159 N=$((N+1))
13162 # Address options fdin and fdout were silently ignored when not applicable
13163 # due to -u or -U option. Now these combinations are caught as errors.
13164 NAME=FDOUT_ERROR
13165 case "$TESTS" in
13166 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
13167 TEST="$NAME: fdout bails out in write-only context"
13168 # use EXEC in write-only context with option fdout. Expected behaviour: error
13169 if ! eval $NUMCOND; then :; else
13170 tf="$td/test$N.stdout"
13171 te="$td/test$N.stderr"
13172 tdiff="$td/test$N.diff"
13173 da="test$N $(date) $RANDOM"
13174 CMD="$SOCAT $opts -u /dev/null EXEC:cat,fdout=1"
13175 printf "test $F_n $TEST... " $N
13176 $CMD >/dev/null 2>"${te}"
13177 rc=$?
13178 if [ $rc -eq 1 ]; then
13179 $PRINTF "$OK\n"
13180 numOK=$((numOK+1))
13181 listOK="$listOK $N"
13182 else
13183 $PRINTF "$FAILED\n"
13184 echo "$CMD"
13185 cat "${te}"
13186 echo "command did not terminate with error!"
13187 numFAIL=$((numFAIL+1))
13188 listFAIL="$listFAIL $N"
13190 fi # NUMCOND
13192 esac
13193 N=$((N+1))
13196 # test if failure exit code of SYSTEM invocation causes socat to also exit
13197 # with !=0
13198 NAME=SYSTEM_RC
13199 case "$TESTS" in
13200 *%$N%*|*%functions%*|*%system%*|*%$NAME%*)
13201 TEST="$NAME: promote failure of SYSTEM"
13202 # run socat with SYSTEM:false and check if socat exits with !=0
13203 if ! eval $NUMCOND; then :; else
13204 tf="$td/test$N.stdout"
13205 te="$td/test$N.stderr"
13206 tdiff="$td/test$N.diff"
13207 da="test$N $(date) $RANDOM"
13208 # shut-none makes sure that the child is not killed by parent
13209 CMD0="$TRACE $SOCAT $opts - SYSTEM:false,shut-none"
13210 printf "test $F_n $TEST... " $N
13211 sleep 1 |$CMD0 >/dev/null 2>"${te}0"
13212 rc0=$?
13213 if [ $rc0 -eq 0 ]; then
13214 $PRINTF "$FAILED\n"
13215 echo "$CMD0"
13216 cat "${te}0"
13217 numFAIL=$((numFAIL+1))
13218 listFAIL="$listFAIL $N"
13219 else
13220 $PRINTF "$OK\n"
13221 numOK=$((numOK+1))
13222 listOK="$listOK $N"
13224 fi # NUMCOND
13226 esac
13227 N=$((N+1))
13230 # test if failure exit code of EXEC invocation causes socat to also exit
13231 # with !=0
13232 NAME=EXEC_RC
13233 case "$TESTS" in
13234 *%$N%*|*%functions%*|*%exec%*|*%$NAME%*)
13235 TEST="$NAME: promote failure of EXEC"
13236 # run socat with EXEC:false and check if socat exits with !=0
13237 if ! eval $NUMCOND; then :; else
13238 tf="$td/test$N.stdout"
13239 te="$td/test$N.stderr"
13240 tdiff="$td/test$N.diff"
13241 da="test$N $(date) $RANDOM"
13242 # shut-none makes sure that the child is not killed by parent
13243 CMD0="$TRACE $SOCAT $opts - EXEC:false,shut-none"
13244 printf "test $F_n $TEST... " $N
13245 sleep 1 |$CMD0 >/dev/null 2>"${te}0"
13246 rc0=$?
13247 if [ $rc0 -eq 0 ]; then
13248 $PRINTF "$FAILED\n"
13249 echo "$CMD0"
13250 cat "${te}0"
13251 numFAIL=$((numFAIL+1))
13252 listFAIL="$listFAIL $N"
13253 else
13254 $PRINTF "$OK\n"
13255 numOK=$((numOK+1))
13256 listOK="$listOK $N"
13258 fi # NUMCOND
13260 esac
13261 N=$((N+1))
13264 # test the so-reuseaddr option
13265 NAME=SO_REUSEADDR
13266 case "$TESTS" in
13267 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
13268 TEST="$NAME: test the so-reuseaddr option"
13269 # process 0 provides a tcp listening socket with so-reuseaddr;
13270 # process 1 connects to this port; thus the port is connected but no longer
13271 # listening
13272 # process 2 tries to listen on this port with SO_REUSEADDR, will fail if the
13273 # SO_REUSEADDR socket options did not work
13274 # process 3 connects to this port; only if it is successful the test is ok
13275 if ! eval $NUMCOND; then :;
13276 elif ! feat=$(testoptions so-reuseaddr); then
13277 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
13278 numCANT=$((numCANT+1))
13279 listCANT="$listCANT $N"
13280 else
13281 newport tcp4; tp="$PORT"
13282 tf="$td/test$N.stdout"
13283 te="$td/test$N.stderr"
13284 tdiff="$td/test$N.diff"
13285 da="test$N $(date) $RANDOM"
13286 CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,$REUSEADDR PIPE"
13287 CMD1="$TRACE $SOCAT $opts - TCP4:localhost:$tp"
13288 CMD2="$CMD0"
13289 CMD3="$CMD1"
13290 printf "test $F_n $TEST... " $N
13291 $CMD0 >/dev/null 2>"${te}0" &
13292 pid0=$!
13293 waittcp4port $tp 1
13294 (echo "$da"; relsleep 3) |$CMD1 >"$tf" 2>"${te}1" & # this should always work
13295 pid1=$!
13296 relsleep 1
13297 $CMD2 >/dev/null 2>"${te}2" &
13298 pid2=$!
13299 waittcp4port $tp 1
13300 (echo "$da") |$CMD3 >"${tf}3" 2>"${te}3"
13301 rc3=$?
13302 kill $pid0 $pid1 $pid2 2>/dev/null; wait
13303 if ! echo "$da" |diff - "$tf"; then
13304 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
13305 echo "$CMD0 &"
13306 echo "$CMD1"
13307 numCANT=$((numCANT+1))
13308 listCANT="$listCANT $N"
13309 elif [ $rc3 -ne 0 ]; then
13310 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
13311 echo "$CMD0 &"
13312 echo "$CMD1"
13313 echo "$CMD2 &"
13314 echo "$CMD3"
13315 cat "${te}2" "${te}3"
13316 numFAIL=$((numFAIL+1))
13317 listFAIL="$listFAIL $N"
13318 elif ! echo "$da" |diff - "${tf}3"; then
13319 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
13320 echo "$CMD0 &"
13321 echo "$CMD1"
13322 echo "$CMD2 &"
13323 echo "$CMD3"
13324 echo "$da" |diff - "${tf}3"
13325 numCANT=$((numCANT+1))
13326 listCANT="$listCANT $N"
13327 else
13328 $PRINTF "$OK\n"
13329 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
13330 numOK=$((numOK+1))
13331 listOK="$listOK $N"
13333 fi # NUMCOND, SO_REUSEADDR
13335 esac
13336 N=$((N+1))
13339 # test the so-reuseport option
13340 NAME=SO_REUSEPORT
13341 case "$TESTS" in
13342 *%$N%*|*%functions%*|*%ip4%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
13343 TEST="$NAME: test the so-reuseport option"
13344 # process 0 provides a tcp listening socket with so-reuseport;
13345 # process 1 provides an equivalent tcp listening socket with so-reuseport;
13346 # process 2 connects to this port and transfers data
13347 # process 3 connects to this port and transfers data
13348 # test succeeds when both data transfers work
13349 if ! eval $NUMCOND; then :;
13350 elif ! feat=$(testoptions so-reuseport); then
13351 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
13352 numCANT=$((numCANT+1))
13353 listCANT="$listCANT $N"
13354 else
13355 newport tcp4; tp="$PORT"
13356 tf="$td/test$N.stdout"
13357 te="$td/test$N.stderr"
13358 tdiff="$td/test$N.diff"
13359 da2="test$N $(date) $RANDOM"
13360 da3="test$N $(date) $RANDOM"
13361 CMD0="$TRACE $SOCAT $opts TCP4-L:$tp,$REUSEADDR,so-reuseport PIPE"
13362 CMD1="$CMD0"
13363 CMD2="$TRACE $SOCAT $opts - TCP4:localhost:$tp"
13364 CMD3="$CMD2"
13365 printf "test $F_n $TEST... " $N
13366 $CMD0 >/dev/null 2>"${te}0" &
13367 pid0=$!
13368 $CMD1 >/dev/null 2>"${te}1" &
13369 pid1=$!
13370 waittcp4port $tp 1
13371 (echo "$da2") |$CMD2 >"${tf}2" 2>"${te}2" # this should always work
13372 rc2=$?
13373 (echo "$da3") |$CMD3 >"${tf}3" 2>"${te}3"
13374 rc3=$?
13375 kill $pid0 $pid1 $pid2 2>/dev/null; wait
13376 if ! echo "$da2" |diff - "${tf}2"; then
13377 $PRINTF "${YELLOW}phase 1 failed${NORMAL}\n"
13378 echo "$CMD0 &"
13379 cat "${te}0"
13380 echo "$CMD1 &"
13381 cat "${te}1"
13382 echo "$CMD2"
13383 cat "${te}2"
13384 numCANT=$((numCANT+1))
13385 listCANT="$listCANT $N"
13386 elif [ $rc3 -ne 0 ]; then
13387 $PRINTF "$FAILED:\n"
13388 echo "$CMD0 &"
13389 cat "${te}0"
13390 echo "$CMD1 &"
13391 cat "${te}1"
13392 echo "$CMD2"
13393 cat "${te}2"
13394 echo "$CMD3"
13395 cat "${te}3"
13396 numFAIL=$((numFAIL+1))
13397 listFAIL="$listFAIL $N"
13398 elif ! echo "$da2" |diff - "${tf}2"; then
13399 $PRINTF "$FAILED:\n"
13400 echo "$CMD0 &"
13401 cat "${te}0"
13402 echo "$CMD1 &"
13403 cat "${te}1"
13404 echo "$CMD2"
13405 cat "${te}2"
13406 echo "$CMD3"
13407 cat "${te}3"
13408 echo "$da2" |diff - "${tf}2"
13409 numFAIL=$((numFAIL+1))
13410 listFAIL="$listFAIL $N"
13411 elif ! echo "$da3" |diff - "${tf}3"; then
13412 $PRINTF "$FAILED:\n"
13413 echo "$CMD0 &"
13414 cat "${te}0"
13415 echo "$CMD1 &"
13416 cat "${te}1"
13417 echo "$CMD2"
13418 cat "${te}2"
13419 echo "$CMD3"
13420 cat "${te}3"
13421 echo "$da3" |diff - "${tf}3"
13422 numFAIL=$((numFAIL+1))
13423 listFAIL="$listFAIL $N"
13424 else
13425 $PRINTF "$OK\n"
13426 if [ -n "$debug" ]; then cat "${te}0" "${te}1" "${te}2" "${te}3"; fi
13427 numOK=$((numOK+1))
13428 listOK="$listOK $N"
13430 fi # NUMCOND, SO_REUSEPORT
13432 esac
13433 N=$((N+1))
13436 # Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped.
13437 NAME=EXEC_NOFORK_UNIDIR
13438 case "$TESTS" in
13439 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*)
13440 TEST="$NAME: Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped"
13441 # invoke a simple echo command with EXEC, nofork, and -u
13442 # expected behaviour: output appears on stdout
13443 if ! eval $NUMCOND; then :; else
13444 tf="$td/test$N.stdout"
13445 te="$td/test$N.stderr"
13446 tdiff="$td/test$N.diff"
13447 da="test$N $(date) $RANDOM"
13448 CMD0="$TRACE $SOCAT $opts -u /dev/null EXEC:\"echo \\\\\\\"\\\"$da\\\"\\\\\\\"\",nofork"
13449 printf "test $F_n $TEST... " $N
13450 eval "$CMD0" >"${tf}0" 2>"${te}0"
13451 rc1=$?
13452 if echo "$da" |diff - "${tf}0" >"$tdiff"; then
13453 $PRINTF "$OK\n"
13454 numOK=$((numOK+1))
13455 listOK="$listOK $N"
13456 else
13457 $PRINTF "$FAILED\n"
13458 echo "$CMD0"
13459 cat "${te}0"
13460 cat "$tdiff"
13461 numFAIL=$((numFAIL+1))
13462 listFAIL="$listFAIL $N"
13464 fi # NUMCOND
13466 esac
13467 N=$((N+1))
13470 # OpenSSL ECDHE ciphers were introduced in socat 1.7.3.0 but in the same release
13471 # they were broken by a porting effort. This test checks if OpenSSL ECDHE works
13472 # 2019-02: this does no longer work (Ubuntu-18.04)
13473 NAME=OPENSSL_ECDHE
13474 case "$TESTS" in
13475 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%socket%*|*%listen%*|*%$NAME%*)
13476 TEST="$NAME: test OpenSSL ECDHE"
13477 # generate a ECDHE key, start an OpenSSL server, connect with a client and try to
13478 # pass data
13479 if ! eval $NUMCOND; then :;
13480 elif ! testfeats openssl >/dev/null; then
13481 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
13482 numCANT=$((numCANT+1))
13483 listCANT="$listCANT $N"
13484 elif ! openssl ciphers |grep -q '\<ECDHE\>'; then
13485 $PRINTF "test $F_n $TEST... ${YELLOW}openssl: cipher ECDHE not available${NORMAL}\n" $N
13486 numCANT=$((numCANT+1))
13487 listCANT="$listCANT $N"
13488 else
13489 tf="$td/test$N.stdout"
13490 te="$td/test$N.stderr"
13491 tdiff="$td/test$N.diff"
13492 da="test$N $(date) $RANDOM"
13493 #TESTSRV=./testsrvec; gentesteccert $TESTSRV
13494 TESTSRV=./testsrv; gentestcert $TESTSRV
13495 newport tcp4
13496 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=$TESTSRV.crt,key=$TESTSRV.pem,verify=0 PIPE"
13497 CMD1="$TRACE $SOCAT $opts - OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cipher=ECDHE-ECDSA-AES256-GCM-SHA384,cafile=$TESTSRV.crt,verify=0"
13498 printf "test $F_n $TEST... " $N
13499 $CMD0 >/dev/null 2>"${te}0" &
13500 pid0=$!
13501 waittcp4port $PORT 1
13502 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13503 rc1=$?
13504 kill $pid0 2>/dev/null; wait
13505 if [ $rc1 -ne 0 ]; then
13506 $PRINTF "$FAILED\n"
13507 echo "failure symptom: client error" >&2
13508 echo "server and stderr:" >&2
13509 echo "$CMD0 &"
13510 cat "${te}0"
13511 echo "client and stderr:" >&2
13512 echo "$CMD1"
13513 cat "${te}1"
13514 numFAIL=$((numFAIL+1))
13515 listFAIL="$listFAIL $N"
13516 elif echo "$da" |diff - "${tf}1" >"$tdiff"; then
13517 $PRINTF "$OK\n"
13518 numOK=$((numOK+1))
13519 listOK="$listOK $N"
13520 else
13521 $PRINTF "$FAILED\n"
13522 echo "server and stderr:" >&2
13523 echo "$CMD1"
13524 cat "${te}1"
13525 echo "client and stderr:" >&2
13526 echo "$CMD0 &"
13527 cat "${te}0"
13528 numFAIL=$((numFAIL+1))
13529 listFAIL="$listFAIL $N"
13531 fi # NUMCOND
13533 esac
13534 N=$((N+1))
13537 # option ipv6-join-group "could not be used"
13538 # fixed in 1.7.3.2
13539 NAME=USE_IPV6_JOIN_GROUP
13540 case "$TESTS" in
13541 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip6%*|*%udp%*|*%udp6%*|*%dgram%*|*%multicast%*|*%$NAME%*)
13542 TEST="$NAME: is option ipv6-join-group used"
13543 # Invoke socat with option ipv6-join-group on UDP6 address.
13544 # Terminate immediately, do not transfer data.
13545 # If socat exits with 0 the test succeeds.
13546 # Up to 1.7.3.1 it failed with "1 option(s) could not be used"
13547 if ! eval $NUMCOND; then :; else
13548 tf="$td/test$N.stdout"
13549 te="$td/test$N.stderr"
13550 tdiff="$td/test$N.diff"
13551 da="test$N $(date) $RANDOM"
13552 newport udp6
13553 CMD0="$TRACE $SOCAT $opts -T 0.001 -u UDP6-RECV:$PORT,ipv6-join-group=[ff02::2]:$MCINTERFACE /dev/null"
13554 printf "test $F_n $TEST... " $N
13555 $CMD0 >/dev/null 2>"${te}0"
13556 rc0=$?
13557 if [ $rc0 -eq 0 ]; then
13558 $PRINTF "$OK\n"
13559 numOK=$((numOK+1))
13560 listOK="$listOK $N"
13561 else
13562 $PRINTF "$FAILED\n"
13563 echo "$CMD0"
13564 cat "${te}0"
13565 numFAIL=$((numFAIL+1))
13566 listFAIL="$listFAIL $N"
13568 fi # NUMCOND
13570 esac
13571 N=$((N+1))
13574 # The fix to "Make code async-signal-safe" used internally FD 3 and FD 4.
13575 # Using option fdin=3 did not pass data to executed program.
13576 NAME=DIAG_FDIN
13577 case "$TESTS" in
13578 *%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*)
13579 TEST="$NAME: test use of fdin=3"
13580 # Use FD 3 explicitely with fdin and test if Socat passes data to executed
13581 # program
13582 if ! eval $NUMCOND; then :; else
13583 tf="$td/test$N.stdout"
13584 te="$td/test$N.stderr"
13585 tdiff="$td/test$N.diff"
13586 da="test$N $(date) $RANDOM"
13587 CMD0="$TRACE $SOCAT $opts - SYSTEM:\"cat >&3 <&4\",fdin=4,fdout=3"
13588 printf "test $F_n $TEST... " $N
13589 echo "$da" |$TRACE $SOCAT $opts - SYSTEM:"cat <&3 >&4",fdin=3,fdout=4 >${tf}0 2>"${te}0"
13590 rc0=$?
13591 if [ $rc0 -ne 0 ]; then
13592 $PRINTF "$FAILED\n"
13593 echo "$CMD0"
13594 cat "${te}0"
13595 numFAIL=$((numFAIL+1))
13596 listFAIL="$listFAIL $N"
13597 elif echo "$da" |diff - ${tf}0 >$tdiff; then
13598 $PRINTF "$OK\n"
13599 numOK=$((numOK+1))
13600 listOK="$listOK $N"
13601 else
13602 $PRINTF "$FAILED\n"
13603 echo "$CMD0"
13604 cat "${te}0"
13605 cat "$tdiff"
13606 numFAIL=$((numFAIL+1))
13607 listFAIL="$listFAIL $N"
13609 fi # NUMCOND
13611 esac
13612 N=$((N+1))
13615 NAME=SOCAT_OPT_HINT
13616 case "$TESTS" in
13617 *%$N%*|*%functions%*|*%$NAME%*)
13618 TEST="$NAME: check if merging single character options is rejected"
13619 if ! eval $NUMCOND; then :; else
13620 te="$td/test$N.stderr"
13621 CMD0="$TRACE $SOCAT $opts -vx FILE:/dev/null ECHO"
13622 printf "test $F_n $TEST... " $N
13623 $CMD0 >/dev/null 2>"${te}0"
13624 rc0=$?
13625 if [ "$rc0" = "1" ]; then
13626 $PRINTF "$OK\n"
13627 numOK=$((numOK+1))
13628 listOK="$listOK $N"
13629 else
13630 $PRINTF "$FAILED\n"
13631 echo "$CMD0" >&2
13632 numFAIL=$((numFAIL+1))
13633 listFAIL="$listFAIL $N"
13635 fi ;; # NUMCOND
13636 esac
13637 N=$((N+1))
13640 # test for a bug in Socat version 1.7.3.3 where
13641 # termios options of the first address were applied to the second address.
13642 NAME=TERMIOS_PH_ALL
13643 case "$TESTS" in
13644 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%termios%*|*%$NAME%*)
13645 TEST="$NAME: are termios options applied to the correct address"
13646 # add a termios option to the first address, a tty, and have a second address
13647 # with pipe. If no error occurs the termios option was not applied to the pipe,
13648 # thus the test succeeded.
13649 if ! eval $NUMCOND; then :; else
13650 tf="$td/test$N.stdout"
13651 te="$td/test$N.stderr"
13652 tdiff="$td/test$N.diff"
13653 da="test$N $(date) $RANDOM"
13654 CMD0="$TRACE $SOCAT $opts -T 1 STDIO,echo=0 EXEC:cat 2>${te}0"
13655 echo "$CMD0" >$td/test$N.sh
13656 chmod a+x $td/test$N.sh
13657 # EXEC need not work with script (musl libc), so use SYSTEM
13658 CMD1="$TRACE $SOCAT $opts /dev/null SYSTEM:$td/test$N.sh,pty,$PTYOPTS"
13659 printf "test $F_n $TEST... " $N
13660 $CMD1 2>"${te}1"
13661 rc0=$?
13662 if [ $rc0 -eq 0 ]; then
13663 $PRINTF "$OK\n"
13664 numOK=$((numOK+1))
13665 listOK="$listOK $N"
13666 else
13667 $PRINTF "$FAILED\n"
13668 echo "$CMD0"
13669 cat "${te}0"
13670 echo "$CMD1"
13671 cat "${te}1"
13672 numFAIL=$((numFAIL+1))
13673 listFAIL="$listFAIL $N"
13675 fi # NUMCOND
13677 esac
13678 N=$((N+1))
13681 # Due to a fallback logic before calling getaddrinfo(), intended to allow use
13682 # of service (port) names with SCTP, raw socket addresses where resolved with
13683 # socket type stream, which fails for protocol 6 (TCP)
13684 # Fixed after 1.7.3.3
13685 NAME=IP_SENDTO_6
13686 case "$TESTS" in
13687 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%rawip%*|*%rawip4%*|*%$NAME%*)
13688 TEST="$NAME: IP-SENDTO::6 passes getaddrinfo()"
13689 # invoke socat with address IP-SENDTO:*:6; when this does not fail with
13690 # "ai_socktype not supported", the test succeeded
13691 if ! eval $NUMCOND; then :; else
13692 tf="$td/test$N.stdout"
13693 te="$td/test$N.stderr"
13694 tdiff="$td/test$N.diff"
13695 CMD0="$TRACE $SOCAT $opts -u /dev/null IP-SENDTO:127.0.0.1:6"
13696 printf "test $F_n $TEST... " $N
13697 $CMD0 >/dev/null 2>"${te}0"
13698 if ! grep -q "ai_socktype not supported" ${te}0; then
13699 $PRINTF "$OK\n"
13700 numOK=$((numOK+1))
13701 listOK="$listOK $N"
13702 else
13703 $PRINTF "$FAILED\n"
13704 echo "$CMD0"
13705 cat "${te}0"
13706 numFAIL=$((numFAIL+1))
13707 listFAIL="$listFAIL $N"
13709 fi # NUMCOND
13711 esac
13712 N=$((N+1))
13715 # test if the multiple EOF messages are fixed
13716 NAME=MULTIPLE_EOF
13717 case "$TESTS" in
13718 *%$N%*|*%functions%*|*%bugs%*|*%unix%*|*%socket%*|*%listen%*|*%$NAME%*)
13719 TEST="$NAME: multiple EOF messages"
13720 # 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
13721 if ! eval $NUMCOND; then :; else
13722 ts="$td/test$N.sock"
13723 tf="$td/test$N.stdout"
13724 te="$td/test$N.stderr"
13725 tdiff="$td/test$N.diff"
13726 da="test$N $(date) $RANDOM"
13727 CMD0="$TRACE $SOCAT $opts -d -d UNIX-LISTEN:$ts /dev/null"
13728 CMD1="$TRACE $SOCAT $opts -d -d - UNIX-CONNECT:$ts"
13729 printf "test $F_n $TEST... " $N
13730 $CMD0 >/dev/null 2>"${te}0" &
13731 pid0=$!
13732 waitunixport $ts 1
13733 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13734 rc1=$?
13735 kill $pid0 2>/dev/null; wait
13736 if [ $(grep "socket 2 (fd .*) is at EOF" ${te}0 |wc -l) -eq 1 ]; then
13737 $PRINTF "$OK\n"
13738 numOK=$((numOK+1))
13739 listOK="$listOK $N"
13740 else
13741 $PRINTF "$FAILED\n"
13742 echo "$CMD0 &"
13743 echo "$CMD1"
13744 cat "${te}0"
13745 cat "${te}1"
13746 numFAIL=$((numFAIL+1))
13747 listFAIL="$listFAIL $N"
13749 fi # NUMCOND
13751 esac
13752 N=$((N+1))
13755 # Test for integer overflow with data transfer block size parameter
13756 NAME=BLKSIZE_INT_OVERFL
13757 case "$TESTS" in
13758 *%$N%*|*%functions%*|*%bugs%*|*%security%*|*%$NAME%*)
13759 TEST="$NAME: integer overflow with buffer size parameter"
13760 # Use a buffer size that would lead to integer overflow
13761 # Test succeeds when Socat terminates with correct error message
13762 if ! eval $NUMCOND; then :; else
13763 tf="$td/test$N.stdout"
13764 te="$td/test$N.stderr"
13765 tdiff="$td/test$N.diff"
13766 dat="$td/test$N.dat"
13767 # calculate the minimal length with integer overflow
13768 case $SIZE_T in
13769 2) CHKSIZE=32768 ;;
13770 4) CHKSIZE=2147483648 ;;
13771 8) CHKSIZE=9223372036854775808 ;;
13772 16) CHKSIZE=170141183460469231731687303715884105728 ;;
13773 *) echo "Unsupported SIZE_T=\"$SIZE_T\"" >2 ;;
13774 esac
13775 CMD0="$TRACE $SOCAT $opts -T 1 -b $CHKSIZE /dev/null PIPE"
13776 printf "test $F_n $TEST... " $N
13777 $CMD0 >/dev/null 2>"${te}0"
13778 rc0=$?
13779 if [ $rc0 -eq 0 ]; then
13780 $PRINTF "$FAILED (rc=$rc0)\n"
13781 echo "$CMD0"
13782 cat "${te}0"
13783 numFAIL=$((numFAIL+1))
13784 listFAIL="$listFAIL $N"
13785 elif [ $rc0 -eq 1 ]; then
13786 if grep -q "buffer size option (-b) to big" "${te}0"; then
13787 $PRINTF "$OK\n"
13788 numOK=$((numOK+1))
13789 listOK="$listOK $N"
13790 else
13791 $PRINTF "$FAILED (rc=$rc0)\n"
13792 echo "$CMD0"
13793 cat "${te}0"
13794 numFAIL=$((numFAIL+1))
13795 listFAIL="$listFAIL $N"
13798 fi # NUMCOND
13800 esac
13801 N=$((N+1))
13803 # Test if unbalanced quoting in Socat addresses is detected
13804 NAME=UNBALANCED_QUOTE
13805 case "$TESTS" in
13806 *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*)
13807 TEST="$NAME: Test fix of unbalanced quoting"
13808 # Invoke Socat with an address containing unbalanced quoting. If Socat prints
13809 # a "syntax error" message, the test succeeds
13810 if ! eval $NUMCOND; then :; else
13811 tf="$td/test$N.stdout"
13812 te="$td/test$N.stderr"
13813 tdiff="$td/test$N.diff"
13814 da="test$N $(date) $RANDOM"
13815 CMD0="$TRACE $SOCAT $opts -u FILE:$td/ab\"cd FILE:/dev/null"
13816 printf "test $F_n $TEST... " $N
13817 $CMD0 >/dev/null 2>"${te}0"
13818 if grep -q -i -e "syntax error" -e "unexpected end" "${te}0"; then
13819 $PRINTF "$OK\n"
13820 if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi
13821 if [ "$debug" ]; then cat ${te} >&2; fi
13822 numOK=$((numOK+1))
13823 listOK="$listOK $N"
13824 else
13825 $PRINTF "$FAILED\n"
13826 echo "$CMD0"
13827 cat "${te}0"
13828 numFAIL=$((numFAIL+1))
13829 listFAIL="$listFAIL $N"
13831 fi # NUMCOND
13833 esac
13834 N=$((N+1))
13837 # Currently (2020) SCTP has not found its way into main distributions
13838 # /etc/services file. A fallback mechanism has been implemented in Socat
13839 # that allows use of TCP service names when service resolution for SCTP failed.
13840 # Furthermore, older getaddrinfo() implementations to not handle SCTP as SOCK_STREAM
13841 # at all, fall back to unspecified socktype then.
13842 NAME=SCTP_SERVICENAME
13843 case "$TESTS" in
13844 *%$N%*|*%functions%*|*%socket%*|*%sctp%*|*%$NAME%*)
13845 TEST="$NAME: Service name resolution works with SCTP"
13846 # invoke socat with address SCTP4-CONNECT:$LOCALHOST:http; when this fails with
13847 # "Connection refused", or does not fail at all, the test succeeded
13848 if ! eval $NUMCOND; then :;
13849 elif ! runssctp4 >/dev/null; then
13850 $PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
13851 numCANT=$((numCANT+1))
13852 listCANT="$listCANT $N"
13853 else
13854 tf="$td/test$N.stdout"
13855 te="$td/test$N.stderr"
13856 tdiff="$td/test$N.diff"
13857 CMD0="$TRACE $SOCAT $opts -u /dev/null SCTP4-CONNECT:$LOCALHOST:http"
13858 printf "test $F_n $TEST... " $N
13859 $CMD0 >/dev/null 2>"${te}0"
13860 if [ $? -eq 0 ]; then
13861 $PRINTF "$OK\n"
13862 numOK=$((numOK+1))
13863 listOK="$listOK $N"
13864 elif grep -q "Connection refused" ${te}0; then
13865 $PRINTF "$OK\n"
13866 numOK=$((numOK+1))
13867 listOK="$listOK $N"
13868 else
13869 $PRINTF "$FAILED\n"
13870 echo "$CMD0"
13871 cat "${te}0"
13872 numFAIL=$((numFAIL+1))
13873 listFAIL="$listFAIL $N"
13875 fi # NUMCOND
13877 esac
13878 N=$((N+1))
13881 # Test the o-direct option on reading
13882 NAME=O_DIRECT
13883 case "$TESTS" in
13884 *%$N%*|*%functions%*|*%engine%*|*%file%*|*%$NAME%*)
13885 TEST="$NAME: echo via file with o-direct"
13886 # Write data to a file and read it with options o-direct (and ignoreeof)
13887 # When the data read is the same as the data written the test succeeded.
13888 if ! eval $NUMCOND; then :;
13889 elif ! testoptions o-direct >/dev/null; then
13890 $PRINTF "test $F_n $TEST... ${YELLOW}o-direct not available${NORMAL}\n" $N
13891 numCANT=$((numCANT+1))
13892 listCANT="$listCANT $N"
13893 else
13894 tf="$td/test$N.file"
13895 to="$td/test$N.stdout"
13896 te="$td/test$N.stderr"
13897 tdiff="$td/test$N.diff"
13898 da="test$N $(date) $RANDOM"
13899 $PRINTF "test $F_n $TEST... " $N
13900 CMD="$TRACE $SOCAT $opts - $tf,o-direct,ignoreeof!!$tf"
13901 echo "$da" |$CMD >"$to" 2>"$te"
13902 rc=$?
13903 if [ $rc -ne 0 ] && grep -q "Invalid argument" "$te" && [ $UNAME = Linux ]; then
13904 case $(stat -f $tf |grep "Type: [^[:space:]]*" |sed -e 's/.*\(Type: [^[:space:]]*\).*/\1/' |cut -c 7-) in
13905 #case $(stat -f $tf |grep -o "Type: [^[:space:]]*" |cut -c 7-) in
13906 ext2/ext3|xfs|reiserfs)
13907 $PRINTF "${FAILED}\n"
13908 echo "$CMD" >&2
13909 cat "$te" >&2
13910 numFAIL=$((numFAIL+1))
13911 listFAIL="$listFAIL $N" ;;
13912 *) $PRINTF "${YELLOW}inable file system${NORMAL}\n"
13913 numCANT=$((numCANT+1))
13914 listCANT="$listCANT $N" ;;
13915 esac
13916 elif [ $rc -ne 0 ]; then
13917 $PRINTF "${FAILED}:\n"
13918 echo "$CMD" >&2
13919 cat "$te" >&2
13920 numFAIL=$((numFAIL+1))
13921 listFAIL="$listFAIL $N"
13922 elif ! echo "$da" |diff - "$to" >$tdiff; then
13923 $PRINTF "${FAILED}\n"
13924 echo "$CMD" >&2
13925 cat "$te" >&2
13926 cat "$tdiff" >&2
13927 numFAIL=$((numFAIL+1))
13928 listFAIL="$listFAIL $N"
13929 else
13930 $PRINTF "$OK\n"
13931 numOK=$((numOK+1))
13932 listOK="$listOK $N"
13933 fi # command ok
13934 fi ;; # NUMCOND, feats
13935 esac
13936 N=$((N+1))
13939 # test if option unlink-close removes the bind socket file
13940 NAME=UNIX_SENDTO_UNLINK
13941 case "$TESTS" in
13942 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%$NAME%*)
13943 TEST="$NAME: Option unlink-close with UNIX sendto socket"
13944 # Have a recv socket with option unlink-close=0
13945 # and a sendto socket with option unlink-close=1
13946 # Expected beavior: the recv socket is kept, the
13947 # sendto/bind socket is removed
13948 if ! eval $NUMCOND; then :; else
13949 tf="$td/test$N.stdout"
13950 te="$td/test$N.stderr"
13951 uns="$td/test$N.server"
13952 unc="$td/test$N.client"
13953 tdiff="$td/test$N.diff"
13954 da="test$N $(date) $RANDOM"
13955 CMD0="$TRACE $SOCAT $opts -u UNIX-RECV:$uns,unlink-close=0 GOPEN:$tf"
13956 CMD1="$TRACE $SOCAT $opts - UNIX-SENDTO:$uns,bind=$unc,unlink-close=1"
13957 printf "test $F_n $TEST... " $N
13958 $CMD0 >/dev/null 2>"${te}0" &
13959 pid0=$!
13960 waitunixport $uns 1
13961 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
13962 rc1=$?
13963 kill $pid0 2>/dev/null; wait
13964 if test -S $uns && ! test -S $unc; then
13965 $PRINTF "$OK\n"
13966 numOK=$((numOK+1))
13967 listOK="$listOK $N"
13968 else
13969 $PRINTF "$FAILED\n"
13970 echo "$CMD0 &"
13971 echo "$CMD1"
13972 ls -ld $uns $unc
13973 cat "${te}0"
13974 cat "${te}1"
13975 numFAIL=$((numFAIL+1))
13976 listFAIL="$listFAIL $N"
13978 fi # NUMCOND
13980 esac
13981 N=$((N+1))
13983 # test if option unlink-close removes the bind socket file
13984 NAME=UNIX_CONNECT_UNLINK
13985 case "$TESTS" in
13986 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%listen%*|*%$NAME%*)
13987 TEST="$NAME: Option unlink-close with UNIX connect socket"
13988 # Have a listen socket with option unlink-close=0
13989 # and a connect socket with option unlink-close=1
13990 # Expected beavior: the listen socket entry is kept, the
13991 # connect/bind socket is removed
13992 if ! eval $NUMCOND; then :; else
13993 tf="$td/test$N.stdout"
13994 te="$td/test$N.stderr"
13995 uns="$td/test$N.server"
13996 unc="$td/test$N.client"
13997 tdiff="$td/test$N.diff"
13998 da="test$N $(date) $RANDOM"
13999 CMD0="$TRACE $SOCAT $opts -u UNIX-LISTEN:$uns,unlink-close=0 GOPEN:$tf"
14000 CMD1="$TRACE $SOCAT $opts - UNIX-CONNECT:$uns,bind=$unc,unlink-close=1"
14001 printf "test $F_n $TEST... " $N
14002 $CMD0 >/dev/null 2>"${te}0" &
14003 pid0=$!
14004 waitunixport $uns 1
14005 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14006 rc1=$?
14007 kill $pid0 2>/dev/null; wait
14008 if test -S $uns && ! test -S $unc; then
14009 $PRINTF "$OK\n"
14010 numOK=$((numOK+1))
14011 listOK="$listOK $N"
14012 else
14013 $PRINTF "$FAILED\n"
14014 echo "$CMD0 &"
14015 echo "$CMD1"
14016 ls -ld $uns $unc
14017 cat "${te}0"
14018 cat "${te}1"
14019 numFAIL=$((numFAIL+1))
14020 listFAIL="$listFAIL $N"
14022 fi # NUMCOND
14024 esac
14025 N=$((N+1))
14028 # test the DTLS client feature
14029 NAME=OPENSSL_DTLS_CLIENT
14030 case "$TESTS" in
14031 *%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%$NAME%*)
14032 TEST="$NAME: OpenSSL DTLS client"
14033 # Run openssl s_server in DTLS mode, wrapped into a simple Socat echoing command.
14034 # Start a Socat DTLS client, send data to server and check if reply is received.
14035 if ! eval $NUMCOND; then :;
14036 elif ! a=$(testfeats ip4 udp openssl); then
14037 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available${NORMAL}\n" $N
14038 numCANT=$((numCANT+1))
14039 listCANT="$listCANT $N"
14040 elif ! a=$(testaddrs openssl-dtls-client); then
14041 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
14042 numCANT=$((numCANT+1))
14043 listCANT="$listCANT $N"
14044 elif ! runsip4 >/dev/null; then
14045 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14046 numCANT=$((numCANT+1))
14047 listCANT="$listCANT $N"
14048 elif ! type openssl >/dev/null 2>&1; then
14049 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
14050 numCANT=$((numCANT+1))
14051 listCANT="$listCANT $N"
14052 else
14053 gentestcert testsrv
14054 tf="$td/test$N.stdout"
14055 te="$td/test$N.stderr"
14056 tdiff="$td/test$N.diff"
14057 #set -vx
14058 da="test$N $(date) $RANDOM"
14059 init_openssl_s_server
14060 newport udp4
14061 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"
14062 CMD="$TRACE $SOCAT $opts -T $(reltime 3) - OPENSSL-DTLS-CLIENT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD,so-rcvtimeo=2"
14063 printf "test $F_n $TEST... " $N
14064 ( relsleep 2; echo "$da"; relsleep 1 ) |$CMD1 2>"${te}1" &
14065 pid1=$! # background process id
14066 waitudp4port $PORT
14067 $CMD >$tf 2>"$te"
14068 kill $pid1 2>/dev/null; wait 2>/dev/null
14069 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
14070 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
14071 echo "$CMD1 &"
14072 cat "${te}1"
14073 echo "$CMD"
14074 cat "$te"
14075 cat "$tdiff"
14076 numFAIL=$((numFAIL+1))
14077 listFAIL="$listFAIL $N"
14078 else
14079 $PRINTF "$OK\n"
14080 if [ -n "$debug" ]; then cat "${te}1" "$te"; fi
14081 numOK=$((numOK+1))
14082 listOK="$listOK $N"
14084 fi ;; # NUMCOND, feats
14085 esac
14086 N=$((N+1))
14088 # test the DTLS server feature
14089 NAME=OPENSSL_DTLS_SERVER
14090 case "$TESTS" in
14091 *%$N%*|*%functions%*|*%openssl%*|*%dtls%*|*%udp%*|*%udp4%*|*%ip4%*|*%socket%*|*%$NAME%*)
14092 TEST="$NAME: OpenSSL DTLS server"
14093 # Run a socat OpenSSL DTLS server with echo function
14094 # Start an OpenSSL s_client, send data and check if repley is received.
14095 if ! eval $NUMCOND; then :;
14096 elif ! a=$(testfeats ip4 udp openssl) >/dev/null; then
14097 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14098 numCANT=$((numCANT+1))
14099 listCANT="$listCANT $N"
14100 elif ! a=$(testaddrs openssl-dtls-server); then
14101 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14102 numCANT=$((numCANT+1))
14103 listCANT="$listCANT $N"
14104 elif ! runsip4 >/dev/null; then
14105 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14106 numCANT=$((numCANT+1))
14107 listCANT="$listCANT $N"
14108 elif ! type openssl >/dev/null 2>&1; then
14109 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not found${NORMAL}\n" $N
14110 numCANT=$((numCANT+1))
14111 listCANT="$listCANT $N"
14112 elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then
14113 # also on NetBSD-4 with openssl-0.9.8e
14114 $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
14115 numCANT=$((numCANT+1))
14116 listCANT="$listCANT $N"
14117 else
14118 gentestcert testsrv
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 init_openssl_s_client
14124 newport udp4
14125 CMD1="$TRACE $SOCAT $opts OPENSSL-DTLS-SERVER:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
14126 CMD="openssl s_client $OPENSSL_S_CLIENT_4 -host $LOCALHOST -port $PORT $OPENSSL_S_CLIENT_DTLS"
14127 printf "test $F_n $TEST... " $N
14128 $CMD1 >/dev/null 2>"${te}1" &
14129 pid1=$!
14130 waitudp4port $PORT 1
14131 ( echo "$da"; sleep 0.1 ) |$CMD 2>"$te" |grep "$da" >"$tf"
14132 rc=$?
14133 kill $pid1 2>/dev/null; wait
14134 if echo "$da" |diff - $tf >"$tdiff"; then
14135 $PRINTF "$OK\n"
14136 numOK=$((numOK+1))
14137 listOK="$listOK $N"
14138 else
14139 $PRINTF "$FAILED\n"
14140 echo "$CMD1 &"
14141 cat "${te}1"
14142 echo "$CMD"
14143 cat "$te"
14144 cat "$tdiff"
14145 numFAIL=$((numFAIL+1))
14146 listFAIL="$listFAIL $N"
14148 fi # NUMCOND
14150 esac
14151 N=$((N+1))
14154 NAME=OPENSSL_SERVERALTAUTH
14155 case "$TESTS" in
14156 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
14157 TEST="$NAME: OpenSSL server authentication with SubjectAltName (hostname)"
14158 if ! eval $NUMCOND; then :;
14159 elif ! testfeats openssl >/dev/null; then
14160 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14161 numCANT=$((numCANT+1))
14162 listCANT="$listCANT $N"
14163 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
14164 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
14165 numCANT=$((numCANT+1))
14166 listCANT="$listCANT $N"
14167 else
14168 gentestaltcert testalt
14169 tf="$td/test$N.stdout"
14170 te="$td/test$N.stderr"
14171 tdiff="$td/test$N.diff"
14172 da="test$N $(date) $RANDOM"
14173 newport tcp4
14174 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe"
14175 CMD1="$TRACE $SOCAT $opts - OPENSSL:$LOCALHOST:$PORT,pf=ip4,verify=1,cafile=testalt.crt,$SOCAT_EGD"
14176 printf "test $F_n $TEST... " $N
14177 eval "$CMD0 2>\"${te}0\" &"
14178 pid=$! # background process id
14179 waittcp4port $PORT
14180 echo "$da" |$CMD1 >$tf 2>"${te}1"
14181 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
14182 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
14183 echo "$CMD0 &" >&2
14184 cat "${te}0" >&2
14185 echo "$CMD1" >&2
14186 cat "${te}1" >&2
14187 cat "$tdiff" >&2
14188 numFAIL=$((numFAIL+1))
14189 listFAIL="$listFAIL $N"
14190 else
14191 $PRINTF "$OK\n"
14192 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
14193 numOK=$((numOK+1))
14194 listOK="$listOK $N"
14196 kill $pid 2>/dev/null
14197 wait
14198 fi ;; # NUMCOND, feats
14199 esac
14200 N=$((N+1))
14202 NAME=OPENSSL_SERVERALTIP4AUTH
14203 case "$TESTS" in
14204 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
14205 TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv4 address)"
14206 if ! eval $NUMCOND; then :;
14207 elif ! testfeats openssl >/dev/null; then
14208 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14209 numCANT=$((numCANT+1))
14210 listCANT="$listCANT $N"
14211 elif ! testfeats listen tcp ip4 openssl >/dev/null || ! runsip4 >/dev/null; then
14212 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
14213 numCANT=$((numCANT+1))
14214 listCANT="$listCANT $N"
14215 else
14216 gentestaltcert testalt
14217 tf="$td/test$N.stdout"
14218 te="$td/test$N.stderr"
14219 tdiff="$td/test$N.diff"
14220 da="test$N $(date) $RANDOM"
14221 newport tcp4
14222 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,$REUSEADDR,pf=ip4,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe"
14223 CMD1="$TRACE $SOCAT $opts - OPENSSL:127.0.0.1:$PORT,verify=1,cafile=testalt.crt,$SOCAT_EGD"
14224 printf "test $F_n $TEST... " $N
14225 eval "$CMD0 2>\"${te}0\" &"
14226 pid=$! # background process id
14227 waittcp4port $PORT
14228 echo "$da" |$CMD1 >$tf 2>"${te}1"
14229 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
14230 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
14231 echo "$CMD0 &" >&2
14232 cat "${te}0" >&2
14233 echo "$CMD1" >&2
14234 cat "${te}1" >&2
14235 cat "$tdiff" >&2
14236 numFAIL=$((numFAIL+1))
14237 listFAIL="$listFAIL $N"
14238 else
14239 $PRINTF "$OK\n"
14240 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
14241 numOK=$((numOK+1))
14242 listOK="$listOK $N"
14244 kill $pid 2>/dev/null
14245 wait
14246 fi ;; # NUMCOND, feats
14247 esac
14248 N=$((N+1))
14250 NAME=OPENSSL_SERVERALTIP6AUTH
14251 case "$TESTS" in
14252 *%$N%*|*%functions%*|*%openssl%*|*%tcp%*|*%tcp6%*|*%ip6%*|*%listen%*|*%$NAME%*)
14253 TEST="$NAME: OpenSSL server authentication with SubjectAltName (IPv6 address)"
14254 if ! eval $NUMCOND; then :;
14255 elif ! testfeats openssl >/dev/null; then
14256 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14257 numCANT=$((numCANT+1))
14258 listCANT="$listCANT $N"
14259 elif ! testfeats listen tcp ip6 openssl >/dev/null || ! runsip6 >/dev/null; then
14260 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv6 not available${NORMAL}\n" $N
14261 numCANT=$((numCANT+1))
14262 listCANT="$listCANT $N"
14263 else
14264 gentestaltcert testalt
14265 tf="$td/test$N.stdout"
14266 te="$td/test$N.stderr"
14267 tdiff="$td/test$N.diff"
14268 da="test$N $(date) $RANDOM"
14269 newport tcp6
14270 CMD0="$TRACE $SOCAT $opts OPENSSL-LISTEN:$PORT,pf=ip6,$REUSEADDR,$SOCAT_EGD,cert=testalt.crt,key=testalt.key,verify=0 pipe"
14271 CMD1="$TRACE $SOCAT $opts - OPENSSL:[::1]:$PORT,verify=1,cafile=testalt.crt,$SOCAT_EGD"
14272 printf "test $F_n $TEST... " $N
14273 eval "$CMD0 2>\"${te}0\" &"
14274 pid=$! # background process id
14275 waittcp6port $PORT
14276 echo "$da" |$CMD1 >$tf 2>"${te}1"
14277 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
14278 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
14279 echo "$CMD0 &" >&2
14280 cat "${te}0" >&2
14281 echo "$CMD1" >&2
14282 cat "${te}1" >&2
14283 cat "$tdiff" >&2
14284 numFAIL=$((numFAIL+1))
14285 listFAIL="$listFAIL $N"
14286 else
14287 $PRINTF "$OK\n"
14288 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
14289 numOK=$((numOK+1))
14290 listOK="$listOK $N"
14292 kill $pid 2>/dev/null
14293 wait
14294 fi ;; # NUMCOND, feats
14295 esac
14296 N=$((N+1))
14299 # Test the -r and -R options
14300 NAME=OPTION_RAW_DUMP
14301 case "$TESTS" in
14302 *%$N%*|*%functions%*|*%option%*|*%$NAME%*)
14303 TEST="$NAME: raw dump of transferred data"
14304 # Start Socat transferring data from left named pipe to right and from right
14305 # pipe to left, use options -r and -R, and check if dump files contain correct
14306 # data
14307 if ! eval $NUMCOND; then :;
14308 elif [ $($SOCAT -h |grep -e ' -[rR] ' |wc -l) -lt 2 ]; then
14309 $PRINTF "test $F_n $TEST... ${YELLOW}Options -r, -R not available${NORMAL}\n" $N
14310 numCANT=$((numCANT+1))
14311 listCANT="$listCANT $N"
14312 else
14313 tf="$td/test$N.stdout"
14314 te="$td/test$N.stderr"
14315 tp1="$td/test$N.pipe1"
14316 tp2="$td/test$N.pipe2"
14317 tr1="$td/test$N.raw1"
14318 tr2="$td/test$N.raw2"
14319 tdiff1="$td/test$N.diff1"
14320 tdiff2="$td/test$N.diff2"
14321 da1="test$N $(date) $RANDOM"
14322 da2="test$N $(date) $RANDOM"
14323 CMD0="$TRACE $SOCAT $opts -r $tr1 -R $tr2 PIPE:$tp1!!/dev/null PIPE:$tp2!!/dev/null"
14324 printf "test $F_n $TEST... " $N
14325 $CMD0 >/dev/null 2>"${te}0" &
14326 pid0=$!
14327 waitfile $tp1 1
14328 echo "$da1" >$tp1
14329 waitfile $tp2 1
14330 echo "$da2" >$tp2
14331 sleep 1
14332 kill $pid0 2>/dev/null; wait
14333 if ! echo "$da1" |diff - $tr1 >$tdiff1 || ! echo "$da2" |diff - $tr2 >$tdiff2; then
14334 $PRINTF "$FAILED\n"
14335 echo "$CMD0 &" >&2
14336 cat "${te}0" >&2
14337 echo "Left-to-right:" >&2
14338 cat $tdiff1 >&2
14339 echo "Right-to-left:" >&2
14340 cat $tdiff2 >&2
14341 numFAIL=$((numFAIL+1))
14342 listFAIL="$listFAIL $N"
14343 else
14344 $PRINTF "$OK\n"
14345 numOK=$((numOK+1))
14346 listOK="$listOK $N"
14348 fi # NUMCOND
14350 esac
14351 N=$((N+1))
14354 # Test the OpenSSL SNI feature
14355 NAME=OPENSSL_SNI
14356 case "$TESTS" in
14357 *%$N%*|*%functions%*|*%socket%*|*%openssl%*|*%internet%*|*%listen%*|*%$NAME%*)
14358 TEST="$NAME: Test the OpenSSL SNI feature"
14359 # Connect to a server that is known to use SNI. Use an SNI name, not the
14360 # certifications default name. When the TLS connection is established
14361 # the test succeeded.
14362 SNISERVER=badssl.com
14363 if ! eval $NUMCOND; then :;
14364 elif ! testaddrs openssl >/dev/null; then
14365 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14366 numCANT=$((numCANT+1))
14367 listCANT="$listCANT $N"
14368 elif ! feat=$(testoptions openssl-snihost); then
14369 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
14370 numCANT=$((numCANT+1))
14371 listCANT="$listCANT $N"
14372 elif [ -z "$INTERNET" ]; then
14373 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
14374 numCANT=$((numCANT+1))
14375 listCANT="$listCANT $N"
14376 else
14377 tf="$td/test$N.stdout"
14378 te="$td/test$N.stderr"
14379 tdiff="$td/test$N.diff"
14380 da="test$N $(date) $RANDOM"
14381 CMD0="$TRACE $SOCAT $opts FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,pf=ip4"
14382 printf "test $F_n $TEST... " $N
14383 $CMD0 >/dev/null 2>"${te}0"
14384 rc0=$?
14385 if [ $rc0 -eq 0 ]; then
14386 $PRINTF "$OK\n"
14387 numOK=$((numOK+1))
14388 listOK="$listOK $N"
14389 else
14390 $PRINTF "$FAILED\n"
14391 echo "$CMD0" >&2
14392 cat "${te}0" >&2
14393 numFAIL=$((numFAIL+1))
14394 listFAIL="$listFAIL $N"
14396 fi # NUMCOND
14398 esac
14399 N=$((N+1))
14402 # Test the openssl-no-sni option
14403 NAME=OPENSSL_NO_SNI
14404 case "$TESTS" in
14405 *%$N%*|*%functions%*|*%socket%*|*%openssl%*|*%internet%*|*%listen%*|*%$NAME%*)
14406 TEST="$NAME: Test the openssl-no-sni option"
14407 # Connect to a server that is known to use SNI. Use an SNI name, not the
14408 # certifications default name, and use option openssl-no-sni.
14409 # When the TLS connection failed the test succeeded.
14410 # Please note that this test is only relevant when test OPENSSL_SNI succeeded.
14411 SNISERVER=badssl.com
14412 if ! eval $NUMCOND; then :;
14413 elif ! testaddrs openssl >/dev/null; then
14414 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
14415 numCANT=$((numCANT+1))
14416 listCANT="$listCANT $N"
14417 elif ! feat=$(testoptions openssl-no-sni); then
14418 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
14419 numCANT=$((numCANT+1))
14420 listCANT="$listCANT $N"
14421 elif [ -z "$INTERNET" ]; then
14422 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
14423 numCANT=$((numCANT+1))
14424 listCANT="$listCANT $N"
14425 else
14426 tf="$td/test$N.stdout"
14427 te="$td/test$N.stderr"
14428 tdiff="$td/test$N.diff"
14429 da="test$N $(date) $RANDOM"
14430 CMD0="$TRACE $SOCAT $opts FILE:/dev/null OPENSSL-CONNECT:$SNISERVER:443,openssl-no-sni"
14431 printf "test $F_n $TEST... " $N
14432 $CMD0 >/dev/null 2>"${te}0"
14433 rc0=$?
14434 if [ $rc0 -ne 0 ]; then
14435 $PRINTF "$OK\n"
14436 numOK=$((numOK+1))
14437 listOK="$listOK $N"
14438 else
14439 $PRINTF "$FAILED\n"
14440 echo "$CMD0" >&2
14441 cat "${te}0" >&2
14442 numFAIL=$((numFAIL+1))
14443 listFAIL="$listFAIL $N"
14445 fi # NUMCOND
14447 esac
14448 N=$((N+1))
14451 # Test the accept-timeout (listen-timeout) address option
14452 NAME=ACCEPTTIMEOUT
14453 case "$TESTS" in
14454 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%listen%*|*%timeout%*|*%$NAME%*)
14455 TEST="$NAME: test the accept-timeout option"
14456 if ! eval $NUMCOND; then :;
14457 elif ! feat=$(testaddrs tcp); then
14458 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
14459 numCANT=$((numCANT+1))
14460 listCANT="$listCANT $N"
14461 elif ! feat=$(testoptions accept-timeout); then
14462 $PRINTF "test $F_n $TEST... ${YELLOW}$(echo "$feat"| tr 'a-z' 'A-Z') not available${NORMAL}\n" $N
14463 numCANT=$((numCANT+1))
14464 listCANT="$listCANT $N"
14465 else
14466 # Just start a process with accept-timeout 1s and check if it still runs 2s later
14467 # but before this, we test if the process waits at all
14468 te1="$td/test$N.stderr1"
14469 tk1="$td/test$N.kill1"
14470 te2="$td/test$N.stderr2"
14471 tk2="$td/test$N.kill2"
14472 $PRINTF "test $F_n $TEST... " $N
14473 # First, try to make socat hang and see if it can be killed
14474 newport tcp4
14475 CMD1="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr PIPE"
14476 $CMD1 >"$te1" 2>&1 </dev/null &
14477 pid1=$!
14478 relsleep 1
14479 if ! kill $pid1 2>"$tk1"; then
14480 $PRINTF "${YELLOW}does not hang${NORMAL}\n"
14481 echo $CMD1 >&2
14482 cat "$te1" >&2
14483 cat "$tk1" >&2
14484 numCANT=$((numCANT+1))
14485 listCANT="$listCANT $N"
14486 else
14487 # Second, set accept-timeout and see if socat exits before kill
14488 CMD2="$TRACE $SOCAT $opts TCP-LISTEN:$PORT,reuseaddr,accept-timeout=$(reltime 1) PIPE"
14489 $CMD2 >"$te2" 2>&1 </dev/null &
14490 pid2=$!
14491 relsleep 2
14492 if kill $pid2 2>"$tk2"; then
14493 $PRINTF "$FAILED\n"
14494 echo "$CMD2" >&2
14495 cat "$te2" >&2
14496 cat "$tk2" >&2
14497 numFAIL=$((numFAIL+1))
14498 listFAIL="$listFAIL $N"
14499 else
14500 $PRINTF "$OK\n"
14501 numOK=$((numOK+1))
14502 listOK="$listOK $N"
14505 wait
14506 fi ;; # testaddrs, NUMCOND
14507 esac
14508 N=$((N+1))
14511 # Test the modified UDP-DATAGRAM address: Now it ignores peerport by default
14512 NAME=UDP_DATAGRAM_PEERPORT
14513 case "$TESTS" in
14514 *%$N%*|*%functions%*|*%udp%*|*%socket%*|*%$NAME%*)
14515 TEST="$NAME: test UDP-DATAGRAM ignoring peerport"
14516 # A UDP-DATAGRAM address bound to PORT has defined peer on PORT+1
14517 # From another Socat instance we send a packet to PORT but with source port
14518 # PORT+2. The first instance should accept the packet
14519 if ! eval $NUMCOND; then :
14520 elif [ $(echo $E "$SOCAT_VERSION\n1.7.3.4" |sort -n |tail -n 1) = 1.7.3.4 ]; then
14521 $PRINTF "test $F_n $TEST... ${YELLOW}Only with Socat 1.7.4.0 or higher${NORMAL}\n" $N
14522 numCANT=$((numCANT+1))
14523 listCANT="$listCANT $N"
14524 else
14525 tf="$td/test$N.stdout"
14526 te="$td/test$N.stderr"
14527 tdiff="$td/test$N.diff"
14528 da="test$N $(date) $RANDOM"
14529 newport udp4; PORT1=$PORT
14530 newport udp4; PORT2=$PORT
14531 newport udp4; PORT3=$PORT
14532 CMD0="$TRACE $SOCAT $opts -u UDP-DATAGRAM:$LOCALHOST:$PORT2,bind=:$PORT1 -"
14533 CMD1="$TRACE $SOCAT $opts -u - UDP-DATAGRAM:$LOCALHOST:$PORT1,bind=:$PORT3"
14534 printf "test $F_n $TEST... " $N
14535 $CMD0 >${tf}0 2>"${te}0" &
14536 pid0=$!
14537 waitudp4port $PORT1 1
14538 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14539 rc1=$?
14540 sleep 0.1
14541 kill $pid0 2>/dev/null; wait
14542 if [ -f ${tf}0 ] && echo "$da" |diff - ${tf}0 >$tdiff; then
14543 $PRINTF "$OK\n"
14544 numOK=$((numOK+1))
14545 listOK="$listOK $N"
14546 else
14547 $PRINTF "$FAILED\n"
14548 echo "$CMD0 &" >&2
14549 cat "${te}0" >&2
14550 echo "$CMD1" >&2
14551 cat "${te}1" >&2
14552 cat "${tdiff}" >&2
14553 numFAIL=$((numFAIL+1))
14554 listFAIL="$listFAIL $N"
14556 fi # NUMCOND
14558 esac
14559 N=$((N+1))
14562 # Test the proxy-authorization-file option
14563 NAME=PROXYAUTHFILE
14564 case "$TESTS" in
14565 *%$N%*|*%functions%*|*%proxyconnect%*|*%proxy%*|*%tcp%*|*%tcp4%*|*%ip4%*|*%listen%*|*%$NAME%*)
14566 TEST="$NAME: proxy-authorization-file option"
14567 if ! eval $NUMCOND; then :;
14568 elif ! testfeats proxy >/dev/null; then
14569 $PRINTF "test $F_n $TEST... ${YELLOW}PROXY not available${NORMAL}\n" $N
14570 numCANT=$((numCANT+1))
14571 listCANT="$listCANT $N"
14572 elif ! testfeats listen tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
14573 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
14574 numCANT=$((numCANT+1))
14575 listCANT="$listCANT $N"
14576 elif ! testoptions proxy-authorization-file >/dev/null; then
14577 $PRINTF "test $F_n $TEST... ${YELLOW}Option proxy-authorization-file not available${NORMAL}\n" $N
14578 numCANT=$((numCANT+1))
14579 listCANT="$listCANT $N"
14580 else
14581 ta="$td/test$N.auth"
14582 tf="$td/test$N.stdout"
14583 te="$td/test$N.stderr"
14584 tdiff="$td/test$N.diff"
14585 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
14586 newport tcp4
14587 CMD0="{ echo -e \"HTTP/1.0 200 OK\\n\"; sleep 2; } |$TRACE $SOCAT $opts - TCP4-L:$PORT,$REUSEADDR,crlf"
14588 CMD1="$TRACE $SOCAT $opts FILE:/dev/null PROXY-CONNECT:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT,proxy-authorization-file=$ta"
14589 printf "test $F_n $TEST... " $N
14590 echo "user:s3cr3t" >$ta
14591 eval "$CMD0 >${tf}0 2>${te}0 &"
14592 pid0=$! # background process id
14593 waittcp4port $PORT 1
14594 $CMD1 >"${tf}1" 2>"${te}1"
14595 rc1=$?
14596 kill $pid0 2>/dev/null
14597 wait $pid0
14598 if [ $rc1 -ne 0 ]; then
14599 $PRINTF "$FAILED\n"
14600 echo "$CMD0 &" >&2
14601 cat "${te}0" >&2
14602 echo "$CMD1" >&2
14603 cat "${te}1" >&2
14604 cat "${tf}0" >&2
14605 numFAIL=$((numFAIL+1))
14606 listFAIL="$listFAIL $N"
14607 elif ! grep -q '^Proxy-authorization: Basic dXNlcjpzM2NyM3QK$' ${tf}0; then
14608 $PRINTF "$FAILED:\n"
14609 echo "$CMD0 &" >&2
14610 cat "${te}0" >&2
14611 echo "$CMD1" >&2
14612 cat "${te}1" >&2
14613 cat "${tf}0" >&2
14614 echo "Authorization string not in client request" >&2
14615 numFAIL=$((numFAIL+1))
14616 listFAIL="$listFAIL $N"
14617 else
14618 $PRINTF "$OK\n"
14619 if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
14620 numOK=$((numOK+1))
14621 listOK="$listOK $N"
14623 kill $pid 2>/dev/null
14624 wait
14625 fi ;; # NUMCOND, feats
14626 esac
14627 N=$((N+1))
14630 # Test communication via vsock loopback socket
14631 NAME=VSOCK_ECHO
14632 case "$TESTS" in
14633 *%$N%*|*%functions%*|*%vsock%*|*%socket%*|*%listen%*|*%$NAME%*)
14634 TEST="$NAME: test communication via VSOCK loopback socket"
14635 # Start a listening echo server
14636 # Connect with a client, send data and compare reply with original data
14637 if ! eval $NUMCOND; then :;
14638 elif ! fea=$(testfeats VSOCK); then
14639 $PRINTF "test $F_n $TEST... ${YELLOW}$fea not available${NORMAL}\n" $N
14640 numCANT=$((numCANT+1))
14641 listCANT="$listCANT $N"
14642 else
14643 tf="$td/test$N.stdout"
14644 te="$td/test$N.stderr"
14645 tdiff="$td/test$N.diff"
14646 da="test$N $(date) $RANDOM"
14647 #newport vsock # nope
14648 CMD0="$TRACE $SOCAT $opts VSOCK-LISTEN:$PORT PIPE"
14649 CMD1="$TRACE $SOCAT $opts - VSOCK-CONNECT:1:$PORT"
14650 printf "test $F_n $TEST... " $N
14651 $CMD0 >/dev/null 2>"${te}0" &
14652 pid0=$!
14653 sleep 1
14654 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
14655 rc1=$?
14656 kill $pid0 2>/dev/null; wait
14657 if [ $rc1 -ne 0 ] && [ "$UNAME" != Linux ]; then
14658 $PRINTF "${YELLOW}works only on Linux?${NORMAL}\n" $N
14659 numCANT=$((numCANT+1))
14660 listCANT="$listCANT $N"
14661 elif [ $rc1 -ne 0 ] && [ "$UNAME" = Linux ] && ! [[ $UNAME_R =~ ^[6-9]\.* ]] && ! [[ $UNAME_R =~ ^5\.[6-]\.* ]] && ! [[ $UNAME_R =~ ^5\.[1-9][0-9].* ]]; then
14662 $PRINTF "${YELLOW}works only on Linux from 5.6${NORMAL}\n" $N
14663 numCANT=$((numCANT+1))
14664 listCANT="$listCANT $N"
14665 elif grep -q "No such device" "${te}1"; then
14666 $PRINTF "${YELLOW}Loopback does not work${NORMAL}\n" $N
14667 numCANT=$((numCANT+1))
14668 listCANT="$listCANT $N"
14669 elif [ $rc1 -ne 0 ]; then
14670 $PRINTF "$FAILED\n"
14671 echo "$CMD0 &" >&2
14672 cat "${te}0" >&2
14673 echo "$CMD1" >&2
14674 cat "${te}1" >&2
14675 numFAIL=$((numFAIL+1))
14676 listFAIL="$listFAIL $N"
14677 elif echo "$da" |diff - ${tf}1 >${tdiff}$N; then
14678 $PRINTF "$OK\n"
14679 numOK=$((numOK+1))
14680 listOK="$listOK $N"
14681 else
14682 $PRINTF "$FAILED\n"
14683 echo "$CMD0 &" >&2
14684 cat "${te}0" >&2
14685 echo "$CMD1" >&2
14686 cat "${te}1" >&2
14687 numFAIL=$((numFAIL+1))
14688 listFAIL="$listFAIL $N"
14690 fi # NUMCOND
14692 esac
14693 N=$((N+1))
14696 # File transfer with OpenSSL stream connection was incomplete
14697 # Test file transfer from client to server
14698 NAME=OPENSSL_STREAM_TO_SERVER
14699 case "$TESTS" in
14700 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
14701 TEST="$NAME: OpenSSL stream from client to server"
14702 # Start a unidirectional OpenSSL server and stream receiver
14703 # Start a unidirectional OpenSSL client that connects to the server and sends
14704 # data
14705 # Test succeeded when the data received and stored by server is the same as
14706 # sent by the client
14707 if ! eval $NUMCOND; then :;
14708 elif ! a=$(testfeats ip4 tcp openssl); then
14709 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14710 numCANT=$((numCANT+1))
14711 listCANT="$listCANT $N"
14712 elif ! a=$(testaddrs openssl-listen openssl-connect); then
14713 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14714 numCANT=$((numCANT+1))
14715 listCANT="$listCANT $N"
14716 elif ! runsip4 >/dev/null; then
14717 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14718 numCANT=$((numCANT+1))
14719 listCANT="$listCANT $N"
14720 else
14721 gentestcert testsrv
14722 ti="$td/test$N.datain"
14723 to="$td/test$N.dataout"
14724 te="$td/test$N.stderr"
14725 tdiff="$td/test$N.diff"
14726 da="test$N $(date) $RANDOM"
14727 newport tcp4
14728 CMD0="$TRACE $SOCAT $opts -u OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 CREAT:$to"
14729 CMD1="$TRACE $SOCAT $opts -u OPEN:$ti OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt"
14730 printf "test $F_n $TEST... " $N
14731 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
14732 $CMD0 >/dev/null 2>"${te}0" &
14733 pid0=$!
14734 waittcp4port $PORT 1
14735 $CMD1 >"${tf}1" 2>"${te}1"
14736 rc1=$?
14737 relsleep 1
14738 kill $pid0 2>/dev/null; wait
14739 if [ $rc1 -ne 0 ]; then
14740 $PRINTF "$FAILED\n"
14741 echo "$CMD0 &" >&2
14742 cat "${te}0" >&2
14743 echo "$CMD1" >&2
14744 cat "${te}1" >&2
14745 numFAIL=$((numFAIL+1))
14746 listFAIL="$listFAIL $N"
14747 elif diff $ti $to >$tdiff; then
14748 $PRINTF "$OK\n"
14749 numOK=$((numOK+1))
14750 listOK="$listOK $N"
14751 else
14752 $PRINTF "$FAILED\n"
14753 echo "$CMD0 &" >&2
14754 cat "${te}0" >&2
14755 echo "$CMD1" >&2
14756 cat "${te}1" >&2
14757 echo "diff:" >&2
14758 head -n 2 $tdiff >&2
14759 echo ... >&2
14760 numFAIL=$((numFAIL+1))
14761 listFAIL="$listFAIL $N"
14763 fi # NUMCOND
14765 esac
14766 N=$((N+1))
14768 # File transfer with OpenSSL stream connection was incomplete
14769 # Test file transfer from server to client
14770 NAME=OPENSSL_STREAM_TO_CLIENT
14771 case "$TESTS" in
14772 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
14773 TEST="$NAME: OpenSSL stream from server to client"
14774 # Start a unidirectional OpenSSL server and stream sender
14775 # Start a unidirectional OpenSSL client that connects to the server and receives
14776 # data
14777 # Test succeeded when the data received and stored by client is the same as
14778 # sent by the server
14779 if ! eval $NUMCOND; then :;
14780 elif ! a=$(testfeats ip4 tcp openssl); then
14781 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14782 numCANT=$((numCANT+1))
14783 listCANT="$listCANT $N"
14784 elif ! a=$(testaddrs openssl-listen openssl-connect); then
14785 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14786 numCANT=$((numCANT+1))
14787 listCANT="$listCANT $N"
14788 elif ! runsip4 >/dev/null; then
14789 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14790 numCANT=$((numCANT+1))
14791 listCANT="$listCANT $N"
14792 else
14793 gentestcert testsrv
14794 ti="$td/test$N.datain"
14795 to="$td/test$N.dataout"
14796 te="$td/test$N.stderr"
14797 tdiff="$td/test$N.diff"
14798 da="test$N $(date) $RANDOM"
14799 newport tcp4
14800 CMD0="$TRACE $SOCAT $opts -U OPENSSL-LISTEN:$PORT,pf=ip4,$REUSEADDR,cert=testsrv.pem,verify=0 OPEN:$ti"
14801 CMD1="$TRACE $SOCAT $opts -u OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt CREAT:$to"
14802 printf "test $F_n $TEST... " $N
14803 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
14804 $CMD0 >/dev/null 2>"${te}0" &
14805 pid0=$!
14806 waittcp4port $PORT 1
14807 $CMD1 >"${tf}1" 2>"${te}1"
14808 rc1=$?
14809 relsleep 1
14810 kill $pid0 2>/dev/null; wait
14811 if [ $rc1 -ne 0 ]; then
14812 $PRINTF "$FAILED\n"
14813 echo "$CMD0 &" >&2
14814 cat "${te}0" >&2
14815 echo "$CMD1" >&2
14816 cat "${te}1" >&2
14817 numFAIL=$((numFAIL+1))
14818 listFAIL="$listFAIL $N"
14819 elif diff $ti $to >$tdiff; then
14820 $PRINTF "$OK\n"
14821 numOK=$((numOK+1))
14822 listOK="$listOK $N"
14823 else
14824 $PRINTF "$FAILED\n"
14825 echo "$CMD0 &" >&2
14826 cat "${te}0" >&2
14827 echo "$CMD1" >&2
14828 cat "${te}1" >&2
14829 echo "diff:" >&2
14830 head -n 2 $tdiff >&2
14831 echo ... >&2
14832 numFAIL=$((numFAIL+1))
14833 listFAIL="$listFAIL $N"
14835 fi # NUMCOND
14837 esac
14838 N=$((N+1))
14840 # Test file transfer from client to server using DTLS
14841 NAME=OPENSSL_DTLS_TO_SERVER
14842 case "$TESTS" in
14843 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%dtls%*|*%udp%*|*%socket%*|*%listen%*|*%$NAME%*)
14844 TEST="$NAME: OpenSSL DTLS transfer from client to server"
14845 # Start a unidirectional OpenSSL DTLS server/receiver
14846 # Start a unidirectional OpenSSL DTLS client that connects to the server and
14847 # sends data
14848 # Test succeeded when the data received and stored by server is the same as
14849 # sent by the client
14850 if ! eval $NUMCOND; then :;
14851 elif ! a=$(testfeats ip4 udp openssl); then
14852 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14853 numCANT=$((numCANT+1))
14854 listCANT="$listCANT $N"
14855 elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then
14856 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14857 numCANT=$((numCANT+1))
14858 listCANT="$listCANT $N"
14859 elif ! runsip4 >/dev/null; then
14860 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14861 numCANT=$((numCANT+1))
14862 listCANT="$listCANT $N"
14863 elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then
14864 # also on NetBSD-4 with openssl-0.9.8e
14865 $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
14866 numCANT=$((numCANT+1))
14867 listCANT="$listCANT $N"
14868 else
14869 gentestcert testsrv
14870 ti="$td/test$N.datain"
14871 to="$td/test$N.dataout"
14872 te="$td/test$N.stderr"
14873 tdiff="$td/test$N.diff"
14874 da="test$N $(date) $RANDOM"
14875 newport udp4
14876 CMD0="$TRACE $SOCAT $opts -u OPENSSL-DTLS-LISTEN:$PORT,pf=ip4,cert=testsrv.pem,verify=0 CREAT:$to"
14877 CMD1="$TRACE $SOCAT $opts -u OPEN:$ti OPENSSL-DTLS-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt"
14878 printf "test $F_n $TEST... " $N
14879 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
14880 $CMD0 >/dev/null 2>"${te}0" &
14881 pid0=$!
14882 waitudp4port $PORT 1
14883 $CMD1 >"${tf}1" 2>"${te}1"
14884 rc1=$?
14885 relsleep 1
14886 kill $pid0 2>/dev/null; wait
14887 if [ $rc1 -ne 0 ]; then
14888 $PRINTF "$FAILED\n"
14889 echo "$CMD0 &" >&2
14890 cat "${te}0" >&2
14891 echo "$CMD1" >&2
14892 cat "${te}1" >&2
14893 numFAIL=$((numFAIL+1))
14894 listFAIL="$listFAIL $N"
14895 elif diff $ti $to >$tdiff; then
14896 $PRINTF "$OK\n"
14897 numOK=$((numOK+1))
14898 listOK="$listOK $N"
14899 else
14900 $PRINTF "$FAILED\n"
14901 echo "$CMD0 &" >&2
14902 cat "${te}0" >&2
14903 echo "$CMD1" >&2
14904 cat "${te}1" >&2
14905 echo "diff:" >&2
14906 head -n 2 $tdiff >&2
14907 echo ... >&2
14908 numFAIL=$((numFAIL+1))
14909 listFAIL="$listFAIL $N"
14911 fi # NUMCOND
14913 esac
14914 N=$((N+1))
14916 # Test file transfer from server to client using DTLS
14917 NAME=OPENSSL_DTLS_TO_CLIENT
14918 case "$TESTS" in
14919 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%dtls%*|*%udp%*|*%socket%*|*%listen%*|*%$NAME%*)
14920 TEST="$NAME: OpenSSL DTLS transfer from server to client"
14921 # Start a unidirectional OpenSSL DTLS server/sender
14922 # Start a unidirectional OpenSSL DTLS client that connects to the server and
14923 # receives data
14924 # Test succeeded when the data received and stored by client is the same as
14925 # sent by the server
14926 if ! eval $NUMCOND; then :;
14927 elif ! a=$(testfeats ip4 udp openssl); then
14928 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14929 numCANT=$((numCANT+1))
14930 listCANT="$listCANT $N"
14931 elif ! a=$(testaddrs openssl-dtls-listen openssl-dtls-connect); then
14932 $PRINTF "test $F_n $TEST... ${YELLOW}$a not available${NORMAL}\n" $N
14933 numCANT=$((numCANT+1))
14934 listCANT="$listCANT $N"
14935 elif ! runsip4 >/dev/null; then
14936 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
14937 numCANT=$((numCANT+1))
14938 listCANT="$listCANT $N"
14939 elif [[ $(openssl version |awk '{print($2);}') =~ 0.9.8[a-ce] ]]; then
14940 # also on NetBSD-4 with openssl-0.9.8e
14941 $PRINTF "test $F_n $TEST... ${YELLOW}openssl s_client might hang${NORMAL}\n" $N
14942 numCANT=$((numCANT+1))
14943 listCANT="$listCANT $N"
14944 else
14945 gentestcert testsrv
14946 ti="$td/test$N.datain"
14947 to="$td/test$N.dataout"
14948 te="$td/test$N.stderr"
14949 tdiff="$td/test$N.diff"
14950 da="test$N $(date) $RANDOM"
14951 newport udp4
14952 CMD0="$TRACE $SOCAT $opts -U OPENSSL-DTLS-LISTEN:$PORT,pf=ip4,cert=testsrv.pem,verify=0 OPEN:$ti"
14953 CMD1="$TRACE $SOCAT $opts -u OPENSSL-DTLS-CONNECT:$LOCALHOST:$PORT,pf=ip4,cafile=testsrv.crt CREAT:$to"
14954 printf "test $F_n $TEST... " $N
14955 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
14956 $CMD0 >/dev/null 2>"${te}0" &
14957 pid0=$!
14958 waitudp4port $PORT 1
14959 $CMD1 >"${tf}1" 2>"${te}1"
14960 rc1=$?
14961 relsleep 1
14962 kill $pid0 2>/dev/null; wait
14963 if [ $rc1 -ne 0 ]; then
14964 $PRINTF "$FAILED\n"
14965 echo "$CMD0 &" >&2
14966 cat "${te}0" >&2
14967 echo "$CMD1" >&2
14968 cat "${te}1" >&2
14969 numFAIL=$((numFAIL+1))
14970 listFAIL="$listFAIL $N"
14971 elif diff $ti $to >$tdiff; then
14972 $PRINTF "$OK\n"
14973 numOK=$((numOK+1))
14974 listOK="$listOK $N"
14975 else
14976 $PRINTF "$FAILED\n"
14977 echo "$CMD0 &" >&2
14978 cat "${te}0" >&2
14979 echo "$CMD1" >&2
14980 cat "${te}1" >&2
14981 echo "diff:" >&2
14982 head -n 2 $tdiff >&2
14983 echo ... >&2
14984 numFAIL=$((numFAIL+1))
14985 listFAIL="$listFAIL $N"
14987 fi # NUMCOND
14989 esac
14990 N=$((N+1))
14993 # Test if the problem with overlapping internal parameters of sockets and
14994 # openssl are fixed
14995 NAME=OPENSSL_PARA_OVERLAP
14996 case "$TESTS" in
14997 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%openssl%*|*%listen%*|*%$NAME%*)
14998 TEST="$NAME: test diverse of socket,openssl params"
14999 # That bug had not many effects; the simplest to use is possible SIGSEGV on
15000 # close when option accept-timeout with fractional seconds was applied
15001 if ! eval $NUMCOND; then :;
15002 elif ! testfeats openssl >/dev/null; then
15003 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
15004 numCANT=$((numCANT+1))
15005 listCANT="$listCANT $N"
15006 elif ! type openssl >/dev/null 2>&1; then
15007 $PRINTF "test $F_n $TEST... ${YELLOW}openssl executable not available${NORMAL}\n" $N
15008 numCANT=$((numCANT+1))
15009 listCANT="$listCANT $N"
15010 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
15011 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
15012 numCANT=$((numCANT+1))
15013 listCANT="$listCANT $N"
15014 else
15015 gentestcert testsrv
15016 tf="$td/test$N.stdout"
15017 te="$td/test$N.stderr"
15018 tdiff="$td/test$N.diff"
15019 trc0="$td/test$N.rc0"
15020 da="test$N $(date) $RANDOM"
15021 newport tcp4
15022 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"
15023 CMD1="$TRACE $SOCAT $opts /dev/null OPENSSL-CONNECT:$LOCALHOST:$PORT,pf=ip4,verify=0,$SOCAT_EGD"
15024 printf "test $F_n $TEST... " $N
15025 $CMD0 >/dev/null 2>"${te}0" || echo $? >$trc0 &
15026 pid0=$!
15027 waittcp4port $PORT 1
15028 $CMD1 >"${tf}1" 2>"${te}1"
15029 rc1=$?
15030 sleep 0.5
15031 kill $pid0 2>/dev/null; wait
15032 if [ $rc1 -ne 0 ]; then
15033 $PRINTF "$CANT\n"
15034 numCANT=$((numCANT+1))
15035 elif [ ! -e $trc0 ]; then
15036 $PRINTF "$OK\n"
15037 numOK=$((numOK+1))
15038 listOK="$listOK $N"
15039 else
15040 $PRINTF "$FAILED\n"
15041 echo "$CMD0 &" >&2
15042 cat "${te}0" >&2
15043 echo "$CMD1" >&2
15044 cat "${te}1" >&2
15045 numFAIL=$((numFAIL+1))
15046 listFAIL="$listFAIL $N"
15048 fi # NUMCOND
15050 esac
15051 N=$((N+1))
15054 # Bug fix, OpenSSL server could be crashed by client cert with IPv6 address in SubjectAltname
15055 NAME=OPENSSL_CLIENT_IP6_CN
15056 case "$TESTS" in
15057 *%$N%*|*%functions%*|*%bugs%*|*%openssl%*|*%ip6%*|*%socket%*|*%listen%*|*%$NAME%*)
15058 TEST="$NAME: Test if OpenSSL server may be crashed by client cert with IPv6 address"
15059 # Socat 1.7.4.1 had a bug that caused OpenSSL server to crash with SIGSEGV when
15060 # it checked a client certificate containing IPv6 address in SubjectAltName and
15061 # no openssl-commonname option was given
15062 if ! eval $NUMCOND; then :;
15063 elif ! testfeats openssl >/dev/null; then
15064 $PRINTF "test $F_n $TEST... ${YELLOW}OPENSSL not available${NORMAL}\n" $N
15065 numCANT=$((numCANT+1))
15066 listCANT="$listCANT $N"
15067 elif ! testfeats tcp ip4 >/dev/null || ! runsip4 >/dev/null; then
15068 $PRINTF "test $F_n $TEST... ${YELLOW}TCP/IPv4 not available${NORMAL}\n" $N
15069 numCANT=$((numCANT+1))
15070 listCANT="$listCANT $N"
15071 else
15072 gentestcert testsrv
15073 gentestaltcert testalt
15074 tf="$td/test$N.stdout"
15075 te="$td/test$N.stderr"
15076 tdiff="$td/test$N.diff"
15077 da="test$N $(date) $RANDOM"
15078 newport tcp4
15079 CMD0="$TRACE $SOCAT $opts -u OPENSSL-LISTEN:$PORT,pf=ip4,reuseaddr,cert=./testsrv.pem,cafile=./testalt.crt -"
15080 CMD1="$TRACE $SOCAT $opts -u - OPENSSL-CONNECT:localhost:$PORT,pf=ip4,cafile=testsrv.crt,cert=testalt.pem,verify=0"
15081 printf "test $F_n $TEST... " $N
15082 $CMD0 >/dev/null >"${tf}0" 2>"${te}0" &
15083 pid0=$!
15084 waittcp4port $PORT 1
15085 echo "$da" |$CMD1 2>"${te}1"
15086 rc1=$?
15087 kill $pid0 2>/dev/null; wait
15088 if [ $rc1 -eq 0 ] && echo "$da" |diff - "${tf}0" >$tdiff; then
15089 $PRINTF "$OK\n"
15090 numOK=$((numOK+1))
15091 listOK="$listOK $N"
15092 else
15093 $PRINTF "$FAILED\n"
15094 echo "$CMD0 &" >&2
15095 cat "${te}0" >&2
15096 echo "$CMD1" >&2
15097 cat "${te}1" >&2
15098 numFAIL=$((numFAIL+1))
15099 listFAIL="$listFAIL $N"
15101 fi # NUMCOND
15103 esac
15104 N=$((N+1))
15107 # Test if unknown service specs are handled properly
15108 NAME=BAD_SERVICE
15109 case "$TESTS" in
15110 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%$NAME%*)
15111 TEST="$NAME: test if unknown service specs are handled properly"
15112 # Try to resolve an unspecified TCP service "
15113 if ! eval $NUMCOND; then :; else
15114 tf="$td/test$N.stdout"
15115 te="$td/test$N.stderr"
15116 tdiff="$td/test$N.diff"
15117 da="test$N $(date) $RANDOM"
15118 CMD="$TRACE $SOCAT $opts - TCP:$LOCALHOST:zyxw"
15119 printf "test $F_n $TEST... " $N
15120 $CMD >/dev/null 2>"${te}" &
15121 pid=$!
15122 sleep 1
15123 kill -9 $pid 2>/dev/null;
15124 rc=$? # did process still exist?
15125 if [ $rc -ne 0 ]; then
15126 $PRINTF "$OK\n"
15127 if [ "$VERBOSE" ]; then
15128 echo "$CMD &" >&2
15130 numOK=$((numOK+1))
15131 listOK="$listOK $N"
15132 else
15133 $PRINTF "$FAILED\n"
15134 echo "$CMD &" >&2
15135 cat "${te}" >&2
15136 numFAIL=$((numFAIL+1))
15137 listFAIL="$listFAIL $N"
15139 fi # NUMCOND
15141 esac
15142 N=$((N+1))
15145 # Test if the user option with abstract UNIX domain socket is not applied to
15146 # file "" (empty name)
15147 NAME=ABSTRACT_USER
15148 case "$TESTS" in
15149 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%abstract%*|*%listen%*|*%$NAME%*)
15150 TEST="$NAME: Is the fs related user option on ABSTRACT socket applied to FD"
15151 # Apply the user option to an abstract socket; check if this produces an error.
15152 # No error should occur
15153 if ! eval $NUMCOND; then :;
15154 elif [ "$UNAME" != Linux ]; then
15155 $PRINTF "test $F_n $TEST... ${YELLOW}only on Linux${NORMAL}\n" $N
15156 numCANT=$((numCANT+1))
15157 listCANT="$listCANT $N"
15158 else
15159 tf="$td/test$N.stdout"
15160 te="$td/test$N.stderr"
15161 tdiff="$td/test$N.diff"
15162 da="test$N $(date) $RANDOM"
15163 CMD="$TRACE $SOCAT ABSTRACT-LISTEN:temp,accept-timeout=0.1,user=$USER FILE:/dev/null"
15164 printf "test $F_n $TEST... " $N
15165 $CMD >/dev/null 2>"${te}"
15166 echo "$da" |$CMD >"${tf}1" 2>"${te}1"
15167 rc=$?
15168 if [ $rc -eq 0 ]; then
15169 $PRINTF "$OK\n"
15170 if [ "$VERBOSE" ]; then
15171 echo "$CMD" >&2
15173 numOK=$((numOK+1))
15174 listOK="$listOK $N"
15175 else
15176 $PRINTF "$FAILED\n"
15177 echo "$CMD" >&2
15178 cat "${te}" >&2
15179 numFAIL=$((numFAIL+1))
15180 listFAIL="$listFAIL $N"
15182 fi # NUMCOND
15184 esac
15185 N=$((N+1))
15188 # Test if option -R does not "sniff" left-to-right traffic
15189 NAME=SNIFF_RIGHT_TO_LEFT
15190 case "$TESTS" in
15191 *%$N%*|*%functions%*|*%bugs%*|*%$NAME%*)
15192 TEST="$NAME: test if option -R does not "sniff" left-to-right traffic"
15193 # Use option -R, check if left-to-right traffic is not in output file
15194 if ! eval $NUMCOND; then :; else
15195 tf="$td/test$N.stdout"
15196 te="$td/test$N.stderr"
15197 ts="$td/test$N.sniffed"
15198 tdiff="$td/test$N.diff"
15199 da="test$N $(date) $RANDOM"
15200 CMD="$TRACE $SOCAT $opts -R $ts - /dev/null"
15201 printf "test $F_n $TEST... " $N
15202 echo "$da" |$CMD >"${tf}" 2>"${te}"
15203 rc=$?
15204 if [ ! -f "$ts" ]; then
15205 $PRINTF "$CANT\n"
15206 if [ "$VERBOSE" ]; then
15207 echo "$CMD" >&2
15208 cat "${te}" >&2
15210 numCANT=$((numCANT+1))
15211 listCANT="$listCANT $N"
15212 elif [ ! -s "$ts" ]; then
15213 $PRINTF "$OK\n"
15214 if [ "$VERBOSE" ]; then
15215 echo "$CMD" >&2
15217 numOK=$((numOK+1))
15218 listOK="$listOK $N"
15219 else
15220 $PRINTF "$FAILED\n"
15221 echo "$CMD &" >&2
15222 cat "${te}" >&2
15223 numFAIL=$((numFAIL+1))
15224 listFAIL="$listFAIL $N"
15226 fi # NUMCOND
15228 esac
15229 PORT=$((PORT+1))
15230 N=$((N+1))
15232 # Socats access to different types of file system entries using various kinds
15233 # of addresses fails in a couple of useless combinations. These failures have
15234 # to print an error message and exit with return code 1.
15235 # Up to version 1.7.4.2 this desired behaviour was found for most combinations,
15236 # however some fix in 1.7.4.3 degraded the overall result.
15237 # This group of tests checks all known compinations.
15238 while read entry method; do
15239 if [ -z "$entry" ] || [[ "$entry" == \#* ]]; then continue; fi
15240 NAME=$(toupper $method)_TO_$(toupper $entry)
15241 case "$TESTS" in
15242 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%listen%*|*%$NAME%*)
15243 #set -vx
15244 TEST="$NAME: Failure handling on $method access to $entry"
15245 # Create some kind of system entry and try to access it with some improper
15246 # address. Check if Socat returns with rc 1 and prints an error message
15247 if ! eval $NUMCOND; then :; else
15248 ts="$td/test$N.socket"
15249 tf="$td/test$N.stdout"
15250 te="$td/test$N.stderr"
15251 tdiff="$td/test$N.diff"
15252 da="test$N $(date) $RANDOM"
15254 printf "test $F_n $TEST... " $N
15255 # create an invalid or non-matching UNIX socket
15256 case "$entry" in
15257 missing) pid0=; rm -f $ts ;;
15258 denied) pid0=; rm -f $ts; touch $ts; chmod 000 $ts ;;
15259 directory) pid0=; mkdir -p $ts ;;
15260 orphaned) pid0= # the remainder of a UNIX socket in FS
15261 SOCAT_MAIN_WAIT= $SOCAT $opts UNIX-LISTEN:$ts,unlink-close=0 /dev/null >${tf}0 2>${te}0 &
15262 waitunixport $ts 1
15263 SOCAT_MAIN_WAIT= $SOCAT $opts /dev/null UNIX-CONNECT:$ts >>${tf}0 2>>${te}0
15265 file) pid0=; rm -f $ts; touch $ts ;;
15266 stream) CMD0="$SOCAT $opts UNIX-LISTEN:$ts /dev/null"
15267 SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 &
15268 pid0=$! ;;
15269 dgram) CMD0="$SOCAT $opts -u UNIX-RECV:$ts /dev/null"
15270 SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 &
15271 pid0=$! ;;
15272 seqpacket) CMD0="$SOCAT $opts UNIX-LISTEN:$ts,socktype=$SOCK_SEQPACKET /dev/null"
15273 SOCAT_MAIN_WAIT= $CMD0 >${tf}0 2>${te}0 &
15274 pid0=$! ;;
15275 esac
15276 [ "$pid0" ] && waitunixport $ts 1
15277 # try to access this socket
15278 case "$method" in
15279 connect) CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts" ;;
15280 send) CMD1="$TRACE $SOCAT $opts -u - UNIX-SEND:$ts" ;;
15281 sendto) CMD1="$TRACE $SOCAT $opts -u - UNIX-SENDTO:$ts" ;;
15282 seqpacket) CMD1="$TRACE $SOCAT $opts -u - UNIX-CONNECT:$ts,socktype=$SOCK_SEQPACKET" ;;
15283 unix) CMD1="$TRACE $SOCAT $opts -u - UNIX-CLIENT:$ts" ;;
15284 gopen) CMD1="$TRACE $SOCAT $opts -u - GOPEN:$ts" ;;
15285 esac
15286 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
15287 rc1=$?
15288 [ "$pid0" ] && { kill $pid0 2>/dev/null; wait; }
15289 if [ $rc1 != 1 ]; then
15290 $PRINTF "$FAILED (bad return code $rc1)\n"
15291 if [ "$pid0" ]; then
15292 echo "$CMD0 &" >&2
15293 cat "${te}0" >&2
15295 echo "$CMD1" >&2
15296 cat "${te}1" >&2
15297 numFAIL=$((numFAIL+1))
15298 listFAIL="$listFAIL $N"
15299 elif nerr=$(grep ' E ' "${te}1" |wc -l); test "$nerr" -ne 1; then
15300 $PRINTF "$FAILED ($nerr error message(s) instead of 1)\n"
15301 if [ "$pid0" ]; then
15302 echo "$CMD0 &" >&2
15303 cat "${te}0" >&2
15305 echo "$CMD1" >&2
15306 cat "${te}1" >&2
15307 numFAIL=$((numFAIL+1))
15308 listFAIL="$listFAIL $N"
15309 else
15310 $PRINTF "$OK\n"
15311 if [ "$VERBOSE" ]; then
15312 if [ "$pid0" ]; then echo "$CMD0 &" >&2; fi
15313 echo "$CMD1" >&2
15315 numOK=$((numOK+1))
15316 listOK="$listOK $N"
15318 set +vx
15319 fi # NUMCOND
15321 esac
15322 N=$((N+1))
15323 done <<<"
15324 missing connect
15325 denied connect
15326 directory connect
15327 orphaned connect
15328 file connect
15329 dgram connect
15330 seqpacket connect
15331 missing send
15332 denied send
15333 directory send
15334 orphaned send
15335 file send
15336 stream send
15337 seqpacket send
15338 missing sendto
15339 denied sendto
15340 directory sendto
15341 orphaned sendto
15342 file sendto
15343 stream sendto
15344 seqpacket sendto
15345 missing seqpacket
15346 denied seqpacket
15347 directory seqpacket
15348 orphaned seqpacket
15349 file seqpacket
15350 stream seqpacket
15351 dgram seqpacket
15352 missing unix
15353 denied unix
15354 directory unix
15355 file unix
15356 orphaned unix
15357 denied gopen
15358 directory gopen
15359 orphaned gopen
15363 # Test TCP with options connect-timeout and retry.
15364 # Up to 1.7.4.3 this terminated immediately on connection refused
15365 NAME=TCP_TIMEOUT_RETRY
15366 case "$TESTS" in
15367 *%$N%*|*%functions%*|*%bugs%*|*%tcp%*|*%socket%*|*%listen%*|*%$NAME%*)
15368 TEST="$NAME: TCP with options connect-timeout and retry"
15369 # In background run a delayed echo server
15370 # In foreground start TCP with connect-timeout and retry. On first attempt the
15371 # server is not listening; when socat makes a second attempt that succeeds, the
15372 # bug is absent and the test succeeded.
15373 if ! eval $NUMCOND; then :; else
15374 tf="$td/test$N.stdout"
15375 te="$td/test$N.stderr"
15376 tdiff="$td/test$N.diff"
15377 da="test$N $(date) $RANDOM"
15378 CMD0="sleep 1 && $TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr PIPE"
15379 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT,connect-timeout=2,retry=1,interval=2"
15380 printf "test $F_n $TEST... " $N
15381 eval "$CMD0" >/dev/null 2>"${te}0" &
15382 pid0=$!
15383 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
15384 rc1=$?
15385 kill $pid0 2>/dev/null; wait
15386 if [ $rc1 -ne 0 ]; then
15387 $PRINTF "$FAILED\n"
15388 echo "$CMD0 &" >&2
15389 cat "${te}0" >&2
15390 echo "$CMD1" >&2
15391 cat "${te}1" >&2
15392 numFAIL=$((numFAIL+1))
15393 listFAIL="$listFAIL $N"
15394 elif echo "$da" |diff - "${tf}1" >$tdiff; then
15395 $PRINTF "$OK\n"
15396 if [ "$VERBOSE" ]; then
15397 echo "$CMD0 &" >&2
15398 echo "$CMD1" >&2
15400 numOK=$((numOK+1))
15401 listOK="$listOK $N"
15402 else
15403 $PRINTF "$FAILED\n"
15404 echo "$CMD0 &" >&2
15405 cat "${te}0" >&2
15406 echo "$CMD1" >&2
15407 cat "${te}1" >&2
15408 numFAIL=$((numFAIL+1))
15409 listFAIL="$listFAIL $N"
15411 fi # NUMCOND
15413 esac
15414 N=$((N+1))
15417 # Test if the rawer option works. Up to Socat 1.7.4.3, it failed because it
15418 # cleared the CREAD flag.
15419 NAME=RAWER
15420 case "$TESTS" in
15421 *%$N%*|*%functions%*|*%bugs%*|*%pty%*|*%$NAME%*)
15422 TEST="$NAME: Test if the rawer option fails"
15423 # Invoke Socat with a terminal address with option rawer. When it has no error
15424 # the test succeeded.
15425 if ! eval $NUMCOND; then :; else
15426 tf="$td/test$N.stdout"
15427 te="$td/test$N.stderr"
15428 tdiff="$td/test$N.diff"
15429 da="test$N $(date) $RANDOM"
15430 CMD0="$SOCAT -lp outer /dev/null EXEC:\"$SOCAT\\ -lp\\ inner\\ -\\,rawer\\ PIPE\",pty"
15431 printf "test $F_n $TEST... " $N
15432 eval "$CMD0" >/dev/null 2>"${te}0"
15433 rc0=$?
15434 if [ $rc0 -eq 0 ]; then
15435 $PRINTF "$OK\n"
15436 if [ "$VERBOSE" ]; then
15437 echo "$CMD0" >&2
15439 numOK=$((numOK+1))
15440 listOK="$listOK $N"
15441 else
15442 $PRINTF "$FAILED\n"
15443 echo "$CMD0" >&2
15444 cat "${te}0" >&2
15445 numFAIL=$((numFAIL+1))
15446 listFAIL="$listFAIL $N"
15448 fi # NUMCOND
15450 esac
15451 PORT=$((PORT+1))
15452 N=$((N+1))
15454 # Up to 1.7.4.3 there was a bug with the lowport option:
15455 # Active addresses UDP-SEND, UDP-SENDTO always bound to port 1 instead of
15456 # 640..1023
15457 NAME=UDP_LOWPORT
15458 case "$TESTS" in
15459 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
15460 TEST="$NAME: UDP4-SEND with lowport"
15461 # Run Socat with UDP4-SEND:...,lowport and full logging and check the
15462 # parameters of bind() call. If port is in the range 640..1023 the test
15463 # succeeded.
15464 # This test does not require root because it just checks log of bind() but does
15465 # not require success
15466 # This test fails if WITH_SYCLS is turned off
15467 if ! eval $NUMCOND; then :; else
15468 tf="$td/test$N.stdout"
15469 te="$td/test$N.stderr"
15470 tdiff="$td/test$N.diff"
15471 da="test$N $(date) $RANDOM"
15472 #newport udp4 # not needed in this test
15473 CMD="$TRACE $SOCAT $opts -d -d -d -d /dev/null UDP4-SENDTO:$LOCALHOST:$PORT,lowport"
15474 printf "test $F_n $TEST... " $N
15475 $CMD >/dev/null 2>"${te}"
15476 rc1=$?
15477 LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head -n 1)
15478 #echo "LOWPORT=\"$LOWPORT\"" >&2
15479 #type socat >&2
15480 if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then
15481 $PRINTF "$OK\n"
15482 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15483 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15484 numOK=$((numOK+1))
15485 listOK="$listOK $N"
15486 elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then
15487 $PRINTF "$CANT (no SYCLS)\n"
15488 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15489 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15490 numCANT=$((numCANT+1))
15491 listCANT="$listCANT $N"
15492 else
15493 $PRINTF "$FAILED\n"
15494 echo "$CMD"
15495 cat "${te}" >&2
15496 numFAIL=$((numFAIL+1))
15497 listFAIL="$listFAIL $N"
15499 fi # NUMCOND
15501 esac
15502 PORT=$((PORT+1))
15503 N=$((N+1))
15505 # Test if trailing garbage in integer type options gives error
15506 NAME=MISSING_INTEGER
15507 case "$TESTS" in
15508 *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*)
15509 TEST="$NAME: Error on option that's missing integer value"
15510 # Invoke Socat with pty and option ispeed=b19200.
15511 # When socat terminates with error the test succeeded
15512 if ! eval $NUMCOND; then :; else
15513 tf="$td/test$N.stdout"
15514 te="$td/test$N.stderr"
15515 tdiff="$td/test$N.diff"
15516 da="test$N $(date) $RANDOM"
15517 CMD0="$TRACE $SOCAT $opts - PTY,ispeed=b19200"
15518 printf "test $F_n $TEST... " $N
15519 $CMD0 </dev/null >/dev/null 2>"${te}0"
15520 if grep -q "missing numerical value" "${te}0"; then
15521 $PRINTF "$OK\n"
15522 numOK=$((numOK+1))
15523 listOK="$listOK $N"
15524 else
15525 $PRINTF "$FAILED\n"
15526 echo "$CMD0"
15527 cat "${te}0"
15528 numFAIL=$((numFAIL+1))
15529 listFAIL="$listFAIL $N"
15531 fi # NUMCOND
15533 esac
15534 N=$((N+1))
15536 # Test if trailing garbage in integer type options gives error
15537 NAME=INTEGER_GARBAGE
15538 case "$TESTS" in
15539 *%$N%*|*%functions%*|*%syntax%*|*%bugs%*|*%$NAME%*)
15540 TEST="$NAME: Error on trailing garbage"
15541 # Invoke Socat with pty and option ispeed=b19200.
15542 # When socat terminates with error the test succeeded
15543 if ! eval $NUMCOND; then :; else
15544 tf="$td/test$N.stdout"
15545 te="$td/test$N.stderr"
15546 tdiff="$td/test$N.diff"
15547 da="test$N $(date) $RANDOM"
15548 CMD0="$TRACE $SOCAT $opts - PTY,ispeed=19200B"
15549 printf "test $F_n $TEST... " $N
15550 $CMD0 </dev/null >/dev/null 2>"${te}0"
15551 if grep -q "trailing garbage" "${te}0"; then
15552 $PRINTF "$OK\n"
15553 if [ "$VERBOSE" ]; then echo "$CMD0" >&2; fi
15554 if [ "$debug" ]; then cat ${te} >&2; fi
15555 numOK=$((numOK+1))
15556 listOK="$listOK $N"
15557 else
15558 $PRINTF "$FAILED\n"
15559 echo "$CMD0"
15560 cat "${te}0"
15561 numFAIL=$((numFAIL+1))
15562 listFAIL="$listFAIL $N"
15564 fi # NUMCOND
15566 esac
15567 N=$((N+1))
15570 # Test if Filan can print the target of symbolic links
15571 NAME=FILANSYMLINK
15572 case "$TESTS" in
15573 *%$N%*|*%filan%*|*%$NAME%*)
15574 TEST="$NAME: capability to display symlink target"
15575 # Run Filan on a symbolic link
15576 # When its output contains "LINKTARGET=<target>" the test succeeded
15577 if ! eval $NUMCOND; then :; else
15578 tf="$td/test$N.file"
15579 tl="$td/test$N.symlink"
15580 te="$td/test$N.stderr"
15581 printf "test $F_n $TEST... " $N
15582 touch "$tf"
15583 ln -s "$tf" "$tl"
15584 target=$($FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/')
15585 if [ "$target" = "$tf" ]; then
15586 $PRINTF "$OK\n"
15587 if [ "$VERBOSE" ]; then
15588 echo "touch \"$tf\""
15589 echo "ln -s \"$tf\" \"$tl\""
15590 echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'"
15592 numOK=$((numOK+1))
15593 listOK="$listOK $N"
15594 else
15595 $PRINTF "$FAILED\n"
15596 echo "touch \"$tf\"" >&2
15597 echo "ln -s \"$tf\" \"$tl\"" >&2
15598 echo "$FILAN -f "$tl" 2>$te |tail -n 1 |sed 's/.*LINKTARGET=\([^ ]*\)/\1/'" >&2
15599 cat "$te"
15600 numFAIL=$((numFAIL+1))
15601 listFAIL="$listFAIL $N"
15603 kill $spid 2>/dev/null
15604 wait
15605 fi ;; # NUMCOND
15606 esac
15607 N=$((N+1))
15610 # Test preservation of packet boundaries from Socat to sub processes of
15611 # various kind and back to Socat via socketpair with socket type datagram.
15612 # (EXECSOCKETPAIRPACKETS SYSTEMSOCKETPAIRPACKETS)
15613 for addr in exec system; do
15614 ADDR=$(echo $addr |tr a-z A-Z)
15615 NAME=${ADDR}SOCKETPAIRPACKETS
15616 case "$TESTS" in
15617 *%$N%*|*%functions%*|*%exec%*|*%socketpair%*|*%unix%*|*%dgram%*|*%packets%*|*%$NAME%*)
15618 TEST="$NAME: simple echo via $addr of cat with socketpair, keeping packet boundaries"
15619 # Start a Socat process with a UNIX datagram socket on the left side and with
15620 # a sub process connected via datagram socketpair that keeps packet boundaries
15621 # (here: another Socat process in unidirectional mode).
15622 # Pass two packets to the UNIX datagram socket; let Socat wait a little time
15623 # before processing,
15624 # so the packets are at the same time in the receive queue.
15625 # The process that sends these packet uses a short packet size (-b),
15626 # so the returned data is truncated in case the packets were merged.
15627 # When the complete data is returned, the test succeeded.
15628 if ! eval $NUMCOND; then :; else
15629 SAVEMICS=$MICROS
15630 MICROS=500000
15631 ts0="$td/test$N.sock0"
15632 ts1="$td/test$N.sock1"
15633 tf="$td/test$N.stdout"
15634 te="$td/test$N.stderr"
15635 tdiff="$td/test$N.diff"
15636 da="test$N $(date) $RANDOM"
15637 #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
15638 CMD0="$TRACE $SOCAT $opts -lp server -t $(reltime 1) -T $(reltime 2) UNIX-SENDTO:$ts1,bind=$ts0,null-eof $ADDR:\"$SOCAT -lp echoer -u - -\",socktype=$SOCK_DGRAM",shut-null
15639 CMD1="$SOCAT $opts -lp client -b 24 -t $(reltime 2) -T $(reltime 3) - UNIX-SENDTO:$ts0,bind=$ts1",shut-null
15640 printf "test $F_n $TEST... " $N
15641 export SOCAT_TRANSFER_WAIT=1
15642 eval "$CMD0" >/dev/null 2>"${te}0" &
15643 pid0="$!"
15644 unset SOCAT_TRANSFER_WAIT
15645 waitunixport $ts0 1
15646 { echo -n "${da:0:20}"; relsleep 1; echo "${da:20}"; } |$CMD1 >"${tf}1" 2>"${te}1"
15647 rc1=$?
15648 kill $pid0 2>/dev/null; wait
15649 if [ "$rc1" -ne 0 ]; then
15650 $PRINTF "$FAILED (rc1=$rc1): $TRACE $SOCAT:\n"
15651 echo "$CMD0 &"
15652 cat "${te}0"
15653 echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1"
15654 cat "${te}1"
15655 numFAIL=$((numFAIL+1))
15656 listFAIL="$listFAIL $N"
15657 elif ! echo "$da" |diff - "${tf}1" >"$tdiff"; then
15658 $PRINTF "$FAILED (diff)\n"
15659 echo "$CMD0 &" >&2
15660 cat "${te}0" >&2
15661 echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" >&2
15662 cat "${te}1" >&2
15663 echo "diff:" >&2
15664 cat $tdiff >&2
15665 numFAIL=$((numFAIL+1))
15666 listFAIL="$listFAIL $N"
15667 else
15668 $PRINTF "$OK\n"
15669 if [ "$VERBOSE" ]; then
15670 echo "$CMD0 &" >&2
15671 echo "{ echo -n \"${da:0:20}\"; relsleep 1; echo \"${da:20}\"; } |$CMD1" >&2
15673 numOK=$((numOK+1))
15674 listOK="$listOK $N"
15676 MICROS=$SAVEMICS
15677 fi # NUMCOND
15679 esac
15680 N=$((N+1))
15681 done # for
15684 # Test if a special quote based syntax error in dalan module does not raise
15685 # SIGSEGV
15686 NAME=DALAN_NO_SIGSEGV
15687 case "$TESTS" in
15688 *%$N%*|*%functions%*|*%bugs%*|*%dalan%*|*%listen%*|*%$NAME%*)
15689 TEST="$NAME: Dalan syntax error does not raise SIGSEGV"
15690 # Invoke Socat with an address that has this quote based syntax error.
15691 # When exit code is 1 (due to syntax error) the test succeeded.
15692 if ! eval $NUMCOND; then :
15693 elif ! a=$(testfeats GOPEN); then
15694 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
15695 numCANT=$((numCANT+1))
15696 listCANT="$listCANT $N"
15697 elif ! a=$(testaddrs - GOPEN SOCKET-LISTEN); then
15698 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
15699 numCANT=$((numCANT+1))
15700 listCANT="$listCANT $N"
15701 else
15702 tf="$td/test$N.stdout"
15703 te="$td/test$N.stderr"
15704 tdiff="$td/test$N.diff"
15705 da="test$N $(date) $RANDOM"
15706 CMD="$TRACE $SOCAT $opts /dev/null SOCKET-LISTEN:1:1:'"/tmp/sock"'"
15707 printf "test $F_n $TEST... " $N
15708 $CMD >/dev/null 2>"${te}"
15709 rc1=$?
15710 if [ $rc1 -eq 1 ]; then
15711 $PRINTF "$OK\n"
15712 if [ "$VERBOSE" ]; then echo "$CMD"; fi
15713 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15714 numOK=$((numOK+1))
15715 listOK="$listOK $N"
15716 elif [ $rc1 -eq 139 ]; then
15717 $PRINTF "$FAILED\n"
15718 echo "$CMD"
15719 cat "${te}" >&2
15720 numFAIL=$((numFAIL+1))
15721 listFAIL="$listFAIL $N"
15722 else
15723 # soemthing unexpected happened
15724 $PRINTF "$CANT\n"
15725 echo "$CMD"
15726 cat "${te}" >&2
15727 numCANT=$((numCANT+1))
15728 listCANT="$listCANT $N"
15730 fi # NUMCOND
15732 esac
15733 N=$((N+1))
15736 # Test if filan -s correctly displays TCP on appropriate FDs
15737 # This feature was broken in version 1.7.4.4
15738 NAME=FILAN_SHORT_TCP
15739 case "$TESTS" in
15740 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%listen%*|*%$NAME%*)
15741 TEST="$NAME: filan -s displays TCP etc"
15742 # Establish a TCP connection using Socat server and client; on the server
15743 # exec() filan -s using nofork option, so its output appears on the client.
15744 # When the second word in the first line is "tcp" the test succeeded.
15745 if ! eval $NUMCOND; then :
15746 elif ! a=$(testfeats STDIO IP4 TCP LISTEN EXEC); then
15747 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
15748 numCANT=$((numCANT+1))
15749 listCANT="$listCANT $N"
15750 elif ! a=$(testaddrs STDIO TCP4 TCP4-LISTEN EXEC); then
15751 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
15752 numCANT=$((numCANT+1))
15753 listCANT="$listCANT $N"
15754 elif ! o=$(testoptions so-reuseaddr nofork ) >/dev/null; then
15755 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15756 numCANT=$((numCANT+1))
15757 listCANT="$listCANT $N"
15758 elif ! runsip4 >/dev/null; then
15759 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
15760 numCANT=$((numCANT+1))
15761 listCANT="$listCANT $N"
15762 else
15763 tf="$td/test$N.stdout"
15764 te="$td/test$N.stderr"
15765 tdiff="$td/test$N.diff"
15766 da="test$N $(date) $RANDOM"
15767 CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork"
15768 CMD1="$TRACE $SOCAT $opts -t $T4 - TCP4:localhost:$PORT"
15769 printf "test $F_n $TEST... " $N
15770 eval "$CMD0" >/dev/null 2>"${te}0" &
15771 pid0=$!
15772 waittcp4port $PORT 1
15773 $CMD1 >"${tf}1" 2>"${te}1" </dev/null
15774 rc1=$?
15775 kill $pid0 2>/dev/null; wait
15776 result="$(head -n 1 ${tf}1 |awk '{print($2);}')"
15777 if [ $rc1 -eq 0 -a "$result" = tcp ]; then
15778 $PRINTF "$OK\n"
15779 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
15780 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
15781 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
15782 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
15783 numOK=$((numOK+1))
15784 listOK="$listOK $N"
15785 else
15786 $PRINTF "$FAILED\n"
15787 if [ $rc1 -ne 0 ]; then
15788 echo "rc=$rc1" >&2
15789 else
15790 echo "result is \"$result\" instead of \"tcp\"" >&2
15792 echo "$CMD0 &"
15793 cat "${te}0" >&2
15794 echo "$CMD1"
15795 cat "${te}1" >&2
15796 numFAIL=$((numFAIL+1))
15797 listFAIL="$listFAIL $N"
15799 fi # NUMCOND
15801 esac
15802 PORT=$((PORT+1))
15803 N=$((N+1))
15806 # Test if the settings of the terminal that Socat is invoked in are restored
15807 # on termination.
15808 # This failed on Open-Solaris family OSes up to 1.7.4.4
15809 NAME=RESTORE_TTY
15810 case "$TESTS" in
15811 *%$N%*|*%functions%*|*%bugs%*|*%termios%*|*%tty%*|*%$NAME%*)
15812 TEST="$NAME: Restoring of terminal settings"
15813 # With an outer Socat command create a new pty and a bash in it.
15814 # In this bash store the current terminal settings, then invoke a temporary
15815 # inner Socat command that changes the term to raw mode and terminates.
15816 # When the terminal settings afterwards are the same as before the call the
15817 # test succeeded.
15818 if ! eval $NUMCOND; then :
15819 elif ! $(type stty >/dev/null 2>&1); then
15820 $PRINTF "test $F_n $TEST... ${YELLOW}stty not available${NORMAL}\n" $N
15821 numCANT=$((numCANT+1))
15822 listCANT="$listCANT $N"
15823 elif ! a=$(testfeats STDIO SYSTEM PTY GOPEN); then
15824 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $a not available in $SOCAT${NORMAL}\n" $N
15825 numCANT=$((numCANT+1))
15826 listCANT="$listCANT $N"
15827 elif ! a=$(testaddrs - STDIO SYSTEM GOPEN); then
15828 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available in $SOCAT${NORMAL}\n" $N
15829 numCANT=$((numCANT+1))
15830 listCANT="$listCANT $N"
15831 elif ! o=$(testoptions cfmakeraw pty setsid ctty stderr) >/dev/null; then
15832 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
15833 numCANT=$((numCANT+1))
15834 listCANT="$listCANT $N"
15835 else
15836 te="$td/test$N.stderr"
15837 tx0="$td/test$N.stty0"
15838 tx1="$td/test$N.stty1"
15839 tdiff="$td/test$N.diff"
15840 da="test$N $(date) $RANDOM"
15841 CMD="$TRACE $SOCAT $opts -lp outersocat - SYSTEM:\"stty\ >$tx0;\ $SOCAT\ -\,cfmakeraw\ /dev/nul\l >${te};\ stty\ >$tx1\",pty,setsid,ctty,stderr"
15842 printf "test $F_n $TEST... " $N
15843 eval "$CMD" >/dev/null 2>${te}.outer
15844 rc=$?
15845 if diff $tx0 $tx1 >$tdiff 2>&1; then
15846 $PRINTF "$OK\n"
15847 if [ "$VERBOSE" ]; then echo "$CMD &"; fi
15848 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15849 numOK=$((numOK+1))
15850 listOK="$listOK $N"
15851 else
15852 $PRINTF "$FAILED\n"
15853 echo "$CMD"
15854 cat "${te}" >&2
15855 cat "${te}.outer" >&2
15856 cat $tdiff >&2
15857 numFAIL=$((numFAIL+1))
15858 listFAIL="$listFAIL $N"
15860 fi # NUMCOND
15862 esac
15863 PORT=$((PORT+1))
15864 N=$((N+1))
15867 # Test if EXEC'd program inherits only the stdio file descriptors
15868 # thus there are no FD leaks from Socat to EXEC'd program
15869 NAME=EXEC_FDS
15870 case "$TESTS" in
15871 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%$NAME%*)
15872 TEST="$NAME: Socat does not leak FDs to EXEC'd program"
15873 # Run Socat with EXEC address, execute Filan to display its file descriptors
15874 # Test succeeds when only FDs 0, 1, 2 are in use.
15875 if ! eval $NUMCOND; then :;
15876 elif ! a=$(testaddrs STDIO EXEC); then
15877 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
15878 numCANT=$((numCANT+1))
15879 listCANT="$listCANT $N"
15880 elif ! o=$(testoptions stderr) >/dev/null; then
15881 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15882 numCANT=$((numCANT+1))
15883 listCANT="$listCANT $N"
15884 else
15885 tf="$td/test$N.stdout"
15886 te="$td/test$N.stderr"
15887 tdiff="$td/test$N.diff"
15888 da="test$N $(date) $RANDOM"
15889 CMD="$TRACE $SOCAT $opts - EXEC:\"$FILAN -s\""
15890 printf "test $F_n $TEST... " $N
15891 eval "$CMD" >"${tf}" 2>"${te}"
15892 # "door" is a special FD type on Solaris/SunOS
15893 if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then
15894 $PRINTF "$OK\n"
15895 if [ "$VERBOSE" ]; then echo "$CMD"; fi
15896 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15897 numOK=$((numOK+1))
15898 listOK="$listOK $N"
15899 else
15900 $PRINTF "$FAILED\n"
15901 echo "$CMD" >&2
15902 cat "${te}" >&2
15903 cat "${tf}" >&2
15904 numFAIL=$((numFAIL+1))
15905 listFAIL="$listFAIL $N"
15907 fi # NUMCOND
15909 esac
15910 PORT=$((PORT+1))
15911 N=$((N+1))
15913 # Test if Socat makes the sniffing file descriptos (-r, -R) CLOEXEC to not leak
15914 # them to EXEC'd program
15915 NAME=EXEC_SNIFF
15916 case "$TESTS" in
15917 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%filan%*|*%$NAME%*)
15918 TEST="$NAME: Socat does not leak sniffing FDs"
15919 # Run Socat sniffing both directions, with EXEC address,
15920 # execute Filan to display its file descriptors
15921 # Test succeeds when only FDs 0, 1, 2 are in use.
15922 if ! eval $NUMCOND; then :;
15923 elif ! a=$(testaddrs STDIO EXEC); then
15924 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
15925 numCANT=$((numCANT+1))
15926 listCANT="$listCANT $N"
15927 elif ! o=$(testoptions stderr) >/dev/null; then
15928 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15929 numCANT=$((numCANT+1))
15930 listCANT="$listCANT $N"
15931 else
15932 tf="$td/test$N.stdout"
15933 te="$td/test$N.stderr"
15934 tdiff="$td/test$N.diff"
15935 da="test$N $(date) $RANDOM"
15936 CMD="$TRACE $SOCAT $opts -r $td/test$N.-r -R $td/test$N.-R - EXEC:\"$FILAN -s\""
15937 printf "test $F_n $TEST... " $N
15938 eval "$CMD" >"${tf}" 2>"${te}"
15939 # "door" is a special FD type on Solaris/SunOS
15940 if [ "$(cat "${tf}" |grep -v ' door ' |wc -l)" -eq 3 ]; then
15941 $PRINTF "$OK\n"
15942 if [ "$VERBOSE" ]; then echo "$CMD"; fi
15943 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
15944 numOK=$((numOK+1))
15945 listOK="$listOK $N"
15946 else
15947 $PRINTF "$FAILED\n"
15948 echo "$CMD" >&2
15949 cat "${te}" >&2
15950 cat "${tf}" >&2
15951 numFAIL=$((numFAIL+1))
15952 listFAIL="$listFAIL $N"
15954 fi # NUMCOND
15956 esac
15957 PORT=$((PORT+1))
15958 N=$((N+1))
15961 while read KEYW FEAT RUNS ADDR IPPORT; do
15962 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
15963 PROTO=$KEYW
15964 proto="$(tolower "$PROTO")"
15965 feat="$(tolower "$FEAT")"
15966 # test the fork option on really RECVFROM oriented sockets
15967 NAME=${KEYW}_FORK
15968 case "$TESTS" in
15969 *%$N%*|*%functions%*|*%fork%*|*%$feat%*|*%$proto%*|*%socket%*|*%$NAME%*)
15970 TEST="$NAME: ${KEYW}-RECVFROM with fork option"
15971 # Start a RECVFROM process with fork option and SYSTEM address where clients
15972 # data determines the sleep time; send a record with sleep before storing the
15973 # data, then send a record with 0 sleep before storing data.
15974 # When the second record is stored before the first one the test succeeded.
15975 if ! eval $NUMCOND; then :;
15976 elif ! F=$(testfeats $FEAT STDIO SYSTEM); then
15977 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
15978 numCANT=$((numCANT+1))
15979 listCANT="$listCANT $N"
15980 elif ! A=$(testaddrs - STDIO SYSTEM $PROTO-RECVFROM $PROTO-SENDTO); then
15981 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
15982 numCANT=$((numCANT+1))
15983 listCANT="$listCANT $N"
15984 elif ! o=$(testoptions fork ) >/dev/null; then
15985 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
15986 numCANT=$((numCANT+1))
15987 listCANT="$listCANT $N"
15988 elif ! runs$RUNS >/dev/null; then
15989 $PRINTF "test $F_n $TEST... ${YELLOW}$(toupper $RUNS) not available${NORMAL}\n" $N
15990 numCANT=$((numCANT+1))
15991 listCANT="$listCANT $N"
15992 else
15993 case "X$IPPORT" in
15994 "XPORT")
15995 newport $proto
15996 tsl=$PORT # test socket listen address
15997 tsc="$ADDR:$PORT" # test socket connect address
16000 tsl="$(eval echo "$ADDR")" # resolve $N
16001 tsc=$tsl
16002 esac
16003 #ts="$td/test$N.sock"
16004 tf="$td/test$N.stdout"
16005 te="$td/test$N.stderr"
16006 tdiff="$td/test$N.diff"
16007 da="test$N $(date) $RANDOM"
16008 CMD0="$TRACE $SOCAT $opts -t $(reltime 30) $PROTO-RECVFROM:$tsl,fork,so-rcvtimeo=1 SYSTEM:'read t x; sleep \$t; echo \\\"\$x\\\" >>'\"$tf\""
16009 CMD1="$TRACE $SOCAT $opts -t $(reltime 30) - $PROTO-SENDTO:$tsc"
16010 printf "test $F_n $TEST... " $N
16011 eval $CMD0 </dev/null 2>"${te}0" &
16012 pid0=$!
16013 wait${proto}port $tsl 1
16014 echo "$(reltime 20) $da 1" |$CMD1 >"${tf}1" 2>"${te}1" &
16015 pid1=$!
16016 relsleep 10
16017 echo "$(reltime 0) $da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
16018 pid2=$!
16019 relsleep 20
16020 cpids="$(childpids $pid0 </dev/null)"
16021 kill $pid1 $pid2 $cpids $pid0 2>/dev/null
16022 wait 2>/dev/null
16023 if $ECHO "$da 2\n$da 1" |diff -u - $tf >$tdiff; then
16024 $PRINTF "$OK\n"
16025 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16026 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16027 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16028 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16029 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
16030 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
16031 numOK=$((numOK+1))
16032 listOK="$listOK $N"
16033 else
16034 $PRINTF "$FAILED\n"
16035 echo "$CMD0 &"
16036 cat "${te}0" >&2
16037 echo "$CMD1"
16038 cat "${te}1" >&2
16039 echo "$CMD2"
16040 cat "${te}2" >&2
16041 echo "diff:" >&2
16042 cat "$tdiff" >&2
16043 numFAIL=$((numFAIL+1))
16044 listFAIL="$listFAIL $N"
16045 namesFAIL="$namesFAIL $NAME"
16047 fi # NUMCOND
16049 esac
16050 N=$((N+1))
16051 done <<<"
16052 UDP4 UDP ip4 127.0.0.1 PORT
16053 UDP6 UDP ip6 [::1] PORT
16054 UNIX unix unix $td/test\$N.server -
16058 # Test if option -S turns off logging of SIGTERM
16059 NAME=SIGTERM_NOLOG
16060 case "$TESTS" in
16061 *%$N%*|*%functions%*|*%signal%*|*%$NAME%*)
16062 TEST="$NAME: Option -S can turn off logging of SIGTERM"
16063 # Start Socat with option -S 0x0000, kill it with SIGTERM
16064 # When no logging entry regarding this signal is there, the test succeeded
16065 if ! eval $NUMCOND; then :;
16066 elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
16067 $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
16068 numCANT=$((numCANT+1))
16069 listCANT="$listCANT $N"
16070 elif ! F=$(testfeats PIPE); then
16071 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
16072 numCANT=$((numCANT+1))
16073 listCANT="$listCANT $N"
16074 elif ! A=$(testaddrs PIPE); then
16075 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16076 numCANT=$((numCANT+1))
16077 listCANT="$listCANT $N"
16078 else
16079 tf="$td/test$N.stdout"
16080 te="$td/test$N.stderr"
16081 tdiff="$td/test$N.diff"
16082 CMD0="$TRACE $SOCAT $opts -S 0x0000 PIPE PIPE"
16083 printf "test $F_n $TEST... " $N
16084 $CMD0 >/dev/null 2>"${te}0" &
16085 pid0=$!
16086 relsleep 1 # give process time to start
16087 kill -TERM $pid0 2>/dev/null
16088 wait 2>/dev/null
16089 if ! grep "exiting on signal" ${te}0 >/dev/null; then
16090 $PRINTF "$OK\n"
16091 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16092 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16093 if [ "$DEBUG" ]; then echo "kill -TERM <pid>" >&2; fi
16094 numOK=$((numOK+1))
16095 listOK="$listOK $N"
16096 else
16097 $PRINTF "$FAILED\n"
16098 echo "$CMD0 &"
16099 cat "${te}0" >&2
16100 echo "kill -TERM <pid>" >&2
16101 numFAIL=$((numFAIL+1))
16102 listFAIL="$listFAIL $N"
16103 namesFAIL="$namesFAIL $NAME"
16105 fi # NUMCOND
16107 esac
16108 N=$((N+1))
16111 # Test if option -S turns on logging of signal 31
16112 NAME=SIG31_LOG
16113 case "$TESTS" in
16114 *%$N%*|*%functions%*|*%signal%*|*%$NAME%*)
16115 TEST="$NAME: Option -S can turn on logging of signal 31"
16116 # Start Socat with option -S 0x80000000, kill it with -31
16117 # When a logging entry regarding this signal is there, the test succeeded
16118 if ! eval $NUMCOND; then :;
16119 elif ! $SOCAT -h | grep -e " -S\>" >/dev/null; then
16120 $PRINTF "test $F_n $TEST... ${YELLOW}Option -S not available${NORMAL}\n" $N
16121 numCANT=$((numCANT+1))
16122 listCANT="$listCANT $N"
16123 elif ! F=$(testfeats PIPE); then
16124 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
16125 numCANT=$((numCANT+1))
16126 listCANT="$listCANT $N"
16127 elif ! A=$(testaddrs PIPE); then
16128 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16129 numCANT=$((numCANT+1))
16130 listCANT="$listCANT $N"
16131 else
16132 tf="$td/test$N.stdout"
16133 te="$td/test$N.stderr"
16134 tdiff="$td/test$N.diff"
16135 da="test$N $(date) $RANDOM"
16136 CMD0="$TRACE $SOCAT $opts -S 0x80000000 PIPE PIPE"
16137 printf "test $F_n $TEST... " $N
16138 $CMD0 >/dev/null 2>"${te}0" &
16139 pid0=$!
16140 relsleep 1 # give process time to start
16141 kill -31 $pid0 2>/dev/null; wait
16142 if grep "exiting on signal" ${te}0 >/dev/null; then
16143 $PRINTF "$OK\n"
16144 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16145 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16146 if [ "$DEBUG" ]; then echo "kill -31 <pid>" >&2; fi
16147 numOK=$((numOK+1))
16148 listOK="$listOK $N"
16149 else
16150 $PRINTF "$FAILED\n"
16151 echo "$CMD0 &"
16152 cat "${te}0" >&2
16153 echo "kill -31 <pid>" >&2
16154 numFAIL=$((numFAIL+1))
16155 listFAIL="$listFAIL $N"
16156 namesFAIL="$namesFAIL $NAME"
16158 fi # NUMCOND
16160 esac
16161 N=$((N+1))
16164 # Test the http-version of the PROXY-CONNECT address
16165 NAME=PROXY_HTTPVERSION
16166 case "$TESTS" in
16167 *%$N%*|*%functions%*|*%proxy%*|*%$NAME%*)
16168 TEST="$NAME: PROXY-CONNECT with option http-version"
16169 if ! eval $NUMCOND; then :;
16170 elif ! $(type proxyecho.sh >/dev/null 2>&1); then
16171 $PRINTF "test $F_n $TEST... ${YELLOW}proxyecho.sh not available${NORMAL}\n" $N
16172 numCANT=$((numCANT+1))
16173 listCANT="$listCANT $N"
16174 elif ! F=$(testfeats IP4 TCP LISTEN EXEC STDIO PROXY); then
16175 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured${NORMAL}\n" $N
16176 numCANT=$((numCANT+1))
16177 listCANT="$listCANT $N"
16178 elif ! A=$(testaddrs TCP4-LISTEN EXEC STDIO PROXY-CONNECT); then
16179 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16180 numCANT=$((numCANT+1))
16181 listCANT="$listCANT $N"
16182 elif ! o=$(testoptions so-reuseaddr crlf pf proxyport http-version) >/dev/null; then
16183 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16184 numCANT=$((numCANT+1))
16185 listCANT="$listCANT $N"
16186 elif ! runsip4 >/dev/null; then
16187 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16188 numCANT=$((numCANT+1))
16189 listCANT="$listCANT $N"
16190 else
16191 ts="$td/test$N.sh"
16192 tf="$td/test$N.stdout"
16193 te="$td/test$N.stderr"
16194 tdiff="$td/test$N.diff"
16195 da="test$N $(date) $RANDOM"; da="$da$($ECHO '\r')"
16196 CMD0="$TRACE $SOCAT $opts TCP4-L:$PORT,reuseaddr,crlf EXEC:\"/usr/bin/env bash proxyecho.sh -V 1.1\""
16197 CMD1="$TRACE $SOCAT $opts - PROXY:$LOCALHOST:127.0.0.1:1000,pf=ip4,proxyport=$PORT,http-version=1.1"
16198 printf "test $F_n $TEST... " $N
16199 eval "$CMD0 2>\"${te}1\" &"
16200 pid=$! # background process id
16201 waittcp4port $PORT 1
16202 echo "$da" |$CMD1 >"$tf" 2>"${te}0"
16203 if ! echo "$da" |diff - "$tf" >"$tdiff"; then
16204 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
16205 echo "$CMD0 &"
16206 cat "${te}0" >&2
16207 echo "$CMD1"
16208 cat "${te}1" >&2
16209 echo "diff:" >&2
16210 cat "$tdiff" >&2
16211 numFAIL=$((numFAIL+1))
16212 listFAIL="$listFAIL $N"
16213 else
16214 $PRINTF "$OK\n"
16215 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16216 if [ "$debug" ]; then cat "${te}0" >&2; fi
16217 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16218 if [ "$debug" ]; then cat "${te}1" >&2; fi
16219 numOK=$((numOK+1))
16220 listOK="$listOK $N"
16222 kill $pid 2>/dev/null
16223 wait
16224 fi ;; # NUMCOND, feats
16225 esac
16226 PORT=$((PORT+1))
16227 N=$((N+1))
16230 # Test the so-rcvtimeo address option with DTLS
16231 NAME=RCVTIMEO_DTLS
16232 case "$TESTS" in
16233 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udp%*|*%timeout%*|*%openssl%*|*%dtls%*|*%$NAME%*)
16234 TEST="$NAME: test the so-rcvtimeo option with DTLS"
16235 if ! eval $NUMCOND; then :;
16236 elif ! F=$(testfeats STDIO OPENSSL); then
16237 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
16238 numCANT=$((numCANT+1))
16239 listCANT="$listCANT $N"
16240 elif ! A=$(testaddrs STDIO DTLS); then
16241 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16242 numCANT=$((numCANT+1))
16243 listCANT="$listCANT $N"
16244 elif ! o=$(testoptions verify so-rcvtimeo) >/dev/null; then
16245 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16246 numCANT=$((numCANT+1))
16247 listCANT="$listCANT $N"
16248 elif ! runsip4 >/dev/null; then
16249 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16250 numCANT=$((numCANT+1))
16251 listCANT="$listCANT $N"
16252 else
16253 # We need a hanging connection attempt, guess an address for this
16254 HANGIP=0.0.0.1
16255 te1="$td/test$N.stderr1"
16256 tk1="$td/test$N.kill1"
16257 te2="$td/test$N.stderr2"
16258 tk2="$td/test$N.kill2"
16259 $PRINTF "test $F_n $TEST... " $N
16260 # First, try to make socat hang and see if it can be killed
16261 CMD1="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0"
16262 $CMD1 >"$te1" 2>$te1 </dev/null &
16263 pid1=$!
16264 relsleep 2
16265 if ! kill -0 $pid1 2>"$tk1"; then
16266 $PRINTF "${YELLOW}does not hang${NORMAL}\n"
16267 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
16268 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16269 numCANT=$((numCANT+1))
16270 listCANT="$listCANT $N"
16271 wait
16272 else
16273 # DTLS restarts read() a few times
16274 while kill $pid1 2>/dev/null; do :; done
16275 # Second, set so-rcvtimeo and see if Socat exits before kill
16276 CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=$(reltime 1)"
16277 $CMD2 >"$te1" 2>$te2 </dev/null &
16278 pid2=$!
16279 relsleep 8 # in OpenSSL 1.1.1f DTLS takes two timeouts
16280 if kill $pid2 2>"$tk2"; then
16281 $PRINTF "$FAILED\n"
16282 echo "$CMD2" >&2
16283 cat "$te2" >&2
16284 cat "$tk2" >&2
16285 numFAIL=$((numFAIL+1))
16286 listFAIL="$listFAIL $N"
16287 while kill $pid2 2>/dev/null; do :; done
16288 wait
16289 else
16290 $PRINTF "$OK\n"
16291 if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
16292 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
16293 numOK=$((numOK+1))
16294 listOK="$listOK $N"
16297 wait
16298 fi ;; # testfeats, NUMCOND
16299 esac
16300 N=$((N+1))
16303 # Test the use of interesting variables in the sniffing file names
16304 NAME=VARS_IN_SNIFFPATH
16305 case "$TESTS" in
16306 *%$N%*|*%functions%*|*%socket%*|*%listen%*|*%fork%*|*%$NAME%*)
16307 TEST="$NAME: sniff file names with variables"
16308 # Start a server process with option fork that sniffs traffic and stores it in
16309 # two files for each child process, using PID, timestamp, microseconds, and
16310 # client IP
16311 # Connect two times.
16312 # For now we say that the test succeeded when 4 log files have been generated.
16313 if ! eval $NUMCOND; then :;
16314 elif ! A=$(testfeats IP4 TCP LISTEN PIPE STDIO); then
16315 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16316 numCANT=$((numCANT+1))
16317 listCANT="$listCANT $N"
16318 elif ! A=$(testaddrs - TCP4 TCP4-LISTEN PIPE STDIO); then
16319 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16320 numCANT=$((numCANT+1))
16321 listCANT="$listCANT $N"
16322 elif ! o=$(testoptions so-reuseaddr fork) >/dev/null; then
16323 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16324 numCANT=$((numCANT+1))
16325 listCANT="$listCANT $N"
16326 elif ! runsip4 >/dev/null; then
16327 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16328 numCANT=$((numCANT+1))
16329 listCANT="$listCANT $N"
16330 else
16331 tf="$td/test$N.stdout"
16332 te="$td/test$N.stderr"
16333 tdiff="$td/test$N.diff"
16334 da="test$N $(date) $RANDOM"
16335 newport tcp4
16336 CMD0="$TRACE $SOCAT $opts -T 1 -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"
16337 CMD1="$TRACE $SOCAT $opts - TCP4-CONNECT:$LOCALHOST:$PORT"
16338 printf "test $F_n $TEST... " $N
16339 eval "$CMD0" >/dev/null 2>"${te}0" &
16340 pid0=$!
16341 waittcp4port $PORT 1
16342 echo "$da" |$CMD1 >"${tf}1a" 2>"${te}1a"
16343 rc1a=$?
16344 echo "$da" |$CMD1 >"${tf}1b" 2>"${te}1b"
16345 rc1b=$?
16346 kill $(childpids $pid0) $pid0 2>/dev/null
16347 wait 2>/dev/null
16348 if [ $rc1a != 0 -o $rc1b != 0 ]; then
16349 $PRINTF "$FAILED (client problem)\n"
16350 echo "$CMD0 &"
16351 cat "${te}0" >&2
16352 echo "$CMD1"
16353 cat "${te}1a" >&2
16354 echo "$CMD1"
16355 cat "${te}1b" >&2
16356 numFAIL=$((numFAIL+1))
16357 listFAIL="$listFAIL $N"
16358 namesFAIL="$namesFAIL $NAME"
16359 elif test $(ls -l $td/test$N.*.log |wc -l) -eq 4 &&
16360 test $(ls $td/test$N.*.log |head -n 1 |wc -c) -ge 56; then
16361 # Are the names correct?
16362 # Convert timestamps to epoch and compare
16363 # Are the contents correct?
16364 $PRINTF "$OK\n"
16365 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16366 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16367 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16368 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
16369 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16370 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
16371 numOK=$((numOK+1))
16372 listOK="$listOK $N"
16373 elif test -f $td/test$N.\$PROGNAME-\$TIMESTAMP.\$MICROS-\$SERVER0_PEERADDR-\$\$.in.log; then
16374 $PRINTF "$FAILED (vars not resolved)\n"
16375 echo "$CMD0 &"
16376 cat "${te}0" >&2
16377 echo "$CMD1"
16378 cat "${te}1a" >&2
16379 echo "$CMD1"
16380 cat "${te}1b" >&2
16381 numFAIL=$((numFAIL+1))
16382 listFAIL="$listFAIL $N"
16383 namesFAIL="$namesFAIL $NAME"
16384 else
16385 $PRINTF "$FAILED (unknown)\n"
16386 echo "$CMD0 &"
16387 cat "${te}0" >&2
16388 echo "$CMD1"
16389 cat "${te}1a" >&2
16390 echo "$CMD1"
16391 cat "${te}1b" >&2
16392 numFAIL=$((numFAIL+1))
16393 listFAIL="$listFAIL $N"
16394 namesFAIL="$namesFAIL $NAME"
16396 fi # NUMCOND
16398 esac
16399 N=$((N+1))
16402 # Test logging of statistics on Socat option --statistics
16403 NAME=OPTION_STATISTICS
16404 case "$TESTS" in
16405 *%$N%*|*%functions%*|*%stats%*|*%system%*|*%stdio%*|*%$NAME%*)
16406 TEST="$NAME: Socat option --statistics"
16407 # Invoke Socat with option --statistics, transfer some date, and check the log
16408 # file for the values
16409 if ! eval $NUMCOND; then :;
16410 elif ! $(type >/dev/null 2>&1); then
16411 $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N
16412 numCANT=$((numCANT+1))
16413 listCANT="$listCANT $N"
16414 elif ! F=$(testfeats STATS STDIO SYSTEM); then
16415 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16416 numCANT=$((numCANT+1))
16417 listCANT="$listCANT $N"
16418 elif ! A=$(testaddrs STDIO SYSTEM); then
16419 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16420 numCANT=$((numCANT+1))
16421 listCANT="$listCANT $N"
16422 elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then
16423 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16424 numCANT=$((numCANT+1))
16425 listCANT="$listCANT $N"
16426 else
16427 tf="$td/test$N.stdout"
16428 te="$td/test$N.stderr"
16429 tdiff="$td/test$N.diff"
16430 da="test$N $(date) $RANDOM"
16431 CMD0="$TRACE $SOCAT $opts --statistics STDIO SYSTEM:'tee /dev/stdout',pty,cfmakeraw"
16432 printf "test $F_n $TEST... " $N
16433 echo "$da" |eval "$CMD0" >"${tf}0" 2>"${te}0"
16434 rc0=$?
16435 if [ $rc0 -ne 0 ]; then
16436 # The test could not run meaningfully
16437 $PRINTF "$CANT\n"
16438 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
16439 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16440 numCANT=$((numCANT+1))
16441 listCANT="$listCANT $N"
16442 elif [ $(grep STATISTICS "${te}0" |wc -l) -eq 2 ]; then
16443 $PRINTF "$OK\n"
16444 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
16445 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16446 numOK=$((numOK+1))
16447 listOK="$listOK $N"
16448 else
16449 $PRINTF "$FAILED\n"
16450 echo "$CMD0 &"
16451 cat "${te}0" >&2
16452 numFAIL=$((numFAIL+1))
16453 listFAIL="$listFAIL $N"
16454 namesFAIL="$namesFAIL $NAME"
16456 fi # NUMCOND
16458 esac
16459 N=$((N+1))
16461 # Test logging of statistics on SIGUSR1
16462 NAME=SIGUSR1_STATISTICS
16463 case "$TESTS" in
16464 *%$N%*|*%functions%*|*%signal%*|*%stats%*|*%system%*|*%stdio%*|*%$NAME%*)
16465 TEST="$NAME: statistics on SIGUSR1"
16466 # Invoke Socat without option --statistics, transfer some date, send signal
16467 # USR1,and check the log file for the values
16468 if ! eval $NUMCOND; then :;
16469 elif ! $(type tee >/dev/null 2>&1); then
16470 $PRINTF "test $F_n $TEST... ${YELLOW}tee not available${NORMAL}\n" $N
16471 numCANT=$((numCANT+1))
16472 listCANT="$listCANT $N"
16473 elif ! $(type pkill >/dev/null 2>&1); then
16474 $PRINTF "test $F_n $TEST... ${YELLOW}pkill not available${NORMAL}\n" $N
16475 numCANT=$((numCANT+1))
16476 listCANT="$listCANT $N"
16477 elif ! F=$(testfeats STATS STDIO SYSTEM); then
16478 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16479 numCANT=$((numCANT+1))
16480 listCANT="$listCANT $N"
16481 elif ! A=$(testaddrs STDIO SYSTEM); then
16482 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16483 numCANT=$((numCANT+1))
16484 listCANT="$listCANT $N"
16485 elif ! o=$(testoptions pty cfmakeraw) >/dev/null; then
16486 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16487 numCANT=$((numCANT+1))
16488 listCANT="$listCANT $N"
16489 else
16490 tf="$td/test$N.stdout"
16491 te="$td/test$N.stderr"
16492 tdiff="$td/test$N.diff"
16493 da="test$N $(date) $RANDOM"
16494 CMD0="$TRACE $SOCAT $opts STDIO SYSTEM:'tee /dev/stdout 2>/dev/null',pty,cfmakeraw"
16495 #set -vx
16496 printf "test $F_n $TEST... " $N
16497 { echo "$da"; relsleep 10; } |eval "$CMD0" >"${tf}0" 2>"${te}0" &
16498 pid0=$!
16499 relsleep 2
16500 TTY=$(tty |sed 's|/dev/||')
16501 pkill -USR1 -t $TTY socat || { echo "pkill -t $TTY -USR1 socat"; }
16502 relsleep 2
16503 pkill -t $TTY socat
16504 wait
16505 if [ "$(grep STATISTICS "${te}0" |wc -l)" -eq 2 ]; then
16506 $PRINTF "$OK\n"
16507 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
16508 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16509 numOK=$((numOK+1))
16510 listOK="$listOK $N"
16511 else
16512 $PRINTF "$FAILED\n"
16513 echo "$CMD0 &"
16514 cat "${te}0" >&2
16515 numFAIL=$((numFAIL+1))
16516 listFAIL="$listFAIL $N"
16517 namesFAIL="$namesFAIL $NAME"
16519 fi # NUMCOND
16521 esac
16522 N=$((N+1))
16525 # Test the children-shutup option
16526 NAME=CHILDREN_SHUTUP
16527 case "$TESTS" in
16528 *%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*)
16529 TEST="$NAME: test the children-shutup option"
16530 # Run a UNIX domain listening server with options fork and children-shutup, and
16531 # that connects to a closed TCP4 port.
16532 # Connect to the server and check if it logs the TCP4-CONNECT failure as warning.
16533 if ! eval $NUMCOND; then :;
16534 elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then
16535 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16536 numCANT=$((numCANT+1))
16537 listCANT="$listCANT $N"
16538 elif ! A=$(testaddrs UNIX-LISTEN TCP4 FILE UNIX-CONNECT); then
16539 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
16540 numCANT=$((numCANT+1))
16541 listCANT="$listCANT $N"
16542 elif ! o=$(testoptions fork children-shutup) >/dev/null; then
16543 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
16544 numCANT=$((numCANT+1))
16545 listCANT="$listCANT $N"
16546 else
16547 newport tcp4
16548 ts="$td/test$N.sock"
16549 tf="$td/test$N.stdout"
16550 te="$td/test$N.stderr"
16551 tdiff="$td/test$N.diff"
16552 da="test$N $(date) $RANDOM"
16553 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,fork,children-shutup TCP4:localhost:$PORT"
16554 CMD1="$TRACE $SOCAT $opts -u FILE:/dev/null UNIX-CONNECT:$ts"
16555 printf "test $F_n $TEST... " $N
16556 $CMD0 >/dev/null 2>"${te}0" &
16557 pid0=$!
16558 waitunixport $ts 1
16559 { $CMD1 2>"${te}1"; sleep 1; }
16560 rc1=$?
16561 kill $pid0 2>/dev/null; wait
16562 relsleep 1 # child process might need more time
16563 if grep -q " W connect" ${te}0; then
16564 $PRINTF "$OK\n"
16565 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16566 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16567 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16568 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16569 numOK=$((numOK+1))
16570 listOK="$listOK $N"
16571 else
16572 $PRINTF "$FAILED\n"
16573 echo "$CMD0 &"
16574 cat "${te}0" >&2
16575 echo "$CMD1"
16576 cat "${te}1" >&2
16577 numFAIL=$((numFAIL+1))
16578 listFAIL="$listFAIL $N"
16579 namesFAIL="$namesFAIL $NAME"
16581 fi # NUMCOND
16583 esac
16584 N=$((N+1))
16587 # Socats INTERFACE address has to ignore outgoing packets if possible.
16588 # On Linux is uses socket option PACKET_IGNORE_OUTGOING or it queries per
16589 # packet the PACKET_OUTGOING flag of struct sockaddr_ll.sll_pkttype
16590 NAME=INTERFACE_IGNOREOUTGOING
16591 case "$TESTS" in
16592 *%$N%*|*%functions%*|*%interface%*|*%tun%*|*%root%*|*%$NAME%*)
16593 TEST="$NAME: INTERFACE ignores outgoing packets"
16594 #idea: create a TUN interface and hook with INTERFACE.
16595 # Send a packet out the interface, should not be seen by INTERFACE
16596 if ! eval $NUMCOND; then :;
16597 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
16598 $PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
16599 numCANT=$((numCANT+1))
16600 listCANT="$listCANT $N"
16601 elif ! $(type ping >/dev/null 2>&1); then
16602 $PRINTF "test $F_n $TEST... ${YELLOW}ping not available${NORMAL}\n" $N
16603 numCANT=$((numCANT+1))
16604 listCANT="$listCANT $N"
16605 elif ! feat=$(testfeats TUN STDIO INTERFACE); then
16606 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
16607 numCANT=$((numCANT+1))
16608 listCANT="$listCANT $N"
16609 elif ! A=$(testaddrs - TUN STDIO INTERFACE); then
16610 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16611 numCANT=$((numCANT+1))
16612 listCANT="$listCANT $N"
16613 elif ! o=$(testoptions iff-up tun-type tun-name ) >/dev/null; then
16614 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16615 numCANT=$((numCANT+1))
16616 listCANT="$listCANT $N"
16617 elif ! runsip4 >/dev/null; then
16618 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16619 numCANT=$((numCANT+1))
16620 listCANT="$listCANT $N"
16621 else
16622 tf="$td/test$N.stdout"
16623 te="$td/test$N.stderr"
16624 tdiff="$td/test$N.diff"
16625 tl="$td/test$N.lock"
16626 da="$(date) $RANDOM"
16627 TUNNET=10.255.255
16628 TUNNAME=tun9
16629 CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME -"
16630 CMD1="$TRACE $SOCAT $opts -u INTERFACE:$TUNNAME -"
16631 CMD2="ping -c 1 -w 1 -b $TUNNET.255"
16632 printf "test $F_n $TEST... " $N
16633 sleep 1 |$CMD0 2>"${te}0" >/dev/null &
16634 pid0="$!"
16635 #waitinterface "$TUNNAME"
16636 relsleep 1
16637 $CMD1 >"${tf}1" 2>"${te}1" &
16638 pid1="$!"
16639 relsleep 1
16640 $CMD2 2>"${te}2" 1>&2
16641 kill $pid1 2>/dev/null
16642 relsleep 1
16643 kill $pid0 2>/dev/null
16644 wait
16645 if [ $? -ne 0 ]; then
16646 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
16647 echo "$CMD0 &"
16648 cat "${te}0" >&2
16649 echo "$CMD1"
16650 cat "${te}1" >&2
16651 echo "$CMD2"
16652 cat "${te}2" >&2
16653 numCANT=$((numCANT+1))
16654 listCANT="$listCANT $N"
16655 elif test -s "${tf}1"; then
16656 $PRINTF "$FAILED\n"
16657 echo "$CMD0 &"
16658 cat "${te}0" >&2
16659 echo "$CMD1"
16660 cat "${te}1" >&2
16661 echo "$CMD2"
16662 cat "${te}2" >&2
16663 numFAIL=$((numFAIL+1))
16664 listFAIL="$listFAIL $N"
16665 else
16666 $PRINTF "$OK\n"
16667 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
16668 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
16669 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16670 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16671 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
16672 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
16673 numOK=$((numOK+1))
16674 listOK="$listOK $N"
16676 fi ;; # NUMCOND, feats
16677 esac
16678 PORT=$((PORT+1))
16679 N=$((N+1))
16682 # Test if the SO_REUSEADDR socket option is applied automatically to TCP LISTEN
16683 # type addresses.
16684 NAME=TCP4_REUSEADDR
16685 case "$TESTS" in
16686 *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*)
16687 TEST="$NAME: test if option reuseaddr's default is 1"
16688 # Start a TCP4-LISTEN server, connect with a client, have the server shutdown
16689 # the connection. Start the server on the same port again. If it starts the
16690 # test succeeded.
16691 if ! eval $NUMCOND; then :;
16692 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
16693 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16694 numCANT=$((numCANT+1))
16695 listCANT="$listCANT $N"
16696 elif ! A=$(testaddrs STDIO PIPE TCP4 TCP4-LISTEN); then
16697 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16698 numCANT=$((numCANT+1))
16699 listCANT="$listCANT $N"
16700 elif ! o=$(testoptions accept-timeout) >/dev/null; then
16701 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16702 numCANT=$((numCANT+1))
16703 listCANT="$listCANT $N"
16704 elif ! runsip4 >/dev/null; then
16705 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16706 numCANT=$((numCANT+1))
16707 listCANT="$listCANT $N"
16708 else
16709 tf="$td/test$N.stdout"
16710 te="$td/test$N.stderr"
16711 tdiff="$td/test$N.diff"
16712 da="test$N $(date) $RANDOM"
16713 newport tcp4
16714 CMD0a="$TRACE $SOCAT $opts -T 0.1 TCP4-LISTEN:$PORT PIPE"
16715 CMD0b="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,accept-timeout=0.1 PIPE"
16716 CMD1="$TRACE $SOCAT $opts STDIO TCP4-CONNECT:$LOCALHOST:$PORT"
16717 printf "test $F_n $TEST... " $N
16718 $CMD0a >/dev/null 2>"${te}0a" &
16719 pid0=$!
16720 waittcp4port $PORT 1
16721 $CMD1 >"${tf}1" 2>"${te}1"
16722 rc1=$?
16723 kill $pid0 2>/dev/null; wait
16724 $CMD0b >/dev/null 2>"${te}0b"
16725 rc0b=$?
16726 if [ $rc0b -eq 0 ]; then
16727 $PRINTF "$OK\n"
16728 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16729 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16730 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16731 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16732 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16733 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16734 numOK=$((numOK+1))
16735 listOK="$listOK $N"
16736 else
16737 $PRINTF "$FAILED\n"
16738 echo "$CMD0a &"
16739 cat "${te}0a" >&2
16740 echo "$CMD1"
16741 cat "${te}1" >&2
16742 echo "$CMD0b"
16743 cat "${te}0b" >&2
16744 numFAIL=$((numFAIL+1))
16745 listFAIL="$listFAIL $N"
16746 namesFAIL="$namesFAIL $NAME"
16748 fi # NUMCOND
16750 esac
16751 N=$((N+1))
16753 # Test if the SO_REUSEADDR socket option is applied automatically to OPENSSL LISTEN
16754 # type addresses.
16755 NAME=OPENSSL_6_REUSEADDR
16756 case "$TESTS" in
16757 *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip6%*|*%tcp%*|*%tcp6%*|*%listen%*|*%openssl%*|*%$NAME%*)
16758 TEST="$NAME: test if option reuseaddr's default is 1 with SSL-L"
16759 # Start an OPENSSL-LISTEN server using TCP on IPv6, connect with a client, have
16760 # the server shutdown the connection. Start the server on the same port again.
16761 # If it starts the test succeeded.
16762 if ! eval $NUMCOND; then :;
16763 elif ! F=$(testfeats PIPE IP6 TCP OPENSSL LISTEN); then
16764 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16765 numCANT=$((numCANT+1))
16766 listCANT="$listCANT $N"
16767 elif ! A=$(testaddrs PIPE OPENSSL-CONNECT OPENSSL-LISTEN); then
16768 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16769 numCANT=$((numCANT+1))
16770 listCANT="$listCANT $N"
16771 elif ! o=$(testoptions verify cert key) >/dev/null; then
16772 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16773 numCANT=$((numCANT+1))
16774 listCANT="$listCANT $N"
16775 elif ! runsip6 >/dev/null; then
16776 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available${NORMAL}\n" $N
16777 numCANT=$((numCANT+1))
16778 listCANT="$listCANT $N"
16779 else
16780 tf="$td/test$N.stdout"
16781 te="$td/test$N.stderr"
16782 tdiff="$td/test$N.diff"
16783 da="test$N $(date) $RANDOM"
16784 printf "test $F_n $TEST... " $N
16785 newport tcp6
16786 # Yup, it seems that with OpenSSL the side that begins with shutdown does NOT
16787 # begin shutdown of the TCP connection
16788 # therefore we let the client timeout
16789 # result is not reliable (OK seen even without any SO_REUSEADDR)
16790 CMD0a="$TRACE $SOCAT $opts -lp server1 -6 OPENSSL-LISTEN:$PORT,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
16791 CMD0b="$TRACE $SOCAT $opts -lp server2 -6 OPENSSL-LISTEN:$PORT,accept-timeout=.01,cert=testsrv.crt,key=testsrv.key,verify=0 PIPE"
16792 CMD1="$TRACE $SOCAT $opts -lp client -6 -T 0.1 PIPE OPENSSL-CONNECT:$LOCALHOST6:$PORT,verify=0"
16793 $CMD0a >/dev/null 2>"${te}0a" &
16794 pid0=$!
16795 waittcp6port $PORT 1
16796 $CMD1 >"${tf}1" 2>"${te}1"
16797 rc1=$?
16798 kill $pid0 2>/dev/null; wait
16799 $CMD0b >/dev/null 2>"${te}0b"
16800 rc0b=$?
16801 if [ $rc0b -eq 0 ]; then
16802 $PRINTF "$OK\n"
16803 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16804 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16805 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16806 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16807 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16808 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16809 numOK=$((numOK+1))
16810 listOK="$listOK $N"
16811 else
16812 $PRINTF "$FAILED\n"
16813 echo "$CMD0a &"
16814 cat "${te}0a" >&2
16815 echo "$CMD1"
16816 cat "${te}1" >&2
16817 echo "$CMD0b"
16818 cat "${te}0b" >&2
16819 numFAIL=$((numFAIL+1))
16820 listFAIL="$listFAIL $N"
16821 namesFAIL="$namesFAIL $NAME"
16823 fi # NUMCOND
16825 esac
16826 N=$((N+1))
16828 # Test if the so-reuseaddr= option prevents the SO_REUSEADDR socket option
16829 NAME=REUSEADDR_NULL
16830 case "$TESTS" in
16831 *%$N%*|*%functions%*|*%socket%*|*%ip%*|*%ip4%*|*%tcp%*|*%tcp4%*|*%listen%*|*%$NAME%*)
16832 TEST="$NAME: test option reuseaddr without value"
16833 # Start a TCP4-LISTEN server with so-reuseaddr=, connect with a client, have
16834 # the server shutdown the connection.
16835 # Start the server on the same port again. If it fails with
16836 # "Address already in use" the test succeeded.
16837 if ! eval $NUMCOND; then :;
16838 elif ! F=$(testfeats STDIO PIPE IP4 TCP LISTEN); then
16839 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
16840 numCANT=$((numCANT+1))
16841 listCANT="$listCANT $N"
16842 elif ! A=$(testaddrs STDIO PIPE TCP4-CONNECT TCP4-LISTEN); then
16843 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16844 numCANT=$((numCANT+1))
16845 listCANT="$listCANT $N"
16846 elif ! o=$(testoptions so-reuseaddr accept-timeout) >/dev/null; then
16847 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
16848 numCANT=$((numCANT+1))
16849 listCANT="$listCANT $N"
16850 elif ! runsip4 >/dev/null; then
16851 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16852 numCANT=$((numCANT+1))
16853 listCANT="$listCANT $N"
16854 else
16855 tf="$td/test$N.stdout"
16856 te="$td/test$N.stderr"
16857 tdiff="$td/test$N.diff"
16858 da="test$N $(date) $RANDOM"
16859 newport tcp4
16860 CMD0a="$TRACE $SOCAT $opts -T 0.1 TCP4-LISTEN:$PORT,so-reuseaddr= PIPE"
16861 CMD0b="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,accept-timeout=0.1 PIPE"
16862 CMD1="$TRACE $SOCAT $opts STDIO TCP4-CONNECT:$LOCALHOST:$PORT"
16863 printf "test $F_n $TEST... " $N
16864 $CMD0a >/dev/null 2>"${te}0a" &
16865 pid0=$!
16866 waittcp4port $PORT 1
16867 $CMD1 >"${tf}1" 2>"${te}1"
16868 rc1=$?
16869 kill $pid0 2>/dev/null; wait
16870 $CMD0b >/dev/null 2>"${te}0b"
16871 rc0b=$?
16872 if [ $rc0b -eq 1 ] && grep -q -e "Address already in use" -e "Address in use" "${te}0b"; then
16873 $PRINTF "$OK\n"
16874 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16875 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16876 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16877 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16878 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16879 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16880 numOK=$((numOK+1))
16881 listOK="$listOK $N"
16882 #elif grep -q "accept: \(Connection\|Operation\) timed out" "${te}0b"; then
16883 elif grep -q "accept: .* timed out" "${te}0b"; then
16884 # FreeBSD, Solaris do not seem to need SO_REUSEADDR with TCP at all
16885 $PRINTF "$CANT\n"
16886 if [ "$VERBOSE" ]; then echo "$CMD0a &"; fi
16887 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
16888 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
16889 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
16890 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
16891 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
16892 numCANT=$((numCANT+1))
16893 listCANT="$listCANT $N"
16894 else
16895 $PRINTF "$FAILED\n"
16896 echo "$CMD0a &"
16897 cat "${te}0a" >&2
16898 echo "$CMD1"
16899 cat "${te}1" >&2
16900 echo "$CMD0b"
16901 cat "${te}0b" >&2
16902 numFAIL=$((numFAIL+1))
16903 listFAIL="$listFAIL $N"
16904 namesFAIL="$namesFAIL $NAME"
16906 fi # NUMCOND
16908 esac
16909 N=$((N+1))
16912 # Test if Socats TCP4-client tries all addresses if necessary
16913 NAME=TRY_ADDRS_4
16914 case "$TESTS" in
16915 *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%socket%*|*%internet%*|*%$NAME%*)
16916 TEST="$NAME: try all available TCP4 addresses"
16917 # Connect to a TCP4 port of a hostname that resolves to two addresses where at
16918 # least on the first one the port is closed.
16919 # server-4.dest-unreach.net has been configured for this purpose, it
16920 # resolves to its public address and to 127.0.0.1; unfortunately
16921 # forwarding nameservers need not keep order of A entries, so we need a port
16922 # that is closed on both addresses.
16923 # The test succeeded when the log shows that Socat tried to connect two times.
16924 if ! eval $NUMCOND; then :;
16925 elif ! $(type nslookup >/dev/null 2>&1); then
16926 $PRINTF "test $F_n $TEST... ${YELLOW}nslookup not available${NORMAL}\n" $N
16927 numCANT=$((numCANT+1))
16928 listCANT="$listCANT $N"
16929 #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
16930 # $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
16931 # numCANT=$((numCANT+1))
16932 # listCANT="$listCANT $N"
16933 elif ! F=$(testfeats IP4 TCP GOPEN); then
16934 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
16935 numCANT=$((numCANT+1))
16936 listCANT="$listCANT $N"
16937 elif ! A=$(testaddrs TCP4-CONNECT GOPEN); then
16938 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
16939 numCANT=$((numCANT+1))
16940 listCANT="$listCANT $N"
16941 elif ! runsip4 >/dev/null; then
16942 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
16943 numCANT=$((numCANT+1))
16944 listCANT="$listCANT $N"
16945 elif [ -z "$INTERNET" ]; then
16946 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
16947 numCANT=$((numCANT+1))
16948 listCANT="$listCANT $N"
16949 else
16950 tf="$td/test$N.stdout"
16951 te="$td/test$N.stderr"
16952 tdiff="$td/test$N.diff"
16953 da="test$N $(date) $RANDOM"
16954 if type nslookup >/dev/null 2>&1; then
16955 ADDRS=$(nslookup server-4.dest-unreach.net. |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
16956 elif type host >/dev/null 2>&1; then
16957 ADDRS=$(host server-4.dest-unreach.net. |sed 's/.*address //')
16959 while true; do
16960 newport tcp4
16961 OPEN=
16962 for addr in $ADDRS; do
16963 if $SOCAT /dev/null TCP4:$addr:$PORT 2>/dev/null; then
16964 # port is open :-(
16965 OPEN=1
16966 break
16968 done
16969 if [ -z "$OPEN" ]; then
16970 break;
16972 newport tcp4
16973 done
16974 CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP4:server-4.dest-unreach.net:$PORT"
16975 printf "test $F_n $TEST... " $N
16976 $CMD >/dev/null 2>"${te}"
16977 rc=$?
16978 if [ $(grep " N opening connection to .*AF=2 " ${te} |wc -l) -eq 2 ]; then
16979 $PRINTF "$OK\n"
16980 if [ "$VERBOSE" ]; then echo "$CMD"; fi
16981 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
16982 numOK=$((numOK+1))
16983 listOK="$listOK $N"
16984 else
16985 $PRINTF "$FAILED\n"
16986 echo "$CMD"
16987 cat "${te}" >&2
16988 numFAIL=$((numFAIL+1))
16989 listFAIL="$listFAIL $N"
16990 namesFAIL="$namesFAIL $NAME"
16992 fi # NUMCOND
16994 esac
16995 N=$((N+1))
16998 # Test if Socats TCP-client tries all addresses (IPv4+IPv6) if necessary
16999 # Gives useful result only when getaddrinfo() to return both IPv4 and IPv6 addresses
17000 # Therefore it appears useful to use AI-ADDRCONFIG on non-Linux systems
17001 NAME=TRY_ADDRS_4_6
17002 case "$TESTS" in
17003 *%$N%*|*%functions%*|*%tcp%*|*%tcp4%*|*%tcp6%*|*%socket%*|*%internet%*|*%$NAME%*)
17004 TEST="$NAME: for TCP try all available IPv4 and IPv6 addresses"
17005 # Connect to a TCP port that is not open on localhost-4-6.dest-unreach.net,
17006 # neither IPv4 nor IPv6
17007 # Check the log if Socat tried both addresses
17008 if ! eval $NUMCOND; then :;
17009 #elif ! $(type nslookup >/dev/null 2>&1) && ! $(type host >/dev/null 2>&1); then
17010 # $PRINTF "test $F_n $TEST... ${YELLOW}nslookup and host not available${NORMAL}\n" $N
17011 # numCANT=$((numCANT+1))
17012 # listCANT="$listCANT $N"
17013 elif ! F=$(testfeats IP4 IP6 TCP); then
17014 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
17015 numCANT=$((numCANT+1))
17016 listCANT="$listCANT $N"
17017 elif ! A=$(testaddrs TCP-CONNECT GOPEN); then
17018 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17019 numCANT=$((numCANT+1))
17020 listCANT="$listCANT $N"
17021 elif ! o=$(testoptions ai-addrconfig) >/dev/null; then
17022 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17023 numCANT=$((numCANT+1))
17024 listCANT="$listCANT $N"
17025 elif ! runsip4 >/dev/null; then
17026 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17027 numCANT=$((numCANT+1))
17028 listCANT="$listCANT $N"
17029 elif ! runsip6 >/dev/null; then
17030 $PRINTF "test $F_n $TEST... ${YELLOW}IPv6 not available or not routable${NORMAL}\n" $N
17031 numCANT=$((numCANT+1))
17032 listCANT="$listCANT $N"
17033 elif [ -z "$INTERNET" ]; then # only needs Internet DNS
17034 $PRINTF "test $F_n $TEST... ${YELLOW}use test.sh option --internet${NORMAL}\n" $N
17035 numCANT=$((numCANT+1))
17036 listCANT="$listCANT $N"
17037 else
17038 tf="$td/test$N.stdout"
17039 te="$td/test$N.stderr"
17040 tdiff="$td/test$N.diff"
17041 da="test$N $(date) $RANDOM"
17042 LOCALHOST_4_6=localhost-4-6.dest-unreach.net
17043 if type nslookup >/dev/null 2>&1; then
17044 ADDRS=$(nslookup $LOCALHOST_4_6 |sed -n '/^$/,$ p' |grep ^Address |awk '{print($2);}')
17045 elif type host >/dev/null 2>&1; then
17046 ADDRS=$(host $LOCALHOST_4_6 |sed 's/.*address //')
17048 # Specific config: on Ubuntu-12.04: getaddrinfo(...AI_ADDRCONFIG) does not
17049 # resolve to IPv6 addresses even when there are link local IPv6 addresses
17050 if test -f /etc/os-release &&
17051 grep -q '^NAME="Ubuntu"' /etc/os-release &&
17052 grep -q '^VERSION="12\.04' /etc/os-release; then
17053 AI_ADDRCONFIG="ai-addrconfig=0,"
17054 elif [ $UNAME != 'Linux' ]; then
17055 AI_ADDRCONFIG="ai-addrconfig=0,"
17057 # Check if PORT is really closed on both addresses
17058 while true; do
17059 OPEN=
17060 for addr in $ADDRS; do
17061 case $addr in
17062 *.*) ;;
17063 *:*) addr="[$addr]" ;
17064 esac
17065 if $SOCAT /dev/null TCP:$addr:$PORT,$AI_ADDRCONFIG 2>/dev/null; then
17066 # port is open :-(
17067 OPEN=1
17068 break
17070 done
17071 if [ -z "$OPEN" ]; then
17072 break;
17074 newport tcp4
17075 done
17076 CMD="$TRACE $SOCAT $opts -d -d /dev/null TCP:$LOCALHOST_4_6:$PORT,$AI_ADDRCONFIG"
17077 printf "test $F_n $TEST... " $N
17078 $CMD >/dev/null 2>"${te}"
17079 rc=$?
17080 if [ $(grep " N opening connection to .*AF=[0-9]" ${te} |wc -l) -eq 2 ]; then
17081 $PRINTF "$OK\n"
17082 if [ "$VERBOSE" ]; then echo "$CMD"; fi
17083 if [ "$DEBUG" ]; then cat "${te}" >&2; fi
17084 numOK=$((numOK+1))
17085 listOK="$listOK $N"
17086 else
17087 $PRINTF "$FAILED\n"
17088 echo "$CMD"
17089 cat "${te}" >&2
17090 numFAIL=$((numFAIL+1))
17091 listFAIL="$listFAIL $N"
17092 namesFAIL="$namesFAIL $NAME"
17094 fi # NUMCOND
17096 esac
17097 N=$((N+1))
17100 # Test the netns (net namespace) feature
17101 NAME=NETNS
17102 case "$TESTS" in
17103 *%$N%*|*%functions%*|*%root%*|*%namespace%*|*%netns%*|*%socket%*|*%$NAME%*)
17104 ns=socat-$$-test$N
17105 TEST="$NAME: option netns (net namespace $ns)"
17106 # Start a simple echo server with option netns on localhost of a net namespace;
17107 # use a client process with option netns to send data to the net namespace
17108 # net server and check the reply.
17109 if ! eval $NUMCOND; then :;
17110 elif [ "$UNAME" != Linux ]; then
17111 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17112 numCANT=$((numCANT+1))
17113 listCANT="$listCANT $N"
17114 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
17115 $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
17116 numCANT=$((numCANT+1))
17117 listCANT="$listCANT $N"
17118 elif ! $(type ip >/dev/null 2>&1); then
17119 $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N
17120 numCANT=$((numCANT+1))
17121 listCANT="$listCANT $N"
17122 elif ! F=$(testfeats IP4 TCP LISTEN NAMESPACES); then
17123 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
17124 numCANT=$((numCANT+1))
17125 listCANT="$listCANT $N"
17126 elif ! A=$(testaddrs STDIO TCP-LISTEN TCP EXEC); then
17127 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
17128 numCANT=$((numCANT+1))
17129 listCANT="$listCANT $N"
17130 elif ! o=$(testoptions netns) >/dev/null; then
17131 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
17132 numCANT=$((numCANT+1))
17133 listCANT="$listCANT $N"
17134 elif ! runsip4 >/dev/null; then
17135 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17136 numCANT=$((numCANT+1))
17137 listCANT="$listCANT $N"
17138 else
17139 tf="$td/test$N.stdout"
17140 te="$td/test$N.stderr"
17141 tdiff="$td/test$N.diff"
17142 da="test$N $(date) $RANDOM"
17143 newport tcp4
17144 CMD0="$TRACE $SOCAT $opts --experimental TCP4-LISTEN:$PORT,netns=$ns EXEC:'od -c'"
17145 CMD1="$TRACE $SOCAT $opts --experimental - TCP4:127.0.0.1:$PORT,netns=$ns"
17146 printf "test $F_n $TEST... " $N
17147 ip netns del $ns 2>/dev/null # make sure it does not exist
17148 ip netns add $ns
17149 ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8
17150 ip netns exec $ns ip link set lo up
17151 eval "$CMD0" >/dev/null 2>"${te}0" &
17152 pid0=$!
17153 relsleep 1 # if no matching wait*port function
17154 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
17155 rc1=$?
17156 kill $pid0 2>/dev/null; wait
17157 ip netns del $ns
17158 if [ $rc1 -ne 0 ]; then
17159 $PRINTF "$FAILED (client failed)\n"
17160 echo "ip netns del $ns"
17161 echo "ip netns add $ns"
17162 echo "ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8"
17163 echo "ip netns exec $ns ip link set lo up"
17164 echo "$CMD0 &"
17165 cat "${te}0" >&2
17166 echo "$CMD1"
17167 cat "${te}1" >&2
17168 echo "ip netns del $ns"
17169 numFAIL=$((numFAIL+1))
17170 listFAIL="$listFAIL $N"
17171 namesFAIL="$namesFAIL $NAME"
17172 elif echo "$da" |od -c |diff - ${tf}1 >"$tdiff"; then
17173 $PRINTF "$OK\n"
17174 if [ "$VERBOSE" ]; then
17175 echo "ip netns del $ns"
17176 echo "ip netns add $ns"
17177 echo "ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8"
17178 echo "ip netns exec $ns ip link set lo up"
17180 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17181 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17182 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17183 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17184 if [ "$VERBOSE" ]; then echo "ip netns del $ns"; fi
17185 numOK=$((numOK+1))
17186 listOK="$listOK $N"
17187 else
17188 $PRINTF "$FAILED (bad output)\n"
17189 echo "$CMD0 &"
17190 cat "${te}0" >&2
17191 echo "$CMD1"
17192 cat "${te}1" >&2
17193 diff:
17194 cat "$tdiff"
17195 numFAIL=$((numFAIL+1))
17196 listFAIL="$listFAIL $N"
17197 namesFAIL="$namesFAIL $NAME"
17199 fi # NUMCOND
17201 esac
17202 N=$((N+1))
17204 # Test the netns (net namespace) feature with EXEC and reset
17205 NAME=NETNS_EXEC
17206 case "$TESTS" in
17207 *%$N%*|*%functions%*|*%root%*|*%namespace%*|*%netns%*|*%socket%*|*%abstract%*|*%dgram%*|*%$NAME%*)
17208 ns=socat-$$-test$N
17209 TEST="$NAME: option netns with EXEC (net namespace $ns)"
17210 # Start a simple server with option netns on localhost of a net namespace that
17211 # stores data it receives;
17212 # use a middle process that EXECs a socat client that connects to the server on
17213 # the net namespace; then it listens on default namespace.
17214 # With a third command line connect and send data to the middle process.
17215 # When the data received by the server is correct the test succeeded.
17216 if ! eval $NUMCOND; then :;
17217 elif [ "$UNAME" != Linux ]; then
17218 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17219 numCANT=$((numCANT+1))
17220 listCANT="$listCANT $N"
17221 elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
17222 $PRINTF "test $F_n $TEST... ${YELLOW}Must be root${NORMAL}\n" $N
17223 numCANT=$((numCANT+1))
17224 listCANT="$listCANT $N"
17225 elif ! $(type ip >/dev/null 2>&1); then
17226 $PRINTF "test $F_n $TEST... ${YELLOW}ip program not available${NORMAL}\n" $N
17227 numCANT=$((numCANT+1))
17228 listCANT="$listCANT $N"
17229 elif ! F=$(testfeats IP4 ABSTRACT_UNIXSOCKET UDP LISTEN NAMESPACES STDIO); then
17230 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
17231 numCANT=$((numCANT+1))
17232 listCANT="$listCANT $N"
17233 elif ! A=$(testaddrs ABSTRACT-RECV ABSTRACT-SENDTO CREATE EXEC UDP4-RECV STDIO UDP4); then
17234 $PRINTF "test $F_n $TEST... ${YELLOW}Address $a not available${NORMAL}\n" $N
17235 numCANT=$((numCANT+1))
17236 listCANT="$listCANT $N"
17237 elif ! o=$(testoptions netns) >/dev/null; then
17238 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available${NORMAL}\n" $N
17239 numCANT=$((numCANT+1))
17240 listCANT="$listCANT $N"
17241 elif ! runsip4 >/dev/null; then
17242 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17243 numCANT=$((numCANT+1))
17244 listCANT="$listCANT $N"
17245 else
17246 tf="$td/test$N.stdout"
17247 te="$td/test$N.stderr"
17248 tdiff="$td/test$N.diff"
17249 da="test$N $(date) $RANDOM"
17250 newport udp4
17251 CMD0="$TRACE $SOCAT $opts --experimental -u -T 1 ABSTRACT-RECV:test$N,netns=$ns CREAT:${tf}0"
17252 CMD1="$TRACE $SOCAT $opts --experimental -U -T 1 EXEC:\"$SOCAT STDIO ABSTRACT-SENDTO\:test$N\",netns=$ns UDP4-RECV:$PORT"
17253 CMD2="$TRACE $SOCAT $opts -u STDIO UDP4:127.0.0.1:$PORT"
17254 printf "test $F_n $TEST... " $N
17255 ip netns del $ns 2>/dev/null # make sure it does not exist
17256 ip netns add $ns
17257 #ip netns exec $ns ip -4 addr add dev lo 127.0.0.1/8
17258 #ip netns exec $ns ip link set lo up
17259 eval "$CMD0" >/dev/null 2>"${te}0" &
17260 pid0=$!
17261 relsleep 1 # if no matching wait*port function
17262 eval "$CMD1" 2>${te}1 &
17263 pid1=$!
17264 relsleep 1
17265 echo "$da" |$CMD2 >"${tf}2" 2>"${te}2"
17266 rc1=$?
17267 kill $pid0 $pid1 2>/dev/null; wait
17268 ip netns del $ns
17269 if [ $rc1 -ne 0 ]; then
17270 $PRINTF "$FAILED (client failed)\n"
17271 echo "$CMD0 &"
17272 cat "${te}0" >&2
17273 echo "$CMD1"
17274 cat "${te}1" >&2
17275 echo "$CMD2"
17276 cat "${te}2" >&2
17277 numFAIL=$((numFAIL+1))
17278 listFAIL="$listFAIL $N"
17279 namesFAIL="$namesFAIL $NAME"
17280 elif echo "$da" |diff - ${tf}0 >"$tdiff" 2>/dev/null; then
17281 $PRINTF "$OK\n"
17282 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17283 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17284 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17285 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17286 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
17287 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
17288 numOK=$((numOK+1))
17289 listOK="$listOK $N"
17290 else
17291 $PRINTF "$FAILED (bad output)\n"
17292 echo "$CMD0 &"
17293 cat "${te}0" >&2
17294 echo "$CMD1"
17295 cat "${te}1" >&2
17296 echo "$CMD2"
17297 cat "${te}2" >&2
17298 echo diff:
17299 cat "$tdiff"
17300 numFAIL=$((numFAIL+1))
17301 listFAIL="$listFAIL $N"
17302 namesFAIL="$namesFAIL $NAME"
17304 fi # NUMCOND
17306 esac
17307 N=$((N+1))
17310 NAME=SOCKETPAIR_STREAM
17311 case "$TESTS" in
17312 *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
17313 TEST="$NAME: stdio and internal socketpair with stream"
17314 if ! cond=$(checkconds \
17315 "" \
17316 "" \
17317 "" \
17318 "STDIO SOCKETPAIR" \
17319 "STDIO SOCKETPAIR" \
17320 "" \
17321 "" ); then
17322 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
17323 numCANT=$((numCANT+1))
17324 listCANT="$listCANT $N"
17325 namesCANT="$namesCANT $NAME"
17326 else
17327 testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts"
17329 esac
17330 N=$((N+1))
17332 NAME=SOCKETPAIR_DATAGRAM
17333 case "$TESTS" in
17334 *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
17335 TEST="$NAME: stdio and internal socketpair with datagram"
17336 if ! cond=$(checkconds \
17337 "" \
17338 "" \
17339 "" \
17340 "STDIO SOCKETPAIR" \
17341 "STDIO SOCKETPAIR" \
17342 "" \
17343 "" ); then
17344 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
17345 numCANT=$((numCANT+1))
17346 listCANT="$listCANT $N"
17347 namesCANT="$namesCANT $NAME"
17348 else
17349 testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts"
17351 esac
17352 N=$((N+1))
17354 NAME=SOCKETPAIR_SEQPACKET
17355 case "$TESTS" in
17356 *%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
17357 TEST="$NAME: stdio and internal socketpair with seqpacket"
17358 if ! cond=$(checkconds \
17359 "" \
17360 "" \
17361 "" \
17362 "STDIO SOCKETPAIR" \
17363 "STDIO SOCKETPAIR" \
17364 "" \
17365 "" ); then
17366 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
17367 numCANT=$((numCANT+1))
17368 listCANT="$listCANT $N"
17369 namesCANT="$namesCANT $NAME"
17370 else
17371 testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts"
17373 esac
17374 N=$((N+1))
17376 # Test if SOCKETPAIR address with SOCK_DGRAM keeps packet boundaries
17377 NAME=SOCKETPAIR_BOUNDARIES
17378 case "$TESTS" in
17379 *%$N%*|*%functions%*|*%socketpair%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*)
17380 TEST="$NAME: Internal socketpair keeps packet boundaries"
17381 # Start a UDP4-DATAGRAM process that echoes data with datagram SOCKETPAIR;
17382 # a client sends two packets with 24 and ~18 bytes using a UDP4-DATAGRAM. The
17383 # client truncates packets to size 24, so when a large merged packet comes from
17384 # server some data will be lost. If the original data is received, the test
17385 # succeeded.
17386 if ! eval $NUMCOND; then :;
17387 elif ! F=$(testfeats STDIO IP4 UDP SOCKETPAIR); then
17388 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17389 numCANT=$((numCANT+1))
17390 listCANT="$listCANT $N"
17391 elif ! A=$(testaddrs - STDIO UDP4-DATAGRAM SOCKETPAIR); then
17392 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17393 numCANT=$((numCANT+1))
17394 listCANT="$listCANT $N"
17395 elif ! o=$(testoptions bind socktype ) >/dev/null; then
17396 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17397 numCANT=$((numCANT+1))
17398 listCANT="$listCANT $N"
17399 elif ! runsip4 >/dev/null; then
17400 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17401 numCANT=$((numCANT+1))
17402 listCANT="$listCANT $N"
17403 else
17404 tf="$td/test$N.stdout"
17405 te="$td/test$N.stderr"
17406 tdiff="$td/test$N.diff"
17407 ts1p=$PORT; PORT=$((PORT+1))
17408 ts2p=$PORT; PORT=$((PORT+1))
17409 da="test$N $(date) $RANDOM"
17410 CMD1="$TRACE $SOCAT $opts -T 0.2 UDP4-DATAGRAM:$LOCALHOST:$ts2p,bind=$LOCALHOST:$ts1p SOCKETPAIR,socktype=$SOCK_DGRAM"
17411 CMD2="$TRACE $SOCAT $opts -b 24 -t 0.2 -T 0.3 - UDP4-DATAGRAM:$LOCALHOST:$ts1p,bind=$LOCALHOST:$ts2p"
17412 printf "test $F_n $TEST... " $N
17413 export SOCAT_TRANSFER_WAIT=0.2
17414 $CMD1 2>"${te}1" &
17415 pid1="$!"
17416 unset SOCAT_TRANSFER_WAIT
17417 waitudp4port $ts1p 1
17418 { echo -n "${da:0:20}"; relsleep 1; echo "${da:20}"; } |$CMD2 >>"$tf" 2>>"${te}2"
17419 rc2="$?"
17420 kill "$pid1" 2>/dev/null; wait;
17421 if [ "$rc2" -ne 0 ]; then
17422 $PRINTF "$FAILED (rc2=$rc2): $TRACE $SOCAT:\n"
17423 echo "$CMD1 &"
17424 cat "${te}1" >&2
17425 echo "$CMD2"
17426 cat "${te}2" >&2
17427 numFAIL=$((numFAIL+1))
17428 listFAIL="$listFAIL $N"
17429 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
17430 $PRINTF "$FAILED\n"
17431 echo "$CMD1 &"
17432 cat "${te}1" >&2
17433 echo "$CMD2"
17434 cat "${te}2" >&2
17435 echo diff:
17436 cat "$tdiff"
17437 numFAIL=$((numFAIL+1))
17438 listFAIL="$listFAIL $N"
17439 else
17440 $PRINTF "$OK\n"
17441 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17442 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17443 if [ "$VERBOSE" ]; then echo "$CMD2 &"; fi
17444 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
17445 numOK=$((numOK+1))
17446 listOK="$listOK $N"
17448 fi # NUMCOND
17450 esac
17451 PORT=$((PORT+1))
17452 N=$((N+1))
17455 # Test the ACCEPT-FD address
17456 NAME=ACCEPT_FD
17457 case "$TESTS" in
17458 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%systemd%*|*%accept%*|*%$NAME%*)
17459 TEST="$NAME: ACCEPT-FD address"
17460 # Start Socat with address ACCEPT-FD via systemd-socket-activate for echoing
17461 # data.
17462 # Connect with a client; the test succeeds when the client gets its data back.
17463 if ! eval $NUMCOND; then :;
17464 elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
17465 $PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N
17466 numCANT=$((numCANT+1))
17467 listCANT="$listCANT $N"
17468 elif ! F=$(testfeats IP4 TCP LISTEN); then
17469 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
17470 numCANT=$((numCANT+1))
17471 listCANT="$listCANT $N"
17472 elif ! A=$(testaddrs ACCEPT-FD PIPE STDIO TCP4); then
17473 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
17474 numCANT=$((numCANT+1))
17475 listCANT="$listCANT $N"
17476 elif ! runsip4 >/dev/null; then
17477 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17478 numCANT=$((numCANT+1))
17479 listCANT="$listCANT $N"
17480 else
17481 tf="$td/test$N.stdout"
17482 te="$td/test$N.stderr"
17483 tdiff="$td/test$N.diff"
17484 da="test$N $(date) $RANDOM"
17485 newport tcp4
17486 CMD0="systemd-socket-activate -l $PORT --inetd $TRACE $SOCAT $opts ACCEPT-FD:0 PIPE"
17487 CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
17488 printf "test $F_n $TEST... " $N
17489 $CMD0 >/dev/null 2>"${te}0" &
17490 pid0=$!
17491 waittcp4port $PORT 1
17492 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
17493 rc1=$?
17494 kill $pid0 2>/dev/null; wait
17495 if echo "$da" |diff "${tf}1" - >$tdiff; then
17496 $PRINTF "$OK\n"
17497 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17498 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17499 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17500 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17501 numOK=$((numOK+1))
17502 listOK="$listOK $N"
17503 else
17504 $PRINTF "$FAILED\n"
17505 echo "$CMD0 &"
17506 cat "${te}0" >&2
17507 echo "$CMD1"
17508 cat "${te}1" >&2
17509 cat $tdiff >&2
17510 numFAIL=$((numFAIL+1))
17511 listFAIL="$listFAIL $N"
17512 namesFAIL="$namesFAIL $NAME"
17514 fi # NUMCOND
17516 esac
17517 N=$((N+1))
17521 # Test the POSIX MQ feature with continuous READ and priorization on Linux
17522 NAME=LINUX_POSIXMQ_READ_PRIO
17523 case "$TESTS" in
17524 *%$N%*|*%functions%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17525 TEST="$NAME: POSIX-MQ (Linux) with prio"
17526 # Run a client/sender that creates a POSIX-MQ and sends a normal message and
17527 # then a client/sender with a higher priority message.
17528 # Run a passive/listening/receiving/reading process and check if it receives
17529 # both messages and in the prioritized order
17530 if ! eval $NUMCOND; then :;
17531 elif [ "$UNAME" != Linux ]; then
17532 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17533 numCANT=$((numCANT+1))
17534 listCANT="$listCANT $N"
17535 elif ! F=$(testfeats POSIXMQ STDIO); then
17536 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17537 numCANT=$((numCANT+1))
17538 listCANT="$listCANT $N"
17539 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO); then
17540 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17541 numCANT=$((numCANT+1))
17542 listCANT="$listCANT $N"
17543 elif ! o=$(testoptions mq-prio unlink-early unlink-close) >/dev/null; then
17544 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17545 numCANT=$((numCANT+1))
17546 listCANT="$listCANT $N"
17547 else
17548 tf="$td/test$N.stdout"
17549 te="$td/test$N.stderr"
17550 tdiff="$td/test$N.diff"
17551 da="test$N $(date) $RANDOM"
17552 tq=/test$N
17553 CMD0a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=0,unlink-early"
17554 CMD0b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,mq-prio=1"
17555 CMD1="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-close STDIO"
17556 printf "test $F_n $TEST... " $N
17557 echo "$da 0" |$CMD0a 2>"${te}0a"
17558 rc0a=$?
17559 echo "$da 1" |$CMD0b 2>"${te}0b"
17560 rc0b=$?
17561 $CMD1 >"${tf}1" 2>"${te}1" &
17562 pid1=$!
17563 relsleep 1
17564 kill $pid1; wait
17565 if [ $rc0a -ne 0 -o $rc0b -ne 0 ]; then
17566 $PRINTF "$FAILED\n"
17567 echo "$CMD0a"
17568 cat "${te}0a" >&2
17569 echo "$CMD0b"
17570 cat "${te}0b" >&2
17571 echo "$CMD1"
17572 cat "${te}1" >&2
17573 numFAIL=$((numFAIL+1))
17574 listFAIL="$listFAIL $N"
17575 namesFAIL="$namesFAIL $NAME"
17576 elif $ECHO "$da 1\n$da 0" |diff - ${tf}1 >${tdiff}1; then
17577 $PRINTF "$OK\n"
17578 if [ "$VERBOSE" ]; then echo "$CMD0a"; fi
17579 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
17580 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
17581 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
17582 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17583 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17584 numOK=$((numOK+1))
17585 listOK="$listOK $N"
17586 else
17587 $PRINTF "$FAILED\n"
17588 echo "$CMD0a"
17589 cat "${te}0a" >&2
17590 echo "$CMD0b"
17591 cat "${te}0b" >&2
17592 echo "$CMD1"
17593 cat "${te}1" >&2
17594 echo "difference:" >&2
17595 cat ${tdiff}1 >&2
17596 numFAIL=$((numFAIL+1))
17597 listFAIL="$listFAIL $N"
17598 namesFAIL="$namesFAIL $NAME"
17600 fi # NUMCOND
17602 esac
17603 N=$((N+1))
17605 # Test the POSIX MQ feature with RECV,fork on Linux
17606 NAME=LINUX_POSIXMQ_RECV_FORK
17607 case "$TESTS" in
17608 *%$N%*|*%functions%*|*%fork%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17609 TEST="$NAME: POSIX-MQ (Linux) RECV with fork"
17610 # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its
17611 # output.
17612 # Run two clients/senders each with a message.
17613 # Check if both messages are stored.
17614 if ! eval $NUMCOND; then :;
17615 elif [ "$UNAME" != Linux ]; then
17616 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17617 numCANT=$((numCANT+1))
17618 listCANT="$listCANT $N"
17619 elif ! F=$(testfeats POSIXMQ STDIO); then
17620 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17621 numCANT=$((numCANT+1))
17622 listCANT="$listCANT $N"
17623 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO); then
17624 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17625 numCANT=$((numCANT+1))
17626 listCANT="$listCANT $N"
17627 elif ! o=$(testoptions fork unlink-early unlink-close) >/dev/null; then
17628 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17629 numCANT=$((numCANT+1))
17630 listCANT="$listCANT $N"
17631 else
17632 tf="$td/test$N.stdout"
17633 te="$td/test$N.stderr"
17634 tdiff="$td/test$N.diff"
17635 da="test$N $(date) $RANDOM"
17636 tq=/test$N
17637 CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork STDIO"
17638 CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq"
17639 CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
17640 printf "test $F_n $TEST... " $N
17641 $CMD0 2>"${te}0" >"${tf}0" &
17642 pid0=$!
17643 relsleep 1
17644 echo "$da 0" |$CMD1a >/dev/null 2>"${te}1a"
17645 rc1a=$?
17646 echo "$da 1" |$CMD1b >/dev/null 2>"${te}1b"
17647 rc1b=$?
17648 relsleep 1
17649 kill $pid0; wait
17650 if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then
17651 $PRINTF "$FAILED\n"
17652 echo "$CMD0"
17653 cat "${te}0" >&2
17654 echo "$CMD1a"
17655 cat "${te}1a" >&2
17656 echo "$CMD1b"
17657 cat "${te}1b" >&2
17658 numFAIL=$((numFAIL+1))
17659 listFAIL="$listFAIL $N"
17660 namesFAIL="$namesFAIL $NAME"
17661 elif $ECHO "$da 0\n$da 1" |diff - ${tf}0 >${tdiff}0; then
17662 $PRINTF "$OK\n"
17663 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
17664 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17665 if [ "$VERBOSE" ]; then echo "$CMD1a"; fi
17666 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
17667 if [ "$VERBOSE" ]; then echo "$CMD1b"; fi
17668 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
17669 numOK=$((numOK+1))
17670 listOK="$listOK $N"
17671 else
17672 $PRINTF "$FAILED\n"
17673 echo "$CMD0"
17674 cat "${te}0" >&2
17675 echo "$CMD1a"
17676 cat "${te}1a" >&2
17677 echo "$CMD1b"
17678 cat "${te}1b" >&2
17679 echo "difference:" >&2
17680 cat ${tdiff}0 >&2
17681 numFAIL=$((numFAIL+1))
17682 listFAIL="$listFAIL $N"
17683 namesFAIL="$namesFAIL $NAME"
17685 fi # NUMCOND
17687 esac
17688 N=$((N+1))
17690 # Test the POSIX MQ feature with RECV,fork,max-children on Linux
17691 NAME=LINUX_POSIXMQ_RECV_MAXCHILDREN
17692 case "$TESTS" in
17693 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17694 TEST="$NAME: POSIX-MQ (Linux) RECV with fork,max-children"
17695 # Start a POSIX-MQ receiver with fork that creates a POSIX-MQ and stores its
17696 # output via sub processes that sleeps after writing.
17697 # Run a client/sender that sends message 1;
17698 # run a client/sender that sends message 3, has to wait;
17699 # write message 2 directly into output file;
17700 # Check if the messages are stored in order of their numbers
17701 if ! eval $NUMCOND; then :;
17702 elif [ "$UNAME" != Linux ]; then
17703 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17704 numCANT=$((numCANT+1))
17705 listCANT="$listCANT $N"
17706 elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then
17707 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17708 numCANT=$((numCANT+1))
17709 listCANT="$listCANT $N"
17710 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-RECEIVE STDIO SYSTEM); then
17711 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17712 numCANT=$((numCANT+1))
17713 listCANT="$listCANT $N"
17714 elif ! o=$(testoptions fork max-children unlink-early unlink-close) >/dev/null; then
17715 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17716 numCANT=$((numCANT+1))
17717 listCANT="$listCANT $N"
17718 else
17719 tf="$td/test$N.stdout"
17720 te="$td/test$N.stderr"
17721 tdiff="$td/test$N.diff"
17722 da="test$N $(date) $RANDOM"
17723 tq=/test$N
17724 CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-RECV:$tq,unlink-early,fork,max-children=1 SYSTEM:\"cat\ >>${tf}0;\ sleep\ 1\""
17725 CMD1a="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq"
17726 CMD1b="$TRACE $SOCAT --experimental $opts -u STDIO POSIXMQ-SEND:$tq,unlink-close"
17727 printf "test $F_n $TEST... " $N
17728 eval $CMD0 2>"${te}0" >"${tf}0" &
17729 pid0=$!
17730 relsleep 1
17731 echo "$da 1" |$CMD1a >/dev/null 2>"${te}1a"
17732 rc1a=$?
17733 echo "$da 3" |$CMD1b >/dev/null 2>"${te}1b"
17734 rc1b=$?
17735 sleep 0.5
17736 echo "$da 2" >>"${tf}0"
17737 sleep 1 # as in SYSTEM
17738 kill $(childpids $pid0) $pid0 2>/dev/null
17739 wait 2>/dev/null
17740 if [ $rc1a -ne 0 -o $rc1b -ne 0 ]; then
17741 $PRINTF "$FAILED\n"
17742 echo "$CMD0"
17743 cat "${te}0" >&2
17744 echo "$CMD1a"
17745 cat "${te}1a" >&2
17746 echo "$CMD1b"
17747 cat "${te}1b" >&2
17748 numFAIL=$((numFAIL+1))
17749 listFAIL="$listFAIL $N"
17750 namesFAIL="$namesFAIL $NAME"
17751 elif $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
17752 $PRINTF "$OK\n"
17753 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
17754 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17755 if [ "$VERBOSE" ]; then echo "$CMD1a"; fi
17756 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
17757 if [ "$VERBOSE" ]; then echo "$CMD1b"; fi
17758 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
17759 numOK=$((numOK+1))
17760 listOK="$listOK $N"
17761 else
17762 $PRINTF "$FAILED\n"
17763 echo "$CMD0"
17764 cat "${te}0" >&2
17765 echo "$CMD1a"
17766 cat "${te}1a" >&2
17767 echo "$CMD1b"
17768 cat "${te}1b" >&2
17769 echo "difference:" >&2
17770 cat ${tdiff}0 >&2
17771 numFAIL=$((numFAIL+1))
17772 listFAIL="$listFAIL $N"
17773 namesFAIL="$namesFAIL $NAME"
17775 fi # NUMCOND
17777 esac
17778 N=$((N+1))
17780 # Test the POSIX MQ feature with SEND,fork,max-children on Linux
17781 NAME=LINUX_POSIXMQ_SEND_MAXCHILDREN
17782 case "$TESTS" in
17783 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%posixmq%*|*%$NAME%*)
17784 TEST="$NAME: POSIX-MQ (Linux) SEND with fork,max-children"
17785 # Start a POSIX-MQ receiver that creates a POSIX-MQ and transfers data from
17786 # there to an output file
17787 # Run a POSIX-MQ sender that two times forks and invokes a data generator
17788 # for messages 1 and 3 in a shell process with some trailing sleep.
17789 # Afterwards write message 2 directly into output file; message 3 should be
17790 # delayed due to max-children option
17791 # Check if the messages are stored in order of their numbers.
17792 # The data generator is implemented as a receiver from an MQ with "1", "3"
17793 if ! eval $NUMCOND; then :;
17794 elif [ "$UNAME" != Linux ]; then
17795 $PRINTF "test $F_n $TEST... ${YELLOW}Only on Linux${NORMAL}\n" $N
17796 numCANT=$((numCANT+1))
17797 listCANT="$listCANT $N"
17798 elif ! F=$(testfeats POSIXMQ STDIO SYSTEM); then
17799 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
17800 numCANT=$((numCANT+1))
17801 listCANT="$listCANT $N"
17802 elif ! A=$(testaddrs POSIXMQ-SEND POSIXMQ-READ STDIO SYSTEM); then
17803 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17804 numCANT=$((numCANT+1))
17805 listCANT="$listCANT $N"
17806 elif ! o=$(testoptions fork max-children mq-prio unlink-early unlink-close) >/dev/null; then
17807 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17808 numCANT=$((numCANT+1))
17809 listCANT="$listCANT $N"
17810 #elif ! runsposixmq >/dev/null; then
17811 # $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
17812 # numCANT=$((numCANT+1))
17813 # listCANT="$listCANT $N"
17814 else
17815 tf="$td/test$N.stdout"
17816 te="$td/test$N.stderr"
17817 tdiff="$td/test$N.diff"
17818 da="test$N $(date) $RANDOM"
17819 tq=/test$N
17820 CMD0="$TRACE $SOCAT --experimental $opts -u POSIXMQ-READ:$tq,unlink-early STDIO"
17821 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\""
17822 printf "test $F_n $TEST... " $N
17823 # create data for the generator
17824 echo "$da 1" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data,unlink-early
17825 echo "$da 3" |$SOCAT -u --experimental - POSIXMQ-SEND:$tq-data
17826 eval $CMD0 2>"${te}0" >>"${tf}0" &
17827 pid0=$!
17828 relsleep 1
17829 eval $CMD1 2>"${te}1" &
17830 pid1=$!
17831 sleep 0.5
17832 echo "$da 2" >>"${tf}0"
17833 sleep 1 # as in SYSTEM
17834 kill $pid0 $(childpids $pid0) $pid1 $(childpids $pid1) 2>/dev/null
17835 wait 2>/dev/null
17836 $SOCAT -u --experimental /dev/null POSIXMQ-SEND:$tq-data,unlink-close
17837 if $ECHO "$da 1\n$da 2\n$da 3" |diff - ${tf}0 >${tdiff}0; then
17838 $PRINTF "$OK\n"
17839 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
17840 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17841 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
17842 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
17843 numOK=$((numOK+1))
17844 listOK="$listOK $N"
17845 else
17846 $PRINTF "$FAILED\n"
17847 echo "$CMD0"
17848 cat "${te}0" >&2
17849 echo "$CMD1"
17850 cat "${te}1" >&2
17851 echo "difference:" >&2
17852 cat ${tdiff}0 >&2
17853 numFAIL=$((numFAIL+1))
17854 listFAIL="$listFAIL $N"
17855 namesFAIL="$namesFAIL $NAME"
17857 fi # NUMCOND
17859 esac
17860 N=$((N+1))
17863 # Test the sigint option with SHELL address
17864 NAME=SHELL_SIGINT
17865 case "$TESTS" in
17866 *%$N%*|*%functions%*|*%socket%*|*%shell%*|*%progcall%*|*%sigint%*|*%$NAME%*)
17867 TEST="$NAME: sigint option with SHELL"
17868 # Run Socat with an EXEC address invoking Socat, with option sigint
17869 # Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM)
17870 # the test succeeded
17871 if ! eval $NUMCOND; then :;
17872 elif ! F=$(testfeats STDIO SHELL PIPE); then
17873 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17874 numCANT=$((numCANT+1))
17875 listCANT="$listCANT $N"
17876 elif ! A=$(testaddrs STDIO SHELL PIPE); then
17877 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17878 numCANT=$((numCANT+1))
17879 listCANT="$listCANT $N"
17880 elif ! o=$(testoptions setsid sigint) >/dev/null; then
17881 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
17882 numCANT=$((numCANT+1))
17883 listCANT="$listCANT $N"
17884 else
17885 tf="$td/test$N.stdout"
17886 te="$td/test$N.stderr"
17887 tdiff="$td/test$N.diff"
17888 da="test$N $(date) $RANDOM"
17889 #CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"socat\ -d\ -d\ -d\ -d\ -lu\ PIPE\ PIPE\",pty,setsid,sigint"
17890 #CMD0="$TRACE $SOCAT $opts -T 2 PIPE EXEC:\"$CAT\",pty,setsid,sigint"
17891 CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR EXEC:\"$CAT\",pty,setsid,sigint"
17892 printf "test $F_n $TEST... " $N
17893 eval $CMD0 >/dev/null 2>"${te}0" &
17894 $CMD0 >/dev/null 2>"${te}0" &
17895 pid0=$!
17896 sleep 1
17897 kill -INT $pid0
17898 wait
17899 if grep -q " W waitpid..: child .* exited with status 130" "${te}0" ||
17900 grep -q " W waitpid..: child .* exited on signal 2" "${te}0"; then
17901 $PRINTF "$OK\n"
17902 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
17903 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
17904 numOK=$((numOK+1))
17905 listOK="$listOK $N"
17906 else
17907 $PRINTF "$FAILED\n"
17908 echo "$CMD0 &"
17909 cat "${te}0" >&2
17910 numFAIL=$((numFAIL+1))
17911 listFAIL="$listFAIL $N"
17912 namesFAIL="$namesFAIL $NAME"
17914 fi # NUMCOND
17916 esac
17917 N=$((N+1))
17920 # Test the SHELL address with socketpair (default)
17921 NAME=SHELL_SOCKETPAIR
17922 case "$TESTS" in
17923 *%$N%*|*%functions%*|*%shell%*|*%socketpair%*|*%$NAME%*)
17924 TEST="$NAME: simple echo via SHELL of cat with socketpair"
17925 # testecho ...
17926 if ! eval $NUMCOND; then :;
17927 elif ! F=$(testfeats STDIO SHELL); then
17928 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17929 numCANT=$((numCANT+1))
17930 listCANT="$listCANT $N"
17931 elif ! A=$(testaddrs STDIO SHELL); then
17932 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17933 numCANT=$((numCANT+1))
17934 listCANT="$listCANT $N"
17935 else
17936 testecho "$N" "$TEST" "" "SHELL:$CAT" "$opts" "$val_t"
17938 esac
17939 N=$((N+1))
17941 # Test the SHELL address with pipes
17942 NAME=SHELL_PIPES
17943 case "$TESTS" in
17944 *%$N%*|*%functions%*|*%shell%*|*%pipe%*|*%$NAME%*)
17945 TEST="$NAME: simple echo via SHELL of cat with pipes"
17946 # testecho ...
17947 if ! eval $NUMCOND; then :;
17948 elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then
17949 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17950 numCANT=$((numCANT+1))
17951 listCANT="$listCANT $N"
17952 elif ! A=$(testaddrs STDIO SHELL PIPE); then
17953 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17954 numCANT=$((numCANT+1))
17955 listCANT="$listCANT $N"
17956 else
17957 testecho "$N" "$TEST" "" "SHELL:$CAT,pipes" "$opts" "$val_t"
17959 esac
17960 N=$((N+1))
17962 # Test the SHELL address with pty
17963 NAME=SHELL_PTY
17964 case "$TESTS" in
17965 *%$N%*|*%functions%*|*%shell%*|*%pty%*|*%$NAME%*)
17966 TEST="$NAME: simple echo via SHELL of cat with pty"
17967 # testecho ...
17968 if ! eval $NUMCOND; then :;
17969 elif ! F=$(testfeats STDIO SHELL PTY); then
17970 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17971 numCANT=$((numCANT+1))
17972 listCANT="$listCANT $N"
17973 elif ! A=$(testaddrs STDIO SHELL PTY); then
17974 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
17975 numCANT=$((numCANT+1))
17976 listCANT="$listCANT $N"
17977 elif [ "$SHELL" = /bin/ksh ]; then
17978 # on NetBSD-9.3 this test kills test.sh script...
17979 $PRINTF "test $F_n $TEST... ${YELLOW}/bin/ksh might kill test.sh${NORMAL}\n" $N
17980 numCANT=$((numCANT+1))
17981 listCANT="$listCANT $N"
17982 else
17983 testecho "$N" "$TEST" "" "SHELL:$CAT,pty,$PTYOPTS,$PTYOPTS2" "$opts" "$val_t"
17985 esac
17986 N=$((N+1))
17988 # Test the SHELL address halfclose with socketpair
17989 NAME=SHELL_SOCKETPAIR_FLUSH
17990 case "$TESTS" in
17991 *%$N%*|*%functions%*|*%shell%*|*%socketpair%*|*%halfclose%*|*%$NAME%*)
17992 TEST="$NAME: call od -c via SHELL using socketpair"
17993 # testecho ...
17994 if ! eval $NUMCOND; then :;
17995 elif ! F=$(testfeats STDIO SHELL); then
17996 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
17997 numCANT=$((numCANT+1))
17998 listCANT="$listCANT $N"
17999 elif ! A=$(testaddrs STDIO SHELL); then
18000 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18001 numCANT=$((numCANT+1))
18002 listCANT="$listCANT $N"
18003 else
18004 testod "$N" "$TEST" "" "SHELL:$OD_C" "$opts" "$val_t"
18006 esac
18007 N=$((N+1))
18009 # Test SHELL address halfclose with pipes
18010 NAME=SHELL_PIPES
18011 case "$TESTS" in
18012 *%$N%*|*%functions%*|*%shell%*|*%pipe%*|*%halfclose%*|*%$NAME%*)
18013 TEST="$NAME: call od -c via SHELL using pipes"
18014 # testecho ...
18015 if ! eval $NUMCOND; then :;
18016 elif ! F=$(testfeats STDIO SHELL SOCKETPAIR); then
18017 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18018 numCANT=$((numCANT+1))
18019 listCANT="$listCANT $N"
18020 elif ! A=$(testaddrs STDIO SHELL PIPE); then
18021 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18022 numCANT=$((numCANT+1))
18023 listCANT="$listCANT $N"
18024 else
18025 testod "$N" "$TEST" "" "SHELL:$OD_C,pipes" "$opts" "$val_t"
18027 esac
18028 N=$((N+1))
18031 # Test the sigint option with SYSTEM address
18032 NAME=SYSTEM_SIGINT
18033 case "$TESTS" in
18034 *%$N%*|*%functions%*|*%socket%*|*%progcall%*|*%system%*|*%sigint%*|*%$NAME%*)
18035 TEST="$NAME: sigint option with SYSTEM"
18036 # Run Socat with a SYSTEM address invoking Socat, with option sigint
18037 # Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM)
18038 # the test succeeded
18039 # setsid is required so the initial SIGINT is not delivered to the sub process.
18040 if ! eval $NUMCOND; then :;
18041 elif [ "$UNAME" = "NetBSD" ]; then
18042 # On NetBSD-4.0 and NetBSD-9.3 this test hangs (signal has no effect)
18043 # (other versions not tried)
18044 $PRINTF "test $F_n $TEST... ${YELLOW}might hang on $UNAME${NORMAL}\n" $N
18045 numCANT=$((numCANT+1))
18046 listCANT="$listCANT $N"
18047 elif ! F=$(testfeats SYCLS STDIO SYSTEM SOCKETPAIR); then
18048 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18049 numCANT=$((numCANT+1))
18050 listCANT="$listCANT $N"
18051 elif ! A=$(testaddrs STDIO SYSTEM SOCKETPAIR); then
18052 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18053 numCANT=$((numCANT+1))
18054 listCANT="$listCANT $N"
18055 elif ! o=$(testoptions setsid sigint) >/dev/null; then
18056 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18057 numCANT=$((numCANT+1))
18058 listCANT="$listCANT $N"
18059 else
18060 tf="$td/test$N.stdout"
18061 te="$td/test$N.stderr"
18062 tdiff="$td/test$N.diff"
18063 da="test$N $(date) $RANDOM"
18064 #CMD0="$TRACE $SOCAT $opts PIPE SYSTEM:\"$SOCAT\ -dddd\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
18065 # -T is required on (only?) OpenBSD-4
18066 CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -lf\ ${te}1\ PIPE\ PIPE\",setsid,sigint"
18067 #CMD0="$TRACE $SOCAT $opts -T 2 SOCKETPAIR SYSTEM:\"$SOCAT\ -dddd\ -T\ 1\ -lf ${te}1\ PIPE\ PIPE\",setsid,sigint"
18068 printf "test $F_n $TEST... " $N
18069 eval $CMD0 >/dev/null 2>"${te}0" &
18070 pid0=$!
18071 sleep 1
18072 #echo childpids: $(childpids $pid0)
18073 #echo childpids -r: $(childpids -r $pid0)
18074 kill -INT $(childpids -r $pid0) 2>/dev/null
18075 wait 2>/dev/null
18076 if grep -q " W waitpid..: child .* exited with status 130" "${te}0"; then
18077 $PRINTF "$OK\n"
18078 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18079 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18080 numOK=$((numOK+1))
18081 listOK="$listOK $N"
18082 else
18083 $PRINTF "${YELLOW}FAILED (shell does not propagate SIGINT?${NORMAL}\n"
18084 echo "$CMD0 &"
18085 cat "${te}0" >&2
18086 numCANT=$((numCANT+1))
18087 listCANT="$listCANT $N"
18088 namesCANT="$namesCANT $NAME"
18090 fi # NUMCOND
18092 esac
18093 N=$((N+1))
18096 # Test the res-nsaddr (resolver, dns) option
18097 NAME=RES_NSADDR
18098 case "$TESTS" in
18099 *%$N%*|*%functions%*|*%resolv%*|*%ip4%*|*%tcp4%*|*%socket%*|*%$NAME%*)
18100 TEST="$NAME: test the res-nsaddr option"
18101 # Start a supplementary Socat instance that will receive the DNS query.
18102 # Run main Socat process, opening an IPv4 socket with option res-nsaddr
18103 # directed to the aux process.
18104 # When the supplementary Socat instance received the query the test succeeded.
18105 if ! eval $NUMCOND; then :;
18106 elif ! F=$(testfeats STDIO IP4 UDP TCP); then
18107 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18108 numCANT=$((numCANT+1))
18109 listCANT="$listCANT $N"
18110 elif ! A=$(testaddrs STDIO TCP4 UDP-RECVFROM); then
18111 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18112 numCANT=$((numCANT+1))
18113 listCANT="$listCANT $N"
18114 elif ! o=$(testoptions res-nsaddr) >/dev/null; then
18115 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18116 numCANT=$((numCANT+1))
18117 listCANT="$listCANT $N"
18118 elif ! runsip4 >/dev/null; then
18119 $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N
18120 numCANT=$((numCANT+1))
18121 listCANT="$listCANT $N"
18122 else
18123 tf="$td/test$N.stdout"
18124 te="$td/test$N.stderr"
18125 tdiff="$td/test$N.diff"
18126 da="$(echo test$N $(date) $RANDOM |tr ' :' '-')"
18127 echo "$da" >"$td/test$N.da"
18128 newport udp4
18129 CMD0="$TRACE $SOCAT $opts -u UDP4-RECVFROM:$PORT -"
18130 CMD1="$TRACE $SOCAT $opts - TCP4:$da:0,res-nsaddr=$LOCALHOST:$PORT"
18131 printf "test $F_n $TEST... " $N
18132 $CMD0 >/dev/null 2>"${te}0" >"${tf}0" &
18133 pid0=$!
18134 waitudp4port $PORT 1
18135 $CMD1 >"${tf}1" 2>"${te}1"
18136 rc1=$?
18137 kill $pid0 2>/dev/null; wait
18138 if grep "$da" "${tf}0" >/dev/null; then
18139 $PRINTF "$OK\n"
18140 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18141 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18142 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18143 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18144 numOK=$((numOK+1))
18145 listOK="$listOK $N"
18146 elif pgrep -u root nscd >/dev/null 2>&1; then
18147 $PRINTF "${YELLOW}FAILED (due to nscd?)${NORMAL}\n"
18148 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18149 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18150 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18151 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18152 numCANT=$((numCANT+1))
18153 listCANT="$listCANT $N"
18154 namesCAnT="$namesCANT $NAME"
18155 else
18156 $PRINTF "$FAILED (query not received)\n"
18157 echo "$CMD0 &"
18158 cat "${te}0" >&2
18159 echo "$CMD1"
18160 cat "${te}1" >&2
18161 numFAIL=$((numFAIL+1))
18162 listFAIL="$listFAIL $N"
18163 namesFAIL="$namesFAIL $NAME"
18165 fi # NUMCOND
18167 esac
18168 N=$((N+1))
18171 # Some of the following tests need absolute path of Socat
18172 case "$SOCAT" in
18173 /*) absSOCAT="$SOCAT" ;;
18174 */*) absSOCAT="$PWD/$SOCAT" ;;
18175 *) absSOCAT="$(type -p "$SOCAT")" ;;
18176 esac
18177 [ "$DEFS" ] && echo "absSOCAT=\"$absSOCAT\"" >&2
18179 # Test the chdir option, in particular if chdir with the first address
18180 # (CREATE) does not affect pwd of second address, i.e. original pwd is
18181 # recovered
18182 NAME=CHDIR_ON_CREATE
18183 case "$TESTS" in
18184 *%$N%*|*%functions%*|*%creat%*|*%system%*|*%chdir%*|*%$NAME%*)
18185 TEST="$NAME: restore of pwd after CREAT with chdir option"
18186 # Run Socat with first address CREAT with modified chdir,
18187 # and second address SYSTEM (shell) with pwd command
18188 # Check if the file is created with modified pwd but shell has original pwd
18189 if ! eval $NUMCOND; then :;
18190 elif ! F=$(testfeats CREAT SYSTEM); then
18191 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18192 numCANT=$((numCANT+1))
18193 listCANT="$listCANT $N"
18194 elif ! A=$(testaddrs - CREAT SYSTEM); then
18195 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18196 numCANT=$((numCANT+1))
18197 listCANT="$listCANT $N"
18198 elif ! o=$(testoptions chdir) >/dev/null; then
18199 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18200 numCANT=$((numCANT+1))
18201 listCANT="$listCANT $N"
18202 else
18203 tf="$td/test$N.stdout"
18204 te="$td/test$N.stderr"
18205 tc="test$N.creat"
18206 tdd="test$N.d"
18207 tdiff="$td/test$N.diff"
18208 tdebug="$td/test$N.debug"
18209 opwd=$(pwd)
18210 CMD0="$TRACE $absSOCAT $opts -U CREAT:$tc,chdir=$td SYSTEM:pwd"
18211 printf "test $F_n $TEST... " $N
18212 mkdir "$td/$tdd"
18213 pushd "$td/$tdd" >/dev/null
18214 $CMD0 >/dev/null 2>"${te}0"
18215 rc0=$?
18216 popd >/dev/null
18217 tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*}
18218 pwd2=$(cat $tpwd/$tc </dev/null)
18219 echo "Original pwd: $opwd" >>$tdebug
18220 echo "Temporary pwd: $tpwd" >>$tdebug
18221 echo "Addr2 pwd: $pwd2" >>$tdebug
18222 if [ "$rc0" -ne 0 ]; then
18223 $PRINTF "$FAILED\n"
18224 echo "$CMD0 &"
18225 cat "${te}0" >&2
18226 numFAIL=$((numFAIL+1))
18227 listFAIL="$listFAIL $N"
18228 namesFAIL="$namesFAIL $NAME"
18229 elif [ "$tpwd" != "$td" ]; then
18230 $PRINTF "$FAILED (chdir failed)\n"
18231 echo "$CMD0 &"
18232 cat "${te}0" >&2
18233 numFAIL=$((numFAIL+1))
18234 listFAIL="$listFAIL $N"
18235 namesFAIL="$namesFAIL $NAME"
18236 elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
18237 $PRINTF "$FAILED (bad pwd2)\n"
18238 echo "$CMD0 &"
18239 cat "${te}0" >&2
18240 echo "// diff:" >&2
18241 cat "$tdiff" >&2
18242 numFAIL=$((numFAIL+1))
18243 listFAIL="$listFAIL $N"
18244 namesFAIL="$namesFAIL $NAME"
18245 else
18246 $PRINTF "$OK\n"
18247 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18248 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18249 numOK=$((numOK+1))
18250 listOK="$listOK $N"
18252 fi # NUMCOND
18254 esac
18255 N=$((N+1))
18257 # Test the chdir option, in particular if chdir with first address
18258 # (SHELL) does not affect pwd of second address, i.e. original pwd is
18259 # recovered
18260 NAME=CHDIR_ON_SHELL
18261 case "$TESTS" in
18262 *%$N%*|*%functions%*|*%shell%*|*%system%*|*%chdir%*|*%$NAME%*)
18263 TEST="$NAME: restore of pwd after SYSTEM with chdir option"
18264 # Run Socat with first address SYSTEM:"cat >file" with chdir,
18265 # and second address SYSTEM (shell) with pwd command.
18266 # Check if the file is created with modified pwd but shell has original pwd
18267 if ! eval $NUMCOND; then :;
18268 elif ! F=$(testfeats SHELL SYSTEM); then
18269 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18270 numCANT=$((numCANT+1))
18271 listCANT="$listCANT $N"
18272 elif ! A=$(testaddrs SHELL SYSTEM); then
18273 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18274 numCANT=$((numCANT+1))
18275 listCANT="$listCANT $N"
18276 elif ! o=$(testoptions chdir) >/dev/null; then
18277 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18278 numCANT=$((numCANT+1))
18279 listCANT="$listCANT $N"
18280 else
18281 tf="$td/test$N.stdout"
18282 te="$td/test$N.stderr"
18283 tc="test$N.creat"
18284 tdd="test$N.d"
18285 tdiff="$td/test$N.diff"
18286 tdebug="$td/test$N.debug"
18287 opwd=$(pwd)
18288 CMD0="$TRACE $absSOCAT $opts SHELL:\"cat\ >$tc\",chdir=$td SYSTEM:pwd"
18289 printf "test $F_n $TEST... " $N
18290 mkdir "$td/$tdd"
18291 pushd "$td/$tdd" >/dev/null
18292 eval "$CMD0" >/dev/null 2>"${te}0"
18293 rc0=$?
18294 popd >/dev/null
18295 waitfile "$td/$tc"
18296 tpwd=$(find $td -name $tc -print); tpwd=${tpwd%/*}
18297 pwd2=$(cat $tpwd/$tc </dev/null)
18298 echo "Original pwd: $opwd" >>$tdebug
18299 echo "Temporary pwd: $tpwd" >>$tdebug
18300 echo "Addr2 pwd: $pwd2" >>$tdebug
18301 if [ "$rc0" -ne 0 ]; then
18302 $PRINTF "$FAILED (rc=$rc0)\n"
18303 echo "$CMD0 &"
18304 cat "${te}0" >&2
18305 numFAIL=$((numFAIL+1))
18306 listFAIL="$listFAIL $N"
18307 namesFAIL="$namesFAIL $NAME"
18308 elif [ "$tpwd" != "$td" ]; then
18309 $PRINTF "$FAILED (chdir failed)\n"
18310 echo "$CMD0 &"
18311 cat "${te}0" >&2
18312 numFAIL=$((numFAIL+1))
18313 listFAIL="$listFAIL $N"
18314 namesFAIL="$namesFAIL $NAME"
18315 elif ! echo "$pwd2" |diff "$td/$tc" - >$tdiff; then
18316 $PRINTF "$FAILED (bad pwd)\n"
18317 echo "$CMD0 &"
18318 cat "${te}0" >&2
18319 echo "// diff:" >&2
18320 cat "$tdiff" >&2
18321 numFAIL=$((numFAIL+1))
18322 listFAIL="$listFAIL $N"
18323 namesFAIL="$namesFAIL $NAME"
18324 else
18325 $PRINTF "$OK\n"
18326 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18327 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18328 numOK=$((numOK+1))
18329 listOK="$listOK $N"
18331 fi # NUMCOND
18333 esac
18334 N=$((N+1))
18337 # Test the modified umask option, in particular if umask with first address
18338 # (CREATE) does not affect umask of second address, i.e. original umask is
18339 # recovered
18340 NAME=UMASK_ON_CREATE
18341 case "$TESTS" in
18342 *%$N%*|*%functions%*|*%creat%*|*%system%*|*%umask%*|*%$NAME%*)
18343 TEST="$NAME: test restore after CREAT with umask option"
18344 # Run Socat with first address CREAT with modified umask,
18345 # and second address SYSTEM (shell) with umask command
18346 # Check if the file is created with modified umask but shell has original umask
18347 if ! eval $NUMCOND; then :;
18348 elif ! F=$(testfeats CREAT SYSTEM); then
18349 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18350 numCANT=$((numCANT+1))
18351 listCANT="$listCANT $N"
18352 elif ! A=$(testaddrs CREAT SYSTEM); then
18353 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18354 numCANT=$((numCANT+1))
18355 listCANT="$listCANT $N"
18356 elif ! o=$(testoptions umask) >/dev/null; then
18357 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18358 numCANT=$((numCANT+1))
18359 listCANT="$listCANT $N"
18360 else
18361 tf="$td/test$N.stdout"
18362 te="$td/test$N.stderr"
18363 tc="$td/test$N.creat"
18364 tdiff="$td/test$N.diff"
18365 tdebug="$td/test$N.debug"
18366 oumask=$(umask)
18367 # Construct a temp umask differing from original umask
18368 case oumask in
18369 *066) tumask=0026 ;;
18370 *) tumask=0066 ;;
18371 esac
18372 CMD0="$TRACE $SOCAT $opts -U CREAT:$tc,umask=$tumask SYSTEM:umask"
18373 printf "test $F_n $TEST... " $N
18374 $CMD0 >/dev/null 2>"${te}0"
18375 rc0=$?
18376 tperms=$(fileperms $tc)
18377 case $tperms in
18378 0*) ;;
18379 *) tperms=0$tperms ;;
18380 esac
18381 echo "Original umask: $oumask" >>$tdebug
18382 echo "Temporary umask: $tumask" >>$tdebug
18383 echo "Created umask: $tperms" >>$tdebug
18384 echo "Restored umask: $(cat $tc)" >>$tdebug
18385 if [ "$rc0" -ne 0 ]; then
18386 $PRINTF "$FAILED\n"
18387 echo "$CMD0 &"
18388 cat "${te}0" >&2
18389 numFAIL=$((numFAIL+1))
18390 listFAIL="$listFAIL $N"
18391 namesFAIL="$namesFAIL $NAME"
18392 elif [ $((tumask + tperms - 0666)) -ne 0 ]; then
18393 $PRINTF "$FAILED (umask failed)\n"
18394 echo "$CMD0 &"
18395 cat "${te}0" >&2
18396 numFAIL=$((numFAIL+1))
18397 listFAIL="$listFAIL $N"
18398 namesFAIL="$namesFAIL $NAME"
18399 elif ! [ "$oumask" -eq $(cat "$tc") ]; then
18400 $PRINTF "$FAILED (bad umask)\n"
18401 echo "$CMD0 &"
18402 cat "${te}0" >&2
18403 cat "$tdebug" >&2
18404 numFAIL=$((numFAIL+1))
18405 listFAIL="$listFAIL $N"
18406 namesFAIL="$namesFAIL $NAME"
18407 else
18408 $PRINTF "$OK\n"
18409 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18410 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18411 numOK=$((numOK+1))
18412 listOK="$listOK $N"
18414 fi # NUMCOND
18416 esac
18417 N=$((N+1))
18419 # Test the modified umask option, in particular if umask with first address
18420 # (SHELL) does not affect umask of second address, i.e. original umask is
18421 # recovered
18422 NAME=UMASK_ON_SYSTEM
18423 case "$TESTS" in
18424 *%$N%*|*%functions%*|*%shell%*|*%system%*|*%umask%*|*%socket%*|*%$NAME%*)
18425 TEST="$NAME: test restore after SHELL with umask option"
18426 # Run Socat with first address SHELL:"cat >file" with modified umask,
18427 # and second address SYSTEM (shell) with umask command.
18428 # Check if the file is created with modified umask but shell has original umask
18429 if ! eval $NUMCOND; then :;
18430 elif ! F=$(testfeats SHELL SYSTEM); then
18431 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18432 numCANT=$((numCANT+1))
18433 listCANT="$listCANT $N"
18434 elif ! A=$(testaddrs SHELL SYSTEM); then
18435 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18436 numCANT=$((numCANT+1))
18437 listCANT="$listCANT $N"
18438 elif ! o=$(testoptions umask) >/dev/null; then
18439 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18440 numCANT=$((numCANT+1))
18441 listCANT="$listCANT $N"
18442 else
18443 tf="$td/test$N.stdout"
18444 te="$td/test$N.stderr"
18445 tc="$td/test$N.creat"
18446 tdiff="$td/test$N.diff"
18447 tdebug="$td/test$N.debug"
18448 oumask=$(umask)
18449 # Construct a temp umask differing from original umask
18450 case oumask in
18451 *066) tumask=0026 ;;
18452 *) tumask=0066 ;;
18453 esac
18454 CMD0="$TRACE $SOCAT $opts -U SHELL:\"cat\ >$tc\",umask=$tumask SYSTEM:\"umask; sleep 1\""
18455 printf "test $F_n $TEST... " $N
18456 eval "$CMD0" >/dev/null 2>"${te}0"
18457 rc0=$?
18458 tperms=$(fileperms $tc)
18459 case $tperms in
18460 0*) ;;
18461 *) tperms=0$tperms ;;
18462 esac
18463 echo "Original umask: $oumask" >>$tdebug
18464 echo "Temporary umask: $tumask" >>$tdebug
18465 echo "Created umask: $tperms" >>$tdebug
18466 echo "Restored umask: $(cat $tc)" >>$tdebug
18467 if [ "$rc0" -ne 0 ]; then
18468 $PRINTF "$FAILED\n"
18469 echo "$CMD0 &"
18470 cat "${te}0" >&2
18471 numFAIL=$((numFAIL+1))
18472 listFAIL="$listFAIL $N"
18473 namesFAIL="$namesFAIL $NAME"
18474 elif [ $((tumask + tperms - 0666)) -ne 0 ]; then
18475 $PRINTF "$FAILED (umask failed)\n"
18476 echo "$CMD0 &"
18477 cat "${te}0" >&2
18478 numFAIL=$((numFAIL+1))
18479 listFAIL="$listFAIL $N"
18480 namesFAIL="$namesFAIL $NAME"
18481 elif ! [ "$oumask" -eq $(cat "$tc") ]; then
18482 $PRINTF "$FAILED (bad umask)\n"
18483 echo "$CMD0 &"
18484 cat "${te}0" >&2
18485 cat "$tdebug" >&2
18486 numFAIL=$((numFAIL+1))
18487 listFAIL="$listFAIL $N"
18488 namesFAIL="$namesFAIL $NAME"
18489 else
18490 $PRINTF "$OK\n"
18491 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18492 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18493 numOK=$((numOK+1))
18494 listOK="$listOK $N"
18496 fi # NUMCOND
18498 esac
18499 N=$((N+1))
18502 while read _UNIX _SRV _CLI; do
18503 if [ -z "$_UNIX" ] || [[ "$_UNIX" == \#* ]]; then continue; fi
18504 SRV=${_UNIX}-$_SRV
18505 CLI=${_UNIX}-$_CLI
18506 CLI_=$(echo $CLI |tr x- x_)
18507 PROTO=${_UNIX}
18508 proto=$(tolower $PROTO)
18510 # Test the unix-bind-tempname option
18511 NAME=${_UNIX}_${_SRV}_${_CLI}_BIND_TEMPNAME
18512 case "$TESTS" in
18513 *%$N%*|*%functions%*|*%$proto%*|*%socket%*|*%tempname%*|*%listen%*|*%fork%*|*%$NAME%*)
18514 TEST="$NAME: Option unix-bind-tempname"
18515 # Start a UNIX domain service with forking
18516 # Start a TCP service with forking that relays to the UNIX domain service
18517 # Open two concurrent client sessions to the TCP service.
18518 # When both sessions work (in particular, when the UNIX domain service does not
18519 # log "Transport endpoint is not connected" and the TCP service does not fail
18520 # with "Address already in use"), the test succeeded.
18521 if ! eval $NUMCOND; then :;
18522 elif [[ $CLI_ =~ ABSTRACT-* ]] && ! feat=$(testfeats abstract-unixsocket); then
18523 $PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
18524 numCANT=$((numCANT+1))
18525 listCANT="$listCANT $N"
18526 elif ! o=$(testoptions unix-bind-tempname) >/dev/null; then
18527 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18528 numCANT=$((numCANT+1))
18529 listCANT="$listCANT $N"
18530 else
18531 ts="$td/test$N.sock"
18532 tf="$td/test$N.stdout"
18533 te="$td/test$N.stderr"
18534 tdiff="$td/test$N.diff"
18535 da="test$N $(date) $RANDOM"
18536 CMD0="$TRACE $SOCAT $opts -lp server $SRV:${ts}0,fork PIPE"
18537 # Using this command would show the principal problem: UNIX (and ABSTRACT)
18538 # datagram clients do not internally bind to a defined address and thus cannot
18539 # receive replies. Applies to all(?) Linux, (some)FreeBSD, (some)Solaris, others
18540 # not tried
18541 #CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0"
18542 # Attempt to bind the datagram client to some address works, but only for a
18543 # single client; when multiple clients are forked they conflict
18544 # The following command is the solution: option unix-bind-tempname generates
18545 # random names (like tempnam(2)) for binding the datagram client socket;
18546 # creating the XXXXXX file makes sure that the (non abstract) clients cannot
18547 # erronously bind there (part of the test)
18548 CMD1="$TRACE $SOCAT $opts -lp bind-tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind=${ts}1"
18549 touch ${ts}1.XXXXXX; CMD1="$TRACE $SOCAT $opts -lp tempname TCP4-LISTEN:$PORT,reuseaddr,fork $CLI:${ts}0,bind-tempname=${ts}1.XXXXXX"
18550 CMD2="$TRACE $SOCAT $opts -lp client - TCP4-CONNECT:$LOCALHOST:$PORT"
18551 printf "test $F_n $TEST... " $N
18552 $CMD0 2>"${te}0" &
18553 pid0=$!
18554 wait${proto}port ${ts}0 1
18555 $CMD1 2>"${te}1" &
18556 pid1=$!
18557 waittcp4port $PORT 1
18558 { echo "$da a"; relsleep 2; } |$CMD2 >"${tf}2a" 2>"${te}2a" &
18559 pid2a=$!
18560 relsleep 1
18561 echo "$da b" |$CMD2 >"${tf}2b" 2>"${te}2b"
18562 rc2b=$?
18563 relsleep 1
18564 kill $pid0 $pid1 $pid2a 2>/dev/null; wait
18565 if [ $rc2b -ne 0 ]; then
18566 $PRINTF "$FAILED\n"
18567 echo "$CMD0 &"
18568 cat "${te}0" >&2
18569 echo "$CMD1 &"
18570 cat "${te}1" >&2
18571 echo "$CMD2 &"
18572 cat "${te}2a" >&2
18573 echo "$CMD2"
18574 cat "${te}2b" >&2
18575 numFAIL=$((numFAIL+1))
18576 listFAIL="$listFAIL $N"
18577 elif ! echo "$da a" |diff - ${tf}2a >${tdiff}2a; then
18578 $PRINTF "$FAILED (phase a)\n"
18579 echo "$CMD0 &"
18580 cat "${te}0" >&2
18581 echo "$CMD1 &"
18582 cat "${te}1" >&2
18583 echo "$CMD2"
18584 cat "${te}2a" >&2
18585 echo "diff a:" >&2
18586 cat ${tdiff}2a >&2
18587 numFAIL=$((numFAIL+1))
18588 listFAIL="$listFAIL $N"
18589 elif ! echo "$da b" |diff - ${tf}2b >${tdiff}2b; then
18590 $PRINTF "$FAILED\n"
18591 echo "$CMD0 &"
18592 cat "${te}0" >&2
18593 echo "$CMD1 &"
18594 cat "${te}1" >&2
18595 echo "$CMD2 &"
18596 cat "${te}2a" >&2
18597 echo "$CMD2"
18598 cat "${te}2b" >&2
18599 echo "diff b:" >&2
18600 cat ${tdiff}2b >&2
18601 numFAIL=$((numFAIL+1))
18602 listFAIL="$listFAIL $N"
18603 else
18604 $PRINTF "$OK\n"
18605 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18606 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18607 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18608 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18609 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18610 if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi
18611 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18612 if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi
18613 numOK=$((numOK+1))
18614 listOK="$listOK $N"
18616 fi # NUMCOND
18618 esac
18619 PORT=$((PORT+1))
18620 N=$((N+1))
18622 done <<<"
18623 UNIX LISTEN CONNECT
18624 UNIX LISTEN CLIENT
18625 UNIX RECVFROM CLIENT
18626 UNIX RECVFROM SENDTO
18627 ABSTRACT LISTEN CONNECT
18628 ABSTRACT LISTEN CLIENT
18629 ABSTRACT RECVFROM CLIENT
18630 ABSTRACT RECVFROM SENDTO
18633 # Test if OS/libc is not prone to symlink attacks on UNIX bind()
18634 NAME=TEMPNAME_SEC
18635 case "$TESTS" in
18636 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%unix%*|*%dgram%*|*%security%*|*%$NAME%*)
18637 TEST="$NAME: test if a symlink attack works against bind()"
18638 # Create a symlink .sock2 pointing to non-existing .sock3
18639 # Start Socat with UNIX-SENDTO...,bind=.sock2
18640 # When .sock3 exists the test failed
18641 if ! eval $NUMCOND; then :; else
18642 tf="$td/test$N.stdout"
18643 te="$td/test$N.stderr"
18644 ts1="$td/test$N.sock1"
18645 ts2="$td/test$N.sock2"
18646 ts3="$td/test$N.sock3"
18647 tdiff="$td/test$N.diff"
18648 da="test$N $(date) $RANDOM"
18649 CMD0a="rm -f $ts3"
18650 CMD0b="ln -s $ts3 $ts2"
18651 CMD1="$TRACE $SOCAT $opts UNIX-SENDTO:$ts1,bind=$ts2 PIPE"
18652 rc1=$?
18653 printf "test $F_n $TEST... " $N
18654 $CMD0a
18655 $CMD0b
18656 #echo; ls -l $ts2 $ts3
18657 $CMD1 2>"${te}1" &
18658 pid1=$!
18659 waitunixport $ts1 1 1 2>/dev/null
18660 #res="$(ls -l $ts3 2>/dev/null)"
18661 kill $pid1 2>/dev/null
18662 if [ -e $ts3 ]; then
18663 $PRINTF "$FAILED\n"
18664 echo "symlink target has been created" >&2
18665 echo "$CMD0a" >&2
18666 cat "${te}0a" >&2
18667 echo "$CMD0b" >&2
18668 cat "${te}0b" >&2
18669 echo "$CMD1" >&2
18670 cat "${te}1" >&2
18671 numFAIL=$((numFAIL+1))
18672 listFAIL="$listFAIL $N"
18673 elif ! grep -q " E " ${te}1; then
18674 $PRINTF "$FAILED\n"
18675 echo "Socat did not fail"
18676 echo "$CMD0a" >&2
18677 cat "${te}0a" >&2
18678 echo "$CMD0b" >&2
18679 cat "${te}0b" >&2
18680 echo "$CMD1" >&2
18681 cat "${te}1" >&2
18682 numFAIL=$((numFAIL+1))
18683 listFAIL="$listFAIL $N"
18684 else
18685 $PRINTF "$OK\n"
18686 if [ "$VERBOSE" ]; then echo "$CMD0a"; fi
18687 if [ "$DEBUG" ]; then cat "${te}0a" >&2; fi
18688 if [ "$VERBOSE" ]; then echo "$CMD0b"; fi
18689 if [ "$DEBUG" ]; then cat "${te}0b" >&2; fi
18690 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18691 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18692 numOK=$((numOK+1))
18693 listOK="$listOK $N"
18695 fi # NUMCOND
18697 esac
18698 PORT=$((PORT+1))
18699 N=$((N+1))
18702 # Test the new f-setpipe-sz option on a STDIN pipe
18703 NAME=STDIN_F_SETPIPE_SZ
18704 case "$TESTS" in
18705 *%$N%*|*%functions%*|*%filan%*|*%dual%*|*%stdio%*|*%exec%*|*%pipe%*|*%f-setpipe-sz%*|*%$NAME%*)
18706 TEST="$NAME: f-setpipe-sz on STDIN"
18707 # Start Socat in a shell pipe and have it calling Filan via EXEC and nofork
18708 # Check Filan output if pipe size of its input pipe is modified.
18709 if ! eval $NUMCOND; then :;
18710 elif ! $(type true >/dev/null 2>&1); then
18711 $PRINTF "test $F_n $TEST... ${YELLOW}true not available${NORMAL}\n" $N
18712 numCANT=$((numCANT+1))
18713 listCANT="$listCANT $N"
18714 elif ! F=$(testfeats STDIO EXEC); then
18715 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18716 numCANT=$((numCANT+1))
18717 listCANT="$listCANT $N"
18718 elif ! A=$(testaddrs STDIO EXEC); then
18719 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18720 numCANT=$((numCANT+1))
18721 listCANT="$listCANT $N"
18722 elif ! o=$(testoptions f-setpipe-sz nofork) >/dev/null; then
18723 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18724 numCANT=$((numCANT+1))
18725 listCANT="$listCANT $N"
18726 else
18727 tf="$td/test$N.stdout"
18728 te="$td/test$N.stderr"
18729 tdiff="$td/test$N.diff"
18730 da="test$N $(date) $RANDOM"
18731 newport tcp4 # or whatever proto, or drop this line
18732 # Find the default pipe size
18733 PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18734 PIPESZ2=$((2*PIPESZ))
18735 CMD0="$TRACE $SOCAT $opts STDIN,f-setpipe-sz=$PIPESZ2!!STDOUT EXEC:$FILAN,nofork"
18736 printf "test $F_n $TEST... " $N
18737 true |$CMD0 >"${tf}" 2>"${te}0"
18738 rc0=$?
18739 PIPESZ2b="$(cat "$tf" |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18740 if [ "$rc0" -ne 0 ]; then
18741 $PRINTF "$FAILED\n"
18742 echo "$CMD0"
18743 cat "${te}0" >&2
18744 numFAIL=$((numFAIL+1))
18745 listFAIL="$listFAIL $N"
18746 namesFAIL="$namesFAIL $NAME"
18747 elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then
18748 $PRINTF "$FAILED\n"
18749 echo "$CMD0"
18750 cat "${te}0" >&2
18751 echo "diff:" >&2
18752 cat "$tdiff" >&2
18753 numFAIL=$((numFAIL+1))
18754 listFAIL="$listFAIL $N"
18755 namesFAIL="$namesFAIL $NAME"
18756 else
18757 $PRINTF "$OK\n"
18758 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
18759 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18760 numOK=$((numOK+1))
18761 listOK="$listOK $N"
18763 fi # NUMCOND
18765 esac
18766 N=$((N+1))
18768 # Test the new f-setpipe-sz option on EXEC with pipes
18769 NAME=EXEC_F_SETPIPE_SZ
18770 case "$TESTS" in
18771 *%$N%*|*%functions%*|*%filan%*|*%stdio%*|*%exec%*|*%pipe%*|*%f-setpipe-sz%*|*%$NAME%*)
18772 TEST="$NAME: f-setpipe-sz on EXEC with pipes"
18773 # Start Socat calling Filan via EXEC and pipes and f-setpipe-sz
18774 # Check Filan output if pipe size of both pipes is modified.
18775 if ! eval $NUMCOND; then :;
18776 elif ! F=$(testfeats STDIO EXEC); then
18777 $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
18778 numCANT=$((numCANT+1))
18779 listCANT="$listCANT $N"
18780 elif ! A=$(testaddrs STDIO EXEC); then
18781 $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
18782 numCANT=$((numCANT+1))
18783 listCANT="$listCANT $N"
18784 elif ! o=$(testoptions pipes f-setpipe-sz) >/dev/null; then
18785 $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
18786 numCANT=$((numCANT+1))
18787 listCANT="$listCANT $N"
18788 else
18789 tf="$td/test$N.stdout"
18790 te="$td/test$N.stderr"
18791 tdiff="$td/test$N.diff"
18792 # Find the default pipe size
18793 PIPESZ="$(echo |$FILAN -n 0 |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18794 PIPESZ2=$((2*PIPESZ))
18795 CMD0="$TRACE $SOCAT $opts STDIO EXEC:$FILAN,pipes,f-setpipe-sz=$PIPESZ2"
18796 printf "test $F_n $TEST... " $N
18797 $CMD0 >"$tf" 2>"${te}0"
18798 rc0=$?
18799 PIPESZ2b="$(cat "$tf" |grep "0:" |head -n 1 |sed 's/.*F_GETPIPE_SZ=\([0-9][0-9]*\).*/\1/')"
18800 if [ "$rc0" -ne 0 ]; then
18801 $PRINTF "$FAILED\n"
18802 echo "$CMD0"
18803 cat "${te}0" >&2
18804 numFAIL=$((numFAIL+1))
18805 listFAIL="$listFAIL $N"
18806 namesFAIL="$namesFAIL $NAME"
18807 elif ! diff <(echo $PIPESZ2) <(echo $PIPESZ2b) >$tdiff; then
18808 $PRINTF "$FAILED\n"
18809 echo "$CMD0 &"
18810 cat "${te}0" >&2
18811 echo "diff:" >&2
18812 cat "$tdiff" >&2
18813 numFAIL=$((numFAIL+1))
18814 listFAIL="$listFAIL $N"
18815 namesFAIL="$namesFAIL $NAME"
18816 else
18817 $PRINTF "$OK\n"
18818 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
18819 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18820 numOK=$((numOK+1))
18821 listOK="$listOK $N"
18823 fi # NUMCOND
18825 esac
18826 N=$((N+1))
18829 NAME=DCCP4
18830 case "$TESTS" in
18831 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%dccp%*|*%listen%*|*%$NAME%*)
18832 TEST="$NAME: DCCP over IPv4"
18833 if ! eval $NUMCOND; then :
18834 elif ! cond=$(checkconds "" "" "" \
18835 "IP4 DCCP LISTEN STDIO PIPE" \
18836 "DCCP4-LISTEN PIPE STDIN STDOUT DCCP4" \
18837 "so-reuseaddr" \
18838 "dccp4" ); then
18839 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18840 numCANT=$((numCANT+1))
18841 listCANT="$listCANT $N"
18842 else
18843 tf="$td/test$N.stdout"
18844 te="$td/test$N.stderr"
18845 tdiff="$td/test$N.diff"
18846 newport dccp4; tsl=$PORT
18847 ts="127.0.0.1:$tsl"
18848 da="test$N $(date) $RANDOM"
18849 CMD1="$TRACE $SOCAT $opts DCCP4-LISTEN:$tsl,$REUSEADDR PIPE"
18850 CMD2="$TRACE $SOCAT $opts STDIN!!STDOUT DCCP4:$ts"
18851 printf "test $F_n $TEST... " $N
18852 $CMD1 >"$tf" 2>"${te}1" &
18853 pid1=$!
18854 waittcp4port $tsl 1
18855 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18856 if [ $? -ne 0 ]; then
18857 $PRINTF "$FAILED\n"
18858 echo "$CMD0 &"
18859 cat "${te}0" >&2
18860 echo "$CMD1"
18861 cat "${te}1" >&2
18862 numFAIL=$((numFAIL+1))
18863 listFAIL="$listFAIL $N"
18864 namesFAIL="$namesFAIL $NAME"
18865 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
18866 $PRINTF "$FAILED\n"
18867 echo "$CMD0 &"
18868 cat "${te}0" >&2
18869 echo "$CMD1"
18870 cat "${te}1" >&2
18871 echo "// diff:" >&2
18872 cat "$tdiff" >&2
18873 numFAIL=$((numFAIL+1))
18874 listFAIL="$listFAIL $N"
18875 namesFAIL="$namesFAIL $NAME"
18876 else
18877 $PRINTF "$OK\n"
18878 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
18879 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
18880 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
18881 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18882 numOK=$((numOK+1))
18883 listOK="$listOK $N"
18885 kill $pid1 2>/dev/null
18886 wait
18887 fi ;; # NUMCOND, checkconds
18888 esac
18889 N=$((N+1))
18892 NAME=UDPLITE4STREAM
18893 case "$TESTS" in
18894 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
18895 TEST="$NAME: echo via connection to UDP-Lite V4 socket"
18896 if ! eval $NUMCOND; then :;
18897 elif ! cond=$(checkconds \
18898 "" \
18899 "" \
18900 "" \
18901 "IP4 UDPLITE LISTEN STDIO PIPE" \
18902 "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
18903 "so-reuseaddr" \
18904 "udplite4" ); then
18905 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18906 numCANT=$((numCANT+1))
18907 listCANT="$listCANT $N"
18908 namesCANT="$namesCANT $NAME"
18909 else
18910 tf="$td/test$N.stdout"
18911 te="$td/test$N.stderr"
18912 tdiff="$td/test$N.diff"
18913 tsl=$PORT
18914 ts="$LOCALHOST:$tsl"
18915 da="test$N $(date) $RANDOM"
18916 CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
18917 CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
18918 printf "test $F_n $TEST... " $N
18919 $CMD1 >"$tf" 2>"${te}1" &
18920 pid1=$!
18921 waitudplite4port $tsl 1
18922 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18923 rc2=$?
18924 kill $pid1 2>/dev/null; wait
18925 if [ $rc2 -ne 0 ]; then
18926 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
18927 echo "$CMD1 &"
18928 cat "${te}1" >&2
18929 echo "$CMD2"
18930 cat "${te}2" >&2
18931 numFAIL=$((numFAIL+1))
18932 listFAIL="$listFAIL $N"
18933 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
18934 $PRINTF "$FAILED (diff)\n"
18935 echo "$CMD1 &" >&2
18936 cat "${te}1"
18937 echo "$CMD2" >&2
18938 cat "${te}2" >&2
18939 echo "// diff:" >&2
18940 cat "$tdiff" >&2
18941 numFAIL=$((numFAIL+1))
18942 listFAIL="$listFAIL $N"
18943 namesFAIL="$namesFAIL $NAME"
18944 else
18945 $PRINTF "$OK\n"
18946 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
18947 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
18948 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
18949 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
18950 numOK=$((numOK+1))
18951 listOK="$listOK $N"
18953 fi ;; # NUMCOND
18954 esac
18955 PORT=$((PORT+1))
18956 N=$((N+1))
18959 NAME=UDPLITE4STREAM
18960 case "$TESTS" in
18961 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
18962 TEST="$NAME: echo via connection to UDP-Lite V4 socket"
18963 if ! eval $NUMCOND; then :;
18964 elif ! cond=$(checkconds \
18965 "" \
18966 "" \
18967 "" \
18968 "IP4 UDPLITE LISTEN STDIO PIPE" \
18969 "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
18970 "so-reuseaddr" \
18971 "udplite4" ); then
18972 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
18973 numCANT=$((numCANT+1))
18974 listCANT="$listCANT $N"
18975 namesCANT="$namesCANT $NAME"
18976 else
18977 tf="$td/test$N.stdout"
18978 te="$td/test$N.stderr"
18979 tdiff="$td/test$N.diff"
18980 tsl=$PORT
18981 ts="$LOCALHOST:$tsl"
18982 da="test$N $(date) $RANDOM"
18983 CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
18984 CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
18985 printf "test $F_n $TEST... " $N
18986 $CMD1 >"$tf" 2>"${te}1" &
18987 pid1=$!
18988 waitudplite4port $tsl 1
18989 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
18990 rc2=$?
18991 kill $pid1 2>/dev/null; wait
18992 if [ $rc2 -ne 0 ]; then
18993 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
18994 echo "$CMD1 &"
18995 cat "${te}1" >&2
18996 echo "$CMD2"
18997 cat "${te}2" >&2
18998 numFAIL=$((numFAIL+1))
18999 listFAIL="$listFAIL $N"
19000 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
19001 $PRINTF "$FAILED (diff)\n"
19002 echo "$CMD1 &" >&2
19003 cat "${te}1"
19004 echo "$CMD2" >&2
19005 cat "${te}2" >&2
19006 echo "// diff:" >&2
19007 cat "$tdiff" >&2
19008 numFAIL=$((numFAIL+1))
19009 listFAIL="$listFAIL $N"
19010 namesFAIL="$namesFAIL $NAME"
19011 else
19012 $PRINTF "$OK\n"
19013 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
19014 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19015 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
19016 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
19017 numOK=$((numOK+1))
19018 listOK="$listOK $N"
19020 fi ;; # NUMCOND
19021 esac
19022 PORT=$((PORT+1))
19023 N=$((N+1))
19026 NAME=UDPLITE4STREAM
19027 case "$TESTS" in
19028 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
19029 TEST="$NAME: echo via connection to UDP-Lite V4 socket"
19030 if ! eval $NUMCOND; then :;
19031 elif ! cond=$(checkconds \
19032 "" \
19033 "" \
19034 "" \
19035 "IP4 UDPLITE LISTEN STDIO PIPE" \
19036 "UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
19037 "so-reuseaddr" \
19038 "udplite4" ); then
19039 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19040 numCANT=$((numCANT+1))
19041 listCANT="$listCANT $N"
19042 namesCANT="$namesCANT $NAME"
19043 else
19044 tf="$td/test$N.stdout"
19045 te="$td/test$N.stderr"
19046 tdiff="$td/test$N.diff"
19047 tsl=$PORT
19048 ts="$LOCALHOST:$tsl"
19049 da="test$N $(date) $RANDOM"
19050 CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
19051 CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
19052 printf "test $F_n $TEST... " $N
19053 $CMD1 >"$tf" 2>"${te}1" &
19054 pid1=$!
19055 waitudplite4port $tsl 1
19056 echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
19057 rc2=$?
19058 kill $pid1 2>/dev/null; wait
19059 if [ $rc2 -ne 0 ]; then
19060 $PRINTF "$FAILED: $TRACE $SOCAT:\n"
19061 echo "$CMD1 &"
19062 cat "${te}1" >&2
19063 echo "$CMD2"
19064 cat "${te}2" >&2
19065 numFAIL=$((numFAIL+1))
19066 listFAIL="$listFAIL $N"
19067 elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
19068 $PRINTF "$FAILED (diff)\n"
19069 echo "$CMD1 &" >&2
19070 cat "${te}1"
19071 echo "$CMD2" >&2
19072 cat "${te}2" >&2
19073 echo "// diff:" >&2
19074 cat "$tdiff" >&2
19075 numFAIL=$((numFAIL+1))
19076 listFAIL="$listFAIL $N"
19077 namesFAIL="$namesFAIL $NAME"
19078 else
19079 $PRINTF "$OK\n"
19080 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
19081 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19082 if [ "$VERBOSE" ]; then echo "$CMD2"; fi
19083 if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
19084 numOK=$((numOK+1))
19085 listOK="$listOK $N"
19087 fi ;; # NUMCOND
19088 esac
19089 PORT=$((PORT+1))
19090 N=$((N+1))
19093 # test: setting of environment variables that describe a stream socket
19094 # connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT,
19095 # SOCAT_PEERPORT when applicable
19096 while read KEYW FEAT SEL TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
19097 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
19099 protov="$(echo "$KEYW" |tr A-Z a-z)"
19100 proto="${protov%%[0-9]}"
19101 NAME=${KEYW}LISTENENV
19102 case "$TESTS" in
19103 *%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%$SEL%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
19104 TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
19105 # have a server accepting a connection and invoking some shell code. The shell
19106 # code extracts and prints the SOCAT related environment vars.
19107 # outside code then checks if the environment contains the variables correctly
19108 # describing the peer and local sockets.
19109 if ! eval $NUMCOND; then :;
19110 elif ! cond=$(checkconds \
19111 "" \
19112 "" \
19113 "" \
19114 "$FEAT $(echo $SEL |tr a-z A-Z) STDIO SYSTEM" \
19115 "$KEYW-LISTEN SYSTEM STDIO $KEYW-CONNECT" \
19116 "$REUSEADDR bind" \
19117 "$protov" ); then
19118 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19119 numCANT=$((numCANT+1))
19120 listCANT="$listCANT $N"
19121 namesCANT="$namesCANT $NAME"
19122 else
19123 tf="$td/test$N.stdout"
19124 te="$td/test$N.stderr"
19125 TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars
19126 tsa="$TEST_SOCKADDR" # test server address
19127 if [ "$PORTMETHOD" = PORT ]; then
19128 newport $proto; tsp="$PORT"; # test server port
19129 tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind=
19130 TEST_SOCKPORT=$tsp
19131 else
19132 tsa1="$tsa"; tsa2= # tsa1 used for addr parameter
19134 TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars
19135 tca="$TEST_PEERADDR" # test client address
19136 if [ "$PORTMETHOD" = PORT ]; then
19137 newport $proto; tcp="$PORT"; # test client port
19138 tca="$tca:$tcp"
19139 TEST_PEERPORT=$tcp
19141 #CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\""
19142 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\""
19143 CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
19144 printf "test $F_n $TEST... " $N
19145 eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
19146 pid0=$!
19147 wait${protov}port $tsa1 1
19148 { echo; sleep 0.1; } |$CMD1 2>"${te}1"
19149 rc1=$?
19150 waitfile "$tf" 2
19151 kill $pid0 2>/dev/null; wait
19152 #set -vx
19153 if [ $rc1 != 0 ]; then
19154 $PRINTF "$NO_RESULT (client failed):\n"
19155 echo "$CMD0 &"
19156 cat "${te}0"
19157 echo "$CMD1"
19158 cat "${te}1"
19159 numCANT=$((numCANT+1))
19160 listCANT="$listCANT $N"
19161 elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
19162 "$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
19163 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_SOCKPORT" \) -a \
19164 \( "$PORTMETHOD" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$TEST_PEERPORT" \) \
19165 ]; then
19166 $PRINTF "$OK\n"
19167 if [ "$debug" ]; then
19168 echo "$CMD0 &"
19169 cat "${te}0"
19170 echo "$CMD1"
19171 cat "${te}1"
19173 numOK=$((numOK+1))
19174 listOK="$listOK $N"
19175 else
19176 $PRINTF "$FAILED\n"
19177 echo "$CMD0 &"
19178 cat "${te}0"
19179 echo "$CMD1"
19180 cat "${te}1"
19181 echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
19182 diff - "${tf}"
19183 numFAIL=$((numFAIL+1))
19184 listFAIL="$listFAIL $N"
19186 fi # NUMCOND, feats
19188 esac
19189 N=$((N+1))
19190 #set +xv
19192 done <<<"
19193 UDPLITE4 IP4 udplite 127.0.0.1 $SECONDADDR PORT
19194 UDPLITE6 IP6 udplite [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
19198 # test the max-children option on pseudo connected sockets
19199 while read KEYW FEAT SEL ADDR IPPORT SHUT; do
19200 if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
19201 RUNS=$(tolower $KEYW)
19202 PROTO=$KEYW
19203 proto="$(tolower "$PROTO")"
19204 # test the max-children option on pseudo connected sockets
19205 NAME=${KEYW}MAXCHILDREN
19206 case "$TESTS" in
19207 *%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
19208 TEST="$NAME: max-children option"
19209 # start a listen process with max-children=1; connect with a client, let it
19210 # send data and then sleep; connect with second client that wants to send
19211 # data immediately, but keep first client active until server terminates.
19212 #If max-children is working correctly only the first data should
19213 # arrive.
19214 if ! eval $NUMCOND; then :;
19215 elif ! cond=$(checkconds \
19216 "" \
19217 "" \
19218 "" \
19219 "$FEAT IP${KEYW##*[A-Z]} FILE STDIO" \
19220 "FILE $PROTO-LISTEN STDIO $KEYW-CONNECT" \
19221 "$REUSEADDR o-trunc o-creat o-append fork max-children $SHUT" \
19222 "$RUNS" ); then
19223 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19224 numCANT=$((numCANT+1))
19225 listCANT="$listCANT $N"
19226 namesCANT="$namesCANT $NAME"
19227 else
19228 case "X$IPPORT" in
19229 "XPORT")
19230 newport $proto
19231 tsl=$PORT # test socket listen address
19232 tsc="$ADDR:$PORT" # test socket connect address
19235 tsl="$(eval echo "$ADDR")" # resolve $N
19236 tsc=$tsl
19237 esac
19238 #ts="$td/test$N.sock"
19239 tf="$td/test$N.stdout"
19240 te="$td/test$N.stderr"
19241 tdiff="$td/test$N.diff"
19242 da="test$N $(date) $RANDOM"
19243 # on some Linux distributions it hangs, thus -T option here
19244 CMD0="$TRACE $SOCAT $opts -U -T 4 FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
19245 CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,$SHUT"
19246 printf "test $F_n $TEST... " $N
19247 $CMD0 >/dev/null 2>"${te}0" &
19248 pid0=$!
19249 wait${proto}port $tsl 1
19250 (echo "$da 1"; relsleep 3) |$CMD1 >"${tf}1" 2>"${te}1" &
19251 pid1=$!
19252 relsleep 1
19253 echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
19254 pid2=$!
19255 relsleep 1
19256 cpids="$(childpids $pid0)"
19257 kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait
19258 if echo -e "$da 1" |diff - $tf >$tdiff; then
19259 $PRINTF "$OK\n"
19260 numOK=$((numOK+1))
19261 listOK="$listOK $N"
19262 else
19263 $PRINTF "$FAILED\n"
19264 echo "$CMD0 &"
19265 echo "(echo \"$da 1\"; sleep 2) |$CMD1"
19266 echo "echo \"$da 2\" |$CMD1"
19267 cat "${te}0"
19268 cat "${te}1"
19269 cat "${te}2"
19270 cat "$tdiff"
19271 numFAIL=$((numFAIL+1))
19272 listFAIL="$listFAIL $N"
19274 fi # NUMCOND
19276 esac
19277 N=$((N+1))
19278 done <<<"
19279 UDPLITE4 UDPLITE udplite 127.0.0.1 PORT shut-null
19280 UDPLITE6 UDPLITE udplite [::1] PORT shut-null
19284 # Test the procan controlling terminal output
19285 NAME=PROCAN_CTTY
19286 case "$TESTS" in
19287 *%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
19288 TEST="$NAME: test procan controlling terminal output"
19289 # Run procan and compare its controlling terminal output with tty (oops)"
19290 if ! eval $NUMCOND; then :
19291 elif ! cond=$(checkconds \
19292 "" \
19293 "" \
19294 "tty" \
19295 "" \
19296 "" \
19297 "" \
19298 "" ); then
19299 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19300 numCANT=$((numCANT+1))
19301 listCANT="$listCANT $N"
19302 else
19303 tf="$td/test$N.stdout"
19304 te="$td/test$N.stderr"
19305 tdiff="$td/test$N.diff"
19306 CMD0="$TRACE $PROCAN"
19307 printf "test $F_n $TEST... " $N
19308 $CMD0 >"${tf}0" 2>"${te}0"
19309 rc0=$?
19310 if [ "$rc0" -ne 0 ]; then
19311 $PRINTF "$FAILED\n"
19312 echo "$CMD0"
19313 cat "${te}0" >&2
19314 numFAIL=$((numFAIL+1))
19315 listFAIL="$listFAIL $N"
19316 namesFAIL="$namesFAIL $NAME"
19317 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
19318 $PRINTF "$FAILED\n"
19319 echo "$CMD0"
19320 cat "${te}0" >&2
19321 echo "// diff:" >&2
19322 cat "$tdiff" >&2
19323 numFAIL=$((numFAIL+1))
19324 listFAIL="$listFAIL $N"
19325 namesFAIL="$namesFAIL $NAME"
19326 else
19327 $PRINTF "$OK\n"
19328 if [ "$VERBOSE" ]; then echo "$CMD0"; fi
19329 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19330 numOK=$((numOK+1))
19331 listOK="$listOK $N"
19333 fi # NUMCOND
19335 esac
19336 N=$((N+1))
19339 # Test the socat-chain.sh script with SOCKS4 over UNIX-socket
19340 NAME=SOCAT_CHAIN_SOCKS4
19341 case "$TESTS" in
19342 *%$N%*|*%functions%*|*%scripts%*|*%socat-chain%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%unix%*|*%socks4%*|*%socket%*|*%$NAME%*)
19343 TEST="$NAME: test socat-chain.sh with SOCKS4 over UNIX-socket"
19344 # Run a socks4 server on UNIX-listen
19345 # Connect with socat-chain.sh; check if data transfer is correct
19346 if ! eval $NUMCOND; then :
19347 elif ! cond=$(checkconds \
19348 "" \
19349 "" \
19350 "" \
19351 "IP4 TCP LISTEN STDIO UNIX SOCKS4" \
19352 "TCP4-LISTEN PIPE STDIN STDOUT TCP4 UNIX UNIX-LISTEN" \
19353 "so-reuseaddr" \
19354 "tcp4 unix" ); then
19355 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19356 numCANT=$((numCANT+1))
19357 listCANT="$listCANT $N"
19358 namesCANT="$namesCANT $NAME"
19359 else
19360 ts="$td/test$N.sock"
19361 tf="$td/test$N.stdout"
19362 te="$td/test$N.stderr"
19363 tdiff="$td/test$N.diff"
19364 da="test$N $(date) $RANDOM"
19365 CMD0="$TRACE $SOCAT $opts UNIX-LISTEN:$ts,reuseaddr EXEC:./socks4echo.sh"
19366 CMD1="$TRACE ./socat-chain.sh $opts - SOCKS4::32.98.76.54:32109,socksuser=nobody UNIX:$ts"
19367 printf "test $F_n $TEST... " $N
19368 $CMD0 >/dev/null 2>"${te}0" &
19369 pid0=$!
19370 waitunixport $ts 1
19371 #relsleep 1 # if no matching wait*port function
19372 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
19373 rc1=$?
19374 kill $pid0 2>/dev/null; wait
19375 if [ "$rc1" -ne 0 ]; then
19376 $PRINTF "$FAILED (rc1=$rc1)\n"
19377 echo "$CMD0 &"
19378 cat "${te}0" >&2
19379 echo "$CMD1"
19380 cat "${te}1" >&2
19381 numFAIL=$((numFAIL+1))
19382 listFAIL="$listFAIL $N"
19383 namesFAIL="$namesFAIL $NAME"
19384 elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
19385 $PRINTF "$FAILED (diff)\n"
19386 echo "$CMD0 &"
19387 cat "${te}0" >&2
19388 echo "$CMD1"
19389 cat "${te}1" >&2
19390 echo "// diff:" >&2
19391 cat "$tdiff" >&2
19392 numFAIL=$((numFAIL+1))
19393 listFAIL="$listFAIL $N"
19394 namesFAIL="$namesFAIL $NAME"
19395 else
19396 $PRINTF "$OK\n"
19397 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19398 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19399 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
19400 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19401 numOK=$((numOK+1))
19402 listOK="$listOK $N"
19404 fi # NUMCOND
19406 esac
19407 N=$((N+1))
19409 # Test the socat-chain.sh script by driving SSL over serial
19410 NAME=SOCAT_CHAIN_SSL_PTY
19411 case "$TESTS" in
19412 *%$N%*|*%functions%*|*%scripts%*|*%socat-chain%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%openssl%*|*%unix%*|*%socket%*|*%pty%*|*%$NAME%*)
19413 TEST="$NAME: test socat-chain.sh with SSL over PTY"
19414 # Run a socat-chain.sh instance with SSL listening behind a PTY;
19415 # open the PTY with socat-chain.sh using SSL;
19416 # check if data transfer is correct
19417 if ! eval $NUMCOND; then :
19418 elif ! cond=$(checkconds \
19419 "" \
19420 "" \
19421 "" \
19422 "IP4 TCP LISTEN OPENSSL STDIO PTY" \
19423 "TCP4-LISTEN SOCKETPAIR STDIN STDOUT TCP4 SSL SSL-L" \
19424 "so-reuseaddr" \
19425 "tcp4" ); then
19426 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19427 numCANT=$((numCANT+1))
19428 listCANT="$listCANT $N"
19429 namesCANT="$namesCANT $NAME"
19430 elif [[ $BASH_VERSION =~ ^[1-3]\. ]]; then
19431 $PRINTF "test $F_n $TEST... ${YELLOW}requires bash 4 or higher${NORMAL}\n" $N
19432 numCANT=$((numCANT+1))
19433 listCANT="$listCANT $N"
19434 namesCANT="$namesCANT $NAME"
19435 else
19436 gentestcert testsrv
19437 tp="$td/test$N.pty"
19438 tf="$td/test$N.stdout"
19439 te="$td/test$N.stderr"
19440 tdiff="$td/test$N.diff"
19441 da="test$N $(date) $RANDOM"
19442 CMD0="$TRACE ./socat-chain.sh $opts PTY,link=$tp SSL-L,cert=testsrv.pem,verify=0 SOCKETPAIR"
19443 CMD1="$TRACE ./socat-chain.sh $opts - SSL,cafile=testsrv.crt,commonname=localhost $tp,cfmakeraw"
19444 printf "test $F_n $TEST... " $N
19445 $CMD0 >/dev/null 2>"${te}0" &
19446 pid0=$!
19447 waittcp4port $tp
19448 # NetBSD-9 seems to need massive delay
19449 { echo "$da"; relsleep 100; } |$CMD1 >"${tf}1" 2>"${te}1"
19450 rc1=$?
19451 kill $pid0 2>/dev/null
19452 wait 2>/dev/null
19453 if [ "$rc1" -ne 0 ]; then
19454 $PRINTF "$FAILED (rc1=$rc1)\n"
19455 echo "$CMD0 &"
19456 cat "${te}0" >&2
19457 echo "$CMD1"
19458 cat "${te}1" >&2
19459 numFAIL=$((numFAIL+1))
19460 listFAIL="$listFAIL $N"
19461 namesFAIL="$namesFAIL $NAME"
19462 elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
19463 $PRINTF "$FAILED (diff)\n"
19464 echo "$CMD0 &"
19465 cat "${te}0" >&2
19466 echo "$CMD1"
19467 cat "${te}1" >&2
19468 echo "// diff:" >&2
19469 cat "$tdiff" >&2
19470 numFAIL=$((numFAIL+1))
19471 listFAIL="$listFAIL $N"
19472 namesFAIL="$namesFAIL $NAME"
19473 else
19474 $PRINTF "$OK\n"
19475 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19476 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19477 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
19478 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19479 numOK=$((numOK+1))
19480 listOK="$listOK $N"
19482 fi # NUMCOND
19484 esac
19485 N=$((N+1))
19488 # Test the socat-mux.sh script
19489 # Requires lo/lo0 to have broadcast address 127.255.255.255
19490 NAME=SOCAT_MUX
19491 case "$TESTS" in
19492 *%$N%*|*%functions%*|*%script%*|*%socat-mux%*|*%socket%*|*%udp%*|*%broadcast%*|*%$NAME%*)
19493 TEST="$NAME: test the socat-mux.sh script"
19494 # Start a simple TCP server
19495 # Start socat-mux.sh to connect to this server
19496 # Connect with two clients to mux, send different data records from both.
19497 # Check if both clients received both records in order.
19498 if ! eval $NUMCOND; then :
19499 elif ! cond=$(checkconds \
19500 "" \
19501 "" \
19502 "" \
19503 "IP4 TCP LISTEN STDIO UNIX" \
19504 "TCP4-LISTEN PIPE STDIN STDOUT TCP4 UNIX UNIX-LISTEN" \
19505 "so-reuseaddr" \
19506 "tcp4 unix" ); then
19507 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19508 numCANT=$((numCANT+1))
19509 listCANT="$listCANT $N"
19510 namesCANT="$namesCANT $NAME"
19511 else
19512 tf="$td/test$N.stdout"
19513 te="$td/test$N.stderr"
19514 tdiff="$td/test$N.diff"
19515 newport tcp4
19516 PORT0=$PORT
19517 newport tcp4
19518 PORT1=$PORT
19519 CMD0="$TRACE $SOCAT $opts -lp server TCP-LISTEN:$PORT0 PIPE"
19520 CMD1="./socat-mux.sh $opts TCP-LISTEN:$PORT1 TCP-CONNECT:$LOCALHOST:$PORT0"
19521 CMD2="$TRACE $SOCAT $opts -lp client STDIO TCP:$LOCALHOST:$PORT1"
19522 da_a="test$N $(date) $RANDOM"
19523 da_b="test$N $(date) $RANDOM"
19524 printf "test $F_n $TEST... " $N
19525 $CMD0 >/dev/null 2>"${te}0" &
19526 pid0=$!
19527 waittcp4port $PORT0 1
19528 $CMD1 >/dev/null 2>"${te}1" &
19529 pid1=$!
19530 waittcp4port $PORT1 1
19531 { relsleep 10; echo "$da_a"; relsleep 20; } </dev/null |$CMD2 >"${tf}2a" 2>"${te}2a" &
19532 pid2a=$!
19533 { relsleep 20; echo "$da_b"; relsleep 10; } |$CMD2 >"${tf}2b" 2>"${te}2b"
19534 rc2b=$?
19535 kill $pid0 $(childpids $pid1) $pid1 2>/dev/null
19536 wait 2>/dev/null
19537 kill $pid0 2>/dev/null; wait
19538 if [ "$rc2b" -ne 0 ]; then
19539 $PRINTF "$FAILED (rc2b=$rc2b)\n"
19540 echo "$CMD0 &"
19541 cat "${te}0" >&2
19542 echo "$CMD1 &"
19543 cat "${te}1" >&2
19544 echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD2 &"
19545 cat "${te}2a" >&2
19546 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"
19547 cat "${te}2b" >&2
19548 numFAIL=$((numFAIL+1))
19549 listFAIL="$listFAIL $N"
19550 namesFAIL="$namesFAIL $NAME"
19551 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2a" >${tdiff}_a; then
19552 $PRINTF "$FAILED (diff a)\n"
19553 echo "$CMD0 &"
19554 cat "${te}0" >&2
19555 echo "$CMD1 &"
19556 cat "${te}1" >&2
19557 echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD2 &"
19558 cat "${te}2a" >&2
19559 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"
19560 cat "${te}2b" >&2
19561 echo "// diff a:" >&2
19562 cat "${tdiff}_a" >&2
19563 numFAIL=$((numFAIL+1))
19564 listFAIL="$listFAIL $N"
19565 namesFAIL="$namesFAIL $NAME"
19566 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}2b" >${tdiff}_b; then
19567 $PRINTF "$FAILED (diff b)\n"
19568 echo "$CMD0 &"
19569 cat "${te}0" >&2
19570 echo "$CMD1 &"
19571 cat "${te}1" >&2
19572 echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD2 &"
19573 cat "${te}2a" >&2
19574 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"
19575 cat "${te}2b" >&2
19576 echo "// diff b:" >&2
19577 cat "${tdiff}_b" >&2
19578 numFAIL=$((numFAIL+1))
19579 listFAIL="$listFAIL $N"
19580 namesFAIL="$namesFAIL $NAME"
19581 else
19582 $PRINTF "$OK\n"
19583 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19584 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19585 if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
19586 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19587 if [ "$VERBOSE" ]; then echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD2 &"; fi
19588 if [ "$DEBUG" ]; then cat "${te}2a" >&2; fi
19589 if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD2"; fi
19590 if [ "$DEBUG" ]; then cat "${te}2b" >&2; fi
19591 numOK=$((numOK+1))
19592 listOK="$listOK $N"
19594 fi # NUMCOND
19596 esac
19597 N=$((N+1))
19600 # Test the socat-broker.sh script
19601 # Requires lo/lo0 to have broadcast address 127.255.255.255
19602 NAME=SOCAT_BROKER
19603 case "$TESTS" in
19604 *%$N%*|*%functions%*|*%script%*|*%socat-broker%*|*%socket%*|*%udp%*|*%broadcast%*|*%$NAME%*)
19605 TEST="$NAME: test the socat-broker.sh script"
19606 # Start a socat-broker.sh instance
19607 # Connect with two clients, send different data records from both.
19608 # Check if both client received both records in order.
19609 if ! eval $NUMCOND; then :
19610 elif ! cond=$(checkconds \
19611 "" \
19612 "" \
19613 "" \
19614 "IP4 UDP TCP LISTEN STDIO" \
19615 "TCP4-LISTEN TCP4-CONNECT STDIO UDP-DATAGRAM" \
19616 "so-reuseaddr" \
19617 "udp4 tcp4" ); then
19618 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19619 numCANT=$((numCANT+1))
19620 listCANT="$listCANT $N"
19621 namesCANT="$namesCANT $NAME"
19622 else
19623 tf="$td/test$N.stdout"
19624 te="$td/test$N.stderr"
19625 tdiff="$td/test$N.diff"
19626 newport tcp4
19627 CMD0="$TRACE ./socat-broker.sh $OPTS TCP4-LISTEN:$PORT"
19628 CMD1="$TRACE $SOCAT $OPTS - TCP:$LOCALHOST:$PORT"
19629 da_a="test$N $(date) $RANDOM"
19630 da_b="test$N $(date) $RANDOM"
19631 printf "test $F_n $TEST... " $N
19632 $CMD0 >/dev/null 2>"${te}0" &
19633 pid0=$!
19634 waittcp4port $PORT 1
19635 { relsleep 10; echo "$da_a"; relsleep 20; } </dev/null |$CMD1 >"${tf}1a" 2>"${te}1a" &
19636 pid1a=$!
19637 { relsleep 20; echo "$da_b"; relsleep 10; } |$CMD1 >"${tf}1b" 2>"${te}1b"
19638 rc1b=$?
19639 kill $(childpids $pid0) $pid0 $pid1a 2>/dev/null
19640 wait 2>/dev/null
19641 #kill $pid0 2>/dev/null; wait
19642 if [ "$rc1b" -ne 0 ]; then
19643 $PRINTF "$FAILED (rc1b=$rc1b)\n"
19644 echo "$CMD0 &"
19645 cat "${te}0" >&2
19646 echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD1"
19647 cat "${te}1a" >&2
19648 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD1"
19649 cat "${te}1b" >&2
19650 numFAIL=$((numFAIL+1))
19651 listFAIL="$listFAIL $N"
19652 namesFAIL="$namesFAIL $NAME"
19653 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1a" >${tdiff}_a; then
19654 $PRINTF "$FAILED (diff a)\n"
19655 echo "$CMD0 &"
19656 cat "${te}0" >&2
19657 echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD1"
19658 cat "${te}1a" >&2
19659 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD1"
19660 cat "${te}1b" >&2
19661 echo "// diff a:" >&2
19662 cat "${tdiff}_a" >&2
19663 numFAIL=$((numFAIL+1))
19664 listFAIL="$listFAIL $N"
19665 namesFAIL="$namesFAIL $NAME"
19666 elif ! $ECHO "$da_a\n$da_b" |diff - "${tf}1b" >${tdiff}_b; then
19667 $PRINTF "$FAILED (diff b)\n"
19668 echo "$CMD0 &"
19669 cat "${te}0" >&2
19670 echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD1"
19671 cat "${te}1a" >&2
19672 echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10; } |$CMD1"
19673 cat "${te}1b" >&2
19674 echo "// diff b:" >&2
19675 cat "${tdiff}_b" >&2
19676 numFAIL=$((numFAIL+1))
19677 listFAIL="$listFAIL $N"
19678 namesFAIL="$namesFAIL $NAME"
19679 else
19680 $PRINTF "$OK\n"
19681 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19682 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19683 if [ "$VERBOSE" ]; then echo "{ relsleep 10; echo \"\$da_a\"; relsleep 20; } |$CMD1"; fi
19684 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
19685 if [ "$VERBOSE" ]; then echo "{ relsleep 20; echo \"\$da_b\"; relsleep 10.; } |$CMD1"; fi
19686 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
19687 numOK=$((numOK+1))
19688 listOK="$listOK $N"
19690 fi # NUMCOND
19692 esac
19693 N=$((N+1))
19696 # Socat 1.8.0.0 with addresses of type RECVFROM and option fork entered a
19697 # loop that was only stopped by FD exhaustion cause by FD leak, when the
19698 # second address failed to connect/open in the child process
19699 NAME=RECVFROM_FORK_LOOP
19700 case "$TESTS" in
19701 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%udp4%*|*%fork%*|*%socket%*|*%$NAME%*)
19702 TEST="$NAME: Bug on RECVFROM with fork and child failure"
19703 # Start a Socat process that uses UDP4-RECFROM with fork options, and in the
19704 # second address opens a file in a non existent directory.
19705 # Send a UDP4-packet to the receiver.
19706 # When only one child process is forked off, thus when only one appropriate
19707 # error message is in the log file, the test succeeded.
19708 if ! eval $NUMCOND; then :
19709 elif ! cond=$(checkconds \
19710 "" \
19711 "" \
19712 "" \
19713 "IP4 UDP STDIO FILE" \
19714 "UDP4-RECVFROM OPEN STDIO UDP4-SEND" \
19715 "fork" \
19716 "udp4" ); then
19717 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19718 numCANT=$((numCANT+1))
19719 listCANT="$listCANT $N"
19720 namesCANT="$namesCANT $NAME"
19721 else
19722 tf="$td/test$N.stdout"
19723 te="$td/test$N.stderr"
19724 tdiff="$td/test$N.diff"
19725 da="test$N $(date) $RANDOM"
19726 newport udp4
19727 CMD0="$TRACE $SOCAT $opts UDP4-RECVFROM:$PORT,fork OPEN:$td/nonexistent/file"
19728 CMD1="$TRACE $SOCAT $opts - UDP4-SENDTO:$LOCALHOST4:$PORT"
19729 printf "test $F_n $TEST... " $N
19730 $CMD0 >/dev/null 2>"${te}0" &
19731 pid0=$!
19732 waitudp4port $PORT 1
19733 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
19734 rc1=$?
19735 kill $pid0 2>/dev/null; wait
19736 if [ "$rc1" -ne 0 ]; then
19737 $PRINTF "$CANT (rc1=$rc1)\n"
19738 echo "$CMD0 &"
19739 cat "${te}0" >&2
19740 echo "echo \$da\" |$CMD1"
19741 cat "${te}1" >&2
19742 numCANT=$((numCANT+1))
19743 listCANT="$listCANT $N"
19744 namesCANT="$namesCANT $NAME"
19745 elif [ $(grep -c " E open(" "${te}0") -eq 0 ]; then
19746 $PRINTF "$CANT (no error)\n"
19747 echo "$CMD0 &"
19748 cat "${te}0" >&2
19749 echo "echo \$da\" |$CMD1"
19750 cat "${te}1" >&2
19751 numCANT=$((numCANT+1))
19752 listCANT="$listCANT $N"
19753 namesCANT="$namesCANT $NAME"
19754 elif [ $(grep -c " E open(" "${te}0") -ge 2 ]; then
19755 $PRINTF "$FAILED (this bug)\n"
19756 echo "$CMD0 &"
19757 head -n 2 "${te}0" >&2
19758 echo "echo \$da\" |$CMD1"
19759 cat "${te}1" >&2
19760 numFAIL=$((numFAIL+1))
19761 listFAIL="$listFAIL $N"
19762 namesFAIL="$namesFAIL $NAME"
19763 else
19764 $PRINTF "$OK\n"
19765 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19766 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19767 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
19768 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19769 numOK=$((numOK+1))
19770 listOK="$listOK $N"
19772 fi # NUMCOND
19774 esac
19775 N=$((N+1))
19778 # Socat 1.8.0.0 with addresses of type RECVFROM and option fork had a file
19779 # descriport leak that could lead to FD exhaustion.
19780 NAME=RECVFROM_FORK_LEAK
19781 case "$TESTS" in
19782 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%udp%*|*%udp4%*|*%fork%*|*%socket%*|*%$NAME%*)
19783 TEST="$NAME: FD leak on RECVFROM with fork"
19784 # Start a Socat process that uses UDP4-RECFROM with fork option.
19785 # Send two UDP4-packets to the receiver.
19786 # Check the server logs: when the socketpair calls on the second packet returns
19787 # the same FDs as the first call, the test succeeded.
19788 if ! eval $NUMCOND; then :
19789 elif ! cond=$(checkconds \
19790 "" \
19791 "" \
19792 "" \
19793 "IP4 UDP FILE STDIO" \
19794 "UDP4-RECVFROM FILE STDIO UDP4-SENDTO" \
19795 "fork" \
19796 "udp4" ); then
19797 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19798 numCANT=$((numCANT+1))
19799 listCANT="$listCANT $N"
19800 namesCANT="$namesCANT $NAME"
19801 else
19802 tf="$td/test$N.stdout"
19803 te="$td/test$N.stderr"
19804 tdiff="$td/test$N.diff"
19805 da="test$N $(date) $RANDOM"
19806 newport udp4
19807 CMD0="$TRACE $SOCAT $opts -ddd UDP4-RECVFROM:$PORT,fork FILE:/dev/null"
19808 CMD1="$TRACE $SOCAT $opts - UDP4-SEND:$LOCALHOST4:$PORT"
19809 printf "test $F_n $TEST... " $N
19810 $CMD0 >/dev/null 2>"${te}0" &
19811 pid0=$!
19812 waitudp4port $PORT 1
19813 echo "$da a" |$CMD1 >"${tf}1a" 2>"${te}1a"
19814 echo "$da b" |$CMD1 >"${tf}1b" 2>"${te}1b"
19815 rc1=$?
19816 kill $pid0 2>/dev/null; wait
19817 if [ "$rc1" -ne 0 ]; then
19818 $PRINTF "$CANT (rc1=$rc1)\n"
19819 echo "$CMD0 &"
19820 cat "${te}0" >&2
19821 echo "echo \$da a\" |$CMD1"
19822 cat "${te}1a" >&2
19823 echo "echo \$da b\" |$CMD1"
19824 cat "${te}1b" >&2
19825 numCANT=$((numCANT+1))
19826 listCANT="$listCANT $N"
19827 namesCANT="$namesCANT $NAME"
19828 elif [ $(grep -c " I socketpair(" "${te}0") -ne 2 ]; then
19829 $PRINTF "$CANT (not 2 socketpair())\n"
19830 echo "$CMD0 &"
19831 #cat "${te}0" >&2
19832 echo "echo \$da a\" |$CMD1"
19833 cat "${te}1a" >&2
19834 echo "echo \$da b\" |$CMD1"
19835 cat "${te}1b" >&2
19836 numCANT=$((numCANT+1))
19837 listCANT="$listCANT $N"
19838 namesCANT="$namesCANT $NAME"
19839 elif ! diff <(grep " I socketpair(" "${te}0" |head -n 1 |sed 's/.*\( I socketpair.*\)/\1/') <(grep " I socketpair(" "${te}0" |tail -n 1 |sed 's/.*\( I socketpair.*\)/\1/') >/dev/null 2>&1; then
19840 $PRINTF "$FAILED (this bug)\n"
19841 echo "$CMD0 &"
19842 grep " I socketpair(" "${te}0" >&2
19843 echo "echo \$da a\" |$CMD1"
19844 cat "${te}1a" >&2
19845 echo "echo \$da b\" |$CMD1"
19846 cat "${te}1b" >&2
19847 numFAIL=$((numFAIL+1))
19848 listFAIL="$listFAIL $N"
19849 namesFAIL="$namesFAIL $NAME"
19850 else
19851 $PRINTF "$OK\n"
19852 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19853 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19854 if [ "$VERBOSE" ]; then echo "echo \$da a\" |$CMD1"; fi
19855 if [ "$DEBUG" ]; then cat "${te}1a" >&2; fi
19856 if [ "$VERBOSE" ]; then echo "echo \$da b\" |$CMD1"; fi
19857 if [ "$DEBUG" ]; then cat "${te}1b" >&2; fi
19858 numOK=$((numOK+1))
19859 listOK="$listOK $N"
19861 fi # NUMCOND
19863 esac
19864 N=$((N+1))
19867 # Test for a bug (up to 1.8.0.0) with IP-SENDTO and option pf (protocol-family)
19868 # with protocol name (vs.numeric)
19869 NAME=IP_SENDTO_PF
19870 case "$TESTS" in
19871 *%$N%*|*%functions%*|*%root%*|*%bugs%*|*%socket%*|*%ip4%*|*%rawip%*|*%gopen%*|*%$NAME%*)
19872 TEST="$NAME: test IP-SENDTO with option pf with protocol name"
19873 # Invoke Socat with address IP-SENDTO with option pf=ip4
19874 # When this works the test succeeded; when an error (in particular:
19875 # E retropts_int(): trailing garbage in numerical arg of option "protocol-family")
19876 # occurs, the test fails
19877 if ! eval $NUMCOND; then :
19878 # Remove unneeded checks, adapt lists of the remaining ones
19879 elif ! cond=$(checkconds \
19880 "" \
19881 "root" \
19882 "" \
19883 "IP4 RAWIP GOPEN" \
19884 "GOPEN IP-SENDTO" \
19885 "pf" \
19886 "ip4" ); then
19887 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19888 numCANT=$((numCANT+1))
19889 listCANT="$listCANT $N"
19890 namesCANT="$namesCANT $NAME"
19891 else
19892 tf="$td/test$N.stdout"
19893 te="$td/test$N.stderr"
19894 tdiff="$td/test$N.diff"
19895 da="test$N $(date) $RANDOM"
19896 CMD0="$TRACE $SOCAT $opts -u /dev/null IP-SENDTO:127.0.0.1:254,pf=ip4"
19897 printf "test $F_n $TEST... " $N
19898 $CMD0 >/dev/null 2>"${te}0"
19899 rc0=$?
19900 if [ "$rc0" -ne 0 ]; then
19901 $PRINTF "$FAILED (rc0=$rc0)\n"
19902 echo "$CMD0 &"
19903 cat "${te}0" >&2
19904 numFAIL=$((numFAIL+1))
19905 listFAIL="$listFAIL $N"
19906 namesFAIL="$namesFAIL $NAME"
19907 else
19908 $PRINTF "$OK\n"
19909 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19910 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19911 numOK=$((numOK+1))
19912 listOK="$listOK $N"
19914 fi # NUMCOND
19916 esac
19917 N=$((N+1))
19920 # DEVTESTS IPv4/IPv6 resolver tests: just manually:
19922 # Prepare:
19923 #socat TCP4-LISTEN:12345,reuseaddr,fork PIPE
19924 # These must succeed:
19925 #echo AAAA |socat - TCP4:localhost-4.dest-unreach.net:12345
19926 #echo AAAA |socat - TCP4:localhost-4-6.dest-unreach.net:12345
19927 #echo AAAA |socat - TCP4:localhost-6-4.dest-unreach.net:12345
19929 # Prepare:
19930 #socat TCP6-LISTEN:12345,reuseaddr,fork PIPE
19931 # These must succeed:
19932 #echo AAAA |socat - TCP6:localhost-6.dest-unreach.net:12345
19933 #echo AAAA |socat - TCP6:localhost-6-4.dest-unreach.net:12345
19934 #echo AAAA |socat - TCP6:localhost-4-6.dest-unreach.net:12345
19936 # These must fail with No address associated with hostname
19937 #socat - TCP4:localhost-6.dest-unreach.net:12345
19938 #socat - TCP6:localhost-4.dest-unreach.net:12345
19941 # Is option -0 available?
19942 opt0=
19943 if SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-0[[:space:]]' >/dev/null; then
19944 opt0=-0
19947 # Test if Socat TCP-L without special options and env accepts IPv4 connections.
19948 # This is traditional behaviour, but version 1.8.0.0 did this only on Linux.
19949 NAME=LISTEN_4
19950 case "$TESTS" in
19951 *%$N%*|*%functions%*|*%ip4%*|*%tcp4%*|*%listen%*|*%socket%*|*%$NAME%*)
19952 TEST="$NAME: TCP-L with -0 accepts IPv4"
19953 # Start a listener with TCP-L, check if TCP4-CONNECT succeeds
19954 if ! eval $NUMCOND; then :
19955 elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then
19956 $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N
19957 numCANT=$((numCANT+1))
19958 listCANT="$listCANT $N"
19959 namesCANT="$namesCANT $NAME"
19960 elif ! cond=$(checkconds \
19961 "" \
19962 "" \
19963 "" \
19964 "IP4 TCP LISTEN FILE" \
19965 "TCP-LISTEN TCP4-CONNECT FILE" \
19966 "" \
19967 "tcp4" ); then
19968 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
19969 numCANT=$((numCANT+1))
19970 listCANT="$listCANT $N"
19971 namesCANT="$namesCANT $NAME"
19972 else
19973 opt0=
19974 if SOCAT_MAIN_WAIT= $SOCAT -h |grep -e '[[:space:]]-0[[:space:]]' >/dev/null; then
19975 opt0=-0
19977 tf="$td/test$N.stdout"
19978 te="$td/test$N.stderr"
19979 tdiff="$td/test$N.diff"
19980 da="test$N $(date) $RANDOM"
19981 newport tcp4
19982 CMD0="$TRACE $SOCAT $opts -u $opt0 TCP-LISTEN:$PORT FILE:/dev/null"
19983 CMD1="$TRACE $SOCAT $opts -u FILE:/dev/null TCP4-CONNECT:$LOCALHOST4:$PORT"
19984 printf "test $F_n $TEST... " $N
19985 $CMD0 >/dev/null 2>"${te}0" &
19986 pid0=$!
19987 relsleep 10
19988 $CMD1 >"${tf}1" 2>"${te}1"
19989 rc1=$?
19990 kill $pid0 2>/dev/null; wait
19991 if [ "$rc1" -ne 0 ]; then
19992 case "$UNAME" in
19993 FreeBSD|NetBSD|OpenBSD)
19994 $PRINTF "${GREEN}FAILED${NORMAL} (by design not on BSD)\n"
19995 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
19996 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
19997 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
19998 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
19999 numOK=$((numOK+1)) ;;
20000 Linux)
20001 $PRINTF "$FAILED (rc1=$rc1)\n"
20002 echo "$CMD0 &"
20003 cat "${te}0" >&2
20004 echo "$CMD1"
20005 cat "${te}1" >&2
20006 numFAIL=$((numFAIL+1))
20007 listFAIL="$listFAIL $N"
20008 namesFAIL="$namesFAIL $NAME" ;;
20010 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20011 numCANT=$((numCANT+1))
20012 listCANT="$listCANT $N"
20013 namesCANT="$namesCANT $NAME" ;;
20014 esac
20015 else
20016 $PRINTF "$OK\n"
20017 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20018 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20019 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
20020 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
20021 numOK=$((numOK+1))
20023 fi # NUMCOND
20025 esac
20026 N=$((N+1))
20028 # Test if Socat TCP-L without special options and env accepts IPv6 connections.
20029 # This is a nice-to-have behaviour, it might only work on Linux.
20030 NAME=LISTEN_6
20031 case "$TESTS" in
20032 *%$N%*|*%functions%*|*%ip6%*|*%tcp%*|*%listen%*|*%socket%*|*%$NAME%*)
20033 TEST="$NAME: TCP-L with -0 accepts IPv6"
20034 # Start a listener with TCP-L, check if TCP6-CONNECT succeeds
20035 if ! eval $NUMCOND; then :
20036 elif [ -z "$opt0" -a $SOCAT_VERSION != 1.8.0.0 ]; then
20037 $PRINTF "test $F_n $TEST... ${YELLOW}Option -0 not available${NORMAL}\n" $N
20038 numCANT=$((numCANT+1))
20039 listCANT="$listCANT $N"
20040 namesCANT="$namesCANT $NAME"
20041 elif ! cond=$(checkconds \
20042 "" \
20043 "" \
20044 "" \
20045 "IP6 TCP LISTEN FILE" \
20046 "TCP-LISTEN TCP6-CONNECT FILE" \
20047 "" \
20048 "tcp6" ); then
20049 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20050 numCANT=$((numCANT+1))
20051 listCANT="$listCANT $N"
20052 namesCANT="$namesCANT $NAME"
20053 else
20054 tf="$td/test$N.stdout"
20055 te="$td/test$N.stderr"
20056 tdiff="$td/test$N.diff"
20057 da="test$N $(date) $RANDOM"
20058 newport tcp6
20059 CMD0="$TRACE $SOCAT $opts -u $opt0 TCP-LISTEN:$PORT,ai-addrconfig=0 FILE:/dev/null"
20060 CMD1="$TRACE $SOCAT $opts -u FILE:/dev/null TCP6-CONNECT:$LOCALHOST6:$PORT"
20061 printf "test $F_n $TEST... " $N
20062 $CMD0 >/dev/null 2>"${te}0" &
20063 pid0=$!
20064 relsleep 10
20065 $CMD1 >"${tf}1" 2>"${te}1"
20066 rc1=$?
20067 kill $pid0 2>/dev/null; wait
20068 if [ "$rc1" -ne 0 ]; then
20069 $PRINTF "$FAILED (rc1=$rc1)\n"
20070 echo "$CMD0 &"
20071 cat "${te}0" >&2
20072 echo "$CMD1"
20073 cat "${te}1" >&2
20074 numFAIL=$((numFAIL+1))
20075 listFAIL="$listFAIL $N"
20076 namesFAIL="$namesFAIL $NAME"
20077 else
20078 $PRINTF "$OK\n"
20079 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20080 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20081 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
20082 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
20083 numOK=$((numOK+1))
20085 fi # NUMCOND
20087 esac
20088 N=$((N+1))
20091 BIN_TIMEOUT=
20092 if type timeout >/dev/null 2>&1; then
20093 BIN_TIMEOUT=timeout
20096 # Test regression in 1.8.0.0 of passive IP addresses without explicit IP version
20097 # with options range and bind using IPv4 addresses
20098 while read ADDR protov IPPORT ACCEPT_TIMEOUT option _; do
20099 if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi
20100 [ "$ACCEPT_TIMEOUT" = "." ] && ACCEPT_TIMEOUT=""
20101 FEATS=
20102 case "$ADDR" in *-LISTEN|*-L) FEATS=LISTEN ;; esac
20103 ADDR_="$(echo $ADDR |tr - _)"
20104 PROTO="${ADDR%%-*}"
20105 proto=$(tolower $PROTO)
20106 OPTION=$(toupper $option)
20107 FEATS="$FEATS $PROTO"
20108 case "$PROTO" in OPENSSL*|SSL*) PROTO=TCP ;; esac
20109 OPTKW="${OPTION%%=**}"
20111 NAME="$(echo "V1800_${ADDR_}_${OPTION%%=*}" |sed 's/:[.0-8]*//')"
20112 case "$TESTS" in
20113 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%$protov%*|*$proto%*|*%socket%*|*%$NAME%*)
20114 TEST="$NAME: test regression of $ADDR with IPv4 $OPTKW"
20115 # Start a command with the given address and use bind or range with IPv4
20116 # address, terminate immediately. When no error occurs the test succeeded.
20117 if ! eval $NUMCOND; then :
20118 elif ! cond=$(checkconds \
20119 "" \
20120 "$([ $IPPORT = PROTO ] && echo root)" \
20121 "" \
20122 "$FEATS IP4 PIPE" \
20123 "$ADDR PIPE" \
20124 "${option%%=*}" \
20125 "$(tolower $PROTO)4 $(tolower $PROTO)6" ); then
20126 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20127 numCANT=$((numCANT+1))
20128 listCANT="$listCANT $N"
20129 namesCANT="$namesCANT $NAME"
20130 else
20131 tf="$td/test$N.stdout"
20132 te="$td/test$N.stderr"
20133 tdiff="$td/test$N.diff"
20134 da="test$N $(date) $RANDOM"
20135 case X$IPPORT in
20136 XPORT) newport $(tolower $PROTO); _PORT=$PORT ;;
20137 XPROTO) echo "IPPROTO=\"$IPPROTO\""
20138 _PORT=$IPPROTO ;;
20139 esac
20140 CMD0="$TRACE $SOCAT $opts ${ADDR}:$_PORT,$option,$ACCEPT_TIMEOUT PIPE"
20141 printf "test $F_n $TEST... " $N
20142 if [ -z "$ACCEPT_TIMEOUT" ] && [ -z "$BIN_TIMEOUT" ]; then
20143 $PRINTF "$CANT (would block)\n"
20144 numCANT=$((numCANT+1))
20145 listCANT="$listCANT $N"
20146 namesCANT="$namesCANT $NAME"
20147 else
20148 if [ "$BIN_TIMEOUT" ]; then
20149 $BIN_TIMEOUT 0.1 $CMD0 >/dev/null 2>"${te}0"
20150 else
20151 $CMD0 >/dev/null 2>"${te}0"
20153 rc0=$?
20154 # rc0=124 is SIGALRM from timeout, is success
20155 if [ "$rc0" -ne 0 -a "$rc0" -ne 124 ]; then
20156 $PRINTF "$FAILED (rc0=$rc0)\n"
20157 echo "$CMD0 &"
20158 cat "${te}0" >&2
20159 numFAIL=$((numFAIL+1))
20160 listFAIL="$listFAIL $N"
20161 namesFAIL="$namesFAIL $NAME"
20162 else
20163 $PRINTF "$OK\n"
20164 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20165 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20166 numOK=$((numOK+1))
20167 listOK="$listOK $N"
20169 fi # not would block
20170 fi # NUMCOND
20172 esac
20173 N=$((N+1))
20174 done <<<"
20175 TCP-LISTEN tcp4 PORT accept-timeout=0.001 range=localhost:255.255.255.255
20176 TCP-LISTEN tcp4 PORT accept-timeout=0.001 bind=127.0.0.1 # works
20177 SCTP-LISTEN sctp4 PORT accept-timeout=0.001 range=localhost:255.255.255.255
20178 SCTP-LISTEN sctp4 PORT accept-timeout=0.001 bind=127.0.0.1 # works
20179 DCCP-LISTEN dccp4 PORT accept-timeout=0.001 range=localhost:255.255.255.255
20180 DCCP-LISTEN dccp4 PORT accept-timeout=0.001 bind=127.0.0.1 # works
20181 OPENSSL-LISTEN tcp4 PORT accept-timeout=0.001 range=localhost:255.255.255.255
20182 OPENSSL-LISTEN tcp4 PORT accept-timeout=0.001 bind=127.0.0.1 # works
20183 UDP-LISTEN udp4 PORT . range=127.0.0.1/8
20184 UDP-LISTEN udp4 PORT . bind=127.0.0.1
20185 UDP-RECVFROM udp4 PORT . range=127.0.0.1/8
20186 UDP-RECVFROM udp4 PORT . bind=127.0.0.1
20187 UDPLITE-LISTEN udplite4 PORT . range=127.0.0.1/8
20188 UDPLITE-LISTEN udplite4 PORT . bind=127.0.0.1
20189 UDPLITE-RECVFROM udplite4 PORT . range=127.0.0.1/8
20190 UDPLITE-RECVFROM udplite4 PORT . bind=127.0.0.1
20191 UDP-DATAGRAM:1.2.3.4 udp4 PORT . range=127.0.0.1/8
20192 UDP-DATAGRAM:1.2.3.4 udp4 PORT . bind=127.0.0.1
20193 UDPLITE-DATAGRAM:1.2.3.4 udplite4 PORT . range=127.0.0.1/8
20194 UDPLITE-DATAGRAM:1.2.3.4 udplite4 PORT . bind=127.0.0.1
20195 IP-DATAGRAM:1.2.3.4 ip4 PROTO . range=127.0.0.1/8
20196 IP-DATAGRAM:1.2.3.4 ip4 PROTO . bind=127.0.0.1
20200 # Test if datagram SENDTO to a server name that resolves to IPv6 first and IPv4
20201 # as second address, binding to an IPv4 address, uses IPv4
20202 # This failed in Socat 1.8.0.0
20203 while read ADDR protov IPPORT _; do
20204 if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi
20205 FEATS=
20206 ADDR_="$(echo $ADDR |tr - _)" # UDP_SENDTO
20207 PROTO="${ADDR%%-*}" # UDP
20208 proto=$(tolower $PROTO) # udp
20209 FEATS="$FEATS $PROTO"
20210 NAME="$(echo "V1800_${ADDR_}_RESOLV_6_4" |sed 's/:[.0-8]*//')"
20211 case "$TESTS" in
20212 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%$protov%*|*%$proto%*|*%socket%*|*%$NAME%*)
20213 TEST="$NAME: test regression of $ADDR with IPv6,4 and binding to IPv4"
20214 # Start a SENDTO command to (internal) test name localhost-6-4.dest-unreach.net
20215 # and bind to an IPv4 address, and terminate immediately.
20216 # When no error occurs the test succeeded.
20217 if ! eval $NUMCOND; then :
20218 elif ! cond=$(checkconds \
20219 "" \
20220 "$([ $IPPORT = PROTO ] && echo root)" \
20221 "" \
20222 "$FEATS DEVTESTS IP4" \
20223 "$ADDR GOPEN" \
20224 "bind" \
20225 "$protov" ); then
20226 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20227 numCANT=$((numCANT+1))
20228 listCANT="$listCANT $N"
20229 namesCANT="$namesCANT $NAME"
20230 else
20231 tf="$td/test$N.stdout"
20232 te="$td/test$N.stderr"
20233 tdiff="$td/test$N.diff"
20234 da="test$N $(date) $RANDOM"
20235 case X$IPPORT in
20236 XPORT) newport $(tolower $PROTO); _PORT=$PORT ;;
20237 XPROTO) echo "IPPROTO=\"$IPPROTO\""
20238 _PORT=$IPPROTO ;;
20239 esac
20240 CMD0="$TRACE $SOCAT $opts -u /dev/null $ADDR:localhost-6-4.dest-unreach.net:$_PORT,bind=127.0.0.1"
20241 printf "test $F_n $TEST... " $N
20242 $CMD0 2>"${te}0" </dev/null
20243 rc0=$?
20244 if [ "$rc0" -ne 0 ]; then
20245 $PRINTF "$FAILED (rc0=$rc0)\n"
20246 echo "$CMD0"
20247 cat "${te}0" >&2
20248 numFAIL=$((numFAIL+1))
20249 listFAIL="$listFAIL $N"
20250 namesFAIL="$namesFAIL $NAME"
20251 else
20252 $PRINTF "$OK\n"
20253 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20254 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20255 numOK=$((numOK+1))
20256 listOK="$listOK $N"
20258 fi # NUMCOND
20260 esac
20261 PORT=$((PORT+1))
20262 N=$((N+1))
20263 done <<<"
20264 UDP-SENDTO udp4 PORT
20265 UDPLITE-SENDTO udplite4 PORT
20266 IP-SENDTO ip4 PROTO
20269 # Test if CONNECT to a server name that resolves to IPv6 first and IPv4
20270 # as second address, when binding to an IPv4 address, uses IPv4
20271 # This failed in Socat 1.8.0.0
20272 while read ADDR protov IPPORT _; do
20273 if [ -z "$ADDR" ] || [[ "$ADDR" == \#* ]]; then continue; fi
20274 FEATS=
20275 ADDR_="$(echo $ADDR |tr - _)" # TCP_CONNECT
20276 PROTO="${ADDR%%[-:]*}" # TCP
20277 proto=$(tolower $PROTO) # tcp
20278 FEATS="$FEATS $PROTO"
20279 NAME="$(echo "V1800_${ADDR_}_CONNECT_6_4" |sed 's/:[.0-8]*//')"
20280 case "$TESTS" in
20281 *%$N%*|*%functions%*|*%bugs%*|*%ip4%*|*%$protov%*|*%$proto%*|*%socket%*|*%$NAME%*)
20282 TEST="$NAME: test regression of $ADDR with IPv6,4 and binding to IPv4"
20283 # Run an appropriate server address in background.
20284 # Start a CONNECT command to (internal) test name localhost-6-4.dest-unreach.net
20285 # and bind to an IPv4 address, connect, terminate immediately.
20286 # When no error occurs the test succeeded.
20287 if ! eval $NUMCOND; then :
20288 elif ! cond=$(checkconds \
20289 "" \
20290 "" \
20291 "" \
20292 "$FEATS DEVTESTS IP4" \
20293 "$ADDR GOPEN" \
20294 "bind" \
20295 "$protov" ); then
20296 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20297 numCANT=$((numCANT+1))
20298 listCANT="$listCANT $N"
20299 namesCANT="$namesCANT $NAME"
20300 else
20301 tf="$td/test$N.stdout"
20302 te="$td/test$N.stderr"
20303 tdiff="$td/test$N.diff"
20304 da="test$N $(date) $RANDOM"
20305 case X$IPPORT in
20306 XPORT) newport $(tolower $PROTO); _PORT=$PORT ;;
20307 XPROTO) echo "IPPROTO=\"$IPPROTO\""
20308 _PORT=$IPPROTO ;;
20309 esac
20310 CMD0="$TRACE $SOCAT $opts ${ADDR%%-*}-LISTEN:$_PORT,pf=ip4 PIPE"
20311 CMD1="$TRACE $SOCAT $opts /dev/null $ADDR:localhost-6-4.dest-unreach.net:$_PORT,bind=127.0.0.1"
20312 printf "test $F_n $TEST... " $N
20313 $CMD0 2>"${te}0" </dev/null &
20314 pid0=$!
20315 wait${protov}port $PORT 1
20316 $CMD1 2>"${te}1" </dev/null
20317 rc1=$?
20318 kill $pid0 2>/dev/null; wait
20319 if [ "$rc1" -ne 0 ]; then
20320 $PRINTF "$FAILED (rc1=$rc1)\n"
20321 echo "$CMD0 &"
20322 cat "${te}0" >&2
20323 echo "$CMD1"
20324 cat "${te}1" >&2
20325 numFAIL=$((numFAIL+1))
20326 listFAIL="$listFAIL $N"
20327 namesFAIL="$namesFAIL $NAME"
20328 else
20329 $PRINTF "$OK\n"
20330 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20331 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20332 numOK=$((numOK+1))
20333 listOK="$listOK $N"
20335 fi # NUMCOND
20337 esac
20338 PORT=$((PORT+1))
20339 N=$((N+1))
20340 done <<<"
20341 TCP-CONNECT tcp4 PORT
20342 SCTP-CONNECT sctp4 PORT
20343 DCCP-CONNECT dccp4 PORT
20344 #PENSSL tcp4 PORT
20345 #OCKS4:127.0.0.1 tcp4 PORT
20346 #OCKS4A:127.0.0.1 tcp4 PORT
20347 #OCKS5:127.0.0.1:1080 tcp4 PORT
20348 #ROXY::127.0.0.1 tcp4 PORT
20352 # Test the readline.sh file overwrite vulnerability
20353 NAME=READLINE_SH_OVERWRITE
20354 case "$TESTS" in
20355 *%$N%*|*%functions%*|*%bugs%*|*%readline%*|*%security%*|*%$NAME%*)
20356 TEST="$NAME: Test the readline.sh file overwrite vulnerability"
20357 # Create a symlink /tmp/$USER/stderr2 pointing to a temporary file,
20358 # run readline.sh
20359 # When the temporary file is kept the test succeeded
20360 if ! eval $NUMCOND; then :
20361 elif ! cond=$(checkconds \
20362 "" \
20363 "" \
20364 "readline.sh" \
20365 "" \
20366 "" \
20367 "" \
20368 "" ); then
20369 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20370 numCANT=$((numCANT+1))
20371 listCANT="$listCANT $N"
20372 namesCANT="$namesCANT $NAME"
20373 else
20374 tf="$td/test$N.file"
20375 te="$td/test$N.stderr"
20376 tdiff="$td/test$N.diff"
20377 da="test$N $(date) $RANDOM"
20378 echo "$da" >"$tf"
20379 ln -sf "$tf" /tmp/$USER/stderr2
20380 CMD0="readline.sh cat"
20381 printf "test $F_n $TEST... " $N
20382 $CMD0 </dev/null >/dev/null 2>"${te}0"
20383 rc0=$?
20384 # if [ "$rc0" -ne 0 ]; then
20385 # $PRINTF "$CANT (rc0=$rc0)\n"
20386 # echo "$CMD0"
20387 # cat "${te}0" >&2
20388 # numCANT=$((numCANT+1))
20389 # listCANT="$listCANT $N"
20390 # namesCANT="$namesCANT $NAME"
20391 # elif ! echo "$da" |diff - "$tf" >$tdiff; then
20392 if ! echo "$da" |diff - "$tf" >$tdiff; then
20393 $PRINTF "$FAILED (diff)\n"
20394 echo "$CMD0 &"
20395 cat "${te}0" >&2
20396 echo "// diff:" >&2
20397 cat "$tdiff" >&2
20398 numFAIL=$((numFAIL+1))
20399 listFAIL="$listFAIL $N"
20400 namesFAIL="$namesFAIL $NAME"
20401 else
20402 $PRINTF "$OK\n"
20403 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20404 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20405 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
20406 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
20407 numOK=$((numOK+1))
20408 listOK="$listOK $N"
20410 fi # NUMCOND
20412 esac
20413 N=$((N+1))
20415 # end of common tests
20417 ##################################################################################
20418 #=================================================================================
20419 # here come tests that might affect your systems integrity. Put normal tests
20420 # before this paragraph.
20421 # tests must be explicitely selected by roottough or name (not number)
20423 NAME=PTYGROUPLATE
20424 case "$TESTS" in
20425 *%roottough%*|*%$NAME%*)
20426 TEST="$NAME: pty with group-late works on pty"
20427 # up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of
20428 # the pty with options user-late, group-late, or perm-late.
20429 # here we check for correct behaviour.
20430 # ATTENTION: in case of failure of this test the
20431 # group of /dev/ptmx might be changed!
20432 if ! eval $NUMCOND; then :; else
20433 # save current /dev/ptmx properties
20435 for f in /dev/ptmx /dev/ptc; do
20436 if [ -e $f ]; then
20437 F=$(echo "$f" |tr / ..)
20438 ls -l $f >"$td/test$N.$F.ls-l"
20439 break
20441 done
20442 printf "test $F_n $TEST... " $N
20443 if [ -z "$F" ]; then
20444 echo -e "${YELLOW}no /dev/ptmx or /dev/ptc${NORMAL}"
20445 else
20446 GROUP=daemon
20447 tf="$td/test$N.stdout"
20448 te="$td/test$N.stderr"
20449 tl="$td/test$N.pty"
20450 tdiff="$td/test$N.diff"
20451 da="test$N $(date) $RANDOM"
20452 CMD0="$TRACE $SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE"
20453 CMD1="$TRACE $SOCAT $opts - $tl,raw,echo=0"
20454 $CMD0 >/dev/null 2>"${te}0" &
20455 pid0=$!
20456 (echo "$da"; relsleep 1; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf"
20457 rc1=$?
20458 kill $pid0 2>/dev/null; wait
20459 if [ $rc1 -ne 0 ]; then
20460 $PRINTF "$FAILED\n"
20461 echo "$CMD0 &"
20462 echo "$CMD1"
20463 cat "${te}0"
20464 cat "${te}1"
20465 numFAIL=$((numFAIL+1))
20466 listFAIL="$listFAIL $N"
20467 elif echo "$da" |diff - "$tf" >$tdiff; then
20468 $PRINTF "$OK\n"
20469 numOK=$((numOK+1))
20470 listOK="$listOK $N"
20471 else
20472 $PRINTF "$FAILED\n"
20473 cat "$tdiff"
20474 numFAIL=$((numFAIL+1))
20475 listFAIL="$listFAIL $N"
20477 if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then
20478 $PRINTF "${RED}this test changed properties of $f!${NORMAL}\n"
20480 fi # no /dev/ptmx
20481 fi # NUMCOND
20483 esac
20484 N=$((N+1))
20487 echo "Used temp directory $TD - you might want to remove it after analysis"
20488 echo "Summary: $((N-1)) tests, $((numOK+numFAIL+numCANT)) selected; $numOK ok, $numFAIL failed, $numCANT could not be performed"
20490 set -- $listCANT; while [ "$1" ]; do echo "$1"; shift; done >"$td/cannot.lst"
20491 ln -sf "$td/cannot.lst" .
20492 set -- $listOK; while [ "$1" ]; do echo "$1"; shift; done >"$td/success.lst"
20493 ln -sf "$td/success.lst" .
20494 set -- $listFAIL; while [ "$1" ]; do echo "$1"; shift; done >"$td/failed.lst"
20495 ln -sf "$td/failed.lst" .
20496 sort -n <(cat "$td/success.lst" |while read x; do echo "$x OK"; done) <(cat "$td/cannot.lst" |while read x; do echo "$x CANT"; done) <(cat "$td/failed.lst" |while read x; do echo "$x FAILED"; done) >"$td/result.txt"
20497 ln -sf "$td/result.txt" .
20498 if [ "$numCANT" -gt 0 ]; then
20499 echo "CANT: $listCANT"
20501 if [ "$numFAIL" -gt 0 ]; then
20502 echo "FAILED: $listFAIL"
20505 if [ -z "$OPT_EXPECT_FAIL" ]; then
20506 [ "$numFAIL" -eq 0 ]
20507 exit # with rc from above statement
20510 #set -vx
20512 if [ "$OPT_EXPECT_FAIL" ]; then
20513 diff <(set -- $(echo "$EXPECT_FAIL" |tr ',' ' '); while [ "$1" ]; do echo "$1"; shift; done) "$td/failed.lst" >"$td/failed.diff"
20514 ln -sf "$td/failed.diff" .
20515 #grep "^"
20516 grep "^> " "$td/failed.diff" |awk '{print($2);}' >"$td/failed.unexp"
20517 ln -sf "$td/failed.unexp" .
20518 echo "FAILED unexpected: $(cat "$td/failed.unexp" |xargs echo)"
20519 grep "^< " "$td/failed.diff" |awk '{print($2);}' >"$td/ok.unexp"
20520 ln -sf "$td/ok.unexp" .
20521 echo "OK unexpected: $(cat "$td/ok.unexp" |xargs echo)"
20522 else
20523 touch "$td/failed.diff"
20525 #listFAIL=$(cat "$td/failed.lst" |xargs echo)
20526 #numFAIL="$(wc -l "$td/failed.lst" |awk '{print($1);}')"
20528 ! test -s "$td/failed.unexp"
20529 exit
20531 #==============================================================================
20533 rm -f testsrv.* testcli.* testsrvdsa* testsrvfips* testclifips*
20535 # end
20537 # too dangerous - run as root and having a shell problem, it might purge your
20538 # file systems
20539 #rm -r "$td"
20541 # sometimes subprocesses hang; we want to see this
20542 wait
20544 exit
20546 #==============================================================================
20547 # test template
20549 # Give a description of what is tested (a bugfix, a new feature...)
20550 NAME=SHORT_UNIQUE_TESTNAME
20551 case "$TESTS" in
20552 *%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%$NAME%*)
20553 #*%internet%*|*%root%*|*%listen%*|*%fork%*|*%ip4%*|*%tcp4%*|*%bug%*|...
20554 TEST="$NAME: give a one line description of test"
20555 # Describe how the test is performed, and what's the success criteria
20556 if ! eval $NUMCOND; then :
20557 # Remove unneeded checks, adapt lists of the remaining ones
20558 elif ! cond=$(checkconds \
20559 "Linux FreeBSD" \
20560 "root" \
20561 "nslookup" \
20562 "IP4 TCP LISTEN STDIO PIPE" \
20563 "TCP4-LISTEN PIPE STDIN STDOUT TCP4" \
20564 "so-reuseaddr" \
20565 "tcp4" ); then
20566 $PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
20567 numCANT=$((numCANT+1))
20568 listCANT="$listCANT $N"
20569 namesCANT="$namesCANT $NAME"
20570 else
20571 tf="$td/test$N.stdout"
20572 te="$td/test$N.stderr"
20573 tdiff="$td/test$N.diff"
20574 da="test$N $(date) $RANDOM"
20575 newport tcp4 # or whatever proto, or drop this line
20576 CMD0="$TRACE $SOCAT $opts server-address PIPE"
20577 CMD1="$TRACE $SOCAT $opts - client-address"
20578 printf "test $F_n $TEST... " $N
20579 $CMD0 >/dev/null 2>"${te}0" &
20580 pid0=$!
20581 wait<something>port $PORT 1
20582 #relsleep 1 # if no matching wait*port function
20583 echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
20584 rc1=$?
20585 kill $pid0 2>/dev/null; wait
20586 if [ "$rc1" -ne 0 ]; then
20587 $PRINTF "$FAILED (rc1=$rc1)\n"
20588 echo "$CMD0 &"
20589 cat "${te}0" >&2
20590 echo "$CMD1"
20591 cat "${te}1" >&2
20592 numFAIL=$((numFAIL+1))
20593 listFAIL="$listFAIL $N"
20594 namesFAIL="$namesFAIL $NAME"
20595 elif ! echo "$da" |diff - "${tf}1" >$tdiff; then
20596 $PRINTF "$FAILED (diff)\n"
20597 echo "$CMD0 &"
20598 cat "${te}0" >&2
20599 echo "$CMD1"
20600 cat "${te}1" >&2
20601 echo "// diff:" >&2
20602 cat "$tdiff" >&2
20603 numFAIL=$((numFAIL+1))
20604 listFAIL="$listFAIL $N"
20605 namesFAIL="$namesFAIL $NAME"
20606 elif [ ??? ]; then
20607 # The test could not run meaningfully
20608 $PRINTF "$CANT\n"
20609 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20610 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20611 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
20612 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
20613 numCANT=$((numCANT+1))
20614 listCANT="$listCANT $N"
20615 else
20616 $PRINTF "$OK\n"
20617 if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
20618 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
20619 if [ "$VERBOSE" ]; then echo "$CMD1"; fi
20620 if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
20621 numOK=$((numOK+1))
20622 listOK="$listOK $N"
20624 fi # NUMCOND
20626 esac
20627 N=$((N+1))